[
  {
    "path": ".cargo/config.toml",
    "content": "# we use tokio_unstable to enable runtime::Handle::id so we can separate\n# globals from multiple parallel tests. If that function ever does get removed\n# its possible to replace (with some additional overhead and effort)\n# Annoyingly build.rustflags doesn't work here because it gets overwritten\n# if people have their own global target.<..> config (for example to enable mold)\n# specifying flags this way is more robust as they get merged\n# This still gets overwritten by RUST_FLAGS though, luckily it shouldn't be necessary\n# to set those most of the time. If downstream does overwrite this its not a huge\n# deal since it will only break tests anyway\n[target.\"cfg(all())\"]\nrustflags = [\"--cfg\", \"tokio_unstable\", \"-C\", \"target-feature=-crt-static\"]\n\n\n[alias]\nxtask = \"run --package xtask --\"\nintegration-test = \"test --features integration --profile integration --workspace --test integration\"\n\n"
  },
  {
    "path": ".envrc",
    "content": "watch_file shell.nix\nwatch_file default.nix\nwatch_file flake.lock\nwatch_file rust-toolchain.toml\n\n# try to use flakes, if it fails use normal nix (ie. shell.nix)\nuse flake || use nix\neval \"$shellHook\"\n"
  },
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform normalization\n*          text=auto\n\n*.rs       text diff=rust\n*.toml     text diff=toml\n\n*.scm      text diff=scheme\n*.md       text diff=markdown\n\nbook/theme/highlight.js linguist-vendored\nruntime/queries/**/*.scm linguist-language=Tree-sitter-Query\nCargo.lock text\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "open_collective: helix-editor\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yaml",
    "content": "name: Bug Report\ndescription: Create a report to help us improve\nlabels: C-bug\nbody:\n  - type: markdown\n    attributes:\n      value: Thank you for filing a bug report! 🐛\n  - type: textarea\n    id: problem\n    attributes:\n      label: Summary\n      description: >\n        Please provide a short summary of the bug, along with any information\n        you feel relevant to replicate the bug.\n    validations:\n      required: true\n  - type: textarea\n    id: reproduction-steps\n    attributes:\n      label: Reproduction Steps\n      value: |\n        <!-- Ideally provide a key sequence and/or asciinema.org recording. --> \n\n        I tried this:\n\n        1. `hx`\n\n        I expected this to happen:\n\n        Instead, this happened:\n  - type: textarea\n    id: helix-log\n    attributes:\n      label: Helix log\n      description: See `hx -h` for log file path. If you can reproduce the issue run `RUST_BACKTRACE=1 hx -vv` to generate a more detailed log file.\n      value: |\n        <details><summary>~/.cache/helix/helix.log</summary>\n\n        ```\n        please provide a copy of `~/.cache/helix/helix.log` here if possible, you may need to redact some of the lines\n        ```\n\n        </details>\n  - type: input\n    id: platform\n    attributes:\n      label: Platform\n      placeholder: Linux / macOS / Windows\n    validations:\n      required: true\n  - type: input\n    id: terminal-emulator\n    attributes:\n      label: Terminal Emulator\n      placeholder: wezterm 20220101-133340-7edc5b5a\n    validations:\n      required: true\n  - type: input\n    id: installation-method\n    attributes:\n      label: Installation Method\n      description: >\n        How you installed Helix - from a package manager like Homebrew or the\n        AUR, built from source, downloaded a binary from the releases page, etc.\n      placeholder: \"source / brew / nixpkgs / flake / releases page\"\n    validations:\n      required: true\n  - type: input\n    id: helix-version\n    attributes:\n      label: Helix Version\n      description: >\n        Helix version (`hx -V` if using a release, `git describe` if building\n        from master).\n        **Make sure that you are using the [latest helix release](https://github.com/helix-editor/helix/releases) or a newer master build**\n      placeholder: \"helix 22.12 (5eaa6d97)\"\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/enhancement.md",
    "content": "---\nname: Enhancement\nabout: Suggest an improvement\ntitle: ''\nlabels: C-enhancement\nassignees: ''\n---\n\n<!--\nYour enhancement may already be reported!\nPlease search on the issue tracker before creating a new issue.\nIf this is an idea for a feature, please open an \"Idea\" Discussion instead.\n-->\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# Please see the documentation for all configuration options:\n# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: \"cargo\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n    groups:\n      rust-dependencies:\n        update-types:\n          - \"minor\"\n          - \"patch\"\n\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Build\non:\n  pull_request:\n  push:\n    branches:\n      - master\n  merge_group:\n  schedule:\n    - cron: \"00 01 * * *\"\n\nenv:\n  MSRV: \"1.87\"\n  # This key can be changed to bust the cache of tree-sitter grammars.\n  GRAMMAR_CACHE_VERSION: \"\"\n\njobs:\n  check:\n    name: Check (msrv)\n    runs-on: ubuntu-latest\n    if: github.repository == 'helix-editor/helix' || github.event_name != 'schedule'\n    steps:\n      - name: Checkout sources\n        uses: actions/checkout@v6\n\n      - name: Install MSRV toolchain\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ env.MSRV }}\n\n      - uses: Swatinem/rust-cache@v2\n        with:\n          shared-key: \"build\"\n\n      - name: Cache tree-sitter grammars\n        uses: actions/cache@v5\n        with:\n          path: runtime/grammars\n          key: ${{ runner.os }}-${{ runner.arch }}-stable-v${{ env.GRAMMAR_CACHE_VERSION }}-tree-sitter-grammars-${{ hashFiles('languages.toml') }}\n          restore-keys: ${{ runner.os }}-${{ runner.arch }}-stable-v${{ env.GRAMMAR_CACHE_VERSION }}-tree-sitter-grammars-\n\n      - name: Run cargo check\n        run: cargo check\n\n  test:\n    name: Test Suite\n    runs-on: ${{ matrix.os }}\n    if: github.repository == 'helix-editor/helix' || github.event_name != 'schedule'\n    timeout-minutes: 30\n    env:\n      RUST_BACKTRACE: 1\n      HELIX_LOG_LEVEL: info\n    steps:\n      - name: Checkout sources\n        uses: actions/checkout@v6\n\n      - name: Install MSRV toolchain\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ env.MSRV }}\n\n      - uses: Swatinem/rust-cache@v2\n        with:\n          shared-key: \"build\"\n\n      - name: Cache tree-sitter grammars\n        uses: actions/cache@v5\n        with:\n          path: runtime/grammars\n          key: ${{ runner.os }}-${{ runner.arch }}-stable-v${{ env.GRAMMAR_CACHE_VERSION }}-tree-sitter-grammars-${{ hashFiles('languages.toml') }}\n          restore-keys: ${{ runner.os }}-${{ runner.arch }}-stable-v${{ env.GRAMMAR_CACHE_VERSION }}-tree-sitter-grammars-\n\n      - name: Run cargo test\n        run: cargo test --workspace\n\n      - name: Run cargo integration-test\n        run: cargo integration-test\n\n    strategy:\n      matrix:\n        os: [ubuntu-latest, macos-latest, windows-latest, ubuntu-24.04-arm]\n\n  lints:\n    name: Lints\n    runs-on: ubuntu-latest\n    if: github.repository == 'helix-editor/helix' || github.event_name != 'schedule'\n    steps:\n      - name: Checkout sources\n        uses: actions/checkout@v6\n\n      - name: Install MSRV toolchain\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ env.MSRV }}\n          components: rustfmt, clippy\n\n      - uses: Swatinem/rust-cache@v2\n        with:\n          shared-key: \"build\"\n\n      - name: Cache tree-sitter grammars\n        uses: actions/cache@v5\n        with:\n          path: runtime/grammars\n          key: ${{ runner.os }}-${{ runner.arch }}-stable-v${{ env.GRAMMAR_CACHE_VERSION }}-tree-sitter-grammars-${{ hashFiles('languages.toml') }}\n          restore-keys: ${{ runner.os }}-${{ runner.arch }}-stable-v${{ env.GRAMMAR_CACHE_VERSION }}-tree-sitter-grammars-\n\n      - name: Run cargo fmt\n        run: cargo fmt --all --check\n\n      - name: Run cargo clippy\n        run: cargo clippy --workspace --all-targets -- -D warnings\n\n      - name: Run cargo doc\n        run: cargo doc --no-deps --workspace --document-private-items\n        env:\n          RUSTDOCFLAGS: -D warnings\n\n  docs:\n    name: Docs\n    runs-on: ubuntu-latest\n    if: github.repository == 'helix-editor/helix' || github.event_name != 'schedule'\n    steps:\n      - name: Checkout sources\n        uses: actions/checkout@v6\n\n      - name: Install MSRV toolchain\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ env.MSRV }}\n\n      - uses: Swatinem/rust-cache@v2\n        with:\n          shared-key: \"build\"\n\n      - name: Cache tree-sitter grammars\n        uses: actions/cache@v5\n        with:\n          path: runtime/grammars\n          key: ${{ runner.os }}-${{ runner.arch }}-stable-v${{ env.GRAMMAR_CACHE_VERSION }}-tree-sitter-grammars-${{ hashFiles('languages.toml') }}\n          restore-keys: ${{ runner.os }}-${{ runner.arch }}-stable-v${{ env.GRAMMAR_CACHE_VERSION }}-tree-sitter-grammars-\n\n      - name: Validate queries\n        run: cargo xtask query-check\n\n      - name: Validate themes\n        run: cargo xtask theme-check\n\n      - name: Generate docs\n        run: cargo xtask docgen\n\n      - name: Check uncommitted documentation changes\n        run: |\n          git diff\n          git diff-files --quiet \\\n            || (echo \"Run 'cargo xtask docgen', commit the changes and push again\" \\\n            && exit 1)\n"
  },
  {
    "path": ".github/workflows/cachix.yml",
    "content": "# Publish the Nix flake outputs to Cachix\nname: Cachix\non:\n  push:\n    branches:\n      - master\n\njobs:\n  publish:\n    name: Publish Flake\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-latest, macos-latest]\n    steps:\n    - name: Checkout sources\n      uses: actions/checkout@v6\n\n    - name: Install nix\n      uses: cachix/install-nix-action@v31\n\n    - name: Authenticate with Cachix\n      uses: cachix/cachix-action@v16\n      with:\n        name: helix\n        authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}\n\n    - name: Build nix flake\n      run: nix build -L\n"
  },
  {
    "path": ".github/workflows/gh-pages.yml",
    "content": "name: GitHub Pages\n\non:\n  push:\n    branches:\n      - master\n    tags:\n      - '*'\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Setup mdBook\n        uses: peaceiris/actions-mdbook@v2\n        with:\n          # mdbook-version: 'latest'\n          mdbook-version: '0.5.2'\n\n      - run: mdbook build book\n      \n      - name: Set output directory\n        run: |\n          OUTDIR=$(basename ${{ github.ref }})\n          echo \"OUTDIR=$OUTDIR\" >> $GITHUB_ENV\n\n      - name: Deploy stable\n        uses: peaceiris/actions-gh-pages@v4\n        if: startswith(github.ref, 'refs/tags/')\n        with:\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n          publish_dir: ./book/book\n\n      - name: Deploy\n        uses: peaceiris/actions-gh-pages@v4\n        with:\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n          publish_dir: ./book/book\n          destination_dir: ./${{ env.OUTDIR }}\n"
  },
  {
    "path": ".github/workflows/languages.toml",
    "content": "# This languages.toml is used for testing in CI.\n\n[[language]]\nname = \"rust\"\nscope = \"source.rust\"\ninjection-regex = \"rust\"\nfile-types = [\"rs\"]\ncomment-token = \"//\"\nroots = [\"Cargo.toml\", \"Cargo.lock\"]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"rust\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-rust\", rev = \"0431a2c60828731f27491ee9fdefe25e250ce9c9\" }\n\n[[language]]\nname = \"nix\"\nscope = \"source.nix\"\ninjection-regex = \"nix\"\nfile-types = [\"nix\"]\nshebangs = []\nroots = []\ncomment-token = \"#\"\n\n# A grammar entry is not necessary for this language - it is only used for\n# testing TOML merging behavior.\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\non:\n  push:\n    tags:\n    - '[0-9]+.[0-9]+'\n    - '[0-9]+.[0-9]+.[0-9]+'\n    branches:\n    - 'patch/ci-release-*'\n  pull_request:\n    paths:\n    - '.github/workflows/release.yml'\n\nenv:\n  # Preview mode: Publishes the build output as a CI artifact instead of creating\n  # a release, allowing for manual inspection of the output. This mode is\n  # activated if the CI run was triggered by events other than pushed tags, or\n  # if the repository is a fork.\n  preview: ${{ !startsWith(github.ref, 'refs/tags/') || github.repository != 'helix-editor/helix' }}\n\njobs:\n  fetch-grammars:\n    name: Fetch Grammars\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout sources\n        uses: actions/checkout@v6\n\n      - name: Install stable toolchain\n        uses: dtolnay/rust-toolchain@stable\n\n      - uses: Swatinem/rust-cache@v2\n\n      - name: Fetch tree-sitter grammars\n        run: cargo run --package=helix-loader --bin=hx-loader\n\n      - name: Bundle grammars\n        run: tar cJf grammars.tar.xz -C runtime/grammars/sources .\n\n      - uses: actions/upload-artifact@v7\n        with:\n          name: grammars\n          path: grammars.tar.xz\n\n  dist:\n    name: Dist\n    needs: [fetch-grammars]\n    env:\n      # For some builds, we use cross to test on 32-bit and big-endian\n      # systems.\n      CARGO: cargo\n      # When CARGO is set to CROSS, this is set to `--target matrix.target`.\n      TARGET_FLAGS:\n      # When CARGO is set to CROSS, TARGET_DIR includes matrix.target.\n      TARGET_DIR: ./target\n      # Emit backtraces on panics.\n      RUST_BACKTRACE: 1\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false # don't fail other jobs if one fails\n      matrix:\n        build: [x86_64-linux, aarch64-linux, x86_64-macos, x86_64-windows, aarch64-macos] #, x86_64-win-gnu, win32-msvc\n        include:\n        - build: x86_64-linux\n          # WARN: When changing this to a newer version, make sure that the GLIBC isnt too new, as this can cause issues\n          # with portablity on older systems that dont follow ubuntus more rapid release cadence.\n          os: ubuntu-22.04\n          rust: stable\n          target: x86_64-unknown-linux-gnu\n          cross: false\n        - build: aarch64-linux\n          # Version should be kept in lockstep with the x86_64 version\n          os: ubuntu-22.04-arm\n          rust: stable\n          target: aarch64-unknown-linux-gnu\n          cross: false\n        - build: x86_64-macos\n          os: macos-latest\n          rust: stable\n          target: x86_64-apple-darwin\n          cross: false\n        - build: x86_64-windows\n          os: windows-latest\n          rust: stable\n          target: x86_64-pc-windows-msvc\n          cross: false\n        - build: aarch64-macos\n          os: macos-latest\n          rust: stable\n          target: aarch64-apple-darwin\n          cross: false\n        # - build: riscv64-linux\n        #   os: ubuntu-22.04\n        #   rust: stable\n        #   target: riscv64gc-unknown-linux-gnu\n        #   cross: true\n        # - build: x86_64-win-gnu\n        #   os: windows-2019\n        #   rust: stable-x86_64-gnu\n        #   target: x86_64-pc-windows-gnu\n        # - build: win32-msvc\n        #   os: windows-2019\n        #   rust: stable\n        #   target: i686-pc-windows-msvc\n\n    steps:\n      - name: Checkout sources\n        uses: actions/checkout@v6\n\n      - name: Download grammars\n        uses: actions/download-artifact@v8\n\n      - name: Move grammars under runtime\n        if: \"!startsWith(matrix.os, 'windows')\"\n        run: |\n          mkdir -p runtime/grammars/sources\n          tar xJf grammars.tar.xz -C runtime/grammars/sources\n\n      # The rust-toolchain action ignores rust-toolchain.toml files.\n      # Removing this before building with cargo ensures that the rust-toolchain\n      # is considered the same between installation and usage.\n      - name: Remove the rust-toolchain.toml file\n        run: rm rust-toolchain.toml\n\n      - name: Install ${{ matrix.rust }} toolchain\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ matrix.rust }}\n          target: ${{ matrix.target }}\n\n      # Install a pre-release version of Cross\n      # TODO: We need to pre-install Cross because we need cross-rs/cross#591 to\n      #       get a newer C++ compiler toolchain. Remove this step when Cross\n      #       0.3.0, which includes cross-rs/cross#591, is released.\n      - name: Install Cross\n        if: \"matrix.cross\"\n        run: |\n          cargo install cross --git https://github.com/cross-rs/cross.git --rev 47df5c76e7cba682823a0b6aa6d95c17b31ba63a\n          echo \"CARGO=cross\" >> $GITHUB_ENV\n        # echo \"TARGET_FLAGS=--target ${{ matrix.target }}\" >> $GITHUB_ENV\n        # echo \"TARGET_DIR=./target/${{ matrix.target }}\" >> $GITHUB_ENV\n\n      - name: Show command used for Cargo\n        run: |\n          echo \"cargo command is: ${{ env.CARGO }}\"\n          echo \"target flag is: ${{ env.TARGET_FLAGS }}\"\n\n      - name: Run cargo test\n        if: \"!matrix.skip_tests\"\n        run: ${{ env.CARGO }} test --release --locked --target ${{ matrix.target }} --workspace\n\n      - name: Build release binary\n        run: ${{ env.CARGO }} build --profile opt --locked --target ${{ matrix.target }}\n\n      - name: Build AppImage\n        shell: bash\n        if: matrix.build == 'x86_64-linux'\n        run: |\n          # Required as of 22.x https://github.com/AppImage/AppImageKit/wiki/FUSE\n          sudo add-apt-repository universe\n          sudo apt install libfuse2\n\n          mkdir dist\n\n          name=dev\n          if [[ $GITHUB_REF == refs/tags/* ]]; then\n            name=${GITHUB_REF:10}\n          fi\n\n          build=\"${{ matrix.build }}\"\n\n          export VERSION=\"$name\"\n          export ARCH=${build%-linux}\n          export APP=helix\n          export OUTPUT=\"helix-$VERSION-$ARCH.AppImage\"\n          export UPDATE_INFORMATION=\"gh-releases-zsync|$GITHUB_REPOSITORY_OWNER|helix|latest|$APP-*-$ARCH.AppImage.zsync\"\n\n          mkdir -p \"$APP.AppDir\"/usr/{bin,lib/helix}\n\n          cp \"target/${{ matrix.target }}/opt/hx\" \"$APP.AppDir/usr/bin/hx\"\n          rm -rf runtime/grammars/sources\n          cp -r runtime \"$APP.AppDir/usr/lib/helix/runtime\"\n\n          cat << 'EOF' > \"$APP.AppDir/AppRun\"\n          #!/bin/sh\n\n          APPDIR=\"$(dirname \"$(readlink -f \"${0}\")\")\"\n          HELIX_RUNTIME=\"$APPDIR/usr/lib/helix/runtime\" exec \"$APPDIR/usr/bin/hx\" \"$@\"\n          EOF\n          chmod 755 \"$APP.AppDir/AppRun\"\n\n          curl -Lo linuxdeploy-x86_64.AppImage \\\n              https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage\n          chmod +x linuxdeploy-x86_64.AppImage\n\n          ./linuxdeploy-x86_64.AppImage \\\n              --appdir \"$APP.AppDir\" -d contrib/Helix.desktop \\\n              -i contrib/helix.png --output appimage\n\n          mv \"$APP-$VERSION-$ARCH.AppImage\" \\\n              \"$APP-$VERSION-$ARCH.AppImage.zsync\" dist\n\n      - name: Build Deb\n        shell: bash\n        if: matrix.build == 'x86_64-linux'\n        run: |\n          cargo install cargo-deb\n          mkdir -p target/release\n          cp target/${{ matrix.target }}/opt/hx target/release/\n          cargo deb --no-build\n          mkdir -p dist\n          mv target/debian/*.deb dist/\n\n      - name: Build archive\n        shell: bash\n        run: |\n          mkdir -p dist\n          if [ \"${{ matrix.os }}\" = \"windows-latest\" ]; then\n            cp \"target/${{ matrix.target }}/opt/hx.exe\" \"dist/\"\n          else\n            cp \"target/${{ matrix.target }}/opt/hx\" \"dist/\"\n          fi\n          if [ -d runtime/grammars/sources ]; then\n            rm -rf runtime/grammars/sources\n          fi\n          cp -r runtime dist\n\n      - uses: actions/upload-artifact@v7\n        with:\n          name: bins-${{ matrix.build }}\n          path: dist\n\n  publish:\n    name: Publish\n    needs: [dist]\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout sources\n        uses: actions/checkout@v6\n\n      - uses: actions/download-artifact@v8\n\n      - name: Build archive\n        shell: bash\n        run: |\n          set -ex\n\n          source=\"$(pwd)\"\n          tag=${GITHUB_REF_NAME//\\//}\n          mkdir -p runtime/grammars/sources\n          tar xJf grammars/grammars.tar.xz -C runtime/grammars/sources\n          rm -rf grammars\n\n          cd \"$(mktemp -d)\"\n          mv $source/bins-* .\n          mkdir dist\n\n          for dir in bins-* ; do\n              platform=${dir#\"bins-\"}\n              if [[ $platform =~ \"windows\" ]]; then\n                  exe=\".exe\"\n              fi\n              pkgname=helix-$tag-$platform\n              mkdir -p $pkgname\n              cp $source/LICENSE $source/README.md $pkgname\n              mkdir $pkgname/contrib\n              cp -r $source/contrib/completion $pkgname/contrib\n              mv bins-$platform/runtime $pkgname/\n              mv bins-$platform/hx$exe $pkgname\n              chmod +x $pkgname/hx$exe\n\n              if [[ \"$platform\" = \"x86_64-linux\" ]]; then\n                  mv bins-$platform/helix-*.AppImage* dist/\n                  mv bins-$platform/*.deb dist/\n              fi\n\n              if [ \"$exe\" = \"\" ]; then\n                  tar cJf dist/$pkgname.tar.xz $pkgname\n              else\n                  7z a -r dist/$pkgname.zip $pkgname\n              fi\n          done\n\n          tar cJf dist/helix-$tag-source.tar.xz -C $source .\n          mv dist $source/\n\n      - name: Upload binaries to release\n        uses: svenstaro/upload-release-action@v2\n        if: env.preview == 'false'\n        with:\n          repo_token: ${{ secrets.GITHUB_TOKEN }}\n          file: dist/*\n          file_glob: true\n          tag: ${{ github.ref_name }}\n          overwrite: true\n\n      - name: Upload binaries as artifact\n        uses: actions/upload-artifact@v7\n        if: env.preview == 'true'\n        with:\n          name: release\n          path: dist/*\n"
  },
  {
    "path": ".gitignore",
    "content": "target\n.direnv\nhelix-term/rustfmt.toml\nresult\nruntime/grammars\n.DS_Store\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "<!--\n# YY.0M (YYYY-0M-0D)\n\nBreaking changes:\n\nFeatures:\n\nCommands:\n\nUsability improvements:\n\nFixes:\n\nThemes:\n\nNew languages:\n\nUpdated languages and queries:\n\nPackaging:\n-->\n\n# 25.07.1 (2025-07-18)\n\nThis is a patch release which lowers the GLIBC requirements of the release artifacts published to GitHub ([#13983](https://github.com/helix-editor/helix/pull/13983))\n\n# 25.07 (2025-07-15)\n\nAs always, a big thank you to all of the contributors! This release saw changes from 195 contributors.\n\nBreaking changes:\n\n* The parsing of the command line has been rewritten and now supports flags and expansions ([#12527](https://github.com/helix-editor/helix/pull/12527), [#13018](https://github.com/helix-editor/helix/pull/13018), [9574e55](https://github.com/helix-editor/helix/commit/9574e55), [2d4c2a1](https://github.com/helix-editor/helix/commit/2d4c2a1), [#13192](https://github.com/helix-editor/helix/pull/13192), [67f1fe2](https://github.com/helix-editor/helix/commit/67f1fe2), [#13466](https://github.com/helix-editor/helix/pull/13466), [#13467](https://github.com/helix-editor/helix/pull/13467), [#13840](https://github.com/helix-editor/helix/pull/13840))\n    * Quoting and spaces are now handled differently. This can break existing keymaps which use typable commands, in particular `:sh`, `:set-option` or `:toggle-option`.\n    * The `:rsort` command has been removed. Use the reverse flag instead: `:sort --reverse`\n\nFeatures:\n\n* Add a picker which explores directories ([#11285](https://github.com/helix-editor/helix/pull/11285), [d4aed40](https://github.com/helix-editor/helix/commit/d4aed40))\n* Allow cycling through multiple LSP Hover responses with `A-n`/`A-p` ([#10122](https://github.com/helix-editor/helix/pull/10122), [2367b20](https://github.com/helix-editor/helix/commit/2367b20))\n* Add support for incomplete LSP completions ([5c1f3f8](https://github.com/helix-editor/helix/commit/5c1f3f8))\n* Add support for EditorConfig ([#13056](https://github.com/helix-editor/helix/pull/13056), [#13443](https://github.com/helix-editor/helix/pull/13443))\n* Add support for LSP document colors ([#12308](https://github.com/helix-editor/helix/pull/12308), [d43de14](https://github.com/helix-editor/helix/commit/d43de14), [47cdd23](https://github.com/helix-editor/helix/commit/47cdd23), [ba54b6a](https://github.com/helix-editor/helix/commit/ba54b6a), [#13188](https://github.com/helix-editor/helix/pull/13188))\n* Support expansions in external formatter arguments ([#13429](https://github.com/helix-editor/helix/pull/13429))\n* Switch out the highlighter for the `tree-house` crate ([#12972](https://github.com/helix-editor/helix/pull/12972), [09bc67a](https://github.com/helix-editor/helix/commit/09bc67a), [a7c3a43](https://github.com/helix-editor/helix/commit/a7c3a43), [3ceae88](https://github.com/helix-editor/helix/commit/3ceae88), [05ae617](https://github.com/helix-editor/helix/commit/05ae617), [5a1dcc2](https://github.com/helix-editor/helix/commit/5a1dcc2), [ebf96bd](https://github.com/helix-editor/helix/commit/ebf96bd), [#13644](https://github.com/helix-editor/helix/pull/13644), [b1f4717](https://github.com/helix-editor/helix/commit/b1f4717), [7410fe3](https://github.com/helix-editor/helix/commit/7410fe3), [633c5fb](https://github.com/helix-editor/helix/commit/633c5fb), [362e97e](https://github.com/helix-editor/helix/commit/362e97e), [#13828](https://github.com/helix-editor/helix/pull/13828), [6fd1efd](https://github.com/helix-editor/helix/commit/6fd1efd))\n    * This fixes a number of highlighter bugs.\n    * Locals like parameter highlights are now highlighted even when the definition is not in view.\n    * Markdown is now injected into rust doc comments (`///` and `//!`).\n* Add support for the DAP `startDebugging` reverse request ([#13403](https://github.com/helix-editor/helix/pull/13403))\n\nCommands:\n\n* Add `copy_between_registers` for interactive copying between two registers ([066e938](https://github.com/helix-editor/helix/commit/066e938))\n* Add `extend_to_file_{start,end}`, select-mode variants of `goto_file_{start,end}` ([#11767](https://github.com/helix-editor/helix/pull/11767))\n* Add `:!` alias for `:sh` and `:|` for `:pipe` ([#13263](https://github.com/helix-editor/helix/pull/13263))\n* Add `goto_column` and `extend_to_column` ([#13440](https://github.com/helix-editor/helix/pull/13440))\n* Add an `--insensitive`/`-i` flag to the `:sort` command ([#13560](https://github.com/helix-editor/helix/pull/13560))\n* Add `rotate_selections_first` and `rotate_selections_last` ([#13615](https://github.com/helix-editor/helix/pull/13615))\n* Add a `--no-format` flag for all `:write` commands ([2f56091](https://github.com/helix-editor/helix/commit/2f56091))\n* Add a `--skip-visible` flag for `:buffer-close-others` and `:buffer-close-others!` ([#5393](https://github.com/helix-editor/helix/pull/5393))\n\nUsability improvements:\n\n* Replace current file using `A-ret` in pickers rather than loading it in the background ([#12605](https://github.com/helix-editor/helix/pull/12605))\n* Set multiple selections when passing a file with multiple locations to `hx` ([#12192](https://github.com/helix-editor/helix/pull/12192))\n* Add path completion for multiple cursors ([#12550](https://github.com/helix-editor/helix/pull/12550), [c9dc940](https://github.com/helix-editor/helix/commit/c9dc940))\n* Truncate long prompt lines with \"…\" ([#12036](https://github.com/helix-editor/helix/pull/12036), [9d6ea77](https://github.com/helix-editor/helix/commit/9d6ea77), [0b9701e](https://github.com/helix-editor/helix/commit/0b9701e), [d3fb8fc](https://github.com/helix-editor/helix/commit/d3fb8fc))\n* Allow specifying languages in `:lsp-stop` and `:lsp-restart` ([#12578](https://github.com/helix-editor/helix/pull/12578), [3d7e273](https://github.com/helix-editor/helix/commit/3d7e273))\n* Add `m` (nearest matching pair) to infobox popups for `md` and `mr` ([#12650](https://github.com/helix-editor/helix/pull/12650))\n* Add a hint message in the statusline when using `:sort` on a single selection ([#12585](https://github.com/helix-editor/helix/pull/12585))\n* Avoid wrapping around in `goto_{next,prev}_diag` ([#12704](https://github.com/helix-editor/helix/pull/12704))\n* Support responses from multiple language servers for LSP goto-definition (and declaration, type definition and implementation) and goto-references ([f7394d5](https://github.com/helix-editor/helix/commit/f7394d5), [1a821ac](https://github.com/helix-editor/helix/commit/1a821ac), [d285a8a](https://github.com/helix-editor/helix/commit/d285a8a))\n* Show formatter errors in `:format` ([47f84d0](https://github.com/helix-editor/helix/commit/47f84d0))\n* Show typable command docs in keybinding infobox popups when the command takes no arguments ([e9c16b7](https://github.com/helix-editor/helix/commit/e9c16b7))\n* Add per-command titles to register selection infobox popups for `select_register`, `insert_register` and `copy_between_registers` ([e0da129](https://github.com/helix-editor/helix/commit/e0da129))\n* Add container name column to the LSP symbol picker ([#12930](https://github.com/helix-editor/helix/pull/12930))\n* Add a theme key for highlighting directories in completions and picker items ([#12855](https://github.com/helix-editor/helix/pull/12855), [7bebe0a](https://github.com/helix-editor/helix/commit/7bebe0a))\n* Add `editor.trim-final-newlines` and `editor.trim-trailing-whitespace` config options ([aa20eb8](https://github.com/helix-editor/helix/commit/aa20eb8))\n* Warn when the configured theme is unusable because true-color is not available ([#13058](https://github.com/helix-editor/helix/pull/13058))\n* Allow configuring `[workspace-]diagnostic` statusline element severities ([#13288](https://github.com/helix-editor/helix/pull/13288), [b0528bb](https://github.com/helix-editor/helix/commit/b0528bb))\n* Improve completion for shell commands ([#12883](https://github.com/helix-editor/helix/pull/12883), [532f241](https://github.com/helix-editor/helix/commit/532f241))\n* Show the primary selection index in the `selections` statusline element when there are multiple selections ([#12326](https://github.com/helix-editor/helix/pull/12326))\n* Use configured language server names when possible in `--health` output ([#13573](https://github.com/helix-editor/helix/pull/13573))\n* Add a statusline element for indentation style ([#13632](https://github.com/helix-editor/helix/pull/13632))\n* Set the working directory of language server commands to the workspace root ([#13691](https://github.com/helix-editor/helix/pull/13691))\n* Avoid jumpiness in the picker preview for languages with non-default tab widths ([#13761](https://github.com/helix-editor/helix/pull/13761))\n* Add a config option for limiting LSP inlay hint length ([#13742](https://github.com/helix-editor/helix/pull/13742))\n* Improve heuristics used in the diff gutter ([#13722](https://github.com/helix-editor/helix/pull/13722))\n* Allow moving a file with `:move` when its old path does not exist ([#13748](https://github.com/helix-editor/helix/pull/13748))\n* Allow moving a file into a directory with `:move` ([#13922](https://github.com/helix-editor/helix/pull/13922))\n* Show human-readable file sizes in the statusline message for file writes ([#13627](https://github.com/helix-editor/helix/pull/13627))\n* Add diagnostic source to the diagnosics pickers ([#13758](https://github.com/helix-editor/helix/pull/13758))\n* Show all active scopes under the cursor in `:tree-sitter-highlight-name` ([4a85171](https://github.com/helix-editor/helix/commit/4a85171))\n* Auto-close the LSP code-actions popup ([#13832](https://github.com/helix-editor/helix/pull/13832))\n* Add a configuration option for controlling atomic writes to disk ([#13656](https://github.com/helix-editor/helix/pull/13656))\n\nFixes:\n\n* Fix panic from using `search_selection_detect_word_boundaries` (`*`) at the end of the file ([#12611](https://github.com/helix-editor/helix/pull/12611))\n* Discard placeholder text for zero tabstop `${0:placeholder}` ([#12647](https://github.com/helix-editor/helix/pull/12647))\n* Fix panic in `goto_file` (`gf`) on file names with non-ASCII characters ([#12673](https://github.com/helix-editor/helix/pull/12673))\n* Only accept unmodified characters in `goto_word` (`gw`) ([f5f9f49](https://github.com/helix-editor/helix/commit/f5f9f49), [0364521](https://github.com/helix-editor/helix/commit/0364521))\n* Skip recording keys pressed by macros while recording a macro ([#12733](https://github.com/helix-editor/helix/pull/12733))\n* Deny unknown fields in `editor.smart-tab` config ([28047fe](https://github.com/helix-editor/helix/commit/28047fe))\n* Fix soft-wrap word boundary detection for Unicode combining accent characters ([#12483](https://github.com/helix-editor/helix/pull/12483))\n* Fix clearing of infobox popups in `select_register` and `insert_register` commands ([e882a75](https://github.com/helix-editor/helix/commit/e882a75))\n* Fix handling of `stderr` of DAP child processes ([d0d1693](https://github.com/helix-editor/helix/commit/d0d1693))\n* Cancel all pending requests when a DAP session terminates ([26db541](https://github.com/helix-editor/helix/commit/26db541))\n* Properly discard out-of-date diagnostics ([313a647](https://github.com/helix-editor/helix/commit/313a647))\n* Fix display of multiple language servers in `hx --health` ([#12841](https://github.com/helix-editor/helix/pull/12841))\n* Respect `editor.default-yank-register` in `:yank-joined` ([#12890](https://github.com/helix-editor/helix/pull/12890))\n* Escape percent character when pasting the history register into the picker ([#12886](https://github.com/helix-editor/helix/pull/12886))\n* Render rulers before the cursor ([2d3b75a](https://github.com/helix-editor/helix/commit/2d3b75a))\n* Avoid inserting final newlines in empty files ([67879a1](https://github.com/helix-editor/helix/commit/67879a1))\n* Gracefully handle partial failure in multi-language-server requests ([#13156](https://github.com/helix-editor/helix/pull/13156), [14cab4b](https://github.com/helix-editor/helix/commit/14cab4b))\n* Improve LSP progress message display in the statusline ([#13180](https://github.com/helix-editor/helix/pull/13180))\n* Fix behavior of `<esc>` removing added indentation in documents with CRLF line endings ([702a961](https://github.com/helix-editor/helix/commit/702a961))\n* Append changes to document history before pushing jumplist jumps ([#13619](https://github.com/helix-editor/helix/pull/13619))\n* Fix overflow in the display of large chunks of text in the signature-help component ([#13566](https://github.com/helix-editor/helix/pull/13566))\n* Fix panic from clearing whitespace when changing multiple selections on one line ([#13673](https://github.com/helix-editor/helix/pull/13673))\n* Include formatting options in LSP range formatting request ([#13734](https://github.com/helix-editor/helix/pull/13734))\n* Consistently set statusline errors when LSP features are not available ([#12577](https://github.com/helix-editor/helix/pull/12577))\n* Fix `goto_file` on Windows ([#13770](https://github.com/helix-editor/helix/pull/13770))\n* Fix crash in `goto_word` (`gw`) when `editor.jump-label-alphabet` is configured to be empty ([#13863](https://github.com/helix-editor/helix/pull/13863))\n* Fix `open_above` / `open_below` (`o` / `O`) when using a count on a document with CRLF line-endings ([#13905](https://github.com/helix-editor/helix/pull/13905))\n\nThemes:\n\n* Update `modus` themes ([#12670](https://github.com/helix-editor/helix/pull/12670))\n* Update `snazzy` ([#11089](https://github.com/helix-editor/helix/pull/11089))\n* Update `gruber-darker` ([#12797](https://github.com/helix-editor/helix/pull/12797))\n* Update `cyan_light` ([#12864](https://github.com/helix-editor/helix/pull/12864), [#12891](https://github.com/helix-editor/helix/pull/12891))\n* Update `onedarker` ([#12833](https://github.com/helix-editor/helix/pull/12833))\n* Update `github_light` ([#12907](https://github.com/helix-editor/helix/pull/12907))\n* Update `kanagawa` ([#12895](https://github.com/helix-editor/helix/pull/12895))\n* Add `beans` ([#12963](https://github.com/helix-editor/helix/pull/12963))\n* Update `base16_transparent` ([#13080](https://github.com/helix-editor/helix/pull/13080))\n* Update `sunset` ([#13086](https://github.com/helix-editor/helix/pull/13086))\n* Add `carbon` ([#13067](https://github.com/helix-editor/helix/pull/13067))\n* Update `soralized` ([#13121](https://github.com/helix-editor/helix/pull/13121))\n* Add `focus_nova` ([#13144](https://github.com/helix-editor/helix/pull/13144))\n* Update `onedark` ([#13166](https://github.com/helix-editor/helix/pull/13166))\n* Update `adwaita-light` ([#13174](https://github.com/helix-editor/helix/pull/13174))\n* Add `earl_grey` ([#13203](https://github.com/helix-editor/helix/pull/13203))\n* Update `spacebones` ([#13213](https://github.com/helix-editor/helix/pull/13213))\n* Add `peachpuff` ([#13225](https://github.com/helix-editor/helix/pull/13225))\n* Update catppuccin themes ([#13262](https://github.com/helix-editor/helix/pull/13262))\n* Update gruvbox themes ([#13315](https://github.com/helix-editor/helix/pull/13315))\n* Update serika themes ([#13341](https://github.com/helix-editor/helix/pull/13341))\n* Add `gruvbox-material` ([#13311](https://github.com/helix-editor/helix/pull/13311))\n* Add `ashen` ([#13366](https://github.com/helix-editor/helix/pull/13366))\n* Update Zed themes ([#13370](https://github.com/helix-editor/helix/pull/13370))\n* Update Tokyonight themes ([#13375](https://github.com/helix-editor/helix/pull/13375))\n* Update `onelight` ([#13413](https://github.com/helix-editor/helix/pull/13413))\n* Add `ataraxia` ([#13390](https://github.com/helix-editor/helix/pull/13390))\n* Add `vesper` ([#13394](https://github.com/helix-editor/helix/pull/13394))\n* Add `kinda_nvim` and `kinda_nvim_light` ([#13406](https://github.com/helix-editor/helix/pull/13406))\n* Update `sonokai` ([#13410](https://github.com/helix-editor/helix/pull/13410))\n* Add `nyxvamp` themes ([#12185](https://github.com/helix-editor/helix/pull/12185))\n* Update nord themes ([#13574](https://github.com/helix-editor/helix/pull/13574))\n* Add `lapis_aquamarine` ([#13726](https://github.com/helix-editor/helix/pull/13726))\n* Add `sidra` ([#13575](https://github.com/helix-editor/helix/pull/13575))\n* Add `dark-synthwave` ([#13857](https://github.com/helix-editor/helix/pull/13857))\n* Update `rose_pine` ([#13908](https://github.com/helix-editor/helix/pull/13908))\n* Add `doom-one` ([#13933](https://github.com/helix-editor/helix/pull/13933))\n* Update `nightfox` ([#13957](https://github.com/helix-editor/helix/pull/13957))\n\nNew languages:\n\n* Ghostty config ([#12703](https://github.com/helix-editor/helix/pull/12703))\n* Tera ([#12756](https://github.com/helix-editor/helix/pull/12756))\n* FGA ([#12763](https://github.com/helix-editor/helix/pull/12763))\n* CSV ([#11973](https://github.com/helix-editor/helix/pull/11973))\n* Yara ([#12753](https://github.com/helix-editor/helix/pull/12753))\n* Djot ([#12562](https://github.com/helix-editor/helix/pull/12562))\n* Ink ([#12773](https://github.com/helix-editor/helix/pull/12773))\n* Mail ([#12945](https://github.com/helix-editor/helix/pull/12945))\n* SourcePawn ([#13028](https://github.com/helix-editor/helix/pull/13028))\n* TLA+ ([#13081](https://github.com/helix-editor/helix/pull/13081))\n* Werk ([#13136](https://github.com/helix-editor/helix/pull/13136))\n* Debian control file ([#13245](https://github.com/helix-editor/helix/pull/13245))\n* WESL ([#13267](https://github.com/helix-editor/helix/pull/13267))\n* Fennel ([#13260](https://github.com/helix-editor/helix/pull/13260), [6081a5d](https://github.com/helix-editor/helix/commit/6081a5d))\n* Quarto ([#13339](https://github.com/helix-editor/helix/pull/13339))\n* Pug ([#13435](https://github.com/helix-editor/helix/pull/13435))\n* Slang ([#13449](https://github.com/helix-editor/helix/pull/13449))\n* Dunst config ([#13458](https://github.com/helix-editor/helix/pull/13458))\n* Luau ([#13702](https://github.com/helix-editor/helix/pull/13702))\n* Caddyfile ([#13859](https://github.com/helix-editor/helix/pull/13859))\n* Java properties ([#13874](https://github.com/helix-editor/helix/pull/13874))\n* Git notes ([#13885](https://github.com/helix-editor/helix/pull/13885))\n* systemd (split from INI) ([#13907](https://github.com/helix-editor/helix/pull/13907))\n* JSON-LD (split from JSON) ([#13925](https://github.com/helix-editor/helix/pull/13925))\n* Django HTML ([#13935](https://github.com/helix-editor/helix/pull/13935))\n\nUpdated languages and queries:\n\n* Add `ruby-lsp` for Ruby ([#12511](https://github.com/helix-editor/helix/pull/12511))\n* Add `wat_server` for Wat ([#12581](https://github.com/helix-editor/helix/pull/12581))\n* Recognize `bun.lock` as JSONC ([fcf981b](https://github.com/helix-editor/helix/commit/fcf981b))\n* Update tree-sitter-rust ([#12607](https://github.com/helix-editor/helix/pull/12607), [1afa63d](https://github.com/helix-editor/helix/commit/1afa63d))\n* Fix configuration of `cs-lsp` ([#12615](https://github.com/helix-editor/helix/pull/12615))\n* Add `beancount-language-server` for Beancount ([#12610](https://github.com/helix-editor/helix/pull/12610))\n* Update tree-sitter-fish ([#12456](https://github.com/helix-editor/helix/pull/12456))\n* Add `fish-lsp` for Fish ([#12456](https://github.com/helix-editor/helix/pull/12456))\n* Update tree-sitter-ini ([#12456](https://github.com/helix-editor/helix/pull/12456), [#13088](https://github.com/helix-editor/helix/pull/13088))\n* Recognize `hgrc` as INI ([#12456](https://github.com/helix-editor/helix/pull/12456))\n* Restrict tagged template injection languages for ECMA languages ([#12217](https://github.com/helix-editor/helix/pull/12217))\n* Update tree-sitter-zig ([#11980](https://github.com/helix-editor/helix/pull/11980), [#12708](https://github.com/helix-editor/helix/pull/12708))\n* Update tree-sitter-elixir ([8bf9adf](https://github.com/helix-editor/helix/commit/8bf9adf))\n* Add `asm-lsp` for Assembly dialects ([#12684](https://github.com/helix-editor/helix/pull/12684))\n* Update tree-sitter-just ([#12692](https://github.com/helix-editor/helix/pull/12692), #)\n* Update tree-sitter-cairo ([#12712](https://github.com/helix-editor/helix/pull/12712))\n* Configure a comment token for Svelte ([#12743](https://github.com/helix-editor/helix/pull/12743))\n* Recognize `.sublime-*` files ([#12750](https://github.com/helix-editor/helix/pull/12750))\n* Highlight `$` tagged templates as shell commands in ECMA languages ([#12751](https://github.com/helix-editor/helix/pull/12751))\n* Add `#'` comment token for R ([#12748](https://github.com/helix-editor/helix/pull/12748))\n* Fix module/namespace highlight in Unison ([93fa990](https://github.com/helix-editor/helix/commit/93fa990))\n* Add missing `#not-eq?` and `#not-match?` highlights in TSQ ([3824010](https://github.com/helix-editor/helix/commit/3824010))\n* Reverse the precedence order of highlight queries ([#9458](https://github.com/helix-editor/helix/pull/9458), [#12777](https://github.com/helix-editor/helix/pull/12777), [#12795](https://github.com/helix-editor/helix/pull/12795), [144a4f4](https://github.com/helix-editor/helix/commit/144a4f4), [e1c26eb](https://github.com/helix-editor/helix/commit/e1c26eb), [e1060a2](https://github.com/helix-editor/helix/commit/e1060a2), [7f41670](https://github.com/helix-editor/helix/commit/7f41670), [#13293](https://github.com/helix-editor/helix/pull/13293))\n* Update Rust highlights ([b8bfc44](https://github.com/helix-editor/helix/commit/b8bfc44), [#12871](https://github.com/helix-editor/helix/pull/12871), [#13664](https://github.com/helix-editor/helix/pull/13664))\n* Add block comment configuration for PHP ([0ab403d](https://github.com/helix-editor/helix/commit/0ab403d))\n* Update Gren highlights ([#12769](https://github.com/helix-editor/helix/pull/12769))\n* Remove `ERROR` node highlighting from all highlight queries ([16ff063](https://github.com/helix-editor/helix/commit/16ff063))\n* Update tree-sitter-erlang and highlights ([18b9eb9](https://github.com/helix-editor/helix/commit/18b9eb9), [9f3b193](https://github.com/helix-editor/helix/commit/9f3b193), [12139a4](https://github.com/helix-editor/helix/commit/12139a4))\n* Update Nix injections ([#12776](https://github.com/helix-editor/helix/pull/12776), [#12774](https://github.com/helix-editor/helix/pull/12774), [#13851](https://github.com/helix-editor/helix/pull/13851))\n* Add indent queries for Nix ([#12829](https://github.com/helix-editor/helix/pull/12829))\n* Update Markdown highlights ([#12696](https://github.com/helix-editor/helix/pull/12696))\n* Recognize `xsl` as XML ([#12834](https://github.com/helix-editor/helix/pull/12834))\n* Remove deprecated `typst-lsp` config ([5a66270](https://github.com/helix-editor/helix/commit/5a66270))\n* Replace `pkgbuild-language-server` with `termux-language-server` ([c3c9a0d](https://github.com/helix-editor/helix/commit/c3c9a0d))\n* Update SQL highlights ([#12837](https://github.com/helix-editor/helix/pull/12837))\n* Recognize `mpd` and `smil` as XML ([#12916](https://github.com/helix-editor/helix/pull/12916))\n* Add indents and textojbects for Kotlin ([#12925](https://github.com/helix-editor/helix/pull/12925))\n* Fix module highlights in Koto ([7e87a36](https://github.com/helix-editor/helix/commit/7e87a36))\n* Update language servers for Protobuf ([#12936](https://github.com/helix-editor/helix/pull/12936))\n* Add `astro-ls` for Astro ([#12939](https://github.com/helix-editor/helix/pull/12939))\n* Fix recognition of \"scons*\" files as Python ([#12943](https://github.com/helix-editor/helix/pull/12943))\n* Update C# queries ([#12948](https://github.com/helix-editor/helix/pull/12948))\n* Add comment textojbect to TOML ([#12952](https://github.com/helix-editor/helix/pull/12952))\n* Add `starpls` as Starlark language server ([#12958](https://github.com/helix-editor/helix/pull/12958))\n* Add `pkl-lsp` for PKL ([#12962](https://github.com/helix-editor/helix/pull/12962))\n* Add `kdlfmt` formatter for KDL ([#12967](https://github.com/helix-editor/helix/pull/12967))\n* Update CSS highlights ([#12497](https://github.com/helix-editor/helix/pull/12497), [fed3edc](https://github.com/helix-editor/helix/commit/fed3edc))\n* Add `harper-ls` ([#13029](https://github.com/helix-editor/helix/pull/13029))\n* Change `wgsl_analyzer` to `wgsl-analyzer` ([#13063](https://github.com/helix-editor/helix/pull/13063))\n* Update tree-sitter-vhdl ([#13091](https://github.com/helix-editor/helix/pull/13091))\n* Update tree-sitter-openscad ([#13033](https://github.com/helix-editor/helix/pull/13033))\n* Update Rust injections ([694b615](https://github.com/helix-editor/helix/commit/694b615), [1bd7a39](https://github.com/helix-editor/helix/commit/1bd7a39))\n* Update Ruby highlights ([#13055](https://github.com/helix-editor/helix/pull/13055))\n* Recognize `gitconfig` as an extension ([#13115](https://github.com/helix-editor/helix/pull/13115))\n* Add `///` comment token for Amber ([#13122](https://github.com/helix-editor/helix/pull/13122))\n* Add indent queries for Starlark ([#13126](https://github.com/helix-editor/helix/pull/13126))\n* Recognize more systemd file types as INI ([#13139](https://github.com/helix-editor/helix/pull/13139))\n* Update scheme queries ([#13143](https://github.com/helix-editor/helix/pull/13143))\n* Recognize `tmTheme` as XML ([#13202](https://github.com/helix-editor/helix/pull/13202))\n* Update `golangci-lint` command for v2 ([#13204](https://github.com/helix-editor/helix/pull/13204))\n* Add `just-lsp` for Just ([#13276](https://github.com/helix-editor/helix/pull/13276))\n* Add a tree-sitter-prolog grammar ([#11611](https://github.com/helix-editor/helix/pull/11611))\n* Fix typos in Ada queries ([#13251](https://github.com/helix-editor/helix/pull/13251))\n* Update mint language server args ([#13248](https://github.com/helix-editor/helix/pull/13248))\n* Update typescript highlights ([#13250](https://github.com/helix-editor/helix/pull/13250))\n* Update tree-sitter-jjdescription ([#13329](https://github.com/helix-editor/helix/pull/13329))\n* Add injection queries for Quint ([#13322](https://github.com/helix-editor/helix/pull/13322))\n* Update tree-sitter-scss and highlights ([#13414](https://github.com/helix-editor/helix/pull/13414))\n* Update tree-sitter-go-mod ([#13395](https://github.com/helix-editor/helix/pull/13395))\n* Update tree-sitter-svelte ([#13423](https://github.com/helix-editor/helix/pull/13423))\n* Update Lua highlights ([#13401](https://github.com/helix-editor/helix/pull/13401))\n* Update Go highlights ([#13425](https://github.com/helix-editor/helix/pull/13425), [25b299a](https://github.com/helix-editor/helix/commit/25b299a), [#13825](https://github.com/helix-editor/helix/pull/13825))\n* Recognize `.git-blame-ignore-revs` as gitignore ([#13460](https://github.com/helix-editor/helix/pull/13460))\n* Update Verilog highlights ([#13473](https://github.com/helix-editor/helix/pull/13473), [#13493](https://github.com/helix-editor/helix/pull/13493))\n* Update tree-sitter-v ([#13469](https://github.com/helix-editor/helix/pull/13469))\n* Update WGSL highlights ([#13479](https://github.com/helix-editor/helix/pull/13479))\n* Update Bash highlights ([#13477](https://github.com/helix-editor/helix/pull/13477))\n* Update tree-sitter-cpp ([#13504](https://github.com/helix-editor/helix/pull/13504))\n* Update rust-analyzer config to use server-side file watching ([#13432](https://github.com/helix-editor/helix/pull/13432))\n* Update Vue injections ([#13511](https://github.com/helix-editor/helix/pull/13511))\n* Recognize `sld` as Scheme ([#13528](https://github.com/helix-editor/helix/pull/13528))\n* Recognize more files as git-attributes ([#13540](https://github.com/helix-editor/helix/pull/13540))\n* Update tree-sitter-haskell and queries ([#13475](https://github.com/helix-editor/helix/pull/13475))\n* Align INI highlights with TOML ([#13589](https://github.com/helix-editor/helix/pull/13589))\n* Add tree-sitter-rust-format-args for `format_args!` injections in Rust ([#13533](https://github.com/helix-editor/helix/pull/13533), [#13657](https://github.com/helix-editor/helix/pull/13657), [4dd4ba7](https://github.com/helix-editor/helix/commit/4dd4ba7), [86f10ae](https://github.com/helix-editor/helix/commit/86f10ae))\n* Update Ungrammar highlights ([8d58f6c](https://github.com/helix-editor/helix/commit/8d58f6c))\n* Add `ty` language server for Python ([#13643](https://github.com/helix-editor/helix/pull/13643))\n* Add `clarinet` language server for Clarity ([#13647](https://github.com/helix-editor/helix/pull/13647))\n* Update prisma config to avoid a crash in the language server ([f6878f6](https://github.com/helix-editor/helix/commit/f6878f6))\n* Add `pyrefly` for Python ([#13713](https://github.com/helix-editor/helix/pull/13713))\n* Update Python highlights ([#13715](https://github.com/helix-editor/helix/pull/13715))\n* Update Mojo language server and formatter to `pixi` ([#13648](https://github.com/helix-editor/helix/pull/13648))\n* Add `tombi` for TOML ([#13723](https://github.com/helix-editor/helix/pull/13723))\n* Add `neocmakelsp` for CMake ([#13740](https://github.com/helix-editor/helix/pull/13740))\n* Update C and C++ highlights ([#13747](https://github.com/helix-editor/helix/pull/13747), [#13772](https://github.com/helix-editor/helix/pull/13772))\n* Highlight escape sequences in ECMA languages ([#13762](https://github.com/helix-editor/helix/pull/13762))\n* Add an external formatter config for Crystal ([#13759](https://github.com/helix-editor/helix/pull/13759))\n* Add `amber-lsp` for Amber ([#13763](https://github.com/helix-editor/helix/pull/13763))\n* Update HTML highlights ([#13753](https://github.com/helix-editor/helix/pull/13753))\n* Update tree-sitter-purescript and highlights ([#13782](https://github.com/helix-editor/helix/pull/13782))\n* Update tree-sitter-gleam and highlights ([#13793](https://github.com/helix-editor/helix/pull/13793), [#13807](https://github.com/helix-editor/helix/pull/13807), [#13813](https://github.com/helix-editor/helix/pull/13813))\n* Recognize Buck files as Starlark ([#13810](https://github.com/helix-editor/helix/pull/13810))\n* Use tree-sitter-crystal instead of tree-sitter-ruby for Crystal and add custom queries ([#13805](https://github.com/helix-editor/helix/pull/13805))\n* Update tree-sitter-twig ([#13689](https://github.com/helix-editor/helix/pull/13689))\n* Recognize `jsconfig.json` as JSONC, use as JavaScript and JSX roots ([#13822](https://github.com/helix-editor/helix/pull/13822))\n* Recognize `.gem/credentials` as YAML ([#13843](https://github.com/helix-editor/helix/pull/13843))\n* Update Dockerfile injections ([#13845](https://github.com/helix-editor/helix/pull/13845), 13852)\n* Change tree-sitter parser for Git commit message files ([44293df](https://github.com/helix-editor/helix/commit/44293df))\n* Recognize `mimeapps.list` as INI ([#13850](https://github.com/helix-editor/helix/pull/13850))\n* Update tree-sitter-odin, highlights and indents ([#13877](https://github.com/helix-editor/helix/pull/13877), [#13917](https://github.com/helix-editor/helix/pull/13917))\n* Add locals queries for C, improve parameter highlighting ([#13876](https://github.com/helix-editor/helix/pull/13876))\n* Add textobjects for QML ([#13855](https://github.com/helix-editor/helix/pull/13855))\n* Add comment tokens for DTD ([#13904](https://github.com/helix-editor/helix/pull/13904))\n* Add `dts-lsp` for DeviceTree ([#13907](https://github.com/helix-editor/helix/pull/13907))\n* Update gomod highlights ([#13913](https://github.com/helix-editor/helix/pull/13913))\n* Recognize `compose.yaml` and `compose.yml` as Docker Compose ([#13930](https://github.com/helix-editor/helix/pull/13930))\n\nPackaging:\n\n* Fix handling of spaces in Bash completion ([#12828](https://github.com/helix-editor/helix/pull/12828))\n* Refactor Nix flake ([#12831](https://github.com/helix-editor/helix/pull/12831), [#13024](https://github.com/helix-editor/helix/pull/13024), [cb1ecc9](https://github.com/helix-editor/helix/commit/cb1ecc9), [#13305](https://github.com/helix-editor/helix/pull/13305))\n* Add `ConsoleOnly` to `Helix.desktop` categories ([#13236](https://github.com/helix-editor/helix/pull/13236))\n* Drop Nix flake dependency on flake-utils ([60a03a3](https://github.com/helix-editor/helix/commit/60a03a3))\n* Increase the MSRV to 1.82 ([#13275](https://github.com/helix-editor/helix/pull/13275))\n\n# 25.01.1 (2025-01-19)\n\n25.01.1 is a patch release focusing on fixing bugs and panics from changes in 25.01.\n\nUsability improvements:\n\n* Run external formatters from the document's directory ([#12315](https://github.com/helix-editor/helix/pull/12315))\n\nFixes:\n\n* Fix blank buffer picker preview on doc with no views ([917174e](https://github.com/helix-editor/helix/commit/917174e))\n* Fix `join_selections` behavior on tabs ([#12452](https://github.com/helix-editor/helix/pull/12452))\n* Fix recognition for color LSP completion hex codes for some language servers ([#12501](https://github.com/helix-editor/helix/pull/12501))\n* Fix offsets to selections updated by `open_below`/`open_above` (`o`/`O`) in multi-cursor scenarios ([#12465](https://github.com/helix-editor/helix/pull/12465))\n* Fix offsets to selections updated by `insert_newline` when trimming whitespace in multi-cursor scenarios ([4bd17e5](https://github.com/helix-editor/helix/commit/4bd17e5))\n* Fix panic in path completion from resolving variables like `${HOME:-$HOME}` ([#12556](https://github.com/helix-editor/helix/pull/12556))\n* Prevent line comment continuation when using `change_selection` (`c`) on a line above a comment ([#12575](https://github.com/helix-editor/helix/pull/12575))\n\nThemes:\n\n* Update `onelight` ([#12399](https://github.com/helix-editor/helix/pull/12399))\n* Add cursorline color to iceberg themes ([#12404](https://github.com/helix-editor/helix/pull/12404))\n* Update `special`, `ui.text.directory` and `ui.virtual.wrap` in `dark_plus` ([#12530](https://github.com/helix-editor/helix/pull/12530))\n\nNew languages:\n\n* CodeQL ([#12470](https://github.com/helix-editor/helix/pull/12470))\n* Gren ([#12525](https://github.com/helix-editor/helix/pull/12525))\n\nUpdated languages and queries:\n\n* Fix Teal LSP name ([#12395](https://github.com/helix-editor/helix/pull/12395))\n* Highlight `:` in Rust as a delimiter ([#12408](https://github.com/helix-editor/helix/pull/12408))\n* Update Swift highlights ([#12409](https://github.com/helix-editor/helix/pull/12409))\n* Highlight JSX attributes as `@attribute` ([#12416](https://github.com/helix-editor/helix/pull/12416))\n* Improve markdown heading highlights ([#12417](https://github.com/helix-editor/helix/pull/12417))\n* Add comment tokens configuration for JSONC ([b26903c](https://github.com/helix-editor/helix/commit/b26903c))\n* Highlight the never type `!` as a type in Rust ([#12485](https://github.com/helix-editor/helix/pull/12485))\n* Expand builtin function highlights for ECMA languages, Rust and Haskell ([#12488](https://github.com/helix-editor/helix/pull/12488))\n* Recognize `.clang-tidy` as YAML ([#12498](https://github.com/helix-editor/helix/pull/12498))\n* Update MATLAB grammar and indent queries ([#12518](https://github.com/helix-editor/helix/pull/12518))\n* Recognize `rockspec` as Lua ([#12516](https://github.com/helix-editor/helix/pull/12516))\n* Add `///` to Dart comment tokens configuration ([99d33c7](https://github.com/helix-editor/helix/commit/99d33c7))\n* Update Solidity grammar and queries ([#12457](https://github.com/helix-editor/helix/pull/12457))\n* Update Spade grammar and queries ([#12583](https://github.com/helix-editor/helix/pull/12583))\n* Re-enable Hare fetching and building by default ([#11507](https://github.com/helix-editor/helix/pull/11507))\n\nPackaging:\n\n* `--version` now prints a leading zero for single-digit months, for example `25.01` (03f35af)\n* Pin the Ubuntu GitHub Actions runners used for releases to `ubuntu-22.04` ([#12464](https://github.com/helix-editor/helix/pull/12464))\n* Produce a Debian package (`.deb` file) in the release GitHub Actions workflow ([#12453](https://github.com/helix-editor/helix/pull/12453))\n\n# 25.01 (2025-01-03)\n\nAs always, a big thank you to all of the contributors! This release saw changes from 171 contributors.\n\nBreaking changes:\n\n* The `editor.lsp.display-messages` key now controls messages sent with the LSP `window/showMessage` notification rather than progress messages. If you want to enable progress messages you should now enable the `editor.lsp.display-progress-messages` key instead. ([#5535](https://github.com/helix-editor/helix/pull/5535))\n\nFeatures:\n\n* Big refactor for `Picker`s ([#9647](https://github.com/helix-editor/helix/pull/9647), [#11209](https://github.com/helix-editor/helix/pull/11209), [#11216](https://github.com/helix-editor/helix/pull/11216), [#11211](https://github.com/helix-editor/helix/pull/11211), [#11343](https://github.com/helix-editor/helix/pull/11343), [#11406](https://github.com/helix-editor/helix/pull/11406))\n    * Use a table layout and allow filtering by column\n    * Reimplement `global_search` to allow changing the query dynamically\n* Add an alternative \"inline\" display for LSP diagnostics ([#6417](https://github.com/helix-editor/helix/pull/6417), [#11815](https://github.com/helix-editor/helix/pull/11815))\n* Support defining keybindings as macros ([#4709](https://github.com/helix-editor/helix/pull/4709))\n* Continue line comments in `o`/`O` and on `<ret>` in insert mode ([#10996](https://github.com/helix-editor/helix/pull/10996), [#12213](https://github.com/helix-editor/helix/pull/12213), [#12215](https://github.com/helix-editor/helix/pull/12215))\n* Allow configuring and switching clipboard providers at runtime ([#10839](https://github.com/helix-editor/helix/pull/10839), [b855cd0](https://github.com/helix-editor/helix/commit/b855cd0), [467fad5](https://github.com/helix-editor/helix/commit/467fad5), [191b0f0](https://github.com/helix-editor/helix/commit/191b0f0))\n* Add support for path completion ([#2608](https://github.com/helix-editor/helix/pull/2608))\n* Support bindings with the Super (Cmd/Win/Meta) modifier ([#6592](https://github.com/helix-editor/helix/pull/6592))\n* Support rendering and jumping between tabstops in snippet completions ([#9801](https://github.com/helix-editor/helix/pull/9801))\n* Allow theming directory completions ([#12205](https://github.com/helix-editor/helix/pull/12205), [#12295](https://github.com/helix-editor/helix/pull/12295))\n\nCommands:\n\n* Add commands to move within snake_case or camelCase words ([#8147](https://github.com/helix-editor/helix/pull/8147))\n* Add `search_selection_detect_word_boundaries` ([#12126](https://github.com/helix-editor/helix/pull/12126))\n    * This command takes the `*` key in normal and select mode, replacing `search_selection` which was moved to `A-*`.\n\nUsability improvements:\n\n* Add `:edit` and `:e` aliases for `:open` ([#11186](https://github.com/helix-editor/helix/pull/11186), [#11196](https://github.com/helix-editor/helix/pull/11196))\n* Trim trailing newline from pipe command outputs when the input doesn't have a trailing newline ([#11183](https://github.com/helix-editor/helix/pull/11183), [4f63a46](https://github.com/helix-editor/helix/commit/4f63a46))\n* Add `:mv` alias for `:move` ([#11256](https://github.com/helix-editor/helix/pull/11256))\n* Return document display name instead of absolute path from the `%` special register ([#11275](https://github.com/helix-editor/helix/pull/11275))\n* Track view position on a per-view instead of per-document basis ([#10559](https://github.com/helix-editor/helix/pull/10559))\n* Improve scrolloff calculation to leave a gap in the middle ([#11323](https://github.com/helix-editor/helix/pull/11323))\n* Show a popup for stderr printed by failed `:sh` commands ([#11239](https://github.com/helix-editor/helix/pull/11239))\n* Add statusline errors when nothing is selected with `s`, `K`, `A-K` ([#11370](https://github.com/helix-editor/helix/pull/11370))\n* Add `.svn` as a workspace root marker ([#11429](https://github.com/helix-editor/helix/pull/11429))\n* Trim the end of `:sh` outputs ([#11161](https://github.com/helix-editor/helix/pull/11161))\n* Show LSP `window/showMessage` messages in the statusline ([#5535](https://github.com/helix-editor/helix/pull/5535))\n* Support finding workspace directories via `.jj` directories ([#11685](https://github.com/helix-editor/helix/pull/11685))\n* Join single-line comments with `join_selections` (`J`) ([#11742](https://github.com/helix-editor/helix/pull/11742))\n* Show anonymous syntax tree nodes in `:tree-sitter-subtree` ([#11663](https://github.com/helix-editor/helix/pull/11663), [38e8382](https://github.com/helix-editor/helix/commit/38e8382))\n* Save an undo checkpoint before paste in insert mode ([#8121](https://github.com/helix-editor/helix/pull/8121))\n* Only break on ASCII spaces in `:reflow` ([#12048](https://github.com/helix-editor/helix/pull/12048))\n* Add a `default-yank-register` config option ([#11430](https://github.com/helix-editor/helix/pull/11430))\n* Show a statusline error for `:format` when a formatter is not available ([#12183](https://github.com/helix-editor/helix/pull/12183))\n* Change to the home directory with `:cd` with no arguments ([#12042](https://github.com/helix-editor/helix/pull/12042))\n* Change default comment token to `#` for unrecognized files ([#12080](https://github.com/helix-editor/helix/pull/12080), [#12266](https://github.com/helix-editor/helix/pull/12266), [bae6a58](https://github.com/helix-editor/helix/commit/bae6a58))\n* Trim all trailing whitespace on `insert_newline` ([#12177](https://github.com/helix-editor/helix/pull/12177))\n* Change to the prior directory with `:cd -` ([#12194](https://github.com/helix-editor/helix/pull/12194))\n* Allow parsing `-` (with no modifiers) as a keybinding ([#12191](https://github.com/helix-editor/helix/pull/12191))\n* Improve opening statusline and error messages when opening duplicate files or directories ([#12199](https://github.com/helix-editor/helix/pull/12199))\n* Trim trailing colons in paths passed on the argv ([#9963](https://github.com/helix-editor/helix/pull/9963))\n* Show tree-sitter parser availability in `hx --health <lang>` ([#12228](https://github.com/helix-editor/helix/pull/12228))\n* Show a preview block for colors in the LSP completion menu ([#12299](https://github.com/helix-editor/helix/pull/12299))\n* Add infobox help for `surround_add`, `surround_replace` and `surround_delete` ([#12262](https://github.com/helix-editor/helix/pull/12262))\n\nFixes:\n\n* Respect document indentation settings in `format_selections` (`=`) ([#11169](https://github.com/helix-editor/helix/pull/11169))\n* Avoid switching the current document to normal mode during an LSP `workspace/applyEdit` operation ([#11176](https://github.com/helix-editor/helix/pull/11176))\n* Fix off-by-one in LSP `find_completion_range` ([#11266](https://github.com/helix-editor/helix/pull/11266))\n* Prefer file-system mtime to local system time for detecting external modifications ([#11142](https://github.com/helix-editor/helix/pull/11142), [#11352](https://github.com/helix-editor/helix/pull/11352), [#11358](https://github.com/helix-editor/helix/pull/11358), [#11361](https://github.com/helix-editor/helix/pull/11361))\n* Fix writing of hardlinks ([#11340](https://github.com/helix-editor/helix/pull/11340))\n* Prevent language servers from being automatically restarted when stopped with `:lsp-stop` ([#11321](https://github.com/helix-editor/helix/pull/11321))\n* Stable-sort LSP text edits ([#11357](https://github.com/helix-editor/helix/pull/11357))\n* Fix determination of current language layer in documents with nested language injections ([#11365](https://github.com/helix-editor/helix/pull/11365))\n* Fix a panic from `:move`ing a file to a new extension which starts a language server ([#11387](https://github.com/helix-editor/helix/pull/11387))\n* Fix a panic from duplicating the diff gutter ([#11092](https://github.com/helix-editor/helix/pull/11092))\n* Keep cursor position when exactly replacing text ([#5930](https://github.com/helix-editor/helix/pull/5930))\n* Fix a panic from `jump_backward` on a newly opened split ([#11508](https://github.com/helix-editor/helix/pull/11508))\n* Fix a panic from language servers sending an unknown diagnostic severity ([#11569](https://github.com/helix-editor/helix/pull/11569))\n* Fix a panic when drawing at the edge of the screen ([#11737](https://github.com/helix-editor/helix/pull/11737))\n* Fix git repo detection on symlinks ([#11732](https://github.com/helix-editor/helix/pull/11732))\n* Fix a panic from a language server sending an out-of-range active signature index in `textDocument/signatureHelp` ([#11825](https://github.com/helix-editor/helix/pull/11825))\n* Fix a panic from using `C-k` in a prompt ending in a multi-byte character ([#12237](https://github.com/helix-editor/helix/pull/12237))\n* Expand tildes in paths passed to `:read` ([#12271](https://github.com/helix-editor/helix/pull/12271))\n* Respect per-language `workspace-lsp-roots` configuration when opening new documents ([#12223](https://github.com/helix-editor/helix/pull/12223))\n* Consistently replace line-endings in paste/replace commands ([c262fe4](https://github.com/helix-editor/helix/commit/c262fe4))\n* Fix formatting in error statusline messages when inspecting variables in DAP ([#12354](https://github.com/helix-editor/helix/pull/12354))\n* Fix invisible printing of headers in `--health` output on light terminals ([#12355](https://github.com/helix-editor/helix/pull/12355))\n* Accept integers serialized as floats in the JSONRPC `id` field ([#12376](https://github.com/helix-editor/helix/pull/12376))\n\nThemes:\n\n* Bring `kanagawa` colors better in line with neovim version ([#11187](https://github.com/helix-editor/helix/pull/11187), [#11270](https://github.com/helix-editor/helix/pull/11270))\n* Add `ao` ([#11063](https://github.com/helix-editor/helix/pull/11063))\n* Update `dark_plus` ([#11415](https://github.com/helix-editor/helix/pull/11415))\n* Add `iceberg-light` and `iceberg-dark` ([#10674](https://github.com/helix-editor/helix/pull/10674))\n* Update everforest themes ([#11459](https://github.com/helix-editor/helix/pull/11459))\n* Update gruvbox themes ([#11477](https://github.com/helix-editor/helix/pull/11477))\n* Change primary selection cursor color for `naysayer` ([#11617](https://github.com/helix-editor/helix/pull/11617))\n* Style picker column names in `horizon-dark` ([#11649](https://github.com/helix-editor/helix/pull/11649))\n* Style picker column names in Darcula themes ([#11649](https://github.com/helix-editor/helix/pull/11649))\n* Update diagnostics colors in `snazzy` ([#11731](https://github.com/helix-editor/helix/pull/11731))\n* Update bogster themes ([#11353](https://github.com/helix-editor/helix/pull/11353))\n* Highlight `keyword.storage` in `onedark` ([#11802](https://github.com/helix-editor/helix/pull/11802))\n* Add `ui.virtual.jump-label` to `serika-dark` ([#11911](https://github.com/helix-editor/helix/pull/11911))\n* Add `adwaita-light` ([#10869](https://github.com/helix-editor/helix/pull/10869))\n* Add seoul256 themes ([#11466](https://github.com/helix-editor/helix/pull/11466))\n* Add yo themes ([#11703](https://github.com/helix-editor/helix/pull/11703))\n* Add `eiffel` ([#11679](https://github.com/helix-editor/helix/pull/11679))\n* Add `carbonfox` ([#11558](https://github.com/helix-editor/helix/pull/11558))\n* Set tags color in monokai themes ([#11917](https://github.com/helix-editor/helix/pull/11917))\n* Improve readability of spacebones picker selection ([#12064](https://github.com/helix-editor/helix/pull/12064))\n* Update modus themes ([#11949](https://github.com/helix-editor/helix/pull/11949))\n* Use bold for statusline mode indicator in `onedarker` ([#11958](https://github.com/helix-editor/helix/pull/11958))\n* Update hex themes, add a new hex theme ([#10849](https://github.com/helix-editor/helix/pull/10849))\n* Add `sunset` ([#12093](https://github.com/helix-editor/helix/pull/12093))\n* Add bufferline highlighting for flexoki themes ([#12146](https://github.com/helix-editor/helix/pull/12146))\n* Add colors for (un)checked list items to catppuccin themes ([#12167](https://github.com/helix-editor/helix/pull/12167))\n* Update `voxed` ([#9328](https://github.com/helix-editor/helix/pull/9328))\n* Add `vintage` ([#9361](https://github.com/helix-editor/helix/pull/9361))\n* Add directory style to everforest themes ([#12287](https://github.com/helix-editor/helix/pull/12287))\n* Add inactive text and update jump label highlights in `dark_plus` ([#12289](https://github.com/helix-editor/helix/pull/12289))\n* Sync changes with catppuccin themes ([#12304](https://github.com/helix-editor/helix/pull/12304))\n* Add `ui.text.directory` to `nightfox` ([#12328](https://github.com/helix-editor/helix/pull/12328))\n* Add `ui.text.directory` to `sunset` ([#12328](https://github.com/helix-editor/helix/pull/12328))\n* Add `diagnostic.unnecessary` to Catppuccin themes ([#12391](https://github.com/helix-editor/helix/pull/12391))\n\nNew languages:\n\n* `jjdescription` ([#11271](https://github.com/helix-editor/helix/pull/11271), [#11857](https://github.com/helix-editor/helix/pull/11857), [#12305](https://github.com/helix-editor/helix/pull/12305))\n* i3wm and Sway configs ([#11424](https://github.com/helix-editor/helix/pull/11424))\n* TypeSpec ([#11412](https://github.com/helix-editor/helix/pull/11412))\n* jq ([#11393](https://github.com/helix-editor/helix/pull/11393))\n* Thrift ([#11367](https://github.com/helix-editor/helix/pull/11367))\n* Gherkin ([#11083](https://github.com/helix-editor/helix/pull/11083))\n* Circom ([#11676](https://github.com/helix-editor/helix/pull/11676))\n* Dune ([#11829](https://github.com/helix-editor/helix/pull/11829))\n* Snakemake ([#11858](https://github.com/helix-editor/helix/pull/11858), [#11936](https://github.com/helix-editor/helix/pull/11936))\n* Cylc ([#11830](https://github.com/helix-editor/helix/pull/11830))\n* textproto ([#11874](https://github.com/helix-editor/helix/pull/11874))\n* Spade ([#11448](https://github.com/helix-editor/helix/pull/11448), [#12276](https://github.com/helix-editor/helix/pull/12276))\n* NestedText ([#11987](https://github.com/helix-editor/helix/pull/11987))\n* Quint ([#11898](https://github.com/helix-editor/helix/pull/11898))\n* Amber-lang ([#12021](https://github.com/helix-editor/helix/pull/12021))\n* Vento ([#12147](https://github.com/helix-editor/helix/pull/12147))\n* Teal ([#12081](https://github.com/helix-editor/helix/pull/12081))\n* Koto ([#12307](https://github.com/helix-editor/helix/pull/12307))\n* NGINX ([#12309](https://github.com/helix-editor/helix/pull/12309))\n\nUpdated languages and queries:\n\n* Add comment injections for Hare ([#11173](https://github.com/helix-editor/helix/pull/11173))\n* Improve highlights for `blade.php` files ([#11138](https://github.com/helix-editor/helix/pull/11138))\n* Update tree-sitter-slint ([#11224](https://github.com/helix-editor/helix/pull/11224), [#11757](https://github.com/helix-editor/helix/pull/11757), [#12297](https://github.com/helix-editor/helix/pull/12297))\n* Recognize `just` files as Just ([#11286](https://github.com/helix-editor/helix/pull/11286))\n* Recognize `mdx` as Markdown ([#11122](https://github.com/helix-editor/helix/pull/11122))\n* Update Just grammar and queries ([#11306](https://github.com/helix-editor/helix/pull/11306))\n* Recognize `tclsh` as TCL ([#11236](https://github.com/helix-editor/helix/pull/11236))\n* Update Godot grammar and queries ([#11235](https://github.com/helix-editor/helix/pull/11235))\n* Update Gleam grammar and queries ([#11427](https://github.com/helix-editor/helix/pull/11427))\n* Add `mesonlsp` for Meson ([#11416](https://github.com/helix-editor/helix/pull/11416))\n* Update HTML highlights ([#11400](https://github.com/helix-editor/helix/pull/11400))\n* Add comment textobjects for Verilog ([#11388](https://github.com/helix-editor/helix/pull/11388))\n* Switch tree-sitter-just grammar ([#11380](https://github.com/helix-editor/helix/pull/11380), [#11606](https://github.com/helix-editor/helix/pull/11606), [#12141](https://github.com/helix-editor/helix/pull/12141))\n* Update tree-sitter-fsharp ([#11061](https://github.com/helix-editor/helix/pull/11061))\n* Add `nixd` for Nix ([#10767](https://github.com/helix-editor/helix/pull/10767))\n* Highlight types and enum members from the Rust prelude ([#8535](https://github.com/helix-editor/helix/pull/8535))\n* Improve textobjects for HCL, Nix ([#11513](https://github.com/helix-editor/helix/pull/11513))\n* Add textobjects queries for docker-compose, dockerfile, env, git-config, hcl, hocon, prisma, SQL and YAML ([#11513](https://github.com/helix-editor/helix/pull/11513))\n* Recognize cshtml files as HTML ([#11540](https://github.com/helix-editor/helix/pull/11540))\n* Set a memory limit for the Lean language server ([#11683](https://github.com/helix-editor/helix/pull/11683))\n* Add configurations for jedi and ruff language servers ([#11630](https://github.com/helix-editor/helix/pull/11630))\n* Update Vue highlights ([#11706](https://github.com/helix-editor/helix/pull/11706))\n* Switch tree-sitter-hcl grammar ([#11749](https://github.com/helix-editor/helix/pull/11749))\n* Fix `odinfmt` formatter configuration ([#11759](https://github.com/helix-editor/helix/pull/11759))\n* Recognize `rbs` files as Ruby ([#11786](https://github.com/helix-editor/helix/pull/11786))\n* Update tree-sitter-nickel ([#11771](https://github.com/helix-editor/helix/pull/11771))\n* Recognize `ldtk` and `ldtkl` files as JSON ([#11793](https://github.com/helix-editor/helix/pull/11793))\n* Fix highlights for builtin functions in Fish ([#11792](https://github.com/helix-editor/helix/pull/11792))\n* Add `superhtml` for HTML ([#11609](https://github.com/helix-editor/helix/pull/11609))\n* Add a configuration for the Vale language server ([#11636](https://github.com/helix-editor/helix/pull/11636))\n* Add Erlang Language Platform (`elp`) for Erlang ([#11499](https://github.com/helix-editor/helix/pull/11499))\n* Update Odin highlights ([#11804](https://github.com/helix-editor/helix/pull/11804))\n* Remove auto-pairs for single quotes in SML ([#11838](https://github.com/helix-editor/helix/pull/11838))\n* Add `glsl_analyzer` for GLSL ([#11891](https://github.com/helix-editor/helix/pull/11891))\n* Recognize `.prettierrc` as YAML ([#11997](https://github.com/helix-editor/helix/pull/11997))\n* Fix `swift-format` formatter configuration ([#12052](https://github.com/helix-editor/helix/pull/12052))\n* Add `package.json` and `tsconfig.json` as JS/TS workspace roots ([#10652](https://github.com/helix-editor/helix/pull/10652))\n* Add \"INVARIANT\" to comment error highlights ([#12094](https://github.com/helix-editor/helix/pull/12094))\n* Update Rescript grammar and queries ([#11165](https://github.com/helix-editor/helix/pull/11165))\n* Update tree-sitter-nasm ([#11795](https://github.com/helix-editor/helix/pull/11795))\n* Update LLVM grammars ([#11851](https://github.com/helix-editor/helix/pull/11851))\n* Update Perl and Pod grammars ([#11848](https://github.com/helix-editor/helix/pull/11848))\n* Add Nim injections in Nix ([#11837](https://github.com/helix-editor/helix/pull/11837))\n* Recognize `livemd` as Markdown ([#12034](https://github.com/helix-editor/helix/pull/12034))\n* Update Unison grammar and queries ([#12039](https://github.com/helix-editor/helix/pull/12039))\n* Turn off Swift auto-format by default ([#12071](https://github.com/helix-editor/helix/pull/12071))\n* Recognize `.swift-format` as JSON ([#12071](https://github.com/helix-editor/helix/pull/12071))\n* Recognize `.clangd` and `.clang-format` as YAML ([#12032](https://github.com/helix-editor/helix/pull/12032))\n* Recognize `ssh_config.d/*.conf` as sshclientconfig ([#11947](https://github.com/helix-editor/helix/pull/11947))\n* Update comment token configs for Zig ([#12049](https://github.com/helix-editor/helix/pull/12049))\n* Update tree-sitter-bicep ([#11525](https://github.com/helix-editor/helix/pull/11525))\n* Add `hyperls` for Hyperlang ([#11056](https://github.com/helix-editor/helix/pull/11056))\n* Add highlight queries for Solidity ([#12102](https://github.com/helix-editor/helix/pull/12102))\n* Recognize `WORKSPACE.bzlmod` as Starlark ([#12103](https://github.com/helix-editor/helix/pull/12103))\n* Update Ada grammar and queries ([#12131](https://github.com/helix-editor/helix/pull/12131))\n* Restrict Hocon file-types glob patterns ([#12156](https://github.com/helix-editor/helix/pull/12156))\n* Update Mojo language server to Magic ([#12195](https://github.com/helix-editor/helix/pull/12195))\n* Switch tree-sitter-v grammar ([#12236](https://github.com/helix-editor/helix/pull/12236))\n* Add \"COMPLIANCE\" to comment error highlights ([#12094](https://github.com/helix-editor/helix/pull/12094))\n* Add a language server configuration for `ltex-ls-plus` ([#12251](https://github.com/helix-editor/helix/pull/12251))\n* Update tree-sitter-dockerfile ([#12230](https://github.com/helix-editor/helix/pull/12230))\n* Add `]` to PHP outdents ([#12286](https://github.com/helix-editor/helix/pull/12286))\n* Add textobjects for Odin ([#12302](https://github.com/helix-editor/helix/pull/12302))\n* Update tree-sitter-heex and queries ([#12334](https://github.com/helix-editor/helix/pull/12334))\n* Update protobuf highlights ([#12339](https://github.com/helix-editor/helix/pull/12339))\n* Switch tree-sitter-query (TSQ) grammar ([#12148](https://github.com/helix-editor/helix/pull/12148), [e0bccd2](https://github.com/helix-editor/helix/commit/e0bccd2))\n* Add block comment configurations for jinja and nunjucks ([#12348](https://github.com/helix-editor/helix/pull/12348))\n* Add `uv` shebang for python ([#12360](https://github.com/helix-editor/helix/pull/12360))\n* Update tree-sitter-vento ([#12368](https://github.com/helix-editor/helix/pull/12368))\n* Switch Protobuf tree-sitter grammar ([#12225](https://github.com/helix-editor/helix/pull/12225))\n* Recognize `hypr/*.conf` as Hyprland ([#12384](https://github.com/helix-editor/helix/pull/12384))\n\nPackaging:\n\n* Add completions for Nushell ([#11262](https://github.com/helix-editor/helix/pull/11262), [#11346](https://github.com/helix-editor/helix/pull/11346))\n* Fix completion of flags in Bash completions ([#11246](https://github.com/helix-editor/helix/pull/11246))\n* Include shell completions in Nix outputs ([#11518](https://github.com/helix-editor/helix/pull/11518))\n\n# 24.07 (2024-07-14)\n\nThanks to all of the contributors! This release has changes from 160 contributors.\n\nBreaking changes:\n\nFeatures:\n\n- Add a textobject for entries/elements of list-like things ([#8150](https://github.com/helix-editor/helix/pull/8150))\n- Add a picker showing files changed in VCS ([#5645](https://github.com/helix-editor/helix/pull/5645))\n- Use a temporary file for writes ([#9236](https://github.com/helix-editor/helix/pull/9236), [#10339](https://github.com/helix-editor/helix/pull/10339), [#10790](https://github.com/helix-editor/helix/pull/10790))\n- Allow cycling through LSP signature-help signatures with `A-n`/`A-p` ([#9974](https://github.com/helix-editor/helix/pull/9974), [#10654](https://github.com/helix-editor/helix/pull/10654), [#10655](https://github.com/helix-editor/helix/pull/10655))\n- Use tree-sitter when finding matching brackets and closest pairs ([#8294](https://github.com/helix-editor/helix/pull/8294), [#10613](https://github.com/helix-editor/helix/pull/10613), [#10777](https://github.com/helix-editor/helix/pull/10777))\n- Auto-save all buffers after a delay ([#10899](https://github.com/helix-editor/helix/pull/10899), [#11047](https://github.com/helix-editor/helix/pull/11047))\n\nCommands:\n\n- `select_all_siblings` (`A-a`) - select all siblings of each selection ([87c4161](https://github.com/helix-editor/helix/commit/87c4161))\n- `select_all_children` (`A-I`) - select all children of each selection ([fa67c5c](https://github.com/helix-editor/helix/commit/fa67c5c))\n- `:read` - insert the contents of the given file at each selection ([#10447](https://github.com/helix-editor/helix/pull/10447))\n\nUsability improvements:\n\n- Support scrolling popup contents using the mouse ([#10053](https://github.com/helix-editor/helix/pull/10053))\n- Sort the jumplist picker so that most recent items come first ([#10095](https://github.com/helix-editor/helix/pull/10095))\n- Improve `goto_file`'s (`gf`) automatic path detection strategy ([#9065](https://github.com/helix-editor/helix/pull/9065))\n- Respect language server definition order in code action menu ([#9590](https://github.com/helix-editor/helix/pull/9590))\n- Allow using a count with `goto_next_buffer` (`gn`) and `goto_previous_buffer` (`gp`) ([#10463](https://github.com/helix-editor/helix/pull/10463))\n- Improve the positioning of popups ([#10257](https://github.com/helix-editor/helix/pull/10257), [#10573](https://github.com/helix-editor/helix/pull/10573))\n- Reset all changes overlapped by selections in `:reset-diff-change` ([#10728](https://github.com/helix-editor/helix/pull/10728))\n- Await pending writes in the `suspend` command (`C-z`) ([#10797](https://github.com/helix-editor/helix/pull/10797))\n- Remove special handling of line ending characters in `replace` (`r`) ([#10786](https://github.com/helix-editor/helix/pull/10786))\n- Use the selected register as a history register for `rename_symbol` (`<space>r`) ([#10932](https://github.com/helix-editor/helix/pull/10932))\n- Use the configured insert-mode cursor for prompt entry ([#10945](https://github.com/helix-editor/helix/pull/10945))\n- Add tilted quotes to the matching brackets list ([#10971](https://github.com/helix-editor/helix/pull/10971))\n- Prevent improper files like `/dev/urandom` from being used as file arguments ([#10733](https://github.com/helix-editor/helix/pull/10733))\n- Allow multiple language servers to provide `:lsp-workspace-command`s ([#10176](https://github.com/helix-editor/helix/pull/10176), [#11105](https://github.com/helix-editor/helix/pull/11105))\n- Trim output of commands executed through `:pipe` ([#10952](https://github.com/helix-editor/helix/pull/10952))\n\nFixes:\n\n- Use `lldb-dap` instead of `lldb-vscode` in default DAP configuration ([#10091](https://github.com/helix-editor/helix/pull/10091))\n- Fix creation of uneven splits when closing windows ([#10004](https://github.com/helix-editor/helix/pull/10004))\n- Avoid setting a register in `delete_selection_noyank`, fixing the command's use in command sequences ([#10050](https://github.com/helix-editor/helix/pull/10050), [#10148](https://github.com/helix-editor/helix/pull/10148))\n- Fix jump alphabet config resetting when using `:config-reload` ([#10156](https://github.com/helix-editor/helix/pull/10156))\n- Overlay LSP unnecessary/deprecated diagnostic tag highlights onto regular diagnostic highlights ([#10084](https://github.com/helix-editor/helix/pull/10084))\n- Fix crash on LSP text edits with invalid ranges ([#9649](https://github.com/helix-editor/helix/pull/9649))\n- Handle partial failure when sending multiple LSP `textDocument/didSave` notifications ([#10168](https://github.com/helix-editor/helix/pull/10168))\n- Fix off-by-one error for completion-replace option ([#10279](https://github.com/helix-editor/helix/pull/10279))\n- Fix mouse right-click selection behavior ([#10067](https://github.com/helix-editor/helix/pull/10067))\n- Fix scrolling to the end within a popup ([#10181](https://github.com/helix-editor/helix/pull/10181))\n- Fix jump label highlight locations when jumping in non-ascii text ([#10317](https://github.com/helix-editor/helix/pull/10317))\n- Fix crashes from tree-sitter query captures that return non-grapheme aligned ranges ([#10310](https://github.com/helix-editor/helix/pull/10310))\n- Include VCS change in `mi`/`ma` textobject infobox ([#10496](https://github.com/helix-editor/helix/pull/10496))\n- Override crossterm's support for `NO_COLOR` ([#10514](https://github.com/helix-editor/helix/pull/10514))\n- Respect mode when starting a search ([#10505](https://github.com/helix-editor/helix/pull/10505))\n- Simplify first-in-line computation for indent queries ([#10527](https://github.com/helix-editor/helix/pull/10527))\n- Ignore .svn version controlled files in file pickers ([#10536](https://github.com/helix-editor/helix/pull/10536))\n- Fix overloading language servers with `completionItem/resolve` requests ([38ee845](https://github.com/helix-editor/helix/commit/38ee845), [#10873](https://github.com/helix-editor/helix/pull/10873))\n- Specify direction for `select_next_sibling` / `select_prev_sibling` ([#10542](https://github.com/helix-editor/helix/pull/10542))\n- Fix restarting language servers ([#10614](https://github.com/helix-editor/helix/pull/10614))\n- Don't stop at the first URL in `goto_file` ([#10622](https://github.com/helix-editor/helix/pull/10622))\n- Fix overflows in window size calculations for small terminals ([#10620](https://github.com/helix-editor/helix/pull/10620))\n- Allow missing or empty completion lists in DAP ([#10332](https://github.com/helix-editor/helix/pull/10332))\n- Revert statusline refactor that could cause the statusline to blank out on files with long paths ([#10642](https://github.com/helix-editor/helix/pull/10642))\n- Synchronize files after writing ([#10735](https://github.com/helix-editor/helix/pull/10735))\n- Avoid `cnorm` for cursor-type detection in certain terminals ([#10769](https://github.com/helix-editor/helix/pull/10769))\n- Reset inlay hints when stopping or restarting a language server ([#10741](https://github.com/helix-editor/helix/pull/10741))\n- Fix logic for updating `--version` when development VCS HEAD changes ([#10896](https://github.com/helix-editor/helix/pull/10896))\n- Set a max value for the count ([#10930](https://github.com/helix-editor/helix/pull/10930))\n- Deserialize number IDs in DAP module types ([#10943](https://github.com/helix-editor/helix/pull/10943))\n- Fix the behavior of `jump_backwords` when the jumplist is at capacity ([#10968](https://github.com/helix-editor/helix/pull/10968))\n- Fix injection layer heritage tracking for reused tree-sitter injection layers ([#1098](https://github.com/helix-editor/helix/pull/1098))\n- Fix pluralization of \"buffers\" in the statusline for `:q`, `:q!`, `:wq` ([#11018](https://github.com/helix-editor/helix/pull/11018))\n- Declare LSP formatting client capabilities ([#11064](https://github.com/helix-editor/helix/pull/11064))\n- Commit uncommitted changes before attempting undo/earlier ([#11090](https://github.com/helix-editor/helix/pull/11090))\n- Expand tilde for selected paths in `goto_file` ([#10964](https://github.com/helix-editor/helix/pull/10964))\n- Commit undo checkpoints before `:write[-all]`, fixing the modification indicator ([#11062](https://github.com/helix-editor/helix/pull/11062))\n\nThemes:\n\n- Add jump label styles to `nightfox` ([#10052](https://github.com/helix-editor/helix/pull/10052))\n- Add jump label styles to Solarized themes ([#10056](https://github.com/helix-editor/helix/pull/10056))\n- Add jump label styles to `cyan_light` ([#10058](https://github.com/helix-editor/helix/pull/10058))\n- Add jump label styles to `onelight` ([#10061](https://github.com/helix-editor/helix/pull/10061))\n- Add `flexoki-dark` and `flexoki-light` ([#10002](https://github.com/helix-editor/helix/pull/10002))\n- Add default theme keys for LSP diagnostics tags to existing themes ([#10064](https://github.com/helix-editor/helix/pull/10064))\n- Add jump label styles to base16 themes ([#10076](https://github.com/helix-editor/helix/pull/10076))\n- Dim primary selection in `kanagawa` ([#10094](https://github.com/helix-editor/helix/pull/10094), [#10500](https://github.com/helix-editor/helix/pull/10500))\n- Add jump label styles to tokyonight themes ([#10106](https://github.com/helix-editor/helix/pull/10106))\n- Add jump label styles to papercolor themes ([#10104](https://github.com/helix-editor/helix/pull/10104))\n- Add jump label styles to Darcula themes ([#10116](https://github.com/helix-editor/helix/pull/10116))\n- Add jump label styles to `autumn` ([#10134](https://github.com/helix-editor/helix/pull/10134))\n- Add jump label styles to Ayu themes ([#10133](https://github.com/helix-editor/helix/pull/10133))\n- Add jump label styles to `dark_high_contrast` ([#10133](https://github.com/helix-editor/helix/pull/10133))\n- Update material themes ([#10290](https://github.com/helix-editor/helix/pull/10290))\n- Add jump label styles to `varua` ([#10299](https://github.com/helix-editor/helix/pull/10299))\n- Add ruler style to `adwaita-dark` ([#10260](https://github.com/helix-editor/helix/pull/10260))\n- Remove `ui.highlight` effects from `solarized_dark` ([#10261](https://github.com/helix-editor/helix/pull/10261))\n- Fix statusline color in material themes ([#10308](https://github.com/helix-editor/helix/pull/10308))\n- Brighten `nord` selection highlight ([#10307](https://github.com/helix-editor/helix/pull/10307))\n- Add inlay-hint styles to monokai themes ([#10334](https://github.com/helix-editor/helix/pull/10334))\n- Add bufferline and cursorline colors to `vim_dark_high_contrast` ([#10444](https://github.com/helix-editor/helix/pull/10444))\n- Switch themes with foreground rulers to background ([#10309](https://github.com/helix-editor/helix/pull/10309))\n- Fix statusline colors for `everblush` ([#10394](https://github.com/helix-editor/helix/pull/10394))\n- Use `yellow1` for `gruvbox` warning diagnostics ([#10506](https://github.com/helix-editor/helix/pull/10506))\n- Add jump label styles to Modus themes ([#10538](https://github.com/helix-editor/helix/pull/10538))\n- Refactor `dark_plus` and switch maintainers ([#10543](https://github.com/helix-editor/helix/pull/10543), [#10574](https://github.com/helix-editor/helix/pull/10574))\n- Add debug highlights to `dark_plus` ([#10593](https://github.com/helix-editor/helix/pull/10593))\n- Fix per-mode cursor colors in the default theme ([#10608](https://github.com/helix-editor/helix/pull/10608))\n- Add `tag` and `attribute` highlights to `dark_high_contrast` ([#10705](https://github.com/helix-editor/helix/pull/10705))\n- Improve readability of virtual text with `noctis` theme ([#10910](https://github.com/helix-editor/helix/pull/10910))\n- Sync `catppuccin` themes with upstream ([#10954](https://github.com/helix-editor/helix/pull/10954))\n- Improve jump colors for `github_dark` themes ([#10946](https://github.com/helix-editor/helix/pull/10946))\n- Add modeline and default virtual highlights to `base16_default` ([#10858](https://github.com/helix-editor/helix/pull/10858))\n- Add `iroaseta` ([#10381](https://github.com/helix-editor/helix/pull/10381))\n- Refactor `gruvbox` ([#10773](https://github.com/helix-editor/helix/pull/10773), [#11071](https://github.com/helix-editor/helix/pull/11071))\n- Add cursorcolumn and cursorline to `base16_transparent` ([#11099](https://github.com/helix-editor/helix/pull/11099))\n- Update cursorline color for `fleet_dark` ([#11046](https://github.com/helix-editor/helix/pull/11046))\n- Add `kanagawa-dragon` ([#10172](https://github.com/helix-editor/helix/pull/10172))\n\nNew languages:\n\n- BitBake ([#10010](https://github.com/helix-editor/helix/pull/10010))\n- Earthfile ([#10111](https://github.com/helix-editor/helix/pull/10111), [#10489](https://github.com/helix-editor/helix/pull/10489), [#10779](https://github.com/helix-editor/helix/pull/10779))\n- TCL ([#9837](https://github.com/helix-editor/helix/pull/9837))\n- ADL ([#10029](https://github.com/helix-editor/helix/pull/10029))\n- LDIF ([#10330](https://github.com/helix-editor/helix/pull/10330))\n- XTC ([#10448](https://github.com/helix-editor/helix/pull/10448))\n- Move ([f06a166](https://github.com/helix-editor/helix/commit/f06a166))\n- Pest ([#10616](https://github.com/helix-editor/helix/pull/10616))\n- GJS/GTS ([#9940](https://github.com/helix-editor/helix/pull/9940))\n- Inko ([#10656](https://github.com/helix-editor/helix/pull/10656))\n- Mojo ([#10743](https://github.com/helix-editor/helix/pull/10743))\n- Elisp ([#10644](https://github.com/helix-editor/helix/pull/10644))\n\nUpdated languages and queries:\n\n- Recognize `mkdn` files as markdown ([#10065](https://github.com/helix-editor/helix/pull/10065))\n- Add comment injections for Gleam ([#10062](https://github.com/helix-editor/helix/pull/10062))\n- Recognize BuildKite commands in YAML injections ([#10090](https://github.com/helix-editor/helix/pull/10090))\n- Add F# block comment token configuration ([#10108](https://github.com/helix-editor/helix/pull/10108))\n- Update tree-sitter-templ and queries ([#10114](https://github.com/helix-editor/helix/pull/10114))\n- Recognize `Tiltfile` as Starlark ([#10072](https://github.com/helix-editor/helix/pull/10072))\n- Remove `todo.txt` from files recognized as todotxt ([5fece00](https://github.com/helix-editor/helix/commit/5fece00))\n- Highlight `type` keyword in Python from PEP695 ([#10165](https://github.com/helix-editor/helix/pull/10165))\n- Update tree-sitter-koka, add language server config ([#10119](https://github.com/helix-editor/helix/pull/10119))\n- Recognize node and Python history files ([#10120](https://github.com/helix-editor/helix/pull/10120))\n- Recognize more shell files as bash ([#10120](https://github.com/helix-editor/helix/pull/10120))\n- Recognize the bun shebang as typescript ([#10120](https://github.com/helix-editor/helix/pull/10120))\n- Add a configuration for the angular language server ([#10166](https://github.com/helix-editor/helix/pull/10166))\n- Add textobject queries for Solidity ([#10318](https://github.com/helix-editor/helix/pull/10318))\n- Recognize `meson.options` as Meson ([#10323](https://github.com/helix-editor/helix/pull/10323))\n- Improve Solidity highlighting ([4fc0a4d](https://github.com/helix-editor/helix/commit/4fc0a4d))\n- Recognize `_.tpl` files as Helm ([#10344](https://github.com/helix-editor/helix/pull/10344))\n- Update tree-sitter-ld and highlights ([#10379](https://github.com/helix-editor/helix/pull/10379))\n- Add `lldb-dap` configuration for Odin ([#10175](https://github.com/helix-editor/helix/pull/10175))\n- Update tree-sitter-rust ([#10365](https://github.com/helix-editor/helix/pull/10365))\n- Update tree-sitter-typst ([#10321](https://github.com/helix-editor/helix/pull/10321))\n- Recognize `hyprpaper.conf`, `hypridle.conf` and `hyprlock.conf` as Hyprlang ([#10383](https://github.com/helix-editor/helix/pull/10383))\n- Improve HTML highlighting ([#10503](https://github.com/helix-editor/helix/pull/10503))\n- Add `rust-script` and `cargo` as shebangs for Rust ([#10484](https://github.com/helix-editor/helix/pull/10484))\n- Fix precedence of tag highlights in Svelte ([#10487](https://github.com/helix-editor/helix/pull/10487))\n- Update tree-sitter-bash ([#10526](https://github.com/helix-editor/helix/pull/10526))\n- Recognize `*.ignore` files as ignore ([#10579](https://github.com/helix-editor/helix/pull/10579))\n- Add configuration to enable inlay hints in metals ([#10597](https://github.com/helix-editor/helix/pull/10597))\n- Enable highlighting private members in ECMA languages ([#10554](https://github.com/helix-editor/helix/pull/10554))\n- Add comment injection to typst queries ([#10628](https://github.com/helix-editor/helix/pull/10628))\n- Add textobject queries for Hurl ([#10594](https://github.com/helix-editor/helix/pull/10594))\n- Add `try` keyword to Rust ([#10641](https://github.com/helix-editor/helix/pull/10641))\n- Add `is not` and `not in` to Python highlights ([#10647](https://github.com/helix-editor/helix/pull/10647))\n- Remove ' and ⟨⟩ from Lean autopair configuration ([#10688](https://github.com/helix-editor/helix/pull/10688))\n- Match TOML/YAML highlights for JSON keys ([#10676](https://github.com/helix-editor/helix/pull/10676))\n- Recognize WORKSPACE files as Starlark ([#10713](https://github.com/helix-editor/helix/pull/10713))\n- Switch Odin tree-sitter grammar and highlights ([#10698](https://github.com/helix-editor/helix/pull/10698))\n- Update `tree-sitter-slint` ([#10749](https://github.com/helix-editor/helix/pull/10749))\n- Add missing operators for Solidity highlights ([#10735](https://github.com/helix-editor/helix/pull/10735))\n- Update `tree-sitter-inko` ([#10805](https://github.com/helix-editor/helix/pull/10805))\n- Add `py`, `hs`, `rs` and `typ` injection regexes ([#10785](https://github.com/helix-editor/helix/pull/10785))\n- Update Swift grammar and queries ([#10802](https://github.com/helix-editor/helix/pull/10802))\n- Update Cairo grammar and queries ([#10919](https://github.com/helix-editor/helix/pull/10919), [#11067](https://github.com/helix-editor/helix/pull/11067))\n- Update Rust grammar ([#10973](https://github.com/helix-editor/helix/pull/10973))\n- Add block comment tokens for typst ([#10955](https://github.com/helix-editor/helix/pull/10955))\n- Recognize `jsonl` as JSON ([#11004](https://github.com/helix-editor/helix/pull/11004))\n- Add rulers and text-width at 100 columns for Lean language ([#10969](https://github.com/helix-editor/helix/pull/10969))\n- Improve VDHL highlights ([#10845](https://github.com/helix-editor/helix/pull/10845))\n- Recognize `hsc` as Haskell ([#11074](https://github.com/helix-editor/helix/pull/11074))\n- Fix heredoc and `$'<ansi_string>'` highlights in Bash ([#11118](https://github.com/helix-editor/helix/pull/11118))\n- Add LSP configuration for `basedpyright` ([#11121](https://github.com/helix-editor/helix/pull/11121))\n- Recognize `npmrc` and `.nmprc` files as INI ([#11131](https://github.com/helix-editor/helix/pull/11131))\n- Recognize `~/.config/git/ignore` as git-ignore ([#11131](https://github.com/helix-editor/helix/pull/11131))\n- Recognize `pdm.lock` and `uv.lock` as TOML ([#11131](https://github.com/helix-editor/helix/pull/11131))\n- Recognize `.yml` as well as `.yaml` for Helm chart templates ([#11135](https://github.com/helix-editor/helix/pull/11135))\n- Add regex injections for Bash ([#11112](https://github.com/helix-editor/helix/pull/11112))\n- Update tree-sitter-todo ([#11097](https://github.com/helix-editor/helix/pull/11097))\n\nPackaging:\n\n- Make `Helix.appdata.xml` spec-compliant ([#10051](https://github.com/helix-editor/helix/pull/10051))\n- Expose all flake outputs through flake-compat ([#10673](https://github.com/helix-editor/helix/pull/10673))\n- Bump the MSRV to 1.74.0 ([#10714](https://github.com/helix-editor/helix/pull/10714))\n- Improve FiSH completions ([#10853](https://github.com/helix-editor/helix/pull/10853))\n- Improve ZSH completions ([#10853](https://github.com/helix-editor/helix/pull/10853))\n\n# 24.03 (2024-03-30)\n\nAs always, a big thank you to all of the contributors! This release saw changes from 125 contributors.\n\nBreaking changes:\n\n- `suffix` file-types in the `file-types` key in language configuration have been removed ([#8006](https://github.com/helix-editor/helix/pull/8006))\n- The `file-types` key in language configuration no longer matches full filenames without a glob pattern ([#8006](https://github.com/helix-editor/helix/pull/8006))\n\nFeatures:\n\n- Open URLs with the `goto_file` command ([#5820](https://github.com/helix-editor/helix/pull/5820))\n- Support drawing a border around popups and menus ([#4313](https://github.com/helix-editor/helix/pull/4313), [#9508](https://github.com/helix-editor/helix/pull/9508))\n- Track long lived diagnostic sources like Clippy or `rustc` ([#6447](https://github.com/helix-editor/helix/pull/6447), [#9280](https://github.com/helix-editor/helix/pull/9280))\n    - This improves the handling of diagnostics from sources that only update the diagnostic positions on save.\n- Add support for LSP `window/showDocument` requests ([#8865](https://github.com/helix-editor/helix/pull/8865))\n- Refactor ad-hoc hooks to use a new generic event system ([#8021](https://github.com/helix-editor/helix/pull/8021), [#9668](https://github.com/helix-editor/helix/pull/9668), [#9660](https://github.com/helix-editor/helix/pull/9660))\n    - This improves the behavior of autocompletions. For example navigating in insert mode no longer automatically triggers completions.\n- Allow using globs in the language configuration `file-types` key ([#8006](https://github.com/helix-editor/helix/pull/8006))\n- Allow specifying required roots for situational LSP activation ([#8696](https://github.com/helix-editor/helix/pull/8696))\n- Extend selections using mouse clicks in select mode ([#5436](https://github.com/helix-editor/helix/pull/5436))\n- Toggle block comments ([#4718](https://github.com/helix-editor/helix/pull/4718), [#9894](https://github.com/helix-editor/helix/pull/9894))\n- Support LSP diagnostic tags ([#9780](https://github.com/helix-editor/helix/pull/9780))\n- Add a `file-absolute-path` statusline element ([#4535](https://github.com/helix-editor/helix/pull/4535))\n- Cross injection layers in tree-sitter motions (`A-p`/`A-o`/`A-i`/`A-n`) ([#5176](https://github.com/helix-editor/helix/pull/5176))\n- Add a Amp-editor-like jumping command ([#8875](https://github.com/helix-editor/helix/pull/8875))\n\nCommands:\n\n- `:move` - move buffers with LSP support ([#8584](https://github.com/helix-editor/helix/pull/8584))\n     - Also see [#8949](https://github.com/helix-editor/helix/pull/8949) which made path changes conform to the LSP spec and fixed the behavior of this command.\n- `page_cursor_up`, `page_cursor_down`, `page_cursor_half_up`, `page_cursor_half_down` - commands for scrolling the cursor and page together ([#8015](https://github.com/helix-editor/helix/pull/8015))\n- `:yank-diagnostic` - yank the diagnostic(s) under the primary cursor ([#9640](https://github.com/helix-editor/helix/pull/9640))\n- `select_line_above` / `select_line_below` - extend or shrink a selection based on the direction and anchor ([#9080](https://github.com/helix-editor/helix/pull/9080))\n\nUsability improvements:\n\n- Make `roots` key of `[[language]]` entries in `languages.toml` configuration optional ([#8803](https://github.com/helix-editor/helix/pull/8803))\n- Exit select mode in commands that modify the buffer ([#8689](https://github.com/helix-editor/helix/pull/8689))\n- Use crossterm cursor when out of focus ([#6858](https://github.com/helix-editor/helix/pull/6858), [#8934](https://github.com/helix-editor/helix/pull/8934))\n- Join empty lines with only one space in `join_selections` ([#8989](https://github.com/helix-editor/helix/pull/8989))\n- Introduce a hybrid tree-sitter and contextual indentation heuristic ([#8307](https://github.com/helix-editor/helix/pull/8307))\n- Allow configuring the indentation heuristic ([#8307](https://github.com/helix-editor/helix/pull/8307))\n- Check for LSP rename support before showing rename prompt ([#9277](https://github.com/helix-editor/helix/pull/9277))\n- Normalize `S-<lower-ascii>` keymaps to uppercase ascii ([#9213](https://github.com/helix-editor/helix/pull/9213))\n- Add formatter status to `--health` output ([#7986](https://github.com/helix-editor/helix/pull/7986))\n- Change path normalization strategy to not resolve symlinks ([#9330](https://github.com/helix-editor/helix/pull/9330))\n- Select subtree within injections in `:tree-sitter-subtree` ([#9309](https://github.com/helix-editor/helix/pull/9309))\n- Use tilde expansion and normalization for `$HELIX_RUNTIME` paths ([1bc7aac](https://github.com/helix-editor/helix/commit/1bc7aac))\n- Improve failure message for LSP goto references ([#9382](https://github.com/helix-editor/helix/pull/9382))\n- Use injection syntax trees for bracket matching ([5e0b3cc](https://github.com/helix-editor/helix/commit/5e0b3cc))\n- Respect injections in `:tree-sitter-highlight-name` ([8b6565c](https://github.com/helix-editor/helix/commit/8b6565c))\n- Respect injections in `move_parent_node_end` ([035b8ea](https://github.com/helix-editor/helix/commit/035b8ea))\n- Use `gix` pipeline filter instead of manual CRLF implementation ([#9503](https://github.com/helix-editor/helix/pull/9503))\n- Follow Neovim's truecolor detection ([#9577](https://github.com/helix-editor/helix/pull/9577))\n- Reload language configuration with `:reload`, SIGHUP ([#9415](https://github.com/helix-editor/helix/pull/9415))\n- Allow numbers as bindings ([#8471](https://github.com/helix-editor/helix/pull/8471), [#9887](https://github.com/helix-editor/helix/pull/9887))\n- Respect undercurl config when terminfo is not available ([#9897](https://github.com/helix-editor/helix/pull/9897))\n- Ignore `.pijul`, `.hg`, `.jj` in addition to `.git` in file pickers configured to show hidden files ([#9935](https://github.com/helix-editor/helix/pull/9935))\n- Add completion for registers to `:clear-register` and `:yank-diagnostic` ([#9936](https://github.com/helix-editor/helix/pull/9936))\n- Repeat last motion for goto next/prev diagnostic ([#9966](https://github.com/helix-editor/helix/pull/9966))\n- Allow configuring a character to use when rendering narrow no-breaking space ([#9604](https://github.com/helix-editor/helix/pull/9604))\n- Switch to a streaming regex engine (regex-cursor crate) to significantly speed up regex-based commands and features ([#9422](https://github.com/helix-editor/helix/pull/9422), [#9756](https://github.com/helix-editor/helix/pull/9756), [#9891](https://github.com/helix-editor/helix/pull/9891))\n\nFixes:\n\n- Swap `*` and `+` registers ([#8703](https://github.com/helix-editor/helix/pull/8703), [#8708](https://github.com/helix-editor/helix/pull/8708))\n- Use terminfo to reset terminal cursor style ([#8591](https://github.com/helix-editor/helix/pull/8591))\n- Fix precedence of `@align` captures in indentat computation ([#8659](https://github.com/helix-editor/helix/pull/8659))\n- Only render the preview if a Picker has a preview function ([#8667](https://github.com/helix-editor/helix/pull/8667))\n- Fix the precedence of `ui.virtual.whitespace` ([#8750](https://github.com/helix-editor/helix/pull/8750), [#8879](https://github.com/helix-editor/helix/pull/8879))\n- Fix crash in `:indent-style` ([#9087](https://github.com/helix-editor/helix/pull/9087))\n- Fix `didSave` text inclusion when sync capability is a kind variant ([#9101](https://github.com/helix-editor/helix/pull/9101))\n- Update the history of newly focused views ([#9271](https://github.com/helix-editor/helix/pull/9271))\n- Initialize diagnostics when opening a document ([#8873](https://github.com/helix-editor/helix/pull/8873))\n- Sync views when applying edits to unfocused views ([#9173](https://github.com/helix-editor/helix/pull/9173))\n    - This fixes crashes that could occur from LSP workspace edits or `:write-all`.\n- Treat non-numeric `+arg`s passed in the CLI args as filenames ([#9333](https://github.com/helix-editor/helix/pull/9333))\n- Fix crash when using `mm` on an empty plaintext file ([2fb7e50](https://github.com/helix-editor/helix/commit/2fb7e50))\n- Ignore empty tree-sitter nodes in match bracket ([445f7a2](https://github.com/helix-editor/helix/commit/445f7a2))\n- Exit a language server if it sends a message with invalid JSON ([#9332](https://github.com/helix-editor/helix/pull/9332))\n- Handle failures to enable bracketed paste ([#9353](https://github.com/helix-editor/helix/pull/9353))\n- Gate all captures in a pattern behind `#is-not? local` predicates ([#9390](https://github.com/helix-editor/helix/pull/9390))\n- Make path changes LSP spec conformant ([#8949](https://github.com/helix-editor/helix/pull/8949))\n- Use range positions to determine `insert_newline` motion ([#9448](https://github.com/helix-editor/helix/pull/9448))\n- Fix division by zero when prompt completion area is too small ([#9524](https://github.com/helix-editor/helix/pull/9524))\n- Add changes to history in clipboard replacement typable commands ([#9625](https://github.com/helix-editor/helix/pull/9625))\n- Fix a crash in DAP with an unspecified `line` in breakpoints ([#9632](https://github.com/helix-editor/helix/pull/9632))\n- Fix space handling for filenames in bash completion ([#9702](https://github.com/helix-editor/helix/pull/9702), [#9708](https://github.com/helix-editor/helix/pull/9708))\n- Key diagnostics off of paths instead of LSP URIs ([#7367](https://github.com/helix-editor/helix/pull/7367))\n- Fix panic when using `join_selections_space` ([#9783](https://github.com/helix-editor/helix/pull/9783))\n- Fix panic when using `surround_replace`, `surround_delete` ([#9796](https://github.com/helix-editor/helix/pull/9796))\n- Fix panic in `surround_replace`, `surround_delete` with nested surrounds and multiple cursors ([#9815](https://github.com/helix-editor/helix/pull/9815))\n- Fix panic in `select_textobject_around` ([#9832](https://github.com/helix-editor/helix/pull/9832))\n- Don't stop reloading documents when reloading fails in `:reload-all` ([#9870](https://github.com/helix-editor/helix/pull/9870))\n- Prevent `shell_keep_pipe` from stopping on nonzero exit status codes ([#9817](https://github.com/helix-editor/helix/pull/9817))\n\nThemes:\n\n- Add `gruber-dark` ([#8598](https://github.com/helix-editor/helix/pull/8598))\n- Update `everblush` ([#8705](https://github.com/helix-editor/helix/pull/8705))\n- Update `papercolor` ([#8718](https://github.com/helix-editor/helix/pull/8718), [#8827](https://github.com/helix-editor/helix/pull/8827))\n- Add `polmandres` ([#8759](https://github.com/helix-editor/helix/pull/8759))\n- Add `starlight` ([#8787](https://github.com/helix-editor/helix/pull/8787))\n- Update `naysayer` ([#8838](https://github.com/helix-editor/helix/pull/8838))\n- Add modus operandi themes ([#8728](https://github.com/helix-editor/helix/pull/8728), [#9912](https://github.com/helix-editor/helix/pull/9912))\n- Update `rose_pine` ([#8946](https://github.com/helix-editor/helix/pull/8946))\n- Update `darcula` ([#8738](https://github.com/helix-editor/helix/pull/8738), [#9002](https://github.com/helix-editor/helix/pull/9002), [#9449](https://github.com/helix-editor/helix/pull/9449), [#9588](https://github.com/helix-editor/helix/pull/9588))\n- Add modus vivendi themes ([#8894](https://github.com/helix-editor/helix/pull/8894), [#9912](https://github.com/helix-editor/helix/pull/9912))\n- Add `horizon-dark` ([#9008](https://github.com/helix-editor/helix/pull/9008), [#9493](https://github.com/helix-editor/helix/pull/9493))\n- Update `noctis` ([#9123](https://github.com/helix-editor/helix/pull/9123))\n- Update `nord` ([#9135](https://github.com/helix-editor/helix/pull/9135))\n- Update monokai pro themes ([#9148](https://github.com/helix-editor/helix/pull/9148))\n- Update tokyonight themes ([#9099](https://github.com/helix-editor/helix/pull/9099), [#9724](https://github.com/helix-editor/helix/pull/9724), [#9789](https://github.com/helix-editor/helix/pull/9789))\n- Add `ttox` ([#8524](https://github.com/helix-editor/helix/pull/8524))\n- Add `voxed` ([#9164](https://github.com/helix-editor/helix/pull/9164))\n- Update `sonokai` ([#9370](https://github.com/helix-editor/helix/pull/9370), [#9376](https://github.com/helix-editor/helix/pull/9376), [#5379](https://github.com/helix-editor/helix/pull/5379))\n- Update `onedark`, `onedarker` ([#9397](https://github.com/helix-editor/helix/pull/9397))\n- Update `cyan_light` ([#9375](https://github.com/helix-editor/helix/pull/9375), [#9688](https://github.com/helix-editor/helix/pull/9688))\n- Add `gruvbox_light_soft`, `gruvbox_light_hard` ([#9266](https://github.com/helix-editor/helix/pull/9266))\n- Update GitHub themes ([#9487](https://github.com/helix-editor/helix/pull/9487))\n- Add `term16_dark`, `term16_light` ([#9477](https://github.com/helix-editor/helix/pull/9477))\n- Update Zed themes ([#9544](https://github.com/helix-editor/helix/pull/9544), [#9549](https://github.com/helix-editor/helix/pull/9549))\n- Add `curzon` ([#9553](https://github.com/helix-editor/helix/pull/9553))\n- Add `monokai_soda` ([#9651](https://github.com/helix-editor/helix/pull/9651))\n- Update catppuccin themes ([#9859](https://github.com/helix-editor/helix/pull/9859))\n- Update `rasmus` ([#9939](https://github.com/helix-editor/helix/pull/9939))\n- Update `dark_plus` ([#9949](https://github.com/helix-editor/helix/pull/9949), [628dcd5](https://github.com/helix-editor/helix/commit/628dcd5))\n- Update gruvbox themes ([#9960](https://github.com/helix-editor/helix/pull/9960))\n- Add jump label theming to `dracula` ([#9973](https://github.com/helix-editor/helix/pull/9973))\n- Add jump label theming to `horizon-dark` ([#9984](https://github.com/helix-editor/helix/pull/9984))\n- Add jump label theming to catppuccin themes ([2178adf](https://github.com/helix-editor/helix/commit/2178adf), [#9983](https://github.com/helix-editor/helix/pull/9983))\n- Add jump label theming to `onedark` themes ([da2dec1](https://github.com/helix-editor/helix/commit/da2dec1))\n- Add jump label theming to rose-pine themes ([#9981](https://github.com/helix-editor/helix/pull/9981))\n- Add jump label theming to Nord themes ([#10008](https://github.com/helix-editor/helix/pull/10008))\n- Add jump label theming to Monokai themes ([#10009](https://github.com/helix-editor/helix/pull/10009))\n- Add jump label theming to gruvbox themes ([#10012](https://github.com/helix-editor/helix/pull/10012))\n- Add jump label theming to `kanagawa` ([#10030](https://github.com/helix-editor/helix/pull/10030))\n- Update material themes ([#10043](https://github.com/helix-editor/helix/pull/10043))\n- Add `jetbrains_dark` ([#9967](https://github.com/helix-editor/helix/pull/9967))\n\nNew languages:\n\n- Typst ([#7474](https://github.com/helix-editor/helix/pull/7474))\n- LPF ([#8536](https://github.com/helix-editor/helix/pull/8536))\n- GN ([#6969](https://github.com/helix-editor/helix/pull/6969))\n- DBML ([#8860](https://github.com/helix-editor/helix/pull/8860))\n- log ([#8916](https://github.com/helix-editor/helix/pull/8916))\n- Janet ([#9081](https://github.com/helix-editor/helix/pull/9081), [#9247](https://github.com/helix-editor/helix/pull/9247))\n- Agda ([#8285](https://github.com/helix-editor/helix/pull/8285))\n- Avro ([#9113](https://github.com/helix-editor/helix/pull/9113))\n- Smali ([#9089](https://github.com/helix-editor/helix/pull/9089))\n- HOCON ([#9203](https://github.com/helix-editor/helix/pull/9203))\n- Tact ([#9512](https://github.com/helix-editor/helix/pull/9512))\n- PKL ([#9515](https://github.com/helix-editor/helix/pull/9515))\n- CEL ([#9296](https://github.com/helix-editor/helix/pull/9296))\n- SpiceDB ([#9296](https://github.com/helix-editor/helix/pull/9296))\n- Hoon ([#9190](https://github.com/helix-editor/helix/pull/9190))\n- DockerCompose ([#9661](https://github.com/helix-editor/helix/pull/9661), [#9916](https://github.com/helix-editor/helix/pull/9916))\n- Groovy ([#9350](https://github.com/helix-editor/helix/pull/9350), [#9681](https://github.com/helix-editor/helix/pull/9681), [#9677](https://github.com/helix-editor/helix/pull/9677))\n- FIDL ([#9713](https://github.com/helix-editor/helix/pull/9713))\n- Powershell ([#9827](https://github.com/helix-editor/helix/pull/9827))\n- ld ([#9835](https://github.com/helix-editor/helix/pull/9835))\n- Hyperland config ([#9899](https://github.com/helix-editor/helix/pull/9899))\n- JSONC ([#9906](https://github.com/helix-editor/helix/pull/9906))\n- PHP Blade ([#9513](https://github.com/helix-editor/helix/pull/9513))\n- SuperCollider ([#9329](https://github.com/helix-editor/helix/pull/9329))\n- Koka ([#8727](https://github.com/helix-editor/helix/pull/8727))\n- PKGBUILD ([#9909](https://github.com/helix-editor/helix/pull/9909), [#9943](https://github.com/helix-editor/helix/pull/9943))\n- Ada ([#9908](https://github.com/helix-editor/helix/pull/9908))\n- Helm charts ([#9900](https://github.com/helix-editor/helix/pull/9900))\n- Ember.js templates ([#9902](https://github.com/helix-editor/helix/pull/9902))\n- Ohm ([#9991](https://github.com/helix-editor/helix/pull/9991))\n\nUpdated languages and queries:\n\n- Add HTML injection queries for Rust ([#8603](https://github.com/helix-editor/helix/pull/8603))\n- Switch to tree-sitter-ron for RON ([#8624](https://github.com/helix-editor/helix/pull/8624))\n- Update and improve comment highlighting ([#8564](https://github.com/helix-editor/helix/pull/8564), [#9253](https://github.com/helix-editor/helix/pull/9253), [#9800](https://github.com/helix-editor/helix/pull/9800), [#10014](https://github.com/helix-editor/helix/pull/10014))\n- Highlight type parameters in Rust ([#8660](https://github.com/helix-editor/helix/pull/8660))\n- Change KDL tree-sitter parsers ([#8652](https://github.com/helix-editor/helix/pull/8652))\n- Update tree-sitter-markdown ([#8721](https://github.com/helix-editor/helix/pull/8721), [#10039](https://github.com/helix-editor/helix/pull/10039))\n- Update tree-sitter-purescript ([#8712](https://github.com/helix-editor/helix/pull/8712))\n- Add type parameter highlighting to TypeScript, Go, Haskell, OCaml and Kotlin ([#8718](https://github.com/helix-editor/helix/pull/8718))\n- Add indentation queries for Scheme and lisps using tree-sitter-scheme ([#8720](https://github.com/helix-editor/helix/pull/8720))\n- Recognize `meson_options.txt` as Meson ([#8794](https://github.com/helix-editor/helix/pull/8794))\n- Add language server configuration for Nushell ([#8878](https://github.com/helix-editor/helix/pull/8878))\n- Recognize `musicxml` as XML ([#8935](https://github.com/helix-editor/helix/pull/8935))\n- Update tree-sitter-rescript ([#8962](https://github.com/helix-editor/helix/pull/8962))\n- Update tree-sitter-python ([#8976](https://github.com/helix-editor/helix/pull/8976))\n- Recognize `.envrc.local` and `.envrc.private` as env ([#8988](https://github.com/helix-editor/helix/pull/8988))\n- Update tree-sitter-gleam ([#9003](https://github.com/helix-editor/helix/pull/9003), [9ceeea5](https://github.com/helix-editor/helix/commit/9ceeea5))\n- Update tree-sitter-d ([#9021](https://github.com/helix-editor/helix/pull/9021))\n- Fix R-markdown language name for LSP detection ([#9012](https://github.com/helix-editor/helix/pull/9012))\n- Add haskell-language-server LSP configuration ([#9111](https://github.com/helix-editor/helix/pull/9111))\n- Recognize `glif` as XML ([#9130](https://github.com/helix-editor/helix/pull/9130))\n- Recognize `.prettierrc` as JSON ([#9214](https://github.com/helix-editor/helix/pull/9214))\n- Add auto-pairs configuration for scheme ([#9232](https://github.com/helix-editor/helix/pull/9232))\n- Add textobject queries for Scala ([#9191](https://github.com/helix-editor/helix/pull/9191))\n- Add textobject queries for Protobuf ([#9184](https://github.com/helix-editor/helix/pull/9184))\n- Update tree-sitter-wren ([#8544](https://github.com/helix-editor/helix/pull/8544))\n- Add `spago.yaml` as an LSP root for PureScript ([#9362](https://github.com/helix-editor/helix/pull/9362))\n- Improve highlight and indent queries for Bash, Make and CSS ([#9393](https://github.com/helix-editor/helix/pull/9393))\n- Update tree-sitter-scala ([#9348](https://github.com/helix-editor/helix/pull/9348), [#9340](https://github.com/helix-editor/helix/pull/9340), [#9475](https://github.com/helix-editor/helix/pull/9475))\n- Recognize `.bash_history` as Bash ([#9401](https://github.com/helix-editor/helix/pull/9401))\n- Recognize Helix ignore files as ignore ([#9447](https://github.com/helix-editor/helix/pull/9447))\n- Inject SQL into Scala SQL strings ([#9428](https://github.com/helix-editor/helix/pull/9428))\n- Update gdscript textobjects ([#9288](https://github.com/helix-editor/helix/pull/9288))\n- Update Go queries ([#9510](https://github.com/helix-editor/helix/pull/9510), [#9525](https://github.com/helix-editor/helix/pull/9525))\n- Update tree-sitter-nushell ([#9502](https://github.com/helix-editor/helix/pull/9502))\n- Update tree-sitter-unison, add indent queries ([#9505](https://github.com/helix-editor/helix/pull/9505))\n- Update tree-sitter-slint ([#9551](https://github.com/helix-editor/helix/pull/9551), [#9698](https://github.com/helix-editor/helix/pull/9698))\n- Update tree-sitter-swift ([#9586](https://github.com/helix-editor/helix/pull/9586))\n- Add `fish_indent` as formatter for fish ([78ed3ad](https://github.com/helix-editor/helix/commit/78ed3ad))\n- Recognize `zon` as Zig ([#9582](https://github.com/helix-editor/helix/pull/9582))\n- Add a formatter for Odin ([#9537](https://github.com/helix-editor/helix/pull/9537))\n- Update tree-sitter-erlang ([#9627](https://github.com/helix-editor/helix/pull/9627), [fdcd461](https://github.com/helix-editor/helix/commit/fdcd461))\n- Capture Rust fields as argument textobjects ([#9637](https://github.com/helix-editor/helix/pull/9637))\n- Improve Dart textobjects ([#9644](https://github.com/helix-editor/helix/pull/9644))\n- Recognize `tmux.conf` as a bash file-type ([#9653](https://github.com/helix-editor/helix/pull/9653))\n- Add textobjects queries for Nix ([#9659](https://github.com/helix-editor/helix/pull/9659))\n- Add textobjects queries for HCL ([#9658](https://github.com/helix-editor/helix/pull/9658))\n- Recognize osm and osc extensions as XML ([#9697](https://github.com/helix-editor/helix/pull/9697))\n- Update tree-sitter-sql ([#9634](https://github.com/helix-editor/helix/pull/9634))\n- Recognize pde Processing files as Java ([#9741](https://github.com/helix-editor/helix/pull/9741))\n- Update tree-sitter-lua ([#9727](https://github.com/helix-editor/helix/pull/9727))\n- Switch tree-sitter-nim parsers ([#9722](https://github.com/helix-editor/helix/pull/9722))\n- Recognize GTK builder ui files as XML ([#9754](https://github.com/helix-editor/helix/pull/9754))\n- Add configuration for markdown-oxide language server ([#9758](https://github.com/helix-editor/helix/pull/9758))\n- Add a shebang for elvish ([#9779](https://github.com/helix-editor/helix/pull/9779))\n- Fix precedence of Svelte TypeScript injection ([#9777](https://github.com/helix-editor/helix/pull/9777))\n- Recognize common Dockerfile file types ([#9772](https://github.com/helix-editor/helix/pull/9772))\n- Recognize NUON files as Nu ([#9839](https://github.com/helix-editor/helix/pull/9839))\n- Add textobjects for Java native functions and constructors ([#9806](https://github.com/helix-editor/helix/pull/9806))\n- Fix \"braket\" typo in JSX highlights ([#9910](https://github.com/helix-editor/helix/pull/9910))\n- Update tree-sitter-hurl ([#9775](https://github.com/helix-editor/helix/pull/9775))\n- Add textobjects queries for Vala ([#8541](https://github.com/helix-editor/helix/pull/8541))\n- Update tree-sitter-git-config ([9610254](https://github.com/helix-editor/helix/commit/9610254))\n- Recognize 'mmd' as Mermaid ([459eb9a](https://github.com/helix-editor/helix/commit/459eb9a))\n- Highlight Rust extern crate aliases ([c099dde](https://github.com/helix-editor/helix/commit/c099dde))\n- Improve parameter highlighting in C++ ([f5d95de](https://github.com/helix-editor/helix/commit/f5d95de))\n- Recognize 'rclone.conf' as INI ([#9959](https://github.com/helix-editor/helix/pull/9959))\n- Add injections for GraphQL and ERB in Ruby heredocs ([#10036](https://github.com/helix-editor/helix/pull/10036))\n- Add `main.odin` to Odin LSP roots ([#9968](https://github.com/helix-editor/helix/pull/9968))\n\nPackaging:\n\n- Allow user overlays in Nix grammars build ([#8749](https://github.com/helix-editor/helix/pull/8749))\n- Set Cargo feature resolver to v2 ([#8917](https://github.com/helix-editor/helix/pull/8917))\n- Use workspace inheritance for common Cargo metadata ([#8925](https://github.com/helix-editor/helix/pull/8925))\n- Remove sourcehut-based tree-sitter grammars from default build ([#9316](https://github.com/helix-editor/helix/pull/9316), [#9326](https://github.com/helix-editor/helix/pull/9326))\n- Add icon to Windows executable ([#9104](https://github.com/helix-editor/helix/pull/9104))\n\n# 23.10 (2023-10-24)\n\nA big shout out to all the contributors! We had 118 contributors in this release.\n\nBreaking changes:\n\n- Support multiple language servers per language ([#2507](https://github.com/helix-editor/helix/pull/2507))\n    - This is a breaking change to language configuration\n\nFeatures:\n\n- Support multiple language servers per language ([#2507](https://github.com/helix-editor/helix/pull/2507), [#7082](https://github.com/helix-editor/helix/pull/7082), [#7286](https://github.com/helix-editor/helix/pull/7286), [#8374](https://github.com/helix-editor/helix/pull/8374))\n- Add a statusline element for the selected register ([#7222](https://github.com/helix-editor/helix/pull/7222))\n- Add `%`, `#`, `.`, `*` and `+` special registers ([#6985](https://github.com/helix-editor/helix/pull/6985))\n- Add initial support for LSP DidChangeWatchedFiles notifications ([#7665](https://github.com/helix-editor/helix/pull/7665))\n- Search buffer contents in `global_search` ([#5652](https://github.com/helix-editor/helix/pull/5652))\n- Add a \"smart tab\" command that intelligently jumps the cursor on tab ([#4443](https://github.com/helix-editor/helix/pull/4443))\n- Add a statusline element for whether a file is read-only ([#7222](https://github.com/helix-editor/helix/pull/7222), [#7875](https://github.com/helix-editor/helix/pull/7875))\n- Syntax highlight regex prompts ([#7738](https://github.com/helix-editor/helix/pull/7738))\n- Allow defining alignment in indent queries ([#5355](https://github.com/helix-editor/helix/pull/5355))\n- Show visual feedback in `surround_replace` ([#7588](https://github.com/helix-editor/helix/pull/7588))\n- Switch to Nucleo for fuzzy matching ([#7814](https://github.com/helix-editor/helix/pull/7814), [#8148](https://github.com/helix-editor/helix/pull/8148), [#8192](https://github.com/helix-editor/helix/pull/8192), [#8194](https://github.com/helix-editor/helix/pull/8194))\n- Insert a trailing newline on write ([#8157](https://github.com/helix-editor/helix/pull/8157))\n- Add a `-w`/`--working-dir` CLI flag for specifying a working directory on startup ([#8223](https://github.com/helix-editor/helix/pull/8223), [#8498](https://github.com/helix-editor/helix/pull/8498), [#8520](https://github.com/helix-editor/helix/pull/8520))\n- Accept a `+N` CLI argument to set the first file's line number ([#8521](https://github.com/helix-editor/helix/pull/8521))\n- Accept Helix-specific ignore files in `.helix/ignore` and `~/.config/helix/ignore` ([#8099](https://github.com/helix-editor/helix/pull/8099))\n\nCommands:\n\n- `merge_selections` (`A-minus`) - merge all selections into one selection that covers all ranges ([#7053](https://github.com/helix-editor/helix/pull/7053))\n- `move_prev_long_word_end` and `extend_prev_long_word_end` - move/extend to the end of the previous WORD ([#6905](https://github.com/helix-editor/helix/pull/6905))\n- `reverse_selection_contents` - swaps the values of each selection so they are reversed ([#7329](https://github.com/helix-editor/helix/pull/7329))\n- Add `:rl` and `:rla` aliases for `:reload` and `:reload-all` ([#7158](https://github.com/helix-editor/helix/pull/7158))\n- `yank_joined` - join the selections and yank to the selected register ([#7195](https://github.com/helix-editor/helix/pull/7195))\n- `:write-all!` (`:wa!`) - forcibly write all buffers to disk and create any necessary subdirectories ([#7577](https://github.com/helix-editor/helix/pull/7577))\n- `:redraw` - clear re-render the UI ([#6949](https://github.com/helix-editor/helix/pull/6949))\n- `:tree-sitter-highlight-name` - show the theme scope name of the highlight under the cursor ([#8170](https://github.com/helix-editor/helix/pull/8170))\n\nUsability improvements:\n\n- Allow cycling option values at runtime ([#4411](https://github.com/helix-editor/helix/pull/4411), [#7240](https://github.com/helix-editor/helix/pull/7240), [#7877](https://github.com/helix-editor/helix/pull/7877))\n- Exit gracefully on termination signals ([#7236](https://github.com/helix-editor/helix/pull/7236))\n- Add plaintext matching fallback to tree-sitter pair matching ([#4288](https://github.com/helix-editor/helix/pull/4288))\n- Persist register selection in pending keymaps ([0e08349](https://github.com/helix-editor/helix/commit/0e08349))\n- Propagate the count and register to command palette commands ([b394997](https://github.com/helix-editor/helix/commit/b394997))\n- Auto indent on `insert_at_line_start` ([#5837](https://github.com/helix-editor/helix/pull/5837))\n- Add a config option to control whether LSP completions are automatically inserted on preview ([#7189](https://github.com/helix-editor/helix/pull/7189))\n- Add a config option for default line endings ([#5621](https://github.com/helix-editor/helix/pull/5621), [#7357](https://github.com/helix-editor/helix/pull/7357))\n- Allow ANSI colors in themes ([#5119](https://github.com/helix-editor/helix/pull/5119))\n- Match pairs that don't form a standalone tree-sitter node ([#7242](https://github.com/helix-editor/helix/pull/7242))\n- Allow indent sizes of up to 16 columns ([#7429](https://github.com/helix-editor/helix/pull/7429))\n- Improve performance of mapping positions through changes ([#7408](https://github.com/helix-editor/helix/pull/7408), [8d39a81](https://github.com/helix-editor/helix/commit/8d39a81), [#7471](https://github.com/helix-editor/helix/pull/7471))\n- Mark buffers created from stdin as modified ([#7431](https://github.com/helix-editor/helix/pull/7431))\n- Forcibly shut down uninitialized language servers ([#7449](https://github.com/helix-editor/helix/pull/7449))\n- Add filename completer for shell prompts ([#7569](https://github.com/helix-editor/helix/pull/7569))\n- Allow binding F13-F24 ([#7672](https://github.com/helix-editor/helix/pull/7672))\n- Resolve LSP code actions ([#7677](https://github.com/helix-editor/helix/pull/7677), [#8421](https://github.com/helix-editor/helix/pull/8421))\n- Save an undo checkpoint before accepting completions ([#7747](https://github.com/helix-editor/helix/pull/7747))\n- Include gitignored files in debugger completions ([#7936](https://github.com/helix-editor/helix/pull/7936))\n- Make editor remember the last search register ([#5244](https://github.com/helix-editor/helix/pull/5244))\n- Open directories with `goto_file` ([#7909](https://github.com/helix-editor/helix/pull/7909))\n- Use relative path to open buffer in `goto_file` (`gf`) ([#7965](https://github.com/helix-editor/helix/pull/7965))\n- Support `default` color in themes ([#8083](https://github.com/helix-editor/helix/pull/8083), [#8114](https://github.com/helix-editor/helix/pull/8114))\n- Toggle between relative and absolute line numbers when the terminal loses focus ([#7955](https://github.com/helix-editor/helix/pull/7955))\n- Lower default idle-timeout to 250ms ([060e73a](https://github.com/helix-editor/helix/commit/060e73a))\n- Allow theming diff gutters separately from other diff colors ([#8343](https://github.com/helix-editor/helix/pull/8343))\n- Style bold/italic/strikethrough in markdown doc popups ([#8385](https://github.com/helix-editor/helix/pull/8385))\n- Maintain the cursor position and view when splitting with `:hsplit`/`:vsplit` ([#8109](https://github.com/helix-editor/helix/pull/8109))\n- Accept `-` in macros outside of `<`/`>` ([#8475](https://github.com/helix-editor/helix/pull/8475))\n- Show all language servers for each language in `--health` ([#7315](https://github.com/helix-editor/helix/pull/7315))\n- Don't break on hyphens in `:reflow` ([#8569](https://github.com/helix-editor/helix/pull/8569))\n\nFixes:\n\n- Update diagnostics correctly on language server exit ([#7111](https://github.com/helix-editor/helix/pull/7111))\n- Fix off-by-one in `select_references_to_symbol_under_cursor` ([#7132](https://github.com/helix-editor/helix/pull/7132))\n- Extend selection with repeat-last-motion only if the original motion extended the selection ([#7159](https://github.com/helix-editor/helix/pull/7159))\n- Fix undefined behavior in the diff gutter ([#7227](https://github.com/helix-editor/helix/pull/7227))\n- Check that tab width is non-zero ([#7178](https://github.com/helix-editor/helix/pull/7178))\n- Fix styles being overwritten in table rows with multiple cells ([#7281](https://github.com/helix-editor/helix/pull/7281))\n- Add file for `--log` CLI arg in help text ([#7307](https://github.com/helix-editor/helix/pull/7307))\n- Fix underflow when repeating a completion that has a negative shift position ([#7322](https://github.com/helix-editor/helix/pull/7322))\n- Prefer longer matches in `select_next_sibling` and `select_prev_sibling` ([#7332](https://github.com/helix-editor/helix/pull/7332))\n- Preview scratch buffers in the jumplist picker ([#7331](https://github.com/helix-editor/helix/pull/7331))\n- Fix chunking by bytes in tree-sitter parsing ([#7417](https://github.com/helix-editor/helix/pull/7417))\n- Discard LSP publishDiagnostic from uninitialized servers ([#7467](https://github.com/helix-editor/helix/pull/7467))\n- Use negotiated position encoding for LSP workspace edits ([#7469](https://github.com/helix-editor/helix/pull/7469))\n- Fix error message for unknown gutter types in config ([#7534](https://github.com/helix-editor/helix/pull/7534))\n- Fix `:log-open` when `--log` CLI arg is specified ([#7573](https://github.com/helix-editor/helix/pull/7573), [#7585](https://github.com/helix-editor/helix/pull/7585))\n- Fix debouncing of LSP messages to fix the last message sticking around ([#7538](https://github.com/helix-editor/helix/pull/7538), [#8023](https://github.com/helix-editor/helix/pull/8023))\n- Fix crash when the current working directory is deleted ([#7185](https://github.com/helix-editor/helix/pull/7185))\n- Fix piping to Helix on macOS ([#5468](https://github.com/helix-editor/helix/pull/5468))\n- Fix crash when parsing overlapping injections ([#7621](https://github.com/helix-editor/helix/pull/7621))\n- Clear the statusline when the prompt is visible ([#7646](https://github.com/helix-editor/helix/pull/7646))\n- Fix range formatting error message typo ([#7823](https://github.com/helix-editor/helix/pull/7823))\n- Skip rendering gutters when gutter width exceeds view width ([#7821](https://github.com/helix-editor/helix/pull/7821))\n- Center the picker preview using visual lines ([#7837](https://github.com/helix-editor/helix/pull/7837))\n- Align view correctly for background buffers opened with `A-ret` ([#7691](https://github.com/helix-editor/helix/pull/7691))\n- Fix cursor resetting to block when quitting via a keybind ([#7931](https://github.com/helix-editor/helix/pull/7931))\n- Remove path completions for the `:new` command ([#8010](https://github.com/helix-editor/helix/pull/8010))\n- Use binary path resolved by `which` for formatter commands ([#8064](https://github.com/helix-editor/helix/pull/8064))\n- Handle crossterm's `hidden` modifier ([#8120](https://github.com/helix-editor/helix/pull/8120))\n- Clear completion when switching between windows with the mouse ([#8118](https://github.com/helix-editor/helix/pull/8118))\n- Eagerly remove the last picker (`<space>'`) when the picker has many items ([#8127](https://github.com/helix-editor/helix/pull/8127))\n- Fix find commands for buffers with non-LF line-endings ([#8111](https://github.com/helix-editor/helix/pull/8111))\n- Detect the tmux clipboard provider on macOS ([#8182](https://github.com/helix-editor/helix/pull/8182))\n- Fix syntax highlighting in dynamic picker preview pane ([#8206](https://github.com/helix-editor/helix/pull/8206))\n- Recognize HTML code tags with attributes as code in markdown previews ([#8397](https://github.com/helix-editor/helix/pull/8397))\n- Fix multicursor snippet placeholder directions ([#8423](https://github.com/helix-editor/helix/pull/8423))\n- Only show diagnostic highlights when diagnostics are enabled for a language server ([#8551](https://github.com/helix-editor/helix/pull/8551))\n\nThemes:\n\n- Improve the selection color in `ferra` ([#7138](https://github.com/helix-editor/helix/pull/7138))\n- Add `variable.other.member` theming to `spacebones_light` ([#7125](https://github.com/helix-editor/helix/pull/7125))\n- Update `autumn` and theme the soft-wrap indicator ([#7229](https://github.com/helix-editor/helix/pull/7229))\n- Add `gruvbox_dark_soft` ([#7139](https://github.com/helix-editor/helix/pull/7139))\n- Add `merionette` ([#7186](https://github.com/helix-editor/helix/pull/7186))\n- Add `zed_onedark` and `zed_onelight` ([#7250](https://github.com/helix-editor/helix/pull/7250))\n- Use light-gray for `onedarker` inlay hint theming ([#7433](https://github.com/helix-editor/helix/pull/7433))\n- Update the Nord theme to follow the style guidelines ([#7490](https://github.com/helix-editor/helix/pull/7490))\n- Tune `dark_plus` inlay hint colors ([#7611](https://github.com/helix-editor/helix/pull/7611))\n- Add `naysayer` ([#7570](https://github.com/helix-editor/helix/pull/7570))\n- Add `kaolin-dark`, `kaolin-light` and `kaolin-valley-dark` ([#7151](https://github.com/helix-editor/helix/pull/7151))\n- Fix selection highlighting in gruvbox variants ([#7717](https://github.com/helix-editor/helix/pull/7717))\n- Add soft-wrap indicator to `gruvbox` ([#7736](https://github.com/helix-editor/helix/pull/7736))\n- Add missing palette definitions in `everforest_dark` ([#7739](https://github.com/helix-editor/helix/pull/7739))\n- Increase diagnostics clarity in `pop-dark` ([#7702](https://github.com/helix-editor/helix/pull/7702))\n- Add `vim_dark_high_contrast` ([#7785](https://github.com/helix-editor/helix/pull/7785))\n- Add `new_moon` ([#7834](https://github.com/helix-editor/helix/pull/7834))\n- Add `yellowed` ([#7849](https://github.com/helix-editor/helix/pull/7849))\n- Improve comment readability for `autumn` ([#7939](https://github.com/helix-editor/helix/pull/7939))\n- Distinguish active bufferline buffer in `monokai` ([#7983](https://github.com/helix-editor/helix/pull/7983))\n- Update ruler colors in `nord` ([#7995](https://github.com/helix-editor/helix/pull/7995))\n- Update Catppuccin themes ([#8102](https://github.com/helix-editor/helix/pull/8102))\n- Add text focus scope and diagnostics undercurls for `nord` ([#8165](https://github.com/helix-editor/helix/pull/8165))\n- Add material theme collection ([#8211](https://github.com/helix-editor/helix/pull/8211))\n- Improve indent line color in `dracula` ([#8266](https://github.com/helix-editor/helix/pull/8266))\n- Clean up and refactor `papercolor` to use inheritance ([#8276](https://github.com/helix-editor/helix/pull/8276))\n- Fix `zenburn` inlay hint color ([#8278](https://github.com/helix-editor/helix/pull/8278)a)\n- Fix picker crash when previewing an invalid range ([e9d0bd7](https://github.com/helix-editor/helix/commit/e9d0bd7))\n- Correctly center items in the picker preview ([13d4463](https://github.com/helix-editor/helix/commit/13d4463))\n- Add `cyan_light` ([#8293](https://github.com/helix-editor/helix/pull/8293), [#8587](https://github.com/helix-editor/helix/pull/8587))\n- Theme HTML tags in `onedark` ([#8409](https://github.com/helix-editor/helix/pull/8409))\n- Refine `darcula` and `darcula-solid` themes ([#8412](https://github.com/helix-editor/helix/pull/8412))\n- Improve `nord` highlights ([#8414](https://github.com/helix-editor/helix/pull/8414))\n- Add `nord-night` ([#8549](https://github.com/helix-editor/helix/pull/8549))\n\nNew languages:\n\n- Blueprint ([#7213](https://github.com/helix-editor/helix/pull/7213), [#8161](https://github.com/helix-editor/helix/pull/8161))\n- Forth ([#7256](https://github.com/helix-editor/helix/pull/7256), [#7334](https://github.com/helix-editor/helix/pull/7334))\n- t32 ([#7140](https://github.com/helix-editor/helix/pull/7140), [#7811](https://github.com/helix-editor/helix/pull/7811))\n- WebC ([#7290](https://github.com/helix-editor/helix/pull/7290))\n- Persistent DSL for Haskell ([#7261](https://github.com/helix-editor/helix/pull/7261))\n- F# ([#7619](https://github.com/helix-editor/helix/pull/7619), [#8024](https://github.com/helix-editor/helix/pull/8024))\n- Wren ([#7765](https://github.com/helix-editor/helix/pull/7765), [#7819](https://github.com/helix-editor/helix/pull/7819))\n- Unison ([#7724](https://github.com/helix-editor/helix/pull/7724))\n- Todo.txt ([#7835](https://github.com/helix-editor/helix/pull/7835))\n- Jinja and Handlebars ([#7233](https://github.com/helix-editor/helix/pull/7233))\n- Pod ([#7907](https://github.com/helix-editor/helix/pull/7907))\n- Strace ([#7928](https://github.com/helix-editor/helix/pull/7928))\n- Gemini ([#8070](https://github.com/helix-editor/helix/pull/8070))\n- GNU Assembler (GAS) ([#8291](https://github.com/helix-editor/helix/pull/8291))\n- JSON5 ([#8473](https://github.com/helix-editor/helix/pull/8473))\n- TEMPL ([#8540](https://github.com/helix-editor/helix/pull/8540))\n\nUpdated languages and queries:\n\n- Add one to the ruler numbers for git-commit ([#7072](https://github.com/helix-editor/helix/pull/7072))\n- Recognize XAML files as XML ([#7083](https://github.com/helix-editor/helix/pull/7083))\n- Recognize `Cargo.lock` as TOML ([#7095](https://github.com/helix-editor/helix/pull/7095))\n- Use Rust grammar for Cairo ([c6d1430](https://github.com/helix-editor/helix/commit/c6d1430))\n- Update tree-sitter-nickel ([#7059](https://github.com/helix-editor/helix/pull/7059), [#7551](https://github.com/helix-editor/helix/pull/7551))\n- Tune auto-pair characters for Nickel ([#7059](https://github.com/helix-editor/helix/pull/7059))\n- Recognize `Vagrantfile` as Ruby ([#7112](https://github.com/helix-editor/helix/pull/7112))\n- Recognize hidden justfiles as Just ([#7088](https://github.com/helix-editor/helix/pull/7088))\n- Update Java and TypeScript highlight queries ([#7145](https://github.com/helix-editor/helix/pull/7145))\n- Recognize `.zimrc` as Bash ([#7146](https://github.com/helix-editor/helix/pull/7146))\n- Recognize `.gir` as XML ([#7152](https://github.com/helix-editor/helix/pull/7152))\n- Update tree-sitter-scala ([#7147](https://github.com/helix-editor/helix/pull/7147))\n- Recognize make file-type as Makefile ([#7212](https://github.com/helix-editor/helix/pull/7212))\n- Update tree-sitter-verilog ([#7262](https://github.com/helix-editor/helix/pull/7262))\n- Update tree-sitter-cpp ([#7285](https://github.com/helix-editor/helix/pull/7285))\n- Support core mode for delve debugger ([#7300](https://github.com/helix-editor/helix/pull/7300))\n- Add Fortran comment injections ([#7305](https://github.com/helix-editor/helix/pull/7305))\n- Switch Vue language server to `vue-language-server` ([#7312](https://github.com/helix-editor/helix/pull/7312))\n- Update tree-sitter-sql ([#7387](https://github.com/helix-editor/helix/pull/7387), [#8464](https://github.com/helix-editor/helix/pull/8464))\n- Replace the MATLAB tree-sitter grammar ([#7388](https://github.com/helix-editor/helix/pull/7388), [#7442](https://github.com/helix-editor/helix/pull/7442), [#7491](https://github.com/helix-editor/helix/pull/7491), [#7493](https://github.com/helix-editor/helix/pull/7493), [#7511](https://github.com/helix-editor/helix/pull/7511), [#7532](https://github.com/helix-editor/helix/pull/7532), [#8040](https://github.com/helix-editor/helix/pull/8040))\n- Highlight TOML table headers ([#7441](https://github.com/helix-editor/helix/pull/7441))\n- Recognize `cppm` file-type as C++ ([#7492](https://github.com/helix-editor/helix/pull/7492))\n- Refactor ecma language queries into private and public queries ([#7207](https://github.com/helix-editor/helix/pull/7207))\n- Update tree-sitter-dart ([#7576](https://github.com/helix-editor/helix/pull/7576))\n- Add shebang for nushell files ([#7606](https://github.com/helix-editor/helix/pull/7606))\n- Recognize systemd files as INI ([#7592](https://github.com/helix-editor/helix/pull/7592))\n- Update TypeScript, TSX and Svelte grammars ([#6874](https://github.com/helix-editor/helix/pull/6874))\n- Enable inlay hints in the Svelte language server ([#7622](https://github.com/helix-editor/helix/pull/7622))\n- Recognize `Brewfile`s as Ruby ([#7629](https://github.com/helix-editor/helix/pull/7629))\n- Add more file-types for R ([#7633](https://github.com/helix-editor/helix/pull/7633))\n- Switch tree-sitter-perl to official upstream parser ([#7644](https://github.com/helix-editor/helix/pull/7644), [#7947](https://github.com/helix-editor/helix/pull/7947))\n- Fix predicate typo in comment highlights ([#7732](https://github.com/helix-editor/helix/pull/7732))\n- Update tree-sitter-prql ([#7771](https://github.com/helix-editor/helix/pull/7771))\n- Recognize `.gitf` as JSON ([#7781](https://github.com/helix-editor/helix/pull/7781))\n- Switch V language server to `v-analyzer` ([#7760](https://github.com/helix-editor/helix/pull/7760))\n- Add protobuf language servers ([#7796](https://github.com/helix-editor/helix/pull/7796))\n- Update tree-sitter-zig ([#7803](https://github.com/helix-editor/helix/pull/7803))\n- Update tree-sitter-hare ([#7784](https://github.com/helix-editor/helix/pull/7784))\n- Add Java indent queries ([#7844](https://github.com/helix-editor/helix/pull/7844))\n- Update tree-sitter-scheme ([979933b](https://github.com/helix-editor/helix/commit/979933b))\n- Recognize `scm` as Scheme instead of TSQ ([5707151](https://github.com/helix-editor/helix/commit/5707151))\n- Update tree-sitter-git-commit ([#7831](https://github.com/helix-editor/helix/pull/7831))\n- Update JavaScript, TypeScript and TSX grammars ([#7852](https://github.com/helix-editor/helix/pull/7852))\n- Update tree-sitter-nu ([#7873](https://github.com/helix-editor/helix/pull/7873))\n- Fix YAML indentation ([#6768](https://github.com/helix-editor/helix/pull/6768))\n- Add `csharp-ls`, Pyright, Pylyzer and add roots for Python ([#7897](https://github.com/helix-editor/helix/pull/7897), [#8032](https://github.com/helix-editor/helix/pull/8032))\n- Update tree-sitter-slint ([#7893](https://github.com/helix-editor/helix/pull/7893))\n- Recognize more ZSH file-types as Bash ([#7930](https://github.com/helix-editor/helix/pull/7930))\n- Recognize `star` extension as Starlark ([#7922](https://github.com/helix-editor/helix/pull/7922))\n- Fix inline HTML tag highlighting in markdown ([#7960](https://github.com/helix-editor/helix/pull/7960))\n- Update tree-sitter-robot ([#7970](https://github.com/helix-editor/helix/pull/7970))\n- Highlight Dart 3 `sealed` and `base` keywords ([#7974](https://github.com/helix-editor/helix/pull/7974))\n- Add configuration for `ltex-ls` to the default `languages.toml` ([#7838](https://github.com/helix-editor/helix/pull/7838))\n- Update tree-sitter-strace ([#8087](https://github.com/helix-editor/helix/pull/8087))\n- Update tree-sitter-gleam, enable auto-format ([#8085](https://github.com/helix-editor/helix/pull/8085))\n- Update tree-sitter-esdl ([#8222](https://github.com/helix-editor/helix/pull/8222))\n- Expand ignore file-types ([#8220](https://github.com/helix-editor/helix/pull/8220))\n- Recognize feed related formats as XML ([#8232](https://github.com/helix-editor/helix/pull/8232))\n- Improve YAML injections ([#8217](https://github.com/helix-editor/helix/pull/8217))\n- Add shebangs for TypeScript, Julia, Java and OCaml ([95e994a](https://github.com/helix-editor/helix/commit/95e994a))\n- Highlight abbreviations in Scheme ([ef23847](https://github.com/helix-editor/helix/commit/ef23847))\n- Remove backtic auto-pair in OCaml ([#8260](https://github.com/helix-editor/helix/pull/8260))\n- Recognize `flake.lock` as JSON ([#8304](https://github.com/helix-editor/helix/pull/8304))\n- Add Python test script injection for Nix ([b4494e1](https://github.com/helix-editor/helix/commit/b4494e1))\n- Fix Nix comment injection precedence ([37e48f4](https://github.com/helix-editor/helix/commit/37e48f4))\n- Recognize editorconfig files as INI ([#8308](https://github.com/helix-editor/helix/pull/8308))\n- Recognize `.babelrc` as JSON ([#8309](https://github.com/helix-editor/helix/pull/8309))\n- Switch Purescript to its own tree-sitter parser ([#8306](https://github.com/helix-editor/helix/pull/8306), [#8338](https://github.com/helix-editor/helix/pull/8338), [#8527](https://github.com/helix-editor/helix/pull/8527))\n- Update Unison highlights ([#8315](https://github.com/helix-editor/helix/pull/8315))\n- Recognize `.webmanifest` as JSON ([#8342](https://github.com/helix-editor/helix/pull/8342))\n- Recognize polkit policy files as XML ([#8369](https://github.com/helix-editor/helix/pull/8369))\n- Recognize polkit rules files as JavaScript ([#8370](https://github.com/helix-editor/helix/pull/8370))\n- Update Go highlight queries ([#8399](https://github.com/helix-editor/helix/pull/8399))\n- Add shebangs for Makefiles ([#8410](https://github.com/helix-editor/helix/pull/8410))\n- Add file-type associations from VSCode ([#8388](https://github.com/helix-editor/helix/pull/8388))\n- Add validation to JSON/CSS language server configs ([#8433](https://github.com/helix-editor/helix/pull/8433))\n- Add a configuration for the tailwind language server ([#8442](https://github.com/helix-editor/helix/pull/8442))\n- Add a configuration for the ansible language server ([#7973](https://github.com/helix-editor/helix/pull/7973))\n- Add a configuration for the GraphQL language server ([#8492](https://github.com/helix-editor/helix/pull/8492))\n- Indent while statements in Bash ([#8528](https://github.com/helix-editor/helix/pull/8528))\n- Update tree-sitter-haskell and queries ([#8558](https://github.com/helix-editor/helix/pull/8558))\n\nPackaging:\n\n- Add an overlay to the Nix flake ([#7078](https://github.com/helix-editor/helix/pull/7078))\n- Check for `git` before fetching or building grammars ([#7320](https://github.com/helix-editor/helix/pull/7320))\n- Refactor Nix flake to use Crane ([#7763](https://github.com/helix-editor/helix/pull/7763))\n- Remove the aarch64 appimage from the release CI ([#7832](https://github.com/helix-editor/helix/pull/7832))\n- Add desktop and icon files to Nix flake output ([#7979](https://github.com/helix-editor/helix/pull/7979))\n- Build flake packages with the latest stable Rust ([#8133](https://github.com/helix-editor/helix/pull/8133))\n\n# 23.05 (2023-05-18)\n\n23.05 is a smaller release focusing on fixes. There were 88 contributors in this release. Thank you all!\n\nFeatures:\n\n- Add a config option to exclude declaration from LSP references request ([#6886](https://github.com/helix-editor/helix/pull/6886))\n- Enable injecting languages based on their file extension and shebang ([#3970](https://github.com/helix-editor/helix/pull/3970))\n- Sort the buffer picker by most recent access ([#2980](https://github.com/helix-editor/helix/pull/2980))\n- Perform syntax highlighting in the picker asynchronously ([#7028](https://github.com/helix-editor/helix/pull/7028))\n\nCommands:\n\n- `:update` is now aliased as `:u` ([#6835](https://github.com/helix-editor/helix/pull/6835))\n- Add `extend_to_first_nonwhitespace` which acts the same as `goto_first_nonwhitespace` but always extends ([#6837](https://github.com/helix-editor/helix/pull/6837))\n- Add `:clear-register` for clearing the given register or all registers ([#5695](https://github.com/helix-editor/helix/pull/5695))\n- Add `:write-buffer-close` and `:write-buffer-close!` ([#6947](https://github.com/helix-editor/helix/pull/6947))\n\nFixes:\n\n- Normalize LSP workspace paths ([#6517](https://github.com/helix-editor/helix/pull/6517))\n- Robustly handle invalid LSP ranges ([#6512](https://github.com/helix-editor/helix/pull/6512))\n- Fix line number display for LSP goto pickers ([#6559](https://github.com/helix-editor/helix/pull/6559))\n- Fix toggling of `soft-wrap.enable` option ([#6656](https://github.com/helix-editor/helix/pull/6656), [58e457a](https://github.com/helix-editor/helix/commit/58e457a), [#6742](https://github.com/helix-editor/helix/pull/6742))\n- Handle `workspace/configuration` requests from stopped language servers ([#6693](https://github.com/helix-editor/helix/pull/6693))\n- Fix possible crash from opening the jumplist picker ([#6672](https://github.com/helix-editor/helix/pull/6672))\n- Fix theme preview returning to current theme on line and word deletions ([#6694](https://github.com/helix-editor/helix/pull/6694))\n- Re-run crate build scripts on changes to revision and grammar repositories ([#6743](https://github.com/helix-editor/helix/pull/6743))\n- Fix crash on opening from suspended state ([#6764](https://github.com/helix-editor/helix/pull/6764))\n- Fix unwrap bug in DAP ([#6786](https://github.com/helix-editor/helix/pull/6786))\n- Always build tree-sitter parsers with C++14 and C11 ([#6792](https://github.com/helix-editor/helix/pull/6792), [#6834](https://github.com/helix-editor/helix/pull/6834), [#6845](https://github.com/helix-editor/helix/pull/6845))\n- Exit with a non-zero statuscode when tree-sitter parser builds fail ([#6795](https://github.com/helix-editor/helix/pull/6795))\n- Flip symbol range in LSP goto commands ([#6794](https://github.com/helix-editor/helix/pull/6794))\n- Fix runtime toggling of the `mouse` option ([#6675](https://github.com/helix-editor/helix/pull/6675))\n- Fix panic in inlay hint computation when view anchor is out of bounds ([#6883](https://github.com/helix-editor/helix/pull/6883))\n- Significantly improve performance of git discovery on slow file systems ([#6890](https://github.com/helix-editor/helix/pull/6890))\n- Downgrade gix log level to info ([#6915](https://github.com/helix-editor/helix/pull/6915))\n- Conserve BOM and properly support saving UTF16 files ([#6497](https://github.com/helix-editor/helix/pull/6497))\n- Correctly handle completion re-request ([#6594](https://github.com/helix-editor/helix/pull/6594))\n- Fix offset encoding in LSP `didChange` notifications ([#6921](https://github.com/helix-editor/helix/pull/6921))\n- Change `gix` logging level to info ([#6915](https://github.com/helix-editor/helix/pull/6915))\n- Improve error message when writes fail because parent directories do not exist ([#7014](https://github.com/helix-editor/helix/pull/7014))\n- Replace DAP variables popup instead of pushing more popups ([#7034](https://github.com/helix-editor/helix/pull/7034))\n- Disable tree-sitter for files after parsing for 500ms ([#7028](https://github.com/helix-editor/helix/pull/7028))\n- Fix crash when deleting with multiple cursors ([#6024](https://github.com/helix-editor/helix/pull/6024))\n- Fix selection sliding when deleting forwards in append mode ([#6024](https://github.com/helix-editor/helix/pull/6024))\n- Fix completion on paths containing spaces ([#6779](https://github.com/helix-editor/helix/pull/6779))\n\nThemes:\n\n- Style inlay hints in `dracula` theme ([#6515](https://github.com/helix-editor/helix/pull/6515))\n- Style inlay hints in `onedark` theme ([#6503](https://github.com/helix-editor/helix/pull/6503))\n- Style inlay hints and the soft-wrap indicator in `varua` ([#6568](https://github.com/helix-editor/helix/pull/6568), [#6589](https://github.com/helix-editor/helix/pull/6589))\n- Style inlay hints in `emacs` theme ([#6569](https://github.com/helix-editor/helix/pull/6569))\n- Update `base16_transparent` and `dark_high_contrast` themes ([#6577](https://github.com/helix-editor/helix/pull/6577))\n- Style inlay hints for `mellow` and `rasmus` themes ([#6583](https://github.com/helix-editor/helix/pull/6583))\n- Dim pane divider for `base16_transparent` theme ([#6534](https://github.com/helix-editor/helix/pull/6534))\n- Style inlay hints in `zenburn` theme ([#6593](https://github.com/helix-editor/helix/pull/6593))\n- Style inlay hints in `boo_berry` theme ([#6625](https://github.com/helix-editor/helix/pull/6625))\n- Add `ferra` theme ([#6619](https://github.com/helix-editor/helix/pull/6619), [#6776](https://github.com/helix-editor/helix/pull/6776))\n- Style inlay hints in `nightfox` theme ([#6655](https://github.com/helix-editor/helix/pull/6655))\n- Fix `ayu` theme family markup code block background ([#6538](https://github.com/helix-editor/helix/pull/6538))\n- Improve whitespace and search match colors in `rose_pine` theme ([#6679](https://github.com/helix-editor/helix/pull/6679))\n- Highlight selected items in `base16_transparent` theme ([#6716](https://github.com/helix-editor/helix/pull/6716))\n- Adjust everforest to resemble original more closely ([#5866](https://github.com/helix-editor/helix/pull/5866))\n- Refactor `dracula` theme ([#6552](https://github.com/helix-editor/helix/pull/6552), [#6767](https://github.com/helix-editor/helix/pull/6767), [#6855](https://github.com/helix-editor/helix/pull/6855), [#6987](https://github.com/helix-editor/helix/pull/6987))\n- Style inlay hints in `darcula` theme ([#6732](https://github.com/helix-editor/helix/pull/6732))\n- Style inlay hints in `kanagawa` theme ([#6773](https://github.com/helix-editor/helix/pull/6773))\n- Improve `ayu_dark` theme ([#6622](https://github.com/helix-editor/helix/pull/6622))\n- Refactor `noctis` theme multiple cursor highlighting ([96720e7](https://github.com/helix-editor/helix/commit/96720e7))\n- Refactor `noctis` theme whitespace rendering and indent guides ([f2ccc03](https://github.com/helix-editor/helix/commit/f2ccc03))\n- Add `amberwood` theme ([#6924](https://github.com/helix-editor/helix/pull/6924))\n- Update `nightfox` theme ([#7061](https://github.com/helix-editor/helix/pull/7061))\n\nLanguage support:\n\n- R language server: use the `--no-echo` flag to silence output ([#6570](https://github.com/helix-editor/helix/pull/6570))\n- Recognize CUDA files as C++ ([#6521](https://github.com/helix-editor/helix/pull/6521))\n- Add support for Hurl ([#6450](https://github.com/helix-editor/helix/pull/6450))\n- Add textobject queries for Julia ([#6588](https://github.com/helix-editor/helix/pull/6588))\n- Update Ruby highlight queries ([#6587](https://github.com/helix-editor/helix/pull/6587))\n- Add xsd to XML file-types ([#6631](https://github.com/helix-editor/helix/pull/6631))\n- Support Robot Framework ([#6611](https://github.com/helix-editor/helix/pull/6611))\n- Update Gleam tree-sitter parser ([#6641](https://github.com/helix-editor/helix/pull/6641))\n- Update git-commit tree-sitter parser ([#6692](https://github.com/helix-editor/helix/pull/6692))\n- Update Haskell tree-sitter parser ([#6317](https://github.com/helix-editor/helix/pull/6317))\n- Add injection queries for Haskell quasiquotes ([#6474](https://github.com/helix-editor/helix/pull/6474))\n- Highlight C/C++ escape sequences ([#6724](https://github.com/helix-editor/helix/pull/6724))\n- Support Markdoc ([#6432](https://github.com/helix-editor/helix/pull/6432))\n- Support OpenCL ([#6473](https://github.com/helix-editor/helix/pull/6473))\n- Support DTD ([#6644](https://github.com/helix-editor/helix/pull/6644))\n- Fix constant highlighting in Python queries ([#6751](https://github.com/helix-editor/helix/pull/6751))\n- Support Just ([#6453](https://github.com/helix-editor/helix/pull/6453))\n- Fix Go locals query for `var_spec` identifiers ([#6763](https://github.com/helix-editor/helix/pull/6763))\n- Update Markdown tree-sitter parser ([#6785](https://github.com/helix-editor/helix/pull/6785))\n- Fix Haskell workspace root for cabal projects ([#6828](https://github.com/helix-editor/helix/pull/6828))\n- Avoid extra indentation in Go switches ([#6817](https://github.com/helix-editor/helix/pull/6817))\n- Fix Go workspace roots ([#6884](https://github.com/helix-editor/helix/pull/6884))\n- Set PerlNavigator as the default Perl language server ([#6860](https://github.com/helix-editor/helix/pull/6860))\n- Highlight more sqlx macros in Rust ([#6793](https://github.com/helix-editor/helix/pull/6793))\n- Switch Odin tree-sitter grammar ([#6766](https://github.com/helix-editor/helix/pull/6766))\n- Recognize `poetry.lock` as TOML ([#6928](https://github.com/helix-editor/helix/pull/6928))\n- Recognize Jupyter notebooks as JSON ([#6927](https://github.com/helix-editor/helix/pull/6927))\n- Add language server configuration for Crystal ([#6948](https://github.com/helix-editor/helix/pull/6948))\n- Add `build.gradle.kts` to Java and Scala roots ([#6970](https://github.com/helix-editor/helix/pull/6970))\n- Recognize `sty` and `cls` files as latex ([#6986](https://github.com/helix-editor/helix/pull/6986))\n- Update Dockerfile tree-sitter grammar ([#6895](https://github.com/helix-editor/helix/pull/6895))\n- Add comment injections for Odin ([#7027](https://github.com/helix-editor/helix/pull/7027))\n- Recognize `gml` as XML ([#7055](https://github.com/helix-editor/helix/pull/7055))\n- Recognize `geojson` as JSON ([#7054](https://github.com/helix-editor/helix/pull/7054))\n\nPackaging:\n\n- Update the Nix flake dependencies, remove a deprecated option ([#6546](https://github.com/helix-editor/helix/pull/6546))\n- Fix and re-enable aarch64-macos release binary builds ([#6504](https://github.com/helix-editor/helix/pull/6504))\n- The git dependency on `tree-sitter` has been replaced with a regular crates.io dependency ([#6608](https://github.com/helix-editor/helix/pull/6608))\n\n# 23.03 (2023-03-31)\n\n23.03 brings some long-awaited and exciting features. Thank you to everyone involved! This release saw changes from 102 contributors.\n\nFor the full log, check out the [git log](https://github.com/helix-editor/helix/compare/22.12..23.03).\nAlso check out the [release notes](https://helix-editor.com/news/release-23-03-highlights/) for more commentary on larger features.\n\nBreaking changes:\n\n- Select diagnostic range in `goto_*_diag` commands ([#4713](https://github.com/helix-editor/helix/pull/4713), [#5164](https://github.com/helix-editor/helix/pull/5164), [#6193](https://github.com/helix-editor/helix/pull/6193))\n- Remove jump behavior from `increment`/`decrement` ([#4123](https://github.com/helix-editor/helix/pull/4123), [#5929](https://github.com/helix-editor/helix/pull/5929))\n- Select change range in `goto_*_change` commands ([#5206](https://github.com/helix-editor/helix/pull/5206))\n- Split file modification indicator from filename statusline elements ([#4731](https://github.com/helix-editor/helix/pull/4731), [#6036](https://github.com/helix-editor/helix/pull/6036))\n- Jump to symbol ranges in LSP goto commands ([#5986](https://github.com/helix-editor/helix/pull/5986))\n- Workspace detection now stops at the first `.helix/` directory (merging multiple `.helix/languages.toml` configurations is no longer supported) ([#5748](https://github.com/helix-editor/helix/pull/5748))\n\nFeatures:\n\n- Dynamic workspace symbol picker ([#5055](https://github.com/helix-editor/helix/pull/5055))\n- Soft-wrap ([#5420](https://github.com/helix-editor/helix/pull/5420), [#5786](https://github.com/helix-editor/helix/pull/5786), [#5893](https://github.com/helix-editor/helix/pull/5893), [#6142](https://github.com/helix-editor/helix/pull/6142), [#6440](https://github.com/helix-editor/helix/pull/6440))\n- Initial support for LSP snippet completions ([#5864](https://github.com/helix-editor/helix/pull/5864), [b1f7528](https://github.com/helix-editor/helix/commit/b1f7528), [#6263](https://github.com/helix-editor/helix/pull/6263), [bbf4800](https://github.com/helix-editor/helix/commit/bbf4800), [90348b8](https://github.com/helix-editor/helix/commit/90348b8), [f87299f](https://github.com/helix-editor/helix/commit/f87299f), [#6371](https://github.com/helix-editor/helix/pull/6371), [9fe3adc](https://github.com/helix-editor/helix/commit/9fe3adc))\n- Add a statusline element for showing the current version control HEAD ([#5682](https://github.com/helix-editor/helix/pull/5682))\n- Display LSP type hints ([#5420](https://github.com/helix-editor/helix/pull/5420), [#5934](https://github.com/helix-editor/helix/pull/5934), [#6312](https://github.com/helix-editor/helix/pull/6312))\n- Enable the Kitty keyboard protocol on terminals with support ([#4939](https://github.com/helix-editor/helix/pull/4939), [#6170](https://github.com/helix-editor/helix/pull/6170), [#6194](https://github.com/helix-editor/helix/pull/6194), [#6438](https://github.com/helix-editor/helix/pull/6438))\n- Add a statusline element for the basename of the current file ([#5318](https://github.com/helix-editor/helix/pull/5318))\n- Add substring matching syntax for the picker ([#5658](https://github.com/helix-editor/helix/pull/5658))\n- Support LSP `textDocument/prepareRename` ([#6103](https://github.com/helix-editor/helix/pull/6103))\n- Allow multiple runtime directories with priorities ([#5411](https://github.com/helix-editor/helix/pull/5411))\n- Allow configuring whether to insert or replace completions ([#5728](https://github.com/helix-editor/helix/pull/5728))\n- Allow per-workspace config file `.helix/config.toml` ([#5748](https://github.com/helix-editor/helix/pull/5748))\n- Add `workspace-lsp-roots` config option to support multiple LSP roots for use with monorepos ([#5748](https://github.com/helix-editor/helix/pull/5748))\n\nCommands:\n\n- `:pipe-to` which pipes selections into a shell command and ignores output ([#4931](https://github.com/helix-editor/helix/pull/4931))\n- `merge_consecutive_selections` (`A-_`) combines all consecutive selections ([#5047](https://github.com/helix-editor/helix/pull/5047))\n- `rotate_view_reverse` which focuses the previous view ([#5356](https://github.com/helix-editor/helix/pull/5356))\n- `goto_declaration` (`gD`, requires LSP) which jumps to a symbol's declaration ([#5646](https://github.com/helix-editor/helix/pull/5646))\n- `file_picker_in_current_buffer_directory` ([#4666](https://github.com/helix-editor/helix/pull/4666))\n- `:character-info` which shows information about the character under the cursor ([#4000](https://github.com/helix-editor/helix/pull/4000))\n- `:toggle-option` for toggling config options at runtime ([#4085](https://github.com/helix-editor/helix/pull/4085))\n- `dap_restart` for restarting a debug session in DAP ([#5651](https://github.com/helix-editor/helix/pull/5651))\n- `:lsp-stop` to stop the language server of the current buffer ([#5964](https://github.com/helix-editor/helix/pull/5964))\n- `:reset-diff-change` for resetting a diff hunk to its original text ([#4974](https://github.com/helix-editor/helix/pull/4974))\n- `:config-open-workspace` for opening the config file local to the current workspace ([#5748](https://github.com/helix-editor/helix/pull/5748))\n\nUsability improvements:\n\n- Remove empty detail section in completion menu when LSP doesn't send details ([#4902](https://github.com/helix-editor/helix/pull/4902))\n- Pass client information on LSP initialization ([#4904](https://github.com/helix-editor/helix/pull/4904))\n- Allow specifying environment variables for language servers in language config ([#4004](https://github.com/helix-editor/helix/pull/4004))\n- Allow detached git worktrees to be recognized as root paths ([#5097](https://github.com/helix-editor/helix/pull/5097))\n- Improve error message handling for theme loading failures ([#5073](https://github.com/helix-editor/helix/pull/5073))\n- Print the names of binaries required for LSP/DAP in health-check ([#5195](https://github.com/helix-editor/helix/pull/5195))\n- Improve sorting in the picker in cases of ties ([#5169](https://github.com/helix-editor/helix/pull/5169))\n- Add theming for prompt suggestions ([#5104](https://github.com/helix-editor/helix/pull/5104))\n- Open a file picker when using `:open` on directories ([#2707](https://github.com/helix-editor/helix/pull/2707), [#5278](https://github.com/helix-editor/helix/pull/5278))\n- Reload language config with `:config-reload` ([#5239](https://github.com/helix-editor/helix/pull/5239), [#5381](https://github.com/helix-editor/helix/pull/5381), [#5431](https://github.com/helix-editor/helix/pull/5431))\n- Improve indent queries for python when the tree is errored ([#5332](https://github.com/helix-editor/helix/pull/5332))\n- Picker: Open files without closing the picker with `A-ret` ([#4435](https://github.com/helix-editor/helix/pull/4435))\n- Allow theming cursors by primary/secondary and by mode ([#5130](https://github.com/helix-editor/helix/pull/5130))\n- Allow configuration of the minimum width for the line-numbers gutter ([#4724](https://github.com/helix-editor/helix/pull/4724), [#5696](https://github.com/helix-editor/helix/pull/5696))\n- Use filename completer for `:run-shell-command` command ([#5729](https://github.com/helix-editor/helix/pull/5729))\n- Surround with line-endings with `ms<ret>` ([#4571](https://github.com/helix-editor/helix/pull/4571))\n- Hide duplicate symlinks in file pickers ([#5658](https://github.com/helix-editor/helix/pull/5658))\n- Tabulate buffer picker contents ([#5777](https://github.com/helix-editor/helix/pull/5777))\n- Add an option to disable LSP ([#4425](https://github.com/helix-editor/helix/pull/4425))\n- Short-circuit tree-sitter and word object motions ([#5851](https://github.com/helix-editor/helix/pull/5851))\n- Add exit code to failed command message ([#5898](https://github.com/helix-editor/helix/pull/5898))\n- Make `m` textobject look for pairs enclosing selections ([#3344](https://github.com/helix-editor/helix/pull/3344))\n- Negotiate LSP position encoding ([#5894](https://github.com/helix-editor/helix/pull/5894), [a48d1a4](https://github.com/helix-editor/helix/commit/a48d1a4))\n- Display deprecated LSP completions with strikethrough ([#5932](https://github.com/helix-editor/helix/pull/5932))\n- Add JSONRPC request ID to failed LSP/DAP request log messages ([#6010](https://github.com/helix-editor/helix/pull/6010), [#6018](https://github.com/helix-editor/helix/pull/6018))\n- Ignore case when filtering LSP completions ([#6008](https://github.com/helix-editor/helix/pull/6008))\n- Show current language when no arguments are passed to `:set-language` ([#5895](https://github.com/helix-editor/helix/pull/5895))\n- Refactor and rewrite all book documentation ([#5534](https://github.com/helix-editor/helix/pull/5534))\n- Separate diagnostic picker message and code ([#6095](https://github.com/helix-editor/helix/pull/6095))\n- Add a config option to bypass undercurl detection ([#6253](https://github.com/helix-editor/helix/pull/6253))\n- Only complete appropriate arguments for typed commands ([#5966](https://github.com/helix-editor/helix/pull/5966))\n- Discard outdated LSP diagnostics ([3c9d5d0](https://github.com/helix-editor/helix/commit/3c9d5d0))\n- Discard outdated LSP workspace edits ([b6a4927](https://github.com/helix-editor/helix/commit/b6a4927))\n- Run shell commands asynchronously ([#6373](https://github.com/helix-editor/helix/pull/6373))\n- Show diagnostic codes in LSP diagnostic messages ([#6378](https://github.com/helix-editor/helix/pull/6378))\n- Highlight the current line in a DAP debug session ([#5957](https://github.com/helix-editor/helix/pull/5957))\n- Hide signature help if it overlaps with the completion menu ([#5523](https://github.com/helix-editor/helix/pull/5523), [7a69c40](https://github.com/helix-editor/helix/commit/7a69c40))\n\nFixes:\n\n- Fix behavior of `auto-completion` flag for completion-on-trigger ([#5042](https://github.com/helix-editor/helix/pull/5042))\n- Reset editor mode when changing buffers ([#5072](https://github.com/helix-editor/helix/pull/5072))\n- Respect scrolloff settings in mouse movements ([#5255](https://github.com/helix-editor/helix/pull/5255))\n- Avoid trailing `s` when only one file is opened ([#5189](https://github.com/helix-editor/helix/pull/5189))\n- Fix erroneous indent between closers of auto-pairs ([#5330](https://github.com/helix-editor/helix/pull/5330))\n- Expand `~` when parsing file paths in `:open` ([#5329](https://github.com/helix-editor/helix/pull/5329))\n- Fix theme inheritance for default themes ([#5218](https://github.com/helix-editor/helix/pull/5218))\n- Fix `extend_line` with a count when the current line(s) are selected ([#5288](https://github.com/helix-editor/helix/pull/5288))\n- Prompt: Fix autocompletion for paths containing periods ([#5175](https://github.com/helix-editor/helix/pull/5175))\n- Skip serializing JSONRPC params if params is null ([#5471](https://github.com/helix-editor/helix/pull/5471))\n- Fix interaction with the `xclip` clipboard provider ([#5426](https://github.com/helix-editor/helix/pull/5426))\n- Fix undo/redo execution from the command palette ([#5294](https://github.com/helix-editor/helix/pull/5294))\n- Fix highlighting of non-block cursors ([#5575](https://github.com/helix-editor/helix/pull/5575))\n- Fix panic when nooping in `join_selections` and `join_selections_space` ([#5423](https://github.com/helix-editor/helix/pull/5423))\n- Fix selecting a changed file in global search ([#5639](https://github.com/helix-editor/helix/pull/5639))\n- Fix initial syntax highlight layer sort order ([#5196](https://github.com/helix-editor/helix/pull/5196))\n- Fix UTF-8 length handling for shellwords ([#5738](https://github.com/helix-editor/helix/pull/5738))\n- Remove C-j and C-k bindings from the completion menu ([#5070](https://github.com/helix-editor/helix/pull/5070))\n- Always commit to history when pasting ([#5790](https://github.com/helix-editor/helix/pull/5790))\n- Properly handle LSP position encoding ([#5711](https://github.com/helix-editor/helix/pull/5711))\n- Fix infinite loop in `copy_selection_on_prev_line` ([#5888](https://github.com/helix-editor/helix/pull/5888))\n- Fix completion popup positioning ([#5842](https://github.com/helix-editor/helix/pull/5842))\n- Fix a panic when uncommenting a line with only a comment token ([#5933](https://github.com/helix-editor/helix/pull/5933))\n- Fix panic in `goto_window_center` at EOF ([#5987](https://github.com/helix-editor/helix/pull/5987))\n- Ignore invalid file URIs sent by a language server ([#6000](https://github.com/helix-editor/helix/pull/6000))\n- Decode LSP URIs for the workspace diagnostics picker ([#6016](https://github.com/helix-editor/helix/pull/6016))\n- Fix incorrect usages of `tab_width` with `indent_width` ([#5918](https://github.com/helix-editor/helix/pull/5918))\n- DAP: Send Disconnect if the Terminated event is received ([#5532](https://github.com/helix-editor/helix/pull/5532))\n- DAP: Validate key and index exist when requesting variables ([#5628](https://github.com/helix-editor/helix/pull/5628))\n- Check LSP renaming support before prompting for rename text ([#6257](https://github.com/helix-editor/helix/pull/6257))\n- Fix indent guide rendering ([#6136](https://github.com/helix-editor/helix/pull/6136))\n- Fix division by zero panic ([#6155](https://github.com/helix-editor/helix/pull/6155))\n- Fix lacking space panic ([#6109](https://github.com/helix-editor/helix/pull/6109))\n- Send error replies for malformed and unhandled LSP requests ([#6058](https://github.com/helix-editor/helix/pull/6058))\n- Fix table column calculations for dynamic pickers ([#5920](https://github.com/helix-editor/helix/pull/5920))\n- Skip adding jumplist entries for `:<n>` line number previews ([#5751](https://github.com/helix-editor/helix/pull/5751))\n- Fix completion race conditions ([#6173](https://github.com/helix-editor/helix/pull/6173))\n- Fix `shrink_selection` with multiple cursors ([#6093](https://github.com/helix-editor/helix/pull/6093))\n- Fix indentation calculation for lines with mixed tabs/spaces ([#6278](https://github.com/helix-editor/helix/pull/6278))\n- No-op `client/registerCapability` LSP requests ([#6258](https://github.com/helix-editor/helix/pull/6258))\n- Send the STOP signal to all processes in the process group ([#3546](https://github.com/helix-editor/helix/pull/3546))\n- Fix workspace edit client capabilities declaration ([7bf168d](https://github.com/helix-editor/helix/commit/7bf168d))\n- Fix highlighting in picker results with multiple columns ([#6333](https://github.com/helix-editor/helix/pull/6333))\n- Canonicalize paths before stripping the current dir as a prefix ([#6290](https://github.com/helix-editor/helix/pull/6290))\n- Fix truncation behavior for long path names in the file picker ([#6410](https://github.com/helix-editor/helix/pull/6410), [67783dd](https://github.com/helix-editor/helix/commit/67783dd))\n- Fix theme reloading behavior in `:config-reload` ([ab819d8](https://github.com/helix-editor/helix/commit/ab819d8))\n\nThemes:\n\n- Update `serika` ([#5038](https://github.com/helix-editor/helix/pull/5038), [#6344](https://github.com/helix-editor/helix/pull/6344))\n- Update `flatwhite` ([#5036](https://github.com/helix-editor/helix/pull/5036), [#6323](https://github.com/helix-editor/helix/pull/6323))\n- Update `autumn` ([#5051](https://github.com/helix-editor/helix/pull/5051), [#5397](https://github.com/helix-editor/helix/pull/5397), [#6280](https://github.com/helix-editor/helix/pull/6280), [#6316](https://github.com/helix-editor/helix/pull/6316))\n- Update `acme` ([#5019](https://github.com/helix-editor/helix/pull/5019), [#5486](https://github.com/helix-editor/helix/pull/5486), [#5488](https://github.com/helix-editor/helix/pull/5488))\n- Update `gruvbox` themes ([#5066](https://github.com/helix-editor/helix/pull/5066), [#5333](https://github.com/helix-editor/helix/pull/5333), [#5540](https://github.com/helix-editor/helix/pull/5540), [#6285](https://github.com/helix-editor/helix/pull/6285), [#6295](https://github.com/helix-editor/helix/pull/6295))\n- Update `base16_transparent` ([#5105](https://github.com/helix-editor/helix/pull/5105))\n- Update `dark_high_contrast` ([#5105](https://github.com/helix-editor/helix/pull/5105))\n- Update `dracula` ([#5236](https://github.com/helix-editor/helix/pull/5236), [#5627](https://github.com/helix-editor/helix/pull/5627), [#6414](https://github.com/helix-editor/helix/pull/6414))\n- Update `monokai_pro_spectrum` ([#5250](https://github.com/helix-editor/helix/pull/5250), [#5602](https://github.com/helix-editor/helix/pull/5602))\n- Update `rose_pine` ([#5267](https://github.com/helix-editor/helix/pull/5267), [#5489](https://github.com/helix-editor/helix/pull/5489), [#6384](https://github.com/helix-editor/helix/pull/6384))\n- Update `kanagawa` ([#5273](https://github.com/helix-editor/helix/pull/5273), [#5571](https://github.com/helix-editor/helix/pull/5571), [#6085](https://github.com/helix-editor/helix/pull/6085))\n- Update `emacs` ([#5334](https://github.com/helix-editor/helix/pull/5334))\n- Add `github` themes ([#5353](https://github.com/helix-editor/helix/pull/5353), [efeec12](https://github.com/helix-editor/helix/commit/efeec12))\n    - Dark themes: `github_dark`, `github_dark_colorblind`, `github_dark_dimmed`, `github_dark_high_contrast`, `github_dark_tritanopia`\n    - Light themes: `github_light`, `github_light_colorblind`, `github_light_dimmed`, `github_light_high_contrast`, `github_light_tritanopia`\n- Update `solarized` variants ([#5445](https://github.com/helix-editor/helix/pull/5445), [#6327](https://github.com/helix-editor/helix/pull/6327))\n- Update `catppuccin` variants ([#5404](https://github.com/helix-editor/helix/pull/5404), [#6107](https://github.com/helix-editor/helix/pull/6107), [#6269](https://github.com/helix-editor/helix/pull/6269), [#6464](https://github.com/helix-editor/helix/pull/6464))\n- Use curly underlines in built-in themes ([#5419](https://github.com/helix-editor/helix/pull/5419))\n- Update `zenburn` ([#5573](https://github.com/helix-editor/helix/pull/5573))\n- Rewrite `snazzy` ([#3971](https://github.com/helix-editor/helix/pull/3971))\n- Add `monokai_aqua` ([#5578](https://github.com/helix-editor/helix/pull/5578))\n- Add `markup.strikethrough` to existing themes ([#5619](https://github.com/helix-editor/helix/pull/5619))\n- Update `sonokai` ([#5440](https://github.com/helix-editor/helix/pull/5440))\n- Update `onedark` ([#5755](https://github.com/helix-editor/helix/pull/5755))\n- Add `ayu_evolve` ([#5638](https://github.com/helix-editor/helix/pull/5638), [#6028](https://github.com/helix-editor/helix/pull/6028), [#6225](https://github.com/helix-editor/helix/pull/6225))\n- Add `jellybeans` ([#5719](https://github.com/helix-editor/helix/pull/5719))\n- Update `fleet_dark` ([#5605](https://github.com/helix-editor/helix/pull/5605), [#6266](https://github.com/helix-editor/helix/pull/6266), [#6324](https://github.com/helix-editor/helix/pull/6324), [#6375](https://github.com/helix-editor/helix/pull/6375))\n- Add `darcula-solid` ([#5778](https://github.com/helix-editor/helix/pull/5778))\n- Remove text background from monokai themes ([#6009](https://github.com/helix-editor/helix/pull/6009))\n- Update `pop_dark` ([#5992](https://github.com/helix-editor/helix/pull/5992), [#6208](https://github.com/helix-editor/helix/pull/6208), [#6227](https://github.com/helix-editor/helix/pull/6227), [#6292](https://github.com/helix-editor/helix/pull/6292))\n- Add `everblush` ([#6086](https://github.com/helix-editor/helix/pull/6086))\n- Add `adwaita-dark` ([#6042](https://github.com/helix-editor/helix/pull/6042), [#6342](https://github.com/helix-editor/helix/pull/6342))\n- Update `papercolor` ([#6162](https://github.com/helix-editor/helix/pull/6162))\n- Update `onelight` ([#6192](https://github.com/helix-editor/helix/pull/6192), [#6276](https://github.com/helix-editor/helix/pull/6276))\n- Add `molokai` ([#6260](https://github.com/helix-editor/helix/pull/6260))\n- Update `ayu` variants ([#6329](https://github.com/helix-editor/helix/pull/6329))\n- Update `tokyonight` variants ([#6349](https://github.com/helix-editor/helix/pull/6349))\n- Update `nord` variants ([#6376](https://github.com/helix-editor/helix/pull/6376))\n\nNew languages:\n\n- BibTeX ([#5064](https://github.com/helix-editor/helix/pull/5064))\n- Mermaid.js ([#5147](https://github.com/helix-editor/helix/pull/5147))\n- Crystal ([#4993](https://github.com/helix-editor/helix/pull/4993), [#5205](https://github.com/helix-editor/helix/pull/5205))\n- MATLAB/Octave ([#5192](https://github.com/helix-editor/helix/pull/5192))\n- `tfvars` (uses HCL) ([#5396](https://github.com/helix-editor/helix/pull/5396))\n- Ponylang ([#5416](https://github.com/helix-editor/helix/pull/5416))\n- DHall ([1f6809c](https://github.com/helix-editor/helix/commit/1f6809c))\n- Sagemath ([#5649](https://github.com/helix-editor/helix/pull/5649))\n- MSBuild ([#5793](https://github.com/helix-editor/helix/pull/5793))\n- pem ([#5797](https://github.com/helix-editor/helix/pull/5797))\n- passwd ([#4959](https://github.com/helix-editor/helix/pull/4959))\n- hosts ([#4950](https://github.com/helix-editor/helix/pull/4950), [#5914](https://github.com/helix-editor/helix/pull/5914))\n- uxntal ([#6047](https://github.com/helix-editor/helix/pull/6047))\n- Yuck ([#6064](https://github.com/helix-editor/helix/pull/6064), [#6242](https://github.com/helix-editor/helix/pull/6242))\n- GNU gettext PO ([#5996](https://github.com/helix-editor/helix/pull/5996))\n- Sway ([#6023](https://github.com/helix-editor/helix/pull/6023))\n- NASM ([#6068](https://github.com/helix-editor/helix/pull/6068))\n- PRQL ([#6126](https://github.com/helix-editor/helix/pull/6126))\n- reStructuredText ([#6180](https://github.com/helix-editor/helix/pull/6180))\n- Smithy ([#6370](https://github.com/helix-editor/helix/pull/6370))\n- VHDL ([#5826](https://github.com/helix-editor/helix/pull/5826))\n- Rego (OpenPolicy Agent) ([#6415](https://github.com/helix-editor/helix/pull/6415))\n- Nim ([#6123](https://github.com/helix-editor/helix/pull/6123))\n\nUpdated languages and queries:\n\n- Use diff syntax for patch files ([#5085](https://github.com/helix-editor/helix/pull/5085))\n- Add Haskell textobjects ([#5061](https://github.com/helix-editor/helix/pull/5061))\n- Fix commonlisp configuration ([#5091](https://github.com/helix-editor/helix/pull/5091))\n- Update Scheme ([bae890d](https://github.com/helix-editor/helix/commit/bae890d))\n- Add indent queries for Bash ([#5149](https://github.com/helix-editor/helix/pull/5149))\n- Recognize `c++` as a C++ extension ([#5183](https://github.com/helix-editor/helix/pull/5183))\n- Enable HTTP server in `metals` (Scala) config ([#5551](https://github.com/helix-editor/helix/pull/5551))\n- Change V-lang language server to `v ls` from `vls` ([#5677](https://github.com/helix-editor/helix/pull/5677))\n- Inject comment grammar into Nix ([#5208](https://github.com/helix-editor/helix/pull/5208))\n- Update Rust highlights ([#5238](https://github.com/helix-editor/helix/pull/5238), [#5349](https://github.com/helix-editor/helix/pull/5349))\n- Fix HTML injection within Markdown ([#5265](https://github.com/helix-editor/helix/pull/5265))\n- Fix comment token for godot ([#5276](https://github.com/helix-editor/helix/pull/5276))\n- Expand injections for Vue ([#5268](https://github.com/helix-editor/helix/pull/5268))\n- Add `.bash_aliases` as a Bash file-type ([#5347](https://github.com/helix-editor/helix/pull/5347))\n- Fix comment token for sshclientconfig ([#5351](https://github.com/helix-editor/helix/pull/5351))\n- Update Prisma ([#5417](https://github.com/helix-editor/helix/pull/5417))\n- Update C++ ([#5457](https://github.com/helix-editor/helix/pull/5457))\n- Add more file-types for Python ([#5593](https://github.com/helix-editor/helix/pull/5593))\n- Update tree-sitter-scala ([#5576](https://github.com/helix-editor/helix/pull/5576))\n- Add an injection regex for Lua ([#5606](https://github.com/helix-editor/helix/pull/5606))\n- Add `build.gradle` to java roots configuration ([#5641](https://github.com/helix-editor/helix/pull/5641))\n- Add Hub PR files to markdown file-types ([#5634](https://github.com/helix-editor/helix/pull/5634))\n- Add an external formatter configuration for Cue ([#5679](https://github.com/helix-editor/helix/pull/5679))\n- Add injections for builders and writers to Nix ([#5629](https://github.com/helix-editor/helix/pull/5629))\n- Update tree-sitter-xml to fix whitespace parsing ([#5685](https://github.com/helix-editor/helix/pull/5685))\n- Add `Justfile` to the make file-types configuration ([#5687](https://github.com/helix-editor/helix/pull/5687))\n- Update tree-sitter-sql and highlight queries ([#5683](https://github.com/helix-editor/helix/pull/5683), [#5772](https://github.com/helix-editor/helix/pull/5772))\n- Use the bash grammar and queries for env language ([#5720](https://github.com/helix-editor/helix/pull/5720))\n- Add podspec files to ruby file-types ([#5811](https://github.com/helix-editor/helix/pull/5811))\n- Recognize `.C` and `.H` file-types as C++ ([#5808](https://github.com/helix-editor/helix/pull/5808))\n- Recognize plist and mobileconfig files as XML ([#5863](https://github.com/helix-editor/helix/pull/5863))\n- Fix `select` indentation in Go ([#5713](https://github.com/helix-editor/helix/pull/5713))\n- Check for external file modifications when writing ([#5805](https://github.com/helix-editor/helix/pull/5805))\n- Recognize containerfiles as dockerfile syntax ([#5873](https://github.com/helix-editor/helix/pull/5873))\n- Update godot grammar and queries ([#5944](https://github.com/helix-editor/helix/pull/5944), [#6186](https://github.com/helix-editor/helix/pull/6186))\n- Improve DHall highlights ([#5959](https://github.com/helix-editor/helix/pull/5959))\n- Recognize `.env.dist` and `source.env` as env language ([#6003](https://github.com/helix-editor/helix/pull/6003))\n- Update tree-sitter-git-rebase ([#6030](https://github.com/helix-editor/helix/pull/6030), [#6094](https://github.com/helix-editor/helix/pull/6094))\n- Improve SQL highlights ([#6041](https://github.com/helix-editor/helix/pull/6041))\n- Improve markdown highlights and inject LaTeX ([#6100](https://github.com/helix-editor/helix/pull/6100))\n- Add textobject queries for Elm ([#6084](https://github.com/helix-editor/helix/pull/6084))\n- Recognize graphql schema file type ([#6159](https://github.com/helix-editor/helix/pull/6159))\n- Improve highlighting in comments ([#6143](https://github.com/helix-editor/helix/pull/6143))\n- Improve highlighting for JavaScript/TypeScript/ECMAScript languages ([#6205](https://github.com/helix-editor/helix/pull/6205))\n- Improve PHP highlights ([#6203](https://github.com/helix-editor/helix/pull/6203), [#6250](https://github.com/helix-editor/helix/pull/6250), [#6299](https://github.com/helix-editor/helix/pull/6299))\n- Improve Go highlights ([#6204](https://github.com/helix-editor/helix/pull/6204))\n- Highlight unchecked sqlx functions as SQL in Rust ([#6256](https://github.com/helix-editor/helix/pull/6256))\n- Improve Erlang highlights ([cdd6c8d](https://github.com/helix-editor/helix/commit/cdd6c8d))\n- Improve Nix highlights ([fb4d703](https://github.com/helix-editor/helix/commit/fb4d703))\n- Improve gdscript highlights ([#6311](https://github.com/helix-editor/helix/pull/6311))\n- Improve Vlang highlights ([#6279](https://github.com/helix-editor/helix/pull/6279))\n- Improve Makefile highlights ([#6339](https://github.com/helix-editor/helix/pull/6339))\n- Remove auto-pair for `'` in OCaml ([#6381](https://github.com/helix-editor/helix/pull/6381))\n- Fix indents in switch statements in ECMA languages ([#6369](https://github.com/helix-editor/helix/pull/6369))\n- Recognize xlb and storyboard file-types as XML ([#6407](https://github.com/helix-editor/helix/pull/6407))\n- Recognize cts and mts file-types as TypeScript ([#6424](https://github.com/helix-editor/helix/pull/6424))\n- Recognize SVG file-type as XML ([#6431](https://github.com/helix-editor/helix/pull/6431))\n- Add theme scopes for (un)checked list item markup scopes ([#6434](https://github.com/helix-editor/helix/pull/6434))\n- Update git commit grammar and add the comment textobject ([#6439](https://github.com/helix-editor/helix/pull/6439), [#6493](https://github.com/helix-editor/helix/pull/6493))\n- Recognize ARB file-type as JSON ([#6452](https://github.com/helix-editor/helix/pull/6452))\n- Inject markdown into markdown strings in Julia ([#6489](https://github.com/helix-editor/helix/pull/6489))\n\nPackaging:\n\n- Fix Nix flake devShell for darwin hosts ([#5368](https://github.com/helix-editor/helix/pull/5368))\n- Add Appstream metadata file to `contrib/` ([#5643](https://github.com/helix-editor/helix/pull/5643))\n- Increase the MSRV to 1.65 ([#5570](https://github.com/helix-editor/helix/pull/5570), [#6185](https://github.com/helix-editor/helix/pull/6185))\n- Expose the Nix flake's `wrapper` ([#5994](https://github.com/helix-editor/helix/pull/5994))\n\n# 22.12 (2022-12-06)\n\nThis is a great big release filled with changes from a 99 contributors. A big _thank you_ to you all!\n\nAs usual, the following is a summary of each of the changes since the last release.\nFor the full log, check out the [git log](https://github.com/helix-editor/helix/compare/22.08.1..22.12).\n\nBreaking changes:\n\n- Remove readline-like navigation bindings from the default insert mode keymap ([e12690e](https://github.com/helix-editor/helix/commit/e12690e), [#3811](https://github.com/helix-editor/helix/pull/3811), [#3827](https://github.com/helix-editor/helix/pull/3827), [#3915](https://github.com/helix-editor/helix/pull/3915), [#4088](https://github.com/helix-editor/helix/pull/4088))\n- Rename `append_to_line` as `insert_at_line_end` and `prepend_to_line` as `insert_at_line_start` ([#3753](https://github.com/helix-editor/helix/pull/3753))\n- Swap diagnostic picker and debug mode bindings in the space keymap ([#4229](https://github.com/helix-editor/helix/pull/4229))\n- Select newly inserted text on paste or from shell commands ([#4458](https://github.com/helix-editor/helix/pull/4458), [#4608](https://github.com/helix-editor/helix/pull/4608), [#4619](https://github.com/helix-editor/helix/pull/4619), [#4824](https://github.com/helix-editor/helix/pull/4824))\n- Select newly inserted surrounding characters on `ms<char>` ([#4752](https://github.com/helix-editor/helix/pull/4752))\n- Exit select-mode after executing `replace_*` commands ([#4554](https://github.com/helix-editor/helix/pull/4554))\n- Exit select-mode after executing surround commands ([#4858](https://github.com/helix-editor/helix/pull/4858))\n- Change tree-sitter text-object keys ([#3782](https://github.com/helix-editor/helix/pull/3782))\n- Rename `fleetish` theme to `fleet_dark` ([#4997](https://github.com/helix-editor/helix/pull/4997))\n\nFeatures:\n\n- Bufferline ([#2759](https://github.com/helix-editor/helix/pull/2759))\n- Support underline styles and colors ([#4061](https://github.com/helix-editor/helix/pull/4061), [98c121c](https://github.com/helix-editor/helix/commit/98c121c))\n- Inheritance for themes ([#3067](https://github.com/helix-editor/helix/pull/3067), [#4096](https://github.com/helix-editor/helix/pull/4096))\n- Cursorcolumn ([#4084](https://github.com/helix-editor/helix/pull/4084))\n- Overhauled system for writing files and quitting ([#2267](https://github.com/helix-editor/helix/pull/2267), [#4397](https://github.com/helix-editor/helix/pull/4397))\n- Autosave when terminal loses focus ([#3178](https://github.com/helix-editor/helix/pull/3178))\n- Use OSC52 as a fallback for the system clipboard ([#3220](https://github.com/helix-editor/helix/pull/3220))\n- Show git diffs in the gutter ([#3890](https://github.com/helix-editor/helix/pull/3890), [#5012](https://github.com/helix-editor/helix/pull/5012), [#4995](https://github.com/helix-editor/helix/pull/4995))\n- Add a logo ([dc1ec56](https://github.com/helix-editor/helix/commit/dc1ec56))\n- Multi-cursor completion ([#4496](https://github.com/helix-editor/helix/pull/4496))\n\nCommands:\n\n- `file_picker_in_current_directory` (`<space>F`) ([#3701](https://github.com/helix-editor/helix/pull/3701))\n- `:lsp-restart` to restart the current document's language server ([#3435](https://github.com/helix-editor/helix/pull/3435), [#3972](https://github.com/helix-editor/helix/pull/3972))\n- `join_selections_space` (`A-j`) which joins selections and selects the joining whitespace ([#3549](https://github.com/helix-editor/helix/pull/3549))\n- `:update` to write the current file if it is modified ([#4426](https://github.com/helix-editor/helix/pull/4426))\n- `:lsp-workspace-command` for picking LSP commands to execute ([#3140](https://github.com/helix-editor/helix/pull/3140))\n- `extend_prev_word_end` - the extend variant for `move_prev_word_end` ([7468fa2](https://github.com/helix-editor/helix/commit/7468fa2))\n- `make_search_word_bounded` which adds regex word boundaries to the current search register value ([#4322](https://github.com/helix-editor/helix/pull/4322))\n- `:reload-all` - `:reload` for all open buffers ([#4663](https://github.com/helix-editor/helix/pull/4663), [#4901](https://github.com/helix-editor/helix/pull/4901))\n- `goto_next_change` (`]g`), `goto_prev_change` (`[g`), `goto_first_change` (`[G`), `goto_last_change` (`]G`) textobjects for jumping between VCS changes ([#4650](https://github.com/helix-editor/helix/pull/4650))\n\nUsability improvements and fixes:\n\n- Don't log 'LSP not defined' errors in the logfile ([1caba2d](https://github.com/helix-editor/helix/commit/1caba2d))\n- Look for the external formatter program before invoking it ([#3670](https://github.com/helix-editor/helix/pull/3670))\n- Don't send LSP didOpen events for documents without URLs ([44b4479](https://github.com/helix-editor/helix/commit/44b4479))\n- Fix off-by-one in `extend_line_above` command ([#3689](https://github.com/helix-editor/helix/pull/3689))\n- Use the original scroll offset when opening a split ([1acdfaa](https://github.com/helix-editor/helix/commit/1acdfaa))\n- Handle auto-formatting failures and save the file anyway ([#3684](https://github.com/helix-editor/helix/pull/3684))\n- Ensure the cursor is in view after `:reflow` ([#3733](https://github.com/helix-editor/helix/pull/3733))\n- Add default rulers and reflow config for git commit messages ([#3738](https://github.com/helix-editor/helix/pull/3738))\n- Improve grammar fetching and building output ([#3773](https://github.com/helix-editor/helix/pull/3773))\n- Add a `text` language to language completion ([cc47d3f](https://github.com/helix-editor/helix/commit/cc47d3f))\n- Improve error handling for `:set-language` ([e8add6f](https://github.com/helix-editor/helix/commit/e8add6f))\n- Improve error handling for `:config-reload` ([#3668](https://github.com/helix-editor/helix/pull/3668))\n- Improve error handling when passing improper ranges to syntax highlighting ([#3826](https://github.com/helix-editor/helix/pull/3826))\n- Render `<code>` tags as raw markup in markdown ([#3425](https://github.com/helix-editor/helix/pull/3425))\n- Remove border around the LSP code-actions popup ([#3444](https://github.com/helix-editor/helix/pull/3444))\n- Canonicalize the path to the runtime directory ([#3794](https://github.com/helix-editor/helix/pull/3794))\n- Add a `themelint` xtask for linting themes ([#3234](https://github.com/helix-editor/helix/pull/3234))\n- Re-sort LSP diagnostics after applying transactions ([#3895](https://github.com/helix-editor/helix/pull/3895), [#4319](https://github.com/helix-editor/helix/pull/4319))\n- Add a command-line flag to specify the log file ([#3807](https://github.com/helix-editor/helix/pull/3807))\n- Track source and tag information in LSP diagnostics ([#3898](https://github.com/helix-editor/helix/pull/3898), [1df32c9](https://github.com/helix-editor/helix/commit/1df32c9))\n- Fix theme returning to normal when exiting the `:theme` completion ([#3644](https://github.com/helix-editor/helix/pull/3644))\n- Improve error messages for invalid commands in the keymap ([#3931](https://github.com/helix-editor/helix/pull/3931))\n- Deduplicate regexs in `search_selection` command ([#3941](https://github.com/helix-editor/helix/pull/3941))\n- Split the finding of LSP root and config roots ([#3929](https://github.com/helix-editor/helix/pull/3929))\n- Ensure that the cursor is within view after auto-formatting ([#4047](https://github.com/helix-editor/helix/pull/4047))\n- Add pseudo-pending to commands with on-next-key callbacks ([#4062](https://github.com/helix-editor/helix/pull/4062), [#4077](https://github.com/helix-editor/helix/pull/4077))\n- Add live preview to `:goto` ([#2982](https://github.com/helix-editor/helix/pull/2982))\n- Show regex compilation failure in a popup ([#3049](https://github.com/helix-editor/helix/pull/3049))\n- Add 'cycled to end' and 'no more matches' for search ([#3176](https://github.com/helix-editor/helix/pull/3176), [#4101](https://github.com/helix-editor/helix/pull/4101))\n- Add extending behavior to tree-sitter textobjects ([#3266](https://github.com/helix-editor/helix/pull/3266))\n- Add `ui.gutter.selected` option for themes ([#3303](https://github.com/helix-editor/helix/pull/3303))\n- Make statusline mode names configurable ([#3311](https://github.com/helix-editor/helix/pull/3311))\n- Add a statusline element for total line count ([#3960](https://github.com/helix-editor/helix/pull/3960))\n- Add extending behavior to `goto_window_*` commands ([#3985](https://github.com/helix-editor/helix/pull/3985))\n- Fix a panic in signature help when the preview is too large ([#4030](https://github.com/helix-editor/helix/pull/4030))\n- Add command names to the command palette ([#4071](https://github.com/helix-editor/helix/pull/4071), [#4223](https://github.com/helix-editor/helix/pull/4223), [#4495](https://github.com/helix-editor/helix/pull/4495))\n- Find the LSP workspace root from the current document's path ([#3553](https://github.com/helix-editor/helix/pull/3553))\n- Add an option to skip indent-guide levels ([#3819](https://github.com/helix-editor/helix/pull/3819), [2c36e33](https://github.com/helix-editor/helix/commit/2c36e33))\n- Change focus to modified docs on quit ([#3872](https://github.com/helix-editor/helix/pull/3872))\n- Respond to `USR1` signal by reloading config ([#3952](https://github.com/helix-editor/helix/pull/3952))\n- Exit gracefully when the close operation fails ([#4081](https://github.com/helix-editor/helix/pull/4081))\n- Fix goto/view center mismatch ([#4135](https://github.com/helix-editor/helix/pull/4135))\n- Highlight the current file picker document on idle-timeout ([#3172](https://github.com/helix-editor/helix/pull/3172), [a85e386](https://github.com/helix-editor/helix/commit/a85e386))\n- Apply transactions to jumplist selections ([#4186](https://github.com/helix-editor/helix/pull/4186), [#4227](https://github.com/helix-editor/helix/pull/4227), [#4733](https://github.com/helix-editor/helix/pull/4733), [#4865](https://github.com/helix-editor/helix/pull/4865), [#4912](https://github.com/helix-editor/helix/pull/4912), [#4965](https://github.com/helix-editor/helix/pull/4965), [#4981](https://github.com/helix-editor/helix/pull/4981))\n- Use space as a separator for fuzzy matcher ([#3969](https://github.com/helix-editor/helix/pull/3969))\n- Overlay all diagnostics with highest severity on top ([#4113](https://github.com/helix-editor/helix/pull/4113))\n- Avoid re-parsing unmodified tree-sitter injections ([#4146](https://github.com/helix-editor/helix/pull/4146))\n- Add extending captures for indentation, re-enable python indentation ([#3382](https://github.com/helix-editor/helix/pull/3382), [3e84434](https://github.com/helix-editor/helix/commit/3e84434))\n- Only allow either `--vsplit` or `--hsplit` CLI flags at once ([#4202](https://github.com/helix-editor/helix/pull/4202))\n- Fix append cursor location when selection anchor is at the end of the document ([#4147](https://github.com/helix-editor/helix/pull/4147))\n- Improve selection yanking message ([#4275](https://github.com/helix-editor/helix/pull/4275))\n- Log failures to load tree-sitter grammars as errors ([#4315](https://github.com/helix-editor/helix/pull/4315))\n- Fix rendering of lines longer than 65,536 columns ([#4172](https://github.com/helix-editor/helix/pull/4172))\n- Skip searching `.git` in `global_search` ([#4334](https://github.com/helix-editor/helix/pull/4334))\n- Display tree-sitter scopes in a popup ([#4337](https://github.com/helix-editor/helix/pull/4337))\n- Fix deleting a word from the end of the buffer ([#4328](https://github.com/helix-editor/helix/pull/4328))\n- Pretty print the syntax tree in `:tree-sitter-subtree` ([#4295](https://github.com/helix-editor/helix/pull/4295), [#4606](https://github.com/helix-editor/helix/pull/4606))\n- Allow specifying suffixes for file-type detection ([#2455](https://github.com/helix-editor/helix/pull/2455), [#4414](https://github.com/helix-editor/helix/pull/4414))\n- Fix multi-byte auto-pairs ([#4024](https://github.com/helix-editor/helix/pull/4024))\n- Improve sort scoring for LSP code-actions and completions ([#4134](https://github.com/helix-editor/helix/pull/4134))\n- Fix the handling of quotes within shellwords ([#4098](https://github.com/helix-editor/helix/pull/4098))\n- Fix `delete_word_backward` and `delete_word_forward` on newlines ([#4392](https://github.com/helix-editor/helix/pull/4392))\n- Fix 'no entry found for key' crash on `:write-all` ([#4384](https://github.com/helix-editor/helix/pull/4384))\n- Remove lowercase requirement for tree-sitter grammars ([#4346](https://github.com/helix-editor/helix/pull/4346))\n- Resolve LSP completion items on idle-timeout ([#4406](https://github.com/helix-editor/helix/pull/4406), [#4797](https://github.com/helix-editor/helix/pull/4797))\n- Render diagnostics in the file picker preview ([#4324](https://github.com/helix-editor/helix/pull/4324))\n- Fix terminal freezing on `shell_insert_output` ([#4156](https://github.com/helix-editor/helix/pull/4156))\n- Allow use of the count in the repeat operator (`.`) ([#4450](https://github.com/helix-editor/helix/pull/4450))\n- Show the current theme name on `:theme` with no arguments ([#3740](https://github.com/helix-editor/helix/pull/3740))\n- Fix rendering in very large terminals ([#4318](https://github.com/helix-editor/helix/pull/4318))\n- Sort LSP preselected items to the top of the completion menu ([#4480](https://github.com/helix-editor/helix/pull/4480))\n- Trim braces and quotes from paths in goto-file ([#4370](https://github.com/helix-editor/helix/pull/4370))\n- Prevent automatic signature help outside of insert mode ([#4456](https://github.com/helix-editor/helix/pull/4456))\n- Fix freezes with external programs that process stdin and stdout concurrently ([#4180](https://github.com/helix-editor/helix/pull/4180))\n- Make `scroll` aware of tabs and wide characters ([#4519](https://github.com/helix-editor/helix/pull/4519))\n- Correctly handle escaping in `command_mode` completion ([#4316](https://github.com/helix-editor/helix/pull/4316), [#4587](https://github.com/helix-editor/helix/pull/4587), [#4632](https://github.com/helix-editor/helix/pull/4632))\n- Fix `delete_char_backward` for paired characters ([#4558](https://github.com/helix-editor/helix/pull/4558))\n- Fix crash from two windows editing the same document ([#4570](https://github.com/helix-editor/helix/pull/4570))\n- Fix pasting from the blackhole register ([#4497](https://github.com/helix-editor/helix/pull/4497))\n- Support LSP insertReplace completion items ([1312682](https://github.com/helix-editor/helix/commit/1312682))\n- Dynamically resize the line number gutter width ([#3469](https://github.com/helix-editor/helix/pull/3469))\n- Fix crash for unknown completion item kinds ([#4658](https://github.com/helix-editor/helix/pull/4658))\n- Re-enable `format_selections` for single selection ranges ([d4f5cab](https://github.com/helix-editor/helix/commit/d4f5cab))\n- Limit the number of in-progress tree-sitter query matches ([#4707](https://github.com/helix-editor/helix/pull/4707), [#4830](https://github.com/helix-editor/helix/pull/4830))\n- Use the special `#` register with `increment`/`decrement` to change by range number ([#4418](https://github.com/helix-editor/helix/pull/4418))\n- Add a statusline element to show number of selected chars ([#4682](https://github.com/helix-editor/helix/pull/4682))\n- Add a statusline element showing global LSP diagnostic warning and error counts ([#4569](https://github.com/helix-editor/helix/pull/4569))\n- Add a scrollbar to popups ([#4449](https://github.com/helix-editor/helix/pull/4449))\n- Prefer shorter matches in fuzzy matcher scoring ([#4698](https://github.com/helix-editor/helix/pull/4698))\n- Use key-sequence format for command palette keybinds ([#4712](https://github.com/helix-editor/helix/pull/4712))\n- Remove prefix filtering from autocompletion menu ([#4578](https://github.com/helix-editor/helix/pull/4578))\n- Focus on the parent buffer when closing a split ([#4766](https://github.com/helix-editor/helix/pull/4766))\n- Handle language server termination ([#4797](https://github.com/helix-editor/helix/pull/4797), [#4852](https://github.com/helix-editor/helix/pull/4852))\n- Allow `r`/`t`/`f` to work on tab characters ([#4817](https://github.com/helix-editor/helix/pull/4817))\n- Show a preview for scratch buffers in the buffer picker ([#3454](https://github.com/helix-editor/helix/pull/3454))\n- Set a limit of entries in the jumplist ([#4750](https://github.com/helix-editor/helix/pull/4750))\n- Re-use shell outputs when inserting or appending shell output ([#3465](https://github.com/helix-editor/helix/pull/3465))\n- Check LSP server provider capabilities ([#3554](https://github.com/helix-editor/helix/pull/3554))\n- Improve tree-sitter parsing performance on files with many language layers ([#4716](https://github.com/helix-editor/helix/pull/4716))\n- Move indentation to the next line when using `<ret>` on a line with only whitespace ([#4854](https://github.com/helix-editor/helix/pull/4854))\n- Remove selections for closed views from all documents ([#4888](https://github.com/helix-editor/helix/pull/4888))\n- Improve performance of the `:reload` command ([#4457](https://github.com/helix-editor/helix/pull/4457))\n- Properly handle media keys ([#4887](https://github.com/helix-editor/helix/pull/4887))\n- Support LSP diagnostic data field ([#4935](https://github.com/helix-editor/helix/pull/4935))\n- Handle C-i keycode as tab ([#4961](https://github.com/helix-editor/helix/pull/4961))\n- Fix view alignment for jumplist picker jumps ([#3743](https://github.com/helix-editor/helix/pull/3743))\n- Use OSC52 for tmux clipboard provider ([#5027](https://github.com/helix-editor/helix/pull/5027))\n\nThemes:\n\n- Add `varua` ([#3610](https://github.com/helix-editor/helix/pull/3610), [#4964](https://github.com/helix-editor/helix/pull/4964))\n- Update `boo_berry` ([#3653](https://github.com/helix-editor/helix/pull/3653))\n- Add `rasmus` ([#3728](https://github.com/helix-editor/helix/pull/3728))\n- Add `papercolor_dark` ([#3742](https://github.com/helix-editor/helix/pull/3742))\n- Update `monokai_pro_spectrum` ([#3814](https://github.com/helix-editor/helix/pull/3814))\n- Update `nord` ([#3792](https://github.com/helix-editor/helix/pull/3792))\n- Update `fleetish` ([#3844](https://github.com/helix-editor/helix/pull/3844), [#4487](https://github.com/helix-editor/helix/pull/4487), [#4813](https://github.com/helix-editor/helix/pull/4813))\n- Update `flatwhite` ([#3843](https://github.com/helix-editor/helix/pull/3843))\n- Add `darcula` ([#3739](https://github.com/helix-editor/helix/pull/3739))\n- Update `papercolor` ([#3938](https://github.com/helix-editor/helix/pull/3938), [#4317](https://github.com/helix-editor/helix/pull/4317))\n- Add bufferline colors to multiple themes ([#3881](https://github.com/helix-editor/helix/pull/3881))\n- Add `gruvbox_dark_hard` ([#3948](https://github.com/helix-editor/helix/pull/3948))\n- Add `onedarker` ([#3980](https://github.com/helix-editor/helix/pull/3980), [#4060](https://github.com/helix-editor/helix/pull/4060))\n- Add `dark_high_contrast` ([#3312](https://github.com/helix-editor/helix/pull/3312))\n- Update `bogster` ([#4121](https://github.com/helix-editor/helix/pull/4121), [#4264](https://github.com/helix-editor/helix/pull/4264))\n- Update `sonokai` ([#4089](https://github.com/helix-editor/helix/pull/4089))\n- Update `ayu_*` themes ([#4140](https://github.com/helix-editor/helix/pull/4140), [#4109](https://github.com/helix-editor/helix/pull/4109), [#4662](https://github.com/helix-editor/helix/pull/4662), [#4764](https://github.com/helix-editor/helix/pull/4764))\n- Update `everforest` ([#3998](https://github.com/helix-editor/helix/pull/3998))\n- Update `monokai_pro_octagon` ([#4247](https://github.com/helix-editor/helix/pull/4247))\n- Add `heisenberg` ([#4209](https://github.com/helix-editor/helix/pull/4209))\n- Add `bogster_light` ([#4265](https://github.com/helix-editor/helix/pull/4265))\n- Update `pop-dark` ([#4323](https://github.com/helix-editor/helix/pull/4323))\n- Update `rose_pine` ([#4221](https://github.com/helix-editor/helix/pull/4221))\n- Add `kanagawa` ([#4300](https://github.com/helix-editor/helix/pull/4300))\n- Add `hex_steel`, `hex_toxic` and `hex_lavender` ([#4367](https://github.com/helix-editor/helix/pull/4367), [#4990](https://github.com/helix-editor/helix/pull/4990))\n- Update `tokyonight` and `tokyonight_storm` ([#4415](https://github.com/helix-editor/helix/pull/4415))\n- Update `gruvbox` ([#4626](https://github.com/helix-editor/helix/pull/4626))\n- Update `dark_plus` ([#4661](https://github.com/helix-editor/helix/pull/4661), [#4678](https://github.com/helix-editor/helix/pull/4678))\n- Add `zenburn` ([#4613](https://github.com/helix-editor/helix/pull/4613), [#4977](https://github.com/helix-editor/helix/pull/4977))\n- Update `monokai_pro` ([#4789](https://github.com/helix-editor/helix/pull/4789))\n- Add `mellow` ([#4770](https://github.com/helix-editor/helix/pull/4770))\n- Add `nightfox` ([#4769](https://github.com/helix-editor/helix/pull/4769), [#4966](https://github.com/helix-editor/helix/pull/4966))\n- Update `doom_acario_dark` ([#4979](https://github.com/helix-editor/helix/pull/4979))\n- Update `autumn` ([#4996](https://github.com/helix-editor/helix/pull/4996))\n- Update `acme` ([#4999](https://github.com/helix-editor/helix/pull/4999))\n- Update `nord_light` ([#4999](https://github.com/helix-editor/helix/pull/4999))\n- Update `serika_*` ([#5015](https://github.com/helix-editor/helix/pull/5015))\n\nLSP configurations:\n\n- Switch to `openscad-lsp` for OpenScad ([#3750](https://github.com/helix-editor/helix/pull/3750))\n- Support Jsonnet ([#3748](https://github.com/helix-editor/helix/pull/3748))\n- Support Markdown ([#3499](https://github.com/helix-editor/helix/pull/3499))\n- Support Bass ([#3771](https://github.com/helix-editor/helix/pull/3771))\n- Set roots configuration for Elixir and HEEx ([#3917](https://github.com/helix-editor/helix/pull/3917), [#3959](https://github.com/helix-editor/helix/pull/3959))\n- Support Purescript ([#4242](https://github.com/helix-editor/helix/pull/4242))\n- Set roots configuration for Julia ([#4361](https://github.com/helix-editor/helix/pull/4361))\n- Support D ([#4372](https://github.com/helix-editor/helix/pull/4372))\n- Increase default language server timeout for Julia ([#4575](https://github.com/helix-editor/helix/pull/4575))\n- Use ElixirLS for HEEx ([#4679](https://github.com/helix-editor/helix/pull/4679))\n- Support Bicep ([#4403](https://github.com/helix-editor/helix/pull/4403))\n- Switch to `nil` for Nix ([433ccef](https://github.com/helix-editor/helix/commit/433ccef))\n- Support QML ([#4842](https://github.com/helix-editor/helix/pull/4842))\n- Enable auto-format for CSS ([#4987](https://github.com/helix-editor/helix/pull/4987))\n- Support CommonLisp ([4176769](https://github.com/helix-editor/helix/commit/4176769))\n\nNew languages:\n\n- SML ([#3692](https://github.com/helix-editor/helix/pull/3692))\n- Jsonnet ([#3714](https://github.com/helix-editor/helix/pull/3714))\n- Godot resource ([#3759](https://github.com/helix-editor/helix/pull/3759))\n- Astro ([#3829](https://github.com/helix-editor/helix/pull/3829))\n- SSH config ([#2455](https://github.com/helix-editor/helix/pull/2455), [#4538](https://github.com/helix-editor/helix/pull/4538))\n- Bass ([#3771](https://github.com/helix-editor/helix/pull/3771))\n- WAT (WebAssembly text format) ([#4040](https://github.com/helix-editor/helix/pull/4040), [#4542](https://github.com/helix-editor/helix/pull/4542))\n- Purescript ([#4242](https://github.com/helix-editor/helix/pull/4242))\n- D ([#4372](https://github.com/helix-editor/helix/pull/4372), [#4562](https://github.com/helix-editor/helix/pull/4562))\n- VHS ([#4486](https://github.com/helix-editor/helix/pull/4486))\n- KDL ([#4481](https://github.com/helix-editor/helix/pull/4481))\n- XML ([#4518](https://github.com/helix-editor/helix/pull/4518))\n- WIT ([#4525](https://github.com/helix-editor/helix/pull/4525))\n- ENV ([#4536](https://github.com/helix-editor/helix/pull/4536))\n- INI ([#4538](https://github.com/helix-editor/helix/pull/4538))\n- Bicep ([#4403](https://github.com/helix-editor/helix/pull/4403), [#4751](https://github.com/helix-editor/helix/pull/4751))\n- QML ([#4842](https://github.com/helix-editor/helix/pull/4842))\n- CommonLisp ([4176769](https://github.com/helix-editor/helix/commit/4176769))\n\nUpdated languages and queries:\n\n- Zig ([#3621](https://github.com/helix-editor/helix/pull/3621), [#4745](https://github.com/helix-editor/helix/pull/4745))\n- Rust ([#3647](https://github.com/helix-editor/helix/pull/3647), [#3729](https://github.com/helix-editor/helix/pull/3729), [#3927](https://github.com/helix-editor/helix/pull/3927), [#4073](https://github.com/helix-editor/helix/pull/4073), [#4510](https://github.com/helix-editor/helix/pull/4510), [#4659](https://github.com/helix-editor/helix/pull/4659), [#4717](https://github.com/helix-editor/helix/pull/4717))\n- Solidity ([20ed8c2](https://github.com/helix-editor/helix/commit/20ed8c2))\n- Fish ([#3704](https://github.com/helix-editor/helix/pull/3704))\n- Elixir ([#3645](https://github.com/helix-editor/helix/pull/3645), [#4333](https://github.com/helix-editor/helix/pull/4333), [#4821](https://github.com/helix-editor/helix/pull/4821))\n- Diff ([#3708](https://github.com/helix-editor/helix/pull/3708))\n- Nix ([665e27f](https://github.com/helix-editor/helix/commit/665e27f), [1fe3273](https://github.com/helix-editor/helix/commit/1fe3273))\n- Markdown ([#3749](https://github.com/helix-editor/helix/pull/3749), [#4078](https://github.com/helix-editor/helix/pull/4078), [#4483](https://github.com/helix-editor/helix/pull/4483), [#4478](https://github.com/helix-editor/helix/pull/4478))\n- GDScript ([#3760](https://github.com/helix-editor/helix/pull/3760))\n- JSX and TSX ([#3853](https://github.com/helix-editor/helix/pull/3853), [#3973](https://github.com/helix-editor/helix/pull/3973))\n- Ruby ([#3976](https://github.com/helix-editor/helix/pull/3976), [#4601](https://github.com/helix-editor/helix/pull/4601))\n- R ([#4031](https://github.com/helix-editor/helix/pull/4031))\n- WGSL ([#3996](https://github.com/helix-editor/helix/pull/3996), [#4079](https://github.com/helix-editor/helix/pull/4079))\n- C# ([#4118](https://github.com/helix-editor/helix/pull/4118), [#4281](https://github.com/helix-editor/helix/pull/4281), [#4213](https://github.com/helix-editor/helix/pull/4213))\n- Twig ([#4176](https://github.com/helix-editor/helix/pull/4176))\n- Lua ([#3552](https://github.com/helix-editor/helix/pull/3552))\n- C/C++ ([#4079](https://github.com/helix-editor/helix/pull/4079), [#4278](https://github.com/helix-editor/helix/pull/4278), [#4282](https://github.com/helix-editor/helix/pull/4282))\n- Cairo ([17488f1](https://github.com/helix-editor/helix/commit/17488f1), [431f9c1](https://github.com/helix-editor/helix/commit/431f9c1), [09a6df1](https://github.com/helix-editor/helix/commit/09a6df1))\n- Rescript ([#4356](https://github.com/helix-editor/helix/pull/4356))\n- Zig ([#4409](https://github.com/helix-editor/helix/pull/4409))\n- Scala ([#4353](https://github.com/helix-editor/helix/pull/4353), [#4697](https://github.com/helix-editor/helix/pull/4697), [#4701](https://github.com/helix-editor/helix/pull/4701))\n- LaTeX ([#4528](https://github.com/helix-editor/helix/pull/4528), [#4922](https://github.com/helix-editor/helix/pull/4922))\n- SQL ([#4529](https://github.com/helix-editor/helix/pull/4529))\n- Python ([#4560](https://github.com/helix-editor/helix/pull/4560))\n- Bash/Zsh ([#4582](https://github.com/helix-editor/helix/pull/4582))\n- Nu ([#4583](https://github.com/helix-editor/helix/pull/4583))\n- Julia ([#4588](https://github.com/helix-editor/helix/pull/4588))\n- Typescript ([#4703](https://github.com/helix-editor/helix/pull/4703))\n- Meson ([#4572](https://github.com/helix-editor/helix/pull/4572))\n- Haskell ([#4800](https://github.com/helix-editor/helix/pull/4800))\n- CMake ([#4809](https://github.com/helix-editor/helix/pull/4809))\n- HTML ([#4829](https://github.com/helix-editor/helix/pull/4829), [#4881](https://github.com/helix-editor/helix/pull/4881))\n- Java ([#4886](https://github.com/helix-editor/helix/pull/4886))\n- Go ([#4906](https://github.com/helix-editor/helix/pull/4906), [#4969](https://github.com/helix-editor/helix/pull/4969), [#5010](https://github.com/helix-editor/helix/pull/5010))\n- CSS ([#4882](https://github.com/helix-editor/helix/pull/4882))\n- Racket ([#4915](https://github.com/helix-editor/helix/pull/4915))\n- SCSS ([#5003](https://github.com/helix-editor/helix/pull/5003))\n\nPackaging:\n\n- Filter relevant source files in the Nix flake ([#3657](https://github.com/helix-editor/helix/pull/3657))\n- Build a binary for `aarch64-linux` in the release CI ([038a91d](https://github.com/helix-editor/helix/commit/038a91d))\n- Build an AppImage for `aarch64-linux` in the release CI ([b738031](https://github.com/helix-editor/helix/commit/b738031))\n- Enable CI builds for `riscv64-linux` ([#3685](https://github.com/helix-editor/helix/pull/3685))\n- Support preview releases in CI ([0090a2d](https://github.com/helix-editor/helix/commit/0090a2d))\n- Strip binaries built in CI ([#3780](https://github.com/helix-editor/helix/pull/3780))\n- Fix the development shell for the Nix Flake on `aarch64-darwin` ([#3810](https://github.com/helix-editor/helix/pull/3810))\n- Raise the MSRV and create an MSRV policy ([#3896](https://github.com/helix-editor/helix/pull/3896), [#3913](https://github.com/helix-editor/helix/pull/3913), [#3961](https://github.com/helix-editor/helix/pull/3961))\n- Fix Fish completions for `--config` and `--log` flags ([#3912](https://github.com/helix-editor/helix/pull/3912))\n- Use builtin filenames option in Bash completion ([#4648](https://github.com/helix-editor/helix/pull/4648))\n\n# 22.08.1 (2022-09-01)\n\nThis is a patch release that fixes a panic caused by closing splits or buffers. ([#3633](https://github.com/helix-editor/helix/pull/3633))\n\n# 22.08 (2022-08-31)\n\nA big _thank you_ to our contributors! This release had 87 contributors.\n\nAs usual, the following is a summary of each of the changes since the last release.\nFor the full log, check out the [git log](https://github.com/helix-editor/helix/compare/22.05..22.08).\n\nBreaking changes:\n\n- Special keymap names for `+`, `;` and `%` have been replaced with those literal characters ([#2677](https://github.com/helix-editor/helix/pull/2677), [#3556](https://github.com/helix-editor/helix/pull/3556))\n- `A-Left` and `A-Right` have become `C-Left` and `C-Right` for word-wise motion ([#2500](https://github.com/helix-editor/helix/pull/2500))\n- The `catppuccin` theme's name has been corrected from `catpuccin` ([#2713](https://github.com/helix-editor/helix/pull/2713))\n- `catppuccin` has been replaced by its variants, `catppuccin_frappe`, `catppuccin_latte`, `catppuccin_macchiato`, `catppuccin_mocha` ([#3281](https://github.com/helix-editor/helix/pull/3281))\n- `C-n` and `C-p` have been removed from the default insert mode keymap ([#3340](https://github.com/helix-editor/helix/pull/3340))\n- The `extend_line` command has been replaced with `extend_line_below` and a new `extend_line` command now exists ([#3046](https://github.com/helix-editor/helix/pull/3046))\n\nFeatures:\n\n- Add an integration testing harness ([#2359](https://github.com/helix-editor/helix/pull/2359))\n- Indent guides ([#1796](https://github.com/helix-editor/helix/pull/1796), [906259c](https://github.com/helix-editor/helix/commit/906259c))\n- Cursorline ([#2170](https://github.com/helix-editor/helix/pull/2170), [fde9e03](https://github.com/helix-editor/helix/commit/fde9e03))\n- Select all instances of the symbol under the cursor (`<space>h`) ([#2738](https://github.com/helix-editor/helix/pull/2738))\n- A picker for document and workspace LSP diagnostics (`<space>g`/`<space>G`) ([#2013](https://github.com/helix-editor/helix/pull/2013), [#2984](https://github.com/helix-editor/helix/pull/2984))\n- Allow styling the mode indicator per-mode ([#2676](https://github.com/helix-editor/helix/pull/2676))\n- Live preview for the theme picker ([#1798](https://github.com/helix-editor/helix/pull/1798))\n- Configurable statusline ([#2434](https://github.com/helix-editor/helix/pull/2434))\n- LSP SignatureHelp ([#1755](https://github.com/helix-editor/helix/pull/1755), [a8b123f](https://github.com/helix-editor/helix/commit/a8b123f))\n- A picker for the jumplist ([#3033](https://github.com/helix-editor/helix/pull/3033))\n- Configurable external formatter binaries ([#2942](https://github.com/helix-editor/helix/pull/2942))\n- Bracketed paste support ([#3233](https://github.com/helix-editor/helix/pull/3233), [12ddd03](https://github.com/helix-editor/helix/commit/12ddd03))\n\nCommands:\n\n- `:insert-output` and `:append-output` which insert/append output from a shell command ([#2589](https://github.com/helix-editor/helix/pull/2589))\n- The `t` textobject (`]t`/`[t`/`mit`/`mat`) for navigating tests ([#2807](https://github.com/helix-editor/helix/pull/2807))\n- `C-Backspace` and `C-Delete` for word-wise deletion in prompts and pickers ([#2500](https://github.com/helix-editor/helix/pull/2500))\n- `A-Delete` for forward word-wise deletion in insert mode ([#2500](https://github.com/helix-editor/helix/pull/2500))\n- `C-t` for toggling the preview pane in pickers ([#3021](https://github.com/helix-editor/helix/pull/3021))\n- `extend_line` now extends in the direction of the cursor ([#3046](https://github.com/helix-editor/helix/pull/3046))\n\nUsability improvements and fixes:\n\n- Fix tree-sitter parser builds on illumos ([#2602](https://github.com/helix-editor/helix/pull/2602))\n- Remove empty stratch buffer from jumplists when removing ([5ed6223](https://github.com/helix-editor/helix/commit/5ed6223))\n- Fix panic on undo after `shell_append_output` ([#2625](https://github.com/helix-editor/helix/pull/2625))\n- Sort LSP edits by start range ([3d91c99](https://github.com/helix-editor/helix/commit/3d91c99))\n- Be more defensive about LSP URI conversions ([6de6a3e](https://github.com/helix-editor/helix/commit/6de6a3e), [378f438](https://github.com/helix-editor/helix/commit/378f438))\n- Ignore SendErrors when grammar builds fail ([#2641](https://github.com/helix-editor/helix/pull/2641))\n- Append `set_line_ending` to document history ([#2649](https://github.com/helix-editor/helix/pull/2649))\n- Use last prompt entry when empty ([b14c258](https://github.com/helix-editor/helix/commit/b14c258), [#2870](https://github.com/helix-editor/helix/pull/2870))\n- Do not add extra line breaks in markdown lists ([#2689](https://github.com/helix-editor/helix/pull/2689))\n- Disable dialyzer by default for ElixirLS ([#2710](https://github.com/helix-editor/helix/pull/2710))\n- Refactor textobject node capture ([#2741](https://github.com/helix-editor/helix/pull/2741))\n- Prevent re-selecting the same range with `expand_selection` ([#2760](https://github.com/helix-editor/helix/pull/2760))\n- Introduce `keyword.storage` highlight scope ([#2731](https://github.com/helix-editor/helix/pull/2731))\n- Handle symlinks more consistently ([#2718](https://github.com/helix-editor/helix/pull/2718))\n- Improve markdown list rendering ([#2687](https://github.com/helix-editor/helix/pull/2687))\n- Update auto-pairs and idle-timeout settings when the config is reloaded ([#2736](https://github.com/helix-editor/helix/pull/2736))\n- Fix panic on closing last buffer ([#2658](https://github.com/helix-editor/helix/pull/2658))\n- Prevent modifying jumplist until jumping to a reference ([#2670](https://github.com/helix-editor/helix/pull/2670))\n- Ensure `:quit` and `:quit!` take no arguments ([#2654](https://github.com/helix-editor/helix/pull/2654))\n- Fix crash due to cycles when replaying macros ([#2647](https://github.com/helix-editor/helix/pull/2647))\n- Pass LSP FormattingOptions ([#2635](https://github.com/helix-editor/helix/pull/2635))\n- Prevent showing colors when the health-check is piped ([#2836](https://github.com/helix-editor/helix/pull/2836))\n- Use character indexing for mouse selection ([#2839](https://github.com/helix-editor/helix/pull/2839))\n- Display the highest severity diagnostic for a line in the gutter ([#2835](https://github.com/helix-editor/helix/pull/2835))\n- Default the ruler color to red background ([#2669](https://github.com/helix-editor/helix/pull/2669))\n- Make `move_vertically` aware of tabs and wide characters ([#2620](https://github.com/helix-editor/helix/pull/2620))\n- Enable shellwords for Windows ([#2767](https://github.com/helix-editor/helix/pull/2767))\n- Add history suggestions to global search ([#2717](https://github.com/helix-editor/helix/pull/2717))\n- Fix the scrollbar's length proportional to total menu items ([#2860](https://github.com/helix-editor/helix/pull/2860))\n- Reset terminal modifiers for diagnostic text ([#2861](https://github.com/helix-editor/helix/pull/2861), [#2900](https://github.com/helix-editor/helix/pull/2900))\n- Redetect indents and line-endings after a Language Server replaces the document ([#2778](https://github.com/helix-editor/helix/pull/2778))\n- Check selection's visible width when copying on mouse click ([#2711](https://github.com/helix-editor/helix/pull/2711))\n- Fix edge-case in tree-sitter `expand_selection` command ([#2877](https://github.com/helix-editor/helix/pull/2877))\n- Add a single-width left margin for the completion popup ([#2728](https://github.com/helix-editor/helix/pull/2728))\n- Right-align the scrollbar in the completion popup ([#2754](https://github.com/helix-editor/helix/pull/2754))\n- Fix recursive macro crash and empty macro lockout ([#2902](https://github.com/helix-editor/helix/pull/2902))\n- Fix backwards character deletion on other whitespaces ([#2855](https://github.com/helix-editor/helix/pull/2855))\n- Add search and space/backspace bindings to view modes ([#2803](https://github.com/helix-editor/helix/pull/2803))\n- Add `--vsplit` and `--hsplit` CLI arguments for opening in splits ([#2773](https://github.com/helix-editor/helix/pull/2773), [#3073](https://github.com/helix-editor/helix/pull/3073))\n- Sort themes, languages and files inputs by score and name ([#2675](https://github.com/helix-editor/helix/pull/2675))\n- Highlight entire rows in ([#2939](https://github.com/helix-editor/helix/pull/2939))\n- Fix backwards selection duplication widening bug ([#2945](https://github.com/helix-editor/helix/pull/2945), [#3024](https://github.com/helix-editor/helix/pull/3024))\n- Skip serializing Option type DAP fields ([44f5963](https://github.com/helix-editor/helix/commit/44f5963))\n- Fix required `cwd` field in DAP `RunTerminalArguments` type ([85411be](https://github.com/helix-editor/helix/commit/85411be), [#3240](https://github.com/helix-editor/helix/pull/3240))\n- Add LSP `workspace/applyEdit` to client capabilities ([#3012](https://github.com/helix-editor/helix/pull/3012))\n- Respect count for repeating motion ([#3057](https://github.com/helix-editor/helix/pull/3057))\n- Respect count for selecting next/previous match ([#3056](https://github.com/helix-editor/helix/pull/3056))\n- Respect count for tree-sitter motions ([#3058](https://github.com/helix-editor/helix/pull/3058))\n- Make gutters padding optional ([#2996](https://github.com/helix-editor/helix/pull/2996))\n- Support pre-filling prompts ([#2459](https://github.com/helix-editor/helix/pull/2459), [#3259](https://github.com/helix-editor/helix/pull/3259))\n- Add statusline element to display file line-endings ([#3113](https://github.com/helix-editor/helix/pull/3113))\n- Keep jump and file history when using `:split` ([#3031](https://github.com/helix-editor/helix/pull/3031), [#3160](https://github.com/helix-editor/helix/pull/3160))\n- Make tree-sitter query `; inherits <language>` feature imperative ([#2470](https://github.com/helix-editor/helix/pull/2470))\n- Indent with tabs by default ([#3095](https://github.com/helix-editor/helix/pull/3095))\n- Fix non-msvc grammar compilation on Windows ([#3190](https://github.com/helix-editor/helix/pull/3190))\n- Add spacer element to the statusline ([#3165](https://github.com/helix-editor/helix/pull/3165), [255c173](https://github.com/helix-editor/helix/commit/255c173))\n- Make gutters padding automatic ([#3163](https://github.com/helix-editor/helix/pull/3163))\n- Add `code` for LSP `Diagnostic` type ([#3096](https://github.com/helix-editor/helix/pull/3096))\n- Add position percentage to the statusline ([#3168](https://github.com/helix-editor/helix/pull/3168))\n- Add a configurable and themable statusline separator string ([#3175](https://github.com/helix-editor/helix/pull/3175))\n- Use OR of all selections when `search_selection` acts on multiple selections ([#3138](https://github.com/helix-editor/helix/pull/3138))\n- Add clipboard information to logs and the healthcheck ([#3271](https://github.com/helix-editor/helix/pull/3271))\n- Fix align selection behavior on tabs ([#3276](https://github.com/helix-editor/helix/pull/3276))\n- Fix terminal cursor shape reset ([#3289](https://github.com/helix-editor/helix/pull/3289))\n- Add an `injection.include-unnamed-children` predicate to injections queries ([#3129](https://github.com/helix-editor/helix/pull/3129))\n- Add a `-c`/`--config` CLI flag for specifying config file location ([#2666](https://github.com/helix-editor/helix/pull/2666))\n- Detect indent-style in `:set-language` command ([#3330](https://github.com/helix-editor/helix/pull/3330))\n- Fix non-deterministic highlighting ([#3275](https://github.com/helix-editor/helix/pull/3275))\n- Avoid setting the stdin handle when not necessary ([#3248](https://github.com/helix-editor/helix/pull/3248), [#3379](https://github.com/helix-editor/helix/pull/3379))\n- Fix indent guide styling ([#3324](https://github.com/helix-editor/helix/pull/3324))\n- Fix tab highlight when tab is partially visible ([#3313](https://github.com/helix-editor/helix/pull/3313))\n- Add completion for nested settings ([#3183](https://github.com/helix-editor/helix/pull/3183))\n- Advertise WorkspaceSymbolClientCapabilities LSP client capability ([#3361](https://github.com/helix-editor/helix/pull/3361))\n- Remove duplicate entries from the theme picker ([#3439](https://github.com/helix-editor/helix/pull/3439))\n- Shorted output for grammar fetching and building ([#3396](https://github.com/helix-editor/helix/pull/3396))\n- Add a `tabpad` option for visible tab padding whitespace characters ([#3458](https://github.com/helix-editor/helix/pull/3458))\n- Make DAP external terminal provider configurable ([cb7615e](https://github.com/helix-editor/helix/commit/cb7615e))\n- Use health checkmark character with shorter width ([#3505](https://github.com/helix-editor/helix/pull/3505))\n- Reset document mode to normal on view focus loss ([e4c9d40](https://github.com/helix-editor/helix/commit/e4c9d40))\n- Render indented code-blocks in markdown ([#3503](https://github.com/helix-editor/helix/pull/3503))\n- Add WezTerm to DAP terminal provider defaults ([#3588](https://github.com/helix-editor/helix/pull/3588))\n- Derive `Document` language name from `languages.toml` `name` key ([#3338](https://github.com/helix-editor/helix/pull/3338))\n- Fix process spawning error handling ([#3349](https://github.com/helix-editor/helix/pull/3349))\n- Don't resolve links for `:o` completion ([8a4fbf6](https://github.com/helix-editor/helix/commit/8a4fbf6))\n- Recalculate completion after pasting into prompt ([e77b7d1](https://github.com/helix-editor/helix/commit/e77b7d1))\n- Fix extra selections with regex anchors ([#3598](https://github.com/helix-editor/helix/pull/3598))\n- Move mode transition logic to `handle_keymap_event` ([#2634](https://github.com/helix-editor/helix/pull/2634))\n- Add documents to view history when using the jumplist ([#3593](https://github.com/helix-editor/helix/pull/3593))\n- Prevent panic when loading tree-sitter queries ([fa1dc7e](https://github.com/helix-editor/helix/commit/fa1dc7e))\n- Discard LSP publishDiagnostic when LS is not initialized ([#3403](https://github.com/helix-editor/helix/pull/3403))\n- Refactor tree-sitter textobject motions as repeatable motions ([#3264](https://github.com/helix-editor/helix/pull/3264))\n- Avoid command execution hooks on closed docs ([#3613](https://github.com/helix-editor/helix/pull/3613))\n- Share `restore_term` code between panic and normal exits ([#2612](https://github.com/helix-editor/helix/pull/2612))\n- Show clipboard info in `--health` output ([#2947](https://github.com/helix-editor/helix/pull/2947))\n- Recalculate completion when going through prompt history ([#3193](https://github.com/helix-editor/helix/pull/3193))\n\nThemes:\n\n- Update `tokyonight` and `tokyonight_storm` themes ([#2606](https://github.com/helix-editor/helix/pull/2606))\n- Update `solarized_light` themes ([#2626](https://github.com/helix-editor/helix/pull/2626))\n- Fix `catpuccin` `ui.popup` theme ([#2644](https://github.com/helix-editor/helix/pull/2644))\n- Update selection style of `night_owl` ([#2668](https://github.com/helix-editor/helix/pull/2668))\n- Fix spelling of `catppuccin` theme ([#2713](https://github.com/helix-editor/helix/pull/2713))\n- Update `base16_default`'s `ui.menu` ([#2794](https://github.com/helix-editor/helix/pull/2794))\n- Add `noctis_bordo` ([#2830](https://github.com/helix-editor/helix/pull/2830))\n- Add `acme` ([#2876](https://github.com/helix-editor/helix/pull/2876))\n- Add `meliora` ([#2884](https://github.com/helix-editor/helix/pull/2884), [#2890](https://github.com/helix-editor/helix/pull/2890))\n- Add cursorline scopes to various themes ([33d287a](https://github.com/helix-editor/helix/commit/33d287a), [#2892](https://github.com/helix-editor/helix/pull/2892), [#2915](https://github.com/helix-editor/helix/pull/2915), [#2916](https://github.com/helix-editor/helix/pull/2916), [#2918](https://github.com/helix-editor/helix/pull/2918), [#2927](https://github.com/helix-editor/helix/pull/2927), [#2925](https://github.com/helix-editor/helix/pull/2925), [#2938](https://github.com/helix-editor/helix/pull/2938), [#2962](https://github.com/helix-editor/helix/pull/2962), [#3054](https://github.com/helix-editor/helix/pull/3054))\n- Add mode colors to various themes ([#2926](https://github.com/helix-editor/helix/pull/2926), [#2933](https://github.com/helix-editor/helix/pull/2933), [#2929](https://github.com/helix-editor/helix/pull/2929), [#3098](https://github.com/helix-editor/helix/pull/3098), [#3104](https://github.com/helix-editor/helix/pull/3104), [#3128](https://github.com/helix-editor/helix/pull/3128), [#3135](https://github.com/helix-editor/helix/pull/3135), [#3200](https://github.com/helix-editor/helix/pull/3200))\n- Add `nord_light` ([#2908](https://github.com/helix-editor/helix/pull/2908))\n- Update `night_owl` ([#2929](https://github.com/helix-editor/helix/pull/2929))\n- Update `autumn` ([2e70985](https://github.com/helix-editor/helix/commit/2e70985), [936ed3a](https://github.com/helix-editor/helix/commit/936ed3a))\n- Update `one_dark` ([#3011](https://github.com/helix-editor/helix/pull/3011))\n- Add `noctis` ([#3043](https://github.com/helix-editor/helix/pull/3043), [#3128](https://github.com/helix-editor/helix/pull/3128))\n- Update `boo_berry` ([#3191](https://github.com/helix-editor/helix/pull/3191))\n- Update `monokai` ([#3131](https://github.com/helix-editor/helix/pull/3131))\n- Add `ayu_dark`, `ayu_light`, `ayu_mirage` ([#3184](https://github.com/helix-editor/helix/pull/3184))\n- Update `onelight` ([#3226](https://github.com/helix-editor/helix/pull/3226))\n- Add `base16_transparent` ([#3216](https://github.com/helix-editor/helix/pull/3216), [b565fff](https://github.com/helix-editor/helix/commit/b565fff))\n- Add `flatwhite` ([#3236](https://github.com/helix-editor/helix/pull/3236))\n- Update `dark_plus` ([#3302](https://github.com/helix-editor/helix/pull/3302))\n- Add `doom_acario_dark` ([#3308](https://github.com/helix-editor/helix/pull/3308), [#3539](https://github.com/helix-editor/helix/pull/3539))\n- Add `rose_pine_moon` ([#3229](https://github.com/helix-editor/helix/pull/3229))\n- Update `spacebones_light` ([#3342](https://github.com/helix-editor/helix/pull/3342))\n- Fix typos in themes ([8deaebd](https://github.com/helix-editor/helix/commit/8deaebd), [#3412](https://github.com/helix-editor/helix/pull/3412))\n- Add `emacs` ([#3410](https://github.com/helix-editor/helix/pull/3410))\n- Add `papercolor-light` ([#3426](https://github.com/helix-editor/helix/pull/3426), [#3470](https://github.com/helix-editor/helix/pull/3470), [#3585](https://github.com/helix-editor/helix/pull/3585))\n- Add `penumbra+` ([#3398](https://github.com/helix-editor/helix/pull/3398))\n- Add `fleetish` ([#3591](https://github.com/helix-editor/helix/pull/3591), [#3607](https://github.com/helix-editor/helix/pull/3607))\n- Add `sonokai` ([#3595](https://github.com/helix-editor/helix/pull/3595))\n- Update all themes for theme lints ([#3587](https://github.com/helix-editor/helix/pull/3587))\n\nLSP:\n\n- V ([#2526](https://github.com/helix-editor/helix/pull/2526))\n- Prisma ([#2703](https://github.com/helix-editor/helix/pull/2703))\n- Clojure ([#2780](https://github.com/helix-editor/helix/pull/2780))\n- WGSL ([#2872](https://github.com/helix-editor/helix/pull/2872))\n- Elvish ([#2948](https://github.com/helix-editor/helix/pull/2948))\n- Idris ([#2971](https://github.com/helix-editor/helix/pull/2971))\n- Fortran ([#3025](https://github.com/helix-editor/helix/pull/3025))\n- Gleam ([#3139](https://github.com/helix-editor/helix/pull/3139))\n- Odin ([#3214](https://github.com/helix-editor/helix/pull/3214))\n\nNew languages:\n\n- V ([#2526](https://github.com/helix-editor/helix/pull/2526))\n- EDoc ([#2640](https://github.com/helix-editor/helix/pull/2640))\n- JSDoc ([#2650](https://github.com/helix-editor/helix/pull/2650))\n- OpenSCAD ([#2680](https://github.com/helix-editor/helix/pull/2680))\n- Prisma ([#2703](https://github.com/helix-editor/helix/pull/2703))\n- Clojure ([#2780](https://github.com/helix-editor/helix/pull/2780))\n- Starlark ([#2903](https://github.com/helix-editor/helix/pull/2903))\n- Elvish ([#2948](https://github.com/helix-editor/helix/pull/2948))\n- Fortran ([#3025](https://github.com/helix-editor/helix/pull/3025))\n- Ungrammar ([#3048](https://github.com/helix-editor/helix/pull/3048))\n- SCSS ([#3074](https://github.com/helix-editor/helix/pull/3074))\n- Go Template ([#3091](https://github.com/helix-editor/helix/pull/3091))\n- Graphviz dot ([#3241](https://github.com/helix-editor/helix/pull/3241))\n- Cue ([#3262](https://github.com/helix-editor/helix/pull/3262))\n- Slint ([#3355](https://github.com/helix-editor/helix/pull/3355))\n- Beancount ([#3297](https://github.com/helix-editor/helix/pull/3297))\n- Taskwarrior ([#3468](https://github.com/helix-editor/helix/pull/3468))\n- xit ([#3521](https://github.com/helix-editor/helix/pull/3521))\n- ESDL ([#3526](https://github.com/helix-editor/helix/pull/3526))\n- Awk ([#3528](https://github.com/helix-editor/helix/pull/3528), [#3535](https://github.com/helix-editor/helix/pull/3535))\n- Pascal ([#3542](https://github.com/helix-editor/helix/pull/3542))\n\nUpdated languages and queries:\n\n- Nix ([#2472](https://github.com/helix-editor/helix/pull/2472))\n- Elixir ([#2619](https://github.com/helix-editor/helix/pull/2619))\n- CPON ([#2643](https://github.com/helix-editor/helix/pull/2643))\n- Textobjects queries for Erlang, Elixir, Gleam ([#2661](https://github.com/helix-editor/helix/pull/2661))\n- Capture rust closures as function textobjects ([4a27e2d](https://github.com/helix-editor/helix/commit/4a27e2d))\n- Heex ([#2800](https://github.com/helix-editor/helix/pull/2800), [#3170](https://github.com/helix-editor/helix/pull/3170))\n- Add `<<=` operator highlighting for Rust ([#2805](https://github.com/helix-editor/helix/pull/2805))\n- Fix comment injection in JavaScript/TypeScript ([#2763](https://github.com/helix-editor/helix/pull/2763))\n- Nickel ([#2859](https://github.com/helix-editor/helix/pull/2859))\n- Add `Rakefile` and `Gemfile` to Ruby file-types ([#2875](https://github.com/helix-editor/helix/pull/2875))\n- Erlang ([#2910](https://github.com/helix-editor/helix/pull/2910), [ac669ad](https://github.com/helix-editor/helix/commit/ac669ad))\n- Markdown ([#2910](https://github.com/helix-editor/helix/pull/2910), [#3108](https://github.com/helix-editor/helix/pull/3108), [#3400](https://github.com/helix-editor/helix/pull/3400))\n- Bash ([#2910](https://github.com/helix-editor/helix/pull/2910))\n- Rust ([#2910](https://github.com/helix-editor/helix/pull/2910), [#3397](https://github.com/helix-editor/helix/pull/3397))\n- Edoc ([#2910](https://github.com/helix-editor/helix/pull/2910))\n- HTML ([#2910](https://github.com/helix-editor/helix/pull/2910))\n- Make ([#2910](https://github.com/helix-editor/helix/pull/2910))\n- TSQ ([#2910](https://github.com/helix-editor/helix/pull/2910), [#2960](https://github.com/helix-editor/helix/pull/2960))\n- git-commit ([#2910](https://github.com/helix-editor/helix/pull/2910))\n- Use default fallback for Python indents ([9ae70cc](https://github.com/helix-editor/helix/commit/9ae70cc))\n- Add Haskell LSP roots ([#2954](https://github.com/helix-editor/helix/pull/2954))\n- Ledger ([#2936](https://github.com/helix-editor/helix/pull/2936), [#2988](https://github.com/helix-editor/helix/pull/2988))\n- Nickel ([#2987](https://github.com/helix-editor/helix/pull/2987))\n- JavaScript/TypeScript ([#2961](https://github.com/helix-editor/helix/pull/2961), [#3219](https://github.com/helix-editor/helix/pull/3219), [#3213](https://github.com/helix-editor/helix/pull/3213), [#3280](https://github.com/helix-editor/helix/pull/3280), [#3301](https://github.com/helix-editor/helix/pull/3301))\n- GLSL ([#3051](https://github.com/helix-editor/helix/pull/3051))\n- Fix locals tracking in Rust ([#3027](https://github.com/helix-editor/helix/pull/3027), [#3212](https://github.com/helix-editor/helix/pull/3212), [#3345](https://github.com/helix-editor/helix/pull/3345))\n- Verilog ([#3158](https://github.com/helix-editor/helix/pull/3158))\n- Ruby ([#3173](https://github.com/helix-editor/helix/pull/3173), [#3527](https://github.com/helix-editor/helix/pull/3527))\n- Svelte ([#3147](https://github.com/helix-editor/helix/pull/3147))\n- Add Elixir and HEEx comment textobjects ([#3179](https://github.com/helix-editor/helix/pull/3179))\n- Python ([#3103](https://github.com/helix-editor/helix/pull/3103), [#3201](https://github.com/helix-editor/helix/pull/3201), [#3284](https://github.com/helix-editor/helix/pull/3284))\n- PHP ([#3317](https://github.com/helix-editor/helix/pull/3317))\n- Latex ([#3370](https://github.com/helix-editor/helix/pull/3370))\n- Clojure ([#3387](https://github.com/helix-editor/helix/pull/3387))\n- Swift ([#3461](https://github.com/helix-editor/helix/pull/3461))\n- C# ([#3480](https://github.com/helix-editor/helix/pull/3480), [#3494](https://github.com/helix-editor/helix/pull/3494))\n- Org ([#3489](https://github.com/helix-editor/helix/pull/3489))\n- Elm ([#3497](https://github.com/helix-editor/helix/pull/3497))\n- Dart ([#3419](https://github.com/helix-editor/helix/pull/3419))\n- Julia ([#3507](https://github.com/helix-editor/helix/pull/3507))\n- Fix Rust textobjects ([#3590](https://github.com/helix-editor/helix/pull/3590))\n- C ([00d88e5](https://github.com/helix-editor/helix/commit/00d88e5))\n- Update Rust ([0ef0ef9](https://github.com/helix-editor/helix/commit/0ef0ef9))\n\nPackaging:\n\n- Add `rust-analyzer` to Nix flake devShell ([#2739](https://github.com/helix-editor/helix/pull/2739))\n- Add cachix information to the Nix flake ([#2999](https://github.com/helix-editor/helix/pull/2999))\n- Pass makeWrapperArgs to wrapProgram in the Nix flake ([#3003](https://github.com/helix-editor/helix/pull/3003))\n- Add a way to override which grammars are built by Nix ([#3141](https://github.com/helix-editor/helix/pull/3141))\n- Add a GitHub actions release for `aarch64-macos` ([#3137](https://github.com/helix-editor/helix/pull/3137))\n- Add shell auto-completions for Elvish ([#3331](https://github.com/helix-editor/helix/pull/3331))\n\n# 22.05 (2022-05-28)\n\nAn even bigger shout out than usual to all the contributors - we had a whopping\n110 contributors in this release! That's more than double the number of\ncontributors as last release!\n\nCheck out some of the highlights in the [news section](https://helix-editor.com/news/release-22-05-highlights/).\n\nAs usual, the following is a summary of each of the changes since the last release.\nFor the full log, check out the [git log](https://github.com/helix-editor/helix/compare/22.03..22.05).\n\nBreaking Changes:\n\n- Removed `C-j`, `C-k` bindings from file picker ([#1792](https://github.com/helix-editor/helix/pull/1792))\n- Replaced `C-f` with `C-d` and `C-b` with `C-u` bindings in file picker ([#1792](https://github.com/helix-editor/helix/pull/1792))\n- `A-hjkl` bindings have been moved to `A-pion` ([#2205](https://github.com/helix-editor/helix/pull/2205))\n- `A-Left`/`A-Right` have been moved to `C-Left`/`C-Right` ([#2193](https://github.com/helix-editor/helix/pull/2193))\n\nFeatures:\n\n- The indentation mechanism has been reworked ([#1562](https://github.com/helix-editor/helix/pull/1562), [#1908](https://github.com/helix-editor/helix/pull/1908))\n- Configurable gutters ([#1967](https://github.com/helix-editor/helix/pull/1967))\n- Support for local language configuration ([#1249](https://github.com/helix-editor/helix/pull/1249))\n- Configurable themed rulers ([#2060](https://github.com/helix-editor/helix/pull/2060))\n- Render visible whitespace ([e6b865e](https://github.com/helix-editor/helix/commit/e6b865e), [#2322](https://github.com/helix-editor/helix/pull/2322), [#2331](https://github.com/helix-editor/helix/pull/2331))\n\nCommands:\n\n- Paragraph motion and textobject (`]p`, `[p`) ([#1627](https://github.com/helix-editor/helix/pull/1627), [#1956](https://github.com/helix-editor/helix/pull/1956), [#1969](https://github.com/helix-editor/helix/pull/1969), [#1992](https://github.com/helix-editor/helix/pull/1992), [#2226](https://github.com/helix-editor/helix/pull/2226))\n- `:buffer-next`, `:buffer-previous` ([#1940](https://github.com/helix-editor/helix/pull/1940))\n- `:set-language` to set the buffers language ([#1866](https://github.com/helix-editor/helix/pull/1866), [#1996](https://github.com/helix-editor/helix/pull/1996))\n- Command for picking files from the current working directory (`Space-F`) ([#1600](https://github.com/helix-editor/helix/pull/1600), [#2308](https://github.com/helix-editor/helix/pull/2308))\n- `:write!` which creates non-existent subdirectories ([#1839](https://github.com/helix-editor/helix/pull/1839))\n- Add `m` textobject that selects closest surrounding pair ([de15d70](https://github.com/helix-editor/helix/commit/de15d70), [76175db](https://github.com/helix-editor/helix/commit/76175db))\n- `:pipe` typable command for piping selections ([#1972](https://github.com/helix-editor/helix/pull/1972))\n- `extend_line_above` which extends to previous lines ([#2117](https://github.com/helix-editor/helix/pull/2117))\n- `set_line_ending` which replaces line endings ([#1871](https://github.com/helix-editor/helix/pull/1871))\n- `:get-option` for getting the current value of an option (`:get`) ([#2231](https://github.com/helix-editor/helix/pull/2231))\n- `:run-shell-command` which does not interact with selections ([#1682](https://github.com/helix-editor/helix/pull/1682))\n- `:reflow` which hard-wraps selected text ([#2128](https://github.com/helix-editor/helix/pull/2128))\n- `commit_undo_checkpoint` which adds an undo checkpoint ([#2115](https://github.com/helix-editor/helix/pull/2115))\n- `:log-open` which opens the log file ([#2422](https://github.com/helix-editor/helix/pull/2422))\n- `transpose_view` which transposes window splits ([#2461](https://github.com/helix-editor/helix/pull/2461))\n- View-swapping: `swap_view_right`, `swap_view_left`, `swap_view_up`, `swap_view_down` ([#2445](https://github.com/helix-editor/helix/pull/2445))\n- `shrink_to_line_bounds` which shrinks selections to line-bounds ([#2450](https://github.com/helix-editor/helix/pull/2450))\n\nUsability improvements and fixes:\n\n- Handle broken pipes when piping `hx --health` through `head` ([#1876](https://github.com/helix-editor/helix/pull/1876))\n- Fix for `copy_selection` on newlines ([ab7885e](https://github.com/helix-editor/helix/commit/ab7885e), [236c6b7](https://github.com/helix-editor/helix/commit/236c6b7))\n- Use `win32yank` clipboard provider on WSL2 ([#1912](https://github.com/helix-editor/helix/pull/1912))\n- Jump to the next number on the line before incrementing ([#1778](https://github.com/helix-editor/helix/pull/1778))\n- Fix start position of next search ([#1904](https://github.com/helix-editor/helix/pull/1904))\n- Use check and X marks for health check output ([#1918](https://github.com/helix-editor/helix/pull/1918))\n- Clear terminal after switching to alternate screens ([#1944](https://github.com/helix-editor/helix/pull/1944))\n- Fix `toggle_comments` command on multiple selections ([#1882](https://github.com/helix-editor/helix/pull/1882))\n- Apply `ui.gutter` theming to empty gutter spans ([#2032](https://github.com/helix-editor/helix/pull/2032))\n- Use checkboxes in `hx --health` output ([#1947](https://github.com/helix-editor/helix/pull/1947))\n- Pass unmapped keys through prompt regardless of modifiers ([764adbd](https://github.com/helix-editor/helix/commit/764adbd))\n- LSP: pull formatting options from config ([c18de0e](https://github.com/helix-editor/helix/commit/c18de0e))\n- LSP: provide `rootPath` ([84e799f](https://github.com/helix-editor/helix/commit/84e799f))\n- LSP: implement `workspace_folders` ([8adf0c1](https://github.com/helix-editor/helix/commit/8adf0c1))\n- LSP: fix auto-import ([#2088](https://github.com/helix-editor/helix/pull/2088))\n- Send active diagnostic to LSP when requesting code actions ([#2005](https://github.com/helix-editor/helix/pull/2005))\n- Prevent panic when parsing malformed LSP `PublishDiagnostic` ([#2160](https://github.com/helix-editor/helix/pull/2160))\n- Restore document state on completion cancel ([#2096](https://github.com/helix-editor/helix/pull/2096))\n- Only merge top-level array when merging `languages.toml` ([#2145](https://github.com/helix-editor/helix/pull/2145), [#2215](https://github.com/helix-editor/helix/pull/2215))\n- Fix open on multiline selection ([#2161](https://github.com/helix-editor/helix/pull/2161))\n- Allow re-binding `0` if it is not used in a count ([#2174](https://github.com/helix-editor/helix/pull/2174))\n- Fix `ctrl-u` behavior in insert mode ([#1957](https://github.com/helix-editor/helix/pull/1957))\n- Check LSP rename capabilities before sending rename action ([#2203](https://github.com/helix-editor/helix/pull/2203))\n- Register the `publish_diagnostics` LSP capability ([#2241](https://github.com/helix-editor/helix/pull/2241))\n- Fix paste direction for typed paste commands ([#2288](https://github.com/helix-editor/helix/pull/2288))\n- Improve handling of buffer-close ([#1397](https://github.com/helix-editor/helix/pull/1397))\n- Extend the tutor file ([#2133](https://github.com/helix-editor/helix/pull/2133))\n- Treat slashes as word separators in prompts ([#2315](https://github.com/helix-editor/helix/pull/2315))\n- Auto-complete directory members ([#1682](https://github.com/helix-editor/helix/pull/1682))\n- Allow disabling format-on-save as a global editor setting ([#2321](https://github.com/helix-editor/helix/pull/2321))\n- Wrap command palette in overlay ([#2378](https://github.com/helix-editor/helix/pull/2378))\n- Prevent selections from collapsing when inserting newlines ([#2414](https://github.com/helix-editor/helix/pull/2414))\n- Allow configuration of LSP request timeout ([#2405](https://github.com/helix-editor/helix/pull/2405))\n- Use debug console on Windows for DAP terminal ([#2294](https://github.com/helix-editor/helix/pull/2294))\n- Exclude cursor when deleting with `C-w` in insert mode ([#2431](https://github.com/helix-editor/helix/pull/2431))\n- Prevent panics from LSP parsing errors ([7ae6cad](https://github.com/helix-editor/helix/commit/7ae6cad))\n- Prevent panics from LSP responses without requests ([#2475](https://github.com/helix-editor/helix/pull/2475))\n- Fix scroll rate for documentation popups ([#2497](https://github.com/helix-editor/helix/pull/2497))\n- Support inserting into prompts from registers ([#2458](https://github.com/helix-editor/helix/pull/2458))\n- Separate theme scopes for diagnostic types ([#2437](https://github.com/helix-editor/helix/pull/2437))\n- Use `ui.menu` instead of `ui.statusline` for command completion menu theming ([82fb217](https://github.com/helix-editor/helix/commit/82fb217))\n- Panic when reloading a shrunk file ([#2506](https://github.com/helix-editor/helix/pull/2506))\n- Add theme key for picker separator ([#2523](https://github.com/helix-editor/helix/pull/2523))\n\nThemes:\n\n- Remove `ui.text` background from dark_plus ([#1950](https://github.com/helix-editor/helix/pull/1950))\n- Add `boo_berry` ([#1962](https://github.com/helix-editor/helix/pull/1962))\n- Update `dark_plus` markup colors ([#1989](https://github.com/helix-editor/helix/pull/1989))\n- Update `dark_plus` `tag` and `ui.menu.selected` colors ([#2014](https://github.com/helix-editor/helix/pull/2014))\n- Add `dracula_at_night` ([#2008](https://github.com/helix-editor/helix/pull/2008))\n- Improve `dracula` selection theming ([#2077](https://github.com/helix-editor/helix/pull/2077))\n- Remove dim attribute on `onedark` line-number gutter ([#2155](https://github.com/helix-editor/helix/pull/2155))\n- Add `tokyonight` ([#2162](https://github.com/helix-editor/helix/pull/2162))\n- Use border colors from the original `dark_plus` theme ([#2186](https://github.com/helix-editor/helix/pull/2186))\n- Add `autumn` ([#2212](https://github.com/helix-editor/helix/pull/2212), [#2270](https://github.com/helix-editor/helix/pull/2270), [#2531](https://github.com/helix-editor/helix/pull/2531))\n- Add `tokyonight_storm` ([#2240](https://github.com/helix-editor/helix/pull/2240))\n- Add `pop-dark` ([#2189](https://github.com/helix-editor/helix/pull/2189))\n- Fix `base16_terminal` theme using incorrect ansi-color ([#2279](https://github.com/helix-editor/helix/pull/2279))\n- Add `onelight` ([#2287](https://github.com/helix-editor/helix/pull/2287), [#2323](https://github.com/helix-editor/helix/pull/2323))\n- Add `ui.virtual` scopes to `onedark` theme ([3626e38](https://github.com/helix-editor/helix/commit/3626e38))\n- Add `night_owl` ([#2330](https://github.com/helix-editor/helix/pull/2330))\n- Use yellow foreground and red background for `monokai_pro_spectrum` ([#2433](https://github.com/helix-editor/helix/pull/2433))\n- Add `snazzy` ([#2473](https://github.com/helix-editor/helix/pull/2473))\n- Update `dark_plus` constructor color ([8e8d4ba](https://github.com/helix-editor/helix/commit/8e8d4ba))\n- Add `ui.menu` to the default theme ([e7e13dc](https://github.com/helix-editor/helix/commit/e7e13dc))\n- Add `ui.menu` to any themes missing the key ([9be810f](https://github.com/helix-editor/helix/commit/9be810f))\n- Add `catppuccin` ([#2546](https://github.com/helix-editor/helix/pull/2546), [7160e74](https://github.com/helix-editor/helix/commit/7160e74))\n\nLSP:\n\n- Use texlab for latex ([#1922](https://github.com/helix-editor/helix/pull/1922))\n- HTML ([#2018](https://github.com/helix-editor/helix/pull/2018))\n- JSON ([#2024](https://github.com/helix-editor/helix/pull/2024))\n- CSS ([#2025](https://github.com/helix-editor/helix/pull/2025))\n- PHP ([#2031](https://github.com/helix-editor/helix/pull/2031))\n- Swift ([#2033](https://github.com/helix-editor/helix/pull/2033))\n- OCaml ([#2035](https://github.com/helix-editor/helix/pull/2035))\n- Vue ([#2043](https://github.com/helix-editor/helix/pull/2043))\n- Yaml ([#2234](https://github.com/helix-editor/helix/pull/2234))\n- Vala ([#2243](https://github.com/helix-editor/helix/pull/2243))\n- TOML ([#2302](https://github.com/helix-editor/helix/pull/2302))\n- Java ([#2511](https://github.com/helix-editor/helix/pull/2511))\n- Lua ([#2560](https://github.com/helix-editor/helix/pull/2560))\n- Verilog ([#2552](https://github.com/helix-editor/helix/pull/2552))\n\nNew Languages:\n\n- JSX ([#1906](https://github.com/helix-editor/helix/pull/1906), [a24fb17](https://github.com/helix-editor/helix/commit/a24fb17), [855e438](https://github.com/helix-editor/helix/commit/855e438), [#1921](https://github.com/helix-editor/helix/pull/1921))\n- Rust Object Notation (RON) ([#1925](https://github.com/helix-editor/helix/pull/1925))\n- R and R Markdown ([#1998](https://github.com/helix-editor/helix/pull/1998))\n- Swift ([#2033](https://github.com/helix-editor/helix/pull/2033))\n- EJS and ERB ([#2055](https://github.com/helix-editor/helix/pull/2055))\n- EEx ([9d095e0](https://github.com/helix-editor/helix/commit/9d095e0))\n- HEEx ([4836bb3](https://github.com/helix-editor/helix/commit/4836bb3), [#2149](https://github.com/helix-editor/helix/pull/2149))\n- SQL ([#2097](https://github.com/helix-editor/helix/pull/2097))\n- GDScript ([#1985](https://github.com/helix-editor/helix/pull/1985))\n- Nickel ([#2173](https://github.com/helix-editor/helix/pull/2173), [#2320](https://github.com/helix-editor/helix/pull/2320))\n- `go.mod` and `go.work` ([#2197](https://github.com/helix-editor/helix/pull/2197))\n- Nushell ([#2225](https://github.com/helix-editor/helix/pull/2225))\n- Vala ([#2243](https://github.com/helix-editor/helix/pull/2243))\n- Hare ([#2289](https://github.com/helix-editor/helix/pull/2289), [#2480](https://github.com/helix-editor/helix/pull/2480))\n- DeviceTree ([#2329](https://github.com/helix-editor/helix/pull/2329))\n- Cairo ([7387905](https://github.com/helix-editor/helix/commit/7387905))\n- CPON ([#2355](https://github.com/helix-editor/helix/pull/2355), [#2424](https://github.com/helix-editor/helix/pull/2424))\n- git-ignore ([#2397](https://github.com/helix-editor/helix/pull/2397))\n- git-attributes ([#2397](https://github.com/helix-editor/helix/pull/2397))\n- Odin ([#2399](https://github.com/helix-editor/helix/pull/2399), [#2464](https://github.com/helix-editor/helix/pull/2464))\n- Meson ([#2314](https://github.com/helix-editor/helix/pull/2314))\n- SSH Client Config ([#2498](https://github.com/helix-editor/helix/pull/2498))\n- Scheme ([d25bae8](https://github.com/helix-editor/helix/commit/d25bae8))\n- Verilog ([#2552](https://github.com/helix-editor/helix/pull/2552))\n\nUpdated Languages and Queries:\n\n- Erlang ([e2a5071](https://github.com/helix-editor/helix/commit/e2a5071), [#2149](https://github.com/helix-editor/helix/pull/2149), [82da9bd](https://github.com/helix-editor/helix/commit/82da9bd))\n- Elixir ([1819478](https://github.com/helix-editor/helix/commit/1819478), [8c3c901](https://github.com/helix-editor/helix/commit/8c3c901), [4ac94a5](https://github.com/helix-editor/helix/commit/4ac94a5))\n- Gleam ([7cd6050](https://github.com/helix-editor/helix/commit/7cd6050), [45dd540](https://github.com/helix-editor/helix/commit/45dd540))\n- Bash ([#1917](https://github.com/helix-editor/helix/pull/1917))\n- JavaScript ([#2140](https://github.com/helix-editor/helix/pull/2140))\n- Ruby textobject queries ([#2143](https://github.com/helix-editor/helix/pull/2143))\n- Fix Golang textobject queries ([#2153](https://github.com/helix-editor/helix/pull/2153))\n- Add more bash and HCL file extensions ([#2201](https://github.com/helix-editor/helix/pull/2201))\n- Divide HCL and tfvars into separate languages ([#2244](https://github.com/helix-editor/helix/pull/2244))\n- Use JavaScript for `cjs` files ([#2387](https://github.com/helix-editor/helix/pull/2387))\n- Use Perl for `t` files ([#2395](https://github.com/helix-editor/helix/pull/2395))\n- Use `markup.list` scopes for lists ([#2401](https://github.com/helix-editor/helix/pull/2401))\n- Use PHP for `inc` files ([#2440](https://github.com/helix-editor/helix/pull/2440))\n- Improve Rust textobjects ([#2494](https://github.com/helix-editor/helix/pull/2494), [10463fe](https://github.com/helix-editor/helix/commit/10463fe))\n- Python ([#2451](https://github.com/helix-editor/helix/pull/2451))\n\nPackaging:\n\n- Use `builtins.fromTOML` in Nix Flake on Nix 2.6+ ([#1892](https://github.com/helix-editor/helix/pull/1892))\n- Shell auto-completion files are now available ([#2022](https://github.com/helix-editor/helix/pull/2022))\n- Create an AppImage on release ([#2089](https://github.com/helix-editor/helix/pull/2089))\n\n# 22.03 (2022-03-28)\n\nA big shout out to all the contributors! We had 51 contributors in this release.\n\nThis release is particularly large and featureful. Check out some of the\nhighlights in the [news section](https://helix-editor.com/news/release-22-03-highlights/).\n\nAs usual, the following is a summary of each of the changes since the last release.\nFor the full log, check out the [git log](https://github.com/helix-editor/helix/compare/v0.6.0..22.03).\n\nBreaking changes:\n\n- LSP config now lives under `editor.lsp` ([#1868](https://github.com/helix-editor/helix/pull/1868))\n- Expand-selection was moved from `]o` to `Alt-h` ([#1495](https://github.com/helix-editor/helix/pull/1495))\n\nFeatures:\n\n- Experimental Debug Adapter Protocol (DAP) support ([#574](https://github.com/helix-editor/helix/pull/574))\n- Primary cursor shape may now be customized per mode ([#1154](https://github.com/helix-editor/helix/pull/1154))\n- Overhaul incremental highlights and enable combined injections ([`6728344..4080341`](https://github.com/helix-editor/helix/compare/6728344..4080341))\n- Allow specifying file start position ([#445](https://github.com/helix-editor/helix/pull/445), [#1676](https://github.com/helix-editor/helix/pull/1676))\n- Dynamic line numbers ([#1522](https://github.com/helix-editor/helix/pull/1522))\n- Show an info box with the contents of registers ([#980](https://github.com/helix-editor/helix/pull/980))\n- Wrap-around behavior during search is now configurable ([#1516](https://github.com/helix-editor/helix/pull/1516))\n- Tree-sitter textobjects motions for classes, functions, and parameters ([#1619](https://github.com/helix-editor/helix/pull/1619), [#1708](https://github.com/helix-editor/helix/pull/1708), [#1805](https://github.com/helix-editor/helix/pull/1805))\n- Command palette: a picker for available commands ([#1400](https://github.com/helix-editor/helix/pull/1400))\n- LSP `workspace/configuration` and `workspace/didChangeConfiguration` support ([#1684](https://github.com/helix-editor/helix/pull/1684))\n- `hx --health [LANG]` command ([#1669](https://github.com/helix-editor/helix/pull/1669))\n- Refactor of the tree-sitter grammar system ([#1659](https://github.com/helix-editor/helix/pull/1659))\n  - All submodules have been removed\n  - New `hx --grammar {fetch|build}` flags for fetching and building tree-sitter grammars\n  - A custom grammar selection may now be declared with the `use-grammars` key in `languages.toml`\n\nCommands:\n\n- `:cquit!` - quit forcefully with a non-zero exit-code ([#1414](https://github.com/helix-editor/helix/pull/1414))\n- `shrink_selection` - shrink the selection to a child tree-sitter node (`Alt-j`, [#1340](https://github.com/helix-editor/helix/pull/1340))\n- `:tree-sitter-subtree` - show the tree-sitter subtree under the primary selection ([#1453](https://github.com/helix-editor/helix/pull/1453), [#1524](https://github.com/helix-editor/helix/pull/1524))\n- Add `Alt-Backspace`, `Alt-<`, `Alt->`, and `Ctrl-j` to insert mode ([#1441](https://github.com/helix-editor/helix/pull/1441))\n- `select_next_sibling`, `select_prev_sibling` - select next and previous tree-sitter nodes (`Alt-l` and `Alt-h`, [#1495](https://github.com/helix-editor/helix/pull/1495))\n- `:buffer-close-all`, `:buffer-close-all!`, `:buffer-close-others`, and `:buffer-close-others!` ([#1677](https://github.com/helix-editor/helix/pull/1677))\n- `:vsplit-new` and `:hsplit-new` - open vertical and horizontal splits with new scratch buffers ([#1763](https://github.com/helix-editor/helix/pull/1763))\n- `:open-config` to open the config file and `:refresh-config` to refresh config after changes ([#1771](https://github.com/helix-editor/helix/pull/1771), [#1803](https://github.com/helix-editor/helix/pull/1803))\n\nUsability improvements and fixes:\n\n- Prevent `:cquit` from ignoring unsaved changes ([#1414](https://github.com/helix-editor/helix/pull/1414))\n- Scrolling view keeps selections ([#1420](https://github.com/helix-editor/helix/pull/1420))\n- Only use shellwords parsing on unix platforms ([`7767703`](https://github.com/helix-editor/helix/commit/7767703))\n- Fix slash in search selector status message ([#1449](https://github.com/helix-editor/helix/pull/1449))\n- Use `std::path::MAIN_SEPARATOR` to determine completion ([`3e4f815`](https://github.com/helix-editor/helix/commit/3e4f815))\n- Expand to current node with `expand_selection` when the node has no children ([#1454](https://github.com/helix-editor/helix/pull/1454))\n- Add vertical and horizontal splits to the buffer picker ([#1502](https://github.com/helix-editor/helix/pull/1502))\n- Use the correct language ID for JavaScript & TypeScript LSP ([#1466](https://github.com/helix-editor/helix/pull/1466))\n- Run format command for all buffers being written ([#1444](https://github.com/helix-editor/helix/pull/1444))\n- Fix panics during resizing ([#1408](https://github.com/helix-editor/helix/pull/1408))\n- Fix auto-pairs with CRLF ([#1470](https://github.com/helix-editor/helix/pull/1470))\n- Fix picker scrolling when the bottom is reached ([#1567](https://github.com/helix-editor/helix/pull/1567))\n- Use markup themes for the markdown component ([#1363](https://github.com/helix-editor/helix/pull/1363))\n- Automatically commit changes to history if not in insert mode ([`2a7ae96`](https://github.com/helix-editor/helix/commit/2a7ae96))\n- Render code-actions as a menu and add padding to popup ([`094a0aa`](https://github.com/helix-editor/helix/commit/094a0aa))\n- Only render menu scrollbar if the menu doesn't fit ([`f10a06f`](https://github.com/helix-editor/helix/commit/f10a06f), [`36b975c`](https://github.com/helix-editor/helix/commit/36b975c))\n- Parse git revision instead of tag for version ([`d3221b0`](https://github.com/helix-editor/helix/commit/d3221b0), [#1674](https://github.com/helix-editor/helix/pull/1674))\n- Fix incorrect last modified buffer ([#1621](https://github.com/helix-editor/helix/pull/1621))\n- Add `PageUp`, `PageDown`, `Ctrl-u`, `Ctrl-d`, `Home`, `End` bindings to the file picker ([#1612](https://github.com/helix-editor/helix/pull/1612))\n- Display buffer IDs in the buffer picker ([#1134](https://github.com/helix-editor/helix/pull/1134))\n- Allow multi-line prompt documentation ([`2af0432`](https://github.com/helix-editor/helix/commit/2af0432))\n- Ignore the `.git` directory from the file picker ([#1604](https://github.com/helix-editor/helix/pull/1604))\n- Allow separate styling for markup heading levels ([#1618](https://github.com/helix-editor/helix/pull/1618))\n- Automatically close popups ([#1285](https://github.com/helix-editor/helix/pull/1285))\n- Allow auto-pairs tokens to be configured ([#1624](https://github.com/helix-editor/helix/pull/1624))\n- Don't indent empty lines in `indent` command ([#1653](https://github.com/helix-editor/helix/pull/1653))\n- Ignore `Enter` keypress when a menu has no selection ([#1704](https://github.com/helix-editor/helix/pull/1704))\n- Show errors when surround deletions and replacements fail ([#1709](https://github.com/helix-editor/helix/pull/1709))\n- Show infobox hints for `mi` and `ma` ([#1686](https://github.com/helix-editor/helix/pull/1686))\n- Highlight matching text in file picker suggestions ([#1635](https://github.com/helix-editor/helix/pull/1635))\n- Allow capturing multiple nodes in textobject queries ([#1611](https://github.com/helix-editor/helix/pull/1611))\n- Make repeat operator work with completion edits ([#1640](https://github.com/helix-editor/helix/pull/1640))\n- Save to the jumplist when searching ([#1718](https://github.com/helix-editor/helix/pull/1718))\n- Fix bug with auto-replacement of components in compositor ([#1711](https://github.com/helix-editor/helix/pull/1711))\n- Use Kakoune logic for `align_selection` ([#1675](https://github.com/helix-editor/helix/pull/1675))\n- Fix `follows` for `nixpkgs` in `flake.nix` ([#1729](https://github.com/helix-editor/helix/pull/1729))\n- Performance improvements for the picker ([`78fba86`](https://github.com/helix-editor/helix/commit/78fba86))\n- Rename infobox theme scopes ([#1741](https://github.com/helix-editor/helix/pull/1741))\n- Fallback to broader scopes if a theme scope is not found ([#1714](https://github.com/helix-editor/helix/pull/1714))\n- Add arrow-keys bindings for tree-sitter sibling selection commands ([#1724](https://github.com/helix-editor/helix/pull/1724))\n- Fix a bug in LSP when creating a file in a folder that does not exist ([#1775](https://github.com/helix-editor/helix/pull/1775))\n- Use `^` and `$` regex location assertions for search ([#1793](https://github.com/helix-editor/helix/pull/1793))\n- Fix register names in `insert_register` command ([#1751](https://github.com/helix-editor/helix/pull/1751))\n- Perform extend line for all selections ([#1804](https://github.com/helix-editor/helix/pull/1804))\n- Prevent panic when moving in an empty picker ([#1786](https://github.com/helix-editor/helix/pull/1786))\n- Fix line number calculations for non CR/CRLF line breaks ([`b4a282f`](https://github.com/helix-editor/helix/commit/b4a282f), [`0b96201`](https://github.com/helix-editor/helix/commit/0b96201))\n- Deploy documentation for `master` builds separately from release docs ([#1783](https://github.com/helix-editor/helix/pull/1783))\n\nThemes:\n\n- Add everforest_light ([#1412](https://github.com/helix-editor/helix/pull/1412))\n- Add gruvbox_light ([#1509](https://github.com/helix-editor/helix/pull/1509))\n- Add modified background to dracula popup ([#1434](https://github.com/helix-editor/helix/pull/1434))\n- Markup support for monokai pro themes ([#1553](https://github.com/helix-editor/helix/pull/1553))\n- Markup support for dracula theme ([#1554](https://github.com/helix-editor/helix/pull/1554))\n- Add `tag` to gruvbox theme ([#1555](https://github.com/helix-editor/helix/pull/1555))\n- Markup support for remaining themes ([#1525](https://github.com/helix-editor/helix/pull/1525))\n- Serika light and dark ([#1566](https://github.com/helix-editor/helix/pull/1566))\n- Fix rose_pine and rose_pine_dawn popup background color ([#1606](https://github.com/helix-editor/helix/pull/1606))\n- Fix hover menu item text color in base16 themes ([#1668](https://github.com/helix-editor/helix/pull/1668))\n- Update markup heading styles for everforest ([#1687](https://github.com/helix-editor/helix/pull/1687))\n- Update markup heading styles for rose_pine themes ([#1706](https://github.com/helix-editor/helix/pull/1706))\n- Style bogster cursors ([`6a6a9ab`](https://github.com/helix-editor/helix/commit/6a6a9ab))\n- Fix `ui.selection` in rose_pine themes ([#1716](https://github.com/helix-editor/helix/pull/1716))\n- Use distinct colors for cursor and matched pair in gruvbox ([#1791](https://github.com/helix-editor/helix/pull/1791))\n- Improve colors for `ui.cursor.match` capture in some themes ([#1862](https://github.com/helix-editor/helix/pull/1862))\n\nLSP:\n\n- Add default language server for JavaScript ([#1457](https://github.com/helix-editor/helix/pull/1457))\n- Add `pom.xml` as maven root directory marker ([#1496](https://github.com/helix-editor/helix/pull/1496))\n- Haskell LSP ([#1556](https://github.com/helix-editor/helix/pull/1556))\n- C-sharp LSP support ([#1788](https://github.com/helix-editor/helix/pull/1788))\n- Clean up Julia LSP config ([#1811](https://github.com/helix-editor/helix/pull/1811))\n\nNew Languages:\n\n- llvm-mir ([#1398](https://github.com/helix-editor/helix/pull/1398))\n- regex ([#1362](https://github.com/helix-editor/helix/pull/1362))\n- Make ([#1433](https://github.com/helix-editor/helix/pull/1433), [#1661](https://github.com/helix-editor/helix/pull/1661))\n- git-config ([#1426](https://github.com/helix-editor/helix/pull/1426))\n- Lean ([#1422](https://github.com/helix-editor/helix/pull/1422))\n- Elm ([#1514](https://github.com/helix-editor/helix/pull/1514))\n- GraphQL ([#1515](https://github.com/helix-editor/helix/pull/1515))\n- Twig ([#1602](https://github.com/helix-editor/helix/pull/1602))\n- Rescript ([#1616](https://github.com/helix-editor/helix/pull/1616), [#1863](https://github.com/helix-editor/helix/pull/1863))\n- Erlang ([#1657](https://github.com/helix-editor/helix/pull/1657))\n- Kotlin ([#1689](https://github.com/helix-editor/helix/pull/1689))\n- HCL ([#1705](https://github.com/helix-editor/helix/pull/1705), [#1726](https://github.com/helix-editor/helix/pull/1726))\n- Org ([#1845](https://github.com/helix-editor/helix/pull/1845))\n- Solidity ([#1848](https://github.com/helix-editor/helix/pull/1848), [#1854](https://github.com/helix-editor/helix/pull/1854))\n\nUpdated Languages and Queries:\n\n- Textobject and indent queries for c and cpp ([#1293](https://github.com/helix-editor/helix/pull/1293))\n- Fix null and boolean constant highlights for nix ([#1428](https://github.com/helix-editor/helix/pull/1428))\n- Capture markdown link text as `markup.link.text` ([#1456](https://github.com/helix-editor/helix/pull/1456))\n- Update and re-enable Haskell ([#1417](https://github.com/helix-editor/helix/pull/1417), [#1520](https://github.com/helix-editor/helix/pull/1520))\n- Update Go with generics support ([`ddbf036`](https://github.com/helix-editor/helix/commit/ddbf036))\n- Use `tree-sitter-css` for SCSS files ([#1507](https://github.com/helix-editor/helix/pull/1507))\n- Update Zig ([#1501](https://github.com/helix-editor/helix/pull/1501))\n- Update PHP ([#1521](https://github.com/helix-editor/helix/pull/1521))\n- Expand language support for comment injections ([#1527](https://github.com/helix-editor/helix/pull/1527))\n- Use tree-sitter-bash for `.zshrc` and `.bashrc` ([`7d51042`](https://github.com/helix-editor/helix/commit/7d51042))\n- Use tree-sitter-bash for `.bash_profile` ([#1571](https://github.com/helix-editor/helix/pull/1571))\n- Use tree-sitter-bash for `.zshenv` and ZSH files ([#1574](https://github.com/helix-editor/helix/pull/1574))\n- IEx ([#1576](https://github.com/helix-editor/helix/pull/1576))\n- Textobject queries for PHP ([#1601](https://github.com/helix-editor/helix/pull/1601))\n- C-sharp highlight query improvements ([#1795](https://github.com/helix-editor/helix/pull/1795))\n- Git commit performance has been improved on large verbose commits ([#1838](https://github.com/helix-editor/helix/pull/1838))\n\nPackaging:\n\n- The submodules system has been replaced with command-line flags for fetching and building tree-sitter grammars ([#1659](https://github.com/helix-editor/helix/pull/1659))\n- Flake outputs are pushed to Cachix on each push to `master` ([#1721](https://github.com/helix-editor/helix/pull/1721))\n- Update flake's `nix-cargo-integration` to depend on `dream2nix` ([#1758](https://github.com/helix-editor/helix/pull/1758))\n\n# 0.6.0 (2022-01-04)\n\nHappy new year and a big shout out to all the contributors! We had 55 contributors in this release.\n\nHelix has popped up in DPorts and Fedora Linux via COPR ([#1270](https://github.com/helix-editor/helix/pull/1270))\n\nAs usual the following is a brief summary, refer to the git history for a full log:\n\nBreaking changes:\n\n- fix: Normalize backtab into shift-tab\n\nFeatures:\n\n- Macros ([#1234](https://github.com/helix-editor/helix/pull/1234))\n- Add reverse search functionality ([#958](https://github.com/helix-editor/helix/pull/958))\n- Allow keys to be mapped to sequences of commands ([#589](https://github.com/helix-editor/helix/pull/589))\n- Make it possible to keybind TypableCommands ([#1169](https://github.com/helix-editor/helix/pull/1169))\n- Detect workspace root using language markers ([#1370](https://github.com/helix-editor/helix/pull/1370))\n- Add WORD textobject ([#991](https://github.com/helix-editor/helix/pull/991))\n- Add LSP rename_symbol (`space-r`) ([#1011](https://github.com/helix-editor/helix/pull/1011))\n- Added workspace_symbol_picker ([#1041](https://github.com/helix-editor/helix/pull/1041))\n- Detect filetype from shebang line ([#1001](https://github.com/helix-editor/helix/pull/1001))\n- Allow piping from stdin into a buffer on startup ([#996](https://github.com/helix-editor/helix/pull/996))\n- Add auto pairs for same-char pairs ([#1219](https://github.com/helix-editor/helix/pull/1219))\n- Update settings at runtime ([#798](https://github.com/helix-editor/helix/pull/798))\n- Enable thin LTO ([`cccc194`](https://github.com/helix-editor/helix/commit/cccc194))\n\nCommands:\n\n- `:wonly` -- window only ([#1057](https://github.com/helix-editor/helix/pull/1057))\n- buffer-close (`:bc`, `:bclose`) ([#1035](https://github.com/helix-editor/helix/pull/1035))\n- Add `:<line>` and `:goto <line>` commands ([#1128](https://github.com/helix-editor/helix/pull/1128))\n- `:sort` command ([#1288](https://github.com/helix-editor/helix/pull/1288))\n- Add m textobject for pair under cursor ([#961](https://github.com/helix-editor/helix/pull/961))\n- Implement \"Goto next buffer / Goto previous buffer\" commands ([#950](https://github.com/helix-editor/helix/pull/950))\n- Implement \"Goto last modification\" command ([#1067](https://github.com/helix-editor/helix/pull/1067))\n- Add trim_selections command ([#1092](https://github.com/helix-editor/helix/pull/1092))\n- Add movement shortcut for history ([#1088](https://github.com/helix-editor/helix/pull/1088))\n- Add command to inc/dec number under cursor ([#1027](https://github.com/helix-editor/helix/pull/1027))\n  - Add support for dates for increment/decrement\n- Align selections (`&`) ([#1101](https://github.com/helix-editor/helix/pull/1101))\n- Implement no-yank delete/change ([#1099](https://github.com/helix-editor/helix/pull/1099))\n- Implement black hole register ([#1165](https://github.com/helix-editor/helix/pull/1165))\n- `gf` as goto_file (`gf`) ([#1102](https://github.com/helix-editor/helix/pull/1102))\n- Add last modified file (`gm`) ([#1093](https://github.com/helix-editor/helix/pull/1093))\n- ensure_selections_forward ([#1393](https://github.com/helix-editor/helix/pull/1393))\n- Readline style insert mode ([#1039](https://github.com/helix-editor/helix/pull/1039))\n\nUsability improvements and fixes:\n\n- Detect filetype on `:write` ([#1141](https://github.com/helix-editor/helix/pull/1141))\n- Add single and double quotes to matching pairs ([#995](https://github.com/helix-editor/helix/pull/995))\n- Launch with defaults upon invalid config/theme (rather than panicking) ([#982](https://github.com/helix-editor/helix/pull/982))\n- If switching away from an empty scratch buffer, remove it ([#935](https://github.com/helix-editor/helix/pull/935))\n- Truncate the starts of file paths instead of the ends in picker ([#951](https://github.com/helix-editor/helix/pull/951))\n- Truncate the start of file paths in the StatusLine ([#1351](https://github.com/helix-editor/helix/pull/1351))\n- Prevent picker from previewing binaries or large file ([#939](https://github.com/helix-editor/helix/pull/939))\n- Inform when reaching undo/redo bounds ([#981](https://github.com/helix-editor/helix/pull/981))\n- search_impl will only align cursor center when it isn't in view ([#959](https://github.com/helix-editor/helix/pull/959))\n- Add `<C-h>`, `<C-u>`, `<C-d>`, Delete in prompt mode ([#1034](https://github.com/helix-editor/helix/pull/1034))\n- Restore screen position when aborting search ([#1047](https://github.com/helix-editor/helix/pull/1047))\n- Buffer picker: show is_modifier flag ([#1020](https://github.com/helix-editor/helix/pull/1020))\n- Add commit hash to version info, if present ([#957](https://github.com/helix-editor/helix/pull/957))\n- Implement indent-aware delete ([#1120](https://github.com/helix-editor/helix/pull/1120))\n- Jump to end char of surrounding pair from any cursor pos ([#1121](https://github.com/helix-editor/helix/pull/1121))\n- File picker configuration ([#988](https://github.com/helix-editor/helix/pull/988))\n- Fix surround cursor position calculation ([#1183](https://github.com/helix-editor/helix/pull/1183))\n- Accept count for goto_window ([#1033](https://github.com/helix-editor/helix/pull/1033))\n- Make kill_to_line_end behave like Emacs ([#1235](https://github.com/helix-editor/helix/pull/1235))\n- Only use a single documentation popup ([#1241](https://github.com/helix-editor/helix/pull/1241))\n- ui: popup: Don't allow scrolling past the end of content ([`3307f44c`](https://github.com/helix-editor/helix/commit/3307f44c))\n- Open files with spaces in filename, allow opening multiple files ([#1231](https://github.com/helix-editor/helix/pull/1231))\n- Allow paste commands to take a count ([#1261](https://github.com/helix-editor/helix/pull/1261))\n- Auto pairs selection ([#1254](https://github.com/helix-editor/helix/pull/1254))\n- Use a fuzzy matcher for commands ([#1386](https://github.com/helix-editor/helix/pull/1386))\n- Add `<C-s>` to pick word under doc cursor to prompt line & search completion ([#831](https://github.com/helix-editor/helix/pull/831))\n- Fix `:earlier`/`:later` missing changeset update ([#1069](https://github.com/helix-editor/helix/pull/1069))\n- Support extend for multiple goto ([#909](https://github.com/helix-editor/helix/pull/909))\n- Add arrow-key bindings for window switching ([#933](https://github.com/helix-editor/helix/pull/933))\n- Implement key ordering for info box ([#952](https://github.com/helix-editor/helix/pull/952))\n\nLSP:\n- Implement MarkedString rendering ([`e128a8702`](https://github.com/helix-editor/helix/commit/e128a8702))\n- Don't panic if init fails ([`d31bef7`](https://github.com/helix-editor/helix/commit/d31bef7))\n- Configurable diagnostic severity ([#1325](https://github.com/helix-editor/helix/pull/1325))\n- Resolve completion item ([#1315](https://github.com/helix-editor/helix/pull/1315))\n- Code action command support ([#1304](https://github.com/helix-editor/helix/pull/1304))\n\nGrammars:\n\n- Adds mint language server ([#974](https://github.com/helix-editor/helix/pull/974))\n- Perl ([#978](https://github.com/helix-editor/helix/pull/978)) ([#1280](https://github.com/helix-editor/helix/pull/1280))\n- GLSL ([#993](https://github.com/helix-editor/helix/pull/993))\n- Racket ([#1143](https://github.com/helix-editor/helix/pull/1143))\n- WGSL ([#1166](https://github.com/helix-editor/helix/pull/1166))\n- LLVM ([#1167](https://github.com/helix-editor/helix/pull/1167)) ([#1388](https://github.com/helix-editor/helix/pull/1388)) ([#1409](https://github.com/helix-editor/helix/pull/1409)) ([#1398](https://github.com/helix-editor/helix/pull/1398))\n- Markdown ([`49e06787`](https://github.com/helix-editor/helix/commit/49e06787))\n- Scala ([#1278](https://github.com/helix-editor/helix/pull/1278))\n- Dart ([#1250](https://github.com/helix-editor/helix/pull/1250))\n- Fish ([#1308](https://github.com/helix-editor/helix/pull/1308))\n- Dockerfile ([#1303](https://github.com/helix-editor/helix/pull/1303))\n- Git (commit, rebase, diff) ([#1338](https://github.com/helix-editor/helix/pull/1338)) ([#1402](https://github.com/helix-editor/helix/pull/1402)) ([#1373](https://github.com/helix-editor/helix/pull/1373))\n- tree-sitter-comment ([#1300](https://github.com/helix-editor/helix/pull/1300))\n- Highlight comments in c, cpp, cmake and llvm ([#1309](https://github.com/helix-editor/helix/pull/1309))\n- Improve yaml syntax highlighting highlighting ([#1294](https://github.com/helix-editor/helix/pull/1294))\n- Improve rust syntax highlighting ([#1295](https://github.com/helix-editor/helix/pull/1295))\n- Add textobjects and indents to cmake ([#1307](https://github.com/helix-editor/helix/pull/1307))\n- Add textobjects and indents to c and cpp ([#1293](https://github.com/helix-editor/helix/pull/1293))\n\nNew themes:\n\n- Solarized dark ([#999](https://github.com/helix-editor/helix/pull/999))\n- Solarized light ([#1010](https://github.com/helix-editor/helix/pull/1010))\n- Spacebones light ([#1131](https://github.com/helix-editor/helix/pull/1131))\n- Monokai Pro ([#1206](https://github.com/helix-editor/helix/pull/1206))\n- Base16 Light and Terminal ([#1078](https://github.com/helix-editor/helix/pull/1078))\n  - and a default 16 color theme, truecolor detection\n- Dracula ([#1258](https://github.com/helix-editor/helix/pull/1258))\n\n# 0.5.0 (2021-10-28)\n\nA big shout out to all the contributors! We had 46 contributors in this release.\n\nHelix has popped up in [Scoop, FreeBSD Ports and Gentu GURU](https://repology.org/project/helix/versions)!\n\nThe following is a quick rundown of the larger changes, there were many more\n(check the git history for more details).\n\nBreaking changes:\n\n- A couple of keymaps moved to resolve a few conflicting keybinds.\n  - Documentation popups were moved from `K` to `space+k`\n  - `K` is now `keep_selections` which filters selections to only keeps ones matching the regex\n  - `keep_primary_selection` moved from `space+space` to `,`\n  - `Alt-,` is now `remove_primary_selection` which keeps all selections except the primary one\n  - Opening files in a split moved from `C-h` to `C-s`\n- Some configuration options moved from a `[terminal]` section to `[editor]`. [Consult the documentation for more information.](https://docs.helix-editor.com/configuration.html)\n\nFeatures:\n\n- LSP compatibility greatly improved for some implementations (Julia, Python, Typescript)\n- Autocompletion! Completion now triggers automatically after a set idle timeout\n- Completion documentation is now displayed next to the popup ([#691](https://github.com/helix-editor/helix/pull/691))\n- Treesitter textobjects (select a function via `mf`, class via `mc`) ([#728](https://github.com/helix-editor/helix/pull/728))\n- Global search across entire workspace `space+/` ([#651](https://github.com/helix-editor/helix/pull/651))\n- Relative line number support ([#485](https://github.com/helix-editor/helix/pull/485))\n- Prompts now store a history ([`72cf86e`](https://github.com/helix-editor/helix/commit/72cf86e))\n- `:vsplit` and `:hsplit` commands ([#639](https://github.com/helix-editor/helix/pull/639))\n- `C-w h/j/k/l` can now be used to navigate between splits ([#860](https://github.com/helix-editor/helix/pull/860))\n- `C-j` and `C-k` are now alternative keybindings to `C-n` and `C-p` in the UI ([#876](https://github.com/helix-editor/helix/pull/876))\n- Shell commands (shell-pipe, pipe-to, shell-insert-output, shell-append-output, keep-pipe) ([#547](https://github.com/helix-editor/helix/pull/547))\n- Searching now defaults to smart case search (case insensitive unless uppercase is used) ([#761](https://github.com/helix-editor/helix/pull/761))\n- The preview pane was improved to highlight and center line ranges\n- The user `languages.toml` is now merged into defaults, no longer need to copy the entire file ([`dc57f8dc`](https://github.com/helix-editor/helix/commit/dc57f8dc))\n- Show hidden files in completions ([#648](https://github.com/helix-editor/helix/pull/648))\n- Grammar injections are now properly handled ([`dd0b15e`](https://github.com/helix-editor/helix/commit/dd0b15e))\n- `v` in select mode now switches back to normal mode ([#660](https://github.com/helix-editor/helix/pull/660))\n- View mode can now be triggered as a \"sticky\" mode ([#719](https://github.com/helix-editor/helix/pull/719))\n- `f`/`t` and object selection motions can now be repeated via `Alt-.` ([#891](https://github.com/helix-editor/helix/pull/891))\n- Statusline now displays total selection count and diagnostics counts for both errors and warnings ([#916](https://github.com/helix-editor/helix/pull/916))\n\nNew grammars:\n\n- Ledger ([#572](https://github.com/helix-editor/helix/pull/572))\n- Protobuf ([#614](https://github.com/helix-editor/helix/pull/614))\n- Zig ([#631](https://github.com/helix-editor/helix/pull/631))\n- YAML ([#667](https://github.com/helix-editor/helix/pull/667))\n- Lua ([#665](https://github.com/helix-editor/helix/pull/665))\n- OCaml ([#666](https://github.com/helix-editor/helix/pull/666))\n- Svelte ([#733](https://github.com/helix-editor/helix/pull/733))\n- Vue ([#787](https://github.com/helix-editor/helix/pull/787))\n- Tree-sitter queries ([#845](https://github.com/helix-editor/helix/pull/845))\n- CMake ([#888](https://github.com/helix-editor/helix/pull/888))\n- Elixir (we switched over to the official grammar) ([`6c0786e`](https://github.com/helix-editor/helix/commit/6c0786e))\n- Language server definitions for Nix and Elixir ([#725](https://github.com/helix-editor/helix/pull/725))\n- Python now uses `pylsp` instead of `pyls`\n- Python now supports indentation\n\nNew themes:\n\n- Monokai ([#628](https://github.com/helix-editor/helix/pull/628))\n- Everforest Dark ([#760](https://github.com/helix-editor/helix/pull/760))\n- Nord ([#799](https://github.com/helix-editor/helix/pull/799))\n- Base16 Default Dark ([#833](https://github.com/helix-editor/helix/pull/833))\n- Rose Pine ([#897](https://github.com/helix-editor/helix/pull/897))\n\nFixes:\n\n- Fix crash on empty rust file ([#592](https://github.com/helix-editor/helix/pull/592))\n- Exit select mode after toggle comment ([#598](https://github.com/helix-editor/helix/pull/598))\n- Pin popups with no positioning to the initial position ([`12ea3888`](https://github.com/helix-editor/helix/commit/12ea3888))\n- xsel copy should not freeze the editor ([`6dd7dc4`](https://github.com/helix-editor/helix/commit/6dd7dc4))\n- `*` now only sets the search register and doesn't jump to the next occurrence ([`3426285`](https://github.com/helix-editor/helix/commit/3426285))\n- Goto line start/end commands extend when in select mode ([#739](https://github.com/helix-editor/helix/pull/739)) \n- Fix documentation popups sometimes not getting fully highlighted ([`066367c`](https://github.com/helix-editor/helix/commit/066367c))\n- Refactor apply_workspace_edit to remove assert ([`b02d872`](https://github.com/helix-editor/helix/commit/b02d872))\n- Wrap around the top of the picker menu when scrolling ([`c7d6e44`](https://github.com/helix-editor/helix/commit/c7d6e44))\n- Don't allow closing the last split if there's unsaved changes ([`3ff5b00`](https://github.com/helix-editor/helix/commit/3ff5b00))\n- Indentation used different default on hx vs hx new_file.txt ([`c913bad`](https://github.com/helix-editor/helix/commit/c913bad))\n\n# 0.4.1 (2021-08-14)\n\nA minor release that includes:\n\n- A fix for rendering glitches that would occur after editing with multiple selections.\n- CI fix for grammars not being cross-compiled for aarch64\n\n# 0.4.0 (2021-08-13)\n\nA big shout out to all the contributors! We had 28 contributors in this release.\n\nTwo months have passed, so this is another big release. A big thank you to all\nthe contributors and package maintainers!\n\nHelix has popped up in [Arch, Manjaro, Nix, MacPorts and Parabola and Termux repositories](https://repology.org/project/helix/versions)!\n\nA [large scale refactor](https://github.com/helix-editor/helix/pull/376) landed that allows us to support zero width (empty)\nselections in the future as well as resolves many bugs and edge cases.\n\n- Multi-key remapping! Key binds now support much more complex usecases ([#454](https://github.com/helix-editor/helix/pull/454))\n- Pending keys are shown in the statusline ([#515](https://github.com/helix-editor/helix/pull/515))\n- Object selection / textobjects. `mi(` to select text inside parentheses ([#385](https://github.com/helix-editor/helix/pull/385))\n- Autoinfo: `whichkey`-like popups which show available sub-mode shortcuts ([#316](https://github.com/helix-editor/helix/pull/316))\n- Added WORD movements (W/B/E) ([#390](https://github.com/helix-editor/helix/pull/390))\n- Vertical selections (repeat selection above/below) ([#462](https://github.com/helix-editor/helix/pull/462))\n- Selection rotation via `(` and `)` ([`66a90130`](https://github.com/helix-editor/helix/commit/66a90130a5f99d769e9f6034025297f78ecaa3ec))\n- Selection contents rotation via `Alt-(` and `Alt-)` ([`02cba2a`](https://github.com/helix-editor/helix/commit/02cba2a7f403f48eccb18100fb751f7b42373dba))\n- Completion behavior improvements ([`f917b5a4`](https://github.com/helix-editor/helix/commit/f917b5a441ff3ae582358b6939ffbf889f4aa530), [`627b899`](https://github.com/helix-editor/helix/commit/627b89931576f7af86166ae8d5cbc55537877473))\n- Fixed a language server crash ([`385a6b5a`](https://github.com/helix-editor/helix/commit/385a6b5a1adddfc26e917982641530e1a7c7aa81))\n- Case change commands (`` ` ``, `~`, ``<a-`>``) ([#441](https://github.com/helix-editor/helix/pull/441))\n- File pickers (including goto) now provide a preview! ([#534](https://github.com/helix-editor/helix/pull/534))\n- Injection query support. Rust macro calls and embedded languages are now properly highlighted ([#430](https://github.com/helix-editor/helix/pull/430))\n- Formatting is now asynchronous, and the async job infrastructure has been improved ([#285](https://github.com/helix-editor/helix/pull/285))\n- Grammars are now compiled as separate shared libraries and loaded on-demand at runtime ([#432](https://github.com/helix-editor/helix/pull/432))\n- Code action support ([#478](https://github.com/helix-editor/helix/pull/478))\n- Mouse support ([#509](https://github.com/helix-editor/helix/pull/509), [#548](https://github.com/helix-editor/helix/pull/548))\n- Native Windows clipboard support ([#373](https://github.com/helix-editor/helix/pull/373))\n- Themes can now use color palettes ([#393](https://github.com/helix-editor/helix/pull/393))\n- `:reload` command ([#374](https://github.com/helix-editor/helix/pull/374))\n- Ctrl-z to suspend ([#464](https://github.com/helix-editor/helix/pull/464))\n- Language servers can now be configured with a custom JSON config ([#460](https://github.com/helix-editor/helix/pull/460))\n- Comment toggling now uses a language specific comment token ([#463](https://github.com/helix-editor/helix/pull/463))\n- Julia support ([#413](https://github.com/helix-editor/helix/pull/413))\n- Java support ([#448](https://github.com/helix-editor/helix/pull/448))\n- Prompts have an (in-memory) history ([`63e54e30`](https://github.com/helix-editor/helix/commit/63e54e30a74bb0d1d782877ddbbcf95f2817d061))\n\n# 0.3.0 (2021-06-27)\n\nA big shout out to all the contributors! We had 24 contributors in this release.\n\nAnother big release. \n\nHighlights:\n\n- Indentation is now automatically detected from file heuristics. ([#245](https://github.com/helix-editor/helix/pull/245))\n- Support for other line endings (CRLF). Significantly improved Windows support. ([#224](https://github.com/helix-editor/helix/pull/224))\n- Encodings other than UTF-8 are now supported! ([#228](https://github.com/helix-editor/helix/pull/228))\n- Key bindings can now be configured via a `config.toml` file ([#268](https://github.com/helix-editor/helix/pull/268))\n- Theme can now be configured and changed at runtime. ([Please feel free to contribute more themes!](https://github.com/helix-editor/helix/tree/master/runtime/themes)) ([#267](https://github.com/helix-editor/helix/pull/267))\n- System clipboard yank/paste is now supported! ([#310](https://github.com/helix-editor/helix/pull/310))\n- Surround commands were implemented ([#320](https://github.com/helix-editor/helix/pull/320))\n\nFeatures:\n\n- File picker can now be repeatedly filtered ([#232](https://github.com/helix-editor/helix/pull/232))\n- LSP progress is now received and rendered as a spinner ([#234](https://github.com/helix-editor/helix/pull/234))\n- Current line number can now be themed ([#260](https://github.com/helix-editor/helix/pull/260))\n- Arrow keys & home/end now work in insert mode ([#305](https://github.com/helix-editor/helix/pull/305))\n- Cursors and selections can now be themed ([#325](https://github.com/helix-editor/helix/pull/325))\n- Language servers are now gracefully shut down before `hx` exits ([#287](https://github.com/helix-editor/helix/pull/287))\n- `:show-directory`/`:change-directory` ([#335](https://github.com/helix-editor/helix/pull/335))\n- File picker is now sorted by access time (before filtering) ([#336](https://github.com/helix-editor/helix/pull/336))\n- Code is being migrated from helix-term to helix-view (prerequisite for\n  alternative frontends) ([#366](https://github.com/helix-editor/helix/pull/366))\n- `x` and `X` merged\n  ([`f41688d9`](https://github.com/helix-editor/helix/commit/f41688d960ef89c29c4a51c872b8406fb8f81a85))\n\nFixes:\n\n- The IME popup is now correctly positioned ([#273](https://github.com/helix-editor/helix/pull/273))\n- A bunch of bugs regarding `o`/`O` behavior ([#281](https://github.com/helix-editor/helix/pull/281))\n- `~` expansion now works in file completion ([#284](https://github.com/helix-editor/helix/pull/284))\n- Several UI related overflow crashes ([#318](https://github.com/helix-editor/helix/pull/318))\n- Fix a test failure occurring only on `test --release` ([`4f108ab1`](https://github.com/helix-editor/helix/commit/4f108ab1b2197809506bd7305ad903a3525eabfa))\n- Prompts now support unicode input ([#295](https://github.com/helix-editor/helix/pull/295))\n- Completion documentation no longer overlaps the popup ([#322](https://github.com/helix-editor/helix/pull/322))\n- Fix a crash when trying to select `^` ([`9c534614`](https://github.com/helix-editor/helix/commit/9c53461429a3e72e3b1fb87d7ca490e168d7dee2))\n- Prompt completions are now paginated ([`39dc09e6`](https://github.com/helix-editor/helix/commit/39dc09e6c4172299bc79de4c1c52288d3f624bd7))\n- Goto did not work on Windows ([`503ca112`](https://github.com/helix-editor/helix/commit/503ca112ae57ebdf3ea323baf8940346204b46d2))\n\n# 0.2.1\n\nIncludes a fix where wq/wqa could exit before file saving completed.\n\n# 0.2.0\n\nA big shout out to all the contributors! We had 18 contributors in this release.\n\nEnough has changed to bump the version. We're skipping 0.1.x because\npreviously the CLI would always report version as 0.1.0, and we'd like\nto distinguish it in bug reports..\n\n- The `runtime/` directory is now properly detected on binary releases and\n  on cargo run. `~/.config/helix/runtime` can also be used.\n- Registers can now be selected via \" (for example, `\"ay`)\n- Support for Nix files was added\n- Movement is now fully tested and matches Kakoune implementation\n- A per-file LSP symbol picker was added to space+s\n- Selection can be replaced with yanked text via R\n\n- `1g` now correctly goes to line 1\n- `ctrl-i` now correctly jumps backwards in history\n- A small memory leak was fixed, where we tried to reuse tree-sitter\n  query cursors, but always allocated a new one\n- Auto-formatting is now only on for certain languages\n- The root directory is now provided in LSP initialization, fixing\n  certain language servers (typescript)\n- LSP failing to start no longer panics\n- Elixir language queries were fixed\n\n# 0.0.10\n\nKeymaps:\n- Add mappings to jump to diagnostics\n- Add gt/gm/gb mappings to jump to top/middle/bottom of screen\n- ^ and $ are now gh, gl\n\n- The runtime/ can now optionally be embedded in the binary\n- Haskell syntax added\n- Window mode (ctrl-w) added\n- Show matching bracket (Vim's matchbrackets)\n- Themes now support style modifiers\n- First user contributed theme\n- Create a document if it doesn't exist yet on save\n- Detect language on a new file on save\n\n- Panic fixes, lots of them\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[workspace]\nresolver = \"2\"\nmembers = [\n  \"helix-core\",\n  \"helix-view\",\n  \"helix-term\",\n  \"helix-tui\",\n  \"helix-lsp-types\",\n  \"helix-lsp\",\n  \"helix-event\",\n  \"helix-dap-types\",\n  \"helix-dap\",\n  \"helix-loader\",\n  \"helix-vcs\",\n  \"helix-parsec\",\n  \"helix-stdx\",\n  \"xtask\",\n]\n\ndefault-members = [\n  \"helix-term\"\n]\n\n[profile.release]\nlto = \"thin\"\n\n[profile.opt]\ninherits = \"release\"\nlto = \"fat\"\ncodegen-units = 1\nstrip = true\nopt-level = 3\n\n[profile.integration]\ninherits = \"test\"\npackage.helix-core.opt-level = 2\npackage.helix-tui.opt-level = 2\npackage.helix-term.opt-level = 2\n\n[workspace.dependencies]\ntree-house = { version = \"0.3.0\", default-features = false }\nnucleo = \"0.5.0\"\nslotmap = \"1.1.1\"\nthiserror = \"2.0\"\ntempfile = \"3.26.0\"\nbitflags = \"2.11\"\nunicode-segmentation = \"1.2\"\nropey = { version = \"1.6.1\", default-features = false, features = [\"simd\"] }\nfoldhash = \"0.2\"\nparking_lot = \"0.12\"\nfutures-executor = \"0.3\"\nfutures-util = { version = \"0.3\", features = [\"std\", \"async-await\"], default-features = false }\ntokio-stream = \"0.1.18\"\ntoml = \"1.0\"\ntermina = \"0.2\"\nsonic-rs = \"0.5\"\nglobset = \"0.4\"\netcetera = \"0.11\"\narc-swap = \"1.8\"\n\n[workspace.package]\nversion = \"25.7.1\"\nedition = \"2021\"\nauthors = [\"Blaž Hrastnik <blaz@mxxn.io>\"]\ncategories = [\"editor\"]\nrepository = \"https://github.com/helix-editor/helix\"\nhomepage = \"https://helix-editor.com\"\nlicense = \"MPL-2.0\"\nrust-version = \"1.87\"\n"
  },
  {
    "path": "LICENSE",
    "content": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n    means each individual or legal entity that creates, contributes to\n    the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n    means the combination of the Contributions of others (if any) used\n    by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n    means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n    means Source Code Form to which the initial Contributor has attached\n    the notice in Exhibit A, the Executable Form of such Source Code\n    Form, and Modifications of such Source Code Form, in each case\n    including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n    means\n\n    (a) that the initial Contributor has attached the notice described\n        in Exhibit B to the Covered Software; or\n\n    (b) that the Covered Software was made available under the terms of\n        version 1.1 or earlier of the License, but not also under the\n        terms of a Secondary License.\n\n1.6. \"Executable Form\"\n    means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n    means a work that combines Covered Software with other material, in\n    a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n    means this document.\n\n1.9. \"Licensable\"\n    means having the right to grant, to the maximum extent possible,\n    whether at the time of the initial grant or subsequently, any and\n    all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n    means any of the following:\n\n    (a) any file in Source Code Form that results from an addition to,\n        deletion from, or modification of the contents of Covered\n        Software; or\n\n    (b) any new file in Source Code Form that contains any Covered\n        Software.\n\n1.11. \"Patent Claims\" of a Contributor\n    means any patent claim(s), including without limitation, method,\n    process, and apparatus claims, in any patent Licensable by such\n    Contributor that would be infringed, but for the grant of the\n    License, by the making, using, selling, offering for sale, having\n    made, import, or transfer of either its Contributions or its\n    Contributor Version.\n\n1.12. \"Secondary License\"\n    means either the GNU General Public License, Version 2.0, the GNU\n    Lesser General Public License, Version 2.1, the GNU Affero General\n    Public License, Version 3.0, or any later versions of those\n    licenses.\n\n1.13. \"Source Code Form\"\n    means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n    means an individual or a legal entity exercising rights under this\n    License. For legal entities, \"You\" includes any entity that\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n    Licensable by such Contributor to use, reproduce, make available,\n    modify, display, perform, distribute, and otherwise exploit its\n    Contributions, either on an unmodified basis, with Modifications, or\n    as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n    for sale, have made, import, and otherwise transfer either its\n    Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n    or\n\n(b) for infringements caused by: (i) Your and any other third party's\n    modifications of Covered Software, or (ii) the combination of its\n    Contributions with other software (except as part of its Contributor\n    Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n    its Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\n    Form, as described in Section 3.1, and You must inform recipients of\n    the Executable Form how they can obtain a copy of such Source Code\n    Form by reasonable means in a timely manner, at a charge no more\n    than the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\n    License, or sublicense it under different terms, provided that the\n    license for the Executable Form does not attempt to limit or alter\n    the recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n*                                                                      *\n*  6. Disclaimer of Warranty                                           *\n*  -------------------------                                           *\n*                                                                      *\n*  Covered Software is provided under this License on an \"as is\"       *\n*  basis, without warranty of any kind, either expressed, implied, or  *\n*  statutory, including, without limitation, warranties that the       *\n*  Covered Software is free of defects, merchantable, fit for a        *\n*  particular purpose or non-infringing. The entire risk as to the     *\n*  quality and performance of the Covered Software is with You.        *\n*  Should any Covered Software prove defective in any respect, You     *\n*  (not any Contributor) assume the cost of any necessary servicing,   *\n*  repair, or correction. This disclaimer of warranty constitutes an   *\n*  essential part of this License. No use of any Covered Software is   *\n*  authorized under this License except under this disclaimer.         *\n*                                                                      *\n************************************************************************\n\n************************************************************************\n*                                                                      *\n*  7. Limitation of Liability                                          *\n*  --------------------------                                          *\n*                                                                      *\n*  Under no circumstances and under no legal theory, whether tort      *\n*  (including negligence), contract, or otherwise, shall any           *\n*  Contributor, or anyone who distributes Covered Software as          *\n*  permitted above, be liable to You for any direct, indirect,         *\n*  special, incidental, or consequential damages of any character      *\n*  including, without limitation, damages for lost profits, loss of    *\n*  goodwill, work stoppage, computer failure or malfunction, or any    *\n*  and all other commercial damages or losses, even if such party      *\n*  shall have been informed of the possibility of such damages. This   *\n*  limitation of liability shall not apply to liability for death or   *\n*  personal injury resulting from such party's negligence to the       *\n*  extent applicable law prohibits such limitation. Some               *\n*  jurisdictions do not allow the exclusion or limitation of           *\n*  incidental or consequential damages, so this exclusion and          *\n*  limitation may not apply to You.                                    *\n*                                                                      *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\n  This Source Code Form is subject to the terms of the Mozilla Public\n  License, v. 2.0. If a copy of the MPL was not distributed with this\n  file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\n  This Source Code Form is \"Incompatible With Secondary Licenses\", as\n  defined by the Mozilla Public License, v. 2.0.\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n\n<h1>\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"logo_dark.svg\">\n  <source media=\"(prefers-color-scheme: light)\" srcset=\"logo_light.svg\">\n  <img alt=\"Helix\" height=\"128\" src=\"logo_light.svg\">\n</picture>\n</h1>\n\n[![Build status](https://github.com/helix-editor/helix/actions/workflows/build.yml/badge.svg)](https://github.com/helix-editor/helix/actions)\n[![GitHub Release](https://img.shields.io/github/v/release/helix-editor/helix)](https://github.com/helix-editor/helix/releases/latest)\n[![Documentation](https://shields.io/badge/-documentation-452859)](https://docs.helix-editor.com/)\n[![GitHub contributors](https://img.shields.io/github/contributors/helix-editor/helix)](https://github.com/helix-editor/helix/graphs/contributors)\n[![Matrix Space](https://img.shields.io/matrix/helix-community:matrix.org)](https://matrix.to/#/#helix-community:matrix.org)\n\n</div>\n\n![Screenshot](./screenshot.png)\n\nA [Kakoune](https://github.com/mawww/kakoune) / [Neovim](https://github.com/neovim/neovim) inspired editor, written in Rust.\n\nThe editing model is very heavily based on Kakoune; during development I found\nmyself agreeing with most of Kakoune's design decisions.\n\nFor more information, see the [website](https://helix-editor.com) or\n[documentation](https://docs.helix-editor.com/).\n\nAll shortcuts/keymaps can be found [in the documentation on the website](https://docs.helix-editor.com/keymap.html).\n\n[Troubleshooting](https://github.com/helix-editor/helix/wiki/Troubleshooting)\n\n# Features\n\n- Vim-like modal editing\n- Multiple selections\n- Built-in language server support\n- Smart, incremental syntax highlighting and code editing via tree-sitter\n\nAlthough it's primarily a terminal-based editor, I am interested in exploring\na custom renderer (similar to Emacs) using wgpu.\n\nNote: Only certain languages have indentation definitions at the moment. Check\n`runtime/queries/<lang>/` for `indents.scm`.\n\n# Installation\n\n[Installation documentation](https://docs.helix-editor.com/install.html).\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/helix-editor.svg?exclude_unsupported=1)](https://repology.org/project/helix-editor/versions)\n\n# Contributing\n\nContributing guidelines can be found [here](./docs/CONTRIBUTING.md).\n\n# Getting help\n\nYour question might already be answered on the [FAQ](https://github.com/helix-editor/helix/wiki/FAQ).\n\nDiscuss the project on the community [Matrix Space](https://matrix.to/#/#helix-community:matrix.org) (make sure to join `#helix-editor:matrix.org` if you're on a client that doesn't support Matrix Spaces yet).\n\n# Credits\n\nThanks to [@jakenvac](https://github.com/jakenvac) for designing the logo!\n"
  },
  {
    "path": "base16_theme.toml",
    "content": "# Author: NNB <nnbnh@protonmail.com>\n\n\"ui.menu\" = { fg = \"black\", bg = \"white\" }\n\"ui.menu.selected\" = { modifiers = [\"reversed\"] }\n\"ui.linenr\" = { fg = \"gray\", bg = \"black\" }\n\"ui.popup\" = { modifiers = [\"reversed\"] }\n\"ui.linenr.selected\" = { fg = \"white\", bg = \"black\", modifiers = [\"bold\"] }\n\"ui.selection\" = { fg = \"black\", bg = \"blue\" }\n\"ui.selection.primary\" = { fg = \"white\", bg = \"blue\" }\n\"ui.text.inactive\" = { fg = \"gray\" }\n\"comment\" = { fg = \"gray\" }\n\"ui.statusline\" = { fg = \"black\", bg = \"white\" }\n\"ui.statusline.inactive\" = { fg = \"gray\", bg = \"white\" }\n\"ui.cursor\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"variable\" = \"red\"\n\"constant.numeric\" = \"yellow\"\n\"constant\" = \"yellow\"\n\"attributes\" = \"yellow\"\n\"type\" = \"yellow\"\n\"ui.cursor.match\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"string\"  = \"green\"\n\"variable.other.member\" = \"green\"\n\"constant.character.escape\" = \"cyan\"\n\"function\" = \"blue\"\n\"constructor\" = \"blue\"\n\"special\" = \"blue\"\n\"keyword\" = \"magenta\"\n\"label\" = \"magenta\"\n\"namespace\" = \"magenta\"\n\"ui.help\" = { fg = \"white\", bg = \"black\" }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"blue\" }\n\"ui.virtual\" = { fg = \"gray\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"blue\", modifiers = [\"bold\", \"underlined\"] }\n\"ui.virtual.ruler\" = { bg = \"black\" }\n\n\"markup.heading\" = \"blue\"\n\"markup.list\" = \"red\"\n\"markup.bold\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"magenta\", modifiers = [\"italic\"] }\n\"markup.link.url\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"red\"\n\"markup.quote\" = \"cyan\"\n\"markup.raw\" = \"green\"\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"yellow\"\n\"diff.minus\" = \"red\"\n\n\"diagnostic\" = { modifiers = [\"underlined\"] }\n\"ui.gutter\" = { bg = \"black\" }\n\"info\" = \"blue\"\n\"hint\" = \"gray\"\n\"debug\" = \"gray\"\n\"warning\" = \"yellow\"\n\"error\" = \"red\"\n"
  },
  {
    "path": "contrib/Helix.appdata.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<component type=\"desktop-application\">\n  <id>com.helix_editor.Helix</id>\n  <metadata_license>CC0-1.0</metadata_license>\n  <project_license>MPL-2.0</project_license>\n  <name>Helix</name>\n  <summary>A post-modern text editor</summary>\n  <summary xml:lang=\"ar\">مُحَرِّرُ نُصُوصٍ سَابِقٌ لِعَهدِه</summary>\n  <developer id=\"com.helix_editor\">\n    <name>Blaž Hrastnik</name>\n  </developer>\n\n  <description>\n    <p>\n      Helix is a terminal-based text editor inspired by Kakoune / Neovim and written in Rust.\n    </p>\n    <p xml:lang=\"ar\">\n      مُحَرِّرُ نُصُوصٍ يَعمَلُ فِي الطَّرَفِيَّة، مُستَلهَمٌ مِن Kakoune وَ Neovim وَمَكتُوبٌ بِلُغَةِ رَست البَرمَجِيَّة.\n    </p>\n    <ul>\n      <li>Vim-like modal editing</li>\n      <li xml:lang=\"ar\">تَحرِيرٌ وَضعِيٌّ شَبيهٌ بِـVim</li>\n      <li>Multiple selections</li>\n      <li xml:lang=\"ar\">تَحدِيدَاتٌ لِلنَّصِ مُتَعَدِّدَة</li>\n      <li>Built-in language server support</li>\n      <li xml:lang=\"ar\">دَعْمٌ مُدمَجٌ لِخَوادِمِ اللُّغَات</li>\n      <li>Smart, incremental syntax highlighting and code editing via tree-sitter</li>\n      <li xml:lang=\"ar\">تَحرِيرُ التَّعلِيمَاتِ البَّرمَجِيَّةِ مَعَ تَمييزٍ لِلتَّركِيبِ النَّحُويِّ بِواسِطَةِ tree-sitter</li>\n    </ul>\n  </description>\n\n  <launchable type=\"desktop-id\">Helix.desktop</launchable>\n\n  <screenshots>\n    <screenshot type=\"default\">\n      <caption>Helix with default theme</caption>\n      <image>https://github.com/helix-editor/helix/raw/d4565b4404cabc522bd60822abd374755581d751/screenshot.png</image>\n    </screenshot>\n  </screenshots>\n\n  <url type=\"homepage\">https://helix-editor.com/</url>\n  <url type=\"donation\">https://opencollective.com/helix-editor</url>\n  <url type=\"help\">https://docs.helix-editor.com/</url>\n  <url type=\"vcs-browser\">https://github.com/helix-editor/helix</url>\n  <url type=\"bugtracker\">https://github.com/helix-editor/helix/issues</url>\n\n  <content_rating type=\"oars-1.1\" />\n\n  <releases>\n    <release version=\"25.07.1\" date=\"2025-07-18\">\n      <url>https://github.com/helix-editor/helix/releases/tag/25.07.1</url>\n    </release>\n    <release version=\"25.07\" date=\"2025-07-15\">\n      <url>https://helix-editor.com/news/release-25-07-highlights/</url>\n    </release>\n    <release version=\"25.01.1\" date=\"2025-01-19\">\n      <url>https://github.com/helix-editor/helix/releases/tag/25.01.1</url>\n    </release>\n    <release version=\"25.01\" date=\"2025-01-03\">\n      <url>https://helix-editor.com/news/release-25-01-highlights/</url>\n    </release>\n    <release version=\"24.07\" date=\"2024-07-14\">\n      <url>https://github.com/helix-editor/helix/releases/tag/24.07</url>\n    </release>\n    <release version=\"24.03\" date=\"2024-03-30\">\n      <url>https://helix-editor.com/news/release-24-03-highlights/</url>\n    </release>\n    <release version=\"23.10\" date=\"2023-10-24\">\n      <url>https://helix-editor.com/news/release-23-10-highlights/</url>\n    </release>\n    <release version=\"23.05\" date=\"2023-05-18\">\n      <url>https://github.com/helix-editor/helix/releases/tag/23.05</url>\n    </release>\n    <release version=\"23.03\" date=\"2023-03-31\">\n      <url>https://helix-editor.com/news/release-23-03-highlights/</url>\n    </release>\n    <release version=\"22.12\" date=\"2022-12-6\">\n      <url>https://helix-editor.com/news/release-22-12-highlights/</url>\n    </release>\n    <release version=\"22.08\" date=\"2022-8-31\">\n      <url>https://helix-editor.com/news/release-22-08-highlights/</url>\n    </release>\n    <release version=\"22.05\" date=\"2022-5-28\">\n      <url>https://helix-editor.com/news/release-22-05-highlights/</url>\n    </release>\n    <release version=\"22.03\" date=\"2022-3-28\">\n      <url>https://helix-editor.com/news/release-22-03-highlights/</url>\n    </release>\n  </releases>\n\n  <recommends>\n    <control>keyboard</control>\n  </recommends>\n\n  <categories>\n    <category>Utility</category>\n    <category>TextEditor</category>\n  </categories>\n\n  <keywords>\n    <keyword>text</keyword>\n    <keyword>editor</keyword>\n    <keyword>development</keyword>\n    <keyword>programming</keyword>\n  </keywords>\n\n  <provides>\n    <binary>hx</binary>\n    <mediatype>text/english</mediatype>\n    <mediatype>text/plain</mediatype>\n    <mediatype>text/x-makefile</mediatype>\n    <mediatype>text/x-c++hdr</mediatype>\n    <mediatype>text/x-c++src</mediatype>\n    <mediatype>text/x-chdr</mediatype>\n    <mediatype>text/x-csrc</mediatype>\n    <mediatype>text/x-java</mediatype>\n    <mediatype>text/x-moc</mediatype>\n    <mediatype>text/x-pascal</mediatype>\n    <mediatype>text/x-tcl</mediatype>\n    <mediatype>text/x-tex</mediatype>\n    <mediatype>application/x-shellscript</mediatype>\n    <mediatype>text/x-c</mediatype>\n    <mediatype>text/x-c++</mediatype>\n  </provides>\n</component>\n"
  },
  {
    "path": "contrib/Helix.desktop",
    "content": "[Desktop Entry]\nName=Helix\nGenericName=Text Editor\nGenericName[ar]=مُحَرِّرُ نُصُوص\nGenericName[de]=Texteditor\nGenericName[fr]=Éditeur de texte\nGenericName[ru]=Текстовый редактор\nGenericName[sr]=Едитор текст\nGenericName[tr]=Metin Düzenleyici\nComment=Edit text files\nComment[af]=Redigeer tekslêers\nComment[am]=የጽሑፍ ፋይሎች ያስተካክሉ\nComment[ar]=مُحَرِّرُ مِلَفَّاتٍ نَصِّيَّة\nComment[az]=Mətn fayllarını redaktə edin\nComment[be]=Рэдагаваньне тэкставых файлаў\nComment[bg]=Редактиране на текстови файлове\nComment[bn]=টেক্স্ট ফাইল এডিট করুন\nComment[bs]=Izmijeni tekstualne datoteke\nComment[ca]=Edita fitxers de text\nComment[cs]=Úprava textových souborů\nComment[cy]=Golygu ffeiliau testun\nComment[da]=Redigér tekstfiler\nComment[de]=Textdateien bearbeiten\nComment[el]=Επεξεργασία αρχείων κειμένου\nComment[en_CA]=Edit text files\nComment[en_GB]=Edit text files\nComment[es]=Edita archivos de texto\nComment[et]=Redigeeri tekstifaile\nComment[eu]=Editatu testu-fitxategiak\nComment[fa]=ویرایش پرونده‌های متنی\nComment[fi]=Muokkaa tekstitiedostoja\nComment[fr]=Éditer des fichiers texte\nComment[ga]=Eagar comhad Téacs\nComment[gu]=લખાણ ફાઇલોમાં ફેરફાર કરો\nComment[he]=ערוך קבצי טקסט\nComment[hi]=पाठ फ़ाइलें संपादित करें\nComment[hr]=Uređivanje tekstualne datoteke\nComment[hu]=Szövegfájlok szerkesztése\nComment[id]=Edit file teks\nComment[it]=Modifica file di testo\nComment[ja]=テキストファイルを編集します\nComment[kn]=ಪಠ್ಯ ಕಡತಗಳನ್ನು ಸಂಪಾದಿಸು\nComment[ko]=텍스트 파일을 편집합니다\nComment[lt]=Redaguoti tekstines bylas\nComment[lv]=Rediģēt teksta failus\nComment[mk]=Уреди текстуални фајлови\nComment[ml]=വാചക രചനകള് തിരുത്തുക\nComment[mn]=Текст файл боловсруулах\nComment[mr]=गद्य फाइल संपादित करा\nComment[ms]=Edit fail teks\nComment[nb]=Rediger tekstfiler\nComment[ne]=पाठ फाइललाई संशोधन गर्नुहोस्\nComment[nl]=Tekstbestanden bewerken\nComment[nn]=Rediger tekstfiler\nComment[no]=Rediger tekstfiler\nComment[or]=ପାଠ୍ଯ ଫାଇଲଗୁଡ଼ିକୁ ସମ୍ପାଦନ କରନ୍ତୁ\nComment[pa]=ਪਾਠ ਫਾਇਲਾਂ ਸੰਪਾਦਨ\nComment[pl]=Edytor plików tekstowych\nComment[pt]=Editar ficheiros de texto\nComment[pt_BR]=Edite arquivos de texto\nComment[ro]=Editare fişiere text\nComment[ru]=Редактирование текстовых файлов\nComment[sk]=Úprava textových súborov\nComment[sl]=Urejanje datotek z besedili\nComment[sq]=Përpuno files teksti\nComment[sr]=Уређујте текст фајлове\nComment[sr@Latn]=Izmeni tekstualne datoteke\nComment[sv]=Redigera textfiler\nComment[ta]=உரை கோப்புகளை தொகுக்கவும்\nComment[th]=แก้ไขแฟ้มข้อความ\nComment[tk]=Metin faýllary editle\nComment[tr]=Metin dosyaları düzenleyin\nComment[uk]=Редактор текстових файлів\nComment[vi]=Soạn thảo tập tin văn bản\nComment[wa]=Asspougnî des fitchîs tecses\nComment[zh_CN]=编辑文本文件\nComment[zh_TW]=編輯文字檔\nTryExec=hx\nExec=hx %F\nTerminal=true\nType=Application\nKeywords=Text;editor;\nKeywords[ar]=نص;نصوص;محرر;\nKeywords[fr]=Texte;éditeur;\nKeywords[ru]=текст;текстовый редактор;\nKeywords[sr]=Текст;едитор;\nKeywords[tr]=Metin;düzenleyici;\nIcon=helix\nCategories=Utility;TextEditor;ConsoleOnly\nStartupNotify=false\nMimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;\n"
  },
  {
    "path": "contrib/completion/hx.bash",
    "content": "#!/usr/bin/env bash\n# Bash completion script for Helix editor\n\n_hx() {\n    local cur prev languages\n    COMPREPLY=()\n    cur=\"${COMP_WORDS[COMP_CWORD]}\"\n    prev=\"${COMP_WORDS[COMP_CWORD - 1]}\"\n\n    case \"$prev\" in\n    -g | --grammar)\n        mapfile -t COMPREPLY < <(compgen -W 'fetch build' -- \"$cur\")\n        return 0\n        ;;\n    --health)\n        languages=$(hx --health all-languages | tail -n '+2' | awk '{print $1}' | sed 's/\\x1b\\[[0-9;]*m//g')\n        mapfile -t COMPREPLY < <(compgen -W \"\"\"clipboard languages all-languages all $languages\"\"\" -- \"$cur\")\n        return 0\n        ;;\n    esac\n\n    case \"$2\" in\n    -*)\n        mapfile -t COMPREPLY < <(compgen -W \"-h --help --tutor -V --version -v -vv -vvv --health -g --grammar --vsplit --hsplit -c --config --log\" -- \"\"\"$2\"\"\")\n        return 0\n        ;;\n    *)\n        mapfile -t COMPREPLY < <(compgen -fd -- \"\"\"$2\"\"\")\n        return 0\n        ;;\n    esac\n} && complete -o filenames -F _hx hx\n"
  },
  {
    "path": "contrib/completion/hx.elv",
    "content": "# You can move it here ~/.config/elvish/lib/hx.elv\n# Or add `eval (slurp < ~/$REPOS/helix/contrib/completion/hx.elv)`\n# Be sure to replace `$REPOS` with something that makes sense for you!\n\n### Renders a pretty completion candidate\nvar candidate = { | _stem  _desc | \n  edit:complex-candidate $_stem &display=(styled $_stem bold)(styled \" \"$_desc dim)\n}\n\n### These commands will invalidate further input (i.e. not react to them)\nvar skips = [ \"--tutor\" \"--help\" \"--version\" \"-V\" \"--health\" ]\n\n### Grammar commands\nvar grammar = [ \"--grammar\" \"-g\" ]\n\n### Config commands\nvar config = [ \"--config\" \"-c\" ]\n\n### Set an arg-completer for the `hx` binary\nset edit:completion:arg-completer[hx] = {|@args|\n  var n = (count $args)\n  if (>= $n 3) {\n    # Stop completions if passed arg will take precedence\n    # and invalidate further input\n    if (has-value $skips $args[-2]) {\n      return\n    } \n    # If the previous arg == --grammar, then only suggest:\n    if (has-value $grammar $args[-2]) {\n      $candidate \"fetch\" \"Fetch the tree-sitter grammars\"\n      $candidate \"build\" \"Build the tree-sitter grammars\"\n      return\n    } \n    # When we have --config, we need a file\n    if (has-values $config $args[-2]) {\n      edit:complete-filename $args[-1] | each { |v| put $v[stem] }\n      return\n    } \n    # When we have --log, we need a file\n    if (has-values \"log\" $args[-2]) {\n      edit:complete-filename $args[-1] | each { |v| put $v[stem] }\n      return\n    } \n  } \n  edit:complete-filename $args[-1] | each { |v| put $v[stem]}\n  $candidate \"--help\" \"(Prints help information)\"\n  $candidate \"--version\" \"(Prints version information)\"\n  $candidate \"--tutor\" \"(Loads the tutorial)\"\n  $candidate \"--health\" \"(Checks for errors in editor setup)\"\n  $candidate \"--grammar\" \"(Fetch or build the tree-sitter grammars)\"\n  $candidate \"--vsplit\" \"(Splits all given files vertically)\"\n  $candidate \"--hsplit\" \"(Splits all given files horizontally)\"\n  $candidate \"--config\" \"(Specifies a file to use for configuration)\"\n  $candidate \"--log\" \"(Specifies a file to write log data into)\"\n}\n"
  },
  {
    "path": "contrib/completion/hx.fish",
    "content": "#!/usr/bin/env fish\n# Fish completion script for Helix editor\n\ncomplete -c hx -s h -l help -d \"Prints help information\"\ncomplete -c hx -l tutor -d \"Loads the tutorial\"\ncomplete -c hx -l health -xa \"(__hx_langs_ops)\" -d \"Checks for errors\"\ncomplete -c hx -l health -xka all -d \"Prints all diagnostic informations\"\ncomplete -c hx -l health -xka all-languages -d \"Lists all languages\"\ncomplete -c hx -l health -xka languages -d \"Lists user configured languages\"\ncomplete -c hx -l health -xka clipboard -d \"Prints system clipboard provider\"\ncomplete -c hx -s g -l grammar -x -a \"fetch build\" -d \"Fetch or build tree-sitter grammars\"\ncomplete -c hx -s v -o vv -o vvv -d \"Increases logging verbosity\"\ncomplete -c hx -s V -l version -d \"Prints version information\"\ncomplete -c hx -l vsplit -d \"Splits all given files vertically\"\ncomplete -c hx -l hsplit -d \"Splits all given files horizontally\"\ncomplete -c hx -s c -l config -r -d \"Specifies a file to use for config\"\ncomplete -c hx -l log -r -d \"Specifies a file to use for logging\"\ncomplete -c hx -s w -l working-dir -d \"Specify initial working directory\" -xa \"(__fish_complete_directories)\"\n\nfunction __hx_langs_ops\n    hx --health all-languages | tail -n '+2' | string replace -fr '^(\\S+) .*' '$1'\nend\n"
  },
  {
    "path": "contrib/completion/hx.nu",
    "content": "# Completions for Helix: <https://github.com/helix-editor/helix>\n#\n# NOTE: the `+N` syntax is not supported in Nushell (https://github.com/nushell/nushell/issues/13418)\n#       so it has not been specified here and will not be proposed in the autocompletion of Nushell.\n#       The help message won't be overridden though, so it will still be present here\n\ndef health_categories [] {\n    let languages = ^hx --health all-languages | detect columns | get Language | where { $in != null }\n    let completions = [ \"all\", \"clipboard\", \"languages\", \"all-languages\" ] | append $languages\n    return $completions\n}\n\ndef grammar_categories [] { [\"fetch\", \"build\"] }\n\n# A post-modern text editor.\nexport extern hx [\n    --help(-h),                                 # Prints help information\n    --tutor,                                    # Loads the tutorial\n    --health: string@health_categories,         # Checks for potential errors in editor setup\n    --grammar(-g): string@grammar_categories,   # Fetches or builds tree-sitter grammars listed in `languages.toml`\n    --config(-c): glob,                         # Specifies a file to use for configuration\n    -v,                                         # Increases logging verbosity each use for up to 3 times\n    --log: glob,                                # Specifies a file to use for logging\n    --version(-V),                              # Prints version information\n    --vsplit,                                   # Splits all given files vertically into different windows\n    --hsplit,                                   # Splits all given files horizontally into different windows\n    --working-dir(-w): glob,                    # Specify an initial working directory\n    ...files: glob,                             # Sets the input file to use, position can also be specified via file[:row[:col]]\n]\n"
  },
  {
    "path": "contrib/completion/hx.zsh",
    "content": "#compdef _hx hx\n# Zsh completion script for Helix editor\n\n_hx() {\n\t_arguments -C \\\n\t\t\"-h[Prints help information]\" \\\n\t\t\"--help[Prints help information]\" \\\n\t\t\"-v[Increase logging verbosity]\" \\\n\t\t\"-vv[Increase logging verbosity]\" \\\n\t\t\"-vvv[Increase logging verbosity]\" \\\n\t\t\"-V[Prints version information]\" \\\n\t\t\"--version[Prints version information]\" \\\n\t\t\"--tutor[Loads the tutorial]\" \\\n\t\t\"--health[Checks for errors in editor setup]:language:->health\" \\\n\t\t\"-g[Fetches or builds tree-sitter grammars]:action:->grammar\" \\\n\t\t\"--grammar[Fetches or builds tree-sitter grammars]:action:->grammar\" \\\n\t\t\"--vsplit[Splits all given files vertically]\" \\\n\t\t\"--hsplit[Splits all given files horizontally]\" \\\n\t\t\"-c[Specifies a file to use for configuration]\" \\\n\t\t\"--config[Specifies a file to use for configuration]\" \\\n\t\t\"-w[Specify initial working directory]\" \\\n\t\t\"--working-dir[Specify initial working directory]\" \\\n\t\t\"--log[Specifies a file to use for logging]\" \\\n\t\t\"*:file:_files\"\n\n\tcase \"$state\" in\n\thealth)\n\t\tlocal languages=($(hx --health all-languages | tail -n '+2' | awk '{print $1}' | sed 's/\\x1b\\[[0-9;]*m//g;s/[✘✓]//g'))\n\t\t_values 'language' $languages\n\t\t;;\n\tgrammar)\n\t\t_values 'action' fetch build\n\t\t;;\n\tesac\n}\n"
  },
  {
    "path": "contrib/hx_launcher.sh",
    "content": "#!/usr/bin/env sh\n\nHELIX_RUNTIME=/usr/lib/helix/runtime exec /usr/lib/helix/hx \"$@\"\n"
  },
  {
    "path": "default.nix",
    "content": "{\n  lib,\n  rustPlatform,\n  callPackage,\n  runCommand,\n  installShellFiles,\n  git,\n  gitRev ? null,\n  grammarOverlays ? [],\n  includeGrammarIf ? _: true,\n}: let\n  fs = lib.fileset;\n\n  src = fs.difference (fs.gitTracked ./.) (fs.unions [\n    ./.envrc\n    ./rustfmt.toml\n    ./screenshot.png\n    ./book\n    ./docs\n    ./runtime\n    ./flake.lock\n    (fs.fileFilter (file: lib.strings.hasInfix \".git\" file.name) ./.)\n    (fs.fileFilter (file: file.hasExt \"svg\") ./.)\n    (fs.fileFilter (file: file.hasExt \"md\") ./.)\n    (fs.fileFilter (file: file.hasExt \"nix\") ./.)\n  ]);\n\n  # Next we actually need to build the grammars and the runtime directory\n  # that they reside in. It is built by calling the derivation in the\n  # grammars.nix file, then taking the runtime directory in the git repo\n  # and hooking symlinks up to it.\n  grammars = callPackage ./grammars.nix {inherit grammarOverlays includeGrammarIf;};\n  runtimeDir = runCommand \"helix-runtime\" {} ''\n    mkdir -p $out\n    ln -s ${./runtime}/* $out\n    rm -r $out/grammars\n    ln -s ${grammars} $out/grammars\n  '';\nin\n  rustPlatform.buildRustPackage (self: {\n    cargoLock = {\n      lockFile = ./Cargo.lock;\n      # This is not allowed in nixpkgs but is very convenient here: it allows us to\n      # avoid specifying `outputHashes` here for any git dependencies we might take\n      # on temporarily.\n      allowBuiltinFetchGit = true;\n    };\n\n    propagatedBuildInputs = [ runtimeDir ];\n    \n    nativeBuildInputs = [\n      installShellFiles\n      git\n    ];\n\n    buildType = \"release\";\n\n    name = with builtins; (fromTOML (readFile ./helix-term/Cargo.toml)).package.name;\n    src = fs.toSource {\n      root = ./.;\n      fileset = src;\n    };\n\n    # Helix attempts to reach out to the network and get the grammars. Nix doesn't allow this.\n    HELIX_DISABLE_AUTO_GRAMMAR_BUILD = \"1\";\n\n    # So Helix knows what rev it is.\n    HELIX_NIX_BUILD_REV = gitRev;\n\n    doCheck = false;\n    strictDeps = true;\n\n    # Sets the Helix runtime dir to the grammars\n    env.HELIX_DEFAULT_RUNTIME = \"${runtimeDir}\";\n\n    # Get all the application stuff in the output directory.\n    postInstall = ''\n      mkdir -p $out/lib\n      installShellCompletion ${./contrib/completion}/hx.{bash,fish,zsh}\n      mkdir -p $out/share/{applications,icons/hicolor/{256x256,scalable}/apps}\n      cp ${./contrib/Helix.desktop} $out/share/applications/Helix.desktop\n      cp ${./logo.svg} $out/share/icons/hicolor/scalable/apps/helix.svg\n      cp ${./contrib/helix.png} $out/share/icons/hicolor/256x256/apps/helix.png\n    '';\n\n    meta.mainProgram = \"hx\";\n  })\n"
  },
  {
    "path": "docs/CONTRIBUTING.md",
    "content": "# Contributing\n\nContributors are very welcome! **No contribution is too small and all contributions are valued.**\n\nSome suggestions to get started:\n\n- You can look at the [good first issue][good-first-issue] label on the issue tracker.\n- Help with packaging on various distributions needed!\n- To use print debugging to the [Helix log file][log-file], you must:\n  * Print using `log::info!`, `warn!`, or `error!`. (`log::info!(\"helix!\")`)\n  * Pass the appropriate verbosity level option for the desired log level. (`hx -v <file>` for info, more `v`s for higher verbosity)\n  * Want to display the logs in a separate file instead of using the `:log-open` command in your compiled Helix editor? Start your debug version with `cargo run -- --log foo.log` and in a new terminal use `tail -f foo.log`\n- Instead of running a release version of Helix, while developing you may want to run in debug mode with `cargo run` which is way faster to compile\n- Looking for even faster compile times? Give a try to [mold](https://github.com/rui314/mold)\n- If your preferred language is missing, integrating a tree-sitter grammar for\n    it and defining syntax highlight queries for it is straightforward and\n    doesn't require much knowledge of the internals.\n- If you don't use the Nix development shell and are getting your rust-analyzer binary from rustup, you may need to run `rustup component add rust-analyzer`.\n  This is because `rust-toolchain.toml` selects our MSRV for the development toolchain but doesn't download the matching rust-analyzer automatically.\n\nWe provide an [architecture.md][architecture.md] that should give you\na good overview of the internals.\n\n# Auto generated documentation\n\nSome parts of [the book][docs] are autogenerated from the code itself,\nlike the list of `:commands` and supported languages. To generate these\nfiles, run\n\n```shell\ncargo xtask docgen\n```\n\ninside the project. We use [xtask][xtask] as an ad-hoc task runner.\n\nTo preview the book itself, install [mdbook][mdbook]. Then, run\n\n```shell\nmdbook serve book\n```\n\nand visit [http://localhost:3000](http://localhost:3000).\n\n# Testing\n\n## Unit tests/Documentation tests\n\nRun `cargo test --workspace` to run unit tests and documentation tests in all packages.\n\n## Integration tests\n\nIntegration tests for helix-term can be run with `cargo integration-test`. Code\ncontributors are strongly encouraged to write integration tests for their code.\nExisting tests can be used as examples. Helpers can be found in\n[helpers.rs][helpers.rs]. The log level can be set with the `HELIX_LOG_LEVEL`\nenvironment variable, e.g. `HELIX_LOG_LEVEL=debug cargo integration-test`.\n\nContributors using MacOS might encounter `Too many open files (os error 24)`\nfailures while running integration tests. This can be resolved by increasing\nthe default value (e.g. to `10240` from `256`) by running `ulimit -n 10240`.\n\n## Minimum Stable Rust Version (MSRV) Policy\n\nHelix keeps an intentionally low MSRV for the sake of easy building and packaging\ndownstream. We follow [Firefox's MSRV policy]. Once Firefox's MSRV increases we\nmay bump ours as well, but be sure to check that popular distributions like Ubuntu\npackage the new MSRV version. When increasing the MSRV, update these three places:\n\n* the `workspace.package.rust-version` key in `Cargo.toml` in the repository root\n* the `env.MSRV` key at the top of `.github/workflows/build.yml`\n* the `toolchain.channel` key in `rust-toolchain.toml`\n\n[Firefox's MSRV policy]: https://firefox-source-docs.mozilla.org/writing-rust-code/update-policy.html\n[good-first-issue]: https://github.com/helix-editor/helix/labels/E-easy\n[log-file]: https://github.com/helix-editor/helix/wiki/FAQ#access-the-log-file\n[architecture.md]: ./architecture.md\n[docs]: https://docs.helix-editor.com/\n[xtask]: https://github.com/matklad/cargo-xtask\n[mdbook]: https://rust-lang.github.io/mdBook/guide/installation.html\n[helpers.rs]: ../helix-term/tests/test/helpers.rs\n"
  },
  {
    "path": "docs/architecture.md",
    "content": "\n| Crate           | Description                                                      |\n| -----------     | -----------                                                      |\n| helix-stdx      | Extensions to the standard library (similar to [`rust-analyzer`'s](https://github.com/rust-lang/rust-analyzer/blob/ea413f67a8f730b4211c09e103f8207c62e7dbc3/crates/stdx/Cargo.toml#L5)) |\n| helix-core      | Core editing primitives, functional.                             |\n| helix-lsp       | Language server client                                           |\n| helix-lsp-types | Language Server Protocol type definitions                        |\n| helix-dap       | Debug Adapter Protocol (DAP) client                              |\n| helix-event     | Primitives for defining and handling events within the editor    |\n| helix-loader    | Functions for building, fetching, and loading external resources |\n| helix-view      | UI abstractions for use in backends, imperative shell.           |\n| helix-term      | Terminal UI                                                      |\n| helix-tui       | TUI primitives, forked from tui-rs, inspired by Cursive          |\n\n\nThis document contains a high-level overview of Helix internals.\n\n> NOTE: Use `cargo doc --open` for API documentation as well as dependency\n> documentation.\n\n## Core\n\nThe core contains basic building blocks used to construct the editor. It is\nheavily based on [CodeMirror 6](https://codemirror.net/6/docs/). The primitives\nare functional: most operations won't modify data in place but instead return\na new copy.\n\nThe main data structure used for representing buffers is a `Rope`. We re-export\nthe excellent [ropey](https://github.com/cessen/ropey) library. Ropes are cheap\nto clone, and allow us to easily make snapshots of a text state.\n\nMultiple selections are a core editing primitive. Document selections are\nrepresented by a `Selection`. Each `Range` in the selection consists of a moving\n`head` and an immovable `anchor`. A single cursor in the editor is simply\na selection with a single range, with the head and the anchor in the same\nposition.\n\nRopes are modified by constructing an OT-like `Transaction`. It represents\na single coherent change to the document and can be applied to the rope.\nA transaction can be inverted to produce an undo. Selections and marks can be\nmapped over a transaction to translate to a position in the new text state after\napplying the transaction.\n\n> NOTE: `Transaction::change`/`Transaction::change_by_selection` is the main\n> interface used to generate text edits.\n\n`Syntax` is the interface used to interact with tree-sitter ASTs for syntax\nhighlighting and other features.\n\n## View\n\nThe `view` layer was supposed to be a frontend-agnostic imperative library that\nwould build on top of `core` to provide the common editor logic. Currently it's\ntied to the terminal UI.\n\nA `Document` ties together the `Rope`, `Selection`(s), `Syntax`, document\n`History`, language server (etc.) into a comprehensive representation of an open\nfile.\n\nA `View` represents an open split in the UI. It holds the currently open\ndocument ID and other related state. Views encapsulate the gutter, status line,\ndiagnostics, and the inner area where the code is displayed.\n\n> NOTE: Multiple views are able to display the same document, so the document\n> contains selections for each view. To retrieve, `document.selection()` takes\n> a `ViewId`.\n\n`Info` is the autoinfo box that shows hints when awaiting another key with bindings\nlike `g` and `m`. It is attached to the viewport as a whole.\n\n`Surface` is like a buffer to which widgets draw themselves to, and the\nsurface is then rendered on the screen on each cycle.\n\n`Rect`s are areas (simply an x and y coordinate with the origin at the\nscreen top left and then a height and width) which are part of a\n`Surface`. They can be used to limit the area to which a `Component` can\nrender. For example if we wrap a `Markdown` component in a `Popup`\n(think the documentation popup with space+k), Markdown's render method\nwill get a Rect that is the exact size of the popup.\n\nWidgets are called `Component`s internally, and you can see most of them\nin `helix-term/src/ui`. Some components like `Popup` and `Overlay` can take\nother components as children.\n\n`Layer`s are how multiple components are displayed, and is simply a\n`Vec<Component>`. Layers are managed by the `Compositor`. On each top\nlevel render call, the compositor renders each component in the order\nthey were pushed into the stack. This makes multiple components \"layer\"\non top of one another. Hence we get a file picker displayed over the\neditor, etc.\n\nThe `Editor` holds the global state: all the open documents, a tree\nrepresentation of all the view splits, the configuration, and a registry of \nlanguage servers. To open or close files, interact with the editor.\n\n## LSP\n\nA language server protocol client.\n\n## Term\n\nThe terminal frontend.\n\nThe `main` function sets up a new `Application` that runs the event loop.\n\n`commands.rs` is probably the most interesting file. It contains all commands\n(actions tied to keybindings). \n\n`keymap.rs` links commands to key combinations.\n\n\n## TUI / Term\n\nTODO: document Component and rendering related stuff\n\n## Event\n\nThe `helix-event` crate defines primitives for defining and acting on events\nwithin the editor. \"Events\" cover things like opening, changing and closing of\ndocuments, starting and stopping of language servers and more.\n\n`helix-event` has tools for defining events and registering _hooks_ which run\nany time an event is emitted. `helix-event` also provides `AsyncHook` - a tool\nfor running cancellable tasks which run after events with _debouncing_.\n\nSee the `AsyncHook` type for more information. Events can be created within the\n`events!` macro. Synchronous hooks can be created with `register_hook!`. And\neditor-wide events can be sent to hooks with `helix_event::dispatch`.\n"
  },
  {
    "path": "docs/releases.md",
    "content": "## Checklist\n\nHelix releases are versioned in the Calendar Versioning scheme:\n`YY.0M(.MICRO)`, for example, `22.05` for May of 2022, or in a patch release,\n`22.05.1`. In these instructions we'll use `<tag>` as a placeholder for the tag\nbeing published.\n\n* Merge the PR with the release updates. That branch should:\n    * Update the version:\n        * Update the `workspace.package.version` key in `Cargo.toml`. Cargo only accepts\n          SemVer versions so a CalVer version of `22.07` for example must be formatted\n          as `22.7.0`. Patch/bugfix releases should increment the SemVer patch number. A\n          patch release for 22.07 would be `22.7.1`.\n        * Run `cargo check` and commit the resulting change to `Cargo.lock`\n    * Add changelog notes to `CHANGELOG.md`\n    * Add new `<release>` entry in `contrib/Helix.appdata.xml` with release information according to the [AppStream spec](https://www.freedesktop.org/software/appstream/docs/sect-Metadata-Releases.html)\n* Tag and push\n    * Switch to master and pull\n    * `git tag -s -m \"<tag>\" -a <tag> && git push origin <tag>` (note the `-s` which signs the tag)\n* Wait for the Release CI to finish\n    * It will automatically turn the git tag into a GitHub release when it uploads artifacts\n* Edit the new release\n    * Use `<tag>` as the title\n    * Link to the changelog and release notes\n* Merge the release notes PR\n* Download the macos and linux binaries and update the `sha256`s in the [homebrew formula]\n    * Use `sha256sum` on the downloaded `.tar.xz` files to determine the hash\n* Link to the release notes in this-week-in-rust\n    * [Example PR](https://github.com/rust-lang/this-week-in-rust/pull/3300)\n* Post to reddit\n    * [Example post](https://www.reddit.com/r/rust/comments/uzp5ze/helix_editor_2205_released/)\n\n[homebrew formula]: https://github.com/Homebrew/homebrew-core/blob/master/Formula/h/helix.rb\n\n## Changelog Curation\n\nThe changelog is currently created manually by reading through commits in the\nlog since the last release. GitHub's compare view is a nice way to approach\nthis. For example, when creating the 22.07 release notes, this compare link\nmay be used\n\n```\nhttps://github.com/helix-editor/helix/compare/22.05...master\n```\n\nEither side of the triple-dot may be replaced with an exact revision, so if\nyou wish to incrementally compile the changelog, you can tackle a weeks worth\nor so, record the revision where you stopped, and use that as a starting point\nnext week:\n\n```\nhttps://github.com/helix-editor/helix/compare/7706a4a0d8b67b943c31d0c5f7b00d357b5d838d...master\n```\n\nA work-in-progress commit for a changelog might look like\n[this example](https://github.com/helix-editor/helix/commit/831adfd4c709ca16b248799bfef19698d5175e55).\n\nNot every PR or commit needs a blurb in the changelog. Each release section\ntends to have a blurb that links to a GitHub comparison between release\nversions for convenience:\n\n> As usual, the following is a summary of each of the changes since the last\n> release. For the full log, check out the git log.\n\nTypically, small changes like dependencies or documentation updates, refactors,\nor meta changes like GitHub Actions work are left out.\n"
  },
  {
    "path": "docs/vision.md",
    "content": "The Helix project still has a ways to go before reaching its goals.  This document outlines some of those goals and the overall vision for the project.\n\n# Vision\n\nAn efficient, batteries-included editor you can take anywhere and be productive... if it's your kind of thing.\n\n* **Cross-platform.**  Whether on Linux, Windows, or OSX, you should be able to take your editor with you.\n* **Terminal first.**  Not all environments have a windowing system, and you shouldn't have to abandon your preferred editor in those cases.\n* **Native.**  No Electron or HTML DOM here.  We want an efficient, native-compiled editor that can run with minimal resources when needed.  If you're working on a Raspberry Pi, your editor shouldn't consume half of your RAM.\n* **Batteries included.**  Both the default configuration and bundled features should be enough to have a good editing experience and be productive.  You shouldn't need a massive custom config or external executables and plugins for basic features and functionality.\n* **Don't try to be everything for everyone.**  There are many great editors out there to choose from.  Let's make Helix *one of* those great options, with its own take on things.\n\n# Goals\n\nVision statements are all well and good, but are also vague and subjective.  Here is a (non-exhaustive) list of some of Helix's more concrete goals, to help give a clearer idea of the project's direction:\n\n* **Modal.**  Vim is a great idea.\n* **Selection -> Action**, not Verb -> Object.  Interaction models aren't linguistics, and \"selection first\" lets you see what you're doing (among other benefits).\n* **We aren't playing code golf.**  It's more important for the keymap to be consistent and easy to memorize than it is to save a key stroke or two when editing.\n* **Built-in tools** for working with code bases efficiently.  Most projects aren't a single file, and an editor should handle that as a first-class use case.  In Helix's case, this means (among other things) a fuzzy-search file navigator and LSP support.\n* **Edit anything** that comes up when coding, within reason.  Whether it's a 200 MB XML file, a megabyte of minified javascript on a single line, or Japanese text encoded in ShiftJIS, you should be able to open it and edit it without problems.  (Note: this doesn't mean handle every esoteric use case.  Sometimes you do just need a specialized tool, and Helix isn't that.)\n* **Configurable**, within reason.  Although the defaults should be good, not everyone will agree on what \"good\" is.  Within the bounds of Helix's core interaction models, it should be reasonably configurable so that it can be \"good\" for more people.  This means, for example, custom key maps among other things.\n* **Extensible**, within reason.  Although we want Helix to be productive out-of-the-box, it's not practical or desirable to cram every useful feature and use case into the core editor.  The basics should be built-in, but you should be able to extend it with additional functionality as needed.\n* **Clean code base.**  Sometimes other factors (e.g. significant performance gains, important features, correctness, etc.) will trump strict readability, but we nevertheless want to keep the code base straightforward and easy to understand to the extent we can.\n"
  },
  {
    "path": "flake.nix",
    "content": "{\n  description = \"A post-modern text editor.\";\n\n  inputs = {\n    nixpkgs.url = \"github:nixos/nixpkgs/nixos-unstable\";\n    rust-overlay = {\n      url = \"github:oxalica/rust-overlay\";\n      inputs.nixpkgs.follows = \"nixpkgs\";\n    };\n  };\n\n  outputs = {\n    self,\n    nixpkgs,\n    rust-overlay,\n    ...\n  }: let\n    inherit (nixpkgs) lib;\n    eachSystem = lib.genAttrs lib.systems.flakeExposed;\n    pkgsFor = eachSystem (system:\n      import nixpkgs {\n        localSystem.system = system;\n        overlays = [(import rust-overlay) self.overlays.helix];\n      });\n    gitRev = self.rev or self.dirtyRev or null;\n  in {\n    packages = eachSystem (system: {\n      inherit (pkgsFor.${system}) helix;\n      /*\n      The default Helix build. Uses the latest stable Rust toolchain, and unstable\n      nixpkgs.\n\n      The build inputs can be overridden with the following:\n\n      packages.${system}.default.override { rustPlatform = newPlatform; };\n\n      Overriding a derivation attribute can be done as well:\n\n      packages.${system}.default.overrideAttrs { buildType = \"debug\"; };\n      */\n      default = self.packages.${system}.helix;\n    });\n    checks =\n      lib.mapAttrs (system: pkgs: let\n        # Get Helix's MSRV toolchain to build with by default.\n        msrvToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;\n        msrvPlatform = pkgs.makeRustPlatform {\n          cargo = msrvToolchain;\n          rustc = msrvToolchain;\n        };\n      in {\n        helix = self.packages.${system}.helix.override {\n          rustPlatform = msrvPlatform;\n        };\n      })\n      pkgsFor;\n\n    # Devshell behavior is preserved.\n    devShells =\n      lib.mapAttrs (system: pkgs: {\n        default = let\n          commonRustFlagsEnv = \"-C link-arg=-fuse-ld=lld -C target-cpu=native --cfg tokio_unstable\";\n          platformRustFlagsEnv = lib.optionalString pkgs.stdenv.isLinux \"-Clink-arg=-Wl,--no-rosegment\";\n        in\n          pkgs.mkShell {\n            inputsFrom = [self.checks.${system}.helix];\n            nativeBuildInputs = with pkgs;\n              [\n                lld\n                cargo-flamegraph\n                rust-bin.nightly.latest.rust-analyzer\n              ]\n              ++ (lib.optional (stdenv.isx86_64 && stdenv.isLinux) cargo-tarpaulin)\n              ++ (lib.optional stdenv.isLinux lldb);\n            shellHook = ''\n              export RUST_BACKTRACE=\"1\"\n              export RUSTFLAGS=\"''${RUSTFLAGS:-\"\"} ${commonRustFlagsEnv} ${platformRustFlagsEnv}\"\n            '';\n          };\n      })\n      pkgsFor;\n\n    overlays = {\n      helix = final: prev: {\n        helix = final.callPackage ./default.nix {inherit gitRev;};\n      };\n\n      default = self.overlays.helix;\n    };\n  };\n  nixConfig = {\n    extra-substituters = [\"https://helix.cachix.org\"];\n    extra-trusted-public-keys = [\"helix.cachix.org-1:ejp9KQpR1FBI2onstMQ34yogDm4OgU2ru6lIwPvuCVs=\"];\n  };\n}\n"
  },
  {
    "path": "grammars.nix",
    "content": "{\n  stdenv,\n  lib,\n  runCommand,\n  includeGrammarIf ? _: true,\n  grammarOverlays ? [],\n  ...\n}: let\n  languagesConfig =\n    builtins.fromTOML (builtins.readFile ./languages.toml);\n  isGitGrammar = grammar:\n    builtins.hasAttr \"source\" grammar\n    && builtins.hasAttr \"git\" grammar.source\n    && builtins.hasAttr \"rev\" grammar.source;\n  isGitHubGrammar = grammar: lib.hasPrefix \"https://github.com\" grammar.source.git;\n  toGitHubFetcher = url: let\n    match = builtins.match \"https://github\\\\.com/([^/]*)/([^/]*)/?\" url;\n  in {\n    owner = builtins.elemAt match 0;\n    repo = builtins.elemAt match 1;\n  };\n  # If `use-grammars.only` is set, use only those grammars.\n  # If `use-grammars.except` is set, use all other grammars.\n  # Otherwise use all grammars.\n  useGrammar = grammar:\n    if languagesConfig ? use-grammars.only\n    then builtins.elem grammar.name languagesConfig.use-grammars.only\n    else if languagesConfig ? use-grammars.except\n    then !(builtins.elem grammar.name languagesConfig.use-grammars.except)\n    else true;\n  grammarsToUse = builtins.filter useGrammar languagesConfig.grammar;\n  gitGrammars = builtins.filter isGitGrammar grammarsToUse;\n  buildGrammar = grammar: let\n    gh = toGitHubFetcher grammar.source.git;\n    sourceGit = builtins.fetchTree {\n      type = \"git\";\n      url = grammar.source.git;\n      rev = grammar.source.rev;\n      ref = grammar.source.ref or \"HEAD\";\n      shallow = true;\n    };\n    sourceGitHub = builtins.fetchTree {\n      type = \"github\";\n      owner = gh.owner;\n      repo = gh.repo;\n      inherit (grammar.source) rev;\n    };\n    source =\n      if isGitHubGrammar grammar\n      then sourceGitHub\n      else sourceGit;\n  in\n    stdenv.mkDerivation {\n      # see https://github.com/NixOS/nixpkgs/blob/fbdd1a7c0bc29af5325e0d7dd70e804a972eb465/pkgs/development/tools/parsing/tree-sitter/grammar.nix\n\n      pname = \"helix-tree-sitter-${grammar.name}\";\n      version = grammar.source.rev;\n\n      src = source;\n      sourceRoot =\n        if builtins.hasAttr \"subpath\" grammar.source\n        then \"source/${grammar.source.subpath}\"\n        else \"source\";\n\n      dontConfigure = true;\n\n      FLAGS = [\n        \"-Isrc\"\n        \"-g\"\n        \"-O3\"\n        \"-fPIC\"\n        \"-fno-exceptions\"\n        \"-Wl,-z,relro,-z,now\"\n      ];\n\n      SHARED_LIB = grammar.name + stdenv.hostPlatform.extensions.sharedLibrary;\n\n      buildPhase = ''\n        runHook preBuild\n\n        if [[ -e src/scanner.cc ]]; then\n          $CXX -c src/scanner.cc -o scanner.o $FLAGS\n        elif [[ -e src/scanner.c ]]; then\n          $CC -c src/scanner.c -o scanner.o $FLAGS\n        fi\n\n        $CC -c src/parser.c -o parser.o $FLAGS\n        $CXX -shared -o $SHARED_LIB *.o\n\n        runHook postBuild\n      '';\n\n      installPhase = ''\n        runHook preInstall\n        mkdir $out\n        mv $SHARED_LIB $out/\n        runHook postInstall\n      '';\n\n      # Strip failed on darwin: strip: error: symbols referenced by indirect symbol table entries that can't be stripped\n      fixupPhase = lib.optionalString stdenv.isLinux ''\n        runHook preFixup\n        $STRIP $out/$SHARED_LIB\n        runHook postFixup\n      '';\n    };\n  grammarsToBuild = builtins.filter includeGrammarIf gitGrammars;\n  builtGrammars =\n    builtins.map (grammar: {\n      inherit (grammar) name;\n      value = buildGrammar grammar;\n    })\n    grammarsToBuild;\n  extensibleGrammars =\n    lib.makeExtensible (self: builtins.listToAttrs builtGrammars);\n  overlaidGrammars =\n    lib.pipe extensibleGrammars\n    (builtins.map (overlay: grammar: grammar.extend overlay) grammarOverlays);\n  sharedLibExtension = stdenv.hostPlatform.extensions.sharedLibrary;\n  grammarLinks =\n    lib.mapAttrsToList\n    (name: artifact: \"ln -s ${artifact}/${name}${sharedLibExtension} $out/${name}${sharedLibExtension}\")\n    (lib.filterAttrs (n: v: lib.isDerivation v) overlaidGrammars);\nin\n  runCommand \"consolidated-helix-grammars\" {} ''\n    mkdir -p $out\n    ${builtins.concatStringsSep \"\\n\" grammarLinks}\n  ''\n"
  },
  {
    "path": "helix-core/.gitignore",
    "content": "/target\nCargo.lock\n"
  },
  {
    "path": "helix-core/Cargo.toml",
    "content": "[package]\nname = \"helix-core\"\ndescription = \"Helix editor core editing primitives\"\ninclude = [\"src/**/*\", \"README.md\"]\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n[features]\nunicode-lines = [\"ropey/unicode_lines\"]\nintegration = []\n\n[dependencies]\nhelix-stdx = { path = \"../helix-stdx\" }\nhelix-loader = { path = \"../helix-loader\" }\nhelix-parsec = { path = \"../helix-parsec\" }\n\nropey.workspace = true\nsmallvec = \"1.15\"\nsmartstring = \"1.0.1\"\nunicode-segmentation.workspace = true\n# unicode-width is changing width definitions\n# that both break our logic and disagree with common\n# width definitions in terminals, we need to replace it.\n# For now lets lock the version to avoid rendering glitches\n# when installing without `--locked`\nunicode-width = \"=0.1.12\"\nunicode-general-category = \"1.1\"\nslotmap.workspace = true\ntree-house.workspace = true\nonce_cell = \"1.21\"\narc-swap = \"1\"\nregex = \"1\"\nbitflags.workspace = true\nfoldhash.workspace = true\nurl = \"2.5.4\"\n\nlog = \"0.4\"\nanyhow = \"1.0\"\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0\"\ntoml.workspace = true\n\nimara-diff =  \"0.2.0\"\nencoding_rs = \"0.8\"\n\nchrono = { version = \"0.4\", default-features = false, features = [\"alloc\", \"std\"] }\n\ntextwrap = \"0.16.2\"\n\nnucleo.workspace = true\nparking_lot.workspace = true\nglobset.workspace = true\nregex-cursor = \"0.1.5\"\n\n[dev-dependencies]\nquickcheck = { version = \"1\", default-features = false }\nindoc = \"2.0.6\"\n"
  },
  {
    "path": "helix-core/src/auto_pairs.rs",
    "content": "//! When typing the opening character of one of the possible pairs defined below,\n//! this module provides the functionality to insert the paired closing character.\n\nuse crate::{graphemes, movement::Direction, Range, Rope, Selection, Tendril, Transaction};\nuse std::collections::HashMap;\n\nuse smallvec::SmallVec;\n\n// Heavily based on https://github.com/codemirror/closebrackets/\npub const DEFAULT_PAIRS: &[(char, char)] = &[\n    ('(', ')'),\n    ('{', '}'),\n    ('[', ']'),\n    ('\\'', '\\''),\n    ('\"', '\"'),\n    ('`', '`'),\n];\n\n/// The type that represents the collection of auto pairs,\n/// keyed by both opener and closer.\n#[derive(Debug, Clone)]\npub struct AutoPairs(HashMap<char, Pair>);\n\n/// Represents the config for a particular pairing.\n#[derive(Debug, Clone, Copy)]\npub struct Pair {\n    pub open: char,\n    pub close: char,\n}\n\nimpl Pair {\n    /// true if open == close\n    pub fn same(&self) -> bool {\n        self.open == self.close\n    }\n\n    /// true if all of the pair's conditions hold for the given document and range\n    pub fn should_close(&self, doc: &Rope, range: &Range) -> bool {\n        let mut should_close = Self::next_is_not_alpha(doc, range);\n\n        if self.same() {\n            should_close &= Self::prev_is_not_alpha(doc, range);\n        }\n\n        should_close\n    }\n\n    pub fn next_is_not_alpha(doc: &Rope, range: &Range) -> bool {\n        let cursor = range.cursor(doc.slice(..));\n        let next_char = doc.get_char(cursor);\n        next_char.map(|c| !c.is_alphanumeric()).unwrap_or(true)\n    }\n\n    pub fn prev_is_not_alpha(doc: &Rope, range: &Range) -> bool {\n        let cursor = range.cursor(doc.slice(..));\n        let prev_char = prev_char(doc, cursor);\n        prev_char.map(|c| !c.is_alphanumeric()).unwrap_or(true)\n    }\n}\n\nimpl From<&(char, char)> for Pair {\n    fn from(&(open, close): &(char, char)) -> Self {\n        Self { open, close }\n    }\n}\n\nimpl From<(&char, &char)> for Pair {\n    fn from((open, close): (&char, &char)) -> Self {\n        Self {\n            open: *open,\n            close: *close,\n        }\n    }\n}\n\nimpl AutoPairs {\n    /// Make a new AutoPairs set with the given pairs and default conditions.\n    pub fn new<'a, V, A>(pairs: V) -> Self\n    where\n        V: IntoIterator<Item = A> + 'a,\n        A: Into<Pair>,\n    {\n        let mut auto_pairs = HashMap::new();\n\n        for pair in pairs.into_iter() {\n            let auto_pair = pair.into();\n\n            auto_pairs.insert(auto_pair.open, auto_pair);\n\n            if auto_pair.open != auto_pair.close {\n                auto_pairs.insert(auto_pair.close, auto_pair);\n            }\n        }\n\n        Self(auto_pairs)\n    }\n\n    pub fn get(&self, ch: char) -> Option<&Pair> {\n        self.0.get(&ch)\n    }\n}\n\nimpl Default for AutoPairs {\n    fn default() -> Self {\n        AutoPairs::new(DEFAULT_PAIRS.iter())\n    }\n}\n\n// insert hook:\n// Fn(doc, selection, char) => Option<Transaction>\n// problem is, we want to do this per range, so we can call default handler for some ranges\n// so maybe ret Vec<Option<Change>>\n// but we also need to be able to return transactions...\n//\n// to simplify, maybe return Option<Transaction> and just reimplement the default\n\n// [TODO]\n// * delete implementation where it erases the whole bracket (|) -> |\n// * change to multi character pairs to handle cases like placing the cursor in the\n//   middle of triple quotes, and more exotic pairs like Jinja's {% %}\n\n#[must_use]\npub fn hook(doc: &Rope, selection: &Selection, ch: char, pairs: &AutoPairs) -> Option<Transaction> {\n    log::trace!(\"autopairs hook selection: {:#?}\", selection);\n\n    if let Some(pair) = pairs.get(ch) {\n        if pair.same() {\n            return Some(handle_same(doc, selection, pair));\n        } else if pair.open == ch {\n            return Some(handle_open(doc, selection, pair));\n        } else if pair.close == ch {\n            // && char_at pos == close\n            return Some(handle_close(doc, selection, pair));\n        }\n    }\n\n    None\n}\n\nfn prev_char(doc: &Rope, pos: usize) -> Option<char> {\n    if pos == 0 {\n        return None;\n    }\n\n    doc.get_char(pos - 1)\n}\n\n/// calculate what the resulting range should be for an auto pair insertion\nfn get_next_range(doc: &Rope, start_range: &Range, offset: usize, len_inserted: usize) -> Range {\n    // When the character under the cursor changes due to complete pair\n    // insertion, we must look backward a grapheme and then add the length\n    // of the insertion to put the resulting cursor in the right place, e.g.\n    //\n    // foo[\\r\\n] - anchor: 3, head: 5\n    // foo([)]\\r\\n - anchor: 4, head: 5\n    //\n    // foo[\\r\\n] - anchor: 3, head: 5\n    // foo'[\\r\\n] - anchor: 4, head: 6\n    //\n    // foo([)]\\r\\n - anchor: 4, head: 5\n    // foo()[\\r\\n] - anchor: 5, head: 7\n    //\n    // [foo]\\r\\n - anchor: 0, head: 3\n    // [foo(])\\r\\n - anchor: 0, head: 5\n\n    // inserting at the very end of the document after the last newline\n    if start_range.head == doc.len_chars() && start_range.anchor == doc.len_chars() {\n        return Range::new(\n            start_range.anchor + offset + 1,\n            start_range.head + offset + 1,\n        );\n    }\n\n    let doc_slice = doc.slice(..);\n    let single_grapheme = start_range.is_single_grapheme(doc_slice);\n\n    // just skip over graphemes\n    if len_inserted == 0 {\n        let end_anchor = if single_grapheme {\n            graphemes::next_grapheme_boundary(doc_slice, start_range.anchor) + offset\n\n        // even for backward inserts with multiple grapheme selections,\n        // we want the anchor to stay where it is so that the relative\n        // selection does not change, e.g.:\n        //\n        // foo([) wor]d -> insert ) -> foo()[ wor]d\n        } else {\n            start_range.anchor + offset\n        };\n\n        return Range::new(\n            end_anchor,\n            graphemes::next_grapheme_boundary(doc_slice, start_range.head) + offset,\n        );\n    }\n\n    // trivial case: only inserted a single-char opener, just move the selection\n    if len_inserted == 1 {\n        let end_anchor = if single_grapheme || start_range.direction() == Direction::Backward {\n            start_range.anchor + offset + 1\n        } else {\n            start_range.anchor + offset\n        };\n\n        return Range::new(end_anchor, start_range.head + offset + 1);\n    }\n\n    // If the head = 0, then we must be in insert mode with a backward\n    // cursor, which implies the head will just move\n    let end_head = if start_range.head == 0 || start_range.direction() == Direction::Backward {\n        start_range.head + offset + 1\n    } else {\n        // We must have a forward cursor, which means we must move to the\n        // other end of the grapheme to get to where the new characters\n        // are inserted, then move the head to where it should be\n        let prev_bound = graphemes::prev_grapheme_boundary(doc_slice, start_range.head);\n        log::trace!(\n            \"prev_bound: {}, offset: {}, len_inserted: {}\",\n            prev_bound,\n            offset,\n            len_inserted\n        );\n        prev_bound + offset + len_inserted\n    };\n\n    let end_anchor = match (start_range.len(), start_range.direction()) {\n        // if we have a zero width cursor, it shifts to the same number\n        (0, _) => end_head,\n\n        // If we are inserting for a regular one-width cursor, the anchor\n        // moves with the head. This is the fast path for ASCII.\n        (1, Direction::Forward) => end_head - 1,\n        (1, Direction::Backward) => end_head + 1,\n\n        (_, Direction::Forward) => {\n            if single_grapheme {\n                graphemes::prev_grapheme_boundary(doc.slice(..), start_range.head) + 1\n\n            // if we are appending, the anchor stays where it is; only offset\n            // for multiple range insertions\n            } else {\n                start_range.anchor + offset\n            }\n        }\n\n        (_, Direction::Backward) => {\n            if single_grapheme {\n                // if we're backward, then the head is at the first char\n                // of the typed char, so we need to add the length of\n                // the closing char\n                graphemes::prev_grapheme_boundary(doc.slice(..), start_range.anchor)\n                    + len_inserted\n                    + offset\n            } else {\n                // when we are inserting in front of a selection, we need to move\n                // the anchor over by however many characters were inserted overall\n                start_range.anchor + offset + len_inserted\n            }\n        }\n    };\n\n    Range::new(end_anchor, end_head)\n}\n\nfn handle_open(doc: &Rope, selection: &Selection, pair: &Pair) -> Transaction {\n    let mut end_ranges = SmallVec::with_capacity(selection.len());\n    let mut offs = 0;\n\n    let transaction = Transaction::change_by_selection(doc, selection, |start_range| {\n        let cursor = start_range.cursor(doc.slice(..));\n        let next_char = doc.get_char(cursor);\n        let len_inserted;\n\n        // Since auto pairs are currently limited to single chars, we're either\n        // inserting exactly one or two chars. When arbitrary length pairs are\n        // added, these will need to be changed.\n        let change = match next_char {\n            Some(_) if !pair.should_close(doc, start_range) => {\n                len_inserted = 1;\n                let mut tendril = Tendril::new();\n                tendril.push(pair.open);\n                (cursor, cursor, Some(tendril))\n            }\n            _ => {\n                // insert open & close\n                let pair_str = Tendril::from_iter([pair.open, pair.close]);\n                len_inserted = 2;\n                (cursor, cursor, Some(pair_str))\n            }\n        };\n\n        let next_range = get_next_range(doc, start_range, offs, len_inserted);\n        end_ranges.push(next_range);\n        offs += len_inserted;\n\n        change\n    });\n\n    let t = transaction.with_selection(Selection::new(end_ranges, selection.primary_index()));\n    log::debug!(\"auto pair transaction: {:#?}\", t);\n    t\n}\n\nfn handle_close(doc: &Rope, selection: &Selection, pair: &Pair) -> Transaction {\n    let mut end_ranges = SmallVec::with_capacity(selection.len());\n    let mut offs = 0;\n\n    let transaction = Transaction::change_by_selection(doc, selection, |start_range| {\n        let cursor = start_range.cursor(doc.slice(..));\n        let next_char = doc.get_char(cursor);\n        let mut len_inserted = 0;\n\n        let change = if next_char == Some(pair.close) {\n            // return transaction that moves past close\n            (cursor, cursor, None) // no-op\n        } else {\n            len_inserted = 1;\n            let mut tendril = Tendril::new();\n            tendril.push(pair.close);\n            (cursor, cursor, Some(tendril))\n        };\n\n        let next_range = get_next_range(doc, start_range, offs, len_inserted);\n        end_ranges.push(next_range);\n        offs += len_inserted;\n\n        change\n    });\n\n    let t = transaction.with_selection(Selection::new(end_ranges, selection.primary_index()));\n    log::debug!(\"auto pair transaction: {:#?}\", t);\n    t\n}\n\n/// handle cases where open and close is the same, or in triples (\"\"\"docstring\"\"\")\nfn handle_same(doc: &Rope, selection: &Selection, pair: &Pair) -> Transaction {\n    let mut end_ranges = SmallVec::with_capacity(selection.len());\n\n    let mut offs = 0;\n\n    let transaction = Transaction::change_by_selection(doc, selection, |start_range| {\n        let cursor = start_range.cursor(doc.slice(..));\n        let mut len_inserted = 0;\n        let next_char = doc.get_char(cursor);\n\n        let change = if next_char == Some(pair.open) {\n            //  return transaction that moves past close\n            (cursor, cursor, None) // no-op\n        } else {\n            let mut pair_str = Tendril::new();\n            pair_str.push(pair.open);\n\n            // for equal pairs, don't insert both open and close if either\n            // side has a non-pair char\n            if pair.should_close(doc, start_range) {\n                pair_str.push(pair.close);\n            }\n\n            len_inserted += pair_str.chars().count();\n            (cursor, cursor, Some(pair_str))\n        };\n\n        let next_range = get_next_range(doc, start_range, offs, len_inserted);\n        end_ranges.push(next_range);\n        offs += len_inserted;\n\n        change\n    });\n\n    let t = transaction.with_selection(Selection::new(end_ranges, selection.primary_index()));\n    log::debug!(\"auto pair transaction: {:#?}\", t);\n    t\n}\n"
  },
  {
    "path": "helix-core/src/case_conversion.rs",
    "content": "use crate::Tendril;\n\n// todo: should this be grapheme aware?\n\npub fn to_pascal_case(text: impl Iterator<Item = char>) -> Tendril {\n    let mut res = Tendril::new();\n    to_pascal_case_with(text, &mut res);\n    res\n}\n\npub fn to_pascal_case_with(text: impl Iterator<Item = char>, buf: &mut Tendril) {\n    let mut at_word_start = true;\n    for c in text {\n        // we don't count _ as a word char here so case conversions work well\n        if !c.is_alphanumeric() {\n            at_word_start = true;\n            continue;\n        }\n        if at_word_start {\n            at_word_start = false;\n            buf.extend(c.to_uppercase());\n        } else {\n            buf.push(c)\n        }\n    }\n}\n\npub fn to_upper_case_with(text: impl Iterator<Item = char>, buf: &mut Tendril) {\n    for c in text {\n        for c in c.to_uppercase() {\n            buf.push(c)\n        }\n    }\n}\n\npub fn to_lower_case_with(text: impl Iterator<Item = char>, buf: &mut Tendril) {\n    for c in text {\n        for c in c.to_lowercase() {\n            buf.push(c)\n        }\n    }\n}\n\npub fn to_camel_case(text: impl Iterator<Item = char>) -> Tendril {\n    let mut res = Tendril::new();\n    to_camel_case_with(text, &mut res);\n    res\n}\npub fn to_camel_case_with(mut text: impl Iterator<Item = char>, buf: &mut Tendril) {\n    for c in &mut text {\n        if c.is_alphanumeric() {\n            buf.extend(c.to_lowercase())\n        }\n    }\n    let mut at_word_start = false;\n    for c in text {\n        // we don't count _ as a word char here so case conversions work well\n        if !c.is_alphanumeric() {\n            at_word_start = true;\n            continue;\n        }\n        if at_word_start {\n            at_word_start = false;\n            buf.extend(c.to_uppercase());\n        } else {\n            buf.push(c)\n        }\n    }\n}\n"
  },
  {
    "path": "helix-core/src/chars.rs",
    "content": "//! Utility functions to categorize a `char`.\n\nuse crate::LineEnding;\n\n#[derive(Debug, Eq, PartialEq)]\npub enum CharCategory {\n    Whitespace,\n    Eol,\n    Word,\n    Punctuation,\n    Unknown,\n}\n\n#[inline]\npub fn categorize_char(ch: char) -> CharCategory {\n    if char_is_line_ending(ch) {\n        CharCategory::Eol\n    } else if ch.is_whitespace() {\n        CharCategory::Whitespace\n    } else if char_is_word(ch) {\n        CharCategory::Word\n    } else if char_is_punctuation(ch) {\n        CharCategory::Punctuation\n    } else {\n        CharCategory::Unknown\n    }\n}\n\n/// Determine whether a character is a line ending.\n#[inline]\npub fn char_is_line_ending(ch: char) -> bool {\n    LineEnding::from_char(ch).is_some()\n}\n\n/// Determine whether a character qualifies as (non-line-break)\n/// whitespace.\n#[inline]\npub fn char_is_whitespace(ch: char) -> bool {\n    // TODO: this is a naive binary categorization of whitespace\n    // characters.  For display, word wrapping, etc. we'll need a better\n    // categorization based on e.g. breaking vs non-breaking spaces\n    // and whether they're zero-width or not.\n    match ch {\n        //'\\u{1680}' | // Ogham Space Mark (here for completeness, but usually displayed as a dash, not as whitespace)\n        '\\u{0009}' | // Character Tabulation\n        '\\u{0020}' | // Space\n        '\\u{00A0}' | // No-break Space\n        '\\u{180E}' | // Mongolian Vowel Separator\n        '\\u{202F}' | // Narrow No-break Space\n        '\\u{205F}' | // Medium Mathematical Space\n        '\\u{3000}' | // Ideographic Space\n        '\\u{FEFF}'   // Zero Width No-break Space\n        => true,\n\n        // En Quad, Em Quad, En Space, Em Space, Three-per-em Space,\n        // Four-per-em Space, Six-per-em Space, Figure Space,\n        // Punctuation Space, Thin Space, Hair Space, Zero Width Space.\n        ch if ('\\u{2000}' ..= '\\u{200B}').contains(&ch) => true,\n\n        _ => false,\n    }\n}\n\n#[inline]\npub fn char_is_punctuation(ch: char) -> bool {\n    use unicode_general_category::{get_general_category, GeneralCategory};\n\n    matches!(\n        get_general_category(ch),\n        GeneralCategory::OtherPunctuation\n            | GeneralCategory::OpenPunctuation\n            | GeneralCategory::ClosePunctuation\n            | GeneralCategory::InitialPunctuation\n            | GeneralCategory::FinalPunctuation\n            | GeneralCategory::ConnectorPunctuation\n            | GeneralCategory::DashPunctuation\n            | GeneralCategory::MathSymbol\n            | GeneralCategory::CurrencySymbol\n            | GeneralCategory::ModifierSymbol\n    )\n}\n\n#[inline]\npub fn char_is_word(ch: char) -> bool {\n    ch.is_alphanumeric() || ch == '_'\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn test_categorize() {\n        #[cfg(not(feature = \"unicode-lines\"))]\n        const EOL_TEST_CASE: &str = \"\\n\";\n        #[cfg(feature = \"unicode-lines\")]\n        const EOL_TEST_CASE: &str = \"\\n\\u{000B}\\u{000C}\\u{0085}\\u{2028}\\u{2029}\";\n        const WORD_TEST_CASE: &str = \"_hello_world_あいうえおー1234567890１２３４５６７８９０\";\n        const PUNCTUATION_TEST_CASE: &str =\n            \"!\\\"#$%&\\'()*+,-./:;<=>?@[\\\\]^`{|}~！”＃＄％＆’（）＊＋、。：；＜＝＞？＠「」＾｀｛｜｝～\";\n        const WHITESPACE_TEST_CASE: &str = \"  　   \";\n\n        for ch in EOL_TEST_CASE.chars() {\n            assert_eq!(CharCategory::Eol, categorize_char(ch));\n        }\n\n        for ch in WHITESPACE_TEST_CASE.chars() {\n            assert_eq!(\n                CharCategory::Whitespace,\n                categorize_char(ch),\n                \"Testing '{}', but got `{:?}` instead of `Category::Whitespace`\",\n                ch,\n                categorize_char(ch)\n            );\n        }\n\n        for ch in WORD_TEST_CASE.chars() {\n            assert_eq!(\n                CharCategory::Word,\n                categorize_char(ch),\n                \"Testing '{}', but got `{:?}` instead of `Category::Word`\",\n                ch,\n                categorize_char(ch)\n            );\n        }\n\n        for ch in PUNCTUATION_TEST_CASE.chars() {\n            assert_eq!(\n                CharCategory::Punctuation,\n                categorize_char(ch),\n                \"Testing '{}', but got `{:?}` instead of `Category::Punctuation`\",\n                ch,\n                categorize_char(ch)\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "helix-core/src/command_line.rs",
    "content": "//! Types and parsing code for command mode (`:`) input.\n//!\n//! Command line parsing is done in steps:\n//!\n//! * The `Tokenizer` iterator returns `Token`s from the command line input naively - without\n//!   accounting for a command's signature.\n//! * When executing a command (pressing `<ret>` in command mode), tokens are expanded with\n//!   information from the editor like the current cursor line or column. Otherwise the tokens\n//!   are unwrapped to their inner content.\n//! * `Args` interprets the contents (potentially expanded) as flags or positional arguments.\n//!   When executing a command, `Args` performs validations like checking the number of positional\n//!   arguments supplied and whether duplicate or unknown flags were supplied.\n//!\n//! `Args` is the interface used by typable command implementations. `Args` may be treated as a\n//! slice of `Cow<str>` or `&str` to access positional arguments, for example `for arg in args`\n//! iterates over positional args (never flags) and `&args[0]` always corresponds to the first\n//! positional. Use `Args::has_flag` and `Args::get_flag` to read any specified flags.\n//!\n//! `Args` and `Tokenizer` are intertwined. `Args` may ask the `Tokenizer` for the rest of the\n//! command line as a single token after the configured number of positionals has been reached\n//! (according to `raw_after`). This is used for the custom parsing in `:set-option` and\n//! `:toggle-option` for example. Outside of executing commands, the `Tokenizer` can be used\n//! directly to interpret a string according to the regular tokenization rules.\n//!\n//! This module also defines structs for configuring the parsing of the command line for a\n//! command. See `Flag` and `Signature`.\n\nuse std::{borrow::Cow, collections::HashMap, error::Error, fmt, ops, slice, vec};\n\n/// Splits a command line into the command and arguments parts.\n///\n/// The third tuple member describes whether the command part is finished. When this boolean is\n/// true the completion code for the command line should complete command names, otherwise\n/// command arguments.\npub fn split(line: &str) -> (&str, &str, bool) {\n    const SEPARATOR_PATTERN: [char; 2] = [' ', '\\t'];\n\n    let (command, rest) = line.split_once(SEPARATOR_PATTERN).unwrap_or((line, \"\"));\n\n    let complete_command =\n        command.is_empty() || (rest.trim().is_empty() && !line.ends_with(SEPARATOR_PATTERN));\n\n    (command, rest, complete_command)\n}\n\n/// A Unix-like flag that a command may accept.\n///\n/// For example the `:sort` command accepts a `--reverse` (or `-r` for shorthand) boolean flag\n/// which controls the direction of sorting. Flags may accept an argument by setting the\n/// `completions` field to `Some`.\n#[derive(Debug, Clone, Copy)]\npub struct Flag {\n    /// The name of the flag.\n    ///\n    /// This value is also used to construct the \"longhand\" version of the flag. For example a\n    /// flag with a name \"reverse\" has a longhand `--reverse`.\n    ///\n    /// This value should be supplied when reading a flag out of the [Args] with [Args::get_flag]\n    /// and [Args::has_flag]. The `:sort` command implementation for example should ask for\n    /// `args.has_flag(\"reverse\")`.\n    pub name: &'static str,\n    /// The character that can be used as a shorthand for the flag, optionally.\n    ///\n    /// For example a flag like \"reverse\" mentioned above might take an alias `Some('r')` to\n    /// allow specifying the flag as `-r`.\n    pub alias: Option<char>,\n    pub doc: &'static str,\n    /// The completion values to use when specifying an argument for a flag.\n    ///\n    /// This should be set to `None` for boolean flags and `Some(&[\"foo\", \"bar\", \"baz\"])` for\n    /// example for flags which accept options, with the strings corresponding to values that\n    /// should be shown in completion.\n    pub completions: Option<&'static [&'static str]>,\n}\n\nimpl Flag {\n    // This allows defining flags with the `..Flag::DEFAULT` shorthand. The `name` and `doc`\n    // fields should always be overwritten.\n    pub const DEFAULT: Self = Self {\n        name: \"\",\n        doc: \"\",\n        alias: None,\n        completions: None,\n    };\n}\n\n/// A description of how a command's input should be handled.\n///\n/// Each typable command defines a signature (with the help of `Signature::DEFAULT`) at least to\n/// declare how many positional arguments it accepts. Command flags are also declared in this\n/// struct. The `raw_after` option may be set optionally to avoid evaluating quotes in parts of\n/// the command line (useful for shell commands for example).\n#[derive(Debug, Clone, Copy)]\n#[allow(clippy::manual_non_exhaustive)]\npub struct Signature {\n    /// The minimum and (optionally) maximum number of positional arguments a command may take.\n    ///\n    /// For example accepting exactly one positional can be specified with `(1, Some(1))` while\n    /// accepting zero-or-more positionals can be specified as `(0, None)`.\n    ///\n    /// The number of positionals is checked when hitting `<ret>` in command mode. If the actual\n    /// number of positionals is outside the declared range then the command is not executed and\n    /// an error is shown instead. For example `:write` accepts zero or one positional arguments\n    /// (`(0, Some(1))`). A command line like `:write a.txt b.txt` is outside the declared range\n    /// and is not accepted.\n    pub positionals: (usize, Option<usize>),\n    /// The number of **positional** arguments for the parser to read with normal quoting rules.\n    ///\n    /// Once the number has been exceeded then the tokenizer returns the rest of the input as a\n    /// `TokenKind::Expand` token (see `Tokenizer::rest`), meaning that quoting rules do not apply\n    /// and none of the remaining text may be treated as a flag.\n    ///\n    /// If this is set to `None` then the entire command line is parsed with normal quoting and\n    /// flag rules.\n    ///\n    /// A good example use-case for this option is `:toggle-option` which sets `Some(1)`.\n    /// Everything up to the first positional argument is interpreted according to normal rules\n    /// and the rest of the input is parsed \"raw\". This allows `:toggle-option` to perform custom\n    /// parsing on the rest of the input - namely parsing complicated values as a JSON stream.\n    /// `:toggle-option` could accept a flag in the future. If so, the flag would need to come\n    /// before the first positional argument.\n    ///\n    /// Consider these lines for `:toggle-option` which sets `Some(1)`:\n    ///\n    /// * `:toggle foo` has one positional \"foo\" and no flags.\n    /// * `:toggle foo bar` has two positionals. Expansions for `bar` are evaluated but quotes\n    ///   and anything that looks like a flag are treated literally.\n    /// * `:toggle foo --bar` has two positionals: `[\"foo\", \"--bar\"]`. `--bar` is not considered\n    ///   to be a flag because it comes after the first positional.\n    /// * `:toggle --bar foo` has one positional \"foo\" and one flag \"--bar\".\n    /// * `:toggle --bar foo --baz` has two positionals `[\"foo\", \"--baz\"]` and one flag \"--bar\".\n    pub raw_after: Option<u8>,\n    /// A set of flags that a command may accept.\n    ///\n    /// See the `Flag` struct for more info.\n    pub flags: &'static [Flag],\n    /// Do not set this field. Use `..Signature::DEFAULT` to construct a `Signature` instead.\n    // This field allows adding new fields later with minimal code changes. This works like a\n    // `#[non_exhaustive]` annotation except that it supports the `..Signature::DEFAULT`\n    // shorthand.\n    pub _dummy: (),\n}\n\nimpl Signature {\n    // This allows defining signatures with the `..Signature::DEFAULT` shorthand. The\n    // `positionals` field should always be overwritten.\n    pub const DEFAULT: Self = Self {\n        positionals: (0, None),\n        raw_after: None,\n        flags: &[],\n        _dummy: (),\n    };\n\n    fn check_positional_count(&self, actual: usize) -> Result<(), ParseArgsError<'static>> {\n        let (min, max) = self.positionals;\n        if min <= actual && max.unwrap_or(usize::MAX) >= actual {\n            Ok(())\n        } else {\n            Err(ParseArgsError::WrongPositionalCount { min, max, actual })\n        }\n    }\n}\n\n#[derive(Debug, PartialEq, Eq)]\npub enum ParseArgsError<'a> {\n    WrongPositionalCount {\n        min: usize,\n        max: Option<usize>,\n        actual: usize,\n    },\n    UnterminatedToken {\n        token: Token<'a>,\n    },\n    DuplicatedFlag {\n        flag: &'static str,\n    },\n    UnknownFlag {\n        text: Cow<'a, str>,\n    },\n    FlagMissingArgument {\n        flag: &'static str,\n    },\n    MissingExpansionDelimiter {\n        expansion: &'a str,\n    },\n    UnknownExpansion {\n        kind: &'a str,\n    },\n}\n\nimpl fmt::Display for ParseArgsError<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::WrongPositionalCount { min, max, actual } => {\n                write!(f, \"expected \")?;\n                let maybe_plural = |n| if n == 1 { \"\" } else { \"s\" };\n                match (min, max) {\n                    (0, Some(0)) => write!(f, \"no arguments\")?,\n                    (min, Some(max)) if min == max => {\n                        write!(f, \"exactly {min} argument{}\", maybe_plural(*min))?\n                    }\n                    (min, _) if actual < min => {\n                        write!(f, \"at least {min} argument{}\", maybe_plural(*min))?\n                    }\n                    (_, Some(max)) if actual > max => {\n                        write!(f, \"at most {max} argument{}\", maybe_plural(*max))?\n                    }\n                    // `actual` must be either less than `min` or greater than `max` for this type\n                    // to be constructed.\n                    _ => unreachable!(),\n                }\n\n                write!(f, \", got {actual}\")\n            }\n            Self::UnterminatedToken { token } => {\n                write!(f, \"unterminated token {}\", token.content)\n            }\n            Self::DuplicatedFlag { flag } => {\n                write!(f, \"flag '--{flag}' specified more than once\")\n            }\n            Self::UnknownFlag { text } => write!(f, \"unknown flag '{text}'\"),\n            Self::FlagMissingArgument { flag } => {\n                write!(f, \"flag '--{flag}' missing an argument\")\n            }\n            Self::MissingExpansionDelimiter { expansion } => {\n                if expansion.is_empty() {\n                    write!(f, \"'%' was not properly escaped. Please use '%%'\")\n                } else {\n                    write!(f, \"missing a string delimiter after '%{expansion}'\")\n                }\n            }\n            Self::UnknownExpansion { kind } => {\n                write!(f, \"unknown expansion '{kind}'\")\n            }\n        }\n    }\n}\n\nimpl Error for ParseArgsError<'_> {}\n\n/// The kind of expansion to use on the token's content.\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum ExpansionKind {\n    /// Expand variables from the editor's state.\n    ///\n    /// For example `%{cursor_line}`.\n    Variable,\n    /// Treat the token contents as hexadecimal corresponding to a Unicode codepoint value.\n    ///\n    /// For example `%u{25CF}`.\n    Unicode,\n    /// Run the token's contents via the configured shell program.\n    ///\n    /// For example `%sh{echo hello}`.\n    Shell,\n}\n\nimpl ExpansionKind {\n    pub const VARIANTS: &'static [Self] = &[Self::Variable, Self::Unicode, Self::Shell];\n\n    pub const fn as_str(&self) -> &'static str {\n        match self {\n            Self::Variable => \"\",\n            Self::Unicode => \"u\",\n            Self::Shell => \"sh\",\n        }\n    }\n\n    pub fn from_kind(name: &str) -> Option<Self> {\n        match name {\n            \"\" => Some(Self::Variable),\n            \"u\" => Some(Self::Unicode),\n            \"sh\" => Some(Self::Shell),\n            _ => None,\n        }\n    }\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum Quote {\n    Single,\n    Backtick,\n}\n\nimpl Quote {\n    pub const fn char(&self) -> char {\n        match self {\n            Self::Single => '\\'',\n            Self::Backtick => '`',\n        }\n    }\n\n    // Quotes can be escaped by doubling them: `'hello '' world'` becomes `hello ' world`.\n    pub const fn escape(&self) -> &'static str {\n        match self {\n            Self::Single => \"''\",\n            Self::Backtick => \"``\",\n        }\n    }\n}\n\n/// The type of argument being written.\n///\n/// The token kind decides how an argument in the command line will be expanded upon hitting\n/// `<ret>` in command mode.\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum TokenKind {\n    /// Unquoted text.\n    ///\n    /// For example in `:echo hello world`, \"hello\" and \"world\" are raw tokens.\n    Unquoted,\n    /// Quoted text which is interpreted literally.\n    ///\n    /// The purpose of this kind is to avoid splitting arguments on whitespace. For example\n    /// `:open 'a b.txt'` will result in opening a file with a single argument `\"a b.txt\"`.\n    ///\n    /// Using expansions within single quotes or backticks will result in the expansion text\n    /// being shown literally. For example `:echo '%u{0020}'` will print `\"%u{0020}\"` to the\n    /// statusline.\n    Quoted(Quote),\n    /// Text within double quote delimiters (`\"`).\n    ///\n    /// The inner text of a double quoted argument can be further expanded. For example\n    /// `:echo \"line: #%{cursor_line}\"` could print `\"line: #1\"` to the statusline.\n    Expand,\n    /// An expansion / \"percent token\".\n    ///\n    /// These take the form `%[<kind>]<open><contents><close>`. See `ExpansionKind`.\n    Expansion(ExpansionKind),\n    /// A token kind that exists for the sake of completion.\n    ///\n    /// In input like `%foo` this token contains the text `\"%foo\"`. The content start is the byte\n    /// after the percent token.\n    ///\n    /// When `Tokenizer` is passed `true` for its `validate` parameter this token cannot be\n    /// returned: inputs that would return this token get a validation error instead.\n    ExpansionKind,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct Token<'a> {\n    pub kind: TokenKind,\n    /// The byte index into the input where the token's content starts.\n    ///\n    /// For quoted text this means the byte after the quote. For expansions this means the byte\n    /// after the opening delimiter.\n    pub content_start: usize,\n    /// The inner content of the token.\n    ///\n    /// Usually this content borrows from the input but an owned value may be used in cases of\n    /// escaping. On Unix systems a raw token like `a\\ b` has the contents `\"a b\"`.\n    pub content: Cow<'a, str>,\n    /// Whether the token's opening delimiter is closed.\n    ///\n    /// For example a quote `\"foo\"` is closed but not `\"foo` or an expansion `%sh{..}` is closed\n    /// but not `%sh{echo {}`.\n    pub is_terminated: bool,\n}\n\nimpl<'a> Token<'a> {\n    pub fn empty_at(content_start: usize) -> Self {\n        Self {\n            kind: TokenKind::Unquoted,\n            content_start,\n            content: Cow::Borrowed(\"\"),\n            is_terminated: false,\n        }\n    }\n\n    pub fn expand(content: impl Into<Cow<'a, str>>) -> Self {\n        Self {\n            kind: TokenKind::Expand,\n            content_start: 0,\n            content: content.into(),\n            is_terminated: true,\n        }\n    }\n}\n\n#[derive(Debug)]\npub struct Tokenizer<'a> {\n    input: &'a str,\n    /// Whether to return errors in the iterator for failed validations like unterminated strings\n    /// or expansions. When this is set to `false` the iterator will never return `Err`.\n    validate: bool,\n    /// The current byte index of the input being considered.\n    pos: usize,\n}\n\nimpl<'a> Tokenizer<'a> {\n    pub fn new(input: &'a str, validate: bool) -> Self {\n        Self {\n            input,\n            validate,\n            pos: 0,\n        }\n    }\n\n    /// Returns the current byte index position of the parser in the input.\n    pub fn pos(&self) -> usize {\n        self.pos\n    }\n\n    /// Returns the rest of the input as a single `TokenKind::Expand` token literally.\n    ///\n    /// Returns `None` if the tokenizer is already at the end of the input or advances the\n    /// tokenizer to the end of the input otherwise. Leading whitespace characters are skipped.\n    /// Quoting is not interpreted.\n    pub fn rest(&mut self) -> Option<Token<'a>> {\n        self.skip_blanks();\n\n        if self.pos == self.input.len() {\n            return None;\n        }\n\n        let content_start = self.pos;\n        self.pos = self.input.len();\n        Some(Token {\n            kind: TokenKind::Expand,\n            content_start,\n            content: Cow::Borrowed(&self.input[content_start..]),\n            is_terminated: false,\n        })\n    }\n\n    fn byte(&self) -> Option<u8> {\n        self.input.as_bytes().get(self.pos).copied()\n    }\n\n    fn peek_byte(&self) -> Option<u8> {\n        self.input.as_bytes().get(self.pos + 1).copied()\n    }\n\n    fn prev_byte(&self) -> Option<u8> {\n        self.pos\n            .checked_sub(1)\n            .map(|idx| self.input.as_bytes()[idx])\n    }\n\n    fn skip_blanks(&mut self) {\n        while let Some(b' ' | b'\\t') = self.byte() {\n            self.pos += 1;\n        }\n    }\n\n    fn parse_unquoted(&mut self) -> Cow<'a, str> {\n        // Note that `String::new` starts with no allocation. We only allocate if we see a\n        // backslash escape (on Unix only).\n        let mut escaped = String::new();\n        let mut start = self.pos;\n\n        while let Some(byte) = self.byte() {\n            if matches!(byte, b' ' | b'\\t') {\n                if cfg!(unix) && self.prev_byte() == Some(b'\\\\') {\n                    // Push everything up to but not including the backslash and then this\n                    // whitespace character.\n                    escaped.push_str(&self.input[start..self.pos - 1]);\n                    escaped.push(byte as char);\n                    start = self.pos + 1;\n                } else if escaped.is_empty() {\n                    return Cow::Borrowed(&self.input[start..self.pos]);\n                } else {\n                    break;\n                }\n            }\n\n            self.pos += 1;\n        }\n\n        // Special case for a trailing backslash on Unix: exclude the backslash from the content.\n        // This improves the behavior of completions like `\":open a\\\\\"` (trailing backslash).\n        let end = if cfg!(unix) && self.prev_byte() == Some(b'\\\\') {\n            self.pos - 1\n        } else {\n            self.pos\n        };\n\n        if escaped.is_empty() {\n            assert_eq!(self.pos, self.input.len());\n            Cow::Borrowed(&self.input[start..end])\n        } else {\n            escaped.push_str(&self.input[start..end]);\n            Cow::Owned(escaped)\n        }\n    }\n\n    /// Parses a string quoted by the given grapheme cluster.\n    ///\n    /// The position of the tokenizer is asserted to be immediately after the quote grapheme\n    /// cluster.\n    fn parse_quoted(&mut self, quote: u8) -> (Cow<'a, str>, bool) {\n        assert_eq!(self.byte(), Some(quote));\n        self.pos += 1;\n\n        let mut escaped = String::new();\n        while let Some(offset) = self.input[self.pos..].find(quote as char) {\n            let idx = self.pos + offset;\n            if self.input.as_bytes().get(idx + 1) == Some(&quote) {\n                // Treat two quotes in a row as an escape.\n                escaped.push_str(&self.input[self.pos..idx + 1]);\n                // Advance past the escaped quote.\n                self.pos = idx + 2;\n            } else {\n                // Otherwise this quote string is finished.\n                let quoted = if escaped.is_empty() {\n                    Cow::Borrowed(&self.input[self.pos..idx])\n                } else {\n                    escaped.push_str(&self.input[self.pos..idx]);\n                    Cow::Owned(escaped)\n                };\n                // Advance past the closing quote.\n                self.pos = idx + 1;\n                return (quoted, true);\n            }\n        }\n\n        let quoted = if escaped.is_empty() {\n            Cow::Borrowed(&self.input[self.pos..])\n        } else {\n            escaped.push_str(&self.input[self.pos..]);\n            Cow::Owned(escaped)\n        };\n        self.pos = self.input.len();\n\n        (quoted, false)\n    }\n\n    /// Parses the percent token expansion under the tokenizer's cursor.\n    ///\n    /// This function should only be called when the tokenizer's cursor is on a non-escaped\n    /// percent token.\n    pub fn parse_percent_token(&mut self) -> Option<Result<Token<'a>, ParseArgsError<'a>>> {\n        assert_eq!(self.byte(), Some(b'%'));\n\n        self.pos += 1;\n        let kind_start = self.pos;\n        self.pos += self.input[self.pos..]\n            .bytes()\n            .take_while(|b| b.is_ascii_lowercase())\n            .count();\n        let kind = &self.input[kind_start..self.pos];\n\n        let (open, close) = match self.byte() {\n            // We support a couple of hard-coded chars only to make sure we can provide more\n            // useful errors and avoid weird behavior in case of typos. These should cover\n            // practical cases.\n            Some(b'(') => (b'(', b')'),\n            Some(b'[') => (b'[', b']'),\n            Some(b'{') => (b'{', b'}'),\n            Some(b'<') => (b'<', b'>'),\n            Some(b'\\'') => (b'\\'', b'\\''),\n            Some(b'\\\"') => (b'\\\"', b'\\\"'),\n            Some(b'|') => (b'|', b'|'),\n            Some(_) | None => {\n                return Some(if self.validate {\n                    Err(ParseArgsError::MissingExpansionDelimiter { expansion: kind })\n                } else {\n                    Ok(Token {\n                        kind: TokenKind::ExpansionKind,\n                        content_start: kind_start,\n                        content: Cow::Borrowed(kind),\n                        is_terminated: false,\n                    })\n                });\n            }\n        };\n        // The content start for expansions is the start of the content - after the opening\n        // delimiter grapheme.\n        let content_start = self.pos + 1;\n        let kind = match ExpansionKind::from_kind(kind) {\n            Some(kind) => TokenKind::Expansion(kind),\n            None if self.validate => {\n                return Some(Err(ParseArgsError::UnknownExpansion { kind }));\n            }\n            None => TokenKind::Expand,\n        };\n\n        let (content, is_terminated) = if open == close {\n            self.parse_quoted(open)\n        } else {\n            self.parse_quoted_balanced(open, close)\n        };\n\n        let token = Token {\n            kind,\n            content_start,\n            content,\n            is_terminated,\n        };\n\n        if self.validate && !is_terminated {\n            return Some(Err(ParseArgsError::UnterminatedToken { token }));\n        }\n\n        Some(Ok(token))\n    }\n\n    /// Parse the next string under the cursor given an open and closing pair.\n    ///\n    /// The open and closing pair are different ASCII characters. The cursor is asserted to be\n    /// immediately after the opening delimiter.\n    ///\n    /// This function parses with nesting support. `%sh{echo {hello}}` for example should consume\n    /// the entire input and not quit after the first '}' character is found.\n    fn parse_quoted_balanced(&mut self, open: u8, close: u8) -> (Cow<'a, str>, bool) {\n        assert_eq!(self.byte(), Some(open));\n        self.pos += 1;\n        let start = self.pos;\n        let mut level = 1;\n\n        while let Some(offset) = self.input[self.pos..].find([open as char, close as char]) {\n            let idx = self.pos + offset;\n            // Move past the delimiter.\n            self.pos = idx + 1;\n\n            let byte = self.input.as_bytes()[idx];\n            if byte == open {\n                level += 1;\n            } else if byte == close {\n                level -= 1;\n                if level == 0 {\n                    break;\n                }\n            } else {\n                unreachable!()\n            }\n        }\n\n        let is_terminated = level == 0;\n        let end = if is_terminated {\n            // Exclude the closing delimiter from the token's content.\n            self.pos - 1\n        } else {\n            // When the token is not closed, advance to the end of the input.\n            self.pos = self.input.len();\n            self.pos\n        };\n\n        (Cow::Borrowed(&self.input[start..end]), is_terminated)\n    }\n}\n\nimpl<'a> Iterator for Tokenizer<'a> {\n    type Item = Result<Token<'a>, ParseArgsError<'a>>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.skip_blanks();\n\n        let byte = self.byte()?;\n        match byte {\n            b'\"' | b'\\'' | b'`' => {\n                let content_start = self.pos + 1;\n                let (content, is_terminated) = self.parse_quoted(byte);\n                let token = Token {\n                    kind: match byte {\n                        b'\"' => TokenKind::Expand,\n                        b'\\'' => TokenKind::Quoted(Quote::Single),\n                        b'`' => TokenKind::Quoted(Quote::Backtick),\n                        _ => unreachable!(),\n                    },\n                    content_start,\n                    content,\n                    is_terminated,\n                };\n\n                Some(if self.validate && !is_terminated {\n                    Err(ParseArgsError::UnterminatedToken { token })\n                } else {\n                    Ok(token)\n                })\n            }\n            b'%' => self.parse_percent_token(),\n            _ => {\n                let content_start = self.pos;\n\n                // Allow backslash escaping on Unix for quotes or expansions\n                if cfg!(unix)\n                    && byte == b'\\\\'\n                    && matches!(self.peek_byte(), Some(b'\"' | b'\\'' | b'`' | b'%'))\n                {\n                    self.pos += 1;\n                }\n\n                Some(Ok(Token {\n                    kind: TokenKind::Unquoted,\n                    content_start,\n                    content: self.parse_unquoted(),\n                    is_terminated: false,\n                }))\n            }\n        }\n    }\n}\n\n#[derive(Debug, Default, Clone, Copy)]\npub enum CompletionState {\n    #[default]\n    Positional,\n    Flag(Option<Flag>),\n    FlagArgument(Flag),\n}\n\n/// A set of arguments provided to a command on the command line.\n///\n/// Regular arguments are called \"positional\" arguments (or \"positionals\" for short). Command line\n/// input might also specify \"flags\" which can modify a command's behavior.\n///\n/// ```rust,ignore\n/// // Say that the command accepts a \"bar\" flag which doesn't accept an argument itself.\n/// // This input has two positionals, \"foo\" and \"baz\" and one flag \"--bar\".\n/// let args = Args::parse(\"foo --bar baz\", /* .. */);\n/// // `Args` may be treated like a slice to access positionals.\n/// assert_eq!(args.len(), 2);\n/// assert_eq!(&args[0], \"foo\");\n/// assert_eq!(&args[1], \"baz\");\n/// // Use `has_flag` or `get_flag` to access flags.\n/// assert!(args.has_flag(\"bar\"));\n/// ```\n///\n/// The `Args` type can be treated mostly the same as a slice when accessing positional arguments.\n/// Common slice methods like `len`, `get`, `first` and `join` only expose positional arguments.\n/// Additionally, common syntax like `for arg in args` or `&args[idx]` is supported for accessing\n/// positional arguments.\n///\n/// To look up flags, use `Args::get_flag` for flags which should accept an argument or\n/// `Args::has_flag` for boolean flags.\n///\n/// The way that `Args` is parsed from the input depends on a command's `Signature`. See the\n/// `Signature` type for more details.\n#[derive(Debug)]\npub struct Args<'a> {\n    signature: Signature,\n    /// Whether to validate the arguments.\n    /// See the `ParseArgsError` type for the validations.\n    validate: bool,\n    /// Whether args pushed with `Self::push` should be treated as positionals even if they\n    /// start with '-'.\n    only_positionals: bool,\n    state: CompletionState,\n    positionals: Vec<Cow<'a, str>>,\n    flags: HashMap<&'static str, Cow<'a, str>>,\n}\n\nimpl Default for Args<'_> {\n    fn default() -> Self {\n        Self {\n            signature: Signature::DEFAULT,\n            validate: Default::default(),\n            only_positionals: Default::default(),\n            state: CompletionState::default(),\n            positionals: Default::default(),\n            flags: Default::default(),\n        }\n    }\n}\n\nimpl<'a> Args<'a> {\n    pub fn new(signature: Signature, validate: bool) -> Self {\n        Self {\n            signature,\n            validate,\n            only_positionals: false,\n            positionals: Vec::new(),\n            flags: HashMap::new(),\n            state: CompletionState::default(),\n        }\n    }\n\n    /// Reads the next token out of the given parser.\n    ///\n    /// If the command's signature sets a maximum number of positionals (via `raw_after`) then\n    /// the token may contain the rest of the parser's input.\n    pub fn read_token<'p>(\n        &mut self,\n        parser: &mut Tokenizer<'p>,\n    ) -> Result<Option<Token<'p>>, ParseArgsError<'p>> {\n        if self\n            .signature\n            .raw_after\n            .is_some_and(|max| self.len() >= max as usize)\n        {\n            self.only_positionals = true;\n            Ok(parser.rest())\n        } else {\n            parser.next().transpose()\n        }\n    }\n\n    /// Parses the given command line according to a command's signature.\n    ///\n    /// The `try_map_fn` function can be used to try changing each token before it is considered\n    /// as an argument - this is used for variable expansion.\n    pub fn parse<M>(\n        line: &'a str,\n        signature: Signature,\n        validate: bool,\n        mut try_map_fn: M,\n    ) -> Result<Self, Box<dyn Error + 'a>>\n    where\n        // Note: this is a `FnMut` in case we decide to allow caching expansions in the future.\n        // The `mut` is not currently used.\n        M: FnMut(Token<'a>) -> Result<Cow<'a, str>, Box<dyn Error>>,\n    {\n        let mut tokenizer = Tokenizer::new(line, validate);\n        let mut args = Self::new(signature, validate);\n\n        while let Some(token) = args.read_token(&mut tokenizer)? {\n            let arg = try_map_fn(token)?;\n            args.push(arg)?;\n        }\n\n        args.finish()?;\n\n        Ok(args)\n    }\n\n    /// Adds the given argument token.\n    ///\n    /// Once all arguments have been added, `Self::finish` should be called to perform any\n    /// closing validations.\n    pub fn push(&mut self, arg: Cow<'a, str>) -> Result<(), ParseArgsError<'a>> {\n        if !self.only_positionals && arg == \"--\" {\n            // \"--\" marks the end of flags, everything after is a positional even if it starts\n            // with '-'.\n            self.only_positionals = true;\n            self.state = CompletionState::Flag(None);\n        } else if let Some(flag) = self.flag_awaiting_argument() {\n            // If the last token was a flag which accepts an argument, treat this token as a flag\n            // argument.\n            self.flags.insert(flag.name, arg);\n            self.state = CompletionState::FlagArgument(flag);\n        } else if !self.only_positionals && arg.starts_with('-') {\n            // If the token starts with '-' and we are not only accepting positional arguments,\n            // treat this token as a flag.\n            let flag = if let Some(longhand) = arg.strip_prefix(\"--\") {\n                self.signature\n                    .flags\n                    .iter()\n                    .find(|flag| flag.name == longhand)\n            } else {\n                let shorthand = arg.strip_prefix('-').unwrap();\n                self.signature.flags.iter().find(|flag| {\n                    flag.alias\n                        .is_some_and(|ch| shorthand == ch.encode_utf8(&mut [0; 4]))\n                })\n            };\n\n            let Some(flag) = flag else {\n                if self.validate {\n                    return Err(ParseArgsError::UnknownFlag { text: arg });\n                }\n\n                self.positionals.push(arg);\n                self.state = CompletionState::Flag(None);\n                return Ok(());\n            };\n\n            if self.validate && self.flags.contains_key(flag.name) {\n                return Err(ParseArgsError::DuplicatedFlag { flag: flag.name });\n            }\n\n            self.flags.insert(flag.name, Cow::Borrowed(\"\"));\n            self.state = CompletionState::Flag(Some(*flag));\n        } else {\n            // Otherwise this token is a positional argument.\n            self.positionals.push(arg);\n            self.state = CompletionState::Positional;\n        }\n\n        Ok(())\n    }\n\n    /// Performs any validations that must be done after the input args are finished being pushed\n    /// with `Self::push`.\n    fn finish(&self) -> Result<(), ParseArgsError<'a>> {\n        if !self.validate {\n            return Ok(());\n        };\n\n        if let Some(flag) = self.flag_awaiting_argument() {\n            return Err(ParseArgsError::FlagMissingArgument { flag: flag.name });\n        }\n        self.signature\n            .check_positional_count(self.positionals.len())?;\n\n        Ok(())\n    }\n\n    fn flag_awaiting_argument(&self) -> Option<Flag> {\n        match self.state {\n            CompletionState::Flag(flag) => flag.filter(|f| f.completions.is_some()),\n            _ => None,\n        }\n    }\n\n    /// Returns the kind of argument the last token is considered to be.\n    ///\n    /// For example if the last argument in the command line is `--foo` then the argument may be\n    /// considered to be a flag.\n    pub fn completion_state(&self) -> CompletionState {\n        self.state\n    }\n\n    /// Returns the number of positionals supplied in the input.\n    ///\n    /// This number does not account for any flags passed in the input.\n    pub fn len(&self) -> usize {\n        self.positionals.len()\n    }\n\n    /// Checks whether the arguments contain no positionals.\n    ///\n    /// Note that this function returns `true` if there are no positional arguments even if the\n    /// input contained flags.\n    pub fn is_empty(&self) -> bool {\n        self.positionals.is_empty()\n    }\n\n    /// Gets the first positional argument, if one exists.\n    pub fn first(&'a self) -> Option<&'a str> {\n        self.positionals.first().map(AsRef::as_ref)\n    }\n\n    /// Gets the positional argument at the given index, if one exists.\n    pub fn get(&'a self, index: usize) -> Option<&'a str> {\n        self.positionals.get(index).map(AsRef::as_ref)\n    }\n\n    /// Flattens all positional arguments together with the given separator between each\n    /// positional.\n    pub fn join(&self, sep: &str) -> String {\n        self.positionals.join(sep)\n    }\n\n    /// Returns an iterator over all positional arguments.\n    pub fn iter(&self) -> slice::Iter<'_, Cow<'_, str>> {\n        self.positionals.iter()\n    }\n\n    /// Gets the value associated with a flag's long name if the flag was provided.\n    ///\n    /// This function should be preferred over [Self::has_flag] when the flag accepts an argument.\n    pub fn get_flag(&'a self, name: &'static str) -> Option<&'a str> {\n        debug_assert!(\n            self.signature.flags.iter().any(|flag| flag.name == name),\n            \"flag '--{name}' does not belong to the command's signature\"\n        );\n        debug_assert!(\n            self.signature\n                .flags\n                .iter()\n                .any(|flag| flag.name == name && flag.completions.is_some()),\n            \"Args::get_flag was used for '--{name}' but should only be used for flags with arguments, use Args::has_flag instead\"\n        );\n\n        self.flags.get(name).map(AsRef::as_ref)\n    }\n\n    /// Checks if a flag was provided in the arguments.\n    ///\n    /// This function should be preferred over [Self::get_flag] for boolean flags - flags that\n    /// either are present or not.\n    pub fn has_flag(&self, name: &'static str) -> bool {\n        debug_assert!(\n            self.signature.flags.iter().any(|flag| flag.name == name),\n            \"flag '--{name}' does not belong to the command's signature\"\n        );\n        debug_assert!(\n            self.signature\n                .flags\n                .iter()\n                .any(|flag| flag.name == name && flag.completions.is_none()),\n            \"Args::has_flag was used for '--{name}' but should only be used for flags without arguments, use Args::get_flag instead\"\n        );\n\n        self.flags.contains_key(name)\n    }\n}\n\n// `arg[n]`\nimpl ops::Index<usize> for Args<'_> {\n    type Output = str;\n\n    fn index(&self, index: usize) -> &Self::Output {\n        self.positionals[index].as_ref()\n    }\n}\n\n// `for arg in args { .. }`\nimpl<'a> IntoIterator for Args<'a> {\n    type Item = Cow<'a, str>;\n    type IntoIter = vec::IntoIter<Cow<'a, str>>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        self.positionals.into_iter()\n    }\n}\n\n// `for arg in &args { .. }`\nimpl<'i, 'a> IntoIterator for &'i Args<'a> {\n    type Item = &'i Cow<'a, str>;\n    type IntoIter = slice::Iter<'i, Cow<'a, str>>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        self.positionals.iter()\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[track_caller]\n    fn assert_tokens(input: &str, expected: &[&str]) {\n        let actual: Vec<_> = Tokenizer::new(input, true)\n            .map(|arg| arg.unwrap().content)\n            .collect();\n        let actual: Vec<_> = actual.iter().map(|c| c.as_ref()).collect();\n\n        assert_eq!(actual.as_slice(), expected);\n    }\n\n    #[track_caller]\n    fn assert_incomplete_tokens(input: &str, expected: &[&str]) {\n        assert!(\n            Tokenizer::new(input, true).collect::<Result<Vec<_>, _>>().is_err(),\n            \"`assert_incomplete_tokens` only accepts input that fails validation, consider using `assert_tokens` instead\"\n        );\n\n        let actual: Vec<_> = Tokenizer::new(input, false)\n            .map(|arg| arg.unwrap().content)\n            .collect();\n        let actual: Vec<_> = actual.iter().map(|c| c.as_ref()).collect();\n\n        assert_eq!(actual.as_slice(), expected);\n    }\n\n    #[test]\n    fn tokenize_unquoted() {\n        assert_tokens(\"\", &[]);\n        assert_tokens(\"hello\", &[\"hello\"]);\n        assert_tokens(\"hello world\", &[\"hello\", \"world\"]);\n        // Any amount of whitespace is considered a separator.\n        assert_tokens(\"hello\\t \\tworld\", &[\"hello\", \"world\"]);\n    }\n\n    // This escaping behavior is specific to Unix systems.\n    #[cfg(unix)]\n    #[test]\n    fn tokenize_backslash_unix() {\n        assert_tokens(r#\"hello\\ world\"#, &[\"hello world\"]);\n        assert_tokens(r#\"one\\ two three\"#, &[\"one two\", \"three\"]);\n        assert_tokens(r#\"one two\\ three\"#, &[\"one\", \"two three\"]);\n        // Trailing backslash is ignored - this improves completions.\n        assert_tokens(r#\"hello\\\"#, &[\"hello\"]);\n        // The backslash at the start of the double quote makes the quote be treated as raw.\n        // For the backslash before the ending quote the token is already considered raw so the\n        // backslash and quote are treated literally.\n        assert_tokens(\n            r#\"echo \\\"hello        world\\\"\"#,\n            &[\"echo\", r#\"\"hello\"#, r#\"world\\\"\"#],\n        );\n    }\n\n    #[test]\n    fn tokenize_backslash() {\n        assert_tokens(r#\"\\n\"#, &[\"\\\\n\"]);\n        assert_tokens(r#\"'\\'\"#, &[\"\\\\\"]);\n    }\n\n    #[test]\n    fn tokenize_quoting() {\n        // Using a quote character twice escapes it.\n        assert_tokens(r#\"''\"#, &[\"\"]);\n        assert_tokens(r#\"\"\"\"#, &[\"\"]);\n        assert_tokens(r#\"``\"#, &[\"\"]);\n        assert_tokens(r#\"echo \"\"\"#, &[\"echo\", \"\"]);\n\n        assert_tokens(r#\"'hello'\"#, &[\"hello\"]);\n        assert_tokens(r#\"'hello world'\"#, &[\"hello world\"]);\n\n        assert_tokens(r#\"\"hello \"\" world\"\"#, &[\"hello \\\" world\"]);\n    }\n\n    #[test]\n    fn tokenize_percent() {\n        // Pair delimiters:\n        assert_tokens(r#\"echo %{hello world}\"#, &[\"echo\", \"hello world\"]);\n        assert_tokens(r#\"echo %[hello world]\"#, &[\"echo\", \"hello world\"]);\n        assert_tokens(r#\"echo %(hello world)\"#, &[\"echo\", \"hello world\"]);\n        assert_tokens(r#\"echo %<hello world>\"#, &[\"echo\", \"hello world\"]);\n        assert_tokens(r#\"echo %|hello world|\"#, &[\"echo\", \"hello world\"]);\n        assert_tokens(r#\"echo %'hello world'\"#, &[\"echo\", \"hello world\"]);\n        assert_tokens(r#\"echo %\"hello world\"\"#, &[\"echo\", \"hello world\"]);\n        // When invoking a command, double percents can be used within a string as an escape for\n        // the percent. This is done in the expansion code though, not in the parser here.\n        assert_tokens(r#\"echo \"%%hello world\"\"#, &[\"echo\", \"%%hello world\"]);\n        // Different kinds of quotes nested:\n        assert_tokens(\n            r#\"echo \"%sh{echo 'hello world'}\"\"#,\n            &[\"echo\", r#\"%sh{echo 'hello world'}\"#],\n        );\n        // Nesting of the expansion delimiter:\n        assert_tokens(r#\"echo %{hello {x} world}\"#, &[\"echo\", \"hello {x} world\"]);\n        assert_tokens(\n            r#\"echo %{hello {{😎}} world}\"#,\n            &[\"echo\", \"hello {{😎}} world\"],\n        );\n\n        // Balanced nesting:\n        assert_tokens(\n            r#\"echo %{hello {}} world}\"#,\n            &[\"echo\", \"hello {}\", \"world}\"],\n        );\n\n        // Recursive expansions:\n        assert_tokens(\n            r#\"echo %sh{echo \"%{cursor_line}\"}\"#,\n            &[\"echo\", r#\"echo \"%{cursor_line}\"\"#],\n        );\n        // Completion should provide variable names here. (Unbalanced nesting)\n        assert_incomplete_tokens(r#\"echo %sh{echo \"%{c\"#, &[\"echo\", r#\"echo \"%{c\"#]);\n        assert_incomplete_tokens(r#\"echo %{hello {{} world}\"#, &[\"echo\", \"hello {{} world}\"]);\n    }\n\n    fn parse_signature<'a>(\n        input: &'a str,\n        signature: Signature,\n    ) -> Result<Args<'a>, Box<dyn std::error::Error + 'a>> {\n        Args::parse(input, signature, true, |token| Ok(token.content))\n    }\n\n    #[test]\n    fn signature_validation_positionals() {\n        let signature = Signature {\n            positionals: (2, Some(3)),\n            ..Signature::DEFAULT\n        };\n\n        assert!(parse_signature(\"hello world\", signature).is_ok());\n        assert!(parse_signature(\"foo bar baz\", signature).is_ok());\n        assert!(parse_signature(r#\"a \"b c\" d\"#, signature).is_ok());\n\n        assert!(parse_signature(\"hello\", signature).is_err());\n        assert!(parse_signature(\"foo bar baz quiz\", signature).is_err());\n\n        let signature = Signature {\n            positionals: (1, None),\n            ..Signature::DEFAULT\n        };\n\n        assert!(parse_signature(\"a\", signature).is_ok());\n        assert!(parse_signature(\"a b\", signature).is_ok());\n        assert!(parse_signature(r#\"a \"b c\" d\"#, signature).is_ok());\n\n        assert!(parse_signature(\"\", signature).is_err());\n    }\n\n    #[test]\n    fn flags() {\n        let signature = Signature {\n            positionals: (1, Some(2)),\n            flags: &[\n                Flag {\n                    name: \"foo\",\n                    alias: Some('f'),\n                    doc: \"\",\n                    completions: None,\n                },\n                Flag {\n                    name: \"bar\",\n                    alias: Some('b'),\n                    doc: \"\",\n                    completions: Some(&[]),\n                },\n            ],\n            ..Signature::DEFAULT\n        };\n\n        let args = parse_signature(\"hello\", signature).unwrap();\n        assert_eq!(args.len(), 1);\n        assert_eq!(&args[0], \"hello\");\n        assert!(!args.has_flag(\"foo\"));\n        assert!(args.get_flag(\"bar\").is_none());\n\n        let args = parse_signature(\"--bar abcd hello world --foo\", signature).unwrap();\n        assert_eq!(args.len(), 2);\n        assert_eq!(&args[0], \"hello\");\n        assert_eq!(&args[1], \"world\");\n        assert!(args.has_flag(\"foo\"));\n        assert_eq!(args.get_flag(\"bar\"), Some(\"abcd\"));\n\n        let args = parse_signature(\"hello -f -b abcd world\", signature).unwrap();\n        assert_eq!(args.len(), 2);\n        assert_eq!(&args[0], \"hello\");\n        assert_eq!(&args[1], \"world\");\n        assert!(args.has_flag(\"foo\"));\n        assert_eq!(args.get_flag(\"bar\"), Some(\"abcd\"));\n\n        // The signature requires at least one positional.\n        assert!(parse_signature(\"--foo\", signature).is_err());\n        // And at most two.\n        assert!(parse_signature(\"abc --bar baz def efg\", signature).is_err());\n\n        let args = parse_signature(r#\"abc -b \"xyz 123\" def\"#, signature).unwrap();\n        assert_eq!(args.len(), 2);\n        assert_eq!(&args[0], \"abc\");\n        assert_eq!(&args[1], \"def\");\n        assert_eq!(args.get_flag(\"bar\"), Some(\"xyz 123\"));\n\n        // Unknown flags are validation errors.\n        assert!(parse_signature(r#\"foo --quiz\"#, signature).is_err());\n        // Duplicated flags are parsing errors.\n        assert!(parse_signature(r#\"--foo bar --foo\"#, signature).is_err());\n        assert!(parse_signature(r#\"-f bar --foo\"#, signature).is_err());\n\n        // \"--\" can be used to mark the end of flags. Everything after is considered a positional.\n        let args = parse_signature(r#\"hello --bar baz -- --foo\"#, signature).unwrap();\n        assert_eq!(args.len(), 2);\n        assert_eq!(&args[0], \"hello\");\n        assert_eq!(&args[1], \"--foo\");\n        assert_eq!(args.get_flag(\"bar\"), Some(\"baz\"));\n        assert!(!args.has_flag(\"foo\"));\n    }\n\n    #[test]\n    fn raw_after() {\n        let signature = Signature {\n            positionals: (1, Some(1)),\n            raw_after: Some(0),\n            ..Signature::DEFAULT\n        };\n\n        // All quoting and escaping is treated literally in raw mode.\n        let args = parse_signature(r#\"'\\'\"#, signature).unwrap();\n        assert_eq!(args.len(), 1);\n        assert_eq!(&args[0], \"'\\\\'\");\n        let args = parse_signature(r#\"\\''\"#, signature).unwrap();\n        assert_eq!(args.len(), 1);\n        assert_eq!(&args[0], \"\\\\''\");\n\n        // Leading space is trimmed.\n        let args = parse_signature(r#\"   %sh{foo}\"#, signature).unwrap();\n        assert_eq!(args.len(), 1);\n        assert_eq!(&args[0], \"%sh{foo}\");\n\n        let signature = Signature {\n            positionals: (1, Some(2)),\n            raw_after: Some(1),\n            ..Signature::DEFAULT\n        };\n\n        let args = parse_signature(\"foo\", signature).unwrap();\n        assert_eq!(args.len(), 1);\n        assert_eq!(&args[0], \"foo\");\n\n        // \"--bar\" is treated as a positional.\n        let args = parse_signature(\"foo --bar\", signature).unwrap();\n        assert_eq!(args.len(), 2);\n        assert_eq!(&args[0], \"foo\");\n        assert_eq!(&args[1], \"--bar\");\n\n        let args = parse_signature(\"abc def ghi\", signature).unwrap();\n        assert_eq!(args.len(), 2);\n        assert_eq!(&args[0], \"abc\");\n        assert_eq!(&args[1], \"def ghi\");\n\n        let args = parse_signature(\"rulers [20, 30]\", signature).unwrap();\n        assert_eq!(args.len(), 2);\n        assert_eq!(&args[0], \"rulers\");\n        assert_eq!(&args[1], \"[20, 30]\");\n\n        let args =\n            parse_signature(r#\"gutters [\"diff\"] [\"diff\", \"diagnostics\"]\"#, signature).unwrap();\n        assert_eq!(args.len(), 2);\n        assert_eq!(&args[0], \"gutters\");\n        assert_eq!(&args[1], r#\"[\"diff\"] [\"diff\", \"diagnostics\"]\"#);\n    }\n}\n"
  },
  {
    "path": "helix-core/src/comment.rs",
    "content": "//! This module contains the functionality toggle comments on lines over the selection\n//! using the comment character defined in the user's `languages.toml`\n\nuse smallvec::SmallVec;\n\nuse crate::{\n    syntax::config::BlockCommentToken, Change, Range, Rope, RopeSlice, Selection, Tendril,\n    Transaction,\n};\nuse helix_stdx::rope::RopeSliceExt;\nuse std::borrow::Cow;\n\npub const DEFAULT_COMMENT_TOKEN: &str = \"#\";\n\n/// Returns the longest matching comment token of the given line (if it exists).\npub fn get_comment_token<'a, S: AsRef<str>>(\n    text: RopeSlice,\n    tokens: &'a [S],\n    line_num: usize,\n) -> Option<&'a str> {\n    let line = text.line(line_num);\n    let start = line.first_non_whitespace_char()?;\n\n    tokens\n        .iter()\n        .map(AsRef::as_ref)\n        .filter(|token| line.slice(start..).starts_with(token))\n        .max_by_key(|token| token.len())\n}\n\n/// Given text, a comment token, and a set of line indices, returns the following:\n/// - Whether the given lines should be considered commented\n///     - If any of the lines are uncommented, all lines are considered as such.\n/// - The lines to change for toggling comments\n///     - This is all provided lines excluding blanks lines.\n/// - The column of the comment tokens\n///     - Column of existing tokens, if the lines are commented; column to place tokens at otherwise.\n/// - The margin to the right of the comment tokens\n///     - Defaults to `1`. If any existing comment token is not followed by a space, changes to `0`.\nfn find_line_comment(\n    token: &str,\n    text: RopeSlice,\n    lines: impl IntoIterator<Item = usize>,\n) -> (bool, Vec<usize>, usize, usize) {\n    let mut commented = true;\n    let mut to_change = Vec::new();\n    let mut min = usize::MAX; // minimum col for first_non_whitespace_char\n    let mut margin = 1;\n    let token_len = token.chars().count();\n\n    for line in lines {\n        let line_slice = text.line(line);\n        if let Some(pos) = line_slice.first_non_whitespace_char() {\n            let len = line_slice.len_chars();\n\n            min = std::cmp::min(min, pos);\n\n            // line can be shorter than pos + token len\n            let fragment = Cow::from(line_slice.slice(pos..std::cmp::min(pos + token.len(), len)));\n\n            // as soon as one of the non-blank lines doesn't have a comment, the whole block is\n            // considered uncommented.\n            if fragment != token {\n                commented = false;\n            }\n\n            // determine margin of 0 or 1 for uncommenting; if any comment token is not followed by a space,\n            // a margin of 0 is used for all lines.\n            if !matches!(line_slice.get_char(pos + token_len), Some(c) if c == ' ') {\n                margin = 0;\n            }\n\n            // blank lines don't get pushed.\n            to_change.push(line);\n        }\n    }\n\n    (commented, to_change, min, margin)\n}\n\n#[must_use]\npub fn toggle_line_comments(doc: &Rope, selection: &Selection, token: Option<&str>) -> Transaction {\n    let text = doc.slice(..);\n\n    let token = token.unwrap_or(DEFAULT_COMMENT_TOKEN);\n    let comment = Tendril::from(format!(\"{} \", token));\n\n    let mut lines: Vec<usize> = Vec::with_capacity(selection.len());\n\n    let mut min_next_line = 0;\n    for selection in selection {\n        let (start, end) = selection.line_range(text);\n        let start = start.clamp(min_next_line, text.len_lines());\n        let end = (end + 1).min(text.len_lines());\n\n        lines.extend(start..end);\n        min_next_line = end;\n    }\n\n    let (commented, to_change, min, margin) = find_line_comment(token, text, lines);\n\n    let mut changes: Vec<Change> = Vec::with_capacity(to_change.len());\n\n    for line in to_change {\n        let pos = text.line_to_char(line) + min;\n\n        if !commented {\n            // comment line\n            changes.push((pos, pos, Some(comment.clone())));\n        } else {\n            // uncomment line\n            changes.push((pos, pos + token.len() + margin, None));\n        }\n    }\n\n    Transaction::change(doc, changes.into_iter())\n}\n\n#[derive(Debug, PartialEq, Eq)]\npub enum CommentChange {\n    Commented {\n        range: Range,\n        start_pos: usize,\n        end_pos: usize,\n        start_margin: bool,\n        end_margin: bool,\n        start_token: String,\n        end_token: String,\n    },\n    Uncommented {\n        range: Range,\n        start_pos: usize,\n        end_pos: usize,\n        start_token: String,\n        end_token: String,\n    },\n    Whitespace {\n        range: Range,\n    },\n}\n\npub fn find_block_comments(\n    tokens: &[BlockCommentToken],\n    text: RopeSlice,\n    selection: &Selection,\n) -> (bool, Vec<CommentChange>) {\n    let mut commented = true;\n    let mut only_whitespace = true;\n    let mut comment_changes = Vec::with_capacity(selection.len());\n    let default_tokens = tokens.first().cloned().unwrap_or_default();\n    let mut start_token = default_tokens.start.clone();\n    let mut end_token = default_tokens.end.clone();\n\n    let mut tokens = tokens.to_vec();\n    // sort the tokens by length, so longer tokens will match first\n    tokens.sort_by(|a, b| {\n        if a.start.len() == b.start.len() {\n            b.end.len().cmp(&a.end.len())\n        } else {\n            b.start.len().cmp(&a.start.len())\n        }\n    });\n    for range in selection {\n        let selection_slice = range.slice(text);\n        if let (Some(start_pos), Some(end_pos)) = (\n            selection_slice.first_non_whitespace_char(),\n            selection_slice.last_non_whitespace_char(),\n        ) {\n            let mut line_commented = false;\n            let mut after_start = 0;\n            let mut before_end = 0;\n            let len = (end_pos + 1) - start_pos;\n\n            for BlockCommentToken { start, end } in &tokens {\n                let start_len = start.chars().count();\n                let end_len = end.chars().count();\n                after_start = start_pos + start_len;\n                before_end = end_pos.saturating_sub(end_len);\n\n                if len >= start_len + end_len {\n                    let start_fragment = selection_slice.slice(start_pos..after_start);\n                    let end_fragment = selection_slice.slice(before_end + 1..end_pos + 1);\n\n                    // block commented with these tokens\n                    if start_fragment == start.as_str() && end_fragment == end.as_str() {\n                        start_token = start.to_string();\n                        end_token = end.to_string();\n                        line_commented = true;\n                        break;\n                    }\n                }\n            }\n\n            if !line_commented {\n                comment_changes.push(CommentChange::Uncommented {\n                    range: *range,\n                    start_pos,\n                    end_pos,\n                    start_token: default_tokens.start.clone(),\n                    end_token: default_tokens.end.clone(),\n                });\n                commented = false;\n            } else {\n                comment_changes.push(CommentChange::Commented {\n                    range: *range,\n                    start_pos,\n                    end_pos,\n                    start_margin: selection_slice.get_char(after_start) == Some(' '),\n                    end_margin: after_start != before_end\n                        && (selection_slice.get_char(before_end) == Some(' ')),\n                    start_token: start_token.to_string(),\n                    end_token: end_token.to_string(),\n                });\n            }\n            only_whitespace = false;\n        } else {\n            comment_changes.push(CommentChange::Whitespace { range: *range });\n        }\n    }\n    if only_whitespace {\n        commented = false;\n    }\n    (commented, comment_changes)\n}\n\n#[must_use]\npub fn create_block_comment_transaction(\n    doc: &Rope,\n    selection: &Selection,\n    commented: bool,\n    comment_changes: Vec<CommentChange>,\n) -> (Transaction, SmallVec<[Range; 1]>) {\n    let mut changes: Vec<Change> = Vec::with_capacity(selection.len() * 2);\n    let mut ranges: SmallVec<[Range; 1]> = SmallVec::with_capacity(selection.len());\n    let mut offs = 0;\n    for change in comment_changes {\n        if commented {\n            if let CommentChange::Commented {\n                range,\n                start_pos,\n                end_pos,\n                start_token,\n                end_token,\n                start_margin,\n                end_margin,\n            } = change\n            {\n                let from = range.from();\n                changes.push((\n                    from + start_pos,\n                    from + start_pos + start_token.len() + start_margin as usize,\n                    None,\n                ));\n                changes.push((\n                    from + end_pos - end_token.len() - end_margin as usize + 1,\n                    from + end_pos + 1,\n                    None,\n                ));\n            }\n        } else {\n            // uncommented so manually map ranges through changes\n            match change {\n                CommentChange::Uncommented {\n                    range,\n                    start_pos,\n                    end_pos,\n                    start_token,\n                    end_token,\n                } => {\n                    let from = range.from();\n                    changes.push((\n                        from + start_pos,\n                        from + start_pos,\n                        Some(Tendril::from(format!(\"{} \", start_token))),\n                    ));\n                    changes.push((\n                        from + end_pos + 1,\n                        from + end_pos + 1,\n                        Some(Tendril::from(format!(\" {}\", end_token))),\n                    ));\n\n                    let offset = start_token.chars().count() + end_token.chars().count() + 2;\n                    ranges.push(\n                        Range::new(from + offs, from + offs + end_pos + 1 + offset)\n                            .with_direction(range.direction()),\n                    );\n                    offs += offset;\n                }\n                CommentChange::Commented { range, .. } | CommentChange::Whitespace { range } => {\n                    ranges.push(Range::new(range.from() + offs, range.to() + offs));\n                }\n            }\n        }\n    }\n    (Transaction::change(doc, changes.into_iter()), ranges)\n}\n\n#[must_use]\npub fn toggle_block_comments(\n    doc: &Rope,\n    selection: &Selection,\n    tokens: &[BlockCommentToken],\n) -> Transaction {\n    let text = doc.slice(..);\n    let (commented, comment_changes) = find_block_comments(tokens, text, selection);\n    let (mut transaction, ranges) =\n        create_block_comment_transaction(doc, selection, commented, comment_changes);\n    if !commented {\n        transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));\n    }\n    transaction\n}\n\npub fn split_lines_of_selection(text: RopeSlice, selection: &Selection) -> Selection {\n    let mut ranges = SmallVec::new();\n    for range in selection.ranges() {\n        let (line_start, line_end) = range.line_range(text.slice(..));\n        let mut pos = text.line_to_char(line_start);\n        for line in text.slice(pos..text.line_to_char(line_end + 1)).lines() {\n            let start = pos;\n            pos += line.len_chars();\n            ranges.push(Range::new(start, pos));\n        }\n    }\n    Selection::new(ranges, 0)\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    mod find_line_comment {\n        use super::*;\n\n        #[test]\n        fn not_commented() {\n            // four lines, two space indented, except for line 1 which is blank.\n            let doc = Rope::from(\"  1\\n\\n  2\\n  3\");\n\n            let text = doc.slice(..);\n\n            let res = find_line_comment(\"//\", text, 0..3);\n            // (commented = false, to_change = [line 0, line 2], min = col 2, margin = 0)\n            assert_eq!(res, (false, vec![0, 2], 2, 0));\n        }\n\n        #[test]\n        fn is_commented() {\n            // three lines where the second line is empty.\n            let doc = Rope::from(\"// hello\\n\\n// there\");\n\n            let res = find_line_comment(\"//\", doc.slice(..), 0..3);\n\n            // (commented = true, to_change = [line 0, line 2], min = col 0, margin = 1)\n            assert_eq!(res, (true, vec![0, 2], 0, 1));\n        }\n    }\n\n    // TODO: account for uncommenting with uneven comment indentation\n    mod toggle_line_comment {\n        use super::*;\n\n        #[test]\n        fn comment() {\n            // four lines, two space indented, except for line 1 which is blank.\n            let mut doc = Rope::from(\"  1\\n\\n  2\\n  3\");\n            // select whole document\n            let selection = Selection::single(0, doc.len_chars() - 1);\n\n            let transaction = toggle_line_comments(&doc, &selection, None);\n            transaction.apply(&mut doc);\n\n            assert_eq!(doc, \"  # 1\\n\\n  # 2\\n  # 3\");\n        }\n\n        #[test]\n        fn uncomment() {\n            let mut doc = Rope::from(\"  # 1\\n\\n  # 2\\n  # 3\");\n            let mut selection = Selection::single(0, doc.len_chars() - 1);\n\n            let transaction = toggle_line_comments(&doc, &selection, None);\n            transaction.apply(&mut doc);\n            selection = selection.map(transaction.changes());\n\n            assert_eq!(doc, \"  1\\n\\n  2\\n  3\");\n            assert!(selection.len() == 1); // to ignore the selection unused warning\n        }\n\n        #[test]\n        fn uncomment_0_margin_comments() {\n            let mut doc = Rope::from(\"  #1\\n\\n  #2\\n  #3\");\n            let mut selection = Selection::single(0, doc.len_chars() - 1);\n\n            let transaction = toggle_line_comments(&doc, &selection, None);\n            transaction.apply(&mut doc);\n            selection = selection.map(transaction.changes());\n\n            assert_eq!(doc, \"  1\\n\\n  2\\n  3\");\n            assert!(selection.len() == 1); // to ignore the selection unused warning\n        }\n\n        #[test]\n        fn uncomment_0_margin_comments_with_no_space() {\n            let mut doc = Rope::from(\"#\");\n            let mut selection = Selection::single(0, doc.len_chars() - 1);\n\n            let transaction = toggle_line_comments(&doc, &selection, None);\n            transaction.apply(&mut doc);\n            selection = selection.map(transaction.changes());\n            assert_eq!(doc, \"\");\n            assert!(selection.len() == 1); // to ignore the selection unused warning\n        }\n    }\n\n    #[test]\n    fn test_find_block_comments() {\n        // three lines 5 characters.\n        let mut doc = Rope::from(\"1\\n2\\n3\");\n        // select whole document\n        let selection = Selection::single(0, doc.len_chars());\n\n        let text = doc.slice(..);\n\n        let res = find_block_comments(&[BlockCommentToken::default()], text, &selection);\n\n        assert_eq!(\n            res,\n            (\n                false,\n                vec![CommentChange::Uncommented {\n                    range: Range::new(0, 5),\n                    start_pos: 0,\n                    end_pos: 4,\n                    start_token: \"/*\".to_string(),\n                    end_token: \"*/\".to_string(),\n                }]\n            )\n        );\n\n        // comment\n        let transaction = toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]);\n        transaction.apply(&mut doc);\n\n        assert_eq!(doc, \"/* 1\\n2\\n3 */\");\n\n        // uncomment\n        let selection = Selection::single(0, doc.len_chars());\n        let transaction = toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]);\n        transaction.apply(&mut doc);\n        assert_eq!(doc, \"1\\n2\\n3\");\n\n        // don't panic when there is just a space in comment\n        doc = Rope::from(\"/* */\");\n        let selection = Selection::single(0, doc.len_chars());\n        let transaction = toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]);\n        transaction.apply(&mut doc);\n        assert_eq!(doc, \"\");\n    }\n\n    /// Test, if `get_comment_tokens` works, even if the content of the file includes chars, whose\n    /// byte size unequal the amount of chars\n    #[test]\n    fn test_get_comment_with_char_boundaries() {\n        let rope = Rope::from(\"··\");\n        let tokens = [\"//\", \"///\"];\n\n        assert_eq!(\n            super::get_comment_token(rope.slice(..), tokens.as_slice(), 0),\n            None\n        );\n    }\n\n    /// Test for `get_comment_token`.\n    ///\n    /// Assuming the comment tokens are stored as `[\"///\", \"//\"]`, `get_comment_token` should still\n    /// return `///` instead of `//` if the user is in a doc-comment section.\n    #[test]\n    fn test_use_longest_comment() {\n        let text = Rope::from(\"    /// amogus\");\n        let tokens = [\"///\", \"//\"];\n\n        assert_eq!(\n            super::get_comment_token(text.slice(..), tokens.as_slice(), 0),\n            Some(\"///\")\n        );\n    }\n}\n"
  },
  {
    "path": "helix-core/src/completion.rs",
    "content": "use std::borrow::Cow;\n\nuse crate::{diagnostic::LanguageServerId, Transaction};\n\n#[derive(Debug, PartialEq, Clone)]\npub struct CompletionItem {\n    pub transaction: Transaction,\n    pub label: Cow<'static, str>,\n    pub kind: Cow<'static, str>,\n    /// Containing Markdown\n    pub documentation: Option<String>,\n    pub provider: CompletionProvider,\n}\n\n#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]\npub enum CompletionProvider {\n    Lsp(LanguageServerId),\n    Path,\n    Word,\n}\n\nimpl From<LanguageServerId> for CompletionProvider {\n    fn from(id: LanguageServerId) -> Self {\n        CompletionProvider::Lsp(id)\n    }\n}\n"
  },
  {
    "path": "helix-core/src/config.rs",
    "content": "use crate::syntax::{\n    config::{Configuration, LanguageConfiguration},\n    Loader, LoaderError,\n};\n\n/// Language configuration based on built-in languages.toml.\npub fn default_lang_config() -> Configuration {\n    helix_loader::config::default_lang_config()\n        .try_into()\n        .expect(\"Could not deserialize built-in languages.toml\")\n}\n\n/// Language configuration loader based on built-in languages.toml.\npub fn default_lang_loader() -> Loader {\n    Loader::new(default_lang_config()).expect(\"Could not compile loader for default config\")\n}\n\n#[derive(Debug)]\npub enum LanguageLoaderError {\n    DeserializeError(toml::de::Error),\n    ConfigError(toml::de::Error, String),\n    LoaderError(LoaderError),\n}\n\nimpl std::fmt::Display for LanguageLoaderError {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::DeserializeError(err) => write!(f, \"Failed to parse language config: {err}\"),\n            Self::ConfigError(err, context) => {\n                write!(f, \"Failed to parse language config {context}: {err}\")\n            }\n            Self::LoaderError(err) => write!(f, \"Failed to compile language config: {err}\"),\n        }\n    }\n}\n\nimpl std::error::Error for LanguageLoaderError {}\n\n/// Language configuration based on user configured languages.toml.\npub fn user_lang_config() -> Result<Configuration, toml::de::Error> {\n    helix_loader::config::user_lang_config()?.try_into()\n}\n\n/// Language configuration loader based on user configured languages.toml.\npub fn user_lang_loader() -> Result<Loader, LanguageLoaderError> {\n    let config_val =\n        helix_loader::config::user_lang_config().map_err(LanguageLoaderError::DeserializeError)?;\n    let config = config_val.clone().try_into().map_err(|e| {\n        if let Some(languages) = config_val.get(\"language\").and_then(|v| v.as_array()) {\n            for lang in languages.iter() {\n                let res: Result<LanguageConfiguration, _> = lang.clone().try_into();\n                if let Err(inner_err) = res {\n                    let context = match lang.get(\"name\") {\n                        Some(name) => format!(\"for language {}\", name),\n                        None => \"for unknown language\".to_owned(),\n                    };\n                    return LanguageLoaderError::ConfigError(inner_err, context);\n                }\n            }\n        }\n        LanguageLoaderError::ConfigError(e, String::new())\n    })?;\n    Loader::new(config).map_err(LanguageLoaderError::LoaderError)\n}\n"
  },
  {
    "path": "helix-core/src/diagnostic.rs",
    "content": "//! LSP diagnostic utility types.\nuse std::{fmt, sync::Arc};\n\npub use helix_stdx::range::Range;\nuse serde::{Deserialize, Serialize};\n\n/// Describes the severity level of a [`Diagnostic`].\n#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]\n#[serde(rename_all = \"lowercase\")]\n#[derive(Default)]\npub enum Severity {\n    #[default]\n    Hint,\n    Info,\n    Warning,\n    Error,\n}\n\n#[derive(Debug, Eq, Hash, PartialEq, Clone, Deserialize, Serialize)]\npub enum NumberOrString {\n    Number(i32),\n    String(String),\n}\n\n#[derive(Debug, Clone)]\npub enum DiagnosticTag {\n    Unnecessary,\n    Deprecated,\n}\n\n/// Corresponds to [`lsp_types::Diagnostic`](https://docs.rs/lsp-types/0.94.0/lsp_types/struct.Diagnostic.html)\n#[derive(Debug, Clone)]\npub struct Diagnostic {\n    pub range: Range,\n    // whether this diagnostic ends at the end of(or inside) a word\n    pub ends_at_word: bool,\n    pub starts_at_word: bool,\n    pub zero_width: bool,\n    pub line: usize,\n    pub message: String,\n    pub severity: Option<Severity>,\n    pub code: Option<NumberOrString>,\n    pub provider: DiagnosticProvider,\n    pub tags: Vec<DiagnosticTag>,\n    pub source: Option<String>,\n    pub data: Option<serde_json::Value>,\n}\n\n/// The source of a diagnostic.\n///\n/// This type is cheap to clone: all data is either `Copy` or wrapped in an `Arc`.\n#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]\npub enum DiagnosticProvider {\n    Lsp {\n        /// The ID of the language server which sent the diagnostic.\n        server_id: LanguageServerId,\n        /// An optional identifier under which diagnostics are managed by the client.\n        ///\n        /// `identifier` is a field from the LSP \"Pull Diagnostics\" feature meant to provide an\n        /// optional \"namespace\" for diagnostics: a language server can respond to a diagnostics\n        /// pull request with an identifier and these diagnostics should be treated as separate\n        /// from push diagnostics. Rust-analyzer uses this feature for example to provide Cargo\n        /// diagnostics with push and internal diagnostics with pull. The push diagnostics should\n        /// not clear the pull diagnostics and vice-versa.\n        identifier: Option<Arc<str>>,\n    },\n    // Future internal features can go here...\n}\n\nimpl DiagnosticProvider {\n    pub fn language_server_id(&self) -> Option<LanguageServerId> {\n        match self {\n            Self::Lsp { server_id, .. } => Some(*server_id),\n            // _ => None,\n        }\n    }\n}\n\n// while I would prefer having this in helix-lsp that necessitates a bunch of\n// conversions I would rather not add. I think its fine since this just a very\n// trivial newtype wrapper and we would need something similar once we define\n// completions in core\nslotmap::new_key_type! {\n    pub struct LanguageServerId;\n}\n\nimpl fmt::Display for LanguageServerId {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"{:?}\", self.0)\n    }\n}\n\nimpl Diagnostic {\n    #[inline]\n    pub fn severity(&self) -> Severity {\n        self.severity.unwrap_or(Severity::Warning)\n    }\n}\n"
  },
  {
    "path": "helix-core/src/diff.rs",
    "content": "use std::ops::Range;\nuse std::time::Instant;\n\nuse imara_diff::{Algorithm, Diff, Hunk, IndentHeuristic, IndentLevel, InternedInput};\nuse ropey::RopeSlice;\n\nuse crate::{ChangeSet, Rope, Tendril, Transaction};\n\nstruct ChangeSetBuilder<'a> {\n    res: ChangeSet,\n    after: RopeSlice<'a>,\n    file: &'a InternedInput<RopeSlice<'a>>,\n    current_hunk: InternedInput<char>,\n    char_diff: Diff,\n    pos: u32,\n}\n\nimpl ChangeSetBuilder<'_> {\n    fn process_hunk(&mut self, before: Range<u32>, after: Range<u32>) {\n        let len = self.file.before[self.pos as usize..before.start as usize]\n            .iter()\n            .map(|&it| self.file.interner[it].len_chars())\n            .sum();\n        self.res.retain(len);\n        self.pos = before.end;\n\n        // do not perform diffs on large hunks\n        let len_before = before.end - before.start;\n        let len_after = after.end - after.start;\n\n        // Pure insertions/removals do not require a character diff.\n        // Very large changes are ignored because their character diff is expensive to compute\n        // TODO adjust heuristic to detect large changes?\n        if len_before == 0\n            || len_after == 0\n            || len_after > 5 * len_before\n            || 5 * len_after < len_before && len_before > 10\n            || len_before + len_after > 200\n        {\n            let remove = self.file.before[before.start as usize..before.end as usize]\n                .iter()\n                .map(|&it| self.file.interner[it].len_chars())\n                .sum();\n            self.res.delete(remove);\n            let mut fragment = Tendril::new();\n            if len_after > 500 {\n                // copying a rope line by line is slower then copying the entire\n                // rope. Use to_string for very large changes instead..\n                if self.file.after.len() == after.end as usize {\n                    if after.start == 0 {\n                        fragment = self.after.to_string().into();\n                    } else {\n                        let start = self.after.line_to_char(after.start as usize);\n                        fragment = self.after.slice(start..).to_string().into();\n                    }\n                } else if after.start == 0 {\n                    let end = self.after.line_to_char(after.end as usize);\n                    fragment = self.after.slice(..end).to_string().into();\n                } else {\n                    let start = self.after.line_to_char(after.start as usize);\n                    let end = self.after.line_to_char(after.end as usize);\n                    fragment = self.after.slice(start..end).to_string().into();\n                }\n            } else {\n                for &line in &self.file.after[after.start as usize..after.end as usize] {\n                    for chunk in self.file.interner[line].chunks() {\n                        fragment.push_str(chunk)\n                    }\n                }\n            };\n            self.res.insert(fragment);\n        } else {\n            // for reasonably small hunks, generating a ChangeSet from char diff can save memory\n            // TODO use a tokenizer (word diff?) for improved performance\n            let hunk_before = self.file.before[before.start as usize..before.end as usize]\n                .iter()\n                .flat_map(|&it| self.file.interner[it].chars());\n            let hunk_after = self.file.after[after.start as usize..after.end as usize]\n                .iter()\n                .flat_map(|&it| self.file.interner[it].chars());\n            self.current_hunk.update_before(hunk_before);\n            self.current_hunk.update_after(hunk_after);\n            // the histogram heuristic does not work as well\n            // for characters because the same characters often reoccur\n            // use myer diff instead\n            self.char_diff.compute_with(\n                Algorithm::Myers,\n                &self.current_hunk.before,\n                &self.current_hunk.after,\n                self.current_hunk.interner.num_tokens(),\n            );\n            let mut pos = 0;\n            for Hunk { before, after } in self.char_diff.hunks() {\n                self.res.retain((before.start - pos) as usize);\n                self.res.delete(before.len());\n                pos = before.end;\n\n                let res = self.current_hunk.after[after.start as usize..after.end as usize]\n                    .iter()\n                    .map(|&token| self.current_hunk.interner[token])\n                    .collect();\n\n                self.res.insert(res);\n            }\n            self.res\n                .retain(self.current_hunk.before.len() - pos as usize);\n            // reuse allocations\n            self.current_hunk.clear();\n        }\n    }\n\n    fn finish(mut self) -> ChangeSet {\n        let len = self.file.before[self.pos as usize..]\n            .iter()\n            .map(|&it| self.file.interner[it].len_chars())\n            .sum();\n\n        self.res.retain(len);\n        self.res\n    }\n}\n\nstruct RopeLines<'a>(RopeSlice<'a>);\n\nimpl<'a> imara_diff::TokenSource for RopeLines<'a> {\n    type Token = RopeSlice<'a>;\n    type Tokenizer = ropey::iter::Lines<'a>;\n\n    fn tokenize(&self) -> Self::Tokenizer {\n        self.0.lines()\n    }\n\n    fn estimate_tokens(&self) -> u32 {\n        // we can provide a perfect estimate which is very nice for performance\n        self.0.len_lines() as u32\n    }\n}\n\n/// Compares `old` and `new` to generate a [`Transaction`] describing\n/// the steps required to get from `old` to `new`.\npub fn compare_ropes(before: &Rope, after: &Rope) -> Transaction {\n    let start = Instant::now();\n    let res = ChangeSet::with_capacity(32);\n    let after = after.slice(..);\n    let file = InternedInput::new(RopeLines(before.slice(..)), RopeLines(after));\n    let mut builder = ChangeSetBuilder {\n        res,\n        file: &file,\n        after,\n        pos: 0,\n        current_hunk: InternedInput::default(),\n        char_diff: Diff::default(),\n    };\n    let mut diff = Diff::compute(Algorithm::Histogram, &file);\n    diff.postprocess_with_heuristic(\n        &file,\n        IndentHeuristic::new(|token| IndentLevel::for_ascii_line(file.interner[token].bytes(), 4)),\n    );\n    for hunk in diff.hunks() {\n        builder.process_hunk(hunk.before, hunk.after)\n    }\n    let res = builder.finish().into();\n\n    log::debug!(\n        \"rope diff took {}s\",\n        Instant::now().duration_since(start).as_secs_f64()\n    );\n    res\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    fn test_identity(a: &str, b: &str) {\n        let mut old = Rope::from(a);\n        let new = Rope::from(b);\n        compare_ropes(&old, &new).apply(&mut old);\n        assert_eq!(old, new);\n    }\n\n    quickcheck::quickcheck! {\n        fn test_compare_ropes(a: String, b: String) -> bool {\n            let mut old = Rope::from(a);\n            let new = Rope::from(b);\n            compare_ropes(&old, &new).apply(&mut old);\n            old == new\n        }\n    }\n\n    #[test]\n    fn equal_files() {\n        test_identity(\"foo\", \"foo\");\n    }\n\n    #[test]\n    fn trailing_newline() {\n        test_identity(\"foo\\n\", \"foo\");\n        test_identity(\"foo\", \"foo\\n\");\n    }\n\n    #[test]\n    fn new_file() {\n        test_identity(\"\", \"foo\");\n    }\n\n    #[test]\n    fn deleted_file() {\n        test_identity(\"foo\", \"\");\n    }\n}\n"
  },
  {
    "path": "helix-core/src/doc_formatter/test.rs",
    "content": "use crate::doc_formatter::{DocumentFormatter, TextFormat};\nuse crate::text_annotations::{InlineAnnotation, Overlay, TextAnnotations};\n\nimpl TextFormat {\n    fn new_test(softwrap: bool) -> Self {\n        TextFormat {\n            soft_wrap: softwrap,\n            tab_width: 2,\n            max_wrap: 3,\n            max_indent_retain: 4,\n            wrap_indicator: \".\".into(),\n            wrap_indicator_highlight: None,\n            // use a prime number to allow lining up too often with repeat\n            viewport_width: 17,\n            soft_wrap_at_text_width: false,\n        }\n    }\n}\n\nimpl<'t> DocumentFormatter<'t> {\n    fn collect_to_str(&mut self) -> String {\n        use std::fmt::Write;\n        let mut res = String::new();\n        let viewport_width = self.text_fmt.viewport_width;\n        let soft_wrap_at_text_width = self.text_fmt.soft_wrap_at_text_width;\n        let mut line = 0;\n\n        for grapheme in self {\n            if grapheme.visual_pos.row != line {\n                line += 1;\n                assert_eq!(grapheme.visual_pos.row, line);\n                write!(res, \"\\n{}\", \".\".repeat(grapheme.visual_pos.col)).unwrap();\n            }\n            if !soft_wrap_at_text_width {\n                assert!(\n                    grapheme.visual_pos.col <= viewport_width as usize,\n                    \"softwrapped failed {}<={viewport_width}\",\n                    grapheme.visual_pos.col\n                );\n            }\n            write!(res, \"{}\", grapheme.raw).unwrap();\n        }\n\n        res\n    }\n}\n\nfn softwrap_text(text: &str) -> String {\n    DocumentFormatter::new_at_prev_checkpoint(\n        text.into(),\n        &TextFormat::new_test(true),\n        &TextAnnotations::default(),\n        0,\n    )\n    .collect_to_str()\n}\n\n#[test]\nfn basic_softwrap() {\n    assert_eq!(\n        softwrap_text(&\"foo \".repeat(10)),\n        \"foo foo foo foo \\n.foo foo foo foo \\n.foo foo  \"\n    );\n    assert_eq!(\n        softwrap_text(&\"fooo \".repeat(10)),\n        \"fooo fooo fooo \\n.fooo fooo fooo \\n.fooo fooo fooo \\n.fooo  \"\n    );\n\n    // check that we don't wrap unnecessarily\n    assert_eq!(softwrap_text(\"\\t\\txxxx1xxxx2xx\\n\"), \"    xxxx1xxxx2xx \\n \");\n}\n\n#[test]\nfn softwrap_indentation() {\n    assert_eq!(\n        softwrap_text(\"\\t\\tfoo1 foo2 foo3 foo4 foo5 foo6\\n\"),\n        \"    foo1 foo2 \\n.....foo3 foo4 \\n.....foo5 foo6 \\n \"\n    );\n    assert_eq!(\n        softwrap_text(\"\\t\\t\\tfoo1 foo2 foo3 foo4 foo5 foo6\\n\"),\n        \"      foo1 foo2 \\n.foo3 foo4 foo5 \\n.foo6 \\n \"\n    );\n}\n\n#[test]\nfn long_word_softwrap() {\n    assert_eq!(\n        softwrap_text(\"\\t\\txxxx1xxxx2xxxx3xxxx4xxxx5xxxx6xxxx7xxxx8xxxx9xxx\\n\"),\n        \"    xxxx1xxxx2xxx\\n.....x3xxxx4xxxx5\\n.....xxxx6xxxx7xx\\n.....xx8xxxx9xxx \\n \"\n    );\n    assert_eq!(\n        softwrap_text(\"xxxxxxxx1xxxx2xxx\\n\"),\n        \"xxxxxxxx1xxxx2xxx\\n. \\n \"\n    );\n    assert_eq!(\n        softwrap_text(\"\\t\\txxxx1xxxx 2xxxx3xxxx4xxxx5xxxx6xxxx7xxxx8xxxx9xxx\\n\"),\n        \"    xxxx1xxxx \\n.....2xxxx3xxxx4x\\n.....xxx5xxxx6xxx\\n.....x7xxxx8xxxx9\\n.....xxx \\n \"\n    );\n    assert_eq!(\n        softwrap_text(\"\\t\\txxxx1xxx 2xxxx3xxxx4xxxx5xxxx6xxxx7xxxx8xxxx9xxx\\n\"),\n        \"    xxxx1xxx 2xxx\\n.....x3xxxx4xxxx5\\n.....xxxx6xxxx7xx\\n.....xx8xxxx9xxx \\n \"\n    );\n}\n\n#[test]\nfn softwrap_multichar_grapheme() {\n    assert_eq!(\n        softwrap_text(\"xxxx xxxx xxx a\\u{0301}bc\\n\"),\n        \"xxxx xxxx xxx \\n.ábc \\n \"\n    )\n}\n\nfn softwrap_text_at_text_width(text: &str) -> String {\n    let mut text_fmt = TextFormat::new_test(true);\n    text_fmt.soft_wrap_at_text_width = true;\n    let annotations = TextAnnotations::default();\n    let mut formatter =\n        DocumentFormatter::new_at_prev_checkpoint(text.into(), &text_fmt, &annotations, 0);\n    formatter.collect_to_str()\n}\n#[test]\nfn long_word_softwrap_text_width() {\n    assert_eq!(\n        softwrap_text_at_text_width(\"xxxxxxxx1xxxx2xxx\\nxxxxxxxx1xxxx2xxx\"),\n        \"xxxxxxxx1xxxx2xxx \\nxxxxxxxx1xxxx2xxx \"\n    );\n}\n\nfn overlay_text(text: &str, char_pos: usize, softwrap: bool, overlays: &[Overlay]) -> String {\n    DocumentFormatter::new_at_prev_checkpoint(\n        text.into(),\n        &TextFormat::new_test(softwrap),\n        TextAnnotations::default().add_overlay(overlays, None),\n        char_pos,\n    )\n    .collect_to_str()\n}\n\n#[test]\nfn overlay() {\n    assert_eq!(\n        overlay_text(\n            \"foobar\",\n            0,\n            false,\n            &[Overlay::new(0, \"X\"), Overlay::new(2, \"\\t\")],\n        ),\n        \"Xo  bar \"\n    );\n    assert_eq!(\n        overlay_text(\n            &\"foo \".repeat(10),\n            0,\n            true,\n            &[\n                Overlay::new(2, \"\\t\"),\n                Overlay::new(5, \"\\t\"),\n                Overlay::new(16, \"X\"),\n            ]\n        ),\n        \"fo   f  o foo \\n.foo Xoo foo foo \\n.foo foo foo  \"\n    );\n}\n\nfn annotate_text(text: &str, softwrap: bool, annotations: &[InlineAnnotation]) -> String {\n    DocumentFormatter::new_at_prev_checkpoint(\n        text.into(),\n        &TextFormat::new_test(softwrap),\n        TextAnnotations::default().add_inline_annotations(annotations, None),\n        0,\n    )\n    .collect_to_str()\n}\n\n#[test]\nfn annotation() {\n    assert_eq!(\n        annotate_text(\"bar\", false, &[InlineAnnotation::new(0, \"foo\")]),\n        \"foobar \"\n    );\n    assert_eq!(\n        annotate_text(\n            &\"foo \".repeat(10),\n            true,\n            &[InlineAnnotation::new(0, \"foo \")]\n        ),\n        \"foo foo foo foo \\n.foo foo foo foo \\n.foo foo foo  \"\n    );\n}\n\n#[test]\nfn annotation_and_overlay() {\n    let annotations = [InlineAnnotation {\n        char_idx: 0,\n        text: \"fooo\".into(),\n    }];\n    let overlay = [Overlay {\n        char_idx: 0,\n        grapheme: \"\\t\".into(),\n    }];\n    assert_eq!(\n        DocumentFormatter::new_at_prev_checkpoint(\n            \"bbar\".into(),\n            &TextFormat::new_test(false),\n            TextAnnotations::default()\n                .add_inline_annotations(annotations.as_slice(), None)\n                .add_overlay(overlay.as_slice(), None),\n            0,\n        )\n        .collect_to_str(),\n        \"fooo  bar \"\n    );\n}\n"
  },
  {
    "path": "helix-core/src/doc_formatter.rs",
    "content": "//! The `DocumentFormatter` forms the bridge between the raw document text\n//! and onscreen positioning. It yields the text graphemes as an iterator\n//! and traverses (part) of the document text. During that traversal it\n//! handles grapheme detection, softwrapping and annotations.\n//! It yields `FormattedGrapheme`s and their corresponding visual coordinates.\n//!\n//! As both virtual text and softwrapping can insert additional lines into the document\n//! it is generally not possible to find the start of the previous visual line.\n//! Instead the `DocumentFormatter` starts at the last \"checkpoint\" (usually a linebreak)\n//! called a \"block\" and the caller must advance it as needed.\n\nuse std::borrow::Cow;\nuse std::cmp::Ordering;\nuse std::fmt::Debug;\nuse std::mem::replace;\n\n#[cfg(test)]\nmod test;\n\nuse unicode_segmentation::{Graphemes, UnicodeSegmentation};\n\nuse helix_stdx::rope::{RopeGraphemes, RopeSliceExt};\n\nuse crate::graphemes::{Grapheme, GraphemeStr};\nuse crate::syntax::Highlight;\nuse crate::text_annotations::TextAnnotations;\nuse crate::{Position, RopeSlice};\n\n#[derive(Debug, Clone, Copy)]\npub enum GraphemeSource {\n    Document {\n        codepoints: u32,\n    },\n    /// Inline virtual text can not be highlighted with a `Highlight` iterator\n    /// because it's not part of the document. Instead the `Highlight`\n    /// is emitted right by the document formatter\n    VirtualText {\n        highlight: Option<Highlight>,\n    },\n}\n\nimpl GraphemeSource {\n    /// Returns whether this grapheme is virtual inline text\n    pub fn is_virtual(self) -> bool {\n        matches!(self, GraphemeSource::VirtualText { .. })\n    }\n\n    pub fn is_eof(self) -> bool {\n        // all doc chars except the EOF char have non-zero codepoints\n        matches!(self, GraphemeSource::Document { codepoints: 0 })\n    }\n\n    pub fn doc_chars(self) -> usize {\n        match self {\n            GraphemeSource::Document { codepoints } => codepoints as usize,\n            GraphemeSource::VirtualText { .. } => 0,\n        }\n    }\n}\n\n#[derive(Debug, Clone)]\npub struct FormattedGrapheme<'a> {\n    pub raw: Grapheme<'a>,\n    pub source: GraphemeSource,\n    pub visual_pos: Position,\n    /// Document line at the start of the grapheme\n    pub line_idx: usize,\n    /// Document char position at the start of the grapheme\n    pub char_idx: usize,\n}\n\nimpl FormattedGrapheme<'_> {\n    pub fn is_virtual(&self) -> bool {\n        self.source.is_virtual()\n    }\n\n    pub fn doc_chars(&self) -> usize {\n        self.source.doc_chars()\n    }\n\n    pub fn is_whitespace(&self) -> bool {\n        self.raw.is_whitespace()\n    }\n\n    pub fn width(&self) -> usize {\n        self.raw.width()\n    }\n\n    pub fn is_word_boundary(&self) -> bool {\n        self.raw.is_word_boundary()\n    }\n}\n\n#[derive(Debug, Clone)]\nstruct GraphemeWithSource<'a> {\n    grapheme: Grapheme<'a>,\n    source: GraphemeSource,\n}\n\nimpl<'a> GraphemeWithSource<'a> {\n    fn new(\n        g: GraphemeStr<'a>,\n        visual_x: usize,\n        tab_width: u16,\n        source: GraphemeSource,\n    ) -> GraphemeWithSource<'a> {\n        GraphemeWithSource {\n            grapheme: Grapheme::new(g, visual_x, tab_width),\n            source,\n        }\n    }\n    fn placeholder() -> Self {\n        GraphemeWithSource {\n            grapheme: Grapheme::Other { g: \" \".into() },\n            source: GraphemeSource::Document { codepoints: 0 },\n        }\n    }\n\n    fn doc_chars(&self) -> usize {\n        self.source.doc_chars()\n    }\n\n    fn is_whitespace(&self) -> bool {\n        self.grapheme.is_whitespace()\n    }\n\n    fn is_newline(&self) -> bool {\n        matches!(self.grapheme, Grapheme::Newline)\n    }\n\n    fn is_eof(&self) -> bool {\n        self.source.is_eof()\n    }\n\n    fn width(&self) -> usize {\n        self.grapheme.width()\n    }\n\n    fn is_word_boundary(&self) -> bool {\n        self.grapheme.is_word_boundary()\n    }\n}\n\n#[derive(Debug, Clone)]\npub struct TextFormat {\n    pub soft_wrap: bool,\n    pub tab_width: u16,\n    pub max_wrap: u16,\n    pub max_indent_retain: u16,\n    pub wrap_indicator: Box<str>,\n    pub wrap_indicator_highlight: Option<Highlight>,\n    pub viewport_width: u16,\n    pub soft_wrap_at_text_width: bool,\n}\n\n// test implementation is basically only used for testing or when softwrap is always disabled\nimpl Default for TextFormat {\n    fn default() -> Self {\n        TextFormat {\n            soft_wrap: false,\n            tab_width: 4,\n            max_wrap: 3,\n            max_indent_retain: 4,\n            wrap_indicator: Box::from(\" \"),\n            viewport_width: 17,\n            wrap_indicator_highlight: None,\n            soft_wrap_at_text_width: false,\n        }\n    }\n}\n\n#[derive(Debug)]\npub struct DocumentFormatter<'t> {\n    text_fmt: &'t TextFormat,\n    annotations: &'t TextAnnotations<'t>,\n\n    /// The visual position at the end of the last yielded word boundary\n    visual_pos: Position,\n    graphemes: RopeGraphemes<'t>,\n    /// The character pos of the `graphemes` iter used for inserting annotations\n    char_pos: usize,\n    /// The line pos of the `graphemes` iter used for inserting annotations\n    line_pos: usize,\n    exhausted: bool,\n\n    inline_annotation_graphemes: Option<(Graphemes<'t>, Option<Highlight>)>,\n\n    // softwrap specific\n    /// The indentation of the current line\n    /// Is set to `None` if the indentation level is not yet known\n    /// because no non-whitespace graphemes have been encountered yet\n    indent_level: Option<usize>,\n    /// In case a long word needs to be split a single grapheme might need to be wrapped\n    /// while the rest of the word stays on the same line\n    peeked_grapheme: Option<GraphemeWithSource<'t>>,\n    /// A first-in first-out (fifo) buffer for the Graphemes of any given word\n    word_buf: Vec<GraphemeWithSource<'t>>,\n    /// The index of the next grapheme that will be yielded from the `word_buf`\n    word_i: usize,\n}\n\nimpl<'t> DocumentFormatter<'t> {\n    /// Creates a new formatter at the last block before `char_idx`.\n    /// A block is a chunk which always ends with a linebreak.\n    /// This is usually just a normal line break.\n    /// However very long lines are always wrapped at constant intervals that can be cheaply calculated\n    /// to avoid pathological behaviour.\n    pub fn new_at_prev_checkpoint(\n        text: RopeSlice<'t>,\n        text_fmt: &'t TextFormat,\n        annotations: &'t TextAnnotations,\n        char_idx: usize,\n    ) -> Self {\n        // TODO divide long lines into blocks to avoid bad performance for long lines\n        let block_line_idx = text.char_to_line(char_idx.min(text.len_chars()));\n        let block_char_idx = text.line_to_char(block_line_idx);\n        annotations.reset_pos(block_char_idx);\n\n        DocumentFormatter {\n            text_fmt,\n            annotations,\n            visual_pos: Position { row: 0, col: 0 },\n            graphemes: text.slice(block_char_idx..).graphemes(),\n            char_pos: block_char_idx,\n            exhausted: false,\n            indent_level: None,\n            peeked_grapheme: None,\n            word_buf: Vec::with_capacity(64),\n            word_i: 0,\n            line_pos: block_line_idx,\n            inline_annotation_graphemes: None,\n        }\n    }\n\n    fn next_inline_annotation_grapheme(\n        &mut self,\n        char_pos: usize,\n    ) -> Option<(&'t str, Option<Highlight>)> {\n        loop {\n            if let Some(&mut (ref mut annotation, highlight)) =\n                self.inline_annotation_graphemes.as_mut()\n            {\n                if let Some(grapheme) = annotation.next() {\n                    return Some((grapheme, highlight));\n                }\n            }\n\n            if let Some((annotation, highlight)) =\n                self.annotations.next_inline_annotation_at(char_pos)\n            {\n                self.inline_annotation_graphemes = Some((\n                    UnicodeSegmentation::graphemes(&*annotation.text, true),\n                    highlight,\n                ))\n            } else {\n                return None;\n            }\n        }\n    }\n\n    fn advance_grapheme(&mut self, col: usize, char_pos: usize) -> Option<GraphemeWithSource<'t>> {\n        let (grapheme, source) =\n            if let Some((grapheme, highlight)) = self.next_inline_annotation_grapheme(char_pos) {\n                (grapheme.into(), GraphemeSource::VirtualText { highlight })\n            } else if let Some(grapheme) = self.graphemes.next() {\n                let codepoints = grapheme.len_chars() as u32;\n\n                let overlay = self.annotations.overlay_at(char_pos);\n                let grapheme = match overlay {\n                    Some((overlay, _)) => overlay.grapheme.as_str().into(),\n                    None => Cow::from(grapheme).into(),\n                };\n\n                (grapheme, GraphemeSource::Document { codepoints })\n            } else {\n                if self.exhausted {\n                    return None;\n                }\n                self.exhausted = true;\n                // EOF grapheme is required for rendering\n                // and correct position computations\n                return Some(GraphemeWithSource {\n                    grapheme: Grapheme::Other { g: \" \".into() },\n                    source: GraphemeSource::Document { codepoints: 0 },\n                });\n            };\n\n        let grapheme = GraphemeWithSource::new(grapheme, col, self.text_fmt.tab_width, source);\n\n        Some(grapheme)\n    }\n\n    /// Move a word to the next visual line\n    fn wrap_word(&mut self) -> usize {\n        // softwrap this word to the next line\n        let indent_carry_over = if let Some(indent) = self.indent_level {\n            if indent as u16 <= self.text_fmt.max_indent_retain {\n                indent as u16\n            } else {\n                0\n            }\n        } else {\n            // ensure the indent stays 0\n            self.indent_level = Some(0);\n            0\n        };\n\n        let virtual_lines =\n            self.annotations\n                .virtual_lines_at(self.char_pos, self.visual_pos, self.line_pos);\n        self.visual_pos.col = indent_carry_over as usize;\n        self.visual_pos.row += 1 + virtual_lines;\n        let mut i = 0;\n        let mut word_width = 0;\n        let wrap_indicator = UnicodeSegmentation::graphemes(&*self.text_fmt.wrap_indicator, true)\n            .map(|g| {\n                i += 1;\n                let grapheme = GraphemeWithSource::new(\n                    g.into(),\n                    self.visual_pos.col + word_width,\n                    self.text_fmt.tab_width,\n                    GraphemeSource::VirtualText {\n                        highlight: self.text_fmt.wrap_indicator_highlight,\n                    },\n                );\n                word_width += grapheme.width();\n                grapheme\n            });\n        self.word_buf.splice(0..0, wrap_indicator);\n\n        for grapheme in &mut self.word_buf[i..] {\n            let visual_x = self.visual_pos.col + word_width;\n            grapheme\n                .grapheme\n                .change_position(visual_x, self.text_fmt.tab_width);\n            word_width += grapheme.width();\n        }\n        if let Some(grapheme) = &mut self.peeked_grapheme {\n            let visual_x = self.visual_pos.col + word_width;\n            grapheme\n                .grapheme\n                .change_position(visual_x, self.text_fmt.tab_width);\n        }\n        word_width\n    }\n\n    fn peek_grapheme(&mut self, col: usize, char_pos: usize) -> Option<&GraphemeWithSource<'t>> {\n        if self.peeked_grapheme.is_none() {\n            self.peeked_grapheme = self.advance_grapheme(col, char_pos);\n        }\n        self.peeked_grapheme.as_ref()\n    }\n\n    fn next_grapheme(&mut self, col: usize, char_pos: usize) -> Option<GraphemeWithSource<'t>> {\n        self.peek_grapheme(col, char_pos);\n        self.peeked_grapheme.take()\n    }\n\n    fn advance_to_next_word(&mut self) {\n        self.word_buf.clear();\n        let mut word_width = 0;\n        let mut word_chars = 0;\n\n        if self.exhausted {\n            return;\n        }\n\n        loop {\n            let mut col = self.visual_pos.col + word_width;\n            let char_pos = self.char_pos + word_chars;\n            match col.cmp(&(self.text_fmt.viewport_width as usize)) {\n                // The EOF char and newline chars are always selectable in helix. That means\n                // that wrapping happens \"too-early\" if a word fits a line perfectly. This\n                // is intentional so that all selectable graphemes are always visible (and\n                // therefore the cursor never disappears). However if the user manually set a\n                // lower softwrap width then this is undesirable. Just increasing the viewport-\n                // width by one doesn't work because if a line is wrapped multiple times then\n                // some words may extend past the specified width.\n                //\n                // So we special case a word that ends exactly at line bounds and is followed\n                // by a newline/eof character here.\n                Ordering::Equal\n                    if self.text_fmt.soft_wrap_at_text_width\n                        && self\n                            .peek_grapheme(col, char_pos)\n                            .is_some_and(|grapheme| grapheme.is_newline() || grapheme.is_eof()) => {\n                }\n                Ordering::Equal if word_width > self.text_fmt.max_wrap as usize => return,\n                Ordering::Greater if word_width > self.text_fmt.max_wrap as usize => {\n                    self.peeked_grapheme = self.word_buf.pop();\n                    return;\n                }\n                Ordering::Equal | Ordering::Greater => {\n                    word_width = self.wrap_word();\n                    col = self.visual_pos.col + word_width;\n                }\n                Ordering::Less => (),\n            }\n\n            let Some(grapheme) = self.next_grapheme(col, char_pos) else {\n                return;\n            };\n            word_chars += grapheme.doc_chars();\n\n            // Track indentation\n            if !grapheme.is_whitespace() && self.indent_level.is_none() {\n                self.indent_level = Some(self.visual_pos.col);\n            } else if grapheme.grapheme == Grapheme::Newline {\n                self.indent_level = None;\n            }\n\n            let is_word_boundary = grapheme.is_word_boundary();\n            word_width += grapheme.width();\n            self.word_buf.push(grapheme);\n\n            if is_word_boundary {\n                return;\n            }\n        }\n    }\n\n    /// returns the char index at the end of the last yielded grapheme\n    pub fn next_char_pos(&self) -> usize {\n        self.char_pos\n    }\n    /// returns the visual position at the end of the last yielded grapheme\n    pub fn next_visual_pos(&self) -> Position {\n        self.visual_pos\n    }\n}\n\nimpl<'t> Iterator for DocumentFormatter<'t> {\n    type Item = FormattedGrapheme<'t>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let grapheme = if self.text_fmt.soft_wrap {\n            if self.word_i >= self.word_buf.len() {\n                self.advance_to_next_word();\n                self.word_i = 0;\n            }\n            let grapheme = replace(\n                self.word_buf.get_mut(self.word_i)?,\n                GraphemeWithSource::placeholder(),\n            );\n            self.word_i += 1;\n            grapheme\n        } else {\n            self.advance_grapheme(self.visual_pos.col, self.char_pos)?\n        };\n\n        let grapheme = FormattedGrapheme {\n            raw: grapheme.grapheme,\n            source: grapheme.source,\n            visual_pos: self.visual_pos,\n            line_idx: self.line_pos,\n            char_idx: self.char_pos,\n        };\n\n        self.char_pos += grapheme.doc_chars();\n        if !grapheme.is_virtual() {\n            self.annotations.process_virtual_text_anchors(&grapheme);\n        }\n        if grapheme.raw == Grapheme::Newline {\n            // move to end of newline char\n            self.visual_pos.col += 1;\n            let virtual_lines =\n                self.annotations\n                    .virtual_lines_at(self.char_pos, self.visual_pos, self.line_pos);\n            self.visual_pos.row += 1 + virtual_lines;\n            self.visual_pos.col = 0;\n            if !grapheme.is_virtual() {\n                self.line_pos += 1;\n            }\n        } else {\n            self.visual_pos.col += grapheme.width();\n        }\n        Some(grapheme)\n    }\n}\n"
  },
  {
    "path": "helix-core/src/editor_config.rs",
    "content": "//! Support for [EditorConfig](https://EditorConfig.org) configuration loading.\n//!\n//! EditorConfig is an editor-agnostic format for specifying configuration in an INI-like, human\n//! friendly syntax in `.editorconfig` files (which are intended to be checked into VCS). This\n//! module provides functions to search for all `.editorconfig` files that apply to a given path\n//! and returns an `EditorConfig` type containing any specified configuration options.\n//!\n//! At time of writing, this module follows the [spec](https://spec.editorconfig.org/) at\n//! version 0.17.2.\n\nuse std::{\n    collections::HashMap,\n    fs,\n    num::{NonZeroU16, NonZeroU8},\n    path::Path,\n    str::FromStr,\n};\n\nuse encoding_rs::Encoding;\nuse globset::{GlobBuilder, GlobMatcher};\n\nuse crate::{\n    indent::{IndentStyle, MAX_INDENT},\n    LineEnding,\n};\n\n/// Configuration declared for a path in `.editorconfig` files.\n#[derive(Debug, Default, PartialEq, Eq)]\npub struct EditorConfig {\n    pub indent_style: Option<IndentStyle>,\n    pub tab_width: Option<NonZeroU8>,\n    pub line_ending: Option<LineEnding>,\n    pub encoding: Option<&'static Encoding>,\n    // pub spelling_language: Option<SpellingLanguage>,\n    pub trim_trailing_whitespace: Option<bool>,\n    pub insert_final_newline: Option<bool>,\n    pub max_line_length: Option<NonZeroU16>,\n}\n\nimpl EditorConfig {\n    /// Finds any configuration in `.editorconfig` files which applies to the given path.\n    ///\n    /// If no configuration applies then `EditorConfig::default()` is returned.\n    pub fn find(path: &Path) -> Self {\n        let mut configs = Vec::new();\n        // <https://spec.editorconfig.org/#file-processing>\n        for ancestor in path.ancestors() {\n            let editor_config_file = ancestor.join(\".editorconfig\");\n            let Ok(contents) = fs::read_to_string(&editor_config_file) else {\n                continue;\n            };\n            let ini = match contents.parse::<Ini>() {\n                Ok(ini) => ini,\n                Err(err) => {\n                    log::warn!(\"Ignoring EditorConfig file at '{editor_config_file:?}' because a glob failed to compile: {err}\");\n                    continue;\n                }\n            };\n            let is_root = ini.pairs.get(\"root\").map(AsRef::as_ref) == Some(\"true\");\n            configs.push((ini, ancestor));\n            // > The search shall stop if an EditorConfig file is found with the `root` key set to\n            // > `true` in the preamble or when reaching the root filesystem directory.\n            if is_root {\n                break;\n            }\n        }\n\n        let mut pairs = Pairs::new();\n        // Reverse the configuration stack so that the `.editorconfig` files closest to `path`\n        // are applied last and overwrite settings in files closer to the search ceiling.\n        //\n        // > If multiple EditorConfig files have matching sections, the pairs from the closer\n        // > EditorConfig file are read last, so pairs in closer files take precedence.\n        for (config, dir) in configs.into_iter().rev() {\n            let relative_path = path.strip_prefix(dir).expect(\"dir is an ancestor of path\");\n\n            for section in config.sections {\n                if section.glob.is_match(relative_path) {\n                    log::info!(\n                        \"applying EditorConfig from section '{}' in file {:?}\",\n                        section.glob.glob(),\n                        dir.join(\".editorconfig\")\n                    );\n                    pairs.extend(section.pairs);\n                }\n            }\n        }\n\n        Self::from_pairs(pairs)\n    }\n\n    fn from_pairs(pairs: Pairs) -> Self {\n        enum IndentSize {\n            Tab,\n            Spaces(NonZeroU8),\n        }\n\n        // <https://spec.editorconfig.org/#supported-pairs>\n        let indent_size = pairs.get(\"indent_size\").and_then(|value| {\n            if value.as_ref() == \"tab\" {\n                Some(IndentSize::Tab)\n            } else if let Ok(spaces) = value.parse::<NonZeroU8>() {\n                Some(IndentSize::Spaces(spaces))\n            } else {\n                None\n            }\n        });\n        let tab_width = pairs\n            .get(\"tab_width\")\n            .and_then(|value| value.parse::<NonZeroU8>().ok())\n            .or(match indent_size {\n                Some(IndentSize::Spaces(spaces)) => Some(spaces),\n                _ => None,\n            });\n        let indent_style = pairs\n            .get(\"indent_style\")\n            .and_then(|value| match value.as_ref() {\n                \"tab\" => Some(IndentStyle::Tabs),\n                \"space\" => {\n                    let spaces = match indent_size {\n                        Some(IndentSize::Spaces(spaces)) => spaces.get(),\n                        Some(IndentSize::Tab) => tab_width.map(|n| n.get()).unwrap_or(4),\n                        None => 4,\n                    };\n                    Some(IndentStyle::Spaces(spaces.clamp(1, MAX_INDENT)))\n                }\n                _ => None,\n            });\n        let line_ending = pairs\n            .get(\"end_of_line\")\n            .and_then(|value| match value.as_ref() {\n                \"lf\" => Some(LineEnding::LF),\n                \"crlf\" => Some(LineEnding::Crlf),\n                #[cfg(feature = \"unicode-lines\")]\n                \"cr\" => Some(LineEnding::CR),\n                _ => None,\n            });\n        let encoding = pairs.get(\"charset\").and_then(|value| match value.as_ref() {\n            \"latin1\" => Some(encoding_rs::WINDOWS_1252),\n            \"utf-8\" => Some(encoding_rs::UTF_8),\n            // `utf-8-bom` is intentionally ignored.\n            // > `utf-8-bom` is discouraged.\n            \"utf-16le\" => Some(encoding_rs::UTF_16LE),\n            \"utf-16be\" => Some(encoding_rs::UTF_16BE),\n            _ => None,\n        });\n        let trim_trailing_whitespace =\n            pairs\n                .get(\"trim_trailing_whitespace\")\n                .and_then(|value| match value.as_ref() {\n                    \"true\" => Some(true),\n                    \"false\" => Some(false),\n                    _ => None,\n                });\n        let insert_final_newline = pairs\n            .get(\"insert_final_newline\")\n            .and_then(|value| match value.as_ref() {\n                \"true\" => Some(true),\n                \"false\" => Some(false),\n                _ => None,\n            });\n        // This option is not in the spec but is supported by some editors.\n        // <https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#max_line_length>\n        let max_line_length = pairs\n            .get(\"max_line_length\")\n            .and_then(|value| value.parse::<NonZeroU16>().ok());\n\n        Self {\n            indent_style,\n            tab_width,\n            line_ending,\n            encoding,\n            trim_trailing_whitespace,\n            insert_final_newline,\n            max_line_length,\n        }\n    }\n}\n\ntype Pairs = HashMap<Box<str>, Box<str>>;\n\n#[derive(Debug)]\nstruct Section {\n    glob: GlobMatcher,\n    pairs: Pairs,\n}\n\n#[derive(Debug, Default)]\nstruct Ini {\n    pairs: Pairs,\n    sections: Vec<Section>,\n}\n\nimpl FromStr for Ini {\n    type Err = globset::Error;\n\n    fn from_str(source: &str) -> Result<Self, Self::Err> {\n        // <https://spec.editorconfig.org/#file-format>\n        let mut ini = Ini::default();\n        // > EditorConfig files are in an INI-like file format. To read an EditorConfig file, take\n        // > one line at a time, from beginning to end. For each line:\n        for full_line in source.lines() {\n            // > 1. Remove all leading and trailing whitespace.\n            let line = full_line.trim();\n            // > 2. Process the remaining text as specified for its type below.\n            // > The types of lines are:\n            // > * Blank: contains nothing. Blank lines are ignored.\n            if line.is_empty() {\n                continue;\n            }\n            // > * Comment: starts with a ';' or '#'. Comment lines are ignored.\n            if line.starts_with([';', '#']) {\n                continue;\n            }\n            if let Some(section) = line.strip_prefix('[').and_then(|s| s.strip_suffix(']')) {\n                // > * Section Header: starts with a `[` and ends with a `]`. These lines define\n                // >   globs...\n\n                // <https://spec.editorconfig.org/#glob-expressions>\n                // We need to modify the glob string slightly since EditorConfig's glob flavor\n                // doesn't match `globset`'s exactly. `globset` only allows '**' at the beginning\n                // or end of a glob or between two '/'s. (This replacement is not very fancy but\n                // should cover most practical cases.)\n                let mut glob_str = section.replace(\"**.\", \"**/*.\");\n                if !is_glob_relative(section) {\n                    glob_str.insert_str(0, \"**/\");\n                }\n                let glob = GlobBuilder::new(&glob_str)\n                    .literal_separator(true)\n                    .backslash_escape(true)\n                    .empty_alternates(true)\n                    .build()?;\n                ini.sections.push(Section {\n                    glob: glob.compile_matcher(),\n                    pairs: Pairs::new(),\n                });\n            } else if let Some((key, value)) = line.split_once('=') {\n                // > * Key-Value Pair (or Pair): contains a key and a value, separated by an `=`.\n                // >     * Key: The part before the first `=` on the line.\n                // >     * Value: The part, if any, after the first `=` on the line.\n                // >     * Keys and values are trimmed of leading and trailing whitespace, but\n                // >       include any whitespace that is between non-whitespace characters.\n                // >     * If a value is not provided, then the value is an empty string.\n                let key = key.trim().to_lowercase().into_boxed_str();\n                let value = value.trim().to_lowercase().into_boxed_str();\n                if let Some(section) = ini.sections.last_mut() {\n                    section.pairs.insert(key, value);\n                } else {\n                    ini.pairs.insert(key, value);\n                }\n            }\n        }\n        Ok(ini)\n    }\n}\n\n/// Determines whether a glob is relative to the directory of the config file.\nfn is_glob_relative(source: &str) -> bool {\n    // > If the glob contains a path separator (a `/` not inside square brackets), then the\n    // > glob is relative to the directory level of the particular `.editorconfig` file itself.\n    let mut idx = 0;\n    while let Some(open) = source[idx..].find('[').map(|open| idx + open) {\n        if source[..open].contains('/') {\n            return true;\n        }\n        idx = source[open..]\n            .find(']')\n            .map_or(source.len(), |close| idx + close);\n    }\n    source[idx..].contains('/')\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn is_glob_relative_test() {\n        assert!(is_glob_relative(\"subdir/*.c\"));\n        assert!(!is_glob_relative(\"*.txt\"));\n        assert!(!is_glob_relative(\"[a/b].c\"));\n    }\n\n    fn editor_config(path: impl AsRef<Path>, source: &str) -> EditorConfig {\n        let path = path.as_ref();\n        let ini = source.parse::<Ini>().unwrap();\n        let pairs = ini\n            .sections\n            .into_iter()\n            .filter(|section| section.glob.is_match(path))\n            .fold(Pairs::new(), |mut acc, section| {\n                acc.extend(section.pairs);\n                acc\n            });\n        EditorConfig::from_pairs(pairs)\n    }\n\n    #[test]\n    fn parse_test() {\n        let source = r#\"\n        [*]\n        indent_style = space\n\n        [Makefile]\n        indent_style = tab\n\n        [docs/**.txt]\n        insert_final_newline = true\n        \"#;\n\n        assert_eq!(\n            editor_config(\"a.txt\", source),\n            EditorConfig {\n                indent_style: Some(IndentStyle::Spaces(4)),\n                ..Default::default()\n            }\n        );\n        assert_eq!(\n            editor_config(\"pkg/Makefile\", source),\n            EditorConfig {\n                indent_style: Some(IndentStyle::Tabs),\n                ..Default::default()\n            }\n        );\n        assert_eq!(\n            editor_config(\"docs/config/editor.txt\", source),\n            EditorConfig {\n                indent_style: Some(IndentStyle::Spaces(4)),\n                insert_final_newline: Some(true),\n                ..Default::default()\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "helix-core/src/fuzzy.rs",
    "content": "use std::ops::DerefMut;\n\nuse nucleo::pattern::{Atom, AtomKind, CaseMatching, Normalization};\nuse nucleo::Config;\nuse parking_lot::Mutex;\n\npub struct LazyMutex<T> {\n    inner: Mutex<Option<T>>,\n    init: fn() -> T,\n}\n\nimpl<T> LazyMutex<T> {\n    pub const fn new(init: fn() -> T) -> Self {\n        Self {\n            inner: Mutex::new(None),\n            init,\n        }\n    }\n\n    pub fn lock(&self) -> impl DerefMut<Target = T> + '_ {\n        parking_lot::MutexGuard::map(self.inner.lock(), |val| val.get_or_insert_with(self.init))\n    }\n}\n\npub static MATCHER: LazyMutex<nucleo::Matcher> = LazyMutex::new(nucleo::Matcher::default);\n\n/// convenience function to easily fuzzy match\n/// on a (relatively small list of inputs). This is not recommended for building a full tui\n/// application that can match large numbers of matches as all matching is done on the current\n/// thread, effectively blocking the UI\npub fn fuzzy_match<T: AsRef<str>>(\n    pattern: &str,\n    items: impl IntoIterator<Item = T>,\n    path: bool,\n) -> Vec<(T, u16)> {\n    let mut matcher = MATCHER.lock();\n    matcher.config = Config::DEFAULT;\n    if path {\n        matcher.config.set_match_paths();\n    }\n    let pattern = Atom::new(\n        pattern,\n        CaseMatching::Smart,\n        Normalization::Smart,\n        AtomKind::Fuzzy,\n        false,\n    );\n    pattern.match_list(items, &mut matcher)\n}\n"
  },
  {
    "path": "helix-core/src/graphemes.rs",
    "content": "//! Utility functions to traverse the unicode graphemes of a `Rope`'s text contents.\n//!\n//! Based on <https://github.com/cessen/led/blob/c4fa72405f510b7fd16052f90a598c429b3104a6/src/graphemes.rs>\nuse ropey::{str_utils::byte_to_char_idx, RopeSlice};\nuse unicode_segmentation::{GraphemeCursor, GraphemeIncomplete};\nuse unicode_width::UnicodeWidthStr;\n\nuse std::borrow::Cow;\nuse std::fmt::{self, Debug, Display};\nuse std::marker::PhantomData;\nuse std::ops::Deref;\nuse std::ptr::NonNull;\nuse std::{slice, str};\n\nuse crate::chars::{char_is_whitespace, char_is_word};\nuse crate::LineEnding;\n\n#[inline]\npub fn tab_width_at(visual_x: usize, tab_width: u16) -> usize {\n    tab_width as usize - (visual_x % tab_width as usize)\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum Grapheme<'a> {\n    Newline,\n    Tab { width: usize },\n    Other { g: GraphemeStr<'a> },\n}\n\nimpl<'a> Grapheme<'a> {\n    pub fn new_decoration(g: &'static str) -> Grapheme<'a> {\n        assert_ne!(g, \"\\t\");\n        Grapheme::new(g.into(), 0, 0)\n    }\n\n    pub fn new(g: GraphemeStr<'a>, visual_x: usize, tab_width: u16) -> Grapheme<'a> {\n        match g {\n            g if g == \"\\t\" => Grapheme::Tab {\n                width: tab_width_at(visual_x, tab_width),\n            },\n            _ if LineEnding::from_str(&g).is_some() => Grapheme::Newline,\n            _ => Grapheme::Other { g },\n        }\n    }\n\n    pub fn change_position(&mut self, visual_x: usize, tab_width: u16) {\n        if let Grapheme::Tab { width } = self {\n            *width = tab_width_at(visual_x, tab_width)\n        }\n    }\n\n    /// Returns the a visual width of this grapheme,\n    #[inline]\n    pub fn width(&self) -> usize {\n        match *self {\n            // width is not cached because we are dealing with\n            // ASCII almost all the time which already has a fastpath\n            // it's okay to convert to u16 here because no codepoint has a width larger\n            // than 2 and graphemes are usually atmost two visible codepoints wide\n            Grapheme::Other { ref g } => grapheme_width(g),\n            Grapheme::Tab { width } => width,\n            Grapheme::Newline => 1,\n        }\n    }\n\n    pub fn is_whitespace(&self) -> bool {\n        !matches!(&self, Grapheme::Other { g } if !g.chars().next().is_some_and(char_is_whitespace))\n    }\n\n    // TODO currently word boundaries are used for softwrapping.\n    // This works best for programming languages and well for prose.\n    // This could however be improved in the future by considering unicode\n    // character classes but\n    pub fn is_word_boundary(&self) -> bool {\n        !matches!(&self, Grapheme::Other { g,.. } if g.chars().next().is_some_and(char_is_word))\n    }\n}\n\nimpl Display for Grapheme<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match *self {\n            Grapheme::Newline => write!(f, \" \"),\n            Grapheme::Tab { width } => {\n                for _ in 0..width {\n                    write!(f, \" \")?;\n                }\n                Ok(())\n            }\n            Grapheme::Other { ref g } => {\n                write!(f, \"{g}\")\n            }\n        }\n    }\n}\n\n#[must_use]\npub fn grapheme_width(g: &str) -> usize {\n    if g.as_bytes()[0] <= 127 {\n        // Fast-path ascii.\n        // Point 1: theoretically, ascii control characters should have zero\n        // width, but in our case we actually want them to have width: if they\n        // show up in text, we want to treat them as textual elements that can\n        // be edited.  So we can get away with making all ascii single width\n        // here.\n        // Point 2: we're only examining the first codepoint here, which means\n        // we're ignoring graphemes formed with combining characters.  However,\n        // if it starts with ascii, it's going to be a single-width grapeheme\n        // regardless, so, again, we can get away with that here.\n        // Point 3: we're only examining the first _byte_.  But for utf8, when\n        // checking for ascii range values only, that works.\n        1\n    } else {\n        // We use max(1) here because all grapeheme clusters--even illformed\n        // ones--should have at least some width so they can be edited\n        // properly.\n        // TODO properly handle unicode width for all codepoints\n        // example of where unicode width is currently wrong: 🤦🏼‍♂️ (taken from https://hsivonen.fi/string-length/)\n        UnicodeWidthStr::width(g).max(1)\n    }\n}\n\n// NOTE: for byte indexing versions of these functions see `RopeSliceExt`'s\n// `floor_grapheme_boundary` and `ceil_grapheme_boundary` and the rope grapheme iterators.\n\n#[must_use]\npub fn nth_prev_grapheme_boundary(slice: RopeSlice, char_idx: usize, n: usize) -> usize {\n    // Bounds check\n    debug_assert!(char_idx <= slice.len_chars());\n\n    // We work with bytes for this, so convert.\n    let mut byte_idx = slice.char_to_byte(char_idx);\n\n    // Get the chunk with our byte index in it.\n    let (mut chunk, mut chunk_byte_idx, mut chunk_char_idx, _) = slice.chunk_at_byte(byte_idx);\n\n    // Set up the grapheme cursor.\n    let mut gc = GraphemeCursor::new(byte_idx, slice.len_bytes(), true);\n\n    // Find the previous grapheme cluster boundary.\n    for _ in 0..n {\n        loop {\n            match gc.prev_boundary(chunk, chunk_byte_idx) {\n                Ok(None) => return 0,\n                Ok(Some(n)) => {\n                    byte_idx = n;\n                    break;\n                }\n                Err(GraphemeIncomplete::PrevChunk) => {\n                    let (a, b, c, _) = slice.chunk_at_byte(chunk_byte_idx - 1);\n                    chunk = a;\n                    chunk_byte_idx = b;\n                    chunk_char_idx = c;\n                }\n                Err(GraphemeIncomplete::PreContext(n)) => {\n                    let ctx_chunk = slice.chunk_at_byte(n - 1).0;\n                    gc.provide_context(ctx_chunk, n - ctx_chunk.len());\n                }\n                _ => unreachable!(),\n            }\n        }\n    }\n    let tmp = byte_to_char_idx(chunk, byte_idx - chunk_byte_idx);\n    chunk_char_idx + tmp\n}\n\n/// Finds the previous grapheme boundary before the given char position.\n#[must_use]\n#[inline(always)]\npub fn prev_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> usize {\n    nth_prev_grapheme_boundary(slice, char_idx, 1)\n}\n\n#[must_use]\npub fn nth_next_grapheme_boundary(slice: RopeSlice, char_idx: usize, n: usize) -> usize {\n    // Bounds check\n    debug_assert!(char_idx <= slice.len_chars());\n\n    // We work with bytes for this, so convert.\n    let mut byte_idx = slice.char_to_byte(char_idx);\n\n    // Get the chunk with our byte index in it.\n    let (mut chunk, mut chunk_byte_idx, mut chunk_char_idx, _) = slice.chunk_at_byte(byte_idx);\n\n    // Set up the grapheme cursor.\n    let mut gc = GraphemeCursor::new(byte_idx, slice.len_bytes(), true);\n\n    // Find the nth next grapheme cluster boundary.\n    for _ in 0..n {\n        loop {\n            match gc.next_boundary(chunk, chunk_byte_idx) {\n                Ok(None) => return slice.len_chars(),\n                Ok(Some(n)) => {\n                    byte_idx = n;\n                    break;\n                }\n                Err(GraphemeIncomplete::NextChunk) => {\n                    chunk_byte_idx += chunk.len();\n                    let (a, _, c, _) = slice.chunk_at_byte(chunk_byte_idx);\n                    chunk = a;\n                    chunk_char_idx = c;\n                }\n                Err(GraphemeIncomplete::PreContext(n)) => {\n                    let ctx_chunk = slice.chunk_at_byte(n - 1).0;\n                    gc.provide_context(ctx_chunk, n - ctx_chunk.len());\n                }\n                _ => unreachable!(),\n            }\n        }\n    }\n    let tmp = byte_to_char_idx(chunk, byte_idx - chunk_byte_idx);\n    chunk_char_idx + tmp\n}\n\n/// Finds the next grapheme boundary after the given char position.\n#[must_use]\n#[inline(always)]\npub fn next_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> usize {\n    nth_next_grapheme_boundary(slice, char_idx, 1)\n}\n\n/// Returns the passed char index if it's already a grapheme boundary,\n/// or the next grapheme boundary char index if not.\n#[must_use]\n#[inline]\npub fn ensure_grapheme_boundary_next(slice: RopeSlice, char_idx: usize) -> usize {\n    if char_idx == 0 {\n        char_idx\n    } else {\n        next_grapheme_boundary(slice, char_idx - 1)\n    }\n}\n\n/// Returns the passed char index if it's already a grapheme boundary,\n/// or the prev grapheme boundary char index if not.\n#[must_use]\n#[inline]\npub fn ensure_grapheme_boundary_prev(slice: RopeSlice, char_idx: usize) -> usize {\n    if char_idx == slice.len_chars() {\n        char_idx\n    } else {\n        prev_grapheme_boundary(slice, char_idx + 1)\n    }\n}\n\n/// A highly compressed Cow<'a, str> that holds\n/// atmost u31::MAX bytes and is readonly\npub struct GraphemeStr<'a> {\n    ptr: NonNull<u8>,\n    len: u32,\n    phantom: PhantomData<&'a str>,\n}\n\nimpl GraphemeStr<'_> {\n    const MASK_OWNED: u32 = 1 << 31;\n\n    fn compute_len(&self) -> usize {\n        (self.len & !Self::MASK_OWNED) as usize\n    }\n}\n\nimpl Deref for GraphemeStr<'_> {\n    type Target = str;\n    fn deref(&self) -> &Self::Target {\n        unsafe {\n            let bytes = slice::from_raw_parts(self.ptr.as_ptr(), self.compute_len());\n            str::from_utf8_unchecked(bytes)\n        }\n    }\n}\n\nimpl Drop for GraphemeStr<'_> {\n    fn drop(&mut self) {\n        if self.len & Self::MASK_OWNED != 0 {\n            // free allocation\n            unsafe {\n                drop(Box::from_raw(std::ptr::slice_from_raw_parts_mut(\n                    self.ptr.as_ptr(),\n                    self.compute_len(),\n                )));\n            }\n        }\n    }\n}\n\nimpl<'a> From<&'a str> for GraphemeStr<'a> {\n    fn from(g: &'a str) -> Self {\n        GraphemeStr {\n            ptr: unsafe { NonNull::new_unchecked(g.as_bytes().as_ptr() as *mut u8) },\n            len: i32::try_from(g.len()).unwrap() as u32,\n            phantom: PhantomData,\n        }\n    }\n}\n\nimpl From<String> for GraphemeStr<'_> {\n    fn from(g: String) -> Self {\n        let len = g.len();\n        let ptr = Box::into_raw(g.into_bytes().into_boxed_slice()) as *mut u8;\n        GraphemeStr {\n            ptr: unsafe { NonNull::new_unchecked(ptr) },\n            len: (i32::try_from(len).unwrap() as u32) | Self::MASK_OWNED,\n            phantom: PhantomData,\n        }\n    }\n}\n\nimpl<'a> From<Cow<'a, str>> for GraphemeStr<'a> {\n    fn from(g: Cow<'a, str>) -> Self {\n        match g {\n            Cow::Borrowed(g) => g.into(),\n            Cow::Owned(g) => g.into(),\n        }\n    }\n}\n\nimpl<T: Deref<Target = str>> PartialEq<T> for GraphemeStr<'_> {\n    fn eq(&self, other: &T) -> bool {\n        self.deref() == other.deref()\n    }\n}\nimpl PartialEq<str> for GraphemeStr<'_> {\n    fn eq(&self, other: &str) -> bool {\n        self.deref() == other\n    }\n}\nimpl Eq for GraphemeStr<'_> {}\nimpl Debug for GraphemeStr<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        Debug::fmt(self.deref(), f)\n    }\n}\nimpl Display for GraphemeStr<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        Display::fmt(self.deref(), f)\n    }\n}\nimpl Clone for GraphemeStr<'_> {\n    fn clone(&self) -> Self {\n        self.deref().to_owned().into()\n    }\n}\n"
  },
  {
    "path": "helix-core/src/history.rs",
    "content": "use crate::{Assoc, ChangeSet, Range, Rope, Selection, Transaction};\nuse once_cell::sync::Lazy;\nuse regex::Regex;\nuse std::num::NonZeroUsize;\nuse std::time::{Duration, Instant};\n\n#[derive(Debug, Clone)]\npub struct State {\n    pub doc: Rope,\n    pub selection: Selection,\n}\n\n/// Stores the history of changes to a buffer.\n///\n/// Currently the history is represented as a vector of revisions. The vector\n/// always has at least one element: the empty root revision. Each revision\n/// with the exception of the root has a parent revision, a [Transaction]\n/// that can be applied to its parent to transition from the parent to itself,\n/// and an inversion of that transaction to transition from the parent to its\n/// latest child.\n///\n/// When using `u` to undo a change, an inverse of the stored transaction will\n/// be applied which will transition the buffer to the parent state.\n///\n/// Each revision with the exception of the last in the vector also has a\n/// last child revision. When using `U` to redo a change, the last child transaction\n/// will be applied to the current state of the buffer.\n///\n/// The current revision is the one currently displayed in the buffer.\n///\n/// Committing a new revision to the history will update the last child of the\n/// current revision, and push a new revision to the end of the vector.\n///\n/// Revisions are committed with a timestamp. :earlier and :later can be used\n/// to jump to the closest revision to a moment in time relative to the timestamp\n/// of the current revision plus (:later) or minus (:earlier) the duration\n/// given to the command. If a single integer is given, the editor will instead\n/// jump the given number of revisions in the vector.\n///\n/// Limitations:\n///  * Changes in selections currently don't commit history changes. The selection\n///    will only be updated to the state after a committed buffer change.\n///  * The vector of history revisions is currently unbounded. This might\n///    cause the memory consumption to grow significantly large during long\n///    editing sessions.\n///  * Because delete transactions currently don't store the text that they\n///    delete, we also store an inversion of the transaction.\n///\n/// Using time to navigate the history: <https://github.com/helix-editor/helix/pull/194>\n#[derive(Debug)]\npub struct History {\n    revisions: Vec<Revision>,\n    current: usize,\n}\n\n/// A single point in history. See [History] for more information.\n#[derive(Debug, Clone)]\nstruct Revision {\n    parent: usize,\n    last_child: Option<NonZeroUsize>,\n    transaction: Transaction,\n    // We need an inversion for undos because delete transactions don't store\n    // the deleted text.\n    inversion: Transaction,\n    timestamp: Instant,\n}\n\nimpl Default for History {\n    fn default() -> Self {\n        // Add a dummy root revision with empty transaction\n        Self {\n            revisions: vec![Revision {\n                parent: 0,\n                last_child: None,\n                transaction: Transaction::from(ChangeSet::new(\"\".into())),\n                inversion: Transaction::from(ChangeSet::new(\"\".into())),\n                timestamp: Instant::now(),\n            }],\n            current: 0,\n        }\n    }\n}\n\nimpl History {\n    pub fn commit_revision(&mut self, transaction: &Transaction, original: &State) {\n        self.commit_revision_at_timestamp(transaction, original, Instant::now());\n    }\n\n    pub fn commit_revision_at_timestamp(\n        &mut self,\n        transaction: &Transaction,\n        original: &State,\n        timestamp: Instant,\n    ) {\n        let inversion = transaction\n            .invert(&original.doc)\n            // Store the current cursor position\n            .with_selection(original.selection.clone());\n\n        let new_current = self.revisions.len();\n        self.revisions[self.current].last_child = NonZeroUsize::new(new_current);\n        self.revisions.push(Revision {\n            parent: self.current,\n            last_child: None,\n            transaction: transaction.clone(),\n            inversion,\n            timestamp,\n        });\n        self.current = new_current;\n    }\n\n    #[inline]\n    pub fn current_revision(&self) -> usize {\n        self.current\n    }\n\n    #[inline]\n    pub const fn at_root(&self) -> bool {\n        self.current == 0\n    }\n\n    /// Returns the changes since the given revision composed into a transaction.\n    /// Returns None if there are no changes between the current and given revisions.\n    pub fn changes_since(&self, revision: usize) -> Option<Transaction> {\n        let lca = self.lowest_common_ancestor(revision, self.current);\n        let up = self.path_up(revision, lca);\n        let down = self.path_up(self.current, lca);\n        let up_txns = up\n            .iter()\n            .rev()\n            .map(|&n| self.revisions[n].inversion.clone());\n        let down_txns = down.iter().map(|&n| self.revisions[n].transaction.clone());\n\n        down_txns.chain(up_txns).reduce(|acc, tx| tx.compose(acc))\n    }\n\n    /// Undo the last edit.\n    pub fn undo(&mut self) -> Option<&Transaction> {\n        if self.at_root() {\n            return None;\n        }\n\n        let current_revision = &self.revisions[self.current];\n        self.current = current_revision.parent;\n        Some(&current_revision.inversion)\n    }\n\n    /// Redo the last edit.\n    pub fn redo(&mut self) -> Option<&Transaction> {\n        let current_revision = &self.revisions[self.current];\n        let last_child = current_revision.last_child?;\n        self.current = last_child.get();\n\n        Some(&self.revisions[last_child.get()].transaction)\n    }\n\n    // Get the position of last change\n    pub fn last_edit_pos(&self) -> Option<usize> {\n        if self.current == 0 {\n            return None;\n        }\n        let current_revision = &self.revisions[self.current];\n        let primary_selection = current_revision\n            .inversion\n            .selection()\n            .expect(\"inversion always contains a selection\")\n            .primary();\n        let (_from, to, _fragment) = current_revision\n            .transaction\n            .changes_iter()\n            // find a change that matches the primary selection\n            .find(|(from, to, _fragment)| Range::new(*from, *to).overlaps(&primary_selection))\n            // or use the first change\n            .or_else(|| current_revision.transaction.changes_iter().next())\n            .unwrap();\n        let pos = current_revision\n            .transaction\n            .changes()\n            .map_pos(to, Assoc::After);\n        Some(pos)\n    }\n\n    fn lowest_common_ancestor(&self, mut a: usize, mut b: usize) -> usize {\n        use std::collections::HashSet;\n        let mut a_path_set = HashSet::new();\n        let mut b_path_set = HashSet::new();\n        loop {\n            a_path_set.insert(a);\n            b_path_set.insert(b);\n            if a_path_set.contains(&b) {\n                return b;\n            }\n            if b_path_set.contains(&a) {\n                return a;\n            }\n            a = self.revisions[a].parent; // Relies on the parent of 0 being 0.\n            b = self.revisions[b].parent; // Same as above.\n        }\n    }\n\n    /// List of nodes on the way from `n` to 'a`. Doesn't include `a`.\n    /// Includes `n` unless `a == n`. `a` must be an ancestor of `n`.\n    fn path_up(&self, mut n: usize, a: usize) -> Vec<usize> {\n        let mut path = Vec::new();\n        while n != a {\n            path.push(n);\n            n = self.revisions[n].parent;\n        }\n        path\n    }\n\n    /// Create a [`Transaction`] that will jump to a specific revision in the history.\n    fn jump_to(&mut self, to: usize) -> Vec<Transaction> {\n        let lca = self.lowest_common_ancestor(self.current, to);\n        let up = self.path_up(self.current, lca);\n        let down = self.path_up(to, lca);\n        self.current = to;\n        let up_txns = up.iter().map(|&n| self.revisions[n].inversion.clone());\n        let down_txns = down\n            .iter()\n            .rev()\n            .map(|&n| self.revisions[n].transaction.clone());\n        up_txns.chain(down_txns).collect()\n    }\n\n    /// Creates a [`Transaction`] that will undo `delta` revisions.\n    fn jump_backward(&mut self, delta: usize) -> Vec<Transaction> {\n        self.jump_to(self.current.saturating_sub(delta))\n    }\n\n    /// Creates a [`Transaction`] that will redo `delta` revisions.\n    fn jump_forward(&mut self, delta: usize) -> Vec<Transaction> {\n        self.jump_to(\n            self.current\n                .saturating_add(delta)\n                .min(self.revisions.len() - 1),\n        )\n    }\n\n    /// Helper for a binary search case below.\n    fn revision_closer_to_instant(&self, i: usize, instant: Instant) -> usize {\n        let dur_im1 = instant.duration_since(self.revisions[i - 1].timestamp);\n        let dur_i = self.revisions[i].timestamp.duration_since(instant);\n        use std::cmp::Ordering::*;\n        match dur_im1.cmp(&dur_i) {\n            Less => i - 1,\n            Equal | Greater => i,\n        }\n    }\n\n    /// Creates a [`Transaction`] that will match a revision created at around\n    /// `instant`.\n    fn jump_instant(&mut self, instant: Instant) -> Vec<Transaction> {\n        let search_result = self\n            .revisions\n            .binary_search_by(|rev| rev.timestamp.cmp(&instant));\n        let revision = match search_result {\n            Ok(revision) => revision,\n            Err(insert_point) => match insert_point {\n                0 => 0,\n                n if n == self.revisions.len() => n - 1,\n                i => self.revision_closer_to_instant(i, instant),\n            },\n        };\n        self.jump_to(revision)\n    }\n\n    /// Creates a [`Transaction`] that will match a revision created `duration` ago\n    /// from the timestamp of current revision.\n    fn jump_duration_backward(&mut self, duration: Duration) -> Vec<Transaction> {\n        match self.revisions[self.current].timestamp.checked_sub(duration) {\n            Some(instant) => self.jump_instant(instant),\n            None => self.jump_to(0),\n        }\n    }\n\n    /// Creates a [`Transaction`] that will match a revision created `duration` in\n    /// the future from the timestamp of the current revision.\n    fn jump_duration_forward(&mut self, duration: Duration) -> Vec<Transaction> {\n        match self.revisions[self.current].timestamp.checked_add(duration) {\n            Some(instant) => self.jump_instant(instant),\n            None => self.jump_to(self.revisions.len() - 1),\n        }\n    }\n\n    /// Creates an undo [`Transaction`].\n    pub fn earlier(&mut self, uk: UndoKind) -> Vec<Transaction> {\n        use UndoKind::*;\n        match uk {\n            Steps(n) => self.jump_backward(n),\n            TimePeriod(d) => self.jump_duration_backward(d),\n        }\n    }\n\n    /// Creates a redo [`Transaction`].\n    pub fn later(&mut self, uk: UndoKind) -> Vec<Transaction> {\n        use UndoKind::*;\n        match uk {\n            Steps(n) => self.jump_forward(n),\n            TimePeriod(d) => self.jump_duration_forward(d),\n        }\n    }\n}\n\n/// Whether to undo by a number of edits or a duration of time.\n#[derive(Debug, PartialEq, Eq, Clone, Copy)]\npub enum UndoKind {\n    Steps(usize),\n    TimePeriod(std::time::Duration),\n}\n\n/// A subset of systemd.time time span syntax units.\nconst TIME_UNITS: &[(&[&str], &str, u64)] = &[\n    (&[\"seconds\", \"second\", \"sec\", \"s\"], \"seconds\", 1),\n    (&[\"minutes\", \"minute\", \"min\", \"m\"], \"minutes\", 60),\n    (&[\"hours\", \"hour\", \"hr\", \"h\"], \"hours\", 60 * 60),\n    (&[\"days\", \"day\", \"d\"], \"days\", 24 * 60 * 60),\n];\n\n/// Checks if the duration input can be turned into a valid duration. It must be a\n/// positive integer and denote the [unit of time.](`TIME_UNITS`)\n/// Examples of valid durations:\n///  * `5 sec`\n///  * `5 min`\n///  * `5 hr`\n///  * `5 days`\nstatic DURATION_VALIDATION_REGEX: Lazy<Regex> =\n    Lazy::new(|| Regex::new(r\"^(?:\\d+\\s*[a-z]+\\s*)+$\").unwrap());\n\n/// Captures both the number and unit as separate capture groups.\nstatic NUMBER_UNIT_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r\"(\\d+)\\s*([a-z]+)\").unwrap());\n\n/// Parse a string (e.g. \"5 sec\") and try to convert it into a [`Duration`].\nfn parse_human_duration(s: &str) -> Result<Duration, String> {\n    if !DURATION_VALIDATION_REGEX.is_match(s) {\n        return Err(\"duration should be composed \\\n        of positive integers followed by time units\"\n            .to_string());\n    }\n\n    let mut specified = [false; TIME_UNITS.len()];\n    let mut seconds = 0u64;\n    for cap in NUMBER_UNIT_REGEX.captures_iter(s) {\n        let (n, unit_str) = (&cap[1], &cap[2]);\n\n        let n: u64 = n.parse().map_err(|_| format!(\"integer too large: {}\", n))?;\n\n        let time_unit = TIME_UNITS\n            .iter()\n            .enumerate()\n            .find(|(_, (forms, _, _))| forms.iter().any(|f| f == &unit_str));\n\n        if let Some((i, (_, unit, mul))) = time_unit {\n            if specified[i] {\n                return Err(format!(\"{} specified more than once\", unit));\n            }\n            specified[i] = true;\n\n            let new_seconds = n.checked_mul(*mul).and_then(|s| seconds.checked_add(s));\n            match new_seconds {\n                Some(ns) => seconds = ns,\n                None => return Err(\"duration too large\".to_string()),\n            }\n        } else {\n            return Err(format!(\"incorrect time unit: {}\", unit_str));\n        }\n    }\n\n    Ok(Duration::from_secs(seconds))\n}\n\nimpl std::str::FromStr for UndoKind {\n    type Err = String;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let s = s.trim();\n        if s.is_empty() {\n            Ok(Self::Steps(1usize))\n        } else if let Ok(n) = s.parse::<usize>() {\n            Ok(UndoKind::Steps(n))\n        } else {\n            Ok(Self::TimePeriod(parse_human_duration(s)?))\n        }\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::Selection;\n\n    #[test]\n    fn test_undo_redo() {\n        let mut history = History::default();\n        let doc = Rope::from(\"hello\");\n        let mut state = State {\n            doc,\n            selection: Selection::point(0),\n        };\n\n        let transaction1 =\n            Transaction::change(&state.doc, vec![(5, 5, Some(\" world!\".into()))].into_iter());\n\n        // Need to commit before applying!\n        history.commit_revision(&transaction1, &state);\n        transaction1.apply(&mut state.doc);\n        assert_eq!(\"hello world!\", state.doc);\n\n        // ---\n\n        let transaction2 =\n            Transaction::change(&state.doc, vec![(6, 11, Some(\"世界\".into()))].into_iter());\n\n        // Need to commit before applying!\n        history.commit_revision(&transaction2, &state);\n        transaction2.apply(&mut state.doc);\n        assert_eq!(\"hello 世界!\", state.doc);\n\n        // ---\n        fn undo(history: &mut History, state: &mut State) {\n            if let Some(transaction) = history.undo() {\n                transaction.apply(&mut state.doc);\n            }\n        }\n        fn redo(history: &mut History, state: &mut State) {\n            if let Some(transaction) = history.redo() {\n                transaction.apply(&mut state.doc);\n            }\n        }\n\n        undo(&mut history, &mut state);\n        assert_eq!(\"hello world!\", state.doc);\n        redo(&mut history, &mut state);\n        assert_eq!(\"hello 世界!\", state.doc);\n        undo(&mut history, &mut state);\n        undo(&mut history, &mut state);\n        assert_eq!(\"hello\", state.doc);\n\n        // undo at root is a no-op\n        undo(&mut history, &mut state);\n        assert_eq!(\"hello\", state.doc);\n    }\n\n    #[test]\n    fn test_earlier_later() {\n        let mut history = History::default();\n        let doc = Rope::from(\"a\\n\");\n        let mut state = State {\n            doc,\n            selection: Selection::point(0),\n        };\n\n        fn undo(history: &mut History, state: &mut State) {\n            if let Some(transaction) = history.undo() {\n                transaction.apply(&mut state.doc);\n            }\n        }\n\n        fn earlier(history: &mut History, state: &mut State, uk: UndoKind) {\n            let txns = history.earlier(uk);\n            for txn in txns {\n                txn.apply(&mut state.doc);\n            }\n        }\n\n        fn later(history: &mut History, state: &mut State, uk: UndoKind) {\n            let txns = history.later(uk);\n            for txn in txns {\n                txn.apply(&mut state.doc);\n            }\n        }\n\n        fn commit_change(\n            history: &mut History,\n            state: &mut State,\n            change: crate::transaction::Change,\n            instant: Instant,\n        ) {\n            let txn = Transaction::change(&state.doc, vec![change].into_iter());\n            history.commit_revision_at_timestamp(&txn, state, instant);\n            txn.apply(&mut state.doc);\n        }\n\n        let t0 = Instant::now();\n        let t = |n| t0.checked_add(Duration::from_secs(n)).unwrap();\n\n        commit_change(&mut history, &mut state, (1, 1, Some(\" b\".into())), t(0));\n        assert_eq!(\"a b\\n\", state.doc);\n\n        commit_change(&mut history, &mut state, (3, 3, Some(\" c\".into())), t(10));\n        assert_eq!(\"a b c\\n\", state.doc);\n\n        commit_change(&mut history, &mut state, (5, 5, Some(\" d\".into())), t(20));\n        assert_eq!(\"a b c d\\n\", state.doc);\n\n        undo(&mut history, &mut state);\n        assert_eq!(\"a b c\\n\", state.doc);\n\n        commit_change(&mut history, &mut state, (5, 5, Some(\" e\".into())), t(30));\n        assert_eq!(\"a b c e\\n\", state.doc);\n\n        undo(&mut history, &mut state);\n        undo(&mut history, &mut state);\n        assert_eq!(\"a b\\n\", state.doc);\n\n        commit_change(&mut history, &mut state, (1, 3, None), t(40));\n        assert_eq!(\"a\\n\", state.doc);\n\n        commit_change(&mut history, &mut state, (1, 1, Some(\" f\".into())), t(50));\n        assert_eq!(\"a f\\n\", state.doc);\n\n        use UndoKind::*;\n\n        earlier(&mut history, &mut state, Steps(3));\n        assert_eq!(\"a b c d\\n\", state.doc);\n\n        later(&mut history, &mut state, TimePeriod(Duration::new(20, 0)));\n        assert_eq!(\"a\\n\", state.doc);\n\n        earlier(&mut history, &mut state, TimePeriod(Duration::new(19, 0)));\n        assert_eq!(\"a b c d\\n\", state.doc);\n\n        earlier(\n            &mut history,\n            &mut state,\n            TimePeriod(Duration::new(10000, 0)),\n        );\n        assert_eq!(\"a\\n\", state.doc);\n\n        later(&mut history, &mut state, Steps(50));\n        assert_eq!(\"a f\\n\", state.doc);\n\n        earlier(&mut history, &mut state, Steps(4));\n        assert_eq!(\"a b c\\n\", state.doc);\n\n        later(&mut history, &mut state, TimePeriod(Duration::new(1, 0)));\n        assert_eq!(\"a b c\\n\", state.doc);\n\n        later(&mut history, &mut state, TimePeriod(Duration::new(5, 0)));\n        assert_eq!(\"a b c d\\n\", state.doc);\n\n        later(&mut history, &mut state, TimePeriod(Duration::new(6, 0)));\n        assert_eq!(\"a b c e\\n\", state.doc);\n\n        later(&mut history, &mut state, Steps(1));\n        assert_eq!(\"a\\n\", state.doc);\n    }\n\n    #[test]\n    fn test_parse_undo_kind() {\n        use UndoKind::*;\n\n        // Default is one step.\n        assert_eq!(\"\".parse(), Ok(Steps(1)));\n\n        // An integer means the number of steps.\n        assert_eq!(\"1\".parse(), Ok(Steps(1)));\n        assert_eq!(\"  16 \".parse(), Ok(Steps(16)));\n\n        // Duration has a strict format.\n        let validation_err = Err(\"duration should be composed \\\n         of positive integers followed by time units\"\n            .to_string());\n        assert_eq!(\"  16 33\".parse::<UndoKind>(), validation_err);\n        assert_eq!(\"  seconds 22  \".parse::<UndoKind>(), validation_err);\n        assert_eq!(\"  -4 m\".parse::<UndoKind>(), validation_err);\n        assert_eq!(\"5s 3\".parse::<UndoKind>(), validation_err);\n\n        // Units are u64.\n        assert_eq!(\n            \"18446744073709551616minutes\".parse::<UndoKind>(),\n            Err(\"integer too large: 18446744073709551616\".to_string())\n        );\n\n        // Units are validated.\n        assert_eq!(\n            \"1 millennium\".parse::<UndoKind>(),\n            Err(\"incorrect time unit: millennium\".to_string())\n        );\n\n        // Units can't be specified twice.\n        assert_eq!(\n            \"2 seconds 6s\".parse::<UndoKind>(),\n            Err(\"seconds specified more than once\".to_string())\n        );\n\n        // Various formats are correctly handled.\n        assert_eq!(\n            \"4s\".parse::<UndoKind>(),\n            Ok(TimePeriod(Duration::from_secs(4)))\n        );\n        assert_eq!(\n            \"2m\".parse::<UndoKind>(),\n            Ok(TimePeriod(Duration::from_secs(120)))\n        );\n        assert_eq!(\n            \"5h\".parse::<UndoKind>(),\n            Ok(TimePeriod(Duration::from_secs(5 * 60 * 60)))\n        );\n        assert_eq!(\n            \"3d\".parse::<UndoKind>(),\n            Ok(TimePeriod(Duration::from_secs(3 * 24 * 60 * 60)))\n        );\n        assert_eq!(\n            \"1m30s\".parse::<UndoKind>(),\n            Ok(TimePeriod(Duration::from_secs(90)))\n        );\n        assert_eq!(\n            \"1m 20 seconds\".parse::<UndoKind>(),\n            Ok(TimePeriod(Duration::from_secs(80)))\n        );\n        assert_eq!(\n            \"  2 minute 1day\".parse::<UndoKind>(),\n            Ok(TimePeriod(Duration::from_secs(24 * 60 * 60 + 2 * 60)))\n        );\n        assert_eq!(\n            \"3 d 2hour 5 minutes 30sec\".parse::<UndoKind>(),\n            Ok(TimePeriod(Duration::from_secs(\n                3 * 24 * 60 * 60 + 2 * 60 * 60 + 5 * 60 + 30\n            )))\n        );\n\n        // Sum overflow is handled.\n        assert_eq!(\n            \"18446744073709551615minutes\".parse::<UndoKind>(),\n            Err(\"duration too large\".to_string())\n        );\n        assert_eq!(\n            \"1 minute 18446744073709551615 seconds\".parse::<UndoKind>(),\n            Err(\"duration too large\".to_string())\n        );\n    }\n}\n"
  },
  {
    "path": "helix-core/src/increment/date_time.rs",
    "content": "use chrono::{Duration, NaiveDate, NaiveDateTime, NaiveTime};\nuse once_cell::sync::Lazy;\nuse regex::Regex;\nuse std::fmt::Write;\n\n/// Increment a Date or DateTime\n///\n/// If just a Date is selected the day will be incremented.\n/// If a DateTime is selected the second will be incremented.\npub fn increment(selected_text: &str, amount: i64) -> Option<String> {\n    if selected_text.is_empty() {\n        return None;\n    }\n\n    FORMATS.iter().find_map(|format| {\n        let captures = format.regex.captures(selected_text)?;\n        if captures.len() - 1 != format.fields.len() {\n            return None;\n        }\n\n        let date_time = captures.get(0)?;\n        let has_date = format.fields.iter().any(|f| f.unit.is_date());\n        let has_time = format.fields.iter().any(|f| f.unit.is_time());\n        let date_time = &selected_text[date_time.start()..date_time.end()];\n        match (has_date, has_time) {\n            (true, true) => {\n                let date_time = NaiveDateTime::parse_from_str(date_time, format.fmt).ok()?;\n                Some(\n                    date_time\n                        .checked_add_signed(Duration::try_minutes(amount)?)?\n                        .format(format.fmt)\n                        .to_string(),\n                )\n            }\n            (true, false) => {\n                let date = NaiveDate::parse_from_str(date_time, format.fmt).ok()?;\n                Some(\n                    date.checked_add_signed(Duration::try_days(amount)?)?\n                        .format(format.fmt)\n                        .to_string(),\n                )\n            }\n            (false, true) => {\n                let time = NaiveTime::parse_from_str(date_time, format.fmt).ok()?;\n                let (adjusted_time, _) =\n                    time.overflowing_add_signed(Duration::try_minutes(amount)?);\n                Some(adjusted_time.format(format.fmt).to_string())\n            }\n            (false, false) => None,\n        }\n    })\n}\n\nstatic FORMATS: Lazy<Vec<Format>> = Lazy::new(|| {\n    vec![\n        Format::new(\"%Y-%m-%d %H:%M:%S\"), // 2021-11-24 07:12:23\n        Format::new(\"%Y/%m/%d %H:%M:%S\"), // 2021/11/24 07:12:23\n        Format::new(\"%Y-%m-%d %H:%M\"),    // 2021-11-24 07:12\n        Format::new(\"%Y/%m/%d %H:%M\"),    // 2021/11/24 07:12\n        Format::new(\"%Y-%m-%d\"),          // 2021-11-24\n        Format::new(\"%Y/%m/%d\"),          // 2021/11/24\n        Format::new(\"%a %b %d %Y\"),       // Wed Nov 24 2021\n        Format::new(\"%d-%b-%Y\"),          // 24-Nov-2021\n        Format::new(\"%Y %b %d\"),          // 2021 Nov 24\n        Format::new(\"%b %d, %Y\"),         // Nov 24, 2021\n        Format::new(\"%-I:%M:%S %P\"),      // 7:21:53 am\n        Format::new(\"%-I:%M %P\"),         // 7:21 am\n        Format::new(\"%-I:%M:%S %p\"),      // 7:21:53 AM\n        Format::new(\"%-I:%M %p\"),         // 7:21 AM\n        Format::new(\"%H:%M:%S\"),          // 23:24:23\n        Format::new(\"%H:%M\"),             // 23:24\n    ]\n});\n\n#[derive(Debug)]\nstruct Format {\n    fmt: &'static str,\n    fields: Vec<DateField>,\n    regex: Regex,\n    max_len: usize,\n}\n\nimpl Format {\n    fn new(fmt: &'static str) -> Self {\n        let mut remaining = fmt;\n        let mut fields = Vec::new();\n        let mut regex = \"^\".to_string();\n        let mut max_len = 0;\n\n        while let Some(i) = remaining.find('%') {\n            let after = &remaining[i + 1..];\n            let mut chars = after.chars();\n            let c = chars.next().unwrap();\n\n            let spec_len = if c == '-' {\n                1 + chars.next().unwrap().len_utf8()\n            } else {\n                c.len_utf8()\n            };\n\n            let specifier = &after[..spec_len];\n            let field = DateField::from_specifier(specifier).unwrap();\n            fields.push(field);\n            max_len += field.max_len + remaining[..i].len();\n            regex += &remaining[..i];\n            write!(regex, \"({})\", field.regex).unwrap();\n            remaining = &after[spec_len..];\n        }\n        regex += \"$\";\n\n        let regex = Regex::new(&regex).unwrap();\n\n        Self {\n            fmt,\n            fields,\n            regex,\n            max_len,\n        }\n    }\n}\n\nimpl PartialEq for Format {\n    fn eq(&self, other: &Self) -> bool {\n        self.fmt == other.fmt && self.fields == other.fields && self.max_len == other.max_len\n    }\n}\n\nimpl Eq for Format {}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\nstruct DateField {\n    regex: &'static str,\n    unit: DateUnit,\n    max_len: usize,\n}\n\nimpl DateField {\n    fn from_specifier(specifier: &str) -> Option<Self> {\n        match specifier {\n            \"Y\" => Some(Self {\n                regex: r\"\\d{4}\",\n                unit: DateUnit::Years,\n                max_len: 5,\n            }),\n            \"y\" => Some(Self {\n                regex: r\"\\d\\d\",\n                unit: DateUnit::Years,\n                max_len: 2,\n            }),\n            \"m\" => Some(Self {\n                regex: r\"[0-1]\\d\",\n                unit: DateUnit::Months,\n                max_len: 2,\n            }),\n            \"d\" => Some(Self {\n                regex: r\"[0-3]\\d\",\n                unit: DateUnit::Days,\n                max_len: 2,\n            }),\n            \"-d\" => Some(Self {\n                regex: r\"[1-3]?\\d\",\n                unit: DateUnit::Days,\n                max_len: 2,\n            }),\n            \"a\" => Some(Self {\n                regex: r\"Sun|Mon|Tue|Wed|Thu|Fri|Sat\",\n                unit: DateUnit::Days,\n                max_len: 3,\n            }),\n            \"A\" => Some(Self {\n                regex: r\"Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday\",\n                unit: DateUnit::Days,\n                max_len: 9,\n            }),\n            \"b\" | \"h\" => Some(Self {\n                regex: r\"Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec\",\n                unit: DateUnit::Months,\n                max_len: 3,\n            }),\n            \"B\" => Some(Self {\n                regex: r\"January|February|March|April|May|June|July|August|September|October|November|December\",\n                unit: DateUnit::Months,\n                max_len: 9,\n            }),\n            \"H\" => Some(Self {\n                regex: r\"[0-2]\\d\",\n                unit: DateUnit::Hours,\n                max_len: 2,\n            }),\n            \"M\" => Some(Self {\n                regex: r\"[0-5]\\d\",\n                unit: DateUnit::Minutes,\n                max_len: 2,\n            }),\n            \"S\" => Some(Self {\n                regex: r\"[0-5]\\d\",\n                unit: DateUnit::Seconds,\n                max_len: 2,\n            }),\n            \"I\" => Some(Self {\n                regex: r\"[0-1]\\d\",\n                unit: DateUnit::Hours,\n                max_len: 2,\n            }),\n            \"-I\" => Some(Self {\n                regex: r\"1?\\d\",\n                unit: DateUnit::Hours,\n                max_len: 2,\n            }),\n            \"P\" => Some(Self {\n                regex: r\"am|pm\",\n                unit: DateUnit::AmPm,\n                max_len: 2,\n            }),\n            \"p\" => Some(Self {\n                regex: r\"AM|PM\",\n                unit: DateUnit::AmPm,\n                max_len: 2,\n            }),\n            _ => None,\n        }\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\nenum DateUnit {\n    Years,\n    Months,\n    Days,\n    Hours,\n    Minutes,\n    Seconds,\n    AmPm,\n}\n\nimpl DateUnit {\n    fn is_date(self) -> bool {\n        matches!(self, DateUnit::Years | DateUnit::Months | DateUnit::Days)\n    }\n\n    fn is_time(self) -> bool {\n        matches!(\n            self,\n            DateUnit::Hours | DateUnit::Minutes | DateUnit::Seconds\n        )\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn test_increment_date_times() {\n        let tests = [\n            // (original, cursor, amount, expected)\n            (\"2020-02-28\", 1, \"2020-02-29\"),\n            (\"2020-02-29\", 1, \"2020-03-01\"),\n            (\"2020-01-31\", 1, \"2020-02-01\"),\n            (\"2020-01-20\", 1, \"2020-01-21\"),\n            (\"2021-01-01\", -1, \"2020-12-31\"),\n            (\"2021-01-31\", -2, \"2021-01-29\"),\n            (\"2020-02-28\", 1, \"2020-02-29\"),\n            (\"2021-02-28\", 1, \"2021-03-01\"),\n            (\"2021-03-01\", -1, \"2021-02-28\"),\n            (\"2020-02-29\", -1, \"2020-02-28\"),\n            (\"2020-02-20\", -1, \"2020-02-19\"),\n            (\"2021-03-01\", -1, \"2021-02-28\"),\n            (\"1980/12/21\", 100, \"1981/03/31\"),\n            (\"1980/12/21\", -100, \"1980/09/12\"),\n            (\"1980/12/21\", 1000, \"1983/09/17\"),\n            (\"1980/12/21\", -1000, \"1978/03/27\"),\n            (\"2021-11-24 07:12:23\", 1, \"2021-11-24 07:13:23\"),\n            (\"2021-11-24 07:12\", 1, \"2021-11-24 07:13\"),\n            (\"Wed Nov 24 2021\", 1, \"Thu Nov 25 2021\"),\n            (\"24-Nov-2021\", 1, \"25-Nov-2021\"),\n            (\"2021 Nov 24\", 1, \"2021 Nov 25\"),\n            (\"Nov 24, 2021\", 1, \"Nov 25, 2021\"),\n            (\"7:21:53 am\", 1, \"7:22:53 am\"),\n            (\"7:21:53 AM\", 1, \"7:22:53 AM\"),\n            (\"7:21 am\", 1, \"7:22 am\"),\n            (\"23:24:23\", 1, \"23:25:23\"),\n            (\"23:24\", 1, \"23:25\"),\n            (\"23:59\", 1, \"00:00\"),\n            (\"23:59:59\", 1, \"00:00:59\"),\n        ];\n\n        for (original, amount, expected) in tests {\n            assert_eq!(increment(original, amount).unwrap(), expected);\n        }\n    }\n\n    #[test]\n    fn test_invalid_date_times() {\n        let tests = [\n            \"0000-00-00\",\n            \"1980-2-21\",\n            \"1980-12-1\",\n            \"12345\",\n            \"2020-02-30\",\n            \"1999-12-32\",\n            \"19-12-32\",\n            \"1-2-3\",\n            \"0000/00/00\",\n            \"1980/2/21\",\n            \"1980/12/1\",\n            \"12345\",\n            \"2020/02/30\",\n            \"1999/12/32\",\n            \"19/12/32\",\n            \"1/2/3\",\n            \"123:456:789\",\n            \"11:61\",\n            \"2021-55-12 08:12:54\",\n        ];\n\n        for invalid in tests {\n            assert_eq!(increment(invalid, 1), None)\n        }\n    }\n}\n"
  },
  {
    "path": "helix-core/src/increment/integer.rs",
    "content": "const SEPARATOR: char = '_';\n\n/// Increment an integer.\n///\n/// Supported bases:\n///     2 with prefix 0b\n///     8 with prefix 0o\n///     10 with no prefix\n///     16 with prefix 0x\n///\n/// An integer can contain `_` as a separator but may not start or end with a separator.\n/// Base 10 integers can go negative, but bases 2, 8, and 16 cannot.\n/// All addition and subtraction is saturating.\npub fn increment(selected_text: &str, amount: i64) -> Option<String> {\n    if selected_text.is_empty()\n        || selected_text.ends_with(SEPARATOR)\n        || selected_text.starts_with(SEPARATOR)\n    {\n        return None;\n    }\n\n    let radix = if selected_text.starts_with(\"0x\") {\n        16\n    } else if selected_text.starts_with(\"0o\") {\n        8\n    } else if selected_text.starts_with(\"0b\") {\n        2\n    } else {\n        10\n    };\n\n    // Get separator indexes from right to left.\n    let separator_rtl_indexes: Vec<usize> = selected_text\n        .chars()\n        .rev()\n        .enumerate()\n        .filter_map(|(i, c)| if c == SEPARATOR { Some(i) } else { None })\n        .collect();\n\n    let word: String = selected_text.chars().filter(|&c| c != SEPARATOR).collect();\n\n    let mut new_text = if radix == 10 {\n        let number = &word;\n        let value = i128::from_str_radix(number, radix).ok()?;\n        let new_value = value.saturating_add(amount as i128);\n\n        let format_length = match (value.is_negative(), new_value.is_negative()) {\n            (true, false) => number.len() - 1,\n            (false, true) => number.len() + 1,\n            _ => number.len(),\n        } - separator_rtl_indexes.len();\n\n        if number.starts_with('0') || number.starts_with(\"-0\") {\n            format!(\"{:01$}\", new_value, format_length)\n        } else {\n            format!(\"{}\", new_value)\n        }\n    } else {\n        let number = &word[2..];\n        let value = u128::from_str_radix(number, radix).ok()?;\n        let new_value = (value as i128).saturating_add(amount as i128);\n        let new_value = if new_value < 0 { 0 } else { new_value };\n        let format_length = selected_text.len() - 2 - separator_rtl_indexes.len();\n\n        match radix {\n            2 => format!(\"0b{:01$b}\", new_value, format_length),\n            8 => format!(\"0o{:01$o}\", new_value, format_length),\n            16 => {\n                let (lower_count, upper_count): (usize, usize) =\n                    number.chars().fold((0, 0), |(lower, upper), c| {\n                        (\n                            lower + c.is_ascii_lowercase() as usize,\n                            upper + c.is_ascii_uppercase() as usize,\n                        )\n                    });\n                if upper_count > lower_count {\n                    format!(\"0x{:01$X}\", new_value, format_length)\n                } else {\n                    format!(\"0x{:01$x}\", new_value, format_length)\n                }\n            }\n            _ => unimplemented!(\"radix not supported: {}\", radix),\n        }\n    };\n\n    // Add separators from original number.\n    for &rtl_index in &separator_rtl_indexes {\n        if rtl_index < new_text.len() {\n            let new_index = new_text.len().saturating_sub(rtl_index);\n            if new_index > 0 {\n                new_text.insert(new_index, SEPARATOR);\n            }\n        }\n    }\n\n    // Add in additional separators if necessary.\n    if new_text.len() > selected_text.len() && !separator_rtl_indexes.is_empty() {\n        let spacing = match separator_rtl_indexes.as_slice() {\n            [.., b, a] => a - b - 1,\n            _ => separator_rtl_indexes[0],\n        };\n\n        let prefix_length = if radix == 10 { 0 } else { 2 };\n        if let Some(mut index) = new_text.find(SEPARATOR) {\n            while index - prefix_length > spacing {\n                index -= spacing;\n                new_text.insert(index, SEPARATOR);\n            }\n        }\n    }\n\n    Some(new_text)\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn test_increment_basic_decimal_numbers() {\n        let tests = [\n            (\"100\", 1, \"101\"),\n            (\"100\", -1, \"99\"),\n            (\"99\", 1, \"100\"),\n            (\"100\", 1000, \"1100\"),\n            (\"100\", -1000, \"-900\"),\n            (\"-1\", 1, \"0\"),\n            (\"-1\", 2, \"1\"),\n            (\"1\", -1, \"0\"),\n            (\"1\", -2, \"-1\"),\n        ];\n\n        for (original, amount, expected) in tests {\n            assert_eq!(increment(original, amount).unwrap(), expected);\n        }\n    }\n\n    #[test]\n    fn test_increment_basic_hexadecimal_numbers() {\n        let tests = [\n            (\"0x0100\", 1, \"0x0101\"),\n            (\"0x0100\", -1, \"0x00ff\"),\n            (\"0x0001\", -1, \"0x0000\"),\n            (\"0x0000\", -1, \"0x0000\"),\n            (\"0xffffffffffffffff\", 1, \"0x10000000000000000\"),\n            (\"0xffffffffffffffff\", 2, \"0x10000000000000001\"),\n            (\"0xffffffffffffffff\", -1, \"0xfffffffffffffffe\"),\n            (\"0xABCDEF1234567890\", 1, \"0xABCDEF1234567891\"),\n            (\"0xabcdef1234567890\", 1, \"0xabcdef1234567891\"),\n        ];\n\n        for (original, amount, expected) in tests {\n            assert_eq!(increment(original, amount).unwrap(), expected);\n        }\n    }\n\n    #[test]\n    fn test_increment_basic_octal_numbers() {\n        let tests = [\n            (\"0o0107\", 1, \"0o0110\"),\n            (\"0o0110\", -1, \"0o0107\"),\n            (\"0o0001\", -1, \"0o0000\"),\n            (\"0o7777\", 1, \"0o10000\"),\n            (\"0o1000\", -1, \"0o0777\"),\n            (\"0o0107\", 10, \"0o0121\"),\n            (\"0o0000\", -1, \"0o0000\"),\n            (\"0o1777777777777777777777\", 1, \"0o2000000000000000000000\"),\n            (\"0o1777777777777777777777\", 2, \"0o2000000000000000000001\"),\n            (\"0o1777777777777777777777\", -1, \"0o1777777777777777777776\"),\n        ];\n\n        for (original, amount, expected) in tests {\n            assert_eq!(increment(original, amount).unwrap(), expected);\n        }\n    }\n\n    #[test]\n    fn test_increment_basic_binary_numbers() {\n        let tests = [\n            (\"0b00000100\", 1, \"0b00000101\"),\n            (\"0b00000100\", -1, \"0b00000011\"),\n            (\"0b00000100\", 2, \"0b00000110\"),\n            (\"0b00000100\", -2, \"0b00000010\"),\n            (\"0b00000001\", -1, \"0b00000000\"),\n            (\"0b00111111\", 10, \"0b01001001\"),\n            (\"0b11111111\", 1, \"0b100000000\"),\n            (\"0b10000000\", -1, \"0b01111111\"),\n            (\"0b0000\", -1, \"0b0000\"),\n            (\n                \"0b1111111111111111111111111111111111111111111111111111111111111111\",\n                1,\n                \"0b10000000000000000000000000000000000000000000000000000000000000000\",\n            ),\n            (\n                \"0b1111111111111111111111111111111111111111111111111111111111111111\",\n                2,\n                \"0b10000000000000000000000000000000000000000000000000000000000000001\",\n            ),\n            (\n                \"0b1111111111111111111111111111111111111111111111111111111111111111\",\n                -1,\n                \"0b1111111111111111111111111111111111111111111111111111111111111110\",\n            ),\n        ];\n\n        for (original, amount, expected) in tests {\n            assert_eq!(increment(original, amount).unwrap(), expected);\n        }\n    }\n\n    #[test]\n    fn test_increment_with_separators() {\n        let tests = [\n            (\"999_999\", 1, \"1_000_000\"),\n            (\"1_000_000\", -1, \"999_999\"),\n            (\"-999_999\", -1, \"-1_000_000\"),\n            (\"0x0000_0000_0001\", 0x1_ffff_0000, \"0x0001_ffff_0001\"),\n            (\"0x0000_0000\", -1, \"0x0000_0000\"),\n            (\"0x0000_0000_0000\", -1, \"0x0000_0000_0000\"),\n            (\"0b01111111_11111111\", 1, \"0b10000000_00000000\"),\n            (\"0b11111111_11111111\", 1, \"0b1_00000000_00000000\"),\n        ];\n\n        for (original, amount, expected) in tests {\n            assert_eq!(increment(original, amount).unwrap(), expected);\n        }\n    }\n\n    #[test]\n    fn test_leading_and_trailing_separators_arent_a_match() {\n        assert_eq!(increment(\"9_\", 1), None);\n        assert_eq!(increment(\"_9\", 1), None);\n        assert_eq!(increment(\"_9_\", 1), None);\n    }\n}\n"
  },
  {
    "path": "helix-core/src/increment/mod.rs",
    "content": "mod date_time;\nmod integer;\n\npub fn integer(selected_text: &str, amount: i64) -> Option<String> {\n    integer::increment(selected_text, amount)\n}\n\npub fn date_time(selected_text: &str, amount: i64) -> Option<String> {\n    date_time::increment(selected_text, amount)\n}\n"
  },
  {
    "path": "helix-core/src/indent.rs",
    "content": "use std::{borrow::Cow, collections::HashMap};\n\nuse helix_stdx::rope::RopeSliceExt;\nuse tree_house::TREE_SITTER_MATCH_LIMIT;\n\nuse crate::{\n    chars::{char_is_line_ending, char_is_whitespace},\n    graphemes::{grapheme_width, tab_width_at},\n    syntax::{self, config::IndentationHeuristic},\n    tree_sitter::{\n        self,\n        query::{InvalidPredicateError, UserPredicate},\n        Capture, Grammar, InactiveQueryCursor, Node, Pattern, Query, QueryMatch, RopeInput,\n    },\n    Position, Rope, RopeSlice, Syntax, Tendril,\n};\n\n/// Enum representing indentation style.\n///\n/// Only values 1-8 are valid for the `Spaces` variant.\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub enum IndentStyle {\n    Tabs,\n    Spaces(u8),\n}\n\n// 16 spaces\nconst INDENTS: &str = \"                \";\npub const MAX_INDENT: u8 = 16;\n\nimpl IndentStyle {\n    /// Creates an `IndentStyle` from an indentation string.\n    ///\n    /// For example, passing `\"    \"` (four spaces) will create `IndentStyle::Spaces(4)`.\n    #[allow(clippy::should_implement_trait)]\n    #[inline]\n    pub fn from_str(indent: &str) -> Self {\n        // XXX: do we care about validating the input more than this?  Probably not...?\n        debug_assert!(!indent.is_empty() && indent.len() <= MAX_INDENT as usize);\n\n        if indent.starts_with(' ') {\n            IndentStyle::Spaces(indent.len().clamp(1, MAX_INDENT as usize) as u8)\n        } else {\n            IndentStyle::Tabs\n        }\n    }\n\n    #[inline]\n    pub fn as_str(&self) -> &'static str {\n        match *self {\n            IndentStyle::Tabs => \"\\t\",\n            IndentStyle::Spaces(n) => {\n                // Unsupported indentation style.  This should never happen,\n                debug_assert!(n > 0 && n <= MAX_INDENT);\n\n                // Either way, clamp to the nearest supported value\n                let closest_n = n.clamp(1, MAX_INDENT) as usize;\n                &INDENTS[0..closest_n]\n            }\n        }\n    }\n\n    #[inline]\n    pub fn indent_width(&self, tab_width: usize) -> usize {\n        match *self {\n            IndentStyle::Tabs => tab_width,\n            IndentStyle::Spaces(width) => width as usize,\n        }\n    }\n}\n\n/// Attempts to detect the indentation style used in a document.\n///\n/// Returns the indentation style if the auto-detect confidence is\n/// reasonably high, otherwise returns `None`.\npub fn auto_detect_indent_style(document_text: &Rope) -> Option<IndentStyle> {\n    // Build a histogram of the indentation *increases* between\n    // subsequent lines, ignoring lines that are all whitespace.\n    //\n    // Index 0 is for tabs, the rest are 1-MAX_INDENT spaces.\n    let histogram: [usize; MAX_INDENT as usize + 1] = {\n        let mut histogram = [0; MAX_INDENT as usize + 1];\n        let mut prev_line_is_tabs = false;\n        let mut prev_line_leading_count = 0usize;\n\n        // Loop through the lines, checking for and recording indentation\n        // increases as we go.\n        'outer: for line in document_text.lines().take(1000) {\n            let mut c_iter = line.chars();\n\n            // Is first character a tab or space?\n            let is_tabs = match c_iter.next() {\n                Some('\\t') => true,\n                Some(' ') => false,\n\n                // Ignore blank lines.\n                Some(c) if char_is_line_ending(c) => continue,\n\n                _ => {\n                    prev_line_is_tabs = false;\n                    prev_line_leading_count = 0;\n                    continue;\n                }\n            };\n\n            // Count the line's total leading tab/space characters.\n            let mut leading_count = 1;\n            let mut count_is_done = false;\n            for c in c_iter {\n                match c {\n                    '\\t' if is_tabs && !count_is_done => leading_count += 1,\n                    ' ' if !is_tabs && !count_is_done => leading_count += 1,\n\n                    // We stop counting if we hit whitespace that doesn't\n                    // qualify as indent or doesn't match the leading\n                    // whitespace, but we don't exit the loop yet because\n                    // we still want to determine if the line is blank.\n                    c if char_is_whitespace(c) => count_is_done = true,\n\n                    // Ignore blank lines.\n                    c if char_is_line_ending(c) => continue 'outer,\n\n                    _ => break,\n                }\n\n                // Bound the worst-case execution time for weird text files.\n                if leading_count > 256 {\n                    continue 'outer;\n                }\n            }\n\n            // If there was an increase in indentation over the previous\n            // line, update the histogram with that increase.\n            if (prev_line_is_tabs == is_tabs || prev_line_leading_count == 0)\n                && prev_line_leading_count < leading_count\n            {\n                if is_tabs {\n                    histogram[0] += 1;\n                } else {\n                    let amount = leading_count - prev_line_leading_count;\n                    if amount <= MAX_INDENT as usize {\n                        histogram[amount] += 1;\n                    }\n                }\n            }\n\n            // Store this line's leading whitespace info for use with\n            // the next line.\n            prev_line_is_tabs = is_tabs;\n            prev_line_leading_count = leading_count;\n        }\n\n        // Give more weight to tabs, because their presence is a very\n        // strong indicator.\n        histogram[0] *= 2;\n        // Gives less weight to single indent, as single spaces are\n        // often used in certain languages' comment systems and rarely\n        // used as the actual document indentation.\n        if histogram[1] > 1 {\n            histogram[1] /= 2;\n        }\n\n        histogram\n    };\n\n    // Find the most frequent indent, its frequency, and the frequency of\n    // the next-most frequent indent.\n    let indent = histogram\n        .iter()\n        .enumerate()\n        .max_by_key(|kv| kv.1)\n        .unwrap()\n        .0;\n    let indent_freq = histogram[indent];\n    let indent_freq_2 = *histogram\n        .iter()\n        .enumerate()\n        .filter(|kv| kv.0 != indent)\n        .map(|kv| kv.1)\n        .max()\n        .unwrap();\n\n    // Return the the auto-detected result if we're confident enough in its\n    // accuracy, based on some heuristics.\n    if indent_freq >= 1 && (indent_freq_2 as f64 / indent_freq as f64) < 0.66 {\n        Some(match indent {\n            0 => IndentStyle::Tabs,\n            _ => IndentStyle::Spaces(indent as u8),\n        })\n    } else {\n        None\n    }\n}\n\n/// To determine indentation of a newly inserted line, figure out the indentation at the last col\n/// of the previous line.\npub fn indent_level_for_line(line: RopeSlice, tab_width: usize, indent_width: usize) -> usize {\n    let mut len = 0;\n    for ch in line.chars() {\n        match ch {\n            '\\t' => len += tab_width_at(len, tab_width as u16),\n            ' ' => len += 1,\n            _ => break,\n        }\n    }\n\n    len / indent_width\n}\n\n/// Create a string of tabs & spaces that has the same visual width as the given RopeSlice (independent of the tab width).\nfn whitespace_with_same_width(text: RopeSlice) -> String {\n    let mut s = String::new();\n    for grapheme in text.graphemes() {\n        if grapheme == \"\\t\" {\n            s.push('\\t');\n        } else {\n            s.extend(std::iter::repeat_n(\n                ' ',\n                grapheme_width(&Cow::from(grapheme)),\n            ));\n        }\n    }\n    s\n}\n\n/// normalizes indentation to tabs/spaces based on user configuration\n/// This function does not change the actual indentation width, just the character\n/// composition.\npub fn normalize_indentation(\n    prefix: RopeSlice<'_>,\n    line: RopeSlice<'_>,\n    dst: &mut Tendril,\n    indent_style: IndentStyle,\n    tab_width: usize,\n) -> usize {\n    #[allow(deprecated)]\n    let off = crate::visual_coords_at_pos(prefix, prefix.len_chars(), tab_width).col;\n    let mut len = 0;\n    let mut original_len = 0;\n    for ch in line.chars() {\n        match ch {\n            '\\t' => len += tab_width_at(len + off, tab_width as u16),\n            ' ' => len += 1,\n            _ => break,\n        }\n        original_len += 1;\n    }\n    if indent_style == IndentStyle::Tabs {\n        dst.extend(std::iter::repeat_n('\\t', len / tab_width));\n        len %= tab_width;\n    }\n    dst.extend(std::iter::repeat_n(' ', len));\n    original_len\n}\n\nfn add_indent_level(\n    mut base_indent: String,\n    added_indent_level: isize,\n    indent_style: &IndentStyle,\n    tab_width: usize,\n) -> String {\n    if added_indent_level >= 0 {\n        // Adding a non-negative indent is easy, we can simply append the indent string\n        base_indent.push_str(&indent_style.as_str().repeat(added_indent_level as usize));\n        base_indent\n    } else {\n        // In this case, we want to return a prefix of `base_indent`.\n        // Since the width of a tab depends on its offset, we cannot simply iterate over\n        // the chars of `base_indent` in reverse until we have the desired indent reduction,\n        // instead we iterate over them twice in forward direction.\n        let base_indent_rope = RopeSlice::from(base_indent.as_str());\n        #[allow(deprecated)]\n        let base_indent_width =\n            crate::visual_coords_at_pos(base_indent_rope, base_indent_rope.len_chars(), tab_width)\n                .col;\n        let target_indent_width = base_indent_width\n            .saturating_sub((-added_indent_level) as usize * indent_style.indent_width(tab_width));\n        #[allow(deprecated)]\n        let char_end_idx = crate::pos_at_visual_coords(\n            base_indent_rope,\n            Position {\n                row: 0,\n                col: target_indent_width,\n            },\n            tab_width,\n        );\n        let byte_end_idx = base_indent_rope.char_to_byte(char_end_idx);\n        base_indent.truncate(byte_end_idx);\n        base_indent\n    }\n}\n\n/// Return true if only whitespace comes before the node on its line.\n/// If given, new_line_byte_pos is treated the same way as any existing newline.\nfn is_first_in_line(node: &Node, text: RopeSlice, new_line_byte_pos: Option<u32>) -> bool {\n    let line = text.byte_to_line(node.start_byte() as usize);\n    let mut line_start_byte_pos = text.line_to_byte(line) as u32;\n    if let Some(pos) = new_line_byte_pos {\n        if line_start_byte_pos < pos && pos <= node.start_byte() {\n            line_start_byte_pos = pos;\n        }\n    }\n    text.byte_slice(line_start_byte_pos as usize..node.start_byte() as usize)\n        .chars()\n        .all(|c| c.is_whitespace())\n}\n\n#[derive(Debug, Default)]\npub struct IndentQueryPredicates {\n    not_kind_eq: Vec<(Capture, Box<str>)>,\n    same_line: Option<(Capture, Capture, bool)>,\n    one_line: Option<(Capture, bool)>,\n}\n\nimpl IndentQueryPredicates {\n    fn are_satisfied(\n        &self,\n        match_: &QueryMatch,\n        text: RopeSlice,\n        new_line_byte_pos: Option<u32>,\n    ) -> bool {\n        for (capture, not_expected_kind) in self.not_kind_eq.iter() {\n            let node = match_.nodes_for_capture(*capture).next();\n            if node.is_some_and(|n| n.kind() == not_expected_kind.as_ref()) {\n                return false;\n            }\n        }\n\n        if let Some((capture1, capture2, negated)) = self.same_line {\n            let n1 = match_.nodes_for_capture(capture1).next();\n            let n2 = match_.nodes_for_capture(capture2).next();\n            let satisfied = n1.zip(n2).is_some_and(|(n1, n2)| {\n                let n1_line = get_node_start_line(text, n1, new_line_byte_pos);\n                let n2_line = get_node_start_line(text, n2, new_line_byte_pos);\n                let same_line = n1_line == n2_line;\n                same_line != negated\n            });\n\n            if !satisfied {\n                return false;\n            }\n        }\n\n        if let Some((capture, negated)) = self.one_line {\n            let node = match_.nodes_for_capture(capture).next();\n            let satisfied = node.is_some_and(|node| {\n                let start_line = get_node_start_line(text, node, new_line_byte_pos);\n                let end_line = get_node_end_line(text, node, new_line_byte_pos);\n                let one_line = end_line == start_line;\n                one_line != negated\n            });\n\n            if !satisfied {\n                return false;\n            }\n        }\n\n        true\n    }\n}\n\n#[derive(Debug)]\npub struct IndentQuery {\n    query: Query,\n    properties: HashMap<Pattern, IndentScope>,\n    predicates: HashMap<Pattern, IndentQueryPredicates>,\n    indent_capture: Option<Capture>,\n    indent_always_capture: Option<Capture>,\n    outdent_capture: Option<Capture>,\n    outdent_always_capture: Option<Capture>,\n    align_capture: Option<Capture>,\n    anchor_capture: Option<Capture>,\n    extend_capture: Option<Capture>,\n    extend_prevent_once_capture: Option<Capture>,\n}\n\nimpl IndentQuery {\n    pub fn new(grammar: Grammar, source: &str) -> Result<Self, tree_sitter::query::ParseError> {\n        let mut properties = HashMap::new();\n        let mut predicates: HashMap<Pattern, IndentQueryPredicates> = HashMap::new();\n        let query = Query::new(grammar, source, |pattern, predicate| match predicate {\n            UserPredicate::SetProperty { key: \"scope\", val } => {\n                let scope = match val {\n                    Some(\"all\") => IndentScope::All,\n                    Some(\"tail\") => IndentScope::Tail,\n                    Some(other) => {\n                        return Err(format!(\"unknown scope (#set! scope \\\"{other}\\\")\").into())\n                    }\n                    None => return Err(\"missing scope value (#set! scope ...)\".into()),\n                };\n\n                properties.insert(pattern, scope);\n\n                Ok(())\n            }\n            UserPredicate::Other(predicate) => {\n                let name = predicate.name();\n                match name {\n                    \"not-kind-eq?\" => {\n                        predicate.check_arg_count(2)?;\n                        let capture = predicate.capture_arg(0)?;\n                        let not_expected_kind = predicate.str_arg(1)?;\n\n                        predicates\n                            .entry(pattern)\n                            .or_default()\n                            .not_kind_eq\n                            .push((capture, not_expected_kind.into()));\n                        Ok(())\n                    }\n                    \"same-line?\" | \"not-same-line?\" => {\n                        predicate.check_arg_count(2)?;\n                        let capture1 = predicate.capture_arg(0)?;\n                        let capture2 = predicate.capture_arg(1)?;\n                        let negated = name == \"not-same-line?\";\n\n                        predicates.entry(pattern).or_default().same_line =\n                            Some((capture1, capture2, negated));\n                        Ok(())\n                    }\n                    \"one-line?\" | \"not-one-line?\" => {\n                        predicate.check_arg_count(1)?;\n                        let capture = predicate.capture_arg(0)?;\n                        let negated = name == \"not-one-line?\";\n\n                        predicates.entry(pattern).or_default().one_line = Some((capture, negated));\n                        Ok(())\n                    }\n                    _ => Err(InvalidPredicateError::unknown(UserPredicate::Other(\n                        predicate,\n                    ))),\n                }\n            }\n            _ => Err(InvalidPredicateError::unknown(predicate)),\n        })?;\n\n        Ok(Self {\n            properties,\n            predicates,\n            indent_capture: query.get_capture(\"indent\"),\n            indent_always_capture: query.get_capture(\"indent.always\"),\n            outdent_capture: query.get_capture(\"outdent\"),\n            outdent_always_capture: query.get_capture(\"outdent.always\"),\n            align_capture: query.get_capture(\"align\"),\n            anchor_capture: query.get_capture(\"anchor\"),\n            extend_capture: query.get_capture(\"extend\"),\n            extend_prevent_once_capture: query.get_capture(\"extend.prevent-once\"),\n            query,\n        })\n    }\n}\n\n/// The total indent for some line of code.\n/// This is usually constructed in one of 2 ways:\n/// - Successively add indent captures to get the (added) indent from a single line\n/// - Successively add the indent results for each line\n///   The string that this indentation defines starts with the string contained in the align field (unless it is None), followed by:\n/// - max(0, indent - outdent) tabs, if tabs are used for indentation\n/// - max(0, indent - outdent)*indent_width spaces, if spaces are used for indentation\n#[derive(Default, Debug, PartialEq, Eq, Clone)]\npub struct Indentation<'a> {\n    indent: usize,\n    indent_always: usize,\n    outdent: usize,\n    outdent_always: usize,\n    /// The alignment, as a string containing only tabs & spaces. Storing this as a string instead of e.g.\n    /// the (visual) width ensures that the alignment is preserved even if the tab width changes.\n    align: Option<RopeSlice<'a>>,\n}\n\nimpl<'a> Indentation<'a> {\n    /// Add some other [Indentation] to this.\n    /// The added indent should be the total added indent from one line.\n    /// Indent should always be added starting from the bottom (or equivalently, the innermost tree-sitter node).\n    fn add_line(&mut self, added: Indentation<'a>) {\n        // Align overrides the indent from outer scopes.\n        if self.align.is_some() {\n            return;\n        }\n        if added.align.is_some() {\n            self.align = added.align;\n            return;\n        }\n        self.indent += added.indent;\n        self.indent_always += added.indent_always;\n        self.outdent += added.outdent;\n        self.outdent_always += added.outdent_always;\n    }\n\n    /// Add an indent capture to this indent.\n    /// Only captures that apply to the same line should be added together in this way (otherwise use `add_line`)\n    /// and the captures should be added starting from the innermost tree-sitter node (currently this only matters\n    /// if multiple `@align` patterns occur on the same line).\n    fn add_capture(&mut self, added: IndentCaptureType<'a>) {\n        match added {\n            IndentCaptureType::Indent => {\n                if self.indent_always == 0 {\n                    self.indent = 1;\n                }\n            }\n            IndentCaptureType::IndentAlways => {\n                // any time we encounter an `indent.always` on the same line, we\n                // want to cancel out all regular indents\n                self.indent_always += 1;\n                self.indent = 0;\n            }\n            IndentCaptureType::Outdent => {\n                if self.outdent_always == 0 {\n                    self.outdent = 1;\n                }\n            }\n            IndentCaptureType::OutdentAlways => {\n                self.outdent_always += 1;\n                self.outdent = 0;\n            }\n            IndentCaptureType::Align(align) => {\n                if self.align.is_none() {\n                    self.align = Some(align);\n                }\n            }\n        }\n    }\n    fn net_indent(&self) -> isize {\n        (self.indent + self.indent_always) as isize\n            - ((self.outdent + self.outdent_always) as isize)\n    }\n    /// Convert `self` into a string, taking into account the computed and actual indentation of some other line.\n    fn relative_indent(\n        &self,\n        other_computed_indent: &Self,\n        other_leading_whitespace: RopeSlice,\n        indent_style: &IndentStyle,\n        tab_width: usize,\n    ) -> Option<String> {\n        if self.align == other_computed_indent.align {\n            // If self and baseline are either not aligned to anything or both aligned the same way,\n            // we can simply take `other_leading_whitespace` and add some indent / outdent to it (in the second\n            // case, the alignment should already be accounted for in `other_leading_whitespace`).\n            let indent_diff = self.net_indent() - other_computed_indent.net_indent();\n            Some(add_indent_level(\n                String::from(other_leading_whitespace),\n                indent_diff,\n                indent_style,\n                tab_width,\n            ))\n        } else {\n            // If the alignment of both lines is different, we cannot compare their indentation in any meaningful way\n            None\n        }\n    }\n    pub fn to_string(&self, indent_style: &IndentStyle, tab_width: usize) -> String {\n        add_indent_level(\n            self.align\n                .map_or_else(String::new, whitespace_with_same_width),\n            self.net_indent(),\n            indent_style,\n            tab_width,\n        )\n    }\n}\n\n/// An indent definition which corresponds to a capture from the indent query\n#[derive(Debug)]\nstruct IndentCapture<'a> {\n    capture_type: IndentCaptureType<'a>,\n    scope: IndentScope,\n}\n#[derive(Debug, Clone, PartialEq)]\nenum IndentCaptureType<'a> {\n    Indent,\n    IndentAlways,\n    Outdent,\n    OutdentAlways,\n    /// Alignment given as a string of whitespace\n    Align(RopeSlice<'a>),\n}\n\nimpl IndentCaptureType<'_> {\n    fn default_scope(&self) -> IndentScope {\n        match self {\n            IndentCaptureType::Indent | IndentCaptureType::IndentAlways => IndentScope::Tail,\n            IndentCaptureType::Outdent | IndentCaptureType::OutdentAlways => IndentScope::All,\n            IndentCaptureType::Align(_) => IndentScope::All,\n        }\n    }\n}\n/// This defines which part of a node an [IndentCapture] applies to.\n/// Each [IndentCaptureType] has a default scope, but the scope can be changed\n/// with `#set!` property declarations.\n#[derive(Debug, Clone, Copy)]\nenum IndentScope {\n    /// The indent applies to the whole node\n    All,\n    /// The indent applies to everything except for the first line of the node\n    Tail,\n}\n\n/// A capture from the indent query which does not define an indent but extends\n/// the range of a node. This is used before the indent is calculated.\n#[derive(Debug)]\nenum ExtendCapture {\n    Extend,\n    PreventOnce,\n}\n\n/// The result of running a tree-sitter indent query. This stores for\n/// each node (identified by its ID) the relevant captures (already filtered\n/// by predicates).\n#[derive(Debug)]\nstruct IndentQueryResult<'a> {\n    indent_captures: HashMap<usize, Vec<IndentCapture<'a>>>,\n    extend_captures: HashMap<usize, Vec<ExtendCapture>>,\n}\n\nfn get_node_start_line(text: RopeSlice, node: &Node, new_line_byte_pos: Option<u32>) -> usize {\n    let mut node_line = text.byte_to_line(node.start_byte() as usize);\n    // Adjust for the new line that will be inserted\n    if new_line_byte_pos.is_some_and(|pos| node.start_byte() >= pos) {\n        node_line += 1;\n    }\n    node_line\n}\nfn get_node_end_line(text: RopeSlice, node: &Node, new_line_byte_pos: Option<u32>) -> usize {\n    let mut node_line = text.byte_to_line(node.end_byte() as usize);\n    // Adjust for the new line that will be inserted (with a strict inequality since end_byte is exclusive)\n    if new_line_byte_pos.is_some_and(|pos| node.end_byte() > pos) {\n        node_line += 1;\n    }\n    node_line\n}\n\nfn query_indents<'a>(\n    query: &IndentQuery,\n    syntax: &Syntax,\n    text: RopeSlice<'a>,\n    range: std::ops::Range<u32>,\n    new_line_byte_pos: Option<u32>,\n) -> IndentQueryResult<'a> {\n    let mut indent_captures: HashMap<usize, Vec<IndentCapture>> = HashMap::new();\n    let mut extend_captures: HashMap<usize, Vec<ExtendCapture>> = HashMap::new();\n\n    let mut cursor = InactiveQueryCursor::new(range, TREE_SITTER_MATCH_LIMIT).execute_query(\n        &query.query,\n        &syntax.tree().root_node(),\n        RopeInput::new(text),\n    );\n\n    // Iterate over all captures from the query\n    while let Some(m) = cursor.next_match() {\n        // Skip matches where not all custom predicates are fulfilled\n        if query\n            .predicates\n            .get(&m.pattern())\n            .is_some_and(|preds| !preds.are_satisfied(&m, text, new_line_byte_pos))\n        {\n            continue;\n        }\n        // A list of pairs (node_id, indent_capture) that are added by this match.\n        // They cannot be added to indent_captures immediately since they may depend on other captures (such as an @anchor).\n        let mut added_indent_captures: Vec<(usize, IndentCapture)> = Vec::new();\n        // The row/column position of the optional anchor in this query\n        let mut anchor: Option<&Node> = None;\n        for matched_node in m.matched_nodes() {\n            let node_id = matched_node.node.id();\n            let capture = Some(matched_node.capture);\n            let capture_type = if capture == query.indent_capture {\n                IndentCaptureType::Indent\n            } else if capture == query.indent_always_capture {\n                IndentCaptureType::IndentAlways\n            } else if capture == query.outdent_capture {\n                IndentCaptureType::Outdent\n            } else if capture == query.outdent_always_capture {\n                IndentCaptureType::OutdentAlways\n            } else if capture == query.align_capture {\n                IndentCaptureType::Align(RopeSlice::from(\"\"))\n            } else if capture == query.anchor_capture {\n                if anchor.is_some() {\n                    log::error!(\"Invalid indent query: Encountered more than one @anchor in the same match.\")\n                } else {\n                    anchor = Some(&matched_node.node);\n                }\n                continue;\n            } else if capture == query.extend_capture {\n                extend_captures\n                    .entry(node_id)\n                    .or_insert_with(|| Vec::with_capacity(1))\n                    .push(ExtendCapture::Extend);\n                continue;\n            } else if capture == query.extend_prevent_once_capture {\n                extend_captures\n                    .entry(node_id)\n                    .or_insert_with(|| Vec::with_capacity(1))\n                    .push(ExtendCapture::PreventOnce);\n                continue;\n            } else {\n                // Ignore any unknown captures (these may be needed for predicates such as #match?)\n                continue;\n            };\n\n            // Apply additional settings for this capture\n            let scope = query\n                .properties\n                .get(&m.pattern())\n                .copied()\n                .unwrap_or_else(|| capture_type.default_scope());\n            let indent_capture = IndentCapture {\n                capture_type,\n                scope,\n            };\n            added_indent_captures.push((node_id, indent_capture))\n        }\n        for (node_id, mut capture) in added_indent_captures {\n            // Set the anchor for all align queries.\n            if let IndentCaptureType::Align(_) = capture.capture_type {\n                let Some(anchor) = anchor else {\n                    log::error!(\"Invalid indent query: @align requires an accompanying @anchor.\");\n                    continue;\n                };\n                let line = text.byte_to_line(anchor.start_byte() as usize);\n                let line_start = text.line_to_byte(line);\n                capture.capture_type = IndentCaptureType::Align(\n                    text.byte_slice(line_start..anchor.start_byte() as usize),\n                );\n            }\n            indent_captures\n                .entry(node_id)\n                .or_insert_with(|| Vec::with_capacity(1))\n                .push(capture);\n        }\n    }\n\n    let result = IndentQueryResult {\n        indent_captures,\n        extend_captures,\n    };\n\n    log::trace!(\"indent result = {:?}\", result);\n\n    result\n}\n\n/// Handle extend queries. deepest_preceding is the deepest descendant of node that directly precedes the cursor position.\n/// Any ancestor of deepest_preceding which is also a descendant of node may be \"extended\". In that case, node will be updated,\n/// so that the indent computation starts with the correct syntax node.\nfn extend_nodes<'a>(\n    node: &mut Node<'a>,\n    mut deepest_preceding: Node<'a>,\n    extend_captures: &HashMap<usize, Vec<ExtendCapture>>,\n    text: RopeSlice,\n    line: usize,\n    tab_width: usize,\n    indent_width: usize,\n) {\n    let mut stop_extend = false;\n\n    while deepest_preceding != *node {\n        let mut extend_node = false;\n        // This will be set to true if this node is captured, regardless of whether\n        // it actually will be extended (e.g. because the cursor isn't indented\n        // more than the node).\n        let mut node_captured = false;\n        if let Some(captures) = extend_captures.get(&deepest_preceding.id()) {\n            for capture in captures {\n                match capture {\n                    ExtendCapture::PreventOnce => {\n                        stop_extend = true;\n                    }\n                    ExtendCapture::Extend => {\n                        node_captured = true;\n                        // We extend the node if\n                        // - the cursor is on the same line as the end of the node OR\n                        // - the line that the cursor is on is more indented than the\n                        //   first line of the node\n                        if text.byte_to_line(deepest_preceding.end_byte() as usize) == line {\n                            extend_node = true;\n                        } else {\n                            let cursor_indent =\n                                indent_level_for_line(text.line(line), tab_width, indent_width);\n                            let node_indent = indent_level_for_line(\n                                text.line(\n                                    text.byte_to_line(deepest_preceding.start_byte() as usize),\n                                ),\n                                tab_width,\n                                indent_width,\n                            );\n                            if cursor_indent > node_indent {\n                                extend_node = true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        // If we encountered some `StopExtend` capture before, we don't\n        // extend the node even if we otherwise would\n        if node_captured && stop_extend {\n            stop_extend = false;\n        } else if extend_node && !stop_extend {\n            *node = deepest_preceding.clone();\n            break;\n        }\n        // If the tree contains a syntax error, `deepest_preceding` may not\n        // have a parent despite being a descendant of `node`.\n        deepest_preceding = match deepest_preceding.parent() {\n            Some(parent) => parent,\n            None => return,\n        }\n    }\n}\n\n/// Prepare an indent query by computing:\n/// - The node from which to start the query (this is non-trivial due to `@extend` captures)\n/// - The indent captures for all relevant nodes.\n#[allow(clippy::too_many_arguments)]\nfn init_indent_query<'a, 'b>(\n    query: &IndentQuery,\n    syntax: &'a Syntax,\n    text: RopeSlice<'b>,\n    tab_width: usize,\n    indent_width: usize,\n    line: usize,\n    byte_pos: u32,\n    new_line_byte_pos: Option<u32>,\n) -> Option<(Node<'a>, HashMap<usize, Vec<IndentCapture<'b>>>)> {\n    // The innermost tree-sitter node which is considered for the indent\n    // computation. It may change if some preceding node is extended\n    let mut node = syntax\n        .tree()\n        .root_node()\n        .descendant_for_byte_range(byte_pos, byte_pos)?;\n\n    let (query_result, deepest_preceding) = {\n        // The query range should intersect with all nodes directly preceding\n        // the position of the indent query in case one of them is extended.\n        let mut deepest_preceding = None; // The deepest node preceding the indent query position\n        for child in node.children() {\n            if child.byte_range().end <= byte_pos {\n                deepest_preceding = Some(child.clone());\n            }\n        }\n        deepest_preceding = deepest_preceding.map(|mut prec| {\n            // Get the deepest directly preceding node\n            while prec.child_count() > 0 {\n                prec = prec.child(prec.child_count() - 1).unwrap().clone();\n            }\n            prec\n        });\n        let query_range = deepest_preceding\n            .as_ref()\n            .map(|prec| prec.byte_range().end - 1..byte_pos + 1)\n            .unwrap_or(byte_pos..byte_pos + 1);\n\n        let query_result = query_indents(query, syntax, text, query_range, new_line_byte_pos);\n        (query_result, deepest_preceding)\n    };\n    let extend_captures = query_result.extend_captures;\n\n    // Check for extend captures, potentially changing the node that the indent calculation starts with\n    if let Some(deepest_preceding) = deepest_preceding {\n        extend_nodes(\n            &mut node,\n            deepest_preceding,\n            &extend_captures,\n            text,\n            line,\n            tab_width,\n            indent_width,\n        );\n    }\n    Some((node, query_result.indent_captures))\n}\n\n/// Use the syntax tree to determine the indentation for a given position.\n/// This can be used in 2 ways:\n///\n/// - To get the correct indentation for an existing line (new_line=false), not necessarily equal to the current indentation.\n///   - In this case, pos should be inside the first tree-sitter node on that line.\n///     In most cases, this can just be the first non-whitespace on that line.\n///   - To get the indentation for a new line (new_line=true). This behaves like the first usecase if the part of the current line\n///     after pos were moved to a new line.\n///\n/// The indentation is determined by traversing all the tree-sitter nodes containing the position.\n/// Each of these nodes produces some [Indentation] for:\n///\n/// - The line of the (beginning of the) node. This is defined by the scope `all` if this is the first node on its line.\n/// - The line after the node. This is defined by:\n///   - The scope `tail`.\n///   - The scope `all` if this node is not the first node on its line.\n///\n/// Intuitively, `all` applies to everything contained in this node while `tail` applies to everything except for the first line of the node.\n/// The indents from different nodes for the same line are then combined.\n/// The result [Indentation] is simply the sum of the [Indentation] for all lines.\n///\n/// Specifying which line exactly an [Indentation] applies to is important because indents on the same line combine differently than indents on different lines:\n/// ```ignore\n/// some_function(|| {\n///     // Both the function parameters as well as the contained block should be indented.\n///     // Because they are on the same line, this only yields one indent level\n/// });\n/// ```\n///\n/// ```ignore\n/// some_function(\n///     param1,\n///     || {\n///         // Here we get 2 indent levels because the 'parameters' and the 'block' node begin on different lines\n///     },\n/// );\n/// ```\n#[allow(clippy::too_many_arguments)]\npub fn treesitter_indent_for_pos<'a>(\n    query: &IndentQuery,\n    syntax: &Syntax,\n    tab_width: usize,\n    indent_width: usize,\n    text: RopeSlice<'a>,\n    line: usize,\n    pos: usize,\n    new_line: bool,\n) -> Option<Indentation<'a>> {\n    let byte_pos = text.char_to_byte(pos) as u32;\n    let new_line_byte_pos = new_line.then_some(byte_pos);\n    let (mut node, mut indent_captures) = init_indent_query(\n        query,\n        syntax,\n        text,\n        tab_width,\n        indent_width,\n        line,\n        byte_pos,\n        new_line_byte_pos,\n    )?;\n\n    let mut result = Indentation::default();\n    // We always keep track of all the indent changes on one line, in order to only indent once\n    // even if there are multiple \"indent\" nodes on the same line\n    let mut indent_for_line = Indentation::default();\n    let mut indent_for_line_below = Indentation::default();\n\n    loop {\n        let is_first = is_first_in_line(&node, text, new_line_byte_pos);\n\n        // Apply all indent definitions for this node.\n        // Since we only iterate over each node once, we can remove the\n        // corresponding captures from the HashMap to avoid cloning them.\n        if let Some(definitions) = indent_captures.remove(&node.id()) {\n            for definition in definitions {\n                match definition.scope {\n                    IndentScope::All => {\n                        if is_first {\n                            indent_for_line.add_capture(definition.capture_type);\n                        } else {\n                            indent_for_line_below.add_capture(definition.capture_type);\n                        }\n                    }\n                    IndentScope::Tail => {\n                        indent_for_line_below.add_capture(definition.capture_type);\n                    }\n                }\n            }\n        }\n\n        if let Some(parent) = node.parent() {\n            let node_line = get_node_start_line(text, &node, new_line_byte_pos);\n            let parent_line = get_node_start_line(text, &parent, new_line_byte_pos);\n\n            if node_line != parent_line {\n                // Don't add indent for the line below the line of the query\n                if node_line < line + (new_line as usize) {\n                    result.add_line(indent_for_line_below);\n                }\n\n                if node_line == parent_line + 1 {\n                    indent_for_line_below = indent_for_line;\n                } else {\n                    result.add_line(indent_for_line);\n                    indent_for_line_below = Indentation::default();\n                }\n\n                indent_for_line = Indentation::default();\n            }\n\n            node = parent;\n        } else {\n            // Only add the indentation for the line below if that line\n            // is not after the line that the indentation is calculated for.\n            let node_start_line = text.byte_to_line(node.start_byte() as usize);\n            if node_start_line < line\n                || (new_line && node_start_line == line && node.start_byte() < byte_pos)\n            {\n                result.add_line(indent_for_line_below);\n            }\n            result.add_line(indent_for_line);\n            break;\n        }\n    }\n    Some(result)\n}\n\n/// Returns the indentation for a new line.\n/// This is done either using treesitter, or if that's not available by copying the indentation from the current line\n#[allow(clippy::too_many_arguments)]\npub fn indent_for_newline(\n    loader: &syntax::Loader,\n    syntax: Option<&Syntax>,\n    indent_heuristic: &IndentationHeuristic,\n    indent_style: &IndentStyle,\n    tab_width: usize,\n    text: RopeSlice,\n    line_before: usize,\n    line_before_end_pos: usize,\n    current_line: usize,\n) -> String {\n    let indent_width = indent_style.indent_width(tab_width);\n    if let (\n        IndentationHeuristic::TreeSitter | IndentationHeuristic::Hybrid,\n        Some(query),\n        Some(syntax),\n    ) = (\n        indent_heuristic,\n        syntax.and_then(|syntax| loader.indent_query(syntax.root_language())),\n        syntax,\n    ) {\n        if let Some(indent) = treesitter_indent_for_pos(\n            query,\n            syntax,\n            tab_width,\n            indent_width,\n            text,\n            line_before,\n            line_before_end_pos,\n            true,\n        ) {\n            if *indent_heuristic == IndentationHeuristic::Hybrid {\n                // We want to compute the indentation not only based on the\n                // syntax tree but also on the actual indentation of a previous\n                // line. This makes indentation computation more resilient to\n                // incomplete queries, incomplete source code & differing indentation\n                // styles for the same language.\n                // However, using the indent of a previous line as a baseline may not\n                // make sense, e.g. if it has a different alignment than the new line.\n                // In order to prevent edge cases with long running times, we only try\n                // a constant number of (non-empty) lines.\n                const MAX_ATTEMPTS: usize = 4;\n                let mut num_attempts = 0;\n                for line_idx in (0..=line_before).rev() {\n                    let line = text.line(line_idx);\n                    let first_non_whitespace_char = match line.first_non_whitespace_char() {\n                        Some(i) => i,\n                        None => {\n                            continue;\n                        }\n                    };\n                    if let Some(indent) = (|| {\n                        let computed_indent = treesitter_indent_for_pos(\n                            query,\n                            syntax,\n                            tab_width,\n                            indent_width,\n                            text,\n                            line_idx,\n                            text.line_to_char(line_idx) + first_non_whitespace_char,\n                            false,\n                        )?;\n                        let leading_whitespace = line.slice(0..first_non_whitespace_char);\n                        indent.relative_indent(\n                            &computed_indent,\n                            leading_whitespace,\n                            indent_style,\n                            tab_width,\n                        )\n                    })() {\n                        return indent;\n                    }\n                    num_attempts += 1;\n                    if num_attempts == MAX_ATTEMPTS {\n                        break;\n                    }\n                }\n            }\n            return indent.to_string(indent_style, tab_width);\n        };\n    }\n    // Fallback in case we either don't have indent queries or they failed for some reason\n    let indent_level = indent_level_for_line(text.line(current_line), tab_width, indent_width);\n    indent_style.as_str().repeat(indent_level)\n}\n\npub fn get_scopes<'a>(syntax: Option<&'a Syntax>, text: RopeSlice, pos: usize) -> Vec<&'a str> {\n    let mut scopes = Vec::new();\n    if let Some(syntax) = syntax {\n        let pos = text.char_to_byte(pos) as u32;\n        let mut node = match syntax\n            .tree()\n            .root_node()\n            .descendant_for_byte_range(pos, pos)\n        {\n            Some(node) => node,\n            None => return scopes,\n        };\n\n        scopes.push(node.kind());\n\n        while let Some(parent) = node.parent() {\n            scopes.push(parent.kind());\n            node = parent;\n        }\n    }\n\n    scopes.reverse();\n    scopes\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::Rope;\n\n    #[test]\n    fn test_indent_level() {\n        let tab_width = 4;\n        let indent_width = 4;\n        let line = Rope::from(\"        fn new\"); // 8 spaces\n        assert_eq!(\n            indent_level_for_line(line.slice(..), tab_width, indent_width),\n            2\n        );\n        let line = Rope::from(\"\\t\\t\\tfn new\"); // 3 tabs\n        assert_eq!(\n            indent_level_for_line(line.slice(..), tab_width, indent_width),\n            3\n        );\n        // mixed indentation\n        let line = Rope::from(\"\\t    \\tfn new\"); // 1 tab, 4 spaces, tab\n        assert_eq!(\n            indent_level_for_line(line.slice(..), tab_width, indent_width),\n            3\n        );\n    }\n\n    #[test]\n    fn test_large_indent_level() {\n        let tab_width = 16;\n        let indent_width = 16;\n        let line = Rope::from(\"                fn new\"); // 16 spaces\n        assert_eq!(\n            indent_level_for_line(line.slice(..), tab_width, indent_width),\n            1\n        );\n        let line = Rope::from(\"                                fn new\"); // 32 spaces\n        assert_eq!(\n            indent_level_for_line(line.slice(..), tab_width, indent_width),\n            2\n        );\n    }\n\n    #[test]\n    fn add_capture() {\n        let indent = || Indentation {\n            indent: 1,\n            ..Default::default()\n        };\n        let indent_always = || Indentation {\n            indent_always: 1,\n            ..Default::default()\n        };\n        let outdent = || Indentation {\n            outdent: 1,\n            ..Default::default()\n        };\n        let outdent_always = || Indentation {\n            outdent_always: 1,\n            ..Default::default()\n        };\n\n        fn add_capture<'a>(\n            mut indent: Indentation<'a>,\n            capture: IndentCaptureType<'a>,\n        ) -> Indentation<'a> {\n            indent.add_capture(capture);\n            indent\n        }\n\n        // adding an indent to no indent makes an indent\n        assert_eq!(\n            indent(),\n            add_capture(Indentation::default(), IndentCaptureType::Indent)\n        );\n        assert_eq!(\n            indent_always(),\n            add_capture(Indentation::default(), IndentCaptureType::IndentAlways)\n        );\n        assert_eq!(\n            outdent(),\n            add_capture(Indentation::default(), IndentCaptureType::Outdent)\n        );\n        assert_eq!(\n            outdent_always(),\n            add_capture(Indentation::default(), IndentCaptureType::OutdentAlways)\n        );\n\n        // adding an indent to an already indented has no effect\n        assert_eq!(indent(), add_capture(indent(), IndentCaptureType::Indent));\n        assert_eq!(\n            outdent(),\n            add_capture(outdent(), IndentCaptureType::Outdent)\n        );\n\n        // adding an always to a regular makes it always\n        assert_eq!(\n            indent_always(),\n            add_capture(indent(), IndentCaptureType::IndentAlways)\n        );\n        assert_eq!(\n            outdent_always(),\n            add_capture(outdent(), IndentCaptureType::OutdentAlways)\n        );\n\n        // adding an always to an always is additive\n        assert_eq!(\n            Indentation {\n                indent_always: 2,\n                ..Default::default()\n            },\n            add_capture(indent_always(), IndentCaptureType::IndentAlways)\n        );\n        assert_eq!(\n            Indentation {\n                outdent_always: 2,\n                ..Default::default()\n            },\n            add_capture(outdent_always(), IndentCaptureType::OutdentAlways)\n        );\n\n        // adding regular to always should be associative\n        assert_eq!(\n            Indentation {\n                indent_always: 1,\n                ..Default::default()\n            },\n            add_capture(\n                add_capture(indent(), IndentCaptureType::Indent),\n                IndentCaptureType::IndentAlways\n            )\n        );\n        assert_eq!(\n            Indentation {\n                indent_always: 1,\n                ..Default::default()\n            },\n            add_capture(\n                add_capture(indent(), IndentCaptureType::IndentAlways),\n                IndentCaptureType::Indent\n            )\n        );\n        assert_eq!(\n            Indentation {\n                outdent_always: 1,\n                ..Default::default()\n            },\n            add_capture(\n                add_capture(outdent(), IndentCaptureType::Outdent),\n                IndentCaptureType::OutdentAlways\n            )\n        );\n        assert_eq!(\n            Indentation {\n                outdent_always: 1,\n                ..Default::default()\n            },\n            add_capture(\n                add_capture(outdent(), IndentCaptureType::OutdentAlways),\n                IndentCaptureType::Outdent\n            )\n        );\n    }\n\n    #[test]\n    fn test_relative_indent() {\n        let indent_style = IndentStyle::Spaces(4);\n        let tab_width: usize = 4;\n        let no_align = [\n            Indentation::default(),\n            Indentation {\n                indent: 1,\n                ..Default::default()\n            },\n            Indentation {\n                indent: 5,\n                outdent: 1,\n                ..Default::default()\n            },\n        ];\n        let align = no_align.clone().map(|indent| Indentation {\n            align: Some(RopeSlice::from(\"12345\")),\n            ..indent\n        });\n        let different_align = Indentation {\n            align: Some(RopeSlice::from(\"123456\")),\n            ..Default::default()\n        };\n\n        // Check that relative and absolute indentation computation are the same when the line we compare to is\n        // indented as we expect.\n        let check_consistency = |indent: &Indentation, other: &Indentation| {\n            assert_eq!(\n                indent.relative_indent(\n                    other,\n                    RopeSlice::from(other.to_string(&indent_style, tab_width).as_str()),\n                    &indent_style,\n                    tab_width\n                ),\n                Some(indent.to_string(&indent_style, tab_width))\n            );\n        };\n        for a in &no_align {\n            for b in &no_align {\n                check_consistency(a, b);\n            }\n        }\n        for a in &align {\n            for b in &align {\n                check_consistency(a, b);\n            }\n        }\n\n        // Relative indent computation makes no sense if the alignment differs\n        assert_eq!(\n            align[0].relative_indent(\n                &no_align[0],\n                RopeSlice::from(\"      \"),\n                &indent_style,\n                tab_width\n            ),\n            None\n        );\n        assert_eq!(\n            align[0].relative_indent(\n                &different_align,\n                RopeSlice::from(\"      \"),\n                &indent_style,\n                tab_width\n            ),\n            None\n        );\n    }\n}\n"
  },
  {
    "path": "helix-core/src/lib.rs",
    "content": "pub use encoding_rs as encoding;\n\npub mod auto_pairs;\npub mod case_conversion;\npub mod chars;\npub mod command_line;\npub mod comment;\npub mod completion;\npub mod config;\npub mod diagnostic;\npub mod diff;\npub mod doc_formatter;\npub mod editor_config;\npub mod fuzzy;\npub mod graphemes;\npub mod history;\npub mod increment;\npub mod indent;\npub mod line_ending;\npub mod macros;\npub mod match_brackets;\npub mod movement;\npub mod object;\nmod position;\npub mod search;\npub mod selection;\npub mod snippets;\npub mod surround;\npub mod syntax;\npub mod test;\npub mod text_annotations;\npub mod textobject;\nmod transaction;\npub mod uri;\npub mod wrap;\n\npub mod unicode {\n    pub use unicode_general_category as category;\n    pub use unicode_segmentation as segmentation;\n    pub use unicode_width as width;\n}\n\npub use helix_loader::find_workspace;\n\nmod rope_reader;\n\npub use rope_reader::RopeReader;\npub use ropey::{self, str_utils, Rope, RopeBuilder, RopeSlice};\n\n// pub use tendril::StrTendril as Tendril;\npub use smartstring::SmartString;\n\npub type Tendril = SmartString<smartstring::LazyCompact>;\n\n#[doc(inline)]\npub use {regex, tree_house::tree_sitter};\n\npub use position::{\n    char_idx_at_visual_offset, coords_at_pos, pos_at_coords, softwrapped_dimensions,\n    visual_offset_from_anchor, visual_offset_from_block, Position, VisualOffsetError,\n};\n#[allow(deprecated)]\npub use position::{pos_at_visual_coords, visual_coords_at_pos};\n\npub use selection::{Range, Selection};\npub use smallvec::{smallvec, SmallVec};\npub use syntax::Syntax;\n\npub use completion::CompletionItem;\npub use diagnostic::Diagnostic;\n\npub use line_ending::{LineEnding, NATIVE_LINE_ENDING};\npub use transaction::{Assoc, Change, ChangeSet, Deletion, Operation, Transaction};\n\npub use uri::Uri;\n\npub use tree_house::Language;\n"
  },
  {
    "path": "helix-core/src/line_ending.rs",
    "content": "use crate::{Rope, RopeSlice};\n\n#[cfg(target_os = \"windows\")]\npub const NATIVE_LINE_ENDING: LineEnding = LineEnding::Crlf;\n#[cfg(not(target_os = \"windows\"))]\npub const NATIVE_LINE_ENDING: LineEnding = LineEnding::LF;\n\n/// Represents one of the valid Unicode line endings.\n#[derive(PartialEq, Eq, Copy, Clone, Debug)]\npub enum LineEnding {\n    Crlf, // CarriageReturn followed by LineFeed\n    LF,   // U+000A -- LineFeed\n    #[cfg(feature = \"unicode-lines\")]\n    VT, // U+000B -- VerticalTab\n    #[cfg(feature = \"unicode-lines\")]\n    FF, // U+000C -- FormFeed\n    #[cfg(feature = \"unicode-lines\")]\n    CR, // U+000D -- CarriageReturn\n    #[cfg(feature = \"unicode-lines\")]\n    Nel, // U+0085 -- NextLine\n    #[cfg(feature = \"unicode-lines\")]\n    LS, // U+2028 -- Line Separator\n    #[cfg(feature = \"unicode-lines\")]\n    PS, // U+2029 -- ParagraphSeparator\n}\n\nimpl LineEnding {\n    #[inline]\n    pub const fn len_chars(&self) -> usize {\n        match self {\n            Self::Crlf => 2,\n            _ => 1,\n        }\n    }\n\n    #[inline]\n    pub const fn as_str(&self) -> &'static str {\n        match self {\n            Self::Crlf => \"\\u{000D}\\u{000A}\",\n            Self::LF => \"\\u{000A}\",\n            #[cfg(feature = \"unicode-lines\")]\n            Self::VT => \"\\u{000B}\",\n            #[cfg(feature = \"unicode-lines\")]\n            Self::FF => \"\\u{000C}\",\n            #[cfg(feature = \"unicode-lines\")]\n            Self::CR => \"\\u{000D}\",\n            #[cfg(feature = \"unicode-lines\")]\n            Self::Nel => \"\\u{0085}\",\n            #[cfg(feature = \"unicode-lines\")]\n            Self::LS => \"\\u{2028}\",\n            #[cfg(feature = \"unicode-lines\")]\n            Self::PS => \"\\u{2029}\",\n        }\n    }\n\n    #[inline]\n    pub const fn from_char(ch: char) -> Option<LineEnding> {\n        match ch {\n            '\\u{000A}' => Some(LineEnding::LF),\n            #[cfg(feature = \"unicode-lines\")]\n            '\\u{000B}' => Some(LineEnding::VT),\n            #[cfg(feature = \"unicode-lines\")]\n            '\\u{000C}' => Some(LineEnding::FF),\n            #[cfg(feature = \"unicode-lines\")]\n            '\\u{000D}' => Some(LineEnding::CR),\n            #[cfg(feature = \"unicode-lines\")]\n            '\\u{0085}' => Some(LineEnding::Nel),\n            #[cfg(feature = \"unicode-lines\")]\n            '\\u{2028}' => Some(LineEnding::LS),\n            #[cfg(feature = \"unicode-lines\")]\n            '\\u{2029}' => Some(LineEnding::PS),\n            // Not a line ending\n            _ => None,\n        }\n    }\n\n    // Normally we'd want to implement the FromStr trait, but in this case\n    // that would force us into a different return type than from_char or\n    // or from_rope_slice, which would be weird.\n    #[allow(clippy::should_implement_trait)]\n    #[inline]\n    pub fn from_str(g: &str) -> Option<LineEnding> {\n        match g {\n            \"\\u{000D}\\u{000A}\" => Some(LineEnding::Crlf),\n            \"\\u{000A}\" => Some(LineEnding::LF),\n            #[cfg(feature = \"unicode-lines\")]\n            \"\\u{000B}\" => Some(LineEnding::VT),\n            #[cfg(feature = \"unicode-lines\")]\n            \"\\u{000C}\" => Some(LineEnding::FF),\n            #[cfg(feature = \"unicode-lines\")]\n            \"\\u{000D}\" => Some(LineEnding::CR),\n            #[cfg(feature = \"unicode-lines\")]\n            \"\\u{0085}\" => Some(LineEnding::Nel),\n            #[cfg(feature = \"unicode-lines\")]\n            \"\\u{2028}\" => Some(LineEnding::LS),\n            #[cfg(feature = \"unicode-lines\")]\n            \"\\u{2029}\" => Some(LineEnding::PS),\n            // Not a line ending\n            _ => None,\n        }\n    }\n\n    #[inline]\n    pub fn from_rope_slice(g: &RopeSlice) -> Option<LineEnding> {\n        if let Some(text) = g.as_str() {\n            LineEnding::from_str(text)\n        } else {\n            // Non-contiguous, so it can't be a line ending.\n            // Specifically, Ropey guarantees that CRLF is always\n            // contiguous.  And the remaining line endings are all\n            // single `char`s, and therefore trivially contiguous.\n            None\n        }\n    }\n}\n\n#[inline]\npub fn str_is_line_ending(s: &str) -> bool {\n    LineEnding::from_str(s).is_some()\n}\n\n#[inline]\npub fn rope_is_line_ending(r: RopeSlice) -> bool {\n    r.chunks().all(str_is_line_ending)\n}\n\n/// Attempts to detect what line ending the passed document uses.\npub fn auto_detect_line_ending(doc: &Rope) -> Option<LineEnding> {\n    // Return first matched line ending. Not all possible line endings\n    // are being matched, as they might be special-use only\n    for line in doc.lines().take(100) {\n        match get_line_ending(&line) {\n            None => {}\n            #[cfg(feature = \"unicode-lines\")]\n            Some(LineEnding::VT) | Some(LineEnding::FF) | Some(LineEnding::PS) => {}\n            ending => return ending,\n        }\n    }\n    None\n}\n\n/// Returns the passed line's line ending, if any.\npub fn get_line_ending(line: &RopeSlice) -> Option<LineEnding> {\n    // Last character as str.\n    let g1 = line\n        .slice(line.len_chars().saturating_sub(1)..)\n        .as_str()\n        .unwrap();\n\n    // Last two characters as str, or empty str if they're not contiguous.\n    // It's fine to punt on the non-contiguous case, because Ropey guarantees\n    // that CRLF is always contiguous.\n    let g2 = line\n        .slice(line.len_chars().saturating_sub(2)..)\n        .as_str()\n        .unwrap_or(\"\");\n\n    // First check the two-character case for CRLF, then check the single-character case.\n    LineEnding::from_str(g2).or_else(|| LineEnding::from_str(g1))\n}\n\n#[cfg(not(feature = \"unicode-lines\"))]\n/// Returns the passed line's line ending, if any.\npub fn get_line_ending_of_str(line: &str) -> Option<LineEnding> {\n    if line.ends_with(\"\\u{000D}\\u{000A}\") {\n        Some(LineEnding::Crlf)\n    } else if line.ends_with('\\u{000A}') {\n        Some(LineEnding::LF)\n    } else {\n        None\n    }\n}\n\n#[cfg(feature = \"unicode-lines\")]\n/// Returns the passed line's line ending, if any.\npub fn get_line_ending_of_str(line: &str) -> Option<LineEnding> {\n    if line.ends_with(\"\\u{000D}\\u{000A}\") {\n        Some(LineEnding::Crlf)\n    } else if line.ends_with('\\u{000A}') {\n        Some(LineEnding::LF)\n    } else if line.ends_with('\\u{000B}') {\n        Some(LineEnding::VT)\n    } else if line.ends_with('\\u{000C}') {\n        Some(LineEnding::FF)\n    } else if line.ends_with('\\u{000D}') {\n        Some(LineEnding::CR)\n    } else if line.ends_with('\\u{0085}') {\n        Some(LineEnding::Nel)\n    } else if line.ends_with('\\u{2028}') {\n        Some(LineEnding::LS)\n    } else if line.ends_with('\\u{2029}') {\n        Some(LineEnding::PS)\n    } else {\n        None\n    }\n}\n\n/// Returns the char index of the end of the given line, not including its line ending.\npub fn line_end_char_index(slice: &RopeSlice, line: usize) -> usize {\n    slice.line_to_char(line + 1)\n        - get_line_ending(&slice.line(line))\n            .map(|le| le.len_chars())\n            .unwrap_or(0)\n}\n\npub fn line_end_byte_index(slice: &RopeSlice, line: usize) -> usize {\n    slice.line_to_byte(line + 1)\n        - get_line_ending(&slice.line(line))\n            .map(|le| le.as_str().len())\n            .unwrap_or(0)\n}\n\n/// Fetches line `line_idx` from the passed rope slice, sans any line ending.\npub fn line_without_line_ending<'a>(slice: &'a RopeSlice, line_idx: usize) -> RopeSlice<'a> {\n    let start = slice.line_to_char(line_idx);\n    let end = line_end_char_index(slice, line_idx);\n    slice.slice(start..end)\n}\n\n/// Returns the char index of the end of the given RopeSlice, not including\n/// any final line ending.\npub fn rope_end_without_line_ending(slice: &RopeSlice) -> usize {\n    slice.len_chars() - get_line_ending(slice).map(|le| le.len_chars()).unwrap_or(0)\n}\n\n#[cfg(test)]\nmod line_ending_tests {\n    use super::*;\n\n    #[test]\n    fn line_ending_autodetect() {\n        assert_eq!(\n            auto_detect_line_ending(&Rope::from_str(\"\\n\")),\n            Some(LineEnding::LF)\n        );\n        assert_eq!(\n            auto_detect_line_ending(&Rope::from_str(\"\\r\\n\")),\n            Some(LineEnding::Crlf)\n        );\n        assert_eq!(auto_detect_line_ending(&Rope::from_str(\"hello\")), None);\n        assert_eq!(auto_detect_line_ending(&Rope::from_str(\"\")), None);\n        assert_eq!(\n            auto_detect_line_ending(&Rope::from_str(\"hello\\nhelix\\r\\n\")),\n            Some(LineEnding::LF)\n        );\n        assert_eq!(\n            auto_detect_line_ending(&Rope::from_str(\"a formfeed\\u{000C}\")),\n            None\n        );\n        assert_eq!(\n            auto_detect_line_ending(&Rope::from_str(\"\\n\\u{000A}\\n \\u{000A}\")),\n            Some(LineEnding::LF)\n        );\n        assert_eq!(\n            auto_detect_line_ending(&Rope::from_str(\n                \"a formfeed\\u{000C} with a\\u{000C} linefeed\\u{000A}\"\n            )),\n            Some(LineEnding::LF)\n        );\n        assert_eq!(auto_detect_line_ending(&Rope::from_str(\"a formfeed\\u{000C} with a\\u{000C} carriage return linefeed\\u{000D}\\u{000A} and a linefeed\\u{000A}\")), Some(LineEnding::Crlf));\n    }\n\n    #[test]\n    fn str_to_line_ending() {\n        #[cfg(feature = \"unicode-lines\")]\n        assert_eq!(LineEnding::from_str(\"\\r\"), Some(LineEnding::CR));\n        assert_eq!(LineEnding::from_str(\"\\n\"), Some(LineEnding::LF));\n        assert_eq!(LineEnding::from_str(\"\\r\\n\"), Some(LineEnding::Crlf));\n        assert_eq!(LineEnding::from_str(\"hello\\n\"), None);\n    }\n\n    #[test]\n    fn rope_slice_to_line_ending() {\n        let r = Rope::from_str(\"hello\\r\\n\");\n        #[cfg(feature = \"unicode-lines\")]\n        assert_eq!(\n            LineEnding::from_rope_slice(&r.slice(5..6)),\n            Some(LineEnding::CR)\n        );\n        assert_eq!(\n            LineEnding::from_rope_slice(&r.slice(6..7)),\n            Some(LineEnding::LF)\n        );\n        assert_eq!(\n            LineEnding::from_rope_slice(&r.slice(5..7)),\n            Some(LineEnding::Crlf)\n        );\n        assert_eq!(LineEnding::from_rope_slice(&r.slice(..)), None);\n    }\n\n    #[test]\n    fn get_line_ending_rope_slice() {\n        let r = Rope::from_str(\"Hello\\rworld\\nhow\\r\\nare you?\");\n        #[cfg(feature = \"unicode-lines\")]\n        assert_eq!(get_line_ending(&r.slice(..6)), Some(LineEnding::CR));\n        assert_eq!(get_line_ending(&r.slice(..12)), Some(LineEnding::LF));\n        assert_eq!(get_line_ending(&r.slice(..17)), Some(LineEnding::Crlf));\n        assert_eq!(get_line_ending(&r.slice(..)), None);\n    }\n\n    #[test]\n    fn get_line_ending_str() {\n        let text = \"Hello\\rworld\\nhow\\r\\nare you?\";\n        #[cfg(feature = \"unicode-lines\")]\n        assert_eq!(get_line_ending_of_str(&text[..6]), Some(LineEnding::CR));\n        assert_eq!(get_line_ending_of_str(&text[..12]), Some(LineEnding::LF));\n        assert_eq!(get_line_ending_of_str(&text[..17]), Some(LineEnding::Crlf));\n        assert_eq!(get_line_ending_of_str(text), None);\n    }\n\n    #[test]\n    fn line_end_char_index_rope_slice() {\n        let r = Rope::from_str(\"Hello\\rworld\\nhow\\r\\nare you?\");\n        let s = &r.slice(..);\n        #[cfg(not(feature = \"unicode-lines\"))]\n        {\n            assert_eq!(line_end_char_index(s, 0), 11);\n            assert_eq!(line_end_char_index(s, 1), 15);\n            assert_eq!(line_end_char_index(s, 2), 25);\n        }\n        #[cfg(feature = \"unicode-lines\")]\n        {\n            assert_eq!(line_end_char_index(s, 0), 5);\n            assert_eq!(line_end_char_index(s, 1), 11);\n            assert_eq!(line_end_char_index(s, 2), 15);\n        }\n    }\n}\n"
  },
  {
    "path": "helix-core/src/macros.rs",
    "content": "#[macro_export]\nmacro_rules! hashmap {\n    (@single $($x:tt)*) => (());\n    (@count $($rest:expr),*) => (<[()]>::len(&[$(hashmap!(@single $rest)),*]));\n\n    ($($key:expr => $value:expr,)+) => { hashmap!($($key => $value),+) };\n    ($($key:expr => $value:expr),*) => {\n        {\n            let _cap = hashmap!(@count $($key),*);\n            let mut _map = ::std::collections::HashMap::with_capacity(_cap);\n            $(\n                let _ = _map.insert($key, $value);\n            )*\n            _map\n        }\n    };\n}\n"
  },
  {
    "path": "helix-core/src/match_brackets.rs",
    "content": "use std::iter;\n\nuse crate::tree_sitter::Node;\nuse ropey::RopeSlice;\n\nuse crate::movement::Direction::{self, Backward, Forward};\nuse crate::Syntax;\n\nconst MAX_PLAINTEXT_SCAN: usize = 10000;\nconst MATCH_LIMIT: usize = 16;\n\npub const BRACKETS: [(char, char); 9] = [\n    ('(', ')'),\n    ('{', '}'),\n    ('[', ']'),\n    ('<', '>'),\n    ('‘', '’'),\n    ('“', '”'),\n    ('«', '»'),\n    ('「', '」'),\n    ('（', '）'),\n];\n\n// The difference between BRACKETS and PAIRS is that we can find matching\n// BRACKETS in a plain text file, but we can't do the same for PAIRs.\n// PAIRS also contains all BRACKETS.\npub const PAIRS: [(char, char); BRACKETS.len() + 4] = {\n    let mut pairs = [(' ', ' '); BRACKETS.len() + 4];\n    let mut idx = 0;\n    while idx < BRACKETS.len() {\n        pairs[idx] = BRACKETS[idx];\n        idx += 1;\n    }\n    pairs[idx] = ('\"', '\"');\n    pairs[idx + 1] = ('\\'', '\\'');\n    pairs[idx + 2] = ('`', '`');\n    // Rust closure parameters use `|...|` delimiters. Tree-sitter exposes\n    // them as a `closure_parameters` node whose first and last children are\n    // both `|`, so the tree-sitter path in `find_pair` matches them\n    // correctly without any false positives for bitwise-OR operators.\n    pairs[idx + 3] = ('|', '|');\n    pairs\n};\n\n/// Returns the position of the matching bracket under cursor.\n///\n/// If the cursor is on the opening bracket, the position of\n/// the closing bracket is returned. If the cursor on the closing\n/// bracket, the position of the opening bracket is returned.\n///\n/// If the cursor is not on a bracket, `None` is returned.\n///\n/// If no matching bracket is found, `None` is returned.\n#[must_use]\npub fn find_matching_bracket(syntax: &Syntax, doc: RopeSlice, pos: usize) -> Option<usize> {\n    if pos >= doc.len_chars() || !is_valid_pair(doc.char(pos)) {\n        return None;\n    }\n    find_pair(syntax, doc, pos, false)\n}\n\n// Returns the position of the bracket that is closing the current scope.\n//\n// If the cursor is on an opening or closing bracket, the function\n// behaves equivalent to [`find_matching_bracket`].\n//\n// If the cursor position is within a scope, the function searches\n// for the surrounding scope that is surrounded by brackets and\n// returns the position of the closing bracket for that scope.\n//\n// If no surrounding scope is found, the function returns `None`.\n#[must_use]\npub fn find_matching_bracket_fuzzy(syntax: &Syntax, doc: RopeSlice, pos: usize) -> Option<usize> {\n    find_pair(syntax, doc, pos, true)\n}\n\nfn find_pair(\n    syntax: &Syntax,\n    doc: RopeSlice,\n    pos_: usize,\n    traverse_parents: bool,\n) -> Option<usize> {\n    let pos = doc.char_to_byte(pos_) as u32;\n\n    let root = syntax.tree_for_byte_range(pos, pos).root_node();\n    let mut node = root.descendant_for_byte_range(pos, pos)?;\n\n    loop {\n        if node.is_named() && node.child_count() >= 2 {\n            let open = node.child(0).unwrap();\n            let close = node.child(node.child_count() - 1).unwrap();\n\n            if let (Some((start_pos, open)), Some((end_pos, close))) =\n                (as_char(doc, &open), as_char(doc, &close))\n            {\n                if PAIRS.contains(&(open, close)) && start_pos <= pos_ && pos_ <= end_pos {\n                    if end_pos == pos_ {\n                        return Some(start_pos);\n                    }\n\n                    // We return the end char if the cursor is either on the start char\n                    // or at some arbitrary position between start and end char.\n                    if traverse_parents || start_pos == pos_ {\n                        return Some(end_pos);\n                    }\n                }\n            }\n        }\n        // this node itselt wasn't a pair but maybe its siblings are\n\n        if let Some((start_char, end_char)) = as_close_pair(doc, &node) {\n            if let Some(pair_start) =\n                find_pair_end(doc, node.prev_sibling(), start_char, end_char, Backward)\n            {\n                return Some(pair_start);\n            }\n        }\n        if let Some((start_char, end_char)) = as_open_pair(doc, &node) {\n            if let Some(pair_end) =\n                find_pair_end(doc, node.next_sibling(), start_char, end_char, Forward)\n            {\n                return Some(pair_end);\n            }\n        }\n\n        if traverse_parents {\n            for sibling in\n                iter::successors(node.next_sibling(), |node| node.next_sibling()).take(MATCH_LIMIT)\n            {\n                let Some((start_char, end_char)) = as_close_pair(doc, &sibling) else {\n                    continue;\n                };\n                if find_pair_end(doc, sibling.prev_sibling(), start_char, end_char, Backward)\n                    .is_some()\n                {\n                    return doc.try_byte_to_char(sibling.start_byte() as usize).ok();\n                }\n            }\n        } else if node.is_named() {\n            break;\n        }\n\n        let Some(parent) = node.parent() else {\n            break;\n        };\n        node = parent;\n    }\n    let node = root.named_descendant_for_byte_range(pos, pos + 1)?;\n    if node.child_count() != 0 {\n        return None;\n    }\n    let node_start = doc.byte_to_char(node.start_byte() as usize);\n    let node_text = doc.byte_slice(node.start_byte() as usize..node.end_byte() as usize);\n    find_matching_bracket_plaintext(node_text, pos_ - node_start).map(|pos| pos + node_start)\n}\n\n/// Returns the position of the matching bracket under cursor.\n/// This function works on plain text and ignores tree-sitter grammar.\n/// The search is limited to `MAX_PLAINTEXT_SCAN` characters\n///\n/// If the cursor is on the opening bracket, the position of\n/// the closing bracket is returned. If the cursor on the closing\n/// bracket, the position of the opening bracket is returned.\n///\n/// If the cursor is not on a bracket, `None` is returned.\n///\n/// If no matching bracket is found, `None` is returned.\n#[must_use]\npub fn find_matching_bracket_plaintext(doc: RopeSlice, cursor_pos: usize) -> Option<usize> {\n    let bracket = doc.get_char(cursor_pos)?;\n    let matching_bracket = {\n        let pair = get_pair(bracket);\n        if pair.0 == bracket {\n            pair.1\n        } else {\n            pair.0\n        }\n    };\n    // Don't do anything when the cursor is not on top of a bracket.\n    if !is_valid_bracket(bracket) {\n        return None;\n    }\n\n    // Determine the direction of the matching.\n    let is_fwd = is_open_bracket(bracket);\n    let chars_iter = if is_fwd {\n        doc.chars_at(cursor_pos + 1)\n    } else {\n        doc.chars_at(cursor_pos).reversed()\n    };\n\n    let mut open_cnt = 1;\n\n    for (i, candidate) in chars_iter.take(MAX_PLAINTEXT_SCAN).enumerate() {\n        if candidate == bracket {\n            open_cnt += 1;\n        } else if candidate == matching_bracket {\n            // Return when all pending brackets have been closed.\n            if open_cnt == 1 {\n                return Some(if is_fwd {\n                    cursor_pos + i + 1\n                } else {\n                    cursor_pos - i - 1\n                });\n            }\n            open_cnt -= 1;\n        }\n    }\n\n    None\n}\n\n/// Returns the open and closing chars pair. If not found in\n/// [`BRACKETS`] returns (ch, ch).\n///\n/// ```\n/// use helix_core::match_brackets::get_pair;\n///\n/// assert_eq!(get_pair('['), ('[', ']'));\n/// assert_eq!(get_pair('}'), ('{', '}'));\n/// assert_eq!(get_pair('\"'), ('\"', '\"'));\n/// ```\npub fn get_pair(ch: char) -> (char, char) {\n    PAIRS\n        .iter()\n        .find(|(open, close)| *open == ch || *close == ch)\n        .copied()\n        .unwrap_or((ch, ch))\n}\n\npub fn is_open_bracket(ch: char) -> bool {\n    BRACKETS.iter().any(|(l, _)| *l == ch)\n}\n\npub fn is_close_bracket(ch: char) -> bool {\n    BRACKETS.iter().any(|(_, r)| *r == ch)\n}\n\npub fn is_valid_bracket(ch: char) -> bool {\n    BRACKETS.iter().any(|(l, r)| *l == ch || *r == ch)\n}\n\npub fn is_open_pair(ch: char) -> bool {\n    PAIRS.iter().any(|(l, _)| *l == ch)\n}\n\npub fn is_close_pair(ch: char) -> bool {\n    PAIRS.iter().any(|(_, r)| *r == ch)\n}\n\npub fn is_valid_pair(ch: char) -> bool {\n    PAIRS.iter().any(|(l, r)| *l == ch || *r == ch)\n}\n\n/// Tests if this node is a pair close char and returns the expected open char\n/// and close char contained in this node\nfn as_close_pair(doc: RopeSlice, node: &Node) -> Option<(char, char)> {\n    let close = as_char(doc, node)?.1;\n    PAIRS\n        .iter()\n        .find_map(|&(open, close_)| (close_ == close).then_some((close, open)))\n}\n\n/// Checks if `node` or its siblings (at most MATCH_LIMIT nodes) is the specified closing char\n///\n/// # Returns\n///\n/// The position of the found node or `None` otherwise\nfn find_pair_end(\n    doc: RopeSlice,\n    node: Option<Node>,\n    start_char: char,\n    end_char: char,\n    direction: Direction,\n) -> Option<usize> {\n    let advance = match direction {\n        Forward => Node::next_sibling,\n        Backward => Node::prev_sibling,\n    };\n    let mut depth = 0;\n    iter::successors(node, advance)\n        .take(MATCH_LIMIT)\n        .find_map(|node| {\n            let (pos, c) = as_char(doc, &node)?;\n            if c == end_char {\n                if depth == 0 {\n                    return Some(pos);\n                }\n                depth -= 1;\n            } else if c == start_char {\n                depth += 1;\n            }\n            None\n        })\n}\n\n/// Tests if this node is a pair open char and returns the expected close char\n/// and open char contained in this node\nfn as_open_pair(doc: RopeSlice, node: &Node) -> Option<(char, char)> {\n    let open = as_char(doc, node)?.1;\n    PAIRS\n        .iter()\n        .find_map(|&(open_, close)| (open_ == open).then_some((open, close)))\n}\n\n/// If node is a single char return it (and its char position)\nfn as_char(doc: RopeSlice, node: &Node) -> Option<(usize, char)> {\n    // TODO: multi char/non ASCII pairs\n    if node.byte_range().len() != 1 {\n        return None;\n    }\n    let pos = doc.try_byte_to_char(node.start_byte() as usize).ok()?;\n    Some((pos, doc.char(pos)))\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn find_matching_bracket_empty_file() {\n        let actual = find_matching_bracket_plaintext(\"\".into(), 0);\n        assert_eq!(actual, None);\n    }\n\n    #[test]\n    fn test_find_matching_bracket_current_line_plaintext() {\n        let assert = |input: &str, pos, expected| {\n            let input = RopeSlice::from(input);\n            let actual = find_matching_bracket_plaintext(input, pos);\n            assert_eq!(expected, actual.unwrap());\n\n            let actual = find_matching_bracket_plaintext(input, expected);\n            assert_eq!(pos, actual.unwrap(), \"expected symmetrical behaviour\");\n        };\n\n        assert(\"(hello)\", 0, 6);\n        assert(\"((hello))\", 0, 8);\n        assert(\"((hello))\", 1, 7);\n        assert(\"(((hello)))\", 2, 8);\n\n        assert(\"key: ${value}\", 6, 12);\n        assert(\"key: ${value} # (some comment)\", 16, 29);\n\n        assert(\"(paren (paren {bracket}))\", 0, 24);\n        assert(\"(paren (paren {bracket}))\", 7, 23);\n        assert(\"(paren (paren {bracket}))\", 14, 22);\n\n        assert(\"(prev line\\n ) (middle) ( \\n next line)\", 0, 12);\n        assert(\"(prev line\\n ) (middle) ( \\n next line)\", 14, 21);\n        assert(\"(prev line\\n ) (middle) ( \\n next line)\", 23, 36);\n    }\n}\n"
  },
  {
    "path": "helix-core/src/movement.rs",
    "content": "use std::{borrow::Cow, cmp::Reverse, iter};\n\nuse ropey::iter::Chars;\n\nuse crate::{\n    char_idx_at_visual_offset,\n    chars::{categorize_char, char_is_line_ending, CharCategory},\n    doc_formatter::TextFormat,\n    graphemes::{\n        next_grapheme_boundary, nth_next_grapheme_boundary, nth_prev_grapheme_boundary,\n        prev_grapheme_boundary,\n    },\n    line_ending::rope_is_line_ending,\n    position::char_idx_at_visual_block_offset,\n    syntax,\n    text_annotations::TextAnnotations,\n    textobject::TextObject,\n    tree_sitter::Node,\n    visual_offset_from_block, Range, RopeSlice, Selection, Syntax,\n};\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum Direction {\n    Forward,\n    Backward,\n}\n\n#[derive(Copy, Clone, PartialEq, Eq)]\npub enum Movement {\n    Extend,\n    Move,\n}\n\npub fn move_horizontally(\n    slice: RopeSlice,\n    range: Range,\n    dir: Direction,\n    count: usize,\n    behaviour: Movement,\n    _: &TextFormat,\n    _: &mut TextAnnotations,\n) -> Range {\n    let pos = range.cursor(slice);\n\n    // Compute the new position.\n    let new_pos = match dir {\n        Direction::Forward => nth_next_grapheme_boundary(slice, pos, count),\n        Direction::Backward => nth_prev_grapheme_boundary(slice, pos, count),\n    };\n\n    // Compute the final new range.\n    range.put_cursor(slice, new_pos, behaviour == Movement::Extend)\n}\n\npub fn move_vertically_visual(\n    slice: RopeSlice,\n    range: Range,\n    dir: Direction,\n    count: usize,\n    behaviour: Movement,\n    text_fmt: &TextFormat,\n    annotations: &mut TextAnnotations,\n) -> Range {\n    if !text_fmt.soft_wrap {\n        return move_vertically(slice, range, dir, count, behaviour, text_fmt, annotations);\n    }\n    annotations.clear_line_annotations();\n    let pos = range.cursor(slice);\n\n    // Compute the current position's 2d coordinates.\n    let (visual_pos, block_off) = visual_offset_from_block(slice, pos, pos, text_fmt, annotations);\n    let new_col = range\n        .old_visual_position\n        .map_or(visual_pos.col as u32, |(_, col)| col);\n\n    // Compute the new position.\n    let mut row_off = match dir {\n        Direction::Forward => count as isize,\n        Direction::Backward => -(count as isize),\n    };\n\n    // Compute visual offset relative to block start to avoid trasversing the block twice\n    row_off += visual_pos.row as isize;\n    let (mut new_pos, virtual_rows) = char_idx_at_visual_offset(\n        slice,\n        block_off,\n        row_off,\n        new_col as usize,\n        text_fmt,\n        annotations,\n    );\n    if dir == Direction::Forward {\n        new_pos += (virtual_rows != 0) as usize;\n    }\n\n    // Special-case to avoid moving to the end of the last non-empty line.\n    if behaviour == Movement::Extend && slice.line(slice.char_to_line(new_pos)).len_chars() == 0 {\n        return range;\n    }\n\n    let mut new_range = range.put_cursor(slice, new_pos, behaviour == Movement::Extend);\n    new_range.old_visual_position = Some((0, new_col));\n    new_range\n}\n\npub fn move_vertically(\n    slice: RopeSlice,\n    range: Range,\n    dir: Direction,\n    count: usize,\n    behaviour: Movement,\n    text_fmt: &TextFormat,\n    annotations: &mut TextAnnotations,\n) -> Range {\n    annotations.clear_line_annotations();\n    let pos = range.cursor(slice);\n    let line_idx = slice.char_to_line(pos);\n    let line_start = slice.line_to_char(line_idx);\n\n    // Compute the current position's 2d coordinates.\n    let visual_pos = visual_offset_from_block(slice, line_start, pos, text_fmt, annotations).0;\n    let (mut new_row, new_col) = range\n        .old_visual_position\n        .map_or((visual_pos.row as u32, visual_pos.col as u32), |pos| pos);\n    new_row = new_row.max(visual_pos.row as u32);\n    let line_idx = slice.char_to_line(pos);\n\n    // Compute the new position.\n    let mut new_line_idx = match dir {\n        Direction::Forward => line_idx.saturating_add(count),\n        Direction::Backward => line_idx.saturating_sub(count),\n    };\n\n    let line = if new_line_idx >= slice.len_lines() - 1 {\n        // there is no line terminator for the last line\n        // so the logic below is not necessary here\n        new_line_idx = slice.len_lines() - 1;\n        slice\n    } else {\n        // char_idx_at_visual_block_offset returns a one-past-the-end index\n        // in case it reaches the end of the slice\n        // to avoid moving to the nextline in that case the line terminator is removed from the line\n        let new_line_end = prev_grapheme_boundary(slice, slice.line_to_char(new_line_idx + 1));\n        slice.slice(..new_line_end)\n    };\n\n    let new_line_start = line.line_to_char(new_line_idx);\n\n    let (new_pos, _) = char_idx_at_visual_block_offset(\n        line,\n        new_line_start,\n        new_row as usize,\n        new_col as usize,\n        text_fmt,\n        annotations,\n    );\n\n    // Special-case to avoid moving to the end of the last non-empty line.\n    if behaviour == Movement::Extend && slice.line(new_line_idx).len_chars() == 0 {\n        return range;\n    }\n\n    let mut new_range = range.put_cursor(slice, new_pos, behaviour == Movement::Extend);\n    new_range.old_visual_position = Some((new_row, new_col));\n    new_range\n}\n\npub fn move_next_word_start(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::NextWordStart)\n}\n\npub fn move_next_word_end(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::NextWordEnd)\n}\n\npub fn move_prev_word_start(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::PrevWordStart)\n}\n\npub fn move_prev_word_end(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::PrevWordEnd)\n}\n\npub fn move_next_long_word_start(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::NextLongWordStart)\n}\n\npub fn move_next_long_word_end(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::NextLongWordEnd)\n}\n\npub fn move_prev_long_word_start(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::PrevLongWordStart)\n}\n\npub fn move_prev_long_word_end(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::PrevLongWordEnd)\n}\n\npub fn move_next_sub_word_start(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::NextSubWordStart)\n}\n\npub fn move_next_sub_word_end(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::NextSubWordEnd)\n}\n\npub fn move_prev_sub_word_start(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::PrevSubWordStart)\n}\n\npub fn move_prev_sub_word_end(slice: RopeSlice, range: Range, count: usize) -> Range {\n    word_move(slice, range, count, WordMotionTarget::PrevSubWordEnd)\n}\n\nfn word_move(slice: RopeSlice, range: Range, count: usize, target: WordMotionTarget) -> Range {\n    let is_prev = matches!(\n        target,\n        WordMotionTarget::PrevWordStart\n            | WordMotionTarget::PrevLongWordStart\n            | WordMotionTarget::PrevSubWordStart\n            | WordMotionTarget::PrevWordEnd\n            | WordMotionTarget::PrevLongWordEnd\n            | WordMotionTarget::PrevSubWordEnd\n    );\n\n    // Special-case early-out.\n    if (is_prev && range.head == 0) || (!is_prev && range.head == slice.len_chars()) {\n        return range;\n    }\n\n    // Prepare the range appropriately based on the target movement\n    // direction.  This is addressing two things at once:\n    //\n    //   1. Block-cursor semantics.\n    //   2. The anchor position being irrelevant to the output result.\n    #[allow(clippy::collapsible_else_if)] // Makes the structure clearer in this case.\n    let start_range = if is_prev {\n        if range.anchor < range.head {\n            Range::new(range.head, prev_grapheme_boundary(slice, range.head))\n        } else {\n            Range::new(next_grapheme_boundary(slice, range.head), range.head)\n        }\n    } else {\n        if range.anchor < range.head {\n            Range::new(prev_grapheme_boundary(slice, range.head), range.head)\n        } else {\n            Range::new(range.head, next_grapheme_boundary(slice, range.head))\n        }\n    };\n\n    // Do the main work.\n    let mut range = start_range;\n    for _ in 0..count {\n        let next_range = slice.chars_at(range.head).range_to_target(target, range);\n        if range == next_range {\n            break;\n        }\n        range = next_range;\n    }\n    range\n}\n\npub fn move_prev_paragraph(\n    slice: RopeSlice,\n    range: Range,\n    count: usize,\n    behavior: Movement,\n) -> Range {\n    let mut line = range.cursor_line(slice);\n    let first_char = slice.line_to_char(line) == range.cursor(slice);\n    let prev_line_empty = rope_is_line_ending(slice.line(line.saturating_sub(1)));\n    let curr_line_empty = rope_is_line_ending(slice.line(line));\n    let prev_empty_to_line = prev_line_empty && !curr_line_empty;\n\n    // skip character before paragraph boundary\n    if prev_empty_to_line && !first_char {\n        line += 1;\n    }\n    let mut lines = slice.lines_at(line);\n    lines.reverse();\n    let mut lines = lines.map(rope_is_line_ending).peekable();\n    let mut last_line = line;\n    for _ in 0..count {\n        while lines.next_if(|&e| e).is_some() {\n            line -= 1;\n        }\n        while lines.next_if(|&e| !e).is_some() {\n            line -= 1;\n        }\n        if line == last_line {\n            break;\n        }\n        last_line = line;\n    }\n\n    let head = slice.line_to_char(line);\n    let anchor = if behavior == Movement::Move {\n        // exclude first character after paragraph boundary\n        if prev_empty_to_line && first_char {\n            range.cursor(slice)\n        } else {\n            range.head\n        }\n    } else {\n        range.put_cursor(slice, head, true).anchor\n    };\n    Range::new(anchor, head)\n}\n\npub fn move_next_paragraph(\n    slice: RopeSlice,\n    range: Range,\n    count: usize,\n    behavior: Movement,\n) -> Range {\n    let mut line = range.cursor_line(slice);\n    let last_char =\n        prev_grapheme_boundary(slice, slice.line_to_char(line + 1)) == range.cursor(slice);\n    let curr_line_empty = rope_is_line_ending(slice.line(line));\n    let next_line_empty =\n        rope_is_line_ending(slice.line(slice.len_lines().saturating_sub(1).min(line + 1)));\n    let curr_empty_to_line = curr_line_empty && !next_line_empty;\n\n    // skip character after paragraph boundary\n    if curr_empty_to_line && last_char {\n        line += 1;\n    }\n    let mut lines = slice.lines_at(line).map(rope_is_line_ending).peekable();\n    let mut last_line = line;\n    for _ in 0..count {\n        while lines.next_if(|&e| !e).is_some() {\n            line += 1;\n        }\n        while lines.next_if(|&e| e).is_some() {\n            line += 1;\n        }\n        if line == last_line {\n            break;\n        }\n        last_line = line;\n    }\n    let head = slice.line_to_char(line);\n    let anchor = if behavior == Movement::Move {\n        if curr_empty_to_line && last_char {\n            range.head\n        } else {\n            range.cursor(slice)\n        }\n    } else {\n        range.put_cursor(slice, head, true).anchor\n    };\n    Range::new(anchor, head)\n}\n\n// ---- util ------------\n\n#[inline]\n/// Returns first index that doesn't satisfy a given predicate when\n/// advancing the character index.\n///\n/// Returns none if all characters satisfy the predicate.\npub fn skip_while<F>(slice: RopeSlice, pos: usize, fun: F) -> Option<usize>\nwhere\n    F: Fn(char) -> bool,\n{\n    let mut chars = slice.chars_at(pos).enumerate();\n    chars.find_map(|(i, c)| if !fun(c) { Some(pos + i) } else { None })\n}\n\n#[inline]\n/// Returns first index that doesn't satisfy a given predicate when\n/// retreating the character index, saturating if all elements satisfy\n/// the condition.\npub fn backwards_skip_while<F>(slice: RopeSlice, pos: usize, fun: F) -> Option<usize>\nwhere\n    F: Fn(char) -> bool,\n{\n    let mut chars_starting_from_next = slice.chars_at(pos);\n    let mut backwards = iter::from_fn(|| chars_starting_from_next.prev()).enumerate();\n    backwards.find_map(|(i, c)| {\n        if !fun(c) {\n            Some(pos.saturating_sub(i))\n        } else {\n            None\n        }\n    })\n}\n\n/// Possible targets of a word motion\n#[derive(Copy, Clone, Debug)]\npub enum WordMotionTarget {\n    NextWordStart,\n    NextWordEnd,\n    PrevWordStart,\n    PrevWordEnd,\n    // A \"Long word\" (also known as a WORD in Vim/Kakoune) is strictly\n    // delimited by whitespace, and can consist of punctuation as well\n    // as alphanumerics.\n    NextLongWordStart,\n    NextLongWordEnd,\n    PrevLongWordStart,\n    PrevLongWordEnd,\n    // A sub word is similar to a regular word, except it is also delimited by\n    // underscores and transitions from lowercase to uppercase.\n    NextSubWordStart,\n    NextSubWordEnd,\n    PrevSubWordStart,\n    PrevSubWordEnd,\n}\n\npub trait CharHelpers {\n    fn range_to_target(&mut self, target: WordMotionTarget, origin: Range) -> Range;\n}\n\nimpl CharHelpers for Chars<'_> {\n    /// Note: this only changes the anchor of the range if the head is effectively\n    /// starting on a boundary (either directly or after skipping newline characters).\n    /// Any other changes to the anchor should be handled by the calling code.\n    fn range_to_target(&mut self, target: WordMotionTarget, origin: Range) -> Range {\n        let is_prev = matches!(\n            target,\n            WordMotionTarget::PrevWordStart\n                | WordMotionTarget::PrevLongWordStart\n                | WordMotionTarget::PrevSubWordStart\n                | WordMotionTarget::PrevWordEnd\n                | WordMotionTarget::PrevLongWordEnd\n                | WordMotionTarget::PrevSubWordEnd\n        );\n\n        // Reverse the iterator if needed for the motion direction.\n        if is_prev {\n            self.reverse();\n        }\n\n        // Function to advance index in the appropriate motion direction.\n        let advance: &dyn Fn(&mut usize) = if is_prev {\n            &|idx| *idx = idx.saturating_sub(1)\n        } else {\n            &|idx| *idx += 1\n        };\n\n        // Initialize state variables.\n        let mut anchor = origin.anchor;\n        let mut head = origin.head;\n        let mut prev_ch = {\n            let ch = self.prev();\n            if ch.is_some() {\n                self.next();\n            }\n            ch\n        };\n\n        // Skip any initial newline characters.\n        while let Some(ch) = self.next() {\n            if char_is_line_ending(ch) {\n                prev_ch = Some(ch);\n                advance(&mut head);\n            } else {\n                self.prev();\n                break;\n            }\n        }\n        if prev_ch.map(char_is_line_ending).unwrap_or(false) {\n            anchor = head;\n        }\n\n        // Find our target position(s).\n        let head_start = head;\n        #[allow(clippy::while_let_on_iterator)] // Clippy's suggestion to fix doesn't work here.\n        while let Some(next_ch) = self.next() {\n            if prev_ch.is_none() || reached_target(target, prev_ch.unwrap(), next_ch) {\n                if head == head_start {\n                    anchor = head;\n                } else {\n                    break;\n                }\n            }\n            prev_ch = Some(next_ch);\n            advance(&mut head);\n        }\n\n        // Un-reverse the iterator if needed.\n        if is_prev {\n            self.reverse();\n        }\n\n        Range::new(anchor, head)\n    }\n}\n\nfn is_word_boundary(a: char, b: char) -> bool {\n    categorize_char(a) != categorize_char(b)\n}\n\nfn is_long_word_boundary(a: char, b: char) -> bool {\n    match (categorize_char(a), categorize_char(b)) {\n        (CharCategory::Word, CharCategory::Punctuation)\n        | (CharCategory::Punctuation, CharCategory::Word) => false,\n        (a, b) if a != b => true,\n        _ => false,\n    }\n}\n\nfn is_sub_word_boundary(a: char, b: char, dir: Direction) -> bool {\n    match (categorize_char(a), categorize_char(b)) {\n        (CharCategory::Word, CharCategory::Word) => {\n            if (a == '_') != (b == '_') {\n                return true;\n            }\n\n            // Subword boundaries are directional: in 'fooBar', there is a\n            // boundary between 'o' and 'B', but not between 'B' and 'a'.\n            match dir {\n                Direction::Forward => a.is_lowercase() && b.is_uppercase(),\n                Direction::Backward => a.is_uppercase() && b.is_lowercase(),\n            }\n        }\n        (a, b) if a != b => true,\n        _ => false,\n    }\n}\n\nfn reached_target(target: WordMotionTarget, prev_ch: char, next_ch: char) -> bool {\n    match target {\n        WordMotionTarget::NextWordStart | WordMotionTarget::PrevWordEnd => {\n            is_word_boundary(prev_ch, next_ch)\n                && (char_is_line_ending(next_ch) || !next_ch.is_whitespace())\n        }\n        WordMotionTarget::NextWordEnd | WordMotionTarget::PrevWordStart => {\n            is_word_boundary(prev_ch, next_ch)\n                && (!prev_ch.is_whitespace() || char_is_line_ending(next_ch))\n        }\n        WordMotionTarget::NextLongWordStart | WordMotionTarget::PrevLongWordEnd => {\n            is_long_word_boundary(prev_ch, next_ch)\n                && (char_is_line_ending(next_ch) || !next_ch.is_whitespace())\n        }\n        WordMotionTarget::NextLongWordEnd | WordMotionTarget::PrevLongWordStart => {\n            is_long_word_boundary(prev_ch, next_ch)\n                && (!prev_ch.is_whitespace() || char_is_line_ending(next_ch))\n        }\n        WordMotionTarget::NextSubWordStart => {\n            is_sub_word_boundary(prev_ch, next_ch, Direction::Forward)\n                && (char_is_line_ending(next_ch) || !(next_ch.is_whitespace() || next_ch == '_'))\n        }\n        WordMotionTarget::PrevSubWordEnd => {\n            is_sub_word_boundary(prev_ch, next_ch, Direction::Backward)\n                && (char_is_line_ending(next_ch) || !(next_ch.is_whitespace() || next_ch == '_'))\n        }\n        WordMotionTarget::NextSubWordEnd => {\n            is_sub_word_boundary(prev_ch, next_ch, Direction::Forward)\n                && (!(prev_ch.is_whitespace() || prev_ch == '_') || char_is_line_ending(next_ch))\n        }\n        WordMotionTarget::PrevSubWordStart => {\n            is_sub_word_boundary(prev_ch, next_ch, Direction::Backward)\n                && (!(prev_ch.is_whitespace() || prev_ch == '_') || char_is_line_ending(next_ch))\n        }\n    }\n}\n\n/// Finds the range of the next or previous textobject in the syntax sub-tree of `node`.\n/// Returns the range in the forwards direction.\n#[allow(clippy::too_many_arguments)]\npub fn goto_treesitter_object(\n    slice: RopeSlice,\n    range: Range,\n    object_name: &str,\n    dir: Direction,\n    slice_tree: &Node,\n    syntax: &Syntax,\n    loader: &syntax::Loader,\n    count: usize,\n) -> Range {\n    let textobject_query = loader.textobject_query(syntax.root_language());\n    let get_range = move |range: Range| -> Option<Range> {\n        let byte_pos = slice.char_to_byte(range.cursor(slice));\n\n        let cap_name = |t: TextObject| format!(\"{}.{}\", object_name, t);\n        let nodes = textobject_query?.capture_nodes_any(\n            &[\n                &cap_name(TextObject::Movement),\n                &cap_name(TextObject::Around),\n                &cap_name(TextObject::Inside),\n            ],\n            slice_tree,\n            slice,\n        )?;\n\n        let node = match dir {\n            Direction::Forward => nodes\n                .filter(|n| n.start_byte() > byte_pos)\n                .min_by_key(|n| (n.start_byte(), Reverse(n.end_byte())))?,\n            Direction::Backward => nodes\n                .filter(|n| n.end_byte() < byte_pos)\n                .max_by_key(|n| (n.end_byte(), Reverse(n.start_byte())))?,\n        };\n\n        let len = slice.len_bytes();\n        let start_byte = node.start_byte();\n        let end_byte = node.end_byte();\n        if start_byte >= len || end_byte >= len {\n            return None;\n        }\n\n        let start_char = slice.byte_to_char(start_byte);\n        let end_char = slice.byte_to_char(end_byte);\n\n        // head of range should be at beginning\n        Some(Range::new(start_char, end_char))\n    };\n    let mut last_range = range;\n    for _ in 0..count {\n        match get_range(last_range) {\n            Some(r) if r != last_range => last_range = r,\n            _ => break,\n        }\n    }\n    last_range\n}\n\nfn find_parent_start<'tree>(node: &Node<'tree>) -> Option<Node<'tree>> {\n    let start = node.start_byte();\n    let mut node = Cow::Borrowed(node);\n\n    while node.start_byte() >= start || !node.is_named() {\n        node = Cow::Owned(node.parent()?);\n    }\n\n    Some(node.into_owned())\n}\n\npub fn move_parent_node_end(\n    syntax: &Syntax,\n    text: RopeSlice,\n    selection: Selection,\n    dir: Direction,\n    movement: Movement,\n) -> Selection {\n    selection.transform(|range| {\n        let start_from = text.char_to_byte(range.from()) as u32;\n        let start_to = text.char_to_byte(range.to()) as u32;\n\n        let mut node = match syntax.named_descendant_for_byte_range(start_from, start_to) {\n            Some(node) => node,\n            None => {\n                log::debug!(\n                    \"no descendant found for byte range: {} - {}\",\n                    start_from,\n                    start_to\n                );\n                return range;\n            }\n        };\n\n        let mut end_head = match dir {\n            // moving forward, we always want to move one past the end of the\n            // current node, so use the end byte of the current node, which is an exclusive\n            // end of the range\n            Direction::Forward => text.byte_to_char(node.end_byte() as usize),\n\n            // moving backward, we want the cursor to land on the start char of\n            // the current node, or if it is already at the start of a node, to traverse up to\n            // the parent\n            Direction::Backward => {\n                let end_head = text.byte_to_char(node.start_byte() as usize);\n\n                // if we're already on the beginning, look up to the parent\n                if end_head == range.cursor(text) {\n                    node = find_parent_start(&node).unwrap_or(node);\n                    text.byte_to_char(node.start_byte() as usize)\n                } else {\n                    end_head\n                }\n            }\n        };\n\n        if movement == Movement::Move {\n            // preserve direction of original range\n            if range.direction() == Direction::Forward {\n                Range::new(end_head, end_head + 1)\n            } else {\n                Range::new(end_head + 1, end_head)\n            }\n        } else {\n            // if we end up with a forward range, then adjust it to be one past\n            // where we want\n            if end_head >= range.anchor {\n                end_head += 1;\n            }\n\n            Range::new(range.anchor, end_head)\n        }\n    })\n}\n\n#[cfg(test)]\nmod test {\n    use ropey::Rope;\n\n    use crate::{coords_at_pos, pos_at_coords};\n\n    use super::*;\n\n    const SINGLE_LINE_SAMPLE: &str = \"This is a simple alphabetic line\";\n    const MULTILINE_SAMPLE: &str = \"\\\n        Multiline\\n\\\n        text sample\\n\\\n        which\\n\\\n        is merely alphabetic\\n\\\n        and whitespaced\\n\\\n    \";\n\n    const MULTIBYTE_CHARACTER_SAMPLE: &str = \"\\\n        パーティーへ行かないか\\n\\\n        The text above is Japanese\\n\\\n    \";\n\n    #[test]\n    fn test_vertical_move() {\n        let text = Rope::from(\"abcd\\nefg\\nwrs\");\n        let slice = text.slice(..);\n        let pos = pos_at_coords(slice, (0, 4).into(), true);\n\n        let range = Range::new(pos, pos);\n        assert_eq!(\n            coords_at_pos(\n                slice,\n                move_vertically_visual(\n                    slice,\n                    range,\n                    Direction::Forward,\n                    1,\n                    Movement::Move,\n                    &TextFormat::default(),\n                    &mut TextAnnotations::default(),\n                )\n                .head\n            ),\n            (1, 3).into()\n        );\n    }\n\n    #[test]\n    fn horizontal_moves_through_single_line_text() {\n        let text = Rope::from(SINGLE_LINE_SAMPLE);\n        let slice = text.slice(..);\n        let position = pos_at_coords(slice, (0, 0).into(), true);\n\n        let mut range = Range::point(position);\n\n        let moves_and_expected_coordinates = [\n            ((Direction::Forward, 1usize), (0, 1)), // T|his is a simple alphabetic line\n            ((Direction::Forward, 2usize), (0, 3)), // Thi|s is a simple alphabetic line\n            ((Direction::Forward, 0usize), (0, 3)), // Thi|s is a simple alphabetic line\n            ((Direction::Forward, 999usize), (0, 32)), // This is a simple alphabetic line|\n            ((Direction::Forward, 999usize), (0, 32)), // This is a simple alphabetic line|\n            ((Direction::Backward, 999usize), (0, 0)), // |This is a simple alphabetic line\n        ];\n\n        for ((direction, amount), coordinates) in moves_and_expected_coordinates {\n            range = move_horizontally(\n                slice,\n                range,\n                direction,\n                amount,\n                Movement::Move,\n                &TextFormat::default(),\n                &mut TextAnnotations::default(),\n            );\n            assert_eq!(coords_at_pos(slice, range.head), coordinates.into())\n        }\n    }\n\n    #[test]\n    fn horizontal_moves_through_multiline_text() {\n        let text = Rope::from(MULTILINE_SAMPLE);\n        let slice = text.slice(..);\n        let position = pos_at_coords(slice, (0, 0).into(), true);\n\n        let mut range = Range::point(position);\n\n        let moves_and_expected_coordinates = [\n            ((Direction::Forward, 11usize), (1, 1)), // Multiline\\nt|ext sample\\n...\n            ((Direction::Backward, 1usize), (1, 0)), // Multiline\\n|text sample\\n...\n            ((Direction::Backward, 5usize), (0, 5)), // Multi|line\\ntext sample\\n...\n            ((Direction::Backward, 999usize), (0, 0)), // |Multiline\\ntext sample\\n...\n            ((Direction::Forward, 3usize), (0, 3)),  // Mul|tiline\\ntext sample\\n...\n            ((Direction::Forward, 0usize), (0, 3)),  // Mul|tiline\\ntext sample\\n...\n            ((Direction::Backward, 0usize), (0, 3)), // Mul|tiline\\ntext sample\\n...\n            ((Direction::Forward, 999usize), (5, 0)), // ...and whitespaced\\n|\n            ((Direction::Forward, 999usize), (5, 0)), // ...and whitespaced\\n|\n        ];\n\n        for ((direction, amount), coordinates) in moves_and_expected_coordinates {\n            range = move_horizontally(\n                slice,\n                range,\n                direction,\n                amount,\n                Movement::Move,\n                &TextFormat::default(),\n                &mut TextAnnotations::default(),\n            );\n            assert_eq!(coords_at_pos(slice, range.head), coordinates.into());\n            assert_eq!(range.head, range.anchor);\n        }\n    }\n\n    #[test]\n    fn selection_extending_moves_in_single_line_text() {\n        let text = Rope::from(SINGLE_LINE_SAMPLE);\n        let slice = text.slice(..);\n        let position = pos_at_coords(slice, (0, 0).into(), true);\n\n        let mut range = Range::point(position);\n        let original_anchor = range.anchor;\n\n        let moves = [\n            (Direction::Forward, 1usize),\n            (Direction::Forward, 5usize),\n            (Direction::Backward, 3usize),\n        ];\n\n        for (direction, amount) in moves {\n            range = move_horizontally(\n                slice,\n                range,\n                direction,\n                amount,\n                Movement::Extend,\n                &TextFormat::default(),\n                &mut TextAnnotations::default(),\n            );\n            assert_eq!(range.anchor, original_anchor);\n        }\n    }\n\n    #[test]\n    fn vertical_moves_in_single_column() {\n        let text = Rope::from(MULTILINE_SAMPLE);\n        let slice = text.slice(..);\n        let position = pos_at_coords(slice, (0, 0).into(), true);\n        let mut range = Range::point(position);\n        let moves_and_expected_coordinates = [\n            ((Direction::Forward, 1usize), (1, 0)),\n            ((Direction::Forward, 2usize), (3, 0)),\n            ((Direction::Forward, 1usize), (4, 0)),\n            ((Direction::Backward, 999usize), (0, 0)),\n            ((Direction::Forward, 4usize), (4, 0)),\n            ((Direction::Forward, 0usize), (4, 0)),\n            ((Direction::Backward, 0usize), (4, 0)),\n            ((Direction::Forward, 5), (5, 0)),\n            ((Direction::Forward, 999usize), (5, 0)),\n        ];\n\n        for ((direction, amount), coordinates) in moves_and_expected_coordinates {\n            range = move_vertically_visual(\n                slice,\n                range,\n                direction,\n                amount,\n                Movement::Move,\n                &TextFormat::default(),\n                &mut TextAnnotations::default(),\n            );\n            assert_eq!(coords_at_pos(slice, range.head), coordinates.into());\n            assert_eq!(range.head, range.anchor);\n        }\n    }\n\n    #[test]\n    fn vertical_moves_jumping_column() {\n        let text = Rope::from(MULTILINE_SAMPLE);\n        let slice = text.slice(..);\n        let position = pos_at_coords(slice, (0, 0).into(), true);\n        let mut range = Range::point(position);\n\n        enum Axis {\n            H,\n            V,\n        }\n        let moves_and_expected_coordinates = [\n            // Places cursor at the end of line\n            ((Axis::H, Direction::Forward, 8usize), (0, 8)),\n            // First descent preserves column as the target line is wider\n            ((Axis::V, Direction::Forward, 1usize), (1, 8)),\n            // Second descent clamps column as the target line is shorter\n            ((Axis::V, Direction::Forward, 1usize), (2, 5)),\n            // Third descent restores the original column\n            ((Axis::V, Direction::Forward, 1usize), (3, 8)),\n            // Behaviour is preserved even through long jumps\n            ((Axis::V, Direction::Backward, 999usize), (0, 8)),\n            ((Axis::V, Direction::Forward, 4usize), (4, 8)),\n            ((Axis::V, Direction::Forward, 999usize), (5, 0)),\n        ];\n\n        for ((axis, direction, amount), coordinates) in moves_and_expected_coordinates {\n            range = match axis {\n                Axis::H => move_horizontally(\n                    slice,\n                    range,\n                    direction,\n                    amount,\n                    Movement::Move,\n                    &TextFormat::default(),\n                    &mut TextAnnotations::default(),\n                ),\n                Axis::V => move_vertically_visual(\n                    slice,\n                    range,\n                    direction,\n                    amount,\n                    Movement::Move,\n                    &TextFormat::default(),\n                    &mut TextAnnotations::default(),\n                ),\n            };\n            assert_eq!(coords_at_pos(slice, range.head), coordinates.into());\n            assert_eq!(range.head, range.anchor);\n        }\n    }\n\n    #[test]\n    fn multibyte_character_wide_column_jumps() {\n        let text = Rope::from(MULTIBYTE_CHARACTER_SAMPLE);\n        let slice = text.slice(..);\n        let position = pos_at_coords(slice, (0, 0).into(), true);\n        let mut range = Range::point(position);\n\n        // FIXME: The behaviour captured in this test diverges from both Kakoune and Vim. These\n        // will attempt to preserve the horizontal position of the cursor, rather than\n        // placing it at the same character index.\n        enum Axis {\n            H,\n            V,\n        }\n        let moves_and_expected_coordinates = [\n            // Places cursor at the fourth kana.\n            ((Axis::H, Direction::Forward, 4), (0, 4)),\n            // Descent places cursor at the 8th character.\n            ((Axis::V, Direction::Forward, 1usize), (1, 8)),\n            // Moving back 2 characters.\n            ((Axis::H, Direction::Backward, 2usize), (1, 6)),\n            // Jumping back up 1 line.\n            ((Axis::V, Direction::Backward, 1usize), (0, 3)),\n        ];\n\n        for ((axis, direction, amount), coordinates) in moves_and_expected_coordinates {\n            range = match axis {\n                Axis::H => move_horizontally(\n                    slice,\n                    range,\n                    direction,\n                    amount,\n                    Movement::Move,\n                    &TextFormat::default(),\n                    &mut TextAnnotations::default(),\n                ),\n                Axis::V => move_vertically_visual(\n                    slice,\n                    range,\n                    direction,\n                    amount,\n                    Movement::Move,\n                    &TextFormat::default(),\n                    &mut TextAnnotations::default(),\n                ),\n            };\n            assert_eq!(coords_at_pos(slice, range.head), coordinates.into());\n            assert_eq!(range.head, range.anchor);\n        }\n    }\n\n    #[test]\n    #[should_panic]\n    fn nonsensical_ranges_panic_on_forward_movement_attempt_in_debug_mode() {\n        move_next_word_start(Rope::from(\"Sample\").slice(..), Range::point(99999999), 1);\n    }\n\n    #[test]\n    #[should_panic]\n    fn nonsensical_ranges_panic_on_forward_to_end_movement_attempt_in_debug_mode() {\n        move_next_word_end(Rope::from(\"Sample\").slice(..), Range::point(99999999), 1);\n    }\n\n    #[test]\n    #[should_panic]\n    fn nonsensical_ranges_panic_on_backwards_movement_attempt_in_debug_mode() {\n        move_prev_word_start(Rope::from(\"Sample\").slice(..), Range::point(99999999), 1);\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_start_of_next_words() {\n        let tests = [\n            (\"Basic forward motion stops at the first space\",\n                vec![(1, Range::new(0, 0), Range::new(0, 6))]),\n            (\" Starting from a boundary advances the anchor\",\n                vec![(1, Range::new(0, 0), Range::new(1, 10))]),\n            (\"Long       whitespace gap is bridged by the head\",\n                vec![(1, Range::new(0, 0), Range::new(0, 11))]),\n            (\"Previous anchor is irrelevant for forward motions\",\n                vec![(1, Range::new(12, 0), Range::new(0, 9))]),\n            (\"    Starting from whitespace moves to last space in sequence\",\n                vec![(1, Range::new(0, 0), Range::new(0, 4))]),\n            (\"Starting from mid-word leaves anchor at start position and moves head\",\n                vec![(1, Range::new(3, 3), Range::new(3, 9))]),\n            (\"Identifiers_with_underscores are considered a single word\",\n                vec![(1, Range::new(0, 0), Range::new(0, 29))]),\n            (\"Jumping\\n    into starting whitespace selects the spaces before 'into'\",\n                vec![(1, Range::new(0, 7), Range::new(8, 12))]),\n            (\"alphanumeric.!,and.?=punctuation are considered 'words' for the purposes of word motion\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 12)),\n                    (1, Range::new(0, 12), Range::new(12, 15)),\n                    (1, Range::new(12, 15), Range::new(15, 18))\n                ]),\n            (\"...   ... punctuation and spaces behave as expected\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 6)),\n                    (1, Range::new(0, 6), Range::new(6, 10)),\n                ]),\n            (\".._.._ punctuation is not joined by underscores into a single block\",\n                vec![(1, Range::new(0, 0), Range::new(0, 2))]),\n            (\"Newlines\\n\\nare bridged seamlessly.\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 8)),\n                    (1, Range::new(0, 8), Range::new(10, 14)),\n                ]),\n            (\"Jumping\\n\\n\\n\\n\\n\\n   from newlines to whitespace selects whitespace.\",\n                vec![\n                    (1, Range::new(0, 9), Range::new(13, 16)),\n                ]),\n            (\"A failed motion does not modify the range\",\n                vec![\n                    (3, Range::new(37, 41), Range::new(37, 41)),\n                ]),\n            (\"oh oh oh two character words!\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 3)),\n                    (1, Range::new(0, 3), Range::new(3, 6)),\n                    (1, Range::new(0, 2), Range::new(1, 3)),\n                ]),\n            (\"Multiple motions at once resolve correctly\",\n                vec![\n                    (3, Range::new(0, 0), Range::new(17, 20)),\n                ]),\n            (\"Excessive motions are performed partially\",\n                vec![\n                    (999, Range::new(0, 0), Range::new(32, 41)),\n                ]),\n            (\"\", // Edge case of moving forward in empty string\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 0)),\n                ]),\n            (\"\\n\\n\\n\\n\\n\", // Edge case of moving forward in all newlines\n                vec![\n                    (1, Range::new(0, 0), Range::new(5, 5)),\n                ]),\n            (\"\\n   \\n   \\n Jumping through alternated space blocks and newlines selects the space blocks\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(1, 4)),\n                    (1, Range::new(1, 4), Range::new(5, 8)),\n                ]),\n            (\"ヒーリクス multibyte characters behave as normal characters\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 6)),\n                ]),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_next_word_start(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_start_of_next_sub_words() {\n        let tests = [\n            (\n                \"NextSubwordStart\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 11)),\n                ],\n            ),\n            (\n                \"next_subword_start\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 5)),\n                    (1, Range::new(4, 4), Range::new(5, 13)),\n                ],\n            ),\n            (\n                \"Next_Subword_Start\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 5)),\n                    (1, Range::new(4, 4), Range::new(5, 13)),\n                ],\n            ),\n            (\n                \"NEXT_SUBWORD_START\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 5)),\n                    (1, Range::new(4, 4), Range::new(5, 13)),\n                ],\n            ),\n            (\n                \"next subword start\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 5)),\n                    (1, Range::new(4, 4), Range::new(5, 13)),\n                ],\n            ),\n            (\n                \"Next Subword Start\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 5)),\n                    (1, Range::new(4, 4), Range::new(5, 13)),\n                ],\n            ),\n            (\n                \"NEXT SUBWORD START\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 5)),\n                    (1, Range::new(4, 4), Range::new(5, 13)),\n                ],\n            ),\n            (\n                \"next__subword__start\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 6)),\n                    (1, Range::new(4, 4), Range::new(4, 6)),\n                    (1, Range::new(5, 5), Range::new(6, 15)),\n                ],\n            ),\n            (\n                \"Next__Subword__Start\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 6)),\n                    (1, Range::new(4, 4), Range::new(4, 6)),\n                    (1, Range::new(5, 5), Range::new(6, 15)),\n                ],\n            ),\n            (\n                \"NEXT__SUBWORD__START\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 6)),\n                    (1, Range::new(4, 4), Range::new(4, 6)),\n                    (1, Range::new(5, 5), Range::new(6, 15)),\n                ],\n            ),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_next_sub_word_start(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_end_of_next_sub_words() {\n        let tests = [\n            (\n                \"NextSubwordEnd\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 11)),\n                ],\n            ),\n            (\n                \"next subword end\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 12)),\n                ],\n            ),\n            (\n                \"Next Subword End\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 12)),\n                ],\n            ),\n            (\n                \"NEXT SUBWORD END\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 12)),\n                ],\n            ),\n            (\n                \"next_subword_end\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 12)),\n                ],\n            ),\n            (\n                \"Next_Subword_End\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 12)),\n                ],\n            ),\n            (\n                \"NEXT_SUBWORD_END\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 12)),\n                ],\n            ),\n            (\n                \"next__subword__end\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 13)),\n                    (1, Range::new(5, 5), Range::new(5, 13)),\n                ],\n            ),\n            (\n                \"Next__Subword__End\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 13)),\n                    (1, Range::new(5, 5), Range::new(5, 13)),\n                ],\n            ),\n            (\n                \"NEXT__SUBWORD__END\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 4)),\n                    (1, Range::new(4, 4), Range::new(4, 13)),\n                    (1, Range::new(5, 5), Range::new(5, 13)),\n                ],\n            ),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_next_sub_word_end(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_start_of_next_long_words() {\n        let tests = [\n            (\"Basic forward motion stops at the first space\",\n                vec![(1, Range::new(0, 0), Range::new(0, 6))]),\n            (\" Starting from a boundary advances the anchor\",\n                vec![(1, Range::new(0, 0), Range::new(1, 10))]),\n            (\"Long       whitespace gap is bridged by the head\",\n                vec![(1, Range::new(0, 0), Range::new(0, 11))]),\n            (\"Previous anchor is irrelevant for forward motions\",\n                vec![(1, Range::new(12, 0), Range::new(0, 9))]),\n            (\"    Starting from whitespace moves to last space in sequence\",\n                vec![(1, Range::new(0, 0), Range::new(0, 4))]),\n            (\"Starting from mid-word leaves anchor at start position and moves head\",\n                vec![(1, Range::new(3, 3), Range::new(3, 9))]),\n            (\"Identifiers_with_underscores are considered a single word\",\n                vec![(1, Range::new(0, 0), Range::new(0, 29))]),\n            (\"Jumping\\n    into starting whitespace selects the spaces before 'into'\",\n                vec![(1, Range::new(0, 7), Range::new(8, 12))]),\n            (\"alphanumeric.!,and.?=punctuation are not treated any differently than alphanumerics\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 33)),\n                ]),\n            (\"...   ... punctuation and spaces behave as expected\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 6)),\n                    (1, Range::new(0, 6), Range::new(6, 10)),\n                ]),\n            (\".._.._ punctuation is joined by underscores into a single word, as it behaves like alphanumerics\",\n                vec![(1, Range::new(0, 0), Range::new(0, 7))]),\n            (\"Newlines\\n\\nare bridged seamlessly.\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 8)),\n                    (1, Range::new(0, 8), Range::new(10, 14)),\n                ]),\n            (\"Jumping\\n\\n\\n\\n\\n\\n   from newlines to whitespace selects whitespace.\",\n                vec![\n                    (1, Range::new(0, 9), Range::new(13, 16)),\n                ]),\n            (\"A failed motion does not modify the range\",\n                vec![\n                    (3, Range::new(37, 41), Range::new(37, 41)),\n                ]),\n            (\"oh oh oh two character words!\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 3)),\n                    (1, Range::new(0, 3), Range::new(3, 6)),\n                    (1, Range::new(0, 1), Range::new(0, 3)),\n                ]),\n            (\"Multiple motions at once resolve correctly\",\n                vec![\n                    (3, Range::new(0, 0), Range::new(17, 20)),\n                ]),\n            (\"Excessive motions are performed partially\",\n                vec![\n                    (999, Range::new(0, 0), Range::new(32, 41)),\n                ]),\n            (\"\", // Edge case of moving forward in empty string\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 0)),\n                ]),\n            (\"\\n\\n\\n\\n\\n\", // Edge case of moving forward in all newlines\n                vec![\n                    (1, Range::new(0, 0), Range::new(5, 5)),\n                ]),\n            (\"\\n   \\n   \\n Jumping through alternated space blocks and newlines selects the space blocks\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(1, 4)),\n                    (1, Range::new(1, 4), Range::new(5, 8)),\n                ]),\n            (\"ヒー..リクス multibyte characters behave as normal characters, including their interaction with punctuation\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 8)),\n                ]),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_next_long_word_start(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_start_of_previous_words() {\n        let tests = [\n            (\"Basic backward motion from the middle of a word\",\n                vec![(1, Range::new(3, 3), Range::new(4, 0))]),\n\n            // // Why do we want this behavior?  The current behavior fails this\n            // // test, but seems better and more consistent.\n            // (\"Starting from after boundary retreats the anchor\",\n            //     vec![(1, Range::new(0, 9), Range::new(8, 0))]),\n\n            (\"    Jump to start of a word preceded by whitespace\",\n                vec![(1, Range::new(5, 5), Range::new(6, 4))]),\n            (\"    Jump to start of line from start of word preceded by whitespace\",\n                vec![(1, Range::new(4, 4), Range::new(4, 0))]),\n            (\"Previous anchor is irrelevant for backward motions\",\n                vec![(1, Range::new(12, 5), Range::new(6, 0))]),\n            (\"    Starting from whitespace moves to first space in sequence\",\n                vec![(1, Range::new(0, 4), Range::new(4, 0))]),\n            (\"Identifiers_with_underscores are considered a single word\",\n                vec![(1, Range::new(0, 20), Range::new(20, 0))]),\n            (\"Jumping\\n    \\nback through a newline selects whitespace\",\n                vec![(1, Range::new(0, 13), Range::new(12, 8))]),\n            (\"Jumping to start of word from the end selects the word\",\n                vec![(1, Range::new(6, 7), Range::new(7, 0))]),\n            (\"alphanumeric.!,and.?=punctuation are considered 'words' for the purposes of word motion\",\n                vec![\n                    (1, Range::new(29, 30), Range::new(30, 21)),\n                    (1, Range::new(30, 21), Range::new(21, 18)),\n                    (1, Range::new(21, 18), Range::new(18, 15))\n                ]),\n            (\"...   ... punctuation and spaces behave as expected\",\n                vec![\n                    (1, Range::new(0, 10), Range::new(10, 6)),\n                    (1, Range::new(10, 6), Range::new(6, 0)),\n                ]),\n            (\".._.._ punctuation is not joined by underscores into a single block\",\n                vec![(1, Range::new(0, 6), Range::new(5, 3))]),\n            (\"Newlines\\n\\nare bridged seamlessly.\",\n                vec![\n                    (1, Range::new(0, 10), Range::new(8, 0)),\n                ]),\n            (\"Jumping    \\n\\n\\n\\n\\nback from within a newline group selects previous block\",\n                vec![\n                    (1, Range::new(0, 13), Range::new(11, 0)),\n                ]),\n            (\"Failed motions do not modify the range\",\n                vec![\n                    (0, Range::new(3, 0), Range::new(3, 0)),\n                ]),\n            (\"Multiple motions at once resolve correctly\",\n                vec![\n                    (3, Range::new(18, 18), Range::new(9, 0)),\n                ]),\n            (\"Excessive motions are performed partially\",\n                vec![\n                    (999, Range::new(40, 40), Range::new(10, 0)),\n                ]),\n            (\"\", // Edge case of moving backwards in empty string\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 0)),\n                ]),\n            (\"\\n\\n\\n\\n\\n\", // Edge case of moving backwards in all newlines\n                vec![\n                    (1, Range::new(5, 5), Range::new(0, 0)),\n                ]),\n            (\"   \\n   \\nJumping back through alternated space blocks and newlines selects the space blocks\",\n                vec![\n                    (1, Range::new(0, 8), Range::new(7, 4)),\n                    (1, Range::new(7, 4), Range::new(3, 0)),\n                ]),\n            (\"ヒーリクス multibyte characters behave as normal characters\",\n                vec![\n                    (1, Range::new(0, 6), Range::new(6, 0)),\n                ]),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_prev_word_start(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_start_of_previous_sub_words() {\n        let tests = [\n            (\n                \"PrevSubwordEnd\",\n                vec![\n                    (1, Range::new(13, 13), Range::new(14, 11)),\n                    (1, Range::new(11, 11), Range::new(11, 4)),\n                ],\n            ),\n            (\n                \"prev subword end\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 13)),\n                    (1, Range::new(12, 12), Range::new(13, 5)),\n                ],\n            ),\n            (\n                \"Prev Subword End\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 13)),\n                    (1, Range::new(12, 12), Range::new(13, 5)),\n                ],\n            ),\n            (\n                \"PREV SUBWORD END\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 13)),\n                    (1, Range::new(12, 12), Range::new(13, 5)),\n                ],\n            ),\n            (\n                \"prev_subword_end\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 13)),\n                    (1, Range::new(12, 12), Range::new(13, 5)),\n                ],\n            ),\n            (\n                \"Prev_Subword_End\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 13)),\n                    (1, Range::new(12, 12), Range::new(13, 5)),\n                ],\n            ),\n            (\n                \"PREV_SUBWORD_END\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 13)),\n                    (1, Range::new(12, 12), Range::new(13, 5)),\n                ],\n            ),\n            (\n                \"prev__subword__end\",\n                vec![\n                    (1, Range::new(17, 17), Range::new(18, 15)),\n                    (1, Range::new(13, 13), Range::new(14, 6)),\n                    (1, Range::new(14, 14), Range::new(15, 6)),\n                ],\n            ),\n            (\n                \"Prev__Subword__End\",\n                vec![\n                    (1, Range::new(17, 17), Range::new(18, 15)),\n                    (1, Range::new(13, 13), Range::new(14, 6)),\n                    (1, Range::new(14, 14), Range::new(15, 6)),\n                ],\n            ),\n            (\n                \"PREV__SUBWORD__END\",\n                vec![\n                    (1, Range::new(17, 17), Range::new(18, 15)),\n                    (1, Range::new(13, 13), Range::new(14, 6)),\n                    (1, Range::new(14, 14), Range::new(15, 6)),\n                ],\n            ),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_prev_sub_word_start(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_start_of_previous_long_words() {\n        let tests = [\n            (\n                \"Basic backward motion from the middle of a word\",\n                vec![(1, Range::new(3, 3), Range::new(4, 0))],\n            ),\n\n            // // Why do we want this behavior?  The current behavior fails this\n            // // test, but seems better and more consistent.\n            // (\"Starting from after boundary retreats the anchor\",\n            //     vec![(1, Range::new(0, 9), Range::new(8, 0))]),\n\n            (\n                \"    Jump to start of a word preceded by whitespace\",\n                vec![(1, Range::new(5, 5), Range::new(6, 4))],\n            ),\n            (\n                \"    Jump to start of line from start of word preceded by whitespace\",\n                vec![(1, Range::new(3, 4), Range::new(4, 0))],\n            ),\n            (\"Previous anchor is irrelevant for backward motions\",\n                vec![(1, Range::new(12, 5), Range::new(6, 0))]),\n            (\n                \"    Starting from whitespace moves to first space in sequence\",\n                vec![(1, Range::new(0, 4), Range::new(4, 0))],\n            ),\n            (\"Identifiers_with_underscores are considered a single word\",\n                vec![(1, Range::new(0, 20), Range::new(20, 0))]),\n            (\n                \"Jumping\\n    \\nback through a newline selects whitespace\",\n                vec![(1, Range::new(0, 13), Range::new(12, 8))],\n            ),\n            (\n                \"Jumping to start of word from the end selects the word\",\n                vec![(1, Range::new(6, 7), Range::new(7, 0))],\n            ),\n            (\n                \"alphanumeric.!,and.?=punctuation are treated exactly the same\",\n                vec![(1, Range::new(29, 30), Range::new(30, 0))],\n            ),\n            (\n                \"...   ... punctuation and spaces behave as expected\",\n                vec![\n                    (1, Range::new(0, 10), Range::new(10, 6)),\n                    (1, Range::new(10, 6), Range::new(6, 0)),\n                ],\n            ),\n            (\".._.._ punctuation is joined by underscores into a single block\",\n                vec![(1, Range::new(0, 6), Range::new(6, 0))]),\n            (\n                \"Newlines\\n\\nare bridged seamlessly.\",\n                vec![(1, Range::new(0, 10), Range::new(8, 0))],\n            ),\n            (\n                \"Jumping    \\n\\n\\n\\n\\nback from within a newline group selects previous block\",\n                vec![(1, Range::new(0, 13), Range::new(11, 0))],\n            ),\n            (\n                \"Failed motions do not modify the range\",\n                vec![(0, Range::new(3, 0), Range::new(3, 0))],\n            ),\n            (\n                \"Multiple motions at once resolve correctly\",\n                vec![(3, Range::new(19, 19), Range::new(9, 0))],\n            ),\n            (\n                \"Excessive motions are performed partially\",\n                vec![(999, Range::new(40, 40), Range::new(10, 0))],\n            ),\n            (\n                \"\", // Edge case of moving backwards in empty string\n                vec![(1, Range::new(0, 0), Range::new(0, 0))],\n            ),\n            (\n                \"\\n\\n\\n\\n\\n\", // Edge case of moving backwards in all newlines\n                vec![(1, Range::new(5, 5), Range::new(0, 0))],\n            ),\n            (\"   \\n   \\nJumping back through alternated space blocks and newlines selects the space blocks\",\n                vec![\n                    (1, Range::new(0, 8), Range::new(7, 4)),\n                    (1, Range::new(7, 4), Range::new(3, 0)),\n                ]),\n            (\"ヒーリ..クス multibyte characters behave as normal characters, including when interacting with punctuation\",\n                vec![\n                    (1, Range::new(0, 8), Range::new(8, 0)),\n                ]),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_prev_long_word_start(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_end_of_next_words() {\n        let tests = [\n            (\"Basic forward motion from the start of a word to the end of it\",\n                vec![(1, Range::new(0, 0), Range::new(0, 5))]),\n            (\"Basic forward motion from the end of a word to the end of the next\",\n                vec![(1, Range::new(0, 5), Range::new(5, 13))]),\n            (\"Basic forward motion from the middle of a word to the end of it\",\n                vec![(1, Range::new(2, 2), Range::new(2, 5))]),\n            (\"    Jumping to end of a word preceded by whitespace\",\n                vec![(1, Range::new(0, 0), Range::new(0, 11))]),\n\n            // // Why do we want this behavior?  The current behavior fails this\n            // // test, but seems better and more consistent.\n            // (\" Starting from a boundary advances the anchor\",\n            //     vec![(1, Range::new(0, 0), Range::new(1, 9))]),\n\n            (\"Previous anchor is irrelevant for end of word motion\",\n                vec![(1, Range::new(12, 2), Range::new(2, 8))]),\n            (\"Identifiers_with_underscores are considered a single word\",\n                vec![(1, Range::new(0, 0), Range::new(0, 28))]),\n            (\"Jumping\\n    into starting whitespace selects up to the end of next word\",\n                vec![(1, Range::new(0, 7), Range::new(8, 16))]),\n            (\"alphanumeric.!,and.?=punctuation are considered 'words' for the purposes of word motion\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 12)),\n                    (1, Range::new(0, 12), Range::new(12, 15)),\n                    (1, Range::new(12, 15), Range::new(15, 18))\n                ]),\n            (\"...   ... punctuation and spaces behave as expected\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 3)),\n                    (1, Range::new(0, 3), Range::new(3, 9)),\n                ]),\n            (\".._.._ punctuation is not joined by underscores into a single block\",\n                vec![(1, Range::new(0, 0), Range::new(0, 2))]),\n            (\"Newlines\\n\\nare bridged seamlessly.\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 8)),\n                    (1, Range::new(0, 8), Range::new(10, 13)),\n                ]),\n            (\"Jumping\\n\\n\\n\\n\\n\\n   from newlines to whitespace selects to end of next word.\",\n                vec![\n                    (1, Range::new(0, 8), Range::new(13, 20)),\n                ]),\n            (\"A failed motion does not modify the range\",\n                vec![\n                    (3, Range::new(37, 41), Range::new(37, 41)),\n                ]),\n            (\"Multiple motions at once resolve correctly\",\n                vec![\n                    (3, Range::new(0, 0), Range::new(16, 19)),\n                ]),\n            (\"Excessive motions are performed partially\",\n                vec![\n                    (999, Range::new(0, 0), Range::new(31, 41)),\n                ]),\n            (\"\", // Edge case of moving forward in empty string\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 0)),\n                ]),\n            (\"\\n\\n\\n\\n\\n\", // Edge case of moving forward in all newlines\n                vec![\n                    (1, Range::new(0, 0), Range::new(5, 5)),\n                ]),\n            (\"\\n   \\n   \\n Jumping through alternated space blocks and newlines selects the space blocks\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(1, 4)),\n                    (1, Range::new(1, 4), Range::new(5, 8)),\n                ]),\n            (\"ヒーリクス multibyte characters behave as normal characters\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 5)),\n                ]),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_next_word_end(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_end_of_previous_words() {\n        let tests = [\n            (\"Basic backward motion from the middle of a word\",\n                vec![(1, Range::new(9, 9), Range::new(10, 5))]),\n            (\"Starting from after boundary retreats the anchor\",\n                vec![(1, Range::new(0, 14), Range::new(13, 8))]),\n            (\"Jump     to end of a word succeeded by whitespace\",\n                vec![(1, Range::new(11, 11), Range::new(11, 4))]),\n            (\"    Jump to start of line from end of word preceded by whitespace\",\n                vec![(1, Range::new(8, 8), Range::new(8, 0))]),\n            (\"Previous anchor is irrelevant for backward motions\",\n                vec![(1, Range::new(26, 12), Range::new(13, 8))]),\n            (\"    Starting from whitespace moves to first space in sequence\",\n                vec![(1, Range::new(0, 4), Range::new(4, 0))]),\n            (\"Test identifiers_with_underscores are considered a single word\",\n                vec![(1, Range::new(0, 25), Range::new(25, 4))]),\n            (\"Jumping\\n    \\nback through a newline selects whitespace\",\n                vec![(1, Range::new(0, 13), Range::new(12, 8))]),\n            (\"Jumping to start of word from the end selects the whole word\",\n                vec![(1, Range::new(16, 16), Range::new(16, 10))]),\n            (\"alphanumeric.!,and.?=punctuation are considered 'words' for the purposes of word motion\",\n                vec![\n                    (1, Range::new(30, 30), Range::new(31, 21)),\n                    (1, Range::new(31, 21), Range::new(21, 18)),\n                    (1, Range::new(21, 18), Range::new(18, 15))\n                ]),\n\n            (\"...   ... punctuation and spaces behave as expected\",\n                vec![\n                    (1, Range::new(0, 10), Range::new(9, 3)),\n                    (1, Range::new(9, 3), Range::new(3, 0)),\n                ]),\n            (\".._.._ punctuation is not joined by underscores into a single block\",\n                vec![(1, Range::new(0, 5), Range::new(5, 3))]),\n            (\"Newlines\\n\\nare bridged seamlessly.\",\n                vec![\n                    (1, Range::new(0, 10), Range::new(8, 0)),\n                ]),\n            (\"Jumping    \\n\\n\\n\\n\\nback from within a newline group selects previous block\",\n                vec![\n                    (1, Range::new(0, 13), Range::new(11, 7)),\n                ]),\n            (\"Failed motions do not modify the range\",\n                vec![\n                    (0, Range::new(3, 0), Range::new(3, 0)),\n                ]),\n            (\"Multiple motions at once resolve correctly\",\n                vec![\n                    (3, Range::new(24, 24), Range::new(16, 8)),\n                ]),\n            (\"Excessive motions are performed partially\",\n                vec![\n                    (999, Range::new(40, 40), Range::new(9, 0)),\n                ]),\n            (\"\", // Edge case of moving backwards in empty string\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 0)),\n                ]),\n            (\"\\n\\n\\n\\n\\n\", // Edge case of moving backwards in all newlines\n                vec![\n                    (1, Range::new(5, 5), Range::new(0, 0)),\n                ]),\n            (\"   \\n   \\nJumping back through alternated space blocks and newlines selects the space blocks\",\n                vec![\n                    (1, Range::new(0, 8), Range::new(7, 4)),\n                    (1, Range::new(7, 4), Range::new(3, 0)),\n                ]),\n            (\"Test ヒーリクス multibyte characters behave as normal characters\",\n                vec![\n                    (1, Range::new(0, 10), Range::new(10, 4)),\n                ]),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_prev_word_end(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_end_of_previous_sub_words() {\n        let tests = [\n            (\n                \"PrevSubwordEnd\",\n                vec![\n                    (1, Range::new(13, 13), Range::new(14, 11)),\n                    (1, Range::new(11, 11), Range::new(11, 4)),\n                ],\n            ),\n            (\n                \"prev subword end\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 12)),\n                    (1, Range::new(12, 12), Range::new(12, 4)),\n                ],\n            ),\n            (\n                \"Prev Subword End\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 12)),\n                    (1, Range::new(12, 12), Range::new(12, 4)),\n                ],\n            ),\n            (\n                \"PREV SUBWORD END\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 12)),\n                    (1, Range::new(12, 12), Range::new(12, 4)),\n                ],\n            ),\n            (\n                \"prev_subword_end\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 12)),\n                    (1, Range::new(12, 12), Range::new(12, 4)),\n                ],\n            ),\n            (\n                \"Prev_Subword_End\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 12)),\n                    (1, Range::new(12, 12), Range::new(12, 4)),\n                ],\n            ),\n            (\n                \"PREV_SUBWORD_END\",\n                vec![\n                    (1, Range::new(15, 15), Range::new(16, 12)),\n                    (1, Range::new(12, 12), Range::new(12, 4)),\n                ],\n            ),\n            (\n                \"prev__subword__end\",\n                vec![\n                    (1, Range::new(17, 17), Range::new(18, 13)),\n                    (1, Range::new(13, 13), Range::new(13, 4)),\n                    (1, Range::new(14, 14), Range::new(15, 13)),\n                ],\n            ),\n            (\n                \"Prev__Subword__End\",\n                vec![\n                    (1, Range::new(17, 17), Range::new(18, 13)),\n                    (1, Range::new(13, 13), Range::new(13, 4)),\n                    (1, Range::new(14, 14), Range::new(15, 13)),\n                ],\n            ),\n            (\n                \"PREV__SUBWORD__END\",\n                vec![\n                    (1, Range::new(17, 17), Range::new(18, 13)),\n                    (1, Range::new(13, 13), Range::new(13, 4)),\n                    (1, Range::new(14, 14), Range::new(15, 13)),\n                ],\n            ),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_prev_sub_word_end(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_end_of_next_long_words() {\n        let tests = [\n            (\"Basic forward motion from the start of a word to the end of it\",\n                vec![(1, Range::new(0, 0), Range::new(0, 5))]),\n            (\"Basic forward motion from the end of a word to the end of the next\",\n                vec![(1, Range::new(0, 5), Range::new(5, 13))]),\n            (\"Basic forward motion from the middle of a word to the end of it\",\n                vec![(1, Range::new(2, 2), Range::new(2, 5))]),\n            (\"    Jumping to end of a word preceded by whitespace\",\n                vec![(1, Range::new(0, 0), Range::new(0, 11))]),\n\n            // // Why do we want this behavior?  The current behavior fails this\n            // // test, but seems better and more consistent.\n            // (\" Starting from a boundary advances the anchor\",\n            //     vec![(1, Range::new(0, 0), Range::new(1, 9))]),\n\n            (\"Previous anchor is irrelevant for end of word motion\",\n                vec![(1, Range::new(12, 2), Range::new(2, 8))]),\n            (\"Identifiers_with_underscores are considered a single word\",\n                vec![(1, Range::new(0, 0), Range::new(0, 28))]),\n            (\"Jumping\\n    into starting whitespace selects up to the end of next word\",\n                vec![(1, Range::new(0, 7), Range::new(8, 16))]),\n            (\"alphanumeric.!,and.?=punctuation are treated the same way\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 32)),\n                ]),\n            (\"...   ... punctuation and spaces behave as expected\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 3)),\n                    (1, Range::new(0, 3), Range::new(3, 9)),\n                ]),\n            (\".._.._ punctuation is joined by underscores into a single block\",\n                vec![(1, Range::new(0, 0), Range::new(0, 6))]),\n            (\"Newlines\\n\\nare bridged seamlessly.\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 8)),\n                    (1, Range::new(0, 8), Range::new(10, 13)),\n                ]),\n            (\"Jumping\\n\\n\\n\\n\\n\\n   from newlines to whitespace selects to end of next word.\",\n                vec![\n                    (1, Range::new(0, 9), Range::new(13, 20)),\n                ]),\n            (\"A failed motion does not modify the range\",\n                vec![\n                    (3, Range::new(37, 41), Range::new(37, 41)),\n                ]),\n            (\"Multiple motions at once resolve correctly\",\n                vec![\n                    (3, Range::new(0, 0), Range::new(16, 19)),\n                ]),\n            (\"Excessive motions are performed partially\",\n                vec![\n                    (999, Range::new(0, 0), Range::new(31, 41)),\n                ]),\n            (\"\", // Edge case of moving forward in empty string\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 0)),\n                ]),\n            (\"\\n\\n\\n\\n\\n\", // Edge case of moving forward in all newlines\n                vec![\n                    (1, Range::new(0, 0), Range::new(5, 5)),\n                ]),\n            (\"\\n   \\n   \\n Jumping through alternated space blocks and newlines selects the space blocks\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(1, 4)),\n                    (1, Range::new(1, 4), Range::new(5, 8)),\n                ]),\n            (\"ヒーリ..クス multibyte characters behave as normal characters, including  when they interact with punctuation\",\n                vec![\n                    (1, Range::new(0, 0), Range::new(0, 7)),\n                ]),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_next_long_word_end(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_end_of_prev_long_words() {\n        let tests = [\n            (\n                \"Basic backward motion from the middle of a word\",\n                vec![(1, Range::new(3, 3), Range::new(4, 0))],\n            ),\n            (\"Starting from after boundary retreats the anchor\",\n                vec![(1, Range::new(0, 9), Range::new(8, 0))],\n            ),\n            (\n                \"Jump    to end of a word succeeded by whitespace\",\n                vec![(1, Range::new(10, 10), Range::new(10, 4))],\n            ),\n            (\n                \"    Jump to start of line from end of word preceded by whitespace\",\n                vec![(1, Range::new(3, 4), Range::new(4, 0))],\n            ),\n            (\"Previous anchor is irrelevant for backward motions\",\n                vec![(1, Range::new(12, 5), Range::new(6, 0))]),\n            (\n                \"    Starting from whitespace moves to first space in sequence\",\n                vec![(1, Range::new(0, 4), Range::new(4, 0))],\n            ),\n            (\"Identifiers_with_underscores are considered a single word\",\n                vec![(1, Range::new(0, 20), Range::new(20, 0))]),\n            (\n                \"Jumping\\n    \\nback through a newline selects whitespace\",\n                vec![(1, Range::new(0, 13), Range::new(12, 8))],\n            ),\n            (\n                \"Jumping to start of word from the end selects the word\",\n                vec![(1, Range::new(6, 7), Range::new(7, 0))],\n            ),\n            (\n                \"alphanumeric.!,and.?=punctuation are treated exactly the same\",\n                vec![(1, Range::new(29, 30), Range::new(30, 0))],\n            ),\n            (\n                \"...   ... punctuation and spaces behave as expected\",\n                vec![\n                    (1, Range::new(0, 10), Range::new(9, 3)),\n                    (1, Range::new(10, 6), Range::new(7, 3)),\n                ],\n            ),\n            (\".._.._ punctuation is joined by underscores into a single block\",\n                vec![(1, Range::new(0, 6), Range::new(6, 0))]),\n            (\n                \"Newlines\\n\\nare bridged seamlessly.\",\n                vec![(1, Range::new(0, 10), Range::new(8, 0))],\n            ),\n            (\n                \"Jumping    \\n\\n\\n\\n\\nback from within a newline group selects previous block\",\n                vec![(1, Range::new(0, 13), Range::new(11, 7))],\n            ),\n            (\n                \"Failed motions do not modify the range\",\n                vec![(0, Range::new(3, 0), Range::new(3, 0))],\n            ),\n            (\n                \"Multiple motions at once resolve correctly\",\n                vec![(3, Range::new(19, 19), Range::new(8, 0))],\n            ),\n            (\n                \"Excessive motions are performed partially\",\n                vec![(999, Range::new(40, 40), Range::new(9, 0))],\n            ),\n            (\n                \"\", // Edge case of moving backwards in empty string\n                vec![(1, Range::new(0, 0), Range::new(0, 0))],\n            ),\n            (\n                \"\\n\\n\\n\\n\\n\", // Edge case of moving backwards in all newlines\n                vec![(1, Range::new(5, 5), Range::new(0, 0))],\n            ),\n            (\"   \\n   \\nJumping back through alternated space blocks and newlines selects the space blocks\",\n                vec![\n                    (1, Range::new(0, 8), Range::new(7, 4)),\n                    (1, Range::new(7, 4), Range::new(3, 0)),\n                ]),\n            (\"ヒーリ..クス multibyte characters behave as normal characters, including when interacting with punctuation\",\n                vec![\n                    (1, Range::new(0, 8), Range::new(7, 0)),\n                ]),\n        ];\n\n        for (sample, scenario) in tests {\n            for (count, begin, expected_end) in scenario.into_iter() {\n                let range = move_prev_long_word_end(Rope::from(sample).slice(..), begin, count);\n                assert_eq!(range, expected_end, \"Case failed: [{}]\", sample);\n            }\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_prev_paragraph_single() {\n        let tests = [\n            (\"#[|]#\", \"#[|]#\"),\n            (\"#[s|]#tart at\\nfirst char\\n\", \"#[|s]#tart at\\nfirst char\\n\"),\n            (\"start at\\nlast char#[\\n|]#\", \"#[|start at\\nlast char\\n]#\"),\n            (\n                \"goto\\nfirst\\n\\n#[p|]#aragraph\",\n                \"#[|goto\\nfirst\\n\\n]#paragraph\",\n            ),\n            (\n                \"goto\\nfirst\\n#[\\n|]#paragraph\",\n                \"#[|goto\\nfirst\\n\\n]#paragraph\",\n            ),\n            (\n                \"goto\\nsecond\\n\\np#[a|]#ragraph\",\n                \"goto\\nsecond\\n\\n#[|pa]#ragraph\",\n            ),\n            (\n                \"here\\n\\nhave\\nmultiple\\nparagraph\\n\\n\\n\\n\\n#[|]#\",\n                \"here\\n\\n#[|have\\nmultiple\\nparagraph\\n\\n\\n\\n\\n]#\",\n            ),\n        ];\n\n        for (before, expected) in tests {\n            let (s, selection) = crate::test::print(before);\n            let text = Rope::from(s.as_str());\n            let selection =\n                selection.transform(|r| move_prev_paragraph(text.slice(..), r, 1, Movement::Move));\n            let actual = crate::test::plain(s.as_ref(), &selection);\n            assert_eq!(actual, expected, \"\\nbefore: `{:?}`\", before);\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_prev_paragraph_double() {\n        let tests = [\n            (\n                \"on#[e|]#\\n\\ntwo\\n\\nthree\\n\\n\",\n                \"#[|one]#\\n\\ntwo\\n\\nthree\\n\\n\",\n            ),\n            (\n                \"one\\n\\ntwo\\n\\nth#[r|]#ee\\n\\n\",\n                \"one\\n\\n#[|two\\n\\nthr]#ee\\n\\n\",\n            ),\n        ];\n\n        for (before, expected) in tests {\n            let (s, selection) = crate::test::print(before);\n            let text = Rope::from(s.as_str());\n            let selection =\n                selection.transform(|r| move_prev_paragraph(text.slice(..), r, 2, Movement::Move));\n            let actual = crate::test::plain(s.as_ref(), &selection);\n            assert_eq!(actual, expected, \"\\nbefore: `{:?}`\", before);\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_prev_paragraph_extend() {\n        let tests = [\n            (\n                \"one\\n\\n#[|two\\n\\n]#three\\n\\n\",\n                \"#[|one\\n\\ntwo\\n\\n]#three\\n\\n\",\n            ),\n            (\n                \"#[|one\\n\\ntwo\\n\\n]#three\\n\\n\",\n                \"#[|one\\n\\ntwo\\n\\n]#three\\n\\n\",\n            ),\n        ];\n\n        for (before, expected) in tests {\n            let (s, selection) = crate::test::print(before);\n            let text = Rope::from(s.as_str());\n            let selection = selection\n                .transform(|r| move_prev_paragraph(text.slice(..), r, 1, Movement::Extend));\n            let actual = crate::test::plain(s.as_ref(), &selection);\n            assert_eq!(actual, expected, \"\\nbefore: `{:?}`\", before);\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_next_paragraph_single() {\n        let tests = [\n            (\"#[|]#\", \"#[|]#\"),\n            (\"#[s|]#tart at\\nfirst char\\n\", \"#[start at\\nfirst char\\n|]#\"),\n            (\"start at\\nlast char#[\\n|]#\", \"start at\\nlast char#[\\n|]#\"),\n            (\n                \"a\\nb\\n\\n#[g|]#oto\\nthird\\n\\nparagraph\",\n                \"a\\nb\\n\\n#[goto\\nthird\\n\\n|]#paragraph\",\n            ),\n            (\n                \"a\\nb\\n#[\\n|]#goto\\nthird\\n\\nparagraph\",\n                \"a\\nb\\n\\n#[goto\\nthird\\n\\n|]#paragraph\",\n            ),\n            (\n                \"a\\nb#[\\n|]#\\n\\ngoto\\nsecond\\n\\nparagraph\",\n                \"a\\nb#[\\n\\n|]#goto\\nsecond\\n\\nparagraph\",\n            ),\n            (\n                \"here\\n\\nhave\\n#[m|]#ultiple\\nparagraph\\n\\n\\n\\n\\n\",\n                \"here\\n\\nhave\\n#[multiple\\nparagraph\\n\\n\\n\\n\\n|]#\",\n            ),\n            (\n                \"#[t|]#ext\\n\\n\\nafter two blank lines\\n\\nmore text\\n\",\n                \"#[text\\n\\n\\n|]#after two blank lines\\n\\nmore text\\n\",\n            ),\n            (\n                \"#[text\\n\\n\\n|]#after two blank lines\\n\\nmore text\\n\",\n                \"text\\n\\n\\n#[after two blank lines\\n\\n|]#more text\\n\",\n            ),\n        ];\n\n        for (before, expected) in tests {\n            let (s, selection) = crate::test::print(before);\n            let text = Rope::from(s.as_str());\n            let selection =\n                selection.transform(|r| move_next_paragraph(text.slice(..), r, 1, Movement::Move));\n            let actual = crate::test::plain(s.as_ref(), &selection);\n            assert_eq!(actual, expected, \"\\nbefore: `{:?}`\", before);\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_next_paragraph_double() {\n        let tests = [\n            (\n                \"one\\n\\ntwo\\n\\nth#[r|]#ee\\n\\n\",\n                \"one\\n\\ntwo\\n\\nth#[ree\\n\\n|]#\",\n            ),\n            (\n                \"on#[e|]#\\n\\ntwo\\n\\nthree\\n\\n\",\n                \"on#[e\\n\\ntwo\\n\\n|]#three\\n\\n\",\n            ),\n        ];\n\n        for (before, expected) in tests {\n            let (s, selection) = crate::test::print(before);\n            let text = Rope::from(s.as_str());\n            let selection =\n                selection.transform(|r| move_next_paragraph(text.slice(..), r, 2, Movement::Move));\n            let actual = crate::test::plain(s.as_ref(), &selection);\n            assert_eq!(actual, expected, \"\\nbefore: `{:?}`\", before);\n        }\n    }\n\n    #[test]\n    fn test_behaviour_when_moving_to_next_paragraph_extend() {\n        let tests = [\n            (\n                \"one\\n\\n#[two\\n\\n|]#three\\n\\n\",\n                \"one\\n\\n#[two\\n\\nthree\\n\\n|]#\",\n            ),\n            (\n                \"one\\n\\n#[two\\n\\nthree\\n\\n|]#\",\n                \"one\\n\\n#[two\\n\\nthree\\n\\n|]#\",\n            ),\n        ];\n\n        for (before, expected) in tests {\n            let (s, selection) = crate::test::print(before);\n            let text = Rope::from(s.as_str());\n            let selection = selection\n                .transform(|r| move_next_paragraph(text.slice(..), r, 1, Movement::Extend));\n            let actual = crate::test::plain(s.as_ref(), &selection);\n            assert_eq!(actual, expected, \"\\nbefore: `{:?}`\", before);\n        }\n    }\n}\n"
  },
  {
    "path": "helix-core/src/object.rs",
    "content": "use crate::{movement::Direction, syntax::TreeCursor, Range, RopeSlice, Selection, Syntax};\n\npub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {\n    let cursor = &mut syntax.walk();\n\n    selection.transform(|range| {\n        let from = text.char_to_byte(range.from()) as u32;\n        let to = text.char_to_byte(range.to()) as u32;\n\n        let byte_range = from..to;\n        cursor.reset_to_byte_range(from, to);\n\n        while cursor.node().byte_range() == byte_range {\n            if !cursor.goto_parent() {\n                break;\n            }\n        }\n\n        let node = cursor.node();\n        let from = text.byte_to_char(node.start_byte() as usize);\n        let to = text.byte_to_char(node.end_byte() as usize);\n\n        Range::new(to, from).with_direction(range.direction())\n    })\n}\n\npub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {\n    select_node_impl(\n        syntax,\n        text,\n        selection,\n        |cursor| {\n            cursor.goto_first_child();\n        },\n        None,\n    )\n}\n\npub fn select_next_sibling(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {\n    select_node_impl(\n        syntax,\n        text,\n        selection,\n        |cursor| {\n            while !cursor.goto_next_sibling() {\n                if !cursor.goto_parent() {\n                    break;\n                }\n            }\n        },\n        Some(Direction::Forward),\n    )\n}\n\npub fn select_all_siblings(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {\n    let mut cursor = syntax.walk();\n    selection.transform_iter(move |range| {\n        let (from, to) = range.into_byte_range(text);\n        cursor.reset_to_byte_range(from as u32, to as u32);\n\n        if !cursor.goto_parent_with(|parent| parent.child_count() > 1) {\n            return vec![range].into_iter();\n        }\n\n        select_children(&mut cursor, text, range).into_iter()\n    })\n}\n\npub fn select_all_children(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {\n    let mut cursor = syntax.walk();\n    selection.transform_iter(move |range| {\n        let (from, to) = range.into_byte_range(text);\n        cursor.reset_to_byte_range(from as u32, to as u32);\n        select_children(&mut cursor, text, range).into_iter()\n    })\n}\n\nfn select_children(cursor: &mut TreeCursor, text: RopeSlice, range: Range) -> Vec<Range> {\n    let children = cursor\n        .children()\n        .filter(|child| child.is_named())\n        .map(|child| Range::from_node(child, text, range.direction()))\n        .collect::<Vec<_>>();\n\n    if !children.is_empty() {\n        children\n    } else {\n        vec![range]\n    }\n}\n\npub fn select_prev_sibling(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {\n    select_node_impl(\n        syntax,\n        text,\n        selection,\n        |cursor| {\n            while !cursor.goto_previous_sibling() {\n                if !cursor.goto_parent() {\n                    break;\n                }\n            }\n        },\n        Some(Direction::Backward),\n    )\n}\n\nfn select_node_impl<F>(\n    syntax: &Syntax,\n    text: RopeSlice,\n    selection: Selection,\n    motion: F,\n    direction: Option<Direction>,\n) -> Selection\nwhere\n    F: Fn(&mut TreeCursor),\n{\n    let cursor = &mut syntax.walk();\n\n    selection.transform(|range| {\n        let from = text.char_to_byte(range.from()) as u32;\n        let to = text.char_to_byte(range.to()) as u32;\n\n        cursor.reset_to_byte_range(from, to);\n\n        motion(cursor);\n\n        let node = cursor.node();\n        let from = text.byte_to_char(node.start_byte() as usize);\n        let to = text.byte_to_char(node.end_byte() as usize);\n\n        Range::new(from, to).with_direction(direction.unwrap_or_else(|| range.direction()))\n    })\n}\n"
  },
  {
    "path": "helix-core/src/position.rs",
    "content": "use std::{\n    borrow::Cow,\n    cmp::Ordering,\n    ops::{Add, AddAssign, Sub, SubAssign},\n};\n\nuse helix_stdx::rope::RopeSliceExt;\n\nuse crate::{\n    chars::char_is_line_ending,\n    doc_formatter::{DocumentFormatter, TextFormat},\n    graphemes::{ensure_grapheme_boundary_prev, grapheme_width},\n    line_ending::line_end_char_index,\n    text_annotations::TextAnnotations,\n    RopeSlice,\n};\n\n/// Represents a single point in a text buffer. Zero indexed.\n#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]\npub struct Position {\n    pub row: usize,\n    pub col: usize,\n}\n\nimpl AddAssign for Position {\n    fn add_assign(&mut self, rhs: Self) {\n        self.row += rhs.row;\n        self.col += rhs.col;\n    }\n}\n\nimpl SubAssign for Position {\n    fn sub_assign(&mut self, rhs: Self) {\n        self.row -= rhs.row;\n        self.col -= rhs.col;\n    }\n}\n\nimpl Sub for Position {\n    type Output = Position;\n\n    fn sub(mut self, rhs: Self) -> Self::Output {\n        self -= rhs;\n        self\n    }\n}\n\nimpl Add for Position {\n    type Output = Position;\n\n    fn add(mut self, rhs: Self) -> Self::Output {\n        self += rhs;\n        self\n    }\n}\n\nimpl Position {\n    pub const fn new(row: usize, col: usize) -> Self {\n        Self { row, col }\n    }\n\n    pub const fn is_zero(self) -> bool {\n        self.row == 0 && self.col == 0\n    }\n\n    // TODO: generalize\n    pub fn traverse(self, text: &crate::Tendril) -> Self {\n        let Self { mut row, mut col } = self;\n        // TODO: there should be a better way here\n        let mut chars = text.chars().peekable();\n        while let Some(ch) = chars.next() {\n            if char_is_line_ending(ch) && !(ch == '\\r' && chars.peek() == Some(&'\\n')) {\n                row += 1;\n                col = 0;\n            } else {\n                col += 1;\n            }\n        }\n        Self { row, col }\n    }\n}\n\nimpl From<(usize, usize)> for Position {\n    fn from(tuple: (usize, usize)) -> Self {\n        Self {\n            row: tuple.0,\n            col: tuple.1,\n        }\n    }\n}\n\n/// Convert a character index to (line, column) coordinates.\n///\n/// column in `char` count which can be used for row:column display in\n/// status line. See [`visual_coords_at_pos`] for a visual one.\npub fn coords_at_pos(text: RopeSlice, pos: usize) -> Position {\n    let line = text.char_to_line(pos);\n\n    let line_start = text.line_to_char(line);\n    let pos = ensure_grapheme_boundary_prev(text, pos);\n    let col = text.slice(line_start..pos).graphemes().count();\n\n    Position::new(line, col)\n}\n\n/// Convert a character index to (line, column) coordinates visually.\n///\n/// Takes \\t, double-width characters (CJK) into account as well as text\n/// not in the document in the future.\n/// See [`coords_at_pos`] for an \"objective\" one.\n///\n/// This function should be used very rarely. Usually `visual_offset_from_anchor`\n/// or `visual_offset_from_block` is preferable. However when you want to compute the\n/// actual visual row/column in the text (not what is actually shown on screen)\n/// then you should use this function. For example aligning text should ignore virtual\n/// text and softwrap.\n#[deprecated = \"Doesn't account for softwrap or decorations, use visual_offset_from_anchor instead\"]\npub fn visual_coords_at_pos(text: RopeSlice, pos: usize, tab_width: usize) -> Position {\n    let line = text.char_to_line(pos);\n\n    let line_start = text.line_to_char(line);\n    let pos = ensure_grapheme_boundary_prev(text, pos);\n\n    let mut col = 0;\n\n    for grapheme in text.slice(line_start..pos).graphemes() {\n        if grapheme == \"\\t\" {\n            col += tab_width - (col % tab_width);\n        } else {\n            let grapheme = Cow::from(grapheme);\n            col += grapheme_width(&grapheme);\n        }\n    }\n\n    Position::new(line, col)\n}\n\n/// Returns the visual offset from the start of the first visual line\n/// in the block that contains anchor.\n/// Text is always wrapped at blocks, they usually correspond to\n/// actual line breaks but for very long lines\n/// softwrapping positions are estimated with an O(1) algorithm\n/// to ensure consistent performance for large lines (currently unimplemented)\n///\n/// Usually you want to use `visual_offset_from_anchor` instead but this function\n/// can be useful (and faster) if\n/// * You already know the visual position of the block\n/// * You only care about the horizontal offset (column) and not the vertical offset (row)\npub fn visual_offset_from_block(\n    text: RopeSlice,\n    anchor: usize,\n    pos: usize,\n    text_fmt: &TextFormat,\n    annotations: &TextAnnotations,\n) -> (Position, usize) {\n    let mut last_pos = Position::default();\n    let mut formatter =\n        DocumentFormatter::new_at_prev_checkpoint(text, text_fmt, annotations, anchor);\n    let block_start = formatter.next_char_pos();\n\n    while let Some(grapheme) = formatter.next() {\n        last_pos = grapheme.visual_pos;\n        if formatter.next_char_pos() > pos {\n            return (grapheme.visual_pos, block_start);\n        }\n    }\n\n    (last_pos, block_start)\n}\n\n/// Returns the height of the given text when softwrapping\npub fn softwrapped_dimensions(text: RopeSlice, text_fmt: &TextFormat) -> (usize, u16) {\n    let last_pos =\n        visual_offset_from_block(text, 0, usize::MAX, text_fmt, &TextAnnotations::default()).0;\n    if last_pos.row == 0 {\n        (1, last_pos.col as u16)\n    } else {\n        (last_pos.row + 1, text_fmt.viewport_width)\n    }\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Copy)]\npub enum VisualOffsetError {\n    PosBeforeAnchorRow,\n    PosAfterMaxRow,\n}\n\n/// Returns the visual offset from the start of the visual line\n/// that contains anchor.\npub fn visual_offset_from_anchor(\n    text: RopeSlice,\n    anchor: usize,\n    pos: usize,\n    text_fmt: &TextFormat,\n    annotations: &TextAnnotations,\n    max_rows: usize,\n) -> Result<(Position, usize), VisualOffsetError> {\n    let mut formatter =\n        DocumentFormatter::new_at_prev_checkpoint(text, text_fmt, annotations, anchor);\n    let mut anchor_line = None;\n    let mut found_pos = None;\n    let mut last_pos = Position::default();\n\n    let block_start = formatter.next_char_pos();\n    if pos < block_start {\n        return Err(VisualOffsetError::PosBeforeAnchorRow);\n    }\n\n    while let Some(grapheme) = formatter.next() {\n        last_pos = grapheme.visual_pos;\n\n        if formatter.next_char_pos() > pos {\n            if let Some(anchor_line) = anchor_line {\n                last_pos.row -= anchor_line;\n                return Ok((last_pos, block_start));\n            } else {\n                found_pos = Some(last_pos);\n            }\n        }\n        if formatter.next_char_pos() > anchor && anchor_line.is_none() {\n            if let Some(mut found_pos) = found_pos {\n                return if found_pos.row == last_pos.row {\n                    found_pos.row = 0;\n                    Ok((found_pos, block_start))\n                } else {\n                    Err(VisualOffsetError::PosBeforeAnchorRow)\n                };\n            } else {\n                anchor_line = Some(last_pos.row);\n            }\n        }\n\n        if let Some(anchor_line) = anchor_line {\n            if grapheme.visual_pos.row >= anchor_line + max_rows {\n                return Err(VisualOffsetError::PosAfterMaxRow);\n            }\n        }\n    }\n\n    let anchor_line = anchor_line.unwrap_or(last_pos.row);\n    last_pos.row -= anchor_line;\n\n    Ok((last_pos, block_start))\n}\n\n/// Convert (line, column) coordinates to a character index.\n///\n/// If the `line` coordinate is beyond the end of the file, the EOF\n/// position will be returned.\n///\n/// If the `column` coordinate is past the end of the given line, the\n/// line-end position will be returned.  What constitutes the \"line-end\n/// position\" depends on the parameter `limit_before_line_ending`.  If it's\n/// `true`, the line-end position will be just *before* the line ending\n/// character.  If `false` it will be just *after* the line ending\n/// character--on the border between the current line and the next.\n///\n/// Usually you only want `limit_before_line_ending` to be `true` if you're working\n/// with left-side block-cursor positions, as this prevents the the block cursor\n/// from jumping to the next line.  Otherwise you typically want it to be `false`,\n/// such as when dealing with raw anchor/head positions.\npub fn pos_at_coords(text: RopeSlice, coords: Position, limit_before_line_ending: bool) -> usize {\n    let Position { mut row, col } = coords;\n    if limit_before_line_ending {\n        let lines = text.len_lines() - 1;\n\n        row = row.min(if crate::line_ending::get_line_ending(&text).is_some() {\n            // if the last line is empty, don't jump to it\n            lines - 1\n        } else {\n            lines\n        });\n    };\n    let line_start = text.line_to_char(row);\n    let line_end = if limit_before_line_ending {\n        line_end_char_index(&text, row)\n    } else {\n        text.line_to_char((row + 1).min(text.len_lines()))\n    };\n\n    let mut col_char_offset = 0;\n    for (i, g) in text.slice(line_start..line_end).graphemes().enumerate() {\n        if i == col {\n            break;\n        }\n        col_char_offset += g.chars().count();\n    }\n\n    line_start + col_char_offset\n}\n\n/// Convert visual (line, column) coordinates to a character index.\n///\n/// If the `line` coordinate is beyond the end of the file, the EOF\n/// position will be returned.\n///\n/// If the `column` coordinate is past the end of the given line, the\n/// line-end position (in this case, just before the line ending\n/// character) will be returned.\n/// This function should be used very rarely. Usually `char_idx_at_visual_offset` is preferable.\n/// However when you want to compute a char position from the visual row/column in the text\n/// (not what is actually shown on screen) then you should use this function.\n/// For example aligning text should ignore virtual text and softwrap.\n#[deprecated = \"Doesn't account for softwrap or decorations, use char_idx_at_visual_offset instead\"]\npub fn pos_at_visual_coords(text: RopeSlice, coords: Position, tab_width: usize) -> usize {\n    let Position { mut row, col } = coords;\n    row = row.min(text.len_lines() - 1);\n    let line_start = text.line_to_char(row);\n    let line_end = line_end_char_index(&text, row);\n\n    let mut col_char_offset = 0;\n    let mut cols_remaining = col;\n    for grapheme in text.slice(line_start..line_end).graphemes() {\n        let grapheme_width = if grapheme == \"\\t\" {\n            tab_width - ((col - cols_remaining) % tab_width)\n        } else {\n            let grapheme = Cow::from(grapheme);\n            grapheme_width(&grapheme)\n        };\n\n        // If pos is in the middle of a wider grapheme (tab for example)\n        // return the starting offset.\n        if grapheme_width > cols_remaining {\n            break;\n        }\n\n        cols_remaining -= grapheme_width;\n        col_char_offset += grapheme.chars().count();\n    }\n\n    line_start + col_char_offset\n}\n\n/// Returns the char index on the visual line `row_offset` below the visual line of\n/// the provided char index `anchor` that is closest to the supplied visual `column`.\n///\n/// If the targeted visual line is entirely covered by virtual text the last\n/// char position before the virtual text and a virtual offset is returned instead.\n///\n/// If no (text) grapheme starts at exactly at the specified column the\n/// start of the grapheme to the left is returned. If there is no grapheme\n/// to the left (for example if the line starts with virtual text) then the positioning\n/// of the next grapheme to the right is returned.\n///\n/// If the `line` coordinate is beyond the end of the file, the EOF\n/// position will be returned.\n///\n/// If the `column` coordinate is past the end of the given line, the\n/// line-end position (in this case, just before the line ending\n/// character) will be returned.\n///\n/// # Returns\n///\n/// `(real_char_idx, virtual_lines)`\n///\n/// The nearest character idx \"closest\" (see above) to the specified visual offset\n/// on the visual line is returned if the visual line contains any text:\n/// If the visual line at the specified offset is a virtual line generated by a `LineAnnotation`\n/// the previous char_index is returned, together with the remaining vertical offset (`virtual_lines`)\npub fn char_idx_at_visual_offset(\n    text: RopeSlice,\n    mut anchor: usize,\n    mut row_offset: isize,\n    column: usize,\n    text_fmt: &TextFormat,\n    annotations: &TextAnnotations,\n) -> (usize, usize) {\n    let mut pos = anchor;\n    // convert row relative to visual line containing anchor to row relative to a block containing anchor (anchor may change)\n    loop {\n        let (visual_pos_in_block, block_char_offset) =\n            visual_offset_from_block(text, anchor, pos, text_fmt, annotations);\n        row_offset += visual_pos_in_block.row as isize;\n        anchor = block_char_offset;\n        if row_offset >= 0 {\n            break;\n        }\n\n        if block_char_offset == 0 {\n            row_offset = 0;\n            break;\n        }\n        // the row_offset is negative so we need to look at the previous block\n        // set the anchor to the last char before the current block so that we can compute\n        // the distance of this block from the start of the previous block\n        pos = anchor;\n        anchor -= 1;\n    }\n\n    char_idx_at_visual_block_offset(\n        text,\n        anchor,\n        row_offset as usize,\n        column,\n        text_fmt,\n        annotations,\n    )\n}\n\n/// This function behaves the same as `char_idx_at_visual_offset`, except that\n/// the vertical offset `row` is always computed relative to the block that contains `anchor`\n/// instead of the visual line that contains `anchor`.\n/// Usually `char_idx_at_visual_offset` is more useful but this function can be\n/// used in some situations as an optimization when `visual_offset_from_block` was used\n///\n/// # Returns\n///\n/// `(real_char_idx, virtual_lines)`\n///\n/// See `char_idx_at_visual_offset` for details\npub fn char_idx_at_visual_block_offset(\n    text: RopeSlice,\n    anchor: usize,\n    row: usize,\n    column: usize,\n    text_fmt: &TextFormat,\n    annotations: &TextAnnotations,\n) -> (usize, usize) {\n    let mut formatter =\n        DocumentFormatter::new_at_prev_checkpoint(text, text_fmt, annotations, anchor);\n    let mut last_char_idx = formatter.next_char_pos();\n    let mut found_non_virtual_on_row = false;\n    let mut last_row = 0;\n    for grapheme in &mut formatter {\n        match grapheme.visual_pos.row.cmp(&row) {\n            Ordering::Equal => {\n                if grapheme.visual_pos.col + grapheme.width() > column {\n                    if !grapheme.is_virtual() {\n                        return (grapheme.char_idx, 0);\n                    } else if found_non_virtual_on_row {\n                        return (last_char_idx, 0);\n                    }\n                } else if !grapheme.is_virtual() {\n                    found_non_virtual_on_row = true;\n                    last_char_idx = grapheme.char_idx;\n                }\n            }\n            Ordering::Greater if found_non_virtual_on_row => return (last_char_idx, 0),\n            Ordering::Greater => return (last_char_idx, row - last_row),\n            Ordering::Less => {\n                if !grapheme.is_virtual() {\n                    last_row = grapheme.visual_pos.row;\n                    last_char_idx = grapheme.char_idx;\n                }\n            }\n        }\n    }\n\n    (formatter.next_char_pos(), 0)\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::text_annotations::InlineAnnotation;\n    use crate::Rope;\n\n    #[test]\n    fn test_ordering() {\n        // (0, 5) is less than (1, 0)\n        assert!(Position::new(0, 5) < Position::new(1, 0));\n    }\n\n    #[test]\n    fn test_coords_at_pos() {\n        let text = Rope::from(\"ḧëḷḷö\\nẅöṛḷḋ\");\n        let slice = text.slice(..);\n        assert_eq!(coords_at_pos(slice, 0), (0, 0).into());\n        assert_eq!(coords_at_pos(slice, 5), (0, 5).into()); // position on \\n\n        assert_eq!(coords_at_pos(slice, 6), (1, 0).into()); // position on w\n        assert_eq!(coords_at_pos(slice, 7), (1, 1).into()); // position on o\n        assert_eq!(coords_at_pos(slice, 10), (1, 4).into()); // position on d\n\n        // Test with wide characters.\n        let text = Rope::from(\"今日はいい\\n\");\n        let slice = text.slice(..);\n        assert_eq!(coords_at_pos(slice, 0), (0, 0).into());\n        assert_eq!(coords_at_pos(slice, 1), (0, 1).into());\n        assert_eq!(coords_at_pos(slice, 2), (0, 2).into());\n        assert_eq!(coords_at_pos(slice, 3), (0, 3).into());\n        assert_eq!(coords_at_pos(slice, 4), (0, 4).into());\n        assert_eq!(coords_at_pos(slice, 5), (0, 5).into());\n        assert_eq!(coords_at_pos(slice, 6), (1, 0).into());\n\n        // Test with grapheme clusters.\n        let text = Rope::from(\"a̐éö̲\\r\\n\");\n        let slice = text.slice(..);\n        assert_eq!(coords_at_pos(slice, 0), (0, 0).into());\n        assert_eq!(coords_at_pos(slice, 2), (0, 1).into());\n        assert_eq!(coords_at_pos(slice, 4), (0, 2).into());\n        assert_eq!(coords_at_pos(slice, 7), (0, 3).into());\n        assert_eq!(coords_at_pos(slice, 9), (1, 0).into());\n\n        // Test with wide-character grapheme clusters.\n        let text = Rope::from(\"किमपि\\n\");\n        let slice = text.slice(..);\n        assert_eq!(coords_at_pos(slice, 0), (0, 0).into());\n        assert_eq!(coords_at_pos(slice, 2), (0, 1).into());\n        assert_eq!(coords_at_pos(slice, 3), (0, 2).into());\n        assert_eq!(coords_at_pos(slice, 5), (0, 3).into());\n        assert_eq!(coords_at_pos(slice, 6), (1, 0).into());\n\n        // Test with tabs.\n        let text = Rope::from(\"\\tHello\\n\");\n        let slice = text.slice(..);\n        assert_eq!(coords_at_pos(slice, 0), (0, 0).into());\n        assert_eq!(coords_at_pos(slice, 1), (0, 1).into());\n        assert_eq!(coords_at_pos(slice, 2), (0, 2).into());\n    }\n\n    #[test]\n    #[allow(deprecated)]\n    fn test_visual_coords_at_pos() {\n        let text = Rope::from(\"ḧëḷḷö\\nẅöṛḷḋ\");\n        let slice = text.slice(..);\n        assert_eq!(visual_coords_at_pos(slice, 0, 8), (0, 0).into());\n        assert_eq!(visual_coords_at_pos(slice, 5, 8), (0, 5).into()); // position on \\n\n        assert_eq!(visual_coords_at_pos(slice, 6, 8), (1, 0).into()); // position on w\n        assert_eq!(visual_coords_at_pos(slice, 7, 8), (1, 1).into()); // position on o\n        assert_eq!(visual_coords_at_pos(slice, 10, 8), (1, 4).into()); // position on d\n\n        // Test with wide characters.\n        let text = Rope::from(\"今日はいい\\n\");\n        let slice = text.slice(..);\n        assert_eq!(visual_coords_at_pos(slice, 0, 8), (0, 0).into());\n        assert_eq!(visual_coords_at_pos(slice, 1, 8), (0, 2).into());\n        assert_eq!(visual_coords_at_pos(slice, 2, 8), (0, 4).into());\n        assert_eq!(visual_coords_at_pos(slice, 3, 8), (0, 6).into());\n        assert_eq!(visual_coords_at_pos(slice, 4, 8), (0, 8).into());\n        assert_eq!(visual_coords_at_pos(slice, 5, 8), (0, 10).into());\n        assert_eq!(visual_coords_at_pos(slice, 6, 8), (1, 0).into());\n\n        // Test with grapheme clusters.\n        let text = Rope::from(\"a̐éö̲\\r\\n\");\n        let slice = text.slice(..);\n        assert_eq!(visual_coords_at_pos(slice, 0, 8), (0, 0).into());\n        assert_eq!(visual_coords_at_pos(slice, 2, 8), (0, 1).into());\n        assert_eq!(visual_coords_at_pos(slice, 4, 8), (0, 2).into());\n        assert_eq!(visual_coords_at_pos(slice, 7, 8), (0, 3).into());\n        assert_eq!(visual_coords_at_pos(slice, 9, 8), (1, 0).into());\n\n        // Test with wide-character grapheme clusters.\n        // TODO: account for cluster.\n        let text = Rope::from(\"किमपि\\n\");\n        let slice = text.slice(..);\n        assert_eq!(visual_coords_at_pos(slice, 0, 8), (0, 0).into());\n        assert_eq!(visual_coords_at_pos(slice, 2, 8), (0, 2).into());\n        assert_eq!(visual_coords_at_pos(slice, 3, 8), (0, 3).into());\n        assert_eq!(visual_coords_at_pos(slice, 5, 8), (0, 5).into());\n        assert_eq!(visual_coords_at_pos(slice, 6, 8), (1, 0).into());\n\n        // Test with tabs.\n        let text = Rope::from(\"\\tHello\\n\");\n        let slice = text.slice(..);\n        assert_eq!(visual_coords_at_pos(slice, 0, 8), (0, 0).into());\n        assert_eq!(visual_coords_at_pos(slice, 1, 8), (0, 8).into());\n        assert_eq!(visual_coords_at_pos(slice, 2, 8), (0, 9).into());\n    }\n\n    #[test]\n    fn test_visual_off_from_block() {\n        let text = Rope::from(\"ḧëḷḷö\\nẅöṛḷḋ\");\n        let slice = text.slice(..);\n        let annot = TextAnnotations::default();\n        let text_fmt = TextFormat::default();\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 0, &text_fmt, &annot).0,\n            (0, 0).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 5, &text_fmt, &annot).0,\n            (0, 5).into()\n        ); // position on \\n\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 6, &text_fmt, &annot).0,\n            (1, 0).into()\n        ); // position on w\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 7, &text_fmt, &annot).0,\n            (1, 1).into()\n        ); // position on o\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 10, &text_fmt, &annot).0,\n            (1, 4).into()\n        ); // position on d\n\n        // Test with wide characters.\n        let text = Rope::from(\"今日はいい\\n\");\n        let slice = text.slice(..);\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 0, &text_fmt, &annot).0,\n            (0, 0).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 1, &text_fmt, &annot).0,\n            (0, 2).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 2, &text_fmt, &annot).0,\n            (0, 4).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 3, &text_fmt, &annot).0,\n            (0, 6).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 4, &text_fmt, &annot).0,\n            (0, 8).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 5, &text_fmt, &annot).0,\n            (0, 10).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 6, &text_fmt, &annot).0,\n            (1, 0).into()\n        );\n\n        // Test with grapheme clusters.\n        let text = Rope::from(\"a̐éö̲\\r\\n\");\n        let slice = text.slice(..);\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 0, &text_fmt, &annot).0,\n            (0, 0).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 2, &text_fmt, &annot).0,\n            (0, 1).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 4, &text_fmt, &annot).0,\n            (0, 2).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 7, &text_fmt, &annot).0,\n            (0, 3).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 9, &text_fmt, &annot).0,\n            (1, 0).into()\n        );\n\n        // Test with wide-character grapheme clusters.\n        // TODO: account for cluster.\n        let text = Rope::from(\"किमपि\\n\");\n        let slice = text.slice(..);\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 0, &text_fmt, &annot).0,\n            (0, 0).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 2, &text_fmt, &annot).0,\n            (0, 2).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 3, &text_fmt, &annot).0,\n            (0, 3).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 5, &text_fmt, &annot).0,\n            (0, 5).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 6, &text_fmt, &annot).0,\n            (1, 0).into()\n        );\n\n        // Test with tabs.\n        let text = Rope::from(\"\\tHello\\n\");\n        let slice = text.slice(..);\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 0, &text_fmt, &annot).0,\n            (0, 0).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 1, &text_fmt, &annot).0,\n            (0, 4).into()\n        );\n        assert_eq!(\n            visual_offset_from_block(slice, 0, 2, &text_fmt, &annot).0,\n            (0, 5).into()\n        );\n    }\n    #[test]\n    fn test_pos_at_coords() {\n        let text = Rope::from(\"ḧëḷḷö\\nẅöṛḷḋ\");\n        let slice = text.slice(..);\n        assert_eq!(pos_at_coords(slice, (0, 0).into(), false), 0);\n        assert_eq!(pos_at_coords(slice, (0, 5).into(), false), 5); // position on \\n\n        assert_eq!(pos_at_coords(slice, (0, 6).into(), false), 6); // position after \\n\n        assert_eq!(pos_at_coords(slice, (0, 6).into(), true), 5); // position after \\n\n        assert_eq!(pos_at_coords(slice, (1, 0).into(), false), 6); // position on w\n        assert_eq!(pos_at_coords(slice, (1, 1).into(), false), 7); // position on o\n        assert_eq!(pos_at_coords(slice, (1, 4).into(), false), 10); // position on d\n\n        // Test with wide characters.\n        // TODO: account for character width.\n        let text = Rope::from(\"今日はいい\\n\");\n        let slice = text.slice(..);\n        assert_eq!(pos_at_coords(slice, (0, 0).into(), false), 0);\n        assert_eq!(pos_at_coords(slice, (0, 1).into(), false), 1);\n        assert_eq!(pos_at_coords(slice, (0, 2).into(), false), 2);\n        assert_eq!(pos_at_coords(slice, (0, 3).into(), false), 3);\n        assert_eq!(pos_at_coords(slice, (0, 4).into(), false), 4);\n        assert_eq!(pos_at_coords(slice, (0, 5).into(), false), 5);\n        assert_eq!(pos_at_coords(slice, (0, 6).into(), false), 6);\n        assert_eq!(pos_at_coords(slice, (0, 6).into(), true), 5);\n        assert_eq!(pos_at_coords(slice, (1, 0).into(), false), 6);\n\n        // Test with grapheme clusters.\n        let text = Rope::from(\"a̐éö̲\\r\\n\");\n        let slice = text.slice(..);\n        assert_eq!(pos_at_coords(slice, (0, 0).into(), false), 0);\n        assert_eq!(pos_at_coords(slice, (0, 1).into(), false), 2);\n        assert_eq!(pos_at_coords(slice, (0, 2).into(), false), 4);\n        assert_eq!(pos_at_coords(slice, (0, 3).into(), false), 7); // \\r\\n is one char here\n        assert_eq!(pos_at_coords(slice, (0, 4).into(), false), 9);\n        assert_eq!(pos_at_coords(slice, (0, 4).into(), true), 7);\n        assert_eq!(pos_at_coords(slice, (1, 0).into(), false), 9);\n\n        // Test with wide-character grapheme clusters.\n        // TODO: account for character width.\n        let text = Rope::from(\"किमपि\");\n        // 2 - 1 - 2 codepoints\n        // TODO: delete handling as per https://news.ycombinator.com/item?id=20058454\n        let slice = text.slice(..);\n        assert_eq!(pos_at_coords(slice, (0, 0).into(), false), 0);\n        assert_eq!(pos_at_coords(slice, (0, 1).into(), false), 2);\n        assert_eq!(pos_at_coords(slice, (0, 2).into(), false), 3);\n        assert_eq!(pos_at_coords(slice, (0, 3).into(), false), 5);\n        assert_eq!(pos_at_coords(slice, (0, 3).into(), true), 5);\n\n        // Test with tabs.\n        // Todo: account for tab stops.\n        let text = Rope::from(\"\\tHello\\n\");\n        let slice = text.slice(..);\n        assert_eq!(pos_at_coords(slice, (0, 0).into(), false), 0);\n        assert_eq!(pos_at_coords(slice, (0, 1).into(), false), 1);\n        assert_eq!(pos_at_coords(slice, (0, 2).into(), false), 2);\n\n        // Test out of bounds.\n        let text = Rope::new();\n        let slice = text.slice(..);\n        assert_eq!(pos_at_coords(slice, (10, 0).into(), true), 0);\n        assert_eq!(pos_at_coords(slice, (0, 10).into(), true), 0);\n        assert_eq!(pos_at_coords(slice, (10, 10).into(), true), 0);\n    }\n\n    #[test]\n    #[allow(deprecated)]\n    fn test_pos_at_visual_coords() {\n        let text = Rope::from(\"ḧëḷḷö\\nẅöṛḷḋ\");\n        let slice = text.slice(..);\n        assert_eq!(pos_at_visual_coords(slice, (0, 0).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 5).into(), 4), 5); // position on \\n\n        assert_eq!(pos_at_visual_coords(slice, (0, 6).into(), 4), 5); // position after \\n\n        assert_eq!(pos_at_visual_coords(slice, (1, 0).into(), 4), 6); // position on w\n        assert_eq!(pos_at_visual_coords(slice, (1, 1).into(), 4), 7); // position on o\n        assert_eq!(pos_at_visual_coords(slice, (1, 4).into(), 4), 10); // position on d\n\n        // Test with wide characters.\n        let text = Rope::from(\"今日はいい\\n\");\n        let slice = text.slice(..);\n        assert_eq!(pos_at_visual_coords(slice, (0, 0).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 1).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 2).into(), 4), 1);\n        assert_eq!(pos_at_visual_coords(slice, (0, 3).into(), 4), 1);\n        assert_eq!(pos_at_visual_coords(slice, (0, 4).into(), 4), 2);\n        assert_eq!(pos_at_visual_coords(slice, (0, 5).into(), 4), 2);\n        assert_eq!(pos_at_visual_coords(slice, (0, 6).into(), 4), 3);\n        assert_eq!(pos_at_visual_coords(slice, (0, 7).into(), 4), 3);\n        assert_eq!(pos_at_visual_coords(slice, (0, 8).into(), 4), 4);\n        assert_eq!(pos_at_visual_coords(slice, (0, 9).into(), 4), 4);\n        // assert_eq!(pos_at_visual_coords(slice, (0, 10).into(), 4, false), 5);\n        // assert_eq!(pos_at_visual_coords(slice, (0, 10).into(), 4, true), 5);\n        assert_eq!(pos_at_visual_coords(slice, (1, 0).into(), 4), 6);\n\n        // Test with grapheme clusters.\n        let text = Rope::from(\"a̐éö̲\\r\\n\");\n        let slice = text.slice(..);\n        assert_eq!(pos_at_visual_coords(slice, (0, 0).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 1).into(), 4), 2);\n        assert_eq!(pos_at_visual_coords(slice, (0, 2).into(), 4), 4);\n        assert_eq!(pos_at_visual_coords(slice, (0, 3).into(), 4), 7); // \\r\\n is one char here\n        assert_eq!(pos_at_visual_coords(slice, (0, 4).into(), 4), 7);\n        assert_eq!(pos_at_visual_coords(slice, (1, 0).into(), 4), 9);\n\n        // Test with wide-character grapheme clusters.\n        let text = Rope::from(\"किमपि\");\n        // 2 - 1 - 2 codepoints\n        // TODO: delete handling as per https://news.ycombinator.com/item?id=20058454\n        let slice = text.slice(..);\n        assert_eq!(pos_at_visual_coords(slice, (0, 0).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 1).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 2).into(), 4), 2);\n        assert_eq!(pos_at_visual_coords(slice, (0, 3).into(), 4), 3);\n\n        // Test with tabs.\n        let text = Rope::from(\"\\tHello\\n\");\n        let slice = text.slice(..);\n        assert_eq!(pos_at_visual_coords(slice, (0, 0).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 1).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 2).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 3).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 4).into(), 4), 1);\n        assert_eq!(pos_at_visual_coords(slice, (0, 5).into(), 4), 2);\n\n        // Test out of bounds.\n        let text = Rope::new();\n        let slice = text.slice(..);\n        assert_eq!(pos_at_visual_coords(slice, (10, 0).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (0, 10).into(), 4), 0);\n        assert_eq!(pos_at_visual_coords(slice, (10, 10).into(), 4), 0);\n    }\n\n    #[test]\n    fn test_char_idx_at_visual_row_offset_inline_annotation() {\n        let text = Rope::from(\"foo\\nbar\");\n        let slice = text.slice(..);\n        let mut text_fmt = TextFormat::default();\n        let annotations = [InlineAnnotation {\n            text: \"x\".repeat(100).into(),\n            char_idx: 3,\n        }];\n        text_fmt.soft_wrap = true;\n\n        assert_eq!(\n            char_idx_at_visual_offset(\n                slice,\n                0,\n                1,\n                0,\n                &text_fmt,\n                TextAnnotations::default().add_inline_annotations(&annotations, None)\n            ),\n            (2, 1)\n        );\n    }\n\n    #[test]\n    fn test_char_idx_at_visual_row_offset() {\n        let text = Rope::from(\"ḧëḷḷö\\nẅöṛḷḋ\\nfoo\");\n        let slice = text.slice(..);\n        let mut text_fmt = TextFormat::default();\n        for i in 0isize..3isize {\n            for j in -2isize..=2isize {\n                if !(0..3).contains(&(i + j)) {\n                    continue;\n                }\n                println!(\"{i} {j}\");\n                assert_eq!(\n                    char_idx_at_visual_offset(\n                        slice,\n                        slice.line_to_char(i as usize),\n                        j,\n                        3,\n                        &text_fmt,\n                        &TextAnnotations::default(),\n                    )\n                    .0,\n                    slice.line_to_char((i + j) as usize) + 3\n                );\n            }\n        }\n\n        text_fmt.soft_wrap = true;\n        let mut softwrapped_text = \"foo \".repeat(10);\n        softwrapped_text.push('\\n');\n        let last_char = softwrapped_text.len() - 1;\n\n        let text = Rope::from(softwrapped_text.repeat(3));\n        let slice = text.slice(..);\n        assert_eq!(\n            char_idx_at_visual_offset(\n                slice,\n                last_char,\n                0,\n                0,\n                &text_fmt,\n                &TextAnnotations::default(),\n            )\n            .0,\n            32\n        );\n        assert_eq!(\n            char_idx_at_visual_offset(\n                slice,\n                last_char,\n                -1,\n                0,\n                &text_fmt,\n                &TextAnnotations::default(),\n            )\n            .0,\n            16\n        );\n        assert_eq!(\n            char_idx_at_visual_offset(\n                slice,\n                last_char,\n                -2,\n                0,\n                &text_fmt,\n                &TextAnnotations::default(),\n            )\n            .0,\n            0\n        );\n        assert_eq!(\n            char_idx_at_visual_offset(\n                slice,\n                softwrapped_text.len() + last_char,\n                -2,\n                0,\n                &text_fmt,\n                &TextAnnotations::default(),\n            )\n            .0,\n            softwrapped_text.len()\n        );\n\n        assert_eq!(\n            char_idx_at_visual_offset(\n                slice,\n                softwrapped_text.len() + last_char,\n                -5,\n                0,\n                &text_fmt,\n                &TextAnnotations::default(),\n            )\n            .0,\n            0\n        );\n    }\n}\n"
  },
  {
    "path": "helix-core/src/rope_reader.rs",
    "content": "use std::io;\n\nuse ropey::iter::Chunks;\nuse ropey::RopeSlice;\n\npub struct RopeReader<'a> {\n    current_chunk: &'a [u8],\n    chunks: Chunks<'a>,\n}\n\nimpl<'a> RopeReader<'a> {\n    pub fn new(rope: RopeSlice<'a>) -> RopeReader<'a> {\n        RopeReader {\n            current_chunk: &[],\n            chunks: rope.chunks(),\n        }\n    }\n}\n\nimpl io::Read for RopeReader<'_> {\n    fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {\n        let buf_len = buf.len();\n        loop {\n            let read_bytes = self.current_chunk.read(buf)?;\n            buf = &mut buf[read_bytes..];\n            if buf.is_empty() {\n                return Ok(buf_len);\n            }\n\n            if let Some(next_chunk) = self.chunks.next() {\n                self.current_chunk = next_chunk.as_bytes();\n            } else {\n                return Ok(buf_len - buf.len());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "helix-core/src/search.rs",
    "content": "use crate::movement::Direction;\nuse crate::RopeSlice;\n\n// TODO: switch to std::str::Pattern when it is stable.\npub trait CharMatcher {\n    fn char_match(&self, ch: char) -> bool;\n}\n\nimpl CharMatcher for char {\n    fn char_match(&self, ch: char) -> bool {\n        *self == ch\n    }\n}\n\nimpl<F: Fn(&char) -> bool> CharMatcher for F {\n    fn char_match(&self, ch: char) -> bool {\n        (*self)(&ch)\n    }\n}\n\n// Finds the positions of the nth matching character in given direction\n// starting from the pos gap-index (see Range struct for explanation)\npub fn find_nth_char<M: CharMatcher>(\n    mut n: usize,\n    text: RopeSlice,\n    char_matcher: M,\n    mut pos: usize,\n    direction: Direction,\n) -> Option<usize> {\n    if n == 0 {\n        return None;\n    }\n\n    let mut chars = text.get_chars_at(pos)?;\n\n    match direction {\n        Direction::Forward => loop {\n            let c = chars.next()?;\n            if char_matcher.char_match(c) {\n                n -= 1;\n                if n == 0 {\n                    return Some(pos);\n                }\n            }\n            pos += 1;\n        },\n        Direction::Backward => loop {\n            let c = chars.prev()?;\n            pos -= 1;\n            if char_matcher.char_match(c) {\n                n -= 1;\n                if n == 0 {\n                    return Some(pos);\n                }\n            }\n        },\n    };\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::movement::Direction;\n\n    #[test]\n    fn test_find_nth_char() {\n        let text = RopeSlice::from(\"aa ⌚aa \\r\\n aa\");\n\n        // Forward direction\n        assert_eq!(find_nth_char(1, text, 'a', 5, Direction::Forward), Some(5));\n        assert_eq!(find_nth_char(2, text, 'a', 5, Direction::Forward), Some(10));\n        assert_eq!(find_nth_char(3, text, 'a', 5, Direction::Forward), Some(11));\n        assert_eq!(find_nth_char(4, text, 'a', 5, Direction::Forward), None);\n\n        // Backward direction\n        assert_eq!(find_nth_char(1, text, 'a', 5, Direction::Backward), Some(4));\n        assert_eq!(find_nth_char(2, text, 'a', 5, Direction::Backward), Some(1));\n        assert_eq!(find_nth_char(3, text, 'a', 5, Direction::Backward), Some(0));\n        assert_eq!(find_nth_char(4, text, 'a', 5, Direction::Backward), None);\n\n        // Edge cases\n        assert_eq!(find_nth_char(0, text, 'a', 5, Direction::Forward), None); // n = 0\n        assert_eq!(find_nth_char(1, text, 'x', 5, Direction::Forward), None); // Not found\n        assert_eq!(find_nth_char(1, text, 'a', 20, Direction::Forward), None); // Beyond text\n        assert_eq!(find_nth_char(1, text, 'a', 0, Direction::Backward), None); // At start going backward\n    }\n}\n"
  },
  {
    "path": "helix-core/src/selection.rs",
    "content": "//! Selections are the primary editing construct. Even cursors are\n//! defined as a selection range.\n//!\n//! All positioning is done via `char` offsets into the buffer.\nuse crate::{\n    graphemes::{\n        ensure_grapheme_boundary_next, ensure_grapheme_boundary_prev, next_grapheme_boundary,\n        prev_grapheme_boundary,\n    },\n    line_ending::get_line_ending,\n    movement::Direction,\n    tree_sitter::Node,\n    Assoc, ChangeSet, RopeSlice,\n};\nuse helix_stdx::range::is_subset;\nuse helix_stdx::rope::{self, RopeSliceExt};\nuse smallvec::{smallvec, SmallVec};\nuse std::{borrow::Cow, iter, slice};\n\n/// A single selection range.\n///\n/// A range consists of an \"anchor\" and \"head\" position in\n/// the text.  The head is the part that the user moves when\n/// directly extending a selection.  The head and anchor\n/// can be in any order, or even share the same position.\n///\n/// The anchor and head positions use gap indexing, meaning\n/// that their indices represent the gaps *between* `char`s\n/// rather than the `char`s themselves. For example, 1\n/// represents the position between the first and second `char`.\n///\n/// Below are some examples of `Range` configurations.\n/// The anchor and head indices are shown as \"(anchor, head)\"\n/// tuples, followed by example text with \"[\" and \"]\" symbols\n/// representing the anchor and head positions:\n///\n/// - (0, 3): `[Som]e text`.\n/// - (3, 0): `]Som[e text`.\n/// - (2, 7): `So[me te]xt`.\n/// - (1, 1): `S[]ome text`.\n///\n/// Ranges are considered to be inclusive on the left and\n/// exclusive on the right, regardless of anchor-head ordering.\n/// This means, for example, that non-zero-width ranges that\n/// are directly adjacent, sharing an edge, do not overlap.\n/// However, a zero-width range will overlap with the shared\n/// left-edge of another range.\n///\n/// By convention, user-facing ranges are considered to have\n/// a block cursor on the head-side of the range that spans a\n/// single grapheme inward from the range's edge.  There are a\n/// variety of helper methods on `Range` for working in terms of\n/// that block cursor, all of which have `cursor` in their name.\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub struct Range {\n    /// The anchor of the range: the side that doesn't move when extending.\n    pub anchor: usize,\n    /// The head of the range, moved when extending.\n    pub head: usize,\n    /// The previous visual offset (softwrapped lines and columns) from\n    /// the start of the line\n    pub old_visual_position: Option<(u32, u32)>,\n}\n\nimpl Range {\n    pub fn new(anchor: usize, head: usize) -> Self {\n        Self {\n            anchor,\n            head,\n            old_visual_position: None,\n        }\n    }\n\n    pub fn point(head: usize) -> Self {\n        Self::new(head, head)\n    }\n\n    pub fn from_node(node: Node, text: RopeSlice, direction: Direction) -> Self {\n        let from = text.byte_to_char(node.start_byte() as usize);\n        let to = text.byte_to_char(node.end_byte() as usize);\n        Range::new(from, to).with_direction(direction)\n    }\n\n    /// Start of the range.\n    #[inline]\n    #[must_use]\n    pub fn from(&self) -> usize {\n        std::cmp::min(self.anchor, self.head)\n    }\n\n    /// End of the range.\n    #[inline]\n    #[must_use]\n    pub fn to(&self) -> usize {\n        std::cmp::max(self.anchor, self.head)\n    }\n\n    /// Total length of the range.\n    #[inline]\n    #[must_use]\n    pub fn len(&self) -> usize {\n        self.to() - self.from()\n    }\n\n    /// The (inclusive) range of lines that the range overlaps.\n    #[inline]\n    #[must_use]\n    pub fn line_range(&self, text: RopeSlice) -> (usize, usize) {\n        let from = self.from();\n        let to = if self.is_empty() {\n            self.to()\n        } else {\n            prev_grapheme_boundary(text, self.to()).max(from)\n        };\n\n        (text.char_to_line(from), text.char_to_line(to))\n    }\n\n    /// `true` when head and anchor are at the same position.\n    #[inline]\n    pub fn is_empty(&self) -> bool {\n        self.anchor == self.head\n    }\n\n    /// `Direction::Backward` when head < anchor.\n    /// `Direction::Forward` otherwise.\n    #[inline]\n    #[must_use]\n    pub fn direction(&self) -> Direction {\n        if self.head < self.anchor {\n            Direction::Backward\n        } else {\n            Direction::Forward\n        }\n    }\n\n    /// Flips the direction of the selection\n    pub fn flip(&self) -> Self {\n        Self {\n            anchor: self.head,\n            head: self.anchor,\n            old_visual_position: self.old_visual_position,\n        }\n    }\n\n    /// Returns the selection if it goes in the direction of `direction`,\n    /// flipping the selection otherwise.\n    pub fn with_direction(self, direction: Direction) -> Self {\n        if self.direction() == direction {\n            self\n        } else {\n            self.flip()\n        }\n    }\n\n    /// Check two ranges for overlap.\n    #[must_use]\n    pub fn overlaps(&self, other: &Self) -> bool {\n        // To my eye, it's non-obvious why this works, but I arrived\n        // at it after transforming the slower version that explicitly\n        // enumerated more cases.  The unit tests are thorough.\n        self.from() == other.from() || (self.to() > other.from() && other.to() > self.from())\n    }\n\n    #[inline]\n    pub fn contains_range(&self, other: &Self) -> bool {\n        self.from() <= other.from() && self.to() >= other.to()\n    }\n\n    pub fn contains(&self, pos: usize) -> bool {\n        self.from() <= pos && pos < self.to()\n    }\n\n    /// Map a range through a set of changes. Returns a new range representing\n    /// the same position after the changes are applied. Note that this\n    /// function runs in O(N) (N is number of changes) and can therefore\n    /// cause performance problems if run for a large number of ranges as the\n    /// complexity is then O(MN) (for multicuror M=N usually). Instead use\n    /// [Selection::map] or [ChangeSet::update_positions].\n    pub fn map(mut self, changes: &ChangeSet) -> Self {\n        use std::cmp::Ordering;\n        if changes.is_empty() {\n            return self;\n        }\n\n        let positions_to_map = match self.anchor.cmp(&self.head) {\n            Ordering::Equal => [\n                (&mut self.anchor, Assoc::AfterSticky),\n                (&mut self.head, Assoc::AfterSticky),\n            ],\n            Ordering::Less => [\n                (&mut self.anchor, Assoc::AfterSticky),\n                (&mut self.head, Assoc::BeforeSticky),\n            ],\n            Ordering::Greater => [\n                (&mut self.head, Assoc::AfterSticky),\n                (&mut self.anchor, Assoc::BeforeSticky),\n            ],\n        };\n        changes.update_positions(positions_to_map.into_iter());\n        self.old_visual_position = None;\n        self\n    }\n\n    /// Extend the range to cover at least `from` `to`.\n    #[must_use]\n    pub fn extend(&self, from: usize, to: usize) -> Self {\n        debug_assert!(from <= to);\n\n        if self.anchor <= self.head {\n            Self {\n                anchor: self.anchor.min(from),\n                head: self.head.max(to),\n                old_visual_position: None,\n            }\n        } else {\n            Self {\n                anchor: self.anchor.max(to),\n                head: self.head.min(from),\n                old_visual_position: None,\n            }\n        }\n    }\n\n    /// Returns a range that encompasses both input ranges.\n    ///\n    /// This is like `extend()`, but tries to negotiate the\n    /// anchor/head ordering between the two input ranges.\n    #[must_use]\n    pub fn merge(&self, other: Self) -> Self {\n        if self.anchor > self.head && other.anchor > other.head {\n            Range {\n                anchor: self.anchor.max(other.anchor),\n                head: self.head.min(other.head),\n                old_visual_position: None,\n            }\n        } else {\n            Range {\n                anchor: self.from().min(other.from()),\n                head: self.to().max(other.to()),\n                old_visual_position: None,\n            }\n        }\n    }\n\n    // groupAt\n\n    /// Returns the text inside this range given the text of the whole buffer.\n    ///\n    /// The returned `Cow` is a reference if the range of text is inside a single\n    /// chunk of the rope. Otherwise a copy of the text is returned. Consider\n    /// using `slice` instead if you do not need a `Cow` or `String` to avoid copying.\n    #[inline]\n    pub fn fragment<'a, 'b: 'a>(&'a self, text: RopeSlice<'b>) -> Cow<'b, str> {\n        self.slice(text).into()\n    }\n\n    /// Returns the text inside this range given the text of the whole buffer.\n    ///\n    /// The returned value is a reference to the passed slice. This method never\n    /// copies any contents.\n    #[inline]\n    pub fn slice<'a, 'b: 'a>(&'a self, text: RopeSlice<'b>) -> RopeSlice<'b> {\n        text.slice(self.from()..self.to())\n    }\n\n    //--------------------------------\n    // Alignment methods.\n\n    /// Compute a possibly new range from this range, with its ends\n    /// shifted as needed to align with grapheme boundaries.\n    ///\n    /// Zero-width ranges will always stay zero-width, and non-zero-width\n    /// ranges will never collapse to zero-width.\n    #[must_use]\n    pub fn grapheme_aligned(&self, slice: RopeSlice) -> Self {\n        use std::cmp::Ordering;\n        let (new_anchor, new_head) = match self.anchor.cmp(&self.head) {\n            Ordering::Equal => {\n                let pos = ensure_grapheme_boundary_prev(slice, self.anchor);\n                (pos, pos)\n            }\n            Ordering::Less => (\n                ensure_grapheme_boundary_prev(slice, self.anchor),\n                ensure_grapheme_boundary_next(slice, self.head),\n            ),\n            Ordering::Greater => (\n                ensure_grapheme_boundary_next(slice, self.anchor),\n                ensure_grapheme_boundary_prev(slice, self.head),\n            ),\n        };\n        Range {\n            anchor: new_anchor,\n            head: new_head,\n            old_visual_position: if new_anchor == self.anchor {\n                self.old_visual_position\n            } else {\n                None\n            },\n        }\n    }\n\n    /// Compute a possibly new range from this range, attempting to ensure\n    /// a minimum range width of 1 char by shifting the head in the forward\n    /// direction as needed.\n    ///\n    /// This method will never shift the anchor, and will only shift the\n    /// head in the forward direction.  Therefore, this method can fail\n    /// at ensuring the minimum width if and only if the passed range is\n    /// both zero-width and at the end of the `RopeSlice`.\n    ///\n    /// If the input range is grapheme-boundary aligned, the returned range\n    /// will also be.  Specifically, if the head needs to shift to achieve\n    /// the minimum width, it will shift to the next grapheme boundary.\n    #[must_use]\n    #[inline]\n    pub fn min_width_1(&self, slice: RopeSlice) -> Self {\n        if self.anchor == self.head {\n            Range {\n                anchor: self.anchor,\n                head: next_grapheme_boundary(slice, self.head),\n                old_visual_position: self.old_visual_position,\n            }\n        } else {\n            *self\n        }\n    }\n\n    //--------------------------------\n    // Block-cursor methods.\n\n    /// Gets the left-side position of the block cursor.\n    #[must_use]\n    #[inline]\n    pub fn cursor(self, text: RopeSlice) -> usize {\n        if self.head > self.anchor {\n            prev_grapheme_boundary(text, self.head)\n        } else {\n            self.head\n        }\n    }\n\n    /// Puts the left side of the block cursor at `char_idx`, optionally extending.\n    ///\n    /// This follows \"1-width\" semantics, and therefore does a combination of anchor\n    /// and head moves to behave as if both the front and back of the range are 1-width\n    /// blocks\n    ///\n    /// This method assumes that the range and `char_idx` are already properly\n    /// grapheme-aligned.\n    #[must_use]\n    #[inline]\n    pub fn put_cursor(self, text: RopeSlice, char_idx: usize, extend: bool) -> Range {\n        if extend {\n            let anchor = if self.head >= self.anchor && char_idx < self.anchor {\n                next_grapheme_boundary(text, self.anchor)\n            } else if self.head < self.anchor && char_idx >= self.anchor {\n                prev_grapheme_boundary(text, self.anchor)\n            } else {\n                self.anchor\n            };\n\n            if anchor <= char_idx {\n                Range::new(anchor, next_grapheme_boundary(text, char_idx))\n            } else {\n                Range::new(anchor, char_idx)\n            }\n        } else {\n            Range::point(char_idx)\n        }\n    }\n\n    /// The line number that the block-cursor is on.\n    #[inline]\n    #[must_use]\n    pub fn cursor_line(&self, text: RopeSlice) -> usize {\n        text.char_to_line(self.cursor(text))\n    }\n\n    /// Returns true if this Range covers a single grapheme in the given text\n    pub fn is_single_grapheme(&self, doc: RopeSlice) -> bool {\n        let mut graphemes = doc.slice(self.from()..self.to()).graphemes();\n        let first = graphemes.next();\n        let second = graphemes.next();\n        first.is_some() && second.is_none()\n    }\n\n    /// Converts this char range into an in order byte range, discarding\n    /// direction.\n    pub fn into_byte_range(&self, text: RopeSlice) -> (usize, usize) {\n        (text.char_to_byte(self.from()), text.char_to_byte(self.to()))\n    }\n}\n\nimpl From<(usize, usize)> for Range {\n    fn from((anchor, head): (usize, usize)) -> Self {\n        Self {\n            anchor,\n            head,\n            old_visual_position: None,\n        }\n    }\n}\n\nimpl From<Range> for helix_stdx::Range {\n    fn from(range: Range) -> Self {\n        Self {\n            start: range.from(),\n            end: range.to(),\n        }\n    }\n}\n\n/// A selection consists of one or more selection ranges.\n/// invariant: A selection can never be empty (always contains at least primary range).\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct Selection {\n    ranges: SmallVec<[Range; 1]>,\n    primary_index: usize,\n}\n\n#[allow(clippy::len_without_is_empty)] // a Selection is never empty\nimpl Selection {\n    // eq\n\n    #[inline]\n    #[must_use]\n    pub fn primary(&self) -> Range {\n        self.ranges[self.primary_index]\n    }\n\n    #[inline]\n    #[must_use]\n    pub fn primary_mut(&mut self) -> &mut Range {\n        &mut self.ranges[self.primary_index]\n    }\n\n    /// Ensure selection containing only the primary selection.\n    pub fn into_single(self) -> Self {\n        if self.ranges.len() == 1 {\n            self\n        } else {\n            Self {\n                ranges: smallvec![self.ranges[self.primary_index]],\n                primary_index: 0,\n            }\n        }\n    }\n\n    /// Adds a new range to the selection and makes it the primary range.\n    pub fn push(mut self, range: Range) -> Self {\n        self.ranges.push(range);\n        self.set_primary_index(self.ranges().len() - 1);\n        self.normalize()\n    }\n\n    /// Removes a range from the selection.\n    pub fn remove(mut self, index: usize) -> Self {\n        assert!(\n            self.ranges.len() > 1,\n            \"can't remove the last range from a selection!\"\n        );\n\n        self.ranges.remove(index);\n        if index < self.primary_index || self.primary_index == self.ranges.len() {\n            self.primary_index -= 1;\n        }\n        self\n    }\n\n    /// Replace a range in the selection with a new range.\n    pub fn replace(mut self, index: usize, range: Range) -> Self {\n        self.ranges[index] = range;\n        self.normalize()\n    }\n\n    /// Map selections over a set of changes. Useful for adjusting the selection position after\n    /// applying changes to a document.\n    pub fn map(self, changes: &ChangeSet) -> Self {\n        self.map_no_normalize(changes).normalize()\n    }\n\n    /// Map selections over a set of changes. Useful for adjusting the selection position after\n    /// applying changes to a document. Doesn't normalize the selection\n    pub fn map_no_normalize(mut self, changes: &ChangeSet) -> Self {\n        if changes.is_empty() {\n            return self;\n        }\n\n        let positions_to_map = self.ranges.iter_mut().flat_map(|range| {\n            use std::cmp::Ordering;\n            range.old_visual_position = None;\n            match range.anchor.cmp(&range.head) {\n                Ordering::Equal => [\n                    (&mut range.anchor, Assoc::AfterSticky),\n                    (&mut range.head, Assoc::AfterSticky),\n                ],\n                Ordering::Less => [\n                    (&mut range.anchor, Assoc::AfterSticky),\n                    (&mut range.head, Assoc::BeforeSticky),\n                ],\n                Ordering::Greater => [\n                    (&mut range.head, Assoc::AfterSticky),\n                    (&mut range.anchor, Assoc::BeforeSticky),\n                ],\n            }\n        });\n        changes.update_positions(positions_to_map);\n        self\n    }\n\n    pub fn ranges(&self) -> &[Range] {\n        &self.ranges\n    }\n\n    /// Returns an iterator over the line ranges of each range in the selection.\n    ///\n    /// Adjacent and overlapping line ranges of the [Range]s in the selection are merged.\n    pub fn line_ranges<'a>(&'a self, text: RopeSlice<'a>) -> LineRangeIter<'a> {\n        LineRangeIter {\n            ranges: self.ranges.iter().peekable(),\n            text,\n        }\n    }\n\n    pub fn range_bounds(&self) -> impl Iterator<Item = helix_stdx::Range> + '_ {\n        self.ranges.iter().map(|&range| range.into())\n    }\n\n    pub fn primary_index(&self) -> usize {\n        self.primary_index\n    }\n\n    pub fn set_primary_index(&mut self, idx: usize) {\n        assert!(idx < self.ranges.len());\n        self.primary_index = idx;\n    }\n\n    #[must_use]\n    /// Constructs a selection holding a single range.\n    pub fn single(anchor: usize, head: usize) -> Self {\n        Self {\n            ranges: smallvec![Range {\n                anchor,\n                head,\n                old_visual_position: None\n            }],\n            primary_index: 0,\n        }\n    }\n\n    /// Constructs a selection holding a single cursor.\n    pub fn point(pos: usize) -> Self {\n        Self::single(pos, pos)\n    }\n\n    /// Normalizes a `Selection`.\n    ///\n    /// Ranges are sorted by [Range::from], with overlapping ranges merged.\n    fn normalize(mut self) -> Self {\n        if self.len() < 2 {\n            return self;\n        }\n        let mut primary = self.ranges[self.primary_index];\n        self.ranges.sort_unstable_by_key(Range::from);\n\n        self.ranges.dedup_by(|curr_range, prev_range| {\n            if prev_range.overlaps(curr_range) {\n                let new_range = curr_range.merge(*prev_range);\n                if prev_range == &primary || curr_range == &primary {\n                    primary = new_range;\n                }\n                *prev_range = new_range;\n                true\n            } else {\n                false\n            }\n        });\n\n        self.primary_index = self\n            .ranges\n            .iter()\n            .position(|&range| range == primary)\n            .unwrap();\n\n        self\n    }\n\n    /// Replaces ranges with one spanning from first to last range.\n    pub fn merge_ranges(self) -> Self {\n        let first = self.ranges.first().unwrap();\n        let last = self.ranges.last().unwrap();\n        Selection::new(smallvec![first.merge(*last)], 0)\n    }\n\n    /// Merges all ranges that are consecutive.\n    pub fn merge_consecutive_ranges(mut self) -> Self {\n        let mut primary = self.ranges[self.primary_index];\n\n        self.ranges.dedup_by(|curr_range, prev_range| {\n            if prev_range.to() == curr_range.from() {\n                let new_range = curr_range.merge(*prev_range);\n                if prev_range == &primary || curr_range == &primary {\n                    primary = new_range;\n                }\n                *prev_range = new_range;\n                true\n            } else {\n                false\n            }\n        });\n\n        self.primary_index = self\n            .ranges\n            .iter()\n            .position(|&range| range == primary)\n            .unwrap();\n\n        self\n    }\n\n    #[must_use]\n    pub fn new(ranges: SmallVec<[Range; 1]>, primary_index: usize) -> Self {\n        assert!(!ranges.is_empty());\n        debug_assert!(primary_index < ranges.len());\n\n        let selection = Self {\n            ranges,\n            primary_index,\n        };\n\n        selection.normalize()\n    }\n\n    /// Takes a closure and maps each `Range` over the closure.\n    pub fn transform<F>(mut self, mut f: F) -> Self\n    where\n        F: FnMut(Range) -> Range,\n    {\n        for range in self.ranges.iter_mut() {\n            *range = f(*range)\n        }\n        self.normalize()\n    }\n\n    /// Takes a closure and maps each `Range` over the closure to multiple `Range`s.\n    pub fn transform_iter<F, I>(mut self, f: F) -> Self\n    where\n        F: FnMut(Range) -> I,\n        I: Iterator<Item = Range>,\n    {\n        self.ranges = self.ranges.into_iter().flat_map(f).collect();\n        self.normalize()\n    }\n\n    // Ensures the selection adheres to the following invariants:\n    // 1. All ranges are grapheme aligned.\n    // 2. All ranges are at least 1 character wide, unless at the\n    //    very end of the document.\n    // 3. Ranges are non-overlapping.\n    // 4. Ranges are sorted by their position in the text.\n    pub fn ensure_invariants(self, text: RopeSlice) -> Self {\n        self.transform(|r| r.min_width_1(text).grapheme_aligned(text))\n            .normalize()\n    }\n\n    /// Transforms the selection into all of the left-side head positions,\n    /// using block-cursor semantics.\n    pub fn cursors(self, text: RopeSlice) -> Self {\n        self.transform(|range| Range::point(range.cursor(text)))\n    }\n\n    pub fn fragments<'a>(\n        &'a self,\n        text: RopeSlice<'a>,\n    ) -> impl DoubleEndedIterator<Item = Cow<'a, str>> + ExactSizeIterator<Item = Cow<'a, str>>\n    {\n        self.ranges.iter().map(move |range| range.fragment(text))\n    }\n\n    pub fn slices<'a>(\n        &'a self,\n        text: RopeSlice<'a>,\n    ) -> impl DoubleEndedIterator<Item = RopeSlice<'a>> + ExactSizeIterator<Item = RopeSlice<'a>> + 'a\n    {\n        self.ranges.iter().map(move |range| range.slice(text))\n    }\n\n    #[inline(always)]\n    pub fn iter(&self) -> std::slice::Iter<'_, Range> {\n        self.ranges.iter()\n    }\n\n    #[inline(always)]\n    pub fn len(&self) -> usize {\n        self.ranges.len()\n    }\n\n    /// returns true if self ⊇ other\n    pub fn contains(&self, other: &Selection) -> bool {\n        is_subset::<true>(self.range_bounds(), other.range_bounds())\n    }\n}\n\nimpl<'a> IntoIterator for &'a Selection {\n    type Item = &'a Range;\n    type IntoIter = std::slice::Iter<'a, Range>;\n\n    fn into_iter(self) -> std::slice::Iter<'a, Range> {\n        self.ranges().iter()\n    }\n}\n\nimpl IntoIterator for Selection {\n    type Item = Range;\n    type IntoIter = smallvec::IntoIter<[Range; 1]>;\n\n    fn into_iter(self) -> smallvec::IntoIter<[Range; 1]> {\n        self.ranges.into_iter()\n    }\n}\n\nimpl FromIterator<Range> for Selection {\n    fn from_iter<T: IntoIterator<Item = Range>>(ranges: T) -> Self {\n        Self::new(ranges.into_iter().collect(), 0)\n    }\n}\n\nimpl From<Range> for Selection {\n    fn from(range: Range) -> Self {\n        Self {\n            ranges: smallvec![range],\n            primary_index: 0,\n        }\n    }\n}\n\npub struct LineRangeIter<'a> {\n    ranges: iter::Peekable<slice::Iter<'a, Range>>,\n    text: RopeSlice<'a>,\n}\n\nimpl Iterator for LineRangeIter<'_> {\n    type Item = (usize, usize);\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let (start, mut end) = self.ranges.next()?.line_range(self.text);\n        while let Some((next_start, next_end)) =\n            self.ranges.peek().map(|range| range.line_range(self.text))\n        {\n            // Merge overlapping and adjacent ranges.\n            // This subtraction cannot underflow because the ranges are sorted.\n            if next_start - end <= 1 {\n                end = next_end;\n                self.ranges.next();\n            } else {\n                break;\n            }\n        }\n\n        Some((start, end))\n    }\n}\n\n// TODO: checkSelection -> check if valid for doc length && sorted\n\npub fn keep_or_remove_matches(\n    text: RopeSlice,\n    selection: &Selection,\n    regex: &rope::Regex,\n    remove: bool,\n) -> Option<Selection> {\n    let result: SmallVec<_> = selection\n        .iter()\n        .filter(|range| regex.is_match(text.regex_input_at(range.from()..range.to())) ^ remove)\n        .copied()\n        .collect();\n\n    // TODO: figure out a new primary index\n    if !result.is_empty() {\n        return Some(Selection::new(result, 0));\n    }\n    None\n}\n\n// TODO: support to split on capture #N instead of whole match\npub fn select_on_matches(\n    text: RopeSlice,\n    selection: &Selection,\n    regex: &rope::Regex,\n) -> Option<Selection> {\n    let mut result = SmallVec::with_capacity(selection.len());\n\n    for sel in selection {\n        for mat in regex.find_iter(text.regex_input_at(sel.from()..sel.to())) {\n            // TODO: retain range direction\n\n            let start = text.byte_to_char(mat.start());\n            let end = text.byte_to_char(mat.end());\n\n            let range = Range::new(start, end);\n            // Make sure the match is not right outside of the selection.\n            // These invalid matches can come from using RegEx anchors like `^`, `$`\n            if range != Range::point(sel.to()) {\n                result.push(range);\n            }\n        }\n    }\n\n    // TODO: figure out a new primary index\n    if !result.is_empty() {\n        return Some(Selection::new(result, 0));\n    }\n\n    None\n}\n\npub fn split_on_newline(text: RopeSlice, selection: &Selection) -> Selection {\n    let mut result = SmallVec::with_capacity(selection.len());\n\n    for sel in selection {\n        // Special case: zero-width selection.\n        if sel.from() == sel.to() {\n            result.push(*sel);\n            continue;\n        }\n\n        let sel_start = sel.from();\n        let sel_end = sel.to();\n\n        let mut start = sel_start;\n\n        for line in sel.slice(text).lines() {\n            let Some(line_ending) = get_line_ending(&line) else {\n                break;\n            };\n            let line_end = start + line.len_chars();\n            // TODO: retain range direction\n            result.push(Range::new(start, line_end - line_ending.len_chars()));\n            start = line_end;\n        }\n\n        if start < sel_end {\n            result.push(Range::new(start, sel_end));\n        }\n    }\n\n    // TODO: figure out a new primary index\n    Selection::new(result, 0)\n}\n\npub fn split_on_matches(text: RopeSlice, selection: &Selection, regex: &rope::Regex) -> Selection {\n    let mut result = SmallVec::with_capacity(selection.len());\n\n    for sel in selection {\n        // Special case: zero-width selection.\n        if sel.from() == sel.to() {\n            result.push(*sel);\n            continue;\n        }\n\n        let sel_start = sel.from();\n        let sel_end = sel.to();\n        let mut start = sel_start;\n\n        for mat in regex.find_iter(text.regex_input_at(sel_start..sel_end)) {\n            // TODO: retain range direction\n            let end = text.byte_to_char(mat.start());\n            result.push(Range::new(start, end));\n            start = text.byte_to_char(mat.end());\n        }\n\n        if start < sel_end {\n            result.push(Range::new(start, sel_end));\n        }\n    }\n\n    // TODO: figure out a new primary index\n    Selection::new(result, 0)\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::Rope;\n\n    #[test]\n    #[should_panic]\n    fn test_new_empty() {\n        let _ = Selection::new(smallvec![], 0);\n    }\n\n    #[test]\n    fn test_create_normalizes_and_merges() {\n        let sel = Selection::new(\n            smallvec![\n                Range::new(10, 12),\n                Range::new(6, 7),\n                Range::new(4, 5),\n                Range::new(3, 4),\n                Range::new(0, 6),\n                Range::new(7, 8),\n                Range::new(9, 13),\n                Range::new(13, 14),\n            ],\n            0,\n        );\n\n        let res = sel\n            .ranges\n            .into_iter()\n            .map(|range| format!(\"{}/{}\", range.anchor, range.head))\n            .collect::<Vec<String>>()\n            .join(\",\");\n\n        assert_eq!(res, \"0/6,6/7,7/8,9/13,13/14\");\n\n        // it correctly calculates a new primary index\n        let sel = Selection::new(\n            smallvec![Range::new(0, 2), Range::new(1, 5), Range::new(4, 7)],\n            2,\n        );\n\n        let res = sel\n            .ranges\n            .into_iter()\n            .map(|range| format!(\"{}/{}\", range.anchor, range.head))\n            .collect::<Vec<String>>()\n            .join(\",\");\n\n        assert_eq!(res, \"0/7\");\n        assert_eq!(sel.primary_index, 0);\n    }\n\n    #[test]\n    fn test_create_merges_adjacent_points() {\n        let sel = Selection::new(\n            smallvec![\n                Range::new(10, 12),\n                Range::new(12, 12),\n                Range::new(12, 12),\n                Range::new(10, 10),\n                Range::new(8, 10),\n            ],\n            0,\n        );\n\n        let res = sel\n            .ranges\n            .into_iter()\n            .map(|range| format!(\"{}/{}\", range.anchor, range.head))\n            .collect::<Vec<String>>()\n            .join(\",\");\n\n        assert_eq!(res, \"8/10,10/12,12/12\");\n    }\n\n    #[test]\n    fn test_contains() {\n        let range = Range::new(10, 12);\n\n        assert!(!range.contains(9));\n        assert!(range.contains(10));\n        assert!(range.contains(11));\n        assert!(!range.contains(12));\n        assert!(!range.contains(13));\n\n        let range = Range::new(9, 6);\n        assert!(!range.contains(9));\n        assert!(range.contains(7));\n        assert!(range.contains(6));\n    }\n\n    #[test]\n    fn test_overlaps() {\n        fn overlaps(a: (usize, usize), b: (usize, usize)) -> bool {\n            Range::new(a.0, a.1).overlaps(&Range::new(b.0, b.1))\n        }\n\n        // Two non-zero-width ranges, no overlap.\n        assert!(!overlaps((0, 3), (3, 6)));\n        assert!(!overlaps((0, 3), (6, 3)));\n        assert!(!overlaps((3, 0), (3, 6)));\n        assert!(!overlaps((3, 0), (6, 3)));\n        assert!(!overlaps((3, 6), (0, 3)));\n        assert!(!overlaps((3, 6), (3, 0)));\n        assert!(!overlaps((6, 3), (0, 3)));\n        assert!(!overlaps((6, 3), (3, 0)));\n\n        // Two non-zero-width ranges, overlap.\n        assert!(overlaps((0, 4), (3, 6)));\n        assert!(overlaps((0, 4), (6, 3)));\n        assert!(overlaps((4, 0), (3, 6)));\n        assert!(overlaps((4, 0), (6, 3)));\n        assert!(overlaps((3, 6), (0, 4)));\n        assert!(overlaps((3, 6), (4, 0)));\n        assert!(overlaps((6, 3), (0, 4)));\n        assert!(overlaps((6, 3), (4, 0)));\n\n        // Zero-width and non-zero-width range, no overlap.\n        assert!(!overlaps((0, 3), (3, 3)));\n        assert!(!overlaps((3, 0), (3, 3)));\n        assert!(!overlaps((3, 3), (0, 3)));\n        assert!(!overlaps((3, 3), (3, 0)));\n\n        // Zero-width and non-zero-width range, overlap.\n        assert!(overlaps((1, 4), (1, 1)));\n        assert!(overlaps((4, 1), (1, 1)));\n        assert!(overlaps((1, 1), (1, 4)));\n        assert!(overlaps((1, 1), (4, 1)));\n\n        assert!(overlaps((1, 4), (3, 3)));\n        assert!(overlaps((4, 1), (3, 3)));\n        assert!(overlaps((3, 3), (1, 4)));\n        assert!(overlaps((3, 3), (4, 1)));\n\n        // Two zero-width ranges, no overlap.\n        assert!(!overlaps((0, 0), (1, 1)));\n        assert!(!overlaps((1, 1), (0, 0)));\n\n        // Two zero-width ranges, overlap.\n        assert!(overlaps((1, 1), (1, 1)));\n    }\n\n    #[test]\n    fn test_grapheme_aligned() {\n        let r = Rope::from_str(\"\\r\\nHi\\r\\n\");\n        let s = r.slice(..);\n\n        // Zero-width.\n        assert_eq!(Range::new(0, 0).grapheme_aligned(s), Range::new(0, 0));\n        assert_eq!(Range::new(1, 1).grapheme_aligned(s), Range::new(0, 0));\n        assert_eq!(Range::new(2, 2).grapheme_aligned(s), Range::new(2, 2));\n        assert_eq!(Range::new(3, 3).grapheme_aligned(s), Range::new(3, 3));\n        assert_eq!(Range::new(4, 4).grapheme_aligned(s), Range::new(4, 4));\n        assert_eq!(Range::new(5, 5).grapheme_aligned(s), Range::new(4, 4));\n        assert_eq!(Range::new(6, 6).grapheme_aligned(s), Range::new(6, 6));\n\n        // Forward.\n        assert_eq!(Range::new(0, 1).grapheme_aligned(s), Range::new(0, 2));\n        assert_eq!(Range::new(1, 2).grapheme_aligned(s), Range::new(0, 2));\n        assert_eq!(Range::new(2, 3).grapheme_aligned(s), Range::new(2, 3));\n        assert_eq!(Range::new(3, 4).grapheme_aligned(s), Range::new(3, 4));\n        assert_eq!(Range::new(4, 5).grapheme_aligned(s), Range::new(4, 6));\n        assert_eq!(Range::new(5, 6).grapheme_aligned(s), Range::new(4, 6));\n\n        assert_eq!(Range::new(0, 2).grapheme_aligned(s), Range::new(0, 2));\n        assert_eq!(Range::new(1, 3).grapheme_aligned(s), Range::new(0, 3));\n        assert_eq!(Range::new(2, 4).grapheme_aligned(s), Range::new(2, 4));\n        assert_eq!(Range::new(3, 5).grapheme_aligned(s), Range::new(3, 6));\n        assert_eq!(Range::new(4, 6).grapheme_aligned(s), Range::new(4, 6));\n\n        // Reverse.\n        assert_eq!(Range::new(1, 0).grapheme_aligned(s), Range::new(2, 0));\n        assert_eq!(Range::new(2, 1).grapheme_aligned(s), Range::new(2, 0));\n        assert_eq!(Range::new(3, 2).grapheme_aligned(s), Range::new(3, 2));\n        assert_eq!(Range::new(4, 3).grapheme_aligned(s), Range::new(4, 3));\n        assert_eq!(Range::new(5, 4).grapheme_aligned(s), Range::new(6, 4));\n        assert_eq!(Range::new(6, 5).grapheme_aligned(s), Range::new(6, 4));\n\n        assert_eq!(Range::new(2, 0).grapheme_aligned(s), Range::new(2, 0));\n        assert_eq!(Range::new(3, 1).grapheme_aligned(s), Range::new(3, 0));\n        assert_eq!(Range::new(4, 2).grapheme_aligned(s), Range::new(4, 2));\n        assert_eq!(Range::new(5, 3).grapheme_aligned(s), Range::new(6, 3));\n        assert_eq!(Range::new(6, 4).grapheme_aligned(s), Range::new(6, 4));\n    }\n\n    #[test]\n    fn test_min_width_1() {\n        let r = Rope::from_str(\"\\r\\nHi\\r\\n\");\n        let s = r.slice(..);\n\n        // Zero-width.\n        assert_eq!(Range::new(0, 0).min_width_1(s), Range::new(0, 2));\n        assert_eq!(Range::new(1, 1).min_width_1(s), Range::new(1, 2));\n        assert_eq!(Range::new(2, 2).min_width_1(s), Range::new(2, 3));\n        assert_eq!(Range::new(3, 3).min_width_1(s), Range::new(3, 4));\n        assert_eq!(Range::new(4, 4).min_width_1(s), Range::new(4, 6));\n        assert_eq!(Range::new(5, 5).min_width_1(s), Range::new(5, 6));\n        assert_eq!(Range::new(6, 6).min_width_1(s), Range::new(6, 6));\n\n        // Forward.\n        assert_eq!(Range::new(0, 1).min_width_1(s), Range::new(0, 1));\n        assert_eq!(Range::new(1, 2).min_width_1(s), Range::new(1, 2));\n        assert_eq!(Range::new(2, 3).min_width_1(s), Range::new(2, 3));\n        assert_eq!(Range::new(3, 4).min_width_1(s), Range::new(3, 4));\n        assert_eq!(Range::new(4, 5).min_width_1(s), Range::new(4, 5));\n        assert_eq!(Range::new(5, 6).min_width_1(s), Range::new(5, 6));\n\n        // Reverse.\n        assert_eq!(Range::new(1, 0).min_width_1(s), Range::new(1, 0));\n        assert_eq!(Range::new(2, 1).min_width_1(s), Range::new(2, 1));\n        assert_eq!(Range::new(3, 2).min_width_1(s), Range::new(3, 2));\n        assert_eq!(Range::new(4, 3).min_width_1(s), Range::new(4, 3));\n        assert_eq!(Range::new(5, 4).min_width_1(s), Range::new(5, 4));\n        assert_eq!(Range::new(6, 5).min_width_1(s), Range::new(6, 5));\n    }\n\n    #[test]\n    fn test_select_on_matches() {\n        let r = Rope::from_str(\"Nobody expects the Spanish inquisition\");\n        let s = r.slice(..);\n\n        let selection = Selection::single(0, r.len_chars());\n        assert_eq!(\n            select_on_matches(s, &selection, &rope::Regex::new(r\"[A-Z][a-z]*\").unwrap()),\n            Some(Selection::new(\n                smallvec![Range::new(0, 6), Range::new(19, 26)],\n                0\n            ))\n        );\n\n        let r = Rope::from_str(\"This\\nString\\n\\ncontains multiple\\nlines\");\n        let s = r.slice(..);\n\n        let start_of_line = rope::RegexBuilder::new()\n            .syntax(rope::Config::new().multi_line(true))\n            .build(r\"^\")\n            .unwrap();\n        let end_of_line = rope::RegexBuilder::new()\n            .syntax(rope::Config::new().multi_line(true))\n            .build(r\"$\")\n            .unwrap();\n\n        // line without ending\n        assert_eq!(\n            select_on_matches(s, &Selection::single(0, 4), &start_of_line),\n            Some(Selection::single(0, 0))\n        );\n        assert_eq!(\n            select_on_matches(s, &Selection::single(0, 4), &end_of_line),\n            None\n        );\n        // line with ending\n        assert_eq!(\n            select_on_matches(s, &Selection::single(0, 5), &start_of_line),\n            Some(Selection::single(0, 0))\n        );\n        assert_eq!(\n            select_on_matches(s, &Selection::single(0, 5), &end_of_line),\n            Some(Selection::single(4, 4))\n        );\n        // line with start of next line\n        assert_eq!(\n            select_on_matches(s, &Selection::single(0, 6), &start_of_line),\n            Some(Selection::new(\n                smallvec![Range::point(0), Range::point(5)],\n                0\n            ))\n        );\n        assert_eq!(\n            select_on_matches(s, &Selection::single(0, 6), &end_of_line),\n            Some(Selection::single(4, 4))\n        );\n\n        // multiple lines\n        assert_eq!(\n            select_on_matches(\n                s,\n                &Selection::single(0, s.len_chars()),\n                &rope::RegexBuilder::new()\n                    .syntax(rope::Config::new().multi_line(true))\n                    .build(r\"^[a-z ]*$\")\n                    .unwrap()\n            ),\n            Some(Selection::new(\n                smallvec![Range::point(12), Range::new(13, 30), Range::new(31, 36)],\n                0\n            ))\n        );\n    }\n\n    #[test]\n    fn test_line_range() {\n        let r = Rope::from_str(\"\\r\\nHi\\r\\nthere!\");\n        let s = r.slice(..);\n\n        // Zero-width ranges.\n        assert_eq!(Range::new(0, 0).line_range(s), (0, 0));\n        assert_eq!(Range::new(1, 1).line_range(s), (0, 0));\n        assert_eq!(Range::new(2, 2).line_range(s), (1, 1));\n        assert_eq!(Range::new(3, 3).line_range(s), (1, 1));\n\n        // Forward ranges.\n        assert_eq!(Range::new(0, 1).line_range(s), (0, 0));\n        assert_eq!(Range::new(0, 2).line_range(s), (0, 0));\n        assert_eq!(Range::new(0, 3).line_range(s), (0, 1));\n        assert_eq!(Range::new(1, 2).line_range(s), (0, 0));\n        assert_eq!(Range::new(2, 3).line_range(s), (1, 1));\n        assert_eq!(Range::new(3, 8).line_range(s), (1, 2));\n        assert_eq!(Range::new(0, 12).line_range(s), (0, 2));\n\n        // Reverse ranges.\n        assert_eq!(Range::new(1, 0).line_range(s), (0, 0));\n        assert_eq!(Range::new(2, 0).line_range(s), (0, 0));\n        assert_eq!(Range::new(3, 0).line_range(s), (0, 1));\n        assert_eq!(Range::new(2, 1).line_range(s), (0, 0));\n        assert_eq!(Range::new(3, 2).line_range(s), (1, 1));\n        assert_eq!(Range::new(8, 3).line_range(s), (1, 2));\n        assert_eq!(Range::new(12, 0).line_range(s), (0, 2));\n    }\n\n    #[test]\n    fn selection_line_ranges() {\n        let (text, selection) = crate::test::print(\n            r#\"                                           L0\n            #[|these]# line #(|ranges)# are #(|merged)#   L1\n                                                          L2\n            single one-line #(|range)#                    L3\n                                                          L4\n            single #(|multiline                           L5\n            range)#                                       L6\n                                                          L7\n            these #(|multiline                            L8\n            ranges)# are #(|also                          L9\n            merged)#                                      L10\n                                                          L11\n            adjacent #(|ranges)#                          L12\n            are merged #(|the same way)#                  L13\n            \"#,\n        );\n        let rope = Rope::from_str(&text);\n        assert_eq!(\n            vec![(1, 1), (3, 3), (5, 6), (8, 10), (12, 13)],\n            selection.line_ranges(rope.slice(..)).collect::<Vec<_>>(),\n        );\n    }\n\n    #[test]\n    fn test_cursor() {\n        let r = Rope::from_str(\"\\r\\nHi\\r\\nthere!\");\n        let s = r.slice(..);\n\n        // Zero-width ranges.\n        assert_eq!(Range::new(0, 0).cursor(s), 0);\n        assert_eq!(Range::new(2, 2).cursor(s), 2);\n        assert_eq!(Range::new(3, 3).cursor(s), 3);\n\n        // Forward ranges.\n        assert_eq!(Range::new(0, 2).cursor(s), 0);\n        assert_eq!(Range::new(0, 3).cursor(s), 2);\n        assert_eq!(Range::new(3, 6).cursor(s), 4);\n\n        // Reverse ranges.\n        assert_eq!(Range::new(2, 0).cursor(s), 0);\n        assert_eq!(Range::new(6, 2).cursor(s), 2);\n        assert_eq!(Range::new(6, 3).cursor(s), 3);\n    }\n\n    #[test]\n    fn test_put_cursor() {\n        let r = Rope::from_str(\"\\r\\nHi\\r\\nthere!\");\n        let s = r.slice(..);\n\n        // Zero-width ranges.\n        assert_eq!(Range::new(0, 0).put_cursor(s, 0, true), Range::new(0, 2));\n        assert_eq!(Range::new(0, 0).put_cursor(s, 2, true), Range::new(0, 3));\n        assert_eq!(Range::new(2, 3).put_cursor(s, 4, true), Range::new(2, 6));\n        assert_eq!(Range::new(2, 8).put_cursor(s, 4, true), Range::new(2, 6));\n        assert_eq!(Range::new(8, 8).put_cursor(s, 4, true), Range::new(9, 4));\n\n        // Forward ranges.\n        assert_eq!(Range::new(3, 6).put_cursor(s, 0, true), Range::new(4, 0));\n        assert_eq!(Range::new(3, 6).put_cursor(s, 2, true), Range::new(4, 2));\n        assert_eq!(Range::new(3, 6).put_cursor(s, 3, true), Range::new(3, 4));\n        assert_eq!(Range::new(3, 6).put_cursor(s, 4, true), Range::new(3, 6));\n        assert_eq!(Range::new(3, 6).put_cursor(s, 6, true), Range::new(3, 7));\n        assert_eq!(Range::new(3, 6).put_cursor(s, 8, true), Range::new(3, 9));\n\n        // Reverse ranges.\n        assert_eq!(Range::new(6, 3).put_cursor(s, 0, true), Range::new(6, 0));\n        assert_eq!(Range::new(6, 3).put_cursor(s, 2, true), Range::new(6, 2));\n        assert_eq!(Range::new(6, 3).put_cursor(s, 3, true), Range::new(6, 3));\n        assert_eq!(Range::new(6, 3).put_cursor(s, 4, true), Range::new(6, 4));\n        assert_eq!(Range::new(6, 3).put_cursor(s, 6, true), Range::new(4, 7));\n        assert_eq!(Range::new(6, 3).put_cursor(s, 8, true), Range::new(4, 9));\n    }\n\n    #[test]\n    fn test_split_on_matches() {\n        let text = Rope::from(\" abcd efg wrs   xyz 123 456\");\n\n        let selection = Selection::new(smallvec![Range::new(0, 9), Range::new(11, 20),], 0);\n\n        let result = split_on_matches(\n            text.slice(..),\n            &selection,\n            &rope::Regex::new(r\"\\s+\").unwrap(),\n        );\n\n        assert_eq!(\n            result.ranges(),\n            &[\n                // TODO: rather than this behavior, maybe we want it\n                // to be based on which side is the anchor?\n                //\n                // We get a leading zero-width range when there's\n                // a leading match because ranges are inclusive on\n                // the left.  Imagine, for example, if the entire\n                // selection range were matched: you'd still want\n                // at least one range to remain after the split.\n                Range::new(0, 0),\n                Range::new(1, 5),\n                Range::new(6, 9),\n                Range::new(11, 13),\n                Range::new(16, 19),\n                // In contrast to the comment above, there is no\n                // _trailing_ zero-width range despite the trailing\n                // match, because ranges are exclusive on the right.\n            ]\n        );\n\n        assert_eq!(\n            result.fragments(text.slice(..)).collect::<Vec<_>>(),\n            &[\"\", \"abcd\", \"efg\", \"rs\", \"xyz\"]\n        );\n    }\n\n    #[test]\n    fn test_merge_consecutive_ranges() {\n        let selection = Selection::new(\n            smallvec![\n                Range::new(0, 1),\n                Range::new(1, 10),\n                Range::new(15, 20),\n                Range::new(25, 26),\n                Range::new(26, 30)\n            ],\n            4,\n        );\n\n        let result = selection.merge_consecutive_ranges();\n\n        assert_eq!(\n            result.ranges(),\n            &[Range::new(0, 10), Range::new(15, 20), Range::new(25, 30)]\n        );\n        assert_eq!(result.primary_index, 2);\n\n        let selection = Selection::new(smallvec![Range::new(0, 1)], 0);\n        let result = selection.merge_consecutive_ranges();\n\n        assert_eq!(result.ranges(), &[Range::new(0, 1)]);\n        assert_eq!(result.primary_index, 0);\n\n        let selection = Selection::new(\n            smallvec![\n                Range::new(0, 1),\n                Range::new(1, 5),\n                Range::new(5, 8),\n                Range::new(8, 10),\n                Range::new(10, 15),\n                Range::new(18, 25)\n            ],\n            3,\n        );\n\n        let result = selection.merge_consecutive_ranges();\n\n        assert_eq!(result.ranges(), &[Range::new(0, 15), Range::new(18, 25)]);\n        assert_eq!(result.primary_index, 0);\n    }\n\n    #[test]\n    fn test_selection_contains() {\n        fn contains(a: Vec<(usize, usize)>, b: Vec<(usize, usize)>) -> bool {\n            let sela = Selection::new(a.iter().map(|a| Range::new(a.0, a.1)).collect(), 0);\n            let selb = Selection::new(b.iter().map(|b| Range::new(b.0, b.1)).collect(), 0);\n            sela.contains(&selb)\n        }\n\n        // exact match\n        assert!(contains(vec!((1, 1)), vec!((1, 1))));\n\n        // larger set contains smaller\n        assert!(contains(vec!((1, 1), (2, 2), (3, 3)), vec!((2, 2))));\n\n        // multiple matches\n        assert!(contains(vec!((1, 1), (2, 2)), vec!((1, 1), (2, 2))));\n\n        // smaller set can't contain bigger\n        assert!(!contains(vec!((1, 1)), vec!((1, 1), (2, 2))));\n\n        assert!(contains(\n            vec!((1, 1), (2, 4), (5, 6), (7, 9), (10, 13)),\n            vec!((3, 4), (7, 9))\n        ));\n        assert!(!contains(vec!((1, 1), (5, 6)), vec!((1, 6))));\n\n        // multiple ranges of other are all contained in some ranges of self,\n        assert!(contains(\n            vec!((1, 4), (7, 10)),\n            vec!((1, 2), (3, 4), (7, 9))\n        ));\n    }\n}\n"
  },
  {
    "path": "helix-core/src/snippets/active.rs",
    "content": "use std::ops::{Index, IndexMut};\n\nuse foldhash::HashSet;\nuse helix_stdx::range::{is_exact_subset, is_subset};\nuse helix_stdx::Range;\nuse ropey::Rope;\n\nuse crate::movement::Direction;\nuse crate::snippets::render::{RenderedSnippet, Tabstop};\nuse crate::snippets::TabstopIdx;\nuse crate::{Assoc, ChangeSet, Selection, Transaction};\n\npub struct ActiveSnippet {\n    ranges: Vec<Range>,\n    active_tabstops: HashSet<TabstopIdx>,\n    current_tabstop: TabstopIdx,\n    tabstops: Vec<Tabstop>,\n}\n\nimpl Index<TabstopIdx> for ActiveSnippet {\n    type Output = Tabstop;\n    fn index(&self, index: TabstopIdx) -> &Tabstop {\n        &self.tabstops[index.0]\n    }\n}\n\nimpl IndexMut<TabstopIdx> for ActiveSnippet {\n    fn index_mut(&mut self, index: TabstopIdx) -> &mut Tabstop {\n        &mut self.tabstops[index.0]\n    }\n}\n\nimpl ActiveSnippet {\n    pub fn new(snippet: RenderedSnippet) -> Option<Self> {\n        let snippet = Self {\n            ranges: snippet.ranges,\n            tabstops: snippet.tabstops,\n            active_tabstops: HashSet::default(),\n            current_tabstop: TabstopIdx(0),\n        };\n        (snippet.tabstops.len() != 1).then_some(snippet)\n    }\n\n    pub fn is_valid(&self, new_selection: &Selection) -> bool {\n        is_subset::<false>(self.ranges.iter().copied(), new_selection.range_bounds())\n    }\n\n    pub fn tabstops(&self) -> impl Iterator<Item = &Tabstop> {\n        self.tabstops.iter()\n    }\n\n    pub fn delete_placeholder(&self, doc: &Rope) -> Transaction {\n        Transaction::delete(\n            doc,\n            self[self.current_tabstop]\n                .ranges\n                .iter()\n                .map(|range| (range.start, range.end)),\n        )\n    }\n\n    /// maps the active snippets through a `ChangeSet` updating all tabstop ranges\n    pub fn map(&mut self, changes: &ChangeSet) -> bool {\n        let positions_to_map = self.ranges.iter_mut().flat_map(|range| {\n            [\n                (&mut range.start, Assoc::After),\n                (&mut range.end, Assoc::Before),\n            ]\n        });\n        changes.update_positions(positions_to_map);\n\n        for (i, tabstop) in self.tabstops.iter_mut().enumerate() {\n            if self.active_tabstops.contains(&TabstopIdx(i)) {\n                let positions_to_map = tabstop.ranges.iter_mut().flat_map(|range| {\n                    let end_assoc = if range.start == range.end {\n                        Assoc::Before\n                    } else {\n                        Assoc::After\n                    };\n                    [\n                        (&mut range.start, Assoc::Before),\n                        (&mut range.end, end_assoc),\n                    ]\n                });\n                changes.update_positions(positions_to_map);\n            } else {\n                let positions_to_map = tabstop.ranges.iter_mut().flat_map(|range| {\n                    let end_assoc = if range.start == range.end {\n                        Assoc::After\n                    } else {\n                        Assoc::Before\n                    };\n                    [\n                        (&mut range.start, Assoc::After),\n                        (&mut range.end, end_assoc),\n                    ]\n                });\n                changes.update_positions(positions_to_map);\n            }\n            let mut snippet_ranges = self.ranges.iter();\n            let mut snippet_range = snippet_ranges.next().unwrap();\n            let mut tabstop_i = 0;\n            let mut prev = Range { start: 0, end: 0 };\n            let num_ranges = tabstop.ranges.len() / self.ranges.len();\n            tabstop.ranges.retain_mut(|range| {\n                if tabstop_i == num_ranges {\n                    snippet_range = snippet_ranges.next().unwrap();\n                    tabstop_i = 0;\n                }\n                tabstop_i += 1;\n                let retain = snippet_range.start <= snippet_range.end;\n                if retain {\n                    range.start = range.start.max(snippet_range.start);\n                    range.end = range.end.max(range.start).min(snippet_range.end);\n                    // guaranteed by assoc\n                    debug_assert!(prev.start <= range.start);\n                    debug_assert!(range.start <= range.end);\n                    if prev.end > range.start {\n                        // not really sure what to do in this case. It shouldn't\n                        // really occur in practice, the below just ensures\n                        // our invariants hold\n                        range.start = prev.end;\n                        range.end = range.end.max(range.start)\n                    }\n                    prev = *range;\n                }\n                retain\n            });\n        }\n        self.ranges.iter().all(|range| range.end <= range.start)\n    }\n\n    pub fn next_tabstop(&mut self, current_selection: &Selection) -> (Selection, bool) {\n        let primary_idx = self.primary_idx(current_selection);\n        while self.current_tabstop.0 + 1 < self.tabstops.len() {\n            self.current_tabstop.0 += 1;\n            if self.activate_tabstop() {\n                let selection = self.tabstop_selection(primary_idx, Direction::Forward);\n                return (selection, self.current_tabstop.0 + 1 == self.tabstops.len());\n            }\n        }\n\n        (\n            self.tabstop_selection(primary_idx, Direction::Forward),\n            true,\n        )\n    }\n\n    pub fn prev_tabstop(&mut self, current_selection: &Selection) -> Option<Selection> {\n        let primary_idx = self.primary_idx(current_selection);\n        while self.current_tabstop.0 != 0 {\n            self.current_tabstop.0 -= 1;\n            if self.activate_tabstop() {\n                return Some(self.tabstop_selection(primary_idx, Direction::Forward));\n            }\n        }\n        None\n    }\n    // computes the primary idx adjusted for the number of cursors in the current tabstop\n    fn primary_idx(&self, current_selection: &Selection) -> usize {\n        let primary: Range = current_selection.primary().into();\n        let res = self\n            .ranges\n            .iter()\n            .position(|&range| range.contains(primary));\n        res.unwrap_or_else(|| {\n            unreachable!(\n                \"active snippet must be valid {current_selection:?} {:?}\",\n                self.ranges\n            )\n        })\n    }\n\n    fn activate_tabstop(&mut self) -> bool {\n        let tabstop = &self[self.current_tabstop];\n        if tabstop.has_placeholder() && tabstop.ranges.iter().all(|range| range.is_empty()) {\n            return false;\n        }\n        self.active_tabstops.clear();\n        self.active_tabstops.insert(self.current_tabstop);\n        let mut parent = self[self.current_tabstop].parent;\n        while let Some(tabstop) = parent {\n            self.active_tabstops.insert(tabstop);\n            parent = self[tabstop].parent;\n        }\n        true\n        // TODO: if the user removes the selection(s) in one snippet (but\n        // there are still other cursors in other snippets) and jumps to the\n        // next tabstop the selection in that tabstop is restored (at the\n        // next tabstop). This could be annoying since its not possible to\n        // remove a snippet cursor until the snippet is complete. On the other\n        // hand it may be useful since the user may just have meant to edit\n        // a subselection (like with s) of the tabstops and so the selection\n        // removal was just temporary. Potentially this could have some sort of\n        // separate keymap\n    }\n\n    pub fn tabstop_selection(&self, primary_idx: usize, direction: Direction) -> Selection {\n        let tabstop = &self[self.current_tabstop];\n        tabstop.selection(direction, primary_idx, self.ranges.len())\n    }\n\n    pub fn insert_subsnippet(mut self, snippet: RenderedSnippet) -> Option<Self> {\n        if !snippet.ranges.len().is_multiple_of(self.ranges.len())\n            || !is_exact_subset(self.ranges.iter().copied(), snippet.ranges.iter().copied())\n        {\n            log::warn!(\"number of subsnippets did not match, discarding outer snippet\");\n            return ActiveSnippet::new(snippet);\n        }\n        let mut cnt = 0;\n        let parent = self[self.current_tabstop].parent;\n        let tabstops = snippet.tabstops.into_iter().map(|mut tabstop| {\n            cnt += 1;\n            if let Some(parent) = &mut tabstop.parent {\n                parent.0 += self.current_tabstop.0;\n            } else {\n                tabstop.parent = parent;\n            }\n            tabstop\n        });\n        self.tabstops\n            .splice(self.current_tabstop.0..=self.current_tabstop.0, tabstops);\n        self.activate_tabstop();\n        Some(self)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::iter::{self};\n\n    use ropey::Rope;\n\n    use crate::snippets::{ActiveSnippet, Snippet, SnippetRenderCtx};\n    use crate::{Selection, Transaction};\n\n    #[test]\n    fn fully_remove() {\n        let snippet = Snippet::parse(\"foo(${1:bar})$0\").unwrap();\n        let mut doc = Rope::from(\"bar.\\n\");\n        let (transaction, _, snippet) = snippet.render(\n            &doc,\n            &Selection::point(4),\n            |_| (4, 4),\n            &mut SnippetRenderCtx::test_ctx(),\n        );\n        assert!(transaction.apply(&mut doc));\n        assert_eq!(doc, \"bar.foo(bar)\\n\");\n        let mut snippet = ActiveSnippet::new(snippet).unwrap();\n        let edit = Transaction::change(&doc, iter::once((4, 12, None)));\n        assert!(edit.apply(&mut doc));\n        snippet.map(edit.changes());\n        assert!(!snippet.is_valid(&Selection::point(4)))\n    }\n\n    #[test]\n    fn tabstop_zero_with_placeholder() {\n        // The `$0` tabstop should not have placeholder text. When we receive a snippet like this\n        // (from older versions of clangd for example) we should discard the placeholder text.\n        let snippet = Snippet::parse(\"sizeof(${0:expression-or-type})\").unwrap();\n        let mut doc = Rope::from(\"\\n\");\n        let (transaction, _, snippet) = snippet.render(\n            &doc,\n            &Selection::point(0),\n            |_| (0, 0),\n            &mut SnippetRenderCtx::test_ctx(),\n        );\n        assert!(transaction.apply(&mut doc));\n        assert_eq!(doc, \"sizeof()\\n\");\n        assert!(ActiveSnippet::new(snippet).is_none());\n    }\n}\n"
  },
  {
    "path": "helix-core/src/snippets/elaborate.rs",
    "content": "use std::mem::swap;\nuse std::ops::Index;\nuse std::sync::Arc;\n\nuse anyhow::{anyhow, Result};\nuse helix_stdx::rope::RopeSliceExt;\nuse helix_stdx::Range;\nuse regex_cursor::engines::meta::Builder as RegexBuilder;\nuse regex_cursor::engines::meta::Regex;\nuse regex_cursor::regex_automata::util::syntax::Config as RegexConfig;\nuse ropey::RopeSlice;\n\nuse crate::case_conversion::to_lower_case_with;\nuse crate::case_conversion::to_upper_case_with;\nuse crate::case_conversion::{to_camel_case_with, to_pascal_case_with};\nuse crate::snippets::parser::{self, CaseChange, FormatItem};\nuse crate::snippets::{TabstopIdx, LAST_TABSTOP_IDX};\nuse crate::Tendril;\n\n#[derive(Debug)]\npub struct Snippet {\n    elements: Vec<SnippetElement>,\n    tabstops: Vec<Tabstop>,\n}\n\nimpl Snippet {\n    pub fn parse(snippet: &str) -> Result<Self> {\n        let parsed_snippet = parser::parse(snippet)\n            .map_err(|rest| anyhow!(\"Failed to parse snippet. Remaining input: {}\", rest))?;\n        Ok(Snippet::new(parsed_snippet))\n    }\n\n    pub fn new(elements: Vec<parser::SnippetElement>) -> Snippet {\n        let mut res = Snippet {\n            elements: Vec::new(),\n            tabstops: Vec::new(),\n        };\n        res.elements = res.elaborate(elements, None).into();\n        res.fixup_tabstops();\n        res.ensure_last_tabstop();\n        res.renumber_tabstops();\n        res\n    }\n\n    pub fn elements(&self) -> &[SnippetElement] {\n        &self.elements\n    }\n\n    pub fn tabstops(&self) -> impl Iterator<Item = &Tabstop> {\n        self.tabstops.iter()\n    }\n\n    fn renumber_tabstops(&mut self) {\n        Self::renumber_tabstops_in(&self.tabstops, &mut self.elements);\n        for i in 0..self.tabstops.len() {\n            if let Some(parent) = self.tabstops[i].parent {\n                let parent = self\n                    .tabstops\n                    .binary_search_by_key(&parent, |tabstop| tabstop.idx)\n                    .expect(\"all tabstops have been resolved\");\n                self.tabstops[i].parent = Some(TabstopIdx(parent));\n            }\n            let tabstop = &mut self.tabstops[i];\n            if let TabstopKind::Placeholder { default } = &tabstop.kind {\n                let mut default = default.clone();\n                tabstop.kind = TabstopKind::Empty;\n                Self::renumber_tabstops_in(&self.tabstops, Arc::get_mut(&mut default).unwrap());\n                self.tabstops[i].kind = TabstopKind::Placeholder { default };\n            }\n        }\n    }\n\n    fn renumber_tabstops_in(tabstops: &[Tabstop], elements: &mut [SnippetElement]) {\n        for elem in elements {\n            match elem {\n                SnippetElement::Tabstop { idx } => {\n                    idx.0 = tabstops\n                        .binary_search_by_key(&*idx, |tabstop| tabstop.idx)\n                        .expect(\"all tabstops have been resolved\")\n                }\n                SnippetElement::Variable { default, .. } => {\n                    if let Some(default) = default {\n                        Self::renumber_tabstops_in(tabstops, default);\n                    }\n                }\n                SnippetElement::Text(_) => (),\n            }\n        }\n    }\n\n    fn fixup_tabstops(&mut self) {\n        self.tabstops.sort_by_key(|tabstop| tabstop.idx);\n        self.tabstops.dedup_by(|tabstop1, tabstop2| {\n            if tabstop1.idx != tabstop2.idx {\n                return false;\n            }\n            // use the first non empty tabstop for all multicursor tabstops\n            if tabstop2.kind.is_empty() {\n                swap(tabstop2, tabstop1)\n            }\n            true\n        })\n    }\n\n    fn ensure_last_tabstop(&mut self) {\n        if matches!(self.tabstops.last(), Some(tabstop) if tabstop.idx == LAST_TABSTOP_IDX) {\n            return;\n        }\n        self.tabstops.push(Tabstop {\n            idx: LAST_TABSTOP_IDX,\n            parent: None,\n            kind: TabstopKind::Empty,\n        });\n        self.elements.push(SnippetElement::Tabstop {\n            idx: LAST_TABSTOP_IDX,\n        })\n    }\n\n    fn elaborate(\n        &mut self,\n        default: Vec<parser::SnippetElement>,\n        parent: Option<TabstopIdx>,\n    ) -> Box<[SnippetElement]> {\n        default\n            .into_iter()\n            .map(|val| match val {\n                parser::SnippetElement::Tabstop {\n                    tabstop,\n                    transform: None,\n                } => SnippetElement::Tabstop {\n                    idx: self.elaborate_placeholder(tabstop, parent, Vec::new()),\n                },\n                parser::SnippetElement::Tabstop {\n                    tabstop,\n                    transform: Some(transform),\n                } => SnippetElement::Tabstop {\n                    idx: self.elaborate_transform(tabstop, parent, transform),\n                },\n                parser::SnippetElement::Placeholder { tabstop, value } => SnippetElement::Tabstop {\n                    idx: self.elaborate_placeholder(tabstop, parent, value),\n                },\n                parser::SnippetElement::Choice { tabstop, choices } => SnippetElement::Tabstop {\n                    idx: self.elaborate_choice(tabstop, parent, choices),\n                },\n                parser::SnippetElement::Variable {\n                    name,\n                    default,\n                    transform,\n                } => SnippetElement::Variable {\n                    name,\n                    default: default.map(|default| self.elaborate(default, parent)),\n                    // TODO: error for invalid transforms\n                    transform: transform.and_then(Transform::new).map(Box::new),\n                },\n                parser::SnippetElement::Text(text) => SnippetElement::Text(text),\n            })\n            .collect()\n    }\n\n    fn elaborate_choice(\n        &mut self,\n        idx: usize,\n        parent: Option<TabstopIdx>,\n        choices: Vec<Tendril>,\n    ) -> TabstopIdx {\n        let idx = TabstopIdx::elaborate(idx);\n        self.tabstops.push(Tabstop {\n            idx,\n            parent,\n            kind: TabstopKind::Choice {\n                choices: choices.into(),\n            },\n        });\n        idx\n    }\n\n    fn elaborate_placeholder(\n        &mut self,\n        idx: usize,\n        parent: Option<TabstopIdx>,\n        mut default: Vec<parser::SnippetElement>,\n    ) -> TabstopIdx {\n        let idx = TabstopIdx::elaborate(idx);\n        if idx == LAST_TABSTOP_IDX && !default.is_empty() {\n            // Older versions of clangd for example may send a snippet like `${0:placeholder}`\n            // which is considered by VSCode to be a misuse of the `$0` tabstop.\n            log::warn!(\"Discarding placeholder text for the `$0` tabstop ({default:?}). \\\n                The `$0` tabstop signifies the final cursor position and should not include placeholder text.\");\n            default.clear();\n        }\n        let default = self.elaborate(default, Some(idx));\n        self.tabstops.push(Tabstop {\n            idx,\n            parent,\n            kind: TabstopKind::Placeholder {\n                default: default.into(),\n            },\n        });\n        idx\n    }\n\n    fn elaborate_transform(\n        &mut self,\n        idx: usize,\n        parent: Option<TabstopIdx>,\n        transform: parser::Transform,\n    ) -> TabstopIdx {\n        let idx = TabstopIdx::elaborate(idx);\n        if let Some(transform) = Transform::new(transform) {\n            self.tabstops.push(Tabstop {\n                idx,\n                parent,\n                kind: TabstopKind::Transform(Arc::new(transform)),\n            })\n        } else {\n            // TODO: proper error\n            self.tabstops.push(Tabstop {\n                idx,\n                parent,\n                kind: TabstopKind::Empty,\n            })\n        }\n        idx\n    }\n}\n\nimpl Index<TabstopIdx> for Snippet {\n    type Output = Tabstop;\n    fn index(&self, index: TabstopIdx) -> &Tabstop {\n        &self.tabstops[index.0]\n    }\n}\n\n#[derive(Debug)]\npub enum SnippetElement {\n    Tabstop {\n        idx: TabstopIdx,\n    },\n    Variable {\n        name: Tendril,\n        default: Option<Box<[SnippetElement]>>,\n        transform: Option<Box<Transform>>,\n    },\n    Text(Tendril),\n}\n\n#[derive(Debug)]\npub struct Tabstop {\n    idx: TabstopIdx,\n    pub parent: Option<TabstopIdx>,\n    pub kind: TabstopKind,\n}\n\n#[derive(Debug)]\npub enum TabstopKind {\n    Choice { choices: Arc<[Tendril]> },\n    Placeholder { default: Arc<[SnippetElement]> },\n    Empty,\n    Transform(Arc<Transform>),\n}\n\nimpl TabstopKind {\n    pub fn is_empty(&self) -> bool {\n        matches!(self, TabstopKind::Empty)\n    }\n}\n\n#[derive(Debug)]\npub struct Transform {\n    regex: Regex,\n    regex_str: Box<str>,\n    global: bool,\n    replacement: Box<[FormatItem]>,\n}\n\nimpl PartialEq for Transform {\n    fn eq(&self, other: &Self) -> bool {\n        self.replacement == other.replacement\n            && self.global == other.global\n            // doens't compare m and i setting but close enough\n            && self.regex_str == other.regex_str\n    }\n}\n\nimpl Transform {\n    fn new(transform: parser::Transform) -> Option<Transform> {\n        let mut config = RegexConfig::new();\n        let mut global = false;\n        let mut invalid_config = false;\n        for c in transform.options.chars() {\n            match c {\n                'i' => {\n                    config = config.case_insensitive(true);\n                }\n                'm' => {\n                    config = config.multi_line(true);\n                }\n                'g' => {\n                    global = true;\n                }\n                // we ignore 'u' since we always want to\n                // do unicode aware matching\n                _ => invalid_config = true,\n            }\n        }\n        if invalid_config {\n            log::error!(\"invalid transform configuration characters {transform:?}\");\n        }\n        let regex = match RegexBuilder::new().syntax(config).build(&transform.regex) {\n            Ok(regex) => regex,\n            Err(err) => {\n                log::error!(\"invalid transform {err} {transform:?}\");\n                return None;\n            }\n        };\n        Some(Transform {\n            regex,\n            regex_str: transform.regex.as_str().into(),\n            global,\n            replacement: transform.replacement.into(),\n        })\n    }\n\n    pub fn apply(&self, mut doc: RopeSlice<'_>, range: Range) -> Tendril {\n        let mut buf = Tendril::new();\n        let it = self.regex.captures_iter(doc.regex_input_at(range));\n        doc = doc.slice(range);\n        let mut last_match = 0;\n        for cap in it {\n            // unwrap on 0 is OK because captures only reports matches\n            let m = cap.get_group(0).unwrap();\n            buf.extend(doc.byte_slice(last_match..m.start).chunks());\n            last_match = m.end;\n            for fmt in &*self.replacement {\n                match *fmt {\n                    FormatItem::Text(ref text) => {\n                        buf.push_str(text);\n                    }\n                    FormatItem::Capture(i) => {\n                        if let Some(cap) = cap.get_group(i) {\n                            buf.extend(doc.byte_slice(cap.range()).chunks());\n                        }\n                    }\n                    FormatItem::CaseChange(i, change) => {\n                        if let Some(cap) = cap.get_group(i).filter(|i| !i.is_empty()) {\n                            let mut chars = doc.byte_slice(cap.range()).chars();\n                            match change {\n                                CaseChange::Upcase => to_upper_case_with(chars, &mut buf),\n                                CaseChange::Downcase => to_lower_case_with(chars, &mut buf),\n                                CaseChange::Capitalize => {\n                                    let first_char = chars.next().unwrap();\n                                    buf.extend(first_char.to_uppercase());\n                                    buf.extend(chars);\n                                }\n                                CaseChange::PascalCase => to_pascal_case_with(chars, &mut buf),\n                                CaseChange::CamelCase => to_camel_case_with(chars, &mut buf),\n                            }\n                        }\n                    }\n                    FormatItem::Conditional(i, ref if_, ref else_) => {\n                        if cap.get_group(i).is_none_or(|mat| mat.is_empty()) {\n                            buf.push_str(else_)\n                        } else {\n                            buf.push_str(if_)\n                        }\n                    }\n                }\n            }\n            if !self.global {\n                break;\n            }\n        }\n        buf.extend(doc.byte_slice(last_match..).chunks());\n        buf\n    }\n}\n\nimpl TabstopIdx {\n    fn elaborate(idx: usize) -> Self {\n        TabstopIdx(idx.wrapping_sub(1))\n    }\n}\n"
  },
  {
    "path": "helix-core/src/snippets/parser.rs",
    "content": "/*!\nA parser for LSP/VSCode style snippet syntax\nSee <https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#snippet_syntax>.\n\n``` text\nany         ::= tabstop | placeholder | choice | variable | text\ntabstop     ::= '$' int | '${' int '}'\nplaceholder ::= '${' int ':' any '}'\nchoice      ::= '${' int '|' text (',' text)* '|}'\nvariable    ::= '$' var | '${' var }'\n                | '${' var ':' any '}'\n                | '${' var '/' regex '/' (format | text)+ '/' options '}'\nformat      ::= '$' int | '${' int '}'\n                | '${' int ':' '/upcase' | '/downcase' | '/capitalize' '}'\n                | '${' int ':+' if '}'\n                | '${' int ':?' if ':' else '}'\n                | '${' int ':-' else '}' | '${' int ':' else '}'\nregex       ::= Regular Expression value (ctor-string)\noptions     ::= Regular Expression option (ctor-options)\nvar         ::= [_a-zA-Z] [_a-zA-Z0-9]*\nint         ::= [0-9]+\ntext        ::= .*\nif          ::= text\nelse        ::= text\n```\n*/\n\nuse crate::Tendril;\nuse helix_parsec::*;\n\n#[derive(Debug, PartialEq, Eq, Clone, Copy)]\npub enum CaseChange {\n    Upcase,\n    Downcase,\n    Capitalize,\n    PascalCase,\n    CamelCase,\n}\n\n#[derive(Debug, PartialEq, Eq)]\npub enum FormatItem {\n    Text(Tendril),\n    Capture(usize),\n    CaseChange(usize, CaseChange),\n    Conditional(usize, Tendril, Tendril),\n}\n\n#[derive(Debug, PartialEq, Eq)]\npub struct Transform {\n    pub regex: Tendril,\n    pub replacement: Vec<FormatItem>,\n    pub options: Tendril,\n}\n\n#[derive(Debug, PartialEq, Eq)]\npub enum SnippetElement {\n    Tabstop {\n        tabstop: usize,\n        transform: Option<Transform>,\n    },\n    Placeholder {\n        tabstop: usize,\n        value: Vec<SnippetElement>,\n    },\n    Choice {\n        tabstop: usize,\n        choices: Vec<Tendril>,\n    },\n    Variable {\n        name: Tendril,\n        default: Option<Vec<SnippetElement>>,\n        transform: Option<Transform>,\n    },\n    Text(Tendril),\n}\n\npub fn parse(s: &str) -> Result<Vec<SnippetElement>, &str> {\n    snippet().parse(s).and_then(|(remainder, snippet)| {\n        if remainder.is_empty() {\n            Ok(snippet)\n        } else {\n            Err(remainder)\n        }\n    })\n}\n\nfn var<'a>() -> impl Parser<'a, Output = &'a str> {\n    // var = [_a-zA-Z][_a-zA-Z0-9]*\n    move |input: &'a str| {\n        input\n            .char_indices()\n            .take_while(|(p, c)| {\n                *c == '_'\n                    || if *p == 0 {\n                        c.is_ascii_alphabetic()\n                    } else {\n                        c.is_ascii_alphanumeric()\n                    }\n            })\n            .last()\n            .map(|(index, c)| {\n                let index = index + c.len_utf8();\n                (&input[index..], &input[0..index])\n            })\n            .ok_or(input)\n    }\n}\n\nconst TEXT_ESCAPE_CHARS: &[char] = &['\\\\', '}', '$'];\nconst CHOICE_TEXT_ESCAPE_CHARS: &[char] = &['\\\\', '|', ','];\n\nfn text<'a>(\n    escape_chars: &'static [char],\n    term_chars: &'static [char],\n) -> impl Parser<'a, Output = Tendril> {\n    move |input: &'a str| {\n        let mut chars = input.char_indices().peekable();\n        let mut res = Tendril::new();\n        while let Some((i, c)) = chars.next() {\n            match c {\n                '\\\\' => {\n                    if let Some(&(_, c)) = chars.peek() {\n                        if escape_chars.contains(&c) {\n                            chars.next();\n                            res.push(c);\n                            continue;\n                        }\n                    }\n                    res.push('\\\\');\n                }\n                c if term_chars.contains(&c) => return Ok((&input[i..], res)),\n                c => res.push(c),\n            }\n        }\n\n        Ok((\"\", res))\n    }\n}\n\nfn digit<'a>() -> impl Parser<'a, Output = usize> {\n    filter_map(take_while(|c| c.is_ascii_digit()), |s| s.parse().ok())\n}\n\nfn case_change<'a>() -> impl Parser<'a, Output = CaseChange> {\n    use CaseChange::*;\n\n    choice!(\n        map(\"upcase\", |_| Upcase),\n        map(\"downcase\", |_| Downcase),\n        map(\"capitalize\", |_| Capitalize),\n        map(\"pascalcase\", |_| PascalCase),\n        map(\"camelcase\", |_| CamelCase),\n    )\n}\n\nfn format<'a>() -> impl Parser<'a, Output = FormatItem> {\n    use FormatItem::*;\n\n    choice!(\n        // '$' int\n        map(right(\"$\", digit()), Capture),\n        // '${' int '}'\n        map(seq!(\"${\", digit(), \"}\"), |seq| Capture(seq.1)),\n        // '${' int ':' '/upcase' | '/downcase' | '/capitalize' '}'\n        map(seq!(\"${\", digit(), \":/\", case_change(), \"}\"), |seq| {\n            CaseChange(seq.1, seq.3)\n        }),\n        // '${' int ':+' if '}'\n        map(\n            seq!(\"${\", digit(), \":+\", text(TEXT_ESCAPE_CHARS, &['}']), \"}\"),\n            |seq| { Conditional(seq.1, seq.3, Tendril::new()) }\n        ),\n        // '${' int ':?' if ':' else '}'\n        map(\n            seq!(\n                \"${\",\n                digit(),\n                \":?\",\n                text(TEXT_ESCAPE_CHARS, &[':']),\n                \":\",\n                text(TEXT_ESCAPE_CHARS, &['}']),\n                \"}\"\n            ),\n            |seq| { Conditional(seq.1, seq.3, seq.5) }\n        ),\n        // '${' int ':-' else '}' | '${' int ':' else '}'\n        map(\n            seq!(\n                \"${\",\n                digit(),\n                \":\",\n                optional(\"-\"),\n                text(TEXT_ESCAPE_CHARS, &['}']),\n                \"}\"\n            ),\n            |seq| { Conditional(seq.1, Tendril::new(), seq.4) }\n        ),\n    )\n}\n\nfn regex<'a>() -> impl Parser<'a, Output = Transform> {\n    map(\n        seq!(\n            \"/\",\n            // TODO parse as ECMAScript and convert to rust regex\n            text(&['/'], &['/']),\n            \"/\",\n            zero_or_more(choice!(\n                format(),\n                // text doesn't parse $, if format fails we just accept the $ as text\n                map(\"$\", |_| FormatItem::Text(\"$\".into())),\n                map(text(&['\\\\', '/'], &['/', '$']), FormatItem::Text),\n            )),\n            \"/\",\n            // vscode really doesn't allow escaping } here\n            // so it's impossible to write a regex escape containing a }\n            // we can consider deviating here and allowing the escape\n            text(&[], &['}']),\n        ),\n        |(_, value, _, replacement, _, options)| Transform {\n            regex: value,\n            replacement,\n            options,\n        },\n    )\n}\n\nfn tabstop<'a>() -> impl Parser<'a, Output = SnippetElement> {\n    map(\n        or(\n            map(right(\"$\", digit()), |i| (i, None)),\n            map(\n                seq!(\"${\", digit(), optional(regex()), \"}\"),\n                |(_, i, transform, _)| (i, transform),\n            ),\n        ),\n        |(tabstop, transform)| SnippetElement::Tabstop { tabstop, transform },\n    )\n}\n\nfn placeholder<'a>() -> impl Parser<'a, Output = SnippetElement> {\n    map(\n        seq!(\n            \"${\",\n            digit(),\n            \":\",\n            // according to the grammar there is just a single anything here.\n            // However in the prose it is explained that placeholders can be nested.\n            // The example there contains both a placeholder text and a nested placeholder\n            // which indicates a list. Looking at the VSCode sourcecode, the placeholder\n            // is indeed parsed as zero_or_more so the grammar is simply incorrect here\n            zero_or_more(anything(TEXT_ESCAPE_CHARS, true)),\n            \"}\"\n        ),\n        |seq| SnippetElement::Placeholder {\n            tabstop: seq.1,\n            value: seq.3,\n        },\n    )\n}\n\nfn choice<'a>() -> impl Parser<'a, Output = SnippetElement> {\n    map(\n        seq!(\n            \"${\",\n            digit(),\n            \"|\",\n            sep(text(CHOICE_TEXT_ESCAPE_CHARS, &['|', ',']), \",\"),\n            \"|}\",\n        ),\n        |seq| SnippetElement::Choice {\n            tabstop: seq.1,\n            choices: seq.3,\n        },\n    )\n}\n\nfn variable<'a>() -> impl Parser<'a, Output = SnippetElement> {\n    choice!(\n        // $var\n        map(right(\"$\", var()), |name| SnippetElement::Variable {\n            name: name.into(),\n            default: None,\n            transform: None,\n        }),\n        // ${var}\n        map(seq!(\"${\", var(), \"}\",), |values| SnippetElement::Variable {\n            name: values.1.into(),\n            default: None,\n            transform: None,\n        }),\n        // ${var:default}\n        map(\n            seq!(\n                \"${\",\n                var(),\n                \":\",\n                zero_or_more(anything(TEXT_ESCAPE_CHARS, true)),\n                \"}\",\n            ),\n            |values| SnippetElement::Variable {\n                name: values.1.into(),\n                default: Some(values.3),\n                transform: None,\n            }\n        ),\n        // ${var/value/format/options}\n        map(seq!(\"${\", var(), regex(), \"}\"), |values| {\n            SnippetElement::Variable {\n                name: values.1.into(),\n                default: None,\n                transform: Some(values.2),\n            }\n        }),\n    )\n}\n\nfn anything<'a>(\n    escape_chars: &'static [char],\n    end_at_brace: bool,\n) -> impl Parser<'a, Output = SnippetElement> {\n    let term_chars: &[_] = if end_at_brace { &['$', '}'] } else { &['$'] };\n    move |input: &'a str| {\n        let parser = choice!(\n            tabstop(),\n            placeholder(),\n            choice(),\n            variable(),\n            map(\"$\", |_| SnippetElement::Text(\"$\".into())),\n            map(text(escape_chars, term_chars), SnippetElement::Text),\n        );\n        parser.parse(input)\n    }\n}\n\nfn snippet<'a>() -> impl Parser<'a, Output = Vec<SnippetElement>> {\n    one_or_more(anything(TEXT_ESCAPE_CHARS, false))\n}\n\n#[cfg(test)]\nmod test {\n    use crate::snippets::{Snippet, SnippetRenderCtx};\n\n    use super::SnippetElement::*;\n    use super::*;\n\n    #[test]\n    fn empty_string_is_error() {\n        assert_eq!(Err(\"\"), parse(\"\"));\n    }\n\n    #[test]\n    fn parse_placeholders_in_function_call() {\n        assert_eq!(\n            Ok(vec![\n                Text(\"match(\".into()),\n                Placeholder {\n                    tabstop: 1,\n                    value: vec![Text(\"Arg1\".into())],\n                },\n                Text(\")\".into()),\n            ]),\n            parse(\"match(${1:Arg1})\")\n        );\n        // The `$0` tabstop should not have placeholder text. The parser should handle this case\n        // normally and then the placeholder text should be discarded during elaboration.\n        assert_eq!(\n            Ok(vec![\n                Text(\"sizeof(\".into()),\n                Placeholder {\n                    tabstop: 0,\n                    value: vec![Text(\"expression-or-type\".into())],\n                },\n                Text(\")\".into()),\n            ]),\n            parse(\"sizeof(${0:expression-or-type})\")\n        );\n    }\n\n    #[test]\n    fn unterminated_placeholder() {\n        assert_eq!(\n            Ok(vec![\n                Text(\"match(\".into()),\n                Text(\"$\".into()),\n                Text(\"{1:)\".into())\n            ]),\n            parse(\"match(${1:)\")\n        )\n    }\n\n    #[test]\n    fn parse_empty_placeholder() {\n        assert_eq!(\n            Ok(vec![\n                Text(\"match(\".into()),\n                Placeholder {\n                    tabstop: 1,\n                    value: vec![],\n                },\n                Text(\")\".into()),\n            ]),\n            parse(\"match(${1:})\")\n        )\n    }\n\n    #[test]\n    fn parse_placeholders_in_statement() {\n        assert_eq!(\n            Ok(vec![\n                Text(\"local \".into()),\n                Placeholder {\n                    tabstop: 1,\n                    value: vec![Text(\"var\".into())],\n                },\n                Text(\" = \".into()),\n                Placeholder {\n                    tabstop: 1,\n                    value: vec![Text(\"value\".into())],\n                },\n            ]),\n            parse(\"local ${1:var} = ${1:value}\")\n        )\n    }\n\n    #[test]\n    fn parse_tabstop_nested_in_placeholder() {\n        assert_eq!(\n            Ok(vec![Placeholder {\n                tabstop: 1,\n                value: vec![\n                    Text(\"var, \".into()),\n                    Tabstop {\n                        tabstop: 2,\n                        transform: None\n                    }\n                ],\n            }]),\n            parse(\"${1:var, $2}\")\n        )\n    }\n\n    #[test]\n    fn parse_placeholder_nested_in_placeholder() {\n        assert_eq!(\n            Ok({\n                vec![Placeholder {\n                    tabstop: 1,\n                    value: vec![\n                        Text(\"foo \".into()),\n                        Placeholder {\n                            tabstop: 2,\n                            value: vec![Text(\"bar\".into())],\n                        },\n                    ],\n                }]\n            }),\n            parse(\"${1:foo ${2:bar}}\")\n        )\n    }\n\n    #[test]\n    fn parse_all() {\n        assert_eq!(\n            Ok(vec![\n                Text(\"hello \".into()),\n                Tabstop {\n                    tabstop: 1,\n                    transform: None\n                },\n                Tabstop {\n                    tabstop: 2,\n                    transform: None\n                },\n                Text(\" \".into()),\n                Choice {\n                    tabstop: 1,\n                    choices: vec![\"one\".into(), \"two\".into(), \"three\".into()],\n                },\n                Text(\" \".into()),\n                Variable {\n                    name: \"name\".into(),\n                    default: Some(vec![Text(\"foo\".into())]),\n                    transform: None,\n                },\n                Text(\" \".into()),\n                Variable {\n                    name: \"var\".into(),\n                    default: None,\n                    transform: None,\n                },\n                Text(\" \".into()),\n                Variable {\n                    name: \"TM\".into(),\n                    default: None,\n                    transform: None,\n                },\n            ]),\n            parse(\"hello $1${2} ${1|one,two,three|} ${name:foo} $var $TM\")\n        );\n    }\n\n    #[test]\n    fn regex_capture_replace() {\n        assert_eq!(\n            Ok({\n                vec![Variable {\n                    name: \"TM_FILENAME\".into(),\n                    default: None,\n                    transform: Some(Transform {\n                        regex: \"(.*).+$\".into(),\n                        replacement: vec![FormatItem::Capture(1), FormatItem::Text(\"$\".into())],\n                        options: Tendril::new(),\n                    }),\n                }]\n            }),\n            parse(\"${TM_FILENAME/(.*).+$/$1$/}\")\n        );\n    }\n\n    #[test]\n    fn rust_macro() {\n        assert_eq!(\n            Ok({\n                vec![\n                    Text(\"macro_rules! \".into()),\n                    Tabstop {\n                        tabstop: 1,\n                        transform: None,\n                    },\n                    Text(\" {\\n    (\".into()),\n                    Tabstop {\n                        tabstop: 2,\n                        transform: None,\n                    },\n                    Text(\") => {\\n        \".into()),\n                    Tabstop {\n                        tabstop: 0,\n                        transform: None,\n                    },\n                    Text(\"\\n    };\\n}\".into()),\n                ]\n            }),\n            parse(\"macro_rules! $1 {\\n    ($2) => {\\n        $0\\n    };\\n}\")\n        );\n    }\n\n    fn assert_text(snippet: &str, parsed_text: &str) {\n        let snippet = Snippet::parse(snippet).unwrap();\n        let mut rendered_snippet = snippet.prepare_render();\n        let rendered_text = snippet\n            .render_at(\n                &mut rendered_snippet,\n                \"\".into(),\n                false,\n                &mut SnippetRenderCtx::test_ctx(),\n                0,\n            )\n            .0;\n        assert_eq!(rendered_text, parsed_text)\n    }\n\n    #[test]\n    fn robust_parsing() {\n        assert_text(\"$\", \"$\");\n        assert_text(\"\\\\\\\\$\", \"\\\\$\");\n        assert_text(\"{\", \"{\");\n        assert_text(\"\\\\}\", \"}\");\n        assert_text(\"\\\\abc\", \"\\\\abc\");\n        assert_text(\"foo${f:\\\\}}bar\", \"foo}bar\");\n        assert_text(\"\\\\{\", \"\\\\{\");\n        assert_text(\"I need \\\\\\\\\\\\$\", \"I need \\\\$\");\n        assert_text(\"\\\\\", \"\\\\\");\n        assert_text(\"\\\\{{\", \"\\\\{{\");\n        assert_text(\"{{\", \"{{\");\n        assert_text(\"{{dd\", \"{{dd\");\n        assert_text(\"}}\", \"}}\");\n        assert_text(\"ff}}\", \"ff}}\");\n        assert_text(\"farboo\", \"farboo\");\n        assert_text(\"far{{}}boo\", \"far{{}}boo\");\n        assert_text(\"far{{123}}boo\", \"far{{123}}boo\");\n        assert_text(\"far\\\\{{123}}boo\", \"far\\\\{{123}}boo\");\n        assert_text(\"far{{id:bern}}boo\", \"far{{id:bern}}boo\");\n        assert_text(\"far{{id:bern {{basel}}}}boo\", \"far{{id:bern {{basel}}}}boo\");\n        assert_text(\n            \"far{{id:bern {{id:basel}}}}boo\",\n            \"far{{id:bern {{id:basel}}}}boo\",\n        );\n        assert_text(\n            \"far{{id:bern {{id2:basel}}}}boo\",\n            \"far{{id:bern {{id2:basel}}}}boo\",\n        );\n        assert_text(\"${}$\\\\a\\\\$\\\\}\\\\\\\\\", \"${}$\\\\a$}\\\\\");\n        assert_text(\"farboo\", \"farboo\");\n        assert_text(\"far{{}}boo\", \"far{{}}boo\");\n        assert_text(\"far{{123}}boo\", \"far{{123}}boo\");\n        assert_text(\"far\\\\{{123}}boo\", \"far\\\\{{123}}boo\");\n        assert_text(\"far`123`boo\", \"far`123`boo\");\n        assert_text(\"far\\\\`123\\\\`boo\", \"far\\\\`123\\\\`boo\");\n        assert_text(\"\\\\$far-boo\", \"$far-boo\");\n    }\n\n    fn assert_snippet(snippet: &str, expect: &[SnippetElement]) {\n        let elements = parse(snippet).unwrap();\n        assert_eq!(elements, expect.to_owned())\n    }\n\n    #[test]\n    fn parse_variable() {\n        use SnippetElement::*;\n        assert_snippet(\n            \"$far-boo\",\n            &[\n                Variable {\n                    name: \"far\".into(),\n                    default: None,\n                    transform: None,\n                },\n                Text(\"-boo\".into()),\n            ],\n        );\n        assert_snippet(\n            \"far$farboo\",\n            &[\n                Text(\"far\".into()),\n                Variable {\n                    name: \"farboo\".into(),\n                    transform: None,\n                    default: None,\n                },\n            ],\n        );\n        assert_snippet(\n            \"far${farboo}\",\n            &[\n                Text(\"far\".into()),\n                Variable {\n                    name: \"farboo\".into(),\n                    transform: None,\n                    default: None,\n                },\n            ],\n        );\n        assert_snippet(\n            \"$123\",\n            &[Tabstop {\n                tabstop: 123,\n                transform: None,\n            }],\n        );\n        assert_snippet(\n            \"$farboo\",\n            &[Variable {\n                name: \"farboo\".into(),\n                transform: None,\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"$far12boo\",\n            &[Variable {\n                name: \"far12boo\".into(),\n                transform: None,\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"000_${far}_000\",\n            &[\n                Text(\"000_\".into()),\n                Variable {\n                    name: \"far\".into(),\n                    transform: None,\n                    default: None,\n                },\n                Text(\"_000\".into()),\n            ],\n        );\n    }\n\n    #[test]\n    fn parse_variable_transform() {\n        assert_snippet(\n            \"${foo///}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: Tendril::new(),\n                    replacement: Vec::new(),\n                    options: Tendril::new(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${foo/regex/format/gmi}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \"regex\".into(),\n                    replacement: vec![FormatItem::Text(\"format\".into())],\n                    options: \"gmi\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${foo/([A-Z][a-z])/format/}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \"([A-Z][a-z])\".into(),\n                    replacement: vec![FormatItem::Text(\"format\".into())],\n                    options: Tendril::new(),\n                }),\n                default: None,\n            }],\n        );\n\n        // invalid regex TODO: reneable tests once we actually parse this regex flavor\n        // assert_text(\n        //     \"${foo/([A-Z][a-z])/format/GMI}\",\n        //     \"${foo/([A-Z][a-z])/format/GMI}\",\n        // );\n        // assert_text(\n        //     \"${foo/([A-Z][a-z])/format/funky}\",\n        //     \"${foo/([A-Z][a-z])/format/funky}\",\n        // );\n        // assert_text(\"${foo/([A-Z][a-z]/format/}\", \"${foo/([A-Z][a-z]/format/}\");\n        assert_text(\n            \"${foo/regex\\\\/format/options}\",\n            \"${foo/regex\\\\/format/options}\",\n        );\n\n        // tricky regex\n        assert_snippet(\n            \"${foo/m\\\\/atch/$1/i}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \"m/atch\".into(),\n                    replacement: vec![FormatItem::Capture(1)],\n                    options: \"i\".into(),\n                }),\n                default: None,\n            }],\n        );\n\n        // incomplete\n        assert_text(\"${foo///\", \"${foo///\");\n        assert_text(\"${foo/regex/format/options\", \"${foo/regex/format/options\");\n\n        // format string\n        assert_snippet(\n            \"${foo/.*/${0:fooo}/i}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \".*\".into(),\n                    replacement: vec![FormatItem::Conditional(0, Tendril::new(), \"fooo\".into())],\n                    options: \"i\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${foo/.*/${1}/i}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \".*\".into(),\n                    replacement: vec![FormatItem::Capture(1)],\n                    options: \"i\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${foo/.*/$1/i}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \".*\".into(),\n                    replacement: vec![FormatItem::Capture(1)],\n                    options: \"i\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${foo/.*/This-$1-encloses/i}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \".*\".into(),\n                    replacement: vec![\n                        FormatItem::Text(\"This-\".into()),\n                        FormatItem::Capture(1),\n                        FormatItem::Text(\"-encloses\".into()),\n                    ],\n                    options: \"i\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${foo/.*/complex${1:else}/i}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \".*\".into(),\n                    replacement: vec![\n                        FormatItem::Text(\"complex\".into()),\n                        FormatItem::Conditional(1, Tendril::new(), \"else\".into()),\n                    ],\n                    options: \"i\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${foo/.*/complex${1:-else}/i}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \".*\".into(),\n                    replacement: vec![\n                        FormatItem::Text(\"complex\".into()),\n                        FormatItem::Conditional(1, Tendril::new(), \"else\".into()),\n                    ],\n                    options: \"i\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${foo/.*/complex${1:+if}/i}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \".*\".into(),\n                    replacement: vec![\n                        FormatItem::Text(\"complex\".into()),\n                        FormatItem::Conditional(1, \"if\".into(), Tendril::new()),\n                    ],\n                    options: \"i\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${foo/.*/complex${1:?if:else}/i}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \".*\".into(),\n                    replacement: vec![\n                        FormatItem::Text(\"complex\".into()),\n                        FormatItem::Conditional(1, \"if\".into(), \"else\".into()),\n                    ],\n                    options: \"i\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${foo/.*/complex${1:/upcase}/i}\",\n            &[Variable {\n                name: \"foo\".into(),\n                transform: Some(Transform {\n                    regex: \".*\".into(),\n                    replacement: vec![\n                        FormatItem::Text(\"complex\".into()),\n                        FormatItem::CaseChange(1, CaseChange::Upcase),\n                    ],\n                    options: \"i\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${TM_DIRECTORY/src\\\\//$1/}\",\n            &[Variable {\n                name: \"TM_DIRECTORY\".into(),\n                transform: Some(Transform {\n                    regex: \"src/\".into(),\n                    replacement: vec![FormatItem::Capture(1)],\n                    options: Tendril::new(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${TM_SELECTED_TEXT/a/\\\\/$1/g}\",\n            &[Variable {\n                name: \"TM_SELECTED_TEXT\".into(),\n                transform: Some(Transform {\n                    regex: \"a\".into(),\n                    replacement: vec![FormatItem::Text(\"/\".into()), FormatItem::Capture(1)],\n                    options: \"g\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${TM_SELECTED_TEXT/a/in\\\\/$1ner/g}\",\n            &[Variable {\n                name: \"TM_SELECTED_TEXT\".into(),\n                transform: Some(Transform {\n                    regex: \"a\".into(),\n                    replacement: vec![\n                        FormatItem::Text(\"in/\".into()),\n                        FormatItem::Capture(1),\n                        FormatItem::Text(\"ner\".into()),\n                    ],\n                    options: \"g\".into(),\n                }),\n                default: None,\n            }],\n        );\n        assert_snippet(\n            \"${TM_SELECTED_TEXT/a/end\\\\//g}\",\n            &[Variable {\n                name: \"TM_SELECTED_TEXT\".into(),\n                transform: Some(Transform {\n                    regex: \"a\".into(),\n                    replacement: vec![FormatItem::Text(\"end/\".into())],\n                    options: \"g\".into(),\n                }),\n                default: None,\n            }],\n        );\n    }\n    // TODO port more tests from https://github.com/microsoft/vscode/blob/dce493cb6e36346ef2714e82c42ce14fc461b15c/src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts\n}\n"
  },
  {
    "path": "helix-core/src/snippets/render.rs",
    "content": "use std::borrow::Cow;\nuse std::ops::{Index, IndexMut};\nuse std::sync::Arc;\n\nuse helix_stdx::Range;\nuse ropey::{Rope, RopeSlice};\nuse smallvec::SmallVec;\n\nuse crate::indent::{normalize_indentation, IndentStyle};\nuse crate::movement::Direction;\nuse crate::snippets::elaborate;\nuse crate::snippets::TabstopIdx;\nuse crate::snippets::{Snippet, SnippetElement, Transform};\nuse crate::{selection, Selection, Tendril, Transaction};\n\n#[derive(Debug, Clone, PartialEq)]\npub enum TabstopKind {\n    Choice { choices: Arc<[Tendril]> },\n    Placeholder,\n    Empty,\n    Transform(Arc<Transform>),\n}\n\n#[derive(Debug, PartialEq)]\npub struct Tabstop {\n    pub ranges: SmallVec<[Range; 1]>,\n    pub parent: Option<TabstopIdx>,\n    pub kind: TabstopKind,\n}\n\nimpl Tabstop {\n    pub fn has_placeholder(&self) -> bool {\n        matches!(\n            self.kind,\n            TabstopKind::Choice { .. } | TabstopKind::Placeholder\n        )\n    }\n\n    pub fn selection(\n        &self,\n        direction: Direction,\n        primary_idx: usize,\n        snippet_ranges: usize,\n    ) -> Selection {\n        Selection::new(\n            self.ranges\n                .iter()\n                .map(|&range| {\n                    let mut range = selection::Range::new(range.start, range.end);\n                    if direction == Direction::Backward {\n                        range = range.flip()\n                    }\n                    range\n                })\n                .collect(),\n            primary_idx * (self.ranges.len() / snippet_ranges),\n        )\n    }\n}\n\n#[derive(Debug, Default, PartialEq)]\npub struct RenderedSnippet {\n    pub tabstops: Vec<Tabstop>,\n    pub ranges: Vec<Range>,\n}\n\nimpl RenderedSnippet {\n    pub fn first_selection(&self, direction: Direction, primary_idx: usize) -> Selection {\n        self.tabstops[0].selection(direction, primary_idx, self.ranges.len())\n    }\n}\n\nimpl Index<TabstopIdx> for RenderedSnippet {\n    type Output = Tabstop;\n    fn index(&self, index: TabstopIdx) -> &Tabstop {\n        &self.tabstops[index.0]\n    }\n}\n\nimpl IndexMut<TabstopIdx> for RenderedSnippet {\n    fn index_mut(&mut self, index: TabstopIdx) -> &mut Tabstop {\n        &mut self.tabstops[index.0]\n    }\n}\n\nimpl Snippet {\n    pub fn prepare_render(&self) -> RenderedSnippet {\n        let tabstops =\n            self.tabstops()\n                .map(|tabstop| Tabstop {\n                    ranges: SmallVec::new(),\n                    parent: tabstop.parent,\n                    kind: match &tabstop.kind {\n                        elaborate::TabstopKind::Choice { choices } => TabstopKind::Choice {\n                            choices: choices.clone(),\n                        },\n                        // start out as empty: the first non-empty placeholder will change this to\n                        // a placeholder automatically\n                        elaborate::TabstopKind::Empty\n                        | elaborate::TabstopKind::Placeholder { .. } => TabstopKind::Empty,\n                        elaborate::TabstopKind::Transform(transform) => {\n                            TabstopKind::Transform(transform.clone())\n                        }\n                    },\n                })\n                .collect();\n        RenderedSnippet {\n            tabstops,\n            ranges: Vec::new(),\n        }\n    }\n\n    pub fn render_at(\n        &self,\n        snippet: &mut RenderedSnippet,\n        indent: RopeSlice<'_>,\n        at_newline: bool,\n        ctx: &mut SnippetRenderCtx,\n        pos: usize,\n    ) -> (Tendril, usize) {\n        let mut ctx = SnippetRender {\n            dst: snippet,\n            src: self,\n            indent,\n            text: Tendril::new(),\n            off: pos,\n            ctx,\n            at_newline,\n        };\n        ctx.render_elements(self.elements());\n        let end = ctx.off;\n        let text = ctx.text;\n        snippet.ranges.push(Range { start: pos, end });\n        (text, end - pos)\n    }\n\n    pub fn render(\n        &self,\n        doc: &Rope,\n        selection: &Selection,\n        change_range: impl FnMut(&selection::Range) -> (usize, usize),\n        ctx: &mut SnippetRenderCtx,\n    ) -> (Transaction, Selection, RenderedSnippet) {\n        let mut snippet = self.prepare_render();\n        let mut off = 0;\n        let (transaction, selection) = Transaction::change_by_selection_ignore_overlapping(\n            doc,\n            selection,\n            change_range,\n            |replacement_start, replacement_end| {\n                let line_idx = doc.char_to_line(replacement_start);\n                let line_start = doc.line_to_char(line_idx);\n                let prefix = doc.slice(line_start..replacement_start);\n                let indent_len = prefix.chars().take_while(|c| c.is_whitespace()).count();\n                let indent = prefix.slice(..indent_len);\n                let at_newline = indent_len == replacement_start - line_start;\n\n                let (replacement, replacement_len) = self.render_at(\n                    &mut snippet,\n                    indent,\n                    at_newline,\n                    ctx,\n                    (replacement_start as i128 + off) as usize,\n                );\n                off +=\n                    replacement_start as i128 - replacement_end as i128 + replacement_len as i128;\n\n                Some(replacement)\n            },\n        );\n        (transaction, selection, snippet)\n    }\n}\n\npub type VariableResolver = dyn FnMut(&str) -> Option<Cow<str>>;\npub struct SnippetRenderCtx {\n    pub resolve_var: Box<VariableResolver>,\n    pub tab_width: usize,\n    pub indent_style: IndentStyle,\n    pub line_ending: &'static str,\n}\n\nimpl SnippetRenderCtx {\n    #[cfg(test)]\n    pub(super) fn test_ctx() -> SnippetRenderCtx {\n        SnippetRenderCtx {\n            resolve_var: Box::new(|_| None),\n            tab_width: 4,\n            indent_style: IndentStyle::Spaces(4),\n            line_ending: \"\\n\",\n        }\n    }\n}\n\nstruct SnippetRender<'a> {\n    ctx: &'a mut SnippetRenderCtx,\n    dst: &'a mut RenderedSnippet,\n    src: &'a Snippet,\n    indent: RopeSlice<'a>,\n    text: Tendril,\n    off: usize,\n    at_newline: bool,\n}\n\nimpl SnippetRender<'_> {\n    fn render_elements(&mut self, elements: &[SnippetElement]) {\n        for element in elements {\n            self.render_element(element)\n        }\n    }\n\n    fn render_element(&mut self, element: &SnippetElement) {\n        match *element {\n            SnippetElement::Tabstop { idx } => self.render_tabstop(idx),\n            SnippetElement::Variable {\n                ref name,\n                ref default,\n                ref transform,\n            } => {\n                // TODO: allow resolve_var access to the doc and make it return rope slice\n                // so we can access selections and other document content without allocating\n                if let Some(val) = (self.ctx.resolve_var)(name) {\n                    if let Some(transform) = transform {\n                        self.push_multiline_str(&transform.apply(\n                            (&*val).into(),\n                            Range {\n                                start: 0,\n                                end: val.chars().count(),\n                            },\n                        ));\n                    } else {\n                        self.push_multiline_str(&val)\n                    }\n                } else if let Some(default) = default {\n                    self.render_elements(default)\n                }\n            }\n            SnippetElement::Text(ref text) => self.push_multiline_str(text),\n        }\n    }\n\n    fn push_multiline_str(&mut self, text: &str) {\n        let mut lines = text\n            .split('\\n')\n            .map(|line| line.strip_suffix('\\r').unwrap_or(line));\n        let first_line = lines.next().unwrap();\n        self.push_str(first_line, self.at_newline);\n        for line in lines {\n            self.push_newline();\n            self.push_str(line, true);\n        }\n    }\n\n    fn push_str(&mut self, mut text: &str, at_newline: bool) {\n        if at_newline {\n            let old_len = self.text.len();\n            let old_indent_len = normalize_indentation(\n                self.indent,\n                text.into(),\n                &mut self.text,\n                self.ctx.indent_style,\n                self.ctx.tab_width,\n            );\n            // this is ok because indentation can only be ascii chars (' ' and '\\t')\n            self.off += self.text.len() - old_len;\n            text = &text[old_indent_len..];\n            if text.is_empty() {\n                self.at_newline = true;\n                return;\n            }\n        }\n        self.text.push_str(text);\n        self.off += text.chars().count();\n    }\n\n    fn push_newline(&mut self) {\n        self.off += self.ctx.line_ending.chars().count() + self.indent.len_chars();\n        self.text.push_str(self.ctx.line_ending);\n        self.text.extend(self.indent.chunks());\n    }\n\n    fn render_tabstop(&mut self, tabstop: TabstopIdx) {\n        let start = self.off;\n        let end = match &self.src[tabstop].kind {\n            elaborate::TabstopKind::Placeholder { default } if !default.is_empty() => {\n                self.render_elements(default);\n                self.dst[tabstop].kind = TabstopKind::Placeholder;\n                self.off\n            }\n            _ => start,\n        };\n        self.dst[tabstop].ranges.push(Range { start, end });\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use helix_stdx::Range;\n\n    use crate::snippets::render::Tabstop;\n    use crate::snippets::{Snippet, SnippetRenderCtx};\n\n    use super::TabstopKind;\n\n    fn assert_snippet(snippet: &str, expect: &str, tabstops: &[Tabstop]) {\n        let snippet = Snippet::parse(snippet).unwrap();\n        let mut rendered_snippet = snippet.prepare_render();\n        let rendered_text = snippet\n            .render_at(\n                &mut rendered_snippet,\n                \"\\t\".into(),\n                false,\n                &mut SnippetRenderCtx::test_ctx(),\n                0,\n            )\n            .0;\n        assert_eq!(rendered_text, expect);\n        assert_eq!(&rendered_snippet.tabstops, tabstops);\n        assert_eq!(\n            rendered_snippet.ranges.last().unwrap().end,\n            rendered_text.chars().count()\n        );\n        assert_eq!(rendered_snippet.ranges.last().unwrap().start, 0)\n    }\n\n    #[test]\n    fn rust_macro() {\n        assert_snippet(\n            \"macro_rules! ${1:name} {\\n\\t($3) => {\\n\\t\\t$2\\n\\t};\\n}\",\n            \"macro_rules! name {\\n\\t    () => {\\n\\t        \\n\\t    };\\n\\t}\",\n            &[\n                Tabstop {\n                    ranges: vec![Range { start: 13, end: 17 }].into(),\n                    parent: None,\n                    kind: TabstopKind::Placeholder,\n                },\n                Tabstop {\n                    ranges: vec![Range { start: 42, end: 42 }].into(),\n                    parent: None,\n                    kind: TabstopKind::Empty,\n                },\n                Tabstop {\n                    ranges: vec![Range { start: 26, end: 26 }].into(),\n                    parent: None,\n                    kind: TabstopKind::Empty,\n                },\n                Tabstop {\n                    ranges: vec![Range { start: 53, end: 53 }].into(),\n                    parent: None,\n                    kind: TabstopKind::Empty,\n                },\n            ],\n        );\n    }\n}\n"
  },
  {
    "path": "helix-core/src/snippets.rs",
    "content": "mod active;\nmod elaborate;\nmod parser;\nmod render;\n\n#[derive(PartialEq, Eq, Hash, Debug, PartialOrd, Ord, Clone, Copy)]\npub struct TabstopIdx(usize);\npub const LAST_TABSTOP_IDX: TabstopIdx = TabstopIdx(usize::MAX);\n\npub use active::ActiveSnippet;\npub use elaborate::{Snippet, SnippetElement, Transform};\npub use render::RenderedSnippet;\npub use render::SnippetRenderCtx;\n"
  },
  {
    "path": "helix-core/src/surround.rs",
    "content": "use std::fmt::Display;\n\nuse crate::{\n    graphemes::next_grapheme_boundary,\n    match_brackets::{\n        self, find_matching_bracket, find_matching_bracket_fuzzy, get_pair, is_close_bracket,\n        is_open_bracket,\n    },\n    movement::Direction,\n    search, Range, Selection, Syntax,\n};\nuse ropey::RopeSlice;\n\n#[derive(Debug, PartialEq, Eq)]\npub enum Error {\n    PairNotFound,\n    CursorOverlap,\n    RangeExceedsText,\n    CursorOnAmbiguousPair,\n}\n\nimpl Display for Error {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.write_str(match *self {\n            Error::PairNotFound => \"Surround pair not found around all cursors\",\n            Error::CursorOverlap => \"Cursors overlap for a single surround pair range\",\n            Error::RangeExceedsText => \"Cursor range exceeds text length\",\n            Error::CursorOnAmbiguousPair => \"Cursor on ambiguous surround pair\",\n        })\n    }\n}\n\ntype Result<T> = std::result::Result<T, Error>;\n\n/// Finds the position of surround pairs of any [`crate::match_brackets::PAIRS`]\n/// using tree-sitter when possible.\n///\n/// # Returns\n///\n/// Tuple `(anchor, head)`, meaning it is not always ordered.\npub fn find_nth_closest_pairs_pos(\n    syntax: Option<&Syntax>,\n    text: RopeSlice,\n    range: Range,\n    skip: usize,\n) -> Result<(usize, usize)> {\n    match syntax {\n        Some(syntax) => find_nth_closest_pairs_ts(syntax, text, range, skip),\n        None => find_nth_closest_pairs_plain(text, range, skip),\n    }\n}\n\nfn find_nth_closest_pairs_ts(\n    syntax: &Syntax,\n    text: RopeSlice,\n    range: Range,\n    mut skip: usize,\n) -> Result<(usize, usize)> {\n    let mut opening = range.from();\n    // We want to expand the selection if we are already on the found pair,\n    // otherwise we would need to subtract \"-1\" from \"range.to()\".\n    let mut closing = range.to();\n\n    while skip > 0 {\n        closing = find_matching_bracket_fuzzy(syntax, text, closing).ok_or(Error::PairNotFound)?;\n        opening = find_matching_bracket(syntax, text, closing).ok_or(Error::PairNotFound)?;\n        // If we're already on a closing bracket \"find_matching_bracket_fuzzy\" will return\n        // the position of the opening bracket.\n        if closing < opening {\n            (opening, closing) = (closing, opening);\n        }\n\n        // In case found brackets are partially inside current selection.\n        if range.from() < opening || closing < range.to() - 1 {\n            closing = next_grapheme_boundary(text, closing);\n        } else {\n            skip -= 1;\n            if skip != 0 {\n                closing = next_grapheme_boundary(text, closing);\n            }\n        }\n    }\n\n    // Keep the original direction.\n    if let Direction::Forward = range.direction() {\n        Ok((opening, closing))\n    } else {\n        Ok((closing, opening))\n    }\n}\n\nfn find_nth_closest_pairs_plain(\n    text: RopeSlice,\n    range: Range,\n    mut skip: usize,\n) -> Result<(usize, usize)> {\n    let mut stack = Vec::with_capacity(2);\n    let pos = range.from();\n    let mut close_pos = pos.saturating_sub(1);\n\n    for ch in text.chars_at(pos) {\n        close_pos += 1;\n\n        if is_open_bracket(ch) {\n            // Track open pairs encountered so that we can step over\n            // the corresponding close pairs that will come up further\n            // down the loop. We want to find a lone close pair whose\n            // open pair is before the cursor position.\n            stack.push(ch);\n            continue;\n        }\n\n        if !is_close_bracket(ch) {\n            // We don't care if this character isn't a brace pair item,\n            // so short circuit here.\n            continue;\n        }\n\n        let (open, close) = get_pair(ch);\n\n        if stack.last() == Some(&open) {\n            // If we are encountering the closing pair for an opener\n            // we just found while traversing, then its inside the\n            // selection and should be skipped over.\n            stack.pop();\n            continue;\n        }\n\n        match find_nth_open_pair(text, open, close, close_pos, 1) {\n            // Before we accept this pair, we want to ensure that the\n            // pair encloses the range rather than just the cursor.\n            Some(open_pos)\n                if open_pos <= pos.saturating_add(1)\n                    && close_pos >= range.to().saturating_sub(1) =>\n            {\n                // Since we have special conditions for when to\n                // accept, we can't just pass the skip parameter on\n                // through to the find_nth_*_pair methods, so we\n                // track skips manually here.\n                if skip > 1 {\n                    skip -= 1;\n                    continue;\n                }\n\n                return match range.direction() {\n                    Direction::Forward => Ok((open_pos, close_pos)),\n                    Direction::Backward => Ok((close_pos, open_pos)),\n                };\n            }\n            _ => continue,\n        }\n    }\n\n    Err(Error::PairNotFound)\n}\n\n/// Find the position of surround pairs of `ch` which can be either a closing\n/// or opening pair. `n` will skip n - 1 pairs (eg. n=2 will discard (only)\n/// the first pair found and keep looking)\npub fn find_nth_pairs_pos(\n    syntax: Option<&Syntax>,\n    text: RopeSlice,\n    ch: char,\n    range: Range,\n    n: usize,\n) -> Result<(usize, usize)> {\n    if text.len_chars() < 2 {\n        return Err(Error::PairNotFound);\n    }\n    if range.to() >= text.len_chars() {\n        return Err(Error::RangeExceedsText);\n    }\n\n    let (open, close) = get_pair(ch);\n    let pos = range.cursor(text);\n\n    let (open, close) = if open == close {\n        if Some(open) == text.get_char(pos) {\n            // Cursor is directly on match character for which the opening and closing pairs are the same. For instance: \", ', `\n            //\n            // This is potentially ambiguous, because there's no way to know which side of the char we should be searching on.\n            syntax\n                .map_or_else(\n                    || match_brackets::find_matching_bracket_plaintext(text.slice(..), pos),\n                    |syntax| {\n                        match_brackets::find_matching_bracket_fuzzy(syntax, text.slice(..), pos)\n                    },\n                )\n                .map(|matching_pair_pos| {\n                    if matching_pair_pos > pos {\n                        (Some(pos), Some(matching_pair_pos))\n                    } else {\n                        (Some(matching_pair_pos), Some(pos))\n                    }\n                })\n                .ok_or(Error::CursorOnAmbiguousPair)?\n        } else {\n            (\n                search::find_nth_char(n, text, open, pos, Direction::Backward),\n                search::find_nth_char(n, text, close, pos, Direction::Forward),\n            )\n        }\n    } else {\n        (\n            find_nth_open_pair(text, open, close, pos, n),\n            find_nth_close_pair(text, open, close, pos, n),\n        )\n    };\n\n    // preserve original direction\n    match range.direction() {\n        Direction::Forward => Option::zip(open, close).ok_or(Error::PairNotFound),\n        Direction::Backward => Option::zip(close, open).ok_or(Error::PairNotFound),\n    }\n}\n\nfn find_nth_open_pair(\n    text: RopeSlice,\n    open: char,\n    close: char,\n    mut pos: usize,\n    n: usize,\n) -> Option<usize> {\n    if pos >= text.len_chars() {\n        return None;\n    }\n\n    let mut chars = text.chars_at(pos + 1);\n\n    // Adjusts pos for the first iteration, and handles the case of the\n    // cursor being *on* the close character which will get falsely stepped over\n    // if not skipped here\n    if chars.prev()? == open {\n        return Some(pos);\n    }\n\n    for _ in 0..n {\n        let mut step_over: usize = 0;\n\n        loop {\n            let c = chars.prev()?;\n            pos = pos.saturating_sub(1);\n\n            // ignore other surround pairs that are enclosed *within* our search scope\n            if c == close {\n                step_over += 1;\n            } else if c == open {\n                if step_over == 0 {\n                    break;\n                }\n\n                step_over = step_over.saturating_sub(1);\n            }\n        }\n    }\n\n    Some(pos)\n}\n\nfn find_nth_close_pair(\n    text: RopeSlice,\n    open: char,\n    close: char,\n    mut pos: usize,\n    n: usize,\n) -> Option<usize> {\n    if pos >= text.len_chars() {\n        return None;\n    }\n\n    let mut chars = text.chars_at(pos);\n\n    if chars.next()? == close {\n        return Some(pos);\n    }\n\n    for _ in 0..n {\n        let mut step_over: usize = 0;\n\n        loop {\n            let c = chars.next()?;\n            pos += 1;\n\n            if c == open {\n                step_over += 1;\n            } else if c == close {\n                if step_over == 0 {\n                    break;\n                }\n\n                step_over = step_over.saturating_sub(1);\n            }\n        }\n    }\n\n    Some(pos)\n}\n\n/// Find position of surround characters around every cursor. Returns None\n/// if any positions overlap. Note that the positions are in a flat Vec.\n/// Use get_surround_pos().chunks(2) to get matching pairs of surround positions.\n/// `ch` can be either closing or opening pair. If `ch` is None, surround pairs\n/// are automatically detected around each cursor (note that this may result\n/// in them selecting different surround characters for each selection).\npub fn get_surround_pos(\n    syntax: Option<&Syntax>,\n    text: RopeSlice,\n    selection: &Selection,\n    ch: Option<char>,\n    skip: usize,\n) -> Result<Vec<usize>> {\n    let mut change_pos = Vec::new();\n\n    for &range in selection {\n        let (open_pos, close_pos) = {\n            let range_raw = match ch {\n                Some(ch) => find_nth_pairs_pos(syntax, text, ch, range, skip)?,\n                None => find_nth_closest_pairs_pos(syntax, text, range, skip)?,\n            };\n            let range = Range::new(range_raw.0, range_raw.1);\n            (range.from(), range.to())\n        };\n        if change_pos.contains(&open_pos) || change_pos.contains(&close_pos) {\n            return Err(Error::CursorOverlap);\n        }\n        // ensure the positions are always paired in the forward direction\n        change_pos.extend_from_slice(&[open_pos.min(close_pos), close_pos.max(open_pos)]);\n    }\n    Ok(change_pos)\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::Range;\n\n    use ropey::Rope;\n    use smallvec::SmallVec;\n\n    #[test]\n    fn test_get_surround_pos() {\n        #[rustfmt::skip]\n        let (doc, selection, expectations) =\n            rope_with_selections_and_expectations(\n                \"(some) (chars)\\n(newline)\",\n                \"_ ^  _ _ ^   _\\n_    ^  _\"\n            );\n\n        assert_eq!(\n            get_surround_pos(None, doc.slice(..), &selection, Some('('), 1).unwrap(),\n            expectations\n        );\n    }\n\n    #[test]\n    fn test_get_surround_pos_bail_different_surround_chars() {\n        #[rustfmt::skip]\n        let (doc, selection, _) =\n            rope_with_selections_and_expectations(\n                \"[some]\\n(chars)xx\\n(newline)\",\n                \"  ^   \\n  ^      \\n         \"\n            );\n\n        assert_eq!(\n            get_surround_pos(None, doc.slice(..), &selection, Some('('), 1),\n            Err(Error::PairNotFound)\n        );\n    }\n\n    #[test]\n    fn test_get_surround_pos_bail_overlapping_surround_chars() {\n        #[rustfmt::skip]\n        let (doc, selection, _) =\n            rope_with_selections_and_expectations(\n                \"[some]\\n(chars)xx\\n(newline)\",\n                \"      \\n       ^ \\n      ^  \"\n            );\n\n        assert_eq!(\n            get_surround_pos(None, doc.slice(..), &selection, Some('('), 1),\n            Err(Error::PairNotFound) // overlapping surround chars\n        );\n    }\n\n    #[test]\n    fn test_get_surround_pos_bail_cursor_overlap() {\n        #[rustfmt::skip]\n        let (doc, selection, _) =\n            rope_with_selections_and_expectations(\n                \"[some]\\n(chars)xx\\n(newline)\",\n                \"  ^^  \\n         \\n         \"\n            );\n\n        assert_eq!(\n            get_surround_pos(None, doc.slice(..), &selection, Some('['), 1),\n            Err(Error::CursorOverlap)\n        );\n    }\n\n    #[test]\n    fn test_find_nth_pairs_pos_quote_success() {\n        #[rustfmt::skip]\n        let (doc, selection, expectations) =\n            rope_with_selections_and_expectations(\n                \"some 'quoted text' on this 'line'\\n'and this one'\",\n                \"     _        ^  _               \\n              \"\n            );\n\n        assert_eq!(2, expectations.len());\n        assert_eq!(\n            find_nth_pairs_pos(None, doc.slice(..), '\\'', selection.primary(), 1)\n                .expect(\"find should succeed\"),\n            (expectations[0], expectations[1])\n        )\n    }\n\n    #[test]\n    fn test_find_nth_pairs_pos_nested_quote_success() {\n        #[rustfmt::skip]\n        let (doc, selection, expectations) =\n            rope_with_selections_and_expectations(\n                \"some 'nested 'quoted' text' on this 'line'\\n'and this one'\",\n                \"     _           ^        _               \\n              \"\n            );\n\n        assert_eq!(2, expectations.len());\n        assert_eq!(\n            find_nth_pairs_pos(None, doc.slice(..), '\\'', selection.primary(), 2)\n                .expect(\"find should succeed\"),\n            (expectations[0], expectations[1])\n        )\n    }\n\n    #[test]\n    fn test_find_nth_pairs_pos_inside_quote_ambiguous() {\n        #[rustfmt::skip]\n        let (doc, selection, _) =\n            rope_with_selections_and_expectations(\n                \"some 'nested 'quoted' text' on this 'line'\\n'and this one'\",\n                \"                    ^                     \\n              \"\n            );\n\n        assert_eq!(\n            find_nth_pairs_pos(None, doc.slice(..), '\\'', selection.primary(), 1),\n            Err(Error::CursorOnAmbiguousPair)\n        )\n    }\n\n    #[test]\n    fn test_find_nth_closest_pairs_pos_index_range_panic() {\n        #[rustfmt::skip]\n        let (doc, selection, _) =\n            rope_with_selections_and_expectations(\n                \"(a)c)\",\n                \"^^^^^\"\n            );\n\n        assert_eq!(\n            find_nth_closest_pairs_pos(None, doc.slice(..), selection.primary(), 1),\n            Err(Error::PairNotFound)\n        )\n    }\n\n    // Create a Rope and a matching Selection using a specification language.\n    // ^ is a single-point selection.\n    // _ is an expected index. These are returned as a Vec<usize> for use in assertions.\n    fn rope_with_selections_and_expectations(\n        text: &str,\n        spec: &str,\n    ) -> (Rope, Selection, Vec<usize>) {\n        if text.len() != spec.len() {\n            panic!(\"specification must match text length -- are newlines aligned?\");\n        }\n\n        let rope = Rope::from(text);\n\n        let selections: SmallVec<[Range; 1]> = spec\n            .match_indices('^')\n            .map(|(i, _)| Range::point(i))\n            .collect();\n\n        let expectations: Vec<usize> = spec.match_indices('_').map(|(i, _)| i).collect();\n\n        (rope, Selection::new(selections, 0), expectations)\n    }\n}\n"
  },
  {
    "path": "helix-core/src/syntax/config.rs",
    "content": "use crate::{auto_pairs::AutoPairs, diagnostic::Severity, Language};\n\nuse helix_stdx::rope;\nuse serde::{ser::SerializeSeq as _, Deserialize, Serialize};\nuse serde_json::Value;\n\nuse std::{\n    collections::{HashMap, HashSet},\n    fmt::{self, Display},\n    num::NonZeroU8,\n    path::PathBuf,\n    str::FromStr,\n};\n\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub struct Configuration {\n    pub language: Vec<LanguageConfiguration>,\n    #[serde(default)]\n    pub language_server: HashMap<String, LanguageServerConfiguration>,\n}\n\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\", deny_unknown_fields)]\npub struct LanguageConfiguration {\n    #[serde(skip)]\n    pub(super) language: Option<Language>,\n\n    #[serde(rename = \"name\")]\n    pub language_id: String, // c-sharp, rust, tsx\n    #[serde(rename = \"language-id\")]\n    // see the table under https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentItem\n    pub language_server_language_id: Option<String>, // csharp, rust, typescriptreact, for the language-server\n    pub scope: String,             // source.rust\n    pub file_types: Vec<FileType>, // filename extension or ends_with? <Gemfile, rb, etc>\n    #[serde(default)]\n    pub shebangs: Vec<String>, // interpreter(s) associated with language\n    #[serde(default)]\n    pub roots: RootMarkers, // these indicate project roots <.git, Cargo.toml>\n    #[serde(\n        default,\n        skip_serializing,\n        deserialize_with = \"from_comment_tokens\",\n        alias = \"comment-token\"\n    )]\n    pub comment_tokens: Option<Vec<String>>,\n    #[serde(\n        default,\n        skip_serializing,\n        deserialize_with = \"from_block_comment_tokens\"\n    )]\n    pub block_comment_tokens: Option<Vec<BlockCommentToken>>,\n    pub text_width: Option<usize>,\n    pub soft_wrap: Option<SoftWrap>,\n\n    #[serde(default)]\n    pub auto_format: bool,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub formatter: Option<FormatterConfiguration>,\n\n    /// If set, overrides `editor.path-completion`.\n    pub path_completion: Option<bool>,\n    /// If set, overrides `editor.word-completion`.\n    pub word_completion: Option<WordCompletion>,\n\n    #[serde(default)]\n    pub diagnostic_severity: Severity,\n\n    pub grammar: Option<String>, // tree-sitter grammar name, defaults to language_id\n\n    // content_regex\n    #[serde(default, skip_serializing, deserialize_with = \"deserialize_regex\")]\n    pub injection_regex: Option<rope::Regex>,\n    // first_line_regex\n    //\n    #[serde(\n        default,\n        skip_serializing_if = \"Vec::is_empty\",\n        serialize_with = \"serialize_lang_features\",\n        deserialize_with = \"deserialize_lang_features\"\n    )]\n    pub language_servers: Vec<LanguageServerFeatures>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub indent: Option<IndentationConfiguration>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub debugger: Option<DebugAdapterConfig>,\n\n    /// Automatic insertion of pairs to parentheses, brackets,\n    /// etc. Defaults to true. Optionally, this can be a list of 2-tuples\n    /// to specify a list of characters to pair. This overrides the\n    /// global setting.\n    #[serde(default, skip_serializing, deserialize_with = \"deserialize_auto_pairs\")]\n    pub auto_pairs: Option<AutoPairs>,\n\n    pub rulers: Option<Vec<u16>>, // if set, override editor's rulers\n\n    /// Hardcoded LSP root directories relative to the workspace root, like `examples` or `tools/fuzz`.\n    /// Falling back to the current working directory if none are configured.\n    pub workspace_lsp_roots: Option<Vec<PathBuf>>,\n    #[serde(default)]\n    pub persistent_diagnostic_sources: Vec<String>,\n    /// Overrides the `editor.rainbow-brackets` config key for the language.\n    pub rainbow_brackets: Option<bool>,\n}\n\nimpl LanguageConfiguration {\n    pub fn language(&self) -> Language {\n        // This value must be set by `super::Loader::new`.\n        self.language.unwrap()\n    }\n}\n\npub type RootMarkers = GlobSet;\n\n/// A wrapper around `globset::GlobSet` which implements `Serialize` and `Deserialize`.\n#[derive(Default, Debug)]\npub struct GlobSet {\n    inner: globset::GlobSet,\n    /// Glob patterns as-is before building. This is only used for `Serialize`.\n    patterns: Vec<String>,\n}\n\nimpl GlobSet {\n    pub fn is_match<P: AsRef<std::path::Path>>(&self, path: P) -> bool {\n        self.inner.is_match(path)\n    }\n}\n\nimpl Serialize for GlobSet {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        let mut patterns = serializer.serialize_seq(Some(self.patterns.len()))?;\n        for pattern in &self.patterns {\n            patterns.serialize_element(pattern)?;\n        }\n        patterns.end()\n    }\n}\n\nimpl<'de> Deserialize<'de> for GlobSet {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        let patterns: Vec<String> = Deserialize::deserialize(deserializer)?;\n        let mut builder = globset::GlobSetBuilder::new();\n        for pattern in &patterns {\n            let glob = globset::Glob::new(pattern).map_err(serde::de::Error::custom)?;\n            builder.add(glob);\n        }\n        let inner = builder.build().map_err(serde::de::Error::custom)?;\n        Ok(Self { inner, patterns })\n    }\n}\n\n#[derive(Debug, PartialEq, Eq, Hash)]\npub enum FileType {\n    /// The extension of the file, either the `Path::extension` or the full\n    /// filename if the file does not have an extension.\n    Extension(String),\n    /// A Unix-style path glob. This is compared to the file's absolute path, so\n    /// it can be used to detect files based on their directories. If the glob\n    /// is not an absolute path and does not already start with a glob pattern,\n    /// a glob pattern will be prepended to it.\n    Glob(globset::Glob),\n}\n\nimpl Serialize for FileType {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        use serde::ser::SerializeMap;\n\n        match self {\n            FileType::Extension(extension) => serializer.serialize_str(extension),\n            FileType::Glob(glob) => {\n                let mut map = serializer.serialize_map(Some(1))?;\n                map.serialize_entry(\"glob\", glob.glob())?;\n                map.end()\n            }\n        }\n    }\n}\n\nimpl<'de> Deserialize<'de> for FileType {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::de::Deserializer<'de>,\n    {\n        struct FileTypeVisitor;\n\n        impl<'de> serde::de::Visitor<'de> for FileTypeVisitor {\n            type Value = FileType;\n\n            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {\n                formatter.write_str(\"string or table\")\n            }\n\n            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>\n            where\n                E: serde::de::Error,\n            {\n                Ok(FileType::Extension(value.to_string()))\n            }\n\n            fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>\n            where\n                M: serde::de::MapAccess<'de>,\n            {\n                match map.next_entry::<String, String>()? {\n                    Some((key, mut glob)) if key == \"glob\" => {\n                        // If the glob isn't an absolute path or already starts\n                        // with a glob pattern, add a leading glob so we\n                        // properly match relative paths.\n                        if !glob.starts_with('/') && !glob.starts_with(\"*/\") {\n                            glob.insert_str(0, \"*/\");\n                        }\n\n                        globset::Glob::new(glob.as_str())\n                            .map(FileType::Glob)\n                            .map_err(|err| {\n                                serde::de::Error::custom(format!(\"invalid `glob` pattern: {}\", err))\n                            })\n                    }\n                    Some((key, _value)) => Err(serde::de::Error::custom(format!(\n                        \"unknown key in `file-types` list: {}\",\n                        key\n                    ))),\n                    None => Err(serde::de::Error::custom(\n                        \"expected a `suffix` key in the `file-types` entry\",\n                    )),\n                }\n            }\n        }\n\n        deserializer.deserialize_any(FileTypeVisitor)\n    }\n}\n\nfn from_comment_tokens<'de, D>(deserializer: D) -> Result<Option<Vec<String>>, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    #[derive(Deserialize)]\n    #[serde(untagged)]\n    enum CommentTokens {\n        Multiple(Vec<String>),\n        Single(String),\n    }\n    Ok(\n        Option::<CommentTokens>::deserialize(deserializer)?.map(|tokens| match tokens {\n            CommentTokens::Single(val) => vec![val],\n            CommentTokens::Multiple(vals) => vals,\n        }),\n    )\n}\n\n#[derive(Clone, Debug, Serialize, Deserialize)]\npub struct BlockCommentToken {\n    pub start: String,\n    pub end: String,\n}\n\nimpl Default for BlockCommentToken {\n    fn default() -> Self {\n        BlockCommentToken {\n            start: \"/*\".to_string(),\n            end: \"*/\".to_string(),\n        }\n    }\n}\n\nfn from_block_comment_tokens<'de, D>(\n    deserializer: D,\n) -> Result<Option<Vec<BlockCommentToken>>, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    #[derive(Deserialize)]\n    #[serde(untagged)]\n    enum BlockCommentTokens {\n        Multiple(Vec<BlockCommentToken>),\n        Single(BlockCommentToken),\n    }\n    Ok(\n        Option::<BlockCommentTokens>::deserialize(deserializer)?.map(|tokens| match tokens {\n            BlockCommentTokens::Single(val) => vec![val],\n            BlockCommentTokens::Multiple(vals) => vals,\n        }),\n    )\n}\n\n#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]\n#[serde(rename_all = \"kebab-case\")]\npub enum LanguageServerFeature {\n    Format,\n    GotoDeclaration,\n    GotoDefinition,\n    GotoTypeDefinition,\n    GotoReference,\n    GotoImplementation,\n    // Goto, use bitflags, combining previous Goto members?\n    SignatureHelp,\n    Hover,\n    DocumentHighlight,\n    Completion,\n    CodeAction,\n    DocumentLinks,\n    WorkspaceCommand,\n    DocumentSymbols,\n    WorkspaceSymbols,\n    // Symbols, use bitflags, see above?\n    Diagnostics,\n    PullDiagnostics,\n    RenameSymbol,\n    InlayHints,\n    DocumentColors,\n    CallHierarchy,\n}\n\nimpl Display for LanguageServerFeature {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        use LanguageServerFeature::*;\n        let feature = match self {\n            Format => \"format\",\n            GotoDeclaration => \"goto-declaration\",\n            GotoDefinition => \"goto-definition\",\n            GotoTypeDefinition => \"goto-type-definition\",\n            GotoReference => \"goto-reference\",\n            GotoImplementation => \"goto-implementation\",\n            SignatureHelp => \"signature-help\",\n            Hover => \"hover\",\n            DocumentHighlight => \"document-highlight\",\n            Completion => \"completion\",\n            CodeAction => \"code-action\",\n            DocumentLinks => \"document-links\",\n            WorkspaceCommand => \"workspace-command\",\n            DocumentSymbols => \"document-symbols\",\n            WorkspaceSymbols => \"workspace-symbols\",\n            Diagnostics => \"diagnostics\",\n            PullDiagnostics => \"pull-diagnostics\",\n            RenameSymbol => \"rename-symbol\",\n            InlayHints => \"inlay-hints\",\n            DocumentColors => \"document-colors\",\n            CallHierarchy => \"call-hierarchy\",\n        };\n        write!(f, \"{feature}\",)\n    }\n}\n\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(untagged, rename_all = \"kebab-case\", deny_unknown_fields)]\nenum LanguageServerFeatureConfiguration {\n    #[serde(rename_all = \"kebab-case\")]\n    Features {\n        #[serde(default, skip_serializing_if = \"HashSet::is_empty\")]\n        only_features: HashSet<LanguageServerFeature>,\n        #[serde(default, skip_serializing_if = \"HashSet::is_empty\")]\n        except_features: HashSet<LanguageServerFeature>,\n        name: String,\n    },\n    Simple(String),\n}\n\n#[derive(Debug, Default)]\npub struct LanguageServerFeatures {\n    pub name: String,\n    pub only: HashSet<LanguageServerFeature>,\n    pub excluded: HashSet<LanguageServerFeature>,\n}\n\nimpl LanguageServerFeatures {\n    pub fn has_feature(&self, feature: LanguageServerFeature) -> bool {\n        (self.only.is_empty() || self.only.contains(&feature)) && !self.excluded.contains(&feature)\n    }\n}\n\nfn deserialize_lang_features<'de, D>(\n    deserializer: D,\n) -> Result<Vec<LanguageServerFeatures>, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    let raw: Vec<LanguageServerFeatureConfiguration> = Deserialize::deserialize(deserializer)?;\n    let res = raw\n        .into_iter()\n        .map(|config| match config {\n            LanguageServerFeatureConfiguration::Simple(name) => LanguageServerFeatures {\n                name,\n                ..Default::default()\n            },\n            LanguageServerFeatureConfiguration::Features {\n                only_features,\n                except_features,\n                name,\n            } => LanguageServerFeatures {\n                name,\n                only: only_features,\n                excluded: except_features,\n            },\n        })\n        .collect();\n    Ok(res)\n}\nfn serialize_lang_features<S>(\n    map: &Vec<LanguageServerFeatures>,\n    serializer: S,\n) -> Result<S::Ok, S::Error>\nwhere\n    S: serde::Serializer,\n{\n    let mut serializer = serializer.serialize_seq(Some(map.len()))?;\n    for features in map {\n        let features = if features.only.is_empty() && features.excluded.is_empty() {\n            LanguageServerFeatureConfiguration::Simple(features.name.to_owned())\n        } else {\n            LanguageServerFeatureConfiguration::Features {\n                only_features: features.only.clone(),\n                except_features: features.excluded.clone(),\n                name: features.name.to_owned(),\n            }\n        };\n        serializer.serialize_element(&features)?;\n    }\n    serializer.end()\n}\n\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub struct LanguageServerConfiguration {\n    pub command: String,\n    #[serde(default)]\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub args: Vec<String>,\n    #[serde(default, skip_serializing_if = \"HashMap::is_empty\")]\n    pub environment: HashMap<String, String>,\n    #[serde(default, skip_serializing, deserialize_with = \"deserialize_lsp_config\")]\n    pub config: Option<serde_json::Value>,\n    #[serde(default = \"default_timeout\")]\n    pub timeout: u64,\n    #[serde(default)]\n    pub required_root_patterns: Option<GlobSet>,\n}\n\n#[derive(Debug, Clone, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub struct FormatterConfiguration {\n    pub command: String,\n    #[serde(default)]\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub args: Vec<String>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"kebab-case\")]\npub struct AdvancedCompletion {\n    pub name: Option<String>,\n    pub completion: Option<String>,\n    pub default: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"kebab-case\", untagged)]\npub enum DebugConfigCompletion {\n    Named(String),\n    Advanced(AdvancedCompletion),\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"kebab-case\")]\npub struct DebugTemplate {\n    pub name: String,\n    pub request: String,\n    #[serde(default)]\n    pub completion: Vec<DebugConfigCompletion>,\n    pub args: HashMap<String, Value>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"kebab-case\")]\npub struct DebugAdapterConfig {\n    pub name: String,\n    pub transport: String,\n    #[serde(default)]\n    pub command: String,\n    #[serde(default)]\n    pub args: Vec<String>,\n    pub port_arg: Option<String>,\n    pub templates: Vec<DebugTemplate>,\n    #[serde(default)]\n    pub quirks: DebuggerQuirks,\n}\n\n// Different workarounds for adapters' differences\n#[derive(Debug, Default, PartialEq, Eq, Clone, Serialize, Deserialize)]\npub struct DebuggerQuirks {\n    #[serde(default)]\n    pub absolute_paths: bool,\n}\n\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub struct IndentationConfiguration {\n    #[serde(deserialize_with = \"deserialize_tab_width\")]\n    pub tab_width: usize,\n    pub unit: String,\n}\n\n/// How the indentation for a newly inserted line should be determined.\n/// If the selected heuristic is not available (e.g. because the current\n/// language has no tree-sitter indent queries), a simpler one will be used.\n#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub enum IndentationHeuristic {\n    /// Just copy the indentation of the line that the cursor is currently on.\n    Simple,\n    /// Use tree-sitter indent queries to compute the expected absolute indentation level of the new line.\n    TreeSitter,\n    /// Use tree-sitter indent queries to compute the expected difference in indentation between the new line\n    /// and the line before. Add this to the actual indentation level of the line before.\n    #[default]\n    Hybrid,\n}\n\n/// Configuration for auto pairs\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\", deny_unknown_fields, untagged)]\npub enum AutoPairConfig {\n    /// Enables or disables auto pairing. False means disabled. True means to use the default pairs.\n    Enable(bool),\n\n    /// The mappings of pairs.\n    Pairs(HashMap<char, char>),\n}\n\nimpl Default for AutoPairConfig {\n    fn default() -> Self {\n        AutoPairConfig::Enable(true)\n    }\n}\n\nimpl From<&AutoPairConfig> for Option<AutoPairs> {\n    fn from(auto_pair_config: &AutoPairConfig) -> Self {\n        match auto_pair_config {\n            AutoPairConfig::Enable(false) => None,\n            AutoPairConfig::Enable(true) => Some(AutoPairs::default()),\n            AutoPairConfig::Pairs(pairs) => Some(AutoPairs::new(pairs.iter())),\n        }\n    }\n}\n\nimpl From<AutoPairConfig> for Option<AutoPairs> {\n    fn from(auto_pairs_config: AutoPairConfig) -> Self {\n        (&auto_pairs_config).into()\n    }\n}\n\nimpl FromStr for AutoPairConfig {\n    type Err = std::str::ParseBoolError;\n\n    // only do bool parsing for runtime setting\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let enable: bool = s.parse()?;\n        Ok(AutoPairConfig::Enable(enable))\n    }\n}\n\n#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(default, rename_all = \"kebab-case\", deny_unknown_fields)]\npub struct SoftWrap {\n    /// Soft wrap lines that exceed viewport width. Default to off\n    // NOTE: Option on purpose because the struct is shared between language config and global config.\n    // By default the option is None so that the language config falls back to the global config unless explicitly set.\n    pub enable: Option<bool>,\n    /// Maximum space left free at the end of the line.\n    /// This space is used to wrap text at word boundaries. If that is not possible within this limit\n    /// the word is simply split at the end of the line.\n    ///\n    /// This is automatically hard-limited to a quarter of the viewport to ensure correct display on small views.\n    ///\n    /// Default to 20\n    pub max_wrap: Option<u16>,\n    /// Maximum number of indentation that can be carried over from the previous line when softwrapping.\n    /// If a line is indented further then this limit it is rendered at the start of the viewport instead.\n    ///\n    /// This is automatically hard-limited to a quarter of the viewport to ensure correct display on small views.\n    ///\n    /// Default to 40\n    pub max_indent_retain: Option<u16>,\n    /// Indicator placed at the beginning of softwrapped lines\n    ///\n    /// Defaults to ↪\n    pub wrap_indicator: Option<String>,\n    /// Softwrap at `text_width` instead of viewport width if it is shorter\n    pub wrap_at_text_width: Option<bool>,\n}\n\n#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(default, rename_all = \"kebab-case\", deny_unknown_fields)]\npub struct WordCompletion {\n    pub enable: Option<bool>,\n    pub trigger_length: Option<NonZeroU8>,\n}\n\nfn deserialize_regex<'de, D>(deserializer: D) -> Result<Option<rope::Regex>, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    Option::<String>::deserialize(deserializer)?\n        .map(|buf| rope::Regex::new(&buf).map_err(serde::de::Error::custom))\n        .transpose()\n}\n\nfn deserialize_lsp_config<'de, D>(deserializer: D) -> Result<Option<serde_json::Value>, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    Option::<toml::Value>::deserialize(deserializer)?\n        .map(|toml| toml.try_into().map_err(serde::de::Error::custom))\n        .transpose()\n}\n\nfn deserialize_tab_width<'de, D>(deserializer: D) -> Result<usize, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    usize::deserialize(deserializer).and_then(|n| {\n        if n > 0 && n <= 16 {\n            Ok(n)\n        } else {\n            Err(serde::de::Error::custom(\n                \"tab width must be a value from 1 to 16 inclusive\",\n            ))\n        }\n    })\n}\n\npub fn deserialize_auto_pairs<'de, D>(deserializer: D) -> Result<Option<AutoPairs>, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    Ok(Option::<AutoPairConfig>::deserialize(deserializer)?.and_then(AutoPairConfig::into))\n}\n\nfn default_timeout() -> u64 {\n    20\n}\n"
  },
  {
    "path": "helix-core/src/syntax.rs",
    "content": "pub mod config;\n\nuse std::{\n    borrow::Cow,\n    collections::HashMap,\n    fmt, iter,\n    ops::{self, RangeBounds},\n    path::Path,\n    sync::Arc,\n    time::Duration,\n};\n\nuse anyhow::{Context, Result};\nuse arc_swap::{ArcSwap, Guard};\nuse config::{Configuration, FileType, LanguageConfiguration, LanguageServerConfiguration};\nuse foldhash::HashSet;\nuse helix_loader::grammar::get_language;\nuse helix_stdx::rope::RopeSliceExt as _;\nuse once_cell::sync::OnceCell;\nuse ropey::RopeSlice;\nuse tree_house::{\n    highlighter,\n    query_iter::QueryIter,\n    tree_sitter::{\n        query::{InvalidPredicateError, UserPredicate},\n        Capture, Grammar, InactiveQueryCursor, InputEdit, Node, Pattern, Query, RopeInput, Tree,\n    },\n    Error, InjectionLanguageMarker, LanguageConfig as SyntaxConfig, Layer,\n};\n\nuse crate::{indent::IndentQuery, tree_sitter, ChangeSet, Language};\n\npub use tree_house::{\n    highlighter::{Highlight, HighlightEvent},\n    query_iter::QueryIterEvent,\n    Error as HighlighterError, LanguageLoader, TreeCursor, TREE_SITTER_MATCH_LIMIT,\n};\n\n#[derive(Debug)]\npub struct LanguageData {\n    config: Arc<LanguageConfiguration>,\n    syntax: OnceCell<Option<SyntaxConfig>>,\n    indent_query: OnceCell<Option<IndentQuery>>,\n    textobject_query: OnceCell<Option<TextObjectQuery>>,\n    tag_query: OnceCell<Option<TagQuery>>,\n    rainbow_query: OnceCell<Option<RainbowQuery>>,\n}\n\nimpl LanguageData {\n    fn new(config: LanguageConfiguration) -> Self {\n        Self {\n            config: Arc::new(config),\n            syntax: OnceCell::new(),\n            indent_query: OnceCell::new(),\n            textobject_query: OnceCell::new(),\n            tag_query: OnceCell::new(),\n            rainbow_query: OnceCell::new(),\n        }\n    }\n\n    pub fn config(&self) -> &Arc<LanguageConfiguration> {\n        &self.config\n    }\n\n    /// Loads the grammar and compiles the highlights, injections and locals for the language.\n    /// This function should only be used by this module or the xtask crate.\n    pub fn compile_syntax_config(\n        config: &LanguageConfiguration,\n        loader: &Loader,\n    ) -> Result<Option<SyntaxConfig>> {\n        let name = &config.language_id;\n        let parser_name = config.grammar.as_deref().unwrap_or(name);\n        let Some(grammar) = get_language(parser_name)? else {\n            log::info!(\"Skipping syntax config for '{name}' because the parser's shared library does not exist\");\n            return Ok(None);\n        };\n        let highlight_query_text = read_query(name, \"highlights.scm\");\n        let injection_query_text = read_query(name, \"injections.scm\");\n        let local_query_text = read_query(name, \"locals.scm\");\n        let config = SyntaxConfig::new(\n            grammar,\n            &highlight_query_text,\n            &injection_query_text,\n            &local_query_text,\n        )\n        .with_context(|| format!(\"Failed to compile highlights for '{name}'\"))?;\n\n        reconfigure_highlights(&config, &loader.scopes());\n\n        Ok(Some(config))\n    }\n\n    fn syntax_config(&self, loader: &Loader) -> Option<&SyntaxConfig> {\n        self.syntax\n            .get_or_init(|| {\n                Self::compile_syntax_config(&self.config, loader)\n                    .map_err(|err| {\n                        log::error!(\"{err:#}\");\n                    })\n                    .ok()\n                    .flatten()\n            })\n            .as_ref()\n    }\n\n    /// Compiles the indents.scm query for a language.\n    /// This function should only be used by this module or the xtask crate.\n    pub fn compile_indent_query(\n        grammar: Grammar,\n        config: &LanguageConfiguration,\n    ) -> Result<Option<IndentQuery>> {\n        let name = &config.language_id;\n        let text = read_query(name, \"indents.scm\");\n        if text.is_empty() {\n            return Ok(None);\n        }\n        let indent_query = IndentQuery::new(grammar, &text)\n            .with_context(|| format!(\"Failed to compile indents.scm query for '{name}'\"))?;\n        Ok(Some(indent_query))\n    }\n\n    fn indent_query(&self, loader: &Loader) -> Option<&IndentQuery> {\n        self.indent_query\n            .get_or_init(|| {\n                let grammar = self.syntax_config(loader)?.grammar;\n                Self::compile_indent_query(grammar, &self.config)\n                    .map_err(|err| {\n                        log::error!(\"{err}\");\n                    })\n                    .ok()\n                    .flatten()\n            })\n            .as_ref()\n    }\n\n    /// Compiles the textobjects.scm query for a language.\n    /// This function should only be used by this module or the xtask crate.\n    pub fn compile_textobject_query(\n        grammar: Grammar,\n        config: &LanguageConfiguration,\n    ) -> Result<Option<TextObjectQuery>> {\n        let name = &config.language_id;\n        let text = read_query(name, \"textobjects.scm\");\n        if text.is_empty() {\n            return Ok(None);\n        }\n        let query = Query::new(grammar, &text, |_, _| Ok(()))\n            .with_context(|| format!(\"Failed to compile textobjects.scm queries for '{name}'\"))?;\n        Ok(Some(TextObjectQuery::new(query)))\n    }\n\n    fn textobject_query(&self, loader: &Loader) -> Option<&TextObjectQuery> {\n        self.textobject_query\n            .get_or_init(|| {\n                let grammar = self.syntax_config(loader)?.grammar;\n                Self::compile_textobject_query(grammar, &self.config)\n                    .map_err(|err| {\n                        log::error!(\"{err}\");\n                    })\n                    .ok()\n                    .flatten()\n            })\n            .as_ref()\n    }\n\n    /// Compiles the tags.scm query for a language.\n    /// This function should only be used by this module or the xtask crate.\n    pub fn compile_tag_query(\n        grammar: Grammar,\n        config: &LanguageConfiguration,\n    ) -> Result<Option<TagQuery>> {\n        let name = &config.language_id;\n        let text = read_query(name, \"tags.scm\");\n        if text.is_empty() {\n            return Ok(None);\n        }\n        let query = Query::new(grammar, &text, |_pattern, predicate| match predicate {\n            // TODO: these predicates are allowed in tags.scm queries but not yet used.\n            UserPredicate::IsPropertySet { key: \"local\", .. } => Ok(()),\n            UserPredicate::Other(pred) => match pred.name() {\n                \"strip!\" | \"select-adjacent!\" => Ok(()),\n                _ => Err(InvalidPredicateError::unknown(predicate)),\n            },\n            _ => Err(InvalidPredicateError::unknown(predicate)),\n        })\n        .with_context(|| format!(\"Failed to compile tags.scm query for '{name}'\"))?;\n        Ok(Some(TagQuery { query }))\n    }\n\n    fn tag_query(&self, loader: &Loader) -> Option<&TagQuery> {\n        self.tag_query\n            .get_or_init(|| {\n                let grammar = self.syntax_config(loader)?.grammar;\n                Self::compile_tag_query(grammar, &self.config)\n                    .map_err(|err| {\n                        log::error!(\"{err}\");\n                    })\n                    .ok()\n                    .flatten()\n            })\n            .as_ref()\n    }\n\n    /// Compiles the rainbows.scm query for a language.\n    /// This function should only be used by this module or the xtask crate.\n    pub fn compile_rainbow_query(\n        grammar: Grammar,\n        config: &LanguageConfiguration,\n    ) -> Result<Option<RainbowQuery>> {\n        let name = &config.language_id;\n        let text = read_query(name, \"rainbows.scm\");\n        if text.is_empty() {\n            return Ok(None);\n        }\n        let rainbow_query = RainbowQuery::new(grammar, &text)\n            .with_context(|| format!(\"Failed to compile rainbows.scm query for '{name}'\"))?;\n        Ok(Some(rainbow_query))\n    }\n\n    fn rainbow_query(&self, loader: &Loader) -> Option<&RainbowQuery> {\n        self.rainbow_query\n            .get_or_init(|| {\n                let grammar = self.syntax_config(loader)?.grammar;\n                Self::compile_rainbow_query(grammar, &self.config)\n                    .map_err(|err| {\n                        log::error!(\"{err}\");\n                    })\n                    .ok()\n                    .flatten()\n            })\n            .as_ref()\n    }\n\n    fn reconfigure(&self, scopes: &[String]) {\n        if let Some(Some(config)) = self.syntax.get() {\n            reconfigure_highlights(config, scopes);\n        }\n    }\n}\n\nfn reconfigure_highlights(config: &SyntaxConfig, recognized_names: &[String]) {\n    config.configure(move |capture_name| {\n        let capture_parts: Vec<_> = capture_name.split('.').collect();\n\n        let mut best_index = None;\n        let mut best_match_len = 0;\n        for (i, recognized_name) in recognized_names.iter().enumerate() {\n            let mut len = 0;\n            let mut matches = true;\n            for (i, part) in recognized_name.split('.').enumerate() {\n                match capture_parts.get(i) {\n                    Some(capture_part) if *capture_part == part => len += 1,\n                    _ => {\n                        matches = false;\n                        break;\n                    }\n                }\n            }\n            if matches && len > best_match_len {\n                best_index = Some(i);\n                best_match_len = len;\n            }\n        }\n        best_index.map(|idx| Highlight::new(idx as u32))\n    });\n}\n\npub fn read_query(lang: &str, query_filename: &str) -> String {\n    tree_house::read_query(lang, |language| {\n        helix_loader::grammar::load_runtime_file(language, query_filename).unwrap_or_default()\n    })\n}\n\n#[derive(Debug, Default)]\npub struct Loader {\n    languages: Vec<LanguageData>,\n    languages_by_extension: HashMap<String, Language>,\n    languages_by_shebang: HashMap<String, Language>,\n    languages_glob_matcher: FileTypeGlobMatcher,\n    language_server_configs: HashMap<String, LanguageServerConfiguration>,\n    scopes: ArcSwap<Vec<String>>,\n}\n\npub type LoaderError = globset::Error;\n\nimpl Loader {\n    pub fn new(config: Configuration) -> Result<Self, LoaderError> {\n        let mut languages = Vec::with_capacity(config.language.len());\n        let mut languages_by_extension = HashMap::new();\n        let mut languages_by_shebang = HashMap::new();\n        let mut file_type_globs = Vec::new();\n\n        for mut config in config.language {\n            let language = Language(languages.len() as u32);\n            config.language = Some(language);\n\n            for file_type in &config.file_types {\n                match file_type {\n                    FileType::Extension(extension) => {\n                        languages_by_extension.insert(extension.clone(), language);\n                    }\n                    FileType::Glob(glob) => {\n                        file_type_globs.push(FileTypeGlob::new(glob.to_owned(), language));\n                    }\n                };\n            }\n            for shebang in &config.shebangs {\n                languages_by_shebang.insert(shebang.clone(), language);\n            }\n\n            languages.push(LanguageData::new(config));\n        }\n\n        Ok(Self {\n            languages,\n            languages_by_extension,\n            languages_by_shebang,\n            languages_glob_matcher: FileTypeGlobMatcher::new(file_type_globs)?,\n            language_server_configs: config.language_server,\n            scopes: ArcSwap::from_pointee(Vec::new()),\n        })\n    }\n\n    pub fn languages(&self) -> impl ExactSizeIterator<Item = (Language, &LanguageData)> {\n        self.languages\n            .iter()\n            .enumerate()\n            .map(|(idx, data)| (Language(idx as u32), data))\n    }\n\n    pub fn language_configs(&self) -> impl ExactSizeIterator<Item = &LanguageConfiguration> {\n        self.languages.iter().map(|language| &*language.config)\n    }\n\n    pub fn language(&self, lang: Language) -> &LanguageData {\n        &self.languages[lang.idx()]\n    }\n\n    pub fn language_for_name(&self, name: impl PartialEq<String>) -> Option<Language> {\n        self.languages.iter().enumerate().find_map(|(idx, config)| {\n            (name == config.config.language_id).then_some(Language(idx as u32))\n        })\n    }\n\n    pub fn language_for_scope(&self, scope: &str) -> Option<Language> {\n        self.languages.iter().enumerate().find_map(|(idx, config)| {\n            (scope == config.config.scope).then_some(Language(idx as u32))\n        })\n    }\n\n    pub fn language_for_match(&self, text: RopeSlice) -> Option<Language> {\n        // PERF: If the name matches up with the id, then this saves the need to do expensive regex.\n        let shortcircuit = self.language_for_name(text);\n        if shortcircuit.is_some() {\n            return shortcircuit;\n        }\n\n        // If the name did not match up with a known id, then match on injection regex.\n\n        let mut best_match_length = 0;\n        let mut best_match_position = None;\n        for (idx, data) in self.languages.iter().enumerate() {\n            if let Some(injection_regex) = &data.config.injection_regex {\n                if let Some(mat) = injection_regex.find(text.regex_input()) {\n                    let length = mat.end() - mat.start();\n                    if length > best_match_length {\n                        best_match_position = Some(idx);\n                        best_match_length = length;\n                    }\n                }\n            }\n        }\n\n        best_match_position.map(|i| Language(i as u32))\n    }\n\n    pub fn language_for_filename(&self, path: &Path) -> Option<Language> {\n        // Find all the language configurations that match this file name\n        // or a suffix of the file name.\n\n        // TODO: content_regex handling conflict resolution\n        self.languages_glob_matcher\n            .language_for_path(path)\n            .or_else(|| {\n                path.extension()\n                    .and_then(|extension| extension.to_str())\n                    .and_then(|extension| self.languages_by_extension.get(extension).copied())\n            })\n    }\n\n    pub fn language_for_shebang(&self, text: RopeSlice) -> Option<Language> {\n        // NOTE: this is slightly different than the one for injection markers in tree-house. It\n        // is anchored at the beginning.\n        use helix_stdx::rope::Regex;\n        use once_cell::sync::Lazy;\n        const SHEBANG: &str = r\"^#!\\s*(?:\\S*[/\\\\](?:env\\s+(?:\\-\\S+\\s+)*)?)?([^\\s\\.\\d]+)\";\n        static SHEBANG_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(SHEBANG).unwrap());\n\n        let marker = SHEBANG_REGEX\n            .captures_iter(regex_cursor::Input::new(text))\n            .map(|cap| text.byte_slice(cap.get_group(1).unwrap().range()))\n            .next()?;\n        self.language_for_shebang_marker(marker)\n    }\n\n    fn language_for_shebang_marker(&self, marker: RopeSlice) -> Option<Language> {\n        let shebang: Cow<str> = marker.into();\n        self.languages_by_shebang.get(shebang.as_ref()).copied()\n    }\n\n    pub fn indent_query(&self, lang: Language) -> Option<&IndentQuery> {\n        self.language(lang).indent_query(self)\n    }\n\n    pub fn textobject_query(&self, lang: Language) -> Option<&TextObjectQuery> {\n        self.language(lang).textobject_query(self)\n    }\n\n    pub fn tag_query(&self, lang: Language) -> Option<&TagQuery> {\n        self.language(lang).tag_query(self)\n    }\n\n    fn rainbow_query(&self, lang: Language) -> Option<&RainbowQuery> {\n        self.language(lang).rainbow_query(self)\n    }\n\n    pub fn language_server_configs(&self) -> &HashMap<String, LanguageServerConfiguration> {\n        &self.language_server_configs\n    }\n\n    pub fn scopes(&self) -> Guard<Arc<Vec<String>>> {\n        self.scopes.load()\n    }\n\n    pub fn set_scopes(&self, scopes: Vec<String>) {\n        self.scopes.store(Arc::new(scopes));\n\n        // Reconfigure existing grammars\n        for data in &self.languages {\n            data.reconfigure(&self.scopes());\n        }\n    }\n}\n\nimpl LanguageLoader for Loader {\n    fn language_for_marker(&self, marker: InjectionLanguageMarker) -> Option<Language> {\n        match marker {\n            InjectionLanguageMarker::Name(name) => self.language_for_name(name),\n            InjectionLanguageMarker::Match(text) => self.language_for_match(text),\n            InjectionLanguageMarker::Filename(text) => {\n                let path: Cow<str> = text.into();\n                self.language_for_filename(Path::new(path.as_ref()))\n            }\n            InjectionLanguageMarker::Shebang(text) => self.language_for_shebang_marker(text),\n        }\n    }\n\n    fn get_config(&self, lang: Language) -> Option<&SyntaxConfig> {\n        self.languages[lang.idx()].syntax_config(self)\n    }\n}\n\n#[derive(Debug)]\nstruct FileTypeGlob {\n    glob: globset::Glob,\n    language: Language,\n}\n\nimpl FileTypeGlob {\n    pub fn new(glob: globset::Glob, language: Language) -> Self {\n        Self { glob, language }\n    }\n}\n\n#[derive(Debug)]\nstruct FileTypeGlobMatcher {\n    matcher: globset::GlobSet,\n    file_types: Vec<FileTypeGlob>,\n}\n\nimpl Default for FileTypeGlobMatcher {\n    fn default() -> Self {\n        Self {\n            matcher: globset::GlobSet::empty(),\n            file_types: Default::default(),\n        }\n    }\n}\n\nimpl FileTypeGlobMatcher {\n    fn new(file_types: Vec<FileTypeGlob>) -> Result<Self, globset::Error> {\n        let mut builder = globset::GlobSetBuilder::new();\n        for file_type in &file_types {\n            builder.add(file_type.glob.clone());\n        }\n\n        Ok(Self {\n            matcher: builder.build()?,\n            file_types,\n        })\n    }\n\n    fn language_for_path(&self, path: &Path) -> Option<Language> {\n        self.matcher\n            .matches(path)\n            .iter()\n            .filter_map(|idx| self.file_types.get(*idx))\n            .max_by_key(|file_type| file_type.glob.glob().len())\n            .map(|file_type| file_type.language)\n    }\n}\n\n#[derive(Debug)]\npub struct Syntax {\n    inner: tree_house::Syntax,\n}\n\nconst PARSE_TIMEOUT: Duration = Duration::from_millis(500); // half a second is pretty generous\n\nimpl Syntax {\n    pub fn new(source: RopeSlice, language: Language, loader: &Loader) -> Result<Self, Error> {\n        let inner = tree_house::Syntax::new(source, language, PARSE_TIMEOUT, loader)?;\n        Ok(Self { inner })\n    }\n\n    pub fn update(\n        &mut self,\n        old_source: RopeSlice,\n        source: RopeSlice,\n        changeset: &ChangeSet,\n        loader: &Loader,\n    ) -> Result<(), Error> {\n        let edits = generate_edits(old_source, changeset);\n        if edits.is_empty() {\n            Ok(())\n        } else {\n            self.inner.update(source, PARSE_TIMEOUT, &edits, loader)\n        }\n    }\n\n    pub fn layer(&self, layer: Layer) -> &tree_house::LayerData {\n        self.inner.layer(layer)\n    }\n\n    pub fn root_layer(&self) -> Layer {\n        self.inner.root()\n    }\n\n    /// Finds the smallest injection layer which fully includes the range `start..=end`.\n    ///\n    /// This is the same as using the last item in the `layers_for_byte_range` iterator.\n    pub fn layer_for_byte_range(&self, start: u32, end: u32) -> Layer {\n        self.inner.layer_for_byte_range(start, end)\n    }\n\n    /// Returns an iterator of layers which **fully include** the byte range `start..=end`.\n    ///\n    /// The iterator is non-empty and the root is always the first element. Other layers are\n    /// returned in decreasing order based on the size of each layer. I.e. the last element is\n    /// the smallest layer including the byte range.\n    pub fn layers_for_byte_range(\n        &self,\n        start: u32,\n        end: u32,\n    ) -> impl Iterator<Item = Layer> + use<'_> {\n        self.inner.layers_for_byte_range(start, end)\n    }\n\n    pub fn root_language(&self) -> Language {\n        self.layer(self.root_layer()).language\n    }\n\n    pub fn tree(&self) -> &Tree {\n        self.inner.tree()\n    }\n\n    pub fn tree_for_byte_range(&self, start: u32, end: u32) -> &Tree {\n        self.inner.tree_for_byte_range(start, end)\n    }\n\n    pub fn named_descendant_for_byte_range(&self, start: u32, end: u32) -> Option<Node<'_>> {\n        self.inner.named_descendant_for_byte_range(start, end)\n    }\n\n    pub fn descendant_for_byte_range(&self, start: u32, end: u32) -> Option<Node<'_>> {\n        self.inner.descendant_for_byte_range(start, end)\n    }\n\n    pub fn walk(&self) -> TreeCursor<'_> {\n        self.inner.walk()\n    }\n\n    pub fn highlighter<'a>(\n        &'a self,\n        source: RopeSlice<'a>,\n        loader: &'a Loader,\n        range: impl RangeBounds<u32>,\n    ) -> Highlighter<'a> {\n        Highlighter::new(&self.inner, source, loader, range)\n    }\n\n    pub fn query_iter<'a, QueryLoader, LayerState, Range>(\n        &'a self,\n        source: RopeSlice<'a>,\n        loader: QueryLoader,\n        range: Range,\n    ) -> QueryIter<'a, 'a, QueryLoader, LayerState>\n    where\n        QueryLoader: FnMut(Language) -> Option<&'a Query> + 'a,\n        LayerState: Default,\n        Range: RangeBounds<u32>,\n    {\n        QueryIter::new(&self.inner, source, loader, range)\n    }\n\n    pub fn tags<'a>(\n        &'a self,\n        source: RopeSlice<'a>,\n        loader: &'a Loader,\n        range: impl RangeBounds<u32>,\n    ) -> QueryIter<'a, 'a, impl FnMut(Language) -> Option<&'a Query> + 'a, ()> {\n        self.query_iter(\n            source,\n            |lang| loader.tag_query(lang).map(|q| &q.query),\n            range,\n        )\n    }\n\n    pub fn rainbow_highlights(\n        &self,\n        source: RopeSlice,\n        rainbow_length: usize,\n        loader: &Loader,\n        range: impl RangeBounds<u32>,\n    ) -> OverlayHighlights {\n        struct RainbowScope<'tree> {\n            end: u32,\n            node: Option<Node<'tree>>,\n            highlight: Highlight,\n        }\n\n        let mut scope_stack = Vec::<RainbowScope>::new();\n        let mut highlights = Vec::new();\n        let mut query_iter = self.query_iter::<_, (), _>(\n            source,\n            |lang| loader.rainbow_query(lang).map(|q| &q.query),\n            range,\n        );\n\n        while let Some(event) = query_iter.next() {\n            let QueryIterEvent::Match(mat) = event else {\n                continue;\n            };\n\n            let rainbow_query = loader\n                .rainbow_query(query_iter.current_language())\n                .expect(\"language must have a rainbow query to emit matches\");\n\n            let byte_range = mat.node.byte_range();\n            // Pop any scopes that end before this capture begins.\n            while scope_stack\n                .last()\n                .is_some_and(|scope| byte_range.start >= scope.end)\n            {\n                scope_stack.pop();\n            }\n\n            let capture = Some(mat.capture);\n            if capture == rainbow_query.scope_capture {\n                scope_stack.push(RainbowScope {\n                    end: byte_range.end,\n                    node: if rainbow_query\n                        .include_children_patterns\n                        .contains(&mat.pattern)\n                    {\n                        None\n                    } else {\n                        Some(mat.node.clone())\n                    },\n                    highlight: Highlight::new((scope_stack.len() % rainbow_length) as u32),\n                });\n            } else if capture == rainbow_query.bracket_capture {\n                if let Some(scope) = scope_stack.last() {\n                    if !scope\n                        .node\n                        .as_ref()\n                        .is_some_and(|node| mat.node.parent().as_ref() != Some(node))\n                    {\n                        let start = source\n                            .byte_to_char(source.floor_char_boundary(byte_range.start as usize));\n                        let end =\n                            source.byte_to_char(source.ceil_char_boundary(byte_range.end as usize));\n                        highlights.push((scope.highlight, start..end));\n                    }\n                }\n            }\n        }\n\n        OverlayHighlights::Heterogenous { highlights }\n    }\n}\n\npub type Highlighter<'a> = highlighter::Highlighter<'a, 'a, Loader>;\n\nfn generate_edits(old_text: RopeSlice, changeset: &ChangeSet) -> Vec<InputEdit> {\n    use crate::Operation::*;\n    use tree_sitter::Point;\n\n    let mut old_pos = 0;\n\n    let mut edits = Vec::new();\n\n    if changeset.changes.is_empty() {\n        return edits;\n    }\n\n    let mut iter = changeset.changes.iter().peekable();\n\n    // TODO; this is a lot easier with Change instead of Operation.\n    while let Some(change) = iter.next() {\n        let len = match change {\n            Delete(i) | Retain(i) => *i,\n            Insert(_) => 0,\n        };\n        let mut old_end = old_pos + len;\n\n        match change {\n            Retain(_) => {}\n            Delete(_) => {\n                let start_byte = old_text.char_to_byte(old_pos) as u32;\n                let old_end_byte = old_text.char_to_byte(old_end) as u32;\n\n                // deletion\n                edits.push(InputEdit {\n                    start_byte,               // old_pos to byte\n                    old_end_byte,             // old_end to byte\n                    new_end_byte: start_byte, // old_pos to byte\n                    start_point: Point::ZERO,\n                    old_end_point: Point::ZERO,\n                    new_end_point: Point::ZERO,\n                });\n            }\n            Insert(s) => {\n                let start_byte = old_text.char_to_byte(old_pos) as u32;\n\n                // a subsequent delete means a replace, consume it\n                if let Some(Delete(len)) = iter.peek() {\n                    old_end = old_pos + len;\n                    let old_end_byte = old_text.char_to_byte(old_end) as u32;\n\n                    iter.next();\n\n                    // replacement\n                    edits.push(InputEdit {\n                        start_byte,                                // old_pos to byte\n                        old_end_byte,                              // old_end to byte\n                        new_end_byte: start_byte + s.len() as u32, // old_pos to byte + s.len()\n                        start_point: Point::ZERO,\n                        old_end_point: Point::ZERO,\n                        new_end_point: Point::ZERO,\n                    });\n                } else {\n                    // insert\n                    edits.push(InputEdit {\n                        start_byte,                                // old_pos to byte\n                        old_end_byte: start_byte,                  // same\n                        new_end_byte: start_byte + s.len() as u32, // old_pos + s.len()\n                        start_point: Point::ZERO,\n                        old_end_point: Point::ZERO,\n                        new_end_point: Point::ZERO,\n                    });\n                }\n            }\n        }\n        old_pos = old_end;\n    }\n    edits\n}\n\n/// A set of \"overlay\" highlights and ranges they apply to.\n///\n/// As overlays, the styles for the given `Highlight`s are merged on top of the syntax highlights.\n#[derive(Debug)]\npub enum OverlayHighlights {\n    /// All highlights use a single `Highlight`.\n    ///\n    /// Note that, currently, all ranges are assumed to be non-overlapping. This could change in\n    /// the future though.\n    Homogeneous {\n        highlight: Highlight,\n        ranges: Vec<ops::Range<usize>>,\n    },\n    /// A collection of different highlights for given ranges.\n    ///\n    /// Note that the ranges **must be non-overlapping**.\n    Heterogenous {\n        highlights: Vec<(Highlight, ops::Range<usize>)>,\n    },\n}\n\nimpl OverlayHighlights {\n    pub fn single(highlight: Highlight, range: ops::Range<usize>) -> Self {\n        Self::Homogeneous {\n            highlight,\n            ranges: vec![range],\n        }\n    }\n\n    fn is_empty(&self) -> bool {\n        match self {\n            Self::Homogeneous { ranges, .. } => ranges.is_empty(),\n            Self::Heterogenous { highlights } => highlights.is_empty(),\n        }\n    }\n}\n\n#[derive(Debug)]\nstruct Overlay {\n    highlights: OverlayHighlights,\n    /// The position of the highlighter into the Vec of ranges of the overlays.\n    ///\n    /// Used by the `OverlayHighlighter`.\n    idx: usize,\n    /// The currently active highlight (and the ending character index) for this overlay.\n    ///\n    /// Used by the `OverlayHighlighter`.\n    active_highlight: Option<(Highlight, usize)>,\n}\n\nimpl Overlay {\n    fn new(highlights: OverlayHighlights) -> Option<Self> {\n        (!highlights.is_empty()).then_some(Self {\n            highlights,\n            idx: 0,\n            active_highlight: None,\n        })\n    }\n\n    fn current(&self) -> Option<(Highlight, ops::Range<usize>)> {\n        match &self.highlights {\n            OverlayHighlights::Homogeneous { highlight, ranges } => ranges\n                .get(self.idx)\n                .map(|range| (*highlight, range.clone())),\n            OverlayHighlights::Heterogenous { highlights } => highlights.get(self.idx).cloned(),\n        }\n    }\n\n    fn start(&self) -> Option<usize> {\n        match &self.highlights {\n            OverlayHighlights::Homogeneous { ranges, .. } => {\n                ranges.get(self.idx).map(|range| range.start)\n            }\n            OverlayHighlights::Heterogenous { highlights } => highlights\n                .get(self.idx)\n                .map(|(_highlight, range)| range.start),\n        }\n    }\n}\n\n/// A collection of highlights to apply when rendering which merge on top of syntax highlights.\n#[derive(Debug)]\npub struct OverlayHighlighter {\n    overlays: Vec<Overlay>,\n    next_highlight_start: usize,\n    next_highlight_end: usize,\n}\n\nimpl OverlayHighlighter {\n    pub fn new(overlays: impl IntoIterator<Item = OverlayHighlights>) -> Self {\n        let overlays: Vec<_> = overlays.into_iter().filter_map(Overlay::new).collect();\n        let next_highlight_start = overlays\n            .iter()\n            .filter_map(|overlay| overlay.start())\n            .min()\n            .unwrap_or(usize::MAX);\n\n        Self {\n            overlays,\n            next_highlight_start,\n            next_highlight_end: usize::MAX,\n        }\n    }\n\n    /// The current position in the overlay highlights.\n    ///\n    /// This method is meant to be used when treating this type as a cursor over the overlay\n    /// highlights.\n    ///\n    /// `usize::MAX` is returned when there are no more overlay highlights.\n    pub fn next_event_offset(&self) -> usize {\n        self.next_highlight_start.min(self.next_highlight_end)\n    }\n\n    pub fn advance(&mut self) -> (HighlightEvent, impl Iterator<Item = Highlight> + '_) {\n        let mut refresh = false;\n        let prev_stack_size = self\n            .overlays\n            .iter()\n            .filter(|overlay| overlay.active_highlight.is_some())\n            .count();\n        let pos = self.next_event_offset();\n\n        if self.next_highlight_end == pos {\n            for overlay in self.overlays.iter_mut() {\n                if overlay\n                    .active_highlight\n                    .is_some_and(|(_highlight, end)| end == pos)\n                {\n                    overlay.active_highlight.take();\n                }\n            }\n\n            refresh = true;\n        }\n\n        while self.next_highlight_start == pos {\n            let mut activated_idx = usize::MAX;\n            for (idx, overlay) in self.overlays.iter_mut().enumerate() {\n                let Some((highlight, range)) = overlay.current() else {\n                    continue;\n                };\n                if range.start != self.next_highlight_start {\n                    continue;\n                }\n\n                // If this overlay has a highlight at this start index, set its active highlight\n                // and increment the cursor position within the overlay.\n                overlay.active_highlight = Some((highlight, range.end));\n                overlay.idx += 1;\n\n                activated_idx = activated_idx.min(idx);\n            }\n\n            // If `self.next_highlight_start == pos` that means that some overlay was ready to\n            // emit a highlight, so `activated_idx` must have been set to an existing index.\n            assert!(\n                (0..self.overlays.len()).contains(&activated_idx),\n                \"expected an overlay to highlight (at pos {pos}, there are {} overlays)\",\n                self.overlays.len()\n            );\n\n            // If any overlays are active after the (lowest) one which was just activated, the\n            // highlights need to be refreshed.\n            refresh |= self.overlays[activated_idx..]\n                .iter()\n                .any(|overlay| overlay.active_highlight.is_some());\n\n            self.next_highlight_start = self\n                .overlays\n                .iter()\n                .filter_map(|overlay| overlay.start())\n                .min()\n                .unwrap_or(usize::MAX);\n        }\n\n        self.next_highlight_end = self\n            .overlays\n            .iter()\n            .filter_map(|overlay| Some(overlay.active_highlight?.1))\n            .min()\n            .unwrap_or(usize::MAX);\n\n        let (event, start) = if refresh {\n            (HighlightEvent::Refresh, 0)\n        } else {\n            (HighlightEvent::Push, prev_stack_size)\n        };\n\n        (\n            event,\n            self.overlays\n                .iter()\n                .flat_map(|overlay| overlay.active_highlight)\n                .map(|(highlight, _end)| highlight)\n                .skip(start),\n        )\n    }\n}\n\n#[derive(Debug)]\npub enum CapturedNode<'a> {\n    Single(Node<'a>),\n    /// Guaranteed to be not empty\n    Grouped(Vec<Node<'a>>),\n}\n\nimpl CapturedNode<'_> {\n    pub fn start_byte(&self) -> usize {\n        match self {\n            Self::Single(n) => n.start_byte() as usize,\n            Self::Grouped(ns) => ns[0].start_byte() as usize,\n        }\n    }\n\n    pub fn end_byte(&self) -> usize {\n        match self {\n            Self::Single(n) => n.end_byte() as usize,\n            Self::Grouped(ns) => ns.last().unwrap().end_byte() as usize,\n        }\n    }\n\n    pub fn byte_range(&self) -> ops::Range<usize> {\n        self.start_byte()..self.end_byte()\n    }\n}\n\n#[derive(Debug)]\npub struct TextObjectQuery {\n    query: Query,\n}\n\nimpl TextObjectQuery {\n    pub fn new(query: Query) -> Self {\n        Self { query }\n    }\n\n    /// Run the query on the given node and return sub nodes which match given\n    /// capture (\"function.inside\", \"class.around\", etc).\n    ///\n    /// Captures may contain multiple nodes by using quantifiers (+, *, etc),\n    /// and support for this is partial and could use improvement.\n    ///\n    /// ```query\n    /// (comment)+ @capture\n    ///\n    /// ; OR\n    /// (\n    ///   (comment)*\n    ///   .\n    ///   (function)\n    /// ) @capture\n    /// ```\n    pub fn capture_nodes<'a>(\n        &'a self,\n        capture_name: &str,\n        node: &Node<'a>,\n        slice: RopeSlice<'a>,\n    ) -> Option<impl Iterator<Item = CapturedNode<'a>>> {\n        self.capture_nodes_any(&[capture_name], node, slice)\n    }\n\n    /// Find the first capture that exists out of all given `capture_names`\n    /// and return sub nodes that match this capture.\n    pub fn capture_nodes_any<'a>(\n        &'a self,\n        capture_names: &[&str],\n        node: &Node<'a>,\n        slice: RopeSlice<'a>,\n    ) -> Option<impl Iterator<Item = CapturedNode<'a>>> {\n        let capture = capture_names\n            .iter()\n            .find_map(|cap| self.query.get_capture(cap))?;\n\n        let mut cursor = InactiveQueryCursor::new(0..u32::MAX, TREE_SITTER_MATCH_LIMIT)\n            .execute_query(&self.query, node, RopeInput::new(slice));\n        let capture_node = iter::from_fn(move || {\n            let mat = cursor.next_match()?;\n            Some(mat.nodes_for_capture(capture).cloned().collect())\n        })\n        .filter_map(move |nodes: Vec<_>| {\n            if nodes.len() > 1 {\n                Some(CapturedNode::Grouped(nodes))\n            } else {\n                nodes.into_iter().map(CapturedNode::Single).next()\n            }\n        });\n        Some(capture_node)\n    }\n}\n\n#[derive(Debug)]\npub struct TagQuery {\n    pub query: Query,\n}\n\npub fn pretty_print_tree<W: fmt::Write>(fmt: &mut W, node: Node) -> fmt::Result {\n    if node.child_count() == 0 {\n        if node_is_visible(&node) {\n            write!(fmt, \"({})\", node.kind())\n        } else {\n            write!(fmt, \"\\\"{}\\\"\", format_anonymous_node_kind(node.kind()))\n        }\n    } else {\n        pretty_print_tree_impl(fmt, &mut node.walk(), 0)\n    }\n}\n\nfn node_is_visible(node: &Node) -> bool {\n    node.is_named() && node.grammar().node_kind_is_visible(node.kind_id())\n}\n\nfn format_anonymous_node_kind(kind: &str) -> Cow<'_, str> {\n    if kind.contains('\"') || kind.contains('\\\\') {\n        Cow::Owned(kind.replace('\\\\', \"\\\\\\\\\").replace('\"', \"\\\\\\\"\"))\n    } else {\n        Cow::Borrowed(kind)\n    }\n}\n\nfn pretty_print_tree_impl<W: fmt::Write>(\n    fmt: &mut W,\n    cursor: &mut tree_sitter::TreeCursor,\n    depth: usize,\n) -> fmt::Result {\n    let node = cursor.node();\n    let visible = node_is_visible(&node);\n\n    if visible {\n        let indentation_columns = depth * 2;\n        write!(fmt, \"{:indentation_columns$}\", \"\")?;\n\n        if let Some(field_name) = cursor.field_name() {\n            write!(fmt, \"{}: \", field_name)?;\n        }\n\n        write!(fmt, \"({}\", node.kind())?;\n    } else {\n        write!(fmt, \" \\\"{}\\\"\", format_anonymous_node_kind(node.kind()))?;\n    }\n\n    // Handle children.\n    if cursor.goto_first_child() {\n        loop {\n            if node_is_visible(&cursor.node()) {\n                fmt.write_char('\\n')?;\n            }\n\n            pretty_print_tree_impl(fmt, cursor, depth + 1)?;\n\n            if !cursor.goto_next_sibling() {\n                break;\n            }\n        }\n\n        let moved = cursor.goto_parent();\n        // The parent of the first child must exist, and must be `node`.\n        debug_assert!(moved);\n        debug_assert!(cursor.node() == node);\n    }\n\n    if visible {\n        fmt.write_char(')')?;\n    }\n\n    Ok(())\n}\n\n/// Finds the child of `node` which contains the given byte range.\npub fn child_for_byte_range<'a>(node: &Node<'a>, range: ops::Range<u32>) -> Option<Node<'a>> {\n    for child in node.children() {\n        let child_range = child.byte_range();\n\n        if range.start >= child_range.start && range.end <= child_range.end {\n            return Some(child);\n        }\n    }\n\n    None\n}\n\n#[derive(Debug)]\npub struct RainbowQuery {\n    query: Query,\n    include_children_patterns: HashSet<Pattern>,\n    scope_capture: Option<Capture>,\n    bracket_capture: Option<Capture>,\n}\n\nimpl RainbowQuery {\n    fn new(grammar: Grammar, source: &str) -> Result<Self, tree_sitter::query::ParseError> {\n        let mut include_children_patterns = HashSet::default();\n\n        let query = Query::new(grammar, source, |pattern, predicate| match predicate {\n            UserPredicate::SetProperty {\n                key: \"rainbow.include-children\",\n                val,\n            } => {\n                if val.is_some() {\n                    return Err(\n                        \"property 'rainbow.include-children' does not take an argument\".into(),\n                    );\n                }\n                include_children_patterns.insert(pattern);\n                Ok(())\n            }\n            _ => Err(InvalidPredicateError::unknown(predicate)),\n        })?;\n\n        Ok(Self {\n            include_children_patterns,\n            scope_capture: query.get_capture(\"rainbow.scope\"),\n            bracket_capture: query.get_capture(\"rainbow.bracket\"),\n            query,\n        })\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use once_cell::sync::Lazy;\n\n    use super::*;\n    use crate::{Rope, Transaction};\n\n    static LOADER: Lazy<Loader> = Lazy::new(crate::config::default_lang_loader);\n\n    #[test]\n    fn test_textobject_queries() {\n        let query_str = r#\"\n        (line_comment)+ @quantified_nodes\n        ((line_comment)+) @quantified_nodes_grouped\n        ((line_comment) (line_comment)) @multiple_nodes_grouped\n        \"#;\n        let source = Rope::from_str(\n            r#\"\n/// a comment on\n/// multiple lines\n        \"#,\n        );\n\n        let language = LOADER.language_for_name(\"rust\").unwrap();\n        let grammar = LOADER.get_config(language).unwrap().grammar;\n        let query = Query::new(grammar, query_str, |_, _| Ok(())).unwrap();\n        let textobject = TextObjectQuery::new(query);\n        let syntax = Syntax::new(source.slice(..), language, &LOADER).unwrap();\n\n        let root = syntax.tree().root_node();\n        let test = |capture, range| {\n            let matches: Vec<_> = textobject\n                .capture_nodes(capture, &root, source.slice(..))\n                .unwrap()\n                .collect();\n\n            assert_eq!(\n                matches[0].byte_range(),\n                range,\n                \"@{} expected {:?}\",\n                capture,\n                range\n            )\n        };\n\n        test(\"quantified_nodes\", 1..37);\n        test(\"quantified_nodes_grouped\", 1..37);\n        // TODO: the query for this works instead as\n        // ```\n        // ((line_comment) @capture (line_comment) @capture)\n        // ```\n        // The query used in this test case only captures the first line_comment node.\n        // Determine if this behavior is intentional in tree-sitter.\n        // test(\"multiple_nodes_grouped\", 1..37);\n    }\n\n    #[test]\n    fn test_input_edits() {\n        use tree_sitter::{InputEdit, Point};\n\n        let doc = Rope::from(\"hello world!\\ntest 123\");\n        let transaction = Transaction::change(\n            &doc,\n            vec![(6, 11, Some(\"test\".into())), (12, 17, None)].into_iter(),\n        );\n        let edits = generate_edits(doc.slice(..), transaction.changes());\n        // transaction.apply(&mut state);\n\n        assert_eq!(\n            edits,\n            &[\n                InputEdit {\n                    start_byte: 6,\n                    old_end_byte: 11,\n                    new_end_byte: 10,\n                    start_point: Point::ZERO,\n                    old_end_point: Point::ZERO,\n                    new_end_point: Point::ZERO\n                },\n                InputEdit {\n                    start_byte: 12,\n                    old_end_byte: 17,\n                    new_end_byte: 12,\n                    start_point: Point::ZERO,\n                    old_end_point: Point::ZERO,\n                    new_end_point: Point::ZERO\n                }\n            ]\n        );\n\n        // Testing with the official example from tree-sitter\n        let mut doc = Rope::from(\"fn test() {}\");\n        let transaction =\n            Transaction::change(&doc, vec![(8, 8, Some(\"a: u32\".into()))].into_iter());\n        let edits = generate_edits(doc.slice(..), transaction.changes());\n        transaction.apply(&mut doc);\n\n        assert_eq!(doc, \"fn test(a: u32) {}\");\n        assert_eq!(\n            edits,\n            &[InputEdit {\n                start_byte: 8,\n                old_end_byte: 8,\n                new_end_byte: 14,\n                start_point: Point::ZERO,\n                old_end_point: Point::ZERO,\n                new_end_point: Point::ZERO\n            }]\n        );\n    }\n\n    #[track_caller]\n    fn assert_pretty_print(\n        language_name: &str,\n        source: &str,\n        expected: &str,\n        start: usize,\n        end: usize,\n    ) {\n        let source = Rope::from_str(source);\n        let language = LOADER.language_for_name(language_name).unwrap();\n        let syntax = Syntax::new(source.slice(..), language, &LOADER).unwrap();\n\n        let root = syntax\n            .tree()\n            .root_node()\n            .descendant_for_byte_range(start as u32, end as u32)\n            .unwrap();\n\n        let mut output = String::new();\n        pretty_print_tree(&mut output, root).unwrap();\n\n        assert_eq!(expected, output);\n    }\n\n    #[test]\n    fn test_pretty_print() {\n        let source = r#\"// Hello\"#;\n        assert_pretty_print(\"rust\", source, \"(line_comment \\\"//\\\")\", 0, source.len());\n\n        // A large tree should be indented with fields:\n        let source = r#\"fn main() {\n            println!(\"Hello, World!\");\n        }\"#;\n        assert_pretty_print(\n            \"rust\",\n            source,\n            concat!(\n                \"(function_item \\\"fn\\\"\\n\",\n                \"  name: (identifier)\\n\",\n                \"  parameters: (parameters \\\"(\\\" \\\")\\\")\\n\",\n                \"  body: (block \\\"{\\\"\\n\",\n                \"    (expression_statement\\n\",\n                \"      (macro_invocation\\n\",\n                \"        macro: (identifier) \\\"!\\\"\\n\",\n                \"        (token_tree \\\"(\\\"\\n\",\n                \"          (string_literal \\\"\\\\\\\"\\\"\\n\",\n                \"            (string_content) \\\"\\\\\\\"\\\") \\\")\\\")) \\\";\\\") \\\"}\\\"))\",\n            ),\n            0,\n            source.len(),\n        );\n\n        // Selecting a token should print just that token:\n        let source = r#\"fn main() {}\"#;\n        assert_pretty_print(\"rust\", source, r#\"\"fn\"\"#, 0, 1);\n\n        // Error nodes are printed as errors:\n        let source = r#\"}{\"#;\n        assert_pretty_print(\"rust\", source, \"(ERROR \\\"}\\\" \\\"{\\\")\", 0, source.len());\n\n        // Fields broken under unnamed nodes are determined correctly.\n        // In the following source, `object` belongs to the `singleton_method`\n        // rule but `name` and `body` belong to an unnamed helper `_method_rest`.\n        // This can cause a bug with a pretty-printing implementation that\n        // uses `Node::field_name_for_child` to determine field names but is\n        // fixed when using `tree_sitter::TreeCursor::field_name`.\n        let source = \"def self.method_name\n          true\n        end\";\n        assert_pretty_print(\n            \"ruby\",\n            source,\n            concat!(\n                \"(singleton_method \\\"def\\\"\\n\",\n                \"  object: (self) \\\".\\\"\\n\",\n                \"  name: (identifier)\\n\",\n                \"  body: (body_statement\\n\",\n                \"    (true)) \\\"end\\\")\"\n            ),\n            0,\n            source.len(),\n        );\n    }\n}\n"
  },
  {
    "path": "helix-core/src/test.rs",
    "content": "//! Test helpers.\nuse crate::{Range, Selection};\nuse ropey::Rope;\nuse smallvec::SmallVec;\nuse std::cmp::Reverse;\nuse unicode_segmentation::UnicodeSegmentation;\n\n/// Convert annotated test string to test string and selection.\n///\n/// `#[|` for primary selection with head before anchor followed by `]#`.\n/// `#(|` for secondary selection with head before anchor followed by `)#`.\n/// `#[` for primary selection with head after anchor followed by `|]#`.\n/// `#(` for secondary selection with head after anchor followed by `|)#`.\n///\n/// If the selection contains any LF or CRLF sequences, which are immediately\n/// followed by the same grapheme, then the subsequent one is removed. This is\n/// to allow representing having the cursor over the end of the line.\n///\n/// # Examples\n///\n/// ```\n/// use helix_core::{Range, Selection, test::print};\n/// use smallvec::smallvec;\n///\n/// assert_eq!(\n///     print(\"#[a|]#b#(|c)#\"),\n///     (\"abc\".to_owned(), Selection::new(smallvec![Range::new(0, 1), Range::new(3, 2)], 0))\n/// );\n/// ```\n///\n/// # Panics\n///\n/// Panics when missing primary or appeared more than once.\n/// Panics when missing head or anchor.\n/// Panics when head come after head or anchor come after anchor.\npub fn print(s: &str) -> (String, Selection) {\n    let mut primary_idx = None;\n    let mut ranges = SmallVec::new();\n    let mut iter = UnicodeSegmentation::graphemes(s, true).peekable();\n    let mut left = String::with_capacity(s.len());\n\n    'outer: while let Some(c) = iter.next() {\n        let start = left.chars().count();\n\n        if c != \"#\" {\n            left.push_str(c);\n            continue;\n        }\n\n        let (is_primary, close_pair) = match iter.next() {\n            Some(\"[\") => (true, \"]\"),\n            Some(\"(\") => (false, \")\"),\n            Some(ch) => {\n                left.push('#');\n                left.push_str(ch);\n                continue;\n            }\n            None => break,\n        };\n\n        if is_primary && primary_idx.is_some() {\n            panic!(\"primary `#[` already appeared {:?} {:?}\", left, s);\n        }\n\n        let head_at_beg = iter.next_if_eq(&\"|\").is_some();\n        let last_grapheme = |s: &str| {\n            UnicodeSegmentation::graphemes(s, true)\n                .next_back()\n                .map(String::from)\n        };\n\n        while let Some(c) = iter.next() {\n            let next = iter.peek();\n            let mut prev = last_grapheme(left.as_str());\n\n            if !(c == close_pair && next == Some(&\"#\")) {\n                left.push_str(c);\n                continue;\n            }\n\n            if !head_at_beg {\n                match &prev {\n                    Some(p) if p != \"|\" => {\n                        left.push_str(c);\n                        continue;\n                    }\n                    Some(p) if p == \"|\" => {\n                        left.pop().unwrap(); // pop the |\n                        prev = last_grapheme(left.as_str());\n                    }\n                    _ => (),\n                }\n            }\n\n            iter.next(); // skip \"#\"\n            let next = iter.peek();\n\n            // skip explicit line end inside selection\n            if (prev == Some(String::from(\"\\r\\n\")) || prev == Some(String::from(\"\\n\")))\n                && next.map(|n| String::from(*n)) == prev\n            {\n                iter.next();\n            }\n\n            if is_primary {\n                primary_idx = Some(ranges.len());\n            }\n\n            let (anchor, head) = match head_at_beg {\n                true => (left.chars().count(), start),\n                false => (start, left.chars().count()),\n            };\n\n            ranges.push(Range::new(anchor, head));\n            continue 'outer;\n        }\n\n        if head_at_beg {\n            panic!(\"missing end `{}#` {:?} {:?}\", close_pair, left, s);\n        } else {\n            panic!(\"missing end `|{}#` {:?} {:?}\", close_pair, left, s);\n        }\n    }\n\n    let primary = match primary_idx {\n        Some(i) => i,\n        None => panic!(\"missing primary `#[|]#` {:?}\", s),\n    };\n\n    let selection = Selection::new(ranges, primary);\n    (left, selection)\n}\n\n/// Convert test string and selection to annotated test string.\n///\n/// `#[|` for primary selection with head before anchor followed by `]#`.\n/// `#(|` for secondary selection with head before anchor followed by `)#`.\n/// `#[` for primary selection with head after anchor followed by `|]#`.\n/// `#(` for secondary selection with head after anchor followed by `|)#`.\n///\n/// # Examples\n///\n/// ```\n/// use helix_core::{Range, Selection, test::plain};\n/// use smallvec::smallvec;\n///\n/// assert_eq!(\n///     plain(\"abc\", &Selection::new(smallvec![Range::new(0, 1), Range::new(3, 2)], 0)),\n///     \"#[a|]#b#(|c)#\".to_owned()\n/// );\n/// ```\npub fn plain<R: Into<Rope>>(s: R, selection: &Selection) -> String {\n    let s = s.into();\n    let primary = selection.primary_index();\n    let mut out = String::with_capacity(s.len_bytes() + 5 * selection.len());\n    out.push_str(&s.to_string());\n\n    let mut insertion: Vec<_> = selection\n        .iter()\n        .enumerate()\n        .flat_map(|(i, range)| {\n            // sort like this before reversed so anchor < head later\n            match (range.anchor < range.head, i == primary) {\n                (true, true) => [(range.anchor, \"#[\"), (range.head, \"|]#\")],\n                (true, false) => [(range.anchor, \"#(\"), (range.head, \"|)#\")],\n                (false, true) => [(range.anchor, \"]#\"), (range.head, \"#[|\")],\n                (false, false) => [(range.anchor, \")#\"), (range.head, \"#(|\")],\n            }\n        })\n        .map(|(char_idx, marker)| (s.char_to_byte(char_idx), marker))\n        .collect();\n\n    // insert in reverse order\n    insertion.sort_unstable_by_key(|k| Reverse(k.0));\n    for (i, s) in insertion {\n        out.insert_str(i, s);\n    }\n    out\n}\n\n#[cfg(test)]\n#[allow(clippy::module_inception)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn print_single() {\n        assert_eq!(\n            (String::from(\"hello\"), Selection::single(1, 0)),\n            print(\"#[|h]#ello\")\n        );\n        assert_eq!(\n            (String::from(\"hello\"), Selection::single(0, 1)),\n            print(\"#[h|]#ello\")\n        );\n        assert_eq!(\n            (String::from(\"hello\"), Selection::single(4, 0)),\n            print(\"#[|hell]#o\")\n        );\n        assert_eq!(\n            (String::from(\"hello\"), Selection::single(0, 4)),\n            print(\"#[hell|]#o\")\n        );\n        assert_eq!(\n            (String::from(\"hello\"), Selection::single(5, 0)),\n            print(\"#[|hello]#\")\n        );\n        assert_eq!(\n            (String::from(\"hello\"), Selection::single(0, 5)),\n            print(\"#[hello|]#\")\n        );\n    }\n\n    #[test]\n    fn print_multi() {\n        assert_eq!(\n            (\n                String::from(\"hello\"),\n                Selection::new(\n                    SmallVec::from_slice(&[Range::new(1, 0), Range::new(5, 4)]),\n                    0\n                )\n            ),\n            print(\"#[|h]#ell#(|o)#\")\n        );\n        assert_eq!(\n            (\n                String::from(\"hello\"),\n                Selection::new(\n                    SmallVec::from_slice(&[Range::new(0, 1), Range::new(4, 5)]),\n                    0\n                )\n            ),\n            print(\"#[h|]#ell#(o|)#\")\n        );\n        assert_eq!(\n            (\n                String::from(\"hello\"),\n                Selection::new(\n                    SmallVec::from_slice(&[Range::new(2, 0), Range::new(5, 3)]),\n                    0\n                )\n            ),\n            print(\"#[|he]#l#(|lo)#\")\n        );\n        assert_eq!(\n            (\n                String::from(\"hello\\r\\nhello\\r\\nhello\\r\\n\"),\n                Selection::new(\n                    SmallVec::from_slice(&[\n                        Range::new(7, 5),\n                        Range::new(21, 19),\n                        Range::new(14, 12)\n                    ]),\n                    0\n                )\n            ),\n            print(\"hello#[|\\r\\n]#hello#(|\\r\\n)#hello#(|\\r\\n)#\")\n        );\n    }\n\n    #[test]\n    fn print_multi_byte_code_point() {\n        assert_eq!(\n            (String::from(\"„“\"), Selection::single(1, 0)),\n            print(\"#[|„]#“\")\n        );\n        assert_eq!(\n            (String::from(\"„“\"), Selection::single(2, 1)),\n            print(\"„#[|“]#\")\n        );\n        assert_eq!(\n            (String::from(\"„“\"), Selection::single(0, 1)),\n            print(\"#[„|]#“\")\n        );\n        assert_eq!(\n            (String::from(\"„“\"), Selection::single(1, 2)),\n            print(\"„#[“|]#\")\n        );\n        assert_eq!(\n            (String::from(\"they said „hello“\"), Selection::single(11, 10)),\n            print(\"they said #[|„]#hello“\")\n        );\n    }\n\n    #[test]\n    fn print_multi_code_point_grapheme() {\n        assert_eq!(\n            (String::from(\"hello 👨‍👩‍👧‍👦 goodbye\"), Selection::single(13, 6)),\n            print(\"hello #[|👨‍👩‍👧‍👦]# goodbye\")\n        );\n    }\n\n    #[test]\n    fn plain_single() {\n        assert_eq!(\"#[|h]#ello\", plain(\"hello\", &Selection::single(1, 0)));\n        assert_eq!(\"#[h|]#ello\", plain(\"hello\", &Selection::single(0, 1)));\n        assert_eq!(\"#[|hell]#o\", plain(\"hello\", &Selection::single(4, 0)));\n        assert_eq!(\"#[hell|]#o\", plain(\"hello\", &Selection::single(0, 4)));\n        assert_eq!(\"#[|hello]#\", plain(\"hello\", &Selection::single(5, 0)));\n        assert_eq!(\"#[hello|]#\", plain(\"hello\", &Selection::single(0, 5)));\n    }\n\n    #[test]\n    fn plain_multi() {\n        assert_eq!(\n            plain(\n                \"hello\",\n                &Selection::new(\n                    SmallVec::from_slice(&[Range::new(1, 0), Range::new(5, 4)]),\n                    0\n                )\n            ),\n            String::from(\"#[|h]#ell#(|o)#\")\n        );\n        assert_eq!(\n            plain(\n                \"hello\",\n                &Selection::new(\n                    SmallVec::from_slice(&[Range::new(0, 1), Range::new(4, 5)]),\n                    0\n                )\n            ),\n            String::from(\"#[h|]#ell#(o|)#\")\n        );\n        assert_eq!(\n            plain(\n                \"hello\",\n                &Selection::new(\n                    SmallVec::from_slice(&[Range::new(2, 0), Range::new(5, 3)]),\n                    0\n                )\n            ),\n            String::from(\"#[|he]#l#(|lo)#\")\n        );\n        assert_eq!(\n            plain(\n                \"hello\\r\\nhello\\r\\nhello\\r\\n\",\n                &Selection::new(\n                    SmallVec::from_slice(&[\n                        Range::new(7, 5),\n                        Range::new(21, 19),\n                        Range::new(14, 12)\n                    ]),\n                    0\n                )\n            ),\n            String::from(\"hello#[|\\r\\n]#hello#(|\\r\\n)#hello#(|\\r\\n)#\")\n        );\n    }\n\n    #[test]\n    fn plain_multi_byte_code_point() {\n        assert_eq!(\n            plain(\"„“\", &Selection::single(1, 0)),\n            String::from(\"#[|„]#“\")\n        );\n        assert_eq!(\n            plain(\"„“\", &Selection::single(2, 1)),\n            String::from(\"„#[|“]#\")\n        );\n        assert_eq!(\n            plain(\"„“\", &Selection::single(0, 1)),\n            String::from(\"#[„|]#“\")\n        );\n        assert_eq!(\n            plain(\"„“\", &Selection::single(1, 2)),\n            String::from(\"„#[“|]#\")\n        );\n        assert_eq!(\n            plain(\"they said „hello“\", &Selection::single(11, 10)),\n            String::from(\"they said #[|„]#hello“\")\n        );\n    }\n\n    #[test]\n    fn plain_multi_code_point_grapheme() {\n        assert_eq!(\n            plain(\"hello 👨‍👩‍👧‍👦 goodbye\", &Selection::single(13, 6)),\n            String::from(\"hello #[|👨‍👩‍👧‍👦]# goodbye\")\n        );\n    }\n}\n"
  },
  {
    "path": "helix-core/src/text_annotations.rs",
    "content": "use std::cell::Cell;\nuse std::cmp::Ordering;\nuse std::fmt::Debug;\nuse std::ops::Range;\nuse std::ptr::NonNull;\n\nuse crate::doc_formatter::FormattedGrapheme;\nuse crate::syntax::{Highlight, OverlayHighlights};\nuse crate::{Position, Tendril};\n\n/// An inline annotation is continuous text shown\n/// on the screen before the grapheme that starts at\n/// `char_idx`\n#[derive(Debug, Clone)]\npub struct InlineAnnotation {\n    pub text: Tendril,\n    pub char_idx: usize,\n}\n\nimpl InlineAnnotation {\n    pub fn new(char_idx: usize, text: impl Into<Tendril>) -> Self {\n        Self {\n            char_idx,\n            text: text.into(),\n        }\n    }\n}\n\n/// Represents a **single Grapheme** that is part of the document\n/// that start at `char_idx` that will be replaced with\n/// a different `grapheme`.\n/// If `grapheme` contains multiple graphemes the text\n/// will render incorrectly.\n/// If you want to overlay multiple graphemes simply\n/// use multiple `Overlays`.\n///\n/// # Examples\n///\n/// The following examples are valid overlays for the following text:\n///\n/// `aX͎̊͢͜͝͡bc`\n///\n/// ```\n/// use helix_core::text_annotations::Overlay;\n///\n/// // replaces a\n/// Overlay::new(0, \"X\");\n///\n/// // replaces X͎̊͢͜͝͡\n/// Overlay::new(1, \"\\t\");\n///\n/// // replaces b\n/// Overlay::new(6, \"X̢̢̟͖̲͌̋̇͑͝\");\n/// ```\n///\n/// The following examples are invalid uses\n///\n/// ```\n/// use helix_core::text_annotations::Overlay;\n///\n/// // overlay is not aligned at grapheme boundary\n/// Overlay::new(3, \"x\");\n///\n/// // overlay contains multiple graphemes\n/// Overlay::new(0, \"xy\");\n/// ```\n#[derive(Debug, Clone)]\npub struct Overlay {\n    pub char_idx: usize,\n    pub grapheme: Tendril,\n}\n\nimpl Overlay {\n    pub fn new(char_idx: usize, grapheme: impl Into<Tendril>) -> Self {\n        Self {\n            char_idx,\n            grapheme: grapheme.into(),\n        }\n    }\n}\n\n/// Line annotations allow inserting virtual text lines between normal text\n/// lines.  These lines can be filled with text in the rendering code as their\n/// contents have no effect beyond visual appearance.\n///\n/// The height of virtual text is usually not known ahead of time as virtual\n/// text often requires softwrapping. Furthermore the height of some virtual\n/// text like side-by-side diffs depends on the height of the text (again\n/// influenced by softwrap) and other virtual text. Therefore line annotations\n/// are computed on the fly instead of ahead of time like other annotations.\n///\n/// The core of this trait `insert_virtual_lines` function. It is called at the\n/// end of every  visual line and allows the `LineAnnotation` to insert empty\n/// virtual lines. Apart from that the `LineAnnotation` trait has multiple\n/// methods that allow it to track anchors in the document.\n///\n/// When a new traversal of a document starts `reset_pos` is called. Afterwards\n/// the other functions are called with indices that are larger then the\n/// one passed to `reset_pos`. This allows performing a binary search (use\n/// `partition_point`) in `reset_pos` once and then to only look at the next\n/// anchor during each method call.\n///\n/// The `reset_pos`, `skip_conceal` and `process_anchor` functions all return a\n/// `char_idx` anchor. This anchor is stored when transversing the document and\n/// when the grapheme at the anchor is traversed the `process_anchor` function\n/// is called.\n///\n/// # Note\n///\n/// All functions only receive immutable references to `self`.\n/// `LineAnnotation`s that want to store an internal position or\n/// state of some kind should use `Cell`. Using interior mutability for\n/// caches is preferable as otherwise a lot of lifetimes become invariant\n/// which complicates APIs a lot.\npub trait LineAnnotation {\n    /// Resets the internal position to `char_idx`. This function is called\n    /// when a new traversal of a document starts.\n    ///\n    /// All `char_idx` passed to `insert_virtual_lines` are strictly monotonically increasing\n    /// with the first `char_idx` greater or equal to the `char_idx`\n    /// passed to this function.\n    ///\n    /// # Returns\n    ///\n    /// The `char_idx` of the next anchor this `LineAnnotation` is interested in,\n    /// replaces the currently registered anchor. Return `usize::MAX` to ignore\n    fn reset_pos(&mut self, _char_idx: usize) -> usize {\n        usize::MAX\n    }\n\n    /// Called when a text is concealed that contains an anchor registered by this `LineAnnotation`.\n    /// In this case the line decorations  **must** ensure that virtual text anchored within that\n    /// char range is skipped.\n    ///\n    /// # Returns\n    ///\n    /// The `char_idx` of the next anchor this `LineAnnotation` is interested in,\n    /// **after the end of conceal_end_char_idx**\n    /// replaces the currently registered anchor. Return `usize::MAX` to ignore\n    fn skip_concealed_anchors(&mut self, conceal_end_char_idx: usize) -> usize {\n        self.reset_pos(conceal_end_char_idx)\n    }\n\n    /// Process an anchor (horizontal position is provided) and returns the next anchor.\n    ///\n    /// # Returns\n    ///\n    /// The `char_idx` of the next anchor this `LineAnnotation` is interested in,\n    /// replaces the currently registered anchor. Return `usize::MAX` to ignore\n    fn process_anchor(&mut self, _grapheme: &FormattedGrapheme) -> usize {\n        usize::MAX\n    }\n\n    /// This function is called at the end of a visual line to insert virtual text\n    ///\n    /// # Returns\n    ///\n    /// The number of additional virtual lines to reserve\n    ///\n    /// # Note\n    ///\n    /// The `line_end_visual_pos` parameter indicates the visual vertical distance\n    /// from the start of block where the traversal starts.  This includes the offset\n    /// from other `LineAnnotations`. This allows inline annotations to consider\n    /// the height of the text and \"align\" two different documents (like for side\n    /// by side diffs).  These annotations that want to \"align\" two documents should\n    /// therefore be added last so that other virtual text is also considered while aligning\n    fn insert_virtual_lines(\n        &mut self,\n        line_end_char_idx: usize,\n        line_end_visual_pos: Position,\n        doc_line: usize,\n    ) -> Position;\n}\n\n#[derive(Debug)]\nstruct Layer<'a, A, M> {\n    annotations: &'a [A],\n    current_index: Cell<usize>,\n    metadata: M,\n}\n\nimpl<A, M: Clone> Clone for Layer<'_, A, M> {\n    fn clone(&self) -> Self {\n        Layer {\n            annotations: self.annotations,\n            current_index: self.current_index.clone(),\n            metadata: self.metadata.clone(),\n        }\n    }\n}\n\nimpl<A, M> Layer<'_, A, M> {\n    pub fn reset_pos(&self, char_idx: usize, get_char_idx: impl Fn(&A) -> usize) {\n        let new_index = self\n            .annotations\n            .partition_point(|annot| get_char_idx(annot) < char_idx);\n        self.current_index.set(new_index);\n    }\n\n    pub fn consume(&self, char_idx: usize, get_char_idx: impl Fn(&A) -> usize) -> Option<&A> {\n        let annot = self.annotations.get(self.current_index.get())?;\n        debug_assert!(get_char_idx(annot) >= char_idx);\n        if get_char_idx(annot) == char_idx {\n            self.current_index.set(self.current_index.get() + 1);\n            Some(annot)\n        } else {\n            None\n        }\n    }\n}\n\nimpl<'a, A, M> From<(&'a [A], M)> for Layer<'a, A, M> {\n    fn from((annotations, metadata): (&'a [A], M)) -> Layer<'a, A, M> {\n        Layer {\n            annotations,\n            current_index: Cell::new(0),\n            metadata,\n        }\n    }\n}\n\nfn reset_pos<A, M>(layers: &[Layer<A, M>], pos: usize, get_pos: impl Fn(&A) -> usize) {\n    for layer in layers {\n        layer.reset_pos(pos, &get_pos)\n    }\n}\n\n/// Safety: We store LineAnnotation in a NonNull pointer. This is necessary to work\n/// around an unfortunate inconsistency in rusts variance system that unnnecesarily\n/// makes the lifetime invariant if implemented with safe code. This makes the\n/// DocFormatter API very cumbersome/basically impossible to work with.\n///\n/// Normally object types `dyn Foo + 'a` are covariant so if we used `Box<dyn LineAnnotation + 'a>` below\n/// everything would be alright. However we want to use `Cell<Box<dyn LineAnnotation + 'a>>`\n/// to be able to call the mutable function on `LineAnnotation`. The problem is that\n/// some types like `Cell` make all their arguments invariant. This is important for soundness\n/// normally for the same reasons that `&'a mut T` is invariant over `T`\n/// (see <https://doc.rust-lang.org/nomicon/subtyping.html>). However for `&'a mut` (`dyn Foo + 'b`)\n/// there is a specical rule in the language to make `'b` covariant (otherwise trait objects would be\n/// super annoying to use). See  <https://users.rust-lang.org/t/solved-variance-of-dyn-trait-a> for\n/// why this is sound. Sadly that rule doesn't apply to `Cell<Box<(dyn Foo + 'a)>`\n/// (or other invariant types like `UnsafeCell` or `*mut (dyn Foo + 'a)`).\n///\n/// We sidestep the problem by using `NonNull` which is covariant. In the\n/// special case of trait objects this is sound (easily checked by adding a\n/// `PhantomData<&'a mut Foo + 'a)>` field). We don't need an explicit `Cell`\n/// type here because we never hand out any refereces to the trait objects. That\n/// means any reference to the pointer can create a valid multable reference\n/// that is covariant over `'a` (or in other words it's a raw pointer, as long as\n/// we don't hand out references we are free to do whatever we want).\nstruct RawBox<T: ?Sized>(NonNull<T>);\n\nimpl<T: ?Sized> RawBox<T> {\n    /// Safety: Only a single mutable reference\n    /// created by this function may exist at a given time.\n    #[allow(clippy::mut_from_ref)]\n    unsafe fn get(&self) -> &mut T {\n        &mut *self.0.as_ptr()\n    }\n}\nimpl<T: ?Sized> From<Box<T>> for RawBox<T> {\n    fn from(box_: Box<T>) -> Self {\n        // obviously safe because Box::into_raw never returns null\n        unsafe { Self(NonNull::new_unchecked(Box::into_raw(box_))) }\n    }\n}\n\nimpl<T: ?Sized> Drop for RawBox<T> {\n    fn drop(&mut self) {\n        unsafe { drop(Box::from_raw(self.0.as_ptr())) }\n    }\n}\n\n/// Annotations that change that is displayed when the document is render.\n/// Also commonly called virtual text.\n#[derive(Default)]\npub struct TextAnnotations<'a> {\n    inline_annotations: Vec<Layer<'a, InlineAnnotation, Option<Highlight>>>,\n    overlays: Vec<Layer<'a, Overlay, Option<Highlight>>>,\n    line_annotations: Vec<(Cell<usize>, RawBox<dyn LineAnnotation + 'a>)>,\n}\n\nimpl Debug for TextAnnotations<'_> {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.debug_struct(\"TextAnnotations\")\n            .field(\"inline_annotations\", &self.inline_annotations)\n            .field(\"overlays\", &self.overlays)\n            .finish_non_exhaustive()\n    }\n}\n\nimpl<'a> TextAnnotations<'a> {\n    /// Prepare the TextAnnotations for iteration starting at char_idx\n    pub fn reset_pos(&self, char_idx: usize) {\n        reset_pos(&self.inline_annotations, char_idx, |annot| annot.char_idx);\n        reset_pos(&self.overlays, char_idx, |annot| annot.char_idx);\n        for (next_anchor, layer) in &self.line_annotations {\n            next_anchor.set(unsafe { layer.get().reset_pos(char_idx) });\n        }\n    }\n\n    pub fn collect_overlay_highlights(&self, char_range: Range<usize>) -> OverlayHighlights {\n        let mut highlights = Vec::new();\n        self.reset_pos(char_range.start);\n        for char_idx in char_range {\n            if let Some((_, Some(highlight))) = self.overlay_at(char_idx) {\n                // we don't know the number of chars the original grapheme takes\n                // however it doesn't matter as highlight boundaries are automatically\n                // aligned to grapheme boundaries in the rendering code\n                highlights.push((highlight, char_idx..char_idx + 1));\n            }\n        }\n\n        OverlayHighlights::Heterogenous { highlights }\n    }\n\n    /// Add new inline annotations.\n    ///\n    /// The annotations grapheme will be rendered with `highlight`\n    /// patched on top of `ui.text`.\n    ///\n    /// The annotations **must be sorted** by their `char_idx`.\n    /// Multiple annotations with the same `char_idx` are allowed,\n    /// they will be display in the order that they are present in the layer.\n    ///\n    /// If multiple layers contain annotations at the same position\n    /// the annotations that belong to the layers added first will be shown first.\n    pub fn add_inline_annotations(\n        &mut self,\n        layer: &'a [InlineAnnotation],\n        highlight: Option<Highlight>,\n    ) -> &mut Self {\n        if !layer.is_empty() {\n            self.inline_annotations.push((layer, highlight).into());\n        }\n        self\n    }\n\n    /// Add new grapheme overlays.\n    ///\n    /// The overlaid grapheme will be rendered with `highlight`\n    /// patched on top of `ui.text`.\n    ///\n    /// The overlays **must be sorted** by their `char_idx`.\n    /// Multiple overlays with the same `char_idx` **are allowed**.\n    ///\n    /// If multiple layers contain overlay at the same position\n    /// the overlay from the layer added last will be show.\n    pub fn add_overlay(&mut self, layer: &'a [Overlay], highlight: Option<Highlight>) -> &mut Self {\n        if !layer.is_empty() {\n            self.overlays.push((layer, highlight).into());\n        }\n        self\n    }\n\n    /// Add new annotation lines.\n    ///\n    /// The line annotations **must be sorted** by their `char_idx`.\n    /// Multiple line annotations with the same `char_idx` **are not allowed**.\n    pub fn add_line_annotation(&mut self, layer: Box<dyn LineAnnotation + 'a>) -> &mut Self {\n        self.line_annotations\n            .push((Cell::new(usize::MAX), layer.into()));\n        self\n    }\n\n    /// Removes all line annotations, useful for vertical motions\n    /// so that virtual text lines are automatically skipped.\n    pub fn clear_line_annotations(&mut self) {\n        self.line_annotations.clear();\n    }\n\n    pub(crate) fn next_inline_annotation_at(\n        &self,\n        char_idx: usize,\n    ) -> Option<(&InlineAnnotation, Option<Highlight>)> {\n        self.inline_annotations.iter().find_map(|layer| {\n            let annotation = layer.consume(char_idx, |annot| annot.char_idx)?;\n            Some((annotation, layer.metadata))\n        })\n    }\n\n    pub(crate) fn overlay_at(&self, char_idx: usize) -> Option<(&Overlay, Option<Highlight>)> {\n        let mut overlay = None;\n        for layer in &self.overlays {\n            while let Some(new_overlay) = layer.consume(char_idx, |annot| annot.char_idx) {\n                overlay = Some((new_overlay, layer.metadata));\n            }\n        }\n        overlay\n    }\n\n    pub(crate) fn process_virtual_text_anchors(&self, grapheme: &FormattedGrapheme) {\n        for (next_anchor, layer) in &self.line_annotations {\n            loop {\n                match next_anchor.get().cmp(&grapheme.char_idx) {\n                    Ordering::Less => next_anchor\n                        .set(unsafe { layer.get().skip_concealed_anchors(grapheme.char_idx) }),\n                    Ordering::Equal => {\n                        next_anchor.set(unsafe { layer.get().process_anchor(grapheme) })\n                    }\n                    Ordering::Greater => break,\n                };\n            }\n        }\n    }\n\n    pub(crate) fn virtual_lines_at(\n        &self,\n        char_idx: usize,\n        line_end_visual_pos: Position,\n        doc_line: usize,\n    ) -> usize {\n        let mut virt_off = Position::new(0, 0);\n        for (_, layer) in &self.line_annotations {\n            virt_off += unsafe {\n                layer\n                    .get()\n                    .insert_virtual_lines(char_idx, line_end_visual_pos + virt_off, doc_line)\n            };\n        }\n        virt_off.row\n    }\n}\n"
  },
  {
    "path": "helix-core/src/textobject.rs",
    "content": "use std::fmt::Display;\n\nuse ropey::RopeSlice;\n\nuse crate::chars::{categorize_char, char_is_whitespace, CharCategory};\nuse crate::graphemes::{next_grapheme_boundary, prev_grapheme_boundary};\nuse crate::line_ending::rope_is_line_ending;\nuse crate::movement::Direction;\nuse crate::syntax;\nuse crate::Range;\nuse crate::{surround, Syntax};\n\nfn find_word_boundary(slice: RopeSlice, mut pos: usize, direction: Direction, long: bool) -> usize {\n    use CharCategory::{Eol, Whitespace};\n\n    let iter = match direction {\n        Direction::Forward => slice.chars_at(pos),\n        Direction::Backward => {\n            let mut iter = slice.chars_at(pos);\n            iter.reverse();\n            iter\n        }\n    };\n\n    let mut prev_category = match direction {\n        Direction::Forward if pos == 0 => Whitespace,\n        Direction::Forward => categorize_char(slice.char(pos - 1)),\n        Direction::Backward if pos == slice.len_chars() => Whitespace,\n        Direction::Backward => categorize_char(slice.char(pos)),\n    };\n\n    for ch in iter {\n        match categorize_char(ch) {\n            Eol | Whitespace => return pos,\n            category => {\n                if !long && category != prev_category && pos != 0 && pos != slice.len_chars() {\n                    return pos;\n                } else {\n                    match direction {\n                        Direction::Forward => pos += 1,\n                        Direction::Backward => pos = pos.saturating_sub(1),\n                    }\n                    prev_category = category;\n                }\n            }\n        }\n    }\n\n    pos\n}\n\n#[derive(Copy, Clone, PartialEq, Eq, Debug)]\npub enum TextObject {\n    Around,\n    Inside,\n    /// Used for moving between objects.\n    Movement,\n}\n\nimpl Display for TextObject {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.write_str(match self {\n            Self::Around => \"around\",\n            Self::Inside => \"inside\",\n            Self::Movement => \"movement\",\n        })\n    }\n}\n\n// count doesn't do anything yet\npub fn textobject_word(\n    slice: RopeSlice,\n    range: Range,\n    textobject: TextObject,\n    _count: usize,\n    long: bool,\n) -> Range {\n    let pos = range.cursor(slice);\n\n    let word_start = find_word_boundary(slice, pos, Direction::Backward, long);\n    let word_end = match slice.get_char(pos).map(categorize_char) {\n        None | Some(CharCategory::Whitespace | CharCategory::Eol) => pos,\n        _ => find_word_boundary(slice, pos + 1, Direction::Forward, long),\n    };\n\n    // Special case.\n    if word_start == word_end {\n        return Range::new(word_start, word_end);\n    }\n\n    match textobject {\n        TextObject::Inside => Range::new(word_start, word_end),\n        TextObject::Around => {\n            let whitespace_count_right = slice\n                .chars_at(word_end)\n                .take_while(|c| char_is_whitespace(*c))\n                .count();\n\n            if whitespace_count_right > 0 {\n                Range::new(word_start, word_end + whitespace_count_right)\n            } else {\n                let whitespace_count_left = {\n                    let mut iter = slice.chars_at(word_start);\n                    iter.reverse();\n                    iter.take_while(|c| char_is_whitespace(*c)).count()\n                };\n                Range::new(word_start - whitespace_count_left, word_end)\n            }\n        }\n        TextObject::Movement => unreachable!(),\n    }\n}\n\npub fn textobject_paragraph(\n    slice: RopeSlice,\n    range: Range,\n    textobject: TextObject,\n    count: usize,\n) -> Range {\n    let mut line = range.cursor_line(slice);\n    let prev_line_empty = rope_is_line_ending(slice.line(line.saturating_sub(1)));\n    let curr_line_empty = rope_is_line_ending(slice.line(line));\n    let next_line_empty = rope_is_line_ending(slice.line(line.saturating_sub(1)));\n    let last_char =\n        prev_grapheme_boundary(slice, slice.line_to_char(line + 1)) == range.cursor(slice);\n    let prev_empty_to_line = prev_line_empty && !curr_line_empty;\n    let curr_empty_to_line = curr_line_empty && !next_line_empty;\n\n    // skip character before paragraph boundary\n    let mut line_back = line; // line but backwards\n    if prev_empty_to_line || curr_empty_to_line {\n        line_back += 1;\n    }\n    // do not include current paragraph on paragraph end (include next)\n    if !(curr_empty_to_line && last_char) {\n        let mut lines = slice.lines_at(line_back);\n        lines.reverse();\n        let mut lines = lines.map(rope_is_line_ending).peekable();\n        while lines.next_if(|&e| e).is_some() {\n            line_back -= 1;\n        }\n        while lines.next_if(|&e| !e).is_some() {\n            line_back -= 1;\n        }\n    }\n\n    // skip character after paragraph boundary\n    if curr_empty_to_line && last_char {\n        line += 1;\n    }\n    let mut lines = slice.lines_at(line).map(rope_is_line_ending).peekable();\n    let mut count_done = 0; // count how many non-whitespace paragraphs done\n    for _ in 0..count {\n        let mut done = false;\n        while lines.next_if(|&e| !e).is_some() {\n            line += 1;\n            done = true;\n        }\n        while lines.next_if(|&e| e).is_some() {\n            line += 1;\n        }\n        count_done += done as usize;\n    }\n\n    // search one paragraph backwards for last paragraph\n    // makes `map` at the end of the paragraph with trailing newlines useful\n    let last_paragraph = count_done != count && lines.peek().is_none();\n    if last_paragraph {\n        let mut lines = slice.lines_at(line_back);\n        lines.reverse();\n        let mut lines = lines.map(rope_is_line_ending).peekable();\n        while lines.next_if(|&e| e).is_some() {\n            line_back -= 1;\n        }\n        while lines.next_if(|&e| !e).is_some() {\n            line_back -= 1;\n        }\n    }\n\n    // handle last whitespaces part separately depending on textobject\n    match textobject {\n        TextObject::Around => {}\n        TextObject::Inside => {\n            // remove last whitespace paragraph\n            let mut lines = slice.lines_at(line);\n            lines.reverse();\n            let mut lines = lines.map(rope_is_line_ending).peekable();\n            while lines.next_if(|&e| e).is_some() {\n                line -= 1;\n            }\n        }\n        TextObject::Movement => unreachable!(),\n    }\n\n    let anchor = slice.line_to_char(line_back);\n    let head = slice.line_to_char(line);\n    Range::new(anchor, head)\n}\n\npub fn textobject_pair_surround(\n    syntax: Option<&Syntax>,\n    slice: RopeSlice,\n    range: Range,\n    textobject: TextObject,\n    ch: char,\n    count: usize,\n) -> Range {\n    textobject_pair_surround_impl(syntax, slice, range, textobject, Some(ch), count)\n}\n\npub fn textobject_pair_surround_closest(\n    syntax: Option<&Syntax>,\n    slice: RopeSlice,\n    range: Range,\n    textobject: TextObject,\n    count: usize,\n) -> Range {\n    textobject_pair_surround_impl(syntax, slice, range, textobject, None, count)\n}\n\nfn textobject_pair_surround_impl(\n    syntax: Option<&Syntax>,\n    slice: RopeSlice,\n    range: Range,\n    textobject: TextObject,\n    ch: Option<char>,\n    count: usize,\n) -> Range {\n    let pair_pos = match ch {\n        Some(ch) => surround::find_nth_pairs_pos(syntax, slice, ch, range, count),\n        None => surround::find_nth_closest_pairs_pos(syntax, slice, range, count),\n    };\n    pair_pos\n        .map(|(anchor, head)| match textobject {\n            TextObject::Inside => {\n                if anchor < head {\n                    Range::new(next_grapheme_boundary(slice, anchor), head)\n                } else {\n                    Range::new(anchor, next_grapheme_boundary(slice, head))\n                }\n            }\n            TextObject::Around => {\n                if anchor < head {\n                    Range::new(anchor, next_grapheme_boundary(slice, head))\n                } else {\n                    Range::new(next_grapheme_boundary(slice, anchor), head)\n                }\n            }\n            TextObject::Movement => unreachable!(),\n        })\n        .unwrap_or(range)\n}\n\n/// Transform the given range to select text objects based on tree-sitter.\n/// `object_name` is a query capture base name like \"function\", \"class\", etc.\n/// `slice_tree` is the tree-sitter node corresponding to given text slice.\npub fn textobject_treesitter(\n    slice: RopeSlice,\n    range: Range,\n    textobject: TextObject,\n    object_name: &str,\n    syntax: &Syntax,\n    loader: &syntax::Loader,\n    _count: usize,\n) -> Range {\n    let root = syntax.tree().root_node();\n    let textobject_query = loader.textobject_query(syntax.root_language());\n    let get_range = move || -> Option<Range> {\n        let byte_pos = slice.char_to_byte(range.cursor(slice));\n\n        let capture_name = format!(\"{}.{}\", object_name, textobject); // eg. function.inner\n        let node = textobject_query?\n            .capture_nodes(&capture_name, &root, slice)?\n            .filter(|node| node.byte_range().contains(&byte_pos))\n            .min_by_key(|node| node.byte_range().len())?;\n\n        let len = slice.len_bytes();\n        let start_byte = node.start_byte();\n        let end_byte = node.end_byte();\n        if start_byte >= len || end_byte >= len {\n            return None;\n        }\n\n        let start_char = slice.byte_to_char(start_byte);\n        let end_char = slice.byte_to_char(end_byte);\n\n        Some(Range::new(start_char, end_char))\n    };\n    get_range().unwrap_or(range)\n}\n\n#[cfg(test)]\nmod test {\n    use super::TextObject::*;\n    use super::*;\n\n    use crate::Range;\n    use ropey::Rope;\n\n    #[test]\n    fn test_textobject_word() {\n        // (text, [(char position, textobject, final range), ...])\n        let tests = &[\n            (\n                \"cursor at beginning of doc\",\n                vec![(0, Inside, (0, 6)), (0, Around, (0, 7))],\n            ),\n            (\n                \"cursor at middle of word\",\n                vec![\n                    (13, Inside, (10, 16)),\n                    (10, Inside, (10, 16)),\n                    (15, Inside, (10, 16)),\n                    (13, Around, (10, 17)),\n                    (10, Around, (10, 17)),\n                    (15, Around, (10, 17)),\n                ],\n            ),\n            (\n                \"cursor between word whitespace\",\n                vec![(6, Inside, (6, 6)), (6, Around, (6, 6))],\n            ),\n            (\n                \"cursor on word before newline\\n\",\n                vec![\n                    (22, Inside, (22, 29)),\n                    (28, Inside, (22, 29)),\n                    (25, Inside, (22, 29)),\n                    (22, Around, (21, 29)),\n                    (28, Around, (21, 29)),\n                    (25, Around, (21, 29)),\n                ],\n            ),\n            (\n                \"cursor on newline\\nnext line\",\n                vec![(17, Inside, (17, 17)), (17, Around, (17, 17))],\n            ),\n            (\n                \"cursor on word after newline\\nnext line\",\n                vec![\n                    (29, Inside, (29, 33)),\n                    (30, Inside, (29, 33)),\n                    (32, Inside, (29, 33)),\n                    (29, Around, (29, 34)),\n                    (30, Around, (29, 34)),\n                    (32, Around, (29, 34)),\n                ],\n            ),\n            (\n                \"cursor on #$%:;* punctuation\",\n                vec![\n                    (13, Inside, (10, 16)),\n                    (10, Inside, (10, 16)),\n                    (15, Inside, (10, 16)),\n                    (13, Around, (10, 17)),\n                    (10, Around, (10, 17)),\n                    (15, Around, (10, 17)),\n                ],\n            ),\n            (\n                \"cursor on punc%^#$:;.tuation\",\n                vec![\n                    (14, Inside, (14, 21)),\n                    (20, Inside, (14, 21)),\n                    (17, Inside, (14, 21)),\n                    (14, Around, (14, 21)),\n                    (20, Around, (14, 21)),\n                    (17, Around, (14, 21)),\n                ],\n            ),\n            (\n                \"cursor in   extra whitespace\",\n                vec![\n                    (9, Inside, (9, 9)),\n                    (10, Inside, (10, 10)),\n                    (11, Inside, (11, 11)),\n                    (9, Around, (9, 9)),\n                    (10, Around, (10, 10)),\n                    (11, Around, (11, 11)),\n                ],\n            ),\n            (\n                \"cursor on word   with extra whitespace\",\n                vec![(11, Inside, (10, 14)), (11, Around, (10, 17))],\n            ),\n            (\n                \"cursor at end with extra   whitespace\",\n                vec![(28, Inside, (27, 37)), (28, Around, (24, 37))],\n            ),\n            (\n                \"cursor at end of doc\",\n                vec![(19, Inside, (17, 20)), (19, Around, (16, 20))],\n            ),\n        ];\n\n        for (sample, scenario) in tests {\n            let doc = Rope::from(*sample);\n            let slice = doc.slice(..);\n            for &case in scenario {\n                let (pos, objtype, expected_range) = case;\n                // cursor is a single width selection\n                let range = Range::new(pos, pos + 1);\n                let result = textobject_word(slice, range, objtype, 1, false);\n                assert_eq!(\n                    result,\n                    expected_range.into(),\n                    \"\\nCase failed: {:?} - {:?}\",\n                    sample,\n                    case\n                );\n            }\n        }\n    }\n\n    #[test]\n    fn test_textobject_paragraph_inside_single() {\n        let tests = [\n            (\"#[|]#\", \"#[|]#\"),\n            (\"firs#[t|]#\\n\\nparagraph\\n\\n\", \"#[first\\n|]#\\nparagraph\\n\\n\"),\n            (\n                \"second\\n\\npa#[r|]#agraph\\n\\n\",\n                \"second\\n\\n#[paragraph\\n|]#\\n\",\n            ),\n            (\"#[f|]#irst char\\n\\n\", \"#[first char\\n|]#\\n\"),\n            (\"last char\\n#[\\n|]#\", \"#[last char\\n|]#\\n\"),\n            (\n                \"empty to line\\n#[\\n|]#paragraph boundary\\n\\n\",\n                \"empty to line\\n\\n#[paragraph boundary\\n|]#\\n\",\n            ),\n            (\n                \"line to empty\\n\\n#[p|]#aragraph boundary\\n\\n\",\n                \"line to empty\\n\\n#[paragraph boundary\\n|]#\\n\",\n            ),\n        ];\n\n        for (before, expected) in tests {\n            let (s, selection) = crate::test::print(before);\n            let text = Rope::from(s.as_str());\n            let selection = selection\n                .transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Inside, 1));\n            let actual = crate::test::plain(s.as_ref(), &selection);\n            assert_eq!(actual, expected, \"\\nbefore: `{:?}`\", before);\n        }\n    }\n\n    #[test]\n    fn test_textobject_paragraph_inside_double() {\n        let tests = [\n            (\n                \"last two\\n\\n#[p|]#aragraph\\n\\nwithout whitespaces\\n\\n\",\n                \"last two\\n\\n#[paragraph\\n\\nwithout whitespaces\\n|]#\\n\",\n            ),\n            (\n                \"last two\\n#[\\n|]#paragraph\\n\\nwithout whitespaces\\n\\n\",\n                \"last two\\n\\n#[paragraph\\n\\nwithout whitespaces\\n|]#\\n\",\n            ),\n        ];\n\n        for (before, expected) in tests {\n            let (s, selection) = crate::test::print(before);\n            let text = Rope::from(s.as_str());\n            let selection = selection\n                .transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Inside, 2));\n            let actual = crate::test::plain(s.as_ref(), &selection);\n            assert_eq!(actual, expected, \"\\nbefore: `{:?}`\", before);\n        }\n    }\n\n    #[test]\n    fn test_textobject_paragraph_around_single() {\n        let tests = [\n            (\"#[|]#\", \"#[|]#\"),\n            (\"firs#[t|]#\\n\\nparagraph\\n\\n\", \"#[first\\n\\n|]#paragraph\\n\\n\"),\n            (\n                \"second\\n\\npa#[r|]#agraph\\n\\n\",\n                \"second\\n\\n#[paragraph\\n\\n|]#\",\n            ),\n            (\"#[f|]#irst char\\n\\n\", \"#[first char\\n\\n|]#\"),\n            (\"last char\\n#[\\n|]#\", \"#[last char\\n\\n|]#\"),\n            (\n                \"empty to line\\n#[\\n|]#paragraph boundary\\n\\n\",\n                \"empty to line\\n\\n#[paragraph boundary\\n\\n|]#\",\n            ),\n            (\n                \"line to empty\\n\\n#[p|]#aragraph boundary\\n\\n\",\n                \"line to empty\\n\\n#[paragraph boundary\\n\\n|]#\",\n            ),\n        ];\n\n        for (before, expected) in tests {\n            let (s, selection) = crate::test::print(before);\n            let text = Rope::from(s.as_str());\n            let selection = selection\n                .transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Around, 1));\n            let actual = crate::test::plain(s.as_ref(), &selection);\n            assert_eq!(actual, expected, \"\\nbefore: `{:?}`\", before);\n        }\n    }\n\n    #[test]\n    fn test_textobject_surround() {\n        // (text, [(cursor position, textobject, final range, surround char, count), ...])\n        let tests = &[\n            (\n                \"simple (single) surround pairs\",\n                vec![\n                    (3, Inside, (3, 3), '(', 1),\n                    (7, Inside, (8, 14), ')', 1),\n                    (10, Inside, (8, 14), '(', 1),\n                    (14, Inside, (8, 14), ')', 1),\n                    (3, Around, (3, 3), '(', 1),\n                    (7, Around, (7, 15), ')', 1),\n                    (10, Around, (7, 15), '(', 1),\n                    (14, Around, (7, 15), ')', 1),\n                ],\n            ),\n            (\n                \"samexx 'single' surround pairs\",\n                vec![\n                    (3, Inside, (3, 3), '\\'', 1),\n                    (7, Inside, (7, 7), '\\'', 1),\n                    (10, Inside, (8, 14), '\\'', 1),\n                    (14, Inside, (14, 14), '\\'', 1),\n                    (3, Around, (3, 3), '\\'', 1),\n                    (7, Around, (7, 7), '\\'', 1),\n                    (10, Around, (7, 15), '\\'', 1),\n                    (14, Around, (14, 14), '\\'', 1),\n                ],\n            ),\n            (\n                \"(nested (surround (pairs)) 3 levels)\",\n                vec![\n                    (0, Inside, (1, 35), '(', 1),\n                    (6, Inside, (1, 35), ')', 1),\n                    (8, Inside, (9, 25), '(', 1),\n                    (8, Inside, (9, 35), ')', 2),\n                    (20, Inside, (9, 25), '(', 2),\n                    (20, Inside, (1, 35), ')', 3),\n                    (0, Around, (0, 36), '(', 1),\n                    (6, Around, (0, 36), ')', 1),\n                    (8, Around, (8, 26), '(', 1),\n                    (8, Around, (8, 36), ')', 2),\n                    (20, Around, (8, 26), '(', 2),\n                    (20, Around, (0, 36), ')', 3),\n                ],\n            ),\n            (\n                \"(mixed {surround [pair] same} line)\",\n                vec![\n                    (2, Inside, (1, 34), '(', 1),\n                    (9, Inside, (8, 28), '{', 1),\n                    (18, Inside, (18, 22), '[', 1),\n                    (2, Around, (0, 35), '(', 1),\n                    (9, Around, (7, 29), '{', 1),\n                    (18, Around, (17, 23), '[', 1),\n                ],\n            ),\n            (\n                \"(stepped (surround) pairs (should) skip)\",\n                vec![(22, Inside, (1, 39), '(', 1), (22, Around, (0, 40), '(', 1)],\n            ),\n            (\n                \"[surround pairs{\\non different]\\nlines}\",\n                vec![\n                    (7, Inside, (1, 29), '[', 1),\n                    (15, Inside, (16, 36), '{', 1),\n                    (7, Around, (0, 30), '[', 1),\n                    (15, Around, (15, 37), '{', 1),\n                ],\n            ),\n        ];\n\n        for (sample, scenario) in tests {\n            let doc = Rope::from(*sample);\n            let slice = doc.slice(..);\n            for &case in scenario {\n                let (pos, objtype, expected_range, ch, count) = case;\n                let result =\n                    textobject_pair_surround(None, slice, Range::point(pos), objtype, ch, count);\n                assert_eq!(\n                    result,\n                    expected_range.into(),\n                    \"\\nCase failed: {:?} - {:?}\",\n                    sample,\n                    case\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "helix-core/src/transaction.rs",
    "content": "use ropey::RopeSlice;\nuse smallvec::SmallVec;\n\nuse crate::{chars::char_is_word, Range, Rope, Selection, Tendril};\nuse std::{borrow::Cow, iter::once};\n\n/// (from, to, replacement)\npub type Change = (usize, usize, Option<Tendril>);\npub type Deletion = (usize, usize);\n\n// TODO: pub(crate)\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum Operation {\n    /// Move cursor by n characters.\n    Retain(usize),\n    /// Delete n characters.\n    Delete(usize),\n    /// Insert text at position.\n    Insert(Tendril),\n}\n\nimpl Operation {\n    /// The number of characters affected by the operation.\n    pub fn len_chars(&self) -> usize {\n        match self {\n            Self::Retain(n) | Self::Delete(n) => *n,\n            Self::Insert(s) => s.chars().count(),\n        }\n    }\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum Assoc {\n    Before,\n    After,\n    /// Acts like `After` if a word character is inserted\n    /// after the position, otherwise acts like `Before`\n    AfterWord,\n    /// Acts like `Before` if a word character is inserted\n    /// before the position, otherwise acts like `After`\n    BeforeWord,\n    /// Acts like `Before` but if the position is within an exact replacement\n    /// (exact size) the offset to the start of the replacement is kept\n    BeforeSticky,\n    /// Acts like `After` but if the position is within an exact replacement\n    /// (exact size) the offset to the start of the replacement is kept\n    AfterSticky,\n}\n\nimpl Assoc {\n    /// Whether to stick to gaps\n    fn stay_at_gaps(self) -> bool {\n        !matches!(self, Self::BeforeWord | Self::AfterWord)\n    }\n\n    fn insert_offset(self, s: &str) -> usize {\n        let chars = s.chars().count();\n        match self {\n            Assoc::After | Assoc::AfterSticky => chars,\n            Assoc::AfterWord => s.chars().take_while(|&c| char_is_word(c)).count(),\n            // return position before inserted text\n            Assoc::Before | Assoc::BeforeSticky => 0,\n            Assoc::BeforeWord => chars - s.chars().rev().take_while(|&c| char_is_word(c)).count(),\n        }\n    }\n\n    pub fn sticky(self) -> bool {\n        matches!(self, Assoc::BeforeSticky | Assoc::AfterSticky)\n    }\n}\n\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct ChangeSet {\n    pub(crate) changes: Vec<Operation>,\n    /// The required document length. Will refuse to apply changes unless it matches.\n    len: usize,\n    len_after: usize,\n}\n\nimpl ChangeSet {\n    pub fn with_capacity(capacity: usize) -> Self {\n        Self {\n            changes: Vec::with_capacity(capacity),\n            len: 0,\n            len_after: 0,\n        }\n    }\n\n    #[must_use]\n    pub fn new(doc: RopeSlice) -> Self {\n        let len = doc.len_chars();\n        Self {\n            changes: Vec::new(),\n            len,\n            len_after: len,\n        }\n    }\n\n    // TODO: from iter\n\n    #[doc(hidden)] // used by lsp to convert to LSP changes\n    pub fn changes(&self) -> &[Operation] {\n        &self.changes\n    }\n\n    // Changeset builder operations: delete/insert/retain\n    pub(crate) fn delete(&mut self, n: usize) {\n        use Operation::*;\n        if n == 0 {\n            return;\n        }\n\n        self.len += n;\n\n        if let Some(Delete(count)) = self.changes.last_mut() {\n            *count += n;\n        } else {\n            self.changes.push(Delete(n));\n        }\n    }\n\n    pub(crate) fn insert(&mut self, fragment: Tendril) {\n        use Operation::*;\n\n        if fragment.is_empty() {\n            return;\n        }\n\n        // Avoiding std::str::len() to account for UTF-8 characters.\n        self.len_after += fragment.chars().count();\n\n        let new_last = match self.changes.as_mut_slice() {\n            [.., Insert(prev)] | [.., Insert(prev), Delete(_)] => {\n                prev.push_str(&fragment);\n                return;\n            }\n            [.., last @ Delete(_)] => std::mem::replace(last, Insert(fragment)),\n            _ => Insert(fragment),\n        };\n\n        self.changes.push(new_last);\n    }\n\n    pub(crate) fn retain(&mut self, n: usize) {\n        use Operation::*;\n        if n == 0 {\n            return;\n        }\n\n        self.len += n;\n        self.len_after += n;\n\n        if let Some(Retain(count)) = self.changes.last_mut() {\n            *count += n;\n        } else {\n            self.changes.push(Retain(n));\n        }\n    }\n\n    /// Combine two changesets together.\n    /// In other words,  If `this` goes `docA` → `docB` and `other` represents `docB` → `docC`, the\n    /// returned value will represent the change `docA` → `docC`.\n    pub fn compose(self, other: Self) -> Self {\n        assert!(self.len_after == other.len);\n\n        // composing fails in weird ways if one of the sets is empty\n        // a: [] len: 0 len_after: 1 | b: [Insert(Tendril<UTF8>(inline: \"\\n\")), Retain(1)] len 1\n        if self.changes.is_empty() {\n            return other;\n        }\n        if other.changes.is_empty() {\n            return self;\n        }\n\n        let len = self.changes.len();\n\n        let mut changes_a = self.changes.into_iter();\n        let mut changes_b = other.changes.into_iter();\n\n        let mut head_a = changes_a.next();\n        let mut head_b = changes_b.next();\n\n        let mut changes = Self::with_capacity(len); // TODO: max(a, b), shrink_to_fit() afterwards\n\n        loop {\n            use std::cmp::Ordering;\n            use Operation::*;\n            match (head_a, head_b) {\n                // we are done\n                (None, None) => {\n                    break;\n                }\n                // deletion in A\n                (Some(Delete(i)), b) => {\n                    changes.delete(i);\n                    head_a = changes_a.next();\n                    head_b = b;\n                }\n                // insertion in B\n                (a, Some(Insert(current))) => {\n                    changes.insert(current);\n                    head_a = a;\n                    head_b = changes_b.next();\n                }\n                (None, val) | (val, None) => unreachable!(\"({:?})\", val),\n                (Some(Retain(i)), Some(Retain(j))) => match i.cmp(&j) {\n                    Ordering::Less => {\n                        changes.retain(i);\n                        head_a = changes_a.next();\n                        head_b = Some(Retain(j - i));\n                    }\n                    Ordering::Equal => {\n                        changes.retain(i);\n                        head_a = changes_a.next();\n                        head_b = changes_b.next();\n                    }\n                    Ordering::Greater => {\n                        changes.retain(j);\n                        head_a = Some(Retain(i - j));\n                        head_b = changes_b.next();\n                    }\n                },\n                (Some(Insert(mut s)), Some(Delete(j))) => {\n                    let len = s.chars().count();\n                    match len.cmp(&j) {\n                        Ordering::Less => {\n                            head_a = changes_a.next();\n                            head_b = Some(Delete(j - len));\n                        }\n                        Ordering::Equal => {\n                            head_a = changes_a.next();\n                            head_b = changes_b.next();\n                        }\n                        Ordering::Greater => {\n                            // TODO: cover this with a test\n                            // figure out the byte index of the truncated string end\n                            let (pos, _) = s.char_indices().nth(j).unwrap();\n                            s.replace_range(0..pos, \"\");\n                            head_a = Some(Insert(s));\n                            head_b = changes_b.next();\n                        }\n                    }\n                }\n                (Some(Insert(s)), Some(Retain(j))) => {\n                    let len = s.chars().count();\n                    match len.cmp(&j) {\n                        Ordering::Less => {\n                            changes.insert(s);\n                            head_a = changes_a.next();\n                            head_b = Some(Retain(j - len));\n                        }\n                        Ordering::Equal => {\n                            changes.insert(s);\n                            head_a = changes_a.next();\n                            head_b = changes_b.next();\n                        }\n                        Ordering::Greater => {\n                            // figure out the byte index of the truncated string end\n                            let (pos, _) = s.char_indices().nth(j).unwrap();\n                            let mut before = s;\n                            let after = before.split_off(pos);\n\n                            changes.insert(before);\n                            head_a = Some(Insert(after));\n                            head_b = changes_b.next();\n                        }\n                    }\n                }\n                (Some(Retain(i)), Some(Delete(j))) => match i.cmp(&j) {\n                    Ordering::Less => {\n                        changes.delete(i);\n                        head_a = changes_a.next();\n                        head_b = Some(Delete(j - i));\n                    }\n                    Ordering::Equal => {\n                        changes.delete(j);\n                        head_a = changes_a.next();\n                        head_b = changes_b.next();\n                    }\n                    Ordering::Greater => {\n                        changes.delete(j);\n                        head_a = Some(Retain(i - j));\n                        head_b = changes_b.next();\n                    }\n                },\n            };\n        }\n\n        // starting len should still equal original starting len\n        debug_assert!(changes.len == self.len);\n\n        changes\n    }\n\n    /// Given another change set starting in the same document, maps this\n    /// change set over the other, producing a new change set that can be\n    /// applied to the document produced by applying `other`. When\n    /// `before` is `true`, order changes as if `this` comes before\n    /// `other`, otherwise (the default) treat `other` as coming first.\n    ///\n    /// Given two changes `A` and `B`, `A.compose(B.map(A))` and\n    /// `B.compose(A.map(B, true))` will produce the same document. This\n    /// provides a basic form of [operational\n    /// transformation](https://en.wikipedia.org/wiki/Operational_transformation),\n    /// and can be used for collaborative editing.\n    pub fn map(self, _other: Self) -> Self {\n        unimplemented!()\n    }\n\n    /// Returns a new changeset that reverts this one. Useful for `undo` implementation.\n    /// The document parameter expects the original document before this change was applied.\n    pub fn invert(&self, original_doc: &Rope) -> Self {\n        assert!(original_doc.len_chars() == self.len);\n\n        let mut changes = Self::with_capacity(self.changes.len());\n\n        let mut pos = 0;\n\n        for change in &self.changes {\n            use Operation::*;\n            match change {\n                Retain(n) => {\n                    changes.retain(*n);\n                    pos += n;\n                }\n                Delete(n) => {\n                    let text = Cow::from(original_doc.slice(pos..pos + *n));\n                    changes.insert(Tendril::from(text.as_ref()));\n                    pos += n;\n                }\n                Insert(s) => {\n                    let chars = s.chars().count();\n                    changes.delete(chars);\n                }\n            }\n        }\n\n        changes\n    }\n\n    /// Returns true if applied successfully.\n    pub fn apply(&self, text: &mut Rope) -> bool {\n        if text.len_chars() != self.len {\n            return false;\n        }\n\n        let mut pos = 0;\n\n        for change in &self.changes {\n            use Operation::*;\n            match change {\n                Retain(n) => {\n                    pos += n;\n                }\n                Delete(n) => {\n                    text.remove(pos..pos + *n);\n                    // pos += n;\n                }\n                Insert(s) => {\n                    text.insert(pos, s);\n                    pos += s.chars().count();\n                }\n            }\n        }\n        true\n    }\n\n    /// `true` when the set is empty.\n    #[inline]\n    pub fn is_empty(&self) -> bool {\n        self.changes.is_empty() || self.changes == [Operation::Retain(self.len)]\n    }\n\n    /// Map a (mostly) *sorted* list of positions through the changes.\n    ///\n    /// This is equivalent to updating each position with `map_pos`:\n    ///\n    /// ``` no-compile\n    /// for (pos, assoc) in positions {\n    ///     *pos = changes.map_pos(*pos, assoc);\n    /// }\n    /// ```\n    /// However this function is significantly faster for sorted lists running\n    /// in `O(N+M)` instead of `O(NM)`. This function also handles unsorted/\n    /// partially sorted lists. However, in that case worst case complexity is\n    /// again `O(MN)`.  For lists that are often/mostly sorted (like the end of diagnostic ranges)\n    /// performance is usally close to `O(N + M)`\n    pub fn update_positions<'a>(&self, positions: impl Iterator<Item = (&'a mut usize, Assoc)>) {\n        use Operation::*;\n\n        let mut positions = positions.peekable();\n\n        let mut old_pos = 0;\n        let mut new_pos = 0;\n        let mut iter = self.changes.iter().enumerate().peekable();\n\n        'outer: loop {\n            macro_rules! map {\n                ($map: expr, $i: expr) => {\n                    loop {\n                        let Some((pos, assoc)) = positions.peek_mut() else {\n                            return;\n                        };\n                        if **pos < old_pos {\n                            // Positions are not sorted, revert to the last Operation that\n                            // contains this position and continue iterating from there.\n                            // We can unwrap here since `pos` can not be negative\n                            // (unsigned integer) and iterating backwards to the start\n                            // should always move us back to the start\n                            for (i, change) in self.changes[..$i].iter().enumerate().rev() {\n                                match change {\n                                    Retain(i) => {\n                                        old_pos -= i;\n                                        new_pos -= i;\n                                    }\n                                    Delete(i) => {\n                                        old_pos -= i;\n                                    }\n                                    Insert(ins) => {\n                                        new_pos -= ins.chars().count();\n                                    }\n                                }\n                                if old_pos <= **pos {\n                                    iter = self.changes[i..].iter().enumerate().peekable();\n                                }\n                            }\n                            debug_assert!(old_pos <= **pos, \"Reverse Iter across changeset works\");\n                            continue 'outer;\n                        }\n                        #[allow(clippy::redundant_closure_call)]\n                        let Some(new_pos) = $map(**pos, *assoc) else {\n                            break;\n                        };\n                        **pos = new_pos;\n                        positions.next();\n                    }\n                };\n            }\n\n            let Some((i, change)) = iter.next() else {\n                map!(\n                    |pos, _| (old_pos == pos).then_some(new_pos),\n                    self.changes.len()\n                );\n                break;\n            };\n\n            let len = match change {\n                Delete(i) | Retain(i) => *i,\n                Insert(_) => 0,\n            };\n            let mut old_end = old_pos + len;\n\n            match change {\n                Retain(_) => {\n                    map!(\n                        |pos, _| (old_end > pos).then_some(new_pos + (pos - old_pos)),\n                        i\n                    );\n                    new_pos += len;\n                }\n                Delete(_) => {\n                    // in range\n                    map!(|pos, _| (old_end > pos).then_some(new_pos), i);\n                }\n                Insert(s) => {\n                    // a subsequent delete means a replace, consume it\n                    if let Some((_, Delete(len))) = iter.peek() {\n                        iter.next();\n\n                        old_end = old_pos + len;\n                        // in range of replaced text\n                        map!(\n                            |pos, assoc: Assoc| (old_end > pos).then(|| {\n                                // at point or tracking before\n                                if pos == old_pos && assoc.stay_at_gaps() {\n                                    new_pos\n                                } else {\n                                    let ins = assoc.insert_offset(s);\n                                    // if the deleted and inserted text have the exact same size\n                                    // keep the relative offset into the new text\n                                    if *len == ins && assoc.sticky() {\n                                        new_pos + (pos - old_pos)\n                                    } else {\n                                        new_pos + assoc.insert_offset(s)\n                                    }\n                                }\n                            }),\n                            i\n                        );\n                    } else {\n                        // at insert point\n                        map!(\n                            |pos, assoc: Assoc| (old_pos == pos).then(|| {\n                                // return position before inserted text\n                                new_pos + assoc.insert_offset(s)\n                            }),\n                            i\n                        );\n                    }\n\n                    new_pos += s.chars().count();\n                }\n            }\n            old_pos = old_end;\n        }\n        let out_of_bounds: Vec<_> = positions.collect();\n\n        panic!(\"Positions {out_of_bounds:?} are out of range for changeset len {old_pos}!\",)\n    }\n\n    /// Map a position through the changes.\n    ///\n    /// `assoc` indicates which side to associate the position with. `Before` will keep the\n    /// position close to the character before, and will place it before insertions over that\n    /// range, or at that point. `After` will move it forward, placing it at the end of such\n    /// insertions.\n    pub fn map_pos(&self, mut pos: usize, assoc: Assoc) -> usize {\n        self.update_positions(once((&mut pos, assoc)));\n        pos\n    }\n\n    pub fn changes_iter(&self) -> ChangeIterator<'_> {\n        ChangeIterator::new(self)\n    }\n}\n\n/// Transaction represents a single undoable unit of changes. Several changes can be grouped into\n/// a single transaction.\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct Transaction {\n    changes: ChangeSet,\n    selection: Option<Selection>,\n}\n\nimpl Transaction {\n    /// Create a new, empty transaction.\n    pub fn new(doc: &Rope) -> Self {\n        Self {\n            changes: ChangeSet::new(doc.slice(..)),\n            selection: None,\n        }\n    }\n\n    /// Changes made to the buffer.\n    pub fn changes(&self) -> &ChangeSet {\n        &self.changes\n    }\n\n    /// When set, explicitly updates the selection.\n    pub fn selection(&self) -> Option<&Selection> {\n        self.selection.as_ref()\n    }\n\n    /// Returns true if applied successfully.\n    pub fn apply(&self, doc: &mut Rope) -> bool {\n        if self.changes.is_empty() {\n            return true;\n        }\n\n        // apply changes to the document\n        self.changes.apply(doc)\n    }\n\n    /// Generate a transaction that reverts this one.\n    pub fn invert(&self, original: &Rope) -> Self {\n        let changes = self.changes.invert(original);\n\n        Self {\n            changes,\n            selection: None,\n        }\n    }\n\n    pub fn compose(mut self, other: Self) -> Self {\n        self.changes = self.changes.compose(other.changes);\n        // Other selection takes precedence\n        self.selection = other.selection;\n        self\n    }\n\n    pub fn with_selection(mut self, selection: Selection) -> Self {\n        self.selection = Some(selection);\n        self\n    }\n\n    /// Generate a transaction from a set of potentially overlapping changes. The `change_ranges`\n    /// iterator yield the range (of removed text) in the old document for each edit. If any change\n    /// overlaps with a range overlaps with a previous range then that range is ignored.\n    ///\n    /// The `process_change` callback is called for each edit that is not ignored (in the order\n    /// yielded by `changes`) and should return the new text that the associated range will be\n    /// replaced with.\n    ///\n    /// To make this function more flexible the iterator can yield additional data for each change\n    /// that is passed to `process_change`\n    pub fn change_ignore_overlapping<T>(\n        doc: &Rope,\n        change_ranges: impl Iterator<Item = (usize, usize, T)>,\n        mut process_change: impl FnMut(usize, usize, T) -> Option<Tendril>,\n    ) -> Self {\n        let mut last = 0;\n        let changes = change_ranges.filter_map(|(from, to, data)| {\n            if from < last {\n                return None;\n            }\n            let tendril = process_change(from, to, data);\n            last = to;\n            Some((from, to, tendril))\n        });\n        Self::change(doc, changes)\n    }\n\n    /// Generate a transaction from a set of changes.\n    pub fn change<I>(doc: &Rope, changes: I) -> Self\n    where\n        I: Iterator<Item = Change>,\n    {\n        let len = doc.len_chars();\n\n        let (lower, upper) = changes.size_hint();\n        let size = upper.unwrap_or(lower);\n        let mut changeset = ChangeSet::with_capacity(2 * size + 1); // rough estimate\n\n        let mut last = 0;\n        for (from, to, tendril) in changes {\n            // Verify ranges are ordered and not overlapping\n            debug_assert!(last <= from);\n            // Verify ranges are correct\n            debug_assert!(\n                from <= to,\n                \"Edit end must end before it starts (should {from} <= {to})\"\n            );\n\n            // Retain from last \"to\" to current \"from\"\n            changeset.retain(from - last);\n            let span = to - from;\n            match tendril {\n                Some(text) => {\n                    changeset.insert(text);\n                    changeset.delete(span);\n                }\n                None => changeset.delete(span),\n            }\n            last = to;\n        }\n\n        changeset.retain(len - last);\n\n        Self::from(changeset)\n    }\n\n    /// Generate a transaction from a set of potentially overlapping deletions\n    /// by merging overlapping deletions together.\n    pub fn delete<I>(doc: &Rope, deletions: I) -> Self\n    where\n        I: Iterator<Item = Deletion>,\n    {\n        let len = doc.len_chars();\n\n        let (lower, upper) = deletions.size_hint();\n        let size = upper.unwrap_or(lower);\n        let mut changeset = ChangeSet::with_capacity(2 * size + 1); // rough estimate\n\n        let mut last = 0;\n        for (mut from, to) in deletions {\n            if last > to {\n                continue;\n            }\n            if last > from {\n                from = last\n            }\n            debug_assert!(\n                from <= to,\n                \"Edit end must end before it starts (should {from} <= {to})\"\n            );\n            // Retain from last \"to\" to current \"from\"\n            changeset.retain(from - last);\n            changeset.delete(to - from);\n            last = to;\n        }\n\n        changeset.retain(len - last);\n\n        Self::from(changeset)\n    }\n\n    pub fn insert_at_eof(mut self, text: Tendril) -> Transaction {\n        self.changes.insert(text);\n        self\n    }\n\n    /// Generate a transaction with a change per selection range.\n    pub fn change_by_selection<F>(doc: &Rope, selection: &Selection, f: F) -> Self\n    where\n        F: FnMut(&Range) -> Change,\n    {\n        Self::change(doc, selection.iter().map(f))\n    }\n\n    pub fn change_by_selection_ignore_overlapping(\n        doc: &Rope,\n        selection: &Selection,\n        mut change_range: impl FnMut(&Range) -> (usize, usize),\n        mut create_tendril: impl FnMut(usize, usize) -> Option<Tendril>,\n    ) -> (Transaction, Selection) {\n        let mut last_selection_idx = None;\n        let mut new_primary_idx = None;\n        let mut ranges: SmallVec<[Range; 1]> = SmallVec::new();\n        let process_change = |change_start, change_end, (idx, range): (usize, &Range)| {\n            // update the primary idx\n            if idx == selection.primary_index() {\n                new_primary_idx = Some(idx);\n            } else if new_primary_idx.is_none() {\n                if idx > selection.primary_index() {\n                    new_primary_idx = last_selection_idx;\n                } else {\n                    last_selection_idx = Some(idx);\n                }\n            }\n            ranges.push(*range);\n            create_tendril(change_start, change_end)\n        };\n        let transaction = Self::change_ignore_overlapping(\n            doc,\n            selection.iter().enumerate().map(|range| {\n                let (change_start, change_end) = change_range(range.1);\n                (change_start, change_end, range)\n            }),\n            process_change,\n        );\n\n        (\n            transaction,\n            Selection::new(ranges, new_primary_idx.unwrap_or(0)),\n        )\n    }\n\n    /// Generate a transaction with a deletion per selection range.\n    /// Compared to using `change_by_selection` directly these ranges may overlap.\n    /// In that case they are merged\n    pub fn delete_by_selection<F>(doc: &Rope, selection: &Selection, f: F) -> Self\n    where\n        F: FnMut(&Range) -> Deletion,\n    {\n        Self::delete(doc, selection.iter().map(f))\n    }\n\n    /// Insert text at each selection head.\n    pub fn insert(doc: &Rope, selection: &Selection, text: Tendril) -> Self {\n        Self::change_by_selection(doc, selection, |range| {\n            (range.head, range.head, Some(text.clone()))\n        })\n    }\n\n    pub fn changes_iter(&self) -> ChangeIterator<'_> {\n        self.changes.changes_iter()\n    }\n}\n\nimpl From<ChangeSet> for Transaction {\n    fn from(changes: ChangeSet) -> Self {\n        Self {\n            changes,\n            selection: None,\n        }\n    }\n}\n\npub struct ChangeIterator<'a> {\n    iter: std::iter::Peekable<std::slice::Iter<'a, Operation>>,\n    pos: usize,\n}\n\nimpl<'a> ChangeIterator<'a> {\n    fn new(changeset: &'a ChangeSet) -> Self {\n        let iter = changeset.changes.iter().peekable();\n        Self { iter, pos: 0 }\n    }\n}\n\nimpl Iterator for ChangeIterator<'_> {\n    type Item = Change;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        use Operation::*;\n\n        loop {\n            match self.iter.next()? {\n                Retain(len) => {\n                    self.pos += len;\n                }\n                Delete(len) => {\n                    let start = self.pos;\n                    self.pos += len;\n                    return Some((start, self.pos, None));\n                }\n                Insert(s) => {\n                    let start = self.pos;\n                    // a subsequent delete means a replace, consume it\n                    if let Some(Delete(len)) = self.iter.peek() {\n                        self.iter.next();\n\n                        self.pos += len;\n                        return Some((start, self.pos, Some(s.clone())));\n                    } else {\n                        return Some((start, start, Some(s.clone())));\n                    }\n                }\n            }\n        }\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::history::State;\n\n    #[test]\n    fn composition() {\n        use Operation::*;\n\n        let a = ChangeSet {\n            changes: vec![\n                Retain(5),\n                Insert(\" test!\".into()),\n                Retain(1),\n                Delete(2),\n                Insert(\"abc\".into()),\n            ],\n            len: 8,\n            len_after: 15,\n        };\n\n        let b = ChangeSet {\n            changes: vec![Delete(10), Insert(\"世orld\".into()), Retain(5)],\n            len: 15,\n            len_after: 10,\n        };\n\n        let mut text = Rope::from(\"hello xz\");\n\n        // should probably return cloned text\n        let composed = a.compose(b);\n        assert_eq!(composed.len, 8);\n        assert!(composed.apply(&mut text));\n        assert_eq!(text, \"世orld! abc\");\n    }\n\n    #[test]\n    fn invert() {\n        use Operation::*;\n\n        let changes = ChangeSet {\n            changes: vec![Retain(4), Insert(\"test\".into()), Delete(5), Retain(3)],\n            len: 12,\n            len_after: 11,\n        };\n\n        let doc = Rope::from(\"世界3 hello xz\");\n        let revert = changes.invert(&doc);\n\n        let mut doc2 = doc.clone();\n        changes.apply(&mut doc2);\n\n        // a revert is different\n        assert_ne!(changes, revert);\n        assert_ne!(doc, doc2);\n\n        // but inverting a revert will give us the original\n        assert_eq!(changes, revert.invert(&doc2));\n\n        // applying a revert gives us back the original\n        revert.apply(&mut doc2);\n        assert_eq!(doc, doc2);\n    }\n\n    #[test]\n    fn map_pos() {\n        use Operation::*;\n\n        // maps inserts\n        let cs = ChangeSet {\n            changes: vec![Retain(4), Insert(\"!!\".into()), Retain(4)],\n            len: 8,\n            len_after: 10,\n        };\n\n        assert_eq!(cs.map_pos(0, Assoc::Before), 0); // before insert region\n        assert_eq!(cs.map_pos(4, Assoc::Before), 4); // at insert, track before\n        assert_eq!(cs.map_pos(4, Assoc::After), 6); // at insert, track after\n        assert_eq!(cs.map_pos(5, Assoc::Before), 7); // after insert region\n\n        // maps deletes\n        let cs = ChangeSet {\n            changes: vec![Retain(4), Delete(4), Retain(4)],\n            len: 12,\n            len_after: 8,\n        };\n        assert_eq!(cs.map_pos(0, Assoc::Before), 0); // at start\n        assert_eq!(cs.map_pos(4, Assoc::Before), 4); // before a delete\n        assert_eq!(cs.map_pos(5, Assoc::Before), 4); // inside a delete\n        assert_eq!(cs.map_pos(5, Assoc::After), 4); // inside a delete\n\n        // TODO: delete tracking\n\n        // stays inbetween replacements\n        let cs = ChangeSet {\n            changes: vec![\n                Insert(\"ab\".into()),\n                Delete(2),\n                Insert(\"cd\".into()),\n                Delete(2),\n            ],\n            len: 4,\n            len_after: 4,\n        };\n        assert_eq!(cs.map_pos(2, Assoc::Before), 2);\n        assert_eq!(cs.map_pos(2, Assoc::After), 2);\n        // unsorted selection\n        let cs = ChangeSet {\n            changes: vec![\n                Insert(\"ab\".into()),\n                Delete(2),\n                Insert(\"cd\".into()),\n                Delete(2),\n            ],\n            len: 4,\n            len_after: 4,\n        };\n        let mut positions = [4, 2];\n        cs.update_positions(positions.iter_mut().map(|pos| (pos, Assoc::After)));\n        assert_eq!(positions, [4, 2]);\n        // stays at word boundary\n        let cs = ChangeSet {\n            changes: vec![\n                Retain(2), // <space><space>\n                Insert(\" ab\".into()),\n                Retain(2), // cd\n                Insert(\"de \".into()),\n            ],\n            len: 4,\n            len_after: 10,\n        };\n        assert_eq!(cs.map_pos(2, Assoc::BeforeWord), 3);\n        assert_eq!(cs.map_pos(4, Assoc::AfterWord), 9);\n        let cs = ChangeSet {\n            changes: vec![\n                Retain(1), // <space>\n                Insert(\" b\".into()),\n                Delete(1), // c\n                Retain(1), // d\n                Insert(\"e \".into()),\n                Delete(1), // <space>\n            ],\n            len: 5,\n            len_after: 7,\n        };\n        assert_eq!(cs.map_pos(1, Assoc::BeforeWord), 2);\n        assert_eq!(cs.map_pos(3, Assoc::AfterWord), 5);\n        let cs = ChangeSet {\n            changes: vec![\n                Retain(1), // <space>\n                Insert(\"a\".into()),\n                Delete(2), // <space>b\n                Retain(1), // d\n                Insert(\"e\".into()),\n                Delete(1), // f\n                Retain(1), // <space>\n            ],\n            len: 5,\n            len_after: 7,\n        };\n        assert_eq!(cs.map_pos(2, Assoc::BeforeWord), 1);\n        assert_eq!(cs.map_pos(4, Assoc::AfterWord), 4);\n    }\n\n    #[test]\n    fn transaction_change() {\n        let mut doc = Rope::from(\"hello world!\\ntest 123\");\n        let transaction = Transaction::change(\n            &doc,\n            // (1, 1, None) is a useless 0-width delete that gets factored out\n            vec![(1, 1, None), (6, 11, Some(\"void\".into())), (12, 17, None)].into_iter(),\n        );\n        transaction.apply(&mut doc);\n        assert_eq!(doc, Rope::from_str(\"hello void! 123\"));\n    }\n\n    #[test]\n    fn changes_iter() {\n        let doc = Rope::from(\"hello world!\\ntest 123\");\n        let changes = vec![(6, 11, Some(\"void\".into())), (12, 17, None)];\n        let transaction = Transaction::change(&doc, changes.clone().into_iter());\n        assert_eq!(transaction.changes_iter().collect::<Vec<_>>(), changes);\n    }\n\n    #[test]\n    fn optimized_composition() {\n        let mut state = State {\n            doc: \"\".into(),\n            selection: Selection::point(0),\n        };\n        let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from(\"h\"));\n        t1.apply(&mut state.doc);\n        state.selection = state.selection.clone().map(t1.changes());\n        let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from(\"e\"));\n        t2.apply(&mut state.doc);\n        state.selection = state.selection.clone().map(t2.changes());\n        let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from(\"l\"));\n        t3.apply(&mut state.doc);\n        state.selection = state.selection.clone().map(t3.changes());\n        let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from(\"l\"));\n        t4.apply(&mut state.doc);\n        state.selection = state.selection.clone().map(t4.changes());\n        let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from(\"o\"));\n        t5.apply(&mut state.doc);\n        state.selection = state.selection.clone().map(t5.changes());\n\n        assert_eq!(state.doc, Rope::from_str(\"hello\"));\n\n        // changesets as follows:\n        // h\n        // retain 1, e\n        // retain 2, l\n\n        let changes = t1\n            .changes\n            .compose(t2.changes)\n            .compose(t3.changes)\n            .compose(t4.changes)\n            .compose(t5.changes);\n\n        use Operation::*;\n        assert_eq!(changes.changes, &[Insert(\"hello\".into())]);\n        // instead of insert h, insert e, insert l, insert l, insert o\n    }\n\n    #[test]\n    fn combine_with_empty() {\n        let empty = Rope::from(\"\");\n        let a = ChangeSet::new(empty.slice(..));\n\n        let mut b = ChangeSet::new(empty.slice(..));\n        b.insert(\"a\".into());\n\n        let changes = a.compose(b);\n\n        use Operation::*;\n        assert_eq!(changes.changes, &[Insert(\"a\".into())]);\n    }\n\n    #[test]\n    fn combine_with_utf8() {\n        const TEST_CASE: &str = \"Hello, これはヘリックスエディターです！\";\n\n        let empty = Rope::from(\"\");\n        let a = ChangeSet::new(empty.slice(..));\n\n        let mut b = ChangeSet::new(empty.slice(..));\n        b.insert(TEST_CASE.into());\n\n        let changes = a.compose(b);\n\n        use Operation::*;\n        assert_eq!(changes.changes, &[Insert(TEST_CASE.into())]);\n        assert_eq!(changes.len_after, TEST_CASE.chars().count());\n    }\n}\n"
  },
  {
    "path": "helix-core/src/uri.rs",
    "content": "use std::{\n    fmt,\n    path::{Path, PathBuf},\n    sync::Arc,\n};\n\n/// A generic pointer to a file location.\n///\n/// Currently this type only supports paths to local files.\n///\n/// Cloning this type is cheap: the internal representation uses an Arc.\n#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]\n#[non_exhaustive]\npub enum Uri {\n    File(Arc<Path>),\n}\n\nimpl Uri {\n    // This clippy allow mirrors url::Url::from_file_path\n    #[allow(clippy::result_unit_err)]\n    pub fn to_url(&self) -> Result<url::Url, ()> {\n        match self {\n            Uri::File(path) => url::Url::from_file_path(path),\n        }\n    }\n\n    pub fn as_path(&self) -> Option<&Path> {\n        match self {\n            Self::File(path) => Some(path),\n        }\n    }\n}\n\nimpl From<PathBuf> for Uri {\n    fn from(path: PathBuf) -> Self {\n        Self::File(path.into())\n    }\n}\n\nimpl fmt::Display for Uri {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::File(path) => write!(f, \"{}\", path.display()),\n        }\n    }\n}\n\n#[derive(Debug)]\npub struct UrlConversionError {\n    source: url::Url,\n    kind: UrlConversionErrorKind,\n}\n\n#[derive(Debug)]\npub enum UrlConversionErrorKind {\n    UnsupportedScheme,\n    UnableToConvert,\n}\n\nimpl fmt::Display for UrlConversionError {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self.kind {\n            UrlConversionErrorKind::UnsupportedScheme => {\n                write!(\n                    f,\n                    \"unsupported scheme '{}' in URL {}\",\n                    self.source.scheme(),\n                    self.source\n                )\n            }\n            UrlConversionErrorKind::UnableToConvert => {\n                write!(f, \"unable to convert URL to file path: {}\", self.source)\n            }\n        }\n    }\n}\n\nimpl std::error::Error for UrlConversionError {}\n\nfn convert_url_to_uri(url: &url::Url) -> Result<Uri, UrlConversionErrorKind> {\n    if url.scheme() == \"file\" {\n        url.to_file_path()\n            .map(|path| Uri::File(helix_stdx::path::normalize(path).into()))\n            .map_err(|_| UrlConversionErrorKind::UnableToConvert)\n    } else {\n        Err(UrlConversionErrorKind::UnsupportedScheme)\n    }\n}\n\nimpl TryFrom<url::Url> for Uri {\n    type Error = UrlConversionError;\n\n    fn try_from(url: url::Url) -> Result<Self, Self::Error> {\n        convert_url_to_uri(&url).map_err(|kind| Self::Error { source: url, kind })\n    }\n}\n\nimpl TryFrom<&url::Url> for Uri {\n    type Error = UrlConversionError;\n\n    fn try_from(url: &url::Url) -> Result<Self, Self::Error> {\n        convert_url_to_uri(url).map_err(|kind| Self::Error {\n            source: url.clone(),\n            kind,\n        })\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use url::Url;\n\n    #[test]\n    fn unknown_scheme() {\n        let url = Url::parse(\"csharp:/metadata/foo/bar/Baz.cs\").unwrap();\n        assert!(matches!(\n            Uri::try_from(url),\n            Err(UrlConversionError {\n                kind: UrlConversionErrorKind::UnsupportedScheme,\n                ..\n            })\n        ));\n    }\n}\n"
  },
  {
    "path": "helix-core/src/wrap.rs",
    "content": "use smartstring::{LazyCompact, SmartString};\nuse textwrap::{Options, WordSplitter::NoHyphenation};\n\n/// Given a slice of text, return the text re-wrapped to fit it\n/// within the given width.\npub fn reflow_hard_wrap(text: &str, text_width: usize) -> SmartString<LazyCompact> {\n    let options = Options::new(text_width)\n        .word_splitter(NoHyphenation)\n        .word_separator(textwrap::WordSeparator::AsciiSpace);\n    textwrap::refill(text, options).into()\n}\n"
  },
  {
    "path": "helix-core/tests/data/indent/cpp.cpp",
    "content": "std::vector<std::string>\nfn_with_many_parameters(int parm1, long parm2, float parm3, double parm4,\n                        char* parm5, bool parm6);\n\nstd::vector<std::string>\nfn_with_many_parameters(int parm1, long parm2, float parm3, double parm4,\n                        char* parm5, bool parm6) {\n  auto lambda = []() {\n    return 0;\n  };\n  auto lambda_with_a_really_long_name_that_uses_a_whole_line\n    = [](int some_more_aligned_parameters,\n         std::string parm2) {\n      do_smth();\n    };\n  if (brace_on_same_line) {\n    do_smth();\n  } else if (brace_on_next_line)\n  {\n    do_smth();\n  } else if (another_condition) {\n    do_smth();\n  }\n  else {\n    do_smth();\n  }\n  if (inline_if_statement)\n    do_smth();\n  if (another_inline_if_statement)\n    return [](int parm1, char* parm2) {\n      this_is_a_really_pointless_lambda();\n    };\n\n  switch (var) {\n  case true:\n    return -1;\n  case false:\n    return 42;\n  }\n}\n\nclass MyClass : public MyBaseClass {\npublic:\n  MyClass();\n  void public_fn();\nprivate:\n  super_secret_private_fn();\n}\n"
  },
  {
    "path": "helix-core/tests/data/indent/languages.toml",
    "content": "# This languages.toml should contain definitions for all languages for which we have indent tests\n[[language]]\nname = \"rust\"\nscope = \"source.rust\"\ninjection-regex = \"rust\"\nfile-types = [\"rs\"]\ncomment-token = \"//\"\nroots = [\"Cargo.toml\", \"Cargo.lock\"]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"rust\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-rust\", rev = \"0431a2c60828731f27491ee9fdefe25e250ce9c9\" }\n\n[[language]]\nname = \"cpp\"\nscope = \"source.cpp\"\ninjection-regex = \"cpp\"\nfile-types = [\"cc\", \"hh\", \"c++\", \"cpp\", \"hpp\", \"h\", \"ipp\", \"tpp\", \"cxx\", \"hxx\", \"ixx\", \"txx\", \"ino\", \"C\", \"H\"]\nroots = []\ncomment-token = \"//\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"cpp\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-cpp\", rev = \"2d2c4aee8672af4c7c8edff68e7dd4c07e88d2b1\" }\n"
  },
  {
    "path": "helix-core/tests/data/indent/rust.rs",
    "content": "use std::{\n    io::{self, stdout, Stdout, Write},\n    path::PathBuf,\n    sync::Arc,\n    time::Duration,\n};\nmod test {\n    fn hello_world() {\n        1 + 1;\n\n        let does_indentation_work = 1;\n\n        let mut really_long_variable_name_using_up_the_line =\n            really_long_fn_that_should_definitely_go_on_the_next_line();\n        really_long_variable_name_using_up_the_line =\n            really_long_fn_that_should_definitely_go_on_the_next_line();\n        really_long_variable_name_using_up_the_line |=\n            really_long_fn_that_should_definitely_go_on_the_next_line();\n\n        let (\n            a_long_variable_name_in_this_tuple,\n            b_long_variable_name_in_this_tuple,\n            c_long_variable_name_in_this_tuple,\n            d_long_variable_name_in_this_tuple,\n            e_long_variable_name_in_this_tuple,\n        ): (usize, usize, usize, usize, usize) =\n            if really_long_fn_that_should_definitely_go_on_the_next_line() {\n                (\n                    03294239434,\n                    1213412342314,\n                    21231234134,\n                    834534234549898789,\n                    9879234234543853457,\n                )\n            } else {\n                (0, 1, 2, 3, 4)\n            };\n\n        let test_function = function_with_param(this_param,\n            that_param\n        );\n\n        let test_function = function_with_param(\n            this_param,\n            that_param\n        );\n\n        let test_function = function_with_proper_indent(param1,\n            param2,\n        );\n\n        let selection = Selection::new(\n            changes\n                .clone()\n                .map(|(start, end, text): (usize, usize, Option<Tendril>)| {\n                    let len = text.map(|text| text.len()).unwrap() - 1; // minus newline\n                    let pos = start + len;\n                    Range::new(pos, pos)\n                })\n                .collect(),\n            0,\n        );\n\n        return;\n    }\n}\n\nimpl<A, D> MyTrait<A, D> for YourType\nwhere\n    A: TraitB + TraitC,\n    D: TraitE + TraitF,\n{\n\n}\n#[test]\n//\nmatch test {\n    Some(a) => 1,\n    None => {\n        unimplemented!()\n    }\n}\nstd::panic::set_hook(Box::new(move |info| {\n    hook(info);\n}));\n\n{ { {\n    1\n}}}\n\npub fn change<I>(document: &Document, changes: I) -> Self\nwhere\n    I: IntoIterator<Item = Change> + ExactSizeIterator,\n{\n    [\n        1,\n        2,\n        3,\n    ];\n    (\n        1,\n        2\n    );\n    true\n}\n"
  },
  {
    "path": "helix-core/tests/indent.rs",
    "content": "use helix_core::{\n    indent::{indent_level_for_line, treesitter_indent_for_pos, IndentStyle},\n    syntax::{config::Configuration, Loader},\n    Syntax,\n};\nuse helix_stdx::rope::RopeSliceExt;\nuse ropey::Rope;\nuse std::{ops::Range, path::PathBuf, process::Command};\n\n#[test]\nfn test_treesitter_indent_rust() {\n    standard_treesitter_test(\"rust.rs\", \"source.rust\");\n}\n\n#[test]\nfn test_treesitter_indent_cpp() {\n    standard_treesitter_test(\"cpp.cpp\", \"source.cpp\");\n}\n\n#[test]\nfn test_treesitter_indent_rust_helix() {\n    // We pin a specific git revision to prevent unrelated changes from causing the indent tests to fail.\n    // Ideally, someone updates this once in a while and fixes any errors that occur.\n    let rev = \"af382768cdaf89ff547dbd8f644a1bddd90e7c8f\";\n    let files = Command::new(\"git\")\n        .args([\n            \"ls-tree\",\n            \"-r\",\n            \"--name-only\",\n            \"--full-tree\",\n            rev,\n            \"helix-term/src\",\n        ])\n        .output()\n        .unwrap();\n    let files = String::from_utf8(files.stdout).unwrap();\n\n    let ignored_files = [\n        // Contains many macros that tree-sitter does not parse in a meaningful way and is otherwise not very interesting\n        \"helix-term/src/health.rs\",\n    ];\n\n    for file in files.split_whitespace() {\n        if ignored_files.contains(&file) {\n            continue;\n        }\n        #[allow(clippy::single_range_in_vec_init)]\n        let ignored_lines: Vec<Range<usize>> = match file {\n            \"helix-term/src/application.rs\" => vec![\n                // We can't handle complicated indent rules inside macros (`json!` in this case) since\n                // the tree-sitter grammar only parses them as `token_tree` and `identifier` nodes.\n                1045..1051,\n            ],\n            \"helix-term/src/commands.rs\" => vec![\n                // This is broken because of the current handling of `call_expression`\n                // (i.e. having an indent query for it but outdenting again in specific cases).\n                // The indent query is needed to correctly handle multi-line arguments in function calls\n                // inside indented `field_expression` nodes (which occurs fairly often).\n                //\n                // Once we have the `@indent.always` capture type, it might be possible to just have an indent\n                // capture for the `arguments` field of a call expression. That could enable us to correctly\n                // handle this.\n                2226..2230,\n            ],\n            \"helix-term/src/commands/dap.rs\" => vec![\n                // Complex `format!` macro\n                46..52,\n            ],\n            \"helix-term/src/commands/lsp.rs\" => vec![\n                // Macro\n                624..627,\n                // Return type declaration of a closure. `cargo fmt` adds an additional space here,\n                // which we cannot (yet) model with our indent queries.\n                878..879,\n                // Same as in `helix-term/src/commands.rs`\n                1335..1343,\n            ],\n            \"helix-term/src/config.rs\" => vec![\n                // Multiline string\n                146..152,\n            ],\n            \"helix-term/src/keymap.rs\" => vec![\n                // Complex macro (see above)\n                456..470,\n                // Multiline string without indent\n                563..567,\n            ],\n            \"helix-term/src/main.rs\" => vec![\n                // Multiline string\n                44..70,\n            ],\n            \"helix-term/src/ui/completion.rs\" => vec![\n                // Macro\n                218..232,\n            ],\n            \"helix-term/src/ui/editor.rs\" => vec![\n                // The chained function calls here are not indented, probably because of the comment\n                // in between. Since `cargo fmt` doesn't even attempt to format it, there's probably\n                // no point in trying to indent this correctly.\n                342..350,\n            ],\n            \"helix-term/src/ui/lsp.rs\" => vec![\n                // Macro\n                56..61,\n            ],\n            \"helix-term/src/ui/statusline.rs\" => vec![\n                // Same as in `helix-term/src/commands.rs`\n                436..442,\n                450..456,\n            ],\n            _ => Vec::new(),\n        };\n\n        let git_object = rev.to_string() + \":\" + file;\n        let content = Command::new(\"git\")\n            .args([\"cat-file\", \"blob\", &git_object])\n            .output()\n            .unwrap();\n        let doc = Rope::from_reader(&mut content.stdout.as_slice()).unwrap();\n        test_treesitter_indent(file, doc, \"source.rust\", ignored_lines);\n    }\n}\n\n#[test]\nfn test_indent_level_for_line_with_spaces() {\n    let tab_width: usize = 4;\n    let indent_width: usize = 4;\n\n    let line = ropey::Rope::from_str(\"        Indented with 8 spaces\");\n\n    let indent_level = indent_level_for_line(line.slice(0..), tab_width, indent_width);\n    assert_eq!(indent_level, 2)\n}\n\n#[test]\nfn test_indent_level_for_line_with_tabs() {\n    let tab_width: usize = 4;\n    let indent_width: usize = 4;\n\n    let line = ropey::Rope::from_str(\"\\t\\tIndented with 2 tabs\");\n\n    let indent_level = indent_level_for_line(line.slice(0..), tab_width, indent_width);\n    assert_eq!(indent_level, 2)\n}\n\n#[test]\nfn test_indent_level_for_line_with_spaces_and_tabs() {\n    let tab_width: usize = 4;\n    let indent_width: usize = 4;\n\n    let line = ropey::Rope::from_str(\"   \\t \\tIndented with mix of spaces and tabs\");\n\n    let indent_level = indent_level_for_line(line.slice(0..), tab_width, indent_width);\n    assert_eq!(indent_level, 2)\n}\n\nfn indent_tests_dir() -> PathBuf {\n    let mut test_dir = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"));\n    test_dir.push(\"tests/data/indent\");\n    test_dir\n}\n\nfn indent_test_path(name: &str) -> PathBuf {\n    let mut path = indent_tests_dir();\n    path.push(name);\n    path\n}\n\nfn indent_tests_config() -> Configuration {\n    let mut config_path = indent_tests_dir();\n    config_path.push(\"languages.toml\");\n    let config = std::fs::read_to_string(config_path).unwrap();\n    toml::from_str(&config).unwrap()\n}\n\nfn standard_treesitter_test(file_name: &str, lang_scope: &str) {\n    let test_path = indent_test_path(file_name);\n    let test_file = std::fs::File::open(test_path).unwrap();\n    let doc = ropey::Rope::from_reader(test_file).unwrap();\n    test_treesitter_indent(file_name, doc, lang_scope, Vec::new())\n}\n\n/// Test that all the lines in the given file are indented as expected.\n/// ignored_lines is a list of (1-indexed) line ranges that are excluded from this test.\nfn test_treesitter_indent(\n    test_name: &str,\n    doc: Rope,\n    lang_scope: &str,\n    ignored_lines: Vec<std::ops::Range<usize>>,\n) {\n    let loader = Loader::new(indent_tests_config()).unwrap();\n\n    // set runtime path so we can find the queries\n    let mut runtime = std::path::PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"));\n    runtime.push(\"../runtime\");\n    std::env::set_var(\"HELIX_RUNTIME\", runtime.to_str().unwrap());\n\n    let language = loader.language_for_scope(lang_scope).unwrap();\n    let language_config = loader.language(language).config();\n    let indent_style = IndentStyle::from_str(&language_config.indent.as_ref().unwrap().unit);\n    let text = doc.slice(..);\n    let syntax = Syntax::new(text, language, &loader).unwrap();\n    let indent_query = loader.indent_query(language).unwrap();\n\n    for i in 0..doc.len_lines() {\n        let line = text.line(i);\n        if ignored_lines.iter().any(|range| range.contains(&(i + 1))) {\n            continue;\n        }\n        if let Some(pos) = line.first_non_whitespace_char() {\n            let tab_width: usize = 4;\n            let suggested_indent = treesitter_indent_for_pos(\n                indent_query,\n                &syntax,\n                tab_width,\n                indent_style.indent_width(tab_width),\n                text,\n                i,\n                text.line_to_char(i) + pos,\n                false,\n            )\n            .unwrap()\n            .to_string(&indent_style, tab_width);\n            assert!(\n                line.get_slice(..pos).is_some_and(|s| s == suggested_indent),\n                \"Wrong indentation for file {:?} on line {}:\\n\\\"{}\\\" (original line)\\n\\\"{}\\\" (suggested indentation)\\n\",\n                test_name,\n                i+1,\n                line.slice(..line.len_chars()-1),\n                suggested_indent,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "helix-dap/Cargo.toml",
    "content": "[package]\nname = \"helix-dap\"\ndescription = \"DAP client implementation for Helix project\"\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\nhelix-stdx = { path = \"../helix-stdx\" }\nhelix-core = { path = \"../helix-core\" }\nhelix-dap-types = { path = \"../helix-dap-types\" }\n\nanyhow = \"1.0\"\nlog = \"0.4\"\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0\"\ntokio = { version = \"1\", features = [\"rt\", \"rt-multi-thread\", \"io-util\", \"io-std\", \"time\", \"process\", \"macros\", \"fs\", \"parking_lot\", \"net\", \"sync\"] }\nthiserror.workspace = true\nslotmap.workspace = true\nfutures-executor.workspace = true\nfutures-util.workspace = true\ntokio-stream.workspace = true\nsonic-rs.workspace = true\n\n[dev-dependencies]\nfern = \"0.7\"\n"
  },
  {
    "path": "helix-dap/src/client.rs",
    "content": "use crate::{\n    registry::DebugAdapterId,\n    requests::{DisconnectArguments, TerminateArguments},\n    transport::{Payload, Request, Response, Transport},\n    Error, Result,\n};\nuse helix_core::syntax::config::{DebugAdapterConfig, DebuggerQuirks};\nuse helix_dap_types::*;\n\nuse serde_json::Value;\n\nuse anyhow::anyhow;\nuse std::{\n    collections::HashMap,\n    future::Future,\n    net::{IpAddr, Ipv4Addr, SocketAddr},\n    path::PathBuf,\n    process::Stdio,\n    sync::atomic::{AtomicU64, Ordering},\n};\nuse tokio::{\n    io::{AsyncBufRead, AsyncWrite, BufReader, BufWriter},\n    net::TcpStream,\n    process::{Child, Command},\n    sync::mpsc::{channel, unbounded_channel, UnboundedReceiver, UnboundedSender},\n    time,\n};\n\n#[derive(Debug)]\npub struct Client {\n    id: DebugAdapterId,\n    _process: Option<Child>,\n    server_tx: UnboundedSender<Payload>,\n    request_counter: AtomicU64,\n    connection_type: Option<ConnectionType>,\n    starting_request_args: Option<Value>,\n    /// The socket address of the debugger, if using TCP transport.\n    pub socket: Option<SocketAddr>,\n    pub caps: Option<DebuggerCapabilities>,\n    // thread_id -> frames\n    pub stack_frames: HashMap<ThreadId, Vec<StackFrame>>,\n    pub thread_states: ThreadStates,\n    pub thread_id: Option<ThreadId>,\n    /// Currently active frame for the current thread.\n    pub active_frame: Option<usize>,\n    pub quirks: DebuggerQuirks,\n    /// The config which was used to start this debugger.\n    pub config: Option<DebugAdapterConfig>,\n}\n\nimpl Client {\n    // Spawn a process and communicate with it by either TCP or stdio\n    // The returned stream includes the Client ID so consumers can differentiate between multiple clients\n    pub async fn process(\n        transport: &str,\n        command: &str,\n        args: Vec<&str>,\n        port_arg: Option<&str>,\n        id: DebugAdapterId,\n    ) -> Result<(Self, UnboundedReceiver<(DebugAdapterId, Payload)>)> {\n        if command.is_empty() {\n            return Result::Err(Error::Other(anyhow!(\"Command not provided\")));\n        }\n        match (transport, port_arg) {\n            (\"tcp\", Some(port_arg)) => Self::tcp_process(command, args, port_arg, id).await,\n            (\"stdio\", _) => Self::stdio(command, args, id),\n            _ => Result::Err(Error::Other(anyhow!(\"Incorrect transport {}\", transport))),\n        }\n    }\n\n    pub fn streams(\n        rx: Box<dyn AsyncBufRead + Unpin + Send>,\n        tx: Box<dyn AsyncWrite + Unpin + Send>,\n        err: Option<Box<dyn AsyncBufRead + Unpin + Send>>,\n        id: DebugAdapterId,\n        process: Option<Child>,\n    ) -> Result<(Self, UnboundedReceiver<(DebugAdapterId, Payload)>)> {\n        let (server_rx, server_tx) = Transport::start(rx, tx, err, id);\n        let (client_tx, client_rx) = unbounded_channel();\n\n        let client = Self {\n            id,\n            _process: process,\n            server_tx,\n            request_counter: AtomicU64::new(0),\n            caps: None,\n            connection_type: None,\n            starting_request_args: None,\n            socket: None,\n            stack_frames: HashMap::new(),\n            thread_states: HashMap::new(),\n            thread_id: None,\n            active_frame: None,\n            quirks: DebuggerQuirks::default(),\n            config: None,\n        };\n\n        tokio::spawn(Self::recv(id, server_rx, client_tx));\n\n        Ok((client, client_rx))\n    }\n\n    pub async fn tcp(\n        addr: std::net::SocketAddr,\n        id: DebugAdapterId,\n    ) -> Result<(Self, UnboundedReceiver<(DebugAdapterId, Payload)>)> {\n        let stream = TcpStream::connect(addr).await?;\n        let (rx, tx) = stream.into_split();\n        Self::streams(Box::new(BufReader::new(rx)), Box::new(tx), None, id, None)\n    }\n\n    pub fn stdio(\n        cmd: &str,\n        args: Vec<&str>,\n        id: DebugAdapterId,\n    ) -> Result<(Self, UnboundedReceiver<(DebugAdapterId, Payload)>)> {\n        // Resolve path to the binary\n        let cmd = helix_stdx::env::which(cmd)?;\n\n        let process = Command::new(cmd)\n            .args(args)\n            .stdin(Stdio::piped())\n            .stdout(Stdio::piped())\n            .stderr(Stdio::piped())\n            // make sure the process is reaped on drop\n            .kill_on_drop(true)\n            .spawn();\n\n        let mut process = process?;\n\n        // TODO: do we need bufreader/writer here? or do we use async wrappers on unblock?\n        let writer = BufWriter::new(process.stdin.take().expect(\"Failed to open stdin\"));\n        let reader = BufReader::new(process.stdout.take().expect(\"Failed to open stdout\"));\n        let stderr = BufReader::new(process.stderr.take().expect(\"Failed to open stderr\"));\n\n        Self::streams(\n            Box::new(reader),\n            Box::new(writer),\n            Some(Box::new(stderr)),\n            id,\n            Some(process),\n        )\n    }\n\n    async fn get_port() -> Option<u16> {\n        Some(\n            tokio::net::TcpListener::bind(SocketAddr::new(\n                IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),\n                0,\n            ))\n            .await\n            .ok()?\n            .local_addr()\n            .ok()?\n            .port(),\n        )\n    }\n\n    pub fn starting_request_args(&self) -> Option<&Value> {\n        self.starting_request_args.as_ref()\n    }\n\n    pub async fn tcp_process(\n        cmd: &str,\n        args: Vec<&str>,\n        port_format: &str,\n        id: DebugAdapterId,\n    ) -> Result<(Self, UnboundedReceiver<(DebugAdapterId, Payload)>)> {\n        let port = Self::get_port().await.unwrap();\n\n        let process = Command::new(cmd)\n            .args(args)\n            .args(port_format.replace(\"{}\", &port.to_string()).split(' '))\n            // silence messages\n            .stdin(Stdio::null())\n            .stdout(Stdio::null())\n            .stderr(Stdio::null())\n            // Do not kill debug adapter when leaving, it should exit automatically\n            .spawn()?;\n\n        // Wait for adapter to become ready for connection\n        time::sleep(time::Duration::from_millis(500)).await;\n        let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), port);\n        let stream = TcpStream::connect(socket).await?;\n\n        let (rx, tx) = stream.into_split();\n        let mut result = Self::streams(\n            Box::new(BufReader::new(rx)),\n            Box::new(tx),\n            None,\n            id,\n            Some(process),\n        );\n\n        // Set the socket address for the client\n        if let Ok((client, _)) = &mut result {\n            client.socket = Some(socket);\n        }\n\n        result\n    }\n\n    async fn recv(\n        id: DebugAdapterId,\n        mut server_rx: UnboundedReceiver<Payload>,\n        client_tx: UnboundedSender<(DebugAdapterId, Payload)>,\n    ) {\n        while let Some(msg) = server_rx.recv().await {\n            match msg {\n                Payload::Event(ev) => {\n                    client_tx\n                        .send((id, Payload::Event(ev)))\n                        .expect(\"Failed to send\");\n                }\n                Payload::Response(_) => unreachable!(),\n                Payload::Request(req) => {\n                    client_tx\n                        .send((id, Payload::Request(req)))\n                        .expect(\"Failed to send\");\n                }\n            }\n        }\n    }\n\n    pub fn id(&self) -> DebugAdapterId {\n        self.id\n    }\n\n    pub fn connection_type(&self) -> Option<ConnectionType> {\n        self.connection_type\n    }\n\n    fn next_request_id(&self) -> u64 {\n        // > The `seq` for the first message sent by a client or debug adapter\n        // > is 1, and for each subsequent message is 1 greater than the\n        // > previous message sent by that actor\n        // <https://microsoft.github.io/debug-adapter-protocol/specification#Base_Protocol_ProtocolMessage>\n        self.request_counter.fetch_add(1, Ordering::Relaxed) + 1\n    }\n\n    // Internal, called by specific DAP commands when resuming\n    pub fn resume_application(&mut self) {\n        if let Some(thread_id) = self.thread_id {\n            self.thread_states.insert(thread_id, \"running\".to_string());\n            self.stack_frames.remove(&thread_id);\n        }\n        self.active_frame = None;\n        self.thread_id = None;\n    }\n\n    /// Execute a RPC request on the debugger.\n    pub fn call<R: helix_dap_types::Request>(\n        &self,\n        arguments: R::Arguments,\n    ) -> impl Future<Output = Result<Value>>\n    where\n        R::Arguments: serde::Serialize,\n    {\n        let server_tx = self.server_tx.clone();\n        let id = self.next_request_id();\n\n        async move {\n            use std::time::Duration;\n            use tokio::time::timeout;\n\n            let arguments = Some(serde_json::to_value(arguments)?);\n\n            let (callback_tx, mut callback_rx) = channel(1);\n\n            let req = Request {\n                back_ch: Some(callback_tx),\n                seq: id,\n                command: R::COMMAND.to_string(),\n                arguments,\n            };\n\n            server_tx\n                .send(Payload::Request(req))\n                .map_err(|e| Error::Other(e.into()))?;\n\n            // TODO: specifiable timeout, delay other calls until initialize success\n            let response = timeout(Duration::from_secs(20), callback_rx.recv())\n                .await\n                .map_err(|_| Error::Timeout(id))? // return Timeout\n                .ok_or(Error::StreamClosed)??;\n\n            if !response.success {\n                let message = response\n                    .message\n                    .clone()\n                    .unwrap_or_else(|| \"DAP request failed\".to_string());\n                return Err(Error::Other(anyhow!(message)));\n            }\n\n            Ok(response.body.unwrap_or_default())\n        }\n    }\n\n    pub async fn request<R: helix_dap_types::Request>(\n        &self,\n        params: R::Arguments,\n    ) -> Result<R::Result>\n    where\n        R::Arguments: serde::Serialize,\n    {\n        // a future that resolves into the response\n        let json = self.call::<R>(params).await?;\n        let response = serde_json::from_value(json)?;\n        Ok(response)\n    }\n\n    pub fn reply(\n        &self,\n        request_seq: u64,\n        command: &str,\n        result: core::result::Result<Value, Error>,\n    ) -> impl Future<Output = Result<()>> {\n        let server_tx = self.server_tx.clone();\n        let command = command.to_string();\n\n        async move {\n            let response = match result {\n                Ok(result) => Response {\n                    request_seq,\n                    command,\n                    success: true,\n                    message: None,\n                    body: Some(result),\n                },\n                Err(error) => Response {\n                    request_seq,\n                    command,\n                    success: false,\n                    message: Some(error.to_string()),\n                    body: None,\n                },\n            };\n\n            server_tx\n                .send(Payload::Response(response))\n                .map_err(|e| Error::Other(e.into()))?;\n\n            Ok(())\n        }\n    }\n\n    pub fn capabilities(&self) -> &DebuggerCapabilities {\n        self.caps.as_ref().expect(\"debugger not yet initialized!\")\n    }\n\n    pub async fn initialize(&mut self, adapter_id: String) -> Result<()> {\n        let args = requests::InitializeArguments {\n            client_id: Some(\"hx\".to_owned()),\n            client_name: Some(\"helix\".to_owned()),\n            adapter_id,\n            locale: Some(\"en-us\".to_owned()),\n            lines_start_at_one: Some(true),\n            columns_start_at_one: Some(true),\n            path_format: Some(\"path\".to_owned()),\n            supports_variable_type: Some(true),\n            supports_variable_paging: Some(false),\n            supports_run_in_terminal_request: Some(true),\n            supports_memory_references: Some(false),\n            supports_progress_reporting: Some(false),\n            supports_invalidated_event: Some(false),\n        };\n\n        let response = self.request::<requests::Initialize>(args).await?;\n        self.caps = Some(response);\n\n        Ok(())\n    }\n\n    pub fn disconnect(\n        &mut self,\n        args: Option<DisconnectArguments>,\n    ) -> impl Future<Output = Result<Value>> {\n        self.connection_type = None;\n        self.call::<requests::Disconnect>(args)\n    }\n\n    pub fn terminate(\n        &mut self,\n        args: Option<TerminateArguments>,\n    ) -> impl Future<Output = Result<Value>> {\n        self.connection_type = None;\n        self.call::<requests::Terminate>(args)\n    }\n\n    pub fn launch(&mut self, args: serde_json::Value) -> impl Future<Output = Result<Value>> {\n        self.connection_type = Some(ConnectionType::Launch);\n        self.starting_request_args = Some(args.clone());\n        self.call::<requests::Launch>(args)\n    }\n\n    pub fn attach(&mut self, args: serde_json::Value) -> impl Future<Output = Result<Value>> {\n        self.connection_type = Some(ConnectionType::Attach);\n        self.starting_request_args = Some(args.clone());\n        self.call::<requests::Attach>(args)\n    }\n\n    pub fn restart(&self) -> impl Future<Output = Result<Value>> {\n        let args = if let Some(args) = &self.starting_request_args {\n            args.clone()\n        } else {\n            Value::Null\n        };\n        self.call::<requests::Restart>(args)\n    }\n\n    pub async fn set_breakpoints(\n        &self,\n        file: PathBuf,\n        breakpoints: Vec<SourceBreakpoint>,\n    ) -> Result<Option<Vec<Breakpoint>>> {\n        let args = requests::SetBreakpointsArguments {\n            source: Source {\n                path: Some(file),\n                name: None,\n                source_reference: None,\n                presentation_hint: None,\n                origin: None,\n                sources: None,\n                adapter_data: None,\n                checksums: None,\n            },\n            breakpoints: Some(breakpoints),\n            source_modified: Some(false),\n        };\n\n        let response = self.request::<requests::SetBreakpoints>(args).await?;\n\n        Ok(response.breakpoints)\n    }\n\n    pub async fn configuration_done(&self) -> Result<()> {\n        self.request::<requests::ConfigurationDone>(Some(requests::ConfigurationDoneArguments {}))\n            .await\n    }\n\n    pub fn continue_thread(&self, thread_id: ThreadId) -> impl Future<Output = Result<Value>> {\n        let args = requests::ContinueArguments { thread_id };\n\n        self.call::<requests::Continue>(args)\n    }\n\n    pub async fn stack_trace(\n        &self,\n        thread_id: ThreadId,\n    ) -> Result<(Vec<StackFrame>, Option<usize>)> {\n        let args = requests::StackTraceArguments {\n            thread_id,\n            start_frame: None,\n            levels: None,\n            format: None,\n        };\n\n        let response = self.request::<requests::StackTrace>(args).await?;\n        Ok((response.stack_frames, response.total_frames))\n    }\n\n    pub fn threads(&self) -> impl Future<Output = Result<Value>> {\n        self.call::<requests::Threads>(Some(requests::ThreadsArguments {}))\n    }\n\n    pub async fn scopes(&self, frame_id: usize) -> Result<Vec<Scope>> {\n        let args = requests::ScopesArguments { frame_id };\n\n        let response = self.request::<requests::Scopes>(args).await?;\n        Ok(response.scopes)\n    }\n\n    pub async fn variables(&self, variables_reference: usize) -> Result<Vec<Variable>> {\n        let args = requests::VariablesArguments {\n            variables_reference,\n            filter: None,\n            start: None,\n            count: None,\n            format: None,\n        };\n\n        let response = self.request::<requests::Variables>(args).await?;\n        Ok(response.variables)\n    }\n\n    pub fn step_in(&self, thread_id: ThreadId) -> impl Future<Output = Result<Value>> {\n        let args = requests::StepInArguments {\n            thread_id,\n            target_id: None,\n            granularity: None,\n        };\n\n        self.call::<requests::StepIn>(args)\n    }\n\n    pub fn step_out(&self, thread_id: ThreadId) -> impl Future<Output = Result<Value>> {\n        let args = requests::StepOutArguments {\n            thread_id,\n            granularity: None,\n        };\n\n        self.call::<requests::StepOut>(args)\n    }\n\n    pub fn next(&self, thread_id: ThreadId) -> impl Future<Output = Result<Value>> {\n        let args = requests::NextArguments {\n            thread_id,\n            granularity: None,\n        };\n\n        self.call::<requests::Next>(args)\n    }\n\n    pub fn pause(&self, thread_id: ThreadId) -> impl Future<Output = Result<Value>> {\n        let args = requests::PauseArguments { thread_id };\n\n        self.call::<requests::Pause>(args)\n    }\n\n    pub async fn eval(\n        &self,\n        expression: String,\n        frame_id: Option<usize>,\n    ) -> Result<requests::EvaluateResponse> {\n        let args = requests::EvaluateArguments {\n            expression,\n            frame_id,\n            context: None,\n            format: None,\n        };\n\n        self.request::<requests::Evaluate>(args).await\n    }\n\n    pub fn set_exception_breakpoints(\n        &self,\n        filters: Vec<String>,\n    ) -> impl Future<Output = Result<Value>> {\n        let args = requests::SetExceptionBreakpointsArguments { filters };\n\n        self.call::<requests::SetExceptionBreakpoints>(args)\n    }\n\n    pub fn current_stack_frame(&self) -> Option<&StackFrame> {\n        self.stack_frames\n            .get(&self.thread_id?)?\n            .get(self.active_frame?)\n    }\n}\n"
  },
  {
    "path": "helix-dap/src/lib.rs",
    "content": "mod client;\npub mod registry;\nmod transport;\n\npub use client::Client;\npub use helix_dap_types::*;\npub use transport::{Payload, Response, Transport};\n\nuse serde::de::DeserializeOwned;\n\nuse thiserror::Error;\n#[derive(Error, Debug)]\npub enum Error {\n    #[error(\"failed to parse: {0}\")]\n    Parse(Box<dyn std::error::Error + Send + Sync>),\n    #[error(\"IO Error: {0}\")]\n    IO(#[from] std::io::Error),\n    #[error(\"request {0} timed out\")]\n    Timeout(u64),\n    #[error(\"server closed the stream\")]\n    StreamClosed,\n    #[error(\"Unhandled\")]\n    Unhandled,\n    #[error(transparent)]\n    ExecutableNotFound(#[from] helix_stdx::env::ExecutableNotFoundError),\n    #[error(transparent)]\n    Other(#[from] anyhow::Error),\n}\npub type Result<T> = core::result::Result<T, Error>;\n\nimpl From<serde_json::Error> for Error {\n    fn from(value: serde_json::Error) -> Self {\n        Self::Parse(Box::new(value))\n    }\n}\n\nimpl From<sonic_rs::Error> for Error {\n    fn from(value: sonic_rs::Error) -> Self {\n        Self::Parse(Box::new(value))\n    }\n}\n\n#[derive(Debug)]\npub enum Request {\n    RunInTerminal(<requests::RunInTerminal as helix_dap_types::Request>::Arguments),\n    StartDebugging(<requests::StartDebugging as helix_dap_types::Request>::Arguments),\n}\n\nimpl Request {\n    pub fn parse(command: &str, arguments: Option<serde_json::Value>) -> Result<Self> {\n        use helix_dap_types::Request as _;\n\n        let arguments = arguments.unwrap_or_default();\n        let request = match command {\n            requests::RunInTerminal::COMMAND => Self::RunInTerminal(parse_value(arguments)?),\n            requests::StartDebugging::COMMAND => Self::StartDebugging(parse_value(arguments)?),\n            _ => return Err(Error::Unhandled),\n        };\n\n        Ok(request)\n    }\n}\n\n#[derive(Debug)]\npub enum Event {\n    Initialized(<events::Initialized as events::Event>::Body),\n    Stopped(<events::Stopped as events::Event>::Body),\n    Continued(<events::Continued as events::Event>::Body),\n    Exited(<events::Exited as events::Event>::Body),\n    Terminated(<events::Terminated as events::Event>::Body),\n    Thread(<events::Thread as events::Event>::Body),\n    Output(<events::Output as events::Event>::Body),\n    Breakpoint(<events::Breakpoint as events::Event>::Body),\n    Module(<events::Module as events::Event>::Body),\n    LoadedSource(<events::LoadedSource as events::Event>::Body),\n    Process(<events::Process as events::Event>::Body),\n    Capabilities(<events::Capabilities as events::Event>::Body),\n    // ProgressStart(),\n    // ProgressUpdate(),\n    // ProgressEnd(),\n    // Invalidated(),\n    Memory(<events::Memory as events::Event>::Body),\n}\n\nimpl Event {\n    pub fn parse(event: &str, body: Option<serde_json::Value>) -> Result<Self> {\n        use crate::events::Event as _;\n\n        let body = body.unwrap_or_default();\n        let event = match event {\n            events::Initialized::EVENT => Self::Initialized(parse_value(body)?),\n            events::Stopped::EVENT => Self::Stopped(parse_value(body)?),\n            events::Continued::EVENT => Self::Continued(parse_value(body)?),\n            events::Exited::EVENT => Self::Exited(parse_value(body)?),\n            events::Terminated::EVENT => Self::Terminated(parse_value(body)?),\n            events::Thread::EVENT => Self::Thread(parse_value(body)?),\n            events::Output::EVENT => Self::Output(parse_value(body)?),\n            events::Breakpoint::EVENT => Self::Breakpoint(parse_value(body)?),\n            events::Module::EVENT => Self::Module(parse_value(body)?),\n            events::LoadedSource::EVENT => Self::LoadedSource(parse_value(body)?),\n            events::Process::EVENT => Self::Process(parse_value(body)?),\n            events::Capabilities::EVENT => Self::Capabilities(parse_value(body)?),\n            events::Memory::EVENT => Self::Memory(parse_value(body)?),\n            _ => return Err(Error::Unhandled),\n        };\n\n        Ok(event)\n    }\n}\n\nfn parse_value<T>(value: serde_json::Value) -> Result<T>\nwhere\n    T: DeserializeOwned,\n{\n    serde_json::from_value(value).map_err(|err| err.into())\n}\n"
  },
  {
    "path": "helix-dap/src/registry.rs",
    "content": "use crate::{Client, Payload, Result, StackFrame};\nuse futures_executor::block_on;\nuse futures_util::stream::SelectAll;\nuse helix_core::syntax::config::DebugAdapterConfig;\nuse slotmap::SlotMap;\nuse std::fmt;\nuse tokio_stream::wrappers::UnboundedReceiverStream;\n\n/// The resgistry is a struct that manages and owns multiple debugger clients\n/// This holds the responsibility of managing the lifecycle of each client\n/// plus showing the heirarcihical nature betweeen them\npub struct Registry {\n    inner: SlotMap<DebugAdapterId, Client>,\n    /// The active debugger client\n    ///\n    /// TODO: You can have multiple active debuggers, so the concept of a single active debugger\n    /// may need to be changed\n    current_client_id: Option<DebugAdapterId>,\n    /// A stream of incoming messages from all debuggers\n    pub incoming: SelectAll<UnboundedReceiverStream<(DebugAdapterId, Payload)>>,\n}\n\nimpl Registry {\n    /// Creates a new DebuggerService instance\n    pub fn new() -> Self {\n        Self {\n            inner: SlotMap::with_key(),\n            current_client_id: None,\n            incoming: SelectAll::new(),\n        }\n    }\n\n    pub fn start_client(\n        &mut self,\n        socket: Option<std::net::SocketAddr>,\n        config: &DebugAdapterConfig,\n    ) -> Result<DebugAdapterId> {\n        self.inner.try_insert_with_key(|id| {\n            let result = match socket {\n                Some(socket) => block_on(Client::tcp(socket, id)),\n                None => block_on(Client::process(\n                    &config.transport,\n                    &config.command,\n                    config.args.iter().map(|arg| arg.as_str()).collect(),\n                    config.port_arg.as_deref(),\n                    id,\n                )),\n            };\n\n            let (mut client, receiver) = result?;\n            self.incoming.push(UnboundedReceiverStream::new(receiver));\n\n            client.config = Some(config.clone());\n            block_on(client.initialize(config.name.clone()))?;\n            client.quirks = config.quirks.clone();\n\n            Ok(client)\n        })\n    }\n\n    pub fn remove_client(&mut self, id: DebugAdapterId) {\n        self.inner.remove(id);\n    }\n\n    pub fn get_client(&self, id: DebugAdapterId) -> Option<&Client> {\n        self.inner.get(id)\n    }\n\n    pub fn get_client_mut(&mut self, id: DebugAdapterId) -> Option<&mut Client> {\n        self.inner.get_mut(id)\n    }\n\n    pub fn get_active_client(&self) -> Option<&Client> {\n        self.current_client_id.and_then(|id| self.get_client(id))\n    }\n\n    pub fn get_active_client_mut(&mut self) -> Option<&mut Client> {\n        self.current_client_id\n            .and_then(|id| self.get_client_mut(id))\n    }\n\n    pub fn set_active_client(&mut self, id: DebugAdapterId) {\n        if self.get_client(id).is_some() {\n            self.current_client_id = Some(id);\n        } else {\n            self.current_client_id = None;\n        }\n    }\n\n    pub fn unset_active_client(&mut self) {\n        self.current_client_id = None;\n    }\n\n    pub fn current_stack_frame(&self) -> Option<&StackFrame> {\n        self.get_active_client()\n            .and_then(|debugger| debugger.current_stack_frame())\n    }\n}\n\nimpl Default for Registry {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nslotmap::new_key_type! {\n    pub struct DebugAdapterId;\n}\n\nimpl fmt::Display for DebugAdapterId {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"{:?}\", self.0)\n    }\n}\n"
  },
  {
    "path": "helix-dap/src/transport.rs",
    "content": "use crate::{registry::DebugAdapterId, Error, Result};\nuse anyhow::Context;\nuse log::{error, info, warn};\nuse serde::{Deserialize, Serialize};\nuse serde_json::Value;\nuse std::sync::Arc;\nuse std::{collections::HashMap, fmt::Debug};\nuse tokio::{\n    io::{AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWrite, AsyncWriteExt},\n    sync::{\n        mpsc::{unbounded_channel, Sender, UnboundedReceiver, UnboundedSender},\n        Mutex,\n    },\n};\n\n#[derive(Debug, Clone, Deserialize, Serialize)]\npub struct Request {\n    #[serde(skip)]\n    pub back_ch: Option<Sender<Result<Response>>>,\n    pub seq: u64,\n    pub command: String,\n    pub arguments: Option<Value>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\npub struct Response {\n    // seq is omitted as unused and is not sent by some implementations\n    pub request_seq: u64,\n    pub success: bool,\n    pub command: String,\n    pub message: Option<String>,\n    pub body: Option<Value>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\npub struct Event {\n    pub event: String,\n    pub body: Option<Value>,\n}\n\n#[derive(Debug, Clone, Deserialize, Serialize)]\n#[serde(tag = \"type\", rename_all = \"camelCase\")]\npub enum Payload {\n    // type = \"event\"\n    Event(Event),\n    // type = \"response\"\n    Response(Response),\n    // type = \"request\"\n    Request(Request),\n}\n\n#[derive(Debug)]\npub struct Transport {\n    #[allow(unused)]\n    id: DebugAdapterId,\n    pending_requests: Mutex<HashMap<u64, Sender<Result<Response>>>>,\n}\n\nimpl Transport {\n    pub fn start(\n        server_stdout: Box<dyn AsyncBufRead + Unpin + Send>,\n        server_stdin: Box<dyn AsyncWrite + Unpin + Send>,\n        server_stderr: Option<Box<dyn AsyncBufRead + Unpin + Send>>,\n        id: DebugAdapterId,\n    ) -> (UnboundedReceiver<Payload>, UnboundedSender<Payload>) {\n        let (client_tx, rx) = unbounded_channel();\n        let (tx, client_rx) = unbounded_channel();\n\n        let transport = Self {\n            id,\n            pending_requests: Mutex::new(HashMap::default()),\n        };\n\n        let transport = Arc::new(transport);\n\n        tokio::spawn(Self::recv(id, transport.clone(), server_stdout, client_tx));\n        tokio::spawn(Self::send(transport, server_stdin, client_rx));\n        if let Some(stderr) = server_stderr {\n            tokio::spawn(Self::err(stderr));\n        }\n\n        (rx, tx)\n    }\n\n    async fn recv_server_message(\n        id: DebugAdapterId,\n        reader: &mut Box<dyn AsyncBufRead + Unpin + Send>,\n        buffer: &mut String,\n        content: &mut Vec<u8>,\n    ) -> Result<Payload> {\n        let mut content_length = None;\n        loop {\n            buffer.clear();\n            if reader.read_line(buffer).await? == 0 {\n                return Err(Error::StreamClosed);\n            };\n\n            if buffer == \"\\r\\n\" {\n                // look for an empty CRLF line\n                break;\n            }\n\n            let header = buffer.trim();\n            let parts = header.split_once(\": \");\n\n            match parts {\n                Some((\"Content-Length\", value)) => {\n                    content_length = Some(value.parse().context(\"invalid content length\")?);\n                }\n                Some((_, _)) => {}\n                None => {\n                    // Workaround: Some non-conformant language servers will output logging and other garbage\n                    // into the same stream as JSON-RPC messages. This can also happen from shell scripts that spawn\n                    // the server. Skip such lines and log a warning.\n\n                    // warn!(\"Failed to parse header: {:?}\", header);\n                }\n            }\n        }\n\n        let content_length = content_length.context(\"missing content length\")?;\n        content.resize(content_length, 0);\n        reader.read_exact(content).await?;\n        let msg = std::str::from_utf8(content).context(\"invalid utf8 from server\")?;\n\n        info!(\"[{}] <- DAP {}\", id, msg);\n\n        // NOTE: We avoid using `?` here, since it would return early on error\n        // and skip clearing `content`. By returning the result directly instead,\n        // we ensure `content.clear()` is always called.\n        let output = sonic_rs::from_slice(content).map_err(Into::into);\n\n        content.clear();\n\n        output\n    }\n\n    async fn recv_server_error(\n        err: &mut (impl AsyncBufRead + Unpin + Send),\n        buffer: &mut String,\n    ) -> Result<()> {\n        buffer.truncate(0);\n        if err.read_line(buffer).await? == 0 {\n            return Err(Error::StreamClosed);\n        };\n        error!(\"err <- {}\", buffer);\n\n        Ok(())\n    }\n\n    async fn send_payload_to_server(\n        &self,\n        server_stdin: &mut Box<dyn AsyncWrite + Unpin + Send>,\n        mut payload: Payload,\n    ) -> Result<()> {\n        if let Payload::Request(request) = &mut payload {\n            if let Some(back) = request.back_ch.take() {\n                self.pending_requests.lock().await.insert(request.seq, back);\n            }\n        }\n        let json = serde_json::to_string(&payload)?;\n        self.send_string_to_server(server_stdin, json).await\n    }\n\n    async fn send_string_to_server(\n        &self,\n        server_stdin: &mut Box<dyn AsyncWrite + Unpin + Send>,\n        request: String,\n    ) -> Result<()> {\n        info!(\"[{}] -> DAP {}\", self.id, request);\n\n        // send the headers\n        server_stdin\n            .write_all(format!(\"Content-Length: {}\\r\\n\\r\\n\", request.len()).as_bytes())\n            .await?;\n\n        // send the body\n        server_stdin.write_all(request.as_bytes()).await?;\n\n        server_stdin.flush().await?;\n\n        Ok(())\n    }\n\n    fn process_response(&self, res: Response) -> Result<Response> {\n        if res.success {\n            info!(\n                \"[{}] <- DAP success in response to {}\",\n                self.id, res.request_seq\n            );\n\n            Ok(res)\n        } else {\n            error!(\n                \"[{}] <- DAP error {:?} ({:?}) for command #{} {}\",\n                self.id, res.message, res.body, res.request_seq, res.command\n            );\n\n            Err(Error::Other(anyhow::format_err!(\"{:?}\", res.body)))\n        }\n    }\n\n    async fn process_server_message(\n        &self,\n        client_tx: &UnboundedSender<Payload>,\n        msg: Payload,\n    ) -> Result<()> {\n        match msg {\n            Payload::Response(res) => {\n                let request_seq = res.request_seq;\n                let tx = self.pending_requests.lock().await.remove(&request_seq);\n\n                match tx {\n                    Some(tx) => match tx.send(self.process_response(res)).await {\n                        Ok(_) => (),\n                        Err(_) => error!(\n                            \"Tried sending response into a closed channel (id={:?}), original request likely timed out\",\n                            request_seq\n                        ),\n                    }\n                    None => {\n                        warn!(\"Response to nonexistent request #{}\", res.request_seq);\n                        client_tx.send(Payload::Response(res)).expect(\"Failed to send\");\n                    }\n                }\n\n                Ok(())\n            }\n            Payload::Request(Request {\n                ref command,\n                ref seq,\n                ..\n            }) => {\n                info!(\"[{}] <- DAP request {} #{}\", self.id, command, seq);\n                client_tx.send(msg).expect(\"Failed to send\");\n                Ok(())\n            }\n            Payload::Event(ref event) => {\n                info!(\"[{}] <- DAP event {:?}\", self.id, event);\n                client_tx.send(msg).expect(\"Failed to send\");\n                Ok(())\n            }\n        }\n    }\n\n    async fn recv(\n        id: DebugAdapterId,\n        transport: Arc<Self>,\n        mut server_stdout: Box<dyn AsyncBufRead + Unpin + Send>,\n        client_tx: UnboundedSender<Payload>,\n    ) {\n        let mut recv_buffer = String::new();\n        let mut content_buffer = Vec::new();\n        loop {\n            match Self::recv_server_message(\n                id,\n                &mut server_stdout,\n                &mut recv_buffer,\n                &mut content_buffer,\n            )\n            .await\n            {\n                Ok(msg) => match transport.process_server_message(&client_tx, msg).await {\n                    Ok(_) => (),\n                    Err(err) => {\n                        error!(\" [{id}] err: <- {err:?}\");\n                        break;\n                    }\n                },\n                Err(err) => {\n                    if !matches!(err, Error::StreamClosed) {\n                        error!(\"Exiting after unexpected error: {err:?}\");\n                    }\n\n                    // Close any outstanding requests.\n                    for (id, tx) in transport.pending_requests.lock().await.drain() {\n                        match tx.send(Err(Error::StreamClosed)).await {\n                            Ok(_) => (),\n                            Err(_) => {\n                                error!(\"Could not close request on a closed channel (id={id})\");\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    async fn send_inner(\n        transport: Arc<Self>,\n        mut server_stdin: Box<dyn AsyncWrite + Unpin + Send>,\n        mut client_rx: UnboundedReceiver<Payload>,\n    ) -> Result<()> {\n        while let Some(payload) = client_rx.recv().await {\n            transport\n                .send_payload_to_server(&mut server_stdin, payload)\n                .await?;\n        }\n        Ok(())\n    }\n\n    async fn send(\n        transport: Arc<Self>,\n        server_stdin: Box<dyn AsyncWrite + Unpin + Send>,\n        client_rx: UnboundedReceiver<Payload>,\n    ) {\n        if let Err(err) = Self::send_inner(transport, server_stdin, client_rx).await {\n            error!(\"err: <- {:?}\", err);\n        }\n    }\n\n    async fn err(mut server_stderr: Box<dyn AsyncBufRead + Unpin + Send>) {\n        let mut recv_buffer = String::new();\n        loop {\n            match Self::recv_server_error(&mut server_stderr, &mut recv_buffer).await {\n                Ok(_) => {}\n                Err(err) => {\n                    error!(\"err: <- {:?}\", err);\n                    break;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "helix-dap-types/Cargo.toml",
    "content": "[package]\nname = \"helix-dap-types\"\ndescription = \"Types for interaction with a debug adapaters, using Debug Adapter Protocol\"\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n[dependencies]\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0\"\n"
  },
  {
    "path": "helix-dap-types/src/lib.rs",
    "content": "use serde::{Deserialize, Deserializer, Serialize};\nuse serde_json::Value;\nuse std::collections::HashMap;\nuse std::path::PathBuf;\n\n#[derive(\n    Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize,\n)]\npub struct ThreadId(isize);\n\nimpl std::fmt::Display for ThreadId {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        self.0.fmt(f)\n    }\n}\n\npub type ThreadStates = HashMap<ThreadId, String>;\n\npub trait Request {\n    type Arguments: serde::de::DeserializeOwned + serde::Serialize;\n    type Result: serde::de::DeserializeOwned + serde::Serialize;\n    const COMMAND: &'static str;\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ColumnDescriptor {\n    pub attribute_name: String,\n    pub label: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub format: Option<String>,\n    #[serde(rename = \"type\", skip_serializing_if = \"Option::is_none\")]\n    pub ty: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub width: Option<usize>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ExceptionBreakpointsFilter {\n    pub filter: String,\n    pub label: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub description: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub default: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_condition: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub condition_description: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DebuggerCapabilities {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_configuration_done_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_function_breakpoints: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_conditional_breakpoints: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_hit_conditional_breakpoints: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_evaluate_for_hovers: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_step_back: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_set_variable: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_restart_frame: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_goto_targets_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_step_in_targets_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_completions_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_modules_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_restart_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_exception_options: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_value_formatting_options: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_exception_info_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub support_terminate_debuggee: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub support_suspend_debuggee: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_delayed_stack_trace_loading: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_loaded_sources_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_log_points: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_terminate_threads_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_set_expression: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_terminate_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_data_breakpoints: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_read_memory_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_write_memory_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_disassemble_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_cancel_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_breakpoint_locations_request: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_clipboard_context: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_stepping_granularity: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_instruction_breakpoints: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supports_exception_filter_options: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub exception_breakpoint_filters: Option<Vec<ExceptionBreakpointsFilter>>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub completion_trigger_characters: Option<Vec<String>>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub additional_module_columns: Option<Vec<ColumnDescriptor>>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supported_checksum_algorithms: Option<Vec<String>>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Checksum {\n    pub algorithm: String,\n    pub checksum: String,\n}\n\n#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Source {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub name: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub path: Option<PathBuf>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub source_reference: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub presentation_hint: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub origin: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub sources: Option<Vec<Source>>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub adapter_data: Option<Value>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub checksums: Option<Vec<Checksum>>,\n}\n\n#[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SourceBreakpoint {\n    pub line: usize,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub column: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub condition: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub hit_condition: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub log_message: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Breakpoint {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub id: Option<usize>,\n    pub verified: bool,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub message: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub source: Option<Source>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub line: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub column: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub end_line: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub end_column: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub instruction_reference: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub offset: Option<usize>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct StackFrameFormat {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub parameters: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub parameter_types: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub parameter_names: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub parameter_values: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub line: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub module: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub include_all: Option<bool>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct StackFrame {\n    pub id: usize,\n    pub name: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub source: Option<Source>,\n    pub line: usize,\n    pub column: usize,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub end_line: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub end_column: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub can_restart: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub instruction_pointer_reference: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub module_id: Option<Value>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub presentation_hint: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Thread {\n    pub id: ThreadId,\n    pub name: String,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Scope {\n    pub name: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub presentation_hint: Option<String>,\n    pub variables_reference: usize,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub named_variables: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub indexed_variables: Option<usize>,\n    pub expensive: bool,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub source: Option<Source>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub line: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub column: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub end_line: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub end_column: Option<usize>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ValueFormat {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub hex: Option<bool>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct VariablePresentationHint {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub kind: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub attributes: Option<Vec<String>>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub visibility: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Variable {\n    pub name: String,\n    pub value: String,\n    #[serde(rename = \"type\", skip_serializing_if = \"Option::is_none\")]\n    pub ty: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub presentation_hint: Option<VariablePresentationHint>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub evaluate_name: Option<String>,\n    pub variables_reference: usize,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub named_variables: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub indexed_variables: Option<usize>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub memory_reference: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Module {\n    #[serde(deserialize_with = \"from_number\")]\n    pub id: String,\n    pub name: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub path: Option<PathBuf>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub is_optimized: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub is_user_code: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub version: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub symbol_status: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub symbol_file_path: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub date_time_stamp: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub address_range: Option<String>,\n}\n\nfn from_number<'de, D>(deserializer: D) -> Result<String, D::Error>\nwhere\n    D: Deserializer<'de>,\n{\n    #[derive(Deserialize)]\n    #[serde(untagged)]\n    enum NumberOrString {\n        Number(i64),\n        String(String),\n    }\n\n    match NumberOrString::deserialize(deserializer)? {\n        NumberOrString::Number(n) => Ok(n.to_string()),\n        NumberOrString::String(s) => Ok(s),\n    }\n}\n\npub mod requests {\n    use super::*;\n    #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct InitializeArguments {\n        #[serde(rename = \"clientID\", skip_serializing_if = \"Option::is_none\")]\n        pub client_id: Option<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub client_name: Option<String>,\n        #[serde(rename = \"adapterID\")]\n        pub adapter_id: String,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub locale: Option<String>,\n        #[serde(rename = \"linesStartAt1\", skip_serializing_if = \"Option::is_none\")]\n        pub lines_start_at_one: Option<bool>,\n        #[serde(rename = \"columnsStartAt1\", skip_serializing_if = \"Option::is_none\")]\n        pub columns_start_at_one: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub path_format: Option<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub supports_variable_type: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub supports_variable_paging: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub supports_run_in_terminal_request: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub supports_memory_references: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub supports_progress_reporting: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub supports_invalidated_event: Option<bool>,\n    }\n\n    #[derive(Debug)]\n    pub enum Initialize {}\n\n    impl Request for Initialize {\n        type Arguments = InitializeArguments;\n        type Result = DebuggerCapabilities;\n        const COMMAND: &'static str = \"initialize\";\n    }\n\n    #[derive(Debug)]\n    pub enum Launch {}\n\n    impl Request for Launch {\n        type Arguments = Value;\n        type Result = ();\n        const COMMAND: &'static str = \"launch\";\n    }\n\n    #[derive(Debug)]\n    pub enum Attach {}\n\n    impl Request for Attach {\n        type Arguments = Value;\n        type Result = ();\n        const COMMAND: &'static str = \"attach\";\n    }\n\n    #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct DisconnectArguments {\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub restart: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub terminate_debuggee: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub suspend_debuggee: Option<bool>,\n    }\n\n    #[derive(Debug)]\n    pub enum Restart {}\n\n    impl Request for Restart {\n        type Arguments = Value;\n        type Result = ();\n        const COMMAND: &'static str = \"restart\";\n    }\n\n    #[derive(Debug)]\n    pub enum Disconnect {}\n\n    impl Request for Disconnect {\n        type Arguments = Option<DisconnectArguments>;\n        type Result = ();\n        const COMMAND: &'static str = \"disconnect\";\n    }\n\n    #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct TerminateArguments {\n        pub restart: Option<bool>,\n    }\n\n    #[derive(Debug)]\n    pub enum Terminate {}\n\n    impl Request for Terminate {\n        type Arguments = Option<TerminateArguments>;\n        type Result = ();\n        const COMMAND: &'static str = \"terminate\";\n    }\n\n    #[derive(Debug)]\n    pub enum ConfigurationDone {}\n\n    impl Request for ConfigurationDone {\n        type Arguments = Option<ConfigurationDoneArguments>;\n        type Result = ();\n        const COMMAND: &'static str = \"configurationDone\";\n    }\n\n    #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    pub struct ConfigurationDoneArguments {}\n\n    #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct SetBreakpointsArguments {\n        pub source: Source,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub breakpoints: Option<Vec<SourceBreakpoint>>,\n        // lines is deprecated\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub source_modified: Option<bool>,\n    }\n\n    #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct SetBreakpointsResponse {\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub breakpoints: Option<Vec<Breakpoint>>,\n    }\n\n    #[derive(Debug)]\n    pub enum SetBreakpoints {}\n\n    impl Request for SetBreakpoints {\n        type Arguments = SetBreakpointsArguments;\n        type Result = SetBreakpointsResponse;\n        const COMMAND: &'static str = \"setBreakpoints\";\n    }\n\n    #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct ContinueArguments {\n        pub thread_id: ThreadId,\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct ContinueResponse {\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub all_threads_continued: Option<bool>,\n    }\n\n    #[derive(Debug)]\n    pub enum Continue {}\n\n    impl Request for Continue {\n        type Arguments = ContinueArguments;\n        type Result = ContinueResponse;\n        const COMMAND: &'static str = \"continue\";\n    }\n\n    #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct StackTraceArguments {\n        pub thread_id: ThreadId,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub start_frame: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub levels: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub format: Option<StackFrameFormat>,\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct StackTraceResponse {\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub total_frames: Option<usize>,\n        pub stack_frames: Vec<StackFrame>,\n    }\n\n    #[derive(Debug)]\n    pub enum StackTrace {}\n\n    impl Request for StackTrace {\n        type Arguments = StackTraceArguments;\n        type Result = StackTraceResponse;\n        const COMMAND: &'static str = \"stackTrace\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    pub struct ThreadsArguments {}\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct ThreadsResponse {\n        pub threads: Vec<Thread>,\n    }\n\n    #[derive(Debug)]\n    pub enum Threads {}\n\n    impl Request for Threads {\n        type Arguments = Option<ThreadsArguments>;\n        type Result = ThreadsResponse;\n        const COMMAND: &'static str = \"threads\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct ScopesArguments {\n        pub frame_id: usize,\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct ScopesResponse {\n        pub scopes: Vec<Scope>,\n    }\n\n    #[derive(Debug)]\n    pub enum Scopes {}\n\n    impl Request for Scopes {\n        type Arguments = ScopesArguments;\n        type Result = ScopesResponse;\n        const COMMAND: &'static str = \"scopes\";\n    }\n\n    #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct VariablesArguments {\n        pub variables_reference: usize,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub filter: Option<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub start: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub count: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub format: Option<ValueFormat>,\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct VariablesResponse {\n        pub variables: Vec<Variable>,\n    }\n\n    #[derive(Debug)]\n    pub enum Variables {}\n\n    impl Request for Variables {\n        type Arguments = VariablesArguments;\n        type Result = VariablesResponse;\n        const COMMAND: &'static str = \"variables\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct StepInArguments {\n        pub thread_id: ThreadId,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub target_id: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub granularity: Option<String>,\n    }\n\n    #[derive(Debug)]\n    pub enum StepIn {}\n\n    impl Request for StepIn {\n        type Arguments = StepInArguments;\n        type Result = ();\n        const COMMAND: &'static str = \"stepIn\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct StepOutArguments {\n        pub thread_id: ThreadId,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub granularity: Option<String>,\n    }\n\n    #[derive(Debug)]\n    pub enum StepOut {}\n\n    impl Request for StepOut {\n        type Arguments = StepOutArguments;\n        type Result = ();\n        const COMMAND: &'static str = \"stepOut\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct NextArguments {\n        pub thread_id: ThreadId,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub granularity: Option<String>,\n    }\n\n    #[derive(Debug)]\n    pub enum Next {}\n\n    impl Request for Next {\n        type Arguments = NextArguments;\n        type Result = ();\n        const COMMAND: &'static str = \"next\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct PauseArguments {\n        pub thread_id: ThreadId,\n    }\n\n    #[derive(Debug)]\n    pub enum Pause {}\n\n    impl Request for Pause {\n        type Arguments = PauseArguments;\n        type Result = ();\n        const COMMAND: &'static str = \"pause\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct EvaluateArguments {\n        pub expression: String,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub frame_id: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub context: Option<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub format: Option<ValueFormat>,\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct EvaluateResponse {\n        pub result: String,\n        #[serde(rename = \"type\", skip_serializing_if = \"Option::is_none\")]\n        pub ty: Option<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub presentation_hint: Option<VariablePresentationHint>,\n        pub variables_reference: usize,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub named_variables: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub indexed_variables: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub memory_reference: Option<String>,\n    }\n\n    #[derive(Debug)]\n    pub enum Evaluate {}\n\n    impl Request for Evaluate {\n        type Arguments = EvaluateArguments;\n        type Result = EvaluateResponse;\n        const COMMAND: &'static str = \"evaluate\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct SetExceptionBreakpointsArguments {\n        pub filters: Vec<String>,\n        // pub filterOptions: Option<Vec<ExceptionFilterOptions>>, // needs capability\n        // pub exceptionOptions: Option<Vec<ExceptionOptions>>, // needs capability\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct SetExceptionBreakpointsResponse {\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub breakpoints: Option<Vec<Breakpoint>>,\n    }\n\n    #[derive(Debug)]\n    pub enum SetExceptionBreakpoints {}\n\n    impl Request for SetExceptionBreakpoints {\n        type Arguments = SetExceptionBreakpointsArguments;\n        type Result = SetExceptionBreakpointsResponse;\n        const COMMAND: &'static str = \"setExceptionBreakpoints\";\n    }\n\n    // Reverse Requests\n\n    #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct RunInTerminalResponse {\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub process_id: Option<u32>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub shell_process_id: Option<u32>,\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct RunInTerminalArguments {\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub kind: Option<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub title: Option<String>,\n        pub cwd: String,\n        pub args: Vec<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub env: Option<HashMap<String, Option<String>>>,\n    }\n\n    #[derive(Debug)]\n    pub enum RunInTerminal {}\n\n    impl Request for RunInTerminal {\n        type Arguments = RunInTerminalArguments;\n        type Result = RunInTerminalResponse;\n        const COMMAND: &'static str = \"runInTerminal\";\n    }\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct StartDebuggingArguments {\n        pub request: ConnectionType,\n        pub configuration: Value,\n    }\n\n    #[derive(Debug)]\n    pub enum StartDebugging {}\n\n    impl Request for StartDebugging {\n        type Arguments = StartDebuggingArguments;\n        type Result = ();\n        const COMMAND: &'static str = \"startDebugging\";\n    }\n}\n\n// Events\n\npub mod events {\n    use super::*;\n\n    pub trait Event {\n        type Body: serde::de::DeserializeOwned + serde::Serialize;\n        const EVENT: &'static str;\n    }\n\n    #[derive(Debug)]\n    pub enum Initialized {}\n\n    impl Event for Initialized {\n        type Body = Option<DebuggerCapabilities>;\n        const EVENT: &'static str = \"initialized\";\n    }\n\n    #[derive(Debug)]\n    pub enum Stopped {}\n\n    impl Event for Stopped {\n        type Body = StoppedBody;\n        const EVENT: &'static str = \"stopped\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct StoppedBody {\n        pub reason: String,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub description: Option<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub thread_id: Option<ThreadId>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub preserve_focus_hint: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub text: Option<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub all_threads_stopped: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub hit_breakpoint_ids: Option<Vec<usize>>,\n    }\n\n    #[derive(Debug)]\n    pub enum Continued {}\n\n    impl Event for Continued {\n        type Body = ContinuedBody;\n        const EVENT: &'static str = \"continued\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct ContinuedBody {\n        pub thread_id: ThreadId,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub all_threads_continued: Option<bool>,\n    }\n\n    #[derive(Debug)]\n    pub enum Exited {}\n\n    impl Event for Exited {\n        type Body = ExitedBody;\n        const EVENT: &'static str = \"exited\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct ExitedBody {\n        pub exit_code: usize,\n    }\n\n    #[derive(Debug)]\n    pub enum Terminated {}\n\n    impl Event for Terminated {\n        type Body = Option<TerminatedBody>;\n        const EVENT: &'static str = \"terminated\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct TerminatedBody {\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub restart: Option<Value>,\n    }\n\n    #[derive(Debug)]\n    pub enum Thread {}\n\n    impl Event for Thread {\n        type Body = ThreadBody;\n        const EVENT: &'static str = \"thread\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct ThreadBody {\n        pub reason: String,\n        pub thread_id: ThreadId,\n    }\n\n    #[derive(Debug)]\n    pub enum Output {}\n\n    impl Event for Output {\n        type Body = OutputBody;\n        const EVENT: &'static str = \"output\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct OutputBody {\n        pub output: String,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub category: Option<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub group: Option<String>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub line: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub column: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub variables_reference: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub source: Option<Source>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub data: Option<Value>,\n    }\n\n    #[derive(Debug)]\n    pub enum Breakpoint {}\n\n    impl Event for Breakpoint {\n        type Body = BreakpointBody;\n        const EVENT: &'static str = \"breakpoint\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct BreakpointBody {\n        pub reason: String,\n        pub breakpoint: super::Breakpoint,\n    }\n\n    #[derive(Debug)]\n    pub enum Module {}\n\n    impl Event for Module {\n        type Body = ModuleBody;\n        const EVENT: &'static str = \"module\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct ModuleBody {\n        pub reason: String,\n        pub module: super::Module,\n    }\n\n    #[derive(Debug)]\n    pub enum LoadedSource {}\n\n    impl Event for LoadedSource {\n        type Body = LoadedSourceBody;\n        const EVENT: &'static str = \"loadedSource\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct LoadedSourceBody {\n        pub reason: String,\n        pub source: super::Source,\n    }\n\n    #[derive(Debug)]\n    pub enum Process {}\n\n    impl Event for Process {\n        type Body = ProcessBody;\n        const EVENT: &'static str = \"process\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct ProcessBody {\n        pub name: String,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub system_process_id: Option<usize>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub is_local_process: Option<bool>,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub start_method: Option<String>, // TODO: use enum\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        pub pointer_size: Option<usize>,\n    }\n\n    #[derive(Debug)]\n    pub enum Capabilities {}\n\n    impl Event for Capabilities {\n        type Body = CapabilitiesBody;\n        const EVENT: &'static str = \"capabilities\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct CapabilitiesBody {\n        pub capabilities: super::DebuggerCapabilities,\n    }\n\n    // #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    // #[serde(rename_all = \"camelCase\")]\n    // pub struct InvalidatedBody {\n    // pub areas: Vec<InvalidatedArea>,\n    // pub thread_id: Option<ThreadId>,\n    // pub stack_frame_id: Option<usize>,\n    // }\n\n    #[derive(Debug)]\n    pub enum Memory {}\n\n    impl Event for Memory {\n        type Body = MemoryBody;\n        const EVENT: &'static str = \"memory\";\n    }\n\n    #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n    #[serde(rename_all = \"camelCase\")]\n    pub struct MemoryBody {\n        pub memory_reference: String,\n        pub offset: usize,\n        pub count: usize,\n    }\n}\n\n#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"lowercase\")]\npub enum ConnectionType {\n    Launch,\n    Attach,\n}\n\n#[test]\nfn test_deserialize_module_id_from_number() {\n    let raw = r#\"{\"id\": 0, \"name\": \"Name\"}\"#;\n    let module: Module = serde_json::from_str(raw).expect(\"Error!\");\n    assert_eq!(module.id, \"0\");\n}\n\n#[test]\nfn test_deserialize_module_id_from_string() {\n    let raw = r#\"{\"id\": \"0\", \"name\": \"Name\"}\"#;\n    let module: Module = serde_json::from_str(raw).expect(\"Error!\");\n    assert_eq!(module.id, \"0\");\n}\n"
  },
  {
    "path": "helix-event/Cargo.toml",
    "content": "[package]\nname = \"helix-event\"\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\nfoldhash.workspace = true\nhashbrown = \"0.16\"\ntokio = { version = \"1\", features = [\"rt\", \"rt-multi-thread\", \"time\", \"sync\", \"parking_lot\", \"macros\"] }\n# the event registry is essentially read only but must be an rwlock so we can\n# setup new events on initialization, hardware-lock-elision hugely benefits this case\n# as it essentially makes the lock entirely free as long as there is no writes \nparking_lot = { workspace = true, features = [\"hardware-lock-elision\"] }\nonce_cell = \"1.21\"\n\nanyhow = \"1\"\nlog = \"0.4\"\nfutures-executor = \"0.3.32\"\n\n[features]\nintegration_test = []\n"
  },
  {
    "path": "helix-event/src/cancel.rs",
    "content": "use std::borrow::Borrow;\nuse std::future::Future;\nuse std::sync::atomic::AtomicU64;\nuse std::sync::atomic::Ordering::Relaxed;\nuse std::sync::Arc;\n\nuse tokio::sync::Notify;\n\npub async fn cancelable_future<T>(\n    future: impl Future<Output = T>,\n    cancel: impl Borrow<TaskHandle>,\n) -> Option<T> {\n    tokio::select! {\n        biased;\n        _ = cancel.borrow().canceled() => {\n            None\n        }\n        res = future => {\n            Some(res)\n        }\n    }\n}\n\n#[derive(Default, Debug)]\nstruct Shared {\n    state: AtomicU64,\n    // `Notify` has some features that we don't really need here because it\n    // supports waking single tasks (`notify_one`) and does its own (more\n    // complicated) state tracking, we could reimplement the waiter linked list\n    // with modest effort and reduce memory consumption by one word/8 bytes and\n    // reduce code complexity/number of atomic operations.\n    //\n    // I don't think that's worth the complexity (unsafe code).\n    //\n    // if we only cared about async code then we could also only use a notify\n    // (without the generation count), this would be equivalent (or maybe more\n    // correct if we want to allow cloning the TX) but it would be extremly slow\n    // to frequently check for cancelation from sync code\n    notify: Notify,\n}\n\nimpl Shared {\n    fn generation(&self) -> u32 {\n        self.state.load(Relaxed) as u32\n    }\n\n    fn num_running(&self) -> u32 {\n        (self.state.load(Relaxed) >> 32) as u32\n    }\n\n    /// Increments the generation count and sets `num_running`\n    /// to the provided value, this operation is not with\n    /// regard to the generation counter (doesn't use `fetch_add`)\n    /// so the calling code must ensure it cannot execute concurrently\n    /// to maintain correctness (but not safety)\n    fn inc_generation(&self, num_running: u32) -> (u32, u32) {\n        let state = self.state.load(Relaxed);\n        let generation = state as u32;\n        let prev_running = (state >> 32) as u32;\n        // no need to create a new generation if the refcount is zero (fastpath)\n        if prev_running == 0 && num_running == 0 {\n            return (generation, 0);\n        }\n        let new_generation = generation.saturating_add(1);\n        self.state.store(\n            new_generation as u64 | ((num_running as u64) << 32),\n            Relaxed,\n        );\n        self.notify.notify_waiters();\n        (new_generation, prev_running)\n    }\n\n    fn inc_running(&self, generation: u32) {\n        let mut state = self.state.load(Relaxed);\n        loop {\n            let current_generation = state as u32;\n            if current_generation != generation {\n                break;\n            }\n            let off = 1 << 32;\n            let res = self.state.compare_exchange_weak(\n                state,\n                state.saturating_add(off),\n                Relaxed,\n                Relaxed,\n            );\n            match res {\n                Ok(_) => break,\n                Err(new_state) => state = new_state,\n            }\n        }\n    }\n\n    fn dec_running(&self, generation: u32) {\n        let mut state = self.state.load(Relaxed);\n        loop {\n            let current_generation = state as u32;\n            if current_generation != generation {\n                break;\n            }\n            let num_running = (state >> 32) as u32;\n            // running can't be zero here, that would mean we miscounted somewhere\n            assert_ne!(num_running, 0);\n            let off = 1 << 32;\n            let res = self\n                .state\n                .compare_exchange_weak(state, state - off, Relaxed, Relaxed);\n            match res {\n                Ok(_) => break,\n                Err(new_state) => state = new_state,\n            }\n        }\n    }\n}\n\n// This intentionally doesn't implement `Clone` and requires a mutable reference\n// for cancelation to avoid races (in inc_generation).\n\n/// A task controller allows managing a single subtask enabling the controller\n/// to cancel the subtask and to check whether it is still running.\n///\n/// For efficiency reasons the controller can be reused/restarted,\n/// in that case the previous task is automatically canceled.\n///\n/// If the controller is dropped, the subtasks are automatically canceled.\n#[derive(Default, Debug)]\npub struct TaskController {\n    shared: Arc<Shared>,\n}\n\nimpl TaskController {\n    pub fn new() -> Self {\n        TaskController::default()\n    }\n    /// Cancels the active task (handle).\n    ///\n    /// Returns whether any tasks were still running before the cancelation.\n    pub fn cancel(&mut self) -> bool {\n        self.shared.inc_generation(0).1 != 0\n    }\n\n    /// Checks whether there are any task handles\n    /// that haven't been dropped (or canceled) yet.\n    pub fn is_running(&self) -> bool {\n        self.shared.num_running() != 0\n    }\n\n    /// Starts a new task and cancels the previous task (handles).\n    pub fn restart(&mut self) -> TaskHandle {\n        TaskHandle {\n            generation: self.shared.inc_generation(1).0,\n            shared: self.shared.clone(),\n        }\n    }\n}\n\nimpl Drop for TaskController {\n    fn drop(&mut self) {\n        self.cancel();\n    }\n}\n\n/// A handle that is used to link a task with a task controller.\n///\n/// It can be used to cancel async futures very efficiently but can also be checked for\n/// cancelation very quickly (single atomic read) in blocking code.\n/// The handle can be cheaply cloned (reference counted).\n///\n/// The TaskController can check whether a task is \"running\" by inspecting the\n/// refcount of the (current) tasks handles. Therefore, if that information\n/// is important, ensure that the handle is not dropped until the task fully\n/// completes.\npub struct TaskHandle {\n    shared: Arc<Shared>,\n    generation: u32,\n}\n\nimpl Clone for TaskHandle {\n    fn clone(&self) -> Self {\n        self.shared.inc_running(self.generation);\n        TaskHandle {\n            shared: self.shared.clone(),\n            generation: self.generation,\n        }\n    }\n}\n\nimpl Drop for TaskHandle {\n    fn drop(&mut self) {\n        self.shared.dec_running(self.generation);\n    }\n}\n\nimpl TaskHandle {\n    /// Waits until [`TaskController::cancel`] is called for the corresponding\n    /// [`TaskController`]. Immediately returns if `cancel` was already called since\n    pub async fn canceled(&self) {\n        let notified = self.shared.notify.notified();\n        if !self.is_canceled() {\n            notified.await\n        }\n    }\n\n    pub fn is_canceled(&self) -> bool {\n        self.generation != self.shared.generation()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::future::poll_fn;\n\n    use futures_executor::block_on;\n    use tokio::task::yield_now;\n\n    use crate::{cancelable_future, TaskController};\n\n    #[test]\n    fn immediate_cancel() {\n        let mut controller = TaskController::new();\n        let handle = controller.restart();\n        controller.cancel();\n        assert!(handle.is_canceled());\n        controller.restart();\n        assert!(handle.is_canceled());\n\n        let res = block_on(cancelable_future(\n            poll_fn(|_cx| std::task::Poll::Ready(())),\n            handle,\n        ));\n        assert!(res.is_none());\n    }\n\n    #[test]\n    fn running_count() {\n        let mut controller = TaskController::new();\n        let handle = controller.restart();\n        assert!(controller.is_running());\n        assert!(!handle.is_canceled());\n        drop(handle);\n        assert!(!controller.is_running());\n        assert!(!controller.cancel());\n        let handle = controller.restart();\n        assert!(!handle.is_canceled());\n        assert!(controller.is_running());\n        let handle2 = handle.clone();\n        assert!(!handle.is_canceled());\n        assert!(controller.is_running());\n        drop(handle2);\n        assert!(!handle.is_canceled());\n        assert!(controller.is_running());\n        assert!(controller.cancel());\n        assert!(handle.is_canceled());\n        assert!(!controller.is_running());\n    }\n\n    #[test]\n    fn no_cancel() {\n        let mut controller = TaskController::new();\n        let handle = controller.restart();\n        assert!(!handle.is_canceled());\n\n        let res = block_on(cancelable_future(\n            poll_fn(|_cx| std::task::Poll::Ready(())),\n            handle,\n        ));\n        assert!(res.is_some());\n    }\n\n    #[test]\n    fn delayed_cancel() {\n        let mut controller = TaskController::new();\n        let handle = controller.restart();\n\n        let mut hit = false;\n        let res = block_on(cancelable_future(\n            async {\n                controller.cancel();\n                hit = true;\n                yield_now().await;\n            },\n            handle,\n        ));\n        assert!(res.is_none());\n        assert!(hit);\n    }\n}\n"
  },
  {
    "path": "helix-event/src/debounce.rs",
    "content": "//! Utilities for declaring an async (usually debounced) hook\n\nuse std::time::Duration;\n\nuse futures_executor::block_on;\nuse tokio::sync::mpsc::{self, error::TrySendError, Sender};\nuse tokio::time::Instant;\n\n/// Async hooks provide a convenient framework for implementing (debounced)\n/// async event handlers. Most synchronous event hooks will likely need to\n/// debounce their events, coordinate multiple different hooks and potentially\n/// track some state. `AsyncHooks` facilitate these use cases by running as\n/// a background tokio task that waits for events (usually an enum) to be\n/// sent through a channel.\npub trait AsyncHook: Sync + Send + 'static + Sized {\n    type Event: Sync + Send + 'static;\n    /// Called immediately whenever an event is received, this function can\n    /// consume the event immediately or debounce it. In case of debouncing,\n    /// it can either define a new debounce timeout or continue the current one\n    fn handle_event(&mut self, event: Self::Event, timeout: Option<Instant>) -> Option<Instant>;\n\n    /// Called whenever the debounce timeline is reached\n    fn finish_debounce(&mut self);\n\n    fn spawn(self) -> mpsc::Sender<Self::Event> {\n        // the capacity doesn't matter too much here, unless the cpu is totally overwhelmed\n        // the cap will never be reached since we always immediately drain the channel\n        // so it should only be reached in case of total CPU overload.\n        // However, a bounded channel is much more efficient so it's nice to use here\n        let (tx, rx) = mpsc::channel(128);\n        // only spawn worker if we are inside runtime to avoid having to spawn a runtime for unrelated unit tests\n        if tokio::runtime::Handle::try_current().is_ok() {\n            tokio::spawn(run(self, rx));\n        }\n        tx\n    }\n}\n\nasync fn run<Hook: AsyncHook>(mut hook: Hook, mut rx: mpsc::Receiver<Hook::Event>) {\n    let mut deadline = None;\n    loop {\n        let event = match deadline {\n            Some(deadline_) => {\n                let res = tokio::time::timeout_at(deadline_, rx.recv()).await;\n                match res {\n                    Ok(event) => event,\n                    Err(_) => {\n                        hook.finish_debounce();\n                        deadline = None;\n                        continue;\n                    }\n                }\n            }\n            None => rx.recv().await,\n        };\n        let Some(event) = event else {\n            break;\n        };\n        deadline = hook.handle_event(event, deadline);\n    }\n}\n\npub fn send_blocking<T>(tx: &Sender<T>, data: T) {\n    // block_on has some overhead and in practice the channel should basically\n    // never be full anyway so first try sending without blocking\n    if let Err(TrySendError::Full(data)) = tx.try_send(data) {\n        // set a timeout so that we just drop a message instead of freezing the editor in the worst case\n        let _ = block_on(tx.send_timeout(data, Duration::from_millis(10)));\n    }\n}\n"
  },
  {
    "path": "helix-event/src/hook.rs",
    "content": "//! rust dynamic dispatch is extremely limited so we have to build our\n//! own vtable implementation. Otherwise implementing the event system would not be possible.\n//! A nice bonus of this approach is that we can optimize the vtable a bit more. Normally\n//! a dyn Trait fat pointer contains two pointers: A pointer to the data itself and a\n//! pointer to a global (static) vtable entry which itself contains multiple other pointers\n//! (the various functions of the trait, drop, size and align). That makes dynamic\n//! dispatch pretty slow (double pointer indirections). However, we only have a single function\n//! in the hook trait and don't need a drop implementation (event system is global anyway\n//! and never dropped) so we can just store the entire vtable inline.\n\nuse anyhow::Result;\nuse std::ptr::{self, NonNull};\n\nuse crate::Event;\n\n/// Opaque handle type that represents an erased type parameter.\n///\n/// If extern types were stable, this could be implemented as `extern { pub type Opaque; }` but\n/// until then we can use this.\n///\n/// Care should be taken that we don't use a concrete instance of this. It should only be used\n/// through a reference, so we can maintain something else's lifetime.\nstruct Opaque(());\n\npub(crate) struct ErasedHook {\n    data: NonNull<Opaque>,\n    call: unsafe fn(NonNull<Opaque>, NonNull<Opaque>, NonNull<Opaque>),\n}\n\nimpl ErasedHook {\n    pub(crate) fn new_dynamic<H: Fn() -> Result<()> + 'static + Send + Sync>(\n        hook: H,\n    ) -> ErasedHook {\n        unsafe fn call<F: Fn() -> Result<()> + 'static + Send + Sync>(\n            hook: NonNull<Opaque>,\n            _event: NonNull<Opaque>,\n            result: NonNull<Opaque>,\n        ) {\n            let hook: NonNull<F> = hook.cast();\n            let result: NonNull<Result<()>> = result.cast();\n            let hook: &F = hook.as_ref();\n            let res = hook();\n            ptr::write(result.as_ptr(), res)\n        }\n\n        unsafe {\n            ErasedHook {\n                data: NonNull::new_unchecked(Box::into_raw(Box::new(hook)) as *mut Opaque),\n                call: call::<H>,\n            }\n        }\n    }\n\n    pub(crate) fn new<E: Event, F: Fn(&mut E) -> Result<()>>(hook: F) -> ErasedHook {\n        unsafe fn call<E: Event, F: Fn(&mut E) -> Result<()>>(\n            hook: NonNull<Opaque>,\n            event: NonNull<Opaque>,\n            result: NonNull<Opaque>,\n        ) {\n            let hook: NonNull<F> = hook.cast();\n            let mut event: NonNull<E> = event.cast();\n            let result: NonNull<Result<()>> = result.cast();\n            let hook: &F = hook.as_ref();\n            let res = hook(event.as_mut());\n            ptr::write(result.as_ptr(), res)\n        }\n\n        unsafe {\n            ErasedHook {\n                data: NonNull::new_unchecked(Box::into_raw(Box::new(hook)) as *mut Opaque),\n                call: call::<E, F>,\n            }\n        }\n    }\n\n    pub(crate) unsafe fn call<E: Event>(&self, event: &mut E) -> Result<()> {\n        let mut res = Ok(());\n\n        unsafe {\n            (self.call)(\n                self.data,\n                NonNull::from(event).cast(),\n                NonNull::from(&mut res).cast(),\n            );\n        }\n        res\n    }\n}\n\nunsafe impl Sync for ErasedHook {}\nunsafe impl Send for ErasedHook {}\n"
  },
  {
    "path": "helix-event/src/lib.rs",
    "content": "//! `helix-event` contains systems that allow (often async) communication between\n//! different editor components without strongly coupling them. Specifically\n//! it allows defining synchronous hooks that run when certain editor events\n//! occur.\n//!\n//! The core of the event system are hook callbacks and the [`Event`] trait. A\n//! hook is essentially just a closure `Fn(event: &mut impl Event) -> Result<()>`\n//! that gets called every time an appropriate event is dispatched. The implementation\n//! details of the [`Event`] trait are considered private. The [`events`] macro is\n//! provided which automatically declares event types. Similarly the `register_hook`\n//! macro should be used to (safely) declare event hooks.\n//!\n//! Hooks run synchronously which can be advantageous since they can modify the\n//! current editor state right away (for example to immediately hide the completion\n//! popup). However, they can not contain their own state without locking since\n//! they only receive immutable references. For handler that want to track state, do\n//! expensive background computations or debouncing an [`AsyncHook`] is preferable.\n//! Async hooks are based around a channels that receive events specific to\n//! that `AsyncHook` (usually an enum). These events can be sent by synchronous\n//! hooks. Due to some limitations around tokio channels the [`send_blocking`]\n//! function exported in this crate should be used instead of the builtin\n//! `blocking_send`.\n//!\n//! In addition to the core event system, this crate contains some message queues\n//! that allow transfer of data back to the main event loop from async hooks and\n//! hooks that may not have access to all application data (for example in helix-view).\n//! This include the ability to control rendering ([`lock_frame`], [`request_redraw`]) and\n//! display status messages ([`status`]).\n//!\n//! Hooks declared in helix-term can furthermore dispatch synchronous jobs to be run on the\n//! main loop (including access to the compositor). Ideally that queue will be moved\n//! to helix-view in the future if we manage to detach the compositor from its rendering backend.\n\nuse anyhow::Result;\npub use cancel::{cancelable_future, TaskController, TaskHandle};\npub use debounce::{send_blocking, AsyncHook};\npub use redraw::{\n    lock_frame, redraw_requested, request_redraw, start_frame, RenderLockGuard, RequestRedrawOnDrop,\n};\npub use registry::Event;\n\nmod cancel;\nmod debounce;\nmod hook;\nmod redraw;\nmod registry;\n#[doc(hidden)]\npub mod runtime;\npub mod status;\n\n#[cfg(test)]\nmod test;\n\npub fn register_event<E: Event + 'static>() {\n    registry::with_mut(|registry| registry.register_event::<E>())\n}\n\n/// Registers a hook that will be called when an event of type `E` is dispatched.\n/// This function should usually not be used directly, use the [`register_hook`]\n/// macro instead.\n///\n///\n/// # Safety\n///\n/// `hook` must be totally generic over all lifetime parameters of `E`. For\n/// example if `E` was a known type `Foo<'a, 'b>`, then the correct trait bound\n/// would be `F: for<'a, 'b, 'c> Fn(&'a mut Foo<'b, 'c>)`, but there is no way to\n/// express that kind of constraint for a generic type with the Rust type system\n/// as of this writing.\npub unsafe fn register_hook_raw<E: Event>(\n    hook: impl Fn(&mut E) -> Result<()> + 'static + Send + Sync,\n) {\n    registry::with_mut(|registry| registry.register_hook(hook))\n}\n\n/// Register a hook solely by event name\npub fn register_dynamic_hook(\n    hook: impl Fn() -> Result<()> + 'static + Send + Sync,\n    id: &str,\n) -> Result<()> {\n    registry::with_mut(|reg| reg.register_dynamic_hook(hook, id))\n}\n\npub fn dispatch(e: impl Event) {\n    registry::with(|registry| registry.dispatch(e));\n}\n\n/// Macro to declare events\n///\n/// # Examples\n///\n/// ``` no-compile\n/// events! {\n///     FileWrite(&Path)\n///     ViewScrolled{ view: View, new_pos: ViewOffset }\n///     DocumentChanged<'a> { old_doc: &'a Rope, doc: &'a mut Document, changes: &'a ChangeSet  }\n/// }\n///\n/// fn init() {\n///    register_event::<FileWrite>();\n///    register_event::<ViewScrolled>();\n///    register_event::<DocumentChanged>();\n/// }\n///\n/// fn save(path: &Path, content: &str){\n///     std::fs::write(path, content);\n///     dispatch(FileWrite(path));\n/// }\n/// ```\n#[macro_export]\nmacro_rules! events {\n    ($name: ident<$($lt: lifetime),*> { $($data:ident : $data_ty:ty),* } $($rem:tt)*) => {\n        pub struct $name<$($lt),*> { $(pub $data: $data_ty),* }\n        unsafe impl<$($lt),*> $crate::Event for $name<$($lt),*> {\n            const ID: &'static str = stringify!($name);\n            const LIFETIMES: usize = $crate::events!(@sum $(1, $lt),*);\n            type Static = $crate::events!(@replace_lt $name, $('static, $lt),*);\n        }\n        $crate::events!{ $($rem)* }\n    };\n    ($name: ident { $($data:ident : $data_ty:ty),* } $($rem:tt)*) => {\n        pub struct $name { $(pub $data: $data_ty),* }\n        unsafe impl $crate::Event for $name {\n            const ID: &'static str = stringify!($name);\n            const LIFETIMES: usize = 0;\n            type Static = Self;\n        }\n        $crate::events!{ $($rem)* }\n    };\n    () => {};\n    (@replace_lt $name: ident, $($lt1: lifetime, $lt2: lifetime),* ) => {$name<$($lt1),*>};\n    (@sum $($val: expr, $lt1: lifetime),* ) => {0 $(+ $val)*};\n}\n\n/// Safely register statically typed event hooks\n#[macro_export]\nmacro_rules! register_hook {\n    // Safety: this is safe because we fully control the type of the event here and\n    // ensure all lifetime arguments are fully generic and the correct number of lifetime arguments\n    // is present\n    (move |$event:ident: &mut $event_ty: ident<$($lt: lifetime),*>| $body: expr) => {\n        let val = move |$event: &mut $event_ty<$($lt),*>| $body;\n        unsafe {\n            // Lifetimes are a bit of a pain. We want to allow events being\n            // non-static. Lifetimes don't actually exist at runtime so its\n            // fine to essentially transmute the lifetimes as long as we can\n            // prove soundness. The hook must therefore accept any combination\n            // of lifetimes. In other words fn(&'_ mut Event<'_, '_>) is ok\n            // but examples like fn(&'_ mut Event<'_, 'static>) or fn<'a>(&'a\n            // mut Event<'a, 'a>) are not. To make this safe we use a macro to\n            // forbid the user from specifying lifetimes manually (all lifetimes\n            // specified are always function generics and passed to the event so\n            // lifetimes can't be used multiple times and using 'static causes a\n            // syntax error).\n            //\n            // There is one soundness hole tough: Type Aliases allow\n            // \"accidentally\" creating these problems. For example:\n            //\n            // type Event2  = Event<'static>.\n            // type Event2<'a>  = Event<'a, a>.\n            //\n            // These cases can be caught by counting the number of lifetimes\n            // parameters at the parameter declaration site and then at the hook\n            // declaration site. By asserting the number of lifetime parameters\n            // are equal we can catch all bad type aliases under one assumption:\n            // There are no unused lifetime parameters. Introducing a static\n            // would reduce the number of arguments of the alias by one in the\n            // above example Event2 has zero lifetime arguments while the original\n            // event has one lifetime argument. Similar logic applies to using\n            // a lifetime argument multiple times. The ASSERT below performs a\n            // a compile time assertion to ensure exactly this property.\n            //\n            // With unused lifetime arguments it is still one way to cause unsound code:\n            //\n            // type Event2<'a, 'b> = Event<'a, 'a>;\n            //\n            // However, this case will always emit a compiler warning/cause CI\n            // failures so a user would have to introduce #[allow(unused)] which\n            // is easily caught in review (and a very theoretical case anyway).\n            // If we want to be pedantic we can simply compile helix with\n            // forbid(unused). All of this is just a safety net to prevent\n            // very theoretical misuse. This won't come up in real code (and is\n            // easily caught in review).\n            #[allow(unused)]\n            const ASSERT: () = {\n                if <$event_ty as $crate::Event>::LIFETIMES != 0 + $crate::events!(@sum $(1, $lt),*){\n                    panic!(\"invalid type alias\");\n                }\n            };\n            $crate::register_hook_raw::<$crate::events!(@replace_lt $event_ty, $('static, $lt),*)>(val);\n        }\n    };\n    (move |$event:ident: &mut $event_ty: ident| $body: expr) => {\n        let val = move |$event: &mut $event_ty| $body;\n        unsafe {\n            #[allow(unused)]\n            const ASSERT: () = {\n                if <$event_ty as $crate::Event>::LIFETIMES != 0{\n                    panic!(\"invalid type alias\");\n                }\n            };\n            $crate::register_hook_raw::<$event_ty>(val);\n        }\n    };\n}\n"
  },
  {
    "path": "helix-event/src/redraw.rs",
    "content": "//! Signals that control when/if the editor redraws\n\nuse std::future::Future;\n\nuse parking_lot::{RwLock, RwLockReadGuard};\nuse tokio::sync::Notify;\n\nuse crate::runtime_local;\n\nruntime_local! {\n    /// A `Notify` instance that can be used to (asynchronously) request\n    /// the editor to render a new frame.\n    static REDRAW_NOTIFY: Notify = Notify::const_new();\n\n    /// A `RwLock` that prevents the next frame from being\n    /// drawn until an exclusive (write) lock can be acquired.\n    /// This allows asynchronous tasks to acquire `non-exclusive`\n    /// locks (read) to prevent the next frame from being drawn\n    /// until a certain computation has finished.\n    static RENDER_LOCK: RwLock<()> = RwLock::new(());\n}\n\npub type RenderLockGuard = RwLockReadGuard<'static, ()>;\n\n/// Requests that the editor is redrawn. The redraws are debounced (currently to\n/// 30FPS) so this can be called many times without causing a ton of frames to\n/// be rendered.\npub fn request_redraw() {\n    REDRAW_NOTIFY.notify_one();\n}\n\n/// Returns a future that will yield once a redraw has been asynchronously\n/// requested using [`request_redraw`].\npub fn redraw_requested() -> impl Future<Output = ()> {\n    REDRAW_NOTIFY.notified()\n}\n\n/// Wait until all locks acquired with [`lock_frame`] have been released.\n/// This function is called before rendering and is intended to allow the frame\n/// to wait for async computations that should be included in the current frame.\npub fn start_frame() {\n    drop(RENDER_LOCK.write());\n    // exhaust any leftover redraw notifications\n    let notify = REDRAW_NOTIFY.notified();\n    tokio::pin!(notify);\n    notify.enable();\n}\n\n/// Acquires the render lock which will prevent the next frame from being drawn\n/// until the returned guard is dropped.\npub fn lock_frame() -> RenderLockGuard {\n    RENDER_LOCK.read()\n}\n\n/// A zero sized type that requests a redraw via [request_redraw] when the type [Drop]s.\npub struct RequestRedrawOnDrop;\n\nimpl Drop for RequestRedrawOnDrop {\n    fn drop(&mut self) {\n        request_redraw();\n    }\n}\n"
  },
  {
    "path": "helix-event/src/registry.rs",
    "content": "//! A global registry where events are registered and can be\n//! subscribed to by registering hooks. The registry identifies event\n//! types using their type name so multiple event with the same type name\n//! may not be registered (will cause a panic to ensure soundness)\n\nuse std::any::TypeId;\n\nuse anyhow::{bail, Result};\nuse hashbrown::hash_map::Entry;\nuse hashbrown::HashMap;\nuse parking_lot::RwLock;\n\nuse crate::hook::ErasedHook;\nuse crate::runtime_local;\n\npub struct Registry {\n    events: HashMap<&'static str, TypeId, foldhash::fast::FixedState>,\n    handlers: HashMap<&'static str, Vec<ErasedHook>, foldhash::fast::FixedState>,\n}\n\nimpl Registry {\n    pub fn register_event<E: Event + 'static>(&mut self) {\n        let ty = TypeId::of::<E>();\n        assert_eq!(ty, TypeId::of::<E::Static>());\n        match self.events.entry(E::ID) {\n            Entry::Occupied(entry) => {\n                if entry.get() == &ty {\n                    // don't warn during tests to avoid log spam\n                    #[cfg(not(feature = \"integration_test\"))]\n                    panic!(\"Event {} was registered multiple times\", E::ID);\n                } else {\n                    panic!(\"Multiple events with ID {} were registered\", E::ID);\n                }\n            }\n            Entry::Vacant(ent) => {\n                ent.insert(ty);\n                self.handlers.insert(E::ID, Vec::new());\n            }\n        }\n    }\n\n    /// # Safety\n    ///\n    /// `hook` must be totally generic over all lifetime parameters of `E`. For\n    /// example if `E` was a known type `Foo<'a, 'b> then the correct trait bound\n    /// would be `F: for<'a, 'b, 'c> Fn(&'a mut Foo<'b, 'c>)` but there is no way to\n    /// express that kind of constraint for a generic type with the rust type system\n    /// right now.\n    pub unsafe fn register_hook<E: Event>(\n        &mut self,\n        hook: impl Fn(&mut E) -> Result<()> + 'static + Send + Sync,\n    ) {\n        // ensure event type ids match so we can rely on them always matching\n        let id = E::ID;\n        let Some(&event_id) = self.events.get(id) else {\n            panic!(\"Tried to register handler for unknown event {id}\");\n        };\n        assert!(\n            TypeId::of::<E::Static>() == event_id,\n            \"Tried to register invalid hook for event {id}\"\n        );\n        let hook = ErasedHook::new(hook);\n        self.handlers.get_mut(id).unwrap().push(hook);\n    }\n\n    pub fn register_dynamic_hook(\n        &mut self,\n        hook: impl Fn() -> Result<()> + 'static + Send + Sync,\n        id: &str,\n    ) -> Result<()> {\n        // ensure event type ids match so we can rely on them always matching\n        if self.events.get(id).is_none() {\n            bail!(\"Tried to register handler for unknown event {id}\");\n        };\n        let hook = ErasedHook::new_dynamic(hook);\n        self.handlers.get_mut(id).unwrap().push(hook);\n        Ok(())\n    }\n\n    pub fn dispatch<E: Event>(&self, mut event: E) {\n        let Some(hooks) = self.handlers.get(E::ID) else {\n            log::error!(\"Dispatched unknown event {}\", E::ID);\n            return;\n        };\n        let event_id = self.events[E::ID];\n\n        assert_eq!(\n            TypeId::of::<E::Static>(),\n            event_id,\n            \"Tried to dispatch invalid event {}\",\n            E::ID\n        );\n\n        for hook in hooks {\n            // safety: event type is the same\n            if let Err(err) = unsafe { hook.call(&mut event) } {\n                log::error!(\"{} hook failed: {err:#?}\", E::ID);\n                crate::status::report_blocking(err);\n            }\n        }\n    }\n}\n\nruntime_local! {\n    static REGISTRY: RwLock<Registry> = RwLock::new(Registry {\n        // hardcoded random number is good enough here we don't care about DOS resistance\n        // and avoids the additional complexity of `Option<Registry>`\n        events: HashMap::with_hasher(foldhash::fast::FixedState::with_seed(72536814787)),\n        handlers: HashMap::with_hasher(foldhash::fast::FixedState::with_seed(72536814787)),\n    });\n}\n\npub(crate) fn with<T>(f: impl FnOnce(&Registry) -> T) -> T {\n    f(&REGISTRY.read())\n}\n\npub(crate) fn with_mut<T>(f: impl FnOnce(&mut Registry) -> T) -> T {\n    f(&mut REGISTRY.write())\n}\n\n/// # Safety\n/// The number of specified lifetimes and the static type *must* be correct.\n/// This is ensured automatically by the [`events`](crate::events)\n/// macro.\npub unsafe trait Event: Sized {\n    /// Globally unique (case sensitive)  string that identifies this type.\n    /// A good candidate is the events type name\n    const ID: &'static str;\n    const LIFETIMES: usize;\n    type Static: Event + 'static;\n}\n"
  },
  {
    "path": "helix-event/src/runtime.rs",
    "content": "//! The event system makes use of global to decouple different systems.\n//! However, this can cause problems for the integration test system because\n//! it runs multiple helix applications in parallel. Making the globals\n//! thread-local does not work because a applications can/does have multiple\n//! runtime threads. Instead this crate implements a similar notion to a thread\n//! local but instead of being local to a single thread, the statics are local to\n//! a single tokio-runtime. The implementation requires locking so it's not exactly efficient.\n//!\n//! Therefore this function is only enabled during integration tests and behaves like\n//! a normal static otherwise. I would prefer this module to be fully private and to only\n//! export the macro but the macro still need to construct these internals so it's marked\n//! `doc(hidden)` instead\n\nuse std::ops::Deref;\n\n#[cfg(not(feature = \"integration_test\"))]\npub struct RuntimeLocal<T: 'static> {\n    /// inner API used in the macro, not part of public API\n    #[doc(hidden)]\n    pub __data: T,\n}\n\n#[cfg(not(feature = \"integration_test\"))]\nimpl<T> Deref for RuntimeLocal<T> {\n    type Target = T;\n\n    fn deref(&self) -> &Self::Target {\n        &self.__data\n    }\n}\n\n#[cfg(not(feature = \"integration_test\"))]\n#[macro_export]\nmacro_rules! runtime_local {\n    ($($(#[$attr:meta])* $vis: vis static $name:ident: $ty: ty = $init: expr;)*) => {\n        $($(#[$attr])* $vis static $name: $crate::runtime::RuntimeLocal<$ty> = $crate::runtime::RuntimeLocal {\n            __data: $init\n        };)*\n    };\n}\n\n#[cfg(feature = \"integration_test\")]\npub struct RuntimeLocal<T: 'static> {\n    data: parking_lot::RwLock<\n        hashbrown::HashMap<tokio::runtime::Id, &'static T, foldhash::fast::FixedState>,\n    >,\n    init: fn() -> T,\n}\n\n#[cfg(feature = \"integration_test\")]\nimpl<T> RuntimeLocal<T> {\n    /// inner API used in the macro, not part of public API\n    #[doc(hidden)]\n    pub const fn __new(init: fn() -> T) -> Self {\n        Self {\n            data: parking_lot::RwLock::new(hashbrown::HashMap::with_hasher(\n                foldhash::fast::FixedState::with_seed(12345678910),\n            )),\n            init,\n        }\n    }\n}\n\n#[cfg(feature = \"integration_test\")]\nimpl<T> Deref for RuntimeLocal<T> {\n    type Target = T;\n    fn deref(&self) -> &T {\n        let id = tokio::runtime::Handle::current().id();\n        let guard = self.data.read();\n        match guard.get(&id) {\n            Some(res) => res,\n            None => {\n                drop(guard);\n                let data = Box::leak(Box::new((self.init)()));\n                let mut guard = self.data.write();\n                guard.insert(id, data);\n                data\n            }\n        }\n    }\n}\n\n#[cfg(feature = \"integration_test\")]\n#[macro_export]\nmacro_rules! runtime_local {\n    ($($(#[$attr:meta])* $vis: vis static $name:ident: $ty: ty = $init: expr;)*) => {\n         $($(#[$attr])* $vis static $name: $crate::runtime::RuntimeLocal<$ty> = $crate::runtime::RuntimeLocal::__new(|| $init);)*\n    };\n}\n"
  },
  {
    "path": "helix-event/src/status.rs",
    "content": "//! A queue of async messages/errors that will be shown in the editor\n\nuse std::borrow::Cow;\nuse std::time::Duration;\n\nuse crate::{runtime_local, send_blocking};\nuse once_cell::sync::OnceCell;\nuse tokio::sync::mpsc::{Receiver, Sender};\n\n/// Describes the severity level of a [`StatusMessage`].\n#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]\npub enum Severity {\n    Hint,\n    Info,\n    Warning,\n    Error,\n}\n\npub struct StatusMessage {\n    pub severity: Severity,\n    pub message: Cow<'static, str>,\n}\n\nimpl From<anyhow::Error> for StatusMessage {\n    fn from(err: anyhow::Error) -> Self {\n        StatusMessage {\n            severity: Severity::Error,\n            message: err.to_string().into(),\n        }\n    }\n}\n\nimpl From<&'static str> for StatusMessage {\n    fn from(msg: &'static str) -> Self {\n        StatusMessage {\n            severity: Severity::Info,\n            message: msg.into(),\n        }\n    }\n}\n\nruntime_local! {\n    static MESSAGES: OnceCell<Sender<StatusMessage>> = OnceCell::new();\n}\n\npub async fn report(msg: impl Into<StatusMessage>) {\n    // if the error channel overflows just ignore it\n    let _ = MESSAGES\n        .wait()\n        .send_timeout(msg.into(), Duration::from_millis(10))\n        .await;\n}\n\npub fn report_blocking(msg: impl Into<StatusMessage>) {\n    let messages = MESSAGES.wait();\n    send_blocking(messages, msg.into())\n}\n\n/// Must be called once during editor startup exactly once\n/// before any of the messages in this module can be used\n///\n/// # Panics\n/// If called multiple times\npub fn setup() -> Receiver<StatusMessage> {\n    let (tx, rx) = tokio::sync::mpsc::channel(128);\n    let _ = MESSAGES.set(tx);\n    rx\n}\n"
  },
  {
    "path": "helix-event/src/test.rs",
    "content": "use std::sync::atomic::{AtomicUsize, Ordering};\nuse std::sync::Arc;\nuse std::time::Duration;\n\nuse parking_lot::Mutex;\n\nuse crate::{dispatch, events, register_dynamic_hook, register_event, register_hook};\n#[test]\nfn smoke_test() {\n    events! {\n        Event1 { content: String }\n        Event2 { content: usize }\n    }\n    register_event::<Event1>();\n    register_event::<Event2>();\n\n    // setup hooks\n    let res1: Arc<Mutex<String>> = Arc::default();\n    let acc = Arc::clone(&res1);\n    register_hook!(move |event: &mut Event1| {\n        acc.lock().push_str(&event.content);\n        Ok(())\n    });\n    let res2: Arc<AtomicUsize> = Arc::default();\n    let acc = Arc::clone(&res2);\n    register_hook!(move |event: &mut Event2| {\n        acc.fetch_add(event.content, Ordering::Relaxed);\n        Ok(())\n    });\n\n    // triggers events\n    let thread = std::thread::spawn(|| {\n        for i in 0..1000 {\n            dispatch(Event2 { content: i });\n        }\n    });\n    std::thread::sleep(Duration::from_millis(1));\n    dispatch(Event1 {\n        content: \"foo\".to_owned(),\n    });\n    dispatch(Event2 { content: 42 });\n    dispatch(Event1 {\n        content: \"bar\".to_owned(),\n    });\n    dispatch(Event1 {\n        content: \"hello world\".to_owned(),\n    });\n    thread.join().unwrap();\n\n    // check output\n    assert_eq!(&**res1.lock(), \"foobarhello world\");\n    assert_eq!(\n        res2.load(Ordering::Relaxed),\n        42 + (0..1000usize).sum::<usize>()\n    );\n}\n\n#[test]\n#[allow(dead_code)]\nfn dynamic() {\n    events! {\n        Event3 {}\n        Event4 { count: usize }\n    };\n    register_event::<Event3>();\n    register_event::<Event4>();\n\n    let count = Arc::new(AtomicUsize::new(0));\n    let count1 = count.clone();\n    let count2 = count.clone();\n    register_dynamic_hook(\n        move || {\n            count1.fetch_add(2, Ordering::Relaxed);\n            Ok(())\n        },\n        \"Event3\",\n    )\n    .unwrap();\n    register_dynamic_hook(\n        move || {\n            count2.fetch_add(3, Ordering::Relaxed);\n            Ok(())\n        },\n        \"Event4\",\n    )\n    .unwrap();\n    dispatch(Event3 {});\n    dispatch(Event4 { count: 0 });\n    dispatch(Event3 {});\n    assert_eq!(count.load(Ordering::Relaxed), 7)\n}\n"
  },
  {
    "path": "helix-loader/Cargo.toml",
    "content": "[package]\nname = \"helix-loader\"\ndescription = \"Build bootstrapping for Helix crates\"\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n[[bin]]\nname = \"hx-loader\"\npath = \"src/main.rs\"\n\n[dependencies]\nhelix-stdx = { path = \"../helix-stdx\" }\n\nanyhow = \"1\"\nserde = { version = \"1.0\", features = [\"derive\"] }\ntoml.workspace = true\netcetera.workspace = true\nonce_cell = \"1.21\"\nlog = \"0.4\"\n\n# TODO: these two should be on !wasm32 only\n\n# cloning/compiling tree-sitter grammars\ncc = { version = \"1\" }\nthreadpool = { version = \"1.0\" }\ntempfile.workspace = true\n\ntree-house.workspace = true\n"
  },
  {
    "path": "helix-loader/build.rs",
    "content": "use std::borrow::Cow;\nuse std::path::Path;\nuse std::process::Command;\n\nconst MAJOR: &str = env!(\"CARGO_PKG_VERSION_MAJOR\");\nconst MINOR: &str = env!(\"CARGO_PKG_VERSION_MINOR\");\nconst PATCH: &str = env!(\"CARGO_PKG_VERSION_PATCH\");\n\nfn main() {\n    let git_hash = Command::new(\"git\")\n        .args([\"rev-parse\", \"HEAD\"])\n        .output()\n        .ok()\n        .filter(|output| output.status.success())\n        .and_then(|x| String::from_utf8(x.stdout).ok())\n        .or_else(|| option_env!(\"HELIX_NIX_BUILD_REV\").map(|s| s.to_string()));\n\n    let minor = if MINOR.len() == 1 {\n        // Print single-digit months in '0M' format\n        format!(\"0{MINOR}\")\n    } else {\n        MINOR.to_string()\n    };\n    let calver = if PATCH == \"0\" {\n        format!(\"{MAJOR}.{minor}\")\n    } else {\n        format!(\"{MAJOR}.{minor}.{PATCH}\")\n    };\n    let version: Cow<_> = match &git_hash {\n        Some(git_hash) => format!(\"{} ({})\", calver, &git_hash[..8]).into(),\n        None => calver.into(),\n    };\n\n    println!(\n        \"cargo:rustc-env=BUILD_TARGET={}\",\n        std::env::var(\"TARGET\").unwrap()\n    );\n\n    println!(\"cargo:rustc-env=VERSION_AND_GIT_HASH={}\", version);\n\n    if git_hash.is_none() {\n        return;\n    }\n\n    // we need to revparse because the git dir could be anywhere if you are\n    // using detached worktrees but there is no good way to obtain an OsString\n    // from command output so for now we can't accept non-utf8 paths here\n    // probably rare enough where it doesn't matter tough we could use gitoxide\n    // here but that would be make it a hard dependency and slow compile times\n    let Some(git_dir): Option<String> = Command::new(\"git\")\n        .args([\"rev-parse\", \"--git-dir\"])\n        .output()\n        .ok()\n        .filter(|output| output.status.success())\n        .and_then(|x| String::from_utf8(x.stdout).ok())\n        .map(|x| x.trim().to_string())\n    else {\n        return;\n    };\n    // If heads starts pointing at something else (different branch)\n    // we need to return\n    let head = Path::new(&git_dir).join(\"HEAD\");\n    if head.exists() {\n        println!(\"cargo:rerun-if-changed={}\", head.display());\n    }\n    // if the thing head points to (branch) itself changes\n    // we need to return\n    let Some(head_ref): Option<String> = Command::new(\"git\")\n        .args([\"symbolic-ref\", \"HEAD\"])\n        .output()\n        .ok()\n        .filter(|output| output.status.success())\n        .and_then(|x| String::from_utf8(x.stdout).ok())\n        .map(|x| x.trim().to_string())\n    else {\n        return;\n    };\n    let head_ref = Path::new(&git_dir).join(head_ref);\n    if head_ref.exists() {\n        println!(\"cargo:rerun-if-changed={}\", head_ref.display());\n    }\n}\n"
  },
  {
    "path": "helix-loader/src/config.rs",
    "content": "use std::str::from_utf8;\n\n/// Default built-in languages.toml.\npub fn default_lang_config() -> toml::Value {\n    let default_config = include_bytes!(\"../../languages.toml\");\n    toml::from_str(from_utf8(default_config).unwrap())\n        .expect(\"Could not parse built-in languages.toml to valid toml\")\n}\n\n/// User configured languages.toml file, merged with the default config.\npub fn user_lang_config() -> Result<toml::Value, toml::de::Error> {\n    let config = [\n        crate::config_dir(),\n        crate::find_workspace().0.join(\".helix\"),\n    ]\n    .into_iter()\n    .map(|path| path.join(\"languages.toml\"))\n    .filter_map(|file| {\n        std::fs::read_to_string(file)\n            .map(|config| toml::from_str(&config))\n            .ok()\n    })\n    .collect::<Result<Vec<_>, _>>()?\n    .into_iter()\n    .fold(default_lang_config(), |a, b| {\n        crate::merge_toml_values(a, b, 3)\n    });\n\n    Ok(config)\n}\n"
  },
  {
    "path": "helix-loader/src/grammar.rs",
    "content": "use anyhow::{anyhow, bail, Context, Result};\nuse serde::{Deserialize, Serialize};\nuse std::fs;\nuse std::time::SystemTime;\nuse std::{\n    collections::HashSet,\n    path::{Path, PathBuf},\n    process::Command,\n    sync::mpsc::channel,\n};\nuse tempfile::TempPath;\nuse tree_house::tree_sitter::Grammar;\n\n#[cfg(target_os = \"macos\")]\nconst DYLIB_EXTENSION: &str = \"dylib\";\n\n#[cfg(all(unix, not(target_os = \"macos\")))]\nconst DYLIB_EXTENSION: &str = \"so\";\n\n#[cfg(windows)]\nconst DYLIB_EXTENSION: &str = \"dll\";\n\n#[cfg(target_arch = \"wasm32\")]\nconst DYLIB_EXTENSION: &str = \"wasm\";\n\n#[derive(Debug, Serialize, Deserialize)]\nstruct Configuration {\n    #[serde(rename = \"use-grammars\")]\n    pub grammar_selection: Option<GrammarSelection>,\n    pub grammar: Vec<GrammarConfiguration>,\n}\n\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"lowercase\", untagged)]\npub enum GrammarSelection {\n    Only { only: HashSet<String> },\n    Except { except: HashSet<String> },\n}\n\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(deny_unknown_fields)]\npub struct GrammarConfiguration {\n    #[serde(rename = \"name\")]\n    pub grammar_id: String,\n    pub source: GrammarSource,\n}\n\n#[derive(Debug, Serialize, Deserialize)]\n#[serde(rename_all = \"lowercase\", untagged)]\npub enum GrammarSource {\n    Local {\n        path: String,\n    },\n    Git {\n        #[serde(rename = \"git\")]\n        remote: String,\n        #[serde(rename = \"rev\")]\n        revision: String,\n        subpath: Option<String>,\n    },\n}\n\nconst BUILD_TARGET: &str = env!(\"BUILD_TARGET\");\nconst REMOTE_NAME: &str = \"origin\";\n\n#[cfg(target_arch = \"wasm32\")]\npub fn get_language(name: &str) -> Result<Option<Grammar>> {\n    unimplemented!()\n}\n\n#[cfg(not(target_arch = \"wasm32\"))]\npub fn get_language(name: &str) -> Result<Option<Grammar>> {\n    let mut rel_library_path = PathBuf::new().join(\"grammars\").join(name);\n    rel_library_path.set_extension(DYLIB_EXTENSION);\n    let library_path = crate::runtime_file(&rel_library_path);\n    if !library_path.exists() {\n        return Ok(None);\n    }\n\n    let grammar = unsafe { Grammar::new(name, &library_path) }?;\n    Ok(Some(grammar))\n}\n\nfn ensure_git_is_available() -> Result<()> {\n    helix_stdx::env::which(\"git\")?;\n    Ok(())\n}\n\npub fn fetch_grammars() -> Result<()> {\n    ensure_git_is_available()?;\n\n    // We do not need to fetch local grammars.\n    let mut grammars = get_grammar_configs()?;\n    grammars.retain(|grammar| !matches!(grammar.source, GrammarSource::Local { .. }));\n\n    println!(\"Fetching {} grammars\", grammars.len());\n    let results = run_parallel(grammars, fetch_grammar);\n\n    let mut errors = Vec::new();\n    let mut git_updated = Vec::new();\n    let mut git_up_to_date = 0;\n    let mut non_git = Vec::new();\n\n    for (grammar_id, res) in results {\n        match res {\n            Ok(FetchStatus::GitUpToDate) => git_up_to_date += 1,\n            Ok(FetchStatus::GitUpdated { revision }) => git_updated.push((grammar_id, revision)),\n            Ok(FetchStatus::NonGit) => non_git.push(grammar_id),\n            Err(e) => errors.push((grammar_id, e)),\n        }\n    }\n\n    non_git.sort_unstable();\n    git_updated.sort_unstable_by(|a, b| a.0.cmp(&b.0));\n\n    if git_up_to_date != 0 {\n        println!(\"{} up to date git grammars\", git_up_to_date);\n    }\n\n    if !non_git.is_empty() {\n        println!(\"{} non git grammars\", non_git.len());\n        println!(\"\\t{:?}\", non_git);\n    }\n\n    if !git_updated.is_empty() {\n        println!(\"{} updated grammars\", git_updated.len());\n        // We checked the vec is not empty, unwrapping will not panic\n        let longest_id = git_updated.iter().map(|x| x.0.len()).max().unwrap();\n        for (id, rev) in git_updated {\n            println!(\n                \"\\t{id:width$} now on {rev}\",\n                id = id,\n                width = longest_id,\n                rev = rev\n            );\n        }\n    }\n\n    if !errors.is_empty() {\n        let len = errors.len();\n        for (i, (grammar, error)) in errors.into_iter().enumerate() {\n            println!(\"Failure {}/{len}: {grammar} {error}\", i + 1);\n        }\n        bail!(\"{len} grammars failed to fetch\");\n    }\n\n    Ok(())\n}\n\npub fn build_grammars(target: Option<String>) -> Result<()> {\n    ensure_git_is_available()?;\n\n    let grammars = get_grammar_configs()?;\n    println!(\"Building {} grammars\", grammars.len());\n    let results = run_parallel(grammars, move |grammar| {\n        build_grammar(grammar, target.as_deref())\n    });\n\n    let mut errors = Vec::new();\n    let mut already_built = 0;\n    let mut built = Vec::new();\n\n    for (grammar_id, res) in results {\n        match res {\n            Ok(BuildStatus::AlreadyBuilt) => already_built += 1,\n            Ok(BuildStatus::Built) => built.push(grammar_id),\n            Err(e) => errors.push((grammar_id, e)),\n        }\n    }\n\n    built.sort_unstable();\n\n    if already_built != 0 {\n        println!(\"{} grammars already built\", already_built);\n    }\n\n    if !built.is_empty() {\n        println!(\"{} grammars built now\", built.len());\n        println!(\"\\t{:?}\", built);\n    }\n\n    if !errors.is_empty() {\n        let len = errors.len();\n        for (i, (grammar_id, error)) in errors.into_iter().enumerate() {\n            println!(\"Failure {}/{len}: {grammar_id} {error}\", i + 1);\n        }\n        bail!(\"{len} grammars failed to build\");\n    }\n\n    Ok(())\n}\n\n// Returns the set of grammar configurations the user requests.\n// Grammars are configured in the default and user `languages.toml` and are\n// merged. The `grammar_selection` key of the config is then used to filter\n// down all grammars into a subset of the user's choosing.\nfn get_grammar_configs() -> Result<Vec<GrammarConfiguration>> {\n    let config: Configuration = crate::config::user_lang_config()\n        .context(\"Could not parse languages.toml\")?\n        .try_into()?;\n\n    let grammars = match config.grammar_selection {\n        Some(GrammarSelection::Only { only: selections }) => config\n            .grammar\n            .into_iter()\n            .filter(|grammar| selections.contains(&grammar.grammar_id))\n            .collect(),\n        Some(GrammarSelection::Except { except: rejections }) => config\n            .grammar\n            .into_iter()\n            .filter(|grammar| !rejections.contains(&grammar.grammar_id))\n            .collect(),\n        None => config.grammar,\n    };\n\n    Ok(grammars)\n}\n\npub fn get_grammar_names() -> Result<Option<HashSet<String>>> {\n    let config: Configuration = crate::config::user_lang_config()\n        .context(\"Could not parse languages.toml\")?\n        .try_into()?;\n\n    let grammars = match config.grammar_selection {\n        Some(GrammarSelection::Only { only: selections }) => Some(selections),\n        Some(GrammarSelection::Except { except: rejections }) => Some(\n            config\n                .grammar\n                .into_iter()\n                .map(|grammar| grammar.grammar_id)\n                .filter(|id| !rejections.contains(id))\n                .collect(),\n        ),\n        None => None,\n    };\n\n    Ok(grammars)\n}\n\nfn run_parallel<F, Res>(grammars: Vec<GrammarConfiguration>, job: F) -> Vec<(String, Result<Res>)>\nwhere\n    F: Fn(GrammarConfiguration) -> Result<Res> + Send + 'static + Clone,\n    Res: Send + 'static,\n{\n    let pool = threadpool::Builder::new().build();\n    let (tx, rx) = channel();\n\n    for grammar in grammars {\n        let tx = tx.clone();\n        let job = job.clone();\n\n        pool.execute(move || {\n            // Ignore any SendErrors, if any job in another thread has encountered an\n            // error the Receiver will be closed causing this send to fail.\n            let _ = tx.send((grammar.grammar_id.clone(), job(grammar)));\n        });\n    }\n\n    drop(tx);\n\n    rx.iter().collect()\n}\n\nenum FetchStatus {\n    GitUpToDate,\n    GitUpdated { revision: String },\n    NonGit,\n}\n\nstruct VendoredGrammar {\n    dir: PathBuf,\n}\n\nimpl VendoredGrammar {\n    fn new(grammar: &str) -> Self {\n        let dir = crate::runtime_dirs()\n            .first()\n            .expect(\"No runtime directories provided\") // guaranteed by post-condition\n            .join(\"grammars\")\n            .join(\"sources\")\n            .join(grammar);\n\n        Self { dir }\n    }\n\n    /// Gets the current revision of the repo.\n    fn revision(&self) -> Option<String> {\n        git(&self.dir, [\"rev-parse\", \"HEAD\"]).ok()\n    }\n\n    /// Fetches grammar at the given revision.\n    ///\n    /// To ensure clean state, existing grammar directory is removed and re-inited\n    /// before fetch operation.\n    fn fetch(&self, remote: &str, rev: &str) -> Result<()> {\n        self.reinit(remote)?;\n\n        git(&self.dir, [\"fetch\", \"--depth\", \"1\", REMOTE_NAME, rev])?;\n        git(&self.dir, [\"checkout\", rev])?;\n\n        Ok(())\n    }\n\n    /// Initializes the grammar directory.\n    ///\n    /// Creates directory and sets it up as a git repo, with remote set correctly.\n    fn init(&self, remote: &str) -> Result<()> {\n        // Create the grammar directory if needed.\n        fs::create_dir_all(&self.dir).context(format!(\n            \"Could not create grammar directory {:?}\",\n            &self.dir\n        ))?;\n\n        // Ensure directory is git initialized.\n        if !self.dir.join(\".git\").exists() {\n            git(&self.dir, [\"init\"])?;\n        }\n\n        // Ensure the remote matches the configured remote, setting if needed.\n        if self.remote().as_deref() != Some(remote) {\n            self.set_remote(remote)?;\n        }\n\n        Ok(())\n    }\n\n    /// Removes the grammar directory before initializing again.\n    fn reinit(&self, remote: &str) -> Result<()> {\n        fs::remove_dir_all(&self.dir)?;\n        self.init(remote)?;\n        Ok(())\n    }\n\n    /// Gets remote URL of grammar repo.\n    fn remote(&self) -> Option<String> {\n        git(&self.dir, [\"remote\", \"get-url\", REMOTE_NAME]).ok()\n    }\n\n    /// Sets remote URL of grammar repo.\n    fn set_remote(&self, remote: &str) -> Result<()> {\n        git(&self.dir, [\"remote\", \"set-url\", REMOTE_NAME, remote])\n            .or_else(|_| git(&self.dir, [\"remote\", \"add\", REMOTE_NAME, remote]))?;\n        Ok(())\n    }\n}\n\nfn fetch_grammar(grammar: GrammarConfiguration) -> Result<FetchStatus> {\n    let GrammarSource::Git {\n        remote, revision, ..\n    } = grammar.source\n    else {\n        return Ok(FetchStatus::NonGit);\n    };\n\n    let repo = VendoredGrammar::new(&grammar.grammar_id);\n\n    // WARN: Must init before other operations are done.\n    repo.init(&remote)?;\n\n    if repo.revision().is_some_and(|rev| rev == revision) {\n        return Ok(FetchStatus::GitUpToDate);\n    }\n\n    // Fetch the grammar if the revision doesn't match.\n    repo.fetch(&remote, &revision)?;\n\n    Ok(FetchStatus::GitUpdated { revision })\n}\n\n// A wrapper around 'git' commands which returns stdout in success and a\n// helpful error message showing the command, stdout, and stderr in error.\nfn git<I, S>(repository_dir: &Path, args: I) -> Result<String>\nwhere\n    I: IntoIterator<Item = S>,\n    S: AsRef<std::ffi::OsStr>,\n{\n    let output = Command::new(\"git\")\n        .args(args)\n        .current_dir(repository_dir)\n        .output()?;\n\n    if output.status.success() {\n        Ok(String::from_utf8_lossy(&output.stdout)\n            .trim_end()\n            .to_owned())\n    } else {\n        // TODO: figure out how to display the git command using `args`\n        Err(anyhow!(\n            \"Git command failed.\\nStdout: {}\\nStderr: {}\",\n            String::from_utf8_lossy(&output.stdout),\n            String::from_utf8_lossy(&output.stderr),\n        ))\n    }\n}\n\nenum BuildStatus {\n    AlreadyBuilt,\n    Built,\n}\n\nfn build_grammar(grammar: GrammarConfiguration, target: Option<&str>) -> Result<BuildStatus> {\n    let grammar_dir = if let GrammarSource::Local { path } = &grammar.source {\n        PathBuf::from(&path)\n    } else {\n        crate::runtime_dirs()\n            .first()\n            .expect(\"No runtime directories provided\") // guaranteed by post-condition\n            .join(\"grammars\")\n            .join(\"sources\")\n            .join(&grammar.grammar_id)\n    };\n\n    let grammar_dir_entries = grammar_dir.read_dir().with_context(|| {\n        format!(\n            \"Failed to read directory {:?}. Did you use 'hx --grammar fetch'?\",\n            grammar_dir\n        )\n    })?;\n\n    if grammar_dir_entries.count() == 0 {\n        return Err(anyhow!(\n            \"Directory {:?} is empty. Did you use 'hx --grammar fetch'?\",\n            grammar_dir\n        ));\n    };\n\n    let path = match &grammar.source {\n        GrammarSource::Git {\n            subpath: Some(subpath),\n            ..\n        } => grammar_dir.join(subpath),\n        _ => grammar_dir,\n    }\n    .join(\"src\");\n\n    build_tree_sitter_library(&path, grammar, target)\n}\n\nfn build_tree_sitter_library(\n    src_path: &Path,\n    grammar: GrammarConfiguration,\n    target: Option<&str>,\n) -> Result<BuildStatus> {\n    let header_path = src_path;\n    let parser_path = src_path.join(\"parser.c\");\n    let mut scanner_path = src_path.join(\"scanner.c\");\n\n    let scanner_path = if scanner_path.exists() {\n        Some(scanner_path)\n    } else {\n        scanner_path.set_extension(\"cc\");\n        if scanner_path.exists() {\n            Some(scanner_path)\n        } else {\n            None\n        }\n    };\n    let parser_lib_path = crate::runtime_dirs()\n        .first()\n        .expect(\"No runtime directories provided\") // guaranteed by post-condition\n        .join(\"grammars\");\n    let mut library_path = parser_lib_path.join(&grammar.grammar_id);\n    library_path.set_extension(DYLIB_EXTENSION);\n\n    // if we are running inside a buildscript emit cargo metadata\n    // to detect if we are running from a buildscript check some env variables\n    // that cargo only sets for build scripts\n    if std::env::var(\"OUT_DIR\").is_ok() && std::env::var(\"CARGO\").is_ok() {\n        if let Some(scanner_path) = scanner_path.as_ref().and_then(|path| path.to_str()) {\n            println!(\"cargo:rerun-if-changed={scanner_path}\");\n        }\n        if let Some(parser_path) = parser_path.to_str() {\n            println!(\"cargo:rerun-if-changed={parser_path}\");\n        }\n    }\n\n    let recompile = needs_recompile(&library_path, &parser_path, scanner_path.as_ref())\n        .context(\"Failed to compare source and binary timestamps\")?;\n\n    if !recompile {\n        return Ok(BuildStatus::AlreadyBuilt);\n    }\n\n    let mut config = cc::Build::new();\n    config\n        .cpp(true)\n        .opt_level(3)\n        .cargo_metadata(false)\n        .host(BUILD_TARGET)\n        .target(target.unwrap_or(BUILD_TARGET));\n    let compiler = config.get_compiler();\n    let mut command = Command::new(compiler.path());\n    command.current_dir(src_path);\n    for (key, value) in compiler.env() {\n        command.env(key, value);\n    }\n\n    command.args(compiler.args());\n    // used to delay dropping the temporary object file until after the compilation is complete\n    let _path_guard;\n\n    if compiler.is_like_msvc() {\n        command\n            .args([\"/nologo\", \"/LD\", \"/I\"])\n            .arg(header_path)\n            .arg(\"/utf-8\")\n            .arg(\"/std:c11\");\n        if let Some(scanner_path) = scanner_path.as_ref() {\n            if scanner_path.extension() == Some(\"c\".as_ref()) {\n                command.arg(scanner_path);\n            } else {\n                let mut cpp_command = Command::new(compiler.path());\n                cpp_command.current_dir(src_path);\n                for (key, value) in compiler.env() {\n                    cpp_command.env(key, value);\n                }\n                cpp_command.args(compiler.args());\n                let object_file =\n                    library_path.with_file_name(format!(\"{}_scanner.obj\", &grammar.grammar_id));\n                cpp_command\n                    .args([\"/nologo\", \"/LD\", \"/I\"])\n                    .arg(header_path)\n                    .arg(\"/utf-8\")\n                    .arg(\"/std:c++14\")\n                    .arg(format!(\"/Fo{}\", object_file.display()))\n                    .arg(\"/c\")\n                    .arg(scanner_path);\n                let output = cpp_command\n                    .output()\n                    .context(\"Failed to execute C++ compiler\")?;\n\n                if !output.status.success() {\n                    return Err(anyhow!(\n                        \"Parser compilation failed.\\nStdout: {}\\nStderr: {}\",\n                        String::from_utf8_lossy(&output.stdout),\n                        String::from_utf8_lossy(&output.stderr)\n                    ));\n                }\n                command.arg(&object_file);\n                _path_guard = TempPath::from_path(object_file);\n            }\n        }\n\n        command\n            .arg(parser_path)\n            .arg(\"/link\")\n            .arg(format!(\"/out:{}\", library_path.to_str().unwrap()));\n    } else {\n        #[cfg(not(windows))]\n        command.arg(\"-fPIC\");\n\n        command\n            .arg(\"-shared\")\n            .arg(\"-fno-exceptions\")\n            .arg(\"-I\")\n            .arg(header_path)\n            .arg(\"-o\")\n            .arg(&library_path);\n\n        if let Some(scanner_path) = scanner_path.as_ref() {\n            if scanner_path.extension() == Some(\"c\".as_ref()) {\n                command.arg(\"-xc\").arg(\"-std=c11\").arg(scanner_path);\n            } else {\n                let mut cpp_command = Command::new(compiler.path());\n                cpp_command.current_dir(src_path);\n                for (key, value) in compiler.env() {\n                    cpp_command.env(key, value);\n                }\n                cpp_command.args(compiler.args());\n                let object_file =\n                    library_path.with_file_name(format!(\"{}_scanner.o\", &grammar.grammar_id));\n\n                #[cfg(not(windows))]\n                cpp_command.arg(\"-fPIC\");\n\n                cpp_command\n                    .arg(\"-fno-exceptions\")\n                    .arg(\"-I\")\n                    .arg(header_path)\n                    .arg(\"-o\")\n                    .arg(&object_file)\n                    .arg(\"-std=c++14\")\n                    .arg(\"-c\")\n                    .arg(scanner_path);\n                let output = cpp_command\n                    .output()\n                    .context(\"Failed to execute C++ compiler\")?;\n                if !output.status.success() {\n                    return Err(anyhow!(\n                        \"Parser compilation failed.\\nStdout: {}\\nStderr: {}\",\n                        String::from_utf8_lossy(&output.stdout),\n                        String::from_utf8_lossy(&output.stderr)\n                    ));\n                }\n\n                command.arg(&object_file);\n                _path_guard = TempPath::from_path(object_file);\n            }\n        }\n        command.arg(\"-xc\").arg(\"-std=c11\").arg(parser_path);\n        if cfg!(all(\n            unix,\n            not(any(target_os = \"macos\", target_os = \"illumos\"))\n        )) {\n            command.arg(\"-Wl,-z,relro,-z,now\");\n        }\n    }\n\n    let output = command\n        .output()\n        .context(\"Failed to execute C/C++ compiler\")?;\n    if !output.status.success() {\n        return Err(anyhow!(\n            \"Parser compilation failed.\\nStdout: {}\\nStderr: {}\",\n            String::from_utf8_lossy(&output.stdout),\n            String::from_utf8_lossy(&output.stderr)\n        ));\n    }\n\n    Ok(BuildStatus::Built)\n}\n\nfn needs_recompile(\n    lib_path: &Path,\n    parser_c_path: &Path,\n    scanner_path: Option<&PathBuf>,\n) -> Result<bool> {\n    if !lib_path.exists() {\n        return Ok(true);\n    }\n    let lib_mtime = mtime(lib_path)?;\n    if mtime(parser_c_path)? > lib_mtime {\n        return Ok(true);\n    }\n    if let Some(scanner_path) = scanner_path {\n        if mtime(scanner_path)? > lib_mtime {\n            return Ok(true);\n        }\n    }\n    Ok(false)\n}\n\nfn mtime(path: &Path) -> Result<SystemTime> {\n    Ok(fs::metadata(path)?.modified()?)\n}\n\n/// Gives the contents of a file from a language's `runtime/queries/<lang>`\n/// directory\npub fn load_runtime_file(language: &str, filename: &str) -> Result<String, std::io::Error> {\n    let path = crate::runtime_file(PathBuf::new().join(\"queries\").join(language).join(filename));\n    std::fs::read_to_string(path)\n}\n"
  },
  {
    "path": "helix-loader/src/lib.rs",
    "content": "pub mod config;\npub mod grammar;\n\nuse helix_stdx::{env::current_working_dir, path};\n\nuse etcetera::base_strategy::{choose_base_strategy, BaseStrategy};\nuse std::path::{Path, PathBuf};\n\npub const VERSION_AND_GIT_HASH: &str = env!(\"VERSION_AND_GIT_HASH\");\n\nstatic RUNTIME_DIRS: once_cell::sync::Lazy<Vec<PathBuf>> =\n    once_cell::sync::Lazy::new(prioritize_runtime_dirs);\n\nstatic CONFIG_FILE: once_cell::sync::OnceCell<PathBuf> = once_cell::sync::OnceCell::new();\n\nstatic LOG_FILE: once_cell::sync::OnceCell<PathBuf> = once_cell::sync::OnceCell::new();\n\npub fn initialize_config_file(specified_file: Option<PathBuf>) {\n    let config_file = specified_file.unwrap_or_else(default_config_file);\n    ensure_parent_dir(&config_file);\n    CONFIG_FILE.set(config_file).ok();\n}\n\npub fn initialize_log_file(specified_file: Option<PathBuf>) {\n    let log_file = specified_file.unwrap_or_else(default_log_file);\n    ensure_parent_dir(&log_file);\n    LOG_FILE.set(log_file).ok();\n}\n\n/// A list of runtime directories from highest to lowest priority\n///\n/// The priority is:\n///\n/// 1. sibling directory to `CARGO_MANIFEST_DIR` (if environment variable is set)\n/// 2. subdirectory of user config directory (always included)\n/// 3. `HELIX_RUNTIME` (if environment variable is set)\n/// 4. `HELIX_DEFAULT_RUNTIME` (if environment variable is set *at build time*)\n/// 5. subdirectory of path to helix executable (always included)\n///\n/// Postcondition: returns at least two paths (they might not exist).\nfn prioritize_runtime_dirs() -> Vec<PathBuf> {\n    const RT_DIR: &str = \"runtime\";\n    // Adding higher priority first\n    let mut rt_dirs = Vec::new();\n    if let Ok(dir) = std::env::var(\"CARGO_MANIFEST_DIR\") {\n        // this is the directory of the crate being run by cargo, we need the workspace path so we take the parent\n        let path = PathBuf::from(dir).parent().unwrap().join(RT_DIR);\n        log::debug!(\"runtime dir: {}\", path.to_string_lossy());\n        rt_dirs.push(path);\n    }\n\n    let conf_rt_dir = config_dir().join(RT_DIR);\n    rt_dirs.push(conf_rt_dir);\n\n    if let Ok(dir) = std::env::var(\"HELIX_RUNTIME\") {\n        let dir = path::expand_tilde(Path::new(&dir));\n        rt_dirs.push(path::normalize(dir));\n    }\n\n    // If this variable is set during build time, it will always be included\n    // in the lookup list. This allows downstream packagers to set a fallback\n    // directory to a location that is conventional on their distro so that they\n    // need not resort to a wrapper script or a global environment variable.\n    if let Some(dir) = std::option_env!(\"HELIX_DEFAULT_RUNTIME\") {\n        rt_dirs.push(dir.into());\n    }\n\n    // fallback to location of the executable being run\n    // canonicalize the path in case the executable is symlinked\n    let exe_rt_dir = std::env::current_exe()\n        .ok()\n        .and_then(|path| std::fs::canonicalize(path).ok())\n        .and_then(|path| path.parent().map(|path| path.to_path_buf().join(RT_DIR)))\n        .unwrap();\n    rt_dirs.push(exe_rt_dir);\n    rt_dirs\n}\n\n/// Runtime directories ordered from highest to lowest priority\n///\n/// All directories should be checked when looking for files.\n///\n/// Postcondition: returns at least one path (it might not exist).\npub fn runtime_dirs() -> &'static [PathBuf] {\n    &RUNTIME_DIRS\n}\n\n/// Find file with path relative to runtime directory\n///\n/// `rel_path` should be the relative path from within the `runtime/` directory.\n/// The valid runtime directories are searched in priority order and the first\n/// file found to exist is returned, otherwise None.\nfn find_runtime_file(rel_path: &Path) -> Option<PathBuf> {\n    RUNTIME_DIRS.iter().find_map(|rt_dir| {\n        let path = rt_dir.join(rel_path);\n        if path.exists() {\n            Some(path)\n        } else {\n            None\n        }\n    })\n}\n\n/// Find file with path relative to runtime directory\n///\n/// `rel_path` should be the relative path from within the `runtime/` directory.\n/// The valid runtime directories are searched in priority order and the first\n/// file found to exist is returned, otherwise the path to the final attempt\n/// that failed.\npub fn runtime_file(rel_path: impl AsRef<Path>) -> PathBuf {\n    find_runtime_file(rel_path.as_ref()).unwrap_or_else(|| {\n        RUNTIME_DIRS\n            .last()\n            .map(|dir| dir.join(rel_path))\n            .unwrap_or_default()\n    })\n}\n\npub fn config_dir() -> PathBuf {\n    // TODO: allow env var override\n    let strategy = choose_base_strategy().expect(\"Unable to find the config directory!\");\n    let mut path = strategy.config_dir();\n    path.push(\"helix\");\n    path\n}\n\npub fn cache_dir() -> PathBuf {\n    // TODO: allow env var override\n    let strategy = choose_base_strategy().expect(\"Unable to find the cache directory!\");\n    let mut path = strategy.cache_dir();\n    path.push(\"helix\");\n    path\n}\n\npub fn config_file() -> PathBuf {\n    CONFIG_FILE.get().map(|path| path.to_path_buf()).unwrap()\n}\n\npub fn log_file() -> PathBuf {\n    LOG_FILE.get().map(|path| path.to_path_buf()).unwrap()\n}\n\npub fn workspace_config_file() -> PathBuf {\n    find_workspace().0.join(\".helix\").join(\"config.toml\")\n}\n\npub fn lang_config_file() -> PathBuf {\n    config_dir().join(\"languages.toml\")\n}\n\npub fn default_log_file() -> PathBuf {\n    cache_dir().join(\"helix.log\")\n}\n\n/// Merge two TOML documents, merging values from `right` onto `left`\n///\n/// `merge_depth` sets the nesting depth up to which values are merged instead\n/// of overridden.\n///\n/// When a table exists in both `left` and `right`, the merged table consists of\n/// all keys in `left`'s table unioned with all keys in `right` with the values\n/// of `right` being merged recursively onto values of `left`.\n///\n/// `crate::merge_toml_values(a, b, 3)` combines, for example:\n///\n/// b:\n/// ```toml\n/// [[language]]\n/// name = \"toml\"\n/// language-server = { command = \"taplo\", args = [\"lsp\", \"stdio\"] }\n/// ```\n/// a:\n/// ```toml\n/// [[language]]\n/// language-server = { command = \"/usr/bin/taplo\" }\n/// ```\n///\n/// into:\n/// ```toml\n/// [[language]]\n/// name = \"toml\"\n/// language-server = { command = \"/usr/bin/taplo\" }\n/// ```\n///\n/// thus it overrides the third depth-level of b with values of a if they exist,\n/// but otherwise merges their values\npub fn merge_toml_values(left: toml::Value, right: toml::Value, merge_depth: usize) -> toml::Value {\n    use toml::Value;\n\n    fn get_name(v: &Value) -> Option<&str> {\n        v.get(\"name\").and_then(Value::as_str)\n    }\n\n    match (left, right) {\n        (Value::Array(mut left_items), Value::Array(right_items)) => {\n            if merge_depth > 0 {\n                left_items.reserve(right_items.len());\n                for rvalue in right_items {\n                    let lvalue = get_name(&rvalue)\n                        .and_then(|rname| {\n                            left_items.iter().position(|v| get_name(v) == Some(rname))\n                        })\n                        .map(|lpos| left_items.remove(lpos));\n                    let mvalue = match lvalue {\n                        Some(lvalue) => merge_toml_values(lvalue, rvalue, merge_depth - 1),\n                        None => rvalue,\n                    };\n                    left_items.push(mvalue);\n                }\n                Value::Array(left_items)\n            } else {\n                Value::Array(right_items)\n            }\n        }\n        (Value::Table(mut left_map), Value::Table(right_map)) => {\n            if merge_depth > 0 {\n                for (rname, rvalue) in right_map {\n                    match left_map.remove(&rname) {\n                        Some(lvalue) => {\n                            let merged_value = merge_toml_values(lvalue, rvalue, merge_depth - 1);\n                            left_map.insert(rname, merged_value);\n                        }\n                        None => {\n                            left_map.insert(rname, rvalue);\n                        }\n                    }\n                }\n                Value::Table(left_map)\n            } else {\n                Value::Table(right_map)\n            }\n        }\n        // Catch everything else we didn't handle, and use the right value\n        (_, value) => value,\n    }\n}\n\n/// Finds the current workspace folder.\n/// Used as a ceiling dir for LSP root resolution, the filepicker and potentially as a future filewatching root\n///\n/// This function starts searching the FS upward from the CWD\n/// and returns the first directory that contains either `.git`, `.svn`, `.jj` or `.helix`.\n/// If no workspace was found returns (CWD, true).\n/// Otherwise (workspace, false) is returned\npub fn find_workspace() -> (PathBuf, bool) {\n    let current_dir = current_working_dir();\n    find_workspace_in(current_dir)\n}\n\npub fn find_workspace_in(dir: impl AsRef<Path>) -> (PathBuf, bool) {\n    let dir = dir.as_ref();\n    for ancestor in dir.ancestors() {\n        if ancestor.join(\".git\").exists()\n            || ancestor.join(\".svn\").exists()\n            || ancestor.join(\".jj\").exists()\n            || ancestor.join(\".helix\").exists()\n        {\n            return (ancestor.to_owned(), false);\n        }\n    }\n\n    (dir.to_owned(), true)\n}\n\nfn default_config_file() -> PathBuf {\n    config_dir().join(\"config.toml\")\n}\n\nfn ensure_parent_dir(path: &Path) {\n    if let Some(parent) = path.parent() {\n        if !parent.exists() {\n            std::fs::create_dir_all(parent).ok();\n        }\n    }\n}\n\n#[cfg(test)]\nmod merge_toml_tests {\n    use std::str;\n\n    use super::merge_toml_values;\n    use toml::Value;\n\n    #[test]\n    fn language_toml_map_merges() {\n        const USER: &str = r#\"\n        [[language]]\n        name = \"nix\"\n        test = \"bbb\"\n        indent = { tab-width = 4, unit = \"    \", test = \"aaa\" }\n        \"#;\n\n        let base = include_bytes!(\"../../languages.toml\");\n        let base = str::from_utf8(base).expect(\"Couldn't parse built-in languages config\");\n        let base: Value = toml::from_str(base).expect(\"Couldn't parse built-in languages config\");\n        let user: Value = toml::from_str(USER).unwrap();\n\n        let merged = merge_toml_values(base, user, 3);\n        let languages = merged.get(\"language\").unwrap().as_array().unwrap();\n        let nix = languages\n            .iter()\n            .find(|v| v.get(\"name\").unwrap().as_str().unwrap() == \"nix\")\n            .unwrap();\n        let nix_indent = nix.get(\"indent\").unwrap();\n\n        // We changed tab-width and unit in indent so check them if they are the new values\n        assert_eq!(\n            nix_indent.get(\"tab-width\").unwrap().as_integer().unwrap(),\n            4\n        );\n        assert_eq!(nix_indent.get(\"unit\").unwrap().as_str().unwrap(), \"    \");\n        // We added a new keys, so check them\n        assert_eq!(nix.get(\"test\").unwrap().as_str().unwrap(), \"bbb\");\n        assert_eq!(nix_indent.get(\"test\").unwrap().as_str().unwrap(), \"aaa\");\n        // We didn't change comment-token so it should be same\n        assert_eq!(nix.get(\"comment-token\").unwrap().as_str().unwrap(), \"#\");\n    }\n\n    #[test]\n    fn language_toml_nested_array_merges() {\n        const USER: &str = r#\"\n        [[language]]\n        name = \"typescript\"\n        language-server = { command = \"deno\", args = [\"lsp\"] }\n        \"#;\n\n        let base = include_bytes!(\"../../languages.toml\");\n        let base = str::from_utf8(base).expect(\"Couldn't parse built-in languages config\");\n        let base: Value = toml::from_str(base).expect(\"Couldn't parse built-in languages config\");\n        let user: Value = toml::from_str(USER).unwrap();\n\n        let merged = merge_toml_values(base, user, 3);\n        let languages = merged.get(\"language\").unwrap().as_array().unwrap();\n        let ts = languages\n            .iter()\n            .find(|v| v.get(\"name\").unwrap().as_str().unwrap() == \"typescript\")\n            .unwrap();\n        assert_eq!(\n            ts.get(\"language-server\")\n                .unwrap()\n                .get(\"args\")\n                .unwrap()\n                .as_array()\n                .unwrap(),\n            &vec![Value::String(\"lsp\".into())]\n        )\n    }\n}\n"
  },
  {
    "path": "helix-loader/src/main.rs",
    "content": "use anyhow::Result;\nuse helix_loader::grammar::fetch_grammars;\n\n// This binary is used in the Release CI as an optimization to cut down on\n// compilation time. This is not meant to be run manually.\n\nfn main() -> Result<()> {\n    fetch_grammars()\n}\n"
  },
  {
    "path": "helix-lsp/Cargo.toml",
    "content": "[package]\nname = \"helix-lsp\"\ndescription = \"LSP client implementation for Helix project\"\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\nhelix-stdx = { path = \"../helix-stdx\" }\nhelix-core = { path = \"../helix-core\" }\nhelix-loader = { path = \"../helix-loader\" }\nhelix-lsp-types = { path = \"../helix-lsp-types\" }\n\nanyhow = \"1.0\"\nfutures-executor.workspace = true\nfutures-util.workspace = true\nglobset.workspace = true\nlog = \"0.4\"\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0\"\ntokio = { version = \"1.50\", features = [\"rt\", \"rt-multi-thread\", \"io-util\", \"io-std\", \"time\", \"process\", \"macros\", \"fs\", \"parking_lot\", \"sync\"] }\ntokio-stream.workspace = true\nparking_lot.workspace = true\narc-swap = \"1\"\nslotmap.workspace = true\nthiserror.workspace = true\nsonic-rs.workspace = true\n"
  },
  {
    "path": "helix-lsp/src/client.rs",
    "content": "use crate::{\n    file_operations::FileOperationsInterest,\n    find_lsp_workspace, jsonrpc,\n    transport::{Payload, Transport},\n    Call, Error, LanguageServerId, OffsetEncoding, Result,\n};\nuse log::info;\n\nuse crate::lsp::{\n    self, notification::DidChangeWorkspaceFolders, CodeActionCapabilityResolveSupport,\n    DidChangeWorkspaceFoldersParams, OneOf, PositionEncodingKind, SignatureHelp, Url,\n    WorkspaceFolder, WorkspaceFoldersChangeEvent,\n};\nuse helix_core::{\n    find_workspace,\n    syntax::config::{LanguageServerFeature, RootMarkers},\n    ChangeSet, Rope,\n};\nuse helix_loader::VERSION_AND_GIT_HASH;\nuse helix_stdx::path;\nuse parking_lot::Mutex;\nuse serde::Deserialize;\nuse serde_json::Value;\nuse std::{collections::HashMap, path::PathBuf};\nuse std::{\n    ffi::OsStr,\n    sync::{\n        atomic::{AtomicU64, Ordering},\n        Arc,\n    },\n};\nuse std::{future::Future, sync::OnceLock};\nuse std::{path::Path, process::Stdio};\nuse tokio::{\n    io::{BufReader, BufWriter},\n    process::{Child, Command},\n    sync::{\n        mpsc::{channel, UnboundedReceiver, UnboundedSender},\n        Notify, OnceCell,\n    },\n};\n\nfn workspace_for_uri(uri: lsp::Url) -> WorkspaceFolder {\n    lsp::WorkspaceFolder {\n        name: uri\n            .path_segments()\n            .and_then(|mut segments| segments.next_back())\n            .map(|basename| basename.to_string())\n            .unwrap_or_default(),\n        uri,\n    }\n}\n\n#[derive(Debug)]\npub struct Client {\n    id: LanguageServerId,\n    name: String,\n    _process: Child,\n    server_tx: UnboundedSender<Payload>,\n    request_counter: AtomicU64,\n    pub(crate) capabilities: OnceCell<lsp::ServerCapabilities>,\n    pub(crate) file_operation_interest: OnceLock<FileOperationsInterest>,\n    config: Option<Value>,\n    root_path: std::path::PathBuf,\n    root_uri: Option<lsp::Url>,\n    workspace_folders: Mutex<Vec<lsp::WorkspaceFolder>>,\n    initialize_notify: Arc<Notify>,\n    /// workspace folders added while the server is still initializing\n    req_timeout: u64,\n}\n\nimpl Client {\n    pub fn try_add_doc(\n        self: &Arc<Self>,\n        root_markers: &RootMarkers,\n        manual_roots: &[PathBuf],\n        doc_path: Option<&std::path::PathBuf>,\n        may_support_workspace: bool,\n    ) -> bool {\n        let (workspace, workspace_is_cwd) = find_workspace();\n        let workspace = path::normalize(workspace);\n        let root = find_lsp_workspace(\n            doc_path\n                .and_then(|x| x.parent().and_then(|x| x.to_str()))\n                .unwrap_or(\".\"),\n            root_markers,\n            manual_roots,\n            &workspace,\n            workspace_is_cwd,\n        );\n        let root_uri = root\n            .as_ref()\n            .and_then(|root| lsp::Url::from_file_path(root).ok());\n\n        if self.root_path == root.unwrap_or(workspace)\n            || root_uri.as_ref().is_some_and(|root_uri| {\n                self.workspace_folders\n                    .lock()\n                    .iter()\n                    .any(|workspace| &workspace.uri == root_uri)\n            })\n        {\n            // workspace URI is already registered so we can use this client\n            return true;\n        }\n\n        // this server definitely doesn't support multiple workspace, no need to check capabilities\n        if !may_support_workspace {\n            return false;\n        }\n\n        let Some(capabilities) = self.capabilities.get() else {\n            let client = Arc::clone(self);\n            // initialization hasn't finished yet, deal with this new root later\n            // TODO: In the edgecase that a **new root** is added\n            // for an LSP that **doesn't support workspace_folders** before initaliation is finished\n            // the new roots are ignored.\n            // That particular edgecase would require retroactively spawning new LSP\n            // clients and therefore also require us to retroactively update the corresponding\n            // documents LSP client handle. It's doable but a pretty weird edgecase so let's\n            // wait and see if anyone ever runs into it.\n            tokio::spawn(async move {\n                client.initialize_notify.notified().await;\n                if let Some(workspace_folders_caps) = client\n                    .capabilities()\n                    .workspace\n                    .as_ref()\n                    .and_then(|cap| cap.workspace_folders.as_ref())\n                    .filter(|cap| cap.supported.unwrap_or(false))\n                {\n                    client.add_workspace_folder(\n                        root_uri,\n                        workspace_folders_caps.change_notifications.as_ref(),\n                    );\n                }\n            });\n            return true;\n        };\n\n        if let Some(workspace_folders_caps) = capabilities\n            .workspace\n            .as_ref()\n            .and_then(|cap| cap.workspace_folders.as_ref())\n            .filter(|cap| cap.supported.unwrap_or(false))\n        {\n            self.add_workspace_folder(\n                root_uri,\n                workspace_folders_caps.change_notifications.as_ref(),\n            );\n            true\n        } else {\n            // the server doesn't support multi workspaces, we need a new client\n            false\n        }\n    }\n\n    fn add_workspace_folder(\n        &self,\n        root_uri: Option<lsp::Url>,\n        change_notifications: Option<&OneOf<bool, String>>,\n    ) {\n        // root_uri is None just means that there isn't really any LSP workspace\n        // associated with this file. For servers that support multiple workspaces\n        // there is just one server so we can always just use that shared instance.\n        // No need to add a new workspace root here as there is no logical root for this file\n        // let the server deal with this\n        let Some(root_uri) = root_uri else {\n            return;\n        };\n\n        // server supports workspace folders, let's add the new root to the list\n        self.workspace_folders\n            .lock()\n            .push(workspace_for_uri(root_uri.clone()));\n        if Some(&OneOf::Left(false)) == change_notifications {\n            // server specifically opted out of DidWorkspaceChange notifications\n            // let's assume the server will request the workspace folders itself\n            // and that we can therefore reuse the client (but are done now)\n            return;\n        }\n        self.did_change_workspace(vec![workspace_for_uri(root_uri)], Vec::new())\n    }\n\n    /// Merge FormattingOptions with 'config.format' and return it\n    fn get_merged_formatting_options(\n        &self,\n        options: lsp::FormattingOptions,\n    ) -> lsp::FormattingOptions {\n        let config_format = self\n            .config\n            .as_ref()\n            .and_then(|cfg| cfg.get(\"format\"))\n            .and_then(|fmt| HashMap::<String, lsp::FormattingProperty>::deserialize(fmt).ok());\n\n        if let Some(mut properties) = config_format {\n            // passed in options take precedence over 'config.format'\n            properties.extend(options.properties);\n            lsp::FormattingOptions {\n                properties,\n                ..options\n            }\n        } else {\n            options\n        }\n    }\n\n    #[allow(clippy::type_complexity, clippy::too_many_arguments)]\n    pub fn start(\n        cmd: &str,\n        args: &[String],\n        config: Option<Value>,\n        server_environment: impl IntoIterator<Item = (impl AsRef<OsStr>, impl AsRef<OsStr>)>,\n        root_path: PathBuf,\n        root_uri: Option<lsp::Url>,\n        id: LanguageServerId,\n        name: String,\n        req_timeout: u64,\n    ) -> Result<(\n        Self,\n        UnboundedReceiver<(LanguageServerId, Call)>,\n        Arc<Notify>,\n    )> {\n        info!(\"Starting lsp {name:?} in root {root_path:?}\");\n        // Resolve path to the binary\n        let cmd = helix_stdx::env::which(cmd)?;\n\n        let process = Command::new(cmd)\n            .envs(server_environment)\n            .args(args)\n            .stdin(Stdio::piped())\n            .stdout(Stdio::piped())\n            .stderr(Stdio::piped())\n            .current_dir(&root_path)\n            // make sure the process is reaped on drop\n            .kill_on_drop(true)\n            .spawn();\n\n        let mut process = process?;\n\n        // TODO: do we need bufreader/writer here? or do we use async wrappers on unblock?\n        let writer = BufWriter::new(process.stdin.take().expect(\"Failed to open stdin\"));\n        let reader = BufReader::new(process.stdout.take().expect(\"Failed to open stdout\"));\n        let stderr = BufReader::new(process.stderr.take().expect(\"Failed to open stderr\"));\n\n        let (server_rx, server_tx, initialize_notify) =\n            Transport::start(reader, writer, stderr, id, name.clone());\n\n        let workspace_folders = root_uri\n            .clone()\n            .map(|root| vec![workspace_for_uri(root)])\n            .unwrap_or_default();\n\n        let client = Self {\n            id,\n            name,\n            _process: process,\n            server_tx,\n            request_counter: AtomicU64::new(0),\n            capabilities: OnceCell::new(),\n            file_operation_interest: OnceLock::new(),\n            config,\n            req_timeout,\n            root_path,\n            root_uri,\n            workspace_folders: Mutex::new(workspace_folders),\n            initialize_notify: initialize_notify.clone(),\n        };\n\n        Ok((client, server_rx, initialize_notify))\n    }\n\n    pub fn name(&self) -> &str {\n        &self.name\n    }\n\n    pub fn id(&self) -> LanguageServerId {\n        self.id\n    }\n\n    fn next_request_id(&self) -> jsonrpc::Id {\n        let id = self.request_counter.fetch_add(1, Ordering::Relaxed);\n        jsonrpc::Id::Num(id)\n    }\n\n    fn value_into_params(value: Value) -> jsonrpc::Params {\n        use jsonrpc::Params;\n\n        match value {\n            Value::Null => Params::None,\n            Value::Bool(_) | Value::Number(_) | Value::String(_) => Params::Array(vec![value]),\n            Value::Array(vec) => Params::Array(vec),\n            Value::Object(map) => Params::Map(map),\n        }\n    }\n\n    pub fn is_initialized(&self) -> bool {\n        self.capabilities.get().is_some()\n    }\n\n    pub fn capabilities(&self) -> &lsp::ServerCapabilities {\n        self.capabilities\n            .get()\n            .expect(\"language server not yet initialized!\")\n    }\n\n    pub(crate) fn file_operations_intests(&self) -> &FileOperationsInterest {\n        self.file_operation_interest\n            .get_or_init(|| FileOperationsInterest::new(self.capabilities()))\n    }\n\n    /// Client has to be initialized otherwise this function panics\n    #[inline]\n    pub fn supports_feature(&self, feature: LanguageServerFeature) -> bool {\n        let capabilities = self.capabilities();\n\n        use lsp::*;\n        match feature {\n            LanguageServerFeature::Format => matches!(\n                capabilities.document_formatting_provider,\n                Some(OneOf::Left(true) | OneOf::Right(_))\n            ),\n            LanguageServerFeature::GotoDeclaration => matches!(\n                capabilities.declaration_provider,\n                Some(\n                    DeclarationCapability::Simple(true)\n                        | DeclarationCapability::RegistrationOptions(_)\n                        | DeclarationCapability::Options(_),\n                )\n            ),\n            LanguageServerFeature::GotoDefinition => matches!(\n                capabilities.definition_provider,\n                Some(OneOf::Left(true) | OneOf::Right(_))\n            ),\n            LanguageServerFeature::GotoTypeDefinition => matches!(\n                capabilities.type_definition_provider,\n                Some(\n                    TypeDefinitionProviderCapability::Simple(true)\n                        | TypeDefinitionProviderCapability::Options(_),\n                )\n            ),\n            LanguageServerFeature::GotoReference => matches!(\n                capabilities.references_provider,\n                Some(OneOf::Left(true) | OneOf::Right(_))\n            ),\n            LanguageServerFeature::GotoImplementation => matches!(\n                capabilities.implementation_provider,\n                Some(\n                    ImplementationProviderCapability::Simple(true)\n                        | ImplementationProviderCapability::Options(_),\n                )\n            ),\n            LanguageServerFeature::SignatureHelp => capabilities.signature_help_provider.is_some(),\n            LanguageServerFeature::Hover => matches!(\n                capabilities.hover_provider,\n                Some(HoverProviderCapability::Simple(true) | HoverProviderCapability::Options(_),)\n            ),\n            LanguageServerFeature::DocumentHighlight => matches!(\n                capabilities.document_highlight_provider,\n                Some(OneOf::Left(true) | OneOf::Right(_))\n            ),\n            LanguageServerFeature::Completion => capabilities.completion_provider.is_some(),\n            LanguageServerFeature::CodeAction => matches!(\n                capabilities.code_action_provider,\n                Some(\n                    CodeActionProviderCapability::Simple(true)\n                        | CodeActionProviderCapability::Options(_),\n                )\n            ),\n            LanguageServerFeature::DocumentLinks => capabilities.document_link_provider.is_some(),\n            LanguageServerFeature::WorkspaceCommand => {\n                capabilities.execute_command_provider.is_some()\n            }\n            LanguageServerFeature::DocumentSymbols => matches!(\n                capabilities.document_symbol_provider,\n                Some(OneOf::Left(true) | OneOf::Right(_))\n            ),\n            LanguageServerFeature::WorkspaceSymbols => matches!(\n                capabilities.workspace_symbol_provider,\n                Some(OneOf::Left(true) | OneOf::Right(_))\n            ),\n            LanguageServerFeature::Diagnostics => true, // there's no extra server capability\n            LanguageServerFeature::PullDiagnostics => capabilities.diagnostic_provider.is_some(),\n            LanguageServerFeature::RenameSymbol => matches!(\n                capabilities.rename_provider,\n                Some(OneOf::Left(true)) | Some(OneOf::Right(_))\n            ),\n            LanguageServerFeature::InlayHints => matches!(\n                capabilities.inlay_hint_provider,\n                Some(OneOf::Left(true) | OneOf::Right(InlayHintServerCapabilities::Options(_)))\n            ),\n            LanguageServerFeature::DocumentColors => matches!(\n                capabilities.color_provider,\n                Some(\n                    ColorProviderCapability::Simple(true)\n                        | ColorProviderCapability::ColorProvider(_)\n                        | ColorProviderCapability::Options(_)\n                )\n            ),\n            LanguageServerFeature::CallHierarchy => matches!(\n                capabilities.call_hierarchy_provider,\n                Some(\n                    CallHierarchyServerCapability::Simple(true)\n                        | CallHierarchyServerCapability::Options(_)\n                )\n            ),\n        }\n    }\n\n    pub fn offset_encoding(&self) -> OffsetEncoding {\n        self.capabilities()\n            .position_encoding\n            .as_ref()\n            .and_then(|encoding| match encoding.as_str() {\n                \"utf-8\" => Some(OffsetEncoding::Utf8),\n                \"utf-16\" => Some(OffsetEncoding::Utf16),\n                \"utf-32\" => Some(OffsetEncoding::Utf32),\n                encoding => {\n                    log::error!(\"Server provided invalid position encoding {encoding}, defaulting to utf-16\");\n                    None\n                },\n            })\n            .unwrap_or_default()\n    }\n\n    pub fn config(&self) -> Option<&Value> {\n        self.config.as_ref()\n    }\n\n    pub async fn workspace_folders(\n        &self,\n    ) -> parking_lot::MutexGuard<'_, Vec<lsp::WorkspaceFolder>> {\n        self.workspace_folders.lock()\n    }\n\n    /// Execute a RPC request on the language server.\n    fn call<R: lsp::request::Request>(\n        &self,\n        params: R::Params,\n    ) -> impl Future<Output = Result<R::Result>>\n    where\n        R::Params: serde::Serialize,\n    {\n        self.call_with_ref::<R>(&params)\n    }\n\n    fn call_with_ref<R: lsp::request::Request>(\n        &self,\n        params: &R::Params,\n    ) -> impl Future<Output = Result<R::Result>>\n    where\n        R::Params: serde::Serialize,\n    {\n        self.call_with_timeout::<R>(params, self.req_timeout)\n    }\n\n    fn call_with_timeout<R: lsp::request::Request>(\n        &self,\n        params: &R::Params,\n        timeout_secs: u64,\n    ) -> impl Future<Output = Result<R::Result>>\n    where\n        R::Params: serde::Serialize,\n    {\n        let server_tx = self.server_tx.clone();\n        let id = self.next_request_id();\n\n        // It's important that this is not part of the future so that it gets executed right away\n        // and the request order stays consistent.\n        let rx = serde_json::to_value(params)\n            .map_err(Error::from)\n            .and_then(|params| {\n                let request = jsonrpc::MethodCall {\n                    jsonrpc: Some(jsonrpc::Version::V2),\n                    id: id.clone(),\n                    method: R::METHOD.to_string(),\n                    params: Self::value_into_params(params),\n                };\n                let (tx, rx) = channel::<Result<Value>>(1);\n                server_tx\n                    .send(Payload::Request {\n                        chan: tx,\n                        value: request,\n                    })\n                    .map_err(|e| Error::Other(e.into()))?;\n                Ok(rx)\n            });\n\n        async move {\n            use std::time::Duration;\n            use tokio::time::timeout;\n            // TODO: delay other calls until initialize success\n            timeout(Duration::from_secs(timeout_secs), rx?.recv())\n                .await\n                .map_err(|_| Error::Timeout(id))? // return Timeout\n                .ok_or(Error::StreamClosed)?\n                .and_then(|value| serde_json::from_value(value).map_err(Into::into))\n        }\n    }\n\n    /// Send a RPC notification to the language server.\n    pub fn notify<R: lsp::notification::Notification>(&self, params: R::Params)\n    where\n        R::Params: serde::Serialize,\n    {\n        let server_tx = self.server_tx.clone();\n\n        let params = match serde_json::to_value(params) {\n            Ok(params) => params,\n            Err(err) => {\n                log::error!(\n                    \"Failed to serialize params for notification '{}' for server '{}': {err}\",\n                    R::METHOD,\n                    self.name,\n                );\n                return;\n            }\n        };\n\n        let notification = jsonrpc::Notification {\n            jsonrpc: Some(jsonrpc::Version::V2),\n            method: R::METHOD.to_string(),\n            params: Self::value_into_params(params),\n        };\n\n        if let Err(err) = server_tx.send(Payload::Notification(notification)) {\n            log::error!(\n                \"Failed to send notification '{}' to server '{}': {err}\",\n                R::METHOD,\n                self.name\n            );\n        }\n    }\n\n    /// Reply to a language server RPC call.\n    pub fn reply(\n        &self,\n        id: jsonrpc::Id,\n        result: core::result::Result<Value, jsonrpc::Error>,\n    ) -> Result<()> {\n        use jsonrpc::{Failure, Output, Success, Version};\n\n        let server_tx = self.server_tx.clone();\n\n        let output = match result {\n            Ok(result) => Output::Success(Success {\n                jsonrpc: Some(Version::V2),\n                id,\n                result,\n            }),\n            Err(error) => Output::Failure(Failure {\n                jsonrpc: Some(Version::V2),\n                id,\n                error,\n            }),\n        };\n\n        server_tx\n            .send(Payload::Response(output))\n            .map_err(|e| Error::Other(e.into()))?;\n\n        Ok(())\n    }\n\n    // -------------------------------------------------------------------------------------------\n    // General messages\n    // -------------------------------------------------------------------------------------------\n\n    pub(crate) async fn initialize(&self, enable_snippets: bool) -> Result<lsp::InitializeResult> {\n        if let Some(config) = &self.config {\n            log::info!(\"Using custom LSP config: {}\", config);\n        }\n\n        #[allow(deprecated)]\n        let params = lsp::InitializeParams {\n            process_id: Some(std::process::id()),\n            workspace_folders: Some(self.workspace_folders.lock().clone()),\n            // root_path is obsolete, but some clients like pyright still use it so we specify both.\n            // clients will prefer _uri if possible\n            root_path: self.root_path.to_str().map(|path| path.to_owned()),\n            root_uri: self.root_uri.clone(),\n            initialization_options: self.config.clone(),\n            capabilities: lsp::ClientCapabilities {\n                workspace: Some(lsp::WorkspaceClientCapabilities {\n                    configuration: Some(true),\n                    did_change_configuration: Some(lsp::DynamicRegistrationClientCapabilities {\n                        dynamic_registration: Some(false),\n                    }),\n                    workspace_folders: Some(true),\n                    apply_edit: Some(true),\n                    symbol: Some(lsp::WorkspaceSymbolClientCapabilities {\n                        dynamic_registration: Some(false),\n                        ..Default::default()\n                    }),\n                    execute_command: Some(lsp::DynamicRegistrationClientCapabilities {\n                        dynamic_registration: Some(false),\n                    }),\n                    inlay_hint: Some(lsp::InlayHintWorkspaceClientCapabilities {\n                        refresh_support: Some(false),\n                    }),\n                    workspace_edit: Some(lsp::WorkspaceEditClientCapabilities {\n                        document_changes: Some(true),\n                        resource_operations: Some(vec![\n                            lsp::ResourceOperationKind::Create,\n                            lsp::ResourceOperationKind::Rename,\n                            lsp::ResourceOperationKind::Delete,\n                        ]),\n                        failure_handling: Some(lsp::FailureHandlingKind::Abort),\n                        normalizes_line_endings: Some(false),\n                        change_annotation_support: None,\n                    }),\n                    did_change_watched_files: Some(lsp::DidChangeWatchedFilesClientCapabilities {\n                        dynamic_registration: Some(true),\n                        relative_pattern_support: Some(true),\n                    }),\n                    file_operations: Some(lsp::WorkspaceFileOperationsClientCapabilities {\n                        will_rename: Some(true),\n                        did_rename: Some(true),\n                        ..Default::default()\n                    }),\n                    diagnostic: Some(lsp::DiagnosticWorkspaceClientCapabilities {\n                        refresh_support: Some(true),\n                    }),\n                    ..Default::default()\n                }),\n                text_document: Some(lsp::TextDocumentClientCapabilities {\n                    completion: Some(lsp::CompletionClientCapabilities {\n                        completion_item: Some(lsp::CompletionItemCapability {\n                            snippet_support: Some(enable_snippets),\n                            resolve_support: Some(lsp::CompletionItemCapabilityResolveSupport {\n                                properties: vec![\n                                    String::from(\"documentation\"),\n                                    String::from(\"detail\"),\n                                    String::from(\"additionalTextEdits\"),\n                                ],\n                            }),\n                            insert_replace_support: Some(true),\n                            deprecated_support: Some(true),\n                            tag_support: Some(lsp::TagSupport {\n                                value_set: vec![lsp::CompletionItemTag::DEPRECATED],\n                            }),\n                            ..Default::default()\n                        }),\n                        completion_item_kind: Some(lsp::CompletionItemKindCapability {\n                            ..Default::default()\n                        }),\n                        context_support: None, // additional context information Some(true)\n                        ..Default::default()\n                    }),\n                    hover: Some(lsp::HoverClientCapabilities {\n                        // if not specified, rust-analyzer returns plaintext marked as markdown but\n                        // badly formatted.\n                        content_format: Some(vec![lsp::MarkupKind::Markdown]),\n                        ..Default::default()\n                    }),\n                    signature_help: Some(lsp::SignatureHelpClientCapabilities {\n                        signature_information: Some(lsp::SignatureInformationSettings {\n                            documentation_format: Some(vec![lsp::MarkupKind::Markdown]),\n                            parameter_information: Some(lsp::ParameterInformationSettings {\n                                label_offset_support: Some(true),\n                            }),\n                            active_parameter_support: Some(true),\n                        }),\n                        ..Default::default()\n                    }),\n                    rename: Some(lsp::RenameClientCapabilities {\n                        dynamic_registration: Some(false),\n                        prepare_support: Some(true),\n                        prepare_support_default_behavior: None,\n                        honors_change_annotations: Some(false),\n                    }),\n                    formatting: Some(lsp::DocumentFormattingClientCapabilities {\n                        dynamic_registration: Some(false),\n                    }),\n                    code_action: Some(lsp::CodeActionClientCapabilities {\n                        code_action_literal_support: Some(lsp::CodeActionLiteralSupport {\n                            code_action_kind: lsp::CodeActionKindLiteralSupport {\n                                value_set: [\n                                    lsp::CodeActionKind::EMPTY,\n                                    lsp::CodeActionKind::QUICKFIX,\n                                    lsp::CodeActionKind::REFACTOR,\n                                    lsp::CodeActionKind::REFACTOR_EXTRACT,\n                                    lsp::CodeActionKind::REFACTOR_INLINE,\n                                    lsp::CodeActionKind::REFACTOR_REWRITE,\n                                    lsp::CodeActionKind::SOURCE,\n                                    lsp::CodeActionKind::SOURCE_ORGANIZE_IMPORTS,\n                                    lsp::CodeActionKind::SOURCE_FIX_ALL,\n                                ]\n                                .iter()\n                                .map(|kind| kind.as_str().to_string())\n                                .collect(),\n                            },\n                        }),\n                        is_preferred_support: Some(true),\n                        disabled_support: Some(true),\n                        data_support: Some(true),\n                        resolve_support: Some(CodeActionCapabilityResolveSupport {\n                            properties: vec![\"edit\".to_owned(), \"command\".to_owned()],\n                        }),\n                        ..Default::default()\n                    }),\n                    diagnostic: Some(lsp::DiagnosticClientCapabilities {\n                        dynamic_registration: Some(false),\n                        related_document_support: Some(true),\n                    }),\n                    publish_diagnostics: Some(lsp::PublishDiagnosticsClientCapabilities {\n                        version_support: Some(true),\n                        tag_support: Some(lsp::TagSupport {\n                            value_set: vec![\n                                lsp::DiagnosticTag::UNNECESSARY,\n                                lsp::DiagnosticTag::DEPRECATED,\n                            ],\n                        }),\n                        ..Default::default()\n                    }),\n                    inlay_hint: Some(lsp::InlayHintClientCapabilities {\n                        dynamic_registration: Some(false),\n                        resolve_support: None,\n                    }),\n                    document_link: Some(lsp::DocumentLinkClientCapabilities {\n                        dynamic_registration: Some(false),\n                        tooltip_support: Some(false),\n                    }),\n                    call_hierarchy: Some(lsp::DynamicRegistrationClientCapabilities {\n                        dynamic_registration: Some(false),\n                    }),\n                    ..Default::default()\n                }),\n                window: Some(lsp::WindowClientCapabilities {\n                    show_message: Some(lsp::ShowMessageRequestClientCapabilities {\n                        message_action_item: Some(lsp::MessageActionItemCapabilities {\n                            additional_properties_support: Some(true),\n                        }),\n                    }),\n                    work_done_progress: Some(true),\n                    show_document: Some(lsp::ShowDocumentClientCapabilities { support: true }),\n                }),\n                general: Some(lsp::GeneralClientCapabilities {\n                    position_encodings: Some(vec![\n                        PositionEncodingKind::UTF8,\n                        PositionEncodingKind::UTF32,\n                        PositionEncodingKind::UTF16,\n                    ]),\n                    ..Default::default()\n                }),\n                ..Default::default()\n            },\n            trace: None,\n            client_info: Some(lsp::ClientInfo {\n                name: String::from(\"helix\"),\n                version: Some(String::from(VERSION_AND_GIT_HASH)),\n            }),\n            locale: None, // TODO\n            work_done_progress_params: lsp::WorkDoneProgressParams::default(),\n        };\n\n        self.call::<lsp::request::Initialize>(params).await\n    }\n\n    pub async fn shutdown(&self) -> Result<()> {\n        self.call::<lsp::request::Shutdown>(()).await\n    }\n\n    pub fn exit(&self) {\n        self.notify::<lsp::notification::Exit>(())\n    }\n\n    /// Tries to shut down the language server but returns\n    /// early if server responds with an error.\n    pub async fn shutdown_and_exit(&self) -> Result<()> {\n        self.shutdown().await?;\n        self.exit();\n        Ok(())\n    }\n\n    /// Forcefully shuts down the language server ignoring any errors.\n    pub async fn force_shutdown(&self) -> Result<()> {\n        if let Err(e) = self.shutdown().await {\n            log::warn!(\"language server failed to terminate gracefully - {}\", e);\n        }\n        self.exit();\n        Ok(())\n    }\n\n    // -------------------------------------------------------------------------------------------\n    // Workspace\n    // -------------------------------------------------------------------------------------------\n\n    pub fn did_change_configuration(&self, settings: Value) {\n        self.notify::<lsp::notification::DidChangeConfiguration>(\n            lsp::DidChangeConfigurationParams { settings },\n        )\n    }\n\n    pub fn did_change_workspace(&self, added: Vec<WorkspaceFolder>, removed: Vec<WorkspaceFolder>) {\n        self.notify::<DidChangeWorkspaceFolders>(DidChangeWorkspaceFoldersParams {\n            event: WorkspaceFoldersChangeEvent { added, removed },\n        })\n    }\n\n    pub fn will_rename(\n        &self,\n        old_path: &Path,\n        new_path: &Path,\n        is_dir: bool,\n    ) -> Option<impl Future<Output = Result<Option<lsp::WorkspaceEdit>>>> {\n        let capabilities = self.file_operations_intests();\n        if !capabilities.will_rename.has_interest(old_path, is_dir) {\n            return None;\n        }\n        let url_from_path = |path| {\n            let url = if is_dir {\n                Url::from_directory_path(path)\n            } else {\n                Url::from_file_path(path)\n            };\n            Some(url.ok()?.to_string())\n        };\n        let files = vec![lsp::FileRename {\n            old_uri: url_from_path(old_path)?,\n            new_uri: url_from_path(new_path)?,\n        }];\n        Some(self.call_with_timeout::<lsp::request::WillRenameFiles>(\n            &lsp::RenameFilesParams { files },\n            5,\n        ))\n    }\n\n    pub fn did_rename(&self, old_path: &Path, new_path: &Path, is_dir: bool) -> Option<()> {\n        let capabilities = self.file_operations_intests();\n        if !capabilities.did_rename.has_interest(new_path, is_dir) {\n            return None;\n        }\n        let url_from_path = |path| {\n            let url = if is_dir {\n                Url::from_directory_path(path)\n            } else {\n                Url::from_file_path(path)\n            };\n            Some(url.ok()?.to_string())\n        };\n\n        let files = vec![lsp::FileRename {\n            old_uri: url_from_path(old_path)?,\n            new_uri: url_from_path(new_path)?,\n        }];\n        self.notify::<lsp::notification::DidRenameFiles>(lsp::RenameFilesParams { files });\n        Some(())\n    }\n\n    // -------------------------------------------------------------------------------------------\n    // Text document\n    // -------------------------------------------------------------------------------------------\n\n    pub fn text_document_did_open(\n        &self,\n        uri: lsp::Url,\n        version: i32,\n        doc: &Rope,\n        language_id: String,\n    ) {\n        self.notify::<lsp::notification::DidOpenTextDocument>(lsp::DidOpenTextDocumentParams {\n            text_document: lsp::TextDocumentItem {\n                uri,\n                language_id,\n                version,\n                text: String::from(doc),\n            },\n        })\n    }\n\n    pub fn changeset_to_changes(\n        old_text: &Rope,\n        new_text: &Rope,\n        changeset: &ChangeSet,\n        offset_encoding: OffsetEncoding,\n    ) -> Vec<lsp::TextDocumentContentChangeEvent> {\n        let mut iter = changeset.changes().iter().peekable();\n        let mut old_pos = 0;\n        let mut new_pos = 0;\n\n        let mut changes = Vec::new();\n\n        use crate::util::pos_to_lsp_pos;\n        use helix_core::Operation::*;\n\n        // this is dumb. TextEdit describes changes to the initial doc (concurrent), but\n        // TextDocumentContentChangeEvent describes a series of changes (sequential).\n        // So S -> S1 -> S2, meaning positioning depends on the previous edits.\n        //\n        // Calculation is therefore a bunch trickier.\n\n        use helix_core::RopeSlice;\n        fn traverse(\n            pos: lsp::Position,\n            text: RopeSlice,\n            offset_encoding: OffsetEncoding,\n        ) -> lsp::Position {\n            let lsp::Position {\n                mut line,\n                mut character,\n            } = pos;\n\n            let mut chars = text.chars().peekable();\n            while let Some(ch) = chars.next() {\n                // LSP only considers \\n, \\r or \\r\\n as line endings\n                if ch == '\\n' || ch == '\\r' {\n                    // consume a \\r\\n\n                    if ch == '\\r' && chars.peek() == Some(&'\\n') {\n                        chars.next();\n                    }\n                    line += 1;\n                    character = 0;\n                } else {\n                    character += match offset_encoding {\n                        OffsetEncoding::Utf8 => ch.len_utf8() as u32,\n                        OffsetEncoding::Utf16 => ch.len_utf16() as u32,\n                        OffsetEncoding::Utf32 => 1,\n                    };\n                }\n            }\n            lsp::Position { line, character }\n        }\n\n        let old_text = old_text.slice(..);\n\n        while let Some(change) = iter.next() {\n            let len = match change {\n                Delete(i) | Retain(i) => *i,\n                Insert(_) => 0,\n            };\n            let mut old_end = old_pos + len;\n\n            match change {\n                Retain(i) => {\n                    new_pos += i;\n                }\n                Delete(_) => {\n                    let start = pos_to_lsp_pos(new_text, new_pos, offset_encoding);\n                    let end = traverse(start, old_text.slice(old_pos..old_end), offset_encoding);\n\n                    // deletion\n                    changes.push(lsp::TextDocumentContentChangeEvent {\n                        range: Some(lsp::Range::new(start, end)),\n                        text: \"\".to_string(),\n                        range_length: None,\n                    });\n                }\n                Insert(s) => {\n                    let start = pos_to_lsp_pos(new_text, new_pos, offset_encoding);\n\n                    new_pos += s.chars().count();\n\n                    // a subsequent delete means a replace, consume it\n                    let end = if let Some(Delete(len)) = iter.peek() {\n                        old_end = old_pos + len;\n                        let end =\n                            traverse(start, old_text.slice(old_pos..old_end), offset_encoding);\n\n                        iter.next();\n\n                        // replacement\n                        end\n                    } else {\n                        // insert\n                        start\n                    };\n\n                    changes.push(lsp::TextDocumentContentChangeEvent {\n                        range: Some(lsp::Range::new(start, end)),\n                        text: s.to_string(),\n                        range_length: None,\n                    });\n                }\n            }\n            old_pos = old_end;\n        }\n\n        changes\n    }\n\n    pub fn text_document_did_change(\n        &self,\n        text_document: lsp::VersionedTextDocumentIdentifier,\n        old_text: &Rope,\n        new_text: &Rope,\n        changes: &ChangeSet,\n    ) -> Option<()> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support document sync.\n        let sync_capabilities = match capabilities.text_document_sync {\n            Some(\n                lsp::TextDocumentSyncCapability::Kind(kind)\n                | lsp::TextDocumentSyncCapability::Options(lsp::TextDocumentSyncOptions {\n                    change: Some(kind),\n                    ..\n                }),\n            ) => kind,\n            // None | SyncOptions { changes: None }\n            _ => return None,\n        };\n\n        let changes = match sync_capabilities {\n            lsp::TextDocumentSyncKind::FULL => {\n                vec![lsp::TextDocumentContentChangeEvent {\n                    // range = None -> whole document\n                    range: None,        //Some(Range)\n                    range_length: None, // u64 apparently deprecated\n                    text: new_text.to_string(),\n                }]\n            }\n            lsp::TextDocumentSyncKind::INCREMENTAL => {\n                Self::changeset_to_changes(old_text, new_text, changes, self.offset_encoding())\n            }\n            lsp::TextDocumentSyncKind::NONE => return None,\n            kind => unimplemented!(\"{:?}\", kind),\n        };\n\n        self.notify::<lsp::notification::DidChangeTextDocument>(lsp::DidChangeTextDocumentParams {\n            text_document,\n            content_changes: changes,\n        });\n        Some(())\n    }\n\n    pub fn text_document_did_close(&self, text_document: lsp::TextDocumentIdentifier) {\n        self.notify::<lsp::notification::DidCloseTextDocument>(lsp::DidCloseTextDocumentParams {\n            text_document,\n        })\n    }\n\n    // will_save / will_save_wait_until\n\n    pub fn text_document_did_save(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        text: &Rope,\n    ) -> Option<()> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        let include_text = match &capabilities.text_document_sync.as_ref()? {\n            lsp::TextDocumentSyncCapability::Options(lsp::TextDocumentSyncOptions {\n                save: options,\n                ..\n            }) => match options.as_ref()? {\n                lsp::TextDocumentSyncSaveOptions::Supported(true) => false,\n                lsp::TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {\n                    include_text,\n                }) => include_text.unwrap_or(false),\n                lsp::TextDocumentSyncSaveOptions::Supported(false) => return None,\n            },\n            // see: https://github.com/microsoft/language-server-protocol/issues/288\n            lsp::TextDocumentSyncCapability::Kind(..) => false,\n        };\n\n        self.notify::<lsp::notification::DidSaveTextDocument>(lsp::DidSaveTextDocumentParams {\n            text_document,\n            text: include_text.then_some(text.into()),\n        });\n        Some(())\n    }\n\n    pub fn completion(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        work_done_token: Option<lsp::ProgressToken>,\n        context: lsp::CompletionContext,\n    ) -> Option<impl Future<Output = Result<Option<lsp::CompletionResponse>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support completion.\n        capabilities.completion_provider.as_ref()?;\n\n        let params = lsp::CompletionParams {\n            text_document_position: lsp::TextDocumentPositionParams {\n                text_document,\n                position,\n            },\n            context: Some(context),\n            // TODO: support these tokens by async receiving and updating the choice list\n            work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },\n            partial_result_params: lsp::PartialResultParams {\n                partial_result_token: None,\n            },\n        };\n\n        Some(self.call::<lsp::request::Completion>(params))\n    }\n\n    pub fn resolve_completion_item(\n        &self,\n        completion_item: &lsp::CompletionItem,\n    ) -> impl Future<Output = Result<lsp::CompletionItem>> {\n        self.call_with_ref::<lsp::request::ResolveCompletionItem>(completion_item)\n    }\n\n    pub fn resolve_code_action(\n        &self,\n        code_action: &lsp::CodeAction,\n    ) -> Option<impl Future<Output = Result<lsp::CodeAction>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support resolving code actions.\n        match capabilities.code_action_provider {\n            Some(lsp::CodeActionProviderCapability::Options(lsp::CodeActionOptions {\n                resolve_provider: Some(true),\n                ..\n            })) => (),\n            _ => return None,\n        }\n\n        Some(self.call_with_ref::<lsp::request::CodeActionResolveRequest>(code_action))\n    }\n\n    pub fn text_document_signature_help(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<SignatureHelp>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support signature help.\n        capabilities.signature_help_provider.as_ref()?;\n\n        let params = lsp::SignatureHelpParams {\n            text_document_position_params: lsp::TextDocumentPositionParams {\n                text_document,\n                position,\n            },\n            work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },\n            context: None,\n            // lsp::SignatureHelpContext\n        };\n\n        Some(self.call::<lsp::request::SignatureHelpRequest>(params))\n    }\n\n    pub fn text_document_range_inlay_hints(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        range: lsp::Range,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<Vec<lsp::InlayHint>>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        match capabilities.inlay_hint_provider {\n            Some(\n                lsp::OneOf::Left(true)\n                | lsp::OneOf::Right(lsp::InlayHintServerCapabilities::Options(_)),\n            ) => (),\n            _ => return None,\n        }\n\n        let params = lsp::InlayHintParams {\n            text_document,\n            range,\n            work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },\n        };\n\n        Some(self.call::<lsp::request::InlayHintRequest>(params))\n    }\n\n    pub fn text_document_document_color(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Vec<lsp::ColorInformation>>>> {\n        self.capabilities.get().unwrap().color_provider.as_ref()?;\n        let params = lsp::DocumentColorParams {\n            text_document,\n            work_done_progress_params: lsp::WorkDoneProgressParams {\n                work_done_token: work_done_token.clone(),\n            },\n            partial_result_params: helix_lsp_types::PartialResultParams {\n                partial_result_token: work_done_token,\n            },\n        };\n\n        Some(self.call::<lsp::request::DocumentColor>(params))\n    }\n\n    pub fn text_document_document_link(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<Vec<lsp::DocumentLink>>>>> {\n        if !self.supports_feature(LanguageServerFeature::DocumentLinks) {\n            return None;\n        }\n\n        let params = lsp::DocumentLinkParams {\n            text_document,\n            work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },\n            partial_result_params: lsp::PartialResultParams::default(),\n        };\n\n        Some(self.call::<lsp::request::DocumentLinkRequest>(params))\n    }\n\n    pub fn resolve_document_link(\n        &self,\n        params: lsp::DocumentLink,\n    ) -> Option<impl Future<Output = Result<lsp::DocumentLink>>> {\n        if !self.supports_feature(LanguageServerFeature::DocumentLinks) {\n            return None;\n        }\n\n        Some(self.call::<lsp::request::DocumentLinkResolve>(params))\n    }\n\n    pub fn text_document_hover(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<lsp::Hover>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support hover.\n        match capabilities.hover_provider {\n            Some(\n                lsp::HoverProviderCapability::Simple(true)\n                | lsp::HoverProviderCapability::Options(_),\n            ) => (),\n            _ => return None,\n        }\n\n        let params = lsp::HoverParams {\n            text_document_position_params: lsp::TextDocumentPositionParams {\n                text_document,\n                position,\n            },\n            work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },\n            // lsp::SignatureHelpContext\n        };\n\n        Some(self.call::<lsp::request::HoverRequest>(params))\n    }\n\n    // formatting\n\n    pub fn text_document_formatting(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        options: lsp::FormattingOptions,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<Vec<lsp::TextEdit>>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support formatting.\n        match capabilities.document_formatting_provider {\n            Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) => (),\n            _ => return None,\n        };\n\n        let options = self.get_merged_formatting_options(options);\n\n        let params = lsp::DocumentFormattingParams {\n            text_document,\n            options,\n            work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },\n        };\n\n        Some(self.call::<lsp::request::Formatting>(params))\n    }\n\n    pub fn text_document_range_formatting(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        range: lsp::Range,\n        options: lsp::FormattingOptions,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<Vec<lsp::TextEdit>>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support range formatting.\n        match capabilities.document_range_formatting_provider {\n            Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) => (),\n            _ => return None,\n        };\n\n        let options = self.get_merged_formatting_options(options);\n\n        let params = lsp::DocumentRangeFormattingParams {\n            text_document,\n            range,\n            options,\n            work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },\n        };\n\n        Some(self.call::<lsp::request::RangeFormatting>(params))\n    }\n\n    pub fn text_document_diagnostic(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        previous_result_id: Option<String>,\n    ) -> Option<impl Future<Output = Result<lsp::DocumentDiagnosticReportResult>>> {\n        let capabilities = self.capabilities();\n\n        // Return early if the server does not support pull diagnostic.\n        let identifier = match capabilities.diagnostic_provider.as_ref()? {\n            lsp::DiagnosticServerCapabilities::Options(cap) => cap.identifier.clone(),\n            lsp::DiagnosticServerCapabilities::RegistrationOptions(cap) => {\n                cap.diagnostic_options.identifier.clone()\n            }\n        };\n\n        let params = lsp::DocumentDiagnosticParams {\n            text_document,\n            identifier,\n            previous_result_id,\n            work_done_progress_params: lsp::WorkDoneProgressParams::default(),\n            partial_result_params: lsp::PartialResultParams::default(),\n        };\n\n        Some(self.call::<lsp::request::DocumentDiagnosticRequest>(params))\n    }\n\n    pub fn text_document_document_highlight(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<Vec<lsp::DocumentHighlight>>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support document highlight.\n        match capabilities.document_highlight_provider {\n            Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) => (),\n            _ => return None,\n        }\n\n        let params = lsp::DocumentHighlightParams {\n            text_document_position_params: lsp::TextDocumentPositionParams {\n                text_document,\n                position,\n            },\n            work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },\n            partial_result_params: lsp::PartialResultParams {\n                partial_result_token: None,\n            },\n        };\n\n        Some(self.call::<lsp::request::DocumentHighlightRequest>(params))\n    }\n\n    fn goto_request<\n        T: lsp::request::Request<\n            Params = lsp::GotoDefinitionParams,\n            Result = Option<lsp::GotoDefinitionResponse>,\n        >,\n    >(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> impl Future<Output = Result<T::Result>> {\n        let params = lsp::GotoDefinitionParams {\n            text_document_position_params: lsp::TextDocumentPositionParams {\n                text_document,\n                position,\n            },\n            work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },\n            partial_result_params: lsp::PartialResultParams {\n                partial_result_token: None,\n            },\n        };\n\n        self.call::<T>(params)\n    }\n\n    pub fn goto_definition(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<lsp::GotoDefinitionResponse>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support goto-definition.\n        match capabilities.definition_provider {\n            Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) => (),\n            _ => return None,\n        }\n\n        Some(self.goto_request::<lsp::request::GotoDefinition>(\n            text_document,\n            position,\n            work_done_token,\n        ))\n    }\n\n    pub fn goto_declaration(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<lsp::GotoDefinitionResponse>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support goto-declaration.\n        match capabilities.declaration_provider {\n            Some(\n                lsp::DeclarationCapability::Simple(true)\n                | lsp::DeclarationCapability::RegistrationOptions(_)\n                | lsp::DeclarationCapability::Options(_),\n            ) => (),\n            _ => return None,\n        }\n\n        Some(self.goto_request::<lsp::request::GotoDeclaration>(\n            text_document,\n            position,\n            work_done_token,\n        ))\n    }\n\n    pub fn goto_type_definition(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<lsp::GotoDefinitionResponse>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support goto-type-definition.\n        match capabilities.type_definition_provider {\n            Some(\n                lsp::TypeDefinitionProviderCapability::Simple(true)\n                | lsp::TypeDefinitionProviderCapability::Options(_),\n            ) => (),\n            _ => return None,\n        }\n\n        Some(self.goto_request::<lsp::request::GotoTypeDefinition>(\n            text_document,\n            position,\n            work_done_token,\n        ))\n    }\n\n    pub fn goto_implementation(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<lsp::GotoDefinitionResponse>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support goto-definition.\n        match capabilities.implementation_provider {\n            Some(\n                lsp::ImplementationProviderCapability::Simple(true)\n                | lsp::ImplementationProviderCapability::Options(_),\n            ) => (),\n            _ => return None,\n        }\n\n        Some(self.goto_request::<lsp::request::GotoImplementation>(\n            text_document,\n            position,\n            work_done_token,\n        ))\n    }\n\n    pub fn goto_reference(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        include_declaration: bool,\n        work_done_token: Option<lsp::ProgressToken>,\n    ) -> Option<impl Future<Output = Result<Option<Vec<lsp::Location>>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support goto-reference.\n        match capabilities.references_provider {\n            Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) => (),\n            _ => return None,\n        }\n\n        let params = lsp::ReferenceParams {\n            text_document_position: lsp::TextDocumentPositionParams {\n                text_document,\n                position,\n            },\n            context: lsp::ReferenceContext {\n                include_declaration,\n            },\n            work_done_progress_params: lsp::WorkDoneProgressParams { work_done_token },\n            partial_result_params: lsp::PartialResultParams {\n                partial_result_token: None,\n            },\n        };\n\n        Some(self.call::<lsp::request::References>(params))\n    }\n\n    pub fn document_symbols(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n    ) -> Option<impl Future<Output = Result<Option<lsp::DocumentSymbolResponse>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support document symbols.\n        match capabilities.document_symbol_provider {\n            Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) => (),\n            _ => return None,\n        }\n\n        let params = lsp::DocumentSymbolParams {\n            text_document,\n            work_done_progress_params: lsp::WorkDoneProgressParams::default(),\n            partial_result_params: lsp::PartialResultParams::default(),\n        };\n\n        Some(self.call::<lsp::request::DocumentSymbolRequest>(params))\n    }\n\n    pub fn prepare_call_hierarchy(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n    ) -> Option<impl Future<Output = Result<Option<Vec<lsp::CallHierarchyItem>>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        match capabilities.call_hierarchy_provider {\n            Some(\n                lsp::CallHierarchyServerCapability::Simple(true)\n                | lsp::CallHierarchyServerCapability::Options(_),\n            ) => (),\n            _ => return None,\n        }\n\n        let params = lsp::CallHierarchyPrepareParams {\n            text_document_position_params: lsp::TextDocumentPositionParams {\n                text_document,\n                position,\n            },\n            work_done_progress_params: lsp::WorkDoneProgressParams::default(),\n        };\n\n        Some(self.call::<lsp::request::CallHierarchyPrepare>(params))\n    }\n\n    pub fn call_hierarchy_incoming(\n        &self,\n        item: lsp::CallHierarchyItem,\n    ) -> Option<impl Future<Output = Result<Option<Vec<lsp::CallHierarchyIncomingCall>>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        match capabilities.call_hierarchy_provider {\n            Some(\n                lsp::CallHierarchyServerCapability::Simple(true)\n                | lsp::CallHierarchyServerCapability::Options(_),\n            ) => (),\n            _ => return None,\n        }\n\n        let params = lsp::CallHierarchyIncomingCallsParams {\n            item,\n            work_done_progress_params: lsp::WorkDoneProgressParams::default(),\n            partial_result_params: lsp::PartialResultParams::default(),\n        };\n\n        Some(self.call::<lsp::request::CallHierarchyIncomingCalls>(params))\n    }\n\n    pub fn call_hierarchy_outgoing(\n        &self,\n        item: lsp::CallHierarchyItem,\n    ) -> Option<impl Future<Output = Result<Option<Vec<lsp::CallHierarchyOutgoingCall>>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        match capabilities.call_hierarchy_provider {\n            Some(\n                lsp::CallHierarchyServerCapability::Simple(true)\n                | lsp::CallHierarchyServerCapability::Options(_),\n            ) => (),\n            _ => return None,\n        }\n\n        let params = lsp::CallHierarchyOutgoingCallsParams {\n            item,\n            work_done_progress_params: lsp::WorkDoneProgressParams::default(),\n            partial_result_params: lsp::PartialResultParams::default(),\n        };\n\n        Some(self.call::<lsp::request::CallHierarchyOutgoingCalls>(params))\n    }\n\n    pub fn prepare_rename(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n    ) -> Option<impl Future<Output = Result<Option<lsp::PrepareRenameResponse>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        match capabilities.rename_provider {\n            Some(lsp::OneOf::Right(lsp::RenameOptions {\n                prepare_provider: Some(true),\n                ..\n            })) => (),\n            _ => return None,\n        }\n\n        let params = lsp::TextDocumentPositionParams {\n            text_document,\n            position,\n        };\n\n        Some(self.call::<lsp::request::PrepareRenameRequest>(params))\n    }\n\n    // empty string to get all symbols\n    pub fn workspace_symbols(\n        &self,\n        query: String,\n    ) -> Option<impl Future<Output = Result<Option<lsp::WorkspaceSymbolResponse>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support workspace symbols.\n        match capabilities.workspace_symbol_provider {\n            Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) => (),\n            _ => return None,\n        }\n\n        let params = lsp::WorkspaceSymbolParams {\n            query,\n            work_done_progress_params: lsp::WorkDoneProgressParams::default(),\n            partial_result_params: lsp::PartialResultParams::default(),\n        };\n\n        Some(self.call::<lsp::request::WorkspaceSymbolRequest>(params))\n    }\n\n    pub fn code_actions(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        range: lsp::Range,\n        context: lsp::CodeActionContext,\n    ) -> Option<impl Future<Output = Result<Option<Vec<lsp::CodeActionOrCommand>>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the server does not support code actions.\n        match capabilities.code_action_provider {\n            Some(\n                lsp::CodeActionProviderCapability::Simple(true)\n                | lsp::CodeActionProviderCapability::Options(_),\n            ) => (),\n            _ => return None,\n        }\n\n        let params = lsp::CodeActionParams {\n            text_document,\n            range,\n            context,\n            work_done_progress_params: lsp::WorkDoneProgressParams::default(),\n            partial_result_params: lsp::PartialResultParams::default(),\n        };\n\n        Some(self.call::<lsp::request::CodeActionRequest>(params))\n    }\n\n    pub fn rename_symbol(\n        &self,\n        text_document: lsp::TextDocumentIdentifier,\n        position: lsp::Position,\n        new_name: String,\n    ) -> Option<impl Future<Output = Result<Option<lsp::WorkspaceEdit>>>> {\n        if !self.supports_feature(LanguageServerFeature::RenameSymbol) {\n            return None;\n        }\n\n        let params = lsp::RenameParams {\n            text_document_position: lsp::TextDocumentPositionParams {\n                text_document,\n                position,\n            },\n            new_name,\n            work_done_progress_params: lsp::WorkDoneProgressParams {\n                work_done_token: None,\n            },\n        };\n\n        Some(self.call::<lsp::request::Rename>(params))\n    }\n\n    pub fn command(\n        &self,\n        command: lsp::Command,\n    ) -> Option<impl Future<Output = Result<Option<Value>>>> {\n        let capabilities = self.capabilities.get().unwrap();\n\n        // Return early if the language server does not support executing commands.\n        capabilities.execute_command_provider.as_ref()?;\n\n        let params = lsp::ExecuteCommandParams {\n            command: command.command,\n            arguments: command.arguments.unwrap_or_default(),\n            work_done_progress_params: lsp::WorkDoneProgressParams {\n                work_done_token: None,\n            },\n        };\n\n        Some(self.call::<lsp::request::ExecuteCommand>(params))\n    }\n\n    pub fn did_change_watched_files(&self, changes: Vec<lsp::FileEvent>) {\n        self.notify::<lsp::notification::DidChangeWatchedFiles>(lsp::DidChangeWatchedFilesParams {\n            changes,\n        })\n    }\n}\n"
  },
  {
    "path": "helix-lsp/src/file_event.rs",
    "content": "use std::{collections::HashMap, path::PathBuf, sync::Weak};\n\nuse globset::{GlobBuilder, GlobSetBuilder};\nuse tokio::sync::mpsc;\n\nuse crate::{lsp, Client, LanguageServerId};\n\nenum Event {\n    FileChanged {\n        path: PathBuf,\n    },\n    Register {\n        client_id: LanguageServerId,\n        client: Weak<Client>,\n        registration_id: String,\n        options: lsp::DidChangeWatchedFilesRegistrationOptions,\n    },\n    Unregister {\n        client_id: LanguageServerId,\n        registration_id: String,\n    },\n    RemoveClient {\n        client_id: LanguageServerId,\n    },\n}\n\n#[derive(Default)]\nstruct ClientState {\n    client: Weak<Client>,\n    registered: HashMap<String, globset::GlobSet>,\n}\n\n/// The Handler uses a dedicated tokio task to respond to file change events by\n/// forwarding changes to LSPs that have registered for notifications with a\n/// matching glob.\n///\n/// When an LSP registers for the DidChangeWatchedFiles notification, the\n/// Handler is notified by sending the registration details in addition to a\n/// weak reference to the LSP client. This is done so that the Handler can have\n/// access to the client without preventing the client from being dropped if it\n/// is closed and the Handler isn't properly notified.\n#[derive(Clone, Debug)]\npub struct Handler {\n    tx: mpsc::UnboundedSender<Event>,\n}\n\nimpl Default for Handler {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl Handler {\n    pub fn new() -> Self {\n        let (tx, rx) = mpsc::unbounded_channel();\n        tokio::spawn(Self::run(rx));\n        Self { tx }\n    }\n\n    pub fn register(\n        &self,\n        client_id: LanguageServerId,\n        client: Weak<Client>,\n        registration_id: String,\n        options: lsp::DidChangeWatchedFilesRegistrationOptions,\n    ) {\n        let _ = self.tx.send(Event::Register {\n            client_id,\n            client,\n            registration_id,\n            options,\n        });\n    }\n\n    pub fn unregister(&self, client_id: LanguageServerId, registration_id: String) {\n        let _ = self.tx.send(Event::Unregister {\n            client_id,\n            registration_id,\n        });\n    }\n\n    pub fn file_changed(&self, path: PathBuf) {\n        let _ = self.tx.send(Event::FileChanged { path });\n    }\n\n    pub fn remove_client(&self, client_id: LanguageServerId) {\n        let _ = self.tx.send(Event::RemoveClient { client_id });\n    }\n\n    async fn run(mut rx: mpsc::UnboundedReceiver<Event>) {\n        let mut state: HashMap<LanguageServerId, ClientState> = HashMap::new();\n        while let Some(event) = rx.recv().await {\n            match event {\n                Event::FileChanged { path } => {\n                    log::debug!(\"Received file event for {:?}\", &path);\n\n                    state.retain(|id, client_state| {\n                        if !client_state\n                            .registered\n                            .values()\n                            .any(|glob| glob.is_match(&path))\n                        {\n                            return true;\n                        }\n                        let Some(client) = client_state.client.upgrade() else {\n                            log::warn!(\"LSP client was dropped: {id}\");\n                            return false;\n                        };\n                        let Ok(uri) = lsp::Url::from_file_path(&path) else {\n                            return true;\n                        };\n                        log::debug!(\n                            \"Sending didChangeWatchedFiles notification to client '{}'\",\n                            client.name()\n                        );\n                        client.did_change_watched_files(vec![lsp::FileEvent {\n                            uri,\n                            // We currently always send the CHANGED state\n                            // since we don't actually have more context at\n                            // the moment.\n                            typ: lsp::FileChangeType::CHANGED,\n                        }]);\n                        true\n                    });\n                }\n                Event::Register {\n                    client_id,\n                    client,\n                    registration_id,\n                    options: ops,\n                } => {\n                    log::debug!(\n                        \"Registering didChangeWatchedFiles for client '{}' with id '{}'\",\n                        client_id,\n                        registration_id\n                    );\n\n                    let entry = state.entry(client_id).or_default();\n                    entry.client = client;\n\n                    let mut builder = GlobSetBuilder::new();\n                    for watcher in ops.watchers {\n                        if let lsp::GlobPattern::String(pattern) = watcher.glob_pattern {\n                            if let Ok(glob) = GlobBuilder::new(&pattern).build() {\n                                builder.add(glob);\n                            }\n                        }\n                    }\n                    match builder.build() {\n                        Ok(globset) => {\n                            entry.registered.insert(registration_id, globset);\n                        }\n                        Err(err) => {\n                            // Remove any old state for that registration id and\n                            // remove the entire client if it's now empty.\n                            entry.registered.remove(&registration_id);\n                            if entry.registered.is_empty() {\n                                state.remove(&client_id);\n                            }\n                            log::warn!(\n                                \"Unable to build globset for LSP didChangeWatchedFiles {err}\"\n                            )\n                        }\n                    }\n                }\n                Event::Unregister {\n                    client_id,\n                    registration_id,\n                } => {\n                    log::debug!(\n                        \"Unregistering didChangeWatchedFiles with id '{}' for client '{}'\",\n                        registration_id,\n                        client_id\n                    );\n                    if let Some(client_state) = state.get_mut(&client_id) {\n                        client_state.registered.remove(&registration_id);\n                        if client_state.registered.is_empty() {\n                            state.remove(&client_id);\n                        }\n                    }\n                }\n                Event::RemoveClient { client_id } => {\n                    log::debug!(\"Removing LSP client: {client_id}\");\n                    state.remove(&client_id);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "helix-lsp/src/file_operations.rs",
    "content": "use std::path::Path;\n\nuse globset::{GlobBuilder, GlobSet};\n\nuse crate::lsp;\n\n#[derive(Default, Debug)]\npub(crate) struct FileOperationFilter {\n    dir_globs: GlobSet,\n    file_globs: GlobSet,\n}\n\nimpl FileOperationFilter {\n    fn new(capability: Option<&lsp::FileOperationRegistrationOptions>) -> FileOperationFilter {\n        let Some(cap) = capability else {\n            return FileOperationFilter::default();\n        };\n        let mut dir_globs = GlobSet::builder();\n        let mut file_globs = GlobSet::builder();\n        for filter in &cap.filters {\n            // TODO: support other url schemes\n            let is_non_file_schema = filter\n                .scheme\n                .as_ref()\n                .is_some_and(|schema| schema != \"file\");\n            if is_non_file_schema {\n                continue;\n            }\n            let ignore_case = filter\n                .pattern\n                .options\n                .as_ref()\n                .and_then(|opts| opts.ignore_case)\n                .unwrap_or(false);\n            let mut glob_builder = GlobBuilder::new(&filter.pattern.glob);\n            glob_builder.case_insensitive(!ignore_case);\n            let glob = match glob_builder.build() {\n                Ok(glob) => glob,\n                Err(err) => {\n                    log::error!(\"invalid glob send by LS: {err}\");\n                    continue;\n                }\n            };\n            match filter.pattern.matches {\n                Some(lsp::FileOperationPatternKind::File) => {\n                    file_globs.add(glob);\n                }\n                Some(lsp::FileOperationPatternKind::Folder) => {\n                    dir_globs.add(glob);\n                }\n                None => {\n                    file_globs.add(glob.clone());\n                    dir_globs.add(glob);\n                }\n            };\n        }\n        let file_globs = file_globs.build().unwrap_or_else(|err| {\n            log::error!(\"invalid globs send by LS: {err}\");\n            GlobSet::empty()\n        });\n        let dir_globs = dir_globs.build().unwrap_or_else(|err| {\n            log::error!(\"invalid globs send by LS: {err}\");\n            GlobSet::empty()\n        });\n        FileOperationFilter {\n            dir_globs,\n            file_globs,\n        }\n    }\n\n    pub(crate) fn has_interest(&self, path: &Path, is_dir: bool) -> bool {\n        if is_dir {\n            self.dir_globs.is_match(path)\n        } else {\n            self.file_globs.is_match(path)\n        }\n    }\n}\n\n#[derive(Default, Debug)]\npub(crate) struct FileOperationsInterest {\n    // TODO: support other notifications\n    // did_create: FileOperationFilter,\n    // will_create: FileOperationFilter,\n    pub did_rename: FileOperationFilter,\n    pub will_rename: FileOperationFilter,\n    // did_delete: FileOperationFilter,\n    // will_delete: FileOperationFilter,\n}\n\nimpl FileOperationsInterest {\n    pub fn new(capabilities: &lsp::ServerCapabilities) -> FileOperationsInterest {\n        let capabilities = capabilities\n            .workspace\n            .as_ref()\n            .and_then(|capabilities| capabilities.file_operations.as_ref());\n        let Some(capabilities) = capabilities else {\n            return FileOperationsInterest::default();\n        };\n        FileOperationsInterest {\n            did_rename: FileOperationFilter::new(capabilities.did_rename.as_ref()),\n            will_rename: FileOperationFilter::new(capabilities.will_rename.as_ref()),\n        }\n    }\n}\n"
  },
  {
    "path": "helix-lsp/src/jsonrpc.rs",
    "content": "//! An implementation of the JSONRPC 2.0 spec types\n\n// Upstream implementation: https://github.com/paritytech/jsonrpc/tree/38af3c9439aa75481805edf6c05c6622a5ab1e70/core/src/types\n// Changes from upstream:\n// * unused functions (almost all non-trait-implementation functions) have been removed\n// * `#[serde(deny_unknown_fields)]` annotations have been removed on types for compatibility.\n//   (For examples https://github.com/helix-editor/helix/issues/2786, https://github.com/helix-editor/helix/issues/15078)\n// * some variable names have been lengthened for readability\n\nuse serde::de::{self, DeserializeOwned, Visitor};\nuse serde::{Deserialize, Serialize};\nuse serde_json::Value;\n\n// https://www.jsonrpc.org/specification#error_object\n#[derive(Debug, PartialEq, Eq, Clone)]\npub enum ErrorCode {\n    ParseError,\n    InvalidRequest,\n    MethodNotFound,\n    InvalidParams,\n    InternalError,\n    ServerError(i64),\n}\n\nimpl ErrorCode {\n    pub fn code(&self) -> i64 {\n        match *self {\n            ErrorCode::ParseError => -32700,\n            ErrorCode::InvalidRequest => -32600,\n            ErrorCode::MethodNotFound => -32601,\n            ErrorCode::InvalidParams => -32602,\n            ErrorCode::InternalError => -32603,\n            ErrorCode::ServerError(code) => code,\n        }\n    }\n}\n\nimpl From<i64> for ErrorCode {\n    fn from(code: i64) -> Self {\n        match code {\n            -32700 => ErrorCode::ParseError,\n            -32600 => ErrorCode::InvalidRequest,\n            -32601 => ErrorCode::MethodNotFound,\n            -32602 => ErrorCode::InvalidParams,\n            -32603 => ErrorCode::InternalError,\n            code => ErrorCode::ServerError(code),\n        }\n    }\n}\n\nimpl<'de> Deserialize<'de> for ErrorCode {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        let code: i64 = Deserialize::deserialize(deserializer)?;\n        Ok(ErrorCode::from(code))\n    }\n}\n\nimpl Serialize for ErrorCode {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        serializer.serialize_i64(self.code())\n    }\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]\npub struct Error {\n    pub code: ErrorCode,\n    pub message: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data: Option<Value>,\n}\n\nimpl Error {\n    pub fn invalid_params<M>(message: M) -> Self\n    where\n        M: Into<String>,\n    {\n        Error {\n            code: ErrorCode::InvalidParams,\n            message: message.into(),\n            data: None,\n        }\n    }\n}\n\nimpl std::fmt::Display for Error {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{:?}: {}\", self.code, self.message)\n    }\n}\n\nimpl std::error::Error for Error {}\n\n// https://www.jsonrpc.org/specification#request_object\n\n/// Request ID\n#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum Id {\n    Null,\n    Num(#[serde(deserialize_with = \"deserialize_jsonrpc_id_num\")] u64),\n    Str(String),\n}\n\nfn deserialize_jsonrpc_id_num<'de, D>(deserializer: D) -> Result<u64, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    let num = serde_json::Number::deserialize(deserializer)?;\n\n    if let Some(val) = num.as_u64() {\n        return Ok(val);\n    };\n\n    // Accept floats as long as they represent positive whole numbers.\n    // The JSONRPC spec says \"Numbers SHOULD NOT contain fractional parts\" so we should try to\n    // accept them if possible. The JavaScript type system lumps integers and floats together so\n    // some languages may serialize integer IDs as floats with a zeroed fractional part.\n    // See <https://github.com/helix-editor/helix/issues/12367>.\n    if let Some(val) = num\n        .as_f64()\n        .filter(|f| f.is_sign_positive() && f.fract() == 0.0)\n    {\n        return Ok(val as u64);\n    }\n\n    Err(de::Error::custom(\n        \"number must be integer or float representing a whole number in valid u64 range\",\n    ))\n}\n\nimpl std::fmt::Display for Id {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Id::Null => f.write_str(\"null\"),\n            Id::Num(num) => write!(f, \"{}\", num),\n            Id::Str(string) => f.write_str(string),\n        }\n    }\n}\n\n/// Protocol Version\n#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]\npub enum Version {\n    V2,\n}\n\nimpl Serialize for Version {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        match *self {\n            Version::V2 => serializer.serialize_str(\"2.0\"),\n        }\n    }\n}\n\nstruct VersionVisitor;\n\nimpl Visitor<'_> for VersionVisitor {\n    type Value = Version;\n\n    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {\n        formatter.write_str(\"a string\")\n    }\n    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>\n    where\n        E: de::Error,\n    {\n        match value {\n            \"2.0\" => Ok(Version::V2),\n            _ => Err(de::Error::custom(\"invalid version\")),\n        }\n    }\n}\n\nimpl<'de> Deserialize<'de> for Version {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        deserializer.deserialize_identifier(VersionVisitor)\n    }\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]\n#[serde(untagged)]\npub enum Params {\n    None,\n    Array(Vec<Value>),\n    Map(serde_json::Map<String, Value>),\n}\n\nimpl Params {\n    pub fn parse<D>(self) -> Result<D, Error>\n    where\n        D: DeserializeOwned,\n    {\n        let value: Value = self.into();\n        serde_json::from_value(value)\n            .map_err(|err| Error::invalid_params(format!(\"Invalid params: {}.\", err)))\n    }\n\n    pub fn is_none(&self) -> bool {\n        self == &Params::None\n    }\n}\n\nimpl From<Params> for Value {\n    fn from(params: Params) -> Value {\n        match params {\n            Params::Array(vec) => Value::Array(vec),\n            Params::Map(map) => Value::Object(map),\n            Params::None => Value::Null,\n        }\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]\npub struct MethodCall {\n    pub jsonrpc: Option<Version>,\n    pub method: String,\n    #[serde(default = \"default_params\", skip_serializing_if = \"Params::is_none\")]\n    pub params: Params,\n    pub id: Id,\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]\npub struct Notification {\n    pub jsonrpc: Option<Version>,\n    pub method: String,\n    #[serde(default = \"default_params\", skip_serializing_if = \"Params::is_none\")]\n    pub params: Params,\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]\n#[serde(deny_unknown_fields)]\n#[serde(untagged)]\npub enum Call {\n    MethodCall(MethodCall),\n    Notification(Notification),\n    Invalid {\n        // We can attempt to salvage the id out of the invalid request\n        // for better debugging\n        #[serde(default = \"default_id\")]\n        id: Id,\n    },\n}\n\nfn default_params() -> Params {\n    Params::None\n}\n\nfn default_id() -> Id {\n    Id::Null\n}\n\nimpl From<MethodCall> for Call {\n    fn from(method_call: MethodCall) -> Self {\n        Call::MethodCall(method_call)\n    }\n}\n\nimpl From<Notification> for Call {\n    fn from(notification: Notification) -> Self {\n        Call::Notification(notification)\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]\n#[serde(deny_unknown_fields)]\n#[serde(untagged)]\npub enum Request {\n    Single(Call),\n    Batch(Vec<Call>),\n}\n\n// https://www.jsonrpc.org/specification#response_object\n\n#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]\npub struct Success {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub jsonrpc: Option<Version>,\n    pub result: Value,\n    pub id: Id,\n}\n\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\npub struct Failure {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub jsonrpc: Option<Version>,\n    pub error: Error,\n    pub id: Id,\n}\n\n// Note that failure comes first because we're not using\n// #[serde(deny_unknown_field)]: we want a request that contains\n// both `result` and `error` to be a `Failure`.\n#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum Output {\n    Failure(Failure),\n    Success(Success),\n}\n\nimpl From<Output> for Result<Value, Error> {\n    fn from(output: Output) -> Self {\n        match output {\n            Output::Success(success) => Ok(success.result),\n            Output::Failure(failure) => Err(failure.error),\n        }\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum Response {\n    Single(Output),\n    Batch(Vec<Output>),\n}\n\nimpl From<Failure> for Response {\n    fn from(failure: Failure) -> Self {\n        Response::Single(Output::Failure(failure))\n    }\n}\n\nimpl From<Success> for Response {\n    fn from(success: Success) -> Self {\n        Response::Single(Output::Success(success))\n    }\n}\n\n#[test]\nfn method_call_serialize() {\n    use serde_json;\n\n    let m = MethodCall {\n        jsonrpc: Some(Version::V2),\n        method: \"update\".to_owned(),\n        params: Params::Array(vec![Value::from(1), Value::from(2)]),\n        id: Id::Num(1),\n    };\n\n    let serialized = serde_json::to_string(&m).unwrap();\n    assert_eq!(\n        serialized,\n        r#\"{\"jsonrpc\":\"2.0\",\"method\":\"update\",\"params\":[1,2],\"id\":1}\"#\n    );\n}\n\n#[test]\nfn notification_serialize() {\n    use serde_json;\n\n    let n = Notification {\n        jsonrpc: Some(Version::V2),\n        method: \"update\".to_owned(),\n        params: Params::Array(vec![Value::from(1), Value::from(2)]),\n    };\n\n    let serialized = serde_json::to_string(&n).unwrap();\n    assert_eq!(\n        serialized,\n        r#\"{\"jsonrpc\":\"2.0\",\"method\":\"update\",\"params\":[1,2]}\"#\n    );\n}\n\n#[test]\nfn serialize_skip_none_params() {\n    use serde_json;\n\n    let m = MethodCall {\n        jsonrpc: Some(Version::V2),\n        method: \"shutdown\".to_owned(),\n        params: Params::None,\n        id: Id::Num(1),\n    };\n\n    let serialized = serde_json::to_string(&m).unwrap();\n    assert_eq!(\n        serialized,\n        r#\"{\"jsonrpc\":\"2.0\",\"method\":\"shutdown\",\"id\":1}\"#\n    );\n\n    let n = Notification {\n        jsonrpc: Some(Version::V2),\n        method: \"exit\".to_owned(),\n        params: Params::None,\n    };\n\n    let serialized = serde_json::to_string(&n).unwrap();\n    assert_eq!(serialized, r#\"{\"jsonrpc\":\"2.0\",\"method\":\"exit\"}\"#);\n}\n\n#[test]\nfn id_deserialize() {\n    use serde_json;\n\n    let id = r#\"8\"#;\n    let deserialized: Id = serde_json::from_str(id).unwrap();\n    assert_eq!(deserialized, Id::Num(8));\n\n    let id = r#\"4.0\"#;\n    let deserialized: Id = serde_json::from_str(id).unwrap();\n    assert_eq!(deserialized, Id::Num(4));\n\n    let id = r#\"0.01\"#;\n    assert!(serde_json::from_str::<Id>(id).is_err());\n}\n\n#[test]\nfn success_output_deserialize() {\n    use serde_json;\n\n    let dso = r#\"{\"jsonrpc\":\"2.0\",\"result\":1,\"id\":1}\"#;\n\n    let deserialized: Output = serde_json::from_str(dso).unwrap();\n    assert_eq!(\n        deserialized,\n        Output::Success(Success {\n            jsonrpc: Some(Version::V2),\n            result: Value::from(1),\n            id: Id::Num(1)\n        })\n    );\n}\n\n#[test]\nfn success_output_deserialize_with_extra_fields() {\n    use serde_json::{self, json};\n\n    // https://github.com/helix-editor/helix/issues/2786\n    let dso = r#\"{\"jsonrpc\":\"2.0\",\"result\":1,\"id\":1,\"requestMethod\":\"initialize\"}\"#;\n\n    let deserialized: Output = serde_json::from_str(dso).unwrap();\n    assert_eq!(\n        deserialized,\n        Output::Success(Success {\n            jsonrpc: Some(Version::V2),\n            result: Value::from(1),\n            id: Id::Num(1)\n        })\n    );\n\n    // https://github.com/helix-editor/helix/issues/15078\n    let json = r#\"{\"traceparent\":\"00-84b1954eb787286f09bf07937689f8cb-5f78c8b6ed6bc71a-00\",\"jsonrpc\":\"2.0\",\"method\":\"window/logMessage\",\"params\":{\"type\":5,\"message\":\"Initialized\"}}\"#;\n    assert_eq!(\n        serde_json::from_str::<Notification>(json).unwrap(),\n        Notification {\n            jsonrpc: Some(Version::V2),\n            method: \"window/logMessage\".to_owned(),\n            params: Params::Map(\n                json!({\"type\":5,\"message\":\"Initialized\"})\n                    .as_object()\n                    .unwrap()\n                    .clone()\n            ),\n        }\n    );\n}\n"
  },
  {
    "path": "helix-lsp/src/lib.rs",
    "content": "mod client;\npub mod file_event;\nmod file_operations;\npub mod jsonrpc;\nmod transport;\n\nuse arc_swap::ArcSwap;\npub use client::Client;\npub use futures_executor::block_on;\npub use helix_lsp_types as lsp;\npub use jsonrpc::Call;\nuse log::warn;\npub use lsp::{Position, Url};\n\nuse futures_util::stream::select_all::SelectAll;\nuse helix_core::syntax::config::{\n    LanguageConfiguration, LanguageServerConfiguration, LanguageServerFeatures, RootMarkers,\n};\nuse helix_stdx::path;\nuse slotmap::SlotMap;\nuse tokio::sync::mpsc::UnboundedReceiver;\n\nuse std::{\n    collections::HashMap,\n    fs,\n    path::{Path, PathBuf},\n    sync::Arc,\n};\n\nuse thiserror::Error;\nuse tokio_stream::wrappers::UnboundedReceiverStream;\n\npub type Result<T, E = Error> = core::result::Result<T, E>;\npub type LanguageServerName = String;\npub use helix_core::diagnostic::LanguageServerId;\n\n#[derive(Error, Debug)]\npub enum Error {\n    #[error(\"protocol error: {0}\")]\n    Rpc(#[from] jsonrpc::Error),\n    #[error(\"failed to parse: {0}\")]\n    Parse(Box<dyn std::error::Error + Send + Sync>),\n    #[error(\"IO Error: {0}\")]\n    IO(#[from] std::io::Error),\n    #[error(\"request {0} timed out\")]\n    Timeout(jsonrpc::Id),\n    #[error(\"server closed the stream\")]\n    StreamClosed,\n    #[error(\"Unhandled\")]\n    Unhandled,\n    #[error(transparent)]\n    ExecutableNotFound(#[from] helix_stdx::env::ExecutableNotFoundError),\n    #[error(transparent)]\n    Other(#[from] anyhow::Error),\n}\n\nimpl From<serde_json::Error> for Error {\n    fn from(value: serde_json::Error) -> Self {\n        Self::Parse(Box::new(value))\n    }\n}\n\nimpl From<sonic_rs::Error> for Error {\n    fn from(value: sonic_rs::Error) -> Self {\n        Self::Parse(Box::new(value))\n    }\n}\n\n#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]\npub enum OffsetEncoding {\n    /// UTF-8 code units aka bytes\n    Utf8,\n    /// UTF-32 code units aka chars\n    Utf32,\n    /// UTF-16 code units\n    #[default]\n    Utf16,\n}\n\npub mod util {\n    use super::*;\n    use helix_core::line_ending::{line_end_byte_index, line_end_char_index};\n    use helix_core::snippets::{RenderedSnippet, Snippet, SnippetRenderCtx};\n    use helix_core::{chars, RopeSlice};\n    use helix_core::{diagnostic::NumberOrString, Range, Rope, Selection, Tendril, Transaction};\n\n    /// Converts a diagnostic in the document to [`lsp::Diagnostic`].\n    ///\n    /// Panics when [`pos_to_lsp_pos`] would for an invalid range on the diagnostic.\n    pub fn diagnostic_to_lsp_diagnostic(\n        doc: &Rope,\n        diag: &helix_core::diagnostic::Diagnostic,\n        offset_encoding: OffsetEncoding,\n    ) -> lsp::Diagnostic {\n        use helix_core::diagnostic::Severity::*;\n\n        let range = Range::new(diag.range.start, diag.range.end);\n        let severity = diag.severity.map(|s| match s {\n            Hint => lsp::DiagnosticSeverity::HINT,\n            Info => lsp::DiagnosticSeverity::INFORMATION,\n            Warning => lsp::DiagnosticSeverity::WARNING,\n            Error => lsp::DiagnosticSeverity::ERROR,\n        });\n\n        let code = match diag.code.clone() {\n            Some(x) => match x {\n                NumberOrString::Number(x) => Some(lsp::NumberOrString::Number(x)),\n                NumberOrString::String(x) => Some(lsp::NumberOrString::String(x)),\n            },\n            None => None,\n        };\n\n        let new_tags: Vec<_> = diag\n            .tags\n            .iter()\n            .map(|tag| match tag {\n                helix_core::diagnostic::DiagnosticTag::Unnecessary => {\n                    lsp::DiagnosticTag::UNNECESSARY\n                }\n                helix_core::diagnostic::DiagnosticTag::Deprecated => lsp::DiagnosticTag::DEPRECATED,\n            })\n            .collect();\n\n        let tags = if !new_tags.is_empty() {\n            Some(new_tags)\n        } else {\n            None\n        };\n\n        lsp::Diagnostic {\n            range: range_to_lsp_range(doc, range, offset_encoding),\n            severity,\n            code,\n            source: diag.source.clone(),\n            message: diag.message.to_owned(),\n            related_information: None,\n            tags,\n            data: diag.data.to_owned(),\n            ..Default::default()\n        }\n    }\n\n    /// Converts [`lsp::Position`] to a position in the document.\n    ///\n    /// Returns `None` if position.line is out of bounds or an overflow occurs\n    pub fn lsp_pos_to_pos(\n        doc: &Rope,\n        pos: lsp::Position,\n        offset_encoding: OffsetEncoding,\n    ) -> Option<usize> {\n        let pos_line = pos.line as usize;\n        if pos_line > doc.len_lines() - 1 {\n            // If it extends past the end, truncate it to the end. This is because the\n            // way the LSP describes the range including the last newline is by\n            // specifying a line number after what we would call the last line.\n            log::warn!(\"LSP position {pos:?} out of range assuming EOF\");\n            return Some(doc.len_chars());\n        }\n\n        // We need to be careful here to fully comply ith the LSP spec.\n        // Two relevant quotes from the spec:\n        //\n        // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position\n        // > If the character value is greater than the line length it defaults back\n        // >  to the line length.\n        //\n        // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocuments\n        // > To ensure that both client and server split the string into the same\n        // > line representation the protocol specifies the following end-of-line sequences:\n        // > ‘\\n’, ‘\\r\\n’ and ‘\\r’. Positions are line end character agnostic.\n        // > So you can not specify a position that denotes \\r|\\n or \\n| where | represents the character offset.\n        //\n        // This means that while the line must be in bounds the `character`\n        // must be capped to the end of the line.\n        // Note that the end of the line here is **before** the line terminator\n        // so we must use `line_end_char_index` instead of `doc.line_to_char(pos_line + 1)`\n        //\n        // FIXME: Helix does not fully comply with the LSP spec for line terminators.\n        // The LSP standard requires that line terminators are ['\\n', '\\r\\n', '\\r'].\n        // Without the unicode-linebreak feature disabled, the `\\r` terminator is not handled by helix.\n        // With the unicode-linebreak feature, helix recognizes multiple extra line break chars\n        // which means that positions will be decoded/encoded incorrectly in their presence\n\n        let line = match offset_encoding {\n            OffsetEncoding::Utf8 => {\n                let line_start = doc.line_to_byte(pos_line);\n                let line_end = line_end_byte_index(&doc.slice(..), pos_line);\n                line_start..line_end\n            }\n            OffsetEncoding::Utf16 => {\n                // TODO directly translate line index to char-idx\n                // ropey can do this just as easily as utf-8 byte translation\n                // but the functions are just missing.\n                // Translate to char first and then utf-16 as a workaround\n                let line_start = doc.line_to_char(pos_line);\n                let line_end = line_end_char_index(&doc.slice(..), pos_line);\n                doc.char_to_utf16_cu(line_start)..doc.char_to_utf16_cu(line_end)\n            }\n            OffsetEncoding::Utf32 => {\n                let line_start = doc.line_to_char(pos_line);\n                let line_end = line_end_char_index(&doc.slice(..), pos_line);\n                line_start..line_end\n            }\n        };\n\n        // The LSP spec demands that the offset is capped to the end of the line\n        let pos = line\n            .start\n            .checked_add(pos.character as usize)\n            .unwrap_or(line.end)\n            .min(line.end);\n\n        match offset_encoding {\n            OffsetEncoding::Utf8 => doc.try_byte_to_char(pos).ok(),\n            OffsetEncoding::Utf16 => doc.try_utf16_cu_to_char(pos).ok(),\n            OffsetEncoding::Utf32 => Some(pos),\n        }\n    }\n\n    /// Converts position in the document to [`lsp::Position`].\n    ///\n    /// Panics when `pos` is out of `doc` bounds or operation overflows.\n    pub fn pos_to_lsp_pos(\n        doc: &Rope,\n        pos: usize,\n        offset_encoding: OffsetEncoding,\n    ) -> lsp::Position {\n        match offset_encoding {\n            OffsetEncoding::Utf8 => {\n                let line = doc.char_to_line(pos);\n                let line_start = doc.line_to_byte(line);\n                let col = doc.char_to_byte(pos) - line_start;\n\n                lsp::Position::new(line as u32, col as u32)\n            }\n            OffsetEncoding::Utf16 => {\n                let line = doc.char_to_line(pos);\n                let line_start = doc.char_to_utf16_cu(doc.line_to_char(line));\n                let col = doc.char_to_utf16_cu(pos) - line_start;\n\n                lsp::Position::new(line as u32, col as u32)\n            }\n            OffsetEncoding::Utf32 => {\n                let line = doc.char_to_line(pos);\n                let line_start = doc.line_to_char(line);\n                let col = pos - line_start;\n\n                lsp::Position::new(line as u32, col as u32)\n            }\n        }\n    }\n\n    /// Converts a range in the document to [`lsp::Range`].\n    pub fn range_to_lsp_range(\n        doc: &Rope,\n        range: Range,\n        offset_encoding: OffsetEncoding,\n    ) -> lsp::Range {\n        let start = pos_to_lsp_pos(doc, range.from(), offset_encoding);\n        let end = pos_to_lsp_pos(doc, range.to(), offset_encoding);\n\n        lsp::Range::new(start, end)\n    }\n\n    pub fn lsp_range_to_range(\n        doc: &Rope,\n        mut range: lsp::Range,\n        offset_encoding: OffsetEncoding,\n    ) -> Option<Range> {\n        // This is sort of an edgecase. It's not clear from the spec how to deal with\n        // ranges where end < start. They don't make much sense but vscode simply caps start to end\n        // and because it's not specified quite a few LS rely on this as a result (for example the TS server)\n        if range.start > range.end {\n            log::error!(\n                \"Invalid LSP range start {:?} > end {:?}, using an empty range at the end instead\",\n                range.start,\n                range.end\n            );\n            range.start = range.end;\n        }\n        let start = lsp_pos_to_pos(doc, range.start, offset_encoding)?;\n        let end = lsp_pos_to_pos(doc, range.end, offset_encoding)?;\n\n        Some(Range::new(start, end))\n    }\n\n    /// If the LS did not provide a range for the completion or the range of the\n    /// primary cursor can not be used for the secondary cursor, this function\n    /// can be used to find the completion range for a cursor\n    fn find_completion_range(text: RopeSlice, replace_mode: bool, cursor: usize) -> (usize, usize) {\n        let start = cursor\n            - text\n                .chars_at(cursor)\n                .reversed()\n                .take_while(|ch| chars::char_is_word(*ch))\n                .count();\n        let mut end = cursor;\n        if replace_mode {\n            end += text\n                .chars_at(cursor)\n                .take_while(|ch| chars::char_is_word(*ch))\n                .count();\n        }\n        (start, end)\n    }\n    fn completion_range(\n        text: RopeSlice,\n        edit_offset: Option<(i128, i128)>,\n        replace_mode: bool,\n        cursor: usize,\n    ) -> Option<(usize, usize)> {\n        let res = match edit_offset {\n            Some((start_offset, end_offset)) => {\n                let start_offset = cursor as i128 + start_offset;\n                if start_offset < 0 {\n                    return None;\n                }\n                let end_offset = cursor as i128 + end_offset;\n                if end_offset > text.len_chars() as i128 {\n                    return None;\n                }\n                (start_offset as usize, end_offset as usize)\n            }\n            None => find_completion_range(text, replace_mode, cursor),\n        };\n        Some(res)\n    }\n\n    /// Creates a [Transaction] from the [lsp::TextEdit] in a completion response.\n    /// The transaction applies the edit to all cursors.\n    pub fn generate_transaction_from_completion_edit(\n        doc: &Rope,\n        selection: &Selection,\n        edit_offset: Option<(i128, i128)>,\n        replace_mode: bool,\n        new_text: String,\n    ) -> Transaction {\n        let replacement: Option<Tendril> = if new_text.is_empty() {\n            None\n        } else {\n            Some(new_text.into())\n        };\n\n        let text = doc.slice(..);\n        let (removed_start, removed_end) = completion_range(\n            text,\n            edit_offset,\n            replace_mode,\n            selection.primary().cursor(text),\n        )\n        .expect(\"transaction must be valid for primary selection\");\n        let removed_text = text.slice(removed_start..removed_end);\n\n        let (transaction, mut selection) = Transaction::change_by_selection_ignore_overlapping(\n            doc,\n            selection,\n            |range| {\n                let cursor = range.cursor(text);\n                completion_range(text, edit_offset, replace_mode, cursor)\n                    .filter(|(start, end)| text.slice(start..end) == removed_text)\n                    .unwrap_or_else(|| find_completion_range(text, replace_mode, cursor))\n            },\n            |_, _| replacement.clone(),\n        );\n        if transaction.changes().is_empty() {\n            return transaction;\n        }\n        selection = selection.map(transaction.changes());\n        transaction.with_selection(selection)\n    }\n\n    /// Creates a [Transaction] from the [Snippet] in a completion response.\n    /// The transaction applies the edit to all cursors.\n    pub fn generate_transaction_from_snippet(\n        doc: &Rope,\n        selection: &Selection,\n        edit_offset: Option<(i128, i128)>,\n        replace_mode: bool,\n        snippet: Snippet,\n        cx: &mut SnippetRenderCtx,\n    ) -> (Transaction, RenderedSnippet) {\n        let text = doc.slice(..);\n        let (removed_start, removed_end) = completion_range(\n            text,\n            edit_offset,\n            replace_mode,\n            selection.primary().cursor(text),\n        )\n        .expect(\"transaction must be valid for primary selection\");\n        let removed_text = text.slice(removed_start..removed_end);\n        let (transaction, mapped_selection, snippet) = snippet.render(\n            doc,\n            selection,\n            |range| {\n                let cursor = range.cursor(text);\n                completion_range(text, edit_offset, replace_mode, cursor)\n                    .filter(|(start, end)| text.slice(start..end) == removed_text)\n                    .unwrap_or_else(|| find_completion_range(text, replace_mode, cursor))\n            },\n            cx,\n        );\n        let transaction = transaction.with_selection(snippet.first_selection(\n            // we keep the direction of the old primary selection in case it changed during mapping\n            // but use the primary idx from the mapped selection in case ranges had to be merged\n            selection.primary().direction(),\n            mapped_selection.primary_index(),\n        ));\n        (transaction, snippet)\n    }\n\n    pub fn generate_transaction_from_edits(\n        doc: &Rope,\n        mut edits: Vec<lsp::TextEdit>,\n        offset_encoding: OffsetEncoding,\n    ) -> Transaction {\n        // Sort edits by start range, since some LSPs (Omnisharp) send them\n        // in reverse order.\n        edits.sort_by_key(|edit| edit.range.start);\n\n        // Generate a diff if the edit is a full document replacement.\n        #[allow(clippy::collapsible_if)]\n        if edits.len() == 1 {\n            let is_document_replacement = edits.first().and_then(|edit| {\n                let start = lsp_pos_to_pos(doc, edit.range.start, offset_encoding)?;\n                let end = lsp_pos_to_pos(doc, edit.range.end, offset_encoding)?;\n                Some(start..end)\n            }) == Some(0..doc.len_chars());\n            if is_document_replacement {\n                let new_text = Rope::from(edits.pop().unwrap().new_text);\n                return helix_core::diff::compare_ropes(doc, &new_text);\n            }\n        }\n\n        Transaction::change(\n            doc,\n            edits.into_iter().map(|edit| {\n                // simplify \"\" into None for cleaner changesets\n                let replacement = if !edit.new_text.is_empty() {\n                    Some(edit.new_text.into())\n                } else {\n                    None\n                };\n\n                let start =\n                    if let Some(start) = lsp_pos_to_pos(doc, edit.range.start, offset_encoding) {\n                        start\n                    } else {\n                        return (0, 0, None);\n                    };\n                let end = if let Some(end) = lsp_pos_to_pos(doc, edit.range.end, offset_encoding) {\n                    end\n                } else {\n                    return (0, 0, None);\n                };\n\n                if start > end {\n                    log::error!(\n                        \"Invalid LSP text edit start {:?} > end {:?}, discarding\",\n                        start,\n                        end\n                    );\n                    return (0, 0, None);\n                }\n\n                (start, end, replacement)\n            }),\n        )\n    }\n}\n\n#[derive(Debug, PartialEq, Clone)]\npub enum MethodCall {\n    WorkDoneProgressCreate(lsp::WorkDoneProgressCreateParams),\n    ApplyWorkspaceEdit(lsp::ApplyWorkspaceEditParams),\n    WorkspaceFolders,\n    WorkspaceConfiguration(lsp::ConfigurationParams),\n    RegisterCapability(lsp::RegistrationParams),\n    UnregisterCapability(lsp::UnregistrationParams),\n    ShowDocument(lsp::ShowDocumentParams),\n    WorkspaceDiagnosticRefresh,\n    ShowMessageRequest(lsp::ShowMessageRequestParams),\n}\n\nimpl MethodCall {\n    pub fn parse(method: &str, params: jsonrpc::Params) -> Result<MethodCall> {\n        use lsp::request::Request;\n        let request = match method {\n            lsp::request::WorkDoneProgressCreate::METHOD => {\n                let params: lsp::WorkDoneProgressCreateParams = params.parse()?;\n                Self::WorkDoneProgressCreate(params)\n            }\n            lsp::request::ApplyWorkspaceEdit::METHOD => {\n                let params: lsp::ApplyWorkspaceEditParams = params.parse()?;\n                Self::ApplyWorkspaceEdit(params)\n            }\n            lsp::request::WorkspaceFoldersRequest::METHOD => Self::WorkspaceFolders,\n            lsp::request::WorkspaceConfiguration::METHOD => {\n                let params: lsp::ConfigurationParams = params.parse()?;\n                Self::WorkspaceConfiguration(params)\n            }\n            lsp::request::RegisterCapability::METHOD => {\n                let params: lsp::RegistrationParams = params.parse()?;\n                Self::RegisterCapability(params)\n            }\n            lsp::request::UnregisterCapability::METHOD => {\n                let params: lsp::UnregistrationParams = params.parse()?;\n                Self::UnregisterCapability(params)\n            }\n            lsp::request::ShowDocument::METHOD => {\n                let params: lsp::ShowDocumentParams = params.parse()?;\n                Self::ShowDocument(params)\n            }\n            lsp::request::WorkspaceDiagnosticRefresh::METHOD => Self::WorkspaceDiagnosticRefresh,\n            lsp::request::ShowMessageRequest::METHOD => {\n                let params: lsp::ShowMessageRequestParams = params.parse()?;\n                Self::ShowMessageRequest(params)\n            }\n            _ => {\n                return Err(Error::Unhandled);\n            }\n        };\n        Ok(request)\n    }\n}\n\n#[derive(Debug, PartialEq, Clone)]\npub enum Notification {\n    // we inject this notification to signal the LSP is ready\n    Initialized,\n    // and this notification to signal that the LSP exited\n    Exit,\n    PublishDiagnostics(lsp::PublishDiagnosticsParams),\n    ShowMessage(lsp::ShowMessageParams),\n    LogMessage(lsp::LogMessageParams),\n    ProgressMessage(lsp::ProgressParams),\n}\n\nimpl Notification {\n    pub fn parse(method: &str, params: jsonrpc::Params) -> Result<Notification> {\n        use lsp::notification::Notification as _;\n\n        let notification = match method {\n            lsp::notification::Initialized::METHOD => Self::Initialized,\n            lsp::notification::Exit::METHOD => Self::Exit,\n            lsp::notification::PublishDiagnostics::METHOD => {\n                let params: lsp::PublishDiagnosticsParams = params.parse()?;\n                Self::PublishDiagnostics(params)\n            }\n\n            lsp::notification::ShowMessage::METHOD => {\n                let params: lsp::ShowMessageParams = params.parse()?;\n                Self::ShowMessage(params)\n            }\n            lsp::notification::LogMessage::METHOD => {\n                let params: lsp::LogMessageParams = params.parse()?;\n                Self::LogMessage(params)\n            }\n            lsp::notification::Progress::METHOD => {\n                let params: lsp::ProgressParams = params.parse()?;\n                Self::ProgressMessage(params)\n            }\n            _ => {\n                return Err(Error::Unhandled);\n            }\n        };\n\n        Ok(notification)\n    }\n}\n\n#[derive(Debug)]\npub struct Registry {\n    inner: SlotMap<LanguageServerId, Arc<Client>>,\n    inner_by_name: HashMap<LanguageServerName, Vec<Arc<Client>>>,\n    syn_loader: Arc<ArcSwap<helix_core::syntax::Loader>>,\n    pub incoming: SelectAll<UnboundedReceiverStream<(LanguageServerId, Call)>>,\n    pub file_event_handler: file_event::Handler,\n}\n\nimpl Registry {\n    pub fn new(syn_loader: Arc<ArcSwap<helix_core::syntax::Loader>>) -> Self {\n        Self {\n            inner: SlotMap::with_key(),\n            inner_by_name: HashMap::new(),\n            syn_loader,\n            incoming: SelectAll::new(),\n            file_event_handler: file_event::Handler::new(),\n        }\n    }\n\n    pub fn get_by_id(&self, id: LanguageServerId) -> Option<&Arc<Client>> {\n        self.inner.get(id)\n    }\n\n    pub fn remove_by_id(&mut self, id: LanguageServerId) {\n        let Some(client) = self.inner.remove(id) else {\n            log::debug!(\"client was already removed\");\n            return;\n        };\n        self.file_event_handler.remove_client(id);\n        let instances = self\n            .inner_by_name\n            .get_mut(client.name())\n            .expect(\"inner and inner_by_name must be synced\");\n        instances.retain(|ls| id != ls.id());\n        if instances.is_empty() {\n            self.inner_by_name.remove(client.name());\n        }\n    }\n\n    fn start_client(\n        &mut self,\n        name: String,\n        ls_config: &LanguageConfiguration,\n        doc_path: Option<&std::path::PathBuf>,\n        root_dirs: &[PathBuf],\n        enable_snippets: bool,\n    ) -> Result<Arc<Client>, StartupError> {\n        let syn_loader = self.syn_loader.load();\n        let config = syn_loader\n            .language_server_configs()\n            .get(&name)\n            .ok_or_else(|| anyhow::anyhow!(\"Language server '{name}' not defined\"))?;\n        let id = self.inner.try_insert_with_key(|id| {\n            start_client(\n                id,\n                name,\n                ls_config,\n                config,\n                doc_path,\n                root_dirs,\n                enable_snippets,\n            )\n            .map(|client| {\n                self.incoming.push(UnboundedReceiverStream::new(client.1));\n                client.0\n            })\n        })?;\n        Ok(self.inner[id].clone())\n    }\n\n    /// If this method is called, all documents that have a reference to the language server have to refresh their language servers,\n    /// See helix_view::editor::Editor::refresh_language_servers\n    pub fn restart_server(\n        &mut self,\n        name: &str,\n        language_config: &LanguageConfiguration,\n        doc_path: Option<&std::path::PathBuf>,\n        root_dirs: &[PathBuf],\n        enable_snippets: bool,\n    ) -> Option<Result<Arc<Client>>> {\n        if let Some(old_clients) = self.inner_by_name.remove(name) {\n            if old_clients.is_empty() {\n                log::info!(\"restarting client for '{name}' which was manually stopped\");\n            } else {\n                log::info!(\"stopping existing clients for '{name}'\");\n            }\n            for old_client in old_clients {\n                self.file_event_handler.remove_client(old_client.id());\n                self.inner.remove(old_client.id());\n                tokio::spawn(async move {\n                    let _ = old_client.force_shutdown().await;\n                });\n            }\n        }\n        let client = match self.start_client(\n            name.to_string(),\n            language_config,\n            doc_path,\n            root_dirs,\n            enable_snippets,\n        ) {\n            Ok(client) => client,\n            Err(StartupError::NoRequiredRootFound) => return None,\n            Err(StartupError::Error(err)) => return Some(Err(err)),\n        };\n        self.inner_by_name\n            .insert(name.to_owned(), vec![client.clone()]);\n\n        Some(Ok(client))\n    }\n\n    pub fn stop(&mut self, name: &str) {\n        if let Some(clients) = self.inner_by_name.get_mut(name) {\n            // Drain the clients vec so that the entry in `inner_by_name` remains\n            // empty. We use the empty vec as a \"tombstone\" to mean that a server\n            // has been manually stopped with :lsp-stop and shouldn't be automatically\n            // restarted by `get`. :lsp-restart can be used to restart the server\n            // manually.\n            for client in clients.drain(..) {\n                self.file_event_handler.remove_client(client.id());\n                self.inner.remove(client.id());\n                tokio::spawn(async move {\n                    let _ = client.force_shutdown().await;\n                });\n            }\n        }\n    }\n\n    pub fn get<'a>(\n        &'a mut self,\n        language_config: &'a LanguageConfiguration,\n        doc_path: Option<&'a std::path::PathBuf>,\n        root_dirs: &'a [PathBuf],\n        enable_snippets: bool,\n    ) -> impl Iterator<Item = (LanguageServerName, Result<Arc<Client>>)> + 'a {\n        language_config.language_servers.iter().filter_map(\n            move |LanguageServerFeatures { name, .. }| {\n                if let Some(clients) = self.inner_by_name.get(name) {\n                    // If the clients vec is empty, do not automatically start a client\n                    // for this server. The empty vec is a tombstone left to mean that a\n                    // server has been manually stopped and shouldn't be started automatically.\n                    // See `stop`.\n                    if clients.is_empty() {\n                        return None;\n                    }\n\n                    if let Some((_, client)) = clients.iter().enumerate().find(|(i, client)| {\n                        let manual_roots = language_config\n                            .workspace_lsp_roots\n                            .as_deref()\n                            .unwrap_or(root_dirs);\n                        client.try_add_doc(&language_config.roots, manual_roots, doc_path, *i == 0)\n                    }) {\n                        return Some((name.to_owned(), Ok(client.clone())));\n                    }\n                }\n                match self.start_client(\n                    name.clone(),\n                    language_config,\n                    doc_path,\n                    root_dirs,\n                    enable_snippets,\n                ) {\n                    Ok(client) => {\n                        self.inner_by_name\n                            .entry(name.to_owned())\n                            .or_default()\n                            .push(client.clone());\n                        Some((name.clone(), Ok(client)))\n                    }\n                    Err(StartupError::NoRequiredRootFound) => None,\n                    Err(StartupError::Error(err)) => Some((name.to_owned(), Err(err))),\n                }\n            },\n        )\n    }\n\n    pub fn iter_clients(&self) -> impl Iterator<Item = &Arc<Client>> {\n        self.inner.values()\n    }\n}\n\n#[derive(Debug)]\npub enum ProgressStatus {\n    Created,\n    Started {\n        title: String,\n        progress: lsp::WorkDoneProgress,\n    },\n}\n\nimpl ProgressStatus {\n    pub fn progress(&self) -> Option<&lsp::WorkDoneProgress> {\n        match &self {\n            ProgressStatus::Created => None,\n            ProgressStatus::Started { title: _, progress } => Some(progress),\n        }\n    }\n}\n\n#[derive(Default, Debug)]\n/// Acts as a container for progress reported by language servers. Each server\n/// has a unique id assigned at creation through [`Registry`]. This id is then used\n/// to store the progress in this map.\npub struct LspProgressMap(HashMap<LanguageServerId, HashMap<lsp::ProgressToken, ProgressStatus>>);\n\nimpl LspProgressMap {\n    pub fn new() -> Self {\n        Self::default()\n    }\n\n    /// Returns a map of all tokens corresponding to the language server with `id`.\n    pub fn progress_map(\n        &self,\n        id: LanguageServerId,\n    ) -> Option<&HashMap<lsp::ProgressToken, ProgressStatus>> {\n        self.0.get(&id)\n    }\n\n    pub fn is_progressing(&self, id: LanguageServerId) -> bool {\n        self.0.get(&id).map(|it| !it.is_empty()).unwrap_or_default()\n    }\n\n    /// Returns last progress status for a given server with `id` and `token`.\n    pub fn progress(\n        &self,\n        id: LanguageServerId,\n        token: &lsp::ProgressToken,\n    ) -> Option<&ProgressStatus> {\n        self.0.get(&id).and_then(|values| values.get(token))\n    }\n\n    pub fn title(&self, id: LanguageServerId, token: &lsp::ProgressToken) -> Option<&String> {\n        self.progress(id, token).and_then(|p| match p {\n            ProgressStatus::Created => None,\n            ProgressStatus::Started { title, .. } => Some(title),\n        })\n    }\n\n    /// Checks if progress `token` for server with `id` is created.\n    pub fn is_created(&mut self, id: LanguageServerId, token: &lsp::ProgressToken) -> bool {\n        self.0\n            .get(&id)\n            .map(|values| values.get(token).is_some())\n            .unwrap_or_default()\n    }\n\n    pub fn create(&mut self, id: LanguageServerId, token: lsp::ProgressToken) {\n        self.0\n            .entry(id)\n            .or_default()\n            .insert(token, ProgressStatus::Created);\n    }\n\n    /// Ends the progress by removing the `token` from server with `id`, if removed returns the value.\n    pub fn end_progress(\n        &mut self,\n        id: LanguageServerId,\n        token: &lsp::ProgressToken,\n    ) -> Option<ProgressStatus> {\n        self.0.get_mut(&id).and_then(|vals| vals.remove(token))\n    }\n\n    /// Updates the progress of `token` for server with `id` to begin state `status`\n    pub fn begin(\n        &mut self,\n        id: LanguageServerId,\n        token: lsp::ProgressToken,\n        status: lsp::WorkDoneProgressBegin,\n    ) {\n        self.0.entry(id).or_default().insert(\n            token,\n            ProgressStatus::Started {\n                title: status.title.clone(),\n                progress: lsp::WorkDoneProgress::Begin(status),\n            },\n        );\n    }\n\n    /// Updates the progress of `token` for server with `id` to report state `status`.\n    pub fn update(\n        &mut self,\n        id: LanguageServerId,\n        token: lsp::ProgressToken,\n        status: lsp::WorkDoneProgressReport,\n    ) {\n        self.0\n            .entry(id)\n            .or_default()\n            .entry(token)\n            .and_modify(|e| match e {\n                ProgressStatus::Created => (),\n                ProgressStatus::Started { progress, .. } => {\n                    *progress = lsp::WorkDoneProgress::Report(status)\n                }\n            });\n    }\n}\n\nstruct NewClient(Arc<Client>, UnboundedReceiver<(LanguageServerId, Call)>);\n\nenum StartupError {\n    NoRequiredRootFound,\n    Error(Error),\n}\n\nimpl<T: Into<Error>> From<T> for StartupError {\n    fn from(value: T) -> Self {\n        StartupError::Error(value.into())\n    }\n}\n\n/// start_client takes both a LanguageConfiguration and a LanguageServerConfiguration to ensure that\n/// it is only called when it makes sense.\nfn start_client(\n    id: LanguageServerId,\n    name: String,\n    config: &LanguageConfiguration,\n    ls_config: &LanguageServerConfiguration,\n    doc_path: Option<&std::path::PathBuf>,\n    root_dirs: &[PathBuf],\n    enable_snippets: bool,\n) -> Result<NewClient, StartupError> {\n    let (workspace, workspace_is_cwd) = helix_loader::find_workspace();\n    let workspace = path::normalize(workspace);\n    let root = find_lsp_workspace(\n        doc_path\n            .and_then(|x| x.parent().and_then(|x| x.to_str()))\n            .unwrap_or(\".\"),\n        &config.roots,\n        config.workspace_lsp_roots.as_deref().unwrap_or(root_dirs),\n        &workspace,\n        workspace_is_cwd,\n    );\n\n    // `root_uri` and `workspace_folder` can be empty in case there is no workspace\n    // `root_url` can not, use `workspace` as a fallback\n    let root_path = root.clone().unwrap_or_else(|| workspace.clone());\n    let root_uri = root.and_then(|root| lsp::Url::from_file_path(root).ok());\n\n    if let Some(globset) = &ls_config.required_root_patterns {\n        if !root_path\n            .read_dir()?\n            .flatten()\n            .map(|entry| entry.file_name())\n            .any(|entry| globset.is_match(entry))\n        {\n            // TODO: also show the globset that should be matched: https://github.com/BurntSushi/ripgrep/issues/3274\n            warn!(\"The lsp {name:?} tried to start at {root_path:?} but failed to match it's 'required_root_patterns'\");\n            return Err(StartupError::NoRequiredRootFound);\n        }\n    }\n\n    let (client, incoming, initialize_notify) = Client::start(\n        &ls_config.command,\n        &ls_config.args,\n        ls_config.config.clone(),\n        &ls_config.environment,\n        root_path,\n        root_uri,\n        id,\n        name,\n        ls_config.timeout,\n    )?;\n\n    let client = Arc::new(client);\n\n    // Initialize the client asynchronously\n    let _client = client.clone();\n    tokio::spawn(async move {\n        use futures_util::TryFutureExt;\n        let value = _client\n            .capabilities\n            .get_or_try_init(|| {\n                _client\n                    .initialize(enable_snippets)\n                    .map_ok(|response| response.capabilities)\n            })\n            .await;\n\n        if let Err(e) = value {\n            log::error!(\"failed to initialize language server: {}\", e);\n            return;\n        }\n\n        // next up, notify<initialized>\n        _client.notify::<lsp::notification::Initialized>(lsp::InitializedParams {});\n\n        initialize_notify.notify_one();\n    });\n\n    Ok(NewClient(client, incoming))\n}\n\n/// Find an LSP workspace of a file using the following mechanism:\n/// * if the file is outside `workspace` return `None`\n/// * start at `file` and search the file tree upward\n/// * stop the search at the first `root_dirs` entry that contains `file`\n/// * if no `root_dirs` matches `file` stop at workspace\n/// * Returns the top most directory that contains a `root_marker`\n/// * If no root marker and we stopped at a `root_dirs` entry, return the directory we stopped at\n/// * If we stopped at `workspace` instead and `workspace_is_cwd == false` return `None`\n/// * If we stopped at `workspace` instead and `workspace_is_cwd == true` return `workspace`\npub fn find_lsp_workspace(\n    file: &str,\n    root_markers: &RootMarkers,\n    root_dirs: &[PathBuf],\n    workspace: &Path,\n    workspace_is_cwd: bool,\n) -> Option<PathBuf> {\n    let file = std::path::Path::new(file);\n    let mut file = if file.is_absolute() {\n        file.to_path_buf()\n    } else {\n        let current_dir = helix_stdx::env::current_working_dir();\n        current_dir.join(file)\n    };\n    file = path::normalize(&file);\n\n    if !file.starts_with(workspace) {\n        return None;\n    }\n\n    let mut top_marker = None;\n    for ancestor in file.ancestors() {\n        let Ok(mut dir) = fs::read_dir(ancestor) else {\n            continue;\n        };\n\n        if dir.any(|entry| {\n            if let Ok(entry) = entry {\n                return root_markers.is_match(entry.file_name());\n            }\n            false\n        }) {\n            top_marker = Some(ancestor);\n        }\n\n        if root_dirs\n            .iter()\n            .any(|root_dir| path::normalize(workspace.join(root_dir)) == ancestor)\n        {\n            // if the worskapce is the cwd do not search any higher for workspaces\n            // but specify\n            return Some(top_marker.unwrap_or(workspace).to_owned());\n        }\n        if ancestor == workspace {\n            // if the workspace is the CWD, let the LSP decide what the workspace\n            // is\n            return top_marker\n                .or_else(|| (!workspace_is_cwd).then_some(workspace))\n                .map(Path::to_owned);\n        }\n    }\n\n    debug_assert!(false, \"workspace must be an ancestor of <file>\");\n    None\n}\n\n#[cfg(test)]\nmod tests {\n    use super::{lsp, util::*, OffsetEncoding};\n    use helix_core::Rope;\n\n    #[test]\n    fn converts_lsp_pos_to_pos() {\n        macro_rules! test_case {\n            ($doc:expr, ($x:expr, $y:expr) => $want:expr) => {\n                let doc = Rope::from($doc);\n                let pos = lsp::Position::new($x, $y);\n                assert_eq!($want, lsp_pos_to_pos(&doc, pos, OffsetEncoding::Utf16));\n                assert_eq!($want, lsp_pos_to_pos(&doc, pos, OffsetEncoding::Utf8))\n            };\n        }\n\n        test_case!(\"\", (0, 0) => Some(0));\n        test_case!(\"\", (0, 1) => Some(0));\n        test_case!(\"\", (1, 0) => Some(0));\n        test_case!(\"\\n\\n\", (0, 0) => Some(0));\n        test_case!(\"\\n\\n\", (1, 0) => Some(1));\n        test_case!(\"\\n\\n\", (1, 1) => Some(1));\n        test_case!(\"\\n\\n\", (2, 0) => Some(2));\n        test_case!(\"\\n\\n\", (3, 0) => Some(2));\n        test_case!(\"test\\n\\n\\n\\ncase\", (4, 3) => Some(11));\n        test_case!(\"test\\n\\n\\n\\ncase\", (4, 4) => Some(12));\n        test_case!(\"test\\n\\n\\n\\ncase\", (4, 5) => Some(12));\n        test_case!(\"\", (u32::MAX, u32::MAX) => Some(0));\n    }\n\n    #[test]\n    fn emoji_format_gh_4791() {\n        use lsp::{Position, Range, TextEdit};\n\n        let edits = vec![\n            TextEdit {\n                range: Range {\n                    start: Position {\n                        line: 0,\n                        character: 1,\n                    },\n                    end: Position {\n                        line: 1,\n                        character: 0,\n                    },\n                },\n                new_text: \"\\n  \".to_string(),\n            },\n            TextEdit {\n                range: Range {\n                    start: Position {\n                        line: 1,\n                        character: 7,\n                    },\n                    end: Position {\n                        line: 2,\n                        character: 0,\n                    },\n                },\n                new_text: \"\\n  \".to_string(),\n            },\n        ];\n\n        let mut source = Rope::from_str(\"[\\n\\\"🇺🇸\\\",\\n\\\"🎄\\\",\\n]\");\n\n        let transaction = generate_transaction_from_edits(&source, edits, OffsetEncoding::Utf16);\n        assert!(transaction.apply(&mut source));\n        assert_eq!(source, \"[\\n  \\\"🇺🇸\\\",\\n  \\\"🎄\\\",\\n]\");\n    }\n}\n"
  },
  {
    "path": "helix-lsp/src/transport.rs",
    "content": "use crate::{\n    jsonrpc,\n    lsp::{self, notification::Notification as _},\n    Error, LanguageServerId, Result,\n};\nuse anyhow::Context;\nuse log::{error, info};\nuse serde::{Deserialize, Serialize};\nuse serde_json::Value;\nuse std::collections::HashMap;\nuse std::sync::Arc;\nuse tokio::{\n    io::{AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter},\n    process::{ChildStderr, ChildStdin, ChildStdout},\n    sync::{\n        mpsc::{unbounded_channel, Sender, UnboundedReceiver, UnboundedSender},\n        Mutex, Notify,\n    },\n};\n\n#[derive(Debug)]\npub enum Payload {\n    Request {\n        chan: Sender<Result<Value>>,\n        value: jsonrpc::MethodCall,\n    },\n    Notification(jsonrpc::Notification),\n    Response(jsonrpc::Output),\n}\n\n/// A type representing all possible values sent from the server to the client.\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(deny_unknown_fields)]\n#[serde(untagged)]\nenum ServerMessage {\n    /// A regular JSON-RPC request output (single response).\n    Output(jsonrpc::Output),\n    /// A JSON-RPC request or notification.\n    Call(jsonrpc::Call),\n}\n\n#[derive(Debug)]\npub struct Transport {\n    id: LanguageServerId,\n    name: String,\n    pending_requests: Mutex<HashMap<jsonrpc::Id, Sender<Result<Value>>>>,\n}\n\nimpl Transport {\n    pub fn start(\n        server_stdout: BufReader<ChildStdout>,\n        server_stdin: BufWriter<ChildStdin>,\n        server_stderr: BufReader<ChildStderr>,\n        id: LanguageServerId,\n        name: String,\n    ) -> (\n        UnboundedReceiver<(LanguageServerId, jsonrpc::Call)>,\n        UnboundedSender<Payload>,\n        Arc<Notify>,\n    ) {\n        let (client_tx, rx) = unbounded_channel();\n        let (tx, client_rx) = unbounded_channel();\n        let notify = Arc::new(Notify::new());\n\n        let transport = Self {\n            id,\n            name,\n            pending_requests: Mutex::new(HashMap::default()),\n        };\n\n        let transport = Arc::new(transport);\n\n        tokio::spawn(Self::recv(\n            transport.clone(),\n            server_stdout,\n            client_tx.clone(),\n        ));\n        tokio::spawn(Self::err(transport.clone(), server_stderr));\n        tokio::spawn(Self::send(\n            transport,\n            server_stdin,\n            client_tx,\n            client_rx,\n            notify.clone(),\n        ));\n\n        (rx, tx, notify)\n    }\n\n    async fn recv_server_message(\n        reader: &mut (impl AsyncBufRead + Unpin + Send),\n        buffer: &mut String,\n        content: &mut Vec<u8>,\n        language_server_name: &str,\n    ) -> Result<ServerMessage> {\n        let mut content_length = None;\n        loop {\n            buffer.clear();\n            if reader.read_line(buffer).await? == 0 {\n                return Err(Error::StreamClosed);\n            }\n\n            // debug!(\"<- header {:?}\", buffer);\n\n            if buffer == \"\\r\\n\" {\n                // look for an empty CRLF line\n                break;\n            }\n\n            let header = buffer.trim();\n\n            let parts = header.split_once(\": \");\n\n            match parts {\n                Some((\"Content-Length\", value)) => {\n                    content_length = Some(value.parse().context(\"invalid content length\")?);\n                }\n                Some((_, _)) => {}\n                None => {\n                    // Workaround: Some non-conformant language servers will output logging and other garbage\n                    // into the same stream as JSON-RPC messages. This can also happen from shell scripts that spawn\n                    // the server. Skip such lines and log a warning.\n\n                    // warn!(\"Failed to parse header: {:?}\", header);\n                }\n            }\n        }\n\n        let content_length = content_length.context(\"missing content length\")?;\n        content.resize(content_length, 0);\n        reader.read_exact(content).await?;\n        let msg = std::str::from_utf8(content).context(\"invalid utf8 from server\")?;\n\n        info!(\"{language_server_name} <- {msg}\");\n\n        // NOTE: We avoid using `?` here, since it would return early on error\n        // and skip clearing `content`. By returning the result directly instead,\n        // we ensure `content.clear()` is always called.\n        let output = sonic_rs::from_slice(content).map_err(Into::into);\n\n        content.clear();\n\n        output\n    }\n\n    async fn recv_server_error(\n        err: &mut (impl AsyncBufRead + Unpin + Send),\n        buffer: &mut String,\n        language_server_name: &str,\n    ) -> Result<()> {\n        buffer.truncate(0);\n        if err.read_line(buffer).await? == 0 {\n            return Err(Error::StreamClosed);\n        };\n        error!(\"{language_server_name} err <- {buffer:?}\");\n\n        Ok(())\n    }\n\n    async fn send_payload_to_server(\n        &self,\n        server_stdin: &mut BufWriter<ChildStdin>,\n        payload: Payload,\n    ) -> Result<()> {\n        //TODO: reuse string\n        let json = match payload {\n            Payload::Request { chan, value } => {\n                self.pending_requests\n                    .lock()\n                    .await\n                    .insert(value.id.clone(), chan);\n                serde_json::to_string(&value)?\n            }\n            Payload::Notification(value) => serde_json::to_string(&value)?,\n            Payload::Response(error) => serde_json::to_string(&error)?,\n        };\n        self.send_string_to_server(server_stdin, json, &self.name)\n            .await\n    }\n\n    async fn send_string_to_server(\n        &self,\n        server_stdin: &mut BufWriter<ChildStdin>,\n        request: String,\n        language_server_name: &str,\n    ) -> Result<()> {\n        info!(\"{language_server_name} -> {request}\");\n\n        // send the headers\n        server_stdin\n            .write_all(format!(\"Content-Length: {}\\r\\n\\r\\n\", request.len()).as_bytes())\n            .await?;\n\n        // send the body\n        server_stdin.write_all(request.as_bytes()).await?;\n\n        server_stdin.flush().await?;\n\n        Ok(())\n    }\n\n    async fn process_server_message(\n        &self,\n        client_tx: &UnboundedSender<(LanguageServerId, jsonrpc::Call)>,\n        msg: ServerMessage,\n        language_server_name: &str,\n    ) -> Result<()> {\n        match msg {\n            ServerMessage::Output(output) => {\n                self.process_request_response(output, language_server_name)\n                    .await?\n            }\n            ServerMessage::Call(call) => {\n                client_tx\n                    .send((self.id, call))\n                    .context(\"failed to send a message to server\")?;\n                // let notification = Notification::parse(&method, params);\n            }\n        };\n        Ok(())\n    }\n\n    async fn process_request_response(\n        &self,\n        output: jsonrpc::Output,\n        language_server_name: &str,\n    ) -> Result<()> {\n        let (id, result) = match output {\n            jsonrpc::Output::Success(jsonrpc::Success { id, result, .. }) => (id, Ok(result)),\n            jsonrpc::Output::Failure(jsonrpc::Failure { id, error, .. }) => {\n                error!(\"{language_server_name} <- {error}\");\n                (id, Err(error.into()))\n            }\n        };\n\n        if let Some(tx) = self.pending_requests.lock().await.remove(&id) {\n            match tx.send(result).await {\n                Ok(_) => (),\n                Err(_) => error!(\n                    \"Tried sending response into a closed channel (id={:?}), original request likely timed out\",\n                    id\n                ),\n            };\n        } else {\n            log::error!(\n                \"Discarding Language Server response without a request (id={:?}) {:?}\",\n                id,\n                result\n            );\n        }\n\n        Ok(())\n    }\n\n    async fn recv(\n        transport: Arc<Self>,\n        mut server_stdout: BufReader<ChildStdout>,\n        client_tx: UnboundedSender<(LanguageServerId, jsonrpc::Call)>,\n    ) {\n        let mut recv_buffer = String::new();\n        let mut content_buffer = Vec::new();\n        loop {\n            match Self::recv_server_message(\n                &mut server_stdout,\n                &mut recv_buffer,\n                &mut content_buffer,\n                &transport.name,\n            )\n            .await\n            {\n                Ok(msg) => {\n                    match transport\n                        .process_server_message(&client_tx, msg, &transport.name)\n                        .await\n                    {\n                        Ok(_) => {}\n                        Err(err) => {\n                            error!(\"{} err: <- {err:?}\", transport.name);\n                            break;\n                        }\n                    };\n                }\n                Err(err) => {\n                    if !matches!(err, Error::StreamClosed) {\n                        error!(\n                            \"Exiting {} after unexpected error: {err:?}\",\n                            &transport.name\n                        );\n                    }\n\n                    // Close any outstanding requests.\n                    for (id, tx) in transport.pending_requests.lock().await.drain() {\n                        match tx.send(Err(Error::StreamClosed)).await {\n                            Ok(_) => (),\n                            Err(_) => {\n                                error!(\"Could not close request on a closed channel (id={:?})\", id)\n                            }\n                        }\n                    }\n\n                    // Hack: inject a terminated notification so we trigger code that needs to happen after exit\n                    let notification =\n                        ServerMessage::Call(jsonrpc::Call::Notification(jsonrpc::Notification {\n                            jsonrpc: None,\n                            method: lsp::notification::Exit::METHOD.to_string(),\n                            params: jsonrpc::Params::None,\n                        }));\n                    match transport\n                        .process_server_message(&client_tx, notification, &transport.name)\n                        .await\n                    {\n                        Ok(_) => {}\n                        Err(err) => {\n                            error!(\"err: <- {:?}\", err);\n                        }\n                    }\n                    break;\n                }\n            }\n        }\n    }\n\n    async fn err(transport: Arc<Self>, mut server_stderr: BufReader<ChildStderr>) {\n        let mut recv_buffer = String::new();\n        loop {\n            match Self::recv_server_error(&mut server_stderr, &mut recv_buffer, &transport.name)\n                .await\n            {\n                Ok(_) => {}\n                Err(err) => {\n                    error!(\"{} err: <- {err:?}\", transport.name);\n                    break;\n                }\n            }\n        }\n    }\n\n    async fn send(\n        transport: Arc<Self>,\n        mut server_stdin: BufWriter<ChildStdin>,\n        client_tx: UnboundedSender<(LanguageServerId, jsonrpc::Call)>,\n        mut client_rx: UnboundedReceiver<Payload>,\n        initialize_notify: Arc<Notify>,\n    ) {\n        let mut pending_messages: Vec<Payload> = Vec::new();\n        let mut is_pending = true;\n\n        // Determine if a message is allowed to be sent early\n        fn is_initialize(payload: &Payload) -> bool {\n            use lsp::{\n                notification::Initialized,\n                request::{Initialize, Request},\n            };\n            match payload {\n                Payload::Request {\n                    value: jsonrpc::MethodCall { method, .. },\n                    ..\n                } if method == Initialize::METHOD => true,\n                Payload::Notification(jsonrpc::Notification { method, .. })\n                    if method == Initialized::METHOD =>\n                {\n                    true\n                }\n                _ => false,\n            }\n        }\n\n        fn is_shutdown(payload: &Payload) -> bool {\n            use lsp::request::{Request, Shutdown};\n            matches!(payload, Payload::Request { value: jsonrpc::MethodCall { method, .. }, .. } if method == Shutdown::METHOD)\n        }\n\n        // TODO: events that use capabilities need to do the right thing\n\n        loop {\n            tokio::select! {\n                biased;\n                _ = initialize_notify.notified() => { // TODO: notified is technically not cancellation safe\n                    // server successfully initialized\n                    is_pending = false;\n\n                    // Hack: inject an initialized notification so we trigger code that needs to happen after init\n                    let notification = ServerMessage::Call(jsonrpc::Call::Notification(jsonrpc::Notification {\n                        jsonrpc: None,\n\n                        method: lsp::notification::Initialized::METHOD.to_string(),\n                        params: jsonrpc::Params::None,\n                    }));\n                    let language_server_name = &transport.name;\n                    match transport.process_server_message(&client_tx, notification, language_server_name).await {\n                        Ok(_) => {}\n                        Err(err) => {\n                            error!(\"{language_server_name} err: <- {err:?}\");\n                        }\n                    }\n\n                    // drain the pending queue and send payloads to server\n                    for msg in pending_messages.drain(..) {\n                        log::info!(\"Draining pending message {:?}\", msg);\n                        match transport.send_payload_to_server(&mut server_stdin, msg).await {\n                            Ok(_) => {}\n                            Err(err) => {\n                                error!(\"{language_server_name} err: <- {err:?}\");\n                            }\n                        }\n                    }\n                }\n                msg = client_rx.recv() => {\n                    if let Some(msg) = msg {\n                        if is_pending && is_shutdown(&msg) {\n                            log::info!(\"Language server not initialized, shutting down\");\n                            break;\n                        } else if is_pending && !is_initialize(&msg) {\n                            // ignore notifications\n                            if let Payload::Notification(_) = msg {\n                                continue;\n                            }\n\n                            log::info!(\"Language server not initialized, delaying request\");\n                            pending_messages.push(msg);\n                        } else {\n                            match transport.send_payload_to_server(&mut server_stdin, msg).await {\n                                Ok(_) => {}\n                                Err(err) => {\n                                    error!(\"{} err: <- {err:?}\", transport.name);\n                                }\n                            }\n                        }\n                    } else {\n                        // channel closed\n                        break;\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "helix-lsp-types/Cargo.toml",
    "content": "[package]\nname = \"helix-lsp-types\"\nversion = \"0.95.1\"\nauthors = [\n  # Original authors\n  \"Markus Westerlind <marwes91@gmail.com>\",\n  \"Bruno Medeiros <bruno.do.medeiros@gmail.com>\",\n  # Since forking\n  \"Helix contributors\"\n]\nedition = \"2018\"\ndescription = \"Types for interaction with a language server, using VSCode's Language Server Protocol\"\n\nrepository = \"https://github.com/gluon-lang/lsp-types\"\ndocumentation = \"https://docs.rs/lsp-types\"\n\nreadme = \"README.md\"\n\nkeywords = [\"language\", \"server\", \"lsp\", \"vscode\", \"lsif\"]\n\nlicense = \"MIT\"\n\n[dependencies]\nbitflags.workspace = true\nserde = { version = \"1.0.228\", features = [\"derive\"] }\nserde_json = \"1.0.149\"\nurl = {version = \"2.5.4\", features = [\"serde\"]}\n\n[features]\ndefault = []\n# Enables proposed LSP extensions.\n# NOTE: No semver compatibility is guaranteed for types enabled by this feature.\nproposed = []\n"
  },
  {
    "path": "helix-lsp-types/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 Markus Westerlind\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n"
  },
  {
    "path": "helix-lsp-types/README.md",
    "content": "# Helix's `lsp-types`\n\nThis is a fork of the [`lsp-types`](https://crates.io/crates/lsp-types) crate ([`gluon-lang/lsp-types`](https://github.com/gluon-lang/lsp-types)) taken at version v0.95.1 (commit [3e6daee](https://github.com/gluon-lang/lsp-types/commit/3e6daee771d14db4094a554b8d03e29c310dfcbe)). This fork focuses usability improvements that make the types easier to work with for the Helix codebase. For example the URL type - the `uri` crate at this version of `lsp-types` - will be replaced with a wrapper around a string.\n"
  },
  {
    "path": "helix-lsp-types/src/call_hierarchy.rs",
    "content": "use serde::{Deserialize, Serialize};\nuse serde_json::Value;\n\nuse crate::{\n    DynamicRegistrationClientCapabilities, PartialResultParams, Range, SymbolKind, SymbolTag,\n    TextDocumentPositionParams, Url, WorkDoneProgressOptions, WorkDoneProgressParams,\n};\n\npub type CallHierarchyClientCapabilities = DynamicRegistrationClientCapabilities;\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize, Copy)]\n#[serde(rename_all = \"camelCase\")]\npub struct CallHierarchyOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize, Copy)]\n#[serde(untagged)]\npub enum CallHierarchyServerCapability {\n    Simple(bool),\n    Options(CallHierarchyOptions),\n}\n\nimpl From<CallHierarchyOptions> for CallHierarchyServerCapability {\n    fn from(from: CallHierarchyOptions) -> Self {\n        Self::Options(from)\n    }\n}\n\nimpl From<bool> for CallHierarchyServerCapability {\n    fn from(from: bool) -> Self {\n        Self::Simple(from)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CallHierarchyPrepareParams {\n    #[serde(flatten)]\n    pub text_document_position_params: TextDocumentPositionParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n}\n\n#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct CallHierarchyItem {\n    /// The name of this item.\n    pub name: String,\n\n    /// The kind of this item.\n    pub kind: SymbolKind,\n\n    /// Tags for this item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tags: Option<Vec<SymbolTag>>,\n\n    /// More detail for this item, e.g. the signature of a function.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub detail: Option<String>,\n\n    /// The resource identifier of this item.\n    pub uri: Url,\n\n    /// The range enclosing this symbol not including leading/trailing whitespace but everything else, e.g. comments and code.\n    pub range: Range,\n\n    /// The range that should be selected and revealed when this symbol is being picked, e.g. the name of a function.\n    /// Must be contained by the [`range`](#CallHierarchyItem.range).\n    pub selection_range: Range,\n\n    /// A data entry field that is preserved between a call hierarchy prepare and incoming calls or outgoing calls requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data: Option<Value>,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CallHierarchyIncomingCallsParams {\n    pub item: CallHierarchyItem,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// Represents an incoming call, e.g. a caller of a method or constructor.\n#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct CallHierarchyIncomingCall {\n    /// The item that makes the call.\n    pub from: CallHierarchyItem,\n\n    /// The range at which at which the calls appears. This is relative to the caller\n    /// denoted by [`this.from`](#CallHierarchyIncomingCall.from).\n    pub from_ranges: Vec<Range>,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CallHierarchyOutgoingCallsParams {\n    pub item: CallHierarchyItem,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// Represents an outgoing call, e.g. calling a getter from a method or a method from a constructor etc.\n#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct CallHierarchyOutgoingCall {\n    /// The item that is called.\n    pub to: CallHierarchyItem,\n\n    /// The range at which this item is called. This is the range relative to the caller, e.g the item\n    /// passed to [`provideCallHierarchyOutgoingCalls`](#CallHierarchyItemProvider.provideCallHierarchyOutgoingCalls)\n    /// and not [`this.to`](#CallHierarchyOutgoingCall.to).\n    pub from_ranges: Vec<Range>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/code_action.rs",
    "content": "use crate::{\n    Command, Diagnostic, PartialResultParams, Range, TextDocumentIdentifier,\n    WorkDoneProgressOptions, WorkDoneProgressParams, WorkspaceEdit,\n};\nuse serde::{Deserialize, Serialize};\n\nuse serde_json::Value;\n\nuse std::borrow::Cow;\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum CodeActionProviderCapability {\n    Simple(bool),\n    Options(CodeActionOptions),\n}\n\nimpl From<CodeActionOptions> for CodeActionProviderCapability {\n    fn from(from: CodeActionOptions) -> Self {\n        Self::Options(from)\n    }\n}\n\nimpl From<bool> for CodeActionProviderCapability {\n    fn from(from: bool) -> Self {\n        Self::Simple(from)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeActionClientCapabilities {\n    ///\n    /// This capability supports dynamic registration.\n    ///\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// The client support code action literals as a valid\n    /// response of the `textDocument/codeAction` request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub code_action_literal_support: Option<CodeActionLiteralSupport>,\n\n    /// Whether code action supports the `isPreferred` property.\n    ///\n    /// @since 3.15.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub is_preferred_support: Option<bool>,\n\n    /// Whether code action supports the `disabled` property.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub disabled_support: Option<bool>,\n\n    /// Whether code action supports the `data` property which is\n    /// preserved between a `textDocument/codeAction` and a\n    /// `codeAction/resolve` request.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data_support: Option<bool>,\n\n    /// Whether the client supports resolving additional code action\n    /// properties via a separate `codeAction/resolve` request.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resolve_support: Option<CodeActionCapabilityResolveSupport>,\n\n    /// Whether the client honors the change annotations in\n    /// text edits and resource operations returned via the\n    /// `CodeAction#edit` property by for example presenting\n    /// the workspace edit in the user interface and asking\n    /// for confirmation.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub honors_change_annotations: Option<bool>,\n}\n\n/// Whether the client supports resolving additional code action\n/// properties via a separate `codeAction/resolve` request.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeActionCapabilityResolveSupport {\n    /// The properties that a client can resolve lazily.\n    pub properties: Vec<String>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeActionLiteralSupport {\n    /// The code action kind is support with the following value set.\n    pub code_action_kind: CodeActionKindLiteralSupport,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeActionKindLiteralSupport {\n    /// The code action kind values the client supports. When this\n    /// property exists the client also guarantees that it will\n    /// handle values outside its set gracefully and falls back\n    /// to a default value when unknown.\n    pub value_set: Vec<String>,\n}\n\n/// Params for the CodeActionRequest\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeActionParams {\n    /// The document in which the command was invoked.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The range for which the command was invoked.\n    pub range: Range,\n\n    /// Context carrying additional information.\n    pub context: CodeActionContext,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// response for CodeActionRequest\npub type CodeActionResponse = Vec<CodeActionOrCommand>;\n\n#[allow(clippy::large_enum_variant)] // TODO: In a separate PR attempt the `Box<CodeAction>` pattern.\n#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum CodeActionOrCommand {\n    Command(Command),\n    CodeAction(CodeAction),\n}\n\nimpl From<Command> for CodeActionOrCommand {\n    fn from(command: Command) -> Self {\n        CodeActionOrCommand::Command(command)\n    }\n}\n\nimpl From<CodeAction> for CodeActionOrCommand {\n    fn from(action: CodeAction) -> Self {\n        CodeActionOrCommand::CodeAction(action)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)]\npub struct CodeActionKind(Cow<'static, str>);\n\nimpl CodeActionKind {\n    /// Empty kind.\n    pub const EMPTY: CodeActionKind = CodeActionKind::new(\"\");\n\n    /// Base kind for quickfix actions: 'quickfix'\n    pub const QUICKFIX: CodeActionKind = CodeActionKind::new(\"quickfix\");\n\n    /// Base kind for refactoring actions: 'refactor'\n    pub const REFACTOR: CodeActionKind = CodeActionKind::new(\"refactor\");\n\n    /// Base kind for refactoring extraction actions: 'refactor.extract'\n    ///\n    /// Example extract actions:\n    ///\n    /// - Extract method\n    /// - Extract function\n    /// - Extract variable\n    /// - Extract interface from class\n    /// - ...\n    pub const REFACTOR_EXTRACT: CodeActionKind = CodeActionKind::new(\"refactor.extract\");\n\n    /// Base kind for refactoring inline actions: 'refactor.inline'\n    ///\n    /// Example inline actions:\n    ///\n    /// - Inline function\n    /// - Inline variable\n    /// - Inline constant\n    /// - ...\n    pub const REFACTOR_INLINE: CodeActionKind = CodeActionKind::new(\"refactor.inline\");\n\n    /// Base kind for refactoring rewrite actions: 'refactor.rewrite'\n    ///\n    /// Example rewrite actions:\n    ///\n    /// - Convert JavaScript function to class\n    /// - Add or remove parameter\n    /// - Encapsulate field\n    /// - Make method static\n    /// - Move method to base class\n    /// - ...\n    pub const REFACTOR_REWRITE: CodeActionKind = CodeActionKind::new(\"refactor.rewrite\");\n\n    /// Base kind for source actions: `source`\n    ///\n    /// Source code actions apply to the entire file.\n    pub const SOURCE: CodeActionKind = CodeActionKind::new(\"source\");\n\n    /// Base kind for an organize imports source action: `source.organizeImports`\n    pub const SOURCE_ORGANIZE_IMPORTS: CodeActionKind =\n        CodeActionKind::new(\"source.organizeImports\");\n\n    /// Base kind for a 'fix all' source action: `source.fixAll`.\n    ///\n    /// 'Fix all' actions automatically fix errors that have a clear fix that\n    /// do not require user input. They should not suppress errors or perform\n    /// unsafe fixes such as generating new types or classes.\n    ///\n    /// @since 3.17.0\n    pub const SOURCE_FIX_ALL: CodeActionKind = CodeActionKind::new(\"source.fixAll\");\n\n    pub const fn new(tag: &'static str) -> Self {\n        CodeActionKind(Cow::Borrowed(tag))\n    }\n\n    pub fn as_str(&self) -> &str {\n        &self.0\n    }\n}\n\nimpl From<String> for CodeActionKind {\n    fn from(from: String) -> Self {\n        CodeActionKind(Cow::from(from))\n    }\n}\n\nimpl From<&'static str> for CodeActionKind {\n    fn from(from: &'static str) -> Self {\n        CodeActionKind::new(from)\n    }\n}\n\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeAction {\n    /// A short, human-readable, title for this code action.\n    pub title: String,\n\n    /// The kind of the code action.\n    /// Used to filter code actions.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub kind: Option<CodeActionKind>,\n\n    /// The diagnostics that this code action resolves.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub diagnostics: Option<Vec<Diagnostic>>,\n\n    /// The workspace edit this code action performs.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub edit: Option<WorkspaceEdit>,\n\n    /// A command this code action executes. If a code action\n    /// provides an edit and a command, first the edit is\n    /// executed and then the command.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub command: Option<Command>,\n\n    /// Marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted\n    /// by keybindings.\n    /// A quick fix should be marked preferred if it properly addresses the underlying error.\n    /// A refactoring should be marked preferred if it is the most reasonable choice of actions to take.\n    ///\n    /// @since 3.15.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub is_preferred: Option<bool>,\n\n    /// Marks that the code action cannot currently be applied.\n    ///\n    /// Clients should follow the following guidelines regarding disabled code actions:\n    ///\n    /// - Disabled code actions are not shown in automatic\n    ///   [lightbulb](https://code.visualstudio.com/docs/editor/editingevolved#_code-action)\n    ///   code action menu.\n    ///\n    /// - Disabled actions are shown as faded out in the code action menu when the user request\n    ///   a more specific type of code action, such as refactorings.\n    ///\n    /// - If the user has a keybinding that auto applies a code action and only a disabled code\n    ///   actions are returned, the client should show the user an error message with `reason`\n    ///   in the editor.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub disabled: Option<CodeActionDisabled>,\n\n    /// A data entry field that is preserved on a code action between\n    /// a `textDocument/codeAction` and a `codeAction/resolve` request.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data: Option<Value>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeActionDisabled {\n    /// Human readable description of why the code action is currently disabled.\n    ///\n    /// This is displayed in the code actions UI.\n    pub reason: String,\n}\n\n/// The reason why code actions were requested.\n///\n/// @since 3.17.0\n#[derive(Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct CodeActionTriggerKind(i32);\nlsp_enum! {\nimpl CodeActionTriggerKind {\n    /// Code actions were explicitly requested by the user or by an extension.\n    pub const INVOKED: CodeActionTriggerKind = CodeActionTriggerKind(1);\n\n    /// Code actions were requested automatically.\n    ///\n    /// This typically happens when current selection in a file changes, but can\n    /// also be triggered when file content changes.\n    pub const AUTOMATIC: CodeActionTriggerKind = CodeActionTriggerKind(2);\n}\n}\n\n/// Contains additional diagnostic information about the context in which\n/// a code action is run.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeActionContext {\n    /// An array of diagnostics.\n    pub diagnostics: Vec<Diagnostic>,\n\n    /// Requested kind of actions to return.\n    ///\n    /// Actions not of this kind are filtered out by the client before being shown. So servers\n    /// can omit computing them.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub only: Option<Vec<CodeActionKind>>,\n\n    /// The reason why code actions were requested.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub trigger_kind: Option<CodeActionTriggerKind>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize, Default)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeActionOptions {\n    /// CodeActionKinds that this server may return.\n    ///\n    /// The list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server\n    /// may list out every specific kind they provide.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub code_action_kinds: Option<Vec<CodeActionKind>>,\n\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n\n    /// The server provides support to resolve additional\n    /// information for a code action.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resolve_provider: Option<bool>,\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::tests::test_serialization;\n\n    #[test]\n    fn test_code_action_response() {\n        test_serialization(\n            &vec![\n                CodeActionOrCommand::Command(Command {\n                    title: \"title\".to_string(),\n                    command: \"command\".to_string(),\n                    arguments: None,\n                }),\n                CodeActionOrCommand::CodeAction(CodeAction {\n                    title: \"title\".to_string(),\n                    kind: Some(CodeActionKind::QUICKFIX),\n                    command: None,\n                    diagnostics: None,\n                    edit: None,\n                    is_preferred: None,\n                    ..CodeAction::default()\n                }),\n            ],\n            r#\"[{\"title\":\"title\",\"command\":\"command\"},{\"title\":\"title\",\"kind\":\"quickfix\"}]\"#,\n        )\n    }\n}\n"
  },
  {
    "path": "helix-lsp-types/src/code_lens.rs",
    "content": "use serde::{Deserialize, Serialize};\nuse serde_json::Value;\n\nuse crate::{\n    Command, DynamicRegistrationClientCapabilities, PartialResultParams, Range,\n    TextDocumentIdentifier, WorkDoneProgressParams,\n};\n\npub type CodeLensClientCapabilities = DynamicRegistrationClientCapabilities;\n\n/// Code Lens options.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize, Copy)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeLensOptions {\n    /// Code lens has a resolve provider as well.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resolve_provider: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeLensParams {\n    /// The document to request code lens for.\n    pub text_document: TextDocumentIdentifier,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// A code lens represents a command that should be shown along with\n/// source text, like the number of references, a way to run tests, etc.\n///\n/// A code lens is _unresolved_ when no command is associated to it. For performance\n/// reasons the creation of a code lens and resolving should be done in two stages.\n#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeLens {\n    /// The range in which this code lens is valid. Should only span a single line.\n    pub range: Range,\n\n    /// The command this code lens represents.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub command: Option<Command>,\n\n    /// A data entry field that is preserved on a code lens item between\n    /// a code lens and a code lens resolve request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data: Option<Value>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeLensWorkspaceClientCapabilities {\n    /// Whether the client implementation supports a refresh request sent from the\n    /// server to the client.\n    ///\n    /// Note that this event is global and will force the client to refresh all\n    /// code lenses currently shown. It should be used with absolute care and is\n    /// useful for situation where a server for example detect a project wide\n    /// change that requires such a calculation.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub refresh_support: Option<bool>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/color.rs",
    "content": "use crate::{\n    DocumentSelector, DynamicRegistrationClientCapabilities, PartialResultParams, Range,\n    TextDocumentIdentifier, TextEdit, WorkDoneProgressParams,\n};\nuse serde::{Deserialize, Serialize};\n\npub type DocumentColorClientCapabilities = DynamicRegistrationClientCapabilities;\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ColorProviderOptions {}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct StaticTextDocumentColorProviderOptions {\n    /// A document selector to identify the scope of the registration. If set to null\n    /// the document selector provided on the client side will be used.\n    pub document_selector: Option<DocumentSelector>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub id: Option<String>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum ColorProviderCapability {\n    Simple(bool),\n    ColorProvider(ColorProviderOptions),\n    Options(StaticTextDocumentColorProviderOptions),\n}\n\nimpl From<ColorProviderOptions> for ColorProviderCapability {\n    fn from(from: ColorProviderOptions) -> Self {\n        Self::ColorProvider(from)\n    }\n}\n\nimpl From<StaticTextDocumentColorProviderOptions> for ColorProviderCapability {\n    fn from(from: StaticTextDocumentColorProviderOptions) -> Self {\n        Self::Options(from)\n    }\n}\n\nimpl From<bool> for ColorProviderCapability {\n    fn from(from: bool) -> Self {\n        Self::Simple(from)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentColorParams {\n    /// The text document\n    pub text_document: TextDocumentIdentifier,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ColorInformation {\n    /// The range in the document where this color appears.\n    pub range: Range,\n    /// The actual color value for this color range.\n    pub color: Color,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Copy)]\n#[serde(rename_all = \"camelCase\")]\npub struct Color {\n    /// The red component of this color in the range [0-1].\n    pub red: f32,\n    /// The green component of this color in the range [0-1].\n    pub green: f32,\n    /// The blue component of this color in the range [0-1].\n    pub blue: f32,\n    /// The alpha component of this color in the range [0-1].\n    pub alpha: f32,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ColorPresentationParams {\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The color information to request presentations for.\n    pub color: Color,\n\n    /// The range where the color would be inserted. Serves as a context.\n    pub range: Range,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Default, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct ColorPresentation {\n    /// The label of this color presentation. It will be shown on the color\n    /// picker header. By default this is also the text that is inserted when selecting\n    /// this color presentation.\n    pub label: String,\n\n    /// An [edit](#TextEdit) which is applied to a document when selecting\n    /// this presentation for the color.  When `falsy` the [label](#ColorPresentation.label)\n    /// is used.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub text_edit: Option<TextEdit>,\n\n    /// An optional array of additional [text edits](#TextEdit) that are applied when\n    /// selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub additional_text_edits: Option<Vec<TextEdit>>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/completion.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::{\n    Command, Documentation, MarkupKind, PartialResultParams, TagSupport,\n    TextDocumentPositionParams, TextDocumentRegistrationOptions, TextEdit, WorkDoneProgressOptions,\n    WorkDoneProgressParams,\n};\n\nuse crate::Range;\nuse serde_json::Value;\nuse std::fmt::Debug;\n\n/// Defines how to interpret the insert text in a completion item\n#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]\n#[serde(transparent)]\npub struct InsertTextFormat(i32);\nlsp_enum! {\nimpl InsertTextFormat {\n    pub const PLAIN_TEXT: InsertTextFormat = InsertTextFormat(1);\n    pub const SNIPPET: InsertTextFormat = InsertTextFormat(2);\n}\n}\n\n/// The kind of a completion entry.\n#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]\n#[serde(transparent)]\npub struct CompletionItemKind(i32);\nlsp_enum! {\nimpl CompletionItemKind {\n    pub const TEXT: CompletionItemKind = CompletionItemKind(1);\n    pub const METHOD: CompletionItemKind = CompletionItemKind(2);\n    pub const FUNCTION: CompletionItemKind = CompletionItemKind(3);\n    pub const CONSTRUCTOR: CompletionItemKind = CompletionItemKind(4);\n    pub const FIELD: CompletionItemKind = CompletionItemKind(5);\n    pub const VARIABLE: CompletionItemKind = CompletionItemKind(6);\n    pub const CLASS: CompletionItemKind = CompletionItemKind(7);\n    pub const INTERFACE: CompletionItemKind = CompletionItemKind(8);\n    pub const MODULE: CompletionItemKind = CompletionItemKind(9);\n    pub const PROPERTY: CompletionItemKind = CompletionItemKind(10);\n    pub const UNIT: CompletionItemKind = CompletionItemKind(11);\n    pub const VALUE: CompletionItemKind = CompletionItemKind(12);\n    pub const ENUM: CompletionItemKind = CompletionItemKind(13);\n    pub const KEYWORD: CompletionItemKind = CompletionItemKind(14);\n    pub const SNIPPET: CompletionItemKind = CompletionItemKind(15);\n    pub const COLOR: CompletionItemKind = CompletionItemKind(16);\n    pub const FILE: CompletionItemKind = CompletionItemKind(17);\n    pub const REFERENCE: CompletionItemKind = CompletionItemKind(18);\n    pub const FOLDER: CompletionItemKind = CompletionItemKind(19);\n    pub const ENUM_MEMBER: CompletionItemKind = CompletionItemKind(20);\n    pub const CONSTANT: CompletionItemKind = CompletionItemKind(21);\n    pub const STRUCT: CompletionItemKind = CompletionItemKind(22);\n    pub const EVENT: CompletionItemKind = CompletionItemKind(23);\n    pub const OPERATOR: CompletionItemKind = CompletionItemKind(24);\n    pub const TYPE_PARAMETER: CompletionItemKind = CompletionItemKind(25);\n}\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionItemCapability {\n    /// Client supports snippets as insert text.\n    ///\n    /// A snippet can define tab stops and placeholders with `$1`, `$2`\n    /// and `${3:foo}`. `$0` defines the final tab stop, it defaults to\n    /// the end of the snippet. Placeholders with equal identifiers are linked,\n    /// that is typing in one will update others too.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub snippet_support: Option<bool>,\n\n    /// Client supports commit characters on a completion item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub commit_characters_support: Option<bool>,\n\n    /// Client supports the follow content formats for the documentation\n    /// property. The order describes the preferred format of the client.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub documentation_format: Option<Vec<MarkupKind>>,\n\n    /// Client supports the deprecated property on a completion item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub deprecated_support: Option<bool>,\n\n    /// Client supports the preselect property on a completion item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub preselect_support: Option<bool>,\n\n    /// Client supports the tag property on a completion item. Clients supporting\n    /// tags have to handle unknown tags gracefully. Clients especially need to\n    /// preserve unknown tags when sending a completion item back to the server in\n    /// a resolve call.\n    #[serde(\n        default,\n        skip_serializing_if = \"Option::is_none\",\n        deserialize_with = \"TagSupport::deserialize_compat\"\n    )]\n    pub tag_support: Option<TagSupport<CompletionItemTag>>,\n\n    /// Client support insert replace edit to control different behavior if a\n    /// completion item is inserted in the text or should replace text.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub insert_replace_support: Option<bool>,\n\n    /// Indicates which properties a client can resolve lazily on a completion\n    /// item. Before version 3.16.0 only the predefined properties `documentation`\n    /// and `details` could be resolved lazily.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resolve_support: Option<CompletionItemCapabilityResolveSupport>,\n\n    /// The client supports the `insertTextMode` property on\n    /// a completion item to override the whitespace handling mode\n    /// as defined by the client.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub insert_text_mode_support: Option<InsertTextModeSupport>,\n\n    /// The client has support for completion item label\n    /// details (see also `CompletionItemLabelDetails`).\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub label_details_support: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionItemCapabilityResolveSupport {\n    /// The properties that a client can resolve lazily.\n    pub properties: Vec<String>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InsertTextModeSupport {\n    pub value_set: Vec<InsertTextMode>,\n}\n\n/// How whitespace and indentation is handled during completion\n/// item insertion.\n///\n/// @since 3.16.0\n#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]\n#[serde(transparent)]\npub struct InsertTextMode(i32);\nlsp_enum! {\nimpl InsertTextMode {\n    /// The insertion or replace strings is taken as it is. If the\n    /// value is multi line the lines below the cursor will be\n    /// inserted using the indentation defined in the string value.\n    /// The client will not apply any kind of adjustments to the\n    /// string.\n    pub const AS_IS: InsertTextMode = InsertTextMode(1);\n\n    /// The editor adjusts leading whitespace of new lines so that\n    /// they match the indentation up to the cursor of the line for\n    /// which the item is accepted.\n    ///\n    /// Consider a line like this: `<2tabs><cursor><3tabs>foo`. Accepting a\n    /// multi line completion item is indented using 2 tabs all\n    /// following lines inserted will be indented using 2 tabs as well.\n    pub const ADJUST_INDENTATION: InsertTextMode = InsertTextMode(2);\n}\n}\n\n#[derive(Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct CompletionItemTag(i32);\nlsp_enum! {\nimpl CompletionItemTag {\n    pub const DEPRECATED: CompletionItemTag = CompletionItemTag(1);\n}\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionItemKindCapability {\n    /// The completion item kind values the client supports. When this\n    /// property exists the client also guarantees that it will\n    /// handle values outside its set gracefully and falls back\n    /// to a default value when unknown.\n    ///\n    /// If this property is not present the client only supports\n    /// the completion items kinds from `Text` to `Reference` as defined in\n    /// the initial version of the protocol.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub value_set: Option<Vec<CompletionItemKind>>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionListCapability {\n    /// The client supports the following itemDefaults on\n    /// a completion list.\n    ///\n    /// The value lists the supported property names of the\n    /// `CompletionList.itemDefaults` object. If omitted\n    /// no properties are supported.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub item_defaults: Option<Vec<String>>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionClientCapabilities {\n    /// Whether completion supports dynamic registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// The client supports the following `CompletionItem` specific\n    /// capabilities.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub completion_item: Option<CompletionItemCapability>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub completion_item_kind: Option<CompletionItemKindCapability>,\n\n    /// The client supports to send additional context information for a\n    /// `textDocument/completion` request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub context_support: Option<bool>,\n\n    /// The client's default when the completion item doesn't provide a\n    /// `insertTextMode` property.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub insert_text_mode: Option<InsertTextMode>,\n\n    /// The client supports the following `CompletionList` specific\n    /// capabilities.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub completion_list: Option<CompletionListCapability>,\n}\n\n/// A special text edit to provide an insert and a replace operation.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InsertReplaceEdit {\n    /// The string to be inserted.\n    pub new_text: String,\n\n    /// The range if the insert is requested\n    pub insert: Range,\n\n    /// The range if the replace is requested.\n    pub replace: Range,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum CompletionTextEdit {\n    Edit(TextEdit),\n    InsertAndReplace(InsertReplaceEdit),\n}\n\nimpl From<TextEdit> for CompletionTextEdit {\n    fn from(edit: TextEdit) -> Self {\n        CompletionTextEdit::Edit(edit)\n    }\n}\n\nimpl From<InsertReplaceEdit> for CompletionTextEdit {\n    fn from(edit: InsertReplaceEdit) -> Self {\n        CompletionTextEdit::InsertAndReplace(edit)\n    }\n}\n\n/// Completion options.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionOptions {\n    /// The server provides support to resolve additional information for a completion item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resolve_provider: Option<bool>,\n\n    /// Most tools trigger completion request automatically without explicitly\n    /// requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they\n    /// do so when the user starts to type an identifier. For example if the user\n    /// types `c` in a JavaScript file code complete will automatically pop up\n    /// present `console` besides others as a completion item. Characters that\n    /// make up identifiers don't need to be listed here.\n    ///\n    /// If code complete should automatically be trigger on characters not being\n    /// valid inside an identifier (for example `.` in JavaScript) list them in\n    /// `triggerCharacters`.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub trigger_characters: Option<Vec<String>>,\n\n    /// The list of all possible characters that commit a completion. This field\n    /// can be used if clients don't support individual commit characters per\n    /// completion item. See client capability\n    /// `completion.completionItem.commitCharactersSupport`.\n    ///\n    /// If a server provides both `allCommitCharacters` and commit characters on\n    /// an individual completion item the ones on the completion item win.\n    ///\n    /// @since 3.2.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub all_commit_characters: Option<Vec<String>>,\n\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n\n    /// The server supports the following `CompletionItem` specific\n    /// capabilities.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub completion_item: Option<CompletionOptionsCompletionItem>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionOptionsCompletionItem {\n    /// The server has support for completion item label\n    /// details (see also `CompletionItemLabelDetails`) when receiving\n    /// a completion item in a resolve call.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub label_details_support: Option<bool>,\n}\n\n#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]\npub struct CompletionRegistrationOptions {\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub completion_options: CompletionOptions,\n}\n\n#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]\n#[serde(untagged)]\npub enum CompletionResponse {\n    Array(Vec<CompletionItem>),\n    List(CompletionList),\n}\n\nimpl From<Vec<CompletionItem>> for CompletionResponse {\n    fn from(items: Vec<CompletionItem>) -> Self {\n        CompletionResponse::Array(items)\n    }\n}\n\nimpl From<CompletionList> for CompletionResponse {\n    fn from(list: CompletionList) -> Self {\n        CompletionResponse::List(list)\n    }\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionParams {\n    // This field was \"mixed-in\" from TextDocumentPositionParams\n    #[serde(flatten)]\n    pub text_document_position: TextDocumentPositionParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n\n    // CompletionParams properties:\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub context: Option<CompletionContext>,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionContext {\n    /// How the completion was triggered.\n    pub trigger_kind: CompletionTriggerKind,\n\n    /// The trigger character (a single character) that has trigger code complete.\n    /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub trigger_character: Option<String>,\n}\n\n/// How a completion was triggered.\n#[derive(Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct CompletionTriggerKind(i32);\nlsp_enum! {\nimpl CompletionTriggerKind {\n    pub const INVOKED: CompletionTriggerKind = CompletionTriggerKind(1);\n    pub const TRIGGER_CHARACTER: CompletionTriggerKind = CompletionTriggerKind(2);\n    pub const TRIGGER_FOR_INCOMPLETE_COMPLETIONS: CompletionTriggerKind = CompletionTriggerKind(3);\n}\n}\n\n/// Represents a collection of [completion items](#CompletionItem) to be presented\n/// in the editor.\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionList {\n    /// This list it not complete. Further typing should result in recomputing\n    /// this list.\n    pub is_incomplete: bool,\n\n    /// The completion items.\n    pub items: Vec<CompletionItem>,\n}\n\n#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionItem {\n    /// The label of this completion item. By default\n    /// also the text that is inserted when selecting\n    /// this completion.\n    pub label: String,\n\n    /// Additional details for the label\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub label_details: Option<CompletionItemLabelDetails>,\n\n    /// The kind of this completion item. Based of the kind\n    /// an icon is chosen by the editor.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub kind: Option<CompletionItemKind>,\n\n    /// A human-readable string with additional information\n    /// about this item, like type or symbol information.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub detail: Option<String>,\n\n    /// A human-readable string that represents a doc-comment.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub documentation: Option<Documentation>,\n\n    /// Indicates if this item is deprecated.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub deprecated: Option<bool>,\n\n    /// Select this item when showing.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub preselect: Option<bool>,\n\n    /// A string that should be used when comparing this item\n    /// with other items. When `falsy` the label is used\n    /// as the sort text for this item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub sort_text: Option<String>,\n\n    /// A string that should be used when filtering a set of\n    /// completion items. When `falsy` the label is used as the\n    /// filter text for this item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub filter_text: Option<String>,\n\n    /// A string that should be inserted into a document when selecting\n    /// this completion. When `falsy` the label is used as the insert text\n    /// for this item.\n    ///\n    /// The `insertText` is subject to interpretation by the client side.\n    /// Some tools might not take the string literally. For example\n    /// VS Code when code complete is requested in this example\n    /// `con<cursor position>` and a completion item with an `insertText` of\n    /// `console` is provided it will only insert `sole`. Therefore it is\n    /// recommended to use `textEdit` instead since it avoids additional client\n    /// side interpretation.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub insert_text: Option<String>,\n\n    /// The format of the insert text. The format applies to both the `insertText` property\n    /// and the `newText` property of a provided `textEdit`. If omitted defaults to `InsertTextFormat.PlainText`.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub insert_text_format: Option<InsertTextFormat>,\n\n    /// How whitespace and indentation is handled during completion\n    /// item insertion. If not provided the client's default value depends on\n    /// the `textDocument.completion.insertTextMode` client capability.\n    ///\n    /// @since 3.16.0\n    /// @since 3.17.0 - support for `textDocument.completion.insertTextMode`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub insert_text_mode: Option<InsertTextMode>,\n\n    /// An edit which is applied to a document when selecting\n    /// this completion. When an edit is provided the value of\n    /// insertText is ignored.\n    ///\n    /// Most editors support two different operation when accepting a completion item. One is to insert a\n    /// completion text and the other is to replace an existing text with a completion text. Since this can\n    /// usually not predetermined by a server it can report both ranges. Clients need to signal support for\n    /// `InsertReplaceEdits` via the `textDocument.completion.insertReplaceSupport` client capability\n    /// property.\n    ///\n    /// *Note 1:* The text edit's range as well as both ranges from a insert replace edit must be a\n    /// [single line] and they must contain the position at which completion has been requested.\n    /// *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range must be a prefix of\n    /// the edit's replace range, that means it must be contained and starting at the same position.\n    ///\n    /// @since 3.16.0 additional type `InsertReplaceEdit`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub text_edit: Option<CompletionTextEdit>,\n\n    /// An optional array of additional text edits that are applied when\n    /// selecting this completion. Edits must not overlap with the main edit\n    /// nor with themselves.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub additional_text_edits: Option<Vec<TextEdit>>,\n\n    /// An optional command that is executed *after* inserting this completion. *Note* that\n    /// additional modifications to the current document should be described with the\n    /// additionalTextEdits-property.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub command: Option<Command>,\n\n    /// An optional set of characters that when pressed while this completion is\n    /// active will accept it first and then type that character. *Note* that all\n    /// commit characters should have `length=1` and that superfluous characters\n    /// will be ignored.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub commit_characters: Option<Vec<String>>,\n\n    /// An data entry field that is preserved on a completion item between\n    /// a completion and a completion resolve request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data: Option<Value>,\n\n    /// Tags for this completion item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tags: Option<Vec<CompletionItemTag>>,\n}\n\nimpl CompletionItem {\n    /// Create a CompletionItem with the minimum possible info (label and detail).\n    pub fn new_simple(label: String, detail: String) -> CompletionItem {\n        CompletionItem {\n            label,\n            detail: Some(detail),\n            ..Self::default()\n        }\n    }\n}\n\n/// Additional details for a completion item label.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct CompletionItemLabelDetails {\n    /// An optional string which is rendered less prominently directly after\n    /// {@link CompletionItemLabel.label label}, without any spacing. Should be\n    /// used for function signatures or type annotations.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub detail: Option<String>,\n\n    /// An optional string which is rendered less prominently after\n    /// {@link CompletionItemLabel.detail}. Should be used for fully qualified\n    /// names or file path.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub description: Option<String>,\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::tests::test_deserialization;\n\n    #[test]\n    fn test_tag_support_deserialization() {\n        let empty = CompletionItemCapability {\n            tag_support: None,\n            ..CompletionItemCapability::default()\n        };\n\n        test_deserialization(r#\"{}\"#, &empty);\n        test_deserialization(r#\"{\"tagSupport\": false}\"#, &empty);\n\n        let t = CompletionItemCapability {\n            tag_support: Some(TagSupport { value_set: vec![] }),\n            ..CompletionItemCapability::default()\n        };\n        test_deserialization(r#\"{\"tagSupport\": true}\"#, &t);\n\n        let t = CompletionItemCapability {\n            tag_support: Some(TagSupport {\n                value_set: vec![CompletionItemTag::DEPRECATED],\n            }),\n            ..CompletionItemCapability::default()\n        };\n        test_deserialization(r#\"{\"tagSupport\": {\"valueSet\": [1]}}\"#, &t);\n    }\n\n    #[test]\n    fn test_debug_enum() {\n        assert_eq!(format!(\"{:?}\", CompletionItemKind::TEXT), \"Text\");\n        assert_eq!(\n            format!(\"{:?}\", CompletionItemKind::TYPE_PARAMETER),\n            \"TypeParameter\"\n        );\n    }\n\n    #[test]\n    fn test_try_from_enum() {\n        use std::convert::TryInto;\n        assert_eq!(\"Text\".try_into(), Ok(CompletionItemKind::TEXT));\n        assert_eq!(\n            \"TypeParameter\".try_into(),\n            Ok(CompletionItemKind::TYPE_PARAMETER)\n        );\n    }\n}\n"
  },
  {
    "path": "helix-lsp-types/src/document_diagnostic.rs",
    "content": "use std::{collections::HashMap, sync::Arc};\n\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n    Diagnostic, PartialResultParams, StaticRegistrationOptions, TextDocumentIdentifier,\n    TextDocumentRegistrationOptions, Url, WorkDoneProgressOptions, WorkDoneProgressParams,\n};\n\n/// Client capabilities specific to diagnostic pull requests.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DiagnosticClientCapabilities {\n    /// Whether implementation supports dynamic registration.\n    ///\n    /// If this is set to `true` the client supports the new `(TextDocumentRegistrationOptions &\n    /// StaticRegistrationOptions)` return value for the corresponding server capability as well.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// Whether the clients supports related documents for document diagnostic pulls.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub related_document_support: Option<bool>,\n}\n\n/// Diagnostic options.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DiagnosticOptions {\n    /// An optional identifier under which the diagnostics are\n    /// managed by the client.\n    #[serde(\n        default,\n        skip_serializing_if = \"Option::is_none\",\n        serialize_with = \"serialize_option_arc_str\",\n        deserialize_with = \"deserialize_option_arc_str\"\n    )]\n    pub identifier: Option<Arc<str>>,\n\n    /// Whether the language has inter file dependencies, meaning that editing code in one file can\n    /// result in a different diagnostic set in another file. Inter file dependencies are common\n    /// for most programming languages and typically uncommon for linters.\n    pub inter_file_dependencies: bool,\n\n    /// The server provides support for workspace diagnostics as well.\n    pub workspace_diagnostics: bool,\n\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\nfn serialize_option_arc_str<S: serde::Serializer>(\n    val: &Option<Arc<str>>,\n    serializer: S,\n) -> Result<S::Ok, S::Error> {\n    serializer.serialize_str(val.as_ref().unwrap())\n}\n\nfn deserialize_option_arc_str<'de, D: serde::Deserializer<'de>>(\n    deserializer: D,\n) -> Result<Option<Arc<str>>, D::Error> {\n    Option::<String>::deserialize(deserializer).map(|opt| opt.map(|s| s.into()))\n}\n\n/// Diagnostic registration options.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DiagnosticRegistrationOptions {\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub diagnostic_options: DiagnosticOptions,\n\n    #[serde(flatten)]\n    pub static_registration_options: StaticRegistrationOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum DiagnosticServerCapabilities {\n    Options(DiagnosticOptions),\n    RegistrationOptions(DiagnosticRegistrationOptions),\n}\n\n/// Parameters of the document diagnostic request.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentDiagnosticParams {\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The additional identifier provided during registration.\n    #[serde(\n        default,\n        skip_serializing_if = \"Option::is_none\",\n        serialize_with = \"serialize_option_arc_str\",\n        deserialize_with = \"deserialize_option_arc_str\"\n    )]\n    pub identifier: Option<Arc<str>>,\n\n    /// The result ID of a previous response if provided.\n    pub previous_result_id: Option<String>,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// A diagnostic report with a full set of problems.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct FullDocumentDiagnosticReport {\n    /// An optional result ID. If provided it will be sent on the next diagnostic request for the\n    /// same document.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub result_id: Option<String>,\n\n    /// The actual items.\n    pub items: Vec<Diagnostic>,\n}\n\n/// A diagnostic report indicating that the last returned report is still accurate.\n///\n/// A server can only return `unchanged` if result ids are provided.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct UnchangedDocumentDiagnosticReport {\n    /// A result ID which will be sent on the next diagnostic request for the same document.\n    pub result_id: String,\n}\n\n/// The document diagnostic report kinds.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(tag = \"kind\", rename_all = \"lowercase\")]\npub enum DocumentDiagnosticReportKind {\n    /// A diagnostic report with a full set of problems.\n    Full(FullDocumentDiagnosticReport),\n    /// A report indicating that the last returned report is still accurate.\n    Unchanged(UnchangedDocumentDiagnosticReport),\n}\n\nimpl From<FullDocumentDiagnosticReport> for DocumentDiagnosticReportKind {\n    fn from(from: FullDocumentDiagnosticReport) -> Self {\n        DocumentDiagnosticReportKind::Full(from)\n    }\n}\n\nimpl From<UnchangedDocumentDiagnosticReport> for DocumentDiagnosticReportKind {\n    fn from(from: UnchangedDocumentDiagnosticReport) -> Self {\n        DocumentDiagnosticReportKind::Unchanged(from)\n    }\n}\n\n/// A full diagnostic report with a set of related documents.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct RelatedFullDocumentDiagnosticReport {\n    /// Diagnostics of related documents.\n    ///\n    /// This information is useful in programming languages where code in a file A can generate\n    /// diagnostics in a file B which A depends on. An example of such a language is C/C++ where\n    /// macro definitions in a file `a.cpp` result in errors in a header file `b.hpp`.\n    ///\n    /// @since 3.17.0\n    #[serde(with = \"crate::url_map\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[serde(default)]\n    pub related_documents: Option<HashMap<Url, DocumentDiagnosticReportKind>>,\n    // relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };\n    #[serde(flatten)]\n    pub full_document_diagnostic_report: FullDocumentDiagnosticReport,\n}\n\n/// An unchanged diagnostic report with a set of related documents.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct RelatedUnchangedDocumentDiagnosticReport {\n    /// Diagnostics of related documents.\n    ///\n    /// This information is useful in programming languages where code in a file A can generate\n    /// diagnostics in a file B which A depends on. An example of such a language is C/C++ where\n    /// macro definitions in a file `a.cpp` result in errors in a header file `b.hpp`.\n    ///\n    /// @since 3.17.0\n    #[serde(with = \"crate::url_map\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[serde(default)]\n    pub related_documents: Option<HashMap<Url, DocumentDiagnosticReportKind>>,\n    // relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };\n    #[serde(flatten)]\n    pub unchanged_document_diagnostic_report: UnchangedDocumentDiagnosticReport,\n}\n\n/// The result of a document diagnostic pull request.\n///\n/// A report can either be a full report containing all diagnostics for the requested document or\n/// an unchanged report indicating that nothing has changed in terms of diagnostics in comparison\n/// to the last pull request.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(tag = \"kind\", rename_all = \"lowercase\")]\npub enum DocumentDiagnosticReport {\n    /// A diagnostic report with a full set of problems.\n    Full(RelatedFullDocumentDiagnosticReport),\n    /// A report indicating that the last returned report is still accurate.\n    Unchanged(RelatedUnchangedDocumentDiagnosticReport),\n}\n\nimpl From<RelatedFullDocumentDiagnosticReport> for DocumentDiagnosticReport {\n    fn from(from: RelatedFullDocumentDiagnosticReport) -> Self {\n        DocumentDiagnosticReport::Full(from)\n    }\n}\n\nimpl From<RelatedUnchangedDocumentDiagnosticReport> for DocumentDiagnosticReport {\n    fn from(from: RelatedUnchangedDocumentDiagnosticReport) -> Self {\n        DocumentDiagnosticReport::Unchanged(from)\n    }\n}\n\n/// A partial result for a document diagnostic report.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentDiagnosticReportPartialResult {\n    #[serde(with = \"crate::url_map\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[serde(default)]\n    pub related_documents: Option<HashMap<Url, DocumentDiagnosticReportKind>>,\n    // relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };\n}\n\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(untagged)]\npub enum DocumentDiagnosticReportResult {\n    Report(DocumentDiagnosticReport),\n    Partial(DocumentDiagnosticReportPartialResult),\n}\n\nimpl From<DocumentDiagnosticReport> for DocumentDiagnosticReportResult {\n    fn from(from: DocumentDiagnosticReport) -> Self {\n        DocumentDiagnosticReportResult::Report(from)\n    }\n}\n\nimpl From<DocumentDiagnosticReportPartialResult> for DocumentDiagnosticReportResult {\n    fn from(from: DocumentDiagnosticReportPartialResult) -> Self {\n        DocumentDiagnosticReportResult::Partial(from)\n    }\n}\n\n/// Cancellation data returned from a diagnostic request.\n///\n/// If no data is provided, it defaults to `{ retrigger_request: true }`.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct DiagnosticServerCancellationData {\n    pub retrigger_request: bool,\n}\n\nimpl Default for DiagnosticServerCancellationData {\n    fn default() -> Self {\n        DiagnosticServerCancellationData {\n            retrigger_request: true,\n        }\n    }\n}\n"
  },
  {
    "path": "helix-lsp-types/src/document_highlight.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::{\n    DynamicRegistrationClientCapabilities, PartialResultParams, Range, TextDocumentPositionParams,\n    WorkDoneProgressParams,\n};\n\npub type DocumentHighlightClientCapabilities = DynamicRegistrationClientCapabilities;\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentHighlightParams {\n    #[serde(flatten)]\n    pub text_document_position_params: TextDocumentPositionParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// A document highlight is a range inside a text document which deserves\n/// special attention. Usually a document highlight is visualized by changing\n/// the background color of its range.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct DocumentHighlight {\n    /// The range this highlight applies to.\n    pub range: Range,\n\n    /// The highlight kind, default is DocumentHighlightKind.Text.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub kind: Option<DocumentHighlightKind>,\n}\n\n/// A document highlight kind.\n#[derive(Eq, PartialEq, Copy, Clone, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct DocumentHighlightKind(i32);\nlsp_enum! {\nimpl DocumentHighlightKind {\n    /// A textual occurrence.\n    pub const TEXT: DocumentHighlightKind = DocumentHighlightKind(1);\n\n    /// Read-access of a symbol, like reading a variable.\n    pub const READ: DocumentHighlightKind = DocumentHighlightKind(2);\n\n    /// Write-access of a symbol, like writing to a variable.\n    pub const WRITE: DocumentHighlightKind = DocumentHighlightKind(3);\n}\n}\n"
  },
  {
    "path": "helix-lsp-types/src/document_link.rs",
    "content": "use crate::{\n    PartialResultParams, Range, TextDocumentIdentifier, Url, WorkDoneProgressOptions,\n    WorkDoneProgressParams,\n};\nuse serde::{Deserialize, Serialize};\nuse serde_json::Value;\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentLinkClientCapabilities {\n    /// Whether document link supports dynamic registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// Whether the client support the `tooltip` property on `DocumentLink`.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tooltip_support: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentLinkOptions {\n    /// Document links have a resolve provider as well.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resolve_provider: Option<bool>,\n\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentLinkParams {\n    /// The document to provide document links for.\n    pub text_document: TextDocumentIdentifier,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// A document link is a range in a text document that links to an internal or external resource, like another\n/// text document or a web site.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct DocumentLink {\n    /// The range this link applies to.\n    pub range: Range,\n    /// The uri this link points to.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub target: Option<Url>,\n\n    /// The tooltip text when you hover over this link.\n    ///\n    /// If a tooltip is provided, is will be displayed in a string that includes instructions on how to\n    /// trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS,\n    /// user settings, and localization.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tooltip: Option<String>,\n\n    /// A data entry field that is preserved on a document link between a DocumentLinkRequest\n    /// and a DocumentLinkResolveRequest.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data: Option<Value>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/document_symbols.rs",
    "content": "use crate::{\n    Location, PartialResultParams, Range, SymbolKind, SymbolKindCapability, TextDocumentIdentifier,\n    WorkDoneProgressParams,\n};\n\nuse crate::{SymbolTag, TagSupport};\n\nuse serde::{Deserialize, Serialize};\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentSymbolClientCapabilities {\n    /// This capability supports dynamic registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// Specific capabilities for the `SymbolKind`.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub symbol_kind: Option<SymbolKindCapability>,\n\n    /// The client support hierarchical document symbols.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub hierarchical_document_symbol_support: Option<bool>,\n\n    /// The client supports tags on `SymbolInformation`. Tags are supported on\n    /// `DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true.\n    /// Clients supporting tags have to handle unknown tags gracefully.\n    ///\n    /// @since 3.16.0\n    #[serde(\n        default,\n        skip_serializing_if = \"Option::is_none\",\n        deserialize_with = \"TagSupport::deserialize_compat\"\n    )]\n    pub tag_support: Option<TagSupport<SymbolTag>>,\n}\n\n#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]\n#[serde(untagged)]\npub enum DocumentSymbolResponse {\n    Flat(Vec<SymbolInformation>),\n    Nested(Vec<DocumentSymbol>),\n}\n\nimpl From<Vec<SymbolInformation>> for DocumentSymbolResponse {\n    fn from(info: Vec<SymbolInformation>) -> Self {\n        DocumentSymbolResponse::Flat(info)\n    }\n}\n\nimpl From<Vec<DocumentSymbol>> for DocumentSymbolResponse {\n    fn from(symbols: Vec<DocumentSymbol>) -> Self {\n        DocumentSymbolResponse::Nested(symbols)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentSymbolParams {\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// Represents programming constructs like variables, classes, interfaces etc.\n/// that appear in a document. Document symbols can be hierarchical and they have two ranges:\n/// one that encloses its definition and one that points to its most interesting range,\n/// e.g. the range of an identifier.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentSymbol {\n    /// The name of this symbol.\n    pub name: String,\n    /// More detail for this symbol, e.g the signature of a function. If not provided the\n    /// name is used.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub detail: Option<String>,\n    /// The kind of this symbol.\n    pub kind: SymbolKind,\n    /// Tags for this completion item.\n    ///\n    /// @since 3.15.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tags: Option<Vec<SymbolTag>>,\n    /// Indicates if this symbol is deprecated.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[deprecated(note = \"Use tags instead\")]\n    pub deprecated: Option<bool>,\n    /// The range enclosing this symbol not including leading/trailing whitespace but everything else\n    /// like comments. This information is typically used to determine if the the clients cursor is\n    /// inside the symbol to reveal in the symbol in the UI.\n    pub range: Range,\n    /// The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.\n    /// Must be contained by the the `range`.\n    pub selection_range: Range,\n    /// Children of this symbol, e.g. properties of a class.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub children: Option<Vec<DocumentSymbol>>,\n}\n\n/// Represents information about programming constructs like variables, classes,\n/// interfaces etc.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SymbolInformation {\n    /// The name of this symbol.\n    pub name: String,\n\n    /// The kind of this symbol.\n    pub kind: SymbolKind,\n\n    /// Tags for this completion item.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tags: Option<Vec<SymbolTag>>,\n\n    /// Indicates if this symbol is deprecated.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[deprecated(note = \"Use tags instead\")]\n    pub deprecated: Option<bool>,\n\n    /// The location of this symbol.\n    pub location: Location,\n\n    /// The name of the symbol containing this symbol.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub container_name: Option<String>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/error_codes.rs",
    "content": "//! In this module we only define constants for lsp specific error codes.\n//! There are other error codes that are defined in the\n//! [JSON RPC specification](https://www.jsonrpc.org/specification#error_object).\n\n/// Defined in the LSP specification but in the range reserved for JSON-RPC error codes,\n/// namely the -32099 to -32000 \"Reserved for implementation-defined server-errors.\" range.\n/// The code has, nonetheless, been left in this range for backwards compatibility reasons.\npub const SERVER_NOT_INITIALIZED: i64 = -32002;\n\n/// Defined in the LSP specification but in the range reserved for JSON-RPC error codes,\n/// namely the -32099 to -32000 \"Reserved for implementation-defined server-errors.\" range.\n/// The code has, nonetheless, left in this range for backwards compatibility reasons.\npub const UNKNOWN_ERROR_CODE: i64 = -32001;\n\n/// This is the start range of LSP reserved error codes.\n/// It doesn't denote a real error code.\n///\n/// @since 3.16.0\npub const LSP_RESERVED_ERROR_RANGE_START: i64 = -32899;\n\n/// A request failed but it was syntactically correct, e.g the\n/// method name was known and the parameters were valid. The error\n/// message should contain human readable information about why\n/// the request failed.\n///\n/// @since 3.17.0\npub const REQUEST_FAILED: i64 = -32803;\n\n/// The server cancelled the request. This error code should\n/// only be used for requests that explicitly support being\n/// server cancellable.\n///\n/// @since 3.17.0\npub const SERVER_CANCELLED: i64 = -32802;\n\n/// The server detected that the content of a document got\n/// modified outside normal conditions. A server should\n/// NOT send this error code if it detects a content change\n/// in it unprocessed messages. The result even computed\n/// on an older state might still be useful for the client.\n///\n/// If a client decides that a result is not of any use anymore\n/// the client should cancel the request.\npub const CONTENT_MODIFIED: i64 = -32801;\n\n/// The client has canceled a request and a server as detected\n/// the cancel.\npub const REQUEST_CANCELLED: i64 = -32800;\n\n/// This is the end range of LSP reserved error codes.\n/// It doesn't denote a real error code.\n///\n/// @since 3.16.0\npub const LSP_RESERVED_ERROR_RANGE_END: i64 = -32800;\n"
  },
  {
    "path": "helix-lsp-types/src/file_operations.rs",
    "content": "use serde::{Deserialize, Serialize};\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceFileOperationsClientCapabilities {\n    /// Whether the client supports dynamic registration for file\n    /// requests/notifications.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// The client has support for sending didCreateFiles notifications.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub did_create: Option<bool>,\n\n    /// The server is interested in receiving willCreateFiles requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub will_create: Option<bool>,\n\n    /// The server is interested in receiving didRenameFiles requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub did_rename: Option<bool>,\n\n    /// The server is interested in receiving willRenameFiles requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub will_rename: Option<bool>,\n\n    /// The server is interested in receiving didDeleteFiles requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub did_delete: Option<bool>,\n\n    /// The server is interested in receiving willDeleteFiles requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub will_delete: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceFileOperationsServerCapabilities {\n    /// The server is interested in receiving didCreateFiles\n    /// notifications.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub did_create: Option<FileOperationRegistrationOptions>,\n\n    /// The server is interested in receiving willCreateFiles requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub will_create: Option<FileOperationRegistrationOptions>,\n\n    /// The server is interested in receiving didRenameFiles\n    /// notifications.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub did_rename: Option<FileOperationRegistrationOptions>,\n\n    /// The server is interested in receiving willRenameFiles requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub will_rename: Option<FileOperationRegistrationOptions>,\n\n    /// The server is interested in receiving didDeleteFiles file\n    /// notifications.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub did_delete: Option<FileOperationRegistrationOptions>,\n\n    /// The server is interested in receiving willDeleteFiles file\n    /// requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub will_delete: Option<FileOperationRegistrationOptions>,\n}\n\n/// The options to register for file operations.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FileOperationRegistrationOptions {\n    /// The actual filters.\n    pub filters: Vec<FileOperationFilter>,\n}\n\n/// A filter to describe in which file operation requests or notifications\n/// the server is interested in.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FileOperationFilter {\n    /// A Uri like `file` or `untitled`.\n    pub scheme: Option<String>,\n\n    /// The actual file operation pattern.\n    pub pattern: FileOperationPattern,\n}\n\n/// A pattern kind describing if a glob pattern matches a file a folder or\n/// both.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"lowercase\")]\npub enum FileOperationPatternKind {\n    /// The pattern matches a file only.\n    File,\n\n    /// The pattern matches a folder only.\n    Folder,\n}\n\n/// Matching options for the file operation pattern.\n///\n/// @since 3.16.0\n///\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FileOperationPatternOptions {\n    /// The pattern should be matched ignoring casing.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub ignore_case: Option<bool>,\n}\n\n/// A pattern to describe in which file operation requests or notifications\n/// the server is interested in.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FileOperationPattern {\n    /// The glob pattern to match. Glob patterns can have the following syntax:\n    /// - `*` to match one or more characters in a path segment\n    /// - `?` to match on one character in a path segment\n    /// - `**` to match any number of path segments, including none\n    /// - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript\n    ///   and JavaScript files)\n    /// - `[]` to declare a range of characters to match in a path segment\n    ///   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)\n    /// - `[!...]` to negate a range of characters to match in a path segment\n    ///   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but\n    ///   not `example.0`)\n    pub glob: String,\n\n    /// Whether to match files or folders with this pattern.\n    ///\n    /// Matches both if undefined.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub matches: Option<FileOperationPatternKind>,\n\n    /// Additional options used during matching.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub options: Option<FileOperationPatternOptions>,\n}\n\n/// The parameters sent in notifications/requests for user-initiated creation\n/// of files.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CreateFilesParams {\n    /// An array of all files/folders created in this operation.\n    pub files: Vec<FileCreate>,\n}\n/// Represents information on a file/folder create.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FileCreate {\n    /// A file:// URI for the location of the file/folder being created.\n    pub uri: String,\n}\n\n/// The parameters sent in notifications/requests for user-initiated renames\n/// of files.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct RenameFilesParams {\n    /// An array of all files/folders renamed in this operation. When a folder\n    /// is renamed, only the folder will be included, and not its children.\n    pub files: Vec<FileRename>,\n}\n\n/// Represents information on a file/folder rename.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FileRename {\n    /// A file:// URI for the original location of the file/folder being renamed.\n    pub old_uri: String,\n\n    /// A file:// URI for the new location of the file/folder being renamed.\n    pub new_uri: String,\n}\n\n/// The parameters sent in notifications/requests for user-initiated deletes\n/// of files.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DeleteFilesParams {\n    /// An array of all files/folders deleted in this operation.\n    pub files: Vec<FileDelete>,\n}\n\n/// Represents information on a file/folder delete.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FileDelete {\n    /// A file:// URI for the location of the file/folder being deleted.\n    pub uri: String,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/folding_range.rs",
    "content": "use crate::{\n    PartialResultParams, StaticTextDocumentColorProviderOptions, TextDocumentIdentifier,\n    WorkDoneProgressParams,\n};\nuse serde::{Deserialize, Serialize};\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FoldingRangeParams {\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum FoldingRangeProviderCapability {\n    Simple(bool),\n    FoldingProvider(FoldingProviderOptions),\n    Options(StaticTextDocumentColorProviderOptions),\n}\n\nimpl From<StaticTextDocumentColorProviderOptions> for FoldingRangeProviderCapability {\n    fn from(from: StaticTextDocumentColorProviderOptions) -> Self {\n        Self::Options(from)\n    }\n}\n\nimpl From<FoldingProviderOptions> for FoldingRangeProviderCapability {\n    fn from(from: FoldingProviderOptions) -> Self {\n        Self::FoldingProvider(from)\n    }\n}\n\nimpl From<bool> for FoldingRangeProviderCapability {\n    fn from(from: bool) -> Self {\n        Self::Simple(from)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct FoldingProviderOptions {}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FoldingRangeKindCapability {\n    /// The folding range kind values the client supports. When this\n    /// property exists the client also guarantees that it will\n    /// handle values outside its set gracefully and falls back\n    /// to a default value when unknown.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub value_set: Option<Vec<FoldingRangeKind>>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FoldingRangeCapability {\n    /// If set, the client signals that it supports setting collapsedText on\n    /// folding ranges to display custom labels instead of the default text.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub collapsed_text: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FoldingRangeClientCapabilities {\n    /// Whether implementation supports dynamic registration for folding range providers. If this is set to `true`\n    /// the client supports the new `(FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)`\n    /// return value for the corresponding server capability as well.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// The maximum number of folding ranges that the client prefers to receive per document. The value serves as a\n    /// hint, servers are free to follow the limit.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub range_limit: Option<u32>,\n\n    /// If set, the client signals that it only supports folding complete lines. If set, client will\n    /// ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub line_folding_only: Option<bool>,\n\n    /// Specific options for the folding range kind.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub folding_range_kind: Option<FoldingRangeKindCapability>,\n\n    /// Specific options for the folding range.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub folding_range: Option<FoldingRangeCapability>,\n}\n\n/// Enum of known range kinds\n#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"lowercase\")]\npub enum FoldingRangeKind {\n    /// Folding range for a comment\n    Comment,\n    /// Folding range for a imports or includes\n    Imports,\n    /// Folding range for a region (e.g. `#region`)\n    Region,\n}\n\n/// Represents a folding range.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FoldingRange {\n    /// The zero-based line number from where the folded range starts.\n    pub start_line: u32,\n\n    /// The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub start_character: Option<u32>,\n\n    /// The zero-based line number where the folded range ends.\n    pub end_line: u32,\n\n    /// The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub end_character: Option<u32>,\n\n    /// Describes the kind of the folding range such as `comment' or 'region'. The kind\n    /// is used to categorize folding ranges and used by commands like 'Fold all comments'. See\n    /// [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub kind: Option<FoldingRangeKind>,\n\n    /// The text that the client should show when the specified range is\n    /// collapsed. If not defined or not supported by the client, a default\n    /// will be chosen by the client.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub collapsed_text: Option<String>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/formatting.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::{\n    DocumentSelector, DynamicRegistrationClientCapabilities, Range, TextDocumentIdentifier,\n    TextDocumentPositionParams, WorkDoneProgressParams,\n};\n\nuse std::collections::HashMap;\n\npub type DocumentFormattingClientCapabilities = DynamicRegistrationClientCapabilities;\npub type DocumentRangeFormattingClientCapabilities = DynamicRegistrationClientCapabilities;\npub type DocumentOnTypeFormattingClientCapabilities = DynamicRegistrationClientCapabilities;\n\n/// Format document on type options\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentOnTypeFormattingOptions {\n    /// A character on which formatting should be triggered, like `}`.\n    pub first_trigger_character: String,\n\n    /// More trigger characters.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub more_trigger_character: Option<Vec<String>>,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentFormattingParams {\n    /// The document to format.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The format options.\n    pub options: FormattingOptions,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n}\n\n/// Value-object describing what options formatting should use.\n#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FormattingOptions {\n    /// Size of a tab in spaces.\n    pub tab_size: u32,\n\n    /// Prefer spaces over tabs.\n    pub insert_spaces: bool,\n\n    /// Signature for further properties.\n    #[serde(flatten)]\n    pub properties: HashMap<String, FormattingProperty>,\n\n    /// Trim trailing whitespace on a line.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub trim_trailing_whitespace: Option<bool>,\n\n    /// Insert a newline character at the end of the file if one does not exist.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub insert_final_newline: Option<bool>,\n\n    /// Trim all newlines after the final newline at the end of the file.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub trim_final_newlines: Option<bool>,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum FormattingProperty {\n    Bool(bool),\n    Number(i32),\n    String(String),\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentRangeFormattingParams {\n    /// The document to format.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The range to format\n    pub range: Range,\n\n    /// The format options\n    pub options: FormattingOptions,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentOnTypeFormattingParams {\n    /// Text Document and Position fields.\n    #[serde(flatten)]\n    pub text_document_position: TextDocumentPositionParams,\n\n    /// The character that has been typed.\n    pub ch: String,\n\n    /// The format options.\n    pub options: FormattingOptions,\n}\n\n/// Extends TextDocumentRegistrationOptions\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentOnTypeFormattingRegistrationOptions {\n    /// A document selector to identify the scope of the registration. If set to null\n    /// the document selector provided on the client side will be used.\n    pub document_selector: Option<DocumentSelector>,\n\n    /// A character on which formatting should be triggered, like `}`.\n    pub first_trigger_character: String,\n\n    /// More trigger characters.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub more_trigger_character: Option<Vec<String>>,\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::tests::test_serialization;\n\n    #[test]\n    fn formatting_options() {\n        test_serialization(\n            &FormattingOptions {\n                tab_size: 123,\n                insert_spaces: true,\n                properties: HashMap::new(),\n                trim_trailing_whitespace: None,\n                insert_final_newline: None,\n                trim_final_newlines: None,\n            },\n            r#\"{\"tabSize\":123,\"insertSpaces\":true}\"#,\n        );\n\n        test_serialization(\n            &FormattingOptions {\n                tab_size: 123,\n                insert_spaces: true,\n                properties: vec![(\"prop\".to_string(), FormattingProperty::Number(1))]\n                    .into_iter()\n                    .collect(),\n                trim_trailing_whitespace: None,\n                insert_final_newline: None,\n                trim_final_newlines: None,\n            },\n            r#\"{\"tabSize\":123,\"insertSpaces\":true,\"prop\":1}\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "helix-lsp-types/src/hover.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::{\n    MarkedString, MarkupContent, MarkupKind, Range, TextDocumentPositionParams,\n    TextDocumentRegistrationOptions, WorkDoneProgressOptions, WorkDoneProgressParams,\n};\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct HoverClientCapabilities {\n    /// Whether completion supports dynamic registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// Client supports the follow content formats for the content\n    /// property. The order describes the preferred format of the client.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub content_format: Option<Vec<MarkupKind>>,\n}\n\n/// Hover options.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct HoverOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct HoverRegistrationOptions {\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub hover_options: HoverOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum HoverProviderCapability {\n    Simple(bool),\n    Options(HoverOptions),\n}\n\nimpl From<HoverOptions> for HoverProviderCapability {\n    fn from(from: HoverOptions) -> Self {\n        Self::Options(from)\n    }\n}\n\nimpl From<bool> for HoverProviderCapability {\n    fn from(from: bool) -> Self {\n        Self::Simple(from)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct HoverParams {\n    #[serde(flatten)]\n    pub text_document_position_params: TextDocumentPositionParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n}\n\n/// The result of a hover request.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct Hover {\n    /// The hover's content\n    pub contents: HoverContents,\n    /// An optional range is a range inside a text document\n    /// that is used to visualize a hover, e.g. by changing the background color.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub range: Option<Range>,\n}\n\n/// Hover contents could be single entry or multiple entries.\n#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]\n#[serde(untagged)]\npub enum HoverContents {\n    Scalar(MarkedString),\n    Array(Vec<MarkedString>),\n    Markup(MarkupContent),\n}\n"
  },
  {
    "path": "helix-lsp-types/src/inlay_hint.rs",
    "content": "use crate::{\n    Command, LSPAny, Location, MarkupContent, Position, Range, StaticRegistrationOptions,\n    TextDocumentIdentifier, TextDocumentRegistrationOptions, TextEdit, WorkDoneProgressOptions,\n    WorkDoneProgressParams,\n};\nuse serde::{Deserialize, Serialize};\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(untagged)]\npub enum InlayHintServerCapabilities {\n    Options(InlayHintOptions),\n    RegistrationOptions(InlayHintRegistrationOptions),\n}\n\n/// Inlay hint client capabilities.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlayHintClientCapabilities {\n    /// Whether inlay hints support dynamic registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// Indicates which properties a client can resolve lazily on a inlay\n    /// hint.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resolve_support: Option<InlayHintResolveClientCapabilities>,\n}\n\n/// Inlay hint options used during static registration.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlayHintOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n\n    /// The server provides support to resolve additional\n    /// information for an inlay hint item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resolve_provider: Option<bool>,\n}\n\n/// Inlay hint options used during static or dynamic registration.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlayHintRegistrationOptions {\n    #[serde(flatten)]\n    pub inlay_hint_options: InlayHintOptions,\n\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub static_registration_options: StaticRegistrationOptions,\n}\n\n/// A parameter literal used in inlay hint requests.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlayHintParams {\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The visible document range for which inlay hints should be computed.\n    pub range: Range,\n}\n\n/// Inlay hint information.\n///\n/// @since 3.17.0\n#[derive(Debug, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlayHint {\n    /// The position of this hint.\n    pub position: Position,\n\n    /// The label of this hint. A human readable string or an array of\n    /// InlayHintLabelPart label parts.\n    ///\n    /// *Note* that neither the string nor the label part can be empty.\n    pub label: InlayHintLabel,\n\n    /// The kind of this hint. Can be omitted in which case the client\n    /// should fall back to a reasonable default.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub kind: Option<InlayHintKind>,\n\n    /// Optional text edits that are performed when accepting this inlay hint.\n    ///\n    /// *Note* that edits are expected to change the document so that the inlay\n    /// hint (or its nearest variant) is now part of the document and the inlay\n    /// hint itself is now obsolete.\n    ///\n    /// Depending on the client capability `inlayHint.resolveSupport` clients\n    /// might resolve this property late using the resolve request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub text_edits: Option<Vec<TextEdit>>,\n\n    /// The tooltip text when you hover over this item.\n    ///\n    /// Depending on the client capability `inlayHint.resolveSupport` clients\n    /// might resolve this property late using the resolve request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tooltip: Option<InlayHintTooltip>,\n\n    /// Render padding before the hint.\n    ///\n    /// Note: Padding should use the editor's background color, not the\n    /// background color of the hint itself. That means padding can be used\n    /// to visually align/separate an inlay hint.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub padding_left: Option<bool>,\n\n    /// Render padding after the hint.\n    ///\n    /// Note: Padding should use the editor's background color, not the\n    /// background color of the hint itself. That means padding can be used\n    /// to visually align/separate an inlay hint.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub padding_right: Option<bool>,\n\n    /// A data entry field that is preserved on a inlay hint between\n    /// a `textDocument/inlayHint` and a `inlayHint/resolve` request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data: Option<LSPAny>,\n}\n\n#[derive(Debug, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum InlayHintLabel {\n    String(String),\n    LabelParts(Vec<InlayHintLabelPart>),\n}\n\nimpl From<String> for InlayHintLabel {\n    #[inline]\n    fn from(from: String) -> Self {\n        Self::String(from)\n    }\n}\n\nimpl From<Vec<InlayHintLabelPart>> for InlayHintLabel {\n    #[inline]\n    fn from(from: Vec<InlayHintLabelPart>) -> Self {\n        Self::LabelParts(from)\n    }\n}\n\n#[derive(Debug, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum InlayHintTooltip {\n    String(String),\n    MarkupContent(MarkupContent),\n}\n\nimpl From<String> for InlayHintTooltip {\n    #[inline]\n    fn from(from: String) -> Self {\n        Self::String(from)\n    }\n}\n\nimpl From<MarkupContent> for InlayHintTooltip {\n    #[inline]\n    fn from(from: MarkupContent) -> Self {\n        Self::MarkupContent(from)\n    }\n}\n\n/// An inlay hint label part allows for interactive and composite labels\n/// of inlay hints.\n#[derive(Debug, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlayHintLabelPart {\n    /// The value of this label part.\n    pub value: String,\n\n    /// The tooltip text when you hover over this label part. Depending on\n    /// the client capability `inlayHint.resolveSupport` clients might resolve\n    /// this property late using the resolve request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tooltip: Option<InlayHintLabelPartTooltip>,\n\n    /// An optional source code location that represents this\n    /// label part.\n    ///\n    /// The editor will use this location for the hover and for code navigation\n    /// features: This part will become a clickable link that resolves to the\n    /// definition of the symbol at the given location (not necessarily the\n    /// location itself), it shows the hover that shows at the given location,\n    /// and it shows a context menu with further code navigation commands.\n    ///\n    /// Depending on the client capability `inlayHint.resolveSupport` clients\n    /// might resolve this property late using the resolve request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub location: Option<Location>,\n\n    /// An optional command for this label part.\n    ///\n    /// Depending on the client capability `inlayHint.resolveSupport` clients\n    /// might resolve this property late using the resolve request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub command: Option<Command>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum InlayHintLabelPartTooltip {\n    String(String),\n    MarkupContent(MarkupContent),\n}\n\nimpl From<String> for InlayHintLabelPartTooltip {\n    #[inline]\n    fn from(from: String) -> Self {\n        Self::String(from)\n    }\n}\n\nimpl From<MarkupContent> for InlayHintLabelPartTooltip {\n    #[inline]\n    fn from(from: MarkupContent) -> Self {\n        Self::MarkupContent(from)\n    }\n}\n\n/// Inlay hint kinds.\n///\n/// @since 3.17.0\n#[derive(Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]\n#[serde(transparent)]\npub struct InlayHintKind(i32);\nlsp_enum! {\nimpl InlayHintKind {\n    /// An inlay hint that for a type annotation.\n    pub const TYPE: InlayHintKind = InlayHintKind(1);\n\n    /// An inlay hint that is for a parameter.\n    pub const PARAMETER: InlayHintKind = InlayHintKind(2);\n}\n}\n\n/// Inlay hint client capabilities.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlayHintResolveClientCapabilities {\n    /// The properties that a client can resolve lazily.\n    pub properties: Vec<String>,\n}\n\n/// Client workspace capabilities specific to inlay hints.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlayHintWorkspaceClientCapabilities {\n    /// Whether the client implementation supports a refresh request sent from\n    /// the server to the client.\n    ///\n    /// Note that this event is global and will force the client to refresh all\n    /// inlay hints currently shown. It should be used with absolute care and\n    /// is useful for situation where a server for example detects a project wide\n    /// change that requires such a calculation.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub refresh_support: Option<bool>,\n}\n\n// TODO(sno2): add tests once stabilized\n"
  },
  {
    "path": "helix-lsp-types/src/inline_completion.rs",
    "content": "use crate::{\n    Command, InsertTextFormat, Range, StaticRegistrationOptions, TextDocumentPositionParams,\n    TextDocumentRegistrationOptions, WorkDoneProgressOptions, WorkDoneProgressParams,\n};\nuse serde::{Deserialize, Serialize};\n\n/// Client capabilities specific to inline completions.\n///\n/// @since 3.18.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlineCompletionClientCapabilities {\n    /// Whether implementation supports dynamic registration for inline completion providers.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n}\n\n/// Inline completion options used during static registration.\n///\n/// @since 3.18.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct InlineCompletionOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n/// Inline completion options used during static or dynamic registration.\n///\n// @since 3.18.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct InlineCompletionRegistrationOptions {\n    #[serde(flatten)]\n    pub inline_completion_options: InlineCompletionOptions,\n\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub static_registration_options: StaticRegistrationOptions,\n}\n\n/// A parameter literal used in inline completion requests.\n///\n/// @since 3.18.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlineCompletionParams {\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub text_document_position: TextDocumentPositionParams,\n\n    /// Additional information about the context in which inline completions were requested.\n    pub context: InlineCompletionContext,\n}\n\n/// Describes how an [`InlineCompletionItemProvider`] was triggered.\n///\n/// @since 3.18.0\n#[derive(Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]\npub struct InlineCompletionTriggerKind(i32);\nlsp_enum! {\nimpl InlineCompletionTriggerKind {\n    /// Completion was triggered explicitly by a user gesture.\n    /// Return multiple completion items to enable cycling through them.\n    pub const Invoked: InlineCompletionTriggerKind = InlineCompletionTriggerKind(1);\n\n    /// Completion was triggered automatically while editing.\n    /// It is sufficient to return a single completion item in this case.\n    pub const Automatic: InlineCompletionTriggerKind = InlineCompletionTriggerKind(2);\n}\n}\n\n/// Describes the currently selected completion item.\n///\n/// @since 3.18.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct SelectedCompletionInfo {\n    /// The range that will be replaced if this completion item is accepted.\n    pub range: Range,\n    /// The text the range will be replaced with if this completion is\n    /// accepted.\n    pub text: String,\n}\n\n/// Provides information about the context in which an inline completion was\n/// requested.\n///\n/// @since 3.18.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlineCompletionContext {\n    /// Describes how the inline completion was triggered.\n    pub trigger_kind: InlineCompletionTriggerKind,\n    /// Provides information about the currently selected item in the\n    /// autocomplete widget if it is visible.\n    ///\n    /// If set, provided inline completions must extend the text of the\n    /// selected item and use the same range, otherwise they are not shown as\n    /// preview.\n    /// As an example, if the document text is `console.` and the selected item\n    /// is `.log` replacing the `.` in the document, the inline completion must\n    /// also replace `.` and start with `.log`, for example `.log()`.\n    ///\n    /// Inline completion providers are requested again whenever the selected\n    /// item changes.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub selected_completion_info: Option<SelectedCompletionInfo>,\n}\n\n/// InlineCompletion response can be multiple completion items, or a list of completion items\n#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]\n#[serde(untagged)]\npub enum InlineCompletionResponse {\n    Array(Vec<InlineCompletionItem>),\n    List(InlineCompletionList),\n}\n\n/// Represents a collection of [`InlineCompletionItem`] to be presented in the editor.\n///\n/// @since 3.18.0\n#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]\npub struct InlineCompletionList {\n    /// The inline completion items\n    pub items: Vec<InlineCompletionItem>,\n}\n\n/// An inline completion item represents a text snippet that is proposed inline\n/// to complete text that is being typed.\n///\n/// @since 3.18.0\n#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlineCompletionItem {\n    /// The text to replace the range with. Must be set.\n    /// Is used both for the preview and the accept operation.\n    pub insert_text: String,\n    /// A text that is used to decide if this inline completion should be\n    /// shown. When `falsy` the [`InlineCompletionItem::insertText`] is\n    /// used.\n    ///\n    /// An inline completion is shown if the text to replace is a prefix of the\n    /// filter text.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub filter_text: Option<String>,\n    /// The range to replace.\n    /// Must begin and end on the same line.\n    ///\n    /// Prefer replacements over insertions to provide a better experience when\n    /// the user deletes typed text.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub range: Option<Range>,\n    /// An optional command that is executed *after* inserting this\n    /// completion.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub command: Option<Command>,\n    /// The format of the insert text. The format applies to the `insertText`.\n    /// If omitted defaults to `InsertTextFormat.PlainText`.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub insert_text_format: Option<InsertTextFormat>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/inline_value.rs",
    "content": "use crate::{\n    DynamicRegistrationClientCapabilities, Range, StaticRegistrationOptions,\n    TextDocumentIdentifier, TextDocumentRegistrationOptions, WorkDoneProgressOptions,\n    WorkDoneProgressParams,\n};\nuse serde::{Deserialize, Serialize};\n\npub type InlineValueClientCapabilities = DynamicRegistrationClientCapabilities;\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum InlineValueServerCapabilities {\n    Options(InlineValueOptions),\n    RegistrationOptions(InlineValueRegistrationOptions),\n}\n\n/// Inline value options used during static registration.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct InlineValueOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n/// Inline value options used during static or dynamic registration.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct InlineValueRegistrationOptions {\n    #[serde(flatten)]\n    pub inline_value_options: InlineValueOptions,\n\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub static_registration_options: StaticRegistrationOptions,\n}\n\n/// A parameter literal used in inline value requests.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlineValueParams {\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The document range for which inline values should be computed.\n    pub range: Range,\n\n    /// Additional information about the context in which inline values were\n    /// requested.\n    pub context: InlineValueContext,\n}\n\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlineValueContext {\n    /// The stack frame (as a DAP Id) where the execution has stopped.\n    pub frame_id: i32,\n\n    /// The document range where execution has stopped.\n    /// Typically the end position of the range denotes the line where the\n    /// inline values are shown.\n    pub stopped_location: Range,\n}\n\n/// Provide inline value as text.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct InlineValueText {\n    /// The document range for which the inline value applies.\n    pub range: Range,\n\n    /// The text of the inline value.\n    pub text: String,\n}\n\n/// Provide inline value through a variable lookup.\n///\n/// If only a range is specified, the variable name will be extracted from\n/// the underlying document.\n///\n/// An optional variable name can be used to override the extracted name.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlineValueVariableLookup {\n    /// The document range for which the inline value applies.\n    /// The range is used to extract the variable name from the underlying\n    /// document.\n    pub range: Range,\n\n    /// If specified the name of the variable to look up.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub variable_name: Option<String>,\n\n    /// How to perform the lookup.\n    pub case_sensitive_lookup: bool,\n}\n\n/// Provide an inline value through an expression evaluation.\n///\n/// If only a range is specified, the expression will be extracted from the\n/// underlying document.\n///\n/// An optional expression can be used to override the extracted expression.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InlineValueEvaluatableExpression {\n    /// The document range for which the inline value applies.\n    /// The range is used to extract the evaluatable expression from the\n    /// underlying document.\n    pub range: Range,\n\n    /// If specified the expression overrides the extracted expression.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub expression: Option<String>,\n}\n\n/// Inline value information can be provided by different means:\n/// - directly as a text value (class InlineValueText).\n/// - as a name to use for a variable lookup (class InlineValueVariableLookup)\n/// - as an evaluatable expression (class InlineValueEvaluatableExpression)\n///\n/// The InlineValue types combines all inline value types into one type.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum InlineValue {\n    Text(InlineValueText),\n    VariableLookup(InlineValueVariableLookup),\n    EvaluatableExpression(InlineValueEvaluatableExpression),\n}\n\nimpl From<InlineValueText> for InlineValue {\n    #[inline]\n    fn from(from: InlineValueText) -> Self {\n        Self::Text(from)\n    }\n}\n\nimpl From<InlineValueVariableLookup> for InlineValue {\n    #[inline]\n    fn from(from: InlineValueVariableLookup) -> Self {\n        Self::VariableLookup(from)\n    }\n}\n\nimpl From<InlineValueEvaluatableExpression> for InlineValue {\n    #[inline]\n    fn from(from: InlineValueEvaluatableExpression) -> Self {\n        Self::EvaluatableExpression(from)\n    }\n}\n\n/// Client workspace capabilities specific to inline values.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n///\n/// @since 3.17.0\n#[serde(rename_all = \"camelCase\")]\npub struct InlineValueWorkspaceClientCapabilities {\n    /// Whether the client implementation supports a refresh request sent from\n    /// the server to the client.\n    ///\n    /// Note that this event is global and will force the client to refresh all\n    /// inline values currently shown. It should be used with absolute care and\n    /// is useful for situation where a server for example detect a project wide\n    /// change that requires such a calculation.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub refresh_support: Option<bool>,\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::tests::test_serialization;\n    use crate::Position;\n\n    #[test]\n    fn inline_values() {\n        test_serialization(\n            &InlineValueText {\n                range: Range::new(Position::new(0, 0), Position::new(0, 4)),\n                text: \"one\".to_owned(),\n            },\n            r#\"{\"range\":{\"start\":{\"line\":0,\"character\":0},\"end\":{\"line\":0,\"character\":4}},\"text\":\"one\"}\"#,\n        );\n\n        test_serialization(\n            &InlineValue::VariableLookup(InlineValueVariableLookup {\n                range: Range::new(Position::new(1, 0), Position::new(1, 4)),\n                variable_name: None,\n                case_sensitive_lookup: false,\n            }),\n            r#\"{\"range\":{\"start\":{\"line\":1,\"character\":0},\"end\":{\"line\":1,\"character\":4}},\"caseSensitiveLookup\":false}\"#,\n        );\n\n        test_serialization(\n            &InlineValue::EvaluatableExpression(InlineValueEvaluatableExpression {\n                range: Range::new(Position::new(2, 0), Position::new(2, 4)),\n                expression: None,\n            }),\n            r#\"{\"range\":{\"start\":{\"line\":2,\"character\":0},\"end\":{\"line\":2,\"character\":4}}}\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "helix-lsp-types/src/lib.rs",
    "content": "/*!\n\nLanguage Server Protocol types for Rust.\n\nBased on: <https://microsoft.github.io/language-server-protocol/specification>\n\nThis library uses the URL crate for parsing URIs.  Note that there is\nsome confusion on the meaning of URLs vs URIs:\n<http://stackoverflow.com/a/28865728/393898>.  According to that\ninformation, on the classical sense of \"URLs\", \"URLs\" are a subset of\nURIs, But on the modern/new meaning of URLs, they are the same as\nURIs.  The important take-away aspect is that the URL crate should be\nable to parse any URI, such as `urn:isbn:0451450523`.\n\n\n*/\n#![allow(non_upper_case_globals)]\n#![forbid(unsafe_code)]\n\nuse bitflags::bitflags;\n\nuse std::{collections::HashMap, fmt::Debug};\n\nuse serde::{de, de::Error as Error_, Deserialize, Serialize};\nuse serde_json::Value;\npub use url::Url;\n\n// Large enough to contain any enumeration name defined in this crate\ntype PascalCaseBuf = [u8; 32];\nconst fn fmt_pascal_case_const(name: &str) -> (PascalCaseBuf, usize) {\n    let mut buf = [0; 32];\n    let mut buf_i = 0;\n    let mut name_i = 0;\n    let name = name.as_bytes();\n    while name_i < name.len() {\n        let first = name[name_i];\n        name_i += 1;\n\n        buf[buf_i] = first;\n        buf_i += 1;\n\n        while name_i < name.len() {\n            let rest = name[name_i];\n            name_i += 1;\n            if rest == b'_' {\n                break;\n            }\n\n            buf[buf_i] = rest.to_ascii_lowercase();\n            buf_i += 1;\n        }\n    }\n    (buf, buf_i)\n}\n\nfn fmt_pascal_case(f: &mut std::fmt::Formatter<'_>, name: &str) -> std::fmt::Result {\n    for word in name.split('_') {\n        let mut chars = word.chars();\n        let first = chars.next().unwrap();\n        write!(f, \"{}\", first)?;\n        for rest in chars {\n            write!(f, \"{}\", rest.to_lowercase())?;\n        }\n    }\n    Ok(())\n}\n\nmacro_rules! lsp_enum {\n    (impl $typ: ident { $( $(#[$attr:meta])* pub const $name: ident : $enum_type: ty = $value: expr; )* }) => {\n        impl $typ {\n            $(\n            $(#[$attr])*\n            pub const $name: $enum_type = $value;\n            )*\n        }\n\n        impl std::fmt::Debug for $typ {\n            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n                match *self {\n                    $(\n                    Self::$name => crate::fmt_pascal_case(f, stringify!($name)),\n                    )*\n                    _ => write!(f, \"{}({})\", stringify!($typ), self.0),\n                }\n            }\n        }\n\n        impl std::convert::TryFrom<&str> for $typ {\n            type Error = &'static str;\n            fn try_from(value: &str) -> Result<Self, Self::Error> {\n                match () {\n                    $(\n                        _ if {\n                            const X: (crate::PascalCaseBuf, usize) = crate::fmt_pascal_case_const(stringify!($name));\n                            let (buf, len) = X;\n                            &buf[..len] == value.as_bytes()\n                        } => Ok(Self::$name),\n                    )*\n                    _ => Err(\"unknown enum variant\"),\n                }\n            }\n        }\n\n    }\n}\n\npub mod error_codes;\npub mod notification;\npub mod request;\n\nmod call_hierarchy;\npub use call_hierarchy::*;\n\nmod code_action;\npub use code_action::*;\n\nmod code_lens;\npub use code_lens::*;\n\nmod color;\npub use color::*;\n\nmod completion;\npub use completion::*;\n\nmod document_diagnostic;\npub use document_diagnostic::*;\n\nmod document_highlight;\npub use document_highlight::*;\n\nmod document_link;\npub use document_link::*;\n\nmod document_symbols;\npub use document_symbols::*;\n\nmod file_operations;\npub use file_operations::*;\n\nmod folding_range;\npub use folding_range::*;\n\nmod formatting;\npub use formatting::*;\n\nmod hover;\npub use hover::*;\n\nmod inlay_hint;\npub use inlay_hint::*;\n\nmod inline_value;\npub use inline_value::*;\n\n#[cfg(feature = \"proposed\")]\nmod inline_completion;\n#[cfg(feature = \"proposed\")]\npub use inline_completion::*;\n\nmod moniker;\npub use moniker::*;\n\nmod progress;\npub use progress::*;\n\nmod references;\npub use references::*;\n\nmod rename;\npub use rename::*;\n\npub mod selection_range;\npub use selection_range::*;\n\nmod semantic_tokens;\npub use semantic_tokens::*;\n\nmod signature_help;\npub use signature_help::*;\n\nmod type_hierarchy;\npub use type_hierarchy::*;\n\nmod linked_editing;\npub use linked_editing::*;\n\nmod window;\npub use window::*;\n\nmod workspace_diagnostic;\npub use workspace_diagnostic::*;\n\nmod workspace_folders;\npub use workspace_folders::*;\n\nmod workspace_symbols;\npub use workspace_symbols::*;\n\npub mod lsif;\n\nmod trace;\npub use trace::*;\n\n/* ----------------- Auxiliary types ----------------- */\n\n#[derive(Debug, Eq, Hash, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum NumberOrString {\n    Number(i32),\n    String(String),\n}\n\n/* ----------------- Cancel support ----------------- */\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct CancelParams {\n    /// The request id to cancel.\n    pub id: NumberOrString,\n}\n\n/* ----------------- Basic JSON Structures ----------------- */\n\n/// The LSP any type\n///\n/// @since 3.17.0\npub type LSPAny = serde_json::Value;\n\n/// LSP object definition.\n///\n/// @since 3.17.0\npub type LSPObject = serde_json::Map<String, serde_json::Value>;\n\n/// LSP arrays.\n///\n/// @since 3.17.0\npub type LSPArray = Vec<serde_json::Value>;\n\n/// Position in a text document expressed as zero-based line and character offset.\n/// A position is between two characters like an 'insert' cursor in a editor.\n#[derive(\n    Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Default, Deserialize, Serialize, Hash,\n)]\npub struct Position {\n    /// Line position in a document (zero-based).\n    pub line: u32,\n    /// Character offset on a line in a document (zero-based). The meaning of this\n    /// offset is determined by the negotiated `PositionEncodingKind`.\n    ///\n    /// If the character value is greater than the line length it defaults back\n    /// to the line length.\n    pub character: u32,\n}\n\nimpl Position {\n    pub fn new(line: u32, character: u32) -> Position {\n        Position { line, character }\n    }\n}\n\n/// A range in a text document expressed as (zero-based) start and end positions.\n/// A range is comparable to a selection in an editor. Therefore the end position is exclusive.\n#[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Deserialize, Serialize, Hash)]\npub struct Range {\n    /// The range's start position.\n    pub start: Position,\n    /// The range's end position.\n    pub end: Position,\n}\n\nimpl Range {\n    pub fn new(start: Position, end: Position) -> Range {\n        Range { start, end }\n    }\n}\n\n/// Represents a location inside a resource, such as a line inside a text file.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize, Hash)]\npub struct Location {\n    pub uri: Url,\n    pub range: Range,\n}\n\nimpl Location {\n    pub fn new(uri: Url, range: Range) -> Location {\n        Location { uri, range }\n    }\n}\n\n/// Represents a link between a source and a target location.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct LocationLink {\n    /// Span of the origin of this link.\n    ///\n    /// Used as the underlined span for mouse interaction. Defaults to the word range at\n    /// the mouse position.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub origin_selection_range: Option<Range>,\n\n    /// The target resource identifier of this link.\n    pub target_uri: Url,\n\n    /// The full target range of this link.\n    pub target_range: Range,\n\n    /// The span of this link.\n    pub target_selection_range: Range,\n}\n\n/// A type indicating how positions are encoded,\n/// specifically what column offsets mean.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)]\npub struct PositionEncodingKind(std::borrow::Cow<'static, str>);\n\nimpl PositionEncodingKind {\n    /// Character offsets count UTF-8 code units.\n    pub const UTF8: PositionEncodingKind = PositionEncodingKind::new(\"utf-8\");\n\n    /// Character offsets count UTF-16 code units.\n    ///\n    /// This is the default and must always be supported\n    /// by servers\n    pub const UTF16: PositionEncodingKind = PositionEncodingKind::new(\"utf-16\");\n\n    /// Character offsets count UTF-32 code units.\n    ///\n    /// Implementation note: these are the same as Unicode code points,\n    /// so this `PositionEncodingKind` may also be used for an\n    /// encoding-agnostic representation of character offsets.\n    pub const UTF32: PositionEncodingKind = PositionEncodingKind::new(\"utf-32\");\n\n    pub const fn new(tag: &'static str) -> Self {\n        PositionEncodingKind(std::borrow::Cow::Borrowed(tag))\n    }\n\n    pub fn as_str(&self) -> &str {\n        &self.0\n    }\n}\n\nimpl From<String> for PositionEncodingKind {\n    fn from(from: String) -> Self {\n        PositionEncodingKind(std::borrow::Cow::from(from))\n    }\n}\n\nimpl From<&'static str> for PositionEncodingKind {\n    fn from(from: &'static str) -> Self {\n        PositionEncodingKind::new(from)\n    }\n}\n\n/// Represents a diagnostic, such as a compiler error or warning.\n/// Diagnostic objects are only valid in the scope of a resource.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Diagnostic {\n    /// The range at which the message applies.\n    pub range: Range,\n\n    /// The diagnostic's severity. Can be omitted. If omitted it is up to the\n    /// client to interpret diagnostics as error, warning, info or hint.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub severity: Option<DiagnosticSeverity>,\n\n    /// The diagnostic's code. Can be omitted.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub code: Option<NumberOrString>,\n\n    /// An optional property to describe the error code.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub code_description: Option<CodeDescription>,\n\n    /// A human-readable string describing the source of this\n    /// diagnostic, e.g. 'typescript' or 'super lint'.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub source: Option<String>,\n\n    /// The diagnostic's message.\n    pub message: String,\n\n    /// An array of related diagnostic information, e.g. when symbol-names within\n    /// a scope collide all definitions can be marked via this property.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub related_information: Option<Vec<DiagnosticRelatedInformation>>,\n\n    /// Additional metadata about the diagnostic.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tags: Option<Vec<DiagnosticTag>>,\n\n    /// A data entry field that is preserved between a `textDocument/publishDiagnostics`\n    /// notification and `textDocument/codeAction` request.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data: Option<serde_json::Value>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CodeDescription {\n    pub href: Url,\n}\n\nimpl Diagnostic {\n    pub fn new(\n        range: Range,\n        severity: Option<DiagnosticSeverity>,\n        code: Option<NumberOrString>,\n        source: Option<String>,\n        message: String,\n        related_information: Option<Vec<DiagnosticRelatedInformation>>,\n        tags: Option<Vec<DiagnosticTag>>,\n    ) -> Diagnostic {\n        Diagnostic {\n            range,\n            severity,\n            code,\n            source,\n            message,\n            related_information,\n            tags,\n            ..Diagnostic::default()\n        }\n    }\n\n    pub fn new_simple(range: Range, message: String) -> Diagnostic {\n        Self::new(range, None, None, None, message, None, None)\n    }\n\n    pub fn new_with_code_number(\n        range: Range,\n        severity: DiagnosticSeverity,\n        code_number: i32,\n        source: Option<String>,\n        message: String,\n    ) -> Diagnostic {\n        let code = Some(NumberOrString::Number(code_number));\n        Self::new(range, Some(severity), code, source, message, None, None)\n    }\n}\n\n/// The protocol currently supports the following diagnostic severities:\n#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct DiagnosticSeverity(i32);\nlsp_enum! {\nimpl DiagnosticSeverity {\n    /// Reports an error.\n    pub const ERROR: DiagnosticSeverity = DiagnosticSeverity(1);\n    /// Reports a warning.\n    pub const WARNING: DiagnosticSeverity = DiagnosticSeverity(2);\n    /// Reports an information.\n    pub const INFORMATION: DiagnosticSeverity = DiagnosticSeverity(3);\n    /// Reports a hint.\n    pub const HINT: DiagnosticSeverity = DiagnosticSeverity(4);\n}\n}\n\n/// Represents a related message and source code location for a diagnostic. This\n/// should be used to point to code locations that cause or related to a\n/// diagnostics, e.g when duplicating a symbol in a scope.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct DiagnosticRelatedInformation {\n    /// The location of this related diagnostic information.\n    pub location: Location,\n\n    /// The message of this related diagnostic information.\n    pub message: String,\n}\n\n/// The diagnostic tags.\n#[derive(Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct DiagnosticTag(i32);\nlsp_enum! {\nimpl DiagnosticTag {\n    /// Unused or unnecessary code.\n    /// Clients are allowed to render diagnostics with this tag faded out instead of having\n    /// an error squiggle.\n    pub const UNNECESSARY: DiagnosticTag = DiagnosticTag(1);\n\n    /// Deprecated or obsolete code.\n    /// Clients are allowed to rendered diagnostics with this tag strike through.\n    pub const DEPRECATED: DiagnosticTag = DiagnosticTag(2);\n}\n}\n\n/// Represents a reference to a command. Provides a title which will be used to represent a command in the UI.\n/// Commands are identified by a string identifier. The recommended way to handle commands is to implement\n/// their execution on the server side if the client and server provides the corresponding capabilities.\n/// Alternatively the tool extension code could handle the command.\n/// The protocol currently doesn’t specify a set of well-known commands.\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct Command {\n    /// Title of the command, like `save`.\n    pub title: String,\n    /// The identifier of the actual command handler.\n    pub command: String,\n    /// Arguments that the command handler should be\n    /// invoked with.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub arguments: Option<Vec<Value>>,\n}\n\nimpl Command {\n    pub fn new(title: String, command: String, arguments: Option<Vec<Value>>) -> Command {\n        Command {\n            title,\n            command,\n            arguments,\n        }\n    }\n}\n\n/// A textual edit applicable to a text document.\n///\n/// If n `TextEdit`s are applied to a text document all text edits describe changes to the initial document version.\n/// Execution wise text edits should applied from the bottom to the top of the text document. Overlapping text edits\n/// are not supported.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextEdit {\n    /// The range of the text document to be manipulated. To insert\n    /// text into a document create a range where start === end.\n    pub range: Range,\n    /// The string to be inserted. For delete operations use an\n    /// empty string.\n    pub new_text: String,\n}\n\nimpl TextEdit {\n    pub fn new(range: Range, new_text: String) -> TextEdit {\n        TextEdit { range, new_text }\n    }\n}\n\n/// An identifier referring to a change annotation managed by a workspace\n/// edit.\n///\n/// @since 3.16.0\npub type ChangeAnnotationIdentifier = String;\n\n/// A special text edit with an additional change annotation.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct AnnotatedTextEdit {\n    #[serde(flatten)]\n    pub text_edit: TextEdit,\n\n    /// The actual annotation\n    pub annotation_id: ChangeAnnotationIdentifier,\n}\n\n/// Describes textual changes on a single text document. The text document is referred to as a\n/// `OptionalVersionedTextDocumentIdentifier` to allow clients to check the text document version before an\n/// edit is applied. A `TextDocumentEdit` describes all changes on a version Si and after they are\n/// applied move the document to version Si+1. So the creator of a `TextDocumentEdit` doesn't need to\n/// sort the array or do any kind of ordering. However the edits must be non overlapping.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextDocumentEdit {\n    /// The text document to change.\n    pub text_document: OptionalVersionedTextDocumentIdentifier,\n\n    /// The edits to be applied.\n    ///\n    /// @since 3.16.0 - support for AnnotatedTextEdit. This is guarded by the\n    /// client capability `workspace.workspaceEdit.changeAnnotationSupport`\n    pub edits: Vec<OneOf<TextEdit, AnnotatedTextEdit>>,\n}\n\n/// Additional information that describes document changes.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ChangeAnnotation {\n    /// A human-readable string describing the actual change. The string\n    /// is rendered prominent in the user interface.\n    pub label: String,\n\n    /// A flag which indicates that user confirmation is needed\n    /// before applying the change.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub needs_confirmation: Option<bool>,\n\n    /// A human-readable string which is rendered less prominent in\n    /// the user interface.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub description: Option<String>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ChangeAnnotationWorkspaceEditClientCapabilities {\n    /// Whether the client groups edits with equal labels into tree nodes,\n    /// for instance all edits labelled with \"Changes in Strings\" would\n    /// be a tree node.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub groups_on_label: Option<bool>,\n}\n\n/// Options to create a file.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CreateFileOptions {\n    /// Overwrite existing file. Overwrite wins over `ignoreIfExists`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub overwrite: Option<bool>,\n    /// Ignore if exists.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub ignore_if_exists: Option<bool>,\n}\n\n/// Create file operation\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct CreateFile {\n    /// The resource to create.\n    pub uri: Url,\n    /// Additional options\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub options: Option<CreateFileOptions>,\n\n    /// An optional annotation identifier describing the operation.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub annotation_id: Option<ChangeAnnotationIdentifier>,\n}\n\n/// Rename file options\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct RenameFileOptions {\n    /// Overwrite target if existing. Overwrite wins over `ignoreIfExists`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub overwrite: Option<bool>,\n    /// Ignores if target exists.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub ignore_if_exists: Option<bool>,\n}\n\n/// Rename file operation\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct RenameFile {\n    /// The old (existing) location.\n    pub old_uri: Url,\n    /// The new location.\n    pub new_uri: Url,\n    /// Rename options.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub options: Option<RenameFileOptions>,\n\n    /// An optional annotation identifier describing the operation.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub annotation_id: Option<ChangeAnnotationIdentifier>,\n}\n\n/// Delete file options\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DeleteFileOptions {\n    /// Delete the content recursively if a folder is denoted.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub recursive: Option<bool>,\n    /// Ignore the operation if the file doesn't exist.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub ignore_if_not_exists: Option<bool>,\n\n    /// An optional annotation identifier describing the operation.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub annotation_id: Option<ChangeAnnotationIdentifier>,\n}\n\n/// Delete file operation\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DeleteFile {\n    /// The file to delete.\n    pub uri: Url,\n    /// Delete options.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub options: Option<DeleteFileOptions>,\n}\n\n/// A workspace edit represents changes to many resources managed in the workspace.\n/// The edit should either provide `changes` or `documentChanges`.\n/// If the client can handle versioned document edits and if `documentChanges` are present,\n/// the latter are preferred over `changes`.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceEdit {\n    /// Holds changes to existing resources.\n    #[serde(with = \"url_map\")]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[serde(default)]\n    pub changes: Option<HashMap<Url, Vec<TextEdit>>>, //    changes?: { [uri: string]: TextEdit[]; };\n\n    /// Depending on the client capability `workspace.workspaceEdit.resourceOperations` document changes\n    /// are either an array of `TextDocumentEdit`s to express changes to n different text documents\n    /// where each text document edit addresses a specific version of a text document. Or it can contain\n    /// above `TextDocumentEdit`s mixed with create, rename and delete file / folder operations.\n    ///\n    /// Whether a client supports versioned document edits is expressed via\n    /// `workspace.workspaceEdit.documentChanges` client capability.\n    ///\n    /// If a client neither supports `documentChanges` nor `workspace.workspaceEdit.resourceOperations` then\n    /// only plain `TextEdit`s using the `changes` property are supported.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_changes: Option<DocumentChanges>,\n\n    /// A map of change annotations that can be referenced in\n    /// `AnnotatedTextEdit`s or create, rename and delete file / folder\n    /// operations.\n    ///\n    /// Whether clients honor this property depends on the client capability\n    /// `workspace.changeAnnotationSupport`.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub change_annotations: Option<HashMap<ChangeAnnotationIdentifier, ChangeAnnotation>>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum DocumentChanges {\n    Edits(Vec<TextDocumentEdit>),\n    Operations(Vec<DocumentChangeOperation>),\n}\n\n// TODO: Once https://github.com/serde-rs/serde/issues/912 is solved\n// we can remove ResourceOp and switch to the following implementation\n// of DocumentChangeOperation:\n//\n// #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n// #[serde(tag = \"kind\", rename_all=\"lowercase\" )]\n// pub enum DocumentChangeOperation {\n//     Create(CreateFile),\n//     Rename(RenameFile),\n//     Delete(DeleteFile),\n//\n//     #[serde(other)]\n//     Edit(TextDocumentEdit),\n// }\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged, rename_all = \"lowercase\")]\npub enum DocumentChangeOperation {\n    Op(ResourceOp),\n    Edit(TextDocumentEdit),\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(tag = \"kind\", rename_all = \"lowercase\")]\npub enum ResourceOp {\n    Create(CreateFile),\n    Rename(RenameFile),\n    Delete(DeleteFile),\n}\n\npub type DidChangeConfigurationClientCapabilities = DynamicRegistrationClientCapabilities;\n\n#[derive(Debug, Default, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ConfigurationParams {\n    pub items: Vec<ConfigurationItem>,\n}\n\n#[derive(Debug, Default, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ConfigurationItem {\n    /// The scope to get the configuration section for.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub scope_uri: Option<Url>,\n\n    ///The configuration section asked for.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub section: Option<String>,\n}\n\nmod url_map {\n    use std::fmt;\n    use std::marker::PhantomData;\n\n    use super::*;\n\n    pub fn deserialize<'de, D, V>(deserializer: D) -> Result<Option<HashMap<Url, V>>, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n        V: de::DeserializeOwned,\n    {\n        struct UrlMapVisitor<V> {\n            _marker: PhantomData<V>,\n        }\n\n        impl<V: de::DeserializeOwned> Default for UrlMapVisitor<V> {\n            fn default() -> Self {\n                UrlMapVisitor {\n                    _marker: PhantomData,\n                }\n            }\n        }\n        impl<'de, V: de::DeserializeOwned> de::Visitor<'de> for UrlMapVisitor<V> {\n            type Value = HashMap<Url, V>;\n\n            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n                formatter.write_str(\"map\")\n            }\n\n            fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>\n            where\n                M: de::MapAccess<'de>,\n            {\n                let mut values = HashMap::with_capacity(visitor.size_hint().unwrap_or(0));\n\n                // While there are entries remaining in the input, add them\n                // into our map.\n                while let Some((key, value)) = visitor.next_entry::<Url, _>()? {\n                    values.insert(key, value);\n                }\n\n                Ok(values)\n            }\n        }\n\n        struct OptionUrlMapVisitor<V> {\n            _marker: PhantomData<V>,\n        }\n        impl<V: de::DeserializeOwned> Default for OptionUrlMapVisitor<V> {\n            fn default() -> Self {\n                OptionUrlMapVisitor {\n                    _marker: PhantomData,\n                }\n            }\n        }\n        impl<'de, V: de::DeserializeOwned> de::Visitor<'de> for OptionUrlMapVisitor<V> {\n            type Value = Option<HashMap<Url, V>>;\n\n            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n                formatter.write_str(\"option\")\n            }\n\n            #[inline]\n            fn visit_unit<E>(self) -> Result<Self::Value, E>\n            where\n                E: serde::de::Error,\n            {\n                Ok(None)\n            }\n\n            #[inline]\n            fn visit_none<E>(self) -> Result<Self::Value, E>\n            where\n                E: serde::de::Error,\n            {\n                Ok(None)\n            }\n\n            #[inline]\n            fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>\n            where\n                D: serde::Deserializer<'de>,\n            {\n                deserializer\n                    .deserialize_map(UrlMapVisitor::<V>::default())\n                    .map(Some)\n            }\n        }\n\n        // Instantiate our Visitor and ask the Deserializer to drive\n        // it over the input data, resulting in an instance of MyMap.\n        deserializer.deserialize_option(OptionUrlMapVisitor::default())\n    }\n\n    pub fn serialize<S, V>(\n        changes: &Option<HashMap<Url, V>>,\n        serializer: S,\n    ) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n        V: serde::Serialize,\n    {\n        use serde::ser::SerializeMap;\n\n        match *changes {\n            Some(ref changes) => {\n                let mut map = serializer.serialize_map(Some(changes.len()))?;\n                for (k, v) in changes {\n                    map.serialize_entry(k.as_str(), v)?;\n                }\n                map.end()\n            }\n            None => serializer.serialize_none(),\n        }\n    }\n}\n\nimpl WorkspaceEdit {\n    pub fn new(changes: HashMap<Url, Vec<TextEdit>>) -> WorkspaceEdit {\n        WorkspaceEdit {\n            changes: Some(changes),\n            document_changes: None,\n            ..Default::default()\n        }\n    }\n}\n\n/// Text documents are identified using a URI. On the protocol level, URIs are passed as strings.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct TextDocumentIdentifier {\n    // !!!!!! Note:\n    // In the spec VersionedTextDocumentIdentifier extends TextDocumentIdentifier\n    // This modelled by \"mixing-in\" TextDocumentIdentifier in VersionedTextDocumentIdentifier,\n    // so any changes to this type must be effected in the sub-type as well.\n    /// The text document's URI.\n    pub uri: Url,\n}\n\nimpl TextDocumentIdentifier {\n    pub fn new(uri: Url) -> TextDocumentIdentifier {\n        TextDocumentIdentifier { uri }\n    }\n}\n\n/// An item to transfer a text document from the client to the server.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextDocumentItem {\n    /// The text document's URI.\n    pub uri: Url,\n\n    /// The text document's language identifier.\n    pub language_id: String,\n\n    /// The version number of this document (it will strictly increase after each\n    /// change, including undo/redo).\n    pub version: i32,\n\n    /// The content of the opened text document.\n    pub text: String,\n}\n\nimpl TextDocumentItem {\n    pub fn new(uri: Url, language_id: String, version: i32, text: String) -> TextDocumentItem {\n        TextDocumentItem {\n            uri,\n            language_id,\n            version,\n            text,\n        }\n    }\n}\n\n/// An identifier to denote a specific version of a text document. This information usually flows from the client to the server.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct VersionedTextDocumentIdentifier {\n    // This field was \"mixed-in\" from TextDocumentIdentifier\n    /// The text document's URI.\n    pub uri: Url,\n\n    /// The version number of this document.\n    ///\n    /// The version number of a document will increase after each change,\n    /// including undo/redo. The number doesn't need to be consecutive.\n    pub version: i32,\n}\n\nimpl VersionedTextDocumentIdentifier {\n    pub fn new(uri: Url, version: i32) -> VersionedTextDocumentIdentifier {\n        VersionedTextDocumentIdentifier { uri, version }\n    }\n}\n\n/// An identifier which optionally denotes a specific version of a text document. This information usually flows from the server to the client\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct OptionalVersionedTextDocumentIdentifier {\n    // This field was \"mixed-in\" from TextDocumentIdentifier\n    /// The text document's URI.\n    pub uri: Url,\n\n    /// The version number of this document. If an optional versioned text document\n    /// identifier is sent from the server to the client and the file is not\n    /// open in the editor (the server has not received an open notification\n    /// before) the server can send `null` to indicate that the version is\n    /// known and the content on disk is the master (as specified with document\n    /// content ownership).\n    ///\n    /// The version number of a document will increase after each change,\n    /// including undo/redo. The number doesn't need to be consecutive.\n    pub version: Option<i32>,\n}\n\nimpl OptionalVersionedTextDocumentIdentifier {\n    pub fn new(uri: Url, version: i32) -> OptionalVersionedTextDocumentIdentifier {\n        OptionalVersionedTextDocumentIdentifier {\n            uri,\n            version: Some(version),\n        }\n    }\n}\n\n/// A parameter literal used in requests to pass a text document and a position inside that document.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextDocumentPositionParams {\n    // !!!!!! Note:\n    // In the spec ReferenceParams extends TextDocumentPositionParams\n    // This modelled by \"mixing-in\" TextDocumentPositionParams in ReferenceParams,\n    // so any changes to this type must be effected in sub-type as well.\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The position inside the text document.\n    pub position: Position,\n}\n\nimpl TextDocumentPositionParams {\n    pub fn new(\n        text_document: TextDocumentIdentifier,\n        position: Position,\n    ) -> TextDocumentPositionParams {\n        TextDocumentPositionParams {\n            text_document,\n            position,\n        }\n    }\n}\n\n/// A document filter denotes a document through properties like language, schema or pattern.\n/// Examples are a filter that applies to TypeScript files on disk or a filter the applies to JSON\n/// files with name package.json:\n///\n/// { language: 'typescript', scheme: 'file' }\n/// { language: 'json', pattern: '**/package.json' }\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct DocumentFilter {\n    /// A language id, like `typescript`.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub language: Option<String>,\n\n    /// A Uri [scheme](#Uri.scheme), like `file` or `untitled`.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub scheme: Option<String>,\n\n    /// A glob pattern, like `*.{ts,js}`.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub pattern: Option<String>,\n}\n\n/// A document selector is the combination of one or many document filters.\npub type DocumentSelector = Vec<DocumentFilter>;\n\n// ========================= Actual Protocol =========================\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Default)]\n#[serde(rename_all = \"camelCase\")]\npub struct InitializeParams {\n    /// The process Id of the parent process that started\n    /// the server. Is null if the process has not been started by another process.\n    /// If the parent process is not alive then the server should exit (see exit notification) its process.\n    pub process_id: Option<u32>,\n\n    /// The rootPath of the workspace. Is null\n    /// if no folder is open.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[deprecated(note = \"Use `root_uri` instead when possible\")]\n    pub root_path: Option<String>,\n\n    /// The rootUri of the workspace. Is null if no\n    /// folder is open. If both `rootPath` and `rootUri` are set\n    /// `rootUri` wins.\n    #[serde(default)]\n    #[deprecated(note = \"Use `workspace_folders` instead when possible\")]\n    pub root_uri: Option<Url>,\n\n    /// User provided initialization options.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub initialization_options: Option<Value>,\n\n    /// The capabilities provided by the client (editor or tool)\n    pub capabilities: ClientCapabilities,\n\n    /// The initial trace setting. If omitted trace is disabled ('off').\n    #[serde(default)]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub trace: Option<TraceValue>,\n\n    /// The workspace folders configured in the client when the server starts.\n    /// This property is only available if the client supports workspace folders.\n    /// It can be `null` if the client supports workspace folders but none are\n    /// configured.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub workspace_folders: Option<Vec<WorkspaceFolder>>,\n\n    /// Information about the client.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub client_info: Option<ClientInfo>,\n\n    /// The locale the client is currently showing the user interface\n    /// in. This must not necessarily be the locale of the operating\n    /// system.\n    ///\n    /// Uses IETF language tags as the value's syntax\n    /// (See <https://en.wikipedia.org/wiki/IETF_language_tag>)\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub locale: Option<String>,\n\n    /// The LSP server may report about initialization progress to the client\n    /// by using the following work done token if it was passed by the client.\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\npub struct ClientInfo {\n    /// The name of the client as defined by the client.\n    pub name: String,\n    /// The client's version as defined by the client.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub version: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Clone, Copy, Deserialize, Serialize)]\npub struct InitializedParams {}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct GenericRegistrationOptions {\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub options: GenericOptions,\n\n    #[serde(flatten)]\n    pub static_registration_options: StaticRegistrationOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct GenericOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct GenericParams {\n    #[serde(flatten)]\n    pub text_document_position_params: TextDocumentPositionParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Copy, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DynamicRegistrationClientCapabilities {\n    /// This capability supports dynamic registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Copy, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct GotoCapability {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// The client supports additional metadata in the form of definition links.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub link_support: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceEditClientCapabilities {\n    /// The client supports versioned document changes in `WorkspaceEdit`s\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_changes: Option<bool>,\n\n    /// The resource operations the client supports. Clients should at least\n    /// support 'create', 'rename' and 'delete' files and folders.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resource_operations: Option<Vec<ResourceOperationKind>>,\n\n    /// The failure handling strategy of a client if applying the workspace edit fails.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub failure_handling: Option<FailureHandlingKind>,\n\n    /// Whether the client normalizes line endings to the client specific\n    /// setting.\n    /// If set to `true` the client will normalize line ending characters\n    /// in a workspace edit to the client specific new line character(s).\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub normalizes_line_endings: Option<bool>,\n\n    /// Whether the client in general supports change annotations on text edits,\n    /// create file, rename file and delete file changes.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub change_annotation_support: Option<ChangeAnnotationWorkspaceEditClientCapabilities>,\n}\n\n#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Copy, Clone)]\n#[serde(rename_all = \"lowercase\")]\npub enum ResourceOperationKind {\n    Create,\n    Rename,\n    Delete,\n}\n\n#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Copy, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub enum FailureHandlingKind {\n    Abort,\n    Transactional,\n    TextOnlyTransactional,\n    Undo,\n}\n\n/// A symbol kind.\n#[derive(Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]\n#[serde(transparent)]\npub struct SymbolKind(i32);\nlsp_enum! {\nimpl SymbolKind {\n    pub const FILE: SymbolKind = SymbolKind(1);\n    pub const MODULE: SymbolKind = SymbolKind(2);\n    pub const NAMESPACE: SymbolKind = SymbolKind(3);\n    pub const PACKAGE: SymbolKind = SymbolKind(4);\n    pub const CLASS: SymbolKind = SymbolKind(5);\n    pub const METHOD: SymbolKind = SymbolKind(6);\n    pub const PROPERTY: SymbolKind = SymbolKind(7);\n    pub const FIELD: SymbolKind = SymbolKind(8);\n    pub const CONSTRUCTOR: SymbolKind = SymbolKind(9);\n    pub const ENUM: SymbolKind = SymbolKind(10);\n    pub const INTERFACE: SymbolKind = SymbolKind(11);\n    pub const FUNCTION: SymbolKind = SymbolKind(12);\n    pub const VARIABLE: SymbolKind = SymbolKind(13);\n    pub const CONSTANT: SymbolKind = SymbolKind(14);\n    pub const STRING: SymbolKind = SymbolKind(15);\n    pub const NUMBER: SymbolKind = SymbolKind(16);\n    pub const BOOLEAN: SymbolKind = SymbolKind(17);\n    pub const ARRAY: SymbolKind = SymbolKind(18);\n    pub const OBJECT: SymbolKind = SymbolKind(19);\n    pub const KEY: SymbolKind = SymbolKind(20);\n    pub const NULL: SymbolKind = SymbolKind(21);\n    pub const ENUM_MEMBER: SymbolKind = SymbolKind(22);\n    pub const STRUCT: SymbolKind = SymbolKind(23);\n    pub const EVENT: SymbolKind = SymbolKind(24);\n    pub const OPERATOR: SymbolKind = SymbolKind(25);\n    pub const TYPE_PARAMETER: SymbolKind = SymbolKind(26);\n}\n}\n\n/// Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SymbolKindCapability {\n    /// The symbol kind values the client supports. When this\n    /// property exists the client also guarantees that it will\n    /// handle values outside its set gracefully and falls back\n    /// to a default value when unknown.\n    ///\n    /// If this property is not present the client only supports\n    /// the symbol kinds from `File` to `Array` as defined in\n    /// the initial version of the protocol.\n    pub value_set: Option<Vec<SymbolKind>>,\n}\n\n/// Workspace specific client capabilities.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceClientCapabilities {\n    /// The client supports applying batch edits to the workspace by supporting\n    /// the request 'workspace/applyEdit'\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub apply_edit: Option<bool>,\n\n    /// Capabilities specific to `WorkspaceEdit`s\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub workspace_edit: Option<WorkspaceEditClientCapabilities>,\n\n    /// Capabilities specific to the `workspace/didChangeConfiguration` notification.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub did_change_configuration: Option<DidChangeConfigurationClientCapabilities>,\n\n    /// Capabilities specific to the `workspace/didChangeWatchedFiles` notification.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub did_change_watched_files: Option<DidChangeWatchedFilesClientCapabilities>,\n\n    /// Capabilities specific to the `workspace/symbol` request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub symbol: Option<WorkspaceSymbolClientCapabilities>,\n\n    /// Capabilities specific to the `workspace/executeCommand` request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub execute_command: Option<ExecuteCommandClientCapabilities>,\n\n    /// The client has support for workspace folders.\n    ///\n    /// @since 3.6.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub workspace_folders: Option<bool>,\n\n    /// The client supports `workspace/configuration` requests.\n    ///\n    /// @since 3.6.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub configuration: Option<bool>,\n\n    /// Capabilities specific to the semantic token requests scoped to the workspace.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub semantic_tokens: Option<SemanticTokensWorkspaceClientCapabilities>,\n\n    /// Capabilities specific to the code lens requests scoped to the workspace.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub code_lens: Option<CodeLensWorkspaceClientCapabilities>,\n\n    /// The client has support for file requests/notifications.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub file_operations: Option<WorkspaceFileOperationsClientCapabilities>,\n\n    /// Client workspace capabilities specific to inline values.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub inline_value: Option<InlineValueWorkspaceClientCapabilities>,\n\n    /// Client workspace capabilities specific to inlay hints.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub inlay_hint: Option<InlayHintWorkspaceClientCapabilities>,\n\n    /// Client workspace capabilities specific to diagnostics.\n    /// since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub diagnostic: Option<DiagnosticWorkspaceClientCapabilities>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextDocumentSyncClientCapabilities {\n    /// Whether text document synchronization supports dynamic registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// The client supports sending will save notifications.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub will_save: Option<bool>,\n\n    /// The client supports sending a will save request and\n    /// waits for a response providing text edits which will\n    /// be applied to the document before it is saved.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub will_save_wait_until: Option<bool>,\n\n    /// The client supports did save notifications.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub did_save: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct PublishDiagnosticsClientCapabilities {\n    /// Whether the clients accepts diagnostics with related information.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub related_information: Option<bool>,\n\n    /// Client supports the tag property to provide meta data about a diagnostic.\n    /// Clients supporting tags have to handle unknown tags gracefully.\n    #[serde(\n        default,\n        skip_serializing_if = \"Option::is_none\",\n        deserialize_with = \"TagSupport::deserialize_compat\"\n    )]\n    pub tag_support: Option<TagSupport<DiagnosticTag>>,\n\n    /// Whether the client interprets the version property of the\n    /// `textDocument/publishDiagnostics` notification's parameter.\n    ///\n    /// @since 3.15.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub version_support: Option<bool>,\n\n    /// Client supports a codeDescription property\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub code_description_support: Option<bool>,\n\n    /// Whether code action supports the `data` property which is\n    /// preserved between a `textDocument/publishDiagnostics` and\n    /// `textDocument/codeAction` request.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data_support: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TagSupport<T> {\n    /// The tags supported by the client.\n    pub value_set: Vec<T>,\n}\n\nimpl<T> TagSupport<T> {\n    /// Support for deserializing a boolean tag Support, in case it's present.\n    ///\n    /// This is currently the case for vscode 1.41.1\n    fn deserialize_compat<'de, S>(serializer: S) -> Result<Option<TagSupport<T>>, S::Error>\n    where\n        S: serde::Deserializer<'de>,\n        T: serde::Deserialize<'de>,\n    {\n        Ok(\n            match Option::<Value>::deserialize(serializer).map_err(serde::de::Error::custom)? {\n                Some(Value::Bool(false)) => None,\n                Some(Value::Bool(true)) => Some(TagSupport { value_set: vec![] }),\n                Some(other) => {\n                    Some(TagSupport::<T>::deserialize(other).map_err(serde::de::Error::custom)?)\n                }\n                None => None,\n            },\n        )\n    }\n}\n\n/// Text document specific client capabilities.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextDocumentClientCapabilities {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub synchronization: Option<TextDocumentSyncClientCapabilities>,\n    /// Capabilities specific to the `textDocument/completion`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub completion: Option<CompletionClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/hover`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub hover: Option<HoverClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/signatureHelp`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub signature_help: Option<SignatureHelpClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/references`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub references: Option<ReferenceClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/documentHighlight`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_highlight: Option<DocumentHighlightClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/documentSymbol`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_symbol: Option<DocumentSymbolClientCapabilities>,\n    /// Capabilities specific to the `textDocument/formatting`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub formatting: Option<DocumentFormattingClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/rangeFormatting`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub range_formatting: Option<DocumentRangeFormattingClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/onTypeFormatting`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub on_type_formatting: Option<DocumentOnTypeFormattingClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/declaration`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub declaration: Option<GotoCapability>,\n\n    /// Capabilities specific to the `textDocument/definition`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub definition: Option<GotoCapability>,\n\n    /// Capabilities specific to the `textDocument/typeDefinition`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub type_definition: Option<GotoCapability>,\n\n    /// Capabilities specific to the `textDocument/implementation`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub implementation: Option<GotoCapability>,\n\n    /// Capabilities specific to the `textDocument/codeAction`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub code_action: Option<CodeActionClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/codeLens`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub code_lens: Option<CodeLensClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/documentLink`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_link: Option<DocumentLinkClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/documentColor` and the\n    /// `textDocument/colorPresentation` request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub color_provider: Option<DocumentColorClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/rename`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub rename: Option<RenameClientCapabilities>,\n\n    /// Capabilities specific to `textDocument/publishDiagnostics`.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub publish_diagnostics: Option<PublishDiagnosticsClientCapabilities>,\n\n    /// Capabilities specific to `textDocument/foldingRange` requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub folding_range: Option<FoldingRangeClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/selectionRange` request.\n    ///\n    /// @since 3.15.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub selection_range: Option<SelectionRangeClientCapabilities>,\n\n    /// Capabilities specific to `textDocument/linkedEditingRange` requests.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub linked_editing_range: Option<LinkedEditingRangeClientCapabilities>,\n\n    /// Capabilities specific to the various call hierarchy requests.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub call_hierarchy: Option<CallHierarchyClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/semanticTokens/*` requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub semantic_tokens: Option<SemanticTokensClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/moniker` request.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub moniker: Option<MonikerClientCapabilities>,\n\n    /// Capabilities specific to the various type hierarchy requests.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub type_hierarchy: Option<TypeHierarchyClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/inlineValue` request.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub inline_value: Option<InlineValueClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/inlayHint` request.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub inlay_hint: Option<InlayHintClientCapabilities>,\n\n    /// Capabilities specific to the diagnostic pull model.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub diagnostic: Option<DiagnosticClientCapabilities>,\n\n    /// Capabilities specific to the `textDocument/inlineCompletion` request.\n    ///\n    /// @since 3.18.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[cfg(feature = \"proposed\")]\n    pub inline_completion: Option<InlineCompletionClientCapabilities>,\n}\n\n/// Where ClientCapabilities are currently empty:\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ClientCapabilities {\n    /// Workspace specific client capabilities.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub workspace: Option<WorkspaceClientCapabilities>,\n\n    /// Text document specific client capabilities.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub text_document: Option<TextDocumentClientCapabilities>,\n\n    /// Window specific client capabilities.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub window: Option<WindowClientCapabilities>,\n\n    /// General client capabilities.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub general: Option<GeneralClientCapabilities>,\n\n    /// Unofficial UT8-offsets extension.\n    ///\n    /// See https://clangd.llvm.org/extensions.html#utf-8-offsets.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[cfg(feature = \"proposed\")]\n    pub offset_encoding: Option<Vec<String>>,\n\n    /// Experimental client capabilities.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub experimental: Option<Value>,\n}\n\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct GeneralClientCapabilities {\n    /// Client capabilities specific to regular expressions.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub regular_expressions: Option<RegularExpressionsClientCapabilities>,\n\n    /// Client capabilities specific to the client's markdown parser.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub markdown: Option<MarkdownClientCapabilities>,\n\n    /// Client capability that signals how the client handles stale requests (e.g. a request for\n    /// which the client will not process the response anymore since the information is outdated).\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub stale_request_support: Option<StaleRequestSupportClientCapabilities>,\n\n    /// The position encodings supported by the client. Client and server\n    /// have to agree on the same position encoding to ensure that offsets\n    /// (e.g. character position in a line) are interpreted the same on both\n    /// side.\n    ///\n    /// To keep the protocol backwards compatible the following applies: if\n    /// the value 'utf-16' is missing from the array of position encodings\n    /// servers can assume that the client supports UTF-16. UTF-16 is\n    /// therefore a mandatory encoding.\n    ///\n    /// If omitted it defaults to ['utf-16'].\n    ///\n    /// Implementation considerations: since the conversion from one encoding\n    /// into another requires the content of the file / line the conversion\n    /// is best done where the file is read which is usually on the server\n    /// side.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub position_encodings: Option<Vec<PositionEncodingKind>>,\n}\n\n/// Client capability that signals how the client\n/// handles stale requests (e.g. a request\n/// for which the client will not process the response\n/// anymore since the information is outdated).\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct StaleRequestSupportClientCapabilities {\n    /// The client will actively cancel the request.\n    pub cancel: bool,\n\n    /// The list of requests for which the client\n    /// will retry the request if it receives a\n    /// response with error code `ContentModified``\n    pub retry_on_content_modified: Vec<String>,\n}\n\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct RegularExpressionsClientCapabilities {\n    /// The engine's name.\n    pub engine: String,\n\n    /// The engine's version\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub version: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct MarkdownClientCapabilities {\n    /// The name of the parser.\n    pub parser: String,\n\n    /// The version of the parser.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub version: Option<String>,\n\n    /// A list of HTML tags that the client allows / supports in\n    /// Markdown.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub allowed_tags: Option<Vec<String>>,\n}\n\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct InitializeResult {\n    /// The capabilities the language server provides.\n    pub capabilities: ServerCapabilities,\n\n    /// Information about the server.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub server_info: Option<ServerInfo>,\n\n    /// Unofficial UT8-offsets extension.\n    ///\n    /// See https://clangd.llvm.org/extensions.html#utf-8-offsets.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[cfg(feature = \"proposed\")]\n    pub offset_encoding: Option<String>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct ServerInfo {\n    /// The name of the server as defined by the server.\n    pub name: String,\n    /// The servers's version as defined by the server.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub version: Option<String>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct InitializeError {\n    /// Indicates whether the client execute the following retry logic:\n    ///\n    /// - (1) show the message provided by the ResponseError to the user\n    /// - (2) user selects retry or cancel\n    /// - (3) if user selected retry the initialize method is sent again.\n    pub retry: bool,\n}\n\n// The server can signal the following capabilities:\n\n/// Defines how the host (editor) should sync document changes to the language server.\n#[derive(Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct TextDocumentSyncKind(i32);\nlsp_enum! {\nimpl TextDocumentSyncKind {\n    /// Documents should not be synced at all.\n    pub const NONE: TextDocumentSyncKind = TextDocumentSyncKind(0);\n\n    /// Documents are synced by always sending the full content of the document.\n    pub const FULL: TextDocumentSyncKind = TextDocumentSyncKind(1);\n\n    /// Documents are synced by sending the full content on open. After that only\n    /// incremental updates to the document are sent.\n    pub const INCREMENTAL: TextDocumentSyncKind = TextDocumentSyncKind(2);\n}\n}\n\npub type ExecuteCommandClientCapabilities = DynamicRegistrationClientCapabilities;\n\n/// Execute command options.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct ExecuteCommandOptions {\n    /// The commands to be executed on the server\n    pub commands: Vec<String>,\n\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n/// Save options.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SaveOptions {\n    /// The client is supposed to include the content on save.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub include_text: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum TextDocumentSyncSaveOptions {\n    Supported(bool),\n    SaveOptions(SaveOptions),\n}\n\nimpl From<SaveOptions> for TextDocumentSyncSaveOptions {\n    fn from(from: SaveOptions) -> Self {\n        Self::SaveOptions(from)\n    }\n}\n\nimpl From<bool> for TextDocumentSyncSaveOptions {\n    fn from(from: bool) -> Self {\n        Self::Supported(from)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextDocumentSyncOptions {\n    /// Open and close notifications are sent to the server.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub open_close: Option<bool>,\n\n    /// Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full\n    /// and TextDocumentSyncKindIncremental.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub change: Option<TextDocumentSyncKind>,\n\n    /// Will save notifications are sent to the server.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub will_save: Option<bool>,\n\n    /// Will save wait until requests are sent to the server.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub will_save_wait_until: Option<bool>,\n\n    /// Save notifications are sent to the server.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub save: Option<TextDocumentSyncSaveOptions>,\n}\n\n#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum OneOf<A, B> {\n    Left(A),\n    Right(B),\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum TextDocumentSyncCapability {\n    Kind(TextDocumentSyncKind),\n    Options(TextDocumentSyncOptions),\n}\n\nimpl From<TextDocumentSyncOptions> for TextDocumentSyncCapability {\n    fn from(from: TextDocumentSyncOptions) -> Self {\n        Self::Options(from)\n    }\n}\n\nimpl From<TextDocumentSyncKind> for TextDocumentSyncCapability {\n    fn from(from: TextDocumentSyncKind) -> Self {\n        Self::Kind(from)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum ImplementationProviderCapability {\n    Simple(bool),\n    Options(StaticTextDocumentRegistrationOptions),\n}\n\nimpl From<StaticTextDocumentRegistrationOptions> for ImplementationProviderCapability {\n    fn from(from: StaticTextDocumentRegistrationOptions) -> Self {\n        Self::Options(from)\n    }\n}\n\nimpl From<bool> for ImplementationProviderCapability {\n    fn from(from: bool) -> Self {\n        Self::Simple(from)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum TypeDefinitionProviderCapability {\n    Simple(bool),\n    Options(StaticTextDocumentRegistrationOptions),\n}\n\nimpl From<StaticTextDocumentRegistrationOptions> for TypeDefinitionProviderCapability {\n    fn from(from: StaticTextDocumentRegistrationOptions) -> Self {\n        Self::Options(from)\n    }\n}\n\nimpl From<bool> for TypeDefinitionProviderCapability {\n    fn from(from: bool) -> Self {\n        Self::Simple(from)\n    }\n}\n\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ServerCapabilities {\n    /// The position encoding the server picked from the encodings offered\n    /// by the client via the client capability `general.positionEncodings`.\n    ///\n    /// If the client didn't provide any position encodings the only valid\n    /// value that a server can return is 'utf-16'.\n    ///\n    /// If omitted it defaults to 'utf-16'.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub position_encoding: Option<PositionEncodingKind>,\n\n    /// Defines how text documents are synced.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub text_document_sync: Option<TextDocumentSyncCapability>,\n\n    /// Capabilities specific to `textDocument/selectionRange` requests.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub selection_range_provider: Option<SelectionRangeProviderCapability>,\n\n    /// The server provides hover support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub hover_provider: Option<HoverProviderCapability>,\n\n    /// The server provides completion support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub completion_provider: Option<CompletionOptions>,\n\n    /// The server provides signature help support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub signature_help_provider: Option<SignatureHelpOptions>,\n\n    /// The server provides goto definition support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub definition_provider: Option<OneOf<bool, DefinitionOptions>>,\n\n    /// The server provides goto type definition support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub type_definition_provider: Option<TypeDefinitionProviderCapability>,\n\n    /// The server provides goto implementation support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub implementation_provider: Option<ImplementationProviderCapability>,\n\n    /// The server provides find references support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub references_provider: Option<OneOf<bool, ReferencesOptions>>,\n\n    /// The server provides document highlight support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_highlight_provider: Option<OneOf<bool, DocumentHighlightOptions>>,\n\n    /// The server provides document symbol support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_symbol_provider: Option<OneOf<bool, DocumentSymbolOptions>>,\n\n    /// The server provides workspace symbol support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub workspace_symbol_provider: Option<OneOf<bool, WorkspaceSymbolOptions>>,\n\n    /// The server provides code actions.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub code_action_provider: Option<CodeActionProviderCapability>,\n\n    /// The server provides code lens.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub code_lens_provider: Option<CodeLensOptions>,\n\n    /// The server provides document formatting.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_formatting_provider: Option<OneOf<bool, DocumentFormattingOptions>>,\n\n    /// The server provides document range formatting.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_range_formatting_provider: Option<OneOf<bool, DocumentRangeFormattingOptions>>,\n\n    /// The server provides document formatting on typing.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_on_type_formatting_provider: Option<DocumentOnTypeFormattingOptions>,\n\n    /// The server provides rename support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub rename_provider: Option<OneOf<bool, RenameOptions>>,\n\n    /// The server provides document link support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub document_link_provider: Option<DocumentLinkOptions>,\n\n    /// The server provides color provider support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub color_provider: Option<ColorProviderCapability>,\n\n    /// The server provides folding provider support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub folding_range_provider: Option<FoldingRangeProviderCapability>,\n\n    /// The server provides go to declaration support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub declaration_provider: Option<DeclarationCapability>,\n\n    /// The server provides execute command support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub execute_command_provider: Option<ExecuteCommandOptions>,\n\n    /// Workspace specific server capabilities\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub workspace: Option<WorkspaceServerCapabilities>,\n\n    /// Call hierarchy provider capabilities.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub call_hierarchy_provider: Option<CallHierarchyServerCapability>,\n\n    /// Semantic tokens server capabilities.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub semantic_tokens_provider: Option<SemanticTokensServerCapabilities>,\n\n    /// Whether server provides moniker support.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub moniker_provider: Option<OneOf<bool, MonikerServerCapabilities>>,\n\n    /// The server provides linked editing range support.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub linked_editing_range_provider: Option<LinkedEditingRangeServerCapabilities>,\n\n    /// The server provides inline values.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub inline_value_provider: Option<OneOf<bool, InlineValueServerCapabilities>>,\n\n    /// The server provides inlay hints.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub inlay_hint_provider: Option<OneOf<bool, InlayHintServerCapabilities>>,\n\n    /// The server has support for pull model diagnostics.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub diagnostic_provider: Option<DiagnosticServerCapabilities>,\n\n    /// The server provides inline completions.\n    ///\n    /// @since 3.18.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    #[cfg(feature = \"proposed\")]\n    pub inline_completion_provider: Option<OneOf<bool, InlineCompletionOptions>>,\n\n    /// Experimental server capabilities.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub experimental: Option<Value>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceServerCapabilities {\n    /// The server supports workspace folder.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub workspace_folders: Option<WorkspaceFoldersServerCapabilities>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub file_operations: Option<WorkspaceFileOperationsServerCapabilities>,\n}\n\n/// General parameters to to register for a capability.\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Registration {\n    /// The id used to register the request. The id can be used to deregister\n    /// the request again.\n    pub id: String,\n\n    /// The method / capability to register for.\n    pub method: String,\n\n    /// Options necessary for the registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub register_options: Option<Value>,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\npub struct RegistrationParams {\n    pub registrations: Vec<Registration>,\n}\n\n/// Since most of the registration options require to specify a document selector there is a base\n/// interface that can be used.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextDocumentRegistrationOptions {\n    /// A document selector to identify the scope of the registration. If set to null\n    /// the document selector provided on the client side will be used.\n    pub document_selector: Option<DocumentSelector>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum DeclarationCapability {\n    Simple(bool),\n    RegistrationOptions(DeclarationRegistrationOptions),\n    Options(DeclarationOptions),\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DeclarationRegistrationOptions {\n    #[serde(flatten)]\n    pub declaration_options: DeclarationOptions,\n\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub static_registration_options: StaticRegistrationOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DeclarationOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct StaticRegistrationOptions {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub id: Option<String>,\n}\n\n#[derive(Debug, Default, Eq, PartialEq, Clone, Deserialize, Serialize, Copy)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkDoneProgressOptions {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub work_done_progress: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentFormattingOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentRangeFormattingOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DefinitionOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentSymbolOptions {\n    /// A human-readable string that is shown when multiple outlines trees are\n    /// shown for the same document.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub label: Option<String>,\n\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ReferencesOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DocumentHighlightOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceSymbolOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n\n    /// The server provides support to resolve additional\n    /// information for a workspace symbol.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resolve_provider: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct StaticTextDocumentRegistrationOptions {\n    /// A document selector to identify the scope of the registration. If set to null\n    /// the document selector provided on the client side will be used.\n    pub document_selector: Option<DocumentSelector>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub id: Option<String>,\n}\n\n/// General parameters to unregister a capability.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct Unregistration {\n    /// The id used to unregister the request or notification. Usually an id\n    /// provided during the register request.\n    pub id: String,\n\n    /// The method / capability to unregister for.\n    pub method: String,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct UnregistrationParams {\n    pub unregisterations: Vec<Unregistration>,\n}\n\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\npub struct DidChangeConfigurationParams {\n    /// The actual changed settings\n    pub settings: Value,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DidOpenTextDocumentParams {\n    /// The document that was opened.\n    pub text_document: TextDocumentItem,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DidChangeTextDocumentParams {\n    /// The document that did change. The version number points\n    /// to the version after all provided content changes have\n    /// been applied.\n    pub text_document: VersionedTextDocumentIdentifier,\n    /// The actual content changes.\n    pub content_changes: Vec<TextDocumentContentChangeEvent>,\n}\n\n/// An event describing a change to a text document. If range and rangeLength are omitted\n/// the new text is considered to be the full content of the document.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextDocumentContentChangeEvent {\n    /// The range of the document that changed.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub range: Option<Range>,\n\n    /// The length of the range that got replaced.\n    ///\n    /// Deprecated: Use range instead\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub range_length: Option<u32>,\n\n    /// The new text of the document.\n    pub text: String,\n}\n\n/// Describe options to be used when registering for text document change events.\n///\n/// Extends TextDocumentRegistrationOptions\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextDocumentChangeRegistrationOptions {\n    /// A document selector to identify the scope of the registration. If set to null\n    /// the document selector provided on the client side will be used.\n    pub document_selector: Option<DocumentSelector>,\n\n    /// How documents are synced to the server. See TextDocumentSyncKind.Full\n    /// and TextDocumentSyncKindIncremental.\n    pub sync_kind: i32,\n}\n\n/// The parameters send in a will save text document notification.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WillSaveTextDocumentParams {\n    /// The document that will be saved.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The 'TextDocumentSaveReason'.\n    pub reason: TextDocumentSaveReason,\n}\n\n/// Represents reasons why a text document is saved.\n#[derive(Copy, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct TextDocumentSaveReason(i32);\nlsp_enum! {\nimpl TextDocumentSaveReason {\n    /// Manually triggered, e.g. by the user pressing save, by starting debugging,\n    /// or by an API call.\n    pub const MANUAL: TextDocumentSaveReason = TextDocumentSaveReason(1);\n\n    /// Automatic after a delay.\n    pub const AFTER_DELAY: TextDocumentSaveReason = TextDocumentSaveReason(2);\n\n    /// When the editor lost focus.\n    pub const FOCUS_OUT: TextDocumentSaveReason = TextDocumentSaveReason(3);\n}\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DidCloseTextDocumentParams {\n    /// The document that was closed.\n    pub text_document: TextDocumentIdentifier,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DidSaveTextDocumentParams {\n    /// The document that was saved.\n    pub text_document: TextDocumentIdentifier,\n\n    /// Optional the content when saved. Depends on the includeText value\n    /// when the save notification was requested.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub text: Option<String>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TextDocumentSaveRegistrationOptions {\n    /// The client is supposed to include the content on save.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub include_text: Option<bool>,\n\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Copy, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DidChangeWatchedFilesClientCapabilities {\n    /// Did change watched files notification supports dynamic registration.\n    /// Please note that the current protocol doesn't support static\n    /// configuration for file changes from the server side.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// Whether the client has support for relative patterns\n    /// or not.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub relative_pattern_support: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct DidChangeWatchedFilesParams {\n    /// The actual file events.\n    pub changes: Vec<FileEvent>,\n}\n\n/// The file event type.\n#[derive(Eq, PartialEq, Hash, Copy, Clone, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct FileChangeType(i32);\nlsp_enum! {\nimpl FileChangeType {\n    /// The file got created.\n    pub const CREATED: FileChangeType = FileChangeType(1);\n\n    /// The file got changed.\n    pub const CHANGED: FileChangeType = FileChangeType(2);\n\n    /// The file got deleted.\n    pub const DELETED: FileChangeType = FileChangeType(3);\n}\n}\n\n/// An event describing a file change.\n#[derive(Debug, Eq, Hash, PartialEq, Clone, Deserialize, Serialize)]\npub struct FileEvent {\n    /// The file's URI.\n    pub uri: Url,\n\n    /// The change type.\n    #[serde(rename = \"type\")]\n    pub typ: FileChangeType,\n}\n\nimpl FileEvent {\n    pub fn new(uri: Url, typ: FileChangeType) -> FileEvent {\n        FileEvent { uri, typ }\n    }\n}\n\n/// Describe options to be used when registered for text document change events.\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Deserialize, Serialize)]\npub struct DidChangeWatchedFilesRegistrationOptions {\n    /// The watchers to register.\n    pub watchers: Vec<FileSystemWatcher>,\n}\n\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct FileSystemWatcher {\n    /// The glob pattern to watch. See {@link GlobPattern glob pattern}\n    /// for more detail.\n    ///\n    /// @since 3.17.0 support for relative patterns.\n    pub glob_pattern: GlobPattern,\n\n    /// The kind of events of interest. If omitted it defaults to WatchKind.Create |\n    /// WatchKind.Change | WatchKind.Delete which is 7.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub kind: Option<WatchKind>,\n}\n\n/// The glob pattern. Either a string pattern or a relative pattern.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum GlobPattern {\n    String(Pattern),\n    Relative(RelativePattern),\n}\n\nimpl From<Pattern> for GlobPattern {\n    #[inline]\n    fn from(from: Pattern) -> Self {\n        Self::String(from)\n    }\n}\n\nimpl From<RelativePattern> for GlobPattern {\n    #[inline]\n    fn from(from: RelativePattern) -> Self {\n        Self::Relative(from)\n    }\n}\n\n/// A relative pattern is a helper to construct glob patterns that are matched\n/// relatively to a base URI. The common value for a `baseUri` is a workspace\n/// folder root, but it can be another absolute URI as well.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct RelativePattern {\n    /// A workspace folder or a base URI to which this pattern will be matched\n    /// against relatively.\n    pub base_uri: OneOf<WorkspaceFolder, Url>,\n\n    /// The actual glob pattern.\n    pub pattern: Pattern,\n}\n\n/// The glob pattern to watch relative to the base path. Glob patterns can have\n/// the following syntax:\n/// - `*` to match one or more characters in a path segment\n/// - `?` to match on one character in a path segment\n/// - `**` to match any number of path segments, including none\n/// - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript\n///   and JavaScript files)\n/// - `[]` to declare a range of characters to match in a path segment\n///   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)\n/// - `[!...]` to negate a range of characters to match in a path segment\n///   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`,\n///   but not `example.0`)\n///\n/// @since 3.17.0\npub type Pattern = String;\n\nbitflags! {\n#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]\npub struct WatchKind: u8 {\n    /// Interested in create events.\n    const Create = 1;\n    /// Interested in change events\n    const Change = 2;\n    /// Interested in delete events\n    const Delete = 4;\n}\n}\n\nimpl<'de> serde::Deserialize<'de> for WatchKind {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        let i = u8::deserialize(deserializer)?;\n        WatchKind::from_bits(i).ok_or_else(|| {\n            D::Error::invalid_value(de::Unexpected::Unsigned(u64::from(i)), &\"Unknown flag\")\n        })\n    }\n}\n\nimpl serde::Serialize for WatchKind {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        serializer.serialize_u8(self.bits())\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct PublishDiagnosticsParams {\n    /// The URI for which diagnostic information is reported.\n    pub uri: Url,\n\n    /// An array of diagnostic information items.\n    pub diagnostics: Vec<Diagnostic>,\n\n    /// Optional the version number of the document the diagnostics are published for.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub version: Option<i32>,\n}\n\nimpl PublishDiagnosticsParams {\n    pub fn new(\n        uri: Url,\n        diagnostics: Vec<Diagnostic>,\n        version: Option<i32>,\n    ) -> PublishDiagnosticsParams {\n        PublishDiagnosticsParams {\n            uri,\n            diagnostics,\n            version,\n        }\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(untagged)]\npub enum Documentation {\n    String(String),\n    MarkupContent(MarkupContent),\n}\n\n/// MarkedString can be used to render human readable text. It is either a\n/// markdown string or a code-block that provides a language and a code snippet.\n/// The language identifier is semantically equal to the optional language\n/// identifier in fenced code blocks in GitHub issues.\n///\n/// The pair of a language and a value is an equivalent to markdown:\n///\n/// <pre><code>```${language}\n/// ${value}\n/// ```</code></pre>\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum MarkedString {\n    String(String),\n    LanguageString(LanguageString),\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct LanguageString {\n    pub language: String,\n    pub value: String,\n}\n\nimpl MarkedString {\n    pub fn from_markdown(markdown: String) -> MarkedString {\n        MarkedString::String(markdown)\n    }\n\n    pub fn from_language_code(language: String, code_block: String) -> MarkedString {\n        MarkedString::LanguageString(LanguageString {\n            language,\n            value: code_block,\n        })\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct GotoDefinitionParams {\n    #[serde(flatten)]\n    pub text_document_position_params: TextDocumentPositionParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// GotoDefinition response can be single location, or multiple Locations or a link.\n#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]\n#[serde(untagged)]\npub enum GotoDefinitionResponse {\n    Scalar(Location),\n    Array(Vec<Location>),\n    Link(Vec<LocationLink>),\n}\n\nimpl From<Location> for GotoDefinitionResponse {\n    fn from(location: Location) -> Self {\n        GotoDefinitionResponse::Scalar(location)\n    }\n}\n\nimpl From<Vec<Location>> for GotoDefinitionResponse {\n    fn from(locations: Vec<Location>) -> Self {\n        GotoDefinitionResponse::Array(locations)\n    }\n}\n\nimpl From<Vec<LocationLink>> for GotoDefinitionResponse {\n    fn from(locations: Vec<LocationLink>) -> Self {\n        GotoDefinitionResponse::Link(locations)\n    }\n}\n\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct ExecuteCommandParams {\n    /// The identifier of the actual command handler.\n    pub command: String,\n    /// Arguments that the command should be invoked with.\n    #[serde(default)]\n    pub arguments: Vec<Value>,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n}\n\n/// Execute command registration options.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct ExecuteCommandRegistrationOptions {\n    /// The commands to be executed on the server\n    pub commands: Vec<String>,\n\n    #[serde(flatten)]\n    pub execute_command_options: ExecuteCommandOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ApplyWorkspaceEditParams {\n    /// An optional label of the workspace edit. This label is\n    /// presented in the user interface for example on an undo\n    /// stack to undo the workspace edit.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub label: Option<String>,\n\n    /// The edits to apply.\n    pub edit: WorkspaceEdit,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ApplyWorkspaceEditResponse {\n    /// Indicates whether the edit was applied or not.\n    pub applied: bool,\n\n    /// An optional textual description for why the edit was not applied.\n    /// This may be used may be used by the server for diagnostic\n    /// logging or to provide a suitable error for a request that\n    /// triggered the edit\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub failure_reason: Option<String>,\n\n    /// Depending on the client's failure handling strategy `failedChange` might\n    /// contain the index of the change that failed. This property is only available\n    /// if the client signals a `failureHandlingStrategy` in its client capabilities.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub failed_change: Option<u32>,\n}\n\n/// Describes the content type that a client supports in various\n/// result literals like `Hover`, `ParameterInfo` or `CompletionItem`.\n///\n/// Please note that `MarkupKinds` must not start with a `$`. This kinds\n/// are reserved for internal usage.\n#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"lowercase\")]\npub enum MarkupKind {\n    /// Plain text is supported as a content format\n    PlainText,\n    /// Markdown is supported as a content format\n    Markdown,\n}\n\n/// A `MarkupContent` literal represents a string value which content can be represented in different formats.\n/// Currently `plaintext` and `markdown` are supported formats. A `MarkupContent` is usually used in\n/// documentation properties of result literals like `CompletionItem` or `SignatureInformation`.\n/// If the format is `markdown` the content should follow the [GitHub Flavored Markdown Specification](https://github.github.com/gfm/).\n///\n/// Here is an example how such a string can be constructed using JavaScript / TypeScript:\n///\n/// ```ignore\n/// let markdown: MarkupContent = {\n///     kind: MarkupKind::Markdown,\n///     value: [\n///         \"# Header\",\n///         \"Some text\",\n///         \"```typescript\",\n///         \"someCode();\",\n///         \"```\"\n///     ]\n///     .join(\"\\n\"),\n/// };\n/// ```\n///\n/// Please *Note* that clients might sanitize the return markdown. A client could decide to\n/// remove HTML from the markdown to avoid script execution.\n#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)]\npub struct MarkupContent {\n    pub kind: MarkupKind,\n    pub value: String,\n}\n\n/// A parameter literal used to pass a partial result token.\n#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct PartialResultParams {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub partial_result_token: Option<ProgressToken>,\n}\n\n/// Symbol tags are extra annotations that tweak the rendering of a symbol.\n///\n/// @since 3.16.0\n#[derive(Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct SymbolTag(i32);\nlsp_enum! {\nimpl SymbolTag {\n    /// Render a symbol as obsolete, usually using a strike-out.\n    pub const DEPRECATED: SymbolTag = SymbolTag(1);\n}\n}\n\n#[cfg(test)]\nmod tests {\n    use serde::{Deserialize, Serialize};\n\n    use super::*;\n\n    pub(crate) fn test_serialization<SER>(ms: &SER, expected: &str)\n    where\n        SER: Serialize + for<'de> Deserialize<'de> + PartialEq + std::fmt::Debug,\n    {\n        let json_str = serde_json::to_string(ms).unwrap();\n        assert_eq!(&json_str, expected);\n        let deserialized: SER = serde_json::from_str(&json_str).unwrap();\n        assert_eq!(&deserialized, ms);\n    }\n\n    pub(crate) fn test_deserialization<T>(json: &str, expected: &T)\n    where\n        T: for<'de> Deserialize<'de> + PartialEq + std::fmt::Debug,\n    {\n        let value = serde_json::from_str::<T>(json).unwrap();\n        assert_eq!(&value, expected);\n    }\n\n    #[test]\n    fn one_of() {\n        test_serialization(&OneOf::<bool, ()>::Left(true), r#\"true\"#);\n        test_serialization(&OneOf::<String, ()>::Left(\"abcd\".into()), r#\"\"abcd\"\"#);\n        test_serialization(\n            &OneOf::<String, WorkDoneProgressOptions>::Right(WorkDoneProgressOptions {\n                work_done_progress: Some(false),\n            }),\n            r#\"{\"workDoneProgress\":false}\"#,\n        );\n    }\n\n    #[test]\n    fn number_or_string() {\n        test_serialization(&NumberOrString::Number(123), r#\"123\"#);\n\n        test_serialization(&NumberOrString::String(\"abcd\".into()), r#\"\"abcd\"\"#);\n    }\n\n    #[test]\n    fn marked_string() {\n        test_serialization(&MarkedString::from_markdown(\"xxx\".into()), r#\"\"xxx\"\"#);\n\n        test_serialization(\n            &MarkedString::from_language_code(\"lang\".into(), \"code\".into()),\n            r#\"{\"language\":\"lang\",\"value\":\"code\"}\"#,\n        );\n    }\n\n    #[test]\n    fn language_string() {\n        test_serialization(\n            &LanguageString {\n                language: \"LL\".into(),\n                value: \"VV\".into(),\n            },\n            r#\"{\"language\":\"LL\",\"value\":\"VV\"}\"#,\n        );\n    }\n\n    #[test]\n    fn workspace_edit() {\n        test_serialization(\n            &WorkspaceEdit {\n                changes: Some(vec![].into_iter().collect()),\n                document_changes: None,\n                ..Default::default()\n            },\n            r#\"{\"changes\":{}}\"#,\n        );\n\n        test_serialization(\n            &WorkspaceEdit {\n                changes: None,\n                document_changes: None,\n                ..Default::default()\n            },\n            r#\"{}\"#,\n        );\n\n        test_serialization(\n            &WorkspaceEdit {\n                changes: Some(\n                    vec![(Url::parse(\"file://test\").unwrap(), vec![])]\n                        .into_iter()\n                        .collect(),\n                ),\n                document_changes: None,\n                ..Default::default()\n            },\n            r#\"{\"changes\":{\"file://test/\":[]}}\"#,\n        );\n    }\n\n    #[test]\n    fn root_uri_can_be_missing() {\n        serde_json::from_str::<InitializeParams>(r#\"{ \"capabilities\": {} }\"#).unwrap();\n    }\n\n    #[test]\n    fn test_watch_kind() {\n        test_serialization(&WatchKind::Create, \"1\");\n        test_serialization(&(WatchKind::Create | WatchKind::Change), \"3\");\n        test_serialization(\n            &(WatchKind::Create | WatchKind::Change | WatchKind::Delete),\n            \"7\",\n        );\n    }\n\n    #[test]\n    fn test_resource_operation_kind() {\n        test_serialization(\n            &vec![\n                ResourceOperationKind::Create,\n                ResourceOperationKind::Rename,\n                ResourceOperationKind::Delete,\n            ],\n            r#\"[\"create\",\"rename\",\"delete\"]\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "helix-lsp-types/src/linked_editing.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::{\n    DynamicRegistrationClientCapabilities, Range, StaticRegistrationOptions,\n    TextDocumentPositionParams, TextDocumentRegistrationOptions, WorkDoneProgressOptions,\n    WorkDoneProgressParams,\n};\n\npub type LinkedEditingRangeClientCapabilities = DynamicRegistrationClientCapabilities;\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct LinkedEditingRangeOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct LinkedEditingRangeRegistrationOptions {\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub linked_editing_range_options: LinkedEditingRangeOptions,\n\n    #[serde(flatten)]\n    pub static_registration_options: StaticRegistrationOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum LinkedEditingRangeServerCapabilities {\n    Simple(bool),\n    Options(LinkedEditingRangeOptions),\n    RegistrationOptions(LinkedEditingRangeRegistrationOptions),\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct LinkedEditingRangeParams {\n    #[serde(flatten)]\n    pub text_document_position_params: TextDocumentPositionParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct LinkedEditingRanges {\n    /// A list of ranges that can be renamed together. The ranges must have\n    /// identical length and contain identical text content. The ranges cannot overlap.\n    pub ranges: Vec<Range>,\n\n    /// An optional word pattern (regular expression) that describes valid contents for\n    /// the given ranges. If no pattern is provided, the client configuration's word\n    /// pattern will be used.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub word_pattern: Option<String>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/lsif.rs",
    "content": "//! Types of Language Server Index Format (LSIF). LSIF is a standard format\n//! for language servers or other programming tools to dump their knowledge\n//! about a workspace.\n//!\n//! Based on <https://microsoft.github.io/language-server-protocol/specifications/lsif/0.6.0/specification/>\n\nuse crate::{Range, Url};\nuse serde::{Deserialize, Serialize};\n\npub type Id = crate::NumberOrString;\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(untagged)]\npub enum LocationOrRangeId {\n    Location(crate::Location),\n    RangeId(Id),\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Entry {\n    pub id: Id,\n    #[serde(flatten)]\n    pub data: Element,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(tag = \"type\")]\npub enum Element {\n    Vertex(Vertex),\n    Edge(Edge),\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\npub struct ToolInfo {\n    pub name: String,\n    #[serde(default = \"Default::default\")]\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub args: Vec<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub version: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Copy)]\npub enum Encoding {\n    /// Currently only 'utf-16' is supported due to the limitations in LSP.\n    #[serde(rename = \"utf-16\")]\n    Utf16,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\npub struct RangeBasedDocumentSymbol {\n    pub id: Id,\n    #[serde(default = \"Default::default\")]\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub children: Vec<RangeBasedDocumentSymbol>,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(untagged)]\npub enum DocumentSymbolOrRangeBasedVec {\n    DocumentSymbol(Vec<crate::DocumentSymbol>),\n    RangeBased(Vec<RangeBasedDocumentSymbol>),\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DefinitionTag {\n    /// The text covered by the range     \n    text: String,\n    /// The symbol kind.\n    kind: crate::SymbolKind,\n    /// Indicates if this symbol is deprecated.\n    #[serde(default)]\n    #[serde(skip_serializing_if = \"std::ops::Not::not\")]\n    deprecated: bool,\n    /// The full range of the definition not including leading/trailing whitespace but everything else, e.g comments and code.\n    /// The range must be included in fullRange.\n    full_range: Range,\n    /// Optional detail information for the definition.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    detail: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DeclarationTag {\n    /// The text covered by the range     \n    text: String,\n    /// The symbol kind.\n    kind: crate::SymbolKind,\n    /// Indicates if this symbol is deprecated.\n    #[serde(default)]\n    deprecated: bool,\n    /// The full range of the definition not including leading/trailing whitespace but everything else, e.g comments and code.\n    /// The range must be included in fullRange.\n    full_range: Range,\n    /// Optional detail information for the definition.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    detail: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ReferenceTag {\n    text: String,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct UnknownTag {\n    text: String,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(tag = \"type\")]\npub enum RangeTag {\n    Definition(DefinitionTag),\n    Declaration(DeclarationTag),\n    Reference(ReferenceTag),\n    Unknown(UnknownTag),\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(tag = \"label\")]\npub enum Vertex {\n    MetaData(MetaData),\n    /// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#the-project-vertex>\n    Project(Project),\n    Document(Document),\n    /// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#ranges>\n    Range {\n        #[serde(flatten)]\n        range: Range,\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        tag: Option<RangeTag>,\n    },\n    /// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set>\n    ResultSet(ResultSet),\n    Moniker(crate::Moniker),\n    PackageInformation(PackageInformation),\n\n    #[serde(rename = \"$event\")]\n    Event(Event),\n\n    DefinitionResult,\n    DeclarationResult,\n    TypeDefinitionResult,\n    ReferenceResult,\n    ImplementationResult,\n    FoldingRangeResult {\n        result: Vec<crate::FoldingRange>,\n    },\n    HoverResult {\n        result: crate::Hover,\n    },\n    DocumentSymbolResult {\n        result: DocumentSymbolOrRangeBasedVec,\n    },\n    DocumentLinkResult {\n        result: Vec<crate::DocumentLink>,\n    },\n    DiagnosticResult {\n        result: Vec<crate::Diagnostic>,\n    },\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub enum EventKind {\n    Begin,\n    End,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub enum EventScope {\n    Document,\n    Project,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\npub struct Event {\n    pub kind: EventKind,\n    pub scope: EventScope,\n    pub data: Id,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(tag = \"label\")]\npub enum Edge {\n    Contains(EdgeDataMultiIn),\n    Moniker(EdgeData),\n    NextMoniker(EdgeData),\n    Next(EdgeData),\n    PackageInformation(EdgeData),\n    Item(Item),\n\n    // Methods\n    #[serde(rename = \"textDocument/definition\")]\n    Definition(EdgeData),\n    #[serde(rename = \"textDocument/declaration\")]\n    Declaration(EdgeData),\n    #[serde(rename = \"textDocument/hover\")]\n    Hover(EdgeData),\n    #[serde(rename = \"textDocument/references\")]\n    References(EdgeData),\n    #[serde(rename = \"textDocument/implementation\")]\n    Implementation(EdgeData),\n    #[serde(rename = \"textDocument/typeDefinition\")]\n    TypeDefinition(EdgeData),\n    #[serde(rename = \"textDocument/foldingRange\")]\n    FoldingRange(EdgeData),\n    #[serde(rename = \"textDocument/documentLink\")]\n    DocumentLink(EdgeData),\n    #[serde(rename = \"textDocument/documentSymbol\")]\n    DocumentSymbol(EdgeData),\n    #[serde(rename = \"textDocument/diagnostic\")]\n    Diagnostic(EdgeData),\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct EdgeData {\n    pub in_v: Id,\n    pub out_v: Id,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct EdgeDataMultiIn {\n    pub in_vs: Vec<Id>,\n    pub out_v: Id,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(untagged)]\npub enum DefinitionResultType {\n    Scalar(LocationOrRangeId),\n    Array(LocationOrRangeId),\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub enum ItemKind {\n    Declarations,\n    Definitions,\n    References,\n    ReferenceResults,\n    ImplementationResults,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Item {\n    pub document: Id,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub property: Option<ItemKind>,\n    #[serde(flatten)]\n    pub edge_data: EdgeDataMultiIn,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Document {\n    pub uri: Url,\n    pub language_id: String,\n}\n\n/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set>\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ResultSet {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub key: Option<String>,\n}\n\n/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#the-project-vertex>\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Project {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resource: Option<Url>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub content: Option<String>,\n    pub kind: String,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct MetaData {\n    /// The version of the LSIF format using semver notation. See <https://semver.org/>. Please note\n    /// the version numbers starting with 0 don't adhere to semver and adopters have to assume\n    /// that each new version is breaking.\n    pub version: String,\n\n    /// The project root (in form of an URI) used to compute this dump.\n    pub project_root: Url,\n\n    /// The string encoding used to compute line and character values in\n    /// positions and ranges.\n    pub position_encoding: Encoding,\n\n    /// Information about the tool that created the dump\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tool_info: Option<ToolInfo>,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Repository {\n    pub r#type: String,\n    pub url: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub commit_id: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Serialize, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct PackageInformation {\n    pub name: String,\n    pub manager: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub uri: Option<Url>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub content: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub repository: Option<Repository>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub version: Option<String>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/moniker.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::{\n    DynamicRegistrationClientCapabilities, PartialResultParams, TextDocumentPositionParams,\n    TextDocumentRegistrationOptions, WorkDoneProgressOptions, WorkDoneProgressParams,\n};\n\npub type MonikerClientCapabilities = DynamicRegistrationClientCapabilities;\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum MonikerServerCapabilities {\n    Options(MonikerOptions),\n    RegistrationOptions(MonikerRegistrationOptions),\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct MonikerOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct MonikerRegistrationOptions {\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub moniker_options: MonikerOptions,\n}\n\n/// Moniker uniqueness level to define scope of the moniker.\n#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Copy, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub enum UniquenessLevel {\n    /// The moniker is only unique inside a document\n    Document,\n    /// The moniker is unique inside a project for which a dump got created\n    Project,\n    /// The moniker is unique inside the group to which a project belongs\n    Group,\n    /// The moniker is unique inside the moniker scheme.\n    Scheme,\n    /// The moniker is globally unique\n    Global,\n}\n\n/// The moniker kind.\n#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Copy, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub enum MonikerKind {\n    /// The moniker represent a symbol that is imported into a project\n    Import,\n    /// The moniker represent a symbol that is exported into a project\n    Export,\n    /// The moniker represents a symbol that is local to a project (e.g. a local\n    /// variable of a function, a class not visible outside the project, ...)\n    Local,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct MonikerParams {\n    #[serde(flatten)]\n    pub text_document_position_params: TextDocumentPositionParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// Moniker definition to match LSIF 0.5 moniker definition.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Moniker {\n    /// The scheme of the moniker. For example tsc or .Net\n    pub scheme: String,\n\n    /// The identifier of the moniker. The value is opaque in LSIF however\n    /// schema owners are allowed to define the structure if they want.\n    pub identifier: String,\n\n    /// The scope in which the moniker is unique\n    pub unique: UniquenessLevel,\n\n    /// The moniker kind if known.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub kind: Option<MonikerKind>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/notification.rs",
    "content": "use super::*;\n\nuse serde::{de::DeserializeOwned, Serialize};\n\npub trait Notification {\n    type Params: DeserializeOwned + Serialize + Send + Sync + 'static;\n    const METHOD: &'static str;\n}\n\n#[macro_export]\nmacro_rules! lsp_notification {\n    (\"$/cancelRequest\") => {\n        $crate::notification::Cancel\n    };\n    (\"$/setTrace\") => {\n        $crate::notification::SetTrace\n    };\n    (\"$/logTrace\") => {\n        $crate::notification::LogTrace\n    };\n    (\"initialized\") => {\n        $crate::notification::Initialized\n    };\n    (\"exit\") => {\n        $crate::notification::Exit\n    };\n\n    (\"window/showMessage\") => {\n        $crate::notification::ShowMessage\n    };\n    (\"window/logMessage\") => {\n        $crate::notification::LogMessage\n    };\n    (\"window/workDoneProgress/cancel\") => {\n        $crate::notification::WorkDoneProgressCancel\n    };\n\n    (\"telemetry/event\") => {\n        $crate::notification::TelemetryEvent\n    };\n\n    (\"textDocument/didOpen\") => {\n        $crate::notification::DidOpenTextDocument\n    };\n    (\"textDocument/didChange\") => {\n        $crate::notification::DidChangeTextDocument\n    };\n    (\"textDocument/willSave\") => {\n        $crate::notification::WillSaveTextDocument\n    };\n    (\"textDocument/didSave\") => {\n        $crate::notification::DidSaveTextDocument\n    };\n    (\"textDocument/didClose\") => {\n        $crate::notification::DidCloseTextDocument\n    };\n    (\"textDocument/publishDiagnostics\") => {\n        $crate::notification::PublishDiagnostics\n    };\n\n    (\"workspace/didChangeConfiguration\") => {\n        $crate::notification::DidChangeConfiguration\n    };\n    (\"workspace/didChangeWatchedFiles\") => {\n        $crate::notification::DidChangeWatchedFiles\n    };\n    (\"workspace/didChangeWorkspaceFolders\") => {\n        $crate::notification::DidChangeWorkspaceFolders\n    };\n    (\"$/progress\") => {\n        $crate::notification::Progress\n    };\n    (\"workspace/didCreateFiles\") => {\n        $crate::notification::DidCreateFiles\n    };\n    (\"workspace/didRenameFiles\") => {\n        $crate::notification::DidRenameFiles\n    };\n    (\"workspace/didDeleteFiles\") => {\n        $crate::notification::DidDeleteFiles\n    };\n}\n\n/// The base protocol now offers support for request cancellation. To cancel a request,\n/// a notification message with the following properties is sent:\n///\n/// A request that got canceled still needs to return from the server and send a response back.\n/// It can not be left open / hanging. This is in line with the JSON RPC protocol that requires\n/// that every request sends a response back. In addition it allows for returning partial results on cancel.\n#[derive(Debug)]\npub enum Cancel {}\n\nimpl Notification for Cancel {\n    type Params = CancelParams;\n    const METHOD: &'static str = \"$/cancelRequest\";\n}\n\n/// A notification that should be used by the client to modify the trace\n/// setting of the server.\n#[derive(Debug)]\npub enum SetTrace {}\n\nimpl Notification for SetTrace {\n    type Params = SetTraceParams;\n    const METHOD: &'static str = \"$/setTrace\";\n}\n\n/// A notification to log the trace of the server’s execution.\n/// The amount and content of these notifications depends on the current trace configuration.\n///\n/// `LogTrace` should be used for systematic trace reporting. For single debugging messages,\n/// the server should send `LogMessage` notifications.\n#[derive(Debug)]\npub enum LogTrace {}\n\nimpl Notification for LogTrace {\n    type Params = LogTraceParams;\n    const METHOD: &'static str = \"$/logTrace\";\n}\n\n/// The initialized notification is sent from the client to the server after the client received\n/// the result of the initialize request but before the client is sending any other request or\n/// notification to the server. The server can use the initialized notification for example to\n/// dynamically register capabilities.\n#[derive(Debug)]\npub enum Initialized {}\n\nimpl Notification for Initialized {\n    type Params = InitializedParams;\n    const METHOD: &'static str = \"initialized\";\n}\n\n/// A notification to ask the server to exit its process.\n/// The server should exit with success code 0 if the shutdown request has been received before;\n/// otherwise with error code 1.\n#[derive(Debug)]\npub enum Exit {}\n\nimpl Notification for Exit {\n    type Params = ();\n    const METHOD: &'static str = \"exit\";\n}\n\n/// The show message notification is sent from a server to a client to ask the client to display a particular message\n/// in the user interface.\n#[derive(Debug)]\npub enum ShowMessage {}\n\nimpl Notification for ShowMessage {\n    type Params = ShowMessageParams;\n    const METHOD: &'static str = \"window/showMessage\";\n}\n\n/// The log message notification is sent from the server to the client to ask the client to log a particular message.\n#[derive(Debug)]\npub enum LogMessage {}\n\nimpl Notification for LogMessage {\n    type Params = LogMessageParams;\n    const METHOD: &'static str = \"window/logMessage\";\n}\n\n/// The telemetry notification is sent from the server to the client to ask the client to log a telemetry event.\n/// The protocol doesn't specify the payload since no interpretation of the data happens in the protocol. Most clients even don't handle\n/// the event directly but forward them to the extensions owning the corresponding server issuing the event.\n#[derive(Debug)]\npub enum TelemetryEvent {}\n\nimpl Notification for TelemetryEvent {\n    type Params = OneOf<LSPObject, LSPArray>;\n    const METHOD: &'static str = \"telemetry/event\";\n}\n\n/// A notification sent from the client to the server to signal the change of configuration settings.\n#[derive(Debug)]\npub enum DidChangeConfiguration {}\n\nimpl Notification for DidChangeConfiguration {\n    type Params = DidChangeConfigurationParams;\n    const METHOD: &'static str = \"workspace/didChangeConfiguration\";\n}\n\n/// The document open notification is sent from the client to the server to signal newly opened text documents.\n/// The document's truth is now managed by the client and the server must not try to read the document's truth\n/// using the document's uri.\n#[derive(Debug)]\npub enum DidOpenTextDocument {}\n\nimpl Notification for DidOpenTextDocument {\n    type Params = DidOpenTextDocumentParams;\n    const METHOD: &'static str = \"textDocument/didOpen\";\n}\n\n/// The document change notification is sent from the client to the server to signal changes to a text document.\n/// In 2.0 the shape of the params has changed to include proper version numbers and language ids.\n#[derive(Debug)]\npub enum DidChangeTextDocument {}\n\nimpl Notification for DidChangeTextDocument {\n    type Params = DidChangeTextDocumentParams;\n    const METHOD: &'static str = \"textDocument/didChange\";\n}\n\n/// The document will save notification is sent from the client to the server before the document\n/// is actually saved.\n#[derive(Debug)]\npub enum WillSaveTextDocument {}\n\nimpl Notification for WillSaveTextDocument {\n    type Params = WillSaveTextDocumentParams;\n    const METHOD: &'static str = \"textDocument/willSave\";\n}\n\n/// The document close notification is sent from the client to the server when the document got closed in the client.\n/// The document's truth now exists where the document's uri points to (e.g. if the document's uri is a file uri\n/// the truth now exists on disk).\n#[derive(Debug)]\npub enum DidCloseTextDocument {}\n\nimpl Notification for DidCloseTextDocument {\n    type Params = DidCloseTextDocumentParams;\n    const METHOD: &'static str = \"textDocument/didClose\";\n}\n\n/// The document save notification is sent from the client to the server when the document was saved in the client.\n#[derive(Debug)]\npub enum DidSaveTextDocument {}\n\nimpl Notification for DidSaveTextDocument {\n    type Params = DidSaveTextDocumentParams;\n    const METHOD: &'static str = \"textDocument/didSave\";\n}\n\n/// The watched files notification is sent from the client to the server when the client detects changes to files and folders\n/// watched by the language client (note although the name suggest that only file events are sent it is about file system events which include folders as well).\n/// It is recommended that servers register for these file system events using the registration mechanism.\n/// In former implementations clients pushed file events without the server actively asking for it.\n#[derive(Debug)]\npub enum DidChangeWatchedFiles {}\n\nimpl Notification for DidChangeWatchedFiles {\n    type Params = DidChangeWatchedFilesParams;\n    const METHOD: &'static str = \"workspace/didChangeWatchedFiles\";\n}\n\n/// The workspace/didChangeWorkspaceFolders notification is sent from the client to the server to inform the server\n/// about workspace folder configuration changes\n#[derive(Debug)]\npub enum DidChangeWorkspaceFolders {}\n\nimpl Notification for DidChangeWorkspaceFolders {\n    type Params = DidChangeWorkspaceFoldersParams;\n    const METHOD: &'static str = \"workspace/didChangeWorkspaceFolders\";\n}\n\n/// Diagnostics notification are sent from the server to the client to signal results of validation runs.\n#[derive(Debug)]\npub enum PublishDiagnostics {}\n\nimpl Notification for PublishDiagnostics {\n    type Params = PublishDiagnosticsParams;\n    const METHOD: &'static str = \"textDocument/publishDiagnostics\";\n}\n\n/// The progress notification is sent from the server to the client to ask\n/// the client to indicate progress.\n#[derive(Debug)]\npub enum Progress {}\n\nimpl Notification for Progress {\n    type Params = ProgressParams;\n    const METHOD: &'static str = \"$/progress\";\n}\n\n/// The `window/workDoneProgress/cancel` notification is sent from the client\n/// to the server to cancel a progress initiated on the server side using the `window/workDoneProgress/create`.\n#[derive(Debug)]\npub enum WorkDoneProgressCancel {}\n\nimpl Notification for WorkDoneProgressCancel {\n    type Params = WorkDoneProgressCancelParams;\n    const METHOD: &'static str = \"window/workDoneProgress/cancel\";\n}\n\n/// The did create files notification is sent from the client to the server when files were created from within the client.\n#[derive(Debug)]\npub enum DidCreateFiles {}\n\nimpl Notification for DidCreateFiles {\n    type Params = CreateFilesParams;\n    const METHOD: &'static str = \"workspace/didCreateFiles\";\n}\n\n/// The did rename files notification is sent from the client to the server when files were renamed from within the client.\n#[derive(Debug)]\npub enum DidRenameFiles {}\n\nimpl Notification for DidRenameFiles {\n    type Params = RenameFilesParams;\n    const METHOD: &'static str = \"workspace/didRenameFiles\";\n}\n\n/// The did delete files notification is sent from the client to the server when files were deleted from within the client.\n#[derive(Debug)]\npub enum DidDeleteFiles {}\n\nimpl Notification for DidDeleteFiles {\n    type Params = DeleteFilesParams;\n    const METHOD: &'static str = \"workspace/didDeleteFiles\";\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    fn fake_call<N>()\n    where\n        N: Notification,\n        N::Params: serde::Serialize,\n    {\n    }\n\n    macro_rules! check_macro {\n        ($name:tt) => {\n            // check whether the macro name matches the method\n            assert_eq!(<lsp_notification!($name) as Notification>::METHOD, $name);\n            // test whether type checking passes for each component\n            fake_call::<lsp_notification!($name)>();\n        };\n    }\n\n    #[test]\n    fn check_macro_definitions() {\n        check_macro!(\"$/cancelRequest\");\n        check_macro!(\"$/progress\");\n        check_macro!(\"$/logTrace\");\n        check_macro!(\"$/setTrace\");\n        check_macro!(\"initialized\");\n        check_macro!(\"exit\");\n        check_macro!(\"window/showMessage\");\n        check_macro!(\"window/logMessage\");\n        check_macro!(\"window/workDoneProgress/cancel\");\n        check_macro!(\"telemetry/event\");\n        check_macro!(\"textDocument/didOpen\");\n        check_macro!(\"textDocument/didChange\");\n        check_macro!(\"textDocument/willSave\");\n        check_macro!(\"textDocument/didSave\");\n        check_macro!(\"textDocument/didClose\");\n        check_macro!(\"textDocument/publishDiagnostics\");\n        check_macro!(\"workspace/didChangeConfiguration\");\n        check_macro!(\"workspace/didChangeWatchedFiles\");\n        check_macro!(\"workspace/didChangeWorkspaceFolders\");\n        check_macro!(\"workspace/didCreateFiles\");\n        check_macro!(\"workspace/didRenameFiles\");\n        check_macro!(\"workspace/didDeleteFiles\");\n    }\n\n    #[test]\n    #[cfg(feature = \"proposed\")]\n    fn check_proposed_macro_definitions() {}\n}\n"
  },
  {
    "path": "helix-lsp-types/src/progress.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::NumberOrString;\n\npub type ProgressToken = NumberOrString;\n\n/// The progress notification is sent from the server to the client to ask\n/// the client to indicate progress.\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct ProgressParams {\n    /// The progress token provided by the client.\n    pub token: ProgressToken,\n\n    /// The progress data.\n    pub value: ProgressParamsValue,\n}\n\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(untagged)]\npub enum ProgressParamsValue {\n    WorkDone(WorkDoneProgress),\n}\n\n/// The `window/workDoneProgress/create` request is sent\n/// from the server to the client to ask the client to create a work done progress.\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkDoneProgressCreateParams {\n    /// The token to be used to report progress.\n    pub token: ProgressToken,\n}\n\n/// The `window/workDoneProgress/cancel` notification is sent from the client\n/// to the server to cancel a progress initiated on the server side using the `window/workDoneProgress/create`.\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkDoneProgressCancelParams {\n    /// The token to be used to report progress.\n    pub token: ProgressToken,\n}\n\n/// An optional token that a server can use to report work done progress\n#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkDoneProgressParams {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub work_done_token: Option<ProgressToken>,\n}\n\n#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkDoneProgressBegin {\n    /// Mandatory title of the progress operation. Used to briefly inform\n    /// about the kind of operation being performed.\n    /// Examples: \"Indexing\" or \"Linking dependencies\".\n    pub title: String,\n\n    /// Controls if a cancel button should show to allow the user to cancel the\n    /// long running operation. Clients that don't support cancellation are allowed\n    /// to ignore the setting.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub cancellable: Option<bool>,\n\n    /// Optional, more detailed associated progress message. Contains\n    /// complementary information to the `title`.\n    ///\n    /// Examples: \"3/25 files\", \"project/src/module2\", \"node_modules/some_dep\".\n    /// If unset, the previous progress message (if any) is still valid.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub message: Option<String>,\n\n    /// Optional progress percentage to display (value 100 is considered 100%).\n    /// If not provided infinite progress is assumed and clients are allowed\n    /// to ignore the `percentage` value in subsequent in report notifications.\n    ///\n    /// The value should be steadily rising. Clients are free to ignore values\n    /// that are not following this rule. The value range is [0, 100]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub percentage: Option<u32>,\n}\n\n#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkDoneProgressReport {\n    /// Controls if a cancel button should show to allow the user to cancel the\n    /// long running operation. Clients that don't support cancellation are allowed\n    /// to ignore the setting.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub cancellable: Option<bool>,\n\n    /// Optional, more detailed associated progress message. Contains\n    /// complementary information to the `title`.\n    /// Examples: \"3/25 files\", \"project/src/module2\", \"node_modules/some_dep\".\n    /// If unset, the previous progress message (if any) is still valid.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub message: Option<String>,\n\n    /// Optional progress percentage to display (value 100 is considered 100%).\n    /// If not provided infinite progress is assumed and clients are allowed\n    /// to ignore the `percentage` value in subsequent in report notifications.\n    ///\n    /// The value should be steadily rising. Clients are free to ignore values\n    /// that are not following this rule. The value range is [0, 100]\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub percentage: Option<u32>,\n}\n\n#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkDoneProgressEnd {\n    /// Optional, more detailed associated progress message. Contains\n    /// complementary information to the `title`.\n    /// Examples: \"3/25 files\", \"project/src/module2\", \"node_modules/some_dep\".\n    /// If unset, the previous progress message (if any) is still valid.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub message: Option<String>,\n}\n\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(tag = \"kind\", rename_all = \"lowercase\")]\npub enum WorkDoneProgress {\n    Begin(WorkDoneProgressBegin),\n    Report(WorkDoneProgressReport),\n    End(WorkDoneProgressEnd),\n}\n"
  },
  {
    "path": "helix-lsp-types/src/references.rs",
    "content": "use crate::{\n    DynamicRegistrationClientCapabilities, PartialResultParams, TextDocumentPositionParams,\n    WorkDoneProgressParams,\n};\nuse serde::{Deserialize, Serialize};\n\npub type ReferenceClientCapabilities = DynamicRegistrationClientCapabilities;\n#[derive(Debug, Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ReferenceContext {\n    /// Include the declaration of the current symbol.\n    pub include_declaration: bool,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ReferenceParams {\n    // Text Document and Position fields\n    #[serde(flatten)]\n    pub text_document_position: TextDocumentPositionParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n\n    // ReferenceParams properties:\n    pub context: ReferenceContext,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/rename.rs",
    "content": "use crate::{Range, TextDocumentPositionParams, WorkDoneProgressOptions, WorkDoneProgressParams};\nuse serde::{Deserialize, Serialize};\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct RenameParams {\n    /// Text Document and Position fields\n    #[serde(flatten)]\n    pub text_document_position: TextDocumentPositionParams,\n\n    /// The new name of the symbol. If the given name is not valid the\n    /// request must return a [ResponseError](#ResponseError) with an\n    /// appropriate message set.\n    pub new_name: String,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct RenameOptions {\n    /// Renames should be checked and tested before being executed.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub prepare_provider: Option<bool>,\n\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct RenameClientCapabilities {\n    /// Whether rename supports dynamic registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// Client supports testing for validity of rename operations before execution.\n    ///\n    /// @since 3.12.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub prepare_support: Option<bool>,\n\n    /// Client supports the default behavior result.\n    ///\n    /// The value indicates the default behavior used by the\n    /// client.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub prepare_support_default_behavior: Option<PrepareSupportDefaultBehavior>,\n\n    /// Whether the client honors the change annotations in\n    /// text edits and resource operations returned via the\n    /// rename request's workspace edit by for example presenting\n    /// the workspace edit in the user interface and asking\n    /// for confirmation.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub honors_change_annotations: Option<bool>,\n}\n\n#[derive(Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]\n#[serde(transparent)]\npub struct PrepareSupportDefaultBehavior(i32);\nlsp_enum! {\nimpl PrepareSupportDefaultBehavior {\n    /// The client's default behavior is to select the identifier\n    /// according the to language's syntax rule\n    pub const IDENTIFIER: PrepareSupportDefaultBehavior = PrepareSupportDefaultBehavior(1);\n}\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\n#[serde(rename_all = \"camelCase\")]\npub enum PrepareRenameResponse {\n    Range(Range),\n    RangeWithPlaceholder {\n        range: Range,\n        placeholder: String,\n    },\n    #[serde(rename_all = \"camelCase\")]\n    DefaultBehavior {\n        default_behavior: bool,\n    },\n}\n"
  },
  {
    "path": "helix-lsp-types/src/request.rs",
    "content": "use super::*;\n\nuse serde::{de::DeserializeOwned, Serialize};\n\npub trait Request {\n    type Params: DeserializeOwned + Serialize + Send + Sync + 'static;\n    type Result: DeserializeOwned + Serialize + Send + Sync + 'static;\n    const METHOD: &'static str;\n}\n\n#[macro_export]\nmacro_rules! lsp_request {\n    (\"initialize\") => {\n        $crate::request::Initialize\n    };\n    (\"shutdown\") => {\n        $crate::request::Shutdown\n    };\n\n    (\"window/showMessageRequest\") => {\n        $crate::request::ShowMessageRequest\n    };\n\n    (\"client/registerCapability\") => {\n        $crate::request::RegisterCapability\n    };\n    (\"client/unregisterCapability\") => {\n        $crate::request::UnregisterCapability\n    };\n\n    (\"workspace/symbol\") => {\n        $crate::request::WorkspaceSymbolRequest\n    };\n    (\"workspaceSymbol/resolve\") => {\n        $crate::request::WorkspaceSymbolResolve\n    };\n    (\"workspace/executeCommand\") => {\n        $crate::request::ExecuteCommand\n    };\n\n    (\"textDocument/willSaveWaitUntil\") => {\n        $crate::request::WillSaveWaitUntil\n    };\n\n    (\"textDocument/completion\") => {\n        $crate::request::Completion\n    };\n    (\"completionItem/resolve\") => {\n        $crate::request::ResolveCompletionItem\n    };\n    (\"textDocument/hover\") => {\n        $crate::request::HoverRequest\n    };\n    (\"textDocument/signatureHelp\") => {\n        $crate::request::SignatureHelpRequest\n    };\n    (\"textDocument/declaration\") => {\n        $crate::request::GotoDeclaration\n    };\n    (\"textDocument/definition\") => {\n        $crate::request::GotoDefinition\n    };\n    (\"textDocument/references\") => {\n        $crate::request::References\n    };\n    (\"textDocument/documentHighlight\") => {\n        $crate::request::DocumentHighlightRequest\n    };\n    (\"textDocument/documentSymbol\") => {\n        $crate::request::DocumentSymbolRequest\n    };\n    (\"textDocument/codeAction\") => {\n        $crate::request::CodeActionRequest\n    };\n    (\"textDocument/codeLens\") => {\n        $crate::request::CodeLensRequest\n    };\n    (\"codeLens/resolve\") => {\n        $crate::request::CodeLensResolve\n    };\n    (\"textDocument/documentLink\") => {\n        $crate::request::DocumentLinkRequest\n    };\n    (\"documentLink/resolve\") => {\n        $crate::request::DocumentLinkResolve\n    };\n    (\"workspace/applyEdit\") => {\n        $crate::request::ApplyWorkspaceEdit\n    };\n    (\"textDocument/rangeFormatting\") => {\n        $crate::request::RangeFormatting\n    };\n    (\"textDocument/onTypeFormatting\") => {\n        $crate::request::OnTypeFormatting\n    };\n    (\"textDocument/formatting\") => {\n        $crate::request::Formatting\n    };\n    (\"textDocument/rename\") => {\n        $crate::request::Rename\n    };\n    (\"textDocument/documentColor\") => {\n        $crate::request::DocumentColor\n    };\n    (\"textDocument/colorPresentation\") => {\n        $crate::request::ColorPresentationRequest\n    };\n    (\"textDocument/foldingRange\") => {\n        $crate::request::FoldingRangeRequest\n    };\n    (\"textDocument/prepareRename\") => {\n        $crate::request::PrepareRenameRequest\n    };\n    (\"textDocument/implementation\") => {\n        $crate::request::GotoImplementation\n    };\n    (\"textDocument/typeDefinition\") => {\n        $crate::request::GotoTypeDefinition\n    };\n    (\"textDocument/selectionRange\") => {\n        $crate::request::SelectionRangeRequest\n    };\n    (\"workspace/workspaceFolders\") => {\n        $crate::request::WorkspaceFoldersRequest\n    };\n    (\"workspace/configuration\") => {\n        $crate::request::WorkspaceConfiguration\n    };\n    (\"window/workDoneProgress/create\") => {\n        $crate::request::WorkDoneProgressCreate\n    };\n    (\"callHierarchy/incomingCalls\") => {\n        $crate::request::CallHierarchyIncomingCalls\n    };\n    (\"callHierarchy/outgoingCalls\") => {\n        $crate::request::CallHierarchyOutgoingCalls\n    };\n    (\"textDocument/moniker\") => {\n        $crate::request::MonikerRequest\n    };\n    (\"textDocument/linkedEditingRange\") => {\n        $crate::request::LinkedEditingRange\n    };\n    (\"textDocument/prepareCallHierarchy\") => {\n        $crate::request::CallHierarchyPrepare\n    };\n    (\"textDocument/prepareTypeHierarchy\") => {\n        $crate::request::TypeHierarchyPrepare\n    };\n    (\"textDocument/semanticTokens/full\") => {\n        $crate::request::SemanticTokensFullRequest\n    };\n    (\"textDocument/semanticTokens/full/delta\") => {\n        $crate::request::SemanticTokensFullDeltaRequest\n    };\n    (\"textDocument/semanticTokens/range\") => {\n        $crate::request::SemanticTokensRangeRequest\n    };\n    (\"textDocument/inlayHint\") => {\n        $crate::request::InlayHintRequest\n    };\n    (\"textDocument/inlineValue\") => {\n        $crate::request::InlineValueRequest\n    };\n    (\"textDocument/diagnostic\") => {\n        $crate::request::DocumentDiagnosticRequest\n    };\n    (\"workspace/diagnostic\") => {\n        $crate::request::WorkspaceDiagnosticRequest\n    };\n    (\"workspace/diagnostic/refresh\") => {\n        $crate::request::WorkspaceDiagnosticRefresh\n    };\n    (\"typeHierarchy/supertypes\") => {\n        $crate::request::TypeHierarchySupertypes\n    };\n    (\"typeHierarchy/subtypes\") => {\n        $crate::request::TypeHierarchySubtypes\n    };\n    (\"workspace/willCreateFiles\") => {\n        $crate::request::WillCreateFiles\n    };\n    (\"workspace/willRenameFiles\") => {\n        $crate::request::WillRenameFiles\n    };\n    (\"workspace/willDeleteFiles\") => {\n        $crate::request::WillDeleteFiles\n    };\n    (\"workspace/semanticTokens/refresh\") => {\n        $crate::request::SemanticTokensRefresh\n    };\n    (\"workspace/codeLens/refresh\") => {\n        $crate::request::CodeLensRefresh\n    };\n    (\"workspace/inlayHint/refresh\") => {\n        $crate::request::InlayHintRefreshRequest\n    };\n    (\"workspace/inlineValue/refresh\") => {\n        $crate::request::InlineValueRefreshRequest\n    };\n    (\"codeAction/resolve\") => {\n        $crate::request::CodeActionResolveRequest\n    };\n    (\"inlayHint/resolve\") => {\n        $crate::request::InlayHintResolveRequest\n    };\n    (\"window/showDocument\") => {\n        $crate::request::ShowDocument\n    };\n}\n\n/// The initialize request is sent as the first request from the client to the server.\n/// If the server receives request or notification before the `initialize` request it should act as follows:\n///\n/// * for a request the respond should be errored with `code: -32001`. The message can be picked by the server.\n/// * notifications should be dropped.\n#[derive(Debug)]\npub enum Initialize {}\n\nimpl Request for Initialize {\n    type Params = InitializeParams;\n    type Result = InitializeResult;\n    const METHOD: &'static str = \"initialize\";\n}\n\n/// The shutdown request is sent from the client to the server. It asks the server to shut down,\n/// but to not exit (otherwise the response might not be delivered correctly to the client).\n/// There is a separate exit notification that asks the server to exit.\n#[derive(Debug)]\npub enum Shutdown {}\n\nimpl Request for Shutdown {\n    type Params = ();\n    type Result = ();\n    const METHOD: &'static str = \"shutdown\";\n}\n\n/// The show message request is sent from a server to a client to ask the client to display a particular message\n/// in the user interface. In addition to the show message notification the request allows to pass actions and to\n/// wait for an answer from the client.\n#[derive(Debug)]\npub enum ShowMessageRequest {}\n\nimpl Request for ShowMessageRequest {\n    type Params = ShowMessageRequestParams;\n    type Result = Option<MessageActionItem>;\n    const METHOD: &'static str = \"window/showMessageRequest\";\n}\n\n/// The client/registerCapability request is sent from the server to the client to register for a new capability\n/// on the client side. Not all clients need to support dynamic capability registration. A client opts in via the\n/// ClientCapabilities.GenericCapability property.\n#[derive(Debug)]\npub enum RegisterCapability {}\n\nimpl Request for RegisterCapability {\n    type Params = RegistrationParams;\n    type Result = ();\n    const METHOD: &'static str = \"client/registerCapability\";\n}\n\n/// The client/unregisterCapability request is sent from the server to the client to unregister a\n/// previously register capability.\n#[derive(Debug)]\npub enum UnregisterCapability {}\n\nimpl Request for UnregisterCapability {\n    type Params = UnregistrationParams;\n    type Result = ();\n    const METHOD: &'static str = \"client/unregisterCapability\";\n}\n\n/// The Completion request is sent from the client to the server to compute completion items at a given cursor position.\n/// Completion items are presented in the IntelliSense user interface. If computing full completion items is expensive,\n/// servers can additionally provide a handler for the completion item resolve request ('completionItem/resolve').\n/// This request is sent when a completion item is selected in the user interface. A typical use case is for example:\n/// the 'textDocument/completion' request doesn’t fill in the documentation property for returned completion items\n/// since it is expensive to compute. When the item is selected in the user interface then a ‘completionItem/resolve’\n/// request is sent with the selected completion item as a param. The returned completion item should have the\n/// documentation property filled in. The request can delay the computation of the detail and documentation properties.\n/// However, properties that are needed for the initial sorting and filtering, like sortText, filterText, insertText,\n/// and textEdit must be provided in the textDocument/completion request and must not be changed during resolve.\n#[derive(Debug)]\npub enum Completion {}\n\nimpl Request for Completion {\n    type Params = CompletionParams;\n    type Result = Option<CompletionResponse>;\n    const METHOD: &'static str = \"textDocument/completion\";\n}\n\n/// The request is sent from the client to the server to resolve additional information for a given completion item.\n#[derive(Debug)]\npub enum ResolveCompletionItem {}\n\nimpl Request for ResolveCompletionItem {\n    type Params = CompletionItem;\n    type Result = CompletionItem;\n    const METHOD: &'static str = \"completionItem/resolve\";\n}\n\n/// The hover request is sent from the client to the server to request hover information at a given text\n/// document position.\n#[derive(Debug)]\npub enum HoverRequest {}\n\nimpl Request for HoverRequest {\n    type Params = HoverParams;\n    type Result = Option<Hover>;\n    const METHOD: &'static str = \"textDocument/hover\";\n}\n\n/// The signature help request is sent from the client to the server to request signature information at\n/// a given cursor position.\n#[derive(Debug)]\npub enum SignatureHelpRequest {}\n\nimpl Request for SignatureHelpRequest {\n    type Params = SignatureHelpParams;\n    type Result = Option<SignatureHelp>;\n    const METHOD: &'static str = \"textDocument/signatureHelp\";\n}\n\n#[derive(Debug)]\npub enum GotoDeclaration {}\npub type GotoDeclarationParams = GotoDefinitionParams;\npub type GotoDeclarationResponse = GotoDefinitionResponse;\n\n/// The goto declaration request is sent from the client to the server to resolve the declaration location of\n/// a symbol at a given text document position.\nimpl Request for GotoDeclaration {\n    type Params = GotoDeclarationParams;\n    type Result = Option<GotoDeclarationResponse>;\n    const METHOD: &'static str = \"textDocument/declaration\";\n}\n\n/// The goto definition request is sent from the client to the server to resolve the definition location of\n/// a symbol at a given text document position.\n#[derive(Debug)]\npub enum GotoDefinition {}\n\nimpl Request for GotoDefinition {\n    type Params = GotoDefinitionParams;\n    type Result = Option<GotoDefinitionResponse>;\n    const METHOD: &'static str = \"textDocument/definition\";\n}\n\n/// The references request is sent from the client to the server to resolve project-wide references for the\n/// symbol denoted by the given text document position.\n#[derive(Debug)]\npub enum References {}\n\nimpl Request for References {\n    type Params = ReferenceParams;\n    type Result = Option<Vec<Location>>;\n    const METHOD: &'static str = \"textDocument/references\";\n}\n\n/// The goto type definition request is sent from the client to the\n/// server to resolve the type definition location of a symbol at a\n/// given text document position.\n#[derive(Debug)]\npub enum GotoTypeDefinition {}\n\npub type GotoTypeDefinitionParams = GotoDefinitionParams;\npub type GotoTypeDefinitionResponse = GotoDefinitionResponse;\n\nimpl Request for GotoTypeDefinition {\n    type Params = GotoTypeDefinitionParams;\n    type Result = Option<GotoTypeDefinitionResponse>;\n    const METHOD: &'static str = \"textDocument/typeDefinition\";\n}\n\n/// The goto implementation request is sent from the client to the\n/// server to resolve the implementation location of a symbol at a\n/// given text document position.\n#[derive(Debug)]\npub enum GotoImplementation {}\n\npub type GotoImplementationParams = GotoTypeDefinitionParams;\npub type GotoImplementationResponse = GotoDefinitionResponse;\n\nimpl Request for GotoImplementation {\n    type Params = GotoImplementationParams;\n    type Result = Option<GotoImplementationResponse>;\n    const METHOD: &'static str = \"textDocument/implementation\";\n}\n\n/// The document highlight request is sent from the client to the server to resolve a document highlights\n/// for a given text document position.\n/// For programming languages this usually highlights all references to the symbol scoped to this file.\n/// However we kept 'textDocument/documentHighlight' and 'textDocument/references' separate requests since\n/// the first one is allowed to be more fuzzy.\n/// Symbol matches usually have a DocumentHighlightKind of Read or Write whereas fuzzy or textual matches\n/// use Text as the kind.\n#[derive(Debug)]\npub enum DocumentHighlightRequest {}\n\nimpl Request for DocumentHighlightRequest {\n    type Params = DocumentHighlightParams;\n    type Result = Option<Vec<DocumentHighlight>>;\n    const METHOD: &'static str = \"textDocument/documentHighlight\";\n}\n\n/// The document symbol request is sent from the client to the server to list all symbols found in a given\n/// text document.\n#[derive(Debug)]\npub enum DocumentSymbolRequest {}\n\nimpl Request for DocumentSymbolRequest {\n    type Params = DocumentSymbolParams;\n    type Result = Option<DocumentSymbolResponse>;\n    const METHOD: &'static str = \"textDocument/documentSymbol\";\n}\n\n/// The workspace symbol request is sent from the client to the server to list project-wide symbols\n/// matching the query string.\n#[derive(Debug)]\npub enum WorkspaceSymbolRequest {}\n\nimpl Request for WorkspaceSymbolRequest {\n    type Params = WorkspaceSymbolParams;\n    type Result = Option<WorkspaceSymbolResponse>;\n    const METHOD: &'static str = \"workspace/symbol\";\n}\n\n/// The `workspaceSymbol/resolve` request is sent from the client to the server to resolve\n/// additional information for a given workspace symbol.\n#[derive(Debug)]\npub enum WorkspaceSymbolResolve {}\n\nimpl Request for WorkspaceSymbolResolve {\n    type Params = WorkspaceSymbol;\n    type Result = WorkspaceSymbol;\n    const METHOD: &'static str = \"workspaceSymbol/resolve\";\n}\n\n/// The workspace/executeCommand request is sent from the client to the server to trigger command execution on the server.\n/// In most cases the server creates a WorkspaceEdit structure and applies the changes to the workspace using the request\n/// workspace/applyEdit which is sent from the server to the client.\n#[derive(Debug)]\npub enum ExecuteCommand {}\n\nimpl Request for ExecuteCommand {\n    type Params = ExecuteCommandParams;\n    type Result = Option<Value>;\n    const METHOD: &'static str = \"workspace/executeCommand\";\n}\n\n/// The document will save request is sent from the client to the server before the document is\n/// actually saved. The request can return an array of TextEdits which will be applied to the text\n/// document before it is saved. Please note that clients might drop results if computing the text\n/// edits took too long or if a server constantly fails on this request. This is done to keep the\n/// save fast and reliable.\n#[derive(Debug)]\npub enum WillSaveWaitUntil {}\n\nimpl Request for WillSaveWaitUntil {\n    type Params = WillSaveTextDocumentParams;\n    type Result = Option<Vec<TextEdit>>;\n    const METHOD: &'static str = \"textDocument/willSaveWaitUntil\";\n}\n\n/// The workspace/applyEdit request is sent from the server to the client to modify resource on the\n/// client side.\n#[derive(Debug)]\npub enum ApplyWorkspaceEdit {}\n\nimpl Request for ApplyWorkspaceEdit {\n    type Params = ApplyWorkspaceEditParams;\n    type Result = ApplyWorkspaceEditResponse;\n    const METHOD: &'static str = \"workspace/applyEdit\";\n}\n\n/// The workspace/configuration request is sent from the server to the client to fetch configuration settings\n/// from the client. The request can fetch several configuration settings in one roundtrip.\n/// The order of the returned configuration settings correspond to the order of the passed ConfigurationItems\n/// (e.g. the first item in the response is the result for the first configuration item in the params).\n///\n/// A ConfigurationItem consists of the configuration section to ask for and an additional scope URI.\n/// The configuration section ask for is defined by the server and doesn’t necessarily need to correspond to\n/// the configuration store used be the client. So a server might ask for a configuration cpp.formatterOptions\n/// but the client stores the configuration in a XML store layout differently.\n/// It is up to the client to do the necessary conversion. If a scope URI is provided the client should return\n/// the setting scoped to the provided resource. If the client for example uses EditorConfig to manage its\n/// settings the configuration should be returned for the passed resource URI. If the client can’t provide a\n/// configuration setting for a given scope then null need to be present in the returned array.\n#[derive(Debug)]\npub enum WorkspaceConfiguration {}\n\nimpl Request for WorkspaceConfiguration {\n    type Params = ConfigurationParams;\n    type Result = Vec<Value>;\n    const METHOD: &'static str = \"workspace/configuration\";\n}\n\n/// The code action request is sent from the client to the server to compute commands for a given text document\n/// and range. The request is triggered when the user moves the cursor into a problem marker in the editor or\n/// presses the lightbulb associated with a marker.\n#[derive(Debug)]\npub enum CodeActionRequest {}\n\nimpl Request for CodeActionRequest {\n    type Params = CodeActionParams;\n    type Result = Option<CodeActionResponse>;\n    const METHOD: &'static str = \"textDocument/codeAction\";\n}\n\n/// The request is sent from the client to the server to resolve additional information for a given code action.\n/// This is usually used to compute the `edit` property of a code action to avoid its unnecessary computation\n/// during the `textDocument/codeAction` request.\n///\n/// @since 3.16.0\n#[derive(Debug)]\npub enum CodeActionResolveRequest {}\n\nimpl Request for CodeActionResolveRequest {\n    type Params = CodeAction;\n    type Result = CodeAction;\n    const METHOD: &'static str = \"codeAction/resolve\";\n}\n\n/// The code lens request is sent from the client to the server to compute code lenses for a given text document.\n#[derive(Debug)]\npub enum CodeLensRequest {}\n\nimpl Request for CodeLensRequest {\n    type Params = CodeLensParams;\n    type Result = Option<Vec<CodeLens>>;\n    const METHOD: &'static str = \"textDocument/codeLens\";\n}\n\n/// The code lens resolve request is sent from the client to the server to resolve the command for a\n/// given code lens item.\n#[derive(Debug)]\npub enum CodeLensResolve {}\n\nimpl Request for CodeLensResolve {\n    type Params = CodeLens;\n    type Result = CodeLens;\n    const METHOD: &'static str = \"codeLens/resolve\";\n}\n\n/// The document links request is sent from the client to the server to request the location of links in a document.\n#[derive(Debug)]\npub enum DocumentLinkRequest {}\n\nimpl Request for DocumentLinkRequest {\n    type Params = DocumentLinkParams;\n    type Result = Option<Vec<DocumentLink>>;\n    const METHOD: &'static str = \"textDocument/documentLink\";\n}\n\n/// The document link resolve request is sent from the client to the server to resolve the target of\n/// a given document link.\n#[derive(Debug)]\npub enum DocumentLinkResolve {}\n\nimpl Request for DocumentLinkResolve {\n    type Params = DocumentLink;\n    type Result = DocumentLink;\n    const METHOD: &'static str = \"documentLink/resolve\";\n}\n\n/// The document formatting request is sent from the server to the client to format a whole document.\n#[derive(Debug)]\npub enum Formatting {}\n\nimpl Request for Formatting {\n    type Params = DocumentFormattingParams;\n    type Result = Option<Vec<TextEdit>>;\n    const METHOD: &'static str = \"textDocument/formatting\";\n}\n\n/// The document range formatting request is sent from the client to the server to format a given range in a document.\n#[derive(Debug)]\npub enum RangeFormatting {}\n\nimpl Request for RangeFormatting {\n    type Params = DocumentRangeFormattingParams;\n    type Result = Option<Vec<TextEdit>>;\n    const METHOD: &'static str = \"textDocument/rangeFormatting\";\n}\n\n/// The document on type formatting request is sent from the client to the server to format parts of\n/// the document during typing.\n#[derive(Debug)]\npub enum OnTypeFormatting {}\n\nimpl Request for OnTypeFormatting {\n    type Params = DocumentOnTypeFormattingParams;\n    type Result = Option<Vec<TextEdit>>;\n    const METHOD: &'static str = \"textDocument/onTypeFormatting\";\n}\n\n/// The linked editing request is sent from the client to the server to return for a given position in a document\n/// the range of the symbol at the position and all ranges that have the same content.\n/// Optionally a word pattern can be returned to describe valid contents. A rename to one of the ranges can be applied\n/// to all other ranges if the new content is valid. If no result-specific word pattern is provided, the word pattern from\n/// the client’s language configuration is used.\n#[derive(Debug)]\npub enum LinkedEditingRange {}\n\nimpl Request for LinkedEditingRange {\n    type Params = LinkedEditingRangeParams;\n    type Result = Option<LinkedEditingRanges>;\n    const METHOD: &'static str = \"textDocument/linkedEditingRange\";\n}\n\n/// The rename request is sent from the client to the server to perform a workspace-wide rename of a symbol.\n#[derive(Debug)]\npub enum Rename {}\n\nimpl Request for Rename {\n    type Params = RenameParams;\n    type Result = Option<WorkspaceEdit>;\n    const METHOD: &'static str = \"textDocument/rename\";\n}\n\n/// The document color request is sent from the client to the server to list all color references found in a given text document.\n/// Along with the range, a color value in RGB is returned.\n#[derive(Debug)]\npub enum DocumentColor {}\n\nimpl Request for DocumentColor {\n    type Params = DocumentColorParams;\n    type Result = Vec<ColorInformation>;\n    const METHOD: &'static str = \"textDocument/documentColor\";\n}\n\n/// The color presentation request is sent from the client to the server to obtain a list of presentations for a color value\n/// at a given location.\n#[derive(Debug)]\npub enum ColorPresentationRequest {}\n\nimpl Request for ColorPresentationRequest {\n    type Params = ColorPresentationParams;\n    type Result = Vec<ColorPresentation>;\n    const METHOD: &'static str = \"textDocument/colorPresentation\";\n}\n\n/// The folding range request is sent from the client to the server to return all folding ranges found in a given text document.\n#[derive(Debug)]\npub enum FoldingRangeRequest {}\n\nimpl Request for FoldingRangeRequest {\n    type Params = FoldingRangeParams;\n    type Result = Option<Vec<FoldingRange>>;\n    const METHOD: &'static str = \"textDocument/foldingRange\";\n}\n\n/// The prepare rename request is sent from the client to the server to setup and test the validity of a rename operation\n/// at a given location.\n#[derive(Debug)]\npub enum PrepareRenameRequest {}\n\nimpl Request for PrepareRenameRequest {\n    type Params = TextDocumentPositionParams;\n    type Result = Option<PrepareRenameResponse>;\n    const METHOD: &'static str = \"textDocument/prepareRename\";\n}\n\n#[derive(Debug)]\n#[cfg(feature = \"proposed\")]\npub enum InlineCompletionRequest {}\n\n#[cfg(feature = \"proposed\")]\nimpl Request for InlineCompletionRequest {\n    type Params = InlineCompletionParams;\n    type Result = Option<InlineCompletionResponse>;\n    const METHOD: &'static str = \"textDocument/inlineCompletion\";\n}\n\n/// The workspace/workspaceFolders request is sent from the server to the client to fetch the current open list of\n/// workspace folders. Returns null in the response if only a single file is open in the tool.\n/// Returns an empty array if a workspace is open but no folders are configured.\n#[derive(Debug)]\npub enum WorkspaceFoldersRequest {}\n\nimpl Request for WorkspaceFoldersRequest {\n    type Params = ();\n    type Result = Option<Vec<WorkspaceFolder>>;\n    const METHOD: &'static str = \"workspace/workspaceFolders\";\n}\n\n/// The `window/workDoneProgress/create` request is sent from the server\n/// to the client to ask the client to create a work done progress.\n#[derive(Debug)]\npub enum WorkDoneProgressCreate {}\n\nimpl Request for WorkDoneProgressCreate {\n    type Params = WorkDoneProgressCreateParams;\n    type Result = ();\n    const METHOD: &'static str = \"window/workDoneProgress/create\";\n}\n\n/// The selection range request is sent from the client to the server to return\n/// suggested selection ranges at given positions. A selection range is a range\n/// around the cursor position which the user might be interested in selecting.\n///\n/// A selection range in the return array is for the position in the provided parameters at the same index.\n/// Therefore `positions[i]` must be contained in `result[i].range`.\n///\n/// Typically, but not necessary, selection ranges correspond to the nodes of the\n/// syntax tree.\npub enum SelectionRangeRequest {}\n\nimpl Request for SelectionRangeRequest {\n    type Params = SelectionRangeParams;\n    type Result = Option<Vec<SelectionRange>>;\n    const METHOD: &'static str = \"textDocument/selectionRange\";\n}\n\npub enum CallHierarchyPrepare {}\n\nimpl Request for CallHierarchyPrepare {\n    type Params = CallHierarchyPrepareParams;\n    type Result = Option<Vec<CallHierarchyItem>>;\n    const METHOD: &'static str = \"textDocument/prepareCallHierarchy\";\n}\n\npub enum CallHierarchyIncomingCalls {}\n\nimpl Request for CallHierarchyIncomingCalls {\n    type Params = CallHierarchyIncomingCallsParams;\n    type Result = Option<Vec<CallHierarchyIncomingCall>>;\n    const METHOD: &'static str = \"callHierarchy/incomingCalls\";\n}\n\npub enum CallHierarchyOutgoingCalls {}\n\nimpl Request for CallHierarchyOutgoingCalls {\n    type Params = CallHierarchyOutgoingCallsParams;\n    type Result = Option<Vec<CallHierarchyOutgoingCall>>;\n    const METHOD: &'static str = \"callHierarchy/outgoingCalls\";\n}\n\npub enum SemanticTokensFullRequest {}\n\nimpl Request for SemanticTokensFullRequest {\n    type Params = SemanticTokensParams;\n    type Result = Option<SemanticTokensResult>;\n    const METHOD: &'static str = \"textDocument/semanticTokens/full\";\n}\n\npub enum SemanticTokensFullDeltaRequest {}\n\nimpl Request for SemanticTokensFullDeltaRequest {\n    type Params = SemanticTokensDeltaParams;\n    type Result = Option<SemanticTokensFullDeltaResult>;\n    const METHOD: &'static str = \"textDocument/semanticTokens/full/delta\";\n}\n\npub enum SemanticTokensRangeRequest {}\n\nimpl Request for SemanticTokensRangeRequest {\n    type Params = SemanticTokensRangeParams;\n    type Result = Option<SemanticTokensRangeResult>;\n    const METHOD: &'static str = \"textDocument/semanticTokens/range\";\n}\n\n/// The `workspace/semanticTokens/refresh` request is sent from the server to the client.\n/// Servers can use it to ask clients to refresh the editors for which this server provides semantic tokens.\n/// As a result the client should ask the server to recompute the semantic tokens for these editors.\n/// This is useful if a server detects a project wide configuration change which requires a re-calculation of all semantic tokens.\n/// Note that the client still has the freedom to delay the re-calculation of the semantic tokens if for example an editor is currently not visible.\npub enum SemanticTokensRefresh {}\n\nimpl Request for SemanticTokensRefresh {\n    type Params = ();\n    type Result = ();\n    const METHOD: &'static str = \"workspace/semanticTokens/refresh\";\n}\n\n/// The workspace/codeLens/refresh request is sent from the server to the client.\n/// Servers can use it to ask clients to refresh the code lenses currently shown in editors.\n/// As a result the client should ask the server to recompute the code lenses for these editors.\n/// This is useful if a server detects a configuration change which requires a re-calculation of all code lenses.\n/// Note that the client still has the freedom to delay the re-calculation of the code lenses if for example an editor is currently not visible.\npub enum CodeLensRefresh {}\n\nimpl Request for CodeLensRefresh {\n    type Params = ();\n    type Result = ();\n    const METHOD: &'static str = \"workspace/codeLens/refresh\";\n}\n\n/// The will create files request is sent from the client to the server before files are actually created as long as the creation is triggered from within the client. The request can return a WorkspaceEdit which will be applied to workspace before the files are created. Please note that clients might drop results if computing the edit took too long or if a server constantly fails on this request. This is done to keep creates fast and reliable.\npub enum WillCreateFiles {}\n\nimpl Request for WillCreateFiles {\n    type Params = CreateFilesParams;\n    type Result = Option<WorkspaceEdit>;\n    const METHOD: &'static str = \"workspace/willCreateFiles\";\n}\n\n/// The will rename files request is sent from the client to the server before files are actually renamed as long as the rename is triggered from within the client. The request can return a WorkspaceEdit which will be applied to workspace before the files are renamed. Please note that clients might drop results if computing the edit took too long or if a server constantly fails on this request. This is done to keep renames fast and reliable.\npub enum WillRenameFiles {}\n\nimpl Request for WillRenameFiles {\n    type Params = RenameFilesParams;\n    type Result = Option<WorkspaceEdit>;\n    const METHOD: &'static str = \"workspace/willRenameFiles\";\n}\n\n/// The will delete files request is sent from the client to the server before files are actually deleted as long as the deletion is triggered from within the client. The request can return a WorkspaceEdit which will be applied to workspace before the files are deleted. Please note that clients might drop results if computing the edit took too long or if a server constantly fails on this request. This is done to keep deletes fast and reliable.\npub enum WillDeleteFiles {}\n\nimpl Request for WillDeleteFiles {\n    type Params = DeleteFilesParams;\n    type Result = Option<WorkspaceEdit>;\n    const METHOD: &'static str = \"workspace/willDeleteFiles\";\n}\n\n/// The show document request is sent from a server to a client to ask the client to display a particular document in the user interface.\npub enum ShowDocument {}\n\nimpl Request for ShowDocument {\n    type Params = ShowDocumentParams;\n    type Result = ShowDocumentResult;\n    const METHOD: &'static str = \"window/showDocument\";\n}\n\npub enum MonikerRequest {}\n\nimpl Request for MonikerRequest {\n    type Params = MonikerParams;\n    type Result = Option<Vec<Moniker>>;\n    const METHOD: &'static str = \"textDocument/moniker\";\n}\n\n/// The inlay hints request is sent from the client to the server to compute inlay hints for a given\n/// [text document, range] tuple that may be rendered in the editor in place with other text.\npub enum InlayHintRequest {}\n\nimpl Request for InlayHintRequest {\n    type Params = InlayHintParams;\n    type Result = Option<Vec<InlayHint>>;\n    const METHOD: &'static str = \"textDocument/inlayHint\";\n}\n\n/// The `inlayHint/resolve` request is sent from the client to the server to resolve additional\n/// information for a given inlay hint. This is usually used to compute the tooltip, location or\n/// command properties of a inlay hint’s label part to avoid its unnecessary computation during the\n/// `textDocument/inlayHint` request.\npub enum InlayHintResolveRequest {}\n\nimpl Request for InlayHintResolveRequest {\n    type Params = InlayHint;\n    type Result = InlayHint;\n    const METHOD: &'static str = \"inlayHint/resolve\";\n}\n\n/// The `workspace/inlayHint/refresh` request is sent from the server to the client. Servers can use\n/// it to ask clients to refresh the inlay hints currently shown in editors. As a result the client\n/// should ask the server to recompute the inlay hints for these editors. This is useful if a server\n/// detects a configuration change which requires a re-calculation of all inlay hints. Note that the\n/// client still has the freedom to delay the re-calculation of the inlay hints if for example an\n/// editor is currently not visible.\npub enum InlayHintRefreshRequest {}\n\nimpl Request for InlayHintRefreshRequest {\n    type Params = ();\n    type Result = ();\n    const METHOD: &'static str = \"workspace/inlayHint/refresh\";\n}\n\n/// The inline value request is sent from the client to the server to compute inline values for a\n/// given text document that may be rendered in the editor at the end of lines.\npub enum InlineValueRequest {}\n\nimpl Request for InlineValueRequest {\n    type Params = InlineValueParams;\n    type Result = Option<InlineValue>;\n    const METHOD: &'static str = \"textDocument/inlineValue\";\n}\n\n/// The `workspace/inlineValue/refresh` request is sent from the server to the client. Servers can\n/// use it to ask clients to refresh the inline values currently shown in editors. As a result the\n/// client should ask the server to recompute the inline values for these editors. This is useful if\n/// a server detects a configuration change which requires a re-calculation of all inline values.\n/// Note that the client still has the freedom to delay the re-calculation of the inline values if\n/// for example an editor is currently not visible.\npub enum InlineValueRefreshRequest {}\n\nimpl Request for InlineValueRefreshRequest {\n    type Params = ();\n    type Result = ();\n    const METHOD: &'static str = \"workspace/inlineValue/refresh\";\n}\n\n/// The text document diagnostic request is sent from the client to the server to ask the server to\n/// compute the diagnostics for a given document. As with other pull requests the server is asked\n/// to compute the diagnostics for the currently synced version of the document.\n#[derive(Debug)]\npub enum DocumentDiagnosticRequest {}\n\nimpl Request for DocumentDiagnosticRequest {\n    type Params = DocumentDiagnosticParams;\n    type Result = DocumentDiagnosticReportResult;\n    const METHOD: &'static str = \"textDocument/diagnostic\";\n}\n\n/// The workspace diagnostic request is sent from the client to the server to ask the server to\n/// compute workspace wide diagnostics which previously where pushed from the server to the client.\n/// In contrast to the document diagnostic request the workspace request can be long running and is\n/// not bound to a specific workspace or document state. If the client supports streaming for the\n/// workspace diagnostic pull it is legal to provide a document diagnostic report multiple times\n/// for the same document URI. The last one reported will win over previous reports.\n#[derive(Debug)]\npub enum WorkspaceDiagnosticRequest {}\n\nimpl Request for WorkspaceDiagnosticRequest {\n    type Params = WorkspaceDiagnosticParams;\n    const METHOD: &'static str = \"workspace/diagnostic\";\n    type Result = WorkspaceDiagnosticReportResult;\n}\n\n/// The `workspace/diagnostic/refresh` request is sent from the server to the client. Servers can\n/// use it to ask clients to refresh all needed document and workspace diagnostics. This is useful\n/// if a server detects a project wide configuration change which requires a re-calculation of all\n/// diagnostics.\n#[derive(Debug)]\npub enum WorkspaceDiagnosticRefresh {}\n\nimpl Request for WorkspaceDiagnosticRefresh {\n    type Params = ();\n    type Result = ();\n    const METHOD: &'static str = \"workspace/diagnostic/refresh\";\n}\n\n/// The type hierarchy request is sent from the client to the server to return a type hierarchy for\n/// the language element of given text document positions. Will return null if the server couldn’t\n/// infer a valid type from the position. The type hierarchy requests are executed in two steps:\n///\n/// 1. first a type hierarchy item is prepared for the given text document position.\n/// 2. for a type hierarchy item the supertype or subtype type hierarchy items are resolved.\npub enum TypeHierarchyPrepare {}\n\nimpl Request for TypeHierarchyPrepare {\n    type Params = TypeHierarchyPrepareParams;\n    type Result = Option<Vec<TypeHierarchyItem>>;\n    const METHOD: &'static str = \"textDocument/prepareTypeHierarchy\";\n}\n\n/// The `typeHierarchy/supertypes` request is sent from the client to the server to resolve the\n/// supertypes for a given type hierarchy item. Will return null if the server couldn’t infer a\n/// valid type from item in the params. The request doesn’t define its own client and server\n/// capabilities. It is only issued if a server registers for the\n/// `textDocument/prepareTypeHierarchy` request.\npub enum TypeHierarchySupertypes {}\n\nimpl Request for TypeHierarchySupertypes {\n    type Params = TypeHierarchySupertypesParams;\n    type Result = Option<Vec<TypeHierarchyItem>>;\n    const METHOD: &'static str = \"typeHierarchy/supertypes\";\n}\n\n/// The `typeHierarchy/subtypes` request is sent from the client to the server to resolve the\n/// subtypes for a given type hierarchy item. Will return null if the server couldn’t infer a valid\n/// type from item in the params. The request doesn’t define its own client and server capabilities.\n/// It is only issued if a server registers for the textDocument/prepareTypeHierarchy request.\npub enum TypeHierarchySubtypes {}\n\nimpl Request for TypeHierarchySubtypes {\n    type Params = TypeHierarchySubtypesParams;\n    type Result = Option<Vec<TypeHierarchyItem>>;\n    const METHOD: &'static str = \"typeHierarchy/subtypes\";\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    fn fake_call<R>()\n    where\n        R: Request,\n        R::Params: serde::Serialize,\n        R::Result: serde::de::DeserializeOwned,\n    {\n    }\n\n    macro_rules! check_macro {\n        ($name:tt) => {\n            // check whether the macro name matches the method\n            assert_eq!(<lsp_request!($name) as Request>::METHOD, $name);\n            // test whether type checking passes for each component\n            fake_call::<lsp_request!($name)>();\n        };\n    }\n\n    #[test]\n    fn check_macro_definitions() {\n        check_macro!(\"initialize\");\n        check_macro!(\"shutdown\");\n\n        check_macro!(\"window/showDocument\");\n        check_macro!(\"window/showMessageRequest\");\n        check_macro!(\"window/workDoneProgress/create\");\n\n        check_macro!(\"client/registerCapability\");\n        check_macro!(\"client/unregisterCapability\");\n\n        check_macro!(\"textDocument/willSaveWaitUntil\");\n        check_macro!(\"textDocument/completion\");\n        check_macro!(\"textDocument/hover\");\n        check_macro!(\"textDocument/signatureHelp\");\n        check_macro!(\"textDocument/declaration\");\n        check_macro!(\"textDocument/definition\");\n        check_macro!(\"textDocument/references\");\n        check_macro!(\"textDocument/documentHighlight\");\n        check_macro!(\"textDocument/documentSymbol\");\n        check_macro!(\"textDocument/codeAction\");\n        check_macro!(\"textDocument/codeLens\");\n        check_macro!(\"textDocument/documentLink\");\n        check_macro!(\"textDocument/rangeFormatting\");\n        check_macro!(\"textDocument/onTypeFormatting\");\n        check_macro!(\"textDocument/formatting\");\n        check_macro!(\"textDocument/rename\");\n        check_macro!(\"textDocument/documentColor\");\n        check_macro!(\"textDocument/colorPresentation\");\n        check_macro!(\"textDocument/foldingRange\");\n        check_macro!(\"textDocument/prepareRename\");\n        check_macro!(\"textDocument/implementation\");\n        check_macro!(\"textDocument/selectionRange\");\n        check_macro!(\"textDocument/typeDefinition\");\n        check_macro!(\"textDocument/moniker\");\n        check_macro!(\"textDocument/linkedEditingRange\");\n        check_macro!(\"textDocument/prepareCallHierarchy\");\n        check_macro!(\"textDocument/prepareTypeHierarchy\");\n        check_macro!(\"textDocument/semanticTokens/full\");\n        check_macro!(\"textDocument/semanticTokens/full/delta\");\n        check_macro!(\"textDocument/semanticTokens/range\");\n        check_macro!(\"textDocument/inlayHint\");\n        check_macro!(\"textDocument/inlineValue\");\n        check_macro!(\"textDocument/diagnostic\");\n\n        check_macro!(\"workspace/applyEdit\");\n        check_macro!(\"workspace/symbol\");\n        check_macro!(\"workspace/executeCommand\");\n        check_macro!(\"workspace/configuration\");\n        check_macro!(\"workspace/diagnostic\");\n        check_macro!(\"workspace/diagnostic/refresh\");\n        check_macro!(\"workspace/willCreateFiles\");\n        check_macro!(\"workspace/willRenameFiles\");\n        check_macro!(\"workspace/willDeleteFiles\");\n        check_macro!(\"workspace/workspaceFolders\");\n        check_macro!(\"workspace/semanticTokens/refresh\");\n        check_macro!(\"workspace/codeLens/refresh\");\n        check_macro!(\"workspace/inlayHint/refresh\");\n        check_macro!(\"workspace/inlineValue/refresh\");\n\n        check_macro!(\"callHierarchy/incomingCalls\");\n        check_macro!(\"callHierarchy/outgoingCalls\");\n        check_macro!(\"codeAction/resolve\");\n        check_macro!(\"codeLens/resolve\");\n        check_macro!(\"completionItem/resolve\");\n        check_macro!(\"documentLink/resolve\");\n        check_macro!(\"inlayHint/resolve\");\n        check_macro!(\"typeHierarchy/subtypes\");\n        check_macro!(\"typeHierarchy/supertypes\");\n        check_macro!(\"workspaceSymbol/resolve\");\n    }\n\n    #[test]\n    #[cfg(feature = \"proposed\")]\n    fn check_proposed_macro_definitions() {}\n}\n"
  },
  {
    "path": "helix-lsp-types/src/selection_range.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::{\n    PartialResultParams, Position, Range, StaticTextDocumentRegistrationOptions,\n    TextDocumentIdentifier, WorkDoneProgressOptions, WorkDoneProgressParams,\n};\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SelectionRangeClientCapabilities {\n    /// Whether implementation supports dynamic registration for selection range\n    /// providers. If this is set to `true` the client supports the new\n    /// `SelectionRangeRegistrationOptions` return value for the corresponding\n    /// server capability as well.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct SelectionRangeOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct SelectionRangeRegistrationOptions {\n    #[serde(flatten)]\n    pub selection_range_options: SelectionRangeOptions,\n\n    #[serde(flatten)]\n    pub registration_options: StaticTextDocumentRegistrationOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum SelectionRangeProviderCapability {\n    Simple(bool),\n    Options(SelectionRangeOptions),\n    RegistrationOptions(SelectionRangeRegistrationOptions),\n}\n\nimpl From<SelectionRangeRegistrationOptions> for SelectionRangeProviderCapability {\n    fn from(from: SelectionRangeRegistrationOptions) -> Self {\n        Self::RegistrationOptions(from)\n    }\n}\n\nimpl From<SelectionRangeOptions> for SelectionRangeProviderCapability {\n    fn from(from: SelectionRangeOptions) -> Self {\n        Self::Options(from)\n    }\n}\n\nimpl From<bool> for SelectionRangeProviderCapability {\n    fn from(from: bool) -> Self {\n        Self::Simple(from)\n    }\n}\n\n/// A parameter literal used in selection range requests.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SelectionRangeParams {\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The positions inside the text document.\n    pub positions: Vec<Position>,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// Represents a selection range.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SelectionRange {\n    /// Range of the selection.\n    pub range: Range,\n\n    /// The parent selection range containing this range.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub parent: Option<Box<SelectionRange>>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/semantic_tokens.rs",
    "content": "use std::borrow::Cow;\n\nuse serde::ser::SerializeSeq;\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n    PartialResultParams, Range, StaticRegistrationOptions, TextDocumentIdentifier,\n    TextDocumentRegistrationOptions, WorkDoneProgressOptions, WorkDoneProgressParams,\n};\n/// A set of predefined token types. This set is not fixed\n/// and clients can specify additional token types via the\n/// corresponding client capabilities.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)]\npub struct SemanticTokenType(Cow<'static, str>);\n\nimpl SemanticTokenType {\n    pub const NAMESPACE: SemanticTokenType = SemanticTokenType::new(\"namespace\");\n    pub const TYPE: SemanticTokenType = SemanticTokenType::new(\"type\");\n    pub const CLASS: SemanticTokenType = SemanticTokenType::new(\"class\");\n    pub const ENUM: SemanticTokenType = SemanticTokenType::new(\"enum\");\n    pub const INTERFACE: SemanticTokenType = SemanticTokenType::new(\"interface\");\n    pub const STRUCT: SemanticTokenType = SemanticTokenType::new(\"struct\");\n    pub const TYPE_PARAMETER: SemanticTokenType = SemanticTokenType::new(\"typeParameter\");\n    pub const PARAMETER: SemanticTokenType = SemanticTokenType::new(\"parameter\");\n    pub const VARIABLE: SemanticTokenType = SemanticTokenType::new(\"variable\");\n    pub const PROPERTY: SemanticTokenType = SemanticTokenType::new(\"property\");\n    pub const ENUM_MEMBER: SemanticTokenType = SemanticTokenType::new(\"enumMember\");\n    pub const EVENT: SemanticTokenType = SemanticTokenType::new(\"event\");\n    pub const FUNCTION: SemanticTokenType = SemanticTokenType::new(\"function\");\n    pub const METHOD: SemanticTokenType = SemanticTokenType::new(\"method\");\n    pub const MACRO: SemanticTokenType = SemanticTokenType::new(\"macro\");\n    pub const KEYWORD: SemanticTokenType = SemanticTokenType::new(\"keyword\");\n    pub const MODIFIER: SemanticTokenType = SemanticTokenType::new(\"modifier\");\n    pub const COMMENT: SemanticTokenType = SemanticTokenType::new(\"comment\");\n    pub const STRING: SemanticTokenType = SemanticTokenType::new(\"string\");\n    pub const NUMBER: SemanticTokenType = SemanticTokenType::new(\"number\");\n    pub const REGEXP: SemanticTokenType = SemanticTokenType::new(\"regexp\");\n    pub const OPERATOR: SemanticTokenType = SemanticTokenType::new(\"operator\");\n\n    /// @since 3.17.0\n    pub const DECORATOR: SemanticTokenType = SemanticTokenType::new(\"decorator\");\n\n    pub const fn new(tag: &'static str) -> Self {\n        SemanticTokenType(Cow::Borrowed(tag))\n    }\n\n    pub fn as_str(&self) -> &str {\n        &self.0\n    }\n}\n\nimpl From<String> for SemanticTokenType {\n    fn from(from: String) -> Self {\n        SemanticTokenType(Cow::from(from))\n    }\n}\n\nimpl From<&'static str> for SemanticTokenType {\n    fn from(from: &'static str) -> Self {\n        SemanticTokenType::new(from)\n    }\n}\n\n/// A set of predefined token modifiers. This set is not fixed\n/// and clients can specify additional token types via the\n/// corresponding client capabilities.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)]\npub struct SemanticTokenModifier(Cow<'static, str>);\n\nimpl SemanticTokenModifier {\n    pub const DECLARATION: SemanticTokenModifier = SemanticTokenModifier::new(\"declaration\");\n    pub const DEFINITION: SemanticTokenModifier = SemanticTokenModifier::new(\"definition\");\n    pub const READONLY: SemanticTokenModifier = SemanticTokenModifier::new(\"readonly\");\n    pub const STATIC: SemanticTokenModifier = SemanticTokenModifier::new(\"static\");\n    pub const DEPRECATED: SemanticTokenModifier = SemanticTokenModifier::new(\"deprecated\");\n    pub const ABSTRACT: SemanticTokenModifier = SemanticTokenModifier::new(\"abstract\");\n    pub const ASYNC: SemanticTokenModifier = SemanticTokenModifier::new(\"async\");\n    pub const MODIFICATION: SemanticTokenModifier = SemanticTokenModifier::new(\"modification\");\n    pub const DOCUMENTATION: SemanticTokenModifier = SemanticTokenModifier::new(\"documentation\");\n    pub const DEFAULT_LIBRARY: SemanticTokenModifier = SemanticTokenModifier::new(\"defaultLibrary\");\n\n    pub const fn new(tag: &'static str) -> Self {\n        SemanticTokenModifier(Cow::Borrowed(tag))\n    }\n\n    pub fn as_str(&self) -> &str {\n        &self.0\n    }\n}\n\nimpl From<String> for SemanticTokenModifier {\n    fn from(from: String) -> Self {\n        SemanticTokenModifier(Cow::from(from))\n    }\n}\n\nimpl From<&'static str> for SemanticTokenModifier {\n    fn from(from: &'static str) -> Self {\n        SemanticTokenModifier::new(from)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)]\npub struct TokenFormat(Cow<'static, str>);\n\nimpl TokenFormat {\n    pub const RELATIVE: TokenFormat = TokenFormat::new(\"relative\");\n\n    pub const fn new(tag: &'static str) -> Self {\n        TokenFormat(Cow::Borrowed(tag))\n    }\n\n    pub fn as_str(&self) -> &str {\n        &self.0\n    }\n}\n\nimpl From<String> for TokenFormat {\n    fn from(from: String) -> Self {\n        TokenFormat(Cow::from(from))\n    }\n}\n\nimpl From<&'static str> for TokenFormat {\n    fn from(from: &'static str) -> Self {\n        TokenFormat::new(from)\n    }\n}\n\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensLegend {\n    /// The token types a server uses.\n    pub token_types: Vec<SemanticTokenType>,\n\n    /// The token modifiers a server uses.\n    pub token_modifiers: Vec<SemanticTokenModifier>,\n}\n\n/// The actual tokens.\n#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)]\npub struct SemanticToken {\n    pub delta_line: u32,\n    pub delta_start: u32,\n    pub length: u32,\n    pub token_type: u32,\n    pub token_modifiers_bitset: u32,\n}\n\nimpl SemanticToken {\n    fn deserialize_tokens<'de, D>(deserializer: D) -> Result<Vec<SemanticToken>, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        let data = Vec::<u32>::deserialize(deserializer)?;\n        let chunks = data.chunks_exact(5);\n\n        if !chunks.remainder().is_empty() {\n            return Result::Err(serde::de::Error::custom(\"Length is not divisible by 5\"));\n        }\n\n        Result::Ok(\n            chunks\n                .map(|chunk| SemanticToken {\n                    delta_line: chunk[0],\n                    delta_start: chunk[1],\n                    length: chunk[2],\n                    token_type: chunk[3],\n                    token_modifiers_bitset: chunk[4],\n                })\n                .collect(),\n        )\n    }\n\n    fn serialize_tokens<S>(tokens: &[SemanticToken], serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        let mut seq = serializer.serialize_seq(Some(tokens.len() * 5))?;\n        for token in tokens.iter() {\n            seq.serialize_element(&token.delta_line)?;\n            seq.serialize_element(&token.delta_start)?;\n            seq.serialize_element(&token.length)?;\n            seq.serialize_element(&token.token_type)?;\n            seq.serialize_element(&token.token_modifiers_bitset)?;\n        }\n        seq.end()\n    }\n\n    fn deserialize_tokens_opt<'de, D>(\n        deserializer: D,\n    ) -> Result<Option<Vec<SemanticToken>>, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        #[derive(Deserialize)]\n        #[serde(transparent)]\n        struct Wrapper {\n            #[serde(deserialize_with = \"SemanticToken::deserialize_tokens\")]\n            tokens: Vec<SemanticToken>,\n        }\n\n        Ok(Option::<Wrapper>::deserialize(deserializer)?.map(|wrapper| wrapper.tokens))\n    }\n\n    fn serialize_tokens_opt<S>(\n        data: &Option<Vec<SemanticToken>>,\n        serializer: S,\n    ) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        #[derive(Serialize)]\n        #[serde(transparent)]\n        struct Wrapper {\n            #[serde(serialize_with = \"SemanticToken::serialize_tokens\")]\n            tokens: Vec<SemanticToken>,\n        }\n\n        let opt = data.as_ref().map(|t| Wrapper { tokens: t.to_vec() });\n\n        opt.serialize(serializer)\n    }\n}\n\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokens {\n    /// An optional result id. If provided and clients support delta updating\n    /// the client will include the result id in the next semantic token request.\n    /// A server can then instead of computing all semantic tokens again simply\n    /// send a delta.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub result_id: Option<String>,\n\n    /// The actual tokens. For a detailed description about how the data is\n    /// structured please see\n    /// <https://github.com/microsoft/vscode-extension-samples/blob/5ae1f7787122812dcc84e37427ca90af5ee09f14/semantic-tokens-sample/vscode.proposed.d.ts#L71>\n    #[serde(\n        deserialize_with = \"SemanticToken::deserialize_tokens\",\n        serialize_with = \"SemanticToken::serialize_tokens\"\n    )]\n    pub data: Vec<SemanticToken>,\n}\n\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensPartialResult {\n    #[serde(\n        deserialize_with = \"SemanticToken::deserialize_tokens\",\n        serialize_with = \"SemanticToken::serialize_tokens\"\n    )]\n    pub data: Vec<SemanticToken>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(untagged)]\npub enum SemanticTokensResult {\n    Tokens(SemanticTokens),\n    Partial(SemanticTokensPartialResult),\n}\n\nimpl From<SemanticTokens> for SemanticTokensResult {\n    fn from(from: SemanticTokens) -> Self {\n        SemanticTokensResult::Tokens(from)\n    }\n}\n\nimpl From<SemanticTokensPartialResult> for SemanticTokensResult {\n    fn from(from: SemanticTokensPartialResult) -> Self {\n        SemanticTokensResult::Partial(from)\n    }\n}\n\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensEdit {\n    pub start: u32,\n    pub delete_count: u32,\n\n    #[serde(\n        default,\n        skip_serializing_if = \"Option::is_none\",\n        deserialize_with = \"SemanticToken::deserialize_tokens_opt\",\n        serialize_with = \"SemanticToken::serialize_tokens_opt\"\n    )]\n    pub data: Option<Vec<SemanticToken>>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(untagged)]\npub enum SemanticTokensFullDeltaResult {\n    Tokens(SemanticTokens),\n    TokensDelta(SemanticTokensDelta),\n    PartialTokensDelta { edits: Vec<SemanticTokensEdit> },\n}\n\nimpl From<SemanticTokens> for SemanticTokensFullDeltaResult {\n    fn from(from: SemanticTokens) -> Self {\n        SemanticTokensFullDeltaResult::Tokens(from)\n    }\n}\n\nimpl From<SemanticTokensDelta> for SemanticTokensFullDeltaResult {\n    fn from(from: SemanticTokensDelta) -> Self {\n        SemanticTokensFullDeltaResult::TokensDelta(from)\n    }\n}\n\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensDelta {\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub result_id: Option<String>,\n    /// For a detailed description how these edits are structured please see\n    /// <https://github.com/microsoft/vscode-extension-samples/blob/5ae1f7787122812dcc84e37427ca90af5ee09f14/semantic-tokens-sample/vscode.proposed.d.ts#L131>\n    pub edits: Vec<SemanticTokensEdit>,\n}\n\n/// Capabilities specific to the `textDocument/semanticTokens/*` requests.\n///\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensClientCapabilities {\n    /// Whether implementation supports dynamic registration. If this is set to `true`\n    /// the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`\n    /// return value for the corresponding server capability as well.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// Which requests the client supports and might send to the server\n    /// depending on the server's capability. Please note that clients might not\n    /// show semantic tokens or degrade some of the user experience if a range\n    /// or full request is advertised by the client but not provided by the\n    /// server. If for example the client capability `requests.full` and\n    /// `request.range` are both set to true but the server only provides a\n    /// range provider the client might not render a minimap correctly or might\n    /// even decide to not show any semantic tokens at all.\n    pub requests: SemanticTokensClientCapabilitiesRequests,\n\n    /// The token types that the client supports.\n    pub token_types: Vec<SemanticTokenType>,\n\n    /// The token modifiers that the client supports.\n    pub token_modifiers: Vec<SemanticTokenModifier>,\n\n    /// The token formats the clients supports.\n    pub formats: Vec<TokenFormat>,\n\n    /// Whether the client supports tokens that can overlap each other.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub overlapping_token_support: Option<bool>,\n\n    /// Whether the client supports tokens that can span multiple lines.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub multiline_token_support: Option<bool>,\n\n    /// Whether the client allows the server to actively cancel a\n    /// semantic token request, e.g. supports returning\n    /// ErrorCodes.ServerCancelled. If a server does the client\n    /// needs to retrigger the request.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub server_cancel_support: Option<bool>,\n\n    /// Whether the client uses semantic tokens to augment existing\n    /// syntax tokens. If set to `true` client side created syntax\n    /// tokens and semantic tokens are both used for colorization. If\n    /// set to `false` the client only uses the returned semantic tokens\n    /// for colorization.\n    ///\n    /// If the value is `undefined` then the client behavior is not\n    /// specified.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub augments_syntax_tokens: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensClientCapabilitiesRequests {\n    /// The client will send the `textDocument/semanticTokens/range` request if the server provides a corresponding handler.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub range: Option<bool>,\n\n    /// The client will send the `textDocument/semanticTokens/full` request if the server provides a corresponding handler.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub full: Option<SemanticTokensFullOptions>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(untagged)]\npub enum SemanticTokensFullOptions {\n    Bool(bool),\n    Delta {\n        /// The client will send the `textDocument/semanticTokens/full/delta` request if the server provides a corresponding handler.\n        /// The server supports deltas for full documents.\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        delta: Option<bool>,\n    },\n}\n\n/// @since 3.16.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n\n    /// The legend used by the server\n    pub legend: SemanticTokensLegend,\n\n    /// Server supports providing semantic tokens for a specific range\n    /// of a document.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub range: Option<bool>,\n\n    /// Server supports providing semantic tokens for a full document.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub full: Option<SemanticTokensFullOptions>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensRegistrationOptions {\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n\n    #[serde(flatten)]\n    pub semantic_tokens_options: SemanticTokensOptions,\n\n    #[serde(flatten)]\n    pub static_registration_options: StaticRegistrationOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(untagged)]\npub enum SemanticTokensServerCapabilities {\n    SemanticTokensOptions(SemanticTokensOptions),\n    SemanticTokensRegistrationOptions(SemanticTokensRegistrationOptions),\n}\n\nimpl From<SemanticTokensOptions> for SemanticTokensServerCapabilities {\n    fn from(from: SemanticTokensOptions) -> Self {\n        SemanticTokensServerCapabilities::SemanticTokensOptions(from)\n    }\n}\n\nimpl From<SemanticTokensRegistrationOptions> for SemanticTokensServerCapabilities {\n    fn from(from: SemanticTokensRegistrationOptions) -> Self {\n        SemanticTokensServerCapabilities::SemanticTokensRegistrationOptions(from)\n    }\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensWorkspaceClientCapabilities {\n    /// Whether the client implementation supports a refresh request sent from\n    /// the server to the client.\n    ///\n    /// Note that this event is global and will force the client to refresh all\n    /// semantic tokens currently shown. It should be used with absolute care\n    /// and is useful for situation where a server for example detect a project\n    /// wide change that requires such a calculation.\n    pub refresh_support: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensParams {\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensDeltaParams {\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The result id of a previous response. The result Id can either point to a full response\n    /// or a delta response depending on what was received last.\n    pub previous_result_id: String,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SemanticTokensRangeParams {\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n\n    /// The text document.\n    pub text_document: TextDocumentIdentifier,\n\n    /// The range the semantic tokens are requested for.\n    pub range: Range,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\n#[serde(untagged)]\npub enum SemanticTokensRangeResult {\n    Tokens(SemanticTokens),\n    Partial(SemanticTokensPartialResult),\n}\n\nimpl From<SemanticTokens> for SemanticTokensRangeResult {\n    fn from(tokens: SemanticTokens) -> Self {\n        SemanticTokensRangeResult::Tokens(tokens)\n    }\n}\n\nimpl From<SemanticTokensPartialResult> for SemanticTokensRangeResult {\n    fn from(partial: SemanticTokensPartialResult) -> Self {\n        SemanticTokensRangeResult::Partial(partial)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::tests::{test_deserialization, test_serialization};\n\n    #[test]\n    fn test_semantic_tokens_support_serialization() {\n        test_serialization(\n            &SemanticTokens {\n                result_id: None,\n                data: vec![],\n            },\n            r#\"{\"data\":[]}\"#,\n        );\n\n        test_serialization(\n            &SemanticTokens {\n                result_id: None,\n                data: vec![SemanticToken {\n                    delta_line: 2,\n                    delta_start: 5,\n                    length: 3,\n                    token_type: 0,\n                    token_modifiers_bitset: 3,\n                }],\n            },\n            r#\"{\"data\":[2,5,3,0,3]}\"#,\n        );\n\n        test_serialization(\n            &SemanticTokens {\n                result_id: None,\n                data: vec![\n                    SemanticToken {\n                        delta_line: 2,\n                        delta_start: 5,\n                        length: 3,\n                        token_type: 0,\n                        token_modifiers_bitset: 3,\n                    },\n                    SemanticToken {\n                        delta_line: 0,\n                        delta_start: 5,\n                        length: 4,\n                        token_type: 1,\n                        token_modifiers_bitset: 0,\n                    },\n                ],\n            },\n            r#\"{\"data\":[2,5,3,0,3,0,5,4,1,0]}\"#,\n        );\n    }\n\n    #[test]\n    fn test_semantic_tokens_support_deserialization() {\n        test_deserialization(\n            r#\"{\"data\":[]}\"#,\n            &SemanticTokens {\n                result_id: None,\n                data: vec![],\n            },\n        );\n\n        test_deserialization(\n            r#\"{\"data\":[2,5,3,0,3]}\"#,\n            &SemanticTokens {\n                result_id: None,\n                data: vec![SemanticToken {\n                    delta_line: 2,\n                    delta_start: 5,\n                    length: 3,\n                    token_type: 0,\n                    token_modifiers_bitset: 3,\n                }],\n            },\n        );\n\n        test_deserialization(\n            r#\"{\"data\":[2,5,3,0,3,0,5,4,1,0]}\"#,\n            &SemanticTokens {\n                result_id: None,\n                data: vec![\n                    SemanticToken {\n                        delta_line: 2,\n                        delta_start: 5,\n                        length: 3,\n                        token_type: 0,\n                        token_modifiers_bitset: 3,\n                    },\n                    SemanticToken {\n                        delta_line: 0,\n                        delta_start: 5,\n                        length: 4,\n                        token_type: 1,\n                        token_modifiers_bitset: 0,\n                    },\n                ],\n            },\n        );\n    }\n\n    #[test]\n    #[should_panic]\n    fn test_semantic_tokens_support_deserialization_err() {\n        test_deserialization(\n            r#\"{\"data\":[1]}\"#,\n            &SemanticTokens {\n                result_id: None,\n                data: vec![],\n            },\n        );\n    }\n\n    #[test]\n    fn test_semantic_tokens_edit_support_deserialization() {\n        test_deserialization(\n            r#\"{\"start\":0,\"deleteCount\":1,\"data\":[2,5,3,0,3,0,5,4,1,0]}\"#,\n            &SemanticTokensEdit {\n                start: 0,\n                delete_count: 1,\n                data: Some(vec![\n                    SemanticToken {\n                        delta_line: 2,\n                        delta_start: 5,\n                        length: 3,\n                        token_type: 0,\n                        token_modifiers_bitset: 3,\n                    },\n                    SemanticToken {\n                        delta_line: 0,\n                        delta_start: 5,\n                        length: 4,\n                        token_type: 1,\n                        token_modifiers_bitset: 0,\n                    },\n                ]),\n            },\n        );\n\n        test_deserialization(\n            r#\"{\"start\":0,\"deleteCount\":1}\"#,\n            &SemanticTokensEdit {\n                start: 0,\n                delete_count: 1,\n                data: None,\n            },\n        );\n    }\n\n    #[test]\n    fn test_semantic_tokens_edit_support_serialization() {\n        test_serialization(\n            &SemanticTokensEdit {\n                start: 0,\n                delete_count: 1,\n                data: Some(vec![\n                    SemanticToken {\n                        delta_line: 2,\n                        delta_start: 5,\n                        length: 3,\n                        token_type: 0,\n                        token_modifiers_bitset: 3,\n                    },\n                    SemanticToken {\n                        delta_line: 0,\n                        delta_start: 5,\n                        length: 4,\n                        token_type: 1,\n                        token_modifiers_bitset: 0,\n                    },\n                ]),\n            },\n            r#\"{\"start\":0,\"deleteCount\":1,\"data\":[2,5,3,0,3,0,5,4,1,0]}\"#,\n        );\n\n        test_serialization(\n            &SemanticTokensEdit {\n                start: 0,\n                delete_count: 1,\n                data: None,\n            },\n            r#\"{\"start\":0,\"deleteCount\":1}\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "helix-lsp-types/src/signature_help.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::{\n    Documentation, MarkupKind, TextDocumentPositionParams, TextDocumentRegistrationOptions,\n    WorkDoneProgressOptions, WorkDoneProgressParams,\n};\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SignatureInformationSettings {\n    /// Client supports the follow content formats for the documentation\n    /// property. The order describes the preferred format of the client.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub documentation_format: Option<Vec<MarkupKind>>,\n\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub parameter_information: Option<ParameterInformationSettings>,\n\n    /// The client support the `activeParameter` property on `SignatureInformation`\n    /// literal.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub active_parameter_support: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ParameterInformationSettings {\n    /// The client supports processing label offsets instead of a\n    /// simple label string.\n    ///\n    /// @since 3.14.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub label_offset_support: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SignatureHelpClientCapabilities {\n    /// Whether completion supports dynamic registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// The client supports the following `SignatureInformation`\n    /// specific properties.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub signature_information: Option<SignatureInformationSettings>,\n\n    /// The client supports to send additional context information for a\n    /// `textDocument/signatureHelp` request. A client that opts into\n    /// contextSupport will also support the `retriggerCharacters` on\n    /// `SignatureHelpOptions`.\n    ///\n    /// @since 3.15.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub context_support: Option<bool>,\n}\n\n/// Signature help options.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SignatureHelpOptions {\n    /// The characters that trigger signature help automatically.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub trigger_characters: Option<Vec<String>>,\n\n    /// List of characters that re-trigger signature help.\n    /// These trigger characters are only active when signature help is already showing. All trigger characters\n    /// are also counted as re-trigger characters.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub retrigger_characters: Option<Vec<String>>,\n\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n/// Signature help options.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct SignatureHelpRegistrationOptions {\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n}\n\n/// Signature help options.\n#[derive(Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct SignatureHelpTriggerKind(i32);\nlsp_enum! {\nimpl SignatureHelpTriggerKind {\n    /// Signature help was invoked manually by the user or by a command.\n    pub const INVOKED: SignatureHelpTriggerKind = SignatureHelpTriggerKind(1);\n    /// Signature help was triggered by a trigger character.\n    pub const TRIGGER_CHARACTER: SignatureHelpTriggerKind = SignatureHelpTriggerKind(2);\n    /// Signature help was triggered by the cursor moving or by the document content changing.\n    pub const CONTENT_CHANGE: SignatureHelpTriggerKind = SignatureHelpTriggerKind(3);\n}\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SignatureHelpParams {\n    /// The signature help context. This is only available if the client specifies\n    /// to send this using the client capability  `textDocument.signatureHelp.contextSupport === true`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub context: Option<SignatureHelpContext>,\n\n    #[serde(flatten)]\n    pub text_document_position_params: TextDocumentPositionParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SignatureHelpContext {\n    /// Action that caused signature help to be triggered.\n    pub trigger_kind: SignatureHelpTriggerKind,\n\n    /// Character that caused signature help to be triggered.\n    /// This is undefined when `triggerKind !== SignatureHelpTriggerKind.TriggerCharacter`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub trigger_character: Option<String>,\n\n    /// `true` if signature help was already showing when it was triggered.\n    /// Retriggers occur when the signature help is already active and can be caused by actions such as\n    /// typing a trigger character, a cursor move, or document content changes.\n    pub is_retrigger: bool,\n\n    /// The currently active `SignatureHelp`.\n    /// The `activeSignatureHelp` has its `SignatureHelp.activeSignature` field updated based on\n    /// the user navigating through available signatures.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub active_signature_help: Option<SignatureHelp>,\n}\n\n/// Signature help represents the signature of something\n/// callable. There can be multiple signature but only one\n/// active and only one active parameter.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SignatureHelp {\n    /// One or more signatures.\n    pub signatures: Vec<SignatureInformation>,\n\n    /// The active signature.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub active_signature: Option<u32>,\n\n    /// The active parameter of the active signature.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub active_parameter: Option<u32>,\n}\n\n/// Represents the signature of something callable. A signature\n/// can have a label, like a function-name, a doc-comment, and\n/// a set of parameters.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct SignatureInformation {\n    /// The label of this signature. Will be shown in\n    /// the UI.\n    pub label: String,\n\n    /// The human-readable doc-comment of this signature. Will be shown\n    /// in the UI but can be omitted.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub documentation: Option<Documentation>,\n\n    /// The parameters of this signature.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub parameters: Option<Vec<ParameterInformation>>,\n\n    /// The index of the active parameter.\n    ///\n    /// If provided, this is used in place of `SignatureHelp.activeParameter`.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub active_parameter: Option<u32>,\n}\n\n/// Represents a parameter of a callable-signature. A parameter can\n/// have a label and a doc-comment.\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ParameterInformation {\n    /// The label of this parameter information.\n    ///\n    /// Either a string or an inclusive start and exclusive end offsets within its containing\n    /// signature label. (see SignatureInformation.label). *Note*: A label of type string must be\n    /// a substring of its containing signature label.\n    pub label: ParameterLabel,\n\n    /// The human-readable doc-comment of this parameter. Will be shown\n    /// in the UI but can be omitted.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub documentation: Option<Documentation>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum ParameterLabel {\n    Simple(String),\n    LabelOffsets([u32; 2]),\n}\n"
  },
  {
    "path": "helix-lsp-types/src/trace.rs",
    "content": "use serde::{Deserialize, Serialize};\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct SetTraceParams {\n    /// The new value that should be assigned to the trace setting.\n    pub value: TraceValue,\n}\n\n/// A TraceValue represents the level of verbosity with which the server systematically\n/// reports its execution trace using `LogTrace` notifications.\n///\n/// The initial trace value is set by the client at initialization and can be modified\n/// later using the `SetTrace` notification.\n#[derive(Debug, Eq, PartialEq, Clone, Copy, Deserialize, Serialize, Default)]\n#[serde(rename_all = \"camelCase\")]\npub enum TraceValue {\n    /// The server should not send any `$/logTrace` notification\n    #[default]\n    Off,\n    /// The server should not add the 'verbose' field in the `LogTraceParams`\n    Messages,\n    Verbose,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct LogTraceParams {\n    /// The message to be logged.\n    pub message: String,\n    /// Additional information that can be computed if the `trace` configuration\n    /// is set to `'verbose'`\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub verbose: Option<String>,\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::tests::test_serialization;\n\n    #[test]\n    fn test_set_trace_params() {\n        test_serialization(\n            &SetTraceParams {\n                value: TraceValue::Off,\n            },\n            r#\"{\"value\":\"off\"}\"#,\n        );\n    }\n\n    #[test]\n    fn test_log_trace_params() {\n        test_serialization(\n            &LogTraceParams {\n                message: \"message\".into(),\n                verbose: None,\n            },\n            r#\"{\"message\":\"message\"}\"#,\n        );\n\n        test_serialization(\n            &LogTraceParams {\n                message: \"message\".into(),\n                verbose: Some(\"verbose\".into()),\n            },\n            r#\"{\"message\":\"message\",\"verbose\":\"verbose\"}\"#,\n        );\n    }\n\n    #[test]\n    fn test_trace_value() {\n        test_serialization(\n            &vec![TraceValue::Off, TraceValue::Messages, TraceValue::Verbose],\n            r#\"[\"off\",\"messages\",\"verbose\"]\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "helix-lsp-types/src/type_hierarchy.rs",
    "content": "use crate::{\n    DynamicRegistrationClientCapabilities, LSPAny, PartialResultParams, Range,\n    StaticRegistrationOptions, SymbolKind, SymbolTag, TextDocumentPositionParams,\n    TextDocumentRegistrationOptions, Url, WorkDoneProgressOptions, WorkDoneProgressParams,\n};\n\nuse serde::{Deserialize, Serialize};\n\npub type TypeHierarchyClientCapabilities = DynamicRegistrationClientCapabilities;\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct TypeHierarchyOptions {\n    #[serde(flatten)]\n    pub work_done_progress_options: WorkDoneProgressOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct TypeHierarchyRegistrationOptions {\n    #[serde(flatten)]\n    pub text_document_registration_options: TextDocumentRegistrationOptions,\n    #[serde(flatten)]\n    pub type_hierarchy_options: TypeHierarchyOptions,\n    #[serde(flatten)]\n    pub static_registration_options: StaticRegistrationOptions,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct TypeHierarchyPrepareParams {\n    #[serde(flatten)]\n    pub text_document_position_params: TextDocumentPositionParams,\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct TypeHierarchySupertypesParams {\n    pub item: TypeHierarchyItem,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct TypeHierarchySubtypesParams {\n    pub item: TypeHierarchyItem,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct TypeHierarchyItem {\n    /// The name of this item.\n    pub name: String,\n\n    /// The kind of this item.\n    pub kind: SymbolKind,\n\n    /// Tags for this item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tags: Option<SymbolTag>,\n\n    /// More detail for this item, e.g. the signature of a function.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub detail: Option<String>,\n\n    /// The resource identifier of this item.\n    pub uri: Url,\n\n    /// The range enclosing this symbol not including leading/trailing whitespace\n    /// but everything else, e.g. comments and code.\n    pub range: Range,\n\n    /// The range that should be selected and revealed when this symbol is being\n    /// picked, e.g. the name of a function. Must be contained by the\n    /// [`range`](#TypeHierarchyItem.range).\n    pub selection_range: Range,\n\n    /// A data entry field that is preserved between a type hierarchy prepare and\n    /// supertypes or subtypes requests. It could also be used to identify the\n    /// type hierarchy in the server, helping improve the performance on\n    /// resolving supertypes and subtypes.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data: Option<LSPAny>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/window.rs",
    "content": "use std::collections::HashMap;\n\nuse serde::{Deserialize, Serialize};\n\nuse serde_json::Value;\n\nuse crate::{Range, Url};\n\n#[derive(Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]\n#[serde(transparent)]\npub struct MessageType(i32);\nlsp_enum! {\nimpl MessageType {\n    /// An error message.\n    pub const ERROR: MessageType = MessageType(1);\n    /// A warning message.\n    pub const WARNING: MessageType = MessageType(2);\n    /// An information message;\n    pub const INFO: MessageType = MessageType(3);\n    /// A log message.\n    pub const LOG: MessageType = MessageType(4);\n}\n}\n\n/// Window specific client capabilities.\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WindowClientCapabilities {\n    /// Whether client supports handling progress notifications. If set\n    /// servers are allowed to report in `workDoneProgress` property in the\n    /// request specific server capabilities.\n    ///\n    /// @since 3.15.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub work_done_progress: Option<bool>,\n\n    /// Capabilities specific to the showMessage request.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub show_message: Option<ShowMessageRequestClientCapabilities>,\n\n    /// Client capabilities for the show document request.\n    ///\n    /// @since 3.16.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub show_document: Option<ShowDocumentClientCapabilities>,\n}\n\n/// Show message request client capabilities\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ShowMessageRequestClientCapabilities {\n    /// Capabilities specific to the `MessageActionItem` type.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub message_action_item: Option<MessageActionItemCapabilities>,\n}\n\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct MessageActionItemCapabilities {\n    /// Whether the client supports additional attributes which\n    /// are preserved and send back to the server in the\n    /// request's response.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub additional_properties_support: Option<bool>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct MessageActionItem {\n    /// A short title like 'Retry', 'Open Log' etc.\n    pub title: String,\n\n    /// Additional attributes that the client preserves and\n    /// sends back to the server. This depends on the client\n    /// capability window.messageActionItem.additionalPropertiesSupport\n    #[serde(flatten)]\n    pub properties: HashMap<String, MessageActionItemProperty>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(untagged)]\npub enum MessageActionItemProperty {\n    String(String),\n    Boolean(bool),\n    Integer(i32),\n    Object(Value),\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct LogMessageParams {\n    /// The message type. See {@link MessageType}\n    #[serde(rename = \"type\")]\n    pub typ: MessageType,\n\n    /// The actual message\n    pub message: String,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct ShowMessageParams {\n    /// The message type. See {@link MessageType}.\n    #[serde(rename = \"type\")]\n    pub typ: MessageType,\n\n    /// The actual message.\n    pub message: String,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct ShowMessageRequestParams {\n    /// The message type. See {@link MessageType}\n    #[serde(rename = \"type\")]\n    pub typ: MessageType,\n\n    /// The actual message\n    pub message: String,\n\n    /// The message action items to present.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub actions: Option<Vec<MessageActionItem>>,\n}\n\n/// Client capabilities for the show document request.\n#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ShowDocumentClientCapabilities {\n    /// The client has support for the show document request.\n    pub support: bool,\n}\n\n/// Params to show a document.\n///\n/// @since 3.16.0\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ShowDocumentParams {\n    /// The document uri to show.\n    pub uri: Url,\n\n    /// Indicates to show the resource in an external program.\n    /// To show for example `https://code.visualstudio.com/`\n    /// in the default WEB browser set `external` to `true`.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub external: Option<bool>,\n\n    /// An optional property to indicate whether the editor\n    /// showing the document should take focus or not.\n    /// Clients might ignore this property if an external\n    /// program in started.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub take_focus: Option<bool>,\n\n    /// An optional selection range if the document is a text\n    /// document. Clients might ignore the property if an\n    /// external program is started or the file is not a text\n    /// file.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub selection: Option<Range>,\n}\n\n/// The result of an show document request.\n///\n/// @since 3.16.0\n#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct ShowDocumentResult {\n    /// A boolean indicating if the show was successful.\n    pub success: bool,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/workspace_diagnostic.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::{\n    FullDocumentDiagnosticReport, PartialResultParams, UnchangedDocumentDiagnosticReport, Url,\n    WorkDoneProgressParams,\n};\n\n/// Workspace client capabilities specific to diagnostic pull requests.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DiagnosticWorkspaceClientCapabilities {\n    /// Whether the client implementation supports a refresh request sent from\n    /// the server to the client.\n    ///\n    /// Note that this event is global and will force the client to refresh all\n    /// pulled diagnostics currently shown. It should be used with absolute care\n    /// and is useful for situation where a server for example detects a project\n    /// wide change that requires such a calculation.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub refresh_support: Option<bool>,\n}\n\n/// A previous result ID in a workspace pull request.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct PreviousResultId {\n    /// The URI for which the client knows a result ID.\n    pub uri: Url,\n\n    /// The value of the previous result ID.\n    pub value: String,\n}\n\n/// Parameters of the workspace diagnostic request.\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceDiagnosticParams {\n    /// The additional identifier provided during registration.\n    pub identifier: Option<String>,\n\n    /// The currently known diagnostic reports with their\n    /// previous result ids.\n    pub previous_result_ids: Vec<PreviousResultId>,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n}\n\n/// A full document diagnostic report for a workspace diagnostic result.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceFullDocumentDiagnosticReport {\n    /// The URI for which diagnostic information is reported.\n    pub uri: Url,\n\n    /// The version number for which the diagnostics are reported.\n    ///\n    /// If the document is not marked as open, `None` can be provided.\n    pub version: Option<i64>,\n\n    #[serde(flatten)]\n    pub full_document_diagnostic_report: FullDocumentDiagnosticReport,\n}\n\n/// An unchanged document diagnostic report for a workspace diagnostic result.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceUnchangedDocumentDiagnosticReport {\n    /// The URI for which diagnostic information is reported.\n    pub uri: Url,\n\n    /// The version number for which the diagnostics are reported.\n    ///\n    /// If the document is not marked as open, `None` can be provided.\n    pub version: Option<i64>,\n\n    #[serde(flatten)]\n    pub unchanged_document_diagnostic_report: UnchangedDocumentDiagnosticReport,\n}\n\n/// A workspace diagnostic document report.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(tag = \"kind\", rename_all = \"lowercase\")]\npub enum WorkspaceDocumentDiagnosticReport {\n    Full(WorkspaceFullDocumentDiagnosticReport),\n    Unchanged(WorkspaceUnchangedDocumentDiagnosticReport),\n}\n\nimpl From<WorkspaceFullDocumentDiagnosticReport> for WorkspaceDocumentDiagnosticReport {\n    fn from(from: WorkspaceFullDocumentDiagnosticReport) -> Self {\n        WorkspaceDocumentDiagnosticReport::Full(from)\n    }\n}\n\nimpl From<WorkspaceUnchangedDocumentDiagnosticReport> for WorkspaceDocumentDiagnosticReport {\n    fn from(from: WorkspaceUnchangedDocumentDiagnosticReport) -> Self {\n        WorkspaceDocumentDiagnosticReport::Unchanged(from)\n    }\n}\n\n/// A workspace diagnostic report.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]\npub struct WorkspaceDiagnosticReport {\n    pub items: Vec<WorkspaceDocumentDiagnosticReport>,\n}\n\n/// A partial result for a workspace diagnostic report.\n///\n/// @since 3.17.0\n#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]\npub struct WorkspaceDiagnosticReportPartialResult {\n    pub items: Vec<WorkspaceDocumentDiagnosticReport>,\n}\n\n#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]\n#[serde(untagged)]\npub enum WorkspaceDiagnosticReportResult {\n    Report(WorkspaceDiagnosticReport),\n    Partial(WorkspaceDiagnosticReportPartialResult),\n}\n\nimpl From<WorkspaceDiagnosticReport> for WorkspaceDiagnosticReportResult {\n    fn from(from: WorkspaceDiagnosticReport) -> Self {\n        WorkspaceDiagnosticReportResult::Report(from)\n    }\n}\n\nimpl From<WorkspaceDiagnosticReportPartialResult> for WorkspaceDiagnosticReportResult {\n    fn from(from: WorkspaceDiagnosticReportPartialResult) -> Self {\n        WorkspaceDiagnosticReportResult::Partial(from)\n    }\n}\n"
  },
  {
    "path": "helix-lsp-types/src/workspace_folders.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::{OneOf, Url};\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceFoldersServerCapabilities {\n    /// The server has support for workspace folders\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub supported: Option<bool>,\n\n    /// Whether the server wants to receive workspace folder\n    /// change notifications.\n    ///\n    /// If a string is provided, the string is treated as an ID\n    /// under which the notification is registered on the client\n    /// side. The ID can be used to unregister for these events\n    /// using the `client/unregisterCapability` request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub change_notifications: Option<OneOf<bool, String>>,\n}\n\n#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceFolder {\n    /// The associated URI for this workspace folder.\n    pub uri: Url,\n    /// The name of the workspace folder. Defaults to the uri's basename.\n    pub name: String,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct DidChangeWorkspaceFoldersParams {\n    /// The actual workspace folder change event.\n    pub event: WorkspaceFoldersChangeEvent,\n}\n\n/// The workspace folder change event.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceFoldersChangeEvent {\n    /// The array of added workspace folders\n    pub added: Vec<WorkspaceFolder>,\n\n    /// The array of the removed workspace folders\n    pub removed: Vec<WorkspaceFolder>,\n}\n"
  },
  {
    "path": "helix-lsp-types/src/workspace_symbols.rs",
    "content": "use crate::{\n    LSPAny, Location, OneOf, PartialResultParams, SymbolInformation, SymbolKind,\n    SymbolKindCapability, SymbolTag, TagSupport, Url, WorkDoneProgressParams,\n};\n\nuse serde::{Deserialize, Serialize};\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceSymbolClientCapabilities {\n    /// This capability supports dynamic registration.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dynamic_registration: Option<bool>,\n\n    /// Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub symbol_kind: Option<SymbolKindCapability>,\n\n    /// The client supports tags on `SymbolInformation`.\n    /// Clients supporting tags have to handle unknown tags gracefully.\n    ///\n    /// @since 3.16.0\n    #[serde(\n        default,\n        skip_serializing_if = \"Option::is_none\",\n        deserialize_with = \"TagSupport::deserialize_compat\"\n    )]\n    pub tag_support: Option<TagSupport<SymbolTag>>,\n\n    /// The client support partial workspace symbols. The client will send the\n    /// request `workspaceSymbol/resolve` to the server to resolve additional\n    /// properties.\n    ///\n    /// @since 3.17.0\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub resolve_support: Option<WorkspaceSymbolResolveSupportCapability>,\n}\n\n/// The parameters of a Workspace Symbol Request.\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct WorkspaceSymbolParams {\n    #[serde(flatten)]\n    pub partial_result_params: PartialResultParams,\n\n    #[serde(flatten)]\n    pub work_done_progress_params: WorkDoneProgressParams,\n\n    /// A non-empty query string\n    pub query: String,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]\npub struct WorkspaceSymbolResolveSupportCapability {\n    /// The properties that a client can resolve lazily. Usually\n    /// `location.range`\n    pub properties: Vec<String>,\n}\n\n/// A special workspace symbol that supports locations without a range\n///\n/// @since 3.17.0\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct WorkspaceSymbol {\n    /// The name of this symbol.\n    pub name: String,\n\n    /// The kind of this symbol.\n    pub kind: SymbolKind,\n\n    /// Tags for this completion item.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub tags: Option<Vec<SymbolTag>>,\n\n    /// The name of the symbol containing this symbol. This information is for\n    /// user interface purposes (e.g. to render a qualifier in the user interface\n    /// if necessary). It can't be used to re-infer a hierarchy for the document\n    /// symbols.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub container_name: Option<String>,\n\n    /// The location of this symbol. Whether a server is allowed to\n    /// return a location without a range depends on the client\n    /// capability `workspace.symbol.resolveSupport`.\n    ///\n    /// See also `SymbolInformation.location`.\n    pub location: OneOf<Location, WorkspaceLocation>,\n\n    /// A data entry field that is preserved on a workspace symbol between a\n    /// workspace symbol request and a workspace symbol resolve request.\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub data: Option<LSPAny>,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]\npub struct WorkspaceLocation {\n    pub uri: Url,\n}\n\n#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]\n#[serde(untagged)]\npub enum WorkspaceSymbolResponse {\n    Flat(Vec<SymbolInformation>),\n    Nested(Vec<WorkspaceSymbol>),\n}\n"
  },
  {
    "path": "helix-parsec/Cargo.toml",
    "content": "[package]\nname = \"helix-parsec\"\ndescription = \"Parser combinators for Helix\"\ninclude = [\"src/**/*\", \"README.md\"]\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n[dependencies]\n"
  },
  {
    "path": "helix-parsec/src/lib.rs",
    "content": "//! Parser-combinator functions\n//!\n//! This module provides parsers and parser combinators which can be used\n//! together to build parsers by functional composition.\n\n// This module implements parser combinators following https://bodil.lol/parser-combinators/.\n// `sym` (trait implementation for `&'static str`), `map`, `pred` (filter), `one_or_more`,\n// `zero_or_more`, as well as the `Parser` trait originate mostly from that post.\n// The remaining parsers and parser combinators are either based on\n// https://github.com/archseer/snippets.nvim/blob/a583da6ef130d2a4888510afd8c4e5ffd62d0dce/lua/snippet/parser.lua#L5-L138\n// or are novel.\n\n// When a parser matches the input successfully, it returns `Ok((next_input, some_value))`\n// where the type of the returned value depends on the parser. If the parser fails to match,\n// it returns `Err(input)`.\ntype ParseResult<'a, Output> = Result<(&'a str, Output), &'a str>;\n\n/// A parser or parser-combinator.\n///\n/// Parser-combinators compose multiple parsers together to parse input.\n/// For example, two basic parsers (`&'static str`s) may be combined with\n/// a parser-combinator like [or] to produce a new parser.\n///\n/// ```\n/// use helix_parsec::{or, Parser};\n/// let foo = \"foo\"; // matches \"foo\" literally\n/// let bar = \"bar\"; // matches \"bar\" literally\n/// let foo_or_bar = or(foo, bar); // matches either \"foo\" or \"bar\"\n/// assert_eq!(Ok((\"\", \"foo\")), foo_or_bar.parse(\"foo\"));\n/// assert_eq!(Ok((\"\", \"bar\")), foo_or_bar.parse(\"bar\"));\n/// assert_eq!(Err(\"baz\"), foo_or_bar.parse(\"baz\"));\n/// ```\npub trait Parser<'a> {\n    type Output;\n\n    fn parse(&self, input: &'a str) -> ParseResult<'a, Self::Output>;\n}\n\n// Most parser-combinators are written as higher-order functions which take some\n// parser(s) as input and return a new parser: a function that takes input and returns\n// a parse result. The underlying implementation of [Parser::parse] for these functions\n// is simply application.\n#[doc(hidden)]\nimpl<'a, F, T> Parser<'a> for F\nwhere\n    F: Fn(&'a str) -> ParseResult<'a, T>,\n{\n    type Output = T;\n\n    fn parse(&self, input: &'a str) -> ParseResult<'a, Self::Output> {\n        self(input)\n    }\n}\n\n/// A parser which matches the string literal exactly.\n///\n/// This parser succeeds if the next characters in the input are equal to the given\n/// string literal.\n///\n/// Note that [str::parse] interferes with calling [Parser::parse] on string literals\n/// directly; this trait implementation works when used within any parser combinator\n/// but does not work on its own. To call [Parser::parse] on a parser for a string\n/// literal, use the [token] parser.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{or, Parser};\n/// let parser = or(\"foo\", \"bar\");\n/// assert_eq!(Ok((\"\", \"foo\")), parser.parse(\"foo\"));\n/// assert_eq!(Ok((\"\", \"bar\")), parser.parse(\"bar\"));\n/// assert_eq!(Err(\"baz\"), parser.parse(\"baz\"));\n/// ```\nimpl<'a> Parser<'a> for &'static str {\n    type Output = &'a str;\n\n    fn parse(&self, input: &'a str) -> ParseResult<'a, Self::Output> {\n        match input.get(0..self.len()) {\n            Some(actual) if actual == *self => Ok((&input[self.len()..], &input[0..self.len()])),\n            _ => Err(input),\n        }\n    }\n}\n\n// Parsers\n\n/// A parser which matches the given string literally.\n///\n/// This function is a convenience for interpreting string literals as parsers\n/// and is only necessary to avoid conflict with [str::parse]. See the documentation\n/// for the `&'static str` implementation of [Parser].\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{token, Parser};\n/// let parser = token(\"foo\");\n/// assert_eq!(Ok((\"\", \"foo\")), parser.parse(\"foo\"));\n/// assert_eq!(Err(\"bar\"), parser.parse(\"bar\"));\n/// ```\npub fn token<'a>(literal: &'static str) -> impl Parser<'a, Output = &'a str> {\n    literal\n}\n\n/// A parser which matches all values until the specified pattern is found.\n///\n/// If the pattern is not found, this parser does not match. The input up to the\n/// character which returns `true` is returned but not that character itself.\n///\n/// If the pattern function returns true on the first input character, this\n/// parser fails.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{take_until, Parser};\n/// let parser = take_until(|c| c == '.');\n/// assert_eq!(Ok((\".bar\", \"foo\")), parser.parse(\"foo.bar\"));\n/// assert_eq!(Err(\".foo\"), parser.parse(\".foo\"));\n/// assert_eq!(Err(\"foo\"), parser.parse(\"foo\"));\n/// ```\npub fn take_until<'a, F>(pattern: F) -> impl Parser<'a, Output = &'a str>\nwhere\n    F: Fn(char) -> bool,\n{\n    move |input: &'a str| match input.find(&pattern) {\n        Some(index) if index != 0 => Ok((&input[index..], &input[0..index])),\n        _ => Err(input),\n    }\n}\n\n/// A parser which matches all values until the specified pattern no longer match.\n///\n/// This parser only ever fails if the input has a length of zero.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{take_while, Parser};\n/// let parser = take_while(|c| c == '1');\n/// assert_eq!(Ok((\"2\", \"11\")), parser.parse(\"112\"));\n/// assert_eq!(Err(\"22\"), parser.parse(\"22\"));\n/// ```\npub fn take_while<'a, F>(pattern: F) -> impl Parser<'a, Output = &'a str>\nwhere\n    F: Fn(char) -> bool,\n{\n    move |input: &'a str| match input\n        .char_indices()\n        .take_while(|(_p, c)| pattern(*c))\n        .last()\n    {\n        Some((index, c)) => {\n            let index = index + c.len_utf8();\n            Ok((&input[index..], &input[0..index]))\n        }\n        _ => Err(input),\n    }\n}\n\n// Variadic parser combinators\n\n/// A parser combinator which matches a sequence of parsers in an all-or-nothing fashion.\n///\n/// The returned value is a tuple containing the outputs of all parsers in order. Each\n/// parser in the sequence may be typed differently.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{seq, Parser};\n/// let parser = seq!(\"<\", \"a\", \">\");\n/// assert_eq!(Ok((\"\", (\"<\", \"a\", \">\"))), parser.parse(\"<a>\"));\n/// assert_eq!(Err(\"<b>\"), parser.parse(\"<b>\"));\n/// ```\n#[macro_export]\nmacro_rules! seq {\n    ($($parsers: expr),+ $(,)?) => {\n        ($($parsers),+)\n    }\n}\n\n// Seq is implemented using trait-implementations of Parser for various size tuples.\n// This allows sequences to be typed heterogeneously.\nmacro_rules! seq_impl {\n    ($($parser:ident),+) => {\n        #[allow(non_snake_case)]\n        impl<'a, $($parser),+> Parser<'a> for ($($parser),+)\n        where\n            $($parser: Parser<'a>),+\n        {\n            type Output = ($($parser::Output),+);\n\n            fn parse(&self, input: &'a str) -> ParseResult<'a, Self::Output> {\n                let ($($parser),+) = self;\n                seq_body_impl!(input, input, $($parser),+ ; )\n            }\n        }\n    }\n}\n\nmacro_rules! seq_body_impl {\n    ($input:expr, $next_input:expr, $head:ident, $($tail:ident),+ ; $(,)? $($acc:ident),*) => {\n        match $head.parse($next_input) {\n            Ok((next_input, $head)) => seq_body_impl!($input, next_input, $($tail),+ ; $($acc),*, $head),\n            Err(_) => Err($input),\n        }\n    };\n    ($input:expr, $next_input:expr, $last:ident ; $(,)? $($acc:ident),*) => {\n        match $last.parse($next_input) {\n            Ok((next_input, last)) => Ok((next_input, ($($acc),+, last))),\n            Err(_) => Err($input),\n        }\n    }\n}\n\nseq_impl!(A, B);\nseq_impl!(A, B, C);\nseq_impl!(A, B, C, D);\nseq_impl!(A, B, C, D, E);\nseq_impl!(A, B, C, D, E, F);\nseq_impl!(A, B, C, D, E, F, G);\nseq_impl!(A, B, C, D, E, F, G, H);\nseq_impl!(A, B, C, D, E, F, G, H, I);\nseq_impl!(A, B, C, D, E, F, G, H, I, J);\n\n/// A parser combinator which chooses the first of the input parsers which matches\n/// successfully.\n///\n/// All input parsers must have the same output type. This is a variadic form for [or].\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{choice, or, Parser};\n/// let parser = choice!(\"foo\", \"bar\", \"baz\");\n/// assert_eq!(Ok((\"\", \"foo\")), parser.parse(\"foo\"));\n/// assert_eq!(Ok((\"\", \"bar\")), parser.parse(\"bar\"));\n/// assert_eq!(Err(\"quiz\"), parser.parse(\"quiz\"));\n/// ```\n#[macro_export]\nmacro_rules! choice {\n    ($parser: expr $(,)?) => {\n        $parser\n    };\n    ($parser: expr, $($rest: expr),+ $(,)?) => {\n        or($parser, choice!($($rest),+))\n    }\n}\n\n// Ordinary parser combinators\n\n/// A parser combinator which takes a parser as input and maps the output using the\n/// given transformation function.\n///\n/// This corresponds to [Result::map]. The value is only mapped if the input parser\n/// matches against input.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{map, Parser};\n/// let parser = map(\"123\", |s| s.parse::<i32>().unwrap());\n/// assert_eq!(Ok((\"\", 123)), parser.parse(\"123\"));\n/// assert_eq!(Err(\"abc\"), parser.parse(\"abc\"));\n/// ```\npub fn map<'a, P, F, T>(parser: P, map_fn: F) -> impl Parser<'a, Output = T>\nwhere\n    P: Parser<'a>,\n    F: Fn(P::Output) -> T,\n{\n    move |input| {\n        parser\n            .parse(input)\n            .map(|(next_input, result)| (next_input, map_fn(result)))\n    }\n}\n\n/// A parser combinator which succeeds if the given parser matches the input and\n/// the given `filter_map_fn` returns `Some`.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{filter_map, take_until, Parser};\n/// let parser = filter_map(take_until(|c| c == '.'), |s| s.parse::<i32>().ok());\n/// assert_eq!(Ok((\".456\", 123)), parser.parse(\"123.456\"));\n/// assert_eq!(Err(\"abc.def\"), parser.parse(\"abc.def\"));\n/// ```\npub fn filter_map<'a, P, F, T>(parser: P, filter_map_fn: F) -> impl Parser<'a, Output = T>\nwhere\n    P: Parser<'a>,\n    F: Fn(P::Output) -> Option<T>,\n{\n    move |input| match parser.parse(input) {\n        Ok((next_input, value)) => match filter_map_fn(value) {\n            Some(value) => Ok((next_input, value)),\n            None => Err(input),\n        },\n        Err(_) => Err(input),\n    }\n}\n\n/// A parser combinator which succeeds if the first given parser matches the input and\n/// the second given parse also matches.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{reparse_as, take_until, one_or_more, Parser};\n/// let parser = reparse_as(take_until(|c| c == '/'), one_or_more(\"a\"));\n/// assert_eq!(Ok((\"/bb\", vec![\"a\", \"a\"])), parser.parse(\"aa/bb\"));\n/// ```\npub fn reparse_as<'a, P1, P2, T>(parser1: P1, parser2: P2) -> impl Parser<'a, Output = T>\nwhere\n    P1: Parser<'a, Output = &'a str>,\n    P2: Parser<'a, Output = T>,\n{\n    filter_map(parser1, move |str| {\n        parser2.parse(str).map(|(_, value)| value).ok()\n    })\n}\n\n/// A parser combinator which only matches the input when the predicate function\n/// returns true.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{filter, take_until, Parser};\n/// let parser = filter(take_until(|c| c == '.'), |s| s == &\"123\");\n/// assert_eq!(Ok((\".456\", \"123\")), parser.parse(\"123.456\"));\n/// assert_eq!(Err(\"456.123\"), parser.parse(\"456.123\"));\n/// ```\npub fn filter<'a, P, F, T>(parser: P, pred_fn: F) -> impl Parser<'a, Output = T>\nwhere\n    P: Parser<'a, Output = T>,\n    F: Fn(&P::Output) -> bool,\n{\n    move |input| {\n        if let Ok((next_input, value)) = parser.parse(input) {\n            if pred_fn(&value) {\n                return Ok((next_input, value));\n            }\n        }\n        Err(input)\n    }\n}\n\n/// A parser combinator which matches either of the input parsers.\n///\n/// Both parsers must have the same output type. For a variadic form which\n/// can take any number of parsers, use `choice!`.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{or, Parser};\n/// let parser = or(\"foo\", \"bar\");\n/// assert_eq!(Ok((\"\", \"foo\")), parser.parse(\"foo\"));\n/// assert_eq!(Ok((\"\", \"bar\")), parser.parse(\"bar\"));\n/// assert_eq!(Err(\"baz\"), parser.parse(\"baz\"));\n/// ```\npub fn or<'a, P1, P2, T>(parser1: P1, parser2: P2) -> impl Parser<'a, Output = T>\nwhere\n    P1: Parser<'a, Output = T>,\n    P2: Parser<'a, Output = T>,\n{\n    move |input| match parser1.parse(input) {\n        ok @ Ok(_) => ok,\n        Err(_) => parser2.parse(input),\n    }\n}\n\n/// A parser combinator which attempts to match the given parser, returning a\n/// `None` output value if the parser does not match.\n///\n/// The parser produced with this combinator always succeeds. If the given parser\n/// succeeds, `Some(value)` is returned where `value` is the output of the given\n/// parser. Otherwise, `None`.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{optional, Parser};\n/// let parser = optional(\"foo\");\n/// assert_eq!(Ok((\"bar\", Some(\"foo\"))), parser.parse(\"foobar\"));\n/// assert_eq!(Ok((\"bar\", None)), parser.parse(\"bar\"));\n/// ```\npub fn optional<'a, P, T>(parser: P) -> impl Parser<'a, Output = Option<T>>\nwhere\n    P: Parser<'a, Output = T>,\n{\n    move |input| match parser.parse(input) {\n        Ok((next_input, value)) => Ok((next_input, Some(value))),\n        Err(_) => Ok((input, None)),\n    }\n}\n\n/// A parser combinator which runs the given parsers in sequence and returns the\n/// value of `left` if both are matched.\n///\n/// This is useful for two-element sequences in which you only want the output\n/// value of the `left` parser.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{left, Parser};\n/// let parser = left(\"foo\", \"bar\");\n/// assert_eq!(Ok((\"\", \"foo\")), parser.parse(\"foobar\"));\n/// ```\npub fn left<'a, L, R, T>(left: L, right: R) -> impl Parser<'a, Output = T>\nwhere\n    L: Parser<'a, Output = T>,\n    R: Parser<'a>,\n{\n    map(seq!(left, right), |(left_value, _)| left_value)\n}\n\n/// A parser combinator which runs the given parsers in sequence and returns the\n/// value of `right` if both are matched.\n///\n/// This is useful for two-element sequences in which you only want the output\n/// value of the `right` parser.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{right, Parser};\n/// let parser = right(\"foo\", \"bar\");\n/// assert_eq!(Ok((\"\", \"bar\")), parser.parse(\"foobar\"));\n/// ```\npub fn right<'a, L, R, T>(left: L, right: R) -> impl Parser<'a, Output = T>\nwhere\n    L: Parser<'a>,\n    R: Parser<'a, Output = T>,\n{\n    map(seq!(left, right), |(_, right_value)| right_value)\n}\n\n/// A parser combinator which matches the given parser against the input zero or\n/// more times.\n///\n/// This parser always succeeds and returns the empty Vec when it matched zero\n/// times.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{zero_or_more, Parser};\n/// let parser = zero_or_more(\"a\");\n/// assert_eq!(Ok((\"\", vec![])), parser.parse(\"\"));\n/// assert_eq!(Ok((\"\", vec![\"a\"])), parser.parse(\"a\"));\n/// assert_eq!(Ok((\"\", vec![\"a\", \"a\"])), parser.parse(\"aa\"));\n/// assert_eq!(Ok((\"bb\", vec![])), parser.parse(\"bb\"));\n/// ```\npub fn zero_or_more<'a, P, T>(parser: P) -> impl Parser<'a, Output = Vec<T>>\nwhere\n    P: Parser<'a, Output = T>,\n{\n    let parser = non_empty(parser);\n    move |mut input| {\n        let mut values = Vec::new();\n\n        while let Ok((next_input, value)) = parser.parse(input) {\n            input = next_input;\n            values.push(value);\n        }\n\n        Ok((input, values))\n    }\n}\n\n/// A parser combinator which matches the given parser against the input one or\n/// more times.\n///\n/// This parser combinator acts the same as [zero_or_more] but must match at\n/// least once.\n///\n/// # Examples\n///\n/// ```\n/// use helix_parsec::{one_or_more, Parser};\n/// let parser = one_or_more(\"a\");\n/// assert_eq!(Err(\"\"), parser.parse(\"\"));\n/// assert_eq!(Ok((\"\", vec![\"a\"])), parser.parse(\"a\"));\n/// assert_eq!(Ok((\"\", vec![\"a\", \"a\"])), parser.parse(\"aa\"));\n/// assert_eq!(Err(\"bb\"), parser.parse(\"bb\"));\n/// ```\npub fn one_or_more<'a, P, T>(parser: P) -> impl Parser<'a, Output = Vec<T>>\nwhere\n    P: Parser<'a, Output = T>,\n{\n    let parser = non_empty(parser);\n    move |mut input| {\n        let mut values = Vec::new();\n\n        match parser.parse(input) {\n            Ok((next_input, value)) => {\n                input = next_input;\n                values.push(value);\n            }\n            Err(err) => return Err(err),\n        }\n\n        while let Ok((next_input, value)) = parser.parse(input) {\n            input = next_input;\n            values.push(value);\n        }\n\n        Ok((input, values))\n    }\n}\n\n/// A parser combinator which matches one or more instances of the given parser\n/// interspersed with the separator parser.\n///\n/// Output values of the separator parser are discarded.\n///\n/// This is typically used to parse function arguments or list items.\n///\n/// # Examples\n///\n/// ```rust\n/// use helix_parsec::{sep, Parser};\n/// let parser = sep(\"a\", \",\");\n/// assert_eq!(Ok((\"\", vec![\"a\", \"a\", \"a\"])), parser.parse(\"a,a,a\"));\n/// ```\npub fn sep<'a, P, S, T>(parser: P, separator: S) -> impl Parser<'a, Output = Vec<T>>\nwhere\n    P: Parser<'a, Output = T>,\n    S: Parser<'a>,\n{\n    move |mut input| {\n        let mut values = Vec::new();\n\n        match parser.parse(input) {\n            Ok((next_input, value)) => {\n                input = next_input;\n                values.push(value);\n            }\n            Err(err) => return Err(err),\n        }\n\n        loop {\n            match separator.parse(input) {\n                Ok((next_input, _)) => input = next_input,\n                Err(_) => break,\n            }\n\n            match parser.parse(input) {\n                Ok((next_input, value)) => {\n                    input = next_input;\n                    values.push(value);\n                }\n                Err(_) => break,\n            }\n        }\n\n        Ok((input, values))\n    }\n}\n\npub fn non_empty<'a, T>(p: impl Parser<'a, Output = T>) -> impl Parser<'a, Output = T> {\n    move |input| {\n        let (new_input, res) = p.parse(input)?;\n        if new_input.len() == input.len() {\n            Err(input)\n        } else {\n            Ok((new_input, res))\n        }\n    }\n}\n"
  },
  {
    "path": "helix-stdx/Cargo.toml",
    "content": "[package]\nname = \"helix-stdx\"\ndescription = \"Standard library extensions\"\ninclude = [\"src/**/*\", \"README.md\"]\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n[dependencies]\ndunce = \"1.0\"\netcetera.workspace = true\nropey.workspace = true\nwhich = \"8.0\"\nregex-cursor = \"0.1.5\"\nbitflags.workspace = true\nonce_cell = \"1.21\"\nregex-automata = \"0.4.14\"\nunicode-segmentation.workspace = true\n\n[target.'cfg(windows)'.dependencies]\nwindows-sys = { version = \"0.61\", features = [\"Win32_Foundation\", \"Win32_Security\", \"Win32_Security_Authorization\", \"Win32_Storage_FileSystem\", \"Win32_System_Threading\"] }\n\n[target.'cfg(unix)'.dependencies]\nrustix = { version = \"1.1\", features = [\"fs\", \"thread\"] }\n\n[dev-dependencies]\ntempfile.workspace = true\n"
  },
  {
    "path": "helix-stdx/src/env.rs",
    "content": "//! Functions for working with the host environment.\nuse std::{\n    borrow::Cow,\n    ffi::{OsStr, OsString},\n    path::{Path, PathBuf},\n    sync::RwLock,\n};\n\nuse once_cell::sync::Lazy;\n\n// We keep the CWD as a static so that we can access it in places where we don't have access to the Editor\nstatic CWD: RwLock<Option<PathBuf>> = RwLock::new(None);\n\n/// Get the current working directory.\n/// This information is managed internally as the call to std::env::current_dir\n/// might fail if the cwd has been deleted.\npub fn current_working_dir() -> PathBuf {\n    if let Some(path) = &*CWD.read().unwrap() {\n        return path.clone();\n    }\n\n    // implementation of crossplatform pwd -L\n    // we want pwd -L so that symlinked directories are handled correctly\n    let mut cwd = std::env::current_dir().expect(\"Couldn't determine current working directory\");\n\n    let pwd = std::env::var_os(\"PWD\");\n    #[cfg(windows)]\n    let pwd = pwd.or_else(|| std::env::var_os(\"CD\"));\n\n    if let Some(pwd) = pwd.map(PathBuf::from) {\n        if pwd.canonicalize().ok().as_ref() == Some(&cwd) {\n            cwd = pwd;\n        }\n    }\n    let mut dst = CWD.write().unwrap();\n    *dst = Some(cwd.clone());\n\n    cwd\n}\n\n/// Update the current working directory.\npub fn set_current_working_dir(path: impl AsRef<Path>) -> std::io::Result<Option<PathBuf>> {\n    let path = crate::path::canonicalize(path);\n    std::env::set_current_dir(&path)?;\n    let mut cwd = CWD.write().unwrap();\n\n    Ok(cwd.replace(path))\n}\n\n/// Checks if the given environment variable is set.\npub fn env_var_is_set(env_var_name: &str) -> bool {\n    std::env::var_os(env_var_name).is_some()\n}\n\n/// Checks if a binary with the given name exists.\npub fn binary_exists<T: AsRef<OsStr>>(binary_name: T) -> bool {\n    which::which(binary_name).is_ok()\n}\n\n/// Attempts to find a binary of the given name. See [which](https://linux.die.net/man/1/which).\npub fn which<T: AsRef<OsStr>>(\n    binary_name: T,\n) -> Result<std::path::PathBuf, ExecutableNotFoundError> {\n    let binary_name = binary_name.as_ref();\n    which::which(binary_name).map_err(|err| ExecutableNotFoundError {\n        command: binary_name.to_string_lossy().into_owned(),\n        inner: err,\n    })\n}\n\nfn find_brace_end(src: &[u8]) -> Option<usize> {\n    use regex_automata::meta::Regex;\n\n    static REGEX: Lazy<Regex> = Lazy::new(|| Regex::builder().build(\"[{}]\").unwrap());\n    let mut depth = 0;\n    for mat in REGEX.find_iter(src) {\n        let pos = mat.start();\n        match src[pos] {\n            b'{' => depth += 1,\n            b'}' if depth == 0 => return Some(pos),\n            b'}' => depth -= 1,\n            _ => unreachable!(),\n        }\n    }\n    None\n}\n\nfn expand_impl(src: &OsStr, mut resolve: impl FnMut(&OsStr) -> Option<OsString>) -> Cow<'_, OsStr> {\n    use regex_automata::meta::Regex;\n\n    static REGEX: Lazy<Regex> = Lazy::new(|| {\n        Regex::builder()\n            .build_many(&[\n                r\"\\$\\{([^\\}:]+):-\",\n                r\"\\$\\{([^\\}:]+):=\",\n                r\"\\$\\{([^\\}-]+)-\",\n                r\"\\$\\{([^\\}=]+)=\",\n                r\"\\$\\{([^\\}]+)\",\n                r\"\\$(\\w+)\",\n            ])\n            .unwrap()\n    });\n\n    let bytes = src.as_encoded_bytes();\n    let mut res = Vec::with_capacity(bytes.len());\n    let mut pos = 0;\n    for captures in REGEX.captures_iter(bytes) {\n        let mat = captures.get_match().unwrap();\n        let pattern_id = mat.pattern().as_usize();\n        let mut range = mat.range();\n        // A pattern may match multiple times on a single variable, for example `${HOME:-$HOME}`:\n        // `${HOME:-` matches and also the default value (`$HOME`). Skip past any variables which\n        // have already been expanded.\n        if range.start < pos {\n            continue;\n        }\n        let var = &bytes[captures.get_group(1).unwrap().range()];\n        let default = if pattern_id != 5 {\n            let Some(bracket_pos) = find_brace_end(&bytes[range.end..]) else {\n                break;\n            };\n            let default = &bytes[range.end..range.end + bracket_pos];\n            range.end += bracket_pos + 1;\n            default\n        } else {\n            &[]\n        };\n        // safety: this is a codepoint aligned substring of an osstr (always valid)\n        let var = unsafe { OsStr::from_encoded_bytes_unchecked(var) };\n        let expansion = resolve(var);\n        let expansion = match &expansion {\n            Some(val) => {\n                if val.is_empty() && pattern_id < 2 {\n                    default\n                } else {\n                    val.as_encoded_bytes()\n                }\n            }\n            None => default,\n        };\n        res.extend_from_slice(&bytes[pos..range.start]);\n        pos = range.end;\n        res.extend_from_slice(expansion);\n    }\n    if pos == 0 {\n        src.into()\n    } else {\n        res.extend_from_slice(&bytes[pos..]);\n        // safety: this is a composition of valid osstr (and codepoint aligned slices which are also valid)\n        unsafe { OsString::from_encoded_bytes_unchecked(res) }.into()\n    }\n}\n\n/// performs substitution of enviorment variables. Supports the following (POSIX) syntax:\n///\n/// * `$<var>`, `${<var>}`\n/// * `${<var>:-<default>}`, `${<var>-<default>}`\n/// * `${<var>:=<default>}`, `${<var>=default}`\n///\npub fn expand<S: AsRef<OsStr> + ?Sized>(src: &S) -> Cow<'_, OsStr> {\n    expand_impl(src.as_ref(), |var| std::env::var_os(var))\n}\n\n#[derive(Debug)]\npub struct ExecutableNotFoundError {\n    command: String,\n    inner: which::Error,\n}\n\nimpl std::fmt::Display for ExecutableNotFoundError {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"command '{}' not found: {}\", self.command, self.inner)\n    }\n}\n\nimpl std::error::Error for ExecutableNotFoundError {}\n\n#[cfg(test)]\nmod tests {\n    use std::ffi::{OsStr, OsString};\n\n    use super::{current_working_dir, expand_impl, set_current_working_dir};\n\n    #[test]\n    fn current_dir_is_set() {\n        let new_path = dunce::canonicalize(std::env::temp_dir()).unwrap();\n        let cwd = current_working_dir();\n        assert_ne!(cwd, new_path);\n\n        set_current_working_dir(&new_path).expect(\"Couldn't set new path\");\n\n        let cwd = current_working_dir();\n        assert_eq!(cwd, new_path);\n    }\n\n    macro_rules! assert_env_expand {\n        ($env: expr, $lhs: expr, $rhs: expr) => {\n            assert_eq!(&*expand_impl($lhs.as_ref(), $env), OsStr::new($rhs));\n        };\n    }\n\n    /// paths that should work on all platforms\n    #[test]\n    fn test_env_expand() {\n        let env = |var: &OsStr| -> Option<OsString> {\n            match var.to_str().unwrap() {\n                \"FOO\" => Some(\"foo\".into()),\n                \"EMPTY\" => Some(\"\".into()),\n                _ => None,\n            }\n        };\n        assert_env_expand!(env, \"pass_trough\", \"pass_trough\");\n        assert_env_expand!(env, \"$FOO\", \"foo\");\n        assert_env_expand!(env, \"bar/$FOO/baz\", \"bar/foo/baz\");\n        assert_env_expand!(env, \"bar/${FOO}/baz\", \"bar/foo/baz\");\n        assert_env_expand!(env, \"baz/${BAR:-bar}/foo\", \"baz/bar/foo\");\n        assert_env_expand!(env, \"baz/${FOO:-$FOO}/foo\", \"baz/foo/foo\");\n        assert_env_expand!(env, \"baz/${BAR:=bar}/foo\", \"baz/bar/foo\");\n        assert_env_expand!(env, \"baz/${BAR-bar}/foo\", \"baz/bar/foo\");\n        assert_env_expand!(env, \"baz/${BAR=bar}/foo\", \"baz/bar/foo\");\n        assert_env_expand!(env, \"baz/${EMPTY:-bar}/foo\", \"baz/bar/foo\");\n        assert_env_expand!(env, \"baz/${EMPTY:=bar}/foo\", \"baz/bar/foo\");\n        assert_env_expand!(env, \"baz/${EMPTY-bar}/foo\", \"baz//foo\");\n        assert_env_expand!(env, \"baz/${EMPTY=bar}/foo\", \"baz//foo\");\n    }\n}\n"
  },
  {
    "path": "helix-stdx/src/faccess.rs",
    "content": "//! Functions for managine file metadata.\n//! From <https://github.com/Freaky/faccess>\n\nuse std::io;\nuse std::path::Path;\n\nuse bitflags::bitflags;\n\n// Licensed under MIT from faccess\nbitflags! {\n    /// Access mode flags for `access` function to test for.\n    pub struct AccessMode: u8 {\n        /// Path exists\n        const EXISTS  = 0b0001;\n        /// Path can likely be read\n        const READ    = 0b0010;\n        /// Path can likely be written to\n        const WRITE   = 0b0100;\n        /// Path can likely be executed\n        const EXECUTE = 0b1000;\n    }\n}\n\n#[cfg(unix)]\nmod imp {\n    use super::*;\n\n    use rustix::fs::Access;\n    use std::os::unix::fs::{MetadataExt, PermissionsExt};\n\n    pub fn access(p: &Path, mode: AccessMode) -> io::Result<()> {\n        #[cfg(target_os = \"linux\")]\n        {\n            // If helix has ambient CAP_DAC_OVERRIDE, everything is accessible regardless of mode bits\n            use rustix::thread::{capability_is_in_ambient_set, CapabilitySet};\n            if capability_is_in_ambient_set(CapabilitySet::DAC_OVERRIDE).unwrap_or(false) {\n                return Ok(());\n            }\n        }\n\n        let mut imode = Access::empty();\n\n        if mode.contains(AccessMode::EXISTS) {\n            imode |= Access::EXISTS;\n        }\n\n        if mode.contains(AccessMode::READ) {\n            imode |= Access::READ_OK;\n        }\n\n        if mode.contains(AccessMode::WRITE) {\n            imode |= Access::WRITE_OK;\n        }\n\n        if mode.contains(AccessMode::EXECUTE) {\n            imode |= Access::EXEC_OK;\n        }\n\n        rustix::fs::access(p, imode)?;\n        Ok(())\n    }\n\n    fn chown(p: &Path, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {\n        let uid = uid.map(rustix::fs::Uid::from_raw);\n        let gid = gid.map(rustix::fs::Gid::from_raw);\n        rustix::fs::chown(p, uid, gid)?;\n        Ok(())\n    }\n\n    pub fn copy_metadata(from: &Path, to: &Path) -> io::Result<()> {\n        let from_meta = std::fs::metadata(from)?;\n        let to_meta = std::fs::metadata(to)?;\n        let from_gid = from_meta.gid();\n        let to_gid = to_meta.gid();\n\n        let mut perms = from_meta.permissions();\n        perms.set_mode(perms.mode() & 0o0777);\n        if from_gid != to_gid && chown(to, None, Some(from_gid)).is_err() {\n            let new_perms = (perms.mode() & 0o0707) | ((perms.mode() & 0o07) << 3);\n            perms.set_mode(new_perms);\n        }\n\n        #[cfg(target_os = \"macos\")]\n        {\n            use std::fs::{File, FileTimes};\n            use std::os::macos::fs::FileTimesExt;\n\n            let to_file = File::options().write(true).open(to)?;\n            let times = FileTimes::new().set_created(from_meta.created()?);\n            to_file.set_times(times)?;\n        }\n\n        std::fs::set_permissions(to, perms)?;\n\n        Ok(())\n    }\n\n    pub fn hardlink_count(p: &Path) -> std::io::Result<u64> {\n        let metadata = p.metadata()?;\n        Ok(metadata.nlink())\n    }\n}\n\n// Licensed under MIT from faccess except for `chown`, `copy_metadata` and `is_acl_inherited`\n#[cfg(windows)]\nmod imp {\n\n    use windows_sys::Win32::Foundation::{CloseHandle, LocalFree, ERROR_SUCCESS, HANDLE};\n    use windows_sys::Win32::Security::Authorization::{\n        GetNamedSecurityInfoW, SetNamedSecurityInfoW, SE_FILE_OBJECT,\n    };\n    use windows_sys::Win32::Security::{\n        AccessCheck, AclSizeInformation, GetAce, GetAclInformation, GetSidIdentifierAuthority,\n        ImpersonateSelf, IsValidAcl, IsValidSid, MapGenericMask, RevertToSelf,\n        SecurityImpersonation, ACCESS_ALLOWED_CALLBACK_ACE, ACL, ACL_SIZE_INFORMATION,\n        DACL_SECURITY_INFORMATION, GENERIC_MAPPING, GROUP_SECURITY_INFORMATION, INHERITED_ACE,\n        LABEL_SECURITY_INFORMATION, OBJECT_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION,\n        PRIVILEGE_SET, PROTECTED_DACL_SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, PSID,\n        SID_IDENTIFIER_AUTHORITY, TOKEN_DUPLICATE, TOKEN_QUERY,\n    };\n    use windows_sys::Win32::Storage::FileSystem::{\n        GetFileInformationByHandle, BY_HANDLE_FILE_INFORMATION, FILE_ACCESS_RIGHTS,\n        FILE_ALL_ACCESS, FILE_GENERIC_EXECUTE, FILE_GENERIC_READ, FILE_GENERIC_WRITE,\n    };\n    use windows_sys::Win32::System::Threading::{GetCurrentThread, OpenThreadToken};\n\n    use super::*;\n\n    use std::ffi::c_void;\n\n    use std::os::windows::{\n        ffi::OsStrExt,\n        fs::{FileTimesExt, OpenOptionsExt},\n        io::AsRawHandle,\n    };\n\n    use std::fs::{File, FileTimes};\n\n    struct SecurityDescriptor {\n        sd: PSECURITY_DESCRIPTOR,\n        owner: PSID,\n        group: PSID,\n        dacl: *mut ACL,\n    }\n\n    impl Drop for SecurityDescriptor {\n        fn drop(&mut self) {\n            if !self.sd.is_null() {\n                unsafe {\n                    LocalFree(self.sd);\n                }\n            }\n        }\n    }\n\n    impl SecurityDescriptor {\n        fn for_path(p: &Path) -> io::Result<SecurityDescriptor> {\n            let path = std::fs::canonicalize(p)?;\n            let pathos = path.into_os_string();\n            let mut pathw: Vec<u16> = Vec::with_capacity(pathos.len() + 1);\n            pathw.extend(pathos.encode_wide());\n            pathw.push(0);\n\n            let mut sd = std::ptr::null_mut();\n            let mut owner = std::ptr::null_mut();\n            let mut group = std::ptr::null_mut();\n            let mut dacl = std::ptr::null_mut();\n\n            let err = unsafe {\n                GetNamedSecurityInfoW(\n                    pathw.as_ptr(),\n                    SE_FILE_OBJECT,\n                    OWNER_SECURITY_INFORMATION\n                        | GROUP_SECURITY_INFORMATION\n                        | DACL_SECURITY_INFORMATION\n                        | LABEL_SECURITY_INFORMATION,\n                    &mut owner,\n                    &mut group,\n                    &mut dacl,\n                    std::ptr::null_mut(),\n                    &mut sd,\n                )\n            };\n\n            if err == ERROR_SUCCESS {\n                Ok(SecurityDescriptor {\n                    sd,\n                    owner,\n                    group,\n                    dacl,\n                })\n            } else {\n                Err(io::Error::last_os_error())\n            }\n        }\n\n        fn is_acl_inherited(&self) -> bool {\n            let mut acl_info: ACL_SIZE_INFORMATION = unsafe { ::core::mem::zeroed() };\n            let acl_info_ptr: *mut c_void = &mut acl_info as *mut _ as *mut c_void;\n            let mut ace: ACCESS_ALLOWED_CALLBACK_ACE = unsafe { ::core::mem::zeroed() };\n\n            unsafe {\n                GetAclInformation(\n                    self.dacl,\n                    acl_info_ptr,\n                    std::mem::size_of_val(&acl_info) as u32,\n                    AclSizeInformation,\n                )\n            };\n\n            for i in 0..acl_info.AceCount {\n                let mut ptr = &mut ace as *mut _ as *mut c_void;\n                unsafe { GetAce(self.dacl, i, &mut ptr) };\n                if (ace.Header.AceFlags as u32 & INHERITED_ACE) != 0 {\n                    return true;\n                }\n            }\n\n            false\n        }\n\n        fn descriptor(&self) -> &PSECURITY_DESCRIPTOR {\n            &self.sd\n        }\n\n        fn owner(&self) -> &PSID {\n            &self.owner\n        }\n    }\n\n    struct ThreadToken(HANDLE);\n    impl Drop for ThreadToken {\n        fn drop(&mut self) {\n            unsafe {\n                CloseHandle(self.0);\n            }\n        }\n    }\n\n    impl ThreadToken {\n        fn new() -> io::Result<Self> {\n            unsafe {\n                if ImpersonateSelf(SecurityImpersonation) == 0 {\n                    return Err(io::Error::last_os_error());\n                }\n\n                let token: *mut HANDLE = std::ptr::null_mut();\n                let err =\n                    OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, 0, token);\n\n                RevertToSelf();\n\n                if err == 0 {\n                    return Err(io::Error::last_os_error());\n                }\n\n                Ok(Self(*token))\n            }\n        }\n\n        fn as_handle(&self) -> &HANDLE {\n            &self.0\n        }\n    }\n\n    // Based roughly on Tcl's NativeAccess()\n    // https://github.com/tcltk/tcl/blob/2ee77587e4dc2150deb06b48f69db948b4ab0584/win/tclWinFile.c\n    fn eaccess(p: &Path, mut mode: FILE_ACCESS_RIGHTS) -> io::Result<()> {\n        let md = p.metadata()?;\n\n        if !md.is_dir() {\n            // Read Only is ignored for directories\n            if mode & FILE_GENERIC_WRITE == FILE_GENERIC_WRITE && md.permissions().readonly() {\n                return Err(io::Error::new(\n                    io::ErrorKind::PermissionDenied,\n                    \"File is read only\",\n                ));\n            }\n\n            // If it doesn't have the correct extension it isn't executable\n            if mode & FILE_GENERIC_EXECUTE == FILE_GENERIC_EXECUTE {\n                if let Some(ext) = p.extension().and_then(|s| s.to_str()) {\n                    match ext {\n                        \"exe\" | \"com\" | \"bat\" | \"cmd\" => (),\n                        _ => {\n                            return Err(io::Error::new(\n                                io::ErrorKind::InvalidData,\n                                \"File not executable\",\n                            ))\n                        }\n                    }\n                }\n            }\n\n            return std::fs::OpenOptions::new()\n                .access_mode(mode)\n                .open(p)\n                .map(|_| ());\n        }\n\n        let sd = SecurityDescriptor::for_path(p)?;\n\n        // Unmapped Samba users are assigned a top level authority of 22\n        // ACL tests are likely to be misleading\n        const SAMBA_UNMAPPED: SID_IDENTIFIER_AUTHORITY = SID_IDENTIFIER_AUTHORITY {\n            Value: [0, 0, 0, 0, 0, 22],\n        };\n        unsafe {\n            let owner = sd.owner();\n            if IsValidSid(*owner) != 0\n                && (*GetSidIdentifierAuthority(*owner)).Value == SAMBA_UNMAPPED.Value\n            {\n                return Ok(());\n            }\n        }\n\n        let token = ThreadToken::new()?;\n\n        let mut privileges: PRIVILEGE_SET = unsafe { std::mem::zeroed() };\n        let mut granted_access: u32 = 0;\n        let mut privileges_length = std::mem::size_of::<PRIVILEGE_SET>() as u32;\n        let mut result = 0;\n\n        let mapping = GENERIC_MAPPING {\n            GenericRead: FILE_GENERIC_READ,\n            GenericWrite: FILE_GENERIC_WRITE,\n            GenericExecute: FILE_GENERIC_EXECUTE,\n            GenericAll: FILE_ALL_ACCESS,\n        };\n\n        unsafe { MapGenericMask(&mut mode, &mapping) };\n\n        if unsafe {\n            AccessCheck(\n                *sd.descriptor(),\n                *token.as_handle(),\n                mode,\n                &mapping,\n                &mut privileges,\n                &mut privileges_length,\n                &mut granted_access,\n                &mut result,\n            )\n        } != 0\n        {\n            if result == 0 {\n                Err(io::Error::new(\n                    io::ErrorKind::PermissionDenied,\n                    \"Permission Denied\",\n                ))\n            } else {\n                Ok(())\n            }\n        } else {\n            Err(io::Error::last_os_error())\n        }\n    }\n\n    pub fn access(p: &Path, mode: AccessMode) -> io::Result<()> {\n        let mut imode = 0;\n\n        if mode.contains(AccessMode::READ) {\n            imode |= FILE_GENERIC_READ;\n        }\n\n        if mode.contains(AccessMode::WRITE) {\n            imode |= FILE_GENERIC_WRITE;\n        }\n\n        if mode.contains(AccessMode::EXECUTE) {\n            imode |= FILE_GENERIC_EXECUTE;\n        }\n\n        if imode == 0 {\n            if p.exists() {\n                Ok(())\n            } else {\n                Err(io::Error::new(io::ErrorKind::NotFound, \"Not Found\"))\n            }\n        } else {\n            eaccess(p, imode)\n        }\n    }\n\n    fn chown(p: &Path, sd: SecurityDescriptor) -> io::Result<()> {\n        let path = std::fs::canonicalize(p)?;\n        let pathos = path.as_os_str();\n        let mut pathw = Vec::with_capacity(pathos.len() + 1);\n        pathw.extend(pathos.encode_wide());\n        pathw.push(0);\n\n        let mut owner = std::ptr::null_mut();\n        let mut group = std::ptr::null_mut();\n        let mut dacl = std::ptr::null();\n\n        let mut si = OBJECT_SECURITY_INFORMATION::default();\n        if unsafe { IsValidSid(sd.owner) } != 0 {\n            si |= OWNER_SECURITY_INFORMATION;\n            owner = sd.owner;\n        }\n\n        if unsafe { IsValidSid(sd.group) } != 0 {\n            si |= GROUP_SECURITY_INFORMATION;\n            group = sd.group;\n        }\n\n        if unsafe { IsValidAcl(sd.dacl) } != 0 {\n            si |= DACL_SECURITY_INFORMATION;\n            if !sd.is_acl_inherited() {\n                si |= PROTECTED_DACL_SECURITY_INFORMATION;\n            }\n            dacl = sd.dacl as *const _;\n        }\n\n        let err = unsafe {\n            SetNamedSecurityInfoW(\n                pathw.as_ptr(),\n                SE_FILE_OBJECT,\n                si,\n                owner,\n                group,\n                dacl,\n                std::ptr::null(),\n            )\n        };\n\n        if err == ERROR_SUCCESS {\n            Ok(())\n        } else {\n            Err(io::Error::last_os_error())\n        }\n    }\n\n    pub fn copy_metadata(from: &Path, to: &Path) -> io::Result<()> {\n        let sd = SecurityDescriptor::for_path(from)?;\n        chown(to, sd)?;\n\n        let meta = std::fs::metadata(from)?;\n        let perms = meta.permissions();\n\n        let to_file = File::options().write(true).open(to)?;\n        let times = FileTimes::new().set_created(meta.created()?);\n        to_file.set_times(times)?;\n\n        std::fs::set_permissions(to, perms)?;\n\n        Ok(())\n    }\n\n    pub fn hardlink_count(p: &Path) -> std::io::Result<u64> {\n        let file = std::fs::File::open(p)?;\n        let handle = file.as_raw_handle();\n        let mut info: BY_HANDLE_FILE_INFORMATION = unsafe { std::mem::zeroed() };\n\n        if unsafe { GetFileInformationByHandle(handle, &mut info) } == 0 {\n            Err(std::io::Error::last_os_error())\n        } else {\n            Ok(info.nNumberOfLinks as u64)\n        }\n    }\n}\n\n// Licensed under MIT from faccess except for `copy_metadata`\n#[cfg(not(any(unix, windows)))]\nmod imp {\n    use super::*;\n\n    pub fn access(p: &Path, mode: AccessMode) -> io::Result<()> {\n        if mode.contains(AccessMode::WRITE) {\n            if std::fs::metadata(p)?.permissions().readonly() {\n                return Err(io::Error::new(\n                    io::ErrorKind::PermissionDenied,\n                    \"Path is read only\",\n                ));\n            } else {\n                return Ok(());\n            }\n        }\n\n        if p.exists() {\n            Ok(())\n        } else {\n            Err(io::Error::new(io::ErrorKind::NotFound, \"Path not found\"))\n        }\n    }\n\n    pub fn copy_metadata(from: &path, to: &Path) -> io::Result<()> {\n        let meta = std::fs::metadata(from)?;\n        let perms = meta.permissions();\n        std::fs::set_permissions(to, perms)?;\n\n        Ok(())\n    }\n}\n\npub fn readonly(p: &Path) -> bool {\n    match imp::access(p, AccessMode::WRITE) {\n        Ok(_) => false,\n        Err(err) if err.kind() == std::io::ErrorKind::NotFound => false,\n        Err(_) => true,\n    }\n}\n\npub fn copy_metadata(from: &Path, to: &Path) -> io::Result<()> {\n    imp::copy_metadata(from, to)\n}\n\npub fn hardlink_count(p: &Path) -> io::Result<u64> {\n    imp::hardlink_count(p)\n}\n"
  },
  {
    "path": "helix-stdx/src/lib.rs",
    "content": "//! Extensions to the standard library. A collection of helper functions\n//! used throughout helix.\n\npub mod env;\npub mod faccess;\npub mod path;\npub mod range;\npub mod rope;\n\npub use range::Range;\n"
  },
  {
    "path": "helix-stdx/src/path.rs",
    "content": "//! Functions for working with [Path].\n\npub use etcetera::home_dir;\nuse once_cell::sync::Lazy;\nuse regex_cursor::{engines::meta::Regex, Input};\nuse ropey::RopeSlice;\n\nuse std::{\n    borrow::Cow,\n    ffi::OsString,\n    ops::Range,\n    path::{Component, Path, PathBuf, MAIN_SEPARATOR_STR},\n};\n\nuse crate::env::current_working_dir;\n\n/// Replaces users home directory from `path` with tilde `~` if the directory\n/// is available, otherwise returns the path unchanged.\npub fn fold_home_dir<'a, P>(path: P) -> Cow<'a, Path>\nwhere\n    P: Into<Cow<'a, Path>>,\n{\n    let path = path.into();\n    if let Ok(home) = home_dir() {\n        if let Ok(stripped) = path.strip_prefix(&home) {\n            let mut path = OsString::with_capacity(2 + stripped.as_os_str().len());\n            path.push(\"~\");\n            path.push(MAIN_SEPARATOR_STR);\n            path.push(stripped);\n            return Cow::Owned(PathBuf::from(path));\n        }\n    }\n\n    path\n}\n\n/// Expands tilde `~` into users home directory if available, otherwise returns the path\n/// unchanged.\n///\n/// The tilde will only be expanded when present as the first component of the path\n/// and only slash follows it.\npub fn expand_tilde<'a, P>(path: P) -> Cow<'a, Path>\nwhere\n    P: Into<Cow<'a, Path>>,\n{\n    let path = path.into();\n    let mut components = path.components();\n    if let Some(Component::Normal(c)) = components.next() {\n        if c == \"~\" {\n            if let Ok(mut buf) = home_dir() {\n                buf.push(components);\n                return Cow::Owned(buf);\n            }\n        }\n    }\n\n    path\n}\n\n/// Normalize a path without resolving symlinks.\n// Strategy: start from the first component and move up. Canonicalize previous path,\n// join component, canonicalize new path, strip prefix and join to the final result.\npub fn normalize(path: impl AsRef<Path>) -> PathBuf {\n    let mut components = path.as_ref().components().peekable();\n    let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().copied() {\n        components.next();\n        PathBuf::from(c.as_os_str())\n    } else {\n        PathBuf::new()\n    };\n\n    for component in components {\n        match component {\n            Component::Prefix(..) => unreachable!(),\n            Component::RootDir => {\n                ret.push(component.as_os_str());\n            }\n            Component::CurDir => {}\n            #[cfg(not(windows))]\n            Component::ParentDir => {\n                ret.pop();\n            }\n            #[cfg(windows)]\n            Component::ParentDir => {\n                if let Some(head) = ret.components().next_back() {\n                    match head {\n                        Component::Prefix(_) | Component::RootDir => {}\n                        Component::CurDir => unreachable!(),\n                        // If we left previous component as \"..\" it means we met a symlink before and we can't pop path.\n                        Component::ParentDir => {\n                            ret.push(\"..\");\n                        }\n                        Component::Normal(_) => {\n                            if ret.is_symlink() {\n                                ret.push(\"..\");\n                            } else {\n                                ret.pop();\n                            }\n                        }\n                    }\n                }\n            }\n            #[cfg(not(windows))]\n            Component::Normal(c) => {\n                ret.push(c);\n            }\n            #[cfg(windows)]\n            Component::Normal(c) => 'normal: {\n                use std::fs::canonicalize;\n\n                let new_path = ret.join(c);\n                if new_path.is_symlink() {\n                    ret = new_path;\n                    break 'normal;\n                }\n                let (can_new, can_old) = (canonicalize(&new_path), canonicalize(&ret));\n                match (can_new, can_old) {\n                    (Ok(can_new), Ok(can_old)) => {\n                        let striped = can_new.strip_prefix(can_old);\n                        ret.push(striped.unwrap_or_else(|_| c.as_ref()));\n                    }\n                    _ => ret.push(c),\n                }\n            }\n        }\n    }\n    dunce::simplified(&ret).to_path_buf()\n}\n\n/// Returns the canonical, absolute form of a path with all intermediate components normalized.\n///\n/// This function is used instead of [`std::fs::canonicalize`] because we don't want to verify\n/// here if the path exists, just normalize it's components.\npub fn canonicalize(path: impl AsRef<Path>) -> PathBuf {\n    let path = expand_tilde(path.as_ref());\n    let path = if path.is_relative() {\n        Cow::Owned(current_working_dir().join(path))\n    } else {\n        path\n    };\n\n    normalize(path)\n}\n\n/// Convert path into a relative path\npub fn get_relative_path<'a, P>(path: P) -> Cow<'a, Path>\nwhere\n    P: Into<Cow<'a, Path>>,\n{\n    let path = path.into();\n    if path.is_absolute() {\n        let cwdir = normalize(current_working_dir());\n        if let Ok(stripped) = normalize(&path).strip_prefix(cwdir) {\n            return Cow::Owned(PathBuf::from(stripped));\n        }\n\n        return fold_home_dir(path);\n    }\n\n    path\n}\n\n/// Returns a truncated filepath where the basepart of the path is reduced to the first\n/// char of the folder and the whole filename appended.\n///\n/// Also strip the current working directory from the beginning of the path.\n/// Note that this function does not check if the truncated path is unambiguous.\n///\n/// ```\n///    use helix_stdx::path::get_truncated_path;\n///    use std::path::Path;\n///\n///    assert_eq!(\n///         get_truncated_path(\"/home/cnorris/documents/jokes.txt\").as_path(),\n///         Path::new(\"/h/c/d/jokes.txt\")\n///     );\n///     assert_eq!(\n///         get_truncated_path(\"jokes.txt\").as_path(),\n///         Path::new(\"jokes.txt\")\n///     );\n///     assert_eq!(\n///         get_truncated_path(\"/jokes.txt\").as_path(),\n///         Path::new(\"/jokes.txt\")\n///     );\n///     assert_eq!(\n///         get_truncated_path(\"/h/c/d/jokes.txt\").as_path(),\n///         Path::new(\"/h/c/d/jokes.txt\")\n///     );\n///     assert_eq!(get_truncated_path(\"\").as_path(), Path::new(\"\"));\n/// ```\n///\npub fn get_truncated_path(path: impl AsRef<Path>) -> PathBuf {\n    let cwd = current_working_dir();\n    let path = path.as_ref();\n    let path = path.strip_prefix(cwd).unwrap_or(path);\n    let file = path.file_name().unwrap_or_default();\n    let base = path.parent().unwrap_or_else(|| Path::new(\"\"));\n    let mut ret = PathBuf::with_capacity(file.len());\n    // A char can't be directly pushed to a PathBuf\n    let mut first_char_buffer = String::new();\n    for d in base {\n        let Some(first_char) = d.to_string_lossy().chars().next() else {\n            break;\n        };\n        first_char_buffer.push(first_char);\n        ret.push(&first_char_buffer);\n        first_char_buffer.clear();\n    }\n    ret.push(file);\n    ret\n}\n\nfn path_component_regex(windows: bool) -> String {\n    // TODO: support backslash path escape on windows (when using git bash for example)\n    let space_escape = if windows { r\"[\\^`]\\s\" } else { r\"[\\\\]\\s\" };\n    // partially baesd on what's allowed in an url but with some care to avoid\n    // false positives (like any kind of brackets or quotes)\n    r\"[\\w@.\\-+#$%?!,;~&]|\".to_owned() + space_escape\n}\n\n/// Regex for delimited environment captures like `${HOME}`.\nfn braced_env_regex(windows: bool) -> String {\n    r\"\\$\\{(?:\".to_owned() + &path_component_regex(windows) + r\"|[/:=])+\\}\"\n}\n\nfn compile_path_regex(\n    prefix: &str,\n    postfix: &str,\n    match_single_file: bool,\n    windows: bool,\n) -> Regex {\n    let first_component = format!(\n        \"(?:{}|(?:{}))\",\n        braced_env_regex(windows),\n        path_component_regex(windows)\n    );\n    // For all components except the first we allow an equals so that `foo=/\n    // bar/baz` does not include foo. This is primarily intended for url queries\n    // (where an equals is never in the first component)\n    let component = format!(\"(?:{first_component}|=)\");\n    let sep = if windows { r\"[/\\\\]\" } else { \"/\" };\n    let url_prefix = r\"[\\w+\\-.]+://??\";\n    let path_prefix = if windows {\n        // single slash handles most windows prefixes (like\\\\server\\...) but `\\\n        // \\?\\C:\\..` (and C:\\) needs special handling, since we don't allow : in path\n        // components (so that colon separated paths and <path>:<line> work)\n        r\"\\\\\\\\\\?\\\\\\w:|\\w:|\\\\|\"\n    } else {\n        \"\"\n    };\n    let path_start = format!(\"(?:{first_component}+|~|{path_prefix}{url_prefix})\");\n    let optional = if match_single_file {\n        format!(\"|{path_start}\")\n    } else {\n        String::new()\n    };\n    let path_regex = format!(\n        \"{prefix}(?:{path_start}?(?:(?:{sep}{component}+)+{sep}?|{sep}){optional}){postfix}\"\n    );\n    Regex::new(&path_regex).unwrap()\n}\n\n/// If `src` ends with a path then this function returns the part of the slice.\npub fn get_path_suffix(src: RopeSlice<'_>, match_single_file: bool) -> Option<RopeSlice<'_>> {\n    let regex = if match_single_file {\n        static REGEX: Lazy<Regex> = Lazy::new(|| compile_path_regex(\"\", \"$\", true, cfg!(windows)));\n        &*REGEX\n    } else {\n        static REGEX: Lazy<Regex> = Lazy::new(|| compile_path_regex(\"\", \"$\", false, cfg!(windows)));\n        &*REGEX\n    };\n\n    regex\n        .find(Input::new(src))\n        .map(|mat| src.byte_slice(mat.range()))\n}\n\n/// Returns an iterator of the **byte** ranges in src that contain a path.\npub fn find_paths(\n    src: RopeSlice<'_>,\n    match_single_file: bool,\n) -> impl Iterator<Item = Range<usize>> + '_ {\n    let regex = if match_single_file {\n        static REGEX: Lazy<Regex> = Lazy::new(|| compile_path_regex(\"\", \"\", true, cfg!(windows)));\n        &*REGEX\n    } else {\n        static REGEX: Lazy<Regex> = Lazy::new(|| compile_path_regex(\"\", \"\", false, cfg!(windows)));\n        &*REGEX\n    };\n    regex.find_iter(Input::new(src)).map(|mat| mat.range())\n}\n\n/// Performs substitution of `~` and environment variables, see [`env::expand`](crate::env::expand) and [`expand_tilde`]\npub fn expand<T: AsRef<Path> + ?Sized>(path: &T) -> Cow<'_, Path> {\n    let path = path.as_ref();\n    let path = expand_tilde(path);\n    match crate::env::expand(&*path) {\n        Cow::Borrowed(_) => path,\n        Cow::Owned(path) => PathBuf::from(path).into(),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::{\n        ffi::OsStr,\n        path::{Component, Path},\n    };\n\n    use regex_cursor::Input;\n    use ropey::RopeSlice;\n\n    use crate::path::{self, compile_path_regex};\n\n    #[test]\n    fn expand_tilde() {\n        for path in [\"~\", \"~/foo\"] {\n            let expanded = path::expand_tilde(Path::new(path));\n\n            let tilde = Component::Normal(OsStr::new(\"~\"));\n\n            let mut component_count = 0;\n            for component in expanded.components() {\n                // No tilde left.\n                assert_ne!(component, tilde);\n                component_count += 1;\n            }\n\n            // The path was at least expanded to something.\n            assert_ne!(component_count, 0);\n        }\n    }\n\n    macro_rules! assert_match {\n        ($regex: expr, $haystack: expr) => {\n            let haystack = Input::new(RopeSlice::from($haystack));\n            assert!(\n                $regex.is_match(haystack),\n                \"regex should match {}\",\n                $haystack\n            );\n        };\n    }\n    macro_rules! assert_no_match {\n        ($regex: expr, $haystack: expr) => {\n            let haystack = Input::new(RopeSlice::from($haystack));\n            assert!(\n                !$regex.is_match(haystack),\n                \"regex should not match {}\",\n                $haystack\n            );\n        };\n    }\n\n    macro_rules! assert_matches {\n        ($regex: expr, $haystack: expr, [$($matches: expr),*]) => {\n            let src = $haystack;\n            let matches: Vec<_> = $regex\n                .find_iter(Input::new(RopeSlice::from(src)))\n                .map(|it| &src[it.range()])\n                .collect();\n            assert_eq!(matches, vec![$($matches),*]);\n        };\n    }\n\n    /// Linux-only path\n    #[test]\n    fn path_regex_unix() {\n        // due to ambiguity with the `\\` path separator we can't support space escapes `\\ ` on windows\n        let regex = compile_path_regex(\"^\", \"$\", false, false);\n        assert_match!(regex, \"${FOO}/hello\\\\ world\");\n        assert_match!(regex, \"${FOO}/\\\\ \");\n    }\n\n    /// Windows-only paths\n    #[test]\n    fn path_regex_windows() {\n        let regex = compile_path_regex(\"^\", \"$\", false, true);\n        assert_match!(regex, \"${FOO}/hello^ world\");\n        assert_match!(regex, \"${FOO}/hello` world\");\n        assert_match!(regex, \"${FOO}/^ \");\n        assert_match!(regex, \"${FOO}/` \");\n        assert_match!(regex, r\"foo\\bar\");\n        assert_match!(regex, r\"foo\\bar\");\n        assert_match!(regex, r\"..\\bar\");\n        assert_match!(regex, r\"..\\\");\n        assert_match!(regex, r\"C:\\\");\n        assert_match!(regex, r\"\\\\?\\C:\\foo\");\n        assert_match!(regex, r\"\\\\server\\foo\");\n    }\n\n    /// Paths that should work on all platforms\n    #[test]\n    fn path_regex() {\n        for windows in [false, true] {\n            let regex = compile_path_regex(\"^\", \"$\", false, windows);\n            assert_no_match!(regex, \"foo\");\n            assert_no_match!(regex, \"\");\n            assert_match!(regex, \"https://github.com/notifications/query=foo\");\n            assert_match!(regex, \"file:///foo/bar\");\n            assert_match!(regex, \"foo/bar\");\n            assert_match!(regex, \"$HOME/foo\");\n            assert_match!(regex, \"${FOO:-bar}/baz\");\n            assert_match!(regex, \"foo/bar_\");\n            assert_match!(regex, \"/home/bar\");\n            assert_match!(regex, \"foo/\");\n            assert_match!(regex, \"./\");\n            assert_match!(regex, \"../\");\n            assert_match!(regex, \"../..\");\n            assert_match!(regex, \"./foo\");\n            assert_match!(regex, \"./foo.rs\");\n            assert_match!(regex, \"/\");\n            assert_match!(regex, \"~/\");\n            assert_match!(regex, \"~/foo\");\n            assert_match!(regex, \"~/foo\");\n            assert_match!(regex, \"~/foo/../baz\");\n            assert_match!(regex, \"${HOME}/foo\");\n            assert_match!(regex, \"$HOME/foo\");\n            assert_match!(regex, \"/$FOO\");\n            assert_match!(regex, \"/${FOO}\");\n            assert_match!(regex, \"/${FOO}/${BAR}\");\n            assert_match!(regex, \"/${FOO}/${BAR}/foo\");\n            assert_match!(regex, \"/${FOO}/${BAR}\");\n            assert_match!(regex, \"${FOO}/hello_$WORLD\");\n            assert_match!(regex, \"${FOO}/hello_${WORLD}\");\n            let regex = compile_path_regex(\"\", \"\", false, windows);\n            assert_no_match!(regex, \"\");\n            assert_matches!(\n                regex,\n                r#\"${FOO}/hello_${WORLD}  ${FOO}/hello_${WORLD} foo(\"./bar\", \"/home/foo\")\"\"#,\n                [\n                    \"${FOO}/hello_${WORLD}\",\n                    \"${FOO}/hello_${WORLD}\",\n                    \"./bar\",\n                    \"/home/foo\"\n                ]\n            );\n            assert_matches!(\n                regex,\n                r#\"--> helix-stdx/src/path.rs:427:13\"#,\n                [\"helix-stdx/src/path.rs\"]\n            );\n            assert_matches!(\n                regex,\n                r#\"PATH=/foo/bar:/bar/baz:${foo:-/foo}/bar:${PATH}\"#,\n                [\"/foo/bar\", \"/bar/baz\", \"${foo:-/foo}/bar\"]\n            );\n            let regex = compile_path_regex(\"^\", \"$\", true, windows);\n            assert_no_match!(regex, \"\");\n            assert_match!(regex, \"foo\");\n            assert_match!(regex, \"foo/\");\n            assert_match!(regex, \"$FOO\");\n            assert_match!(regex, \"${BAR}\");\n        }\n    }\n}\n"
  },
  {
    "path": "helix-stdx/src/range.rs",
    "content": "//! Provides [Range] type expanding on [RangeBounds].\n\nuse std::ops::{self, RangeBounds};\n\n/// A range of `char`s within the text.\n#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]\npub struct Range<T = usize> {\n    pub start: T,\n    pub end: T,\n}\n\nimpl<T: PartialOrd> Range<T> {\n    pub fn contains(&self, other: Self) -> bool {\n        self.start <= other.start && other.end <= self.end\n    }\n    pub fn is_empty(&self) -> bool {\n        self.end <= self.start\n    }\n}\n\nimpl<T> RangeBounds<T> for Range<T> {\n    fn start_bound(&self) -> ops::Bound<&T> {\n        ops::Bound::Included(&self.start)\n    }\n\n    fn end_bound(&self) -> ops::Bound<&T> {\n        ops::Bound::Excluded(&self.end)\n    }\n}\n\n/// Returns true if all ranges yielded by `sub_set` are contained by\n/// `super_set`. This is essentially an optimized implementation of\n/// `sub_set.all(|rb| super_set.any(|ra| ra.contains(rb)))` that runs in O(m+n)\n/// instead of O(mn) (and in many cases faster).\n///\n/// Both iterators must uphold a the following invariants:\n/// * ranges must not overlap (but they can be adjacent)\n/// * ranges must be sorted\npub fn is_subset<const ALLOW_EMPTY: bool>(\n    mut super_set: impl Iterator<Item = Range>,\n    mut sub_set: impl Iterator<Item = Range>,\n) -> bool {\n    let (mut super_range, mut sub_range) = (super_set.next(), sub_set.next());\n    loop {\n        match (super_range, sub_range) {\n            // skip over irrelevant ranges\n            (Some(ra), Some(rb))\n                if ra.end <= rb.start && (ra.start != rb.start || !ALLOW_EMPTY) =>\n            {\n                super_range = super_set.next();\n            }\n            (Some(ra), Some(rb)) => {\n                if ra.contains(rb) {\n                    sub_range = sub_set.next();\n                } else {\n                    return false;\n                }\n            }\n            (None, Some(_)) => {\n                // exhausted `super_set`, we can't match the reminder of `sub_set`\n                return false;\n            }\n            (_, None) => {\n                // no elements from `sub_sut` left to match, `super_set` contains `sub_set`\n                return true;\n            }\n        }\n    }\n}\n\n/// Similar to is_subset but requires each element of `super_set` to be matched\npub fn is_exact_subset(\n    mut super_set: impl Iterator<Item = Range>,\n    mut sub_set: impl Iterator<Item = Range>,\n) -> bool {\n    let (mut super_range, mut sub_range) = (super_set.next(), sub_set.next());\n    let mut super_range_matched = true;\n    loop {\n        match (super_range, sub_range) {\n            // skip over irrelevant ranges\n            (Some(ra), Some(rb)) if ra.end <= rb.start && ra.start < rb.start => {\n                if !super_range_matched {\n                    return false;\n                }\n                super_range_matched = false;\n                super_range = super_set.next();\n            }\n            (Some(ra), Some(rb)) => {\n                if ra.contains(rb) {\n                    super_range_matched = true;\n                    sub_range = sub_set.next();\n                } else {\n                    return false;\n                }\n            }\n            (None, Some(_)) => {\n                // exhausted `super_set`, we can't match the reminder of `sub_set`\n                return false;\n            }\n            (_, None) => {\n                // no elements from `sub_sut` left to match, `super_set` contains `sub_set`\n                return super_set.next().is_none();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "helix-stdx/src/rope.rs",
    "content": "//! Functions and types for working with [RopeSlice]\nuse std::fmt;\nuse std::ops::{Bound, RangeBounds};\n\npub use regex_cursor::engines::meta::{Builder as RegexBuilder, Regex};\npub use regex_cursor::regex_automata::util::syntax::Config;\nuse regex_cursor::{Input as RegexInput, RopeyCursor};\nuse ropey::iter::Chunks;\nuse ropey::RopeSlice;\nuse unicode_segmentation::{GraphemeCursor, GraphemeIncomplete};\n\n/// Additional utility functions for [RopeSlice]\npub trait RopeSliceExt<'a>: Sized {\n    fn ends_with(self, text: &str) -> bool;\n    fn starts_with(self, text: &str) -> bool;\n    fn regex_input(self) -> RegexInput<RopeyCursor<'a>>;\n    fn regex_input_at_bytes<R: RangeBounds<usize>>(\n        self,\n        byte_range: R,\n    ) -> RegexInput<RopeyCursor<'a>>;\n    fn regex_input_at<R: RangeBounds<usize>>(self, char_range: R) -> RegexInput<RopeyCursor<'a>>;\n    fn first_non_whitespace_char(self) -> Option<usize>;\n    fn last_non_whitespace_char(self) -> Option<usize>;\n    /// Finds the closest byte index not exceeding `byte_idx` which lies on a character boundary.\n    ///\n    /// If `byte_idx` already lies on a character boundary then it is returned as-is. When\n    /// `byte_idx` lies between two character boundaries, this function returns the byte index of\n    /// the lesser / earlier / left-hand-side boundary.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::RopeSlice;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = RopeSlice::from(\"⌚\"); // three bytes: e2 8c 9a\n    /// assert_eq!(text.floor_char_boundary(0), 0);\n    /// assert_eq!(text.floor_char_boundary(1), 0);\n    /// assert_eq!(text.floor_char_boundary(2), 0);\n    /// assert_eq!(text.floor_char_boundary(3), 3);\n    /// ```\n    fn floor_char_boundary(self, byte_idx: usize) -> usize;\n    /// Finds the closest byte index not below `byte_idx` which lies on a character boundary.\n    ///\n    /// If `byte_idx` already lies on a character boundary then it is returned as-is. When\n    /// `byte_idx` lies between two character boundaries, this function returns the byte index of\n    /// the greater / later / right-hand-side boundary.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::RopeSlice;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = RopeSlice::from(\"⌚\"); // three bytes: e2 8c 9a\n    /// assert_eq!(text.ceil_char_boundary(0), 0);\n    /// assert_eq!(text.ceil_char_boundary(1), 3);\n    /// assert_eq!(text.ceil_char_boundary(2), 3);\n    /// assert_eq!(text.ceil_char_boundary(3), 3);\n    /// ```\n    fn ceil_char_boundary(self, byte_idx: usize) -> usize;\n    /// Checks whether the given `byte_idx` lies on a character boundary.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::RopeSlice;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = RopeSlice::from(\"⌚\"); // three bytes: e2 8c 9a\n    /// assert!(text.is_char_boundary(0));\n    /// assert!(!text.is_char_boundary(1));\n    /// assert!(!text.is_char_boundary(2));\n    /// assert!(text.is_char_boundary(3));\n    /// ```\n    #[allow(clippy::wrong_self_convention)]\n    fn is_char_boundary(self, byte_idx: usize) -> bool;\n    /// Finds the closest byte index not exceeding `byte_idx` which lies on a grapheme cluster\n    /// boundary.\n    ///\n    /// If `byte_idx` already lies on a grapheme cluster boundary then it is returned as-is. When\n    /// `byte_idx` lies between two grapheme cluster boundaries, this function returns the byte\n    /// index of the lesser / earlier / left-hand-side boundary.\n    ///\n    /// `byte_idx` does not need to be aligned to a character boundary.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::RopeSlice;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = RopeSlice::from(\"\\r\\n\"); // U+000D U+000A, hex: 0d 0a\n    /// assert_eq!(text.floor_grapheme_boundary(0), 0);\n    /// assert_eq!(text.floor_grapheme_boundary(1), 0);\n    /// assert_eq!(text.floor_grapheme_boundary(2), 2);\n    /// ```\n    fn floor_grapheme_boundary(self, byte_idx: usize) -> usize;\n    /// Finds the closest byte index not exceeding `byte_idx` which lies on a grapheme cluster\n    /// boundary.\n    ///\n    /// If `byte_idx` already lies on a grapheme cluster boundary then it is returned as-is. When\n    /// `byte_idx` lies between two grapheme cluster boundaries, this function returns the byte\n    /// index of the greater / later / right-hand-side boundary.\n    ///\n    /// `byte_idx` does not need to be aligned to a character boundary.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::RopeSlice;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = RopeSlice::from(\"\\r\\n\"); // U+000D U+000A, hex: 0d 0a\n    /// assert_eq!(text.ceil_grapheme_boundary(0), 0);\n    /// assert_eq!(text.ceil_grapheme_boundary(1), 2);\n    /// assert_eq!(text.ceil_grapheme_boundary(2), 2);\n    /// ```\n    fn ceil_grapheme_boundary(self, byte_idx: usize) -> usize;\n    /// Checks whether the `byte_idx` lies on a grapheme cluster boundary.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::RopeSlice;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = RopeSlice::from(\"\\r\\n\"); // U+000D U+000A, hex: 0d 0a\n    /// assert!(text.is_grapheme_boundary(0));\n    /// assert!(!text.is_grapheme_boundary(1));\n    /// assert!(text.is_grapheme_boundary(2));\n    /// ```\n    #[allow(clippy::wrong_self_convention)]\n    fn is_grapheme_boundary(self, byte_idx: usize) -> bool;\n    /// Returns an iterator over the grapheme clusters in the slice.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::RopeSlice;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = RopeSlice::from(\"😶‍🌫️🏴‍☠️🖼️\");\n    /// let graphemes: Vec<_> = text.graphemes().collect();\n    /// assert_eq!(graphemes.as_slice(), &[\"😶‍🌫️\", \"🏴‍☠️\", \"🖼️\"]);\n    /// ```\n    fn graphemes(self) -> RopeGraphemes<'a> {\n        self.graphemes_at(0)\n    }\n    /// Returns an iterator over the grapheme clusters in the slice, reversed.\n    ///\n    /// The returned iterator starts at the end of the slice and ends at the beginning of the\n    /// slice.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::RopeSlice;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = RopeSlice::from(\"😶‍🌫️🏴‍☠️🖼️\");\n    /// let graphemes: Vec<_> = text.graphemes_rev().collect();\n    /// assert_eq!(graphemes.as_slice(), &[\"🖼️\", \"🏴‍☠️\", \"😶‍🌫️\"]);\n    /// ```\n    fn graphemes_rev(self) -> RopeGraphemes<'a>;\n    /// Returns an iterator over the grapheme clusters in the slice at the given byte index.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::Rope;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = Rope::from_str(\"😶‍🌫️🏴‍☠️🖼️\");\n    /// // 14 is the byte index of the pirate flag's starting cluster boundary.\n    /// let graphemes: Vec<_> = text.slice(..).graphemes_at(14).collect();\n    /// assert_eq!(graphemes.as_slice(), &[\"🏴‍☠️\", \"🖼️\"]);\n    /// // 27 is the byte index of the pirate flag's ending cluster boundary.\n    /// let graphemes: Vec<_> = text.slice(..).graphemes_at(27).reversed().collect();\n    /// assert_eq!(graphemes.as_slice(), &[\"🏴‍☠️\", \"😶‍🌫️\"]);\n    /// ```\n    fn graphemes_at(self, byte_idx: usize) -> RopeGraphemes<'a>;\n    /// Returns an iterator over the grapheme clusters in a rope and the byte index where each\n    /// grapheme cluster starts.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::Rope;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = Rope::from_str(\"😶‍🌫️🏴‍☠️🖼️\");\n    /// let slice = text.slice(..);\n    /// let graphemes: Vec<_> = slice.grapheme_indices_at(0).collect();\n    /// assert_eq!(\n    ///   graphemes.as_slice(),\n    ///   &[(0, \"😶‍🌫️\".into()), (14, \"🏴‍☠️\".into()), (27, \"🖼️\".into())]\n    /// );\n    /// let graphemes: Vec<_> = slice.grapheme_indices_at(slice.len_bytes()).reversed().collect();\n    /// assert_eq!(\n    ///   graphemes.as_slice(),\n    ///   &[(27, \"🖼️\".into()), (14, \"🏴‍☠️\".into()), (0, \"😶‍🌫️\".into())]\n    /// );\n    /// ```\n    fn grapheme_indices_at(self, byte_idx: usize) -> RopeGraphemeIndices<'a>;\n    /// Finds the byte index of the next grapheme boundary after `byte_idx`.\n    ///\n    /// If the byte index lies on the last grapheme cluster in the slice then this function\n    /// returns `RopeSlice::len_bytes`.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::Rope;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = Rope::from_str(\"😶‍🌫️🏴‍☠️🖼️\");\n    /// let slice = text.slice(..);\n    /// let mut byte_idx = 0;\n    /// assert_eq!(slice.graphemes_at(byte_idx).next(), Some(\"😶‍🌫️\".into()));\n    /// byte_idx = slice.next_grapheme_boundary(byte_idx);\n    /// assert_eq!(slice.graphemes_at(byte_idx).next(), Some(\"🏴‍☠️\".into()));\n    ///\n    /// // If `byte_idx` does not lie on a character or grapheme boundary then this function is\n    /// // functionally the same as `ceil_grapheme_boundary`.\n    /// assert_eq!(slice.next_grapheme_boundary(byte_idx - 1), byte_idx);\n    /// assert_eq!(slice.next_grapheme_boundary(byte_idx - 2), byte_idx);\n    /// assert_eq!(slice.next_grapheme_boundary(byte_idx + 1), slice.next_grapheme_boundary(byte_idx));\n    /// assert_eq!(slice.next_grapheme_boundary(byte_idx + 2), slice.next_grapheme_boundary(byte_idx));\n    ///\n    /// byte_idx = slice.next_grapheme_boundary(byte_idx);\n    /// assert_eq!(slice.graphemes_at(byte_idx).next(), Some(\"🖼️\".into()));\n    /// byte_idx = slice.next_grapheme_boundary(byte_idx);\n    /// assert_eq!(slice.graphemes_at(byte_idx).next(), None);\n    /// assert_eq!(byte_idx, slice.len_bytes());\n    /// ```\n    fn next_grapheme_boundary(self, byte_idx: usize) -> usize {\n        self.nth_next_grapheme_boundary(byte_idx, 1)\n    }\n    /// Finds the byte index of the `n`th grapheme cluster after the given `byte_idx`.\n    ///\n    /// If there are fewer than `n` grapheme clusters after `byte_idx` in the rope then this\n    /// function returns `RopeSlice::len_bytes`.\n    ///\n    /// This is functionally equivalent to calling `next_grapheme_boundary` `n` times but is more\n    /// efficient.\n    fn nth_next_grapheme_boundary(self, byte_idx: usize, n: usize) -> usize;\n    /// Finds the byte index of the previous grapheme boundary before `byte_idx`.\n    ///\n    /// If the byte index lies on the first grapheme cluster in the slice then this function\n    /// returns zero.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use ropey::Rope;\n    /// # use helix_stdx::rope::RopeSliceExt;\n    /// let text = Rope::from_str(\"😶‍🌫️🏴‍☠️🖼️\");\n    /// let slice = text.slice(..);\n    /// let mut byte_idx = text.len_bytes();\n    /// assert_eq!(slice.graphemes_at(byte_idx).prev(), Some(\"🖼️\".into()));\n    /// byte_idx = slice.prev_grapheme_boundary(byte_idx);\n    /// assert_eq!(slice.graphemes_at(byte_idx).prev(), Some(\"🏴‍☠️\".into()));\n    ///\n    /// // If `byte_idx` does not lie on a character or grapheme boundary then this function is\n    /// // functionally the same as `floor_grapheme_boundary`.\n    /// assert_eq!(slice.prev_grapheme_boundary(byte_idx + 1), byte_idx);\n    /// assert_eq!(slice.prev_grapheme_boundary(byte_idx + 2), byte_idx);\n    /// assert_eq!(slice.prev_grapheme_boundary(byte_idx - 1), slice.prev_grapheme_boundary(byte_idx));\n    /// assert_eq!(slice.prev_grapheme_boundary(byte_idx - 2), slice.prev_grapheme_boundary(byte_idx));\n    ///\n    /// byte_idx = slice.prev_grapheme_boundary(byte_idx);\n    /// assert_eq!(slice.graphemes_at(byte_idx).prev(), Some(\"😶‍🌫️\".into()));\n    /// byte_idx = slice.prev_grapheme_boundary(byte_idx);\n    /// assert_eq!(slice.graphemes_at(byte_idx).prev(), None);\n    /// assert_eq!(byte_idx, 0);\n    /// ```\n    fn prev_grapheme_boundary(self, byte_idx: usize) -> usize {\n        self.nth_prev_grapheme_boundary(byte_idx, 1)\n    }\n    /// Finds the byte index of the `n`th grapheme cluster before the given `byte_idx`.\n    ///\n    /// If there are fewer than `n` grapheme clusters before `byte_idx` in the rope then this\n    /// function returns zero.\n    ///\n    /// This is functionally equivalent to calling `prev_grapheme_boundary` `n` times but is more\n    /// efficient.\n    fn nth_prev_grapheme_boundary(self, byte_idx: usize, n: usize) -> usize;\n}\n\nimpl<'a> RopeSliceExt<'a> for RopeSlice<'a> {\n    fn ends_with(self, text: &str) -> bool {\n        let len = self.len_bytes();\n        if len < text.len() {\n            return false;\n        }\n        self.get_byte_slice(len - text.len()..)\n            .is_some_and(|end| end == text)\n    }\n\n    fn starts_with(self, text: &str) -> bool {\n        let len = self.len_bytes();\n        if len < text.len() {\n            return false;\n        }\n        self.get_byte_slice(..text.len())\n            .is_some_and(|start| start == text)\n    }\n\n    fn regex_input(self) -> RegexInput<RopeyCursor<'a>> {\n        RegexInput::new(self)\n    }\n\n    fn regex_input_at<R: RangeBounds<usize>>(self, char_range: R) -> RegexInput<RopeyCursor<'a>> {\n        let start_bound = match char_range.start_bound() {\n            Bound::Included(&val) => Bound::Included(self.char_to_byte(val)),\n            Bound::Excluded(&val) => Bound::Excluded(self.char_to_byte(val)),\n            Bound::Unbounded => Bound::Unbounded,\n        };\n        let end_bound = match char_range.end_bound() {\n            Bound::Included(&val) => Bound::Included(self.char_to_byte(val)),\n            Bound::Excluded(&val) => Bound::Excluded(self.char_to_byte(val)),\n            Bound::Unbounded => Bound::Unbounded,\n        };\n        self.regex_input_at_bytes((start_bound, end_bound))\n    }\n    fn regex_input_at_bytes<R: RangeBounds<usize>>(\n        self,\n        byte_range: R,\n    ) -> RegexInput<RopeyCursor<'a>> {\n        let input = match byte_range.start_bound() {\n            Bound::Included(&pos) | Bound::Excluded(&pos) => {\n                RegexInput::new(RopeyCursor::at(self, pos))\n            }\n            Bound::Unbounded => RegexInput::new(self),\n        };\n        input.range(byte_range)\n    }\n    fn first_non_whitespace_char(self) -> Option<usize> {\n        self.chars().position(|ch| !ch.is_whitespace())\n    }\n    fn last_non_whitespace_char(self) -> Option<usize> {\n        self.chars_at(self.len_chars())\n            .reversed()\n            .position(|ch| !ch.is_whitespace())\n            .map(|pos| self.len_chars() - pos - 1)\n    }\n\n    // These three are adapted from std:\n\n    fn floor_char_boundary(self, byte_idx: usize) -> usize {\n        if byte_idx >= self.len_bytes() {\n            self.len_bytes()\n        } else {\n            let offset = self\n                .bytes_at(byte_idx + 1)\n                .reversed()\n                .take(4)\n                .position(is_utf8_char_boundary)\n                // A char can only be four bytes long so we are guaranteed to find a boundary.\n                .unwrap();\n\n            byte_idx - offset\n        }\n    }\n\n    fn ceil_char_boundary(self, byte_idx: usize) -> usize {\n        if byte_idx > self.len_bytes() {\n            self.len_bytes()\n        } else {\n            let upper_bound = self.len_bytes().min(byte_idx + 4);\n            self.bytes_at(byte_idx)\n                .position(is_utf8_char_boundary)\n                .map_or(upper_bound, |pos| pos + byte_idx)\n        }\n    }\n\n    fn is_char_boundary(self, byte_idx: usize) -> bool {\n        if byte_idx == 0 {\n            return true;\n        }\n\n        if byte_idx >= self.len_bytes() {\n            byte_idx == self.len_bytes()\n        } else {\n            is_utf8_char_boundary(self.bytes_at(byte_idx).next().unwrap())\n        }\n    }\n\n    fn floor_grapheme_boundary(self, mut byte_idx: usize) -> usize {\n        if byte_idx >= self.len_bytes() {\n            return self.len_bytes();\n        }\n\n        byte_idx = self.ceil_char_boundary(byte_idx + 1);\n\n        let (mut chunk, mut chunk_byte_idx, _, _) = self.chunk_at_byte(byte_idx);\n\n        let mut cursor = GraphemeCursor::new(byte_idx, self.len_bytes(), true);\n\n        loop {\n            match cursor.prev_boundary(chunk, chunk_byte_idx) {\n                Ok(None) => return 0,\n                Ok(Some(boundary)) => return boundary,\n                Err(GraphemeIncomplete::PrevChunk) => {\n                    let (ch, ch_byte_idx, _, _) = self.chunk_at_byte(chunk_byte_idx - 1);\n                    chunk = ch;\n                    chunk_byte_idx = ch_byte_idx;\n                }\n                Err(GraphemeIncomplete::PreContext(n)) => {\n                    let ctx_chunk = self.chunk_at_byte(n - 1).0;\n                    cursor.provide_context(ctx_chunk, n - ctx_chunk.len());\n                }\n                _ => unreachable!(),\n            }\n        }\n    }\n\n    fn ceil_grapheme_boundary(self, mut byte_idx: usize) -> usize {\n        if byte_idx >= self.len_bytes() {\n            return self.len_bytes();\n        }\n\n        if byte_idx == 0 {\n            return 0;\n        }\n\n        byte_idx = self.floor_char_boundary(byte_idx - 1);\n\n        let (mut chunk, mut chunk_byte_idx, _, _) = self.chunk_at_byte(byte_idx);\n\n        let mut cursor = GraphemeCursor::new(byte_idx, self.len_bytes(), true);\n\n        loop {\n            match cursor.next_boundary(chunk, chunk_byte_idx) {\n                Ok(None) => return self.len_bytes(),\n                Ok(Some(boundary)) => return boundary,\n                Err(GraphemeIncomplete::NextChunk) => {\n                    chunk_byte_idx += chunk.len();\n                    chunk = self.chunk_at_byte(chunk_byte_idx).0;\n                }\n                Err(GraphemeIncomplete::PreContext(n)) => {\n                    let ctx_chunk = self.chunk_at_byte(n - 1).0;\n                    cursor.provide_context(ctx_chunk, n - ctx_chunk.len());\n                }\n                _ => unreachable!(),\n            }\n        }\n    }\n\n    fn is_grapheme_boundary(self, byte_idx: usize) -> bool {\n        // The byte must lie on a character boundary to lie on a grapheme cluster boundary.\n        if !self.is_char_boundary(byte_idx) {\n            return false;\n        }\n\n        let (chunk, chunk_byte_idx, _, _) = self.chunk_at_byte(byte_idx);\n\n        let mut cursor = GraphemeCursor::new(byte_idx, self.len_bytes(), true);\n\n        loop {\n            match cursor.is_boundary(chunk, chunk_byte_idx) {\n                Ok(n) => return n,\n                Err(GraphemeIncomplete::PreContext(n)) => {\n                    let (ctx_chunk, ctx_byte_start, _, _) = self.chunk_at_byte(n - 1);\n                    cursor.provide_context(ctx_chunk, ctx_byte_start);\n                }\n                Err(_) => unreachable!(),\n            }\n        }\n    }\n\n    fn graphemes_rev(self) -> RopeGraphemes<'a> {\n        self.graphemes_at(self.len_bytes()).reversed()\n    }\n\n    fn graphemes_at(self, byte_idx: usize) -> RopeGraphemes<'a> {\n        // Bounds check\n        assert!(byte_idx <= self.len_bytes());\n\n        let (mut chunks, chunk_byte_idx, _, _) = self.chunks_at_byte(byte_idx);\n        let current_chunk = chunks.next().unwrap_or(\"\");\n\n        RopeGraphemes {\n            text: self,\n            chunks,\n            current_chunk,\n            chunk_byte_idx,\n            cursor: GraphemeCursor::new(byte_idx, self.len_bytes(), true),\n            is_reversed: false,\n        }\n    }\n\n    fn grapheme_indices_at(self, byte_idx: usize) -> RopeGraphemeIndices<'a> {\n        // Bounds check\n        assert!(byte_idx <= self.len_bytes());\n        RopeGraphemeIndices {\n            front_offset: byte_idx,\n            iter: self.graphemes_at(byte_idx),\n            is_reversed: false,\n        }\n    }\n\n    fn nth_next_grapheme_boundary(self, mut byte_idx: usize, n: usize) -> usize {\n        // Bounds check\n        assert!(byte_idx <= self.len_bytes());\n\n        byte_idx = self.floor_char_boundary(byte_idx);\n\n        // Get the chunk with our byte index in it.\n        let (mut chunk, mut chunk_byte_idx, _, _) = self.chunk_at_byte(byte_idx);\n\n        // Set up the grapheme cursor.\n        let mut gc = GraphemeCursor::new(byte_idx, self.len_bytes(), true);\n\n        // Find the nth next grapheme cluster boundary.\n        for _ in 0..n {\n            loop {\n                match gc.next_boundary(chunk, chunk_byte_idx) {\n                    Ok(None) => return self.len_bytes(),\n                    Ok(Some(boundary)) => {\n                        byte_idx = boundary;\n                        break;\n                    }\n                    Err(GraphemeIncomplete::NextChunk) => {\n                        chunk_byte_idx += chunk.len();\n                        let (a, _, _, _) = self.chunk_at_byte(chunk_byte_idx);\n                        chunk = a;\n                    }\n                    Err(GraphemeIncomplete::PreContext(n)) => {\n                        let ctx_chunk = self.chunk_at_byte(n - 1).0;\n                        gc.provide_context(ctx_chunk, n - ctx_chunk.len());\n                    }\n                    _ => unreachable!(),\n                }\n            }\n        }\n\n        byte_idx\n    }\n\n    fn nth_prev_grapheme_boundary(self, mut byte_idx: usize, n: usize) -> usize {\n        // Bounds check\n        assert!(byte_idx <= self.len_bytes());\n\n        byte_idx = self.ceil_char_boundary(byte_idx);\n\n        // Get the chunk with our byte index in it.\n        let (mut chunk, mut chunk_byte_idx, _, _) = self.chunk_at_byte(byte_idx);\n\n        // Set up the grapheme cursor.\n        let mut gc = GraphemeCursor::new(byte_idx, self.len_bytes(), true);\n\n        for _ in 0..n {\n            loop {\n                match gc.prev_boundary(chunk, chunk_byte_idx) {\n                    Ok(None) => return 0,\n                    Ok(Some(boundary)) => {\n                        byte_idx = boundary;\n                        break;\n                    }\n                    Err(GraphemeIncomplete::PrevChunk) => {\n                        let (a, b, _, _) = self.chunk_at_byte(chunk_byte_idx - 1);\n                        chunk = a;\n                        chunk_byte_idx = b;\n                    }\n                    Err(GraphemeIncomplete::PreContext(n)) => {\n                        let ctx_chunk = self.chunk_at_byte(n - 1).0;\n                        gc.provide_context(ctx_chunk, n - ctx_chunk.len());\n                    }\n                    _ => unreachable!(),\n                }\n            }\n        }\n\n        byte_idx\n    }\n}\n\n// copied from std\n#[inline]\nconst fn is_utf8_char_boundary(b: u8) -> bool {\n    // This is bit magic equivalent to: b < 128 || b >= 192\n    (b as i8) >= -0x40\n}\n\n/// An iterator over the graphemes of a `RopeSlice`.\n///\n/// This iterator is cursor-like: rather than implementing DoubleEndedIterator it can be reversed\n/// like a cursor. This style matches `Bytes` and `Chars` iterator types in Ropey and is more\n/// natural and useful for wrapping `GraphemeCursor`.\n#[derive(Clone)]\npub struct RopeGraphemes<'a> {\n    text: RopeSlice<'a>,\n    chunks: Chunks<'a>,\n    current_chunk: &'a str,\n    /// Byte index of the start of the current chunk.\n    chunk_byte_idx: usize,\n    cursor: GraphemeCursor,\n    is_reversed: bool,\n}\n\nimpl fmt::Debug for RopeGraphemes<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"RopeGraphemes\")\n            .field(\"text\", &self.text)\n            .field(\"chunks\", &self.chunks)\n            .field(\"current_chunk\", &self.current_chunk)\n            .field(\"chunk_byte_idx\", &self.chunk_byte_idx)\n            // .field(\"cursor\", &self.cursor)\n            .field(\"is_reversed\", &self.is_reversed)\n            .finish()\n    }\n}\n\nimpl<'a> RopeGraphemes<'a> {\n    #[allow(clippy::should_implement_trait)]\n    pub fn next(&mut self) -> Option<RopeSlice<'a>> {\n        if self.is_reversed {\n            self.prev_impl()\n        } else {\n            self.next_impl()\n        }\n    }\n\n    pub fn prev(&mut self) -> Option<RopeSlice<'a>> {\n        if self.is_reversed {\n            self.next_impl()\n        } else {\n            self.prev_impl()\n        }\n    }\n\n    pub fn reverse(&mut self) {\n        self.is_reversed = !self.is_reversed;\n    }\n\n    #[must_use]\n    pub fn reversed(mut self) -> Self {\n        self.reverse();\n        self\n    }\n\n    fn next_impl(&mut self) -> Option<RopeSlice<'a>> {\n        let a = self.cursor.cur_cursor();\n        let b;\n        loop {\n            match self\n                .cursor\n                .next_boundary(self.current_chunk, self.chunk_byte_idx)\n            {\n                Ok(None) => return None,\n                Ok(Some(boundary)) => {\n                    b = boundary;\n                    break;\n                }\n                Err(GraphemeIncomplete::NextChunk) => {\n                    self.chunk_byte_idx += self.current_chunk.len();\n                    self.current_chunk = self.chunks.next().unwrap_or(\"\");\n                }\n                Err(GraphemeIncomplete::PreContext(idx)) => {\n                    let (chunk, byte_idx, _, _) = self.text.chunk_at_byte(idx.saturating_sub(1));\n                    self.cursor.provide_context(chunk, byte_idx);\n                }\n                _ => unreachable!(),\n            }\n        }\n\n        if a < self.chunk_byte_idx {\n            Some(self.text.byte_slice(a..b))\n        } else {\n            let a2 = a - self.chunk_byte_idx;\n            let b2 = b - self.chunk_byte_idx;\n            Some((&self.current_chunk[a2..b2]).into())\n        }\n    }\n\n    fn prev_impl(&mut self) -> Option<RopeSlice<'a>> {\n        let a = self.cursor.cur_cursor();\n        let b;\n        loop {\n            match self\n                .cursor\n                .prev_boundary(self.current_chunk, self.chunk_byte_idx)\n            {\n                Ok(None) => return None,\n                Ok(Some(boundary)) => {\n                    b = boundary;\n                    break;\n                }\n                Err(GraphemeIncomplete::PrevChunk) => {\n                    self.current_chunk = self.chunks.prev().unwrap_or(\"\");\n                    self.chunk_byte_idx -= self.current_chunk.len();\n                }\n                Err(GraphemeIncomplete::PreContext(idx)) => {\n                    let (chunk, byte_idx, _, _) = self.text.chunk_at_byte(idx.saturating_sub(1));\n                    self.cursor.provide_context(chunk, byte_idx);\n                }\n                _ => unreachable!(),\n            }\n        }\n\n        if a >= self.chunk_byte_idx + self.current_chunk.len() {\n            Some(self.text.byte_slice(b..a))\n        } else {\n            let a2 = a - self.chunk_byte_idx;\n            let b2 = b - self.chunk_byte_idx;\n            Some((&self.current_chunk[b2..a2]).into())\n        }\n    }\n}\n\nimpl<'a> Iterator for RopeGraphemes<'a> {\n    type Item = RopeSlice<'a>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        RopeGraphemes::next(self)\n    }\n}\n\n/// An iterator over the grapheme clusters in a rope and the byte indices where each grapheme\n/// cluster starts.\n///\n/// This iterator wraps `RopeGraphemes` and is also cursor-like. Use `reverse` or `reversed` to\n/// toggle the direction of the iterator. See [RopeGraphemes].\n#[derive(Debug, Clone)]\npub struct RopeGraphemeIndices<'a> {\n    front_offset: usize,\n    iter: RopeGraphemes<'a>,\n    is_reversed: bool,\n}\n\nimpl<'a> RopeGraphemeIndices<'a> {\n    #[allow(clippy::should_implement_trait)]\n    pub fn next(&mut self) -> Option<(usize, RopeSlice<'a>)> {\n        if self.is_reversed {\n            self.prev_impl()\n        } else {\n            self.next_impl()\n        }\n    }\n\n    pub fn prev(&mut self) -> Option<(usize, RopeSlice<'a>)> {\n        if self.is_reversed {\n            self.next_impl()\n        } else {\n            self.prev_impl()\n        }\n    }\n\n    pub fn reverse(&mut self) {\n        self.is_reversed = !self.is_reversed;\n    }\n\n    #[must_use]\n    pub fn reversed(mut self) -> Self {\n        self.reverse();\n        self\n    }\n\n    fn next_impl(&mut self) -> Option<(usize, RopeSlice<'a>)> {\n        let slice = self.iter.next()?;\n        let idx = self.front_offset;\n        self.front_offset += slice.len_bytes();\n        Some((idx, slice))\n    }\n\n    fn prev_impl(&mut self) -> Option<(usize, RopeSlice<'a>)> {\n        let slice = self.iter.prev()?;\n        self.front_offset -= slice.len_bytes();\n        Some((self.front_offset, slice))\n    }\n}\n\nimpl<'a> Iterator for RopeGraphemeIndices<'a> {\n    type Item = (usize, RopeSlice<'a>);\n\n    fn next(&mut self) -> Option<Self::Item> {\n        RopeGraphemeIndices::next(self)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use ropey::RopeSlice;\n\n    use crate::rope::RopeSliceExt;\n\n    #[test]\n    fn starts_with() {\n        assert!(RopeSlice::from(\"asdf\").starts_with(\"a\"));\n    }\n\n    #[test]\n    fn ends_with() {\n        assert!(RopeSlice::from(\"asdf\").ends_with(\"f\"));\n    }\n\n    #[test]\n    fn char_boundaries() {\n        let ascii = RopeSlice::from(\"ascii\");\n        // When the given index lies on a character boundary, the index should not change.\n        for byte_idx in 0..=ascii.len_bytes() {\n            assert_eq!(ascii.floor_char_boundary(byte_idx), byte_idx);\n            assert_eq!(ascii.ceil_char_boundary(byte_idx), byte_idx);\n            assert!(ascii.is_char_boundary(byte_idx));\n        }\n\n        // This is a polyfill of a method of this trait which was replaced by ceil_char_boundary.\n        // It returns the _character index_ of the given byte index, rounding up if it does not\n        // already lie on a character boundary.\n        fn byte_to_next_char(slice: RopeSlice, byte_idx: usize) -> usize {\n            slice.byte_to_char(slice.ceil_char_boundary(byte_idx))\n        }\n\n        for i in 0..=6 {\n            assert_eq!(byte_to_next_char(RopeSlice::from(\"foobar\"), i), i);\n        }\n        for char_idx in 0..10 {\n            let len = \"😆\".len();\n            assert_eq!(\n                byte_to_next_char(RopeSlice::from(\"😆😆😆😆😆😆😆😆😆😆\"), char_idx * len),\n                char_idx\n            );\n            for i in 1..=len {\n                assert_eq!(\n                    byte_to_next_char(RopeSlice::from(\"😆😆😆😆😆😆😆😆😆😆\"), char_idx * len + i),\n                    char_idx + 1\n                );\n            }\n        }\n    }\n\n    #[test]\n    fn grapheme_boundaries() {\n        let ascii = RopeSlice::from(\"ascii\");\n        // When the given index lies on a grapheme boundary, the index should not change.\n        for byte_idx in 0..=ascii.len_bytes() {\n            assert_eq!(ascii.floor_char_boundary(byte_idx), byte_idx);\n            assert_eq!(ascii.ceil_char_boundary(byte_idx), byte_idx);\n            assert!(ascii.is_grapheme_boundary(byte_idx));\n        }\n\n        // 🏴‍☠️: U+1F3F4 U+200D U+2620 U+FE0F\n        // 13 bytes, hex: f0 9f 8f b4 + e2 80 8d + e2 98 a0 + ef b8 8f\n        let g = RopeSlice::from(\"🏴‍☠️\\r\\n\");\n        let emoji_len = \"🏴‍☠️\".len();\n        let end = g.len_bytes();\n\n        for byte_idx in 0..emoji_len {\n            assert_eq!(g.floor_grapheme_boundary(byte_idx), 0);\n        }\n        for byte_idx in emoji_len..end {\n            assert_eq!(g.floor_grapheme_boundary(byte_idx), emoji_len);\n        }\n        assert_eq!(g.floor_grapheme_boundary(end), end);\n\n        assert_eq!(g.ceil_grapheme_boundary(0), 0);\n        for byte_idx in 1..=emoji_len {\n            assert_eq!(g.ceil_grapheme_boundary(byte_idx), emoji_len);\n        }\n        for byte_idx in emoji_len + 1..=end {\n            assert_eq!(g.ceil_grapheme_boundary(byte_idx), end);\n        }\n\n        assert!(g.is_grapheme_boundary(0));\n        assert!(g.is_grapheme_boundary(emoji_len));\n        assert!(g.is_grapheme_boundary(end));\n        for byte_idx in (1..emoji_len).chain(emoji_len + 1..end) {\n            assert!(!g.is_grapheme_boundary(byte_idx));\n        }\n    }\n}\n"
  },
  {
    "path": "helix-stdx/tests/path.rs",
    "content": "#![cfg(windows)]\n\nuse std::{env::set_current_dir, error::Error, path::Component};\n\nuse helix_stdx::path;\nuse tempfile::Builder;\n\n// Paths on Windows are almost always case-insensitive.\n// Normalization should return the original path.\n// E.g. mkdir `CaSe`, normalize(`case`) = `CaSe`.\n#[test]\nfn test_case_folding_windows() -> Result<(), Box<dyn Error>> {\n    // tmp/root/case\n    let tmp_prefix = std::env::temp_dir();\n    set_current_dir(&tmp_prefix)?;\n\n    let root = Builder::new().prefix(\"root-\").tempdir()?;\n    let case = Builder::new().prefix(\"CaSe-\").tempdir_in(&root)?;\n\n    let root_without_prefix = root.path().strip_prefix(&tmp_prefix)?;\n\n    let lowercase_case = format!(\n        \"case-{}\",\n        case.path()\n            .file_name()\n            .unwrap()\n            .to_string_lossy()\n            .split_at(5)\n            .1\n    );\n    let test_path = root_without_prefix.join(lowercase_case);\n    assert_eq!(\n        path::normalize(&test_path),\n        case.path().strip_prefix(&tmp_prefix)?\n    );\n\n    Ok(())\n}\n\n#[test]\nfn test_normalize_path() -> Result<(), Box<dyn Error>> {\n    /*\n    tmp/root/\n    ├── link -> dir1/orig_file\n    ├── dir1/\n    │   └── orig_file\n    └── dir2/\n        └── dir_link -> ../dir1/\n    */\n\n    let tmp_prefix = std::env::temp_dir();\n    set_current_dir(&tmp_prefix)?;\n\n    // Create a tree structure as shown above\n    let root = Builder::new().prefix(\"root-\").tempdir()?;\n    let dir1 = Builder::new().prefix(\"dir1-\").tempdir_in(&root)?;\n    let orig_file = Builder::new().prefix(\"orig_file-\").tempfile_in(&dir1)?;\n    let dir2 = Builder::new().prefix(\"dir2-\").tempdir_in(&root)?;\n\n    // Create path and delete existing file\n    let dir_link = Builder::new()\n        .prefix(\"dir_link-\")\n        .tempfile_in(&dir2)?\n        .path()\n        .to_owned();\n    let link = Builder::new()\n        .prefix(\"link-\")\n        .tempfile_in(&root)?\n        .path()\n        .to_owned();\n\n    use std::os::windows;\n    windows::fs::symlink_dir(&dir1, &dir_link)?;\n    windows::fs::symlink_file(&orig_file, &link)?;\n\n    // root/link\n    let path = link.strip_prefix(&tmp_prefix)?;\n    assert_eq!(\n        path::normalize(path),\n        path,\n        \"input {:?} and symlink last component shouldn't be resolved\",\n        path\n    );\n\n    // root/dir2/dir_link/orig_file/../..\n    let path = dir_link\n        .strip_prefix(&tmp_prefix)\n        .unwrap()\n        .join(orig_file.path().file_name().unwrap())\n        .join(Component::ParentDir)\n        .join(Component::ParentDir);\n    let expected = dir_link\n        .strip_prefix(&tmp_prefix)\n        .unwrap()\n        .join(Component::ParentDir);\n    assert_eq!(\n        path::normalize(&path),\n        expected,\n        \"input {:?} and \\\"..\\\" should not erase the symlink that goes ahead\",\n        &path\n    );\n\n    // root/link/.././../dir2/../\n    let path = link\n        .strip_prefix(&tmp_prefix)\n        .unwrap()\n        .join(Component::ParentDir)\n        .join(Component::CurDir)\n        .join(Component::ParentDir)\n        .join(dir2.path().file_name().unwrap())\n        .join(Component::ParentDir);\n    let expected = link\n        .strip_prefix(&tmp_prefix)\n        .unwrap()\n        .join(Component::ParentDir)\n        .join(Component::ParentDir);\n    assert_eq!(path::normalize(&path), expected, \"input {:?}\", &path);\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/.gitignore",
    "content": "/target\n"
  },
  {
    "path": "helix-term/Cargo.toml",
    "content": "[package]\nname = \"helix-term\"\ndescription = \"A post-modern text editor.\"\ninclude = [\"src/**/*\", \"README.md\"]\ndefault-run = \"hx\"\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n[package.metadata.deb]\n# generate a .deb in target/debian/ with the command: cargo deb --no-build\nname = \"helix\"\nassets = [\n  { source = \"target/release/hx\", dest = \"/usr/lib/helix/\", mode = \"755\" },\n  { source = \"../contrib/hx_launcher.sh\", dest = \"/usr/bin/hx\", mode = \"755\" },\n  { source = \"../runtime/*\", dest = \"/usr/lib/helix/runtime/\", mode = \"644\" },\n  { source = \"../runtime/grammars/*\", dest = \"/usr/lib/helix/runtime/grammars/\", mode = \"644\" }, # to avoid sources/\n  { source = \"../runtime/queries/**/*\", dest = \"/usr/lib/helix/runtime/queries/\", mode = \"644\" },\n  { source = \"../runtime/themes/**/*\", dest = \"/usr/lib/helix/runtime/themes/\", mode = \"644\" },\n  { source = \"../README.md\", dest = \"/usr/share/doc/helix/\", mode = \"644\" },\n  { source = \"../contrib/completion/hx.bash\", dest = \"/usr/share/bash-completion/completions/hx\", mode = \"644\" },\n  { source = \"../contrib/completion/hx.fish\", dest = \"/usr/share/fish/vendor_completions.d/hx.fish\", mode = \"644\" },\n  { source = \"../contrib/completion/hx.zsh\", dest = \"/usr/share/zsh/vendor-completions/_hx\", mode = \"644\" },\n  { source = \"../contrib/Helix.desktop\", dest = \"/usr/share/applications/Helix.desktop\", mode = \"644\" },\n  { source = \"../contrib/helix.png\", dest = \"/usr/share/icons/hicolor/256x256/apps/helix.png\", mode = \"644\" },\n]\n\n[features]\ndefault = [\"git\"]\nunicode-lines = [\"helix-core/unicode-lines\", \"helix-view/unicode-lines\"]\nintegration = [\"helix-event/integration_test\"]\ngit = [\"helix-vcs/git\"]\n\n[[bin]]\nname = \"hx\"\npath = \"src/main.rs\"\n\n[dependencies]\nhelix-stdx = { path = \"../helix-stdx\" }\nhelix-core = { path = \"../helix-core\" }\nhelix-event = { path = \"../helix-event\" }\nhelix-view = { path = \"../helix-view\" }\nhelix-lsp = { path = \"../helix-lsp\" }\nhelix-dap = { path = \"../helix-dap\" }\nhelix-vcs = { path = \"../helix-vcs\" }\nhelix-loader = { path = \"../helix-loader\" }\n\nanyhow = \"1\"\nonce_cell = \"1.21\"\n\ntokio = { version = \"1\", features = [\"rt\", \"rt-multi-thread\", \"io-util\", \"io-std\", \"time\", \"process\", \"macros\", \"fs\", \"parking_lot\"] }\ntui = { path = \"../helix-tui\", package = \"helix-tui\", default-features = false, features = [\"termina\", \"crossterm\"] }\ntermina = { workspace = true, features = [\"event-stream\"] }\nsignal-hook = \"0.4\"\ntokio-stream = \"0.1\"\nfutures-util = { version = \"0.3\", features = [\"std\", \"async-await\"], default-features = false }\narc-swap.workspace = true\ntermini = \"1\"\nindexmap = \"2.13\"\n\n# Logging\nfern = \"0.7\"\nchrono = { version = \"0.4\", default-features = false, features = [\"clock\"] }\nlog = \"0.4\"\n\n# File picker\nnucleo.workspace = true\nignore = \"0.4\"\ngrep-regex = \"0.1\"\ngrep-searcher = \"0.1\"\ngrep-matcher = \"0.1\"\n# markdown doc rendering\npulldown-cmark = { version = \"0.13\", default-features = false }\n# file type detection\ncontent_inspector = \"0.2.4\"\nthiserror.workspace = true\n\n# opening URLs\nopen = \"5.3.3\"\nurl = \"2.5.4\"\n\n# config\ntoml.workspace = true\n\nserde_json = \"1.0\"\nserde = { version = \"1.0\", features = [\"derive\"] }\n\ndashmap = \"6.0\"\n\n[target.'cfg(windows)'.dependencies]\ncrossterm = { version = \"0.28\", features = [\"event-stream\"] }\n\n[target.'cfg(not(windows))'.dependencies]  # https://github.com/vorner/signal-hook/issues/100\nsignal-hook-tokio = { version = \"0.4\", features = [\"futures-v0_3\"] }\nlibc = \"0.2.183\"\n\n[build-dependencies]\nhelix-loader = { path = \"../helix-loader\" }\n\n[dev-dependencies]\nsmallvec = \"1.15\"\nindoc = \"2.0.6\"\ntempfile.workspace = true\nsame-file = \"1.0.1\"\n"
  },
  {
    "path": "helix-term/build.rs",
    "content": "use helix_loader::grammar::{build_grammars, fetch_grammars};\n\nfn main() {\n    if std::env::var(\"HELIX_DISABLE_AUTO_GRAMMAR_BUILD\").is_err() {\n        fetch_grammars().expect(\"Failed to fetch tree-sitter grammars\");\n        build_grammars(Some(std::env::var(\"TARGET\").unwrap()))\n            .expect(\"Failed to compile tree-sitter grammars\");\n    }\n\n    #[cfg(windows)]\n    windows_rc::link_icon_in_windows_exe(\"../contrib/helix-256p.ico\");\n}\n\n#[cfg(windows)]\nmod windows_rc {\n    use std::io::prelude::Write;\n    use std::{env, io, path::Path, path::PathBuf, process};\n\n    pub(crate) fn link_icon_in_windows_exe(icon_path: &str) {\n        let rc_exe = find_rc_exe().expect(\"Windows SDK is to be installed along with MSVC\");\n\n        let output = env::var(\"OUT_DIR\").expect(\"Env var OUT_DIR should have been set by compiler\");\n        let output_dir = PathBuf::from(output);\n\n        let rc_path = output_dir.join(\"resource.rc\");\n        write_resource_file(&rc_path, icon_path).unwrap();\n\n        let resource_file = PathBuf::from(&output_dir).join(\"resource.lib\");\n        compile_with_toolkit_msvc(rc_exe, resource_file, rc_path);\n\n        println!(\"cargo:rustc-link-search=native={}\", output_dir.display());\n        println!(\"cargo:rustc-link-lib=dylib=resource\");\n    }\n\n    fn compile_with_toolkit_msvc(rc_exe: PathBuf, output: PathBuf, input: PathBuf) {\n        let mut command = process::Command::new(rc_exe);\n        let command = command.arg(format!(\n            \"/I{}\",\n            env::var(\"CARGO_MANIFEST_DIR\")\n                .expect(\"CARGO_MANIFEST_DIR should have been set by Cargo\")\n        ));\n\n        let status = command\n            .arg(format!(\"/fo{}\", output.display()))\n            .arg(format!(\"{}\", input.display()))\n            .output()\n            .unwrap();\n\n        println!(\n            \"RC Output:\\n{}\\n------\",\n            String::from_utf8_lossy(&status.stdout)\n        );\n        println!(\n            \"RC Error:\\n{}\\n------\",\n            String::from_utf8_lossy(&status.stderr)\n        );\n    }\n\n    fn find_rc_exe() -> io::Result<PathBuf> {\n        let find_reg_key = process::Command::new(\"reg\")\n            .arg(\"query\")\n            .arg(r\"HKLM\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots\")\n            .arg(\"/reg:32\")\n            .arg(\"/v\")\n            .arg(\"KitsRoot10\")\n            .output();\n\n        match find_reg_key {\n            Err(find_reg_key) => Err(io::Error::new(\n                io::ErrorKind::Other,\n                format!(\"Failed to run registry query: {}\", find_reg_key),\n            )),\n            Ok(find_reg_key) => {\n                if find_reg_key.status.code().unwrap() != 0 {\n                    Err(io::Error::new(\n                        io::ErrorKind::Other,\n                        \"Can not find Windows SDK\",\n                    ))\n                } else {\n                    let lines = String::from_utf8(find_reg_key.stdout)\n                        .expect(\"Should be able to parse the output\");\n                    let mut lines: Vec<&str> = lines.lines().collect();\n                    let mut rc_exe_paths: Vec<PathBuf> = Vec::new();\n                    lines.reverse();\n                    for line in lines {\n                        if line.trim().starts_with(\"KitsRoot\") {\n                            let kit: String = line\n                                .chars()\n                                .skip(line.find(\"REG_SZ\").unwrap() + 6)\n                                .skip_while(|c| c.is_whitespace())\n                                .collect();\n\n                            let p = PathBuf::from(&kit);\n                            let rc = if cfg!(target_arch = \"x86_64\") {\n                                p.join(r\"bin\\x64\\rc.exe\")\n                            } else {\n                                p.join(r\"bin\\x86\\rc.exe\")\n                            };\n\n                            if rc.exists() {\n                                println!(\"{:?}\", rc);\n                                rc_exe_paths.push(rc.to_owned());\n                            }\n\n                            if let Ok(bin) = p.join(\"bin\").read_dir() {\n                                for e in bin.filter_map(|e| e.ok()) {\n                                    let p = if cfg!(target_arch = \"x86_64\") {\n                                        e.path().join(r\"x64\\rc.exe\")\n                                    } else {\n                                        e.path().join(r\"x86\\rc.exe\")\n                                    };\n                                    if p.exists() {\n                                        println!(\"{:?}\", p);\n                                        rc_exe_paths.push(p.to_owned());\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    if rc_exe_paths.is_empty() {\n                        return Err(io::Error::new(\n                            io::ErrorKind::Other,\n                            \"Can not find Windows SDK\",\n                        ));\n                    }\n\n                    println!(\"{:?}\", rc_exe_paths);\n                    let rc_path = rc_exe_paths.pop().unwrap();\n\n                    let rc_exe = if !rc_path.exists() {\n                        if cfg!(target_arch = \"x86_64\") {\n                            PathBuf::from(rc_path.parent().unwrap()).join(r\"bin\\x64\\rc.exe\")\n                        } else {\n                            PathBuf::from(rc_path.parent().unwrap()).join(r\"bin\\x86\\rc.exe\")\n                        }\n                    } else {\n                        rc_path\n                    };\n\n                    println!(\"Selected RC path: '{}'\", rc_exe.display());\n                    Ok(rc_exe)\n                }\n            }\n        }\n    }\n\n    fn write_resource_file(rc_path: &Path, icon_path: &str) -> io::Result<()> {\n        let mut f = std::fs::File::create(rc_path)?;\n        writeln!(f, \"{} ICON \\\"{}\\\"\", 1, icon_path)?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "helix-term/src/application.rs",
    "content": "use arc_swap::{access::Map, ArcSwap};\nuse futures_util::Stream;\nuse helix_core::{diagnostic::Severity, pos_at_coords, syntax, Range, Selection};\nuse helix_lsp::{\n    lsp::{self, notification::Notification},\n    util::lsp_range_to_range,\n    LanguageServerId, LspProgressMap,\n};\nuse helix_stdx::path::get_relative_path;\nuse helix_view::{\n    align_view,\n    document::{DocumentOpenError, DocumentSavedEventResult},\n    editor::{ConfigEvent, EditorEvent},\n    graphics::Rect,\n    theme,\n    tree::Layout,\n    Align, Editor,\n};\nuse serde_json::json;\nuse tui::backend::Backend;\n\nuse crate::{\n    args::Args,\n    compositor::{Compositor, Event},\n    config::Config,\n    handlers,\n    job::Jobs,\n    keymap::Keymaps,\n    ui::{self, overlay::overlaid},\n};\n\nuse log::{debug, error, info, warn};\nuse std::{\n    io::{stdin, IsTerminal},\n    path::Path,\n    sync::Arc,\n};\n\n#[cfg_attr(windows, allow(unused_imports))]\nuse anyhow::{Context, Error};\n\n#[cfg(not(windows))]\nuse {signal_hook::consts::signal, signal_hook_tokio::Signals};\n#[cfg(windows)]\ntype Signals = futures_util::stream::Empty<()>;\n\n#[cfg(all(not(windows), not(feature = \"integration\")))]\nuse tui::backend::TerminaBackend;\n\n#[cfg(all(windows, not(feature = \"integration\")))]\nuse tui::backend::CrosstermBackend;\n\n#[cfg(feature = \"integration\")]\nuse tui::backend::TestBackend;\n\n#[cfg(all(not(windows), not(feature = \"integration\")))]\ntype TerminalBackend = TerminaBackend;\n#[cfg(all(windows, not(feature = \"integration\")))]\ntype TerminalBackend = CrosstermBackend<std::io::Stdout>;\n#[cfg(feature = \"integration\")]\ntype TerminalBackend = TestBackend;\n\n#[cfg(not(windows))]\ntype TerminalEvent = termina::Event;\n#[cfg(windows)]\ntype TerminalEvent = crossterm::event::Event;\n\ntype Terminal = tui::terminal::Terminal<TerminalBackend>;\n\npub struct Application {\n    compositor: Compositor,\n    terminal: Terminal,\n    pub editor: Editor,\n\n    config: Arc<ArcSwap<Config>>,\n\n    signals: Signals,\n    jobs: Jobs,\n    lsp_progress: LspProgressMap,\n\n    theme_mode: Option<theme::Mode>,\n}\n\n#[cfg(feature = \"integration\")]\nfn setup_integration_logging() {\n    let level = std::env::var(\"HELIX_LOG_LEVEL\")\n        .map(|lvl| lvl.parse().unwrap())\n        .unwrap_or(log::LevelFilter::Info);\n\n    // Separate file config so we can include year, month and day in file logs\n    let _ = fern::Dispatch::new()\n        .format(|out, message, record| {\n            out.finish(format_args!(\n                \"{} {} [{}] {}\",\n                chrono::Local::now().format(\"%Y-%m-%dT%H:%M:%S%.3f\"),\n                record.target(),\n                record.level(),\n                message\n            ))\n        })\n        .level(level)\n        .chain(std::io::stdout())\n        .apply();\n}\n\nimpl Application {\n    pub fn new(args: Args, config: Config, lang_loader: syntax::Loader) -> Result<Self, Error> {\n        #[cfg(feature = \"integration\")]\n        setup_integration_logging();\n\n        use helix_view::editor::Action;\n\n        let mut theme_parent_dirs = vec![helix_loader::config_dir()];\n        theme_parent_dirs.extend(helix_loader::runtime_dirs().iter().cloned());\n        let theme_loader = theme::Loader::new(&theme_parent_dirs);\n\n        #[cfg(all(not(windows), not(feature = \"integration\")))]\n        let backend = TerminaBackend::new((&config.editor).into())\n            .context(\"failed to create terminal backend\")?;\n        #[cfg(all(windows, not(feature = \"integration\")))]\n        let backend = CrosstermBackend::new(std::io::stdout(), (&config.editor).into());\n\n        #[cfg(feature = \"integration\")]\n        let backend = TestBackend::new(120, 150);\n\n        let theme_mode = backend.get_theme_mode();\n        let mut terminal = Terminal::new(backend)?;\n        let area = terminal.size();\n        let mut compositor = Compositor::new(area);\n        let config = Arc::new(ArcSwap::from_pointee(config));\n        let handlers = handlers::setup(config.clone());\n        let mut editor = Editor::new(\n            area,\n            Arc::new(theme_loader),\n            Arc::new(ArcSwap::from_pointee(lang_loader)),\n            Arc::new(Map::new(Arc::clone(&config), |config: &Config| {\n                &config.editor\n            })),\n            handlers,\n        );\n        Self::load_configured_theme(&mut editor, &config.load(), &mut terminal, theme_mode);\n\n        let keys = Box::new(Map::new(Arc::clone(&config), |config: &Config| {\n            &config.keys\n        }));\n        let editor_view = Box::new(ui::EditorView::new(Keymaps::new(keys)));\n        compositor.push(editor_view);\n\n        let jobs = Jobs::new();\n\n        if args.load_tutor {\n            let path = helix_loader::runtime_file(Path::new(\"tutor\"));\n            editor.open(&path, Action::VerticalSplit)?;\n            // Unset path to prevent accidentally saving to the original tutor file.\n            doc_mut!(editor).set_path(None);\n        } else if !args.files.is_empty() {\n            let mut files_it = args.files.into_iter().peekable();\n\n            // If the first file is a directory, skip it and open a picker\n            if let Some((first, _)) = files_it.next_if(|(p, _)| p.is_dir()) {\n                let picker = ui::file_picker(&editor, first);\n                compositor.push(Box::new(overlaid(picker)));\n            }\n\n            // If there are any more files specified, open them\n            if files_it.peek().is_some() {\n                let mut nr_of_files = 0;\n                for (file, pos) in files_it {\n                    nr_of_files += 1;\n                    if file.is_dir() {\n                        return Err(anyhow::anyhow!(\n                            \"expected a path to file, but found a directory: {file:?}. (to open a directory pass it as first argument)\"\n                        ));\n                    } else {\n                        // If the user passes in either `--vsplit` or\n                        // `--hsplit` as a command line argument, all the given\n                        // files will be opened according to the selected\n                        // option. If neither of those two arguments are passed\n                        // in, just load the files normally.\n                        let action = match args.split {\n                            _ if nr_of_files == 1 => Action::VerticalSplit,\n                            Some(Layout::Vertical) => Action::VerticalSplit,\n                            Some(Layout::Horizontal) => Action::HorizontalSplit,\n                            None => Action::Load,\n                        };\n                        let old_id = editor.document_id_by_path(&file);\n                        let doc_id = match editor.open(&file, action) {\n                            // Ignore irregular files during application init.\n                            Err(DocumentOpenError::IrregularFile) => {\n                                nr_of_files -= 1;\n                                continue;\n                            }\n                            Err(err) => return Err(anyhow::anyhow!(err)),\n                            // We can't open more than 1 buffer for 1 file, in this case we already have opened this file previously\n                            Ok(doc_id) if old_id == Some(doc_id) => {\n                                nr_of_files -= 1;\n                                doc_id\n                            }\n                            Ok(doc_id) => doc_id,\n                        };\n                        // with Action::Load all documents have the same view\n                        // NOTE: this isn't necessarily true anymore. If\n                        // `--vsplit` or `--hsplit` are used, the file which is\n                        // opened last is focused on.\n                        let view_id = editor.tree.focus;\n                        let doc = doc_mut!(editor, &doc_id);\n                        let selection = pos\n                            .into_iter()\n                            .map(|coords| {\n                                Range::point(pos_at_coords(doc.text().slice(..), coords, true))\n                            })\n                            .collect();\n                        doc.set_selection(view_id, selection);\n                    }\n                }\n\n                // if all files were invalid, replace with empty buffer\n                if nr_of_files == 0 {\n                    editor.new_file(Action::VerticalSplit);\n                } else {\n                    editor.set_status(format!(\n                        \"Loaded {} file{}.\",\n                        nr_of_files,\n                        if nr_of_files == 1 { \"\" } else { \"s\" } // avoid \"Loaded 1 files.\" grammo\n                    ));\n                    // align the view to center after all files are loaded,\n                    // does not affect views without pos since it is at the top\n                    let (view, doc) = current!(editor);\n                    align_view(doc, view, Align::Center);\n                }\n            } else {\n                editor.new_file(Action::VerticalSplit);\n            }\n        } else if stdin().is_terminal() || cfg!(feature = \"integration\") {\n            editor.new_file(Action::VerticalSplit);\n        } else {\n            editor\n                .new_file_from_stdin(Action::VerticalSplit)\n                .unwrap_or_else(|_| editor.new_file(Action::VerticalSplit));\n        }\n\n        #[cfg(windows)]\n        let signals = futures_util::stream::empty();\n        #[cfg(not(windows))]\n        let signals = Signals::new([\n            signal::SIGTSTP,\n            signal::SIGCONT,\n            signal::SIGUSR1,\n            signal::SIGTERM,\n            signal::SIGINT,\n        ])\n        .context(\"build signal handler\")?;\n\n        let app = Self {\n            compositor,\n            terminal,\n            editor,\n            config,\n            signals,\n            jobs,\n            lsp_progress: LspProgressMap::new(),\n            theme_mode,\n        };\n\n        Ok(app)\n    }\n\n    async fn render(&mut self) {\n        if self.compositor.full_redraw {\n            self.terminal.clear().expect(\"Cannot clear the terminal\");\n            self.compositor.full_redraw = false;\n        }\n\n        let mut cx = crate::compositor::Context {\n            editor: &mut self.editor,\n            jobs: &mut self.jobs,\n            scroll: None,\n        };\n\n        helix_event::start_frame();\n        cx.editor.needs_redraw = false;\n\n        let area = self\n            .terminal\n            .autoresize()\n            .expect(\"Unable to determine terminal size\");\n\n        // TODO: need to recalculate view tree if necessary\n\n        let surface = self.terminal.current_buffer_mut();\n\n        self.compositor.render(area, surface, &mut cx);\n        let (pos, kind) = self.compositor.cursor(area, &self.editor);\n        // reset cursor cache\n        self.editor.cursor_cache.reset();\n\n        let pos = pos.map(|pos| (pos.col as u16, pos.row as u16));\n        self.terminal.draw(pos, kind).unwrap();\n    }\n\n    pub async fn event_loop<S>(&mut self, input_stream: &mut S)\n    where\n        S: Stream<Item = std::io::Result<TerminalEvent>> + Unpin,\n    {\n        self.render().await;\n\n        loop {\n            if !self.event_loop_until_idle(input_stream).await {\n                break;\n            }\n        }\n    }\n\n    pub async fn event_loop_until_idle<S>(&mut self, input_stream: &mut S) -> bool\n    where\n        S: Stream<Item = std::io::Result<TerminalEvent>> + Unpin,\n    {\n        loop {\n            if self.editor.should_close() {\n                return false;\n            }\n\n            use futures_util::StreamExt;\n\n            tokio::select! {\n                biased;\n\n                Some(signal) = self.signals.next() => {\n                    if !self.handle_signals(signal).await {\n                        return false;\n                    };\n                }\n                Some(event) = input_stream.next() => {\n                    self.handle_terminal_events(event).await;\n                }\n                Some(callback) = self.jobs.callbacks.recv() => {\n                    self.jobs.handle_callback(&mut self.editor, &mut self.compositor, Ok(Some(callback)));\n                    self.render().await;\n                }\n                Some(msg) = self.jobs.status_messages.recv() => {\n                    let severity = match msg.severity{\n                        helix_event::status::Severity::Hint => Severity::Hint,\n                        helix_event::status::Severity::Info => Severity::Info,\n                        helix_event::status::Severity::Warning => Severity::Warning,\n                        helix_event::status::Severity::Error => Severity::Error,\n                    };\n                    // TODO: show multiple status messages at once to avoid clobbering\n                    self.editor.status_msg = Some((msg.message, severity));\n                    helix_event::request_redraw();\n                }\n                Some(callback) = self.jobs.wait_futures.next() => {\n                    self.jobs.handle_callback(&mut self.editor, &mut self.compositor, callback);\n                    self.render().await;\n                }\n                event = self.editor.wait_event() => {\n                    let _idle_handled = self.handle_editor_event(event).await;\n\n                    #[cfg(feature = \"integration\")]\n                    {\n                        if _idle_handled {\n                            return true;\n                        }\n                    }\n                }\n            }\n\n            // for integration tests only, reset the idle timer after every\n            // event to signal when test events are done processing\n            #[cfg(feature = \"integration\")]\n            {\n                self.editor.reset_idle_timer();\n            }\n        }\n    }\n\n    pub fn handle_config_events(&mut self, config_event: ConfigEvent) {\n        let old_editor_config = self.editor.config();\n\n        match config_event {\n            ConfigEvent::Refresh => self.refresh_config(),\n\n            // Since only the Application can make changes to Editor's config,\n            // the Editor must send up a new copy of a modified config so that\n            // the Application can apply it.\n            ConfigEvent::Update(editor_config) => {\n                let mut app_config = (*self.config.load().clone()).clone();\n                app_config.editor = *editor_config;\n                if let Err(err) = self.terminal.reconfigure((&app_config.editor).into()) {\n                    self.editor.set_error(err.to_string());\n                };\n                self.config.store(Arc::new(app_config));\n            }\n            ConfigEvent::ThemeChanged => {\n                let _ = self.terminal.backend_mut().set_background_color(\n                    self.editor\n                        .theme\n                        .try_get_exact(\"ui.background\")\n                        .and_then(|style| style.bg),\n                );\n                return;\n            }\n        }\n\n        // Update all the relevant members in the editor after updating\n        // the configuration.\n        self.editor.refresh_config(&old_editor_config);\n\n        // reset view position in case softwrap was enabled/disabled\n        let scrolloff = self.editor.config().scrolloff;\n        for (view, _) in self.editor.tree.views() {\n            let doc = doc_mut!(self.editor, &view.doc);\n            view.ensure_cursor_in_view(doc, scrolloff);\n        }\n    }\n\n    fn refresh_config(&mut self) {\n        let mut refresh_config = || -> Result<(), Error> {\n            let default_config = Config::load_default()\n                .map_err(|err| anyhow::anyhow!(\"Failed to load config: {}\", err))?;\n\n            // Update the syntax language loader before setting the theme. Setting the theme will\n            // call `Loader::set_scopes` which must be done before the documents are re-parsed for\n            // the sake of locals highlighting.\n            let lang_loader = helix_core::config::user_lang_loader()?;\n            self.editor.syn_loader.store(Arc::new(lang_loader));\n            Self::load_configured_theme(\n                &mut self.editor,\n                &default_config,\n                &mut self.terminal,\n                self.theme_mode,\n            );\n\n            // Re-parse any open documents with the new language config.\n            let lang_loader = self.editor.syn_loader.load();\n            for document in self.editor.documents.values_mut() {\n                // Re-detect .editorconfig\n                document.detect_editor_config();\n                document.detect_language(&lang_loader);\n                let diagnostics = Editor::doc_diagnostics(\n                    &self.editor.language_servers,\n                    &self.editor.diagnostics,\n                    document,\n                );\n                document.replace_diagnostics(diagnostics, &[], None);\n            }\n\n            self.terminal.reconfigure((&default_config.editor).into())?;\n            // Store new config\n            self.config.store(Arc::new(default_config));\n            Ok(())\n        };\n\n        match refresh_config() {\n            Ok(_) => {\n                self.editor.set_status(\"Config refreshed\");\n            }\n            Err(err) => {\n                self.editor.set_error(err.to_string());\n            }\n        }\n    }\n\n    /// Load the theme set in configuration\n    fn load_configured_theme(\n        editor: &mut Editor,\n        config: &Config,\n        terminal: &mut Terminal,\n        mode: Option<theme::Mode>,\n    ) {\n        let true_color = terminal.backend().supports_true_color()\n            || config.editor.true_color\n            || crate::true_color();\n        let theme = config\n            .theme\n            .as_ref()\n            .and_then(|theme_config| {\n                let theme = theme_config.choose(mode);\n                editor\n                    .theme_loader\n                    .load(theme)\n                    .map_err(|e| {\n                        log::warn!(\"failed to load theme `{}` - {}\", theme, e);\n                        e\n                    })\n                    .ok()\n                    .filter(|theme| {\n                        let colors_ok = true_color || theme.is_16_color();\n                        if !colors_ok {\n                            log::warn!(\n                                \"loaded theme `{}` but cannot use it because true color \\\n                                support is not enabled\",\n                                theme.name()\n                            );\n                        }\n                        colors_ok\n                    })\n            })\n            .unwrap_or_else(|| editor.theme_loader.default_theme(true_color));\n        let background_color = theme\n            .try_get_exact(\"ui.background\")\n            .and_then(|style| style.bg);\n        editor.set_theme(theme);\n        let _ = terminal\n            .backend_mut()\n            .set_background_color(background_color);\n    }\n\n    #[cfg(windows)]\n    // no signal handling available on windows\n    pub async fn handle_signals(&mut self, _signal: ()) -> bool {\n        true\n    }\n\n    #[cfg(not(windows))]\n    pub async fn handle_signals(&mut self, signal: i32) -> bool {\n        match signal {\n            signal::SIGTSTP => {\n                self.restore_term().unwrap();\n\n                // SAFETY:\n                //\n                // - helix must have permissions to send signals to all processes in its signal\n                //   group, either by already having the requisite permission, or by having the\n                //   user's UID / EUID / SUID match that of the receiving process(es).\n                let res = unsafe {\n                    // A pid of 0 sends the signal to the entire process group, allowing the user to\n                    // regain control of their terminal if the editor was spawned under another process\n                    // (e.g. when running `git commit`).\n                    //\n                    // We have to send SIGSTOP (not SIGTSTP) to the entire process group, because,\n                    // as mentioned above, the terminal will get stuck if `helix` was spawned from\n                    // an external process and that process waits for `helix` to complete. This may\n                    // be an issue with signal-hook-tokio, but the author of signal-hook believes it\n                    // could be a tokio issue instead:\n                    // https://github.com/vorner/signal-hook/issues/132\n                    libc::kill(0, signal::SIGSTOP)\n                };\n\n                if res != 0 {\n                    let err = std::io::Error::last_os_error();\n                    eprintln!(\"{}\", err);\n                    let res = err.raw_os_error().unwrap_or(1);\n                    std::process::exit(res);\n                }\n            }\n            signal::SIGCONT => {\n                // Copy/Paste from same issue from neovim:\n                // https://github.com/neovim/neovim/issues/12322\n                // https://github.com/neovim/neovim/pull/13084\n                for retries in 1..=10 {\n                    match self.terminal.claim() {\n                        Ok(()) => break,\n                        Err(err) if retries == 10 => panic!(\"Failed to claim terminal: {}\", err),\n                        Err(_) => continue,\n                    }\n                }\n\n                // redraw the terminal\n                let area = self.terminal.size();\n                self.compositor.resize(area);\n                self.terminal.clear().expect(\"couldn't clear terminal\");\n\n                self.render().await;\n            }\n            signal::SIGUSR1 => {\n                self.refresh_config();\n                self.render().await;\n            }\n            signal::SIGTERM | signal::SIGINT => {\n                self.restore_term().unwrap();\n                return false;\n            }\n            _ => unreachable!(),\n        }\n\n        true\n    }\n\n    pub async fn handle_idle_timeout(&mut self) {\n        let mut cx = crate::compositor::Context {\n            editor: &mut self.editor,\n            jobs: &mut self.jobs,\n            scroll: None,\n        };\n        let should_render = self.compositor.handle_event(&Event::IdleTimeout, &mut cx);\n        if should_render || self.editor.needs_redraw {\n            self.render().await;\n        }\n    }\n\n    pub fn handle_document_write(&mut self, doc_save_event: DocumentSavedEventResult) {\n        let doc_save_event = match doc_save_event {\n            Ok(event) => event,\n            Err(err) => {\n                self.editor.set_error(err.to_string());\n                return;\n            }\n        };\n\n        let doc = match self.editor.document_mut(doc_save_event.doc_id) {\n            None => {\n                warn!(\n                    \"received document saved event for non-existent doc id: {}\",\n                    doc_save_event.doc_id\n                );\n\n                return;\n            }\n            Some(doc) => doc,\n        };\n\n        debug!(\n            \"document {:?} saved with revision {}\",\n            doc.path(),\n            doc_save_event.revision\n        );\n\n        doc.set_last_saved_revision(doc_save_event.revision, doc_save_event.save_time);\n\n        let lines = doc_save_event.text.len_lines();\n        let size = doc_save_event.text.len_bytes();\n\n        enum Size {\n            Bytes(u16),\n            HumanReadable(f32, &'static str),\n        }\n\n        impl std::fmt::Display for Size {\n            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n                match self {\n                    Self::Bytes(bytes) => write!(f, \"{bytes}B\"),\n                    Self::HumanReadable(size, suffix) => write!(f, \"{size:.1}{suffix}\"),\n                }\n            }\n        }\n\n        let size = if size < 1024 {\n            Size::Bytes(size as u16)\n        } else {\n            const SUFFIX: [&str; 4] = [\"B\", \"KiB\", \"MiB\", \"GiB\"];\n            let mut size = size as f32;\n            let mut i = 0;\n            while i < SUFFIX.len() - 1 && size >= 1024.0 {\n                size /= 1024.0;\n                i += 1;\n            }\n            Size::HumanReadable(size, SUFFIX[i])\n        };\n\n        self.editor\n            .set_doc_path(doc_save_event.doc_id, &doc_save_event.path);\n        // TODO: fix being overwritten by lsp\n        self.editor.set_status(format!(\n            \"'{}' written, {lines}L {size}\",\n            get_relative_path(&doc_save_event.path).to_string_lossy(),\n        ));\n    }\n\n    #[inline(always)]\n    pub async fn handle_editor_event(&mut self, event: EditorEvent) -> bool {\n        log::debug!(\"received editor event: {:?}\", event);\n\n        match event {\n            EditorEvent::DocumentSaved(event) => {\n                self.handle_document_write(event);\n                self.render().await;\n            }\n            EditorEvent::ConfigEvent(event) => {\n                self.handle_config_events(event);\n                self.render().await;\n            }\n            EditorEvent::LanguageServerMessage((id, call)) => {\n                self.handle_language_server_message(call, id).await;\n                // limit render calls for fast language server messages\n                helix_event::request_redraw();\n            }\n            EditorEvent::DebuggerEvent((id, payload)) => {\n                let needs_render = self.editor.handle_debugger_message(id, payload).await;\n                if needs_render {\n                    self.render().await;\n                }\n            }\n            EditorEvent::Redraw => {\n                self.render().await;\n            }\n            EditorEvent::IdleTimer => {\n                self.editor.clear_idle_timer();\n                self.handle_idle_timeout().await;\n\n                #[cfg(feature = \"integration\")]\n                {\n                    return true;\n                }\n            }\n        }\n\n        false\n    }\n\n    pub async fn handle_terminal_events(&mut self, event: std::io::Result<TerminalEvent>) {\n        #[cfg(not(windows))]\n        use termina::escape::csi;\n\n        let mut cx = crate::compositor::Context {\n            editor: &mut self.editor,\n            jobs: &mut self.jobs,\n            scroll: None,\n        };\n        // Handle key events\n        let should_redraw = match event.unwrap() {\n            #[cfg(not(windows))]\n            termina::Event::WindowResized(termina::WindowSize { rows, cols, .. }) => {\n                self.terminal\n                    .resize(Rect::new(0, 0, cols, rows))\n                    .expect(\"Unable to resize terminal\");\n\n                let area = self.terminal.size();\n\n                self.compositor.resize(area);\n\n                self.compositor\n                    .handle_event(&Event::Resize(cols, rows), &mut cx)\n            }\n            #[cfg(not(windows))]\n            // Ignore keyboard release events.\n            termina::Event::Key(termina::event::KeyEvent {\n                kind: termina::event::KeyEventKind::Release,\n                ..\n            }) => false,\n            #[cfg(not(windows))]\n            termina::Event::Csi(csi::Csi::Mode(csi::Mode::ReportTheme(mode))) => {\n                self.theme_mode = Some(mode.into());\n                Self::load_configured_theme(\n                    &mut self.editor,\n                    &self.config.load(),\n                    &mut self.terminal,\n                    self.theme_mode,\n                );\n                true\n            }\n            #[cfg(windows)]\n            TerminalEvent::Resize(width, height) => {\n                self.terminal\n                    .resize(Rect::new(0, 0, width, height))\n                    .expect(\"Unable to resize terminal\");\n\n                let area = self.terminal.size();\n\n                self.compositor.resize(area);\n\n                self.compositor\n                    .handle_event(&Event::Resize(width, height), &mut cx)\n            }\n            #[cfg(windows)]\n            // Ignore keyboard release events.\n            crossterm::event::Event::Key(crossterm::event::KeyEvent {\n                kind: crossterm::event::KeyEventKind::Release,\n                ..\n            }) => false,\n            event => self.compositor.handle_event(&event.into(), &mut cx),\n        };\n\n        if should_redraw && !self.editor.should_close() {\n            self.render().await;\n        }\n    }\n\n    pub async fn handle_language_server_message(\n        &mut self,\n        call: helix_lsp::Call,\n        server_id: LanguageServerId,\n    ) {\n        use helix_lsp::{Call, MethodCall, Notification};\n\n        macro_rules! language_server {\n            () => {\n                match self.editor.language_server_by_id(server_id) {\n                    Some(language_server) => language_server,\n                    None => {\n                        warn!(\"can't find language server with id `{}`\", server_id);\n                        return;\n                    }\n                }\n            };\n        }\n\n        match call {\n            Call::Notification(helix_lsp::jsonrpc::Notification { method, params, .. }) => {\n                let notification = match Notification::parse(&method, params) {\n                    Ok(notification) => notification,\n                    Err(helix_lsp::Error::Unhandled) => {\n                        info!(\"Ignoring Unhandled notification from Language Server\");\n                        return;\n                    }\n                    Err(err) => {\n                        error!(\n                            \"Ignoring unknown notification from Language Server: {}\",\n                            err\n                        );\n                        return;\n                    }\n                };\n\n                match notification {\n                    Notification::Initialized => {\n                        let language_server = language_server!();\n\n                        // Trigger a workspace/didChangeConfiguration notification after initialization.\n                        // This might not be required by the spec but Neovim does this as well, so it's\n                        // probably a good idea for compatibility.\n                        if let Some(config) = language_server.config() {\n                            language_server.did_change_configuration(config.clone());\n                        }\n\n                        helix_event::dispatch(helix_view::events::LanguageServerInitialized {\n                            editor: &mut self.editor,\n                            server_id,\n                        });\n                    }\n                    Notification::PublishDiagnostics(params) => {\n                        let uri = match helix_core::Uri::try_from(params.uri) {\n                            Ok(uri) => uri,\n                            Err(err) => {\n                                log::error!(\"{err}\");\n                                return;\n                            }\n                        };\n                        let language_server = language_server!();\n                        if !language_server.is_initialized() {\n                            log::error!(\"Discarding publishDiagnostic notification sent by an uninitialized server: {}\", language_server.name());\n                            return;\n                        }\n                        let provider = helix_core::diagnostic::DiagnosticProvider::Lsp {\n                            server_id,\n                            identifier: None,\n                        };\n                        self.editor.handle_lsp_diagnostics(\n                            &provider,\n                            uri,\n                            params.version,\n                            params.diagnostics,\n                        );\n                    }\n                    Notification::ShowMessage(params) => {\n                        self.handle_show_message(params.typ, params.message);\n                    }\n                    Notification::LogMessage(params) => {\n                        log::info!(\"window/logMessage: {:?}\", params);\n                    }\n                    Notification::ProgressMessage(params)\n                        if !self\n                            .compositor\n                            .has_component(std::any::type_name::<ui::Prompt>()) =>\n                    {\n                        let editor_view = self\n                            .compositor\n                            .find::<ui::EditorView>()\n                            .expect(\"expected at least one EditorView\");\n                        let lsp::ProgressParams {\n                            token,\n                            value: lsp::ProgressParamsValue::WorkDone(work),\n                        } = params;\n                        let (title, message, percentage) = match &work {\n                            lsp::WorkDoneProgress::Begin(lsp::WorkDoneProgressBegin {\n                                title,\n                                message,\n                                percentage,\n                                ..\n                            }) => (Some(title), message, percentage),\n                            lsp::WorkDoneProgress::Report(lsp::WorkDoneProgressReport {\n                                message,\n                                percentage,\n                                ..\n                            }) => (None, message, percentage),\n                            lsp::WorkDoneProgress::End(lsp::WorkDoneProgressEnd { message }) => {\n                                if message.is_some() {\n                                    (None, message, &None)\n                                } else {\n                                    self.lsp_progress.end_progress(server_id, &token);\n                                    if !self.lsp_progress.is_progressing(server_id) {\n                                        editor_view.spinners_mut().get_or_create(server_id).stop();\n                                    }\n                                    self.editor.clear_status();\n\n                                    // we want to render to clear any leftover spinners or messages\n                                    return;\n                                }\n                            }\n                        };\n\n                        if self.editor.config().lsp.display_progress_messages {\n                            let title =\n                                title.or_else(|| self.lsp_progress.title(server_id, &token));\n                            if title.is_some() || percentage.is_some() || message.is_some() {\n                                use std::fmt::Write as _;\n                                let mut status = format!(\"{}: \", language_server!().name());\n                                if let Some(percentage) = percentage {\n                                    write!(status, \"{percentage:>2}% \").unwrap();\n                                }\n                                if let Some(title) = title {\n                                    status.push_str(title);\n                                }\n                                if title.is_some() && message.is_some() {\n                                    status.push_str(\" ⋅ \");\n                                }\n                                if let Some(message) = message {\n                                    status.push_str(message);\n                                }\n                                self.editor.set_status(status);\n                            }\n                        }\n\n                        match work {\n                            lsp::WorkDoneProgress::Begin(begin_status) => {\n                                self.lsp_progress\n                                    .begin(server_id, token.clone(), begin_status);\n                            }\n                            lsp::WorkDoneProgress::Report(report_status) => {\n                                self.lsp_progress\n                                    .update(server_id, token.clone(), report_status);\n                            }\n                            lsp::WorkDoneProgress::End(_) => {\n                                self.lsp_progress.end_progress(server_id, &token);\n                                if !self.lsp_progress.is_progressing(server_id) {\n                                    editor_view.spinners_mut().get_or_create(server_id).stop();\n                                };\n                            }\n                        }\n                    }\n                    Notification::ProgressMessage(_params) => {\n                        // do nothing\n                    }\n                    Notification::Exit => {\n                        self.editor.set_status(\"Language server exited\");\n\n                        // LSPs may produce diagnostics for files that haven't been opened in helix,\n                        // we need to clear those and remove the entries from the list if this leads to\n                        // an empty diagnostic list for said files\n                        for diags in self.editor.diagnostics.values_mut() {\n                            diags.retain(|(_, provider)| {\n                                provider.language_server_id() != Some(server_id)\n                            });\n                        }\n\n                        self.editor.diagnostics.retain(|_, diags| !diags.is_empty());\n\n                        // Clear any diagnostics for documents with this server open.\n                        for doc in self.editor.documents_mut() {\n                            doc.clear_diagnostics_for_language_server(server_id);\n                        }\n\n                        helix_event::dispatch(helix_view::events::LanguageServerExited {\n                            editor: &mut self.editor,\n                            server_id,\n                        });\n\n                        // Remove the language server from the registry.\n                        self.editor.language_servers.remove_by_id(server_id);\n                    }\n                }\n            }\n            Call::MethodCall(helix_lsp::jsonrpc::MethodCall {\n                method, params, id, ..\n            }) => {\n                let reply = match MethodCall::parse(&method, params) {\n                    Err(helix_lsp::Error::Unhandled) => {\n                        error!(\n                            \"Language Server: Method {} not found in request {}\",\n                            method, id\n                        );\n                        Err(helix_lsp::jsonrpc::Error {\n                            code: helix_lsp::jsonrpc::ErrorCode::MethodNotFound,\n                            message: format!(\"Method not found: {}\", method),\n                            data: None,\n                        })\n                    }\n                    Err(err) => {\n                        log::error!(\n                            \"Language Server: Received malformed method call {} in request {}: {}\",\n                            method,\n                            id,\n                            err\n                        );\n                        Err(helix_lsp::jsonrpc::Error {\n                            code: helix_lsp::jsonrpc::ErrorCode::ParseError,\n                            message: format!(\"Malformed method call: {}\", method),\n                            data: None,\n                        })\n                    }\n                    Ok(MethodCall::WorkDoneProgressCreate(params)) => {\n                        self.lsp_progress.create(server_id, params.token);\n\n                        let editor_view = self\n                            .compositor\n                            .find::<ui::EditorView>()\n                            .expect(\"expected at least one EditorView\");\n                        let spinner = editor_view.spinners_mut().get_or_create(server_id);\n                        if spinner.is_stopped() {\n                            spinner.start();\n                        }\n\n                        Ok(serde_json::Value::Null)\n                    }\n                    Ok(MethodCall::ApplyWorkspaceEdit(params)) => {\n                        let language_server = language_server!();\n                        if language_server.is_initialized() {\n                            let offset_encoding = language_server.offset_encoding();\n                            let res = self\n                                .editor\n                                .apply_workspace_edit(offset_encoding, &params.edit);\n\n                            Ok(json!(lsp::ApplyWorkspaceEditResponse {\n                                applied: res.is_ok(),\n                                failure_reason: res.as_ref().err().map(|err| err.kind.to_string()),\n                                failed_change: res\n                                    .as_ref()\n                                    .err()\n                                    .map(|err| err.failed_change_idx as u32),\n                            }))\n                        } else {\n                            Err(helix_lsp::jsonrpc::Error {\n                                code: helix_lsp::jsonrpc::ErrorCode::InvalidRequest,\n                                message: \"Server must be initialized to request workspace edits\"\n                                    .to_string(),\n                                data: None,\n                            })\n                        }\n                    }\n                    Ok(MethodCall::WorkspaceFolders) => {\n                        Ok(json!(&*language_server!().workspace_folders().await))\n                    }\n                    Ok(MethodCall::WorkspaceConfiguration(params)) => {\n                        let language_server = language_server!();\n                        let result: Vec<_> = params\n                            .items\n                            .iter()\n                            .map(|item| {\n                                let mut config = language_server.config()?;\n                                if let Some(section) = item.section.as_ref() {\n                                    // for some reason some lsps send an empty string (observed in 'vscode-eslint-language-server')\n                                    if !section.is_empty() {\n                                        for part in section.split('.') {\n                                            config = config.get(part)?;\n                                        }\n                                    }\n                                }\n                                Some(config)\n                            })\n                            .collect();\n                        Ok(json!(result))\n                    }\n                    Ok(MethodCall::RegisterCapability(params)) => {\n                        if let Some(client) = self.editor.language_servers.get_by_id(server_id) {\n                            for reg in params.registrations {\n                                match reg.method.as_str() {\n                                    lsp::notification::DidChangeWatchedFiles::METHOD => {\n                                        let Some(options) = reg.register_options else {\n                                            continue;\n                                        };\n                                        let ops: lsp::DidChangeWatchedFilesRegistrationOptions =\n                                            match serde_json::from_value(options) {\n                                                Ok(ops) => ops,\n                                                Err(err) => {\n                                                    log::warn!(\"Failed to deserialize DidChangeWatchedFilesRegistrationOptions: {err}\");\n                                                    continue;\n                                                }\n                                            };\n                                        self.editor.language_servers.file_event_handler.register(\n                                            client.id(),\n                                            Arc::downgrade(client),\n                                            reg.id,\n                                            ops,\n                                        )\n                                    }\n                                    _ => {\n                                        // Language Servers based on the `vscode-languageserver-node` library often send\n                                        // client/registerCapability even though we do not enable dynamic registration\n                                        // for most capabilities. We should send a MethodNotFound JSONRPC error in this\n                                        // case but that rejects the registration promise in the server which causes an\n                                        // exit. So we work around this by ignoring the request and sending back an OK\n                                        // response.\n                                        log::warn!(\"Ignoring a client/registerCapability request because dynamic capability registration is not enabled. Please report this upstream to the language server\");\n                                    }\n                                }\n                            }\n                        }\n\n                        Ok(serde_json::Value::Null)\n                    }\n                    Ok(MethodCall::UnregisterCapability(params)) => {\n                        for unreg in params.unregisterations {\n                            match unreg.method.as_str() {\n                                lsp::notification::DidChangeWatchedFiles::METHOD => {\n                                    self.editor\n                                        .language_servers\n                                        .file_event_handler\n                                        .unregister(server_id, unreg.id);\n                                }\n                                _ => {\n                                    log::warn!(\"Received unregistration request for unsupported method: {}\", unreg.method);\n                                }\n                            }\n                        }\n                        Ok(serde_json::Value::Null)\n                    }\n                    Ok(MethodCall::ShowDocument(params)) => {\n                        let language_server = language_server!();\n                        let offset_encoding = language_server.offset_encoding();\n\n                        let result = self.handle_show_document(params, offset_encoding);\n                        Ok(json!(result))\n                    }\n                    Ok(MethodCall::WorkspaceDiagnosticRefresh) => {\n                        let language_server = language_server!().id();\n\n                        let documents: Vec<_> = self\n                            .editor\n                            .documents\n                            .values()\n                            .filter(|x| x.supports_language_server(language_server))\n                            .map(|x| x.id())\n                            .collect();\n\n                        for document in documents {\n                            handlers::diagnostics::request_document_diagnostics(\n                                &mut self.editor,\n                                document,\n                            );\n                        }\n\n                        Ok(serde_json::Value::Null)\n                    }\n                    Ok(MethodCall::ShowMessageRequest(params)) => {\n                        if let Some(actions) = params.actions.filter(|a| !a.is_empty()) {\n                            let id = id.clone();\n                            let select = ui::Select::new(\n                                params.message,\n                                actions,\n                                (),\n                                move |editor, action, event| {\n                                    let reply = match event {\n                                        ui::PromptEvent::Update => return,\n                                        ui::PromptEvent::Validate => Some(action.clone()),\n                                        ui::PromptEvent::Abort => None,\n                                    };\n                                    if let Some(language_server) =\n                                        editor.language_server_by_id(server_id)\n                                    {\n                                        if let Err(err) =\n                                            language_server.reply(id.clone(), Ok(json!(reply)))\n                                        {\n                                            log::error!(\n                                                \"Failed to send reply to server '{}' request {id}: {err}\",\n                                                language_server.name()\n                                            );\n                                        }\n                                    }\n                                },\n                            );\n                            self.compositor\n                                .replace_or_push(\"lsp-show-message-request\", select);\n                            // Avoid sending a reply. The `Select` callback above sends the reply.\n                            return;\n                        } else {\n                            self.handle_show_message(params.typ, params.message);\n                            Ok(serde_json::Value::Null)\n                        }\n                    }\n                };\n\n                let language_server = language_server!();\n                if let Err(err) = language_server.reply(id.clone(), reply) {\n                    log::error!(\n                        \"Failed to send reply to server '{}' request {id}: {err}\",\n                        language_server.name()\n                    );\n                }\n            }\n            Call::Invalid { id } => log::error!(\"LSP invalid method call id={:?}\", id),\n        }\n    }\n\n    fn handle_show_message(&mut self, message_type: lsp::MessageType, message: String) {\n        if self.config.load().editor.lsp.display_messages {\n            match message_type {\n                lsp::MessageType::ERROR => self.editor.set_error(message),\n                lsp::MessageType::WARNING => self.editor.set_warning(message),\n                _ => self.editor.set_status(message),\n            }\n        }\n    }\n\n    fn handle_show_document(\n        &mut self,\n        params: lsp::ShowDocumentParams,\n        offset_encoding: helix_lsp::OffsetEncoding,\n    ) -> lsp::ShowDocumentResult {\n        if let lsp::ShowDocumentParams {\n            external: Some(true),\n            uri,\n            ..\n        } = params\n        {\n            self.jobs.callback(crate::open_external_url_callback(uri));\n            return lsp::ShowDocumentResult { success: true };\n        };\n\n        let lsp::ShowDocumentParams {\n            uri,\n            selection,\n            take_focus,\n            ..\n        } = params;\n\n        let uri = match helix_core::Uri::try_from(uri) {\n            Ok(uri) => uri,\n            Err(err) => {\n                log::error!(\"{err}\");\n                return lsp::ShowDocumentResult { success: false };\n            }\n        };\n        // If `Uri` gets another variant other than `Path` this may not be valid.\n        let path = uri.as_path().expect(\"URIs are valid paths\");\n\n        let action = match take_focus {\n            Some(true) => helix_view::editor::Action::Replace,\n            _ => helix_view::editor::Action::VerticalSplit,\n        };\n\n        let doc_id = match self.editor.open(path, action) {\n            Ok(id) => id,\n            Err(err) => {\n                log::error!(\"failed to open path: {:?}: {:?}\", uri, err);\n                return lsp::ShowDocumentResult { success: false };\n            }\n        };\n\n        let doc = doc_mut!(self.editor, &doc_id);\n        if let Some(range) = selection {\n            // TODO: convert inside server\n            if let Some(new_range) = lsp_range_to_range(doc.text(), range, offset_encoding) {\n                let view = view_mut!(self.editor);\n\n                // we flip the range so that the cursor sits on the start of the symbol\n                // (for example start of the function).\n                doc.set_selection(view.id, Selection::single(new_range.head, new_range.anchor));\n                if action.align_view(view, doc.id()) {\n                    align_view(doc, view, Align::Center);\n                }\n            } else {\n                log::warn!(\"lsp position out of bounds - {:?}\", range);\n            };\n        };\n        lsp::ShowDocumentResult { success: true }\n    }\n\n    fn restore_term(&mut self) -> std::io::Result<()> {\n        use helix_view::graphics::CursorKind;\n        self.terminal\n            .backend_mut()\n            .show_cursor(CursorKind::Block)\n            .ok();\n        self.terminal.restore()\n    }\n\n    #[cfg(all(not(feature = \"integration\"), not(windows)))]\n    pub fn event_stream(&self) -> impl Stream<Item = std::io::Result<TerminalEvent>> + Unpin {\n        use termina::{escape::csi, Terminal as _};\n        let reader = self.terminal.backend().terminal().event_reader();\n        termina::EventStream::new(reader, |event| {\n            // Accept either non-escape sequences or theme mode updates.\n            !event.is_escape()\n                || matches!(\n                    event,\n                    termina::Event::Csi(csi::Csi::Mode(csi::Mode::ReportTheme(_)))\n                )\n        })\n    }\n\n    #[cfg(all(not(feature = \"integration\"), windows))]\n    pub fn event_stream(&self) -> impl Stream<Item = std::io::Result<TerminalEvent>> + Unpin {\n        crossterm::event::EventStream::new()\n    }\n\n    #[cfg(feature = \"integration\")]\n    pub fn event_stream(&self) -> impl Stream<Item = std::io::Result<TerminalEvent>> + Unpin {\n        use std::{\n            pin::Pin,\n            task::{Context, Poll},\n        };\n\n        /// A dummy stream that never polls as ready.\n        pub struct DummyEventStream;\n\n        impl Stream for DummyEventStream {\n            type Item = std::io::Result<TerminalEvent>;\n\n            fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {\n                Poll::Pending\n            }\n        }\n\n        DummyEventStream\n    }\n\n    pub async fn run<S>(&mut self, input_stream: &mut S) -> Result<i32, Error>\n    where\n        S: Stream<Item = std::io::Result<TerminalEvent>> + Unpin,\n    {\n        self.terminal.claim()?;\n\n        self.event_loop(input_stream).await;\n\n        let close_errs = self.close().await;\n\n        self.restore_term()?;\n\n        for err in close_errs {\n            self.editor.exit_code = 1;\n            eprintln!(\"Error: {}\", err);\n        }\n\n        Ok(self.editor.exit_code)\n    }\n\n    pub async fn close(&mut self) -> Vec<anyhow::Error> {\n        // [NOTE] we intentionally do not return early for errors because we\n        //        want to try to run as much cleanup as we can, regardless of\n        //        errors along the way\n        let mut errs = Vec::new();\n\n        if let Err(err) = self\n            .jobs\n            .finish(&mut self.editor, Some(&mut self.compositor))\n            .await\n        {\n            log::error!(\"Error executing job: {}\", err);\n            errs.push(err);\n        };\n\n        if let Err(err) = self.editor.flush_writes().await {\n            log::error!(\"Error writing: {}\", err);\n            errs.push(err);\n        }\n\n        if self.editor.close_language_servers(None).await.is_err() {\n            log::error!(\"Timed out waiting for language servers to shutdown\");\n            errs.push(anyhow::format_err!(\n                \"Timed out waiting for language servers to shutdown\"\n            ));\n        }\n\n        errs\n    }\n}\n\nimpl ui::menu::Item for lsp::MessageActionItem {\n    type Data = ();\n    fn format(&self, _data: &Self::Data) -> tui::widgets::Row<'_> {\n        self.title.as_str().into()\n    }\n}\n"
  },
  {
    "path": "helix-term/src/args.rs",
    "content": "use anyhow::Result;\nuse helix_core::Position;\nuse helix_view::tree::Layout;\nuse indexmap::IndexMap;\nuse std::path::{Path, PathBuf};\n\n#[derive(Default)]\npub struct Args {\n    pub display_help: bool,\n    pub display_version: bool,\n    pub health: bool,\n    pub health_arg: Option<String>,\n    pub load_tutor: bool,\n    pub fetch_grammars: bool,\n    pub build_grammars: bool,\n    pub split: Option<Layout>,\n    pub verbosity: u64,\n    pub log_file: Option<PathBuf>,\n    pub config_file: Option<PathBuf>,\n    pub files: IndexMap<PathBuf, Vec<Position>>,\n    pub working_directory: Option<PathBuf>,\n}\n\nimpl Args {\n    pub fn parse_args() -> Result<Args> {\n        let mut args = Args::default();\n        let mut argv = std::env::args().peekable();\n        let mut line_number = 0;\n\n        let mut insert_file_with_position = |file_with_position: &str| {\n            let (filename, position) = parse_file(file_with_position);\n\n            // Before setting the working directory, resolve all the paths in args.files\n            let filename = helix_stdx::path::canonicalize(filename);\n\n            args.files\n                .entry(filename)\n                .and_modify(|positions| positions.push(position))\n                .or_insert_with(|| vec![position]);\n        };\n\n        argv.next(); // skip the program, we don't care about that\n\n        while let Some(arg) = argv.next() {\n            match arg.as_str() {\n                \"--\" => break, // stop parsing at this point treat the remaining as files\n                \"--version\" => args.display_version = true,\n                \"--help\" => args.display_help = true,\n                \"--tutor\" => args.load_tutor = true,\n                \"--vsplit\" => match args.split {\n                    Some(_) => anyhow::bail!(\"can only set a split once of a specific type\"),\n                    None => args.split = Some(Layout::Vertical),\n                },\n                \"--hsplit\" => match args.split {\n                    Some(_) => anyhow::bail!(\"can only set a split once of a specific type\"),\n                    None => args.split = Some(Layout::Horizontal),\n                },\n                \"--health\" => {\n                    args.health = true;\n                    args.health_arg = argv.next_if(|opt| !opt.starts_with('-'));\n                }\n                \"-g\" | \"--grammar\" => match argv.next().as_deref() {\n                    Some(\"fetch\") => args.fetch_grammars = true,\n                    Some(\"build\") => args.build_grammars = true,\n                    _ => {\n                        anyhow::bail!(\"--grammar must be followed by either 'fetch' or 'build'\")\n                    }\n                },\n                \"-c\" | \"--config\" => match argv.next().as_deref() {\n                    Some(path) => args.config_file = Some(path.into()),\n                    None => anyhow::bail!(\"--config must specify a path to read\"),\n                },\n                \"--log\" => match argv.next().as_deref() {\n                    Some(path) => args.log_file = Some(path.into()),\n                    None => anyhow::bail!(\"--log must specify a path to write\"),\n                },\n                \"-w\" | \"--working-dir\" => match argv.next().as_deref() {\n                    Some(path) => {\n                        args.working_directory = if Path::new(path).is_dir() {\n                            Some(PathBuf::from(path))\n                        } else {\n                            anyhow::bail!(\n                                \"--working-dir specified does not exist or is not a directory\"\n                            )\n                        }\n                    }\n                    None => {\n                        anyhow::bail!(\"--working-dir must specify an initial working directory\")\n                    }\n                },\n                arg if arg.starts_with(\"--\") => {\n                    anyhow::bail!(\"unexpected double dash argument: {}\", arg)\n                }\n                arg if arg.starts_with('-') => {\n                    let arg = arg.get(1..).unwrap().chars();\n                    for chr in arg {\n                        match chr {\n                            'v' => args.verbosity += 1,\n                            'V' => args.display_version = true,\n                            'h' => args.display_help = true,\n                            _ => anyhow::bail!(\"unexpected short arg {}\", chr),\n                        }\n                    }\n                }\n                \"+\" => line_number = usize::MAX,\n                arg if arg.starts_with('+') => {\n                    match arg[1..].parse::<usize>() {\n                        Ok(n) => line_number = n.saturating_sub(1),\n                        _ => insert_file_with_position(arg),\n                    };\n                }\n                arg => insert_file_with_position(arg),\n            }\n        }\n\n        // push the remaining args, if any to the files\n        for arg in argv {\n            insert_file_with_position(&arg);\n        }\n\n        if line_number != 0 {\n            if let Some(first_position) = args\n                .files\n                .first_mut()\n                .and_then(|(_, positions)| positions.first_mut())\n            {\n                first_position.row = line_number;\n            }\n        }\n\n        Ok(args)\n    }\n}\n\n/// Parse arg into [`PathBuf`] and position.\npub(crate) fn parse_file(s: &str) -> (PathBuf, Position) {\n    let def = || (PathBuf::from(s), Position::default());\n    if Path::new(s).exists() {\n        return def();\n    }\n    split_path_row_col(s)\n        .or_else(|| split_path_row(s))\n        .unwrap_or_else(def)\n}\n\n/// Split file.rs:10:2 into [`PathBuf`], row and col.\n///\n/// Does not validate if file.rs is a file or directory.\nfn split_path_row_col(s: &str) -> Option<(PathBuf, Position)> {\n    let mut s = s.trim_end_matches(':').rsplitn(3, ':');\n    let col: usize = s.next()?.parse().ok()?;\n    let row: usize = s.next()?.parse().ok()?;\n    let path = s.next()?.into();\n    let pos = Position::new(row.saturating_sub(1), col.saturating_sub(1));\n    Some((path, pos))\n}\n\n/// Split file.rs:10 into [`PathBuf`] and row.\n///\n/// Does not validate if file.rs is a file or directory.\nfn split_path_row(s: &str) -> Option<(PathBuf, Position)> {\n    let (path, row) = s.trim_end_matches(':').rsplit_once(':')?;\n    let row: usize = row.parse().ok()?;\n    let path = path.into();\n    let pos = Position::new(row.saturating_sub(1), 0);\n    Some((path, pos))\n}\n"
  },
  {
    "path": "helix-term/src/commands/dap.rs",
    "content": "use super::{Context, Editor};\nuse crate::{\n    compositor::{self, Compositor},\n    job::{Callback, Jobs},\n    ui::{self, overlay::overlaid, Picker, Popup, Prompt, PromptEvent, Text},\n};\nuse dap::{StackFrame, Thread, ThreadStates};\nuse helix_core::syntax::config::{DebugConfigCompletion, DebugTemplate};\nuse helix_dap::{self as dap, requests::TerminateArguments};\nuse helix_lsp::block_on;\nuse helix_view::editor::Breakpoint;\n\nuse serde_json::{to_value, Value};\nuse tui::text::Spans;\n\nuse std::collections::HashMap;\nuse std::future::Future;\nuse std::path::PathBuf;\n\nuse anyhow::{anyhow, bail};\n\nuse helix_view::handlers::dap::{breakpoints_changed, jump_to_stack_frame, select_thread_id};\n\nfn thread_picker(\n    cx: &mut Context,\n    callback_fn: impl Fn(&mut Editor, &dap::Thread) + Send + 'static,\n) {\n    let debugger = debugger!(cx.editor);\n\n    let future = debugger.threads();\n    dap_callback(\n        cx.jobs,\n        future,\n        move |editor, compositor, response: dap::requests::ThreadsResponse| {\n            let threads = response.threads;\n            if threads.len() == 1 {\n                callback_fn(editor, &threads[0]);\n                return;\n            }\n            let debugger = debugger!(editor);\n\n            let thread_states = debugger.thread_states.clone();\n            let columns = [\n                ui::PickerColumn::new(\"name\", |item: &Thread, _| item.name.as_str().into()),\n                ui::PickerColumn::new(\"state\", |item: &Thread, thread_states: &ThreadStates| {\n                    thread_states\n                        .get(&item.id)\n                        .map(|state| state.as_str())\n                        .unwrap_or(\"unknown\")\n                        .into()\n                }),\n            ];\n            let picker = Picker::new(\n                columns,\n                0,\n                threads,\n                thread_states,\n                move |cx, thread, _action| callback_fn(cx.editor, thread),\n            )\n            .with_preview(move |editor, thread| {\n                let frames = editor\n                    .debug_adapters\n                    .get_active_client()\n                    .as_ref()?\n                    .stack_frames\n                    .get(&thread.id)?;\n                let frame = frames.first()?;\n                let path = frame.source.as_ref()?.path.as_ref()?.as_path();\n                let pos = Some((\n                    frame.line.saturating_sub(1),\n                    frame.end_line.unwrap_or(frame.line).saturating_sub(1),\n                ));\n                Some((path.into(), pos))\n            });\n            compositor.push(Box::new(picker));\n        },\n    );\n}\n\nfn get_breakpoint_at_current_line(editor: &mut Editor) -> Option<(usize, Breakpoint)> {\n    let (view, doc) = current!(editor);\n    let text = doc.text().slice(..);\n\n    let line = doc.selection(view.id).primary().cursor_line(text);\n    let path = doc.path()?;\n    editor.breakpoints.get(path).and_then(|breakpoints| {\n        let i = breakpoints.iter().position(|b| b.line == line);\n        i.map(|i| (i, breakpoints[i].clone()))\n    })\n}\n\n// -- DAP\n\nfn dap_callback<T, F>(\n    jobs: &mut Jobs,\n    call: impl Future<Output = helix_dap::Result<serde_json::Value>> + 'static + Send,\n    callback: F,\n) where\n    T: for<'de> serde::Deserialize<'de> + Send + 'static,\n    F: FnOnce(&mut Editor, &mut Compositor, T) + Send + 'static,\n{\n    let callback = Box::pin(async move {\n        let json = call.await?;\n        let response = serde_json::from_value(json)?;\n        let call: Callback = Callback::EditorCompositor(Box::new(\n            move |editor: &mut Editor, compositor: &mut Compositor| {\n                callback(editor, compositor, response)\n            },\n        ));\n        Ok(call)\n    });\n\n    jobs.callback(callback);\n}\n\npub fn dap_start_impl(\n    cx: &mut compositor::Context,\n    name: Option<&str>,\n    socket: Option<std::net::SocketAddr>,\n    params: Option<Vec<std::borrow::Cow<str>>>,\n) -> Result<(), anyhow::Error> {\n    let doc = doc!(cx.editor);\n    let config = doc\n        .language_config()\n        .and_then(|config| config.debugger.as_ref())\n        .ok_or_else(|| anyhow!(\"No debug adapter available for language\"))?;\n\n    let id = cx\n        .editor\n        .debug_adapters\n        .start_client(socket, config)\n        .map_err(|e| anyhow!(\"Failed to start debug client: {}\", e))?;\n\n    // TODO: avoid refetching all of this... pass a config in\n    let template = match name {\n        Some(name) => config.templates.iter().find(|t| t.name == name),\n        None => config.templates.first(),\n    }\n    .ok_or_else(|| anyhow!(\"No debug config with given name\"))?;\n\n    let mut args: HashMap<&str, Value> = if let Some(params) = params.as_ref() {\n        let preprocessed_params = prepare_dap_params(template, params);\n        template\n            .args\n            .iter()\n            .map(|(k, v)| (k.as_str(), map_value(v, &preprocessed_params)))\n            .collect()\n    } else {\n        template\n            .args\n            .iter()\n            .map(|(k, v)| (k.as_str(), v.clone()))\n            .collect()\n    };\n\n    args.insert(\"cwd\", to_value(helix_stdx::env::current_working_dir())?);\n\n    let args = to_value(args).unwrap();\n\n    let callback = |_editor: &mut Editor, _compositor: &mut Compositor, _response: Value| {\n        // if let Err(e) = result {\n        //     editor.set_error(format!(\"Failed {} target: {}\", template.request, e));\n        // }\n    };\n\n    let debugger = match cx.editor.debug_adapters.get_client_mut(id) {\n        Some(child) => child,\n        None => {\n            bail!(\"Failed to get child debugger.\");\n        }\n    };\n\n    match &template.request[..] {\n        \"launch\" => {\n            let call = debugger.launch(args);\n            dap_callback(cx.jobs, call, callback);\n        }\n        \"attach\" => {\n            let call = debugger.attach(args);\n            dap_callback(cx.jobs, call, callback);\n        }\n        request => bail!(\"Unsupported request '{}'\", request),\n    };\n\n    // TODO: either await \"initialized\" or buffer commands until event is received\n    Ok(())\n}\n\nfn prepare_dap_params(template: &DebugTemplate, params: &[std::borrow::Cow<str>]) -> Vec<String> {\n    params\n        .iter()\n        .enumerate()\n        .map(|(i, x)| {\n            let mut param = x.to_string();\n            if let Some(DebugConfigCompletion::Advanced(cfg)) = template.completion.get(i) {\n                if matches!(cfg.completion.as_deref(), Some(\"filename\" | \"directory\")) {\n                    param = std::fs::canonicalize(x.as_ref())\n                        .ok()\n                        .and_then(|pb| pb.into_os_string().into_string().ok())\n                        .unwrap_or_else(|| x.to_string());\n                }\n            }\n            param\n        })\n        .collect()\n}\n\nfn map_value(value: &Value, params: &[String]) -> Value {\n    match value {\n        Value::String(string) => {\n            let mut string = string.clone();\n            for (i, x) in params.iter().enumerate() {\n                let pattern = format!(\"{{{}}}\", i);\n                string = string.replace(&pattern, x);\n            }\n            if let Ok(integer) = string.parse::<usize>() {\n                to_value(integer).unwrap()\n            } else {\n                to_value(string).unwrap()\n            }\n        }\n        Value::Array(array) => Value::Array(array.iter().map(|x| map_value(x, params)).collect()),\n        Value::Object(object) => Value::Object(\n            object\n                .iter()\n                .map(|(k, v)| (k.clone(), map_value(v, params)))\n                .collect(),\n        ),\n\n        _ => value.clone(),\n    }\n}\n\npub fn dap_launch(cx: &mut Context) {\n    // TODO: Now that we support multiple Clients, we could run multiple debuggers at once but for now keep this as is\n    if cx.editor.debug_adapters.get_active_client().is_some() {\n        cx.editor.set_error(\"Debugger is already running\");\n        return;\n    }\n\n    let doc = doc!(cx.editor);\n\n    let config = match doc\n        .language_config()\n        .and_then(|config| config.debugger.as_ref())\n    {\n        Some(c) => c,\n        None => {\n            cx.editor\n                .set_error(\"No debug adapter available for language\");\n            return;\n        }\n    };\n\n    let templates = config.templates.clone();\n\n    let columns = [ui::PickerColumn::new(\n        \"template\",\n        |item: &DebugTemplate, _| item.name.as_str().into(),\n    )];\n\n    cx.push_layer(Box::new(overlaid(Picker::new(\n        columns,\n        0,\n        templates,\n        (),\n        |cx, template, _action| {\n            if template.completion.is_empty() {\n                if let Err(err) = dap_start_impl(cx, Some(&template.name), None, None) {\n                    cx.editor.set_error(err.to_string());\n                }\n            } else {\n                let completions = template.completion.clone();\n                let name = template.name.clone();\n                let callback = Box::pin(async move {\n                    let call: Callback =\n                        Callback::EditorCompositor(Box::new(move |_editor, compositor| {\n                            let prompt = debug_parameter_prompt(completions, name, Vec::new());\n                            compositor.push(Box::new(prompt));\n                        }));\n                    Ok(call)\n                });\n                cx.jobs.callback(callback);\n            }\n        },\n    ))));\n}\n\npub fn dap_restart(cx: &mut Context) {\n    let debugger = match cx.editor.debug_adapters.get_active_client() {\n        Some(debugger) => debugger,\n        None => {\n            cx.editor.set_error(\"Debugger is not running\");\n            return;\n        }\n    };\n    if !debugger\n        .capabilities()\n        .supports_restart_request\n        .unwrap_or(false)\n    {\n        cx.editor\n            .set_error(\"Debugger does not support session restarts\");\n        return;\n    }\n    if debugger.starting_request_args().is_none() {\n        cx.editor\n            .set_error(\"No arguments found with which to restart the sessions\");\n        return;\n    }\n\n    dap_callback(\n        cx.jobs,\n        debugger.restart(),\n        |editor, _compositor, _resp: ()| editor.set_status(\"Debugging session restarted\"),\n    );\n}\n\nfn debug_parameter_prompt(\n    completions: Vec<DebugConfigCompletion>,\n    config_name: String,\n    mut params: Vec<String>,\n) -> Prompt {\n    let completion = completions.get(params.len()).unwrap();\n    let field_type = if let DebugConfigCompletion::Advanced(cfg) = completion {\n        cfg.completion.as_deref().unwrap_or(\"\")\n    } else {\n        \"\"\n    };\n    let name = match completion {\n        DebugConfigCompletion::Advanced(cfg) => cfg.name.as_deref().unwrap_or(field_type),\n        DebugConfigCompletion::Named(name) => name.as_str(),\n    };\n    let default_val = match completion {\n        DebugConfigCompletion::Advanced(cfg) => cfg.default.as_deref().unwrap_or(\"\"),\n        _ => \"\",\n    }\n    .to_owned();\n\n    let completer = match field_type {\n        \"filename\" => |editor: &Editor, input: &str| {\n            ui::completers::filename_with_git_ignore(editor, input, false)\n        },\n        \"directory\" => |editor: &Editor, input: &str| {\n            ui::completers::directory_with_git_ignore(editor, input, false)\n        },\n        _ => ui::completers::none,\n    };\n\n    Prompt::new(\n        format!(\"{}: \", name).into(),\n        None,\n        completer,\n        move |cx, input: &str, event: PromptEvent| {\n            if event != PromptEvent::Validate {\n                return;\n            }\n\n            let mut value = input.to_owned();\n            if value.is_empty() {\n                value = default_val.clone();\n            }\n            params.push(value);\n\n            if params.len() < completions.len() {\n                let completions = completions.clone();\n                let config_name = config_name.clone();\n                let params = params.clone();\n                let callback = Box::pin(async move {\n                    let call: Callback =\n                        Callback::EditorCompositor(Box::new(move |_editor, compositor| {\n                            let prompt = debug_parameter_prompt(completions, config_name, params);\n                            compositor.push(Box::new(prompt));\n                        }));\n                    Ok(call)\n                });\n                cx.jobs.callback(callback);\n            } else if let Err(err) = dap_start_impl(\n                cx,\n                Some(&config_name),\n                None,\n                Some(params.iter().map(|x| x.into()).collect()),\n            ) {\n                cx.editor.set_error(err.to_string());\n            }\n        },\n    )\n}\n\npub fn dap_toggle_breakpoint(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let path = match doc.path() {\n        Some(path) => path.clone(),\n        None => {\n            cx.editor\n                .set_error(\"Can't set breakpoint: document has no path\");\n            return;\n        }\n    };\n    let text = doc.text().slice(..);\n    let line = doc.selection(view.id).primary().cursor_line(text);\n    dap_toggle_breakpoint_impl(cx, path, line);\n}\n\npub fn dap_toggle_breakpoint_impl(cx: &mut Context, path: PathBuf, line: usize) {\n    // TODO: need to map breakpoints over edits and update them?\n    // we shouldn't really allow editing while debug is running though\n\n    let breakpoints = cx.editor.breakpoints.entry(path.clone()).or_default();\n    // TODO: always keep breakpoints sorted and use binary search to determine insertion point\n    if let Some(pos) = breakpoints\n        .iter()\n        .position(|breakpoint| breakpoint.line == line)\n    {\n        breakpoints.remove(pos);\n    } else {\n        breakpoints.push(Breakpoint {\n            line,\n            ..Default::default()\n        });\n    }\n\n    let debugger = debugger!(cx.editor);\n\n    if let Err(e) = breakpoints_changed(debugger, path, breakpoints) {\n        cx.editor\n            .set_error(format!(\"Failed to set breakpoints: {}\", e));\n    }\n}\n\npub fn dap_continue(cx: &mut Context) {\n    let debugger = debugger!(cx.editor);\n\n    if let Some(thread_id) = debugger.thread_id {\n        let request = debugger.continue_thread(thread_id);\n\n        dap_callback(\n            cx.jobs,\n            request,\n            |editor, _compositor, _response: dap::requests::ContinueResponse| {\n                debugger!(editor).resume_application();\n            },\n        );\n    } else {\n        cx.editor\n            .set_error(\"Currently active thread is not stopped. Switch the thread.\");\n    }\n}\n\npub fn dap_pause(cx: &mut Context) {\n    thread_picker(cx, |editor, thread| {\n        let debugger = debugger!(editor);\n        let request = debugger.pause(thread.id);\n        // NOTE: we don't need to set active thread id here because DAP will emit a \"stopped\" event\n        if let Err(e) = block_on(request) {\n            editor.set_error(format!(\"Failed to pause: {}\", e));\n        }\n    })\n}\n\npub fn dap_step_in(cx: &mut Context) {\n    let debugger = debugger!(cx.editor);\n\n    if let Some(thread_id) = debugger.thread_id {\n        let request = debugger.step_in(thread_id);\n\n        dap_callback(cx.jobs, request, |editor, _compositor, _response: ()| {\n            debugger!(editor).resume_application();\n        });\n    } else {\n        cx.editor\n            .set_error(\"Currently active thread is not stopped. Switch the thread.\");\n    }\n}\n\npub fn dap_step_out(cx: &mut Context) {\n    let debugger = debugger!(cx.editor);\n\n    if let Some(thread_id) = debugger.thread_id {\n        let request = debugger.step_out(thread_id);\n        dap_callback(cx.jobs, request, |editor, _compositor, _response: ()| {\n            debugger!(editor).resume_application();\n        });\n    } else {\n        cx.editor\n            .set_error(\"Currently active thread is not stopped. Switch the thread.\");\n    }\n}\n\npub fn dap_next(cx: &mut Context) {\n    let debugger = debugger!(cx.editor);\n\n    if let Some(thread_id) = debugger.thread_id {\n        let request = debugger.next(thread_id);\n        dap_callback(cx.jobs, request, |editor, _compositor, _response: ()| {\n            debugger!(editor).resume_application();\n        });\n    } else {\n        cx.editor\n            .set_error(\"Currently active thread is not stopped. Switch the thread.\");\n    }\n}\n\npub fn dap_variables(cx: &mut Context) {\n    let debugger = debugger!(cx.editor);\n\n    if debugger.thread_id.is_none() {\n        cx.editor\n            .set_status(\"Cannot access variables while target is running.\");\n        return;\n    }\n    let (frame, thread_id) = match (debugger.active_frame, debugger.thread_id) {\n        (Some(frame), Some(thread_id)) => (frame, thread_id),\n        _ => {\n            cx.editor\n                .set_status(\"Cannot find current stack frame to access variables.\");\n            return;\n        }\n    };\n\n    let thread_frame = match debugger.stack_frames.get(&thread_id) {\n        Some(thread_frame) => thread_frame,\n        None => {\n            cx.editor\n                .set_error(format!(\"Failed to get stack frame for thread: {thread_id}\"));\n            return;\n        }\n    };\n    let stack_frame = match thread_frame.get(frame) {\n        Some(stack_frame) => stack_frame,\n        None => {\n            cx.editor.set_error(format!(\n                \"Failed to get stack frame for thread {thread_id} and frame {frame}.\"\n            ));\n            return;\n        }\n    };\n\n    let frame_id = stack_frame.id;\n    let scopes = match block_on(debugger.scopes(frame_id)) {\n        Ok(s) => s,\n        Err(e) => {\n            cx.editor.set_error(format!(\"Failed to get scopes: {}\", e));\n            return;\n        }\n    };\n\n    // TODO: allow expanding variables into sub-fields\n    let mut variables = Vec::new();\n\n    let theme = &cx.editor.theme;\n    let scope_style = theme.get(\"ui.linenr.selected\");\n    let type_style = theme.get(\"ui.text\");\n    let text_style = theme.get(\"ui.text.focus\");\n\n    for scope in scopes.iter() {\n        // use helix_view::graphics::Style;\n        use tui::text::Span;\n        let response = block_on(debugger.variables(scope.variables_reference));\n\n        variables.push(Spans::from(Span::styled(\n            format!(\"▸ {}\", scope.name),\n            scope_style,\n        )));\n\n        if let Ok(vars) = response {\n            variables.reserve(vars.len());\n            for var in vars {\n                let mut spans = Vec::with_capacity(5);\n\n                spans.push(Span::styled(var.name.to_owned(), text_style));\n                if let Some(ty) = var.ty {\n                    spans.push(Span::raw(\": \"));\n                    spans.push(Span::styled(ty.to_owned(), type_style));\n                }\n                spans.push(Span::raw(\" = \"));\n                spans.push(Span::styled(var.value.to_owned(), text_style));\n                variables.push(Spans::from(spans));\n            }\n        }\n    }\n\n    let contents = Text::from(tui::text::Text::from(variables));\n    let popup = Popup::new(\"dap-variables\", contents);\n    cx.replace_or_push_layer(\"dap-variables\", popup);\n}\n\npub fn dap_terminate(cx: &mut Context) {\n    cx.editor.set_status(\"Terminating debug session...\");\n    let debugger = debugger!(cx.editor);\n\n    if debugger\n        .caps\n        .as_ref()\n        .is_some_and(|c| c.supports_terminate_request.unwrap_or_default())\n    {\n        let terminate_arguments = Some(TerminateArguments {\n            restart: Some(false),\n        });\n\n        let request = debugger.terminate(terminate_arguments);\n        dap_callback(cx.jobs, request, |editor, _compositor, _response: ()| {\n            // editor.set_error(format!(\"Failed to disconnect: {}\", e));\n            editor.debug_adapters.unset_active_client();\n        });\n    } else {\n        cx.editor.debug_adapters.unset_active_client();\n    }\n}\n\npub fn dap_enable_exceptions(cx: &mut Context) {\n    let debugger = debugger!(cx.editor);\n\n    let filters = match &debugger.capabilities().exception_breakpoint_filters {\n        Some(filters) => filters.iter().map(|f| f.filter.clone()).collect(),\n        None => return,\n    };\n\n    let request = debugger.set_exception_breakpoints(filters);\n\n    dap_callback(\n        cx.jobs,\n        request,\n        |_editor, _compositor, _response: dap::requests::SetExceptionBreakpointsResponse| {\n            // editor.set_error(format!(\"Failed to set up exception breakpoints: {}\", e));\n        },\n    )\n}\n\npub fn dap_disable_exceptions(cx: &mut Context) {\n    let debugger = debugger!(cx.editor);\n\n    let request = debugger.set_exception_breakpoints(Vec::new());\n\n    dap_callback(\n        cx.jobs,\n        request,\n        |_editor, _compositor, _response: dap::requests::SetExceptionBreakpointsResponse| {\n            // editor.set_error(format!(\"Failed to set up exception breakpoints: {}\", e));\n        },\n    )\n}\n\n// TODO: both edit condition and edit log need to be stable: we might get new breakpoints from the debugger which can change offsets\npub fn dap_edit_condition(cx: &mut Context) {\n    if let Some((pos, breakpoint)) = get_breakpoint_at_current_line(cx.editor) {\n        let path = match doc!(cx.editor).path() {\n            Some(path) => path.clone(),\n            None => return,\n        };\n        let callback = Box::pin(async move {\n            let call: Callback = Callback::EditorCompositor(Box::new(move |editor, compositor| {\n                let mut prompt = Prompt::new(\n                    \"condition:\".into(),\n                    None,\n                    ui::completers::none,\n                    move |cx, input: &str, event: PromptEvent| {\n                        if event != PromptEvent::Validate {\n                            return;\n                        }\n\n                        let breakpoints = &mut cx.editor.breakpoints.get_mut(&path).unwrap();\n                        breakpoints[pos].condition = match input {\n                            \"\" => None,\n                            input => Some(input.to_owned()),\n                        };\n\n                        let debugger = debugger!(cx.editor);\n\n                        if let Err(e) = breakpoints_changed(debugger, path.clone(), breakpoints) {\n                            cx.editor\n                                .set_error(format!(\"Failed to set breakpoints: {}\", e));\n                        }\n                    },\n                );\n                if let Some(condition) = breakpoint.condition {\n                    prompt.insert_str(&condition, editor)\n                }\n                compositor.push(Box::new(prompt));\n            }));\n            Ok(call)\n        });\n        cx.jobs.callback(callback);\n    }\n}\n\npub fn dap_edit_log(cx: &mut Context) {\n    if let Some((pos, breakpoint)) = get_breakpoint_at_current_line(cx.editor) {\n        let path = match doc!(cx.editor).path() {\n            Some(path) => path.clone(),\n            None => return,\n        };\n        let callback = Box::pin(async move {\n            let call: Callback = Callback::EditorCompositor(Box::new(move |editor, compositor| {\n                let mut prompt = Prompt::new(\n                    \"log-message:\".into(),\n                    None,\n                    ui::completers::none,\n                    move |cx, input: &str, event: PromptEvent| {\n                        if event != PromptEvent::Validate {\n                            return;\n                        }\n\n                        let breakpoints = &mut cx.editor.breakpoints.get_mut(&path).unwrap();\n                        breakpoints[pos].log_message = match input {\n                            \"\" => None,\n                            input => Some(input.to_owned()),\n                        };\n\n                        let debugger = debugger!(cx.editor);\n                        if let Err(e) = breakpoints_changed(debugger, path.clone(), breakpoints) {\n                            cx.editor\n                                .set_error(format!(\"Failed to set breakpoints: {}\", e));\n                        }\n                    },\n                );\n                if let Some(log_message) = breakpoint.log_message {\n                    prompt.insert_str(&log_message, editor);\n                }\n                compositor.push(Box::new(prompt));\n            }));\n            Ok(call)\n        });\n        cx.jobs.callback(callback);\n    }\n}\n\npub fn dap_switch_thread(cx: &mut Context) {\n    thread_picker(cx, |editor, thread| {\n        block_on(select_thread_id(editor, thread.id, true));\n    })\n}\npub fn dap_switch_stack_frame(cx: &mut Context) {\n    let debugger = debugger!(cx.editor);\n\n    let thread_id = match debugger.thread_id {\n        Some(thread_id) => thread_id,\n        None => {\n            cx.editor.set_error(\"No thread is currently active\");\n            return;\n        }\n    };\n\n    let frames = debugger.stack_frames[&thread_id]\n        .iter()\n        .cloned()\n        .enumerate()\n        .collect::<Vec<_>>();\n    let thread_state = debugger\n        .thread_states\n        .get(&thread_id)\n        .cloned()\n        .unwrap_or_else(|| \"unknown\".to_string());\n\n    let columns = [ui::PickerColumn::new(\n        \"frame\",\n        |item: &(usize, StackFrame), thread_state: &String| {\n            format!(\"{} ({})\", item.1.name, thread_state).into()\n        },\n    )];\n    let picker = Picker::new(\n        columns,\n        0,\n        frames,\n        thread_state,\n        move |cx, (index, frame), _action| {\n            let debugger = debugger!(cx.editor);\n            debugger.active_frame = Some(*index);\n            jump_to_stack_frame(cx.editor, frame);\n        },\n    )\n    .with_preview(move |_editor, (_index, frame)| {\n        frame.source.as_ref().and_then(|source| {\n            source.path.as_ref().map(|path| {\n                (\n                    path.as_path().into(),\n                    Some((\n                        frame.line.saturating_sub(1),\n                        frame.end_line.unwrap_or(frame.line).saturating_sub(1),\n                    )),\n                )\n            })\n        })\n    });\n    cx.push_layer(Box::new(picker))\n}\n"
  },
  {
    "path": "helix-term/src/commands/lsp.rs",
    "content": "use futures_util::{stream::FuturesOrdered, FutureExt};\nuse helix_lsp::{\n    block_on,\n    lsp::{\n        self, CodeAction, CodeActionOrCommand, CodeActionTriggerKind, DiagnosticSeverity,\n        NumberOrString,\n    },\n    util::{diagnostic_to_lsp_diagnostic, lsp_range_to_range, range_to_lsp_range},\n    Client, LanguageServerId, OffsetEncoding,\n};\nuse tokio_stream::StreamExt;\nuse tui::{text::Span, widgets::Row};\n\nuse super::{align_view, push_jump, Align, Context, Editor};\n\nuse helix_core::{\n    diagnostic::DiagnosticProvider, syntax::config::LanguageServerFeature,\n    text_annotations::InlineAnnotation, Selection, Uri,\n};\nuse helix_stdx::path;\nuse helix_view::{\n    document::{DocumentInlayHints, DocumentInlayHintsId},\n    editor::Action,\n    handlers::lsp::SignatureHelpInvoked,\n    theme::Style,\n    Document, View,\n};\n\nuse crate::{\n    compositor::{self, Compositor},\n    job::Callback,\n    ui::{self, overlay::overlaid, FileLocation, Picker, Popup, PromptEvent},\n};\n\nuse std::{cmp::Ordering, collections::HashSet, fmt::Display, future::Future, path::Path};\n\n/// Gets the first language server that is attached to a document which supports a specific feature.\n/// If there is no configured language server that supports the feature, this displays a status message.\n/// Using this macro in a context where the editor automatically queries the LSP\n/// (instead of when the user explicitly does so via a keybind like `gd`)\n/// will spam the \"No configured language server supports \\<feature>\" status message confusingly.\n#[macro_export]\nmacro_rules! language_server_with_feature {\n    ($editor:expr, $doc:expr, $feature:expr) => {{\n        let language_server = $doc.language_servers_with_feature($feature).next();\n        match language_server {\n            Some(language_server) => language_server,\n            None => {\n                $editor.set_error(format!(\n                    \"No configured language server supports {}\",\n                    $feature\n                ));\n                return;\n            }\n        }\n    }};\n}\n\n/// A wrapper around `lsp::Location` that swaps out the LSP URI for `helix_core::Uri` and adds\n/// the server's  offset encoding.\n#[derive(Debug, Clone, PartialEq, Eq)]\nstruct Location {\n    uri: Uri,\n    range: lsp::Range,\n    offset_encoding: OffsetEncoding,\n}\n\nfn lsp_location_to_location(\n    location: lsp::Location,\n    offset_encoding: OffsetEncoding,\n) -> Option<Location> {\n    let uri = match location.uri.try_into() {\n        Ok(uri) => uri,\n        Err(err) => {\n            log::warn!(\"discarding invalid or unsupported URI: {err}\");\n            return None;\n        }\n    };\n    Some(Location {\n        uri,\n        range: location.range,\n        offset_encoding,\n    })\n}\n\nstruct SymbolInformationItem {\n    location: Location,\n    symbol: lsp::SymbolInformation,\n}\n\nstruct DiagnosticStyles {\n    hint: Style,\n    info: Style,\n    warning: Style,\n    error: Style,\n}\n\nstruct PickerDiagnostic {\n    location: Location,\n    diag: lsp::Diagnostic,\n}\n\nfn location_to_file_location(location: &Location) -> Option<FileLocation<'_>> {\n    let path = location.uri.as_path()?;\n    let line = Some((\n        location.range.start.line as usize,\n        location.range.end.line as usize,\n    ));\n    Some((path.into(), line))\n}\n\nfn jump_to_location(editor: &mut Editor, location: &Location, action: Action) {\n    let (view, doc) = current!(editor);\n    push_jump(view, doc);\n\n    let Some(path) = location.uri.as_path() else {\n        let err = format!(\"unable to convert URI to filepath: {:?}\", location.uri);\n        editor.set_error(err);\n        return;\n    };\n    jump_to_position(\n        editor,\n        path,\n        location.range,\n        location.offset_encoding,\n        action,\n    );\n}\n\nfn jump_to_position(\n    editor: &mut Editor,\n    path: &Path,\n    range: lsp::Range,\n    offset_encoding: OffsetEncoding,\n    action: Action,\n) {\n    let doc = match editor.open(path, action) {\n        Ok(id) => doc_mut!(editor, &id),\n        Err(err) => {\n            let err = format!(\"failed to open path: {:?}: {:?}\", path, err);\n            editor.set_error(err);\n            return;\n        }\n    };\n    let view = view_mut!(editor);\n    // TODO: convert inside server\n    let new_range = if let Some(new_range) = lsp_range_to_range(doc.text(), range, offset_encoding)\n    {\n        new_range\n    } else {\n        log::warn!(\"lsp position out of bounds - {:?}\", range);\n        return;\n    };\n    // we flip the range so that the cursor sits on the start of the symbol\n    // (for example start of the function).\n    doc.set_selection(view.id, Selection::single(new_range.head, new_range.anchor));\n    if action.align_view(view, doc.id()) {\n        align_view(doc, view, Align::Center);\n    }\n}\n\nfn display_symbol_kind(kind: lsp::SymbolKind) -> &'static str {\n    match kind {\n        lsp::SymbolKind::FILE => \"file\",\n        lsp::SymbolKind::MODULE => \"module\",\n        lsp::SymbolKind::NAMESPACE => \"namespace\",\n        lsp::SymbolKind::PACKAGE => \"package\",\n        lsp::SymbolKind::CLASS => \"class\",\n        lsp::SymbolKind::METHOD => \"method\",\n        lsp::SymbolKind::PROPERTY => \"property\",\n        lsp::SymbolKind::FIELD => \"field\",\n        lsp::SymbolKind::CONSTRUCTOR => \"construct\",\n        lsp::SymbolKind::ENUM => \"enum\",\n        lsp::SymbolKind::INTERFACE => \"interface\",\n        lsp::SymbolKind::FUNCTION => \"function\",\n        lsp::SymbolKind::VARIABLE => \"variable\",\n        lsp::SymbolKind::CONSTANT => \"constant\",\n        lsp::SymbolKind::STRING => \"string\",\n        lsp::SymbolKind::NUMBER => \"number\",\n        lsp::SymbolKind::BOOLEAN => \"boolean\",\n        lsp::SymbolKind::ARRAY => \"array\",\n        lsp::SymbolKind::OBJECT => \"object\",\n        lsp::SymbolKind::KEY => \"key\",\n        lsp::SymbolKind::NULL => \"null\",\n        lsp::SymbolKind::ENUM_MEMBER => \"enummem\",\n        lsp::SymbolKind::STRUCT => \"struct\",\n        lsp::SymbolKind::EVENT => \"event\",\n        lsp::SymbolKind::OPERATOR => \"operator\",\n        lsp::SymbolKind::TYPE_PARAMETER => \"typeparam\",\n        _ => {\n            log::warn!(\"Unknown symbol kind: {:?}\", kind);\n            \"\"\n        }\n    }\n}\n\n#[derive(Copy, Clone, PartialEq)]\nenum DiagnosticsFormat {\n    ShowSourcePath,\n    HideSourcePath,\n}\n\ntype DiagnosticsPicker = Picker<PickerDiagnostic, DiagnosticStyles>;\n\nfn diag_picker(\n    cx: &Context,\n    diagnostics: impl IntoIterator<Item = (Uri, Vec<(lsp::Diagnostic, DiagnosticProvider)>)>,\n    format: DiagnosticsFormat,\n) -> DiagnosticsPicker {\n    // TODO: drop current_path comparison and instead use workspace: bool flag?\n\n    // flatten the map to a vec of (url, diag) pairs\n    let mut flat_diag = Vec::new();\n    for (uri, diags) in diagnostics {\n        flat_diag.reserve(diags.len());\n\n        for (diag, provider) in diags {\n            if let Some(ls) = provider\n                .language_server_id()\n                .and_then(|id| cx.editor.language_server_by_id(id))\n            {\n                flat_diag.push(PickerDiagnostic {\n                    location: Location {\n                        uri: uri.clone(),\n                        range: diag.range,\n                        offset_encoding: ls.offset_encoding(),\n                    },\n                    diag,\n                });\n            }\n        }\n    }\n\n    flat_diag.sort_by(|a, b| {\n        a.diag\n            .severity\n            .unwrap_or(lsp::DiagnosticSeverity::HINT)\n            .cmp(&b.diag.severity.unwrap_or(lsp::DiagnosticSeverity::HINT))\n    });\n\n    let styles = DiagnosticStyles {\n        hint: cx.editor.theme.get(\"hint\"),\n        info: cx.editor.theme.get(\"info\"),\n        warning: cx.editor.theme.get(\"warning\"),\n        error: cx.editor.theme.get(\"error\"),\n    };\n\n    let mut columns = vec![\n        ui::PickerColumn::new(\n            \"severity\",\n            |item: &PickerDiagnostic, styles: &DiagnosticStyles| {\n                match item.diag.severity {\n                    Some(DiagnosticSeverity::HINT) => Span::styled(\"HINT\", styles.hint),\n                    Some(DiagnosticSeverity::INFORMATION) => Span::styled(\"INFO\", styles.info),\n                    Some(DiagnosticSeverity::WARNING) => Span::styled(\"WARN\", styles.warning),\n                    Some(DiagnosticSeverity::ERROR) => Span::styled(\"ERROR\", styles.error),\n                    _ => Span::raw(\"\"),\n                }\n                .into()\n            },\n        ),\n        ui::PickerColumn::new(\"source\", |item: &PickerDiagnostic, _| {\n            item.diag.source.as_deref().unwrap_or(\"\").into()\n        }),\n        ui::PickerColumn::new(\"code\", |item: &PickerDiagnostic, _| {\n            match item.diag.code.as_ref() {\n                Some(NumberOrString::Number(n)) => n.to_string().into(),\n                Some(NumberOrString::String(s)) => s.as_str().into(),\n                None => \"\".into(),\n            }\n        }),\n        ui::PickerColumn::new(\"message\", |item: &PickerDiagnostic, _| {\n            item.diag.message.as_str().into()\n        }),\n    ];\n    let mut primary_column = 3; // message\n\n    if format == DiagnosticsFormat::ShowSourcePath {\n        columns.insert(\n            // between message code and message\n            3,\n            ui::PickerColumn::new(\"path\", |item: &PickerDiagnostic, _| {\n                if let Some(path) = item.location.uri.as_path() {\n                    path::get_truncated_path(path)\n                        .to_string_lossy()\n                        .to_string()\n                        .into()\n                } else {\n                    Default::default()\n                }\n            }),\n        );\n        primary_column += 1;\n    }\n\n    Picker::new(\n        columns,\n        primary_column,\n        flat_diag,\n        styles,\n        move |cx, diag, action| {\n            jump_to_location(cx.editor, &diag.location, action);\n            let (view, doc) = current!(cx.editor);\n            view.diagnostics_handler\n                .immediately_show_diagnostic(doc, view.id);\n        },\n    )\n    .with_preview(move |_editor, diag| location_to_file_location(&diag.location))\n    .truncate_start(false)\n}\n\npub fn symbol_picker(cx: &mut Context) {\n    fn nested_to_flat(\n        list: &mut Vec<SymbolInformationItem>,\n        file: &lsp::TextDocumentIdentifier,\n        uri: &Uri,\n        symbol: lsp::DocumentSymbol,\n        offset_encoding: OffsetEncoding,\n    ) {\n        #[allow(deprecated)]\n        list.push(SymbolInformationItem {\n            symbol: lsp::SymbolInformation {\n                name: symbol.name,\n                kind: symbol.kind,\n                tags: symbol.tags,\n                deprecated: symbol.deprecated,\n                location: lsp::Location::new(file.uri.clone(), symbol.selection_range),\n                container_name: None,\n            },\n            location: Location {\n                uri: uri.clone(),\n                range: symbol.selection_range,\n                offset_encoding,\n            },\n        });\n        for child in symbol.children.into_iter().flatten() {\n            nested_to_flat(list, file, uri, child, offset_encoding);\n        }\n    }\n    let doc = doc!(cx.editor);\n\n    let mut seen_language_servers = HashSet::new();\n\n    let mut futures: FuturesOrdered<_> = doc\n        .language_servers_with_feature(LanguageServerFeature::DocumentSymbols)\n        .filter(|ls| seen_language_servers.insert(ls.id()))\n        .map(|language_server| {\n            let request = language_server.document_symbols(doc.identifier()).unwrap();\n            let offset_encoding = language_server.offset_encoding();\n            let doc_id = doc.identifier();\n            let doc_uri = doc\n                .uri()\n                .expect(\"docs with active language servers must be backed by paths\");\n\n            async move {\n                let symbols = match request.await? {\n                    Some(symbols) => symbols,\n                    None => return anyhow::Ok(vec![]),\n                };\n                // lsp has two ways to represent symbols (flat/nested)\n                // convert the nested variant to flat, so that we have a homogeneous list\n                let symbols = match symbols {\n                    lsp::DocumentSymbolResponse::Flat(symbols) => symbols\n                        .into_iter()\n                        .map(|symbol| SymbolInformationItem {\n                            location: Location {\n                                uri: doc_uri.clone(),\n                                range: symbol.location.range,\n                                offset_encoding,\n                            },\n                            symbol,\n                        })\n                        .collect(),\n                    lsp::DocumentSymbolResponse::Nested(symbols) => {\n                        let mut flat_symbols = Vec::new();\n                        for symbol in symbols {\n                            nested_to_flat(\n                                &mut flat_symbols,\n                                &doc_id,\n                                &doc_uri,\n                                symbol,\n                                offset_encoding,\n                            )\n                        }\n                        flat_symbols\n                    }\n                };\n                Ok(symbols)\n            }\n        })\n        .collect();\n\n    if futures.is_empty() {\n        cx.editor\n            .set_error(\"No configured language server supports document symbols\");\n        return;\n    }\n\n    cx.jobs.callback(async move {\n        let mut symbols = Vec::new();\n        while let Some(response) = futures.next().await {\n            match response {\n                Ok(mut items) => symbols.append(&mut items),\n                Err(err) => log::error!(\"Error requesting document symbols: {err}\"),\n            }\n        }\n        let call = move |_editor: &mut Editor, compositor: &mut Compositor| {\n            let columns = [\n                ui::PickerColumn::new(\"kind\", |item: &SymbolInformationItem, _| {\n                    display_symbol_kind(item.symbol.kind).into()\n                }),\n                // Some symbols in the document symbol picker may have a URI that isn't\n                // the current file. It should be rare though, so we concatenate that\n                // URI in with the symbol name in this picker.\n                ui::PickerColumn::new(\"name\", |item: &SymbolInformationItem, _| {\n                    item.symbol.name.as_str().into()\n                }),\n                ui::PickerColumn::new(\"container\", |item: &SymbolInformationItem, _| {\n                    item.symbol\n                        .container_name\n                        .as_deref()\n                        .unwrap_or_default()\n                        .into()\n                }),\n            ];\n\n            let picker = Picker::new(\n                columns,\n                1, // name column\n                symbols,\n                (),\n                move |cx, item, action| {\n                    jump_to_location(cx.editor, &item.location, action);\n                },\n            )\n            .with_preview(move |_editor, item| location_to_file_location(&item.location))\n            .truncate_start(false);\n\n            compositor.push(Box::new(overlaid(picker)))\n        };\n\n        Ok(Callback::EditorCompositor(Box::new(call)))\n    });\n}\n\npub fn workspace_symbol_picker(cx: &mut Context) {\n    use crate::ui::picker::Injector;\n\n    let doc = doc!(cx.editor);\n    if doc\n        .language_servers_with_feature(LanguageServerFeature::WorkspaceSymbols)\n        .count()\n        == 0\n    {\n        cx.editor\n            .set_error(\"No configured language server supports workspace symbols\");\n        return;\n    }\n\n    let get_symbols = |pattern: &str, editor: &mut Editor, _data, injector: &Injector<_, _>| {\n        let doc = doc!(editor);\n        let mut seen_language_servers = HashSet::new();\n        let mut futures: FuturesOrdered<_> = doc\n            .language_servers_with_feature(LanguageServerFeature::WorkspaceSymbols)\n            .filter(|ls| seen_language_servers.insert(ls.id()))\n            .map(|language_server| {\n                let request = language_server\n                    .workspace_symbols(pattern.to_string())\n                    .unwrap();\n                let offset_encoding = language_server.offset_encoding();\n                async move {\n                    let symbols = request\n                        .await?\n                        .and_then(|resp| match resp {\n                            lsp::WorkspaceSymbolResponse::Flat(symbols) => Some(symbols),\n                            lsp::WorkspaceSymbolResponse::Nested(_) => None,\n                        })\n                        .unwrap_or_default();\n\n                    let response: Vec<_> = symbols\n                        .into_iter()\n                        .filter_map(|symbol| {\n                            let uri = match Uri::try_from(&symbol.location.uri) {\n                                Ok(uri) => uri,\n                                Err(err) => {\n                                    log::warn!(\"discarding symbol with invalid URI: {err}\");\n                                    return None;\n                                }\n                            };\n                            Some(SymbolInformationItem {\n                                location: Location {\n                                    uri,\n                                    range: symbol.location.range,\n                                    offset_encoding,\n                                },\n                                symbol,\n                            })\n                        })\n                        .collect();\n\n                    anyhow::Ok(response)\n                }\n            })\n            .collect();\n\n        if futures.is_empty() {\n            editor.set_error(\"No configured language server supports workspace symbols\");\n        }\n\n        let injector = injector.clone();\n        async move {\n            while let Some(response) = futures.next().await {\n                match response {\n                    Ok(items) => {\n                        for item in items {\n                            injector.push(item)?;\n                        }\n                    }\n                    Err(err) => log::error!(\"Error requesting workspace symbols: {err}\"),\n                }\n            }\n            Ok(())\n        }\n        .boxed()\n    };\n    let columns = [\n        ui::PickerColumn::new(\"kind\", |item: &SymbolInformationItem, _| {\n            display_symbol_kind(item.symbol.kind).into()\n        }),\n        ui::PickerColumn::new(\"name\", |item: &SymbolInformationItem, _| {\n            item.symbol.name.as_str().into()\n        })\n        .without_filtering(),\n        ui::PickerColumn::new(\"container\", |item: &SymbolInformationItem, _| {\n            item.symbol\n                .container_name\n                .as_deref()\n                .unwrap_or_default()\n                .into()\n        }),\n        ui::PickerColumn::new(\"path\", |item: &SymbolInformationItem, _| {\n            if let Some(path) = item.location.uri.as_path() {\n                path::get_relative_path(path)\n                    .to_string_lossy()\n                    .to_string()\n                    .into()\n            } else {\n                item.symbol.location.uri.to_string().into()\n            }\n        }),\n    ];\n\n    let picker = Picker::new(\n        columns,\n        1, // name column\n        [],\n        (),\n        move |cx, item, action| {\n            jump_to_location(cx.editor, &item.location, action);\n        },\n    )\n    .with_preview(|_editor, item| location_to_file_location(&item.location))\n    .with_dynamic_query(get_symbols, None)\n    .truncate_start(false);\n\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\npub fn diagnostics_picker(cx: &mut Context) {\n    let doc = doc!(cx.editor);\n    if let Some(uri) = doc.uri() {\n        let diagnostics = cx.editor.diagnostics.get(&uri).cloned().unwrap_or_default();\n        let picker = diag_picker(cx, [(uri, diagnostics)], DiagnosticsFormat::HideSourcePath);\n        cx.push_layer(Box::new(overlaid(picker)));\n    }\n}\n\npub fn workspace_diagnostics_picker(cx: &mut Context) {\n    // TODO not yet filtered by LanguageServerFeature, need to do something similar as Document::shown_diagnostics here for all open documents\n    let diagnostics = cx.editor.diagnostics.clone();\n    let picker = diag_picker(cx, diagnostics, DiagnosticsFormat::ShowSourcePath);\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\nstruct CodeActionOrCommandItem {\n    lsp_item: lsp::CodeActionOrCommand,\n    language_server_id: LanguageServerId,\n}\n\nimpl ui::menu::Item for CodeActionOrCommandItem {\n    type Data = ();\n    fn format(&self, _data: &Self::Data) -> Row<'_> {\n        match &self.lsp_item {\n            lsp::CodeActionOrCommand::CodeAction(action) => action.title.as_str().into(),\n            lsp::CodeActionOrCommand::Command(command) => command.title.as_str().into(),\n        }\n    }\n}\n\n/// Determines the category of the `CodeAction` using the `CodeAction::kind` field.\n/// Returns a number that represent these categories.\n/// Categories with a lower number should be displayed first.\n///\n///\n/// While the `kind` field is defined as open ended in the LSP spec (any value may be used)\n/// in practice a closed set of common values (mostly suggested in the LSP spec) are used.\n/// VSCode displays each of these categories separately (separated by a heading in the codeactions picker)\n/// to make them easier to navigate. Helix does not display these  headings to the user.\n/// However it does sort code actions by their categories to achieve the same order as the VScode picker,\n/// just without the headings.\n///\n/// The order used here is modeled after the [vscode sourcecode](https://github.com/microsoft/vscode/blob/eaec601dd69aeb4abb63b9601a6f44308c8d8c6e/src/vs/editor/contrib/codeAction/browser/codeActionWidget.ts>)\nfn action_category(action: &CodeActionOrCommand) -> u32 {\n    if let CodeActionOrCommand::CodeAction(CodeAction {\n        kind: Some(kind), ..\n    }) = action\n    {\n        let mut components = kind.as_str().split('.');\n        match components.next() {\n            Some(\"quickfix\") => 0,\n            Some(\"refactor\") => match components.next() {\n                Some(\"extract\") => 1,\n                Some(\"inline\") => 2,\n                Some(\"rewrite\") => 3,\n                Some(\"move\") => 4,\n                Some(\"surround\") => 5,\n                _ => 7,\n            },\n            Some(\"source\") => 6,\n            _ => 7,\n        }\n    } else {\n        7\n    }\n}\n\nfn action_preferred(action: &CodeActionOrCommand) -> bool {\n    matches!(\n        action,\n        CodeActionOrCommand::CodeAction(CodeAction {\n            is_preferred: Some(true),\n            ..\n        })\n    )\n}\n\nfn action_fixes_diagnostics(action: &CodeActionOrCommand) -> bool {\n    matches!(\n        action,\n        CodeActionOrCommand::CodeAction(CodeAction {\n            diagnostics: Some(diagnostics),\n            ..\n        }) if !diagnostics.is_empty()\n    )\n}\n\npub fn code_action(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n\n    let selection_range = doc.selection(view.id).primary();\n\n    let mut seen_language_servers = HashSet::new();\n\n    let mut futures: FuturesOrdered<_> = doc\n        .language_servers_with_feature(LanguageServerFeature::CodeAction)\n        .filter(|ls| seen_language_servers.insert(ls.id()))\n        // TODO this should probably already been filtered in something like \"language_servers_with_feature\"\n        .filter_map(|language_server| {\n            let offset_encoding = language_server.offset_encoding();\n            let language_server_id = language_server.id();\n            let range = range_to_lsp_range(doc.text(), selection_range, offset_encoding);\n            // Filter and convert overlapping diagnostics\n            let code_action_context = lsp::CodeActionContext {\n                diagnostics: doc\n                    .diagnostics()\n                    .iter()\n                    .filter(|&diag| {\n                        selection_range\n                            .overlaps(&helix_core::Range::new(diag.range.start, diag.range.end))\n                    })\n                    .map(|diag| diagnostic_to_lsp_diagnostic(doc.text(), diag, offset_encoding))\n                    .collect(),\n                only: None,\n                trigger_kind: Some(CodeActionTriggerKind::INVOKED),\n            };\n            let code_action_request =\n                language_server.code_actions(doc.identifier(), range, code_action_context)?;\n            Some((code_action_request, language_server_id))\n        })\n        .map(|(request, ls_id)| async move {\n            let Some(mut actions) = request.await? else {\n                return anyhow::Ok(Vec::new());\n            };\n\n            // remove disabled code actions\n            actions.retain(|action| {\n                matches!(\n                    action,\n                    CodeActionOrCommand::Command(_)\n                        | CodeActionOrCommand::CodeAction(CodeAction { disabled: None, .. })\n                )\n            });\n\n            // Sort codeactions into a useful order. This behaviour is only partially described in the LSP spec.\n            // Many details are modeled after vscode because language servers are usually tested against it.\n            // VScode sorts the codeaction two times:\n            //\n            // First the codeactions that fix some diagnostics are moved to the front.\n            // If both codeactions fix some diagnostics (or both fix none) the codeaction\n            // that is marked with `is_preferred` is shown first. The codeactions are then shown in separate\n            // submenus that only contain a certain category (see `action_category`) of actions.\n            //\n            // Below this done in in a single sorting step\n            actions.sort_by(|action1, action2| {\n                // sort actions by category\n                let order = action_category(action1).cmp(&action_category(action2));\n                if order != Ordering::Equal {\n                    return order;\n                }\n                // within the categories sort by relevancy.\n                // Modeled after the `codeActionsComparator` function in vscode:\n                // https://github.com/microsoft/vscode/blob/eaec601dd69aeb4abb63b9601a6f44308c8d8c6e/src/vs/editor/contrib/codeAction/browser/codeAction.ts\n\n                // if one code action fixes a diagnostic but the other one doesn't show it first\n                let order = action_fixes_diagnostics(action1)\n                    .cmp(&action_fixes_diagnostics(action2))\n                    .reverse();\n                if order != Ordering::Equal {\n                    return order;\n                }\n\n                // if one of the codeactions is marked as preferred show it first\n                // otherwise keep the original LSP sorting\n                action_preferred(action1)\n                    .cmp(&action_preferred(action2))\n                    .reverse()\n            });\n\n            Ok(actions\n                .into_iter()\n                .map(|lsp_item| CodeActionOrCommandItem {\n                    lsp_item,\n                    language_server_id: ls_id,\n                })\n                .collect())\n        })\n        .collect();\n\n    if futures.is_empty() {\n        cx.editor\n            .set_error(\"No configured language server supports code actions\");\n        return;\n    }\n\n    cx.jobs.callback(async move {\n        let mut actions = Vec::new();\n\n        while let Some(output) = futures.next().await {\n            match output {\n                Ok(mut lsp_items) => actions.append(&mut lsp_items),\n                Err(err) => log::error!(\"while gathering code actions: {err}\"),\n            }\n        }\n\n        let call = move |editor: &mut Editor, compositor: &mut Compositor| {\n            if actions.is_empty() {\n                editor.set_error(\"No code actions available\");\n                return;\n            }\n            let mut picker = ui::Menu::new(actions, (), move |editor, action, event| {\n                if event != PromptEvent::Validate {\n                    return;\n                }\n\n                // always present here\n                let action = action.unwrap();\n                let Some(language_server) = editor.language_server_by_id(action.language_server_id)\n                else {\n                    editor.set_error(\"Language Server disappeared\");\n                    return;\n                };\n                let offset_encoding = language_server.offset_encoding();\n\n                match &action.lsp_item {\n                    lsp::CodeActionOrCommand::Command(command) => {\n                        log::debug!(\"code action command: {:?}\", command);\n                        editor.execute_lsp_command(command.clone(), action.language_server_id);\n                    }\n                    lsp::CodeActionOrCommand::CodeAction(code_action) => {\n                        log::debug!(\"code action: {:?}\", code_action);\n                        // we support lsp \"codeAction/resolve\" for `edit` and `command` fields\n                        let mut resolved_code_action = None;\n                        if code_action.edit.is_none() || code_action.command.is_none() {\n                            if let Some(future) = language_server.resolve_code_action(code_action) {\n                                if let Ok(code_action) = helix_lsp::block_on(future) {\n                                    resolved_code_action = Some(code_action);\n                                }\n                            }\n                        }\n                        let resolved_code_action =\n                            resolved_code_action.as_ref().unwrap_or(code_action);\n\n                        if let Some(ref workspace_edit) = resolved_code_action.edit {\n                            let _ = editor.apply_workspace_edit(offset_encoding, workspace_edit);\n                        }\n\n                        // if code action provides both edit and command first the edit\n                        // should be applied and then the command\n                        if let Some(command) = &code_action.command {\n                            editor.execute_lsp_command(command.clone(), action.language_server_id);\n                        }\n                    }\n                }\n            });\n            picker.move_down(); // pre-select the first item\n\n            let popup = Popup::new(\"code-action\", picker)\n                .with_scrollbar(false)\n                .auto_close(true);\n\n            compositor.replace_or_push(\"code-action\", popup);\n        };\n\n        Ok(Callback::EditorCompositor(Box::new(call)))\n    });\n}\n\n#[derive(Debug)]\npub struct ApplyEditError {\n    pub kind: ApplyEditErrorKind,\n    pub failed_change_idx: usize,\n}\n\n#[derive(Debug)]\npub enum ApplyEditErrorKind {\n    DocumentChanged,\n    FileNotFound,\n    UnknownURISchema,\n    IoError(std::io::Error),\n    // TODO: check edits before applying and propagate failure\n    // InvalidEdit,\n}\n\nimpl Display for ApplyEditErrorKind {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            ApplyEditErrorKind::DocumentChanged => f.write_str(\"document has changed\"),\n            ApplyEditErrorKind::FileNotFound => f.write_str(\"file not found\"),\n            ApplyEditErrorKind::UnknownURISchema => f.write_str(\"URI schema not supported\"),\n            ApplyEditErrorKind::IoError(err) => f.write_str(&format!(\"{err}\")),\n        }\n    }\n}\n\n/// Precondition: `locations` should be non-empty.\nfn goto_impl(editor: &mut Editor, compositor: &mut Compositor, locations: Vec<Location>) {\n    let cwdir = helix_stdx::env::current_working_dir();\n\n    match locations.as_slice() {\n        [location] => {\n            jump_to_location(editor, location, Action::Replace);\n        }\n        [] => unreachable!(\"`locations` should be non-empty for `goto_impl`\"),\n        _locations => {\n            let columns = [ui::PickerColumn::new(\n                \"location\",\n                |item: &Location, cwdir: &std::path::PathBuf| {\n                    let path = if let Some(path) = item.uri.as_path() {\n                        path.strip_prefix(cwdir).unwrap_or(path).to_string_lossy()\n                    } else {\n                        item.uri.to_string().into()\n                    };\n\n                    format!(\"{path}:{}\", item.range.start.line + 1).into()\n                },\n            )];\n\n            let picker = Picker::new(columns, 0, locations, cwdir, |cx, location, action| {\n                jump_to_location(cx.editor, location, action)\n            })\n            .with_preview(|_editor, location| location_to_file_location(location));\n            compositor.push(Box::new(overlaid(picker)));\n        }\n    }\n}\n\nfn goto_single_impl<P, F>(cx: &mut Context, feature: LanguageServerFeature, request_provider: P)\nwhere\n    P: Fn(&Client, lsp::Position, lsp::TextDocumentIdentifier) -> Option<F>,\n    F: Future<Output = helix_lsp::Result<Option<lsp::GotoDefinitionResponse>>> + 'static + Send,\n{\n    let (view, doc) = current_ref!(cx.editor);\n    let mut futures: FuturesOrdered<_> = doc\n        .language_servers_with_feature(feature)\n        .map(|language_server| {\n            let offset_encoding = language_server.offset_encoding();\n            let pos = doc.position(view.id, offset_encoding);\n            let future = request_provider(language_server, pos, doc.identifier()).unwrap();\n            async move { anyhow::Ok((future.await?, offset_encoding)) }\n        })\n        .collect();\n\n    cx.jobs.callback(async move {\n        let mut locations = Vec::new();\n        while let Some(response) = futures.next().await {\n            match response {\n                Ok((response, offset_encoding)) => match response {\n                    Some(lsp::GotoDefinitionResponse::Scalar(lsp_location)) => {\n                        locations.extend(lsp_location_to_location(lsp_location, offset_encoding));\n                    }\n                    Some(lsp::GotoDefinitionResponse::Array(lsp_locations)) => {\n                        locations.extend(lsp_locations.into_iter().flat_map(|location| {\n                            lsp_location_to_location(location, offset_encoding)\n                        }));\n                    }\n                    Some(lsp::GotoDefinitionResponse::Link(lsp_locations)) => {\n                        locations.extend(\n                            lsp_locations\n                                .into_iter()\n                                .map(|location_link| {\n                                    lsp::Location::new(\n                                        location_link.target_uri,\n                                        location_link.target_range,\n                                    )\n                                })\n                                .flat_map(|location| {\n                                    lsp_location_to_location(location, offset_encoding)\n                                }),\n                        );\n                    }\n                    None => (),\n                },\n                Err(err) => log::error!(\"Error requesting locations: {err}\"),\n            }\n        }\n        let call = move |editor: &mut Editor, compositor: &mut Compositor| {\n            if locations.is_empty() {\n                editor.set_error(match feature {\n                    LanguageServerFeature::GotoDeclaration => \"No declaration found.\",\n                    LanguageServerFeature::GotoDefinition => \"No definition found.\",\n                    LanguageServerFeature::GotoTypeDefinition => \"No type definition found.\",\n                    LanguageServerFeature::GotoImplementation => \"No implementation found.\",\n                    _ => \"No location found.\",\n                });\n            } else {\n                goto_impl(editor, compositor, locations);\n            }\n        };\n        Ok(Callback::EditorCompositor(Box::new(call)))\n    });\n}\n\npub fn goto_declaration(cx: &mut Context) {\n    goto_single_impl(\n        cx,\n        LanguageServerFeature::GotoDeclaration,\n        |ls, pos, doc_id| ls.goto_declaration(doc_id, pos, None),\n    );\n}\n\npub fn goto_definition(cx: &mut Context) {\n    goto_single_impl(\n        cx,\n        LanguageServerFeature::GotoDefinition,\n        |ls, pos, doc_id| ls.goto_definition(doc_id, pos, None),\n    );\n}\n\npub fn goto_type_definition(cx: &mut Context) {\n    goto_single_impl(\n        cx,\n        LanguageServerFeature::GotoTypeDefinition,\n        |ls, pos, doc_id| ls.goto_type_definition(doc_id, pos, None),\n    );\n}\n\npub fn goto_implementation(cx: &mut Context) {\n    goto_single_impl(\n        cx,\n        LanguageServerFeature::GotoImplementation,\n        |ls, pos, doc_id| ls.goto_implementation(doc_id, pos, None),\n    );\n}\n\npub fn goto_reference(cx: &mut Context) {\n    let config = cx.editor.config();\n    let (view, doc) = current_ref!(cx.editor);\n\n    let mut futures: FuturesOrdered<_> = doc\n        .language_servers_with_feature(LanguageServerFeature::GotoReference)\n        .map(|language_server| {\n            let offset_encoding = language_server.offset_encoding();\n            let pos = doc.position(view.id, offset_encoding);\n            let future = language_server\n                .goto_reference(\n                    doc.identifier(),\n                    pos,\n                    config.lsp.goto_reference_include_declaration,\n                    None,\n                )\n                .unwrap();\n            async move { anyhow::Ok((future.await?, offset_encoding)) }\n        })\n        .collect();\n\n    cx.jobs.callback(async move {\n        let mut locations = Vec::new();\n        while let Some(response) = futures.next().await {\n            match response {\n                Ok((lsp_locations, offset_encoding)) => locations.extend(\n                    lsp_locations\n                        .into_iter()\n                        .flatten()\n                        .flat_map(|location| lsp_location_to_location(location, offset_encoding)),\n                ),\n                Err(err) => log::error!(\"Error requesting references: {err}\"),\n            }\n        }\n        let call = move |editor: &mut Editor, compositor: &mut Compositor| {\n            if locations.is_empty() {\n                editor.set_error(\"No references found.\");\n            } else {\n                goto_impl(editor, compositor, locations);\n            }\n        };\n        Ok(Callback::EditorCompositor(Box::new(call)))\n    });\n}\n\npub fn signature_help(cx: &mut Context) {\n    cx.editor\n        .handlers\n        .trigger_signature_help(SignatureHelpInvoked::Manual, cx.editor)\n}\n\npub fn hover(cx: &mut Context) {\n    use ui::lsp::hover::Hover;\n\n    let (view, doc) = current!(cx.editor);\n    if doc\n        .language_servers_with_feature(LanguageServerFeature::Hover)\n        .count()\n        == 0\n    {\n        cx.editor\n            .set_error(\"No configured language server supports hover\");\n        return;\n    }\n\n    let mut seen_language_servers = HashSet::new();\n    let mut futures: FuturesOrdered<_> = doc\n        .language_servers_with_feature(LanguageServerFeature::Hover)\n        .filter(|ls| seen_language_servers.insert(ls.id()))\n        .map(|language_server| {\n            let server_name = language_server.name().to_string();\n            // TODO: factor out a doc.position_identifier() that returns lsp::TextDocumentPositionIdentifier\n            let pos = doc.position(view.id, language_server.offset_encoding());\n            let request = language_server\n                .text_document_hover(doc.identifier(), pos, None)\n                .unwrap();\n\n            async move { anyhow::Ok((server_name, request.await?)) }\n        })\n        .collect();\n\n    cx.jobs.callback(async move {\n        let mut hovers: Vec<(String, lsp::Hover)> = Vec::new();\n\n        while let Some(response) = futures.next().await {\n            match response {\n                Ok((server_name, Some(hover))) => hovers.push((server_name, hover)),\n                Ok(_) => (),\n                Err(err) => log::error!(\"Error requesting hover: {err}\"),\n            }\n        }\n\n        let call = move |editor: &mut Editor, compositor: &mut Compositor| {\n            if hovers.is_empty() {\n                editor.set_status(\"No hover results available.\");\n                return;\n            }\n\n            // create new popup\n            let contents = Hover::new(hovers, editor.syn_loader.clone());\n            let popup = Popup::new(Hover::ID, contents).auto_close(true);\n            compositor.replace_or_push(Hover::ID, popup);\n        };\n        Ok(Callback::EditorCompositor(Box::new(call)))\n    });\n}\n\npub fn rename_symbol(cx: &mut Context) {\n    fn get_prefill_from_word_boundary(editor: &Editor) -> String {\n        let (view, doc) = current_ref!(editor);\n        let text = doc.text().slice(..);\n        let primary_selection = doc.selection(view.id).primary();\n        if primary_selection.len() > 1 {\n            primary_selection\n        } else {\n            use helix_core::textobject::{textobject_word, TextObject};\n            textobject_word(text, primary_selection, TextObject::Inside, 1, false)\n        }\n        .fragment(text)\n        .into()\n    }\n\n    fn get_prefill_from_lsp_response(\n        editor: &Editor,\n        offset_encoding: OffsetEncoding,\n        response: Option<lsp::PrepareRenameResponse>,\n    ) -> Result<String, &'static str> {\n        match response {\n            Some(lsp::PrepareRenameResponse::Range(range)) => {\n                let text = doc!(editor).text();\n\n                Ok(lsp_range_to_range(text, range, offset_encoding)\n                    .ok_or(\"lsp sent invalid selection range for rename\")?\n                    .fragment(text.slice(..))\n                    .into())\n            }\n            Some(lsp::PrepareRenameResponse::RangeWithPlaceholder { placeholder, .. }) => {\n                Ok(placeholder)\n            }\n            Some(lsp::PrepareRenameResponse::DefaultBehavior { .. }) => {\n                Ok(get_prefill_from_word_boundary(editor))\n            }\n            None => Err(\"lsp did not respond to prepare rename request\"),\n        }\n    }\n\n    fn create_rename_prompt(\n        editor: &Editor,\n        prefill: String,\n        history_register: Option<char>,\n        language_server_id: Option<LanguageServerId>,\n    ) -> Box<ui::Prompt> {\n        let prompt = ui::Prompt::new(\n            \"rename-to:\".into(),\n            history_register,\n            ui::completers::none,\n            move |cx: &mut compositor::Context, input: &str, event: PromptEvent| {\n                if event != PromptEvent::Validate {\n                    return;\n                }\n                let (view, doc) = current!(cx.editor);\n\n                let Some(language_server) = doc\n                    .language_servers_with_feature(LanguageServerFeature::RenameSymbol)\n                    .find(|ls| language_server_id.is_none_or(|id| id == ls.id()))\n                else {\n                    cx.editor\n                        .set_error(\"No configured language server supports symbol renaming\");\n                    return;\n                };\n\n                let offset_encoding = language_server.offset_encoding();\n                let pos = doc.position(view.id, offset_encoding);\n                let future = language_server\n                    .rename_symbol(doc.identifier(), pos, input.to_string())\n                    .unwrap();\n\n                match block_on(future) {\n                    Ok(edits) => {\n                        let _ = cx\n                            .editor\n                            .apply_workspace_edit(offset_encoding, &edits.unwrap_or_default());\n                    }\n                    Err(err) => cx.editor.set_error(err.to_string()),\n                }\n            },\n        )\n        .with_line(prefill, editor);\n\n        Box::new(prompt)\n    }\n\n    let (view, doc) = current_ref!(cx.editor);\n    let history_register = cx.register;\n\n    if doc\n        .language_servers_with_feature(LanguageServerFeature::RenameSymbol)\n        .next()\n        .is_none()\n    {\n        cx.editor\n            .set_error(\"No configured language server supports symbol renaming\");\n        return;\n    }\n\n    let language_server_with_prepare_rename_support = doc\n        .language_servers_with_feature(LanguageServerFeature::RenameSymbol)\n        .find(|ls| {\n            matches!(\n                ls.capabilities().rename_provider,\n                Some(lsp::OneOf::Right(lsp::RenameOptions {\n                    prepare_provider: Some(true),\n                    ..\n                }))\n            )\n        });\n\n    if let Some(language_server) = language_server_with_prepare_rename_support {\n        let ls_id = language_server.id();\n        let offset_encoding = language_server.offset_encoding();\n        let pos = doc.position(view.id, offset_encoding);\n        let future = language_server\n            .prepare_rename(doc.identifier(), pos)\n            .unwrap();\n        cx.callback(\n            future,\n            move |editor, compositor, response: Option<lsp::PrepareRenameResponse>| {\n                let prefill = match get_prefill_from_lsp_response(editor, offset_encoding, response)\n                {\n                    Ok(p) => p,\n                    Err(e) => {\n                        editor.set_error(e);\n                        return;\n                    }\n                };\n\n                let prompt = create_rename_prompt(editor, prefill, history_register, Some(ls_id));\n\n                compositor.push(prompt);\n            },\n        );\n    } else {\n        let prefill = get_prefill_from_word_boundary(cx.editor);\n        let prompt = create_rename_prompt(cx.editor, prefill, history_register, None);\n        cx.push_layer(prompt);\n    }\n}\n\npub fn select_references_to_symbol_under_cursor(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let language_server =\n        language_server_with_feature!(cx.editor, doc, LanguageServerFeature::DocumentHighlight);\n    let offset_encoding = language_server.offset_encoding();\n    let pos = doc.position(view.id, offset_encoding);\n    let future = language_server\n        .text_document_document_highlight(doc.identifier(), pos, None)\n        .unwrap();\n\n    cx.callback(\n        future,\n        move |editor, _compositor, response: Option<Vec<lsp::DocumentHighlight>>| {\n            let document_highlights = match response {\n                Some(highlights) if !highlights.is_empty() => highlights,\n                _ => return,\n            };\n            let (view, doc) = current!(editor);\n            let text = doc.text();\n            let pos = doc.selection(view.id).primary().cursor(text.slice(..));\n\n            // We must find the range that contains our primary cursor to prevent our primary cursor to move\n            let mut primary_index = 0;\n            let ranges = document_highlights\n                .iter()\n                .filter_map(|highlight| lsp_range_to_range(text, highlight.range, offset_encoding))\n                .enumerate()\n                .map(|(i, range)| {\n                    if range.contains(pos) {\n                        primary_index = i;\n                    }\n                    range\n                })\n                .collect();\n            let selection = Selection::new(ranges, primary_index);\n            doc.set_selection(view.id, selection);\n        },\n    );\n}\n\npub fn compute_inlay_hints_for_all_views(editor: &mut Editor, jobs: &mut crate::job::Jobs) {\n    if !editor.config().lsp.display_inlay_hints {\n        return;\n    }\n\n    for (view, _) in editor.tree.views() {\n        let doc = match editor.documents.get(&view.doc) {\n            Some(doc) => doc,\n            None => continue,\n        };\n        if let Some(callback) = compute_inlay_hints_for_view(view, doc) {\n            jobs.callback(callback);\n        }\n    }\n}\n\nfn compute_inlay_hints_for_view(\n    view: &View,\n    doc: &Document,\n) -> Option<std::pin::Pin<Box<impl Future<Output = Result<crate::job::Callback, anyhow::Error>>>>> {\n    let view_id = view.id;\n    let doc_id = view.doc;\n\n    let language_server = doc\n        .language_servers_with_feature(LanguageServerFeature::InlayHints)\n        .next()?;\n\n    let doc_text = doc.text();\n    let len_lines = doc_text.len_lines();\n\n    // Compute ~3 times the current view height of inlay hints, that way some scrolling\n    // will not show half the view with hints and half without while still being faster\n    // than computing all the hints for the full file (which could be dozens of time\n    // longer than the view is).\n    let view_height = view.inner_height();\n    let first_visible_line =\n        doc_text.char_to_line(doc.view_offset(view_id).anchor.min(doc_text.len_chars()));\n    let first_line = first_visible_line.saturating_sub(view_height);\n    let last_line = first_visible_line\n        .saturating_add(view_height.saturating_mul(2))\n        .min(len_lines);\n\n    let new_doc_inlay_hints_id = DocumentInlayHintsId {\n        first_line,\n        last_line,\n    };\n    // Don't recompute the annotations in case nothing has changed about the view\n    if !doc.inlay_hints_oudated\n        && doc\n            .inlay_hints(view_id)\n            .is_some_and(|dih| dih.id == new_doc_inlay_hints_id)\n    {\n        return None;\n    }\n\n    let doc_slice = doc_text.slice(..);\n    let first_char_in_range = doc_slice.line_to_char(first_line);\n    let last_char_in_range = doc_slice.line_to_char(last_line);\n\n    let range = helix_lsp::util::range_to_lsp_range(\n        doc_text,\n        helix_core::Range::new(first_char_in_range, last_char_in_range),\n        language_server.offset_encoding(),\n    );\n\n    let offset_encoding = language_server.offset_encoding();\n\n    let callback = super::make_job_callback(\n        language_server.text_document_range_inlay_hints(doc.identifier(), range, None)?,\n        move |editor, _compositor, response: Option<Vec<lsp::InlayHint>>| {\n            // The config was modified or the window was closed while the request was in flight\n            if !editor.config().lsp.display_inlay_hints || editor.tree.try_get(view_id).is_none() {\n                return;\n            }\n\n            // Add annotations to relevant document, not the current one (it may have changed in between)\n            let doc = match editor.documents.get_mut(&doc_id) {\n                Some(doc) => doc,\n                None => return,\n            };\n\n            // If we have neither hints nor an LSP, empty the inlay hints since they're now oudated\n            let mut hints = match response {\n                Some(hints) if !hints.is_empty() => hints,\n                _ => {\n                    doc.set_inlay_hints(\n                        view_id,\n                        DocumentInlayHints::empty_with_id(new_doc_inlay_hints_id),\n                    );\n                    doc.inlay_hints_oudated = false;\n                    return;\n                }\n            };\n\n            // Most language servers will already send them sorted but ensure this is the case to\n            // avoid errors on our end.\n            hints.sort_by_key(|inlay_hint| inlay_hint.position);\n\n            let mut padding_before_inlay_hints = Vec::new();\n            let mut type_inlay_hints = Vec::new();\n            let mut parameter_inlay_hints = Vec::new();\n            let mut other_inlay_hints = Vec::new();\n            let mut padding_after_inlay_hints = Vec::new();\n\n            let doc_text = doc.text();\n            let inlay_hints_length_limit = doc.config.load().lsp.inlay_hints_length_limit;\n\n            for hint in hints {\n                let char_idx =\n                    match helix_lsp::util::lsp_pos_to_pos(doc_text, hint.position, offset_encoding)\n                    {\n                        Some(pos) => pos,\n                        // Skip inlay hints that have no \"real\" position\n                        None => continue,\n                    };\n\n                let mut label = match hint.label {\n                    lsp::InlayHintLabel::String(s) => s,\n                    lsp::InlayHintLabel::LabelParts(parts) => parts\n                        .into_iter()\n                        .map(|p| p.value)\n                        .collect::<Vec<_>>()\n                        .join(\"\"),\n                };\n                // Truncate the hint if too long\n                if let Some(limit) = inlay_hints_length_limit {\n                    // Limit on displayed width\n                    use helix_core::unicode::{\n                        segmentation::UnicodeSegmentation, width::UnicodeWidthStr,\n                    };\n\n                    let width = label.width();\n                    let limit = limit.get().into();\n                    if width > limit {\n                        let mut floor_boundary = 0;\n                        let mut acc = 0;\n                        for (i, grapheme_cluster) in label.grapheme_indices(true) {\n                            acc += grapheme_cluster.width();\n\n                            if acc > limit {\n                                floor_boundary = i;\n                                break;\n                            }\n                        }\n\n                        label.truncate(floor_boundary);\n                        label.push('…');\n                    }\n                }\n\n                let inlay_hints_vec = match hint.kind {\n                    Some(lsp::InlayHintKind::TYPE) => &mut type_inlay_hints,\n                    Some(lsp::InlayHintKind::PARAMETER) => &mut parameter_inlay_hints,\n                    // We can't warn on unknown kind here since LSPs are free to set it or not, for\n                    // example Rust Analyzer does not: every kind will be `None`.\n                    _ => &mut other_inlay_hints,\n                };\n\n                if let Some(true) = hint.padding_left {\n                    padding_before_inlay_hints.push(InlineAnnotation::new(char_idx, \" \"));\n                }\n\n                inlay_hints_vec.push(InlineAnnotation::new(char_idx, label));\n\n                if let Some(true) = hint.padding_right {\n                    padding_after_inlay_hints.push(InlineAnnotation::new(char_idx, \" \"));\n                }\n            }\n\n            doc.set_inlay_hints(\n                view_id,\n                DocumentInlayHints {\n                    id: new_doc_inlay_hints_id,\n                    type_inlay_hints,\n                    parameter_inlay_hints,\n                    other_inlay_hints,\n                    padding_before_inlay_hints,\n                    padding_after_inlay_hints,\n                },\n            );\n            doc.inlay_hints_oudated = false;\n        },\n    );\n\n    Some(callback)\n}\n"
  },
  {
    "path": "helix-term/src/commands/syntax.rs",
    "content": "use std::{\n    collections::HashSet,\n    iter,\n    path::{Path, PathBuf},\n    sync::Arc,\n};\n\nuse dashmap::DashMap;\nuse futures_util::FutureExt;\nuse grep_regex::RegexMatcherBuilder;\nuse grep_searcher::{sinks, BinaryDetection, SearcherBuilder};\nuse helix_core::{\n    syntax::{Loader, QueryIterEvent},\n    Rope, RopeSlice, Selection, Syntax, Uri,\n};\nuse helix_stdx::{\n    path,\n    rope::{self, RopeSliceExt},\n};\nuse helix_view::{\n    align_view,\n    document::{from_reader, SCRATCH_BUFFER_NAME},\n    Align, Document, DocumentId, Editor,\n};\nuse ignore::{DirEntry, WalkBuilder, WalkState};\n\nuse crate::{\n    filter_picker_entry,\n    ui::{\n        overlay::overlaid,\n        picker::{Injector, PathOrId},\n        Picker, PickerColumn,\n    },\n};\n\nuse super::Context;\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\nenum TagKind {\n    Class,\n    Constant,\n    Enum,\n    Function,\n    Interface,\n    Macro,\n    Module,\n    Section,\n    Struct,\n    Type,\n}\n\nimpl TagKind {\n    fn as_str(&self) -> &'static str {\n        match self {\n            Self::Class => \"class\",\n            Self::Constant => \"constant\",\n            Self::Enum => \"enum\",\n            Self::Function => \"function\",\n            Self::Interface => \"interface\",\n            Self::Macro => \"macro\",\n            Self::Module => \"module\",\n            Self::Section => \"section\",\n            Self::Struct => \"struct\",\n            Self::Type => \"type\",\n        }\n    }\n\n    fn from_name(name: &str) -> Option<Self> {\n        match name {\n            \"class\" => Some(TagKind::Class),\n            \"constant\" => Some(TagKind::Constant),\n            \"enum\" => Some(TagKind::Enum),\n            \"function\" => Some(TagKind::Function),\n            \"interface\" => Some(TagKind::Interface),\n            \"macro\" => Some(TagKind::Macro),\n            \"module\" => Some(TagKind::Module),\n            \"section\" => Some(TagKind::Section),\n            \"struct\" => Some(TagKind::Struct),\n            \"type\" => Some(TagKind::Type),\n            _ => None,\n        }\n    }\n}\n\n// NOTE: Uri is cheap to clone and DocumentId is Copy\n#[derive(Debug, Clone)]\nenum UriOrDocumentId {\n    Uri(Uri),\n    Id(DocumentId),\n}\n\nimpl UriOrDocumentId {\n    fn path_or_id(&self) -> Option<PathOrId<'_>> {\n        match self {\n            Self::Id(id) => Some(PathOrId::Id(*id)),\n            Self::Uri(uri) => uri.as_path().map(PathOrId::Path),\n        }\n    }\n}\n\n#[derive(Debug)]\nstruct Tag {\n    kind: TagKind,\n    name: String,\n    start: usize,\n    end: usize,\n    start_line: usize,\n    end_line: usize,\n    doc: UriOrDocumentId,\n}\n\nfn tags_iter<'a>(\n    syntax: &'a Syntax,\n    loader: &'a Loader,\n    text: RopeSlice<'a>,\n    doc: UriOrDocumentId,\n    pattern: Option<&'a rope::Regex>,\n) -> impl Iterator<Item = Tag> + 'a {\n    let mut tags_iter = syntax.tags(text, loader, ..);\n\n    iter::from_fn(move || loop {\n        let QueryIterEvent::Match(mat) = tags_iter.next()? else {\n            continue;\n        };\n        let query = &loader\n            .tag_query(tags_iter.current_language())\n            .expect(\"must have a tags query to emit matches\")\n            .query;\n        let Some(kind) = query\n            .capture_name(mat.capture)\n            .strip_prefix(\"definition.\")\n            .and_then(TagKind::from_name)\n        else {\n            continue;\n        };\n        let range = mat.node.byte_range();\n        if pattern.is_some_and(|pattern| {\n            !pattern.is_match(text.regex_input_at_bytes(range.start as usize..range.end as usize))\n        }) {\n            continue;\n        }\n        let start = text.byte_to_char(range.start as usize);\n        let end = text.byte_to_char(range.end as usize);\n        return Some(Tag {\n            kind,\n            name: text.slice(start..end).to_string(),\n            start,\n            end,\n            start_line: text.char_to_line(start),\n            end_line: text.char_to_line(end),\n            doc: doc.clone(),\n        });\n    })\n}\n\npub fn syntax_symbol_picker(cx: &mut Context) {\n    let doc = doc!(cx.editor);\n    let Some(syntax) = doc.syntax() else {\n        cx.editor\n            .set_error(\"Syntax tree is not available on this buffer\");\n        return;\n    };\n    let doc_id = doc.id();\n    let text = doc.text().slice(..);\n    let loader = cx.editor.syn_loader.load();\n    let tags = tags_iter(syntax, &loader, text, UriOrDocumentId::Id(doc.id()), None);\n\n    let columns = vec![\n        PickerColumn::new(\"kind\", |tag: &Tag, _| tag.kind.as_str().into()),\n        PickerColumn::new(\"name\", |tag: &Tag, _| tag.name.as_str().into()),\n    ];\n\n    let picker = Picker::new(\n        columns,\n        1, // name\n        tags,\n        (),\n        move |cx, tag, action| {\n            cx.editor.switch(doc_id, action);\n            let view = view_mut!(cx.editor);\n            let doc = doc_mut!(cx.editor, &doc_id);\n            doc.set_selection(view.id, Selection::single(tag.start, tag.end));\n            if action.align_view(view, doc.id()) {\n                align_view(doc, view, Align::Center)\n            }\n        },\n    )\n    .with_preview(|_editor, tag| {\n        Some((tag.doc.path_or_id()?, Some((tag.start_line, tag.end_line))))\n    })\n    .truncate_start(false);\n\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\npub fn syntax_workspace_symbol_picker(cx: &mut Context) {\n    #[derive(Debug)]\n    struct SearchState {\n        searcher_builder: SearcherBuilder,\n        walk_builder: WalkBuilder,\n        regex_matcher_builder: RegexMatcherBuilder,\n        rope_regex_builder: rope::RegexBuilder,\n        search_root: PathBuf,\n        /// A cache of files that have been parsed in prior searches.\n        syntax_cache: DashMap<PathBuf, Option<(Rope, Syntax)>>,\n    }\n\n    let mut searcher_builder = SearcherBuilder::new();\n    searcher_builder.binary_detection(BinaryDetection::quit(b'\\x00'));\n\n    // Search from the workspace that the currently focused document is within. This behaves like global\n    // search most of the time but helps when you have two projects open in splits.\n    let search_root = if let Some(path) = doc!(cx.editor).path() {\n        helix_loader::find_workspace_in(path).0\n    } else {\n        helix_loader::find_workspace().0\n    };\n\n    let absolute_root = search_root\n        .canonicalize()\n        .unwrap_or_else(|_| search_root.clone());\n\n    let config = cx.editor.config();\n    let dedup_symlinks = config.file_picker.deduplicate_links;\n\n    let mut walk_builder = WalkBuilder::new(&search_root);\n    walk_builder\n        .hidden(config.file_picker.hidden)\n        .parents(config.file_picker.parents)\n        .ignore(config.file_picker.ignore)\n        .follow_links(config.file_picker.follow_symlinks)\n        .git_ignore(config.file_picker.git_ignore)\n        .git_global(config.file_picker.git_global)\n        .git_exclude(config.file_picker.git_exclude)\n        .max_depth(config.file_picker.max_depth)\n        .filter_entry(move |entry| filter_picker_entry(entry, &absolute_root, dedup_symlinks))\n        .add_custom_ignore_filename(helix_loader::config_dir().join(\"ignore\"))\n        .add_custom_ignore_filename(\".helix/ignore\");\n\n    let mut regex_matcher_builder = RegexMatcherBuilder::new();\n    regex_matcher_builder.case_smart(config.search.smart_case);\n    let mut rope_regex_builder = rope::RegexBuilder::new();\n    rope_regex_builder.syntax(rope::Config::new().case_insensitive(config.search.smart_case));\n    let state = SearchState {\n        searcher_builder,\n        walk_builder,\n        regex_matcher_builder,\n        rope_regex_builder,\n        search_root,\n        syntax_cache: DashMap::default(),\n    };\n    let reg = cx.register.unwrap_or('/');\n    cx.editor.registers.last_search_register = reg;\n    let columns = vec![\n        PickerColumn::new(\"kind\", |tag: &Tag, _| tag.kind.as_str().into()),\n        PickerColumn::new(\"name\", |tag: &Tag, _| tag.name.as_str().into()).without_filtering(),\n        PickerColumn::new(\"path\", |tag: &Tag, state: &SearchState| {\n            match &tag.doc {\n                UriOrDocumentId::Uri(uri) => {\n                    if let Some(path) = uri.as_path() {\n                        let path = if let Ok(stripped) = path.strip_prefix(&state.search_root) {\n                            stripped\n                        } else {\n                            path\n                        };\n                        path.to_string_lossy().into()\n                    } else {\n                        uri.to_string().into()\n                    }\n                }\n                // This picker only uses `Id` for scratch buffers for better display.\n                UriOrDocumentId::Id(_) => SCRATCH_BUFFER_NAME.into(),\n            }\n        }),\n    ];\n\n    let get_tags = |query: &str,\n                    editor: &mut Editor,\n                    state: Arc<SearchState>,\n                    injector: &Injector<_, _>| {\n        if query.len() < 3 {\n            return async { Ok(()) }.boxed();\n        }\n        // Attempt to find the tag in any open documents.\n        let pattern = match state.rope_regex_builder.build(query) {\n            Ok(pattern) => pattern,\n            Err(err) => return async { Err(anyhow::anyhow!(err)) }.boxed(),\n        };\n        let loader = editor.syn_loader.load();\n        for doc in editor.documents() {\n            let Some(syntax) = doc.syntax() else { continue };\n            let text = doc.text().slice(..);\n            let uri_or_id = doc\n                .uri()\n                .map(UriOrDocumentId::Uri)\n                .unwrap_or_else(|| UriOrDocumentId::Id(doc.id()));\n            for tag in tags_iter(syntax, &loader, text.slice(..), uri_or_id, Some(&pattern)) {\n                if injector.push(tag).is_err() {\n                    return async { Ok(()) }.boxed();\n                }\n            }\n        }\n        if !state.search_root.exists() {\n            return async { Err(anyhow::anyhow!(\"Current working directory does not exist\")) }\n                .boxed();\n        }\n        let matcher = match state.regex_matcher_builder.build(query) {\n            Ok(matcher) => {\n                // Clear any \"Failed to compile regex\" errors out of the statusline.\n                editor.clear_status();\n                matcher\n            }\n            Err(err) => {\n                log::info!(\n                    \"Failed to compile search pattern in workspace symbol search: {}\",\n                    err\n                );\n                return async { Err(anyhow::anyhow!(\"Failed to compile regex\")) }.boxed();\n            }\n        };\n        let pattern = Arc::new(pattern);\n        let injector = injector.clone();\n        let loader = editor.syn_loader.load();\n        let documents: HashSet<_> = editor\n            .documents()\n            .filter_map(Document::path)\n            .cloned()\n            .collect();\n        async move {\n            let searcher = state.searcher_builder.build();\n            state.walk_builder.build_parallel().run(|| {\n                let mut searcher = searcher.clone();\n                let matcher = matcher.clone();\n                let injector = injector.clone();\n                let loader = loader.clone();\n                let documents = &documents;\n                let pattern = pattern.clone();\n                let syntax_cache = &state.syntax_cache;\n                Box::new(move |entry: Result<DirEntry, ignore::Error>| -> WalkState {\n                    let entry = match entry {\n                        Ok(entry) => entry,\n                        Err(_) => return WalkState::Continue,\n                    };\n                    if !entry.path().is_file() {\n                        return WalkState::Continue;\n                    }\n                    let path = entry.path();\n                    // If this document is open, skip it because we've already processed it above.\n                    if documents.contains(path) {\n                        return WalkState::Continue;\n                    };\n                    let mut quit = false;\n                    let sink = sinks::UTF8(|_line, _content| {\n                        if !syntax_cache.contains_key(path) {\n                            // Read the file into a Rope and attempt to recognize the language\n                            // and parse it with tree-sitter. Save the Rope and Syntax for future\n                            // queries.\n                            syntax_cache.insert(path.to_path_buf(), syntax_for_path(path, &loader));\n                        };\n                        let entry = syntax_cache.get(path).unwrap();\n                        let Some((text, syntax)) = entry.value() else {\n                            // If the file couldn't be parsed, move on.\n                            return Ok(false);\n                        };\n                        let uri = Uri::from(path::normalize(path));\n                        for tag in tags_iter(\n                            syntax,\n                            &loader,\n                            text.slice(..),\n                            UriOrDocumentId::Uri(uri),\n                            Some(&pattern),\n                        ) {\n                            if injector.push(tag).is_err() {\n                                quit = true;\n                                break;\n                            }\n                        }\n                        // Quit after seeing the first regex match. We only care to find files\n                        // that contain the pattern and then we run the tags query within\n                        // those. The location and contents of a match are irrelevant - it's\n                        // only important _if_ a file matches.\n                        Ok(false)\n                    });\n                    if let Err(err) = searcher.search_path(&matcher, path, sink) {\n                        log::info!(\"Workspace syntax search error: {}, {}\", path.display(), err);\n                    }\n                    if quit {\n                        WalkState::Quit\n                    } else {\n                        WalkState::Continue\n                    }\n                })\n            });\n            Ok(())\n        }\n        .boxed()\n    };\n    let picker = Picker::new(\n        columns,\n        1, // name\n        [],\n        state,\n        move |cx, tag, action| {\n            let doc_id = match &tag.doc {\n                UriOrDocumentId::Id(id) => *id,\n                UriOrDocumentId::Uri(uri) => match cx.editor.open(uri.as_path().expect(\"\"), action) {\n                    Ok(id) => id,\n                    Err(e) => {\n                        cx.editor\n                            .set_error(format!(\"Failed to open file '{uri:?}': {e}\"));\n                        return;\n                    }\n                }\n            };\n            let doc = doc_mut!(cx.editor, &doc_id);\n            let view = view_mut!(cx.editor);\n            let len_chars = doc.text().len_chars();\n            if tag.start >= len_chars || tag.end > len_chars {\n                cx.editor.set_error(\"The location you jumped to does not exist anymore because the file has changed.\");\n                return;\n            }\n            doc.set_selection(view.id, Selection::single(tag.start, tag.end));\n            if action.align_view(view, doc.id()) {\n                align_view(doc, view, Align::Center)\n            }\n        },\n    )\n    .with_dynamic_query(get_tags, Some(275))\n    .with_preview(move |_editor, tag| {\n        Some((\n            tag.doc.path_or_id()?,\n            Some((tag.start_line, tag.end_line)),\n        ))\n    })\n    .with_history_register(Some(reg))\n    .truncate_start(false);\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\n/// Create a Rope and language config for a given existing path without creating a full Document.\nfn syntax_for_path(path: &Path, loader: &Loader) -> Option<(Rope, Syntax)> {\n    let mut file = std::fs::File::open(path).ok()?;\n    let (rope, _encoding, _has_bom) = from_reader(&mut file, None).ok()?;\n    let text = rope.slice(..);\n    let language = loader\n        .language_for_filename(path)\n        .or_else(|| loader.language_for_shebang(text))?;\n    Syntax::new(text, language, loader)\n        .ok()\n        .map(|syntax| (rope, syntax))\n}\n"
  },
  {
    "path": "helix-term/src/commands/typed.rs",
    "content": "use std::fmt::Write;\nuse std::io::BufReader;\nuse std::ops::{self, Deref};\n\nuse crate::job::Job;\n\nuse super::*;\n\nuse helix_core::command_line::{Args, Flag, Signature, Token, TokenKind};\nuse helix_core::fuzzy::fuzzy_match;\nuse helix_core::indent::MAX_INDENT;\nuse helix_core::line_ending;\nuse helix_stdx::path::home_dir;\nuse helix_view::document::{read_to_string, DEFAULT_LANGUAGE_NAME};\nuse helix_view::editor::{CloseError, ConfigEvent};\nuse helix_view::expansion;\nuse serde_json::Value;\nuse ui::completers::{self, Completer};\n\n#[derive(Clone)]\npub struct TypableCommand {\n    pub name: &'static str,\n    pub aliases: &'static [&'static str],\n    pub doc: &'static str,\n    // params, flags, helper, completer\n    pub fun: fn(&mut compositor::Context, Args, PromptEvent) -> anyhow::Result<()>,\n    /// What completion methods, if any, does this command have?\n    pub completer: CommandCompleter,\n    pub signature: Signature,\n}\n\n#[derive(Clone)]\npub struct CommandCompleter {\n    // Arguments with specific completion methods based on their position.\n    positional_args: &'static [Completer],\n\n    // All remaining arguments will use this completion method, if set.\n    var_args: Completer,\n}\n\nimpl CommandCompleter {\n    const fn none() -> Self {\n        Self {\n            positional_args: &[],\n            var_args: completers::none,\n        }\n    }\n\n    const fn positional(completers: &'static [Completer]) -> Self {\n        Self {\n            positional_args: completers,\n            var_args: completers::none,\n        }\n    }\n\n    const fn all(completer: Completer) -> Self {\n        Self {\n            positional_args: &[],\n            var_args: completer,\n        }\n    }\n\n    fn for_argument_number(&self, n: usize) -> &Completer {\n        match self.positional_args.get(n) {\n            Some(completer) => completer,\n            _ => &self.var_args,\n        }\n    }\n}\n\nfn exit(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    if doc!(cx.editor).is_modified() {\n        write_impl(\n            cx,\n            args.first(),\n            WriteOptions {\n                force: false,\n                auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n            },\n        )?;\n    }\n    cx.block_try_flush_writes()?;\n    quit(cx, Args::default(), event)\n}\n\nfn force_exit(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    if doc!(cx.editor).is_modified() {\n        write_impl(\n            cx,\n            args.first(),\n            WriteOptions {\n                force: true,\n                auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n            },\n        )?;\n    }\n    cx.block_try_flush_writes()?;\n    quit(cx, Args::default(), event)\n}\n\nfn quit(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    log::debug!(\"quitting...\");\n\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    // last view and we have unsaved changes\n    if cx.editor.tree.views().count() == 1 {\n        buffers_remaining_impl(cx.editor)?\n    }\n\n    cx.block_try_flush_writes()?;\n    cx.editor.close(view!(cx.editor).id);\n\n    Ok(())\n}\n\nfn force_quit(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    cx.block_try_flush_writes()?;\n    cx.editor.close(view!(cx.editor).id);\n\n    Ok(())\n}\n\nfn open(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    open_impl(cx, args, Action::Replace)\n}\n\nfn open_impl(cx: &mut compositor::Context, args: Args, action: Action) -> anyhow::Result<()> {\n    for arg in args {\n        let (path, pos) = crate::args::parse_file(&arg);\n        let path = helix_stdx::path::expand_tilde(path);\n        // If the path is a directory, open a file picker on that directory and update the status\n        // message\n        if let Ok(true) = std::fs::canonicalize(&path).map(|p| p.is_dir()) {\n            let callback = async move {\n                let call: job::Callback = job::Callback::EditorCompositor(Box::new(\n                    move |editor: &mut Editor, compositor: &mut Compositor| {\n                        let picker =\n                            ui::file_picker(editor, path.into_owned()).with_default_action(action);\n                        compositor.push(Box::new(overlaid(picker)));\n                    },\n                ));\n                Ok(call)\n            };\n            cx.jobs.callback(callback);\n        } else {\n            // Otherwise, just open the file\n            let _ = cx.editor.open(&path, action)?;\n            let (view, doc) = current!(cx.editor);\n            let pos = Selection::point(pos_at_coords(doc.text().slice(..), pos, true));\n            doc.set_selection(view.id, pos);\n            // does not affect opening a buffer without pos\n            align_view(doc, view, Align::Center);\n        }\n    }\n    Ok(())\n}\n\nfn buffer_close_by_ids_impl(\n    cx: &mut compositor::Context,\n    doc_ids: &[DocumentId],\n    force: bool,\n) -> anyhow::Result<()> {\n    cx.block_try_flush_writes()?;\n\n    let (modified_ids, modified_names): (Vec<_>, Vec<_>) = doc_ids\n        .iter()\n        .filter_map(|&doc_id| {\n            if let Err(CloseError::BufferModified(name)) = cx.editor.close_document(doc_id, force) {\n                Some((doc_id, name))\n            } else {\n                None\n            }\n        })\n        .unzip();\n\n    if let Some(first) = modified_ids.first() {\n        let current = doc!(cx.editor);\n        // If the current document is unmodified, and there are modified\n        // documents, switch focus to the first modified doc.\n        if !modified_ids.contains(&current.id()) {\n            cx.editor.switch(*first, Action::Replace);\n        }\n        bail!(\n            \"{} unsaved buffer{} remaining: {:?}\",\n            modified_names.len(),\n            if modified_names.len() == 1 { \"\" } else { \"s\" },\n            modified_names,\n        );\n    }\n\n    Ok(())\n}\n\nfn buffer_gather_paths_impl(editor: &mut Editor, args: Args) -> Vec<DocumentId> {\n    // No arguments implies current document\n    if args.is_empty() {\n        let doc_id = view!(editor).doc;\n        return vec![doc_id];\n    }\n\n    let mut nonexistent_buffers = vec![];\n    let mut document_ids = vec![];\n    for arg in args {\n        let doc_id = editor.documents().find_map(|doc| {\n            let arg_path = Some(Path::new(arg.as_ref()));\n            if doc.path().map(|p| p.as_path()) == arg_path || doc.relative_path() == arg_path {\n                Some(doc.id())\n            } else {\n                None\n            }\n        });\n\n        match doc_id {\n            Some(doc_id) => document_ids.push(doc_id),\n            None => nonexistent_buffers.push(format!(\"'{}'\", arg)),\n        }\n    }\n\n    if !nonexistent_buffers.is_empty() {\n        editor.set_error(format!(\n            \"cannot close non-existent buffers: {}\",\n            nonexistent_buffers.join(\", \")\n        ));\n    }\n\n    document_ids\n}\n\nfn buffer_close(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let document_ids = buffer_gather_paths_impl(cx.editor, args);\n    buffer_close_by_ids_impl(cx, &document_ids, false)\n}\n\nfn force_buffer_close(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let document_ids = buffer_gather_paths_impl(cx.editor, args);\n    buffer_close_by_ids_impl(cx, &document_ids, true)\n}\n\nfn buffer_gather_others_impl(editor: &mut Editor, skip_visible: bool) -> Vec<DocumentId> {\n    if skip_visible {\n        let visible_document_ids = editor\n            .tree\n            .views()\n            .map(|view| &view.0.doc)\n            .collect::<HashSet<_>>();\n        editor\n            .documents()\n            .map(|doc| doc.id())\n            .filter(|doc_id| !visible_document_ids.contains(doc_id))\n            .collect()\n    } else {\n        let current_document = &doc!(editor).id();\n        editor\n            .documents()\n            .map(|doc| doc.id())\n            .filter(|doc_id| doc_id != current_document)\n            .collect()\n    }\n}\n\nfn buffer_close_others(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let document_ids = buffer_gather_others_impl(cx.editor, args.has_flag(\"skip-visible\"));\n    buffer_close_by_ids_impl(cx, &document_ids, false)\n}\n\nfn force_buffer_close_others(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let document_ids = buffer_gather_others_impl(cx.editor, args.has_flag(\"skip-visible\"));\n    buffer_close_by_ids_impl(cx, &document_ids, true)\n}\n\nfn buffer_gather_all_impl(editor: &mut Editor) -> Vec<DocumentId> {\n    editor.documents().map(|doc| doc.id()).collect()\n}\n\nfn buffer_close_all(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let document_ids = buffer_gather_all_impl(cx.editor);\n    buffer_close_by_ids_impl(cx, &document_ids, false)\n}\n\nfn force_buffer_close_all(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let document_ids = buffer_gather_all_impl(cx.editor);\n    buffer_close_by_ids_impl(cx, &document_ids, true)\n}\n\nfn buffer_next(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    goto_buffer(cx.editor, Direction::Forward, 1);\n    Ok(())\n}\n\nfn buffer_previous(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    goto_buffer(cx.editor, Direction::Backward, 1);\n    Ok(())\n}\n\nfn write_impl(\n    cx: &mut compositor::Context,\n    path: Option<&str>,\n    options: WriteOptions,\n) -> anyhow::Result<()> {\n    let config = cx.editor.config();\n    let jobs = &mut cx.jobs;\n    let (view, doc) = current!(cx.editor);\n\n    if doc.trim_trailing_whitespace() {\n        trim_trailing_whitespace(doc, view.id);\n    }\n    if config.trim_final_newlines {\n        trim_final_newlines(doc, view.id);\n    }\n    if doc.insert_final_newline() {\n        insert_final_newline(doc, view.id);\n    }\n\n    // Save an undo checkpoint for any outstanding changes.\n    doc.append_changes_to_history(view);\n\n    let (view, doc) = current_ref!(cx.editor);\n    let fmt = if config.auto_format && options.auto_format {\n        doc.auto_format(cx.editor).map(|fmt| {\n            let callback = make_format_callback(\n                doc.id(),\n                doc.version(),\n                view.id,\n                fmt,\n                Some((path.map(Into::into), options.force)),\n            );\n\n            jobs.add(Job::with_callback(callback).wait_before_exiting());\n        })\n    } else {\n        None\n    };\n\n    if fmt.is_none() {\n        let id = doc.id();\n        cx.editor.save(id, path, options.force)?;\n    }\n\n    Ok(())\n}\n\n/// Trim all whitespace preceding line-endings in a document.\nfn trim_trailing_whitespace(doc: &mut Document, view_id: ViewId) {\n    let text = doc.text();\n    let mut pos = 0;\n    let transaction = Transaction::delete(\n        text,\n        text.lines().filter_map(|line| {\n            let line_end_len_chars = line_ending::get_line_ending(&line)\n                .map(|le| le.len_chars())\n                .unwrap_or_default();\n            // Char after the last non-whitespace character or the beginning of the line if the\n            // line is all whitespace:\n            let first_trailing_whitespace =\n                pos + line.last_non_whitespace_char().map_or(0, |idx| idx + 1);\n            pos += line.len_chars();\n            // Char before the line ending character(s), or the final char in the text if there\n            // is no line-ending on this line:\n            let line_end = pos - line_end_len_chars;\n            if first_trailing_whitespace != line_end {\n                Some((first_trailing_whitespace, line_end))\n            } else {\n                None\n            }\n        }),\n    );\n    doc.apply(&transaction, view_id);\n}\n\n/// Trim any extra line-endings after the final line-ending.\nfn trim_final_newlines(doc: &mut Document, view_id: ViewId) {\n    let rope = doc.text();\n    let mut text = rope.slice(..);\n    let mut total_char_len = 0;\n    let mut final_char_len = 0;\n    while let Some(line_ending) = line_ending::get_line_ending(&text) {\n        total_char_len += line_ending.len_chars();\n        final_char_len = line_ending.len_chars();\n        text = text.slice(..text.len_chars() - line_ending.len_chars());\n    }\n    let chars_to_delete = total_char_len - final_char_len;\n    if chars_to_delete != 0 {\n        let transaction = Transaction::delete(\n            rope,\n            [(rope.len_chars() - chars_to_delete, rope.len_chars())].into_iter(),\n        );\n        doc.apply(&transaction, view_id);\n    }\n}\n\n/// Ensure that the document is terminated with a line ending.\nfn insert_final_newline(doc: &mut Document, view_id: ViewId) {\n    let text = doc.text();\n    if text.len_chars() > 0 && line_ending::get_line_ending(&text.slice(..)).is_none() {\n        let eof = Selection::point(text.len_chars());\n        let insert = Transaction::insert(text, &eof, doc.line_ending.as_str().into());\n        doc.apply(&insert, view_id);\n    }\n}\n\n#[derive(Debug, Clone, Copy)]\npub struct WriteOptions {\n    pub force: bool,\n    pub auto_format: bool,\n}\n\nfn write(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    write_impl(\n        cx,\n        args.first(),\n        WriteOptions {\n            force: false,\n            auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n        },\n    )\n}\n\nfn force_write(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    write_impl(\n        cx,\n        args.first(),\n        WriteOptions {\n            force: true,\n            auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n        },\n    )\n}\n\nfn write_buffer_close(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    write_impl(\n        cx,\n        args.first(),\n        WriteOptions {\n            force: false,\n            auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n        },\n    )?;\n\n    let document_ids = buffer_gather_paths_impl(cx.editor, args);\n    buffer_close_by_ids_impl(cx, &document_ids, false)\n}\n\nfn force_write_buffer_close(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    write_impl(\n        cx,\n        args.first(),\n        WriteOptions {\n            force: true,\n            auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n        },\n    )?;\n\n    let document_ids = buffer_gather_paths_impl(cx.editor, args);\n    buffer_close_by_ids_impl(cx, &document_ids, false)\n}\n\nfn new_file(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    cx.editor.new_file(Action::Replace);\n\n    Ok(())\n}\n\nfn format(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let (view, doc) = current_ref!(cx.editor);\n    let format = doc.format(cx.editor).context(\n        \"A formatter isn't available, and no language server provides formatting capabilities\",\n    )?;\n    let callback = make_format_callback(doc.id(), doc.version(), view.id, format, None);\n    cx.jobs.callback(callback);\n\n    Ok(())\n}\n\nfn set_indent_style(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    use IndentStyle::*;\n\n    // If no argument, report current indent style.\n    if args.is_empty() {\n        let style = doc!(cx.editor).indent_style;\n        cx.editor.set_status(match style {\n            Tabs => \"tabs\".to_owned(),\n            Spaces(1) => \"1 space\".to_owned(),\n            Spaces(n) => format!(\"{} spaces\", n),\n        });\n        return Ok(());\n    }\n\n    // Attempt to parse argument as an indent style.\n    let style = match args.first() {\n        Some(arg) if \"tabs\".starts_with(&arg.to_lowercase()) => Some(Tabs),\n        Some(\"0\") => Some(Tabs),\n        Some(arg) => arg\n            .parse::<u8>()\n            .ok()\n            .filter(|n| (1..=MAX_INDENT).contains(n))\n            .map(Spaces),\n        _ => None,\n    };\n\n    let style = style.context(\"invalid indent style\")?;\n    let doc = doc_mut!(cx.editor);\n    doc.indent_style = style;\n\n    Ok(())\n}\n\n/// Sets or reports the current document's line ending setting.\nfn set_line_ending(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    use LineEnding::*;\n\n    // If no argument, report current line ending setting.\n    if args.is_empty() {\n        let line_ending = doc!(cx.editor).line_ending;\n        cx.editor.set_status(match line_ending {\n            Crlf => \"crlf\",\n            LF => \"line feed\",\n            #[cfg(feature = \"unicode-lines\")]\n            FF => \"form feed\",\n            #[cfg(feature = \"unicode-lines\")]\n            CR => \"carriage return\",\n            #[cfg(feature = \"unicode-lines\")]\n            Nel => \"next line\",\n\n            // These should never be a document's default line ending.\n            #[cfg(feature = \"unicode-lines\")]\n            VT | LS | PS => \"error\",\n        });\n\n        return Ok(());\n    }\n\n    let arg = args\n        .first()\n        .context(\"argument missing\")?\n        .to_ascii_lowercase();\n\n    // Attempt to parse argument as a line ending.\n    let line_ending = match arg {\n        arg if arg.starts_with(\"crlf\") => Crlf,\n        arg if arg.starts_with(\"lf\") => LF,\n        #[cfg(feature = \"unicode-lines\")]\n        arg if arg.starts_with(\"cr\") => CR,\n        #[cfg(feature = \"unicode-lines\")]\n        arg if arg.starts_with(\"ff\") => FF,\n        #[cfg(feature = \"unicode-lines\")]\n        arg if arg.starts_with(\"nel\") => Nel,\n        _ => bail!(\"invalid line ending\"),\n    };\n    let (view, doc) = current!(cx.editor);\n    doc.line_ending = line_ending;\n\n    let mut pos = 0;\n    let transaction = Transaction::change(\n        doc.text(),\n        doc.text().lines().filter_map(|line| {\n            pos += line.len_chars();\n            match helix_core::line_ending::get_line_ending(&line) {\n                Some(ending) if ending != line_ending => {\n                    let start = pos - ending.len_chars();\n                    let end = pos;\n                    Some((start, end, Some(line_ending.as_str().into())))\n                }\n                _ => None,\n            }\n        }),\n    );\n    doc.apply(&transaction, view.id);\n    doc.append_changes_to_history(view);\n\n    Ok(())\n}\nfn earlier(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let uk = args.join(\" \").parse::<UndoKind>().map_err(|s| anyhow!(s))?;\n\n    let (view, doc) = current!(cx.editor);\n    let success = doc.earlier(view, uk);\n    if !success {\n        cx.editor.set_status(\"Already at oldest change\");\n    }\n\n    Ok(())\n}\n\nfn later(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let uk = args.join(\" \").parse::<UndoKind>().map_err(|s| anyhow!(s))?;\n    let (view, doc) = current!(cx.editor);\n    let success = doc.later(view, uk);\n    if !success {\n        cx.editor.set_status(\"Already at newest change\");\n    }\n\n    Ok(())\n}\n\nfn write_quit(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    write_impl(\n        cx,\n        args.first(),\n        WriteOptions {\n            force: false,\n            auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n        },\n    )?;\n    cx.block_try_flush_writes()?;\n    quit(cx, Args::default(), event)\n}\n\nfn force_write_quit(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    write_impl(\n        cx,\n        args.first(),\n        WriteOptions {\n            force: true,\n            auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n        },\n    )?;\n    cx.block_try_flush_writes()?;\n    force_quit(cx, Args::default(), event)\n}\n\n/// Results in an error if there are modified buffers remaining and sets editor\n/// error, otherwise returns `Ok(())`. If the current document is unmodified,\n/// and there are modified documents, switches focus to one of them.\npub(super) fn buffers_remaining_impl(editor: &mut Editor) -> anyhow::Result<()> {\n    let modified_ids: Vec<_> = editor\n        .documents()\n        .filter(|doc| doc.is_modified())\n        .map(|doc| doc.id())\n        .collect();\n\n    if let Some(first) = modified_ids.first() {\n        let current = doc!(editor);\n        // If the current document is unmodified, and there are modified\n        // documents, switch focus to the first modified doc.\n        if !modified_ids.contains(&current.id()) {\n            editor.switch(*first, Action::Replace);\n        }\n\n        let modified_names: Vec<_> = modified_ids\n            .iter()\n            .map(|doc_id| doc!(editor, doc_id).display_name())\n            .collect();\n\n        bail!(\n            \"{} unsaved buffer{} remaining: {:?}\",\n            modified_names.len(),\n            if modified_names.len() == 1 { \"\" } else { \"s\" },\n            modified_names,\n        );\n    }\n    Ok(())\n}\n\n#[derive(Debug, Clone, Copy)]\npub struct WriteAllOptions {\n    pub force: bool,\n    pub write_scratch: bool,\n    pub auto_format: bool,\n}\n\npub fn write_all_impl(\n    cx: &mut compositor::Context,\n    options: WriteAllOptions,\n) -> anyhow::Result<()> {\n    let mut errors: Vec<&'static str> = Vec::new();\n    let config = cx.editor.config();\n    let jobs = &mut cx.jobs;\n    let saves: Vec<_> = cx\n        .editor\n        .documents\n        .keys()\n        .cloned()\n        .collect::<Vec<_>>()\n        .into_iter()\n        .filter_map(|id| {\n            let doc = doc!(cx.editor, &id);\n            if !doc.is_modified() {\n                return None;\n            }\n            if doc.path().is_none() {\n                if options.write_scratch {\n                    errors.push(\"cannot write a buffer without a filename\");\n                }\n                return None;\n            }\n\n            // Look for a view to apply the formatting change to.\n            let target_view = cx.editor.get_synced_view_id(doc.id());\n            Some((id, target_view))\n        })\n        .collect();\n\n    for (doc_id, target_view) in saves {\n        let doc = doc_mut!(cx.editor, &doc_id);\n        let view = view_mut!(cx.editor, target_view);\n\n        if doc.trim_trailing_whitespace() {\n            trim_trailing_whitespace(doc, target_view);\n        }\n        if config.trim_final_newlines {\n            trim_final_newlines(doc, target_view);\n        }\n        if doc.insert_final_newline() {\n            insert_final_newline(doc, target_view);\n        }\n\n        // Save an undo checkpoint for any outstanding changes.\n        doc.append_changes_to_history(view);\n\n        let fmt = if options.auto_format && config.auto_format {\n            let doc = doc!(cx.editor, &doc_id);\n            doc.auto_format(cx.editor).map(|fmt| {\n                let callback = make_format_callback(\n                    doc_id,\n                    doc.version(),\n                    target_view,\n                    fmt,\n                    Some((None, options.force)),\n                );\n                jobs.add(Job::with_callback(callback).wait_before_exiting());\n            })\n        } else {\n            None\n        };\n\n        if fmt.is_none() {\n            cx.editor.save::<PathBuf>(doc_id, None, options.force)?;\n        }\n    }\n\n    if !errors.is_empty() && !options.force {\n        bail!(\"{:?}\", errors);\n    }\n\n    Ok(())\n}\n\nfn write_all(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    write_all_impl(\n        cx,\n        WriteAllOptions {\n            force: false,\n            write_scratch: true,\n            auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n        },\n    )\n}\n\nfn force_write_all(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    write_all_impl(\n        cx,\n        WriteAllOptions {\n            force: true,\n            write_scratch: true,\n            auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n        },\n    )\n}\n\nfn write_all_quit(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n    write_all_impl(\n        cx,\n        WriteAllOptions {\n            force: false,\n            write_scratch: true,\n            auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n        },\n    )?;\n    quit_all_impl(cx, false)\n}\n\nfn force_write_all_quit(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n    let _ = write_all_impl(\n        cx,\n        WriteAllOptions {\n            force: true,\n            write_scratch: true,\n            auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n        },\n    );\n    quit_all_impl(cx, true)\n}\n\nfn quit_all_impl(cx: &mut compositor::Context, force: bool) -> anyhow::Result<()> {\n    cx.block_try_flush_writes()?;\n    if !force {\n        buffers_remaining_impl(cx.editor)?;\n    }\n\n    // close all views\n    let views: Vec<_> = cx.editor.tree.views().map(|(view, _)| view.id).collect();\n    for view_id in views {\n        cx.editor.close(view_id);\n    }\n\n    Ok(())\n}\n\nfn quit_all(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    quit_all_impl(cx, false)\n}\n\nfn force_quit_all(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    quit_all_impl(cx, true)\n}\n\nfn cquit(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let exit_code = args\n        .first()\n        .and_then(|code| code.parse::<i32>().ok())\n        .unwrap_or(1);\n\n    cx.editor.exit_code = exit_code;\n    quit_all_impl(cx, false)\n}\n\nfn force_cquit(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let exit_code = args\n        .first()\n        .and_then(|code| code.parse::<i32>().ok())\n        .unwrap_or(1);\n    cx.editor.exit_code = exit_code;\n\n    quit_all_impl(cx, true)\n}\n\nfn theme(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    let true_color = cx.editor.config.load().true_color || crate::true_color();\n    match event {\n        PromptEvent::Abort => {\n            cx.editor.unset_theme_preview();\n        }\n        PromptEvent::Update => {\n            if args.is_empty() {\n                // Ensures that a preview theme gets cleaned up if the user backspaces until the prompt is empty.\n                cx.editor.unset_theme_preview();\n            } else if let Some(theme_name) = args.first() {\n                if let Ok(theme) = cx.editor.theme_loader.load(theme_name) {\n                    if !(true_color || theme.is_16_color()) {\n                        bail!(\"Unsupported theme: theme requires true color support\");\n                    }\n                    cx.editor.set_theme_preview(theme);\n                };\n            };\n        }\n        PromptEvent::Validate => {\n            if let Some(theme_name) = args.first() {\n                let theme = cx\n                    .editor\n                    .theme_loader\n                    .load(theme_name)\n                    .map_err(|err| anyhow::anyhow!(\"Could not load theme: {}\", err))?;\n                if !(true_color || theme.is_16_color()) {\n                    bail!(\"Unsupported theme: theme requires true color support\");\n                }\n                cx.editor.set_theme(theme);\n                cx.editor.config_events.0.send(ConfigEvent::ThemeChanged)?;\n            } else {\n                let name = cx.editor.theme.name().to_string();\n\n                cx.editor.set_status(name);\n            }\n        }\n    };\n\n    Ok(())\n}\n\nfn yank_main_selection_to_clipboard(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    yank_main_selection_to_register(cx.editor, '+');\n    Ok(())\n}\n\nfn yank_joined(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let doc = doc!(cx.editor);\n    let default_sep = Cow::Borrowed(doc.line_ending.as_str());\n    let separator = args.first().unwrap_or(&default_sep);\n    let register = cx\n        .editor\n        .selected_register\n        .unwrap_or(cx.editor.config().default_yank_register);\n    yank_joined_impl(cx.editor, separator, register);\n    Ok(())\n}\n\nfn yank_joined_to_clipboard(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let doc = doc!(cx.editor);\n    let default_sep = Cow::Borrowed(doc.line_ending.as_str());\n    let separator = args.first().unwrap_or(&default_sep);\n    yank_joined_impl(cx.editor, separator, '+');\n    Ok(())\n}\n\nfn yank_main_selection_to_primary_clipboard(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    yank_main_selection_to_register(cx.editor, '*');\n    Ok(())\n}\n\nfn yank_joined_to_primary_clipboard(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let doc = doc!(cx.editor);\n    let default_sep = Cow::Borrowed(doc.line_ending.as_str());\n    let separator = args.first().unwrap_or(&default_sep);\n    yank_joined_impl(cx.editor, separator, '*');\n    Ok(())\n}\n\nfn paste_clipboard_after(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    paste(cx.editor, '+', Paste::After, 1);\n    Ok(())\n}\n\nfn paste_clipboard_before(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    paste(cx.editor, '+', Paste::Before, 1);\n    Ok(())\n}\n\nfn paste_primary_clipboard_after(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    paste(cx.editor, '*', Paste::After, 1);\n    Ok(())\n}\n\nfn paste_primary_clipboard_before(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    paste(cx.editor, '*', Paste::Before, 1);\n    Ok(())\n}\n\nfn replace_selections_with_clipboard(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    replace_selections_with_register(cx.editor, '+', 1);\n    Ok(())\n}\n\nfn replace_selections_with_primary_clipboard(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    replace_selections_with_register(cx.editor, '*', 1);\n    Ok(())\n}\n\nfn show_clipboard_provider(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    cx.editor\n        .set_status(cx.editor.registers.clipboard_provider_name());\n    Ok(())\n}\n\n/// Helper function to parse the first argument as a directory\n#[inline]\nfn parse_first_arg_as_dir(args: &Args, last_cwd: Option<PathBuf>) -> anyhow::Result<PathBuf> {\n    match args.first().map(AsRef::as_ref) {\n        Some(\"-\") => last_cwd.ok_or_else(|| anyhow!(\"No previous working directory\")),\n        Some(path) => Ok(helix_stdx::path::expand_tilde(Path::new(path)).into_owned()),\n        None => Ok(home_dir()?),\n    }\n}\n\n/// Helper function to apply a directory change for an already-parsed Path ref\n#[inline]\nfn apply_directory_change(cx: &mut compositor::Context, dir: &Path) -> anyhow::Result<()> {\n    cx.editor.set_cwd(dir).map_err(|err| {\n        anyhow!(\n            \"Could not change working directory to '{}': {err}\",\n            dir.display()\n        )\n    })?;\n\n    cx.editor.set_status(format!(\n        \"Current working directory is now {}\",\n        helix_stdx::env::current_working_dir().display()\n    ));\n\n    Ok(())\n}\n\nfn change_current_directory(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let dir = parse_first_arg_as_dir(&args, cx.editor.get_last_cwd().map(|p| p.to_path_buf()))?;\n\n    apply_directory_change(cx, &dir)\n}\n\nfn show_directory_stack(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let serialized_stack = cx\n        .editor\n        .dir_stack\n        .iter()\n        .map(|p| p.display().to_string())\n        .collect::<Vec<_>>()\n        .join(\" \");\n\n    if !serialized_stack.is_empty() {\n        cx.editor.set_status(serialized_stack);\n    } else {\n        cx.editor.set_error(\"Stack is empty\");\n    }\n\n    Ok(())\n}\n\nfn push_directory(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    // avoid an unbounded directory stack and reallocs for perf\n    if cx.editor.dir_stack.len() == cx.editor.dir_stack.capacity() {\n        cx.editor.dir_stack.pop_back();\n    }\n\n    cx.editor\n        .dir_stack\n        .push_front(helix_stdx::env::current_working_dir());\n\n    change_current_directory(cx, args, event)\n}\n\nfn pop_directory(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    if let Some(dir) = cx.editor.dir_stack.pop_front() {\n        apply_directory_change(cx, &dir)?;\n    } else {\n        cx.editor.set_error(\"Stack is empty\");\n    }\n\n    Ok(())\n}\n\nfn show_current_directory(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let cwd = helix_stdx::env::current_working_dir();\n    let message = format!(\"Current working directory is {}\", cwd.display());\n\n    if cwd.exists() {\n        cx.editor.set_status(message);\n    } else {\n        cx.editor.set_error(format!(\"{} (deleted)\", message));\n    }\n    Ok(())\n}\n\n/// Sets the [`Document`]'s encoding..\nfn set_encoding(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let doc = doc_mut!(cx.editor);\n    if let Some(label) = args.first() {\n        doc.set_encoding(label)\n    } else {\n        let encoding = doc.encoding().name().to_owned();\n        cx.editor.set_status(encoding);\n        Ok(())\n    }\n}\n\n/// Shows info about the character under the primary cursor.\nfn get_character_info(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let (view, doc) = current_ref!(cx.editor);\n    let text = doc.text().slice(..);\n\n    let grapheme_start = doc.selection(view.id).primary().cursor(text);\n    let grapheme_end = graphemes::next_grapheme_boundary(text, grapheme_start);\n\n    if grapheme_start == grapheme_end {\n        return Ok(());\n    }\n\n    let grapheme = text.slice(grapheme_start..grapheme_end).to_string();\n    let encoding = doc.encoding();\n\n    let printable = grapheme.chars().fold(String::new(), |mut s, c| {\n        match c {\n            '\\0' => s.push_str(\"\\\\0\"),\n            '\\t' => s.push_str(\"\\\\t\"),\n            '\\n' => s.push_str(\"\\\\n\"),\n            '\\r' => s.push_str(\"\\\\r\"),\n            _ => s.push(c),\n        }\n\n        s\n    });\n\n    // Convert to Unicode codepoints if in UTF-8\n    let unicode = if encoding == encoding::UTF_8 {\n        let mut unicode = \" (\".to_owned();\n\n        for (i, char) in grapheme.chars().enumerate() {\n            if i != 0 {\n                unicode.push(' ');\n            }\n\n            unicode.push_str(\"U+\");\n\n            let codepoint: u32 = if char.is_ascii() {\n                char.into()\n            } else {\n                // Not ascii means it will be multi-byte, so strip out the extra\n                // bits that encode the length & mark continuation bytes\n\n                let s = String::from(char);\n                let bytes = s.as_bytes();\n\n                // First byte starts with 2-4 ones then a zero, so strip those off\n                let first = bytes[0];\n                let codepoint = first & (0xFF >> (first.leading_ones() + 1));\n                let mut codepoint = u32::from(codepoint);\n\n                // Following bytes start with 10\n                for byte in bytes.iter().skip(1) {\n                    codepoint <<= 6;\n                    codepoint += u32::from(*byte) & 0x3F;\n                }\n\n                codepoint\n            };\n\n            write!(unicode, \"{codepoint:0>4x}\").unwrap();\n        }\n\n        unicode.push(')');\n        unicode\n    } else {\n        String::new()\n    };\n\n    // Give the decimal value for ascii characters\n    let dec = if encoding.is_ascii_compatible() && grapheme.len() == 1 {\n        format!(\" Dec {}\", grapheme.as_bytes()[0])\n    } else {\n        String::new()\n    };\n\n    let hex = {\n        let mut encoder = encoding.new_encoder();\n        let max_encoded_len = encoder\n            .max_buffer_length_from_utf8_without_replacement(grapheme.len())\n            .unwrap();\n        let mut bytes = Vec::with_capacity(max_encoded_len);\n        let mut current_byte = 0;\n        let mut hex = String::new();\n\n        for (i, char) in grapheme.chars().enumerate() {\n            if i != 0 {\n                hex.push_str(\" +\");\n            }\n\n            let (result, _input_bytes_read) = encoder.encode_from_utf8_to_vec_without_replacement(\n                &char.to_string(),\n                &mut bytes,\n                true,\n            );\n\n            if let encoding::EncoderResult::Unmappable(char) = result {\n                bail!(\"{char:?} cannot be mapped to {}\", encoding.name());\n            }\n\n            for byte in &bytes[current_byte..] {\n                write!(hex, \" {byte:0>2x}\").unwrap();\n            }\n\n            current_byte = bytes.len();\n        }\n\n        hex\n    };\n\n    cx.editor\n        .set_status(format!(\"\\\"{printable}\\\"{unicode}{dec} Hex{hex}\"));\n\n    Ok(())\n}\n\n/// Reload the [`Document`] from its source file.\nfn reload(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let scrolloff = cx.editor.config().scrolloff;\n    let (view, doc) = current!(cx.editor);\n    doc.reload(view, &cx.editor.diff_providers).map(|_| {\n        view.ensure_cursor_in_view(doc, scrolloff);\n    })?;\n    if let Some(path) = doc.path() {\n        cx.editor\n            .language_servers\n            .file_event_handler\n            .file_changed(path.clone());\n    }\n    Ok(())\n}\n\nfn reload_all(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let scrolloff = cx.editor.config().scrolloff;\n    let view_id = view!(cx.editor).id;\n\n    let docs_view_ids: Vec<(DocumentId, Vec<ViewId>)> = cx\n        .editor\n        .documents_mut()\n        .map(|doc| {\n            let mut view_ids: Vec<_> = doc.selections().keys().cloned().collect();\n\n            if view_ids.is_empty() {\n                doc.ensure_view_init(view_id);\n                view_ids.push(view_id);\n            };\n\n            (doc.id(), view_ids)\n        })\n        .collect();\n\n    for (doc_id, view_ids) in docs_view_ids {\n        let doc = doc_mut!(cx.editor, &doc_id);\n\n        // Every doc is guaranteed to have at least 1 view at this point.\n        let view = view_mut!(cx.editor, view_ids[0]);\n\n        // Ensure that the view is synced with the document's history.\n        view.sync_changes(doc);\n\n        if let Err(error) = doc.reload(view, &cx.editor.diff_providers) {\n            cx.editor.set_error(format!(\"{}\", error));\n            continue;\n        }\n\n        if let Some(path) = doc.path() {\n            cx.editor\n                .language_servers\n                .file_event_handler\n                .file_changed(path.clone());\n        }\n\n        for view_id in view_ids {\n            let view = view_mut!(cx.editor, view_id);\n            if view.doc.eq(&doc_id) {\n                view.ensure_cursor_in_view(doc, scrolloff);\n            }\n        }\n    }\n\n    Ok(())\n}\n\n/// Update the [`Document`] if it has been modified.\nfn update(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let (_view, doc) = current!(cx.editor);\n    if doc.is_modified() {\n        write_impl(\n            cx,\n            None,\n            WriteOptions {\n                force: false,\n                auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),\n            },\n        )\n    } else {\n        Ok(())\n    }\n}\n\nfn lsp_workspace_command(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let doc = doc!(cx.editor);\n    let ls_id_commands = doc\n        .language_servers_with_feature(LanguageServerFeature::WorkspaceCommand)\n        .flat_map(|ls| {\n            ls.capabilities()\n                .execute_command_provider\n                .iter()\n                .flat_map(|options| options.commands.iter())\n                .map(|command| (ls.id(), command))\n        });\n\n    if args.is_empty() {\n        let commands = ls_id_commands\n            .map(|(ls_id, command)| {\n                (\n                    ls_id,\n                    helix_lsp::lsp::Command {\n                        title: command.clone(),\n                        command: command.clone(),\n                        arguments: None,\n                    },\n                )\n            })\n            .collect::<Vec<_>>();\n        let callback = async move {\n            let call: job::Callback = Callback::EditorCompositor(Box::new(\n                move |_editor: &mut Editor, compositor: &mut Compositor| {\n                    let columns = [ui::PickerColumn::new(\n                        \"title\",\n                        |(_ls_id, command): &(_, helix_lsp::lsp::Command), _| {\n                            command.title.as_str().into()\n                        },\n                    )];\n                    let picker = ui::Picker::new(\n                        columns,\n                        0,\n                        commands,\n                        (),\n                        move |cx, (ls_id, command), _action| {\n                            cx.editor.execute_lsp_command(command.clone(), *ls_id);\n                        },\n                    );\n                    compositor.push(Box::new(overlaid(picker)))\n                },\n            ));\n            Ok(call)\n        };\n        cx.jobs.callback(callback);\n    } else {\n        let command = args[0].to_string();\n        let matches: Vec<_> = ls_id_commands\n            .filter(|(_ls_id, c)| *c == &command)\n            .collect();\n\n        match matches.as_slice() {\n            [(ls_id, _command)] => {\n                let arguments = args\n                    .get(1)\n                    .map(|rest| {\n                        serde_json::Deserializer::from_str(rest)\n                            .into_iter()\n                            .collect::<Result<Vec<Value>, _>>()\n                            .map_err(|err| anyhow!(\"failed to parse arguments: {err}\"))\n                    })\n                    .transpose()?\n                    .filter(|args| !args.is_empty());\n\n                cx.editor.execute_lsp_command(\n                    helix_lsp::lsp::Command {\n                        title: command.clone(),\n                        arguments,\n                        command,\n                    },\n                    *ls_id,\n                );\n            }\n            [] => {\n                cx.editor.set_status(format!(\n                    \"`{command}` is not supported for any language server\"\n                ));\n            }\n            _ => {\n                cx.editor.set_status(format!(\n                    \"`{command}` supported by multiple language servers\"\n                ));\n            }\n        }\n    }\n    Ok(())\n}\n\nfn lsp_restart(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let editor_config = cx.editor.config.load();\n    let doc = doc!(cx.editor);\n    let config = doc\n        .language_config()\n        .context(\"LSP not defined for the current document\")?;\n\n    let language_servers: Vec<_> = config\n        .language_servers\n        .iter()\n        .map(|ls| ls.name.as_str())\n        .collect();\n    let language_servers = if args.is_empty() {\n        language_servers\n    } else {\n        let (valid, invalid): (Vec<_>, Vec<_>) = args\n            .iter()\n            .map(|arg| arg.as_ref())\n            .partition(|name| language_servers.contains(name));\n        if !invalid.is_empty() {\n            let s = if invalid.len() == 1 { \"\" } else { \"s\" };\n            bail!(\"Unknown language server{s}: {}\", invalid.join(\", \"));\n        }\n        valid\n    };\n\n    let mut errors = Vec::new();\n    for server in language_servers.iter() {\n        match cx\n            .editor\n            .language_servers\n            .restart_server(\n                server,\n                config,\n                doc.path(),\n                &editor_config.workspace_lsp_roots,\n                editor_config.lsp.snippets,\n            )\n            .transpose()\n        {\n            // Ignore the executable-not-found error unless the server was explicitly requested\n            // in the arguments.\n            Err(helix_lsp::Error::ExecutableNotFound(_))\n                if !args.iter().any(|arg| arg == server) => {}\n            Err(err) => errors.push(err.to_string()),\n            _ => (),\n        }\n    }\n\n    // This collect is needed because refresh_language_server would need to re-borrow editor.\n    let document_ids_to_refresh: Vec<DocumentId> = cx\n        .editor\n        .documents()\n        .filter_map(|doc| match doc.language_config() {\n            Some(config)\n                if config.language_servers.iter().any(|ls| {\n                    language_servers\n                        .iter()\n                        .any(|restarted_ls| restarted_ls == &ls.name)\n                }) =>\n            {\n                Some(doc.id())\n            }\n            _ => None,\n        })\n        .collect();\n\n    for document_id in document_ids_to_refresh {\n        cx.editor.refresh_language_servers(document_id);\n    }\n\n    if errors.is_empty() {\n        Ok(())\n    } else {\n        Err(anyhow::anyhow!(\n            \"Error restarting language servers: {}\",\n            errors.join(\", \")\n        ))\n    }\n}\n\nfn lsp_stop(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n    let doc = doc!(cx.editor);\n\n    let language_servers: Vec<_> = doc\n        .language_servers()\n        .map(|ls| ls.name().to_string())\n        .collect();\n    let language_servers = if args.is_empty() {\n        language_servers\n    } else {\n        let (valid, invalid): (Vec<_>, Vec<_>) = args\n            .iter()\n            .map(|arg| arg.to_string())\n            .partition(|name| language_servers.contains(name));\n        if !invalid.is_empty() {\n            let s = if invalid.len() == 1 { \"\" } else { \"s\" };\n            bail!(\"Unknown language server{s}: {}\", invalid.join(\", \"));\n        }\n        valid\n    };\n\n    for ls_name in &language_servers {\n        cx.editor.language_servers.stop(ls_name);\n\n        for doc in cx.editor.documents_mut() {\n            if let Some(client) = doc.remove_language_server_by_name(ls_name) {\n                doc.clear_diagnostics_for_language_server(client.id());\n                doc.reset_all_inlay_hints();\n                doc.inlay_hints_oudated = true;\n            }\n        }\n    }\n\n    Ok(())\n}\n\nfn tree_sitter_scopes(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n\n    let pos = doc.selection(view.id).primary().cursor(text);\n    let scopes = indent::get_scopes(doc.syntax(), text, pos);\n\n    let contents = format!(\"```json\\n{:?}\\n````\", scopes);\n\n    let callback = async move {\n        let call: job::Callback = Callback::EditorCompositor(Box::new(\n            move |editor: &mut Editor, compositor: &mut Compositor| {\n                let contents = ui::Markdown::new(contents, editor.syn_loader.clone());\n                let popup = Popup::new(\"hover\", contents).auto_close(true);\n                compositor.replace_or_push(\"hover\", popup);\n            },\n        ));\n        Ok(call)\n    };\n\n    cx.jobs.callback(callback);\n\n    Ok(())\n}\n\nfn tree_sitter_highlight_name(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let (view, doc) = current_ref!(cx.editor);\n    let Some(syntax) = doc.syntax() else {\n        return Ok(());\n    };\n    let text = doc.text().slice(..);\n    let cursor = doc.selection(view.id).primary().cursor(text);\n    let byte = text.char_to_byte(cursor) as u32;\n    // Query the same range as the one used in syntax highlighting.\n    let range = {\n        // Calculate viewport byte ranges:\n        let row = text.char_to_line(doc.view_offset(view.id).anchor.min(text.len_chars()));\n        // Saturating subs to make it inclusive zero indexing.\n        let last_line = text.len_lines().saturating_sub(1);\n        let height = view.inner_area(doc).height;\n        let last_visible_line = (row + height as usize).saturating_sub(1).min(last_line);\n        let start = text.line_to_byte(row.min(last_line)) as u32;\n        let end = text.line_to_byte(last_visible_line + 1) as u32;\n\n        start..end\n    };\n\n    let loader = cx.editor.syn_loader.load();\n    let mut highlighter = syntax.highlighter(text, &loader, range);\n    let mut highlights = Vec::new();\n\n    while highlighter.next_event_offset() <= byte {\n        let (event, new_highlights) = highlighter.advance();\n        if event == helix_core::syntax::HighlightEvent::Refresh {\n            highlights.clear();\n        }\n        highlights.extend(new_highlights);\n    }\n\n    let content = highlights\n        .into_iter()\n        .fold(String::new(), |mut acc, highlight| {\n            if !acc.is_empty() {\n                acc.push_str(\", \");\n            }\n            acc.push_str(cx.editor.theme.scope(highlight));\n            acc\n        });\n\n    let callback = async move {\n        let call: job::Callback = Callback::EditorCompositor(Box::new(\n            move |editor: &mut Editor, compositor: &mut Compositor| {\n                let content = ui::Markdown::new(content, editor.syn_loader.clone());\n                let popup = Popup::new(\"hover\", content).auto_close(true);\n                compositor.replace_or_push(\"hover\", popup);\n            },\n        ));\n        Ok(call)\n    };\n\n    cx.jobs.callback(callback);\n\n    Ok(())\n}\n\nfn tree_sitter_layers(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let (view, doc) = current_ref!(cx.editor);\n    let Some(syntax) = doc.syntax() else {\n        bail!(\"Syntax information is not available\");\n    };\n\n    let loader: &helix_core::syntax::Loader = &cx.editor.syn_loader.load();\n    let text = doc.text().slice(..);\n    let cursor = doc.selection(view.id).primary().cursor(text);\n    let byte = text.char_to_byte(cursor) as u32;\n    let languages =\n        syntax\n            .layers_for_byte_range(byte, byte)\n            .fold(String::new(), |mut acc, layer| {\n                if !acc.is_empty() {\n                    acc.push_str(\", \");\n                }\n                acc.push_str(\n                    &loader\n                        .language(syntax.layer(layer).language)\n                        .config()\n                        .language_id,\n                );\n                acc\n            });\n\n    let callback = async move {\n        let call: job::Callback = Callback::EditorCompositor(Box::new(\n            move |editor: &mut Editor, compositor: &mut Compositor| {\n                let content = ui::Markdown::new(languages, editor.syn_loader.clone());\n                let popup = Popup::new(\"hover\", content).auto_close(true);\n                compositor.replace_or_push(\"hover\", popup);\n            },\n        ));\n        Ok(call)\n    };\n\n    cx.jobs.callback(callback);\n\n    Ok(())\n}\n\nfn vsplit(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    if args.is_empty() {\n        split(cx.editor, Action::VerticalSplit);\n    } else {\n        open_impl(cx, args, Action::VerticalSplit)?;\n    }\n\n    Ok(())\n}\n\nfn hsplit(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    if args.is_empty() {\n        split(cx.editor, Action::HorizontalSplit);\n    } else {\n        open_impl(cx, args, Action::HorizontalSplit)?;\n    }\n\n    Ok(())\n}\n\nfn vsplit_new(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    cx.editor.new_file(Action::VerticalSplit);\n\n    Ok(())\n}\n\nfn hsplit_new(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    cx.editor.new_file(Action::HorizontalSplit);\n\n    Ok(())\n}\n\nfn debug_eval(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    if let Some(debugger) = cx.editor.debug_adapters.get_active_client() {\n        let (frame, thread_id) = match (debugger.active_frame, debugger.thread_id) {\n            (Some(frame), Some(thread_id)) => (frame, thread_id),\n            _ => {\n                bail!(\"Cannot find current stack frame to access variables\")\n            }\n        };\n\n        // TODO: support no frame_id\n\n        let frame_id = debugger.stack_frames[&thread_id][frame].id;\n        let response = helix_lsp::block_on(debugger.eval(args.join(\" \"), Some(frame_id)))?;\n        cx.editor.set_status(response.result);\n    }\n    Ok(())\n}\n\nfn debug_start(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let mut args: Vec<_> = args.into_iter().collect();\n    let name = match args.len() {\n        0 => None,\n        _ => Some(args.remove(0)),\n    };\n    dap_start_impl(cx, name.as_deref(), None, Some(args))\n}\n\nfn debug_remote(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let mut args: Vec<_> = args.into_iter().collect();\n    let address = match args.len() {\n        0 => None,\n        _ => Some(args.remove(0).parse()?),\n    };\n    let name = match args.len() {\n        0 => None,\n        _ => Some(args.remove(0)),\n    };\n    dap_start_impl(cx, name.as_deref(), address, Some(args))\n}\n\nfn tutor(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let path = helix_loader::runtime_file(Path::new(\"tutor\"));\n    cx.editor.open(&path, Action::Replace)?;\n    // Unset path to prevent accidentally saving to the original tutor file.\n    doc_mut!(cx.editor).set_path(None);\n    Ok(())\n}\n\nfn abort_goto_line_number_preview(cx: &mut compositor::Context) {\n    if let Some(last_selection) = cx.editor.last_selection.take() {\n        let scrolloff = cx.editor.config().scrolloff;\n\n        let (view, doc) = current!(cx.editor);\n        doc.set_selection(view.id, last_selection);\n        view.ensure_cursor_in_view(doc, scrolloff);\n    }\n}\n\nfn update_goto_line_number_preview(cx: &mut compositor::Context, args: Args) -> anyhow::Result<()> {\n    cx.editor.last_selection.get_or_insert_with(|| {\n        let (view, doc) = current!(cx.editor);\n        doc.selection(view.id).clone()\n    });\n\n    let scrolloff = cx.editor.config().scrolloff;\n    let line = args[0].parse::<usize>()?;\n    goto_line_without_jumplist(\n        cx.editor,\n        NonZeroUsize::new(line),\n        if cx.editor.mode == Mode::Select {\n            Movement::Extend\n        } else {\n            Movement::Move\n        },\n    );\n\n    let (view, doc) = current!(cx.editor);\n    view.ensure_cursor_in_view(doc, scrolloff);\n\n    Ok(())\n}\n\npub(super) fn goto_line_number(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    match event {\n        PromptEvent::Abort => abort_goto_line_number_preview(cx),\n        PromptEvent::Validate => {\n            // If we are invoked directly via a keybinding, Validate is\n            // sent without any prior Update events. Ensure the cursor\n            // is moved to the appropriate location.\n            update_goto_line_number_preview(cx, args)?;\n\n            let last_selection = cx\n                .editor\n                .last_selection\n                .take()\n                .expect(\"update_goto_line_number_preview should always set last_selection\");\n\n            let (view, doc) = current!(cx.editor);\n            view.jumps.push((doc.id(), last_selection));\n        }\n\n        // When a user hits backspace and there are no numbers left,\n        // we can bring them back to their original selection. If they\n        // begin typing numbers again, we'll start a new preview session.\n        PromptEvent::Update if args.is_empty() => abort_goto_line_number_preview(cx),\n        PromptEvent::Update => update_goto_line_number_preview(cx, args)?,\n    }\n\n    Ok(())\n}\n\n// Fetch the current value of a config option and output as status.\nfn get_option(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let key = &args[0].to_lowercase();\n    let key_error = || anyhow::anyhow!(\"Unknown key `{}`\", key);\n\n    let config = serde_json::json!(cx.editor.config().deref());\n    let pointer = format!(\"/{}\", key.replace('.', \"/\"));\n    let value = config.pointer(&pointer).ok_or_else(key_error)?;\n\n    cx.editor.set_status(value.to_string());\n    Ok(())\n}\n\n/// Change config at runtime. Access nested values by dot syntax, for\n/// example to disable smart case search, use `:set search.smart-case false`.\nfn set_option(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let (key, arg) = (&args[0].to_lowercase(), args[1].trim());\n\n    let key_error = || anyhow::anyhow!(\"Unknown key `{}`\", key);\n    let field_error = |_| anyhow::anyhow!(\"Could not parse field `{}`\", arg);\n\n    let mut config = serde_json::json!(&cx.editor.config().deref());\n    let pointer = format!(\"/{}\", key.replace('.', \"/\"));\n    let value = config.pointer_mut(&pointer).ok_or_else(key_error)?;\n\n    *value = if value.is_string() {\n        // JSON strings require quotes, so we can't .parse() directly\n        Value::String(arg.to_string())\n    } else {\n        arg.parse().map_err(field_error)?\n    };\n    let config = serde_json::from_value(config).map_err(field_error)?;\n\n    cx.editor\n        .config_events\n        .0\n        .send(ConfigEvent::Update(config))?;\n    Ok(())\n}\n\n/// Toggle boolean config option at runtime. Access nested values by dot\n/// syntax, for example to toggle smart case search, use `:toggle search.smart-\n/// case`.\nfn toggle_option(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let key = &args[0].to_lowercase();\n\n    let key_error = || anyhow::anyhow!(\"Unknown key `{}`\", key);\n\n    let mut config = serde_json::json!(&cx.editor.config().deref());\n    let pointer = format!(\"/{}\", key.replace('.', \"/\"));\n    let value = config.pointer_mut(&pointer).ok_or_else(key_error)?;\n\n    *value = match value {\n        Value::Bool(ref value) => {\n            ensure!(\n                args.len() == 1,\n                \"Bad arguments. For boolean configurations use: `:toggle {key}`\"\n            );\n            Value::Bool(!value)\n        }\n        Value::String(ref value) => {\n            ensure!(\n                args.len() == 2,\n                \"Bad arguments. For string configurations use: `:toggle {key} val1 val2 ...`\",\n            );\n            // For string values, parse the input according to normal command line rules.\n            let values: Vec<_> = command_line::Tokenizer::new(&args[1], true)\n                .map(|res| res.map(|token| token.content))\n                .collect::<Result<_, _>>()\n                .map_err(|err| anyhow!(\"failed to parse values: {err}\"))?;\n\n            Value::String(\n                values\n                    .iter()\n                    .skip_while(|e| *e != value)\n                    .nth(1)\n                    .map(AsRef::as_ref)\n                    .unwrap_or_else(|| &values[0])\n                    .to_string(),\n            )\n        }\n        Value::Null => bail!(\"Configuration {key} cannot be toggled\"),\n        Value::Number(_) | Value::Array(_) | Value::Object(_) => {\n            ensure!(\n                args.len() == 2,\n                \"Bad arguments. For {kind} configurations use: `:toggle {key} val1 val2 ...`\",\n                kind = match value {\n                    Value::Number(_) => \"number\",\n                    Value::Array(_) => \"array\",\n                    Value::Object(_) => \"object\",\n                    _ => unreachable!(),\n                }\n            );\n            // For numbers, arrays and objects, parse each argument with\n            // `serde_json::StreamDeserializer`.\n            let values: Vec<Value> = serde_json::Deserializer::from_str(&args[1])\n                .into_iter()\n                .collect::<Result<_, _>>()\n                .map_err(|err| anyhow!(\"failed to parse value: {err}\"))?;\n\n            if let Some(wrongly_typed_value) = values\n                .iter()\n                .find(|v| std::mem::discriminant(*v) != std::mem::discriminant(&*value))\n            {\n                bail!(\"value '{wrongly_typed_value}' has a different type than '{value}'\");\n            }\n\n            values\n                .iter()\n                .skip_while(|e| *e != value)\n                .nth(1)\n                .unwrap_or(&values[0])\n                .clone()\n        }\n    };\n\n    let status = format!(\"'{key}' is now set to {value}\");\n    let config = serde_json::from_value(config)\n        .map_err(|err| anyhow::anyhow!(\"Failed to parse config: {err}\"))?;\n\n    cx.editor\n        .config_events\n        .0\n        .send(ConfigEvent::Update(config))?;\n    cx.editor.set_status(status);\n    Ok(())\n}\n\n/// Change the language of the current buffer at runtime.\nfn language(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    if args.is_empty() {\n        let doc = doc!(cx.editor);\n        let language = &doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME);\n        cx.editor.set_status(language.to_string());\n        return Ok(());\n    }\n\n    let doc = doc_mut!(cx.editor);\n\n    let loader = cx.editor.syn_loader.load();\n    if &args[0] == DEFAULT_LANGUAGE_NAME {\n        doc.set_language(None, &loader)\n    } else {\n        doc.set_language_by_language_id(&args[0], &loader)?;\n    }\n    doc.detect_indent_and_line_ending();\n\n    let id = doc.id();\n    cx.editor.refresh_language_servers(id);\n    let doc = doc_mut!(cx.editor);\n    let diagnostics =\n        Editor::doc_diagnostics(&cx.editor.language_servers, &cx.editor.diagnostics, doc);\n    doc.replace_diagnostics(diagnostics, &[], None);\n    Ok(())\n}\n\nfn sort(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let scrolloff = cx.editor.config().scrolloff;\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id);\n\n    if selection.len() == 1 {\n        bail!(\"Sorting requires multiple selections. Hint: split selection first\");\n    }\n\n    let mut fragments: Vec<_> = selection\n        .slices(text)\n        .map(|fragment| fragment.chunks().collect())\n        .collect();\n\n    fragments.sort_by(\n        match (args.has_flag(\"insensitive\"), args.has_flag(\"reverse\")) {\n            (true, true) => |a: &Tendril, b: &Tendril| b.to_lowercase().cmp(&a.to_lowercase()),\n            (true, false) => |a: &Tendril, b: &Tendril| a.to_lowercase().cmp(&b.to_lowercase()),\n            (false, true) => |a: &Tendril, b: &Tendril| b.cmp(a),\n            (false, false) => |a: &Tendril, b: &Tendril| a.cmp(b),\n        },\n    );\n\n    let transaction = Transaction::change(\n        doc.text(),\n        selection\n            .into_iter()\n            .zip(fragments)\n            .map(|(s, fragment)| (s.from(), s.to(), Some(fragment))),\n    );\n\n    doc.apply(&transaction, view.id);\n    doc.append_changes_to_history(view);\n    view.ensure_cursor_in_view(doc, scrolloff);\n\n    Ok(())\n}\n\nfn reflow(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let scrolloff = cx.editor.config().scrolloff;\n    let (view, doc) = current!(cx.editor);\n\n    // Find the text_width by checking the following sources in order:\n    //   - The passed argument in `args`\n    //   - The configured text-width for this language in languages.toml\n    //   - The configured text-width in the config.toml\n    let text_width: usize = args\n        .first()\n        .map(|num| num.parse::<usize>())\n        .transpose()?\n        .unwrap_or_else(|| doc.text_width());\n\n    let rope = doc.text();\n\n    let selection = doc.selection(view.id);\n    let transaction = Transaction::change_by_selection(rope, selection, |range| {\n        let fragment = range.fragment(rope.slice(..));\n        let reflowed_text = helix_core::wrap::reflow_hard_wrap(&fragment, text_width);\n\n        (range.from(), range.to(), Some(reflowed_text))\n    });\n\n    doc.apply(&transaction, view.id);\n    doc.append_changes_to_history(view);\n    view.ensure_cursor_in_view(doc, scrolloff);\n\n    Ok(())\n}\n\nfn tree_sitter_subtree(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let (view, doc) = current!(cx.editor);\n\n    if let Some(syntax) = doc.syntax() {\n        let primary_selection = doc.selection(view.id).primary();\n        let text = doc.text();\n        let from = text.char_to_byte(primary_selection.from()) as u32;\n        let to = text.char_to_byte(primary_selection.to()) as u32;\n        if let Some(selected_node) = syntax.descendant_for_byte_range(from, to) {\n            let mut contents = String::from(\"```tsq\\n\");\n            helix_core::syntax::pretty_print_tree(&mut contents, selected_node)?;\n            contents.push_str(\"\\n```\");\n\n            let callback = async move {\n                let call: job::Callback = Callback::EditorCompositor(Box::new(\n                    move |editor: &mut Editor, compositor: &mut Compositor| {\n                        let contents = ui::Markdown::new(contents, editor.syn_loader.clone());\n                        let popup = Popup::new(\"hover\", contents).auto_close(true);\n                        compositor.replace_or_push(\"hover\", popup);\n                    },\n                ));\n                Ok(call)\n            };\n\n            cx.jobs.callback(callback);\n        }\n    }\n\n    Ok(())\n}\n\nfn open_config(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    cx.editor\n        .open(&helix_loader::config_file(), Action::Replace)?;\n    Ok(())\n}\n\nfn open_workspace_config(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    cx.editor\n        .open(&helix_loader::workspace_config_file(), Action::Replace)?;\n    Ok(())\n}\n\nfn open_log(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    cx.editor.open(&helix_loader::log_file(), Action::Replace)?;\n    Ok(())\n}\n\nfn refresh_config(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    cx.editor.config_events.0.send(ConfigEvent::Refresh)?;\n    Ok(())\n}\n\nfn append_output(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    shell(cx, &args.join(\" \"), &ShellBehavior::Append);\n    Ok(())\n}\n\nfn insert_output(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    shell(cx, &args.join(\" \"), &ShellBehavior::Insert);\n    Ok(())\n}\n\nfn pipe_to(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    pipe_impl(cx, args, event, &ShellBehavior::Ignore)\n}\n\nfn pipe(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    pipe_impl(cx, args, event, &ShellBehavior::Replace)\n}\n\nfn pipe_impl(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n    behavior: &ShellBehavior,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    shell(cx, &args.join(\" \"), behavior);\n    Ok(())\n}\n\nfn run_shell_command(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let shell = cx.editor.config().shell.clone();\n    let args = args.join(\" \");\n\n    let callback = async move {\n        let output = shell_impl_async(&shell, &args, None).await?;\n        let call: job::Callback = Callback::EditorCompositor(Box::new(\n            move |editor: &mut Editor, compositor: &mut Compositor| {\n                if !output.trim().is_empty() {\n                    let contents = ui::Markdown::new(\n                        format!(\"```sh\\n{}\\n```\", output.trim_end()),\n                        editor.syn_loader.clone(),\n                    );\n                    let popup = Popup::new(\"shell\", contents).position(Some(\n                        helix_core::Position::new(editor.cursor().0.unwrap_or_default().row, 2),\n                    ));\n                    compositor.replace_or_push(\"shell\", popup);\n                }\n                editor.set_status(\"Command run\");\n            },\n        ));\n        Ok(call)\n    };\n    cx.jobs.callback(callback);\n\n    Ok(())\n}\n\nfn reset_diff_change(\n    cx: &mut compositor::Context,\n    _args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let editor = &mut cx.editor;\n    let scrolloff = editor.config().scrolloff;\n\n    let (view, doc) = current!(editor);\n    let Some(handle) = doc.diff_handle() else {\n        bail!(\"Diff is not available in the current buffer\")\n    };\n\n    let diff = handle.load();\n    let doc_text = doc.text().slice(..);\n    let diff_base = diff.diff_base();\n    let mut changes = 0;\n\n    let transaction = Transaction::change(\n        doc.text(),\n        diff.hunks_intersecting_line_ranges(doc.selection(view.id).line_ranges(doc_text))\n            .map(|hunk| {\n                changes += 1;\n                let start = diff_base.line_to_char(hunk.before.start as usize);\n                let end = diff_base.line_to_char(hunk.before.end as usize);\n                let text: Tendril = diff_base.slice(start..end).chunks().collect();\n                (\n                    doc_text.line_to_char(hunk.after.start as usize),\n                    doc_text.line_to_char(hunk.after.end as usize),\n                    (!text.is_empty()).then_some(text),\n                )\n            }),\n    );\n    if changes == 0 {\n        bail!(\"There are no changes under any selection\");\n    }\n\n    drop(diff); // make borrow check happy\n    doc.apply(&transaction, view.id);\n    doc.append_changes_to_history(view);\n    view.ensure_cursor_in_view(doc, scrolloff);\n    cx.editor.set_status(format!(\n        \"Reset {changes} change{}\",\n        if changes == 1 { \"\" } else { \"s\" }\n    ));\n    Ok(())\n}\n\nfn clear_register(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    if args.is_empty() {\n        cx.editor.registers.clear();\n        cx.editor.set_status(\"All registers cleared\");\n        return Ok(());\n    }\n\n    ensure!(\n        args[0].chars().count() == 1,\n        format!(\"Invalid register {}\", &args[0])\n    );\n    let register = args[0].chars().next().unwrap_or_default();\n    if cx.editor.registers.remove(register) {\n        cx.editor\n            .set_status(format!(\"Register {} cleared\", register));\n    } else {\n        cx.editor\n            .set_error(format!(\"Register {} not found\", register));\n    }\n    Ok(())\n}\n\nfn set_register(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    ensure!(\n        args[0].chars().count() == 1,\n        format!(\"Invalid register {}\", &args[0])\n    );\n\n    let register = args[0].chars().next().unwrap_or_default();\n    cx.editor.registers.write(register, vec![args[1].into()])\n}\n\nfn redraw(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let callback = Box::pin(async move {\n        let call: job::Callback =\n            job::Callback::EditorCompositor(Box::new(|_editor, compositor| {\n                compositor.need_full_redraw();\n            }));\n\n        Ok(call)\n    });\n\n    cx.jobs.callback(callback);\n\n    Ok(())\n}\n\n#[derive(Debug, Clone, Copy)]\npub struct MoveBufferOptions {\n    pub force: bool,\n}\n\nfn move_buffer(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let new_path: PathBuf = args.first().unwrap().into();\n    move_buffer_impl(cx, new_path, MoveBufferOptions { force: false })\n}\n\nfn force_move_buffer(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let new_path: PathBuf = args.first().unwrap().into();\n    move_buffer_impl(cx, new_path, MoveBufferOptions { force: true })\n}\n\nfn move_buffer_impl(\n    cx: &mut compositor::Context,\n    new_path: PathBuf,\n    options: MoveBufferOptions,\n) -> anyhow::Result<()> {\n    let doc = doc!(cx.editor);\n    let old_path = doc\n        .path()\n        .context(\"Scratch buffer cannot be moved. Use :write instead\")?\n        .clone();\n\n    // if new_path is a directory, append the original file name\n    // to move the file into that directory.\n    let new_path = old_path\n        .file_name()\n        .filter(|_| new_path.is_dir())\n        .map(|old_file_name| new_path.join(old_file_name))\n        .unwrap_or(new_path);\n\n    if old_path.exists() {\n        if let Some(parent) = new_path.parent() {\n            if !parent.exists() {\n                if options.force {\n                    std::fs::DirBuilder::new().recursive(true).create(parent)?;\n                } else {\n                    bail!(\n                        \"can't move file, parent directory does not exist (use :mv! to create it)\"\n                    )\n                }\n            }\n        }\n    }\n\n    if let Err(err) = cx.editor.move_path(&old_path, new_path.as_ref()) {\n        bail!(\"Could not move file: {err}\");\n    }\n    Ok(())\n}\n\nfn yank_diagnostic(\n    cx: &mut compositor::Context,\n    args: Args,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let reg = match args.first() {\n        Some(s) => {\n            ensure!(s.chars().count() == 1, format!(\"Invalid register {s}\"));\n            s.chars().next().unwrap()\n        }\n        None => '+',\n    };\n\n    let (view, doc) = current_ref!(cx.editor);\n    let primary = doc.selection(view.id).primary();\n\n    // Look only for diagnostics that intersect with the primary selection\n    let diag: Vec<_> = doc\n        .diagnostics()\n        .iter()\n        .filter(|d| primary.overlaps(&helix_core::Range::new(d.range.start, d.range.end)))\n        .map(|d| d.message.clone())\n        .collect();\n    let n = diag.len();\n    if n == 0 {\n        bail!(\"No diagnostics under primary selection\");\n    }\n\n    cx.editor.registers.write(reg, diag)?;\n    cx.editor.set_status(format!(\n        \"Yanked {n} diagnostic{} to register {reg}\",\n        if n == 1 { \"\" } else { \"s\" }\n    ));\n    Ok(())\n}\n\nfn read(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let scrolloff = cx.editor.config().scrolloff;\n    let (view, doc) = current!(cx.editor);\n\n    let filename = args.first().unwrap();\n    let path = helix_stdx::path::expand_tilde(PathBuf::from(filename.to_string()));\n\n    ensure!(\n        path.exists() && path.is_file(),\n        \"path is not a file: {:?}\",\n        path\n    );\n\n    let file = std::fs::File::open(path).map_err(|err| anyhow!(\"error opening file: {}\", err))?;\n    let mut reader = BufReader::new(file);\n    let (contents, _, _) = read_to_string(&mut reader, Some(doc.encoding()))\n        .map_err(|err| anyhow!(\"error reading file: {}\", err))?;\n    let contents = Tendril::from(contents);\n    let selection = doc.selection(view.id);\n    let transaction = Transaction::insert(doc.text(), selection, contents);\n    doc.apply(&transaction, view.id);\n    doc.append_changes_to_history(view);\n    view.ensure_cursor_in_view(doc, scrolloff);\n\n    Ok(())\n}\n\nfn echo(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {\n    if event != PromptEvent::Validate {\n        return Ok(());\n    }\n\n    let output = args.into_iter().fold(String::new(), |mut acc, arg| {\n        if !acc.is_empty() {\n            acc.push(' ');\n        }\n        acc.push_str(&arg);\n        acc\n    });\n    cx.editor.set_status(output);\n\n    Ok(())\n}\n\nfn noop(_cx: &mut compositor::Context, _args: Args, _event: PromptEvent) -> anyhow::Result<()> {\n    Ok(())\n}\n\n/// This command accepts a single boolean --skip-visible flag and no positionals.\nconst BUFFER_CLOSE_OTHERS_SIGNATURE: Signature = Signature {\n    positionals: (0, Some(0)),\n    flags: &[Flag {\n        name: \"skip-visible\",\n        alias: Some('s'),\n        doc: \"don't close buffers that are visible\",\n        ..Flag::DEFAULT\n    }],\n    ..Signature::DEFAULT\n};\n\n// TODO: SHELL_SIGNATURE should specify var args for arguments, so that just completers::filename can be used,\n// but Signature does not yet allow for var args.\n\n/// This command handles all of its input as-is with no quoting or flags.\npub const SHELL_SIGNATURE: Signature = Signature {\n    positionals: (1, Some(2)),\n    raw_after: Some(1),\n    ..Signature::DEFAULT\n};\n\npub const SHELL_COMPLETER: CommandCompleter = CommandCompleter::positional(&[\n    // Command name\n    completers::program,\n    // Shell argument(s)\n    completers::repeating_filenames,\n]);\n\nconst WRITE_NO_FORMAT_FLAG: Flag = Flag {\n    name: \"no-format\",\n    doc: \"skip auto-formatting\",\n    ..Flag::DEFAULT\n};\n\npub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[\n    TypableCommand {\n        name: \"exit\",\n        aliases: &[\"x\", \"xit\"],\n        doc: \"Write changes to disk if the buffer is modified and then quit. Accepts an optional path (:exit some/path.txt).\",\n        fun: exit,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"exit!\",\n        aliases: &[\"x!\", \"xit!\"],\n        doc: \"Force write changes to disk, creating necessary subdirectories, if the buffer is modified and then quit. Accepts an optional path (:exit! some/path.txt).\",\n        fun: force_exit,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"quit\",\n        aliases: &[\"q\"],\n        doc: \"Close the current view.\",\n        fun: quit,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"quit!\",\n        aliases: &[\"q!\"],\n        doc: \"Force close the current view, ignoring unsaved changes.\",\n        fun: force_quit,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"open\",\n        aliases: &[\"o\", \"edit\", \"e\"],\n        doc: \"Open a file from disk into the current view.\",\n        fun: open,\n        completer: CommandCompleter::all(completers::filename),\n        signature: Signature {\n            positionals: (1, None),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"buffer-close\",\n        aliases: &[\"bc\", \"bclose\"],\n        doc: \"Close the current buffer.\",\n        fun: buffer_close,\n        completer: CommandCompleter::all(completers::buffer),\n        signature: Signature {\n            positionals: (0, None),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"buffer-close!\",\n        aliases: &[\"bc!\", \"bclose!\"],\n        doc: \"Close the current buffer forcefully, ignoring unsaved changes.\",\n        fun: force_buffer_close,\n        completer: CommandCompleter::all(completers::buffer),\n        signature: Signature {\n            positionals: (0, None),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"buffer-close-others\",\n        aliases: &[\"bco\", \"bcloseother\"],\n        doc: \"Close all buffers but the currently focused one.\",\n        fun: buffer_close_others,\n        completer: CommandCompleter::none(),\n        signature: BUFFER_CLOSE_OTHERS_SIGNATURE,\n    },\n    TypableCommand {\n        name: \"buffer-close-others!\",\n        aliases: &[\"bco!\", \"bcloseother!\"],\n        doc: \"Force close all buffers but the currently focused one.\",\n        fun: force_buffer_close_others,\n        completer: CommandCompleter::none(),\n        signature: BUFFER_CLOSE_OTHERS_SIGNATURE,\n    },\n    TypableCommand {\n        name: \"buffer-close-all\",\n        aliases: &[\"bca\", \"bcloseall\"],\n        doc: \"Close all buffers without quitting.\",\n        fun: buffer_close_all,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"buffer-close-all!\",\n        aliases: &[\"bca!\", \"bcloseall!\"],\n        doc: \"Force close all buffers ignoring unsaved changes without quitting.\",\n        fun: force_buffer_close_all,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"buffer-next\",\n        aliases: &[\"bn\", \"bnext\"],\n        doc: \"Goto next buffer.\",\n        fun: buffer_next,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"buffer-previous\",\n        aliases: &[\"bp\", \"bprev\"],\n        doc: \"Goto previous buffer.\",\n        fun: buffer_previous,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"write\",\n        aliases: &[\"w\"],\n        doc: \"Write changes to disk. Accepts an optional path (:write some/path.txt)\",\n        fun: write,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"write!\",\n        aliases: &[\"w!\"],\n        doc: \"Force write changes to disk creating necessary subdirectories. Accepts an optional path (:write! some/path.txt)\",\n        fun: force_write,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"write-buffer-close\",\n        aliases: &[\"wbc\"],\n        doc: \"Write changes to disk and closes the buffer. Accepts an optional path (:write-buffer-close some/path.txt)\",\n        fun: write_buffer_close,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"write-buffer-close!\",\n        aliases: &[\"wbc!\"],\n        doc: \"Force write changes to disk creating necessary subdirectories and closes the buffer. Accepts an optional path (:write-buffer-close! some/path.txt)\",\n        fun: force_write_buffer_close,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"new\",\n        aliases: &[\"n\"],\n        doc: \"Create a new scratch buffer.\",\n        fun: new_file,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"format\",\n        aliases: &[\"fmt\"],\n        doc: \"Format the file using an external formatter or language server.\",\n        fun: format,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"indent-style\",\n        aliases: &[],\n        doc: \"Set the indentation style for editing. ('t' for tabs or 1-16 for number of spaces.)\",\n        fun: set_indent_style,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"line-ending\",\n        aliases: &[],\n        #[cfg(not(feature = \"unicode-lines\"))]\n        doc: \"Set the document's default line ending. Options: crlf, lf.\",\n        #[cfg(feature = \"unicode-lines\")]\n        doc: \"Set the document's default line ending. Options: crlf, lf, cr, ff, nel.\",\n        fun: set_line_ending,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"earlier\",\n        aliases: &[\"ear\"],\n        doc: \"Jump back to an earlier point in edit history. Accepts a number of steps or a time span.\",\n        fun: earlier,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"later\",\n        aliases: &[\"lat\"],\n        doc: \"Jump to a later point in edit history. Accepts a number of steps or a time span.\",\n        fun: later,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"write-quit\",\n        aliases: &[\"wq\"],\n        doc: \"Write changes to disk and close the current view. Accepts an optional path (:wq some/path.txt)\",\n        fun: write_quit,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"write-quit!\",\n        aliases: &[\"wq!\"],\n        doc: \"Write changes to disk and close the current view forcefully. Accepts an optional path (:wq! some/path.txt)\",\n        fun: force_write_quit,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"write-all\",\n        aliases: &[\"wa\"],\n        doc: \"Write changes from all buffers to disk.\",\n        fun: write_all,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"write-all!\",\n        aliases: &[\"wa!\"],\n        doc: \"Forcefully write changes from all buffers to disk creating necessary subdirectories.\",\n        fun: force_write_all,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"write-quit-all\",\n        aliases: &[\"wqa\", \"xa\"],\n        doc: \"Write changes from all buffers to disk and close all views.\",\n        fun: write_all_quit,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"write-quit-all!\",\n        aliases: &[\"wqa!\", \"xa!\"],\n        doc: \"Forcefully write changes from all buffers to disk, creating necessary subdirectories, and close all views (ignoring unsaved changes).\",\n        fun: force_write_all_quit,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"quit-all\",\n        aliases: &[\"qa\"],\n        doc: \"Close all views.\",\n        fun: quit_all,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"quit-all!\",\n        aliases: &[\"qa!\"],\n        doc: \"Force close all views ignoring unsaved changes.\",\n        fun: force_quit_all,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"cquit\",\n        aliases: &[\"cq\"],\n        doc: \"Quit with exit code (default 1). Accepts an optional integer exit code (:cq 2).\",\n        fun: cquit,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"cquit!\",\n        aliases: &[\"cq!\"],\n        doc: \"Force quit with exit code (default 1) ignoring unsaved changes. Accepts an optional integer exit code (:cq! 2).\",\n        fun: force_cquit,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"theme\",\n        aliases: &[],\n        doc: \"Change the editor theme (show current theme if no name specified).\",\n        fun: theme,\n        completer: CommandCompleter::positional(&[completers::theme]),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"yank-join\",\n        aliases: &[],\n        doc: \"Yank joined selections. A separator can be provided as first argument. Default value is newline.\",\n        fun: yank_joined,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"clipboard-yank\",\n        aliases: &[],\n        doc: \"Yank main selection into system clipboard.\",\n        fun: yank_main_selection_to_clipboard,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"clipboard-yank-join\",\n        aliases: &[],\n        doc: \"Yank joined selections into system clipboard. A separator can be provided as first argument. Default value is newline.\", // FIXME: current UI can't display long doc.\n        fun: yank_joined_to_clipboard,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"primary-clipboard-yank\",\n        aliases: &[],\n        doc: \"Yank main selection into system primary clipboard.\",\n        fun: yank_main_selection_to_primary_clipboard,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"primary-clipboard-yank-join\",\n        aliases: &[],\n        doc: \"Yank joined selections into system primary clipboard. A separator can be provided as first argument. Default value is newline.\", // FIXME: current UI can't display long doc.\n        fun: yank_joined_to_primary_clipboard,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"clipboard-paste-after\",\n        aliases: &[],\n        doc: \"Paste system clipboard after selections.\",\n        fun: paste_clipboard_after,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"clipboard-paste-before\",\n        aliases: &[],\n        doc: \"Paste system clipboard before selections.\",\n        fun: paste_clipboard_before,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"clipboard-paste-replace\",\n        aliases: &[],\n        doc: \"Replace selections with content of system clipboard.\",\n        fun: replace_selections_with_clipboard,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"primary-clipboard-paste-after\",\n        aliases: &[],\n        doc: \"Paste primary clipboard after selections.\",\n        fun: paste_primary_clipboard_after,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"primary-clipboard-paste-before\",\n        aliases: &[],\n        doc: \"Paste primary clipboard before selections.\",\n        fun: paste_primary_clipboard_before,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"primary-clipboard-paste-replace\",\n        aliases: &[],\n        doc: \"Replace selections with content of system primary clipboard.\",\n        fun: replace_selections_with_primary_clipboard,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"show-clipboard-provider\",\n        aliases: &[],\n        doc: \"Show clipboard provider name in status bar.\",\n        fun: show_clipboard_provider,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"change-current-directory\",\n        aliases: &[\"cd\"],\n        doc: \"Change the current working directory.\",\n        fun: change_current_directory,\n        completer: CommandCompleter::positional(&[completers::directory]),\n        signature: Signature {\n            positionals: (1, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"show-directory-stack\",\n        aliases: &[],\n        doc: \"Show the directory stack as a <space> delimited string.\",\n        fun: show_directory_stack,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"push-directory\",\n        aliases: &[\"pushd\"],\n        doc: \"Save and then change the current directory.\",\n        fun: push_directory,\n        completer: CommandCompleter::positional(&[completers::directory]),\n        signature: Signature {\n            positionals: (1, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"pop-directory\",\n        aliases: &[\"popd\"],\n        doc: \"Remove the top entry from the directory stack, and cd to the new top directory..\",\n        fun: pop_directory,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"show-directory\",\n        aliases: &[\"pwd\"],\n        doc: \"Show the current working directory.\",\n        fun: show_current_directory,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"encoding\",\n        aliases: &[],\n        doc: \"Set encoding. Based on `https://encoding.spec.whatwg.org`.\",\n        fun: set_encoding,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"character-info\",\n        aliases: &[\"char\"],\n        doc: \"Get info about the character under the primary cursor.\",\n        fun: get_character_info,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"reload\",\n        aliases: &[\"rl\"],\n        doc: \"Discard changes and reload from the source file.\",\n        fun: reload,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"reload-all\",\n        aliases: &[\"rla\"],\n        doc: \"Discard changes and reload all documents from the source files.\",\n        fun: reload_all,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"update\",\n        aliases: &[\"u\"],\n        doc: \"Write changes only if the file has been modified.\",\n        fun: update,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            flags: &[WRITE_NO_FORMAT_FLAG],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"lsp-workspace-command\",\n        aliases: &[],\n        doc: \"Open workspace command picker\",\n        fun: lsp_workspace_command,\n        completer: CommandCompleter::positional(&[completers::lsp_workspace_command]),\n        signature: Signature {\n            positionals: (0, None),\n            raw_after: Some(1),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"lsp-restart\",\n        aliases: &[],\n        doc: \"Restarts the given language servers, or all language servers that are used by the current file if no arguments are supplied\",\n        fun: lsp_restart,\n        completer: CommandCompleter::all(completers::configured_language_servers),\n        signature: Signature {\n            positionals: (0, None),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"lsp-stop\",\n        aliases: &[],\n        doc: \"Stops the given language servers, or all language servers that are used by the current file if no arguments are supplied\",\n        fun: lsp_stop,\n        completer: CommandCompleter::all(completers::active_language_servers),\n        signature: Signature {\n            positionals: (0, None),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"tree-sitter-scopes\",\n        aliases: &[],\n        doc: \"Display tree sitter scopes, primarily for theming and development.\",\n        fun: tree_sitter_scopes,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"tree-sitter-highlight-name\",\n        aliases: &[],\n        doc: \"Display name of tree-sitter highlight scope under the cursor.\",\n        fun: tree_sitter_highlight_name,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"tree-sitter-layers\",\n        aliases: &[],\n        doc: \"Display language names of tree-sitter injection layers under the cursor.\",\n        fun: tree_sitter_layers,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"debug-start\",\n        aliases: &[\"dbg\"],\n        doc: \"Start a debug session from a given template with given parameters.\",\n        fun: debug_start,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, None),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"debug-remote\",\n        aliases: &[\"dbg-tcp\"],\n        doc: \"Connect to a debug adapter by TCP address and start a debugging session from a given template with given parameters.\",\n        fun: debug_remote,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, None),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"debug-eval\",\n        aliases: &[],\n        doc: \"Evaluate expression in current debug context.\",\n        fun: debug_eval,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (1, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"vsplit\",\n        aliases: &[\"vs\"],\n        doc: \"Open the file in a vertical split.\",\n        fun: vsplit,\n        completer: CommandCompleter::all(completers::filename),\n        signature: Signature {\n            positionals: (0, None),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"vsplit-new\",\n        aliases: &[\"vnew\"],\n        doc: \"Open a scratch buffer in a vertical split.\",\n        fun: vsplit_new,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"hsplit\",\n        aliases: &[\"hs\", \"sp\"],\n        doc: \"Open the file in a horizontal split.\",\n        fun: hsplit,\n        completer: CommandCompleter::all(completers::filename),\n        signature: Signature {\n            positionals: (0, None),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"hsplit-new\",\n        aliases: &[\"hnew\"],\n        doc: \"Open a scratch buffer in a horizontal split.\",\n        fun: hsplit_new,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"tutor\",\n        aliases: &[],\n        doc: \"Open the tutorial.\",\n        fun: tutor,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"goto\",\n        aliases: &[\"g\"],\n        doc: \"Goto line number.\",\n        fun: goto_line_number,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (1, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"set-language\",\n        aliases: &[\"lang\"],\n        doc: \"Set the language of current buffer (show current language if no value specified).\",\n        fun: language,\n        completer: CommandCompleter::positional(&[completers::language]),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"set-option\",\n        aliases: &[\"set\"],\n        doc: \"Set a config option at runtime.\\nFor example to disable smart case search, use `:set search.smart-case false`.\",\n        fun: set_option,\n        // TODO: Add support for completion of the options value(s), when appropriate.\n        completer: CommandCompleter::positional(&[completers::setting]),\n        signature: Signature {\n            positionals: (2, Some(2)),\n            raw_after: Some(1),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"toggle-option\",\n        aliases: &[\"toggle\"],\n        doc: \"Toggle a config option at runtime.\\nFor example to toggle smart case search, use `:toggle search.smart-case`.\",\n        fun: toggle_option,\n        completer: CommandCompleter::positional(&[completers::setting]),\n        signature: Signature {\n            positionals: (1, None),\n            raw_after: Some(1),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"get-option\",\n        aliases: &[\"get\"],\n        doc: \"Get the current value of a config option.\",\n        fun: get_option,\n        completer: CommandCompleter::positional(&[completers::setting]),\n        signature: Signature {\n            positionals: (1, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"sort\",\n        aliases: &[],\n        doc: \"Sort ranges in selection.\",\n        fun: sort,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            flags: &[\n                Flag {\n                    name: \"insensitive\",\n                    alias: Some('i'),\n                    doc: \"sort the ranges case-insensitively\",\n                    ..Flag::DEFAULT\n                },\n                Flag {\n                    name: \"reverse\",\n                    alias: Some('r'),\n                    doc: \"sort ranges in reverse order\",\n                    ..Flag::DEFAULT\n                },\n            ],\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"reflow\",\n        aliases: &[],\n        doc: \"Hard-wrap the current selection of lines to a given width.\",\n        fun: reflow,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"tree-sitter-subtree\",\n        aliases: &[\"ts-subtree\"],\n        doc: \"Display the smallest tree-sitter subtree that spans the primary selection, primarily for debugging queries.\",\n        fun: tree_sitter_subtree,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"config-reload\",\n        aliases: &[],\n        doc: \"Refresh user config.\",\n        fun: refresh_config,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"config-open\",\n        aliases: &[],\n        doc: \"Open the user config.toml file.\",\n        fun: open_config,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"config-open-workspace\",\n        aliases: &[],\n        doc: \"Open the workspace config.toml file.\",\n        fun: open_workspace_config,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"log-open\",\n        aliases: &[],\n        doc: \"Open the helix log file.\",\n        fun: open_log,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"insert-output\",\n        aliases: &[],\n        doc: \"Run shell command, inserting output before each selection.\",\n        fun: insert_output,\n        completer: SHELL_COMPLETER,\n        signature: SHELL_SIGNATURE,\n    },\n    TypableCommand {\n        name: \"append-output\",\n        aliases: &[],\n        doc: \"Run shell command, appending output after each selection.\",\n        fun: append_output,\n        completer: SHELL_COMPLETER,\n        signature: SHELL_SIGNATURE,\n    },\n    TypableCommand {\n        name: \"pipe\",\n        aliases: &[\"|\"],\n        doc: \"Pipe each selection to the shell command.\",\n        fun: pipe,\n        completer: SHELL_COMPLETER,\n        signature: SHELL_SIGNATURE,\n    },\n    TypableCommand {\n        name: \"pipe-to\",\n        aliases: &[],\n        doc: \"Pipe each selection to the shell command, ignoring output.\",\n        fun: pipe_to,\n        completer: SHELL_COMPLETER,\n        signature: SHELL_SIGNATURE,\n    },\n    TypableCommand {\n        name: \"run-shell-command\",\n        aliases: &[\"sh\", \"!\"],\n        doc: \"Run a shell command\",\n        fun: run_shell_command,\n        completer: SHELL_COMPLETER,\n        signature: SHELL_SIGNATURE,\n    },\n    TypableCommand {\n        name: \"reset-diff-change\",\n        aliases: &[\"diffget\", \"diffg\"],\n        doc: \"Reset the diff change at the cursor position.\",\n        fun: reset_diff_change,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"clear-register\",\n        aliases: &[],\n        doc: \"Clear given register. If no argument is provided, clear all registers.\",\n        fun: clear_register,\n        completer: CommandCompleter::all(completers::register),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"set-register\",\n        aliases: &[],\n        doc: \"Set contents of the given register.\",\n        fun: set_register,\n        completer: CommandCompleter::positional(&[completers::register, completers::none]),\n        signature: Signature {\n            positionals: (2, Some(2)),\n            raw_after: Some(1),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"redraw\",\n        aliases: &[],\n        doc: \"Clear and re-render the whole UI\",\n        fun: redraw,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, Some(0)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"move\",\n        aliases: &[\"mv\"],\n        doc: \"Move the current buffer and its corresponding file to a different path\",\n        fun: move_buffer,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (1, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"move!\",\n        aliases: &[\"mv!\"],\n        doc: \"Move the current buffer and its corresponding file to a different path creating necessary subdirectories\",\n        fun: force_move_buffer,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (1, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"yank-diagnostic\",\n        aliases: &[],\n        doc: \"Yank diagnostic(s) under primary cursor to register, or clipboard by default\",\n        fun: yank_diagnostic,\n        completer: CommandCompleter::all(completers::register),\n        signature: Signature {\n            positionals: (0, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"read\",\n        aliases: &[\"r\"],\n        doc: \"Load a file into buffer\",\n        fun: read,\n        completer: CommandCompleter::positional(&[completers::filename]),\n        signature: Signature {\n            positionals: (1, Some(1)),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"echo\",\n        aliases: &[],\n        doc: \"Prints the given arguments to the statusline.\",\n        fun: echo,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (1, None),\n            ..Signature::DEFAULT\n        },\n    },\n    TypableCommand {\n        name: \"noop\",\n        aliases: &[],\n        doc: \"Does nothing.\",\n        fun: noop,\n        completer: CommandCompleter::none(),\n        signature: Signature {\n            positionals: (0, None),\n            ..Signature::DEFAULT\n        },\n    },\n];\n\npub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =\n    Lazy::new(|| {\n        TYPABLE_COMMAND_LIST\n            .iter()\n            .flat_map(|cmd| {\n                std::iter::once((cmd.name, cmd))\n                    .chain(cmd.aliases.iter().map(move |&alias| (alias, cmd)))\n            })\n            .collect()\n    });\n\nfn execute_command_line(\n    cx: &mut compositor::Context,\n    input: &str,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    let (command, rest, _) = command_line::split(input);\n    if command.is_empty() {\n        return Ok(());\n    }\n\n    // If command is numeric, interpret as line number and go there.\n    if command.parse::<usize>().is_ok() && rest.trim().is_empty() {\n        let cmd = TYPABLE_COMMAND_MAP.get(\"goto\").unwrap();\n        return execute_command(cx, cmd, command, event);\n    }\n\n    match typed::TYPABLE_COMMAND_MAP.get(command) {\n        Some(cmd) => execute_command(cx, cmd, rest, event),\n        None if event == PromptEvent::Validate => Err(anyhow!(\"no such command: '{command}'\")),\n        None => Ok(()),\n    }\n}\n\npub(super) fn execute_command(\n    cx: &mut compositor::Context,\n    cmd: &TypableCommand,\n    args: &str,\n    event: PromptEvent,\n) -> anyhow::Result<()> {\n    let args = if event == PromptEvent::Validate {\n        Args::parse(args, cmd.signature, true, |token| {\n            expansion::expand(cx.editor, token).map_err(|err| err.into())\n        })\n        .map_err(|err| anyhow!(\"'{}': {err}\", cmd.name))?\n    } else {\n        Args::parse(args, cmd.signature, false, |token| Ok(token.content))\n            .expect(\"arg parsing cannot fail when validation is turned off\")\n    };\n\n    (cmd.fun)(cx, args, event).map_err(|err| anyhow!(\"'{}': {err}\", cmd.name))\n}\n\n#[allow(clippy::unnecessary_unwrap)]\npub(super) fn command_mode(cx: &mut Context) {\n    let mut prompt = Prompt::new(\n        \":\".into(),\n        Some(':'),\n        complete_command_line,\n        move |cx: &mut compositor::Context, input: &str, event: PromptEvent| {\n            if let Err(err) = execute_command_line(cx, input, event) {\n                cx.editor.set_error(err.to_string());\n            }\n        },\n    );\n    prompt.doc_fn = Box::new(command_line_doc);\n\n    // Calculate initial completion\n    prompt.recalculate_completion(cx.editor);\n    cx.push_layer(Box::new(prompt));\n}\n\nfn command_line_doc(input: &str) -> Option<Cow<'_, str>> {\n    let (command, _, _) = command_line::split(input);\n    let command = TYPABLE_COMMAND_MAP.get(command)?;\n\n    if command.aliases.is_empty() && command.signature.flags.is_empty() {\n        return Some(Cow::Borrowed(command.doc));\n    }\n\n    let mut doc = command.doc.to_string();\n\n    if !command.aliases.is_empty() {\n        write!(doc, \"\\nAliases: {}\", command.aliases.join(\", \")).unwrap();\n    }\n\n    if !command.signature.flags.is_empty() {\n        const ARG_PLACEHOLDER: &str = \" <arg>\";\n\n        fn flag_len(flag: &Flag) -> usize {\n            let name_len = flag.name.len();\n            let alias_len = if let Some(alias) = flag.alias {\n                \"/-\".len() + alias.len_utf8()\n            } else {\n                0\n            };\n            let arg_len = if flag.completions.is_some() {\n                ARG_PLACEHOLDER.len()\n            } else {\n                0\n            };\n            name_len + alias_len + arg_len\n        }\n\n        doc.push_str(\"\\nFlags:\");\n\n        let max_flag_len = command.signature.flags.iter().map(flag_len).max().unwrap();\n\n        for flag in command.signature.flags {\n            let mut buf = [0u8; 4];\n            let this_flag_len = flag_len(flag);\n            write!(\n                doc,\n                \"\\n  --{flag_text}{spacer:spacing$}  {doc}\",\n                doc = flag.doc,\n                // `fmt::Arguments` does not respect width controls so we must place the spacers\n                // explicitly:\n                spacer = \"\",\n                spacing = max_flag_len - this_flag_len,\n                flag_text = format_args!(\n                    \"{}{}{}{}\",\n                    flag.name,\n                    // Ideally this would be written as a `format_args!` too but the borrow\n                    // checker is not yet smart enough.\n                    if flag.alias.is_some() { \"/-\" } else { \"\" },\n                    if let Some(alias) = flag.alias {\n                        alias.encode_utf8(&mut buf)\n                    } else {\n                        \"\"\n                    },\n                    if flag.completions.is_some() {\n                        ARG_PLACEHOLDER\n                    } else {\n                        \"\"\n                    }\n                ),\n            )\n            .unwrap();\n        }\n    }\n\n    Some(Cow::Owned(doc))\n}\n\nfn complete_command_line(editor: &Editor, input: &str) -> Vec<ui::prompt::Completion> {\n    let (command, rest, complete_command) = command_line::split(input);\n\n    if complete_command {\n        fuzzy_match(\n            input,\n            TYPABLE_COMMAND_LIST.iter().map(|command| command.name),\n            false,\n        )\n        .into_iter()\n        .map(|(name, _)| (0.., name.into()))\n        .collect()\n    } else {\n        TYPABLE_COMMAND_MAP\n            .get(command)\n            .map_or_else(Vec::new, |cmd| {\n                let args_offset = command.len() + 1;\n                complete_command_args(editor, cmd.signature, &cmd.completer, rest, args_offset)\n            })\n    }\n}\n\npub fn complete_command_args(\n    editor: &Editor,\n    signature: Signature,\n    completer: &CommandCompleter,\n    input: &str,\n    offset: usize,\n) -> Vec<ui::prompt::Completion> {\n    use command_line::{CompletionState, ExpansionKind, Tokenizer};\n\n    // TODO: completion should depend on the location of the cursor instead of the end of the\n    // string. This refactor is left for the future but the below completion code should respect\n    // the cursor position if it becomes a parameter.\n    let cursor = input.len();\n    let prefix = &input[..cursor];\n    let mut tokenizer = Tokenizer::new(prefix, false);\n    let mut args = Args::new(signature, false);\n    let mut final_token = None;\n    let mut is_last_token = true;\n\n    while let Some(token) = args\n        .read_token(&mut tokenizer)\n        .expect(\"arg parsing cannot fail when validation is turned off\")\n    {\n        final_token = Some(token.clone());\n        args.push(token.content)\n            .expect(\"arg parsing cannot fail when validation is turned off\");\n        if tokenizer.pos() >= cursor {\n            is_last_token = false;\n        }\n    }\n\n    // Use a fake final token when the input is not terminated with a token. This simulates an\n    // empty argument, causing completion on an empty value whenever you type space/tab. For\n    // example if you say `\":open README.md \"` (with that trailing space) you should see the\n    // files in the current dir - completing `\"\"` rather than completions for `\"README.md\"` or\n    // `\"README.md \"`.\n    let token = if is_last_token {\n        let token = Token::empty_at(prefix.len());\n        args.push(token.content.clone()).unwrap();\n        token\n    } else {\n        final_token.unwrap()\n    };\n\n    // Don't complete on closed tokens, for example after writing a closing double quote.\n    if token.is_terminated {\n        return Vec::new();\n    }\n\n    match token.kind {\n        TokenKind::Unquoted | TokenKind::Quoted(_) => {\n            match args.completion_state() {\n                CompletionState::Positional => {\n                    // If the completion state is positional there must be at least one positional\n                    // in `args`.\n                    let n = args\n                        .len()\n                        .checked_sub(1)\n                        .expect(\"completion state to be positional\");\n                    let completer = completer.for_argument_number(n);\n\n                    completer(editor, &token.content)\n                        .into_iter()\n                        .map(|(range, span)| quote_completion(&token, range, span, offset))\n                        .collect()\n                }\n                CompletionState::Flag(_) => fuzzy_match(\n                    token.content.trim_start_matches('-'),\n                    signature.flags.iter().map(|flag| flag.name),\n                    false,\n                )\n                .into_iter()\n                .map(|(name, _)| ((offset + token.content_start).., format!(\"--{name}\").into()))\n                .collect(),\n                CompletionState::FlagArgument(flag) => fuzzy_match(\n                    &token.content,\n                    flag.completions\n                        .expect(\"flags in FlagArgument always have completions\"),\n                    false,\n                )\n                .into_iter()\n                .map(|(value, _)| ((offset + token.content_start).., (*value).into()))\n                .collect(),\n            }\n        }\n        TokenKind::Expand | TokenKind::Expansion(ExpansionKind::Shell) => {\n            // See the comment about the checked sub expect above.\n            let arg_completer = matches!(args.completion_state(), CompletionState::Positional)\n                .then(|| {\n                    let n = args\n                        .len()\n                        .checked_sub(1)\n                        .expect(\"completion state to be positional\");\n                    completer.for_argument_number(n)\n                });\n            complete_expand(editor, &token, arg_completer, offset + token.content_start)\n        }\n        TokenKind::Expansion(ExpansionKind::Variable) => {\n            complete_variable_expansion(&token.content, offset + token.content_start)\n        }\n        TokenKind::Expansion(ExpansionKind::Unicode) => Vec::new(),\n        TokenKind::ExpansionKind => {\n            complete_expansion_kind(&token.content, offset + token.content_start)\n        }\n    }\n}\n\n/// Replace the content and optionally update the range of a positional's completion to account\n/// for quoting.\n///\n/// This is used to handle completions of file or directory names for example. When completing a\n/// file with a space, tab or percent character in the name, the space should be escaped by\n/// quoting the entire token. If the token being completed is already quoted, any quotes within\n/// the completion text should be escaped by doubling them.\nfn quote_completion<'a>(\n    token: &Token,\n    range: ops::RangeFrom<usize>,\n    mut span: Span<'a>,\n    offset: usize,\n) -> (ops::RangeFrom<usize>, Span<'a>) {\n    fn replace<'a>(text: Cow<'a, str>, from: char, to: &str) -> Cow<'a, str> {\n        if text.contains(from) {\n            Cow::Owned(text.replace(from, to))\n        } else {\n            text\n        }\n    }\n\n    match token.kind {\n        TokenKind::Unquoted if span.content.contains([' ', '\\t', '%']) => {\n            span.content = Cow::Owned(format!(\n                \"'{}{}'\",\n                // Escape any inner single quotes by doubling them.\n                replace(token.content[..range.start].into(), '\\'', \"''\"),\n                replace(span.content, '\\'', \"''\")\n            ));\n            // Ignore `range.start` here since we're replacing the entire token. We used\n            // `range.start` above to emulate the replacement that using `range.start` would have\n            // done.\n            ((offset + token.content_start).., span)\n        }\n        TokenKind::Quoted(quote) => {\n            span.content = replace(span.content, quote.char(), quote.escape());\n            ((range.start + offset + token.content_start).., span)\n        }\n        TokenKind::Expand => {\n            // NOTE: `token.content_start` is already accounted for in `offset` for `Expand`\n            // tokens.\n            span.content = replace(span.content, '\"', \"\\\"\\\"\");\n            ((range.start + offset).., span)\n        }\n        _ => ((range.start + offset + token.content_start).., span),\n    }\n}\n\nfn complete_expand(\n    editor: &Editor,\n    token: &Token,\n    completer: Option<&Completer>,\n    offset: usize,\n) -> Vec<ui::prompt::Completion> {\n    use command_line::{ExpansionKind, Tokenizer};\n\n    let mut start = 0;\n\n    // If the expand token contains expansions, complete those.\n    while let Some(idx) = token.content[start..].find('%') {\n        let idx = start + idx;\n        if token.content.as_bytes().get(idx + '%'.len_utf8()).copied() == Some(b'%') {\n            // Two percents together are skipped.\n            start = idx + ('%'.len_utf8() * 2);\n        } else {\n            let mut tokenizer = Tokenizer::new(&token.content[idx..], false);\n            let token = tokenizer\n                .parse_percent_token()\n                .map(|token| token.expect(\"arg parser cannot fail when validation is disabled\"));\n            start = idx + tokenizer.pos();\n\n            // Like closing quote characters in `complete_command_args` above, don't provide\n            // completions if the token is already terminated. This also skips expansions\n            // which have already been fully written, for example\n            // `\"%{cursor_line}:%{cursor_col` should complete `cursor_column` instead of\n            // `cursor_line`.\n            let Some(token) = token.filter(|t| !t.is_terminated) else {\n                continue;\n            };\n\n            let local_offset = offset + idx + token.content_start;\n            match token.kind {\n                TokenKind::Expansion(ExpansionKind::Variable) => {\n                    return complete_variable_expansion(&token.content, local_offset);\n                }\n                TokenKind::Expansion(ExpansionKind::Shell) => {\n                    return complete_expand(editor, &token, None, local_offset);\n                }\n                TokenKind::ExpansionKind => {\n                    return complete_expansion_kind(&token.content, local_offset);\n                }\n                _ => continue,\n            }\n        }\n    }\n\n    match completer {\n        // If no expansions were found and an argument is being completed,\n        Some(completer) if start == 0 => completer(editor, &token.content)\n            .into_iter()\n            .map(|(range, span)| quote_completion(token, range, span, offset))\n            .collect(),\n        _ => Vec::new(),\n    }\n}\n\nfn complete_variable_expansion(content: &str, offset: usize) -> Vec<ui::prompt::Completion> {\n    use expansion::Variable;\n\n    fuzzy_match(\n        content,\n        Variable::VARIANTS.iter().map(Variable::as_str),\n        false,\n    )\n    .into_iter()\n    .map(|(name, _)| (offset.., (*name).into()))\n    .collect()\n}\n\nfn complete_expansion_kind(content: &str, offset: usize) -> Vec<ui::prompt::Completion> {\n    use command_line::ExpansionKind;\n\n    fuzzy_match(\n        content,\n        // Skip `ExpansionKind::Variable` since its kind string is empty.\n        ExpansionKind::VARIANTS\n            .iter()\n            .skip(1)\n            .map(ExpansionKind::as_str),\n        false,\n    )\n    .into_iter()\n    .map(|(name, _)| (offset.., (*name).into()))\n    .collect()\n}\n"
  },
  {
    "path": "helix-term/src/commands.rs",
    "content": "pub(crate) mod dap;\npub(crate) mod lsp;\npub(crate) mod syntax;\npub(crate) mod typed;\n\npub use dap::*;\nuse futures_util::FutureExt;\nuse helix_event::status;\nuse helix_stdx::{\n    path::{self, find_paths},\n    rope::{self, RopeSliceExt},\n};\nuse helix_vcs::{FileChange, Hunk};\npub use lsp::*;\npub use syntax::*;\nuse tui::{\n    text::{Span, Spans},\n    widgets::Cell,\n};\npub use typed::*;\n\nuse helix_core::{\n    char_idx_at_visual_offset,\n    chars::char_is_word,\n    command_line::{self, Args},\n    comment,\n    doc_formatter::TextFormat,\n    encoding, find_workspace,\n    graphemes::{self, next_grapheme_boundary},\n    history::UndoKind,\n    increment,\n    indent::{self, IndentStyle},\n    line_ending::{get_line_ending_of_str, line_end_char_index},\n    match_brackets,\n    movement::{self, move_vertically_visual, Direction},\n    object, pos_at_coords,\n    regex::{self, Regex},\n    search::{self},\n    selection, surround,\n    syntax::config::{BlockCommentToken, LanguageServerFeature},\n    text_annotations::{Overlay, TextAnnotations},\n    textobject,\n    unicode::width::UnicodeWidthChar,\n    visual_offset_from_block, Deletion, LineEnding, Position, Range, Rope, RopeReader, RopeSlice,\n    Selection, SmallVec, Syntax, Tendril, Transaction,\n};\nuse helix_view::{\n    document::{FormatterError, Mode, SCRATCH_BUFFER_NAME},\n    editor::{Action, Motion},\n    expansion,\n    info::Info,\n    input::KeyEvent,\n    keyboard::KeyCode,\n    theme::Style,\n    tree,\n    view::View,\n    Document, DocumentId, Editor, ViewId,\n};\n\nuse anyhow::{anyhow, bail, ensure, Context as _};\nuse arc_swap::access::DynAccess;\nuse insert::*;\nuse movement::Movement;\n\nuse crate::{\n    compositor::{self, Component, Compositor},\n    filter_picker_entry,\n    job::Callback,\n    ui::{self, overlay::overlaid, Picker, PickerColumn, Popup, Prompt, PromptEvent},\n};\n\nuse crate::job::{self, Jobs};\nuse std::{\n    char::{ToLowercase, ToUppercase},\n    cmp::Ordering,\n    collections::{HashMap, HashSet},\n    error::Error,\n    fmt,\n    future::Future,\n    io::Read,\n    num::NonZeroUsize,\n};\n\nuse std::{\n    borrow::Cow,\n    path::{Path, PathBuf},\n};\n\nuse once_cell::sync::Lazy;\nuse serde::de::{self, Deserialize, Deserializer};\nuse url::Url;\n\nuse grep_regex::RegexMatcherBuilder;\nuse grep_searcher::{sinks, BinaryDetection, SearcherBuilder};\nuse ignore::{DirEntry, WalkBuilder, WalkState};\n\npub type OnKeyCallback = Box<dyn FnOnce(&mut Context, KeyEvent)>;\n#[derive(PartialEq, Eq, Clone, Copy, Debug)]\npub enum OnKeyCallbackKind {\n    PseudoPending,\n    Fallback,\n}\n\npub struct Context<'a> {\n    pub register: Option<char>,\n    pub count: Option<NonZeroUsize>,\n    pub editor: &'a mut Editor,\n\n    pub callback: Vec<crate::compositor::Callback>,\n    pub on_next_key_callback: Option<(OnKeyCallback, OnKeyCallbackKind)>,\n    pub jobs: &'a mut Jobs,\n}\n\nimpl Context<'_> {\n    /// Push a new component onto the compositor.\n    pub fn push_layer(&mut self, component: Box<dyn Component>) {\n        self.callback\n            .push(Box::new(|compositor: &mut Compositor, _| {\n                compositor.push(component)\n            }));\n    }\n\n    /// Call `replace_or_push` on the Compositor\n    pub fn replace_or_push_layer<T: Component>(&mut self, id: &'static str, component: T) {\n        self.callback\n            .push(Box::new(move |compositor: &mut Compositor, _| {\n                compositor.replace_or_push(id, component);\n            }));\n    }\n\n    #[inline]\n    pub fn on_next_key(\n        &mut self,\n        on_next_key_callback: impl FnOnce(&mut Context, KeyEvent) + 'static,\n    ) {\n        self.on_next_key_callback = Some((\n            Box::new(on_next_key_callback),\n            OnKeyCallbackKind::PseudoPending,\n        ));\n    }\n\n    #[inline]\n    pub fn on_next_key_fallback(\n        &mut self,\n        on_next_key_callback: impl FnOnce(&mut Context, KeyEvent) + 'static,\n    ) {\n        self.on_next_key_callback =\n            Some((Box::new(on_next_key_callback), OnKeyCallbackKind::Fallback));\n    }\n\n    #[inline]\n    pub fn callback<T, F>(\n        &mut self,\n        call: impl Future<Output = helix_lsp::Result<T>> + 'static + Send,\n        callback: F,\n    ) where\n        T: Send + 'static,\n        F: FnOnce(&mut Editor, &mut Compositor, T) + Send + 'static,\n    {\n        self.jobs.callback(make_job_callback(call, callback));\n    }\n\n    /// Returns 1 if no explicit count was provided\n    #[inline]\n    pub fn count(&self) -> usize {\n        self.count.map_or(1, |v| v.get())\n    }\n\n    /// Waits on all pending jobs, and then tries to flush all pending write\n    /// operations for all documents.\n    pub fn block_try_flush_writes(&mut self) -> anyhow::Result<()> {\n        compositor::Context {\n            editor: self.editor,\n            jobs: self.jobs,\n            scroll: None,\n        }\n        .block_try_flush_writes()\n    }\n}\n\n#[inline]\nfn make_job_callback<T, F>(\n    call: impl Future<Output = helix_lsp::Result<T>> + 'static + Send,\n    callback: F,\n) -> std::pin::Pin<Box<impl Future<Output = Result<Callback, anyhow::Error>>>>\nwhere\n    T: Send + 'static,\n    F: FnOnce(&mut Editor, &mut Compositor, T) + Send + 'static,\n{\n    Box::pin(async move {\n        let response = call.await?;\n        let call: job::Callback = Callback::EditorCompositor(Box::new(\n            move |editor: &mut Editor, compositor: &mut Compositor| {\n                callback(editor, compositor, response)\n            },\n        ));\n        Ok(call)\n    })\n}\n\nuse helix_view::{align_view, Align};\n\n/// MappableCommands are commands that can be bound to keys, executable in\n/// normal, insert or select mode.\n///\n/// There are three kinds:\n///\n/// * Static: commands usually bound to keys and used for editing, movement,\n///   etc., for example `move_char_left`.\n/// * Typable: commands executable from command mode, prefixed with a `:`,\n///   for example `:write!`.\n/// * Macro: a sequence of keys to execute, for example `@miw`.\n#[derive(Clone)]\npub enum MappableCommand {\n    Typable {\n        name: String,\n        args: String,\n        doc: String,\n    },\n    Static {\n        name: &'static str,\n        fun: fn(cx: &mut Context),\n        doc: &'static str,\n    },\n    Macro {\n        name: String,\n        keys: Vec<KeyEvent>,\n    },\n}\n\nmacro_rules! static_commands {\n    ( $($name:ident, $doc:literal,)* ) => {\n        $(\n            #[allow(non_upper_case_globals)]\n            pub const $name: Self = Self::Static {\n                name: stringify!($name),\n                fun: $name,\n                doc: $doc\n            };\n        )*\n\n        pub const STATIC_COMMAND_LIST: &'static [Self] = &[\n            $( Self::$name, )*\n        ];\n    }\n}\n\nimpl MappableCommand {\n    pub fn execute(&self, cx: &mut Context) {\n        match &self {\n            Self::Typable { name, args, doc: _ } => {\n                if let Some(command) = typed::TYPABLE_COMMAND_MAP.get(name.as_str()) {\n                    let mut cx = compositor::Context {\n                        editor: cx.editor,\n                        jobs: cx.jobs,\n                        scroll: None,\n                    };\n                    if let Err(e) =\n                        typed::execute_command(&mut cx, command, args, PromptEvent::Validate)\n                    {\n                        cx.editor.set_error(format!(\"{}\", e));\n                    }\n                } else {\n                    cx.editor.set_error(format!(\"no such command: '{name}'\"));\n                }\n            }\n            Self::Static { fun, .. } => (fun)(cx),\n            Self::Macro { keys, .. } => {\n                // Protect against recursive macros.\n                if cx.editor.macro_replaying.contains(&'@') {\n                    cx.editor.set_error(\n                        \"Cannot execute macro because the [@] register is already playing a macro\",\n                    );\n                    return;\n                }\n                cx.editor.macro_replaying.push('@');\n                let keys = keys.clone();\n                cx.callback.push(Box::new(move |compositor, cx| {\n                    for key in keys.into_iter() {\n                        compositor.handle_event(&compositor::Event::Key(key), cx);\n                    }\n                    cx.editor.macro_replaying.pop();\n                }));\n            }\n        }\n    }\n\n    pub fn name(&self) -> &str {\n        match &self {\n            Self::Typable { name, .. } => name,\n            Self::Static { name, .. } => name,\n            Self::Macro { name, .. } => name,\n        }\n    }\n\n    pub fn doc(&self) -> &str {\n        match &self {\n            Self::Typable { doc, .. } => doc,\n            Self::Static { doc, .. } => doc,\n            Self::Macro { name, .. } => name,\n        }\n    }\n\n    #[rustfmt::skip]\n    static_commands!(\n        no_op, \"Do nothing\",\n        move_char_left, \"Move left\",\n        move_char_right, \"Move right\",\n        move_line_up, \"Move up\",\n        move_line_down, \"Move down\",\n        move_visual_line_up, \"Move up\",\n        move_visual_line_down, \"Move down\",\n        extend_char_left, \"Extend left\",\n        extend_char_right, \"Extend right\",\n        extend_line_up, \"Extend up\",\n        extend_line_down, \"Extend down\",\n        extend_visual_line_up, \"Extend up\",\n        extend_visual_line_down, \"Extend down\",\n        copy_selection_on_next_line, \"Copy selection on next line\",\n        copy_selection_on_prev_line, \"Copy selection on previous line\",\n        move_next_word_start, \"Move to start of next word\",\n        move_prev_word_start, \"Move to start of previous word\",\n        move_next_word_end, \"Move to end of next word\",\n        move_prev_word_end, \"Move to end of previous word\",\n        move_next_long_word_start, \"Move to start of next long word\",\n        move_prev_long_word_start, \"Move to start of previous long word\",\n        move_next_long_word_end, \"Move to end of next long word\",\n        move_prev_long_word_end, \"Move to end of previous long word\",\n        move_next_sub_word_start, \"Move to start of next sub word\",\n        move_prev_sub_word_start, \"Move to start of previous sub word\",\n        move_next_sub_word_end, \"Move to end of next sub word\",\n        move_prev_sub_word_end, \"Move to end of previous sub word\",\n        move_parent_node_end, \"Move to end of the parent node\",\n        move_parent_node_start, \"Move to beginning of the parent node\",\n        extend_next_word_start, \"Extend to start of next word\",\n        extend_prev_word_start, \"Extend to start of previous word\",\n        extend_next_word_end, \"Extend to end of next word\",\n        extend_prev_word_end, \"Extend to end of previous word\",\n        extend_next_long_word_start, \"Extend to start of next long word\",\n        extend_prev_long_word_start, \"Extend to start of previous long word\",\n        extend_next_long_word_end, \"Extend to end of next long word\",\n        extend_prev_long_word_end, \"Extend to end of prev long word\",\n        extend_next_sub_word_start, \"Extend to start of next sub word\",\n        extend_prev_sub_word_start, \"Extend to start of previous sub word\",\n        extend_next_sub_word_end, \"Extend to end of next sub word\",\n        extend_prev_sub_word_end, \"Extend to end of prev sub word\",\n        extend_parent_node_end, \"Extend to end of the parent node\",\n        extend_parent_node_start, \"Extend to beginning of the parent node\",\n        find_till_char, \"Move till next occurrence of char\",\n        find_next_char, \"Move to next occurrence of char\",\n        extend_till_char, \"Extend till next occurrence of char\",\n        extend_next_char, \"Extend to next occurrence of char\",\n        till_prev_char, \"Move till previous occurrence of char\",\n        find_prev_char, \"Move to previous occurrence of char\",\n        extend_till_prev_char, \"Extend till previous occurrence of char\",\n        extend_prev_char, \"Extend to previous occurrence of char\",\n        repeat_last_motion, \"Repeat last motion\",\n        replace, \"Replace with new char\",\n        switch_case, \"Switch (toggle) case\",\n        switch_to_uppercase, \"Switch to uppercase\",\n        switch_to_lowercase, \"Switch to lowercase\",\n        page_up, \"Move page up\",\n        page_down, \"Move page down\",\n        half_page_up, \"Move half page up\",\n        half_page_down, \"Move half page down\",\n        page_cursor_up, \"Move page and cursor up\",\n        page_cursor_down, \"Move page and cursor down\",\n        page_cursor_half_up, \"Move page and cursor half up\",\n        page_cursor_half_down, \"Move page and cursor half down\",\n        select_all, \"Select whole document\",\n        select_regex, \"Select all regex matches inside selections\",\n        split_selection, \"Split selections on regex matches\",\n        split_selection_on_newline, \"Split selection on newlines\",\n        merge_selections, \"Merge selections\",\n        merge_consecutive_selections, \"Merge consecutive selections\",\n        search, \"Search for regex pattern\",\n        rsearch, \"Reverse search for regex pattern\",\n        search_next, \"Select next search match\",\n        search_prev, \"Select previous search match\",\n        extend_search_next, \"Add next search match to selection\",\n        extend_search_prev, \"Add previous search match to selection\",\n        search_selection, \"Use current selection as search pattern\",\n        search_selection_detect_word_boundaries, \"Use current selection as the search pattern, automatically wrapping with `\\\\b` on word boundaries\",\n        make_search_word_bounded, \"Modify current search to make it word bounded\",\n        global_search, \"Global search in workspace folder\",\n        extend_line, \"Select current line, if already selected, extend to another line based on the anchor\",\n        extend_line_below, \"Select current line, if already selected, extend to next line\",\n        extend_line_above, \"Select current line, if already selected, extend to previous line\",\n        select_line_above, \"Select current line, if already selected, extend or shrink line above based on the anchor\",\n        select_line_below, \"Select current line, if already selected, extend or shrink line below based on the anchor\",\n        extend_to_line_bounds, \"Extend selection to line bounds\",\n        shrink_to_line_bounds, \"Shrink selection to line bounds\",\n        delete_selection, \"Delete selection\",\n        delete_selection_noyank, \"Delete selection without yanking\",\n        change_selection, \"Change selection\",\n        change_selection_noyank, \"Change selection without yanking\",\n        collapse_selection, \"Collapse selection into single cursor\",\n        flip_selections, \"Flip selection cursor and anchor\",\n        ensure_selections_forward, \"Ensure all selections face forward\",\n        insert_mode, \"Insert before selection\",\n        append_mode, \"Append after selection\",\n        command_mode, \"Enter command mode\",\n        file_picker, \"Open file picker\",\n        file_picker_in_current_buffer_directory, \"Open file picker at current buffer's directory\",\n        file_picker_in_current_directory, \"Open file picker at current working directory\",\n        file_explorer, \"Open file explorer in workspace root\",\n        file_explorer_in_current_buffer_directory, \"Open file explorer at current buffer's directory\",\n        file_explorer_in_current_directory, \"Open file explorer at current working directory\",\n        code_action, \"Perform code action\",\n        buffer_picker, \"Open buffer picker\",\n        jumplist_picker, \"Open jumplist picker\",\n        symbol_picker, \"Open symbol picker\",\n        syntax_symbol_picker, \"Open symbol picker from syntax information\",\n        lsp_or_syntax_symbol_picker, \"Open symbol picker from LSP or syntax information\",\n        changed_file_picker, \"Open changed file picker\",\n        select_references_to_symbol_under_cursor, \"Select symbol references\",\n        workspace_symbol_picker, \"Open workspace symbol picker\",\n        syntax_workspace_symbol_picker, \"Open workspace symbol picker from syntax information\",\n        lsp_or_syntax_workspace_symbol_picker, \"Open workspace symbol picker from LSP or syntax information\",\n        diagnostics_picker, \"Open diagnostic picker\",\n        workspace_diagnostics_picker, \"Open workspace diagnostic picker\",\n        last_picker, \"Open last picker\",\n        insert_at_line_start, \"Insert at start of line\",\n        insert_at_line_end, \"Insert at end of line\",\n        open_below, \"Open new line below selection\",\n        open_above, \"Open new line above selection\",\n        normal_mode, \"Enter normal mode\",\n        select_mode, \"Enter selection extend mode\",\n        exit_select_mode, \"Exit selection mode\",\n        goto_definition, \"Goto definition\",\n        goto_declaration, \"Goto declaration\",\n        add_newline_above, \"Add newline above\",\n        add_newline_below, \"Add newline below\",\n        goto_type_definition, \"Goto type definition\",\n        goto_implementation, \"Goto implementation\",\n        goto_file_start, \"Goto line number `<n>` else file start\",\n        goto_file_end, \"Goto file end\",\n        extend_to_file_start, \"Extend to line number `<n>` else file start\",\n        extend_to_file_end, \"Extend to file end\",\n        goto_file, \"Goto files/URLs in selections\",\n        goto_file_hsplit, \"Goto files in selections (hsplit)\",\n        goto_file_vsplit, \"Goto files in selections (vsplit)\",\n        goto_reference, \"Goto references\",\n        goto_window_top, \"Goto window top\",\n        goto_window_center, \"Goto window center\",\n        goto_window_bottom, \"Goto window bottom\",\n        goto_last_accessed_file, \"Goto last accessed file\",\n        goto_last_modified_file, \"Goto last modified file\",\n        goto_last_modification, \"Goto last modification\",\n        goto_line, \"Goto line\",\n        goto_last_line, \"Goto last line\",\n        extend_to_last_line, \"Extend to last line\",\n        goto_first_diag, \"Goto first diagnostic\",\n        goto_last_diag, \"Goto last diagnostic\",\n        goto_next_diag, \"Goto next diagnostic\",\n        goto_prev_diag, \"Goto previous diagnostic\",\n        goto_next_change, \"Goto next change\",\n        goto_prev_change, \"Goto previous change\",\n        goto_first_change, \"Goto first change\",\n        goto_last_change, \"Goto last change\",\n        goto_line_start, \"Goto line start\",\n        goto_line_end, \"Goto line end\",\n        goto_column, \"Goto column\",\n        extend_to_column, \"Extend to column\",\n        goto_next_buffer, \"Goto next buffer\",\n        goto_previous_buffer, \"Goto previous buffer\",\n        goto_line_end_newline, \"Goto newline at line end\",\n        goto_first_nonwhitespace, \"Goto first non-blank in line\",\n        trim_selections, \"Trim whitespace from selections\",\n        extend_to_line_start, \"Extend to line start\",\n        extend_to_first_nonwhitespace, \"Extend to first non-blank in line\",\n        extend_to_line_end, \"Extend to line end\",\n        extend_to_line_end_newline, \"Extend to line end\",\n        signature_help, \"Show signature help\",\n        smart_tab, \"Insert tab if all cursors have all whitespace to their left; otherwise, run a separate command.\",\n        insert_tab, \"Insert tab char\",\n        insert_newline, \"Insert newline char\",\n        insert_char_interactive, \"Insert an interactively-chosen char\",\n        append_char_interactive, \"Append an interactively-chosen char\",\n        delete_char_backward, \"Delete previous char\",\n        delete_char_forward, \"Delete next char\",\n        delete_word_backward, \"Delete previous word\",\n        delete_word_forward, \"Delete next word\",\n        kill_to_line_start, \"Delete till start of line\",\n        kill_to_line_end, \"Delete till end of line\",\n        undo, \"Undo change\",\n        redo, \"Redo change\",\n        earlier, \"Move backward in history\",\n        later, \"Move forward in history\",\n        commit_undo_checkpoint, \"Commit changes to new checkpoint\",\n        yank, \"Yank selection\",\n        yank_to_clipboard, \"Yank selections to clipboard\",\n        yank_to_primary_clipboard, \"Yank selections to primary clipboard\",\n        yank_joined, \"Join and yank selections\",\n        yank_joined_to_clipboard, \"Join and yank selections to clipboard\",\n        yank_main_selection_to_clipboard, \"Yank main selection to clipboard\",\n        yank_joined_to_primary_clipboard, \"Join and yank selections to primary clipboard\",\n        yank_main_selection_to_primary_clipboard, \"Yank main selection to primary clipboard\",\n        replace_with_yanked, \"Replace with yanked text\",\n        replace_selections_with_clipboard, \"Replace selections by clipboard content\",\n        replace_selections_with_primary_clipboard, \"Replace selections by primary clipboard\",\n        paste_after, \"Paste after selection\",\n        paste_before, \"Paste before selection\",\n        paste_clipboard_after, \"Paste clipboard after selections\",\n        paste_clipboard_before, \"Paste clipboard before selections\",\n        paste_primary_clipboard_after, \"Paste primary clipboard after selections\",\n        paste_primary_clipboard_before, \"Paste primary clipboard before selections\",\n        indent, \"Indent selection\",\n        unindent, \"Unindent selection\",\n        format_selections, \"Format selection\",\n        join_selections, \"Join lines inside selection\",\n        join_selections_space, \"Join lines inside selection and select spaces\",\n        keep_selections, \"Keep selections matching regex\",\n        remove_selections, \"Remove selections matching regex\",\n        align_selections, \"Align selections in column\",\n        keep_primary_selection, \"Keep primary selection\",\n        remove_primary_selection, \"Remove primary selection\",\n        completion, \"Invoke completion popup\",\n        hover, \"Show docs for item under cursor\",\n        toggle_comments, \"Comment/uncomment selections\",\n        toggle_line_comments, \"Line comment/uncomment selections\",\n        toggle_block_comments, \"Block comment/uncomment selections\",\n        rotate_selections_forward, \"Rotate selections forward\",\n        rotate_selections_backward, \"Rotate selections backward\",\n        rotate_selection_contents_forward, \"Rotate selection contents forward\",\n        rotate_selection_contents_backward, \"Rotate selections contents backward\",\n        reverse_selection_contents, \"Reverse selections contents\",\n        expand_selection, \"Expand selection to parent syntax node\",\n        shrink_selection, \"Shrink selection to previously expanded syntax node\",\n        select_next_sibling, \"Select next sibling in the syntax tree\",\n        select_prev_sibling, \"Select previous sibling the in syntax tree\",\n        select_all_siblings, \"Select all siblings of the current node\",\n        select_all_children, \"Select all children of the current node\",\n        jump_forward, \"Jump forward on jumplist\",\n        jump_backward, \"Jump backward on jumplist\",\n        save_selection, \"Save current selection to jumplist\",\n        jump_view_right, \"Jump to right split\",\n        jump_view_left, \"Jump to left split\",\n        jump_view_up, \"Jump to split above\",\n        jump_view_down, \"Jump to split below\",\n        swap_view_right, \"Swap with right split\",\n        swap_view_left, \"Swap with left split\",\n        swap_view_up, \"Swap with split above\",\n        swap_view_down, \"Swap with split below\",\n        transpose_view, \"Transpose splits\",\n        rotate_view, \"Goto next window\",\n        rotate_view_reverse, \"Goto previous window\",\n        hsplit, \"Horizontal bottom split\",\n        hsplit_new, \"Horizontal bottom split scratch buffer\",\n        vsplit, \"Vertical right split\",\n        vsplit_new, \"Vertical right split scratch buffer\",\n        wclose, \"Close window\",\n        wonly, \"Close windows except current\",\n        select_register, \"Select register\",\n        insert_register, \"Insert register\",\n        copy_between_registers, \"Copy between two registers\",\n        align_view_middle, \"Align view middle\",\n        align_view_top, \"Align view top\",\n        align_view_center, \"Align view center\",\n        align_view_bottom, \"Align view bottom\",\n        scroll_up, \"Scroll view up\",\n        scroll_down, \"Scroll view down\",\n        match_brackets, \"Goto matching bracket\",\n        surround_add, \"Surround add\",\n        surround_replace, \"Surround replace\",\n        surround_delete, \"Surround delete\",\n        select_textobject_around, \"Select around object\",\n        select_textobject_inner, \"Select inside object\",\n        goto_next_function, \"Goto next function\",\n        goto_prev_function, \"Goto previous function\",\n        goto_next_class, \"Goto next type definition\",\n        goto_prev_class, \"Goto previous type definition\",\n        goto_next_parameter, \"Goto next parameter\",\n        goto_prev_parameter, \"Goto previous parameter\",\n        goto_next_comment, \"Goto next comment\",\n        goto_prev_comment, \"Goto previous comment\",\n        goto_next_test, \"Goto next test\",\n        goto_prev_test, \"Goto previous test\",\n        goto_next_xml_element, \"Goto next (X)HTML element\",\n        goto_prev_xml_element, \"Goto previous (X)HTML element\",\n        goto_next_entry, \"Goto next pairing\",\n        goto_prev_entry, \"Goto previous pairing\",\n        goto_next_paragraph, \"Goto next paragraph\",\n        goto_prev_paragraph, \"Goto previous paragraph\",\n        dap_launch, \"Launch debug target\",\n        dap_restart, \"Restart debugging session\",\n        dap_toggle_breakpoint, \"Toggle breakpoint\",\n        dap_continue, \"Continue program execution\",\n        dap_pause, \"Pause program execution\",\n        dap_step_in, \"Step in\",\n        dap_step_out, \"Step out\",\n        dap_next, \"Step to next\",\n        dap_variables, \"List variables\",\n        dap_terminate, \"End debug session\",\n        dap_edit_condition, \"Edit breakpoint condition on current line\",\n        dap_edit_log, \"Edit breakpoint log message on current line\",\n        dap_switch_thread, \"Switch current thread\",\n        dap_switch_stack_frame, \"Switch stack frame\",\n        dap_enable_exceptions, \"Enable exception breakpoints\",\n        dap_disable_exceptions, \"Disable exception breakpoints\",\n        shell_pipe, \"Pipe selections through shell command\",\n        shell_pipe_to, \"Pipe selections into shell command ignoring output\",\n        shell_insert_output, \"Insert shell command output before selections\",\n        shell_append_output, \"Append shell command output after selections\",\n        shell_keep_pipe, \"Filter selections with shell predicate\",\n        suspend, \"Suspend and return to shell\",\n        rename_symbol, \"Rename symbol\",\n        increment, \"Increment item under cursor\",\n        decrement, \"Decrement item under cursor\",\n        record_macro, \"Record macro\",\n        replay_macro, \"Replay macro\",\n        command_palette, \"Open command palette\",\n        goto_word, \"Jump to a two-character label\",\n        extend_to_word, \"Extend to a two-character label\",\n        goto_next_tabstop, \"Goto next snippet placeholder\",\n        goto_prev_tabstop, \"Goto next snippet placeholder\",\n        rotate_selections_first, \"Make the first selection your primary one\",\n        rotate_selections_last, \"Make the last selection your primary one\",\n    );\n}\n\nimpl fmt::Debug for MappableCommand {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            MappableCommand::Static { name, .. } => {\n                f.debug_tuple(\"MappableCommand\").field(name).finish()\n            }\n            MappableCommand::Typable { name, args, .. } => f\n                .debug_tuple(\"MappableCommand\")\n                .field(name)\n                .field(args)\n                .finish(),\n            MappableCommand::Macro { name, keys, .. } => f\n                .debug_tuple(\"MappableCommand\")\n                .field(name)\n                .field(keys)\n                .finish(),\n        }\n    }\n}\n\nimpl fmt::Display for MappableCommand {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.write_str(self.name())\n    }\n}\n\nimpl std::str::FromStr for MappableCommand {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        if let Some(suffix) = s.strip_prefix(':') {\n            let (name, args, _) = command_line::split(suffix);\n            ensure!(!name.is_empty(), \"Expected typable command name\");\n            typed::TYPABLE_COMMAND_MAP\n                .get(name)\n                .map(|cmd| {\n                    let doc = if args.is_empty() {\n                        cmd.doc.to_string()\n                    } else {\n                        format!(\":{} {:?}\", cmd.name, args)\n                    };\n                    MappableCommand::Typable {\n                        name: cmd.name.to_owned(),\n                        doc,\n                        args: args.to_string(),\n                    }\n                })\n                .ok_or_else(|| anyhow!(\"No TypableCommand named '{}'\", s))\n        } else if let Some(suffix) = s.strip_prefix('@') {\n            helix_view::input::parse_macro(suffix).map(|keys| Self::Macro {\n                name: s.to_string(),\n                keys,\n            })\n        } else {\n            MappableCommand::STATIC_COMMAND_LIST\n                .iter()\n                .find(|cmd| cmd.name() == s)\n                .cloned()\n                .ok_or_else(|| anyhow!(\"No command named '{}'\", s))\n        }\n    }\n}\n\nimpl<'de> Deserialize<'de> for MappableCommand {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let s = String::deserialize(deserializer)?;\n        s.parse().map_err(de::Error::custom)\n    }\n}\n\nimpl PartialEq for MappableCommand {\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (\n                MappableCommand::Typable {\n                    name: first_name,\n                    args: first_args,\n                    ..\n                },\n                MappableCommand::Typable {\n                    name: second_name,\n                    args: second_args,\n                    ..\n                },\n            ) => first_name == second_name && first_args == second_args,\n            (\n                MappableCommand::Static {\n                    name: first_name, ..\n                },\n                MappableCommand::Static {\n                    name: second_name, ..\n                },\n            ) => first_name == second_name,\n            _ => false,\n        }\n    }\n}\n\nfn no_op(_cx: &mut Context) {}\n\ntype MoveFn =\n    fn(RopeSlice, Range, Direction, usize, Movement, &TextFormat, &mut TextAnnotations) -> Range;\n\nfn move_impl(cx: &mut Context, move_fn: MoveFn, dir: Direction, behaviour: Movement) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n    let text_fmt = doc.text_format(view.inner_area(doc).width, None);\n    let mut annotations = view.text_annotations(doc, None);\n\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        move_fn(\n            text,\n            range,\n            dir,\n            count,\n            behaviour,\n            &text_fmt,\n            &mut annotations,\n        )\n    });\n    drop(annotations);\n    doc.set_selection(view.id, selection);\n}\n\nuse helix_core::movement::{move_horizontally, move_vertically};\n\nfn move_char_left(cx: &mut Context) {\n    move_impl(cx, move_horizontally, Direction::Backward, Movement::Move)\n}\n\nfn move_char_right(cx: &mut Context) {\n    move_impl(cx, move_horizontally, Direction::Forward, Movement::Move)\n}\n\nfn move_line_up(cx: &mut Context) {\n    move_impl(cx, move_vertically, Direction::Backward, Movement::Move)\n}\n\nfn move_line_down(cx: &mut Context) {\n    move_impl(cx, move_vertically, Direction::Forward, Movement::Move)\n}\n\nfn move_visual_line_up(cx: &mut Context) {\n    move_impl(\n        cx,\n        move_vertically_visual,\n        Direction::Backward,\n        Movement::Move,\n    )\n}\n\nfn move_visual_line_down(cx: &mut Context) {\n    move_impl(\n        cx,\n        move_vertically_visual,\n        Direction::Forward,\n        Movement::Move,\n    )\n}\n\nfn extend_char_left(cx: &mut Context) {\n    move_impl(cx, move_horizontally, Direction::Backward, Movement::Extend)\n}\n\nfn extend_char_right(cx: &mut Context) {\n    move_impl(cx, move_horizontally, Direction::Forward, Movement::Extend)\n}\n\nfn extend_line_up(cx: &mut Context) {\n    move_impl(cx, move_vertically, Direction::Backward, Movement::Extend)\n}\n\nfn extend_line_down(cx: &mut Context) {\n    move_impl(cx, move_vertically, Direction::Forward, Movement::Extend)\n}\n\nfn extend_visual_line_up(cx: &mut Context) {\n    move_impl(\n        cx,\n        move_vertically_visual,\n        Direction::Backward,\n        Movement::Extend,\n    )\n}\n\nfn extend_visual_line_down(cx: &mut Context) {\n    move_impl(\n        cx,\n        move_vertically_visual,\n        Direction::Forward,\n        Movement::Extend,\n    )\n}\n\nfn goto_line_end_impl(view: &mut View, doc: &mut Document, movement: Movement) {\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let line = range.cursor_line(text);\n        let line_start = text.line_to_char(line);\n\n        let pos = graphemes::prev_grapheme_boundary(text, line_end_char_index(&text, line))\n            .max(line_start);\n\n        range.put_cursor(text, pos, movement == Movement::Extend)\n    });\n    doc.set_selection(view.id, selection);\n}\n\nfn goto_line_end(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    goto_line_end_impl(\n        view,\n        doc,\n        if cx.editor.mode == Mode::Select {\n            Movement::Extend\n        } else {\n            Movement::Move\n        },\n    )\n}\n\nfn extend_to_line_end(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    goto_line_end_impl(view, doc, Movement::Extend)\n}\n\nfn goto_line_end_newline_impl(view: &mut View, doc: &mut Document, movement: Movement) {\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let line = range.cursor_line(text);\n        let pos = line_end_char_index(&text, line);\n\n        range.put_cursor(text, pos, movement == Movement::Extend)\n    });\n    doc.set_selection(view.id, selection);\n}\n\nfn goto_line_end_newline(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    goto_line_end_newline_impl(\n        view,\n        doc,\n        if cx.editor.mode == Mode::Select {\n            Movement::Extend\n        } else {\n            Movement::Move\n        },\n    )\n}\n\nfn extend_to_line_end_newline(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    goto_line_end_newline_impl(view, doc, Movement::Extend)\n}\n\nfn goto_line_start_impl(view: &mut View, doc: &mut Document, movement: Movement) {\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let line = range.cursor_line(text);\n\n        // adjust to start of the line\n        let pos = text.line_to_char(line);\n        range.put_cursor(text, pos, movement == Movement::Extend)\n    });\n    doc.set_selection(view.id, selection);\n}\n\nfn goto_line_start(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    goto_line_start_impl(\n        view,\n        doc,\n        if cx.editor.mode == Mode::Select {\n            Movement::Extend\n        } else {\n            Movement::Move\n        },\n    )\n}\n\nfn goto_next_buffer(cx: &mut Context) {\n    goto_buffer(cx.editor, Direction::Forward, cx.count());\n}\n\nfn goto_previous_buffer(cx: &mut Context) {\n    goto_buffer(cx.editor, Direction::Backward, cx.count());\n}\n\nfn goto_buffer(editor: &mut Editor, direction: Direction, count: usize) {\n    let current = view!(editor).doc;\n\n    let id = match direction {\n        Direction::Forward => {\n            let iter = editor.documents.keys();\n            // skip 'count' times past current buffer\n            iter.cycle().skip_while(|id| *id != &current).nth(count)\n        }\n        Direction::Backward => {\n            let iter = editor.documents.keys();\n            // skip 'count' times past current buffer\n            iter.rev()\n                .cycle()\n                .skip_while(|id| *id != &current)\n                .nth(count)\n        }\n    }\n    .unwrap();\n\n    let id = *id;\n\n    editor.switch(id, Action::Replace);\n}\n\nfn extend_to_line_start(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    goto_line_start_impl(view, doc, Movement::Extend)\n}\n\nfn kill_to_line_start(cx: &mut Context) {\n    delete_by_selection_insert_mode(\n        cx,\n        move |text, range| {\n            let line = range.cursor_line(text);\n            let first_char = text.line_to_char(line);\n            let anchor = range.cursor(text);\n            let head = if anchor == first_char && line != 0 {\n                // select until previous line\n                line_end_char_index(&text, line - 1)\n            } else if let Some(pos) = text.line(line).first_non_whitespace_char() {\n                if first_char + pos < anchor {\n                    // select until first non-blank in line if cursor is after it\n                    first_char + pos\n                } else {\n                    // select until start of line\n                    first_char\n                }\n            } else {\n                // select until start of line\n                first_char\n            };\n            (head, anchor)\n        },\n        Direction::Backward,\n    );\n}\n\nfn kill_to_line_end(cx: &mut Context) {\n    delete_by_selection_insert_mode(\n        cx,\n        |text, range| {\n            let line = range.cursor_line(text);\n            let line_end_pos = line_end_char_index(&text, line);\n            let pos = range.cursor(text);\n\n            // if the cursor is on the newline char delete that\n            if pos == line_end_pos {\n                (pos, text.line_to_char(line + 1))\n            } else {\n                (pos, line_end_pos)\n            }\n        },\n        Direction::Forward,\n    );\n}\n\nfn goto_first_nonwhitespace(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n\n    goto_first_nonwhitespace_impl(\n        view,\n        doc,\n        if cx.editor.mode == Mode::Select {\n            Movement::Extend\n        } else {\n            Movement::Move\n        },\n    )\n}\n\nfn extend_to_first_nonwhitespace(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    goto_first_nonwhitespace_impl(view, doc, Movement::Extend)\n}\n\nfn goto_first_nonwhitespace_impl(view: &mut View, doc: &mut Document, movement: Movement) {\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let line = range.cursor_line(text);\n\n        if let Some(pos) = text.line(line).first_non_whitespace_char() {\n            let pos = pos + text.line_to_char(line);\n            range.put_cursor(text, pos, movement == Movement::Extend)\n        } else {\n            range\n        }\n    });\n    doc.set_selection(view.id, selection);\n}\n\nfn trim_selections(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n\n    let ranges: SmallVec<[Range; 1]> = doc\n        .selection(view.id)\n        .iter()\n        .filter_map(|range| {\n            if range.is_empty() || range.slice(text).chars().all(|ch| ch.is_whitespace()) {\n                return None;\n            }\n            let mut start = range.from();\n            let mut end = range.to();\n            start = movement::skip_while(text, start, |x| x.is_whitespace()).unwrap_or(start);\n            end = movement::backwards_skip_while(text, end, |x| x.is_whitespace()).unwrap_or(end);\n            Some(Range::new(start, end).with_direction(range.direction()))\n        })\n        .collect();\n\n    if !ranges.is_empty() {\n        let primary = doc.selection(view.id).primary();\n        let idx = ranges\n            .iter()\n            .position(|range| range.overlaps(&primary))\n            .unwrap_or(ranges.len() - 1);\n        doc.set_selection(view.id, Selection::new(ranges, idx));\n    } else {\n        collapse_selection(cx);\n        keep_primary_selection(cx);\n    };\n}\n\n// align text in selection\n#[allow(deprecated)]\nfn align_selections(cx: &mut Context) {\n    use helix_core::visual_coords_at_pos;\n\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n    let selection = doc.selection(view.id);\n\n    let tab_width = doc.tab_width();\n    let mut column_widths: Vec<Vec<_>> = Vec::new();\n    let mut last_line = text.len_lines() + 1;\n    let mut col = 0;\n\n    for range in selection {\n        let coords = visual_coords_at_pos(text, range.head, tab_width);\n        let anchor_coords = visual_coords_at_pos(text, range.anchor, tab_width);\n\n        if coords.row != anchor_coords.row {\n            cx.editor\n                .set_error(\"align cannot work with multi line selections\");\n            return;\n        }\n\n        col = if coords.row == last_line { col + 1 } else { 0 };\n\n        if col >= column_widths.len() {\n            column_widths.push(Vec::new());\n        }\n        column_widths[col].push((range.from(), coords.col));\n\n        last_line = coords.row;\n    }\n\n    let mut changes = Vec::with_capacity(selection.len());\n\n    // Account for changes on each row\n    let len = column_widths.first().map(|cols| cols.len()).unwrap_or(0);\n    let mut offs = vec![0; len];\n\n    for col in column_widths {\n        let max_col = col\n            .iter()\n            .enumerate()\n            .map(|(row, (_, cursor))| *cursor + offs[row])\n            .max()\n            .unwrap_or(0);\n\n        for (row, (insert_pos, last_col)) in col.into_iter().enumerate() {\n            let ins_count = max_col - (last_col + offs[row]);\n\n            if ins_count == 0 {\n                continue;\n            }\n\n            offs[row] += ins_count;\n\n            changes.push((insert_pos, insert_pos, Some(\" \".repeat(ins_count).into())));\n        }\n    }\n\n    // The changeset has to be sorted\n    changes.sort_unstable_by_key(|(from, _, _)| *from);\n\n    let transaction = Transaction::change(doc.text(), changes.into_iter());\n    doc.apply(&transaction, view.id);\n    exit_select_mode(cx);\n}\n\nfn goto_window(cx: &mut Context, align: Align) {\n    let count = cx.count() - 1;\n    let config = cx.editor.config();\n    let (view, doc) = current!(cx.editor);\n    let view_offset = doc.view_offset(view.id);\n\n    let height = view.inner_height();\n\n    // respect user given count if any\n    // - 1 so we have at least one gap in the middle.\n    // a height of 6 with padding of 3 on each side will keep shifting the view back and forth\n    // as we type\n    let scrolloff = config.scrolloff.min(height.saturating_sub(1) / 2);\n\n    let last_visual_line = view.last_visual_line(doc);\n\n    let visual_line = match align {\n        Align::Top => view_offset.vertical_offset + scrolloff + count,\n        Align::Center => view_offset.vertical_offset + (last_visual_line / 2),\n        Align::Bottom => {\n            view_offset.vertical_offset + last_visual_line.saturating_sub(scrolloff + count)\n        }\n    };\n    let visual_line = visual_line\n        .max(view_offset.vertical_offset + scrolloff)\n        .min(view_offset.vertical_offset + last_visual_line.saturating_sub(scrolloff));\n\n    let pos = view\n        .pos_at_visual_coords(doc, visual_line as u16, 0, false)\n        .expect(\"visual_line was constrained to the view area\");\n\n    let text = doc.text().slice(..);\n    let selection = doc\n        .selection(view.id)\n        .clone()\n        .transform(|range| range.put_cursor(text, pos, cx.editor.mode == Mode::Select));\n    doc.set_selection(view.id, selection);\n}\n\nfn goto_window_top(cx: &mut Context) {\n    goto_window(cx, Align::Top)\n}\n\nfn goto_window_center(cx: &mut Context) {\n    goto_window(cx, Align::Center)\n}\n\nfn goto_window_bottom(cx: &mut Context) {\n    goto_window(cx, Align::Bottom)\n}\n\nfn move_word_impl<F>(cx: &mut Context, move_fn: F)\nwhere\n    F: Fn(RopeSlice, Range, usize) -> Range,\n{\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n\n    let selection = doc\n        .selection(view.id)\n        .clone()\n        .transform(|range| move_fn(text, range, count));\n    doc.set_selection(view.id, selection);\n}\n\nfn move_next_word_start(cx: &mut Context) {\n    move_word_impl(cx, movement::move_next_word_start)\n}\n\nfn move_prev_word_start(cx: &mut Context) {\n    move_word_impl(cx, movement::move_prev_word_start)\n}\n\nfn move_prev_word_end(cx: &mut Context) {\n    move_word_impl(cx, movement::move_prev_word_end)\n}\n\nfn move_next_word_end(cx: &mut Context) {\n    move_word_impl(cx, movement::move_next_word_end)\n}\n\nfn move_next_long_word_start(cx: &mut Context) {\n    move_word_impl(cx, movement::move_next_long_word_start)\n}\n\nfn move_prev_long_word_start(cx: &mut Context) {\n    move_word_impl(cx, movement::move_prev_long_word_start)\n}\n\nfn move_prev_long_word_end(cx: &mut Context) {\n    move_word_impl(cx, movement::move_prev_long_word_end)\n}\n\nfn move_next_long_word_end(cx: &mut Context) {\n    move_word_impl(cx, movement::move_next_long_word_end)\n}\n\nfn move_next_sub_word_start(cx: &mut Context) {\n    move_word_impl(cx, movement::move_next_sub_word_start)\n}\n\nfn move_prev_sub_word_start(cx: &mut Context) {\n    move_word_impl(cx, movement::move_prev_sub_word_start)\n}\n\nfn move_prev_sub_word_end(cx: &mut Context) {\n    move_word_impl(cx, movement::move_prev_sub_word_end)\n}\n\nfn move_next_sub_word_end(cx: &mut Context) {\n    move_word_impl(cx, movement::move_next_sub_word_end)\n}\n\nfn goto_para_impl<F>(cx: &mut Context, move_fn: F)\nwhere\n    F: Fn(RopeSlice, Range, usize, Movement) -> Range + 'static,\n{\n    let count = cx.count();\n    let motion = move |editor: &mut Editor| {\n        let (view, doc) = current!(editor);\n        let text = doc.text().slice(..);\n        let behavior = if editor.mode == Mode::Select {\n            Movement::Extend\n        } else {\n            Movement::Move\n        };\n\n        let selection = doc\n            .selection(view.id)\n            .clone()\n            .transform(|range| move_fn(text, range, count, behavior));\n        doc.set_selection(view.id, selection);\n    };\n    cx.editor.apply_motion(motion)\n}\n\nfn goto_prev_paragraph(cx: &mut Context) {\n    goto_para_impl(cx, movement::move_prev_paragraph)\n}\n\nfn goto_next_paragraph(cx: &mut Context) {\n    goto_para_impl(cx, movement::move_next_paragraph)\n}\n\nfn goto_file_start(cx: &mut Context) {\n    goto_file_start_impl(cx, Movement::Move);\n}\n\nfn extend_to_file_start(cx: &mut Context) {\n    goto_file_start_impl(cx, Movement::Extend);\n}\n\nfn goto_file_start_impl(cx: &mut Context, movement: Movement) {\n    if cx.count.is_some() {\n        goto_line_impl(cx, movement);\n    } else {\n        let (view, doc) = current!(cx.editor);\n        let text = doc.text().slice(..);\n        let selection = doc\n            .selection(view.id)\n            .clone()\n            .transform(|range| range.put_cursor(text, 0, movement == Movement::Extend));\n        push_jump(view, doc);\n        doc.set_selection(view.id, selection);\n    }\n}\n\nfn goto_file_end(cx: &mut Context) {\n    goto_file_end_impl(cx, Movement::Move);\n}\n\nfn extend_to_file_end(cx: &mut Context) {\n    goto_file_end_impl(cx, Movement::Extend)\n}\n\nfn goto_file_end_impl(cx: &mut Context, movement: Movement) {\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n    let pos = doc.text().len_chars();\n    let selection = doc\n        .selection(view.id)\n        .clone()\n        .transform(|range| range.put_cursor(text, pos, movement == Movement::Extend));\n    push_jump(view, doc);\n    doc.set_selection(view.id, selection);\n}\n\nfn goto_file(cx: &mut Context) {\n    goto_file_impl(cx, Action::Replace);\n}\n\nfn goto_file_hsplit(cx: &mut Context) {\n    goto_file_impl(cx, Action::HorizontalSplit);\n}\n\nfn goto_file_vsplit(cx: &mut Context) {\n    goto_file_impl(cx, Action::VerticalSplit);\n}\n\n/// Returns true when a selection overlaps an LSP document link range.\nfn selection_overlaps_document_link(\n    selection: &Range,\n    link: &helix_view::document::DocumentLink,\n) -> bool {\n    if selection.is_empty() {\n        let pos = selection.from();\n        link.start <= pos && pos < link.end\n    } else {\n        selection.from() < link.end && selection.to() > link.start\n    }\n}\n\n/// Resolve a document link target, using the LSP resolve request when needed.\nfn resolve_document_link_target(\n    editor: &Editor,\n    link: &helix_view::document::DocumentLink,\n) -> Option<Url> {\n    if let Some(target) = link.link.target.clone() {\n        return Some(target);\n    }\n\n    let language_server = editor.language_server_by_id(link.language_server_id)?;\n    let supports_resolve = language_server\n        .capabilities()\n        .document_link_provider\n        .as_ref()?\n        .resolve_provider\n        .unwrap_or(false);\n\n    if !supports_resolve {\n        return None;\n    }\n\n    let future = language_server.resolve_document_link(link.link.clone())?;\n    helix_lsp::block_on(future).ok()?.target\n}\n\n/// Goto files/URLs in selection.\n///\n/// Prefers LSP document links when the cursor/selection overlaps a link range,\n/// falling back to the built-in path/URL detection otherwise.\nfn goto_file_impl(cx: &mut Context, action: Action) {\n    let (view, doc) = current_ref!(cx.editor);\n    let text = doc.text().clone();\n    let selections = doc.selection(view.id).ranges().to_vec();\n    let rel_path = doc\n        .relative_path()\n        .map(|path| path.parent().unwrap().to_path_buf())\n        .unwrap_or_default();\n    let text = text.slice(..);\n\n    let mut lsp_targets = Vec::new();\n    let mut lsp_targets_seen = HashSet::new();\n    let mut fallback_ranges = Vec::new();\n\n    if doc.document_links.is_empty() {\n        fallback_ranges.extend_from_slice(&selections);\n    } else {\n        for selection in &selections {\n            let mut matched = false;\n            for link in &doc.document_links {\n                if !selection_overlaps_document_link(selection, link) {\n                    continue;\n                }\n                matched = true;\n                if let Some(target) = resolve_document_link_target(cx.editor, link) {\n                    if lsp_targets_seen.insert(target.clone()) {\n                        lsp_targets.push(target);\n                    }\n                }\n            }\n            if !matched {\n                fallback_ranges.push(*selection);\n            }\n        }\n    }\n\n    for target in lsp_targets {\n        open_url(cx, target, action);\n    }\n\n    if fallback_ranges.is_empty() {\n        return;\n    }\n\n    let paths: Vec<_> = if fallback_ranges.len() == 1 && fallback_ranges[0].len() == 1 {\n        let selection = fallback_ranges[0];\n        // Cap the search at roughly 1k bytes around the cursor.\n        let lookaround = 1000;\n        let pos = text.char_to_byte(selection.cursor(text));\n        let search_start = text\n            .line_to_byte(text.byte_to_line(pos))\n            .max(text.floor_char_boundary(pos.saturating_sub(lookaround)));\n        let search_end = text\n            .line_to_byte(text.byte_to_line(pos) + 1)\n            .min(text.ceil_char_boundary(pos + lookaround));\n        let search_range = text.byte_slice(search_start..search_end);\n        // we also allow paths that are next to the cursor (can be ambiguous but\n        // rarely so in practice) so that gf on quoted/braced path works (not sure about this\n        // but apparently that is how gf has worked historically in helix)\n        let path = find_paths(search_range, true)\n            .take_while(|range| search_start + range.start <= pos + 1)\n            .find(|range| pos <= search_start + range.end)\n            .map(|range| Cow::from(search_range.byte_slice(range)));\n        log::debug!(\"goto_file auto-detected path: {path:?}\");\n        let path = path.unwrap_or_else(|| selection.fragment(text));\n        vec![path.into_owned()]\n    } else {\n        // Otherwise use each selection, trimmed.\n        fallback_ranges\n            .iter()\n            .map(|range| range.fragment(text).trim().to_owned())\n            .filter(|sel| !sel.is_empty())\n            .collect()\n    };\n\n    for sel in paths {\n        if let Ok(url) = Url::parse(&sel) {\n            open_url(cx, url, action);\n            continue;\n        }\n\n        let path = path::expand(&sel);\n        let path = &rel_path.join(path);\n        if path.is_dir() {\n            let picker = ui::file_picker(cx.editor, path.into());\n            cx.push_layer(Box::new(overlaid(picker)));\n        } else if let Err(e) = cx.editor.open(path, action) {\n            cx.editor.set_error(format!(\"Open file failed: {:?}\", e));\n        }\n    }\n}\n\n/// Opens the given url. If the URL points to a valid textual file it is open in helix.\n//  Otherwise, the file is open using external program.\nfn open_url(cx: &mut Context, url: Url, action: Action) {\n    let doc = doc!(cx.editor);\n    let rel_path = doc\n        .relative_path()\n        .map(|path| path.parent().unwrap().to_path_buf())\n        .unwrap_or_default();\n\n    if url.scheme() != \"file\" {\n        return cx.jobs.callback(crate::open_external_url_callback(url));\n    }\n\n    let content_type = std::fs::File::open(url.path()).and_then(|file| {\n        // Read up to 1kb to detect the content type\n        let mut read_buffer = Vec::new();\n        let n = file.take(1024).read_to_end(&mut read_buffer)?;\n        Ok(content_inspector::inspect(&read_buffer[..n]))\n    });\n\n    // we attempt to open binary files - files that can't be open in helix - using external\n    // program as well, e.g. pdf files or images\n    match content_type {\n        Ok(content_inspector::ContentType::BINARY) => {\n            cx.jobs.callback(crate::open_external_url_callback(url))\n        }\n        Ok(_) | Err(_) => {\n            let path = &rel_path.join(url.path());\n            if path.is_dir() {\n                let picker = ui::file_picker(cx.editor, path.into());\n                cx.push_layer(Box::new(overlaid(picker)));\n            } else if let Err(e) = cx.editor.open(path, action) {\n                cx.editor.set_error(format!(\"Open file failed: {:?}\", e));\n            }\n        }\n    }\n}\n\nfn extend_word_impl<F>(cx: &mut Context, extend_fn: F)\nwhere\n    F: Fn(RopeSlice, Range, usize) -> Range,\n{\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let word = extend_fn(text, range, count);\n        let pos = word.cursor(text);\n        range.put_cursor(text, pos, true)\n    });\n    doc.set_selection(view.id, selection);\n}\n\nfn extend_next_word_start(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_next_word_start)\n}\n\nfn extend_prev_word_start(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_prev_word_start)\n}\n\nfn extend_next_word_end(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_next_word_end)\n}\n\nfn extend_prev_word_end(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_prev_word_end)\n}\n\nfn extend_next_long_word_start(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_next_long_word_start)\n}\n\nfn extend_prev_long_word_start(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_prev_long_word_start)\n}\n\nfn extend_prev_long_word_end(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_prev_long_word_end)\n}\n\nfn extend_next_long_word_end(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_next_long_word_end)\n}\n\nfn extend_next_sub_word_start(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_next_sub_word_start)\n}\n\nfn extend_prev_sub_word_start(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_prev_sub_word_start)\n}\n\nfn extend_prev_sub_word_end(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_prev_sub_word_end)\n}\n\nfn extend_next_sub_word_end(cx: &mut Context) {\n    extend_word_impl(cx, movement::move_next_sub_word_end)\n}\n\n/// Separate branch to find_char designed only for `<ret>` char.\n//\n// This is necessary because the one document can have different line endings inside. And we\n// cannot predict what character to find when <ret> is pressed. On the current line it can be `lf`\n// but on the next line it can be `crlf`. That's why [`find_char_impl`] cannot be applied here.\nfn find_char_line_ending_motion(\n    editor: &mut Editor,\n    count: usize,\n    direction: Direction,\n    inclusive: bool,\n    extend: bool,\n) {\n    let (view, doc) = current!(editor);\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let cursor_anchor = range.cursor(text);\n        let cursor_head = next_grapheme_boundary(text, cursor_anchor);\n        let cursor_line = range.cursor_line(text);\n\n        let pos = match direction {\n            Direction::Forward => {\n                let line_end = line_end_char_index(&text, cursor_line);\n                let on_edge = if inclusive {\n                    line_end == cursor_anchor\n                } else {\n                    line_end == cursor_head || line_end == cursor_anchor\n                };\n                let line = cursor_line + count - 1 + on_edge as usize;\n                if line >= text.len_lines() - 1 {\n                    return range;\n                }\n                line_end_char_index(&text, line) - !inclusive as usize\n            }\n            Direction::Backward => {\n                if inclusive {\n                    let line = cursor_line as isize - count as isize;\n                    if line < 0 {\n                        return range;\n                    }\n                    line_end_char_index(&text, line as usize)\n                } else {\n                    let on_edge = text.line_to_char(cursor_line) == cursor_anchor;\n                    let line = cursor_line as isize - count as isize + 1 - on_edge as isize;\n                    if line <= 0 {\n                        return range;\n                    }\n                    text.line_to_char(line as usize)\n                }\n            }\n        };\n\n        if extend {\n            range.put_cursor(text, pos, true)\n        } else {\n            Range::point(range.cursor(text)).put_cursor(text, pos, true)\n        }\n    });\n    doc.set_selection(view.id, selection);\n}\n\nfn find_char(cx: &mut Context, direction: Direction, inclusive: bool, extend: bool) {\n    // TODO: count is reset to 1 before next key so we move it into the closure here.\n    // Would be nice to carry over.\n    let count = cx.count();\n\n    // need to wait for next key\n    // TODO: should this be done by grapheme rather than char?  For example,\n    // we can't properly handle the line-ending CRLF case here in terms of char.\n    cx.on_next_key(move |cx, event| {\n        let motion: Motion = if event.code == KeyCode::Enter {\n            Box::new(move |editor: &mut Editor| {\n                find_char_line_ending_motion(editor, count, direction, inclusive, extend);\n            })\n        } else if let Some(ch) = match event.code {\n            KeyCode::Tab => Some('\\t'),\n            KeyCode::Char(ch) => Some(ch),\n            _ => None,\n        } {\n            Box::new(move |editor: &mut Editor| {\n                let (view, doc) = current!(editor);\n                let text = doc.text().slice(..);\n\n                let selection = doc.selection(view.id).clone().transform(|range| {\n                    let cursor_anchor = range.cursor(text);\n                    let cursor_head = next_grapheme_boundary(text, cursor_anchor);\n\n                    // Exclusive search skips the next char after cursor to enable repeated application\n                    let search_start_pos = match (inclusive, direction) {\n                        (true, Direction::Forward) => cursor_head,\n                        (true, Direction::Backward) => cursor_anchor,\n                        (false, Direction::Forward) => cursor_head + 1,\n                        (false, Direction::Backward) => cursor_anchor - 1,\n                    };\n\n                    search::find_nth_char(count, text, ch, search_start_pos, direction)\n                        // Exclusive search should stop on previous character\n                        .map(|pos| match (inclusive, direction) {\n                            (true, Direction::Forward) => pos,\n                            (true, Direction::Backward) => pos,\n                            (false, Direction::Forward) => pos - 1,\n                            (false, Direction::Backward) => pos + 1,\n                        })\n                        .map_or(range, |pos| {\n                            if extend {\n                                range.put_cursor(text, pos, true)\n                            } else {\n                                Range::point(range.cursor(text)).put_cursor(text, pos, true)\n                            }\n                        })\n                });\n\n                doc.set_selection(view.id, selection);\n            })\n        } else {\n            return;\n        };\n\n        cx.editor.apply_motion(motion);\n    })\n}\n\nfn find_till_char(cx: &mut Context) {\n    find_char(cx, Direction::Forward, false, false);\n}\n\nfn find_next_char(cx: &mut Context) {\n    find_char(cx, Direction::Forward, true, false)\n}\n\nfn extend_till_char(cx: &mut Context) {\n    find_char(cx, Direction::Forward, false, true)\n}\n\nfn extend_next_char(cx: &mut Context) {\n    find_char(cx, Direction::Forward, true, true)\n}\n\nfn till_prev_char(cx: &mut Context) {\n    find_char(cx, Direction::Backward, false, false)\n}\n\nfn find_prev_char(cx: &mut Context) {\n    find_char(cx, Direction::Backward, true, false)\n}\n\nfn extend_till_prev_char(cx: &mut Context) {\n    find_char(cx, Direction::Backward, false, true)\n}\n\nfn extend_prev_char(cx: &mut Context) {\n    find_char(cx, Direction::Backward, true, true)\n}\n\nfn repeat_last_motion(cx: &mut Context) {\n    cx.editor.repeat_last_motion(cx.count())\n}\n\nfn replace(cx: &mut Context) {\n    let mut buf = [0u8; 4]; // To hold utf8 encoded char.\n\n    // need to wait for next key\n    cx.on_next_key(move |cx, event| {\n        let (view, doc) = current!(cx.editor);\n        let ch: Option<&str> = match event {\n            KeyEvent {\n                code: KeyCode::Char(ch),\n                ..\n            } => Some(ch.encode_utf8(&mut buf[..])),\n            KeyEvent {\n                code: KeyCode::Enter,\n                ..\n            } => Some(doc.line_ending.as_str()),\n            KeyEvent {\n                code: KeyCode::Tab, ..\n            } => Some(\"\\t\"),\n            _ => None,\n        };\n\n        let selection = doc.selection(view.id);\n\n        if let Some(ch) = ch {\n            let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {\n                if !range.is_empty() {\n                    let text: Tendril = doc\n                        .text()\n                        .slice(range.from()..range.to())\n                        .graphemes()\n                        .map(|_g| ch)\n                        .collect();\n                    (range.from(), range.to(), Some(text))\n                } else {\n                    // No change.\n                    (range.from(), range.to(), None)\n                }\n            });\n\n            doc.apply(&transaction, view.id);\n            exit_select_mode(cx);\n        }\n    })\n}\n\nfn switch_case_impl<F>(cx: &mut Context, change_fn: F)\nwhere\n    F: Fn(RopeSlice) -> Tendril,\n{\n    let (view, doc) = current!(cx.editor);\n    let selection = doc.selection(view.id);\n    let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {\n        let text: Tendril = change_fn(range.slice(doc.text().slice(..)));\n\n        (range.from(), range.to(), Some(text))\n    });\n\n    doc.apply(&transaction, view.id);\n    exit_select_mode(cx);\n}\n\nenum CaseSwitcher {\n    Upper(ToUppercase),\n    Lower(ToLowercase),\n    Keep(Option<char>),\n}\n\nimpl Iterator for CaseSwitcher {\n    type Item = char;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        match self {\n            CaseSwitcher::Upper(upper) => upper.next(),\n            CaseSwitcher::Lower(lower) => lower.next(),\n            CaseSwitcher::Keep(ch) => ch.take(),\n        }\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        match self {\n            CaseSwitcher::Upper(upper) => upper.size_hint(),\n            CaseSwitcher::Lower(lower) => lower.size_hint(),\n            CaseSwitcher::Keep(ch) => {\n                let n = if ch.is_some() { 1 } else { 0 };\n                (n, Some(n))\n            }\n        }\n    }\n}\n\nimpl ExactSizeIterator for CaseSwitcher {}\n\nfn switch_case(cx: &mut Context) {\n    switch_case_impl(cx, |string| {\n        string\n            .chars()\n            .flat_map(|ch| {\n                if ch.is_lowercase() {\n                    CaseSwitcher::Upper(ch.to_uppercase())\n                } else if ch.is_uppercase() {\n                    CaseSwitcher::Lower(ch.to_lowercase())\n                } else {\n                    CaseSwitcher::Keep(Some(ch))\n                }\n            })\n            .collect()\n    });\n}\n\nfn switch_to_uppercase(cx: &mut Context) {\n    switch_case_impl(cx, |string| {\n        string.chunks().map(|chunk| chunk.to_uppercase()).collect()\n    });\n}\n\nfn switch_to_lowercase(cx: &mut Context) {\n    switch_case_impl(cx, |string| {\n        string.chunks().map(|chunk| chunk.to_lowercase()).collect()\n    });\n}\n\npub fn scroll(cx: &mut Context, offset: usize, direction: Direction, sync_cursor: bool) {\n    use Direction::*;\n    let config = cx.editor.config();\n    let (view, doc) = current!(cx.editor);\n    let mut view_offset = doc.view_offset(view.id);\n\n    let range = doc.selection(view.id).primary();\n    let text = doc.text().slice(..);\n\n    let cursor = range.cursor(text);\n    let height = view.inner_height();\n\n    let scrolloff = config.scrolloff.min(height.saturating_sub(1) / 2);\n    let offset = match direction {\n        Forward => offset as isize,\n        Backward => -(offset as isize),\n    };\n\n    let doc_text = doc.text().slice(..);\n    let viewport = view.inner_area(doc);\n    let text_fmt = doc.text_format(viewport.width, None);\n    (view_offset.anchor, view_offset.vertical_offset) = char_idx_at_visual_offset(\n        doc_text,\n        view_offset.anchor,\n        view_offset.vertical_offset as isize + offset,\n        0,\n        &text_fmt,\n        // &annotations,\n        &view.text_annotations(&*doc, None),\n    );\n    doc.set_view_offset(view.id, view_offset);\n\n    let doc_text = doc.text().slice(..);\n    let mut annotations = view.text_annotations(&*doc, None);\n\n    if sync_cursor {\n        let movement = match cx.editor.mode {\n            Mode::Select => Movement::Extend,\n            _ => Movement::Move,\n        };\n        // TODO: When inline diagnostics gets merged- 1. move_vertically_visual removes\n        // line annotations/diagnostics so the cursor may jump further than the view.\n        // 2. If the cursor lands on a complete line of virtual text, the cursor will\n        // jump a different distance than the view.\n        let selection = doc.selection(view.id).clone().transform(|range| {\n            move_vertically_visual(\n                doc_text,\n                range,\n                direction,\n                offset.unsigned_abs(),\n                movement,\n                &text_fmt,\n                &mut annotations,\n            )\n        });\n        drop(annotations);\n        doc.set_selection(view.id, selection);\n        return;\n    }\n\n    let view_offset = doc.view_offset(view.id);\n\n    let mut head;\n    match direction {\n        Forward => {\n            let off;\n            (head, off) = char_idx_at_visual_offset(\n                doc_text,\n                view_offset.anchor,\n                (view_offset.vertical_offset + scrolloff) as isize,\n                0,\n                &text_fmt,\n                &annotations,\n            );\n            head += (off != 0) as usize;\n            if head <= cursor {\n                return;\n            }\n        }\n        Backward => {\n            head = char_idx_at_visual_offset(\n                doc_text,\n                view_offset.anchor,\n                (view_offset.vertical_offset + height - scrolloff - 1) as isize,\n                0,\n                &text_fmt,\n                &annotations,\n            )\n            .0;\n            if head >= cursor {\n                return;\n            }\n        }\n    }\n\n    let anchor = if cx.editor.mode == Mode::Select {\n        range.anchor\n    } else {\n        head\n    };\n\n    // replace primary selection with an empty selection at cursor pos\n    let prim_sel = Range::new(anchor, head);\n    let mut sel = doc.selection(view.id).clone();\n    let idx = sel.primary_index();\n    sel = sel.replace(idx, prim_sel);\n    drop(annotations);\n    doc.set_selection(view.id, sel);\n}\n\nfn page_up(cx: &mut Context) {\n    let view = view!(cx.editor);\n    let offset = view.inner_height();\n    scroll(cx, offset, Direction::Backward, false);\n}\n\nfn page_down(cx: &mut Context) {\n    let view = view!(cx.editor);\n    let offset = view.inner_height();\n    scroll(cx, offset, Direction::Forward, false);\n}\n\nfn half_page_up(cx: &mut Context) {\n    let view = view!(cx.editor);\n    let offset = view.inner_height() / 2;\n    scroll(cx, offset, Direction::Backward, false);\n}\n\nfn half_page_down(cx: &mut Context) {\n    let view = view!(cx.editor);\n    let offset = view.inner_height() / 2;\n    scroll(cx, offset, Direction::Forward, false);\n}\n\nfn page_cursor_up(cx: &mut Context) {\n    let view = view!(cx.editor);\n    let offset = view.inner_height();\n    scroll(cx, offset, Direction::Backward, true);\n}\n\nfn page_cursor_down(cx: &mut Context) {\n    let view = view!(cx.editor);\n    let offset = view.inner_height();\n    scroll(cx, offset, Direction::Forward, true);\n}\n\nfn page_cursor_half_up(cx: &mut Context) {\n    let view = view!(cx.editor);\n    let offset = view.inner_height() / 2;\n    scroll(cx, offset, Direction::Backward, true);\n}\n\nfn page_cursor_half_down(cx: &mut Context) {\n    let view = view!(cx.editor);\n    let offset = view.inner_height() / 2;\n    scroll(cx, offset, Direction::Forward, true);\n}\n\n#[allow(deprecated)]\n// currently uses the deprecated `visual_coords_at_pos`/`pos_at_visual_coords` functions\n// as this function ignores softwrapping (and virtual text) and instead only cares\n// about \"text visual position\"\n//\n// TODO: implement a variant of that uses visual lines and respects virtual text\nfn copy_selection_on_line(cx: &mut Context, direction: Direction) {\n    use helix_core::{pos_at_visual_coords, visual_coords_at_pos};\n\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n    let selection = doc.selection(view.id);\n    let mut ranges = SmallVec::with_capacity(selection.ranges().len() * (count + 1));\n    ranges.extend_from_slice(selection.ranges());\n    let mut primary_index = 0;\n    for range in selection.iter() {\n        let is_primary = *range == selection.primary();\n\n        // The range is always head exclusive\n        let (head, anchor) = if range.anchor < range.head {\n            (range.head - 1, range.anchor)\n        } else {\n            (range.head, range.anchor.saturating_sub(1))\n        };\n\n        let tab_width = doc.tab_width();\n\n        let head_pos = visual_coords_at_pos(text, head, tab_width);\n        let anchor_pos = visual_coords_at_pos(text, anchor, tab_width);\n\n        let height = std::cmp::max(head_pos.row, anchor_pos.row)\n            - std::cmp::min(head_pos.row, anchor_pos.row)\n            + 1;\n\n        if is_primary {\n            primary_index = ranges.len();\n        }\n        ranges.push(*range);\n\n        let mut sels = 0;\n        let mut i = 0;\n        while sels < count {\n            let offset = (i + 1) * height;\n\n            let anchor_row = match direction {\n                Direction::Forward => anchor_pos.row + offset,\n                Direction::Backward => anchor_pos.row.saturating_sub(offset),\n            };\n\n            let head_row = match direction {\n                Direction::Forward => head_pos.row + offset,\n                Direction::Backward => head_pos.row.saturating_sub(offset),\n            };\n\n            if anchor_row >= text.len_lines() || head_row >= text.len_lines() {\n                break;\n            }\n\n            let anchor =\n                pos_at_visual_coords(text, Position::new(anchor_row, anchor_pos.col), tab_width);\n            let head = pos_at_visual_coords(text, Position::new(head_row, head_pos.col), tab_width);\n\n            // skip lines that are too short\n            if visual_coords_at_pos(text, anchor, tab_width).col == anchor_pos.col\n                && visual_coords_at_pos(text, head, tab_width).col == head_pos.col\n            {\n                if is_primary {\n                    primary_index = ranges.len();\n                }\n                // This is Range::new(anchor, head), but it will place the cursor on the correct column\n                ranges.push(Range::point(anchor).put_cursor(text, head, true));\n                sels += 1;\n            }\n\n            if anchor_row == 0 && head_row == 0 {\n                break;\n            }\n\n            i += 1;\n        }\n    }\n\n    let selection = Selection::new(ranges, primary_index);\n    doc.set_selection(view.id, selection);\n}\n\nfn copy_selection_on_prev_line(cx: &mut Context) {\n    copy_selection_on_line(cx, Direction::Backward)\n}\n\nfn copy_selection_on_next_line(cx: &mut Context) {\n    copy_selection_on_line(cx, Direction::Forward)\n}\n\nfn select_all(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n\n    let end = doc.text().len_chars();\n    doc.set_selection(view.id, Selection::single(0, end))\n}\n\nfn select_regex(cx: &mut Context) {\n    let reg = cx.register.unwrap_or('/');\n    ui::regex_prompt(\n        cx,\n        \"select:\".into(),\n        Some(reg),\n        ui::completers::none,\n        move |cx, regex, event| {\n            let (view, doc) = current!(cx.editor);\n            if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {\n                return;\n            }\n            let text = doc.text().slice(..);\n            if let Some(selection) =\n                selection::select_on_matches(text, doc.selection(view.id), &regex)\n            {\n                doc.set_selection(view.id, selection);\n            } else if event == PromptEvent::Validate {\n                cx.editor.set_error(\"nothing selected\");\n            }\n        },\n    );\n}\n\nfn split_selection(cx: &mut Context) {\n    let reg = cx.register.unwrap_or('/');\n    ui::regex_prompt(\n        cx,\n        \"split:\".into(),\n        Some(reg),\n        ui::completers::none,\n        move |cx, regex, event| {\n            let (view, doc) = current!(cx.editor);\n            if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {\n                return;\n            }\n            let text = doc.text().slice(..);\n            let selection = selection::split_on_matches(text, doc.selection(view.id), &regex);\n            doc.set_selection(view.id, selection);\n        },\n    );\n}\n\nfn split_selection_on_newline(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n    let selection = selection::split_on_newline(text, doc.selection(view.id));\n    doc.set_selection(view.id, selection);\n}\n\nfn merge_selections(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let selection = doc.selection(view.id).clone().merge_ranges();\n    doc.set_selection(view.id, selection);\n}\n\nfn merge_consecutive_selections(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let selection = doc.selection(view.id).clone().merge_consecutive_ranges();\n    doc.set_selection(view.id, selection);\n}\n\n#[allow(clippy::too_many_arguments)]\nfn search_impl(\n    editor: &mut Editor,\n    regex: &rope::Regex,\n    movement: Movement,\n    direction: Direction,\n    scrolloff: usize,\n    wrap_around: bool,\n    show_warnings: bool,\n) {\n    let (view, doc) = current!(editor);\n    let text = doc.text().slice(..);\n    let selection = doc.selection(view.id);\n\n    // Get the right side of the primary block cursor for forward search, or the\n    // grapheme before the start of the selection for reverse search.\n    let start = match direction {\n        Direction::Forward => text.char_to_byte(graphemes::ensure_grapheme_boundary_next(\n            text,\n            selection.primary().to(),\n        )),\n        Direction::Backward => text.char_to_byte(graphemes::ensure_grapheme_boundary_prev(\n            text,\n            selection.primary().from(),\n        )),\n    };\n\n    // A regex::Match returns byte-positions in the str. In the case where we\n    // do a reverse search and wraparound to the end, we don't need to search\n    // the text before the current cursor position for matches, but by slicing\n    // it out, we need to add it back to the position of the selection.\n    let doc = doc!(editor).text().slice(..);\n\n    // use find_at to find the next match after the cursor, loop around the end\n    // Careful, `Regex` uses `bytes` as offsets, not character indices!\n    let mut mat = match direction {\n        Direction::Forward => regex.find(doc.regex_input_at_bytes(start..)),\n        Direction::Backward => regex.find_iter(doc.regex_input_at_bytes(..start)).last(),\n    };\n\n    if mat.is_none() {\n        if wrap_around {\n            mat = match direction {\n                Direction::Forward => regex.find(doc.regex_input()),\n                Direction::Backward => regex.find_iter(doc.regex_input_at_bytes(start..)).last(),\n            };\n        }\n        if show_warnings {\n            if wrap_around && mat.is_some() {\n                editor.set_status(\"Wrapped around document\");\n            } else {\n                editor.set_error(\"No more matches\");\n            }\n        }\n    }\n\n    let (view, doc) = current!(editor);\n    let text = doc.text().slice(..);\n    let selection = doc.selection(view.id);\n\n    if let Some(mat) = mat {\n        let start = text.byte_to_char(mat.start());\n        let end = text.byte_to_char(mat.end());\n\n        if end == 0 {\n            // skip empty matches that don't make sense\n            return;\n        }\n\n        // Determine range direction based on the primary range\n        let primary = selection.primary();\n        let range = Range::new(start, end).with_direction(primary.direction());\n\n        let selection = match movement {\n            Movement::Extend => selection.clone().push(range),\n            Movement::Move => selection.clone().replace(selection.primary_index(), range),\n        };\n\n        doc.set_selection(view.id, selection);\n        view.ensure_cursor_in_view_center(doc, scrolloff);\n    };\n}\n\nfn search_completions(cx: &mut Context, reg: Option<char>) -> Vec<String> {\n    let mut items = reg\n        .and_then(|reg| cx.editor.registers.read(reg, cx.editor))\n        .map_or(Vec::new(), |reg| reg.take(200).collect());\n    items.sort_unstable();\n    items.dedup();\n    items.into_iter().map(|value| value.to_string()).collect()\n}\n\nfn search(cx: &mut Context) {\n    searcher(cx, Direction::Forward)\n}\n\nfn rsearch(cx: &mut Context) {\n    searcher(cx, Direction::Backward)\n}\n\nfn searcher(cx: &mut Context, direction: Direction) {\n    let reg = cx.register.unwrap_or('/');\n    let config = cx.editor.config();\n    let scrolloff = config.scrolloff;\n    let wrap_around = config.search.wrap_around;\n    let movement = if cx.editor.mode() == Mode::Select {\n        Movement::Extend\n    } else {\n        Movement::Move\n    };\n\n    // TODO: could probably share with select_on_matches?\n    let completions = search_completions(cx, Some(reg));\n\n    ui::regex_prompt(\n        cx,\n        \"search:\".into(),\n        Some(reg),\n        move |_editor: &Editor, input: &str| {\n            completions\n                .iter()\n                .filter(|comp| comp.starts_with(input))\n                .map(|comp| (0.., comp.clone().into()))\n                .collect()\n        },\n        move |cx, regex, event| {\n            if event == PromptEvent::Validate {\n                cx.editor.registers.last_search_register = reg;\n            } else if event != PromptEvent::Update {\n                return;\n            }\n            search_impl(\n                cx.editor,\n                &regex,\n                movement,\n                direction,\n                scrolloff,\n                wrap_around,\n                false,\n            );\n        },\n    );\n}\n\nfn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Direction) {\n    let count = cx.count();\n    let register = cx\n        .register\n        .unwrap_or(cx.editor.registers.last_search_register);\n    let config = cx.editor.config();\n    let scrolloff = config.scrolloff;\n    if let Some(query) = cx.editor.registers.first(register, cx.editor) {\n        let search_config = &config.search;\n        let case_insensitive = if search_config.smart_case {\n            !query.chars().any(char::is_uppercase)\n        } else {\n            false\n        };\n        let wrap_around = search_config.wrap_around;\n        if let Ok(regex) = rope::RegexBuilder::new()\n            .syntax(\n                rope::Config::new()\n                    .case_insensitive(case_insensitive)\n                    .multi_line(true),\n            )\n            .build(&query)\n        {\n            for _ in 0..count {\n                search_impl(\n                    cx.editor,\n                    &regex,\n                    movement,\n                    direction,\n                    scrolloff,\n                    wrap_around,\n                    true,\n                );\n            }\n        } else {\n            let error = format!(\"Invalid regex: {}\", query);\n            cx.editor.set_error(error);\n        }\n    }\n}\n\nfn search_next(cx: &mut Context) {\n    search_next_or_prev_impl(cx, Movement::Move, Direction::Forward);\n}\n\nfn search_prev(cx: &mut Context) {\n    search_next_or_prev_impl(cx, Movement::Move, Direction::Backward);\n}\nfn extend_search_next(cx: &mut Context) {\n    search_next_or_prev_impl(cx, Movement::Extend, Direction::Forward);\n}\n\nfn extend_search_prev(cx: &mut Context) {\n    search_next_or_prev_impl(cx, Movement::Extend, Direction::Backward);\n}\n\nfn search_selection(cx: &mut Context) {\n    search_selection_impl(cx, false)\n}\n\nfn search_selection_detect_word_boundaries(cx: &mut Context) {\n    search_selection_impl(cx, true)\n}\n\nfn search_selection_impl(cx: &mut Context, detect_word_boundaries: bool) {\n    fn is_at_word_start(text: RopeSlice, index: usize) -> bool {\n        // This can happen when the cursor is at the last character in\n        // the document +1 (ge + j), in this case text.char(index) will panic as\n        // it will index out of bounds. See https://github.com/helix-editor/helix/issues/12609\n        if index == text.len_chars() {\n            return false;\n        }\n        let ch = text.char(index);\n        if index == 0 {\n            return char_is_word(ch);\n        }\n        let prev_ch = text.char(index - 1);\n\n        !char_is_word(prev_ch) && char_is_word(ch)\n    }\n\n    fn is_at_word_end(text: RopeSlice, index: usize) -> bool {\n        if index == 0 || index == text.len_chars() {\n            return false;\n        }\n        let ch = text.char(index);\n        let prev_ch = text.char(index - 1);\n\n        char_is_word(prev_ch) && !char_is_word(ch)\n    }\n\n    let register = cx.register.unwrap_or('/');\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n\n    let regex = doc\n        .selection(view.id)\n        .iter()\n        .map(|selection| {\n            let add_boundary_prefix =\n                detect_word_boundaries && is_at_word_start(text, selection.from());\n            let add_boundary_suffix =\n                detect_word_boundaries && is_at_word_end(text, selection.to());\n\n            let prefix = if add_boundary_prefix { \"\\\\b\" } else { \"\" };\n            let suffix = if add_boundary_suffix { \"\\\\b\" } else { \"\" };\n\n            let word = regex::escape(&selection.fragment(text));\n            format!(\"{}{}{}\", prefix, word, suffix)\n        })\n        .collect::<HashSet<_>>() // Collect into hashset to deduplicate identical regexes\n        .into_iter()\n        .collect::<Vec<_>>()\n        .join(\"|\");\n\n    let msg = format!(\"register '{}' set to '{}'\", register, &regex);\n    match cx.editor.registers.push(register, regex) {\n        Ok(_) => {\n            cx.editor.registers.last_search_register = register;\n            cx.editor.set_status(msg)\n        }\n        Err(err) => cx.editor.set_error(err.to_string()),\n    }\n}\n\nfn make_search_word_bounded(cx: &mut Context) {\n    // Defaults to the active search register instead `/` to be more ergonomic assuming most people\n    // would use this command following `search_selection`. This avoids selecting the register\n    // twice.\n    let register = cx\n        .register\n        .unwrap_or(cx.editor.registers.last_search_register);\n    let regex = match cx.editor.registers.first(register, cx.editor) {\n        Some(regex) => regex,\n        None => return,\n    };\n    let start_anchored = regex.starts_with(\"\\\\b\");\n    let end_anchored = regex.ends_with(\"\\\\b\");\n\n    if start_anchored && end_anchored {\n        return;\n    }\n\n    let mut new_regex = String::with_capacity(\n        regex.len() + if start_anchored { 0 } else { 2 } + if end_anchored { 0 } else { 2 },\n    );\n\n    if !start_anchored {\n        new_regex.push_str(\"\\\\b\");\n    }\n    new_regex.push_str(&regex);\n    if !end_anchored {\n        new_regex.push_str(\"\\\\b\");\n    }\n\n    let msg = format!(\"register '{}' set to '{}'\", register, &new_regex);\n    match cx.editor.registers.push(register, new_regex) {\n        Ok(_) => {\n            cx.editor.registers.last_search_register = register;\n            cx.editor.set_status(msg)\n        }\n        Err(err) => cx.editor.set_error(err.to_string()),\n    }\n}\n\nfn global_search(cx: &mut Context) {\n    #[derive(Debug)]\n    struct FileResult {\n        path: PathBuf,\n        /// 0 indexed line start\n        line_start: usize,\n        /// 0 indexed line end\n        line_end: usize,\n    }\n\n    impl FileResult {\n        fn new(path: &Path, line_start: usize, line_end: usize) -> Self {\n            Self {\n                path: path.to_path_buf(),\n                line_start,\n                line_end,\n            }\n        }\n    }\n\n    struct GlobalSearchConfig {\n        smart_case: bool,\n        file_picker_config: helix_view::editor::FilePickerConfig,\n        directory_style: Style,\n        number_style: Style,\n        colon_style: Style,\n    }\n\n    let config = cx.editor.config();\n    let config = GlobalSearchConfig {\n        smart_case: config.search.smart_case,\n        file_picker_config: config.file_picker.clone(),\n        directory_style: cx.editor.theme.get(\"ui.text.directory\"),\n        number_style: cx.editor.theme.get(\"constant.numeric.integer\"),\n        colon_style: cx.editor.theme.get(\"punctuation\"),\n    };\n\n    let columns = [\n        PickerColumn::new(\"path\", |item: &FileResult, config: &GlobalSearchConfig| {\n            let path = helix_stdx::path::get_relative_path(&item.path);\n\n            let directories = path\n                .parent()\n                .filter(|p| !p.as_os_str().is_empty())\n                .map(|p| format!(\"{}{}\", p.display(), std::path::MAIN_SEPARATOR))\n                .unwrap_or_default();\n\n            let filename = item\n                .path\n                .file_name()\n                .expect(\"global search paths are normalized (can't end in `..`)\")\n                .to_string_lossy();\n\n            Cell::from(Spans::from(vec![\n                Span::styled(directories, config.directory_style),\n                Span::raw(filename),\n                Span::styled(\":\", config.colon_style),\n                Span::styled((item.line_start + 1).to_string(), config.number_style),\n            ]))\n        }),\n        PickerColumn::hidden(\"contents\"),\n    ];\n\n    let get_files = |query: &str,\n                     editor: &mut Editor,\n                     config: std::sync::Arc<GlobalSearchConfig>,\n                     injector: &ui::picker::Injector<_, _>| {\n        if query.is_empty() {\n            return async { Ok(()) }.boxed();\n        }\n\n        let search_root = helix_stdx::env::current_working_dir();\n        if !search_root.exists() {\n            return async { Err(anyhow::anyhow!(\"Current working directory does not exist\")) }\n                .boxed();\n        }\n\n        let documents: Vec<_> = editor\n            .documents()\n            .map(|doc| (doc.path().cloned(), doc.text().to_owned()))\n            .collect();\n\n        let matcher = match RegexMatcherBuilder::new()\n            .case_smart(config.smart_case)\n            .multi_line(true)\n            .build(query)\n        {\n            Ok(matcher) => {\n                // Clear any \"Failed to compile regex\" errors out of the statusline.\n                editor.clear_status();\n                matcher\n            }\n            Err(err) => {\n                log::info!(\"Failed to compile search pattern in global search: {}\", err);\n                return async { Err(anyhow::anyhow!(\"Failed to compile regex\")) }.boxed();\n            }\n        };\n\n        let dedup_symlinks = config.file_picker_config.deduplicate_links;\n        let absolute_root = search_root\n            .canonicalize()\n            .unwrap_or_else(|_| search_root.clone());\n\n        let injector = injector.clone();\n        async move {\n            let searcher = SearcherBuilder::new()\n                .binary_detection(BinaryDetection::quit(b'\\x00'))\n                .multi_line(true)\n                .build();\n            WalkBuilder::new(search_root)\n                .hidden(config.file_picker_config.hidden)\n                .parents(config.file_picker_config.parents)\n                .ignore(config.file_picker_config.ignore)\n                .follow_links(config.file_picker_config.follow_symlinks)\n                .git_ignore(config.file_picker_config.git_ignore)\n                .git_global(config.file_picker_config.git_global)\n                .git_exclude(config.file_picker_config.git_exclude)\n                .max_depth(config.file_picker_config.max_depth)\n                .filter_entry(move |entry| {\n                    filter_picker_entry(entry, &absolute_root, dedup_symlinks)\n                })\n                .add_custom_ignore_filename(helix_loader::config_dir().join(\"ignore\"))\n                .add_custom_ignore_filename(\".helix/ignore\")\n                .build_parallel()\n                .run(|| {\n                    let mut searcher = searcher.clone();\n                    let matcher = matcher.clone();\n                    let injector = injector.clone();\n                    let documents = &documents;\n                    Box::new(move |entry: Result<DirEntry, ignore::Error>| -> WalkState {\n                        let entry = match entry {\n                            Ok(entry) => entry,\n                            Err(_) => return WalkState::Continue,\n                        };\n\n                        if !entry.path().is_file() {\n                            return WalkState::Continue;\n                        }\n\n                        let mut stop = false;\n                        let sink = sinks::UTF8(|line_start, line_content| {\n                            let line_start = line_start as usize - 1;\n                            let line_end = line_start + line_content.lines().count() - 1;\n                            stop = injector\n                                .push(FileResult::new(entry.path(), line_start, line_end))\n                                .is_err();\n\n                            Ok(!stop)\n                        });\n                        let doc = documents.iter().find(|&(doc_path, _)| {\n                            doc_path\n                                .as_ref()\n                                .is_some_and(|doc_path| doc_path == entry.path())\n                        });\n\n                        let result = if let Some((_, doc)) = doc {\n                            // there is already a buffer for this file\n                            // search the buffer instead of the file because it's faster\n                            // and captures new edits without requiring a save\n                            if searcher.multi_line_with_matcher(&matcher) {\n                                // in this case a continuous buffer is required\n                                // convert the rope to a string\n                                let text = doc.to_string();\n                                searcher.search_slice(&matcher, text.as_bytes(), sink)\n                            } else {\n                                searcher.search_reader(\n                                    &matcher,\n                                    RopeReader::new(doc.slice(..)),\n                                    sink,\n                                )\n                            }\n                        } else {\n                            searcher.search_path(&matcher, entry.path(), sink)\n                        };\n\n                        if let Err(err) = result {\n                            log::error!(\"Global search error: {}, {}\", entry.path().display(), err);\n                        }\n                        if stop {\n                            WalkState::Quit\n                        } else {\n                            WalkState::Continue\n                        }\n                    })\n                });\n            Ok(())\n        }\n        .boxed()\n    };\n\n    let reg = cx.register.unwrap_or('/');\n    cx.editor.registers.last_search_register = reg;\n\n    let picker = Picker::new(\n        columns,\n        1, // contents\n        [],\n        config,\n        move |cx,\n              FileResult {\n                  path,\n                  line_start,\n                  line_end,\n                  ..\n              },\n              action| {\n            let doc = match cx.editor.open(path, action) {\n                Ok(id) => doc_mut!(cx.editor, &id),\n                Err(e) => {\n                    cx.editor\n                        .set_error(format!(\"Failed to open file '{}': {}\", path.display(), e));\n                    return;\n                }\n            };\n\n            let line_start = *line_start;\n            let line_end = *line_end;\n            let view = view_mut!(cx.editor);\n            let text = doc.text();\n            if line_start >= text.len_lines() {\n                cx.editor.set_error(\n                    \"The line you jumped to does not exist anymore because the file has changed.\",\n                );\n                return;\n            }\n            let start = text.line_to_char(line_start);\n            let end = text.line_to_char((line_end + 1).min(text.len_lines()));\n\n            doc.set_selection(view.id, Selection::single(start, end));\n            if action.align_view(view, doc.id()) {\n                align_view(doc, view, Align::Center);\n            }\n        },\n    )\n    .with_preview(\n        |_editor,\n         FileResult {\n             path,\n             line_start,\n             line_end,\n             ..\n         }| { Some((path.as_path().into(), Some((*line_start, *line_end)))) },\n    )\n    .with_history_register(Some(reg))\n    .with_dynamic_query(get_files, Some(275));\n\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\nenum Extend {\n    Above,\n    Below,\n}\n\nfn extend_line(cx: &mut Context) {\n    let (view, doc) = current_ref!(cx.editor);\n    let extend = match doc.selection(view.id).primary().direction() {\n        Direction::Forward => Extend::Below,\n        Direction::Backward => Extend::Above,\n    };\n    extend_line_impl(cx, extend);\n}\n\nfn extend_line_below(cx: &mut Context) {\n    extend_line_impl(cx, Extend::Below);\n}\n\nfn extend_line_above(cx: &mut Context) {\n    extend_line_impl(cx, Extend::Above);\n}\nfn extend_line_impl(cx: &mut Context, extend: Extend) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n\n    let text = doc.text();\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let (start_line, end_line) = range.line_range(text.slice(..));\n\n        let start = text.line_to_char(start_line);\n        let end = text.line_to_char(\n            (end_line + 1) // newline of end_line\n                .min(text.len_lines()),\n        );\n\n        // extend to previous/next line if current line is selected\n        let (anchor, head) = if range.from() == start && range.to() == end {\n            match extend {\n                Extend::Above => (end, text.line_to_char(start_line.saturating_sub(count))),\n                Extend::Below => (\n                    start,\n                    text.line_to_char((end_line + count + 1).min(text.len_lines())),\n                ),\n            }\n        } else {\n            match extend {\n                Extend::Above => (end, text.line_to_char(start_line.saturating_sub(count - 1))),\n                Extend::Below => (\n                    start,\n                    text.line_to_char((end_line + count).min(text.len_lines())),\n                ),\n            }\n        };\n\n        Range::new(anchor, head)\n    });\n\n    doc.set_selection(view.id, selection);\n}\nfn select_line_below(cx: &mut Context) {\n    select_line_impl(cx, Extend::Below);\n}\nfn select_line_above(cx: &mut Context) {\n    select_line_impl(cx, Extend::Above);\n}\nfn select_line_impl(cx: &mut Context, extend: Extend) {\n    let mut count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text();\n    let saturating_add = |a: usize, b: usize| (a + b).min(text.len_lines());\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let (start_line, end_line) = range.line_range(text.slice(..));\n        let start = text.line_to_char(start_line);\n        let end = text.line_to_char(saturating_add(end_line, 1));\n        let direction = range.direction();\n\n        // Extending to line bounds is counted as one step\n        if range.from() != start || range.to() != end {\n            count = count.saturating_sub(1)\n        }\n        let (anchor_line, head_line) = match (&extend, direction) {\n            (Extend::Above, Direction::Forward) => (start_line, end_line.saturating_sub(count)),\n            (Extend::Above, Direction::Backward) => (end_line, start_line.saturating_sub(count)),\n            (Extend::Below, Direction::Forward) => (start_line, saturating_add(end_line, count)),\n            (Extend::Below, Direction::Backward) => (end_line, saturating_add(start_line, count)),\n        };\n        let (anchor, head) = match anchor_line.cmp(&head_line) {\n            Ordering::Less => (\n                text.line_to_char(anchor_line),\n                text.line_to_char(saturating_add(head_line, 1)),\n            ),\n            Ordering::Equal => match extend {\n                Extend::Above => (\n                    text.line_to_char(saturating_add(anchor_line, 1)),\n                    text.line_to_char(head_line),\n                ),\n                Extend::Below => (\n                    text.line_to_char(head_line),\n                    text.line_to_char(saturating_add(anchor_line, 1)),\n                ),\n            },\n\n            Ordering::Greater => (\n                text.line_to_char(saturating_add(anchor_line, 1)),\n                text.line_to_char(head_line),\n            ),\n        };\n        Range::new(anchor, head)\n    });\n\n    doc.set_selection(view.id, selection);\n}\n\nfn extend_to_line_bounds(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n\n    doc.set_selection(\n        view.id,\n        doc.selection(view.id).clone().transform(|range| {\n            let text = doc.text();\n\n            let (start_line, end_line) = range.line_range(text.slice(..));\n            let start = text.line_to_char(start_line);\n            let end = text.line_to_char((end_line + 1).min(text.len_lines()));\n\n            Range::new(start, end).with_direction(range.direction())\n        }),\n    );\n}\n\nfn shrink_to_line_bounds(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n\n    doc.set_selection(\n        view.id,\n        doc.selection(view.id).clone().transform(|range| {\n            let text = doc.text();\n\n            let (start_line, end_line) = range.line_range(text.slice(..));\n\n            // Do nothing if the selection is within one line to prevent\n            // conditional logic for the behavior of this command\n            if start_line == end_line {\n                return range;\n            }\n\n            let mut start = text.line_to_char(start_line);\n\n            // line_to_char gives us the start position of the line, so\n            // we need to get the start position of the next line. In\n            // the editor, this will correspond to the cursor being on\n            // the EOL whitespace character, which is what we want.\n            let mut end = text.line_to_char((end_line + 1).min(text.len_lines()));\n\n            if start != range.from() {\n                start = text.line_to_char((start_line + 1).min(text.len_lines()));\n            }\n\n            if end != range.to() {\n                end = text.line_to_char(end_line);\n            }\n\n            Range::new(start, end).with_direction(range.direction())\n        }),\n    );\n}\n\nenum Operation {\n    Delete,\n    Change,\n}\n\nfn selection_is_linewise(selection: &Selection, text: &Rope) -> bool {\n    selection.ranges().iter().all(|range| {\n        let text = text.slice(..);\n        if range.slice(text).len_lines() < 2 {\n            return false;\n        }\n        // If the start of the selection is at the start of a line and the end at the end of a line.\n        let (start_line, end_line) = range.line_range(text);\n        let start = text.line_to_char(start_line);\n        let end = text.line_to_char((end_line + 1).min(text.len_lines()));\n        start == range.from() && end == range.to()\n    })\n}\n\nenum YankAction {\n    Yank,\n    NoYank,\n}\n\nfn delete_selection_impl(cx: &mut Context, op: Operation, yank: YankAction) {\n    let (view, doc) = current!(cx.editor);\n\n    let selection = doc.selection(view.id);\n    let only_whole_lines = selection_is_linewise(selection, doc.text());\n\n    if cx.register != Some('_') && matches!(yank, YankAction::Yank) {\n        // yank the selection\n        let text = doc.text().slice(..);\n        let values: Vec<String> = selection.fragments(text).map(Cow::into_owned).collect();\n        let reg_name = cx\n            .register\n            .unwrap_or_else(|| cx.editor.config.load().default_yank_register);\n        if let Err(err) = cx.editor.registers.write(reg_name, values) {\n            cx.editor.set_error(err.to_string());\n            return;\n        }\n    }\n\n    // delete the selection\n    let transaction =\n        Transaction::delete_by_selection(doc.text(), selection, |range| (range.from(), range.to()));\n    doc.apply(&transaction, view.id);\n\n    match op {\n        Operation::Delete => {\n            // exit select mode, if currently in select mode\n            exit_select_mode(cx);\n        }\n        Operation::Change => {\n            if only_whole_lines {\n                open(cx, Open::Above, CommentContinuation::Disabled);\n            } else {\n                enter_insert_mode(cx);\n            }\n        }\n    }\n}\n\n#[inline]\nfn delete_by_selection_insert_mode(\n    cx: &mut Context,\n    mut f: impl FnMut(RopeSlice, &Range) -> Deletion,\n    direction: Direction,\n) {\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n    let mut selection = SmallVec::new();\n    let mut insert_newline = false;\n    let text_len = text.len_chars();\n    let mut transaction =\n        Transaction::delete_by_selection(doc.text(), doc.selection(view.id), |range| {\n            let (start, end) = f(text, range);\n            if direction == Direction::Forward {\n                let mut range = *range;\n                if range.head > range.anchor {\n                    insert_newline |= end == text_len;\n                    // move the cursor to the right so that the selection\n                    // doesn't shrink when deleting forward (so the text appears to\n                    // move to  left)\n                    // += 1 is enough here as the range is normalized to grapheme boundaries\n                    // later anyway\n                    range.head += 1;\n                }\n                selection.push(range);\n            }\n            (start, end)\n        });\n\n    // in case we delete the last character and the cursor would be moved to the EOF char\n    // insert a newline, just like when entering append mode\n    if insert_newline {\n        transaction = transaction.insert_at_eof(doc.line_ending.as_str().into());\n    }\n\n    if direction == Direction::Forward {\n        doc.set_selection(\n            view.id,\n            Selection::new(selection, doc.selection(view.id).primary_index()),\n        );\n    }\n    doc.apply(&transaction, view.id);\n}\n\nfn delete_selection(cx: &mut Context) {\n    delete_selection_impl(cx, Operation::Delete, YankAction::Yank);\n}\n\nfn delete_selection_noyank(cx: &mut Context) {\n    delete_selection_impl(cx, Operation::Delete, YankAction::NoYank);\n}\n\nfn change_selection(cx: &mut Context) {\n    delete_selection_impl(cx, Operation::Change, YankAction::Yank);\n}\n\nfn change_selection_noyank(cx: &mut Context) {\n    delete_selection_impl(cx, Operation::Change, YankAction::NoYank);\n}\n\nfn collapse_selection(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let pos = range.cursor(text);\n        Range::new(pos, pos)\n    });\n    doc.set_selection(view.id, selection);\n}\n\nfn flip_selections(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n\n    let selection = doc\n        .selection(view.id)\n        .clone()\n        .transform(|range| range.flip());\n    doc.set_selection(view.id, selection);\n}\n\nfn ensure_selections_forward(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n\n    let selection = doc\n        .selection(view.id)\n        .clone()\n        .transform(|r| r.with_direction(Direction::Forward));\n\n    doc.set_selection(view.id, selection);\n}\n\nfn enter_insert_mode(cx: &mut Context) {\n    cx.editor.mode = Mode::Insert;\n}\n\n// inserts at the start of each selection\nfn insert_mode(cx: &mut Context) {\n    enter_insert_mode(cx);\n    let (view, doc) = current!(cx.editor);\n\n    log::trace!(\n        \"entering insert mode with sel: {:?}, text: {:?}\",\n        doc.selection(view.id),\n        doc.text().to_string()\n    );\n\n    let selection = doc\n        .selection(view.id)\n        .clone()\n        .transform(|range| Range::new(range.to(), range.from()));\n\n    doc.set_selection(view.id, selection);\n}\n\n// inserts at the end of each selection\nfn append_mode(cx: &mut Context) {\n    enter_insert_mode(cx);\n    let (view, doc) = current!(cx.editor);\n    doc.restore_cursor = true;\n    let text = doc.text().slice(..);\n\n    // Make sure there's room at the end of the document if the last\n    // selection butts up against it.\n    let end = text.len_chars();\n    let last_range = doc\n        .selection(view.id)\n        .iter()\n        .last()\n        .expect(\"selection should always have at least one range\");\n    if !last_range.is_empty() && last_range.to() == end {\n        let transaction = Transaction::change(\n            doc.text(),\n            [(end, end, Some(doc.line_ending.as_str().into()))].into_iter(),\n        );\n        doc.apply(&transaction, view.id);\n    }\n\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        Range::new(\n            range.from(),\n            graphemes::next_grapheme_boundary(doc.text().slice(..), range.to()),\n        )\n    });\n    doc.set_selection(view.id, selection);\n}\n\nfn file_picker(cx: &mut Context) {\n    let root = find_workspace().0;\n    if !root.exists() {\n        cx.editor.set_error(\"Workspace directory does not exist\");\n        return;\n    }\n    let picker = ui::file_picker(cx.editor, root);\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\nfn file_picker_in_current_buffer_directory(cx: &mut Context) {\n    let doc_dir = doc!(cx.editor)\n        .path()\n        .and_then(|path| path.parent().map(|path| path.to_path_buf()));\n\n    let path = match doc_dir {\n        Some(path) => path,\n        None => {\n            let cwd = helix_stdx::env::current_working_dir();\n            if !cwd.exists() {\n                cx.editor.set_error(\n                    \"Current buffer has no parent and current working directory does not exist\",\n                );\n                return;\n            }\n            cx.editor.set_error(\n                \"Current buffer has no parent, opening file picker in current working directory\",\n            );\n            cwd\n        }\n    };\n\n    let picker = ui::file_picker(cx.editor, path);\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\nfn file_picker_in_current_directory(cx: &mut Context) {\n    let cwd = helix_stdx::env::current_working_dir();\n    if !cwd.exists() {\n        cx.editor\n            .set_error(\"Current working directory does not exist\");\n        return;\n    }\n    let picker = ui::file_picker(cx.editor, cwd);\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\nfn file_explorer(cx: &mut Context) {\n    let root = find_workspace().0;\n    if !root.exists() {\n        cx.editor.set_error(\"Workspace directory does not exist\");\n        return;\n    }\n\n    if let Ok(picker) = ui::file_explorer(root, cx.editor) {\n        cx.push_layer(Box::new(overlaid(picker)));\n    }\n}\n\nfn file_explorer_in_current_buffer_directory(cx: &mut Context) {\n    let doc_dir = doc!(cx.editor)\n        .path()\n        .and_then(|path| path.parent().map(|path| path.to_path_buf()));\n\n    let path = match doc_dir {\n        Some(path) => path,\n        None => {\n            let cwd = helix_stdx::env::current_working_dir();\n            if !cwd.exists() {\n                cx.editor.set_error(\n                    \"Current buffer has no parent and current working directory does not exist\",\n                );\n                return;\n            }\n            cx.editor.set_error(\n                \"Current buffer has no parent, opening file explorer in current working directory\",\n            );\n            cwd\n        }\n    };\n\n    if let Ok(picker) = ui::file_explorer(path, cx.editor) {\n        cx.push_layer(Box::new(overlaid(picker)));\n    }\n}\n\nfn file_explorer_in_current_directory(cx: &mut Context) {\n    let cwd = helix_stdx::env::current_working_dir();\n    if !cwd.exists() {\n        cx.editor\n            .set_error(\"Current working directory does not exist\");\n        return;\n    }\n\n    if let Ok(picker) = ui::file_explorer(cwd, cx.editor) {\n        cx.push_layer(Box::new(overlaid(picker)));\n    }\n}\n\nfn buffer_picker(cx: &mut Context) {\n    let current = view!(cx.editor).doc;\n\n    struct BufferMeta {\n        id: DocumentId,\n        path: Option<PathBuf>,\n        is_modified: bool,\n        is_current: bool,\n        focused_at: std::time::Instant,\n    }\n\n    let new_meta = |doc: &Document| BufferMeta {\n        id: doc.id(),\n        path: doc.path().cloned(),\n        is_modified: doc.is_modified(),\n        is_current: doc.id() == current,\n        focused_at: doc.focused_at,\n    };\n\n    let mut items = cx\n        .editor\n        .documents\n        .values()\n        .map(new_meta)\n        .collect::<Vec<BufferMeta>>();\n\n    // mru\n    items.sort_unstable_by_key(|item| std::cmp::Reverse(item.focused_at));\n\n    let columns = [\n        PickerColumn::new(\"id\", |meta: &BufferMeta, _| meta.id.to_string().into()),\n        PickerColumn::new(\"flags\", |meta: &BufferMeta, _| {\n            let mut flags = String::new();\n            if meta.is_modified {\n                flags.push('+');\n            }\n            if meta.is_current {\n                flags.push('*');\n            }\n            flags.into()\n        }),\n        PickerColumn::new(\"path\", |meta: &BufferMeta, _| {\n            let path = meta\n                .path\n                .as_deref()\n                .map(helix_stdx::path::get_relative_path);\n            path.as_deref()\n                .and_then(Path::to_str)\n                .unwrap_or(SCRATCH_BUFFER_NAME)\n                .to_string()\n                .into()\n        }),\n    ];\n\n    let initial_cursor = if cx\n        .editor\n        .config()\n        .buffer_picker\n        .start_position\n        .is_previous()\n        && !items.is_empty()\n    {\n        1\n    } else {\n        0\n    };\n\n    let picker = Picker::new(columns, 2, items, (), |cx, meta, action| {\n        cx.editor.switch(meta.id, action);\n    })\n    .with_initial_cursor(initial_cursor)\n    .with_preview(|editor, meta| {\n        let doc = &editor.documents.get(&meta.id)?;\n        let lines = doc.selections().values().next().map(|selection| {\n            let cursor_line = selection.primary().cursor_line(doc.text().slice(..));\n            (cursor_line, cursor_line)\n        });\n        Some((meta.id.into(), lines))\n    });\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\nfn jumplist_picker(cx: &mut Context) {\n    struct JumpMeta {\n        id: DocumentId,\n        path: Option<PathBuf>,\n        selection: Selection,\n        text: String,\n        is_current: bool,\n    }\n\n    for (view, _) in cx.editor.tree.views_mut() {\n        for doc_id in view.jumps.iter().map(|e| e.0).collect::<Vec<_>>().iter() {\n            let doc = doc_mut!(cx.editor, doc_id);\n            view.sync_changes(doc);\n        }\n    }\n\n    let new_meta = |view: &View, doc_id: DocumentId, selection: Selection| {\n        let doc = &cx.editor.documents.get(&doc_id);\n        let text = doc.map_or(\"\".into(), |d| {\n            selection\n                .fragments(d.text().slice(..))\n                .map(Cow::into_owned)\n                .collect::<Vec<_>>()\n                .join(\" \")\n        });\n\n        JumpMeta {\n            id: doc_id,\n            path: doc.and_then(|d| d.path().cloned()),\n            selection,\n            text,\n            is_current: view.doc == doc_id,\n        }\n    };\n\n    let columns = [\n        ui::PickerColumn::new(\"id\", |item: &JumpMeta, _| item.id.to_string().into()),\n        ui::PickerColumn::new(\"path\", |item: &JumpMeta, _| {\n            let path = item\n                .path\n                .as_deref()\n                .map(helix_stdx::path::get_relative_path);\n            path.as_deref()\n                .and_then(Path::to_str)\n                .unwrap_or(SCRATCH_BUFFER_NAME)\n                .to_string()\n                .into()\n        }),\n        ui::PickerColumn::new(\"flags\", |item: &JumpMeta, _| {\n            let mut flags = Vec::new();\n            if item.is_current {\n                flags.push(\"*\");\n            }\n\n            if flags.is_empty() {\n                \"\".into()\n            } else {\n                format!(\" ({})\", flags.join(\"\")).into()\n            }\n        }),\n        ui::PickerColumn::new(\"contents\", |item: &JumpMeta, _| item.text.as_str().into()),\n    ];\n\n    let picker = Picker::new(\n        columns,\n        1, // path\n        cx.editor.tree.views().flat_map(|(view, _)| {\n            view.jumps\n                .iter()\n                .rev()\n                .map(|(doc_id, selection)| new_meta(view, *doc_id, selection.clone()))\n        }),\n        (),\n        |cx, meta, action| {\n            cx.editor.switch(meta.id, action);\n            let config = cx.editor.config();\n            let (view, doc) = (view_mut!(cx.editor), doc_mut!(cx.editor, &meta.id));\n            doc.set_selection(view.id, meta.selection.clone());\n            if action.align_view(view, doc.id()) {\n                view.ensure_cursor_in_view_center(doc, config.scrolloff);\n            }\n        },\n    )\n    .with_preview(|editor, meta| {\n        let doc = &editor.documents.get(&meta.id)?;\n        let line = meta.selection.primary().cursor_line(doc.text().slice(..));\n        Some((meta.id.into(), Some((line, line))))\n    });\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\nfn changed_file_picker(cx: &mut Context) {\n    pub struct FileChangeData {\n        cwd: PathBuf,\n        style_untracked: Style,\n        style_modified: Style,\n        style_conflict: Style,\n        style_deleted: Style,\n        style_renamed: Style,\n    }\n\n    let cwd = helix_stdx::env::current_working_dir();\n    if !cwd.exists() {\n        cx.editor\n            .set_error(\"Current working directory does not exist\");\n        return;\n    }\n\n    let added = cx.editor.theme.get(\"diff.plus\");\n    let modified = cx.editor.theme.get(\"diff.delta\");\n    let conflict = cx.editor.theme.get(\"diff.delta.conflict\");\n    let deleted = cx.editor.theme.get(\"diff.minus\");\n    let renamed = cx.editor.theme.get(\"diff.delta.moved\");\n\n    let columns = [\n        PickerColumn::new(\"change\", |change: &FileChange, data: &FileChangeData| {\n            match change {\n                FileChange::Untracked { .. } => Span::styled(\"+ untracked\", data.style_untracked),\n                FileChange::Modified { .. } => Span::styled(\"~ modified\", data.style_modified),\n                FileChange::Conflict { .. } => Span::styled(\"x conflict\", data.style_conflict),\n                FileChange::Deleted { .. } => Span::styled(\"- deleted\", data.style_deleted),\n                FileChange::Renamed { .. } => Span::styled(\"> renamed\", data.style_renamed),\n            }\n            .into()\n        }),\n        PickerColumn::new(\"path\", |change: &FileChange, data: &FileChangeData| {\n            let display_path = |path: &PathBuf| {\n                path.strip_prefix(&data.cwd)\n                    .unwrap_or(path)\n                    .display()\n                    .to_string()\n            };\n            match change {\n                FileChange::Untracked { path } => display_path(path),\n                FileChange::Modified { path } => display_path(path),\n                FileChange::Conflict { path } => display_path(path),\n                FileChange::Deleted { path } => display_path(path),\n                FileChange::Renamed { from_path, to_path } => {\n                    format!(\"{} -> {}\", display_path(from_path), display_path(to_path))\n                }\n            }\n            .into()\n        }),\n    ];\n\n    let picker = Picker::new(\n        columns,\n        1, // path\n        [],\n        FileChangeData {\n            cwd: cwd.clone(),\n            style_untracked: added,\n            style_modified: modified,\n            style_conflict: conflict,\n            style_deleted: deleted,\n            style_renamed: renamed,\n        },\n        |cx, meta: &FileChange, action| {\n            let path_to_open = meta.path();\n            if let Err(e) = cx.editor.open(path_to_open, action) {\n                let err = if let Some(err) = e.source() {\n                    format!(\"{}\", err)\n                } else {\n                    format!(\"unable to open \\\"{}\\\"\", path_to_open.display())\n                };\n                cx.editor.set_error(err);\n            }\n        },\n    )\n    .with_preview(|_editor, meta| Some((meta.path().into(), None)));\n    let injector = picker.injector();\n\n    cx.editor\n        .diff_providers\n        .clone()\n        .for_each_changed_file(cwd, move |change| match change {\n            Ok(change) => injector.push(change).is_ok(),\n            Err(err) => {\n                status::report_blocking(err);\n                true\n            }\n        });\n    cx.push_layer(Box::new(overlaid(picker)));\n}\n\npub fn command_palette(cx: &mut Context) {\n    let register = cx.register;\n    let count = cx.count;\n\n    cx.callback.push(Box::new(\n        move |compositor: &mut Compositor, cx: &mut compositor::Context| {\n            let keymap = compositor.find::<ui::EditorView>().unwrap().keymaps.map()\n                [&cx.editor.mode]\n                .reverse_map();\n\n            let commands = MappableCommand::STATIC_COMMAND_LIST.iter().cloned().chain(\n                typed::TYPABLE_COMMAND_LIST\n                    .iter()\n                    .map(|cmd| MappableCommand::Typable {\n                        name: cmd.name.to_owned(),\n                        args: String::new(),\n                        doc: cmd.doc.to_owned(),\n                    }),\n            );\n\n            let columns = [\n                ui::PickerColumn::new(\"name\", |item, _| match item {\n                    MappableCommand::Typable { name, .. } => format!(\":{name}\").into(),\n                    MappableCommand::Static { name, .. } => (*name).into(),\n                    MappableCommand::Macro { .. } => {\n                        unreachable!(\"macros aren't included in the command palette\")\n                    }\n                }),\n                ui::PickerColumn::new(\n                    \"bindings\",\n                    |item: &MappableCommand, keymap: &crate::keymap::ReverseKeymap| {\n                        keymap\n                            .get(item.name())\n                            .map(|bindings| {\n                                bindings.iter().fold(String::new(), |mut acc, bind| {\n                                    if !acc.is_empty() {\n                                        acc.push(' ');\n                                    }\n                                    for key in bind {\n                                        acc.push_str(&key.key_sequence_format());\n                                    }\n                                    acc\n                                })\n                            })\n                            .unwrap_or_default()\n                            .into()\n                    },\n                ),\n                ui::PickerColumn::new(\"doc\", |item: &MappableCommand, _| item.doc().into()),\n            ];\n\n            let picker = Picker::new(columns, 0, commands, keymap, move |cx, command, _action| {\n                let mut ctx = Context {\n                    register,\n                    count,\n                    editor: cx.editor,\n                    callback: Vec::new(),\n                    on_next_key_callback: None,\n                    jobs: cx.jobs,\n                };\n                let focus = view!(ctx.editor).id;\n\n                command.execute(&mut ctx);\n\n                if ctx.editor.tree.contains(focus) {\n                    let config = ctx.editor.config();\n                    let mode = ctx.editor.mode();\n                    let view = view_mut!(ctx.editor, focus);\n                    let doc = doc_mut!(ctx.editor, &view.doc);\n\n                    view.ensure_cursor_in_view(doc, config.scrolloff);\n\n                    if mode != Mode::Insert {\n                        doc.append_changes_to_history(view);\n                    }\n                }\n            });\n            compositor.push(Box::new(overlaid(picker)));\n        },\n    ));\n}\n\nfn last_picker(cx: &mut Context) {\n    // TODO: last picker does not seem to work well with buffer_picker\n    cx.callback.push(Box::new(|compositor, cx| {\n        if let Some(picker) = compositor.last_picker.take() {\n            compositor.push(picker);\n        } else {\n            cx.editor.set_error(\"no last picker\")\n        }\n    }));\n}\n\n/// Fallback position to use for [`insert_with_indent`].\nenum IndentFallbackPos {\n    LineStart,\n    LineEnd,\n}\n\n// `I` inserts at the first nonwhitespace character of each line with a selection.\n// If the line is empty, automatically indent.\nfn insert_at_line_start(cx: &mut Context) {\n    insert_with_indent(cx, IndentFallbackPos::LineStart);\n}\n\n// `A` inserts at the end of each line with a selection.\n// If the line is empty, automatically indent.\nfn insert_at_line_end(cx: &mut Context) {\n    insert_with_indent(cx, IndentFallbackPos::LineEnd);\n}\n\n// Enter insert mode and auto-indent the current line if it is empty.\n// If the line is not empty, move the cursor to the specified fallback position.\nfn insert_with_indent(cx: &mut Context, cursor_fallback: IndentFallbackPos) {\n    enter_insert_mode(cx);\n\n    let (view, doc) = current!(cx.editor);\n    let loader = cx.editor.syn_loader.load();\n\n    let text = doc.text().slice(..);\n    let contents = doc.text();\n    let selection = doc.selection(view.id);\n\n    let syntax = doc.syntax();\n    let tab_width = doc.tab_width();\n\n    let mut ranges = SmallVec::with_capacity(selection.len());\n    let mut offs = 0;\n\n    let mut transaction = Transaction::change_by_selection(contents, selection, |range| {\n        let cursor_line = range.cursor_line(text);\n        let cursor_line_start = text.line_to_char(cursor_line);\n\n        if line_end_char_index(&text, cursor_line) == cursor_line_start {\n            // line is empty => auto indent\n            let line_end_index = cursor_line_start;\n\n            let indent = indent::indent_for_newline(\n                &loader,\n                syntax,\n                &doc.config.load().indent_heuristic,\n                &doc.indent_style,\n                tab_width,\n                text,\n                cursor_line,\n                line_end_index,\n                cursor_line,\n            );\n\n            // calculate new selection ranges\n            let pos = offs + cursor_line_start;\n            let indent_width = indent.chars().count();\n            ranges.push(Range::point(pos + indent_width));\n            offs += indent_width;\n\n            (line_end_index, line_end_index, Some(indent.into()))\n        } else {\n            // move cursor to the fallback position\n            let pos = match cursor_fallback {\n                IndentFallbackPos::LineStart => text\n                    .line(cursor_line)\n                    .first_non_whitespace_char()\n                    .map(|ws_offset| ws_offset + cursor_line_start)\n                    .unwrap_or(cursor_line_start),\n                IndentFallbackPos::LineEnd => line_end_char_index(&text, cursor_line),\n            };\n\n            ranges.push(range.put_cursor(text, pos + offs, cx.editor.mode == Mode::Select));\n\n            (cursor_line_start, cursor_line_start, None)\n        }\n    });\n\n    transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));\n    doc.apply(&transaction, view.id);\n}\n\n// Creates an LspCallback that waits for formatting changes to be computed. When they're done,\n// it applies them, but only if the doc hasn't changed.\n//\n// TODO: provide some way to cancel this, probably as part of a more general job cancellation\n// scheme\nasync fn make_format_callback(\n    doc_id: DocumentId,\n    doc_version: i32,\n    view_id: ViewId,\n    format: impl Future<Output = Result<Transaction, FormatterError>> + Send + 'static,\n    write: Option<(Option<PathBuf>, bool)>,\n) -> anyhow::Result<job::Callback> {\n    let format = format.await;\n\n    let call: job::Callback = Callback::Editor(Box::new(move |editor| {\n        if !editor.documents.contains_key(&doc_id) || !editor.tree.contains(view_id) {\n            return;\n        }\n\n        let scrolloff = editor.config().scrolloff;\n        let doc = doc_mut!(editor, &doc_id);\n        let view = view_mut!(editor, view_id);\n\n        match format {\n            Ok(format) => {\n                if doc.version() == doc_version {\n                    doc.apply(&format, view.id);\n                    doc.append_changes_to_history(view);\n                    doc.detect_indent_and_line_ending();\n                    view.ensure_cursor_in_view(doc, scrolloff);\n                } else {\n                    log::info!(\"discarded formatting changes because the document changed\");\n                }\n            }\n            Err(err) => {\n                if write.is_none() {\n                    editor.set_error(err.to_string());\n                    return;\n                }\n                log::info!(\"failed to format '{}': {err}\", doc.display_name());\n            }\n        }\n\n        if let Some((path, force)) = write {\n            let id = doc.id();\n            if let Err(err) = editor.save(id, path, force) {\n                editor.set_error(format!(\"Error saving: {}\", err));\n            }\n        }\n    }));\n\n    Ok(call)\n}\n\n#[derive(PartialEq, Eq)]\npub enum Open {\n    Below,\n    Above,\n}\n\n#[derive(PartialEq)]\npub enum CommentContinuation {\n    Enabled,\n    Disabled,\n}\n\nfn open(cx: &mut Context, open: Open, comment_continuation: CommentContinuation) {\n    let count = cx.count();\n    enter_insert_mode(cx);\n    let config = cx.editor.config();\n    let (view, doc) = current!(cx.editor);\n    let loader = cx.editor.syn_loader.load();\n\n    let text = doc.text().slice(..);\n    let contents = doc.text();\n    let selection = doc.selection(view.id);\n    let mut offs = 0;\n\n    let mut ranges = SmallVec::with_capacity(selection.len());\n\n    let continue_comment_tokens =\n        if comment_continuation == CommentContinuation::Enabled && config.continue_comments {\n            doc.language_config()\n                .and_then(|config| config.comment_tokens.as_ref())\n        } else {\n            None\n        };\n\n    let mut transaction = Transaction::change_by_selection(contents, selection, |range| {\n        // the line number, where the cursor is currently\n        let curr_line_num = text.char_to_line(match open {\n            Open::Below => graphemes::prev_grapheme_boundary(text, range.to()),\n            Open::Above => range.from(),\n        });\n\n        // the next line number, where the cursor will be, after finishing the transaction\n        let next_new_line_num = match open {\n            Open::Below => curr_line_num + 1,\n            Open::Above => curr_line_num,\n        };\n\n        let above_next_new_line_num = next_new_line_num.saturating_sub(1);\n\n        let continue_comment_token = continue_comment_tokens\n            .and_then(|tokens| comment::get_comment_token(text, tokens, curr_line_num));\n\n        // Index to insert newlines after, as well as the char width\n        // to use to compensate for those inserted newlines.\n        let (above_next_line_end_index, above_next_line_end_width) = if next_new_line_num == 0 {\n            (0, 0)\n        } else {\n            (\n                line_end_char_index(&text, above_next_new_line_num),\n                doc.line_ending.len_chars(),\n            )\n        };\n\n        let line = text.line(curr_line_num);\n        let indent = match line.first_non_whitespace_char() {\n            Some(pos) if continue_comment_token.is_some() => line.slice(..pos).to_string(),\n            _ => indent::indent_for_newline(\n                &loader,\n                doc.syntax(),\n                &config.indent_heuristic,\n                &doc.indent_style,\n                doc.tab_width(),\n                text,\n                above_next_new_line_num,\n                above_next_line_end_index,\n                curr_line_num,\n            ),\n        };\n\n        let indent_len = indent.len();\n        let mut text = String::with_capacity(1 + indent_len);\n\n        if open == Open::Above && next_new_line_num == 0 {\n            text.push_str(&indent);\n            if let Some(token) = continue_comment_token {\n                text.push_str(token);\n                text.push(' ');\n            }\n            text.push_str(doc.line_ending.as_str());\n        } else {\n            text.push_str(doc.line_ending.as_str());\n            text.push_str(&indent);\n\n            if let Some(token) = continue_comment_token {\n                text.push_str(token);\n                text.push(' ');\n            }\n        }\n\n        let text = text.repeat(count);\n\n        // calculate new selection ranges\n        let pos = offs + above_next_line_end_index + above_next_line_end_width;\n        let comment_len = continue_comment_token\n            .map(|token| token.len() + 1) // `+ 1` for the extra space added\n            .unwrap_or_default();\n        for i in 0..count {\n            // pos                     -> beginning of reference line,\n            // + (i * (line_ending_len + indent_len + comment_len)) -> beginning of i'th line from pos (possibly including comment token)\n            // + indent_len + comment_len ->        -> indent for i'th line\n            ranges.push(Range::point(\n                pos + (i * (doc.line_ending.len_chars() + indent_len + comment_len))\n                    + indent_len\n                    + comment_len,\n            ));\n        }\n\n        // update the offset for the next range\n        offs += text.chars().count();\n\n        (\n            above_next_line_end_index,\n            above_next_line_end_index,\n            Some(text.into()),\n        )\n    });\n\n    transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));\n\n    doc.apply(&transaction, view.id);\n}\n\n// o inserts a new line after each line with a selection\nfn open_below(cx: &mut Context) {\n    open(cx, Open::Below, CommentContinuation::Enabled)\n}\n\n// O inserts a new line before each line with a selection\nfn open_above(cx: &mut Context) {\n    open(cx, Open::Above, CommentContinuation::Enabled)\n}\n\nfn normal_mode(cx: &mut Context) {\n    cx.editor.enter_normal_mode();\n}\n\n// Store a jump on the jumplist.\nfn push_jump(view: &mut View, doc: &mut Document) {\n    doc.append_changes_to_history(view);\n    let jump = (doc.id(), doc.selection(view.id).clone());\n    view.jumps.push(jump);\n}\n\nfn goto_line(cx: &mut Context) {\n    goto_line_impl(cx, Movement::Move);\n}\n\nfn goto_line_impl(cx: &mut Context, movement: Movement) {\n    if cx.count.is_some() {\n        let (view, doc) = current!(cx.editor);\n        push_jump(view, doc);\n\n        goto_line_without_jumplist(cx.editor, cx.count, movement);\n    }\n}\n\nfn goto_line_without_jumplist(\n    editor: &mut Editor,\n    count: Option<NonZeroUsize>,\n    movement: Movement,\n) {\n    if let Some(count) = count {\n        let (view, doc) = current!(editor);\n        let text = doc.text().slice(..);\n        let max_line = if text.line(text.len_lines() - 1).len_chars() == 0 {\n            // If the last line is blank, don't jump to it.\n            text.len_lines().saturating_sub(2)\n        } else {\n            text.len_lines() - 1\n        };\n        let line_idx = std::cmp::min(count.get() - 1, max_line);\n        let pos = text.line_to_char(line_idx);\n        let selection = doc\n            .selection(view.id)\n            .clone()\n            .transform(|range| range.put_cursor(text, pos, movement == Movement::Extend));\n\n        doc.set_selection(view.id, selection);\n    }\n}\n\nfn goto_last_line(cx: &mut Context) {\n    goto_last_line_impl(cx, Movement::Move)\n}\n\nfn extend_to_last_line(cx: &mut Context) {\n    goto_last_line_impl(cx, Movement::Extend)\n}\n\nfn goto_last_line_impl(cx: &mut Context, movement: Movement) {\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n    let line_idx = if text.line(text.len_lines() - 1).len_chars() == 0 {\n        // If the last line is blank, don't jump to it.\n        text.len_lines().saturating_sub(2)\n    } else {\n        text.len_lines() - 1\n    };\n    let pos = text.line_to_char(line_idx);\n    let selection = doc\n        .selection(view.id)\n        .clone()\n        .transform(|range| range.put_cursor(text, pos, movement == Movement::Extend));\n\n    push_jump(view, doc);\n    doc.set_selection(view.id, selection);\n}\n\nfn goto_column(cx: &mut Context) {\n    goto_column_impl(cx, Movement::Move);\n}\n\nfn extend_to_column(cx: &mut Context) {\n    goto_column_impl(cx, Movement::Extend);\n}\n\nfn goto_column_impl(cx: &mut Context, movement: Movement) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let line = range.cursor_line(text);\n        let line_start = text.line_to_char(line);\n        let line_end = line_end_char_index(&text, line);\n        let pos = graphemes::nth_next_grapheme_boundary(text, line_start, count - 1).min(line_end);\n        range.put_cursor(text, pos, movement == Movement::Extend)\n    });\n    push_jump(view, doc);\n    doc.set_selection(view.id, selection);\n}\n\nfn goto_last_accessed_file(cx: &mut Context) {\n    let view = view_mut!(cx.editor);\n    if let Some(alt) = view.docs_access_history.pop() {\n        cx.editor.switch(alt, Action::Replace);\n    } else {\n        cx.editor.set_error(\"no last accessed buffer\")\n    }\n}\n\nfn goto_last_modification(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let pos = doc.history.get_mut().last_edit_pos();\n    let text = doc.text().slice(..);\n    if let Some(pos) = pos {\n        let selection = doc\n            .selection(view.id)\n            .clone()\n            .transform(|range| range.put_cursor(text, pos, cx.editor.mode == Mode::Select));\n        push_jump(view, doc);\n        doc.set_selection(view.id, selection);\n    }\n}\n\nfn goto_last_modified_file(cx: &mut Context) {\n    let view = view!(cx.editor);\n    let alternate_file = view\n        .last_modified_docs\n        .into_iter()\n        .flatten()\n        .find(|&id| id != view.doc);\n    if let Some(alt) = alternate_file {\n        cx.editor.switch(alt, Action::Replace);\n    } else {\n        cx.editor.set_error(\"no last modified buffer\")\n    }\n}\n\nfn select_mode(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n\n    // Make sure end-of-document selections are also 1-width.\n    // (With the exception of being in an empty document, of course.)\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        if range.is_empty() && range.head == text.len_chars() {\n            Range::new(\n                graphemes::prev_grapheme_boundary(text, range.anchor),\n                range.head,\n            )\n        } else {\n            range\n        }\n    });\n    doc.set_selection(view.id, selection);\n\n    cx.editor.mode = Mode::Select;\n}\n\nfn exit_select_mode(cx: &mut Context) {\n    if cx.editor.mode == Mode::Select {\n        cx.editor.mode = Mode::Normal;\n    }\n}\n\nfn goto_first_diag(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let selection = match doc.diagnostics().first() {\n        Some(diag) => Selection::single(diag.range.start, diag.range.end),\n        None => return,\n    };\n    push_jump(view, doc);\n    doc.set_selection(view.id, selection);\n    view.diagnostics_handler\n        .immediately_show_diagnostic(doc, view.id);\n}\n\nfn goto_last_diag(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let selection = match doc.diagnostics().last() {\n        Some(diag) => Selection::single(diag.range.start, diag.range.end),\n        None => return,\n    };\n    push_jump(view, doc);\n    doc.set_selection(view.id, selection);\n    view.diagnostics_handler\n        .immediately_show_diagnostic(doc, view.id);\n}\n\nfn goto_next_diag(cx: &mut Context) {\n    let motion = move |editor: &mut Editor| {\n        let (view, doc) = current!(editor);\n\n        let cursor_pos = doc\n            .selection(view.id)\n            .primary()\n            .cursor(doc.text().slice(..));\n\n        let diag = doc\n            .diagnostics()\n            .iter()\n            .find(|diag| diag.range.start > cursor_pos);\n\n        let selection = match diag {\n            Some(diag) => Selection::single(diag.range.start, diag.range.end),\n            None => return,\n        };\n        push_jump(view, doc);\n        doc.set_selection(view.id, selection);\n        view.diagnostics_handler\n            .immediately_show_diagnostic(doc, view.id);\n    };\n\n    cx.editor.apply_motion(motion);\n}\n\nfn goto_prev_diag(cx: &mut Context) {\n    let motion = move |editor: &mut Editor| {\n        let (view, doc) = current!(editor);\n\n        let cursor_pos = doc\n            .selection(view.id)\n            .primary()\n            .cursor(doc.text().slice(..));\n\n        let diag = doc\n            .diagnostics()\n            .iter()\n            .rev()\n            .find(|diag| diag.range.start < cursor_pos);\n\n        let selection = match diag {\n            // NOTE: the selection is reversed because we're jumping to the\n            // previous diagnostic.\n            Some(diag) => Selection::single(diag.range.end, diag.range.start),\n            None => return,\n        };\n        push_jump(view, doc);\n        doc.set_selection(view.id, selection);\n        view.diagnostics_handler\n            .immediately_show_diagnostic(doc, view.id);\n    };\n    cx.editor.apply_motion(motion)\n}\n\nfn goto_first_change(cx: &mut Context) {\n    goto_first_change_impl(cx, false);\n}\n\nfn goto_last_change(cx: &mut Context) {\n    goto_first_change_impl(cx, true);\n}\n\nfn goto_first_change_impl(cx: &mut Context, reverse: bool) {\n    let editor = &mut cx.editor;\n    let (view, doc) = current!(editor);\n    if let Some(handle) = doc.diff_handle() {\n        let hunk = {\n            let diff = handle.load();\n            let idx = if reverse {\n                diff.len().saturating_sub(1)\n            } else {\n                0\n            };\n            diff.nth_hunk(idx)\n        };\n        if hunk != Hunk::NONE {\n            let range = hunk_range(hunk, doc.text().slice(..));\n            push_jump(view, doc);\n            doc.set_selection(view.id, Selection::single(range.anchor, range.head));\n        }\n    }\n}\n\nfn goto_next_change(cx: &mut Context) {\n    goto_next_change_impl(cx, Direction::Forward)\n}\n\nfn goto_prev_change(cx: &mut Context) {\n    goto_next_change_impl(cx, Direction::Backward)\n}\n\nfn goto_next_change_impl(cx: &mut Context, direction: Direction) {\n    let count = cx.count() as u32 - 1;\n    let motion = move |editor: &mut Editor| {\n        let (view, doc) = current!(editor);\n        let doc_text = doc.text().slice(..);\n        let diff_handle = if let Some(diff_handle) = doc.diff_handle() {\n            diff_handle\n        } else {\n            editor.set_status(\"Diff is not available in current buffer\");\n            return;\n        };\n\n        let selection = doc.selection(view.id).clone().transform(|range| {\n            let cursor_line = range.cursor_line(doc_text) as u32;\n\n            let diff = diff_handle.load();\n            let hunk_idx = match direction {\n                Direction::Forward => diff\n                    .next_hunk(cursor_line)\n                    .map(|idx| (idx + count).min(diff.len() - 1)),\n                Direction::Backward => diff\n                    .prev_hunk(cursor_line)\n                    .map(|idx| idx.saturating_sub(count)),\n            };\n            let Some(hunk_idx) = hunk_idx else {\n                return range;\n            };\n            let hunk = diff.nth_hunk(hunk_idx);\n            let new_range = hunk_range(hunk, doc_text);\n            if editor.mode == Mode::Select {\n                let head = if new_range.head < range.anchor {\n                    new_range.anchor\n                } else {\n                    new_range.head\n                };\n\n                Range::new(range.anchor, head)\n            } else {\n                new_range.with_direction(direction)\n            }\n        });\n\n        push_jump(view, doc);\n        doc.set_selection(view.id, selection)\n    };\n    cx.editor.apply_motion(motion);\n}\n\n/// Returns the [Range] for a [Hunk] in the given text.\n/// Additions and modifications cover the added and modified ranges.\n/// Deletions are represented as the point at the start of the deletion hunk.\nfn hunk_range(hunk: Hunk, text: RopeSlice) -> Range {\n    let anchor = text.line_to_char(hunk.after.start as usize);\n    let head = if hunk.after.is_empty() {\n        anchor + 1\n    } else {\n        text.line_to_char(hunk.after.end as usize)\n    };\n\n    Range::new(anchor, head)\n}\n\npub mod insert {\n    use crate::{events::PostInsertChar, key};\n\n    use super::*;\n    pub type Hook = fn(&Rope, &Selection, char) -> Option<Transaction>;\n\n    /// Exclude the cursor in range.\n    fn exclude_cursor(text: RopeSlice, range: Range, cursor: Range) -> Range {\n        if range.to() == cursor.to() && text.len_chars() != cursor.to() {\n            Range::new(\n                range.from(),\n                graphemes::prev_grapheme_boundary(text, cursor.to()),\n            )\n        } else {\n            range\n        }\n    }\n\n    // The default insert hook: simply insert the character\n    #[allow(clippy::unnecessary_wraps)] // need to use Option<> because of the Hook signature\n    fn insert(doc: &Rope, selection: &Selection, ch: char) -> Option<Transaction> {\n        let cursors = selection.clone().cursors(doc.slice(..));\n        let mut t = Tendril::new();\n        t.push(ch);\n        let transaction = Transaction::insert(doc, &cursors, t);\n        Some(transaction)\n    }\n\n    use helix_core::auto_pairs;\n    use helix_view::editor::SmartTabConfig;\n\n    pub fn insert_char(cx: &mut Context, c: char) {\n        let (view, doc) = current_ref!(cx.editor);\n        let text = doc.text();\n        let selection = doc.selection(view.id);\n\n        let loader: &helix_core::syntax::Loader = &cx.editor.syn_loader.load();\n        let auto_pairs = doc.auto_pairs(cx.editor, loader, view);\n\n        let transaction = auto_pairs\n            .as_ref()\n            .and_then(|ap| auto_pairs::hook(text, selection, c, ap))\n            .or_else(|| insert(text, selection, c));\n\n        let (view, doc) = current!(cx.editor);\n        if let Some(t) = transaction {\n            doc.apply(&t, view.id);\n        }\n\n        helix_event::dispatch(PostInsertChar { c, cx });\n    }\n\n    pub fn smart_tab(cx: &mut Context) {\n        let (view, doc) = current_ref!(cx.editor);\n        let view_id = view.id;\n\n        if matches!(\n            cx.editor.config().smart_tab,\n            Some(SmartTabConfig { enable: true, .. })\n        ) {\n            let cursors_after_whitespace = doc.selection(view_id).ranges().iter().all(|range| {\n                let cursor = range.cursor(doc.text().slice(..));\n                let current_line_num = doc.text().char_to_line(cursor);\n                let current_line_start = doc.text().line_to_char(current_line_num);\n                let left = doc.text().slice(current_line_start..cursor);\n                left.chars().all(|c| c.is_whitespace())\n            });\n\n            if !cursors_after_whitespace {\n                if doc.active_snippet.is_some() {\n                    goto_next_tabstop(cx);\n                } else {\n                    move_parent_node_end(cx);\n                }\n                return;\n            }\n        }\n\n        insert_tab(cx);\n    }\n\n    pub fn insert_tab(cx: &mut Context) {\n        insert_tab_impl(cx, 1)\n    }\n\n    fn insert_tab_impl(cx: &mut Context, count: usize) {\n        let (view, doc) = current!(cx.editor);\n\n        let transaction = Transaction::change(\n            doc.text(),\n            doc.selection(view.id).ranges().iter().map(|range| {\n                let cursor = range.cursor(doc.text().slice(..));\n                let indent = if let IndentStyle::Spaces(indent_width) = doc.indent_style {\n                    let line = range.cursor_line(doc.text().slice(..));\n                    let line_start = doc.text().line_to_char(line);\n                    let offset = (cursor - line_start) % indent_width as usize;\n\n                    Tendril::from(doc.indent_style.as_str().repeat(count)).split_off(offset)\n                } else {\n                    Tendril::from(doc.indent_style.as_str().repeat(count))\n                };\n\n                (cursor, cursor, Some(indent))\n            }),\n        );\n        doc.apply(&transaction, view.id);\n    }\n\n    pub fn append_char_interactive(cx: &mut Context) {\n        // Save the current mode, so we can restore it later.\n        let mode = cx.editor.mode;\n        append_mode(cx);\n        insert_selection_interactive(cx, mode);\n    }\n\n    pub fn insert_char_interactive(cx: &mut Context) {\n        let mode = cx.editor.mode;\n        insert_mode(cx);\n        insert_selection_interactive(cx, mode);\n    }\n\n    fn insert_selection_interactive(cx: &mut Context, old_mode: Mode) {\n        let count = cx.count();\n\n        // need to wait for next key\n        cx.on_next_key(move |cx, event| {\n            match event {\n                KeyEvent {\n                    code: KeyCode::Char(ch),\n                    ..\n                } => {\n                    for _ in 0..count {\n                        insert::insert_char(cx, ch)\n                    }\n                }\n                key!(Enter) => {\n                    if count != 1 {\n                        cx.editor\n                            .set_error(\"inserting multiple newlines not yet supported\");\n                        return;\n                    }\n                    insert_newline(cx)\n                }\n                key!(Tab) => insert_tab_impl(cx, count),\n                _ => (),\n            };\n            // Restore the old mode.\n            cx.editor.mode = old_mode;\n        });\n    }\n\n    pub fn insert_newline(cx: &mut Context) {\n        let config = cx.editor.config();\n        let (view, doc) = current_ref!(cx.editor);\n        let loader = cx.editor.syn_loader.load();\n        let text = doc.text().slice(..);\n        let line_ending = doc.line_ending.as_str();\n\n        let contents = doc.text();\n        let selection = doc.selection(view.id);\n        let mut ranges = SmallVec::with_capacity(selection.len());\n\n        // TODO: this is annoying, but we need to do it to properly calculate pos after edits\n        let mut global_offs = 0;\n        let mut new_text = String::new();\n\n        let continue_comment_tokens = if config.continue_comments {\n            doc.language_config()\n                .and_then(|config| config.comment_tokens.as_ref())\n        } else {\n            None\n        };\n\n        let mut last_pos = 0;\n        let mut transaction = Transaction::change_by_selection(contents, selection, |range| {\n            // Tracks the number of trailing whitespace characters deleted by this selection.\n            let mut chars_deleted = 0;\n            let pos = range.cursor(text);\n\n            let prev = if pos == 0 {\n                ' '\n            } else {\n                contents.char(pos - 1)\n            };\n            let curr = contents.get_char(pos).unwrap_or(' ');\n\n            let current_line = text.char_to_line(pos);\n            let line_start = text.line_to_char(current_line);\n\n            let continue_comment_token = continue_comment_tokens\n                .and_then(|tokens| comment::get_comment_token(text, tokens, current_line));\n\n            let (from, to, local_offs) = if let Some(idx) =\n                text.slice(line_start..pos).last_non_whitespace_char()\n            {\n                let first_trailing_whitespace_char = (line_start + idx + 1).clamp(last_pos, pos);\n                last_pos = pos;\n                let line = text.line(current_line);\n\n                let indent = match line.first_non_whitespace_char() {\n                    Some(pos) if continue_comment_token.is_some() => line.slice(..pos).to_string(),\n                    _ => indent::indent_for_newline(\n                        &loader,\n                        doc.syntax(),\n                        &config.indent_heuristic,\n                        &doc.indent_style,\n                        doc.tab_width(),\n                        text,\n                        current_line,\n                        pos,\n                        current_line,\n                    ),\n                };\n\n                let loader: &helix_core::syntax::Loader = &cx.editor.syn_loader.load();\n                // If we are between pairs (such as brackets), we want to\n                // insert an additional line which is indented one level\n                // more and place the cursor there\n                let on_auto_pair = doc\n                    .auto_pairs(cx.editor, loader, view)\n                    .and_then(|pairs| pairs.get(prev))\n                    .is_some_and(|pair| pair.open == prev && pair.close == curr);\n\n                let local_offs = if let Some(token) = continue_comment_token {\n                    new_text.reserve_exact(line_ending.len() + indent.len() + token.len() + 1);\n                    new_text.push_str(line_ending);\n                    new_text.push_str(&indent);\n                    new_text.push_str(token);\n                    new_text.push(' ');\n                    new_text.chars().count()\n                } else if on_auto_pair {\n                    // line where the cursor will be\n                    let inner_indent = indent.clone() + doc.indent_style.as_str();\n                    new_text\n                        .reserve_exact(line_ending.len() * 2 + indent.len() + inner_indent.len());\n                    new_text.push_str(line_ending);\n                    new_text.push_str(&inner_indent);\n\n                    // line where the matching pair will be\n                    let local_offs = new_text.chars().count();\n                    new_text.push_str(line_ending);\n                    new_text.push_str(&indent);\n\n                    local_offs\n                } else {\n                    new_text.reserve_exact(line_ending.len() + indent.len());\n                    new_text.push_str(line_ending);\n                    new_text.push_str(&indent);\n\n                    new_text.chars().count()\n                };\n\n                // Note that `first_trailing_whitespace_char` is at least `pos` so this unsigned\n                // subtraction cannot underflow.\n                chars_deleted = pos - first_trailing_whitespace_char;\n\n                (\n                    first_trailing_whitespace_char,\n                    pos,\n                    local_offs as isize - chars_deleted as isize,\n                )\n            } else {\n                // If the current line is all whitespace, insert a line ending at the beginning of\n                // the current line. This makes the current line empty and the new line contain the\n                // indentation of the old line.\n                new_text.push_str(line_ending);\n\n                (line_start, line_start, new_text.chars().count() as isize)\n            };\n\n            let new_range = if range.cursor(text) > range.anchor {\n                // when appending, extend the range by local_offs\n                Range::new(\n                    (range.anchor as isize + global_offs) as usize,\n                    (range.head as isize + local_offs + global_offs) as usize,\n                )\n            } else {\n                // when inserting, slide the range by local_offs\n                Range::new(\n                    (range.anchor as isize + local_offs + global_offs) as usize,\n                    (range.head as isize + local_offs + global_offs) as usize,\n                )\n            };\n\n            // TODO: range replace or extend\n            // range.replace(|range| range.is_empty(), head); -> fn extend if cond true, new head pos\n            // can be used with cx.mode to do replace or extend on most changes\n            ranges.push(new_range);\n            global_offs += new_text.chars().count() as isize - chars_deleted as isize;\n            let tendril = Tendril::from(&new_text);\n            new_text.clear();\n\n            (from, to, Some(tendril))\n        });\n\n        transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));\n\n        let (view, doc) = current!(cx.editor);\n        doc.apply(&transaction, view.id);\n    }\n\n    pub fn delete_char_backward(cx: &mut Context) {\n        let count = cx.count();\n        let (view, doc) = current_ref!(cx.editor);\n        let text = doc.text().slice(..);\n        let tab_width = doc.tab_width();\n        let indent_width = doc.indent_width();\n\n        let loader: &helix_core::syntax::Loader = &cx.editor.syn_loader.load();\n        let auto_pairs = doc.auto_pairs(cx.editor, loader, view);\n\n        let transaction =\n            Transaction::delete_by_selection(doc.text(), doc.selection(view.id), |range| {\n                let pos = range.cursor(text);\n                if pos == 0 {\n                    return (pos, pos);\n                }\n                let line_start_pos = text.line_to_char(range.cursor_line(text));\n                // consider to delete by indent level if all characters before `pos` are indent units.\n                let fragment = Cow::from(text.slice(line_start_pos..pos));\n                if !fragment.is_empty() && fragment.chars().all(|ch| ch == ' ' || ch == '\\t') {\n                    if text.get_char(pos.saturating_sub(1)) == Some('\\t') {\n                        // fast path, delete one char\n                        (graphemes::nth_prev_grapheme_boundary(text, pos, 1), pos)\n                    } else {\n                        let width: usize = fragment\n                            .chars()\n                            .map(|ch| {\n                                if ch == '\\t' {\n                                    tab_width\n                                } else {\n                                    // it can be none if it still meet control characters other than '\\t'\n                                    // here just set the width to 1 (or some value better?).\n                                    ch.width().unwrap_or(1)\n                                }\n                            })\n                            .sum();\n                        let mut drop = width % indent_width; // round down to nearest unit\n                        if drop == 0 {\n                            drop = indent_width\n                        }; // if it's already at a unit, consume a whole unit\n                        let mut chars = fragment.chars().rev();\n                        let mut start = pos;\n                        for _ in 0..drop {\n                            // delete up to `drop` spaces\n                            match chars.next() {\n                                Some(' ') => start -= 1,\n                                _ => break,\n                            }\n                        }\n                        (start, pos) // delete!\n                    }\n                } else {\n                    match (\n                        text.get_char(pos.saturating_sub(1)),\n                        text.get_char(pos),\n                        auto_pairs,\n                    ) {\n                        (Some(_x), Some(_y), Some(ap))\n                            if range.is_single_grapheme(text)\n                                && ap.get(_x).is_some()\n                                && ap.get(_x).unwrap().open == _x\n                                && ap.get(_x).unwrap().close == _y =>\n                        // delete both autopaired characters\n                        {\n                            (\n                                graphemes::nth_prev_grapheme_boundary(text, pos, count),\n                                graphemes::nth_next_grapheme_boundary(text, pos, count),\n                            )\n                        }\n                        _ =>\n                        // delete 1 char\n                        {\n                            (graphemes::nth_prev_grapheme_boundary(text, pos, count), pos)\n                        }\n                    }\n                }\n            });\n        let (view, doc) = current!(cx.editor);\n        doc.apply(&transaction, view.id);\n    }\n\n    pub fn delete_char_forward(cx: &mut Context) {\n        let count = cx.count();\n        delete_by_selection_insert_mode(\n            cx,\n            |text, range| {\n                let pos = range.cursor(text);\n                (pos, graphemes::nth_next_grapheme_boundary(text, pos, count))\n            },\n            Direction::Forward,\n        )\n    }\n\n    pub fn delete_word_backward(cx: &mut Context) {\n        let count = cx.count();\n        delete_by_selection_insert_mode(\n            cx,\n            |text, range| {\n                let anchor = movement::move_prev_word_start(text, *range, count).from();\n                let next = Range::new(anchor, range.cursor(text));\n                let range = exclude_cursor(text, next, *range);\n                (range.from(), range.to())\n            },\n            Direction::Backward,\n        );\n    }\n\n    pub fn delete_word_forward(cx: &mut Context) {\n        let count = cx.count();\n        delete_by_selection_insert_mode(\n            cx,\n            |text, range| {\n                let head = movement::move_next_word_end(text, *range, count).to();\n                (range.cursor(text), head)\n            },\n            Direction::Forward,\n        );\n    }\n}\n\n// Undo / Redo\n\nfn undo(cx: &mut Context) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    for _ in 0..count {\n        if !doc.undo(view) {\n            cx.editor.set_status(\"Already at oldest change\");\n            break;\n        }\n    }\n}\n\nfn redo(cx: &mut Context) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    for _ in 0..count {\n        if !doc.redo(view) {\n            cx.editor.set_status(\"Already at newest change\");\n            break;\n        }\n    }\n}\n\nfn earlier(cx: &mut Context) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    for _ in 0..count {\n        // rather than doing in batch we do this so get error halfway\n        if !doc.earlier(view, UndoKind::Steps(1)) {\n            cx.editor.set_status(\"Already at oldest change\");\n            break;\n        }\n    }\n}\n\nfn later(cx: &mut Context) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    for _ in 0..count {\n        // rather than doing in batch we do this so get error halfway\n        if !doc.later(view, UndoKind::Steps(1)) {\n            cx.editor.set_status(\"Already at newest change\");\n            break;\n        }\n    }\n}\n\nfn commit_undo_checkpoint(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    doc.append_changes_to_history(view);\n}\n\n// Yank / Paste\n\nfn yank(cx: &mut Context) {\n    yank_impl(\n        cx.editor,\n        cx.register\n            .unwrap_or(cx.editor.config().default_yank_register),\n    );\n    exit_select_mode(cx);\n}\n\nfn yank_to_clipboard(cx: &mut Context) {\n    yank_impl(cx.editor, '+');\n    exit_select_mode(cx);\n}\n\nfn yank_to_primary_clipboard(cx: &mut Context) {\n    yank_impl(cx.editor, '*');\n    exit_select_mode(cx);\n}\n\nfn yank_impl(editor: &mut Editor, register: char) {\n    let (view, doc) = current!(editor);\n    let text = doc.text().slice(..);\n\n    let values: Vec<String> = doc\n        .selection(view.id)\n        .fragments(text)\n        .map(Cow::into_owned)\n        .collect();\n    let selections = values.len();\n\n    match editor.registers.write(register, values) {\n        Ok(_) => editor.set_status(format!(\n            \"yanked {selections} selection{} to register {register}\",\n            if selections == 1 { \"\" } else { \"s\" }\n        )),\n        Err(err) => editor.set_error(err.to_string()),\n    }\n}\n\nfn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) {\n    let (view, doc) = current!(editor);\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id);\n    let selections = selection.len();\n    let joined = selection\n        .fragments(text)\n        .fold(String::new(), |mut acc, fragment| {\n            if !acc.is_empty() {\n                acc.push_str(separator);\n            }\n            acc.push_str(&fragment);\n            acc\n        });\n\n    match editor.registers.write(register, vec![joined]) {\n        Ok(_) => editor.set_status(format!(\n            \"joined and yanked {selections} selection{} to register {register}\",\n            if selections == 1 { \"\" } else { \"s\" }\n        )),\n        Err(err) => editor.set_error(err.to_string()),\n    }\n}\n\nfn yank_joined(cx: &mut Context) {\n    let separator = doc!(cx.editor).line_ending.as_str();\n    yank_joined_impl(\n        cx.editor,\n        separator,\n        cx.register\n            .unwrap_or(cx.editor.config().default_yank_register),\n    );\n    exit_select_mode(cx);\n}\n\nfn yank_joined_to_clipboard(cx: &mut Context) {\n    let line_ending = doc!(cx.editor).line_ending;\n    yank_joined_impl(cx.editor, line_ending.as_str(), '+');\n    exit_select_mode(cx);\n}\n\nfn yank_joined_to_primary_clipboard(cx: &mut Context) {\n    let line_ending = doc!(cx.editor).line_ending;\n    yank_joined_impl(cx.editor, line_ending.as_str(), '*');\n    exit_select_mode(cx);\n}\n\npub(crate) fn yank_main_selection_to_register(editor: &mut Editor, register: char) {\n    let (view, doc) = current!(editor);\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id).primary().fragment(text).to_string();\n\n    match editor.registers.write(register, vec![selection]) {\n        Ok(_) => editor.set_status(format!(\"yanked primary selection to register {register}\",)),\n        Err(err) => editor.set_error(err.to_string()),\n    }\n}\n\nfn yank_main_selection_to_clipboard(cx: &mut Context) {\n    yank_main_selection_to_register(cx.editor, '+');\n    exit_select_mode(cx);\n}\n\nfn yank_main_selection_to_primary_clipboard(cx: &mut Context) {\n    yank_main_selection_to_register(cx.editor, '*');\n    exit_select_mode(cx);\n}\n\n#[derive(Copy, Clone)]\npub(crate) enum Paste {\n    Before,\n    After,\n    Cursor,\n}\n\nstatic LINE_ENDING_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r\"\\r\\n|\\r|\\n\").unwrap());\n\nfn paste_impl(\n    values: &[String],\n    doc: &mut Document,\n    view: &mut View,\n    action: Paste,\n    count: usize,\n    mode: Mode,\n) {\n    if values.is_empty() {\n        return;\n    }\n\n    if mode == Mode::Insert {\n        doc.append_changes_to_history(view);\n    }\n\n    // if any of values ends with a line ending, it's linewise paste\n    let linewise = values\n        .iter()\n        .any(|value| get_line_ending_of_str(value).is_some());\n\n    let map_value = |value| {\n        let value = LINE_ENDING_REGEX.replace_all(value, doc.line_ending.as_str());\n        let mut out = Tendril::from(value.as_ref());\n        for _ in 1..count {\n            out.push_str(&value);\n        }\n        out\n    };\n\n    let repeat = std::iter::repeat(\n        // `values` is asserted to have at least one entry above.\n        map_value(values.last().unwrap()),\n    );\n\n    let mut values = values.iter().map(|value| map_value(value)).chain(repeat);\n\n    let text = doc.text();\n    let selection = doc.selection(view.id);\n\n    let mut offset = 0;\n    let mut ranges = SmallVec::with_capacity(selection.len());\n\n    let mut transaction = Transaction::change_by_selection(text, selection, |range| {\n        let pos = match (action, linewise) {\n            // paste linewise before\n            (Paste::Before, true) => text.line_to_char(text.char_to_line(range.from())),\n            // paste linewise after\n            (Paste::After, true) => {\n                let line = range.line_range(text.slice(..)).1;\n                text.line_to_char((line + 1).min(text.len_lines()))\n            }\n            // paste insert\n            (Paste::Before, false) => range.from(),\n            // paste append\n            (Paste::After, false) => range.to(),\n            // paste at cursor\n            (Paste::Cursor, _) => range.cursor(text.slice(..)),\n        };\n\n        let value = values.next();\n\n        let value_len = value\n            .as_ref()\n            .map(|content| content.chars().count())\n            .unwrap_or_default();\n        let anchor = offset + pos;\n\n        let new_range = Range::new(anchor, anchor + value_len).with_direction(range.direction());\n        ranges.push(new_range);\n        offset += value_len;\n\n        (pos, pos, value)\n    });\n\n    if mode == Mode::Normal {\n        transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));\n    }\n\n    doc.apply(&transaction, view.id);\n    doc.append_changes_to_history(view);\n}\n\npub(crate) fn paste_bracketed_value(cx: &mut Context, contents: String) {\n    let count = cx.count();\n    let paste = match cx.editor.mode {\n        Mode::Insert | Mode::Select => Paste::Cursor,\n        Mode::Normal => Paste::Before,\n    };\n    let (view, doc) = current!(cx.editor);\n    paste_impl(&[contents], doc, view, paste, count, cx.editor.mode);\n    exit_select_mode(cx);\n}\n\nfn paste_clipboard_after(cx: &mut Context) {\n    paste(cx.editor, '+', Paste::After, cx.count());\n    exit_select_mode(cx);\n}\n\nfn paste_clipboard_before(cx: &mut Context) {\n    paste(cx.editor, '+', Paste::Before, cx.count());\n    exit_select_mode(cx);\n}\n\nfn paste_primary_clipboard_after(cx: &mut Context) {\n    paste(cx.editor, '*', Paste::After, cx.count());\n    exit_select_mode(cx);\n}\n\nfn paste_primary_clipboard_before(cx: &mut Context) {\n    paste(cx.editor, '*', Paste::Before, cx.count());\n    exit_select_mode(cx);\n}\n\nfn replace_with_yanked(cx: &mut Context) {\n    replace_selections_with_register(\n        cx.editor,\n        cx.editor.config().default_yank_register,\n        cx.count(),\n    );\n    exit_select_mode(cx);\n}\n\npub(crate) fn replace_selections_with_register(editor: &mut Editor, register: char, count: usize) {\n    let Some(values) = editor\n        .registers\n        .read(register, editor)\n        .filter(|values| values.len() > 0)\n    else {\n        return;\n    };\n    let scrolloff = editor.config().scrolloff;\n    let (view, doc) = current_ref!(editor);\n\n    let map_value = |value: &Cow<str>| {\n        let value = LINE_ENDING_REGEX.replace_all(value, doc.line_ending.as_str());\n        let mut out = Tendril::from(value.as_ref());\n        for _ in 1..count {\n            out.push_str(&value);\n        }\n        out\n    };\n    let mut values_rev = values.rev().peekable();\n    // `values` is asserted to have at least one entry above.\n    let last = values_rev.peek().unwrap();\n    let repeat = std::iter::repeat(map_value(last));\n    let mut values = values_rev\n        .rev()\n        .map(|value| map_value(&value))\n        .chain(repeat);\n    let selection = doc.selection(view.id);\n    let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {\n        if !range.is_empty() {\n            (range.from(), range.to(), Some(values.next().unwrap()))\n        } else {\n            (range.from(), range.to(), None)\n        }\n    });\n    drop(values);\n\n    let (view, doc) = current!(editor);\n    doc.apply(&transaction, view.id);\n    doc.append_changes_to_history(view);\n    view.ensure_cursor_in_view(doc, scrolloff);\n}\n\nfn replace_selections_with_clipboard(cx: &mut Context) {\n    replace_selections_with_register(cx.editor, '+', cx.count());\n    exit_select_mode(cx);\n}\n\nfn replace_selections_with_primary_clipboard(cx: &mut Context) {\n    replace_selections_with_register(cx.editor, '*', cx.count());\n    exit_select_mode(cx);\n}\n\npub(crate) fn paste(editor: &mut Editor, register: char, pos: Paste, count: usize) {\n    let Some(values) = editor.registers.read(register, editor) else {\n        return;\n    };\n    let values: Vec<_> = values.map(|value| value.to_string()).collect();\n\n    let (view, doc) = current!(editor);\n    paste_impl(&values, doc, view, pos, count, editor.mode);\n}\n\nfn paste_after(cx: &mut Context) {\n    paste(\n        cx.editor,\n        cx.register\n            .unwrap_or(cx.editor.config().default_yank_register),\n        Paste::After,\n        cx.count(),\n    );\n    exit_select_mode(cx);\n}\n\nfn paste_before(cx: &mut Context) {\n    paste(\n        cx.editor,\n        cx.register\n            .unwrap_or(cx.editor.config().default_yank_register),\n        Paste::Before,\n        cx.count(),\n    );\n    exit_select_mode(cx);\n}\n\nfn get_lines(doc: &Document, view_id: ViewId) -> Vec<usize> {\n    let mut lines = Vec::new();\n\n    // Get all line numbers\n    for range in doc.selection(view_id) {\n        let (start, end) = range.line_range(doc.text().slice(..));\n\n        for line in start..=end {\n            lines.push(line)\n        }\n    }\n    lines.sort_unstable(); // sorting by usize so _unstable is preferred\n    lines.dedup();\n    lines\n}\n\nfn indent(cx: &mut Context) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    let lines = get_lines(doc, view.id);\n\n    // Indent by one level\n    let indent = Tendril::from(doc.indent_style.as_str().repeat(count));\n\n    let transaction = Transaction::change(\n        doc.text(),\n        lines.into_iter().filter_map(|line| {\n            let is_blank = doc.text().line(line).chunks().all(|s| s.trim().is_empty());\n            if is_blank {\n                return None;\n            }\n            let pos = doc.text().line_to_char(line);\n\n            let indent = if let IndentStyle::Spaces(indent_width) = doc.indent_style {\n                let line = doc.text().line(line);\n                let offset = line.first_non_whitespace_char().unwrap_or(0) % indent_width as usize;\n                indent.clone().split_off(offset)\n            } else {\n                indent.clone()\n            };\n\n            Some((pos, pos, Some(indent)))\n        }),\n    );\n    doc.apply(&transaction, view.id);\n    exit_select_mode(cx);\n}\n\nfn unindent(cx: &mut Context) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    let lines = get_lines(doc, view.id);\n    let mut changes = Vec::with_capacity(lines.len());\n    let tab_width = doc.tab_width();\n    let indent_width = count * doc.indent_width();\n\n    for line_idx in lines {\n        let line = doc.text().line(line_idx);\n        let mut width = 0;\n        let mut pos = 0;\n\n        for ch in line.chars() {\n            match ch {\n                ' ' => width += 1,\n                '\\t' => width = (width / tab_width + 1) * tab_width,\n                _ => break,\n            }\n\n            pos += 1;\n\n            if width >= indent_width {\n                break;\n            }\n        }\n\n        // now delete from start to first non-blank\n        if pos > 0 {\n            let start = doc.text().line_to_char(line_idx);\n            changes.push((start, start + pos, None))\n        }\n    }\n\n    let transaction = Transaction::change(doc.text(), changes.into_iter());\n\n    doc.apply(&transaction, view.id);\n    exit_select_mode(cx);\n}\n\nfn format_selections(cx: &mut Context) {\n    use helix_lsp::{lsp, util::range_to_lsp_range};\n\n    let (view, doc) = current!(cx.editor);\n    let view_id = view.id;\n\n    // via lsp if available\n    // TODO: else via tree-sitter indentation calculations\n\n    if doc.selection(view_id).len() != 1 {\n        cx.editor\n            .set_error(\"format_selections only supports a single selection for now\");\n        return;\n    }\n\n    // TODO extra LanguageServerFeature::FormatSelections?\n    // maybe such that LanguageServerFeature::Format contains it as well\n    let Some(language_server) = doc\n        .language_servers_with_feature(LanguageServerFeature::Format)\n        .find(|ls| {\n            matches!(\n                ls.capabilities().document_range_formatting_provider,\n                Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_))\n            )\n        })\n    else {\n        cx.editor\n            .set_error(\"No configured language server supports range formatting\");\n        return;\n    };\n\n    let offset_encoding = language_server.offset_encoding();\n    let ranges: Vec<lsp::Range> = doc\n        .selection(view_id)\n        .iter()\n        .map(|range| range_to_lsp_range(doc.text(), *range, offset_encoding))\n        .collect();\n\n    // TODO: handle fails\n    // TODO: concurrent map over all ranges\n\n    let range = ranges[0];\n\n    let future = language_server\n        .text_document_range_formatting(\n            doc.identifier(),\n            range,\n            lsp::FormattingOptions {\n                tab_size: doc.tab_width() as u32,\n                insert_spaces: matches!(doc.indent_style, IndentStyle::Spaces(_)),\n                ..Default::default()\n            },\n            None,\n        )\n        .unwrap();\n\n    let text = doc.text().clone();\n    let doc_id = doc.id();\n    let doc_version = doc.version();\n\n    tokio::spawn(async move {\n        match future.await {\n            Ok(Some(res)) => {\n                let transaction =\n                    helix_lsp::util::generate_transaction_from_edits(&text, res, offset_encoding);\n                job::dispatch(move |editor, _compositor| {\n                    let Some(doc) = editor.document_mut(doc_id) else {\n                        return;\n                    };\n                    // Updating a desynced document causes problems with applying the transaction\n                    if doc.version() != doc_version {\n                        return;\n                    }\n                    doc.apply(&transaction, view_id);\n                })\n                .await\n            }\n            Err(err) => log::error!(\"format sections failed: {err}\"),\n            Ok(None) => (),\n        }\n    });\n}\n\nfn join_selections_impl(cx: &mut Context, select_space: bool) {\n    use movement::skip_while;\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text();\n    let slice = text.slice(..);\n\n    let comment_tokens = doc\n        .language_config()\n        .and_then(|config| config.comment_tokens.as_deref())\n        .unwrap_or(&[]);\n    // Sort by length to handle Rust's /// vs //\n    let mut comment_tokens: Vec<&str> = comment_tokens.iter().map(|x| x.as_str()).collect();\n    comment_tokens.sort_unstable_by_key(|x| std::cmp::Reverse(x.len()));\n\n    let mut changes = Vec::new();\n\n    for selection in doc.selection(view.id) {\n        let (start, mut end) = selection.line_range(slice);\n        if start == end {\n            end = (end + 1).min(text.len_lines() - 1);\n        }\n        let lines = start..end;\n\n        changes.reserve(lines.len());\n\n        let first_line_idx = slice.line_to_char(start);\n        let first_line_idx = skip_while(slice, first_line_idx, |ch| matches!(ch, ' ' | '\\t'))\n            .unwrap_or(first_line_idx);\n        let first_line = slice.slice(first_line_idx..);\n        let mut current_comment_token = comment_tokens\n            .iter()\n            .find(|token| first_line.starts_with(token));\n\n        for line in lines {\n            let start = line_end_char_index(&slice, line);\n            let mut end = text.line_to_char(line + 1);\n            end = skip_while(slice, end, |ch| matches!(ch, ' ' | '\\t')).unwrap_or(end);\n            let slice_from_end = slice.slice(end..);\n            if let Some(token) = comment_tokens\n                .iter()\n                .find(|token| slice_from_end.starts_with(token))\n            {\n                if Some(token) == current_comment_token {\n                    end += token.chars().count();\n                    end = skip_while(slice, end, |ch| matches!(ch, ' ' | '\\t')).unwrap_or(end);\n                } else {\n                    // update current token, but don't delete this one.\n                    current_comment_token = Some(token);\n                }\n            }\n\n            let separator = if end == line_end_char_index(&slice, line + 1) {\n                // the joining line contains only space-characters => don't include a whitespace when joining\n                None\n            } else {\n                Some(Tendril::from(\" \"))\n            };\n            changes.push((start, end, separator));\n        }\n    }\n\n    // nothing to do, bail out early to avoid crashes later\n    if changes.is_empty() {\n        return;\n    }\n\n    changes.sort_unstable_by_key(|(from, _to, _text)| *from);\n    changes.dedup();\n\n    // select inserted spaces\n    let transaction = if select_space {\n        let mut offset: usize = 0;\n        let ranges: SmallVec<_> = changes\n            .iter()\n            .filter_map(|change| {\n                if change.2.is_some() {\n                    let range = Range::point(change.0 - offset);\n                    offset += change.1 - change.0 - 1; // -1 adjusts for the replacement of the range by a space\n                    Some(range)\n                } else {\n                    offset += change.1 - change.0;\n                    None\n                }\n            })\n            .collect();\n        let t = Transaction::change(text, changes.into_iter());\n        if ranges.is_empty() {\n            t\n        } else {\n            let selection = Selection::new(ranges, 0);\n            t.with_selection(selection)\n        }\n    } else {\n        Transaction::change(text, changes.into_iter())\n    };\n\n    doc.apply(&transaction, view.id);\n}\n\nfn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) {\n    // keep or remove selections matching regex\n    let reg = cx.register.unwrap_or('/');\n    ui::regex_prompt(\n        cx,\n        if remove { \"remove:\" } else { \"keep:\" }.into(),\n        Some(reg),\n        ui::completers::none,\n        move |cx, regex, event| {\n            let (view, doc) = current!(cx.editor);\n            if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {\n                return;\n            }\n            let text = doc.text().slice(..);\n\n            if let Some(selection) =\n                selection::keep_or_remove_matches(text, doc.selection(view.id), &regex, remove)\n            {\n                doc.set_selection(view.id, selection);\n            } else if event == PromptEvent::Validate {\n                cx.editor.set_error(\"no selections remaining\");\n            }\n        },\n    )\n}\n\nfn join_selections(cx: &mut Context) {\n    join_selections_impl(cx, false)\n}\n\nfn join_selections_space(cx: &mut Context) {\n    join_selections_impl(cx, true)\n}\n\nfn keep_selections(cx: &mut Context) {\n    keep_or_remove_selections_impl(cx, false)\n}\n\nfn remove_selections(cx: &mut Context) {\n    keep_or_remove_selections_impl(cx, true)\n}\n\nfn keep_primary_selection(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    // TODO: handle count\n\n    let range = doc.selection(view.id).primary();\n    doc.set_selection(view.id, Selection::single(range.anchor, range.head));\n}\n\nfn remove_primary_selection(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    // TODO: handle count\n\n    let selection = doc.selection(view.id);\n    if selection.len() == 1 {\n        cx.editor.set_error(\"no selections remaining\");\n        return;\n    }\n    let index = selection.primary_index();\n    let selection = selection.clone().remove(index);\n\n    doc.set_selection(view.id, selection);\n}\n\npub fn completion(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let range = doc.selection(view.id).primary();\n    let text = doc.text().slice(..);\n    let cursor = range.cursor(text);\n\n    cx.editor\n        .handlers\n        .trigger_completions(cursor, doc.id(), view.id);\n}\n\n// comments\ntype CommentTransactionFn = fn(\n    line_token: Option<&str>,\n    block_tokens: Option<&[BlockCommentToken]>,\n    doc: &Rope,\n    selection: &Selection,\n) -> Transaction;\n\nfn toggle_comments_impl(cx: &mut Context, comment_transaction: CommentTransactionFn) {\n    let (view, doc) = current!(cx.editor);\n    let line_token: Option<&str> = doc\n        .language_config()\n        .and_then(|lc| lc.comment_tokens.as_ref())\n        .and_then(|tc| tc.first())\n        .map(|tc| tc.as_str());\n    let block_tokens: Option<&[BlockCommentToken]> = doc\n        .language_config()\n        .and_then(|lc| lc.block_comment_tokens.as_ref())\n        .map(|tc| &tc[..]);\n\n    let transaction =\n        comment_transaction(line_token, block_tokens, doc.text(), doc.selection(view.id));\n\n    doc.apply(&transaction, view.id);\n    exit_select_mode(cx);\n}\n\n/// commenting behavior:\n/// 1. only line comment tokens -> line comment\n/// 2. each line block commented -> uncomment all lines\n/// 3. whole selection block commented -> uncomment selection\n/// 4. all lines not commented and block tokens -> comment uncommented lines\n/// 5. no comment tokens and not block commented -> line comment\nfn toggle_comments(cx: &mut Context) {\n    toggle_comments_impl(cx, |line_token, block_tokens, doc, selection| {\n        let text = doc.slice(..);\n\n        // only have line comment tokens\n        if line_token.is_some() && block_tokens.is_none() {\n            return comment::toggle_line_comments(doc, selection, line_token);\n        }\n\n        let split_lines = comment::split_lines_of_selection(text, selection);\n\n        let default_block_tokens = &[BlockCommentToken::default()];\n        let block_comment_tokens = block_tokens.unwrap_or(default_block_tokens);\n\n        let (line_commented, line_comment_changes) =\n            comment::find_block_comments(block_comment_tokens, text, &split_lines);\n\n        // block commented by line would also be block commented so check this first\n        if line_commented {\n            return comment::create_block_comment_transaction(\n                doc,\n                &split_lines,\n                line_commented,\n                line_comment_changes,\n            )\n            .0;\n        }\n\n        let (block_commented, comment_changes) =\n            comment::find_block_comments(block_comment_tokens, text, selection);\n\n        // check if selection has block comments\n        if block_commented {\n            return comment::create_block_comment_transaction(\n                doc,\n                selection,\n                block_commented,\n                comment_changes,\n            )\n            .0;\n        }\n\n        // not commented and only have block comment tokens\n        if line_token.is_none() && block_tokens.is_some() {\n            return comment::create_block_comment_transaction(\n                doc,\n                &split_lines,\n                line_commented,\n                line_comment_changes,\n            )\n            .0;\n        }\n\n        // not block commented at all and don't have any tokens\n        comment::toggle_line_comments(doc, selection, line_token)\n    })\n}\n\nfn toggle_line_comments(cx: &mut Context) {\n    toggle_comments_impl(cx, |line_token, block_tokens, doc, selection| {\n        if line_token.is_none() && block_tokens.is_some() {\n            let default_block_tokens = &[BlockCommentToken::default()];\n            let block_comment_tokens = block_tokens.unwrap_or(default_block_tokens);\n            comment::toggle_block_comments(\n                doc,\n                &comment::split_lines_of_selection(doc.slice(..), selection),\n                block_comment_tokens,\n            )\n        } else {\n            comment::toggle_line_comments(doc, selection, line_token)\n        }\n    });\n}\n\nfn toggle_block_comments(cx: &mut Context) {\n    toggle_comments_impl(cx, |line_token, block_tokens, doc, selection| {\n        if line_token.is_some() && block_tokens.is_none() {\n            comment::toggle_line_comments(doc, selection, line_token)\n        } else {\n            let default_block_tokens = &[BlockCommentToken::default()];\n            let block_comment_tokens = block_tokens.unwrap_or(default_block_tokens);\n            comment::toggle_block_comments(doc, selection, block_comment_tokens)\n        }\n    });\n}\n\nfn rotate_selections(cx: &mut Context, direction: Direction) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    let mut selection = doc.selection(view.id).clone();\n    let index = selection.primary_index();\n    let len = selection.len();\n    selection.set_primary_index(match direction {\n        Direction::Forward => (index + count) % len,\n        Direction::Backward => (index + (len.saturating_sub(count) % len)) % len,\n    });\n    doc.set_selection(view.id, selection);\n}\nfn rotate_selections_forward(cx: &mut Context) {\n    rotate_selections(cx, Direction::Forward)\n}\nfn rotate_selections_backward(cx: &mut Context) {\n    rotate_selections(cx, Direction::Backward)\n}\n\nfn rotate_selections_first(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let mut selection = doc.selection(view.id).clone();\n    selection.set_primary_index(0);\n    doc.set_selection(view.id, selection);\n}\n\nfn rotate_selections_last(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let mut selection = doc.selection(view.id).clone();\n    let len = selection.len();\n    selection.set_primary_index(len - 1);\n    doc.set_selection(view.id, selection);\n}\n\n#[derive(Debug)]\nenum ReorderStrategy {\n    RotateForward,\n    RotateBackward,\n    Reverse,\n}\n\nfn reorder_selection_contents(cx: &mut Context, strategy: ReorderStrategy) {\n    let count = cx.count;\n    let (view, doc) = current!(cx.editor);\n    let text = doc.text().slice(..);\n\n    let selection = doc.selection(view.id);\n\n    let mut ranges: Vec<_> = selection\n        .slices(text)\n        .map(|fragment| fragment.chunks().collect())\n        .collect();\n\n    let rotate_by = count.map_or(1, |count| count.get().min(ranges.len()));\n\n    let primary_index = match strategy {\n        ReorderStrategy::RotateForward => {\n            ranges.rotate_right(rotate_by);\n            // Like `usize::wrapping_add`, but provide a custom range from `0` to `ranges.len()`\n            (selection.primary_index() + ranges.len() + rotate_by) % ranges.len()\n        }\n        ReorderStrategy::RotateBackward => {\n            ranges.rotate_left(rotate_by);\n            // Like `usize::wrapping_sub`, but provide a custom range from `0` to `ranges.len()`\n            (selection.primary_index() + ranges.len() - rotate_by) % ranges.len()\n        }\n        ReorderStrategy::Reverse => {\n            if rotate_by.is_multiple_of(2) {\n                // nothing changed, if we reverse something an even\n                // amount of times, the output will be the same\n                return;\n            }\n            ranges.reverse();\n            // -1 to turn 1-based len into 0-based index\n            (ranges.len() - 1) - selection.primary_index()\n        }\n    };\n\n    let transaction = Transaction::change(\n        doc.text(),\n        selection\n            .ranges()\n            .iter()\n            .zip(ranges)\n            .map(|(range, fragment)| (range.from(), range.to(), Some(fragment))),\n    );\n\n    doc.set_selection(\n        view.id,\n        Selection::new(selection.ranges().into(), primary_index),\n    );\n    doc.apply(&transaction, view.id);\n}\n\nfn rotate_selection_contents_forward(cx: &mut Context) {\n    reorder_selection_contents(cx, ReorderStrategy::RotateForward)\n}\nfn rotate_selection_contents_backward(cx: &mut Context) {\n    reorder_selection_contents(cx, ReorderStrategy::RotateBackward)\n}\nfn reverse_selection_contents(cx: &mut Context) {\n    reorder_selection_contents(cx, ReorderStrategy::Reverse)\n}\n\n// tree sitter node selection\n\nfn expand_selection(cx: &mut Context) {\n    let motion = |editor: &mut Editor| {\n        let (view, doc) = current!(editor);\n\n        if let Some(syntax) = doc.syntax() {\n            let text = doc.text().slice(..);\n\n            let current_selection = doc.selection(view.id);\n            let selection = object::expand_selection(syntax, text, current_selection.clone());\n\n            // check if selection is different from the last one\n            if *current_selection != selection {\n                // save current selection so it can be restored using shrink_selection\n                view.object_selections.push(current_selection.clone());\n\n                doc.set_selection(view.id, selection);\n            }\n        }\n    };\n    cx.editor.apply_motion(motion);\n}\n\nfn shrink_selection(cx: &mut Context) {\n    let motion = |editor: &mut Editor| {\n        let (view, doc) = current!(editor);\n        let current_selection = doc.selection(view.id);\n        // try to restore previous selection\n        if let Some(prev_selection) = view.object_selections.pop() {\n            if current_selection.contains(&prev_selection) {\n                doc.set_selection(view.id, prev_selection);\n                return;\n            } else {\n                // clear existing selection as they can't be shrunk to anyway\n                view.object_selections.clear();\n            }\n        }\n        // if not previous selection, shrink to first child\n        if let Some(syntax) = doc.syntax() {\n            let text = doc.text().slice(..);\n            let selection = object::shrink_selection(syntax, text, current_selection.clone());\n            doc.set_selection(view.id, selection);\n        }\n    };\n    cx.editor.apply_motion(motion);\n}\n\nfn select_sibling_impl<F>(cx: &mut Context, sibling_fn: F)\nwhere\n    F: Fn(&helix_core::Syntax, RopeSlice, Selection) -> Selection + 'static,\n{\n    let motion = move |editor: &mut Editor| {\n        let (view, doc) = current!(editor);\n\n        if let Some(syntax) = doc.syntax() {\n            let text = doc.text().slice(..);\n            let current_selection = doc.selection(view.id);\n            let selection = sibling_fn(syntax, text, current_selection.clone());\n            doc.set_selection(view.id, selection);\n        }\n    };\n    cx.editor.apply_motion(motion);\n}\n\nfn select_next_sibling(cx: &mut Context) {\n    select_sibling_impl(cx, object::select_next_sibling)\n}\n\nfn select_prev_sibling(cx: &mut Context) {\n    select_sibling_impl(cx, object::select_prev_sibling)\n}\n\nfn move_node_bound_impl(cx: &mut Context, dir: Direction, movement: Movement) {\n    let motion = move |editor: &mut Editor| {\n        let (view, doc) = current!(editor);\n\n        if let Some(syntax) = doc.syntax() {\n            let text = doc.text().slice(..);\n            let current_selection = doc.selection(view.id);\n\n            let selection = movement::move_parent_node_end(\n                syntax,\n                text,\n                current_selection.clone(),\n                dir,\n                movement,\n            );\n\n            doc.set_selection(view.id, selection);\n        }\n    };\n\n    cx.editor.apply_motion(motion);\n}\n\npub fn move_parent_node_end(cx: &mut Context) {\n    move_node_bound_impl(cx, Direction::Forward, Movement::Move)\n}\n\npub fn move_parent_node_start(cx: &mut Context) {\n    move_node_bound_impl(cx, Direction::Backward, Movement::Move)\n}\n\npub fn extend_parent_node_end(cx: &mut Context) {\n    move_node_bound_impl(cx, Direction::Forward, Movement::Extend)\n}\n\npub fn extend_parent_node_start(cx: &mut Context) {\n    move_node_bound_impl(cx, Direction::Backward, Movement::Extend)\n}\n\nfn select_all_impl<F>(editor: &mut Editor, select_fn: F)\nwhere\n    F: Fn(&Syntax, RopeSlice, Selection) -> Selection,\n{\n    let (view, doc) = current!(editor);\n\n    if let Some(syntax) = doc.syntax() {\n        let text = doc.text().slice(..);\n        let current_selection = doc.selection(view.id);\n        let selection = select_fn(syntax, text, current_selection.clone());\n        doc.set_selection(view.id, selection);\n    }\n}\n\nfn select_all_siblings(cx: &mut Context) {\n    let motion = |editor: &mut Editor| {\n        select_all_impl(editor, object::select_all_siblings);\n    };\n\n    cx.editor.apply_motion(motion);\n}\n\nfn select_all_children(cx: &mut Context) {\n    let motion = |editor: &mut Editor| {\n        select_all_impl(editor, object::select_all_children);\n    };\n\n    cx.editor.apply_motion(motion);\n}\n\nfn match_brackets(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let is_select = cx.editor.mode == Mode::Select;\n    let text = doc.text();\n    let text_slice = text.slice(..);\n\n    let selection = doc.selection(view.id).clone().transform(|range| {\n        let pos = range.cursor(text_slice);\n        if let Some(matched_pos) = doc.syntax().map_or_else(\n            || match_brackets::find_matching_bracket_plaintext(text.slice(..), pos),\n            |syntax| match_brackets::find_matching_bracket_fuzzy(syntax, text.slice(..), pos),\n        ) {\n            range.put_cursor(text_slice, matched_pos, is_select)\n        } else {\n            range\n        }\n    });\n\n    doc.set_selection(view.id, selection);\n}\n\n//\n\nfn jump_forward(cx: &mut Context) {\n    cx.editor.jump_forward(cx.editor.tree.focus, cx.count());\n}\n\nfn jump_backward(cx: &mut Context) {\n    cx.editor.jump_backward(cx.editor.tree.focus, cx.count());\n}\n\nfn save_selection(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    push_jump(view, doc);\n    cx.editor.set_status(\"Selection saved to jumplist\");\n}\n\nfn rotate_view(cx: &mut Context) {\n    cx.editor.focus_next()\n}\n\nfn rotate_view_reverse(cx: &mut Context) {\n    cx.editor.focus_prev()\n}\n\nfn jump_view_right(cx: &mut Context) {\n    cx.editor.focus_direction(tree::Direction::Right)\n}\n\nfn jump_view_left(cx: &mut Context) {\n    cx.editor.focus_direction(tree::Direction::Left)\n}\n\nfn jump_view_up(cx: &mut Context) {\n    cx.editor.focus_direction(tree::Direction::Up)\n}\n\nfn jump_view_down(cx: &mut Context) {\n    cx.editor.focus_direction(tree::Direction::Down)\n}\n\nfn swap_view_right(cx: &mut Context) {\n    cx.editor.swap_split_in_direction(tree::Direction::Right)\n}\n\nfn swap_view_left(cx: &mut Context) {\n    cx.editor.swap_split_in_direction(tree::Direction::Left)\n}\n\nfn swap_view_up(cx: &mut Context) {\n    cx.editor.swap_split_in_direction(tree::Direction::Up)\n}\n\nfn swap_view_down(cx: &mut Context) {\n    cx.editor.swap_split_in_direction(tree::Direction::Down)\n}\n\nfn transpose_view(cx: &mut Context) {\n    cx.editor.transpose_view()\n}\n\n/// Open a new split in the given direction specified by the action.\n///\n/// Maintain the current view (both the cursor's position and view in document).\nfn split(editor: &mut Editor, action: Action) {\n    let (view, doc) = current!(editor);\n    let id = doc.id();\n    let selection = doc.selection(view.id).clone();\n    let offset = doc.view_offset(view.id);\n\n    editor.switch(id, action);\n\n    // match the selection in the previous view\n    let (view, doc) = current!(editor);\n    doc.set_selection(view.id, selection);\n    // match the view scroll offset (switch doesn't handle this fully\n    // since the selection is only matched after the split)\n    doc.set_view_offset(view.id, offset);\n}\n\nfn hsplit(cx: &mut Context) {\n    split(cx.editor, Action::HorizontalSplit);\n}\n\nfn hsplit_new(cx: &mut Context) {\n    cx.editor.new_file(Action::HorizontalSplit);\n}\n\nfn vsplit(cx: &mut Context) {\n    split(cx.editor, Action::VerticalSplit);\n}\n\nfn vsplit_new(cx: &mut Context) {\n    cx.editor.new_file(Action::VerticalSplit);\n}\n\nfn wclose(cx: &mut Context) {\n    if cx.editor.tree.views().count() == 1 {\n        if let Err(err) = typed::buffers_remaining_impl(cx.editor) {\n            cx.editor.set_error(err.to_string());\n            return;\n        }\n    }\n    let view_id = view!(cx.editor).id;\n    // close current split\n    cx.editor.close(view_id);\n}\n\nfn wonly(cx: &mut Context) {\n    let views = cx\n        .editor\n        .tree\n        .views()\n        .map(|(v, focus)| (v.id, focus))\n        .collect::<Vec<_>>();\n    for (view_id, focus) in views {\n        if !focus {\n            cx.editor.close(view_id);\n        }\n    }\n}\n\nfn select_register(cx: &mut Context) {\n    cx.editor.autoinfo = Some(Info::from_registers(\n        \"Select register\",\n        &cx.editor.registers,\n    ));\n    cx.on_next_key(move |cx, event| {\n        cx.editor.autoinfo = None;\n        if let Some(ch) = event.char() {\n            cx.editor.selected_register = Some(ch);\n        }\n    })\n}\n\nfn insert_register(cx: &mut Context) {\n    cx.editor.autoinfo = Some(Info::from_registers(\n        \"Insert register\",\n        &cx.editor.registers,\n    ));\n    cx.on_next_key(move |cx, event| {\n        cx.editor.autoinfo = None;\n        if let Some(ch) = event.char() {\n            cx.register = Some(ch);\n            paste(\n                cx.editor,\n                cx.register\n                    .unwrap_or(cx.editor.config().default_yank_register),\n                Paste::Cursor,\n                cx.count(),\n            );\n        }\n    })\n}\n\nfn copy_between_registers(cx: &mut Context) {\n    cx.editor.autoinfo = Some(Info::from_registers(\n        \"Copy from register\",\n        &cx.editor.registers,\n    ));\n    cx.on_next_key(move |cx, event| {\n        cx.editor.autoinfo = None;\n\n        let Some(source) = event.char() else {\n            return;\n        };\n\n        let Some(values) = cx.editor.registers.read(source, cx.editor) else {\n            cx.editor.set_error(format!(\"register {source} is empty\"));\n            return;\n        };\n        let values: Vec<_> = values.map(|value| value.to_string()).collect();\n\n        cx.editor.autoinfo = Some(Info::from_registers(\n            \"Copy into register\",\n            &cx.editor.registers,\n        ));\n        cx.on_next_key(move |cx, event| {\n            cx.editor.autoinfo = None;\n\n            let Some(dest) = event.char() else {\n                return;\n            };\n\n            let n_values = values.len();\n            match cx.editor.registers.write(dest, values) {\n                Ok(_) => cx.editor.set_status(format!(\n                    \"yanked {n_values} value{} from register {source} to {dest}\",\n                    if n_values == 1 { \"\" } else { \"s\" }\n                )),\n                Err(err) => cx.editor.set_error(err.to_string()),\n            }\n        });\n    });\n}\n\nfn align_view_top(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    align_view(doc, view, Align::Top);\n}\n\nfn align_view_center(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    align_view(doc, view, Align::Center);\n}\n\nfn align_view_bottom(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    align_view(doc, view, Align::Bottom);\n}\n\nfn align_view_middle(cx: &mut Context) {\n    let (view, doc) = current!(cx.editor);\n    let inner_width = view.inner_width(doc);\n    let text_fmt = doc.text_format(inner_width, None);\n    // there is no horizontal position when softwrap is enabled\n    if text_fmt.soft_wrap {\n        return;\n    }\n    let doc_text = doc.text().slice(..);\n    let pos = doc.selection(view.id).primary().cursor(doc_text);\n    let pos = visual_offset_from_block(\n        doc_text,\n        doc.view_offset(view.id).anchor,\n        pos,\n        &text_fmt,\n        &view.text_annotations(doc, None),\n    )\n    .0;\n\n    let mut offset = doc.view_offset(view.id);\n    offset.horizontal_offset = pos\n        .col\n        .saturating_sub((view.inner_area(doc).width as usize) / 2);\n    doc.set_view_offset(view.id, offset);\n}\n\nfn scroll_up(cx: &mut Context) {\n    scroll(cx, cx.count(), Direction::Backward, false);\n}\n\nfn scroll_down(cx: &mut Context) {\n    scroll(cx, cx.count(), Direction::Forward, false);\n}\n\nfn goto_ts_object_impl(cx: &mut Context, object: &'static str, direction: Direction) {\n    let count = cx.count();\n    let motion = move |editor: &mut Editor| {\n        let (view, doc) = current!(editor);\n        let loader = editor.syn_loader.load();\n        if let Some(syntax) = doc.syntax() {\n            let text = doc.text().slice(..);\n            let root = syntax.tree().root_node();\n\n            let selection = doc.selection(view.id).clone().transform(|range| {\n                let new_range = movement::goto_treesitter_object(\n                    text, range, object, direction, &root, syntax, &loader, count,\n                );\n\n                if editor.mode == Mode::Select {\n                    let head = if new_range.head < range.anchor {\n                        new_range.anchor\n                    } else {\n                        new_range.head\n                    };\n\n                    Range::new(range.anchor, head)\n                } else {\n                    new_range.with_direction(direction)\n                }\n            });\n\n            push_jump(view, doc);\n            doc.set_selection(view.id, selection);\n        } else {\n            editor.set_status(\"Syntax-tree is not available in current buffer\");\n        }\n    };\n    cx.editor.apply_motion(motion);\n}\n\nfn goto_next_function(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"function\", Direction::Forward)\n}\n\nfn goto_prev_function(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"function\", Direction::Backward)\n}\n\nfn goto_next_class(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"class\", Direction::Forward)\n}\n\nfn goto_prev_class(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"class\", Direction::Backward)\n}\n\nfn goto_next_parameter(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"parameter\", Direction::Forward)\n}\n\nfn goto_prev_parameter(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"parameter\", Direction::Backward)\n}\n\nfn goto_next_comment(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"comment\", Direction::Forward)\n}\n\nfn goto_prev_comment(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"comment\", Direction::Backward)\n}\n\nfn goto_next_test(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"test\", Direction::Forward)\n}\n\nfn goto_prev_test(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"test\", Direction::Backward)\n}\n\nfn goto_next_xml_element(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"xml-element\", Direction::Forward)\n}\n\nfn goto_prev_xml_element(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"xml-element\", Direction::Backward)\n}\n\nfn goto_next_entry(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"entry\", Direction::Forward)\n}\n\nfn goto_prev_entry(cx: &mut Context) {\n    goto_ts_object_impl(cx, \"entry\", Direction::Backward)\n}\n\nfn select_textobject_around(cx: &mut Context) {\n    select_textobject(cx, textobject::TextObject::Around);\n}\n\nfn select_textobject_inner(cx: &mut Context) {\n    select_textobject(cx, textobject::TextObject::Inside);\n}\n\nfn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {\n    let count = cx.count();\n\n    cx.on_next_key(move |cx, event| {\n        cx.editor.autoinfo = None;\n        if let Some(ch) = event.char() {\n            let textobject = move |editor: &mut Editor| {\n                let (view, doc) = current!(editor);\n                let loader = editor.syn_loader.load();\n                let text = doc.text().slice(..);\n\n                let textobject_treesitter = |obj_name: &str, range: Range| -> Range {\n                    let Some(syntax) = doc.syntax() else {\n                        return range;\n                    };\n                    textobject::textobject_treesitter(\n                        text, range, objtype, obj_name, syntax, &loader, count,\n                    )\n                };\n\n                if ch == 'g' && doc.diff_handle().is_none() {\n                    editor.set_status(\"Diff is not available in current buffer\");\n                    return;\n                }\n\n                let textobject_change = |range: Range| -> Range {\n                    let diff_handle = doc.diff_handle().unwrap();\n                    let diff = diff_handle.load();\n                    let line = range.cursor_line(text);\n                    let hunk_idx = if let Some(hunk_idx) = diff.hunk_at(line as u32, false) {\n                        hunk_idx\n                    } else {\n                        return range;\n                    };\n                    let hunk = diff.nth_hunk(hunk_idx).after;\n\n                    let start = text.line_to_char(hunk.start as usize);\n                    let end = text.line_to_char(hunk.end as usize);\n                    Range::new(start, end).with_direction(range.direction())\n                };\n\n                let selection = doc.selection(view.id).clone().transform(|range| {\n                    match ch {\n                        'w' => textobject::textobject_word(text, range, objtype, count, false),\n                        'W' => textobject::textobject_word(text, range, objtype, count, true),\n                        't' => textobject_treesitter(\"class\", range),\n                        'f' => textobject_treesitter(\"function\", range),\n                        'a' => textobject_treesitter(\"parameter\", range),\n                        'c' => textobject_treesitter(\"comment\", range),\n                        'T' => textobject_treesitter(\"test\", range),\n                        'e' => textobject_treesitter(\"entry\", range),\n                        'x' => textobject_treesitter(\"xml-element\", range),\n                        'p' => textobject::textobject_paragraph(text, range, objtype, count),\n                        'm' => textobject::textobject_pair_surround_closest(\n                            doc.syntax(),\n                            text,\n                            range,\n                            objtype,\n                            count,\n                        ),\n                        'g' => textobject_change(range),\n                        // TODO: cancel new ranges if inconsistent surround matches across lines\n                        ch if !ch.is_ascii_alphanumeric() => textobject::textobject_pair_surround(\n                            doc.syntax(),\n                            text,\n                            range,\n                            objtype,\n                            ch,\n                            count,\n                        ),\n                        _ => range,\n                    }\n                });\n                doc.set_selection(view.id, selection);\n            };\n            cx.editor.apply_motion(textobject);\n        }\n    });\n\n    let title = match objtype {\n        textobject::TextObject::Inside => \"Match inside\",\n        textobject::TextObject::Around => \"Match around\",\n        _ => return,\n    };\n    let help_text = [\n        (\"w\", \"Word\"),\n        (\"W\", \"WORD\"),\n        (\"p\", \"Paragraph\"),\n        (\"t\", \"Type definition (tree-sitter)\"),\n        (\"f\", \"Function (tree-sitter)\"),\n        (\"a\", \"Argument/parameter (tree-sitter)\"),\n        (\"c\", \"Comment (tree-sitter)\"),\n        (\"T\", \"Test (tree-sitter)\"),\n        (\"e\", \"Data structure entry (tree-sitter)\"),\n        (\"m\", \"Closest surrounding pair (tree-sitter)\"),\n        (\"g\", \"Change\"),\n        (\"x\", \"(X)HTML element (tree-sitter)\"),\n        (\" \", \"... or any character acting as a pair\"),\n    ];\n\n    cx.editor.autoinfo = Some(Info::new(title, &help_text));\n}\n\nstatic SURROUND_HELP_TEXT: [(&str, &str); 6] = [\n    (\"m\", \"Nearest matching pair\"),\n    (\"( or )\", \"Parentheses\"),\n    (\"{ or }\", \"Curly braces\"),\n    (\"< or >\", \"Angled brackets\"),\n    (\"[ or ]\", \"Square brackets\"),\n    (\" \", \"... or any character\"),\n];\n\nfn surround_add(cx: &mut Context) {\n    cx.on_next_key(move |cx, event| {\n        cx.editor.autoinfo = None;\n        let (view, doc) = current!(cx.editor);\n        // surround_len is the number of new characters being added.\n        let (open, close, surround_len) = match event.char() {\n            Some(ch) => {\n                let (o, c) = match_brackets::get_pair(ch);\n                let mut open = Tendril::new();\n                open.push(o);\n                let mut close = Tendril::new();\n                close.push(c);\n                (open, close, 2)\n            }\n            None if event.code == KeyCode::Enter => (\n                doc.line_ending.as_str().into(),\n                doc.line_ending.as_str().into(),\n                2 * doc.line_ending.len_chars(),\n            ),\n            None => return,\n        };\n\n        let selection = doc.selection(view.id);\n        let mut changes = Vec::with_capacity(selection.len() * 2);\n        let mut ranges = SmallVec::with_capacity(selection.len());\n        let mut offs = 0;\n\n        for range in selection.iter() {\n            changes.push((range.from(), range.from(), Some(open.clone())));\n            changes.push((range.to(), range.to(), Some(close.clone())));\n\n            ranges.push(\n                Range::new(offs + range.from(), offs + range.to() + surround_len)\n                    .with_direction(range.direction()),\n            );\n\n            offs += surround_len;\n        }\n\n        let transaction = Transaction::change(doc.text(), changes.into_iter())\n            .with_selection(Selection::new(ranges, selection.primary_index()));\n        doc.apply(&transaction, view.id);\n        exit_select_mode(cx);\n    });\n\n    cx.editor.autoinfo = Some(Info::new(\n        \"Surround selections with\",\n        &SURROUND_HELP_TEXT[1..],\n    ));\n}\n\nfn surround_replace(cx: &mut Context) {\n    let count = cx.count();\n    cx.on_next_key(move |cx, event| {\n        cx.editor.autoinfo = None;\n        let surround_ch = match event.char() {\n            Some('m') => None, // m selects the closest surround pair\n            Some(ch) => Some(ch),\n            None => return,\n        };\n        let (view, doc) = current!(cx.editor);\n        let text = doc.text().slice(..);\n        let selection = doc.selection(view.id);\n\n        let change_pos =\n            match surround::get_surround_pos(doc.syntax(), text, selection, surround_ch, count) {\n                Ok(c) => c,\n                Err(err) => {\n                    cx.editor.set_error(err.to_string());\n                    return;\n                }\n            };\n\n        let selection = selection.clone();\n        let ranges: SmallVec<[Range; 1]> = change_pos.iter().map(|&p| Range::point(p)).collect();\n        doc.set_selection(\n            view.id,\n            Selection::new(ranges, selection.primary_index() * 2),\n        );\n\n        cx.on_next_key(move |cx, event| {\n            cx.editor.autoinfo = None;\n            let (view, doc) = current!(cx.editor);\n            let to = match event.char() {\n                Some(to) => to,\n                None => return doc.set_selection(view.id, selection),\n            };\n            let (open, close) = match_brackets::get_pair(to);\n\n            // the changeset has to be sorted to allow nested surrounds\n            let mut sorted_pos: Vec<(usize, char)> = Vec::new();\n            for p in change_pos.chunks(2) {\n                sorted_pos.push((p[0], open));\n                sorted_pos.push((p[1], close));\n            }\n            sorted_pos.sort_unstable();\n\n            let transaction = Transaction::change(\n                doc.text(),\n                sorted_pos.iter().map(|&pos| {\n                    let mut t = Tendril::new();\n                    t.push(pos.1);\n                    (pos.0, pos.0 + 1, Some(t))\n                }),\n            );\n            doc.set_selection(view.id, selection);\n            doc.apply(&transaction, view.id);\n            exit_select_mode(cx);\n        });\n\n        cx.editor.autoinfo = Some(Info::new(\n            \"Replace with a pair of\",\n            &SURROUND_HELP_TEXT[1..],\n        ));\n    });\n\n    cx.editor.autoinfo = Some(Info::new(\n        \"Replace surrounding pair of\",\n        &SURROUND_HELP_TEXT,\n    ));\n}\n\nfn surround_delete(cx: &mut Context) {\n    let count = cx.count();\n    cx.on_next_key(move |cx, event| {\n        cx.editor.autoinfo = None;\n        let surround_ch = match event.char() {\n            Some('m') => None, // m selects the closest surround pair\n            Some(ch) => Some(ch),\n            None => return,\n        };\n        let (view, doc) = current!(cx.editor);\n        let text = doc.text().slice(..);\n        let selection = doc.selection(view.id);\n\n        let mut change_pos =\n            match surround::get_surround_pos(doc.syntax(), text, selection, surround_ch, count) {\n                Ok(c) => c,\n                Err(err) => {\n                    cx.editor.set_error(err.to_string());\n                    return;\n                }\n            };\n        change_pos.sort_unstable(); // the changeset has to be sorted to allow nested surrounds\n        let transaction =\n            Transaction::change(doc.text(), change_pos.into_iter().map(|p| (p, p + 1, None)));\n        doc.apply(&transaction, view.id);\n        exit_select_mode(cx);\n    });\n\n    cx.editor.autoinfo = Some(Info::new(\"Delete surrounding pair of\", &SURROUND_HELP_TEXT));\n}\n\n#[derive(Eq, PartialEq)]\nenum ShellBehavior {\n    Replace,\n    Ignore,\n    Insert,\n    Append,\n}\n\nfn shell_pipe(cx: &mut Context) {\n    shell_prompt_for_behavior(cx, \"pipe:\".into(), ShellBehavior::Replace);\n}\n\nfn shell_pipe_to(cx: &mut Context) {\n    shell_prompt_for_behavior(cx, \"pipe-to:\".into(), ShellBehavior::Ignore);\n}\n\nfn shell_insert_output(cx: &mut Context) {\n    shell_prompt_for_behavior(cx, \"insert-output:\".into(), ShellBehavior::Insert);\n}\n\nfn shell_append_output(cx: &mut Context) {\n    shell_prompt_for_behavior(cx, \"append-output:\".into(), ShellBehavior::Append);\n}\n\nfn shell_keep_pipe(cx: &mut Context) {\n    shell_prompt(cx, \"keep-pipe:\".into(), |cx, args| {\n        let shell = &cx.editor.config().shell;\n        let (view, doc) = current!(cx.editor);\n        let selection = doc.selection(view.id);\n\n        let mut ranges = SmallVec::with_capacity(selection.len());\n        let old_index = selection.primary_index();\n        let mut index: Option<usize> = None;\n        let text = doc.text().slice(..);\n\n        for (i, range) in selection.ranges().iter().enumerate() {\n            let fragment = range.slice(text);\n            if let Err(err) = shell_impl(shell, args.join(\" \").as_str(), Some(fragment.into())) {\n                log::debug!(\"Shell command failed: {}\", err);\n            } else {\n                ranges.push(*range);\n                if i >= old_index && index.is_none() {\n                    index = Some(ranges.len() - 1);\n                }\n            }\n        }\n\n        if ranges.is_empty() {\n            cx.editor.set_error(\"No selections remaining\");\n            return;\n        }\n\n        let index = index.unwrap_or_else(|| ranges.len() - 1);\n        doc.set_selection(view.id, Selection::new(ranges, index));\n    });\n}\n\nfn shell_impl(shell: &[String], cmd: &str, input: Option<Rope>) -> anyhow::Result<Tendril> {\n    tokio::task::block_in_place(|| helix_lsp::block_on(shell_impl_async(shell, cmd, input)))\n}\n\nasync fn shell_impl_async(\n    shell: &[String],\n    cmd: &str,\n    input: Option<Rope>,\n) -> anyhow::Result<Tendril> {\n    use std::process::Stdio;\n    use tokio::process::Command;\n    ensure!(!shell.is_empty(), \"No shell set\");\n\n    let mut process = Command::new(&shell[0]);\n    process\n        .args(&shell[1..])\n        .arg(cmd)\n        .stdout(Stdio::piped())\n        .stderr(Stdio::piped());\n\n    if input.is_some() || cfg!(windows) {\n        process.stdin(Stdio::piped());\n    } else {\n        process.stdin(Stdio::null());\n    }\n\n    let mut process = match process.spawn() {\n        Ok(process) => process,\n        Err(e) => {\n            log::error!(\"Failed to start shell: {}\", e);\n            return Err(e.into());\n        }\n    };\n    let output = if let Some(mut stdin) = process.stdin.take() {\n        let input_task = tokio::spawn(async move {\n            if let Some(input) = input {\n                helix_view::document::to_writer(&mut stdin, (encoding::UTF_8, false), &input)\n                    .await?;\n            }\n            anyhow::Ok(())\n        });\n        let (output, _) = tokio::join! {\n            process.wait_with_output(),\n            input_task,\n        };\n        output?\n    } else {\n        // Process has no stdin, so we just take the output\n        process.wait_with_output().await?\n    };\n\n    let output = if !output.status.success() {\n        if output.stderr.is_empty() {\n            match output.status.code() {\n                Some(exit_code) => bail!(\"Shell command failed: status {}\", exit_code),\n                None => bail!(\"Shell command failed\"),\n            }\n        }\n        String::from_utf8_lossy(&output.stderr)\n        // Prioritize `stderr` output over `stdout`\n    } else if !output.stderr.is_empty() {\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        log::debug!(\"Command printed to stderr: {stderr}\");\n        stderr\n    } else {\n        String::from_utf8_lossy(&output.stdout)\n    };\n\n    Ok(Tendril::from(output))\n}\n\nfn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {\n    let pipe = match behavior {\n        ShellBehavior::Replace | ShellBehavior::Ignore => true,\n        ShellBehavior::Insert | ShellBehavior::Append => false,\n    };\n\n    let config = cx.editor.config();\n    let shell = &config.shell;\n    let (view, doc) = current!(cx.editor);\n    let selection = doc.selection(view.id);\n\n    let mut changes = Vec::with_capacity(selection.len());\n    let mut ranges = SmallVec::with_capacity(selection.len());\n    let text = doc.text().slice(..);\n\n    let mut shell_output: Option<Tendril> = None;\n    let mut offset = 0isize;\n    for range in selection.ranges() {\n        let output = if let Some(output) = shell_output.as_ref() {\n            output.clone()\n        } else {\n            let input = range.slice(text);\n            match shell_impl(shell, cmd, pipe.then(|| input.into())) {\n                Ok(mut output) => {\n                    if !input.ends_with(\"\\n\") && output.ends_with('\\n') {\n                        output.pop();\n                        if output.ends_with('\\r') {\n                            output.pop();\n                        }\n                    }\n\n                    if !pipe {\n                        shell_output = Some(output.clone());\n                    }\n                    output\n                }\n                Err(err) => {\n                    cx.editor.set_error(err.to_string());\n                    return;\n                }\n            }\n        };\n\n        let output_len = output.chars().count();\n\n        let (from, to, deleted_len) = match behavior {\n            ShellBehavior::Replace => (range.from(), range.to(), range.len()),\n            ShellBehavior::Insert => (range.from(), range.from(), 0),\n            ShellBehavior::Append => (range.to(), range.to(), 0),\n            _ => (range.from(), range.from(), 0),\n        };\n\n        // These `usize`s cannot underflow because selection ranges cannot overlap.\n        let anchor = to\n            .checked_add_signed(offset)\n            .expect(\"Selection ranges cannot overlap\")\n            .checked_sub(deleted_len)\n            .expect(\"Selection ranges cannot overlap\");\n        let new_range = Range::new(anchor, anchor + output_len).with_direction(range.direction());\n        ranges.push(new_range);\n        offset = offset\n            .checked_add_unsigned(output_len)\n            .expect(\"Selection ranges cannot overlap\")\n            .checked_sub_unsigned(deleted_len)\n            .expect(\"Selection ranges cannot overlap\");\n\n        changes.push((from, to, Some(output)));\n    }\n\n    if behavior != &ShellBehavior::Ignore {\n        let transaction = Transaction::change(doc.text(), changes.into_iter())\n            .with_selection(Selection::new(ranges, selection.primary_index()));\n        doc.apply(&transaction, view.id);\n        doc.append_changes_to_history(view);\n    }\n\n    // after replace cursor may be out of bounds, do this to\n    // make sure cursor is in view and update scroll as well\n    view.ensure_cursor_in_view(doc, config.scrolloff);\n}\n\nfn shell_prompt<F>(cx: &mut Context, prompt: Cow<'static, str>, mut callback_fn: F)\nwhere\n    F: FnMut(&mut compositor::Context, Args) + 'static,\n{\n    ui::prompt(\n        cx,\n        prompt,\n        Some('|'),\n        |editor, input| complete_command_args(editor, SHELL_SIGNATURE, &SHELL_COMPLETER, input, 0),\n        move |cx, input, event| {\n            if event != PromptEvent::Validate || input.is_empty() {\n                return;\n            }\n            match Args::parse(input, SHELL_SIGNATURE, true, |token| {\n                expansion::expand(cx.editor, token).map_err(|err| err.into())\n            }) {\n                Ok(args) => callback_fn(cx, args),\n                Err(err) => cx.editor.set_error(err.to_string()),\n            }\n        },\n    );\n}\n\nfn shell_prompt_for_behavior(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {\n    shell_prompt(cx, prompt, move |cx, args| {\n        shell(cx, args.join(\" \").as_str(), &behavior)\n    })\n}\n\nfn suspend(_cx: &mut Context) {\n    #[cfg(not(windows))]\n    {\n        // SAFETY: These are calls to standard POSIX functions.\n        // Unsafe is necessary since we are calling outside of Rust.\n        let is_session_leader = unsafe { libc::getpid() == libc::getsid(0) };\n\n        // If helix is the session leader, there is nothing to suspend to, so skip\n        if is_session_leader {\n            return;\n        }\n        _cx.block_try_flush_writes().ok();\n        signal_hook::low_level::raise(signal_hook::consts::signal::SIGTSTP).unwrap();\n    }\n}\n\nfn add_newline_above(cx: &mut Context) {\n    add_newline_impl(cx, Open::Above);\n}\n\nfn add_newline_below(cx: &mut Context) {\n    add_newline_impl(cx, Open::Below)\n}\n\nfn add_newline_impl(cx: &mut Context, open: Open) {\n    let count = cx.count();\n    let (view, doc) = current!(cx.editor);\n    let selection = doc.selection(view.id);\n    let text = doc.text();\n    let slice = text.slice(..);\n\n    let changes = selection.into_iter().map(|range| {\n        let (start, end) = range.line_range(slice);\n        let line = match open {\n            Open::Above => start,\n            Open::Below => end + 1,\n        };\n        let pos = text.line_to_char(line);\n        (\n            pos,\n            pos,\n            Some(doc.line_ending.as_str().repeat(count).into()),\n        )\n    });\n\n    let transaction = Transaction::change(text, changes);\n    doc.apply(&transaction, view.id);\n}\n\nenum IncrementDirection {\n    Increase,\n    Decrease,\n}\n\n/// Increment objects within selections by count.\nfn increment(cx: &mut Context) {\n    increment_impl(cx, IncrementDirection::Increase);\n}\n\n/// Decrement objects within selections by count.\nfn decrement(cx: &mut Context) {\n    increment_impl(cx, IncrementDirection::Decrease);\n}\n\n/// Increment objects within selections by `amount`.\n/// A negative `amount` will decrement objects within selections.\nfn increment_impl(cx: &mut Context, increment_direction: IncrementDirection) {\n    let sign = match increment_direction {\n        IncrementDirection::Increase => 1,\n        IncrementDirection::Decrease => -1,\n    };\n    let mut amount = sign * cx.count() as i64;\n    // If the register is `#` then increase or decrease the `amount` by 1 per element\n    let increase_by = if cx.register == Some('#') { sign } else { 0 };\n\n    let (view, doc) = current!(cx.editor);\n    let selection = doc.selection(view.id);\n    let text = doc.text().slice(..);\n\n    let mut new_selection_ranges = SmallVec::new();\n    let mut cumulative_length_diff: i128 = 0;\n    let mut changes = vec![];\n\n    for range in selection {\n        let selected_text: Cow<str> = range.fragment(text);\n        let new_from = ((range.from() as i128) + cumulative_length_diff) as usize;\n        let incremented = [increment::integer, increment::date_time]\n            .iter()\n            .find_map(|incrementor| incrementor(selected_text.as_ref(), amount));\n\n        amount += increase_by;\n\n        match incremented {\n            None => {\n                let new_range = Range::new(\n                    new_from,\n                    (range.to() as i128 + cumulative_length_diff) as usize,\n                );\n                new_selection_ranges.push(new_range);\n            }\n            Some(new_text) => {\n                let new_range = Range::new(new_from, new_from + new_text.len());\n                cumulative_length_diff += new_text.len() as i128 - selected_text.len() as i128;\n                new_selection_ranges.push(new_range);\n                changes.push((range.from(), range.to(), Some(new_text.into())));\n            }\n        }\n    }\n\n    if !changes.is_empty() {\n        let new_selection = Selection::new(new_selection_ranges, selection.primary_index());\n        let transaction = Transaction::change(doc.text(), changes.into_iter());\n        let transaction = transaction.with_selection(new_selection);\n        doc.apply(&transaction, view.id);\n        exit_select_mode(cx);\n    }\n}\n\nfn goto_next_tabstop(cx: &mut Context) {\n    goto_next_tabstop_impl(cx, Direction::Forward)\n}\n\nfn goto_prev_tabstop(cx: &mut Context) {\n    goto_next_tabstop_impl(cx, Direction::Backward)\n}\n\nfn goto_next_tabstop_impl(cx: &mut Context, direction: Direction) {\n    let (view, doc) = current!(cx.editor);\n    let view_id = view.id;\n    let Some(mut snippet) = doc.active_snippet.take() else {\n        cx.editor.set_error(\"no snippet is currently active\");\n        return;\n    };\n    let tabstop = match direction {\n        Direction::Forward => Some(snippet.next_tabstop(doc.selection(view_id))),\n        Direction::Backward => snippet\n            .prev_tabstop(doc.selection(view_id))\n            .map(|selection| (selection, false)),\n    };\n    let Some((selection, last_tabstop)) = tabstop else {\n        return;\n    };\n    doc.set_selection(view_id, selection);\n    if !last_tabstop {\n        doc.active_snippet = Some(snippet)\n    }\n    if cx.editor.mode() == Mode::Insert {\n        cx.on_next_key_fallback(|cx, key| {\n            if let Some(c) = key.char() {\n                let (view, doc) = current!(cx.editor);\n                if let Some(snippet) = &doc.active_snippet {\n                    doc.apply(&snippet.delete_placeholder(doc.text()), view.id);\n                }\n                insert_char(cx, c);\n            }\n        })\n    }\n}\n\nfn record_macro(cx: &mut Context) {\n    if let Some((reg, mut keys)) = cx.editor.macro_recording.take() {\n        // Remove the keypress which ends the recording\n        keys.pop();\n        let s = keys\n            .into_iter()\n            .map(|key| {\n                let s = key.to_string();\n                if s.chars().count() == 1 {\n                    s\n                } else {\n                    format!(\"<{}>\", s)\n                }\n            })\n            .collect::<String>();\n        match cx.editor.registers.write(reg, vec![s]) {\n            Ok(_) => cx\n                .editor\n                .set_status(format!(\"Recorded to register [{}]\", reg)),\n            Err(err) => cx.editor.set_error(err.to_string()),\n        }\n    } else {\n        let reg = cx.register.take().unwrap_or('@');\n        cx.editor.macro_recording = Some((reg, Vec::new()));\n        cx.editor\n            .set_status(format!(\"Recording to register [{}]\", reg));\n    }\n}\n\nfn replay_macro(cx: &mut Context) {\n    let reg = cx.register.unwrap_or('@');\n\n    if cx.editor.macro_replaying.contains(&reg) {\n        cx.editor.set_error(format!(\n            \"Cannot replay from register [{}] because already replaying from same register\",\n            reg\n        ));\n        return;\n    }\n\n    let keys: Vec<KeyEvent> = if let Some(keys) = cx\n        .editor\n        .registers\n        .read(reg, cx.editor)\n        .filter(|values| values.len() == 1)\n        .map(|mut values| values.next().unwrap())\n    {\n        match helix_view::input::parse_macro(&keys) {\n            Ok(keys) => keys,\n            Err(err) => {\n                cx.editor.set_error(format!(\"Invalid macro: {}\", err));\n                return;\n            }\n        }\n    } else {\n        cx.editor.set_error(format!(\"Register [{}] empty\", reg));\n        return;\n    };\n\n    // Once the macro has been fully validated, it's marked as being under replay\n    // to ensure we don't fall into infinite recursion.\n    cx.editor.macro_replaying.push(reg);\n\n    let count = cx.count();\n    cx.callback.push(Box::new(move |compositor, cx| {\n        for _ in 0..count {\n            for &key in keys.iter() {\n                compositor.handle_event(&compositor::Event::Key(key), cx);\n            }\n        }\n        // The macro under replay is cleared at the end of the callback, not in the\n        // macro replay context, or it will not correctly protect the user from\n        // replaying recursively.\n        cx.editor.macro_replaying.pop();\n    }));\n}\n\nfn goto_word(cx: &mut Context) {\n    jump_to_word(cx, Movement::Move)\n}\n\nfn extend_to_word(cx: &mut Context) {\n    jump_to_word(cx, Movement::Extend)\n}\n\nfn jump_to_label(cx: &mut Context, labels: Vec<Range>, behaviour: Movement) {\n    let doc = doc!(cx.editor);\n    let alphabet = &cx.editor.config().jump_label_alphabet;\n    if labels.is_empty() {\n        return;\n    }\n    let alphabet_char = |i| {\n        let mut res = Tendril::new();\n        res.push(alphabet[i]);\n        res\n    };\n\n    // Add label for each jump candidate to the View as virtual text.\n    let text = doc.text().slice(..);\n    let mut overlays: Vec<_> = labels\n        .iter()\n        .enumerate()\n        .flat_map(|(i, range)| {\n            [\n                Overlay::new(range.from(), alphabet_char(i / alphabet.len())),\n                Overlay::new(\n                    graphemes::next_grapheme_boundary(text, range.from()),\n                    alphabet_char(i % alphabet.len()),\n                ),\n            ]\n        })\n        .collect();\n    overlays.sort_unstable_by_key(|overlay| overlay.char_idx);\n    let (view, doc) = current!(cx.editor);\n    doc.set_jump_labels(view.id, overlays);\n\n    // Accept two characters matching a visible label. Jump to the candidate\n    // for that label if it exists.\n    let primary_selection = doc.selection(view.id).primary();\n    let view = view.id;\n    let doc = doc.id();\n    cx.on_next_key(move |cx, event| {\n        let alphabet = &cx.editor.config().jump_label_alphabet;\n        let Some(i) = event\n            .char()\n            .filter(|_| event.modifiers.is_empty())\n            .and_then(|ch| alphabet.iter().position(|&it| it == ch))\n        else {\n            doc_mut!(cx.editor, &doc).remove_jump_labels(view);\n            return;\n        };\n        let outer = i * alphabet.len();\n        // Bail if the given character cannot be a jump label.\n        if outer > labels.len() {\n            doc_mut!(cx.editor, &doc).remove_jump_labels(view);\n            return;\n        }\n        cx.on_next_key(move |cx, event| {\n            doc_mut!(cx.editor, &doc).remove_jump_labels(view);\n            let alphabet = &cx.editor.config().jump_label_alphabet;\n            let Some(inner) = event\n                .char()\n                .filter(|_| event.modifiers.is_empty())\n                .and_then(|ch| alphabet.iter().position(|&it| it == ch))\n            else {\n                return;\n            };\n            if let Some(mut range) = labels.get(outer + inner).copied() {\n                range = if behaviour == Movement::Extend {\n                    let anchor = if range.anchor < range.head {\n                        let from = primary_selection.from();\n                        if range.anchor < from {\n                            range.anchor\n                        } else {\n                            from\n                        }\n                    } else {\n                        let to = primary_selection.to();\n                        if range.anchor > to {\n                            range.anchor\n                        } else {\n                            to\n                        }\n                    };\n                    Range::new(anchor, range.head)\n                } else {\n                    range.with_direction(Direction::Forward)\n                };\n                save_selection(cx);\n                doc_mut!(cx.editor, &doc).set_selection(view, range.into());\n            }\n        });\n    });\n}\n\nfn jump_to_word(cx: &mut Context, behaviour: Movement) {\n    // Calculate the jump candidates: ranges for any visible words with two or\n    // more characters.\n    let alphabet = &cx.editor.config().jump_label_alphabet;\n    if alphabet.is_empty() {\n        return;\n    }\n\n    let jump_label_limit = alphabet.len() * alphabet.len();\n    let mut words = Vec::with_capacity(jump_label_limit);\n    let (view, doc) = current_ref!(cx.editor);\n    let text = doc.text().slice(..);\n\n    // This is not necessarily exact if there is virtual text like soft wrap.\n    // It's ok though because the extra jump labels will not be rendered.\n    let start = text.line_to_char(text.char_to_line(doc.view_offset(view.id).anchor));\n    let end = text.line_to_char(view.estimate_last_doc_line(doc) + 1);\n\n    let primary_selection = doc.selection(view.id).primary();\n    let cursor = primary_selection.cursor(text);\n    let mut cursor_fwd = Range::point(cursor);\n    let mut cursor_rev = Range::point(cursor);\n    if text.get_char(cursor).is_some_and(|c| !c.is_whitespace()) {\n        let cursor_word_end = movement::move_next_word_end(text, cursor_fwd, 1);\n        //  single grapheme words need a special case\n        if cursor_word_end.anchor == cursor {\n            cursor_fwd = cursor_word_end;\n        }\n        let cursor_word_start = movement::move_prev_word_start(text, cursor_rev, 1);\n        if cursor_word_start.anchor == next_grapheme_boundary(text, cursor) {\n            cursor_rev = cursor_word_start;\n        }\n    }\n    'outer: loop {\n        let mut changed = false;\n        while cursor_fwd.head < end {\n            cursor_fwd = movement::move_next_word_end(text, cursor_fwd, 1);\n            // The cursor is on a word that is atleast two graphemes long and\n            // madeup of word characters. The latter condition is needed because\n            // move_next_word_end simply treats a sequence of characters from\n            // the same char class as a word so `=<` would also count as a word.\n            let add_label = text\n                .slice(..cursor_fwd.head)\n                .graphemes_rev()\n                .take(2)\n                .take_while(|g| g.chars().all(char_is_word))\n                .count()\n                == 2;\n            if !add_label {\n                continue;\n            }\n            changed = true;\n            // skip any leading whitespace\n            cursor_fwd.anchor += text\n                .chars_at(cursor_fwd.anchor)\n                .take_while(|&c| !char_is_word(c))\n                .count();\n            words.push(cursor_fwd);\n            if words.len() == jump_label_limit {\n                break 'outer;\n            }\n            break;\n        }\n        while cursor_rev.head > start {\n            cursor_rev = movement::move_prev_word_start(text, cursor_rev, 1);\n            // The cursor is on a word that is atleast two graphemes long and\n            // madeup of word characters. The latter condition is needed because\n            // move_prev_word_start simply treats a sequence of characters from\n            // the same char class as a word so `=<` would also count as a word.\n            let add_label = text\n                .slice(cursor_rev.head..)\n                .graphemes()\n                .take(2)\n                .take_while(|g| g.chars().all(char_is_word))\n                .count()\n                == 2;\n            if !add_label {\n                continue;\n            }\n            changed = true;\n            cursor_rev.anchor -= text\n                .chars_at(cursor_rev.anchor)\n                .reversed()\n                .take_while(|&c| !char_is_word(c))\n                .count();\n            words.push(cursor_rev);\n            if words.len() == jump_label_limit {\n                break 'outer;\n            }\n            break;\n        }\n        if !changed {\n            break;\n        }\n    }\n    jump_to_label(cx, words, behaviour)\n}\n\nfn lsp_or_syntax_symbol_picker(cx: &mut Context) {\n    let doc = doc!(cx.editor);\n\n    if doc\n        .language_servers_with_feature(LanguageServerFeature::DocumentSymbols)\n        .next()\n        .is_some()\n    {\n        lsp::symbol_picker(cx);\n    } else if doc.syntax().is_some() {\n        syntax_symbol_picker(cx);\n    } else {\n        cx.editor\n            .set_error(\"No language server supporting document symbols or syntax info available\");\n    }\n}\n\nfn lsp_or_syntax_workspace_symbol_picker(cx: &mut Context) {\n    let doc = doc!(cx.editor);\n\n    if doc\n        .language_servers_with_feature(LanguageServerFeature::WorkspaceSymbols)\n        .next()\n        .is_some()\n    {\n        lsp::workspace_symbol_picker(cx);\n    } else {\n        syntax_workspace_symbol_picker(cx);\n    }\n}\n"
  },
  {
    "path": "helix-term/src/compositor.rs",
    "content": "// Each component declares its own size constraints and gets fitted based on its parent.\n// Q: how does this work with popups?\n// cursive does compositor.screen_mut().add_layer_at(pos::absolute(x, y), <component>)\nuse helix_core::Position;\nuse helix_view::graphics::{CursorKind, Rect};\n\nuse tui::buffer::Buffer as Surface;\n\npub type Callback = Box<dyn FnOnce(&mut Compositor, &mut Context)>;\npub type SyncCallback = Box<dyn FnOnce(&mut Compositor, &mut Context) + Sync>;\n\n// Cursive-inspired\npub enum EventResult {\n    Ignored(Option<Callback>),\n    Consumed(Option<Callback>),\n}\n\nuse crate::job::Jobs;\nuse crate::ui::picker;\nuse helix_view::Editor;\n\npub use helix_view::input::Event;\n\npub struct Context<'a> {\n    pub editor: &'a mut Editor,\n    pub scroll: Option<usize>,\n    pub jobs: &'a mut Jobs,\n}\n\nimpl Context<'_> {\n    /// Waits on all pending jobs, and then tries to flush all pending write\n    /// operations for all documents.\n    pub fn block_try_flush_writes(&mut self) -> anyhow::Result<()> {\n        tokio::task::block_in_place(|| helix_lsp::block_on(self.jobs.finish(self.editor, None)))?;\n        tokio::task::block_in_place(|| helix_lsp::block_on(self.editor.flush_writes()))?;\n        Ok(())\n    }\n}\n\npub trait Component: Any + AnyComponent {\n    /// Process input events, return true if handled.\n    fn handle_event(&mut self, _event: &Event, _ctx: &mut Context) -> EventResult {\n        EventResult::Ignored(None)\n    }\n    // , args: ()\n\n    /// Should redraw? Useful for saving redraw cycles if we know component didn't change.\n    fn should_update(&self) -> bool {\n        true\n    }\n\n    /// Render the component onto the provided surface.\n    fn render(&mut self, area: Rect, frame: &mut Surface, ctx: &mut Context);\n\n    /// Get cursor position and cursor kind.\n    fn cursor(&self, _area: Rect, _ctx: &Editor) -> (Option<Position>, CursorKind) {\n        (None, CursorKind::Hidden)\n    }\n\n    /// May be used by the parent component to compute the child area.\n    /// viewport is the maximum allowed area, and the child should stay within those bounds.\n    ///\n    /// The returned size might be larger than the viewport if the child is too big to fit.\n    /// In this case the parent can use the values to calculate scroll.\n    fn required_size(&mut self, _viewport: (u16, u16)) -> Option<(u16, u16)> {\n        None\n    }\n\n    fn type_name(&self) -> &'static str {\n        std::any::type_name::<Self>()\n    }\n\n    fn id(&self) -> Option<&'static str> {\n        None\n    }\n}\n\npub struct Compositor {\n    layers: Vec<Box<dyn Component>>,\n    area: Rect,\n\n    pub(crate) last_picker: Option<Box<dyn Component>>,\n    pub(crate) full_redraw: bool,\n}\n\nimpl Compositor {\n    pub fn new(area: Rect) -> Self {\n        Self {\n            layers: Vec::new(),\n            area,\n            last_picker: None,\n            full_redraw: false,\n        }\n    }\n\n    pub fn size(&self) -> Rect {\n        self.area\n    }\n\n    pub fn resize(&mut self, area: Rect) {\n        self.area = area;\n    }\n\n    /// Add a layer to be rendered in front of all existing layers.\n    pub fn push(&mut self, mut layer: Box<dyn Component>) {\n        // immediately clear last_picker field to avoid excessive memory\n        // consumption for picker with many items\n        if layer.id() == Some(picker::ID) {\n            self.last_picker = None;\n        }\n        let size = self.size();\n        // trigger required_size on init\n        layer.required_size((size.width, size.height));\n        self.layers.push(layer);\n    }\n\n    /// Replace a component that has the given `id` with the new layer and if\n    /// no component is found, push the layer normally.\n    pub fn replace_or_push<T: Component>(&mut self, id: &'static str, layer: T) {\n        if let Some(component) = self.find_id(id) {\n            *component = layer;\n        } else {\n            self.push(Box::new(layer))\n        }\n    }\n\n    pub fn pop(&mut self) -> Option<Box<dyn Component>> {\n        self.layers.pop()\n    }\n\n    pub fn remove(&mut self, id: &'static str) -> Option<Box<dyn Component>> {\n        let idx = self\n            .layers\n            .iter()\n            .position(|layer| layer.id() == Some(id))?;\n        Some(self.layers.remove(idx))\n    }\n\n    pub fn remove_type<T: 'static>(&mut self) {\n        let type_name = std::any::type_name::<T>();\n        self.layers\n            .retain(|component| component.type_name() != type_name);\n    }\n    pub fn handle_event(&mut self, event: &Event, cx: &mut Context) -> bool {\n        // If it is a key event, a macro is being recorded, and a macro isn't being replayed,\n        // push the key event to the recording.\n        if let (Event::Key(key), Some((_, keys))) = (event, &mut cx.editor.macro_recording) {\n            if cx.editor.macro_replaying.is_empty() {\n                keys.push(*key);\n            }\n        }\n\n        let mut callbacks = Vec::new();\n        let mut consumed = false;\n\n        // propagate events through the layers until we either find a layer that consumes it or we\n        // run out of layers (event bubbling), starting at the front layer and then moving to the\n        // background.\n        for layer in self.layers.iter_mut().rev() {\n            match layer.handle_event(event, cx) {\n                EventResult::Consumed(Some(callback)) => {\n                    callbacks.push(callback);\n                    consumed = true;\n                    break;\n                }\n                EventResult::Consumed(None) => {\n                    consumed = true;\n                    break;\n                }\n                EventResult::Ignored(Some(callback)) => {\n                    callbacks.push(callback);\n                }\n                EventResult::Ignored(None) => {}\n            };\n        }\n\n        for callback in callbacks {\n            callback(self, cx)\n        }\n\n        consumed\n    }\n\n    pub fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        for layer in &mut self.layers {\n            layer.render(area, surface, cx);\n        }\n    }\n\n    pub fn cursor(&self, area: Rect, editor: &Editor) -> (Option<Position>, CursorKind) {\n        for layer in self.layers.iter().rev() {\n            if let (Some(pos), kind) = layer.cursor(area, editor) {\n                return (Some(pos), kind);\n            }\n        }\n        (None, CursorKind::Hidden)\n    }\n\n    pub fn has_component(&self, type_name: &str) -> bool {\n        self.layers\n            .iter()\n            .any(|component| component.type_name() == type_name)\n    }\n\n    pub fn find<T: 'static>(&mut self) -> Option<&mut T> {\n        let type_name = std::any::type_name::<T>();\n        self.layers\n            .iter_mut()\n            .find(|component| component.type_name() == type_name)\n            .and_then(|component| component.as_any_mut().downcast_mut())\n    }\n\n    pub fn find_id<T: 'static>(&mut self, id: &'static str) -> Option<&mut T> {\n        self.layers\n            .iter_mut()\n            .find(|component| component.id() == Some(id))\n            .and_then(|component| component.as_any_mut().downcast_mut())\n    }\n\n    pub fn need_full_redraw(&mut self) {\n        self.full_redraw = true;\n    }\n}\n\n// View casting, taken straight from Cursive\n\nuse std::any::Any;\n\n/// A view that can be downcasted to its concrete type.\n///\n/// This trait is automatically implemented for any `T: Component`.\npub trait AnyComponent {\n    /// Downcast self to a `Any`.\n    fn as_any(&self) -> &dyn Any;\n\n    /// Downcast self to a mutable `Any`.\n    fn as_any_mut(&mut self) -> &mut dyn Any;\n\n    /// Returns a boxed any from a boxed self.\n    ///\n    /// Can be used before `Box::downcast()`.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use helix_term::{ui::Text, compositor::Component};\n    /// let boxed: Box<dyn Component> = Box::new(Text::new(\"text\".to_string()));\n    /// let text: Box<Text> = boxed.as_boxed_any().downcast().unwrap();\n    /// ```\n    fn as_boxed_any(self: Box<Self>) -> Box<dyn Any>;\n}\n\nimpl<T: Component> AnyComponent for T {\n    /// Downcast self to a `Any`.\n    fn as_any(&self) -> &dyn Any {\n        self\n    }\n\n    /// Downcast self to a mutable `Any`.\n    fn as_any_mut(&mut self) -> &mut dyn Any {\n        self\n    }\n\n    fn as_boxed_any(self: Box<Self>) -> Box<dyn Any> {\n        self\n    }\n}\n\nimpl dyn AnyComponent {\n    /// Attempts to downcast `self` to a concrete type.\n    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {\n        self.as_any().downcast_ref()\n    }\n\n    /// Attempts to downcast `self` to a concrete type.\n    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {\n        self.as_any_mut().downcast_mut()\n    }\n\n    /// Attempts to downcast `Box<Self>` to a concrete type.\n    pub fn downcast<T: Any>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {\n        // Do the check here + unwrap, so the error\n        // value is `Self` and not `dyn Any`.\n        if self.as_any().is::<T>() {\n            Ok(self.as_boxed_any().downcast().unwrap())\n        } else {\n            Err(self)\n        }\n    }\n\n    /// Checks if this view is of type `T`.\n    pub fn is<T: Any>(&mut self) -> bool {\n        self.as_any().is::<T>()\n    }\n}\n"
  },
  {
    "path": "helix-term/src/config.rs",
    "content": "use crate::keymap;\nuse crate::keymap::{merge_keys, KeyTrie};\nuse helix_loader::merge_toml_values;\nuse helix_view::{document::Mode, theme};\nuse serde::Deserialize;\nuse std::collections::HashMap;\nuse std::fmt::Display;\nuse std::fs;\nuse std::io::Error as IOError;\nuse toml::de::Error as TomlError;\n\n#[derive(Debug, Clone, PartialEq)]\npub struct Config {\n    pub theme: Option<theme::Config>,\n    pub keys: HashMap<Mode, KeyTrie>,\n    pub editor: helix_view::editor::Config,\n}\n\n#[derive(Debug, Clone, PartialEq, Deserialize)]\n#[serde(deny_unknown_fields)]\npub struct ConfigRaw {\n    pub theme: Option<theme::Config>,\n    pub keys: Option<HashMap<Mode, KeyTrie>>,\n    pub editor: Option<toml::Value>,\n}\n\nimpl Default for Config {\n    fn default() -> Config {\n        Config {\n            theme: None,\n            keys: keymap::default(),\n            editor: helix_view::editor::Config::default(),\n        }\n    }\n}\n\n#[derive(Debug)]\npub enum ConfigLoadError {\n    BadConfig(TomlError),\n    Error(IOError),\n}\n\nimpl Default for ConfigLoadError {\n    fn default() -> Self {\n        ConfigLoadError::Error(IOError::new(std::io::ErrorKind::NotFound, \"place holder\"))\n    }\n}\n\nimpl Display for ConfigLoadError {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            ConfigLoadError::BadConfig(err) => err.fmt(f),\n            ConfigLoadError::Error(err) => err.fmt(f),\n        }\n    }\n}\n\nimpl Config {\n    pub fn load(\n        global: Result<String, ConfigLoadError>,\n        local: Result<String, ConfigLoadError>,\n    ) -> Result<Config, ConfigLoadError> {\n        let global_config: Result<ConfigRaw, ConfigLoadError> =\n            global.and_then(|file| toml::from_str(&file).map_err(ConfigLoadError::BadConfig));\n        let local_config: Result<ConfigRaw, ConfigLoadError> =\n            local.and_then(|file| toml::from_str(&file).map_err(ConfigLoadError::BadConfig));\n        let res = match (global_config, local_config) {\n            (Ok(global), Ok(local)) => {\n                let mut keys = keymap::default();\n                if let Some(global_keys) = global.keys {\n                    merge_keys(&mut keys, global_keys)\n                }\n                if let Some(local_keys) = local.keys {\n                    merge_keys(&mut keys, local_keys)\n                }\n\n                let editor = match (global.editor, local.editor) {\n                    (None, None) => helix_view::editor::Config::default(),\n                    (None, Some(val)) | (Some(val), None) => {\n                        val.try_into().map_err(ConfigLoadError::BadConfig)?\n                    }\n                    (Some(global), Some(local)) => merge_toml_values(global, local, 3)\n                        .try_into()\n                        .map_err(ConfigLoadError::BadConfig)?,\n                };\n\n                Config {\n                    theme: local.theme.or(global.theme),\n                    keys,\n                    editor,\n                }\n            }\n            // if any configs are invalid return that first\n            (_, Err(ConfigLoadError::BadConfig(err)))\n            | (Err(ConfigLoadError::BadConfig(err)), _) => {\n                return Err(ConfigLoadError::BadConfig(err))\n            }\n            (Ok(config), Err(_)) | (Err(_), Ok(config)) => {\n                let mut keys = keymap::default();\n                if let Some(keymap) = config.keys {\n                    merge_keys(&mut keys, keymap);\n                }\n                Config {\n                    theme: config.theme,\n                    keys,\n                    editor: config.editor.map_or_else(\n                        || Ok(helix_view::editor::Config::default()),\n                        |val| val.try_into().map_err(ConfigLoadError::BadConfig),\n                    )?,\n                }\n            }\n\n            // these are just two io errors return the one for the global config\n            (Err(err), Err(_)) => return Err(err),\n        };\n\n        Ok(res)\n    }\n\n    pub fn load_default() -> Result<Config, ConfigLoadError> {\n        let global_config =\n            fs::read_to_string(helix_loader::config_file()).map_err(ConfigLoadError::Error);\n        let local_config = fs::read_to_string(helix_loader::workspace_config_file())\n            .map_err(ConfigLoadError::Error);\n        Config::load(global_config, local_config)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    impl Config {\n        fn load_test(config: &str) -> Config {\n            Config::load(Ok(config.to_owned()), Err(ConfigLoadError::default())).unwrap()\n        }\n    }\n\n    #[test]\n    fn parsing_keymaps_config_file() {\n        use crate::keymap;\n        use helix_core::hashmap;\n        use helix_view::document::Mode;\n\n        let sample_keymaps = r#\"\n            [keys.insert]\n            y = \"move_line_down\"\n            S-C-a = \"delete_selection\"\n\n            [keys.normal]\n            A-F12 = \"move_next_word_end\"\n        \"#;\n\n        let mut keys = keymap::default();\n        merge_keys(\n            &mut keys,\n            hashmap! {\n                Mode::Insert => keymap!({ \"Insert mode\"\n                    \"y\" => move_line_down,\n                    \"S-C-a\" => delete_selection,\n                }),\n                Mode::Normal => keymap!({ \"Normal mode\"\n                    \"A-F12\" => move_next_word_end,\n                }),\n            },\n        );\n\n        assert_eq!(\n            Config::load_test(sample_keymaps),\n            Config {\n                keys,\n                ..Default::default()\n            }\n        );\n    }\n\n    #[test]\n    fn keys_resolve_to_correct_defaults() {\n        // From serde default\n        let default_keys = Config::load_test(\"\").keys;\n        assert_eq!(default_keys, keymap::default());\n\n        // From the Default trait\n        let default_keys = Config::default().keys;\n        assert_eq!(default_keys, keymap::default());\n    }\n}\n"
  },
  {
    "path": "helix-term/src/events.rs",
    "content": "use helix_event::{events, register_event};\nuse helix_view::document::Mode;\nuse helix_view::events::{\n    ConfigDidChange, DiagnosticsDidChange, DocumentDidChange, DocumentDidClose, DocumentDidOpen,\n    DocumentFocusLost, LanguageServerExited, LanguageServerInitialized, SelectionDidChange,\n};\n\nuse crate::commands;\nuse crate::keymap::MappableCommand;\n\nevents! {\n    OnModeSwitch<'a, 'cx> { old_mode: Mode, new_mode: Mode, cx: &'a mut commands::Context<'cx> }\n    PostInsertChar<'a, 'cx> { c: char, cx: &'a mut commands::Context<'cx> }\n    PostCommand<'a, 'cx> { command: & 'a MappableCommand, cx: &'a mut commands::Context<'cx> }\n}\n\npub fn register() {\n    register_event::<OnModeSwitch>();\n    register_event::<PostInsertChar>();\n    register_event::<PostCommand>();\n    register_event::<DocumentDidOpen>();\n    register_event::<DocumentDidChange>();\n    register_event::<DocumentDidClose>();\n    register_event::<DocumentFocusLost>();\n    register_event::<SelectionDidChange>();\n    register_event::<DiagnosticsDidChange>();\n    register_event::<LanguageServerInitialized>();\n    register_event::<LanguageServerExited>();\n    register_event::<ConfigDidChange>();\n}\n"
  },
  {
    "path": "helix-term/src/handlers/auto_save.rs",
    "content": "use std::{\n    sync::{\n        atomic::{self, AtomicBool},\n        Arc,\n    },\n    time::Duration,\n};\n\nuse anyhow::Ok;\nuse arc_swap::access::Access;\n\nuse helix_event::{register_hook, send_blocking};\nuse helix_view::{\n    document::Mode,\n    events::DocumentDidChange,\n    handlers::{AutoSaveEvent, Handlers},\n    Editor,\n};\nuse tokio::time::Instant;\n\nuse crate::{\n    commands, compositor,\n    events::OnModeSwitch,\n    job::{self, Jobs},\n};\n\n#[derive(Debug)]\npub(super) struct AutoSaveHandler {\n    save_pending: Arc<AtomicBool>,\n}\n\nimpl AutoSaveHandler {\n    pub fn new() -> AutoSaveHandler {\n        AutoSaveHandler {\n            save_pending: Default::default(),\n        }\n    }\n}\n\nimpl helix_event::AsyncHook for AutoSaveHandler {\n    type Event = AutoSaveEvent;\n\n    fn handle_event(\n        &mut self,\n        event: Self::Event,\n        existing_debounce: Option<tokio::time::Instant>,\n    ) -> Option<Instant> {\n        match event {\n            Self::Event::DocumentChanged { save_after } => {\n                Some(Instant::now() + Duration::from_millis(save_after))\n            }\n            Self::Event::LeftInsertMode => {\n                if existing_debounce.is_some() {\n                    // If the change happened more recently than the debounce, let the\n                    // debounce run down before saving.\n                    existing_debounce\n                } else {\n                    // Otherwise if there is a save pending, save immediately.\n                    if self.save_pending.load(atomic::Ordering::Relaxed) {\n                        self.finish_debounce();\n                    }\n                    None\n                }\n            }\n        }\n    }\n\n    fn finish_debounce(&mut self) {\n        let save_pending = self.save_pending.clone();\n        job::dispatch_blocking(move |editor, _| {\n            if editor.mode() == Mode::Insert {\n                // Avoid saving while in insert mode since this mixes up\n                // the modification indicator and prevents future saves.\n                save_pending.store(true, atomic::Ordering::Relaxed);\n            } else {\n                request_auto_save(editor);\n                save_pending.store(false, atomic::Ordering::Relaxed);\n            }\n        })\n    }\n}\n\nfn request_auto_save(editor: &mut Editor) {\n    let context = &mut compositor::Context {\n        editor,\n        scroll: Some(0),\n        jobs: &mut Jobs::new(),\n    };\n\n    let options = commands::WriteAllOptions {\n        force: false,\n        write_scratch: false,\n        auto_format: false,\n    };\n\n    if let Err(e) = commands::typed::write_all_impl(context, options) {\n        context.editor.set_error(format!(\"{}\", e));\n    }\n}\n\npub(super) fn register_hooks(handlers: &Handlers) {\n    let tx = handlers.auto_save.clone();\n    register_hook!(move |event: &mut DocumentDidChange<'_>| {\n        let config = event.doc.config.load();\n        if config.auto_save.after_delay.enable {\n            send_blocking(\n                &tx,\n                AutoSaveEvent::DocumentChanged {\n                    save_after: config.auto_save.after_delay.timeout,\n                },\n            );\n        }\n        Ok(())\n    });\n\n    let tx = handlers.auto_save.clone();\n    register_hook!(move |event: &mut OnModeSwitch<'_, '_>| {\n        if event.old_mode == Mode::Insert {\n            send_blocking(&tx, AutoSaveEvent::LeftInsertMode)\n        }\n        Ok(())\n    });\n}\n"
  },
  {
    "path": "helix-term/src/handlers/completion/item.rs",
    "content": "use std::mem;\n\nuse helix_core::completion::CompletionProvider;\nuse helix_lsp::{lsp, LanguageServerId};\nuse helix_view::handlers::completion::ResponseContext;\n\npub struct CompletionResponse {\n    pub items: CompletionItems,\n    pub provider: CompletionProvider,\n    pub context: ResponseContext,\n}\n\npub enum CompletionItems {\n    Lsp(Vec<lsp::CompletionItem>),\n    Other(Vec<CompletionItem>),\n}\n\nimpl CompletionItems {\n    pub fn is_empty(&self) -> bool {\n        match self {\n            CompletionItems::Lsp(items) => items.is_empty(),\n            CompletionItems::Other(items) => items.is_empty(),\n        }\n    }\n}\n\nimpl CompletionResponse {\n    pub fn take_items(&mut self, dst: &mut Vec<CompletionItem>) {\n        match &mut self.items {\n            CompletionItems::Lsp(items) => dst.extend(items.drain(..).map(|item| {\n                CompletionItem::Lsp(LspCompletionItem {\n                    item,\n                    provider: match self.provider {\n                        CompletionProvider::Lsp(provider) => provider,\n                        _ => unreachable!(),\n                    },\n                    resolved: false,\n                    provider_priority: self.context.priority,\n                })\n            })),\n            CompletionItems::Other(items) if dst.is_empty() => mem::swap(dst, items),\n            CompletionItems::Other(items) => dst.append(items),\n        }\n    }\n}\n\n#[derive(Debug, PartialEq, Clone)]\npub struct LspCompletionItem {\n    pub item: lsp::CompletionItem,\n    pub provider: LanguageServerId,\n    pub resolved: bool,\n    // TODO: we should not be filtering and sorting incomplete completion list\n    // according to the spec but vscode does that anyway and most servers (\n    // including rust-analyzer) rely on that.. so we can't do that without\n    // breaking completions.\n    pub provider_priority: i8,\n}\n\nimpl LspCompletionItem {\n    #[inline]\n    pub fn filter_text(&self) -> &str {\n        self.item\n            .filter_text\n            .as_ref()\n            .unwrap_or(&self.item.label)\n            .as_str()\n    }\n}\n\n#[allow(clippy::large_enum_variant)] // TODO: In a separate PR attempt the `Box<LspCompletionItem>` pattern.\n#[derive(Debug, PartialEq, Clone)]\npub enum CompletionItem {\n    Lsp(LspCompletionItem),\n    Other(helix_core::CompletionItem),\n}\n\nimpl CompletionItem {\n    #[inline]\n    pub fn filter_text(&self) -> &str {\n        match self {\n            CompletionItem::Lsp(item) => item.filter_text(),\n            CompletionItem::Other(item) => &item.label,\n        }\n    }\n}\n\nimpl PartialEq<CompletionItem> for LspCompletionItem {\n    fn eq(&self, other: &CompletionItem) -> bool {\n        match other {\n            CompletionItem::Lsp(other) => self == other,\n            _ => false,\n        }\n    }\n}\n\nimpl PartialEq<CompletionItem> for helix_core::CompletionItem {\n    fn eq(&self, other: &CompletionItem) -> bool {\n        match other {\n            CompletionItem::Other(other) => self == other,\n            _ => false,\n        }\n    }\n}\n\nimpl CompletionItem {\n    pub fn provider_priority(&self) -> i8 {\n        match self {\n            CompletionItem::Lsp(item) => item.provider_priority,\n            // sorting path completions after LSP for now\n            CompletionItem::Other(_) => 1,\n        }\n    }\n\n    pub fn provider(&self) -> CompletionProvider {\n        match self {\n            CompletionItem::Lsp(item) => CompletionProvider::Lsp(item.provider),\n            CompletionItem::Other(item) => item.provider,\n        }\n    }\n\n    pub fn preselect(&self) -> bool {\n        match self {\n            CompletionItem::Lsp(LspCompletionItem { item, .. }) => item.preselect.unwrap_or(false),\n            CompletionItem::Other(_) => false,\n        }\n    }\n}\n"
  },
  {
    "path": "helix-term/src/handlers/completion/path.rs",
    "content": "use std::{\n    borrow::Cow,\n    fs,\n    path::{Path, PathBuf},\n    str::FromStr as _,\n    sync::Arc,\n};\n\nuse helix_core::{self as core, completion::CompletionProvider, Selection, Transaction};\nuse helix_event::TaskHandle;\nuse helix_stdx::path::{self, canonicalize, fold_home_dir, get_path_suffix};\nuse helix_view::{document::SavePoint, handlers::completion::ResponseContext, Document};\nuse url::Url;\n\nuse crate::handlers::completion::{item::CompletionResponse, CompletionItem, CompletionItems};\n\npub(crate) fn path_completion(\n    selection: Selection,\n    doc: &Document,\n    handle: TaskHandle,\n    savepoint: Arc<SavePoint>,\n) -> Option<impl FnOnce() -> CompletionResponse> {\n    if !doc.path_completion_enabled() {\n        return None;\n    }\n\n    let text = doc.text().clone();\n    let cursor = selection.primary().cursor(text.slice(..));\n    let cur_line = text.char_to_line(cursor);\n    let start = text.line_to_char(cur_line).max(cursor.saturating_sub(1000));\n    let line_until_cursor = text.slice(start..cursor);\n\n    let (dir_path, typed_file_name) =\n        get_path_suffix(line_until_cursor, false).and_then(|matched_path| {\n            let matched_path = Cow::from(matched_path);\n            let path: Cow<_> = if matched_path.starts_with(\"file://\") {\n                Url::from_str(&matched_path)\n                    .ok()\n                    .and_then(|url| url.to_file_path().ok())?\n                    .into()\n            } else {\n                Path::new(&*matched_path).into()\n            };\n            let path = path::expand(&path);\n            let parent_dir = doc.path().and_then(|dp| dp.parent());\n            let path = match parent_dir {\n                Some(parent_dir) if path.is_relative() => parent_dir.join(&path),\n                _ => path.into_owned(),\n            };\n            #[cfg(windows)]\n            let ends_with_slash = matches!(matched_path.as_bytes().last(), Some(b'/' | b'\\\\'));\n            #[cfg(not(windows))]\n            let ends_with_slash = matches!(matched_path.as_bytes().last(), Some(b'/'));\n\n            if ends_with_slash {\n                Some((PathBuf::from(path.as_path()), None))\n            } else {\n                path.parent().map(|parent_path| {\n                    (\n                        PathBuf::from(parent_path),\n                        path.file_name().and_then(|f| f.to_str().map(String::from)),\n                    )\n                })\n            }\n        })?;\n\n    if handle.is_canceled() {\n        return None;\n    }\n\n    // TODO: handle properly in the future\n    const PRIORITY: i8 = 1;\n    let future = move || {\n        let Ok(read_dir) = std::fs::read_dir(&dir_path) else {\n            return CompletionResponse {\n                items: CompletionItems::Other(Vec::new()),\n                provider: CompletionProvider::Path,\n                context: ResponseContext {\n                    is_incomplete: false,\n                    priority: PRIORITY,\n                    savepoint,\n                },\n            };\n        };\n\n        let edit_diff = typed_file_name\n            .as_ref()\n            .map(|s| s.chars().count())\n            .unwrap_or_default();\n\n        let res: Vec<_> = read_dir\n            .filter_map(Result::ok)\n            .filter_map(|dir_entry| {\n                dir_entry\n                    .metadata()\n                    .ok()\n                    .and_then(|md| Some((dir_entry.file_name().into_string().ok()?, md)))\n            })\n            .map_while(|(file_name, md)| {\n                if handle.is_canceled() {\n                    return None;\n                }\n\n                let kind = path_kind(&md);\n                let documentation = path_documentation(&md, &dir_path.join(&file_name), kind);\n\n                let transaction = Transaction::change_by_selection(&text, &selection, |range| {\n                    let cursor = range.cursor(text.slice(..));\n                    (cursor - edit_diff, cursor, Some((&file_name).into()))\n                });\n\n                Some(CompletionItem::Other(core::CompletionItem {\n                    kind: Cow::Borrowed(kind),\n                    label: file_name.into(),\n                    transaction,\n                    documentation: Some(documentation),\n                    provider: CompletionProvider::Path,\n                }))\n            })\n            .collect();\n        CompletionResponse {\n            items: CompletionItems::Other(res),\n            provider: CompletionProvider::Path,\n            context: ResponseContext {\n                is_incomplete: false,\n                priority: PRIORITY,\n                savepoint,\n            },\n        }\n    };\n\n    Some(future)\n}\n\n#[cfg(unix)]\nfn path_documentation(md: &fs::Metadata, full_path: &Path, kind: &str) -> String {\n    let full_path = fold_home_dir(canonicalize(full_path));\n    let full_path_name = full_path.to_string_lossy();\n\n    use std::os::unix::prelude::PermissionsExt;\n    let mode = md.permissions().mode();\n\n    let perms = [\n        (libc::S_IRUSR, 'r'),\n        (libc::S_IWUSR, 'w'),\n        (libc::S_IXUSR, 'x'),\n        (libc::S_IRGRP, 'r'),\n        (libc::S_IWGRP, 'w'),\n        (libc::S_IXGRP, 'x'),\n        (libc::S_IROTH, 'r'),\n        (libc::S_IWOTH, 'w'),\n        (libc::S_IXOTH, 'x'),\n    ]\n    .into_iter()\n    .fold(String::with_capacity(9), |mut acc, (p, s)| {\n        // This cast is necessary on some platforms such as macos as `mode_t` is u16 there\n        #[allow(clippy::unnecessary_cast)]\n        acc.push(if mode & (p as u32) > 0 { s } else { '-' });\n        acc\n    });\n\n    // TODO it would be great to be able to individually color the documentation,\n    // but this will likely require a custom doc implementation (i.e. not `lsp::Documentation`)\n    // and/or different rendering in completion.rs\n    format!(\n        \"type: `{kind}`\\n\\\n         permissions: `[{perms}]`\\n\\\n         full path: `{full_path_name}`\",\n    )\n}\n\n#[cfg(not(unix))]\nfn path_documentation(_md: &fs::Metadata, full_path: &Path, kind: &str) -> String {\n    let full_path = fold_home_dir(canonicalize(full_path));\n    let full_path_name = full_path.to_string_lossy();\n    format!(\"type: `{kind}`\\nfull path: `{full_path_name}`\",)\n}\n\n#[cfg(unix)]\nfn path_kind(md: &fs::Metadata) -> &'static str {\n    if md.is_symlink() {\n        \"link\"\n    } else if md.is_dir() {\n        \"folder\"\n    } else {\n        use std::os::unix::fs::FileTypeExt;\n        if md.file_type().is_block_device() {\n            \"block\"\n        } else if md.file_type().is_socket() {\n            \"socket\"\n        } else if md.file_type().is_char_device() {\n            \"char_device\"\n        } else if md.file_type().is_fifo() {\n            \"fifo\"\n        } else {\n            \"file\"\n        }\n    }\n}\n\n#[cfg(not(unix))]\nfn path_kind(md: &fs::Metadata) -> &'static str {\n    if md.is_symlink() {\n        \"link\"\n    } else if md.is_dir() {\n        \"folder\"\n    } else {\n        \"file\"\n    }\n}\n"
  },
  {
    "path": "helix-term/src/handlers/completion/request.rs",
    "content": "use std::collections::{HashMap, HashSet};\nuse std::sync::Arc;\nuse std::time::Duration;\n\nuse arc_swap::ArcSwap;\nuse futures_util::Future;\nuse helix_core::completion::CompletionProvider;\nuse helix_core::syntax::config::LanguageServerFeature;\nuse helix_event::{cancelable_future, TaskController, TaskHandle};\nuse helix_lsp::lsp;\nuse helix_lsp::lsp::{CompletionContext, CompletionTriggerKind};\nuse helix_lsp::util::pos_to_lsp_pos;\nuse helix_stdx::rope::RopeSliceExt;\nuse helix_view::document::{Mode, SavePoint};\nuse helix_view::handlers::completion::{CompletionEvent, ResponseContext};\nuse helix_view::{Document, DocumentId, Editor, ViewId};\nuse tokio::task::JoinSet;\nuse tokio::time::{timeout_at, Instant};\n\nuse crate::compositor::Compositor;\nuse crate::config::Config;\nuse crate::handlers::completion::item::CompletionResponse;\nuse crate::handlers::completion::path::path_completion;\nuse crate::handlers::completion::{\n    handle_response, replace_completions, show_completion, CompletionItems,\n};\nuse crate::job::{dispatch, dispatch_blocking};\nuse crate::ui;\nuse crate::ui::editor::InsertEvent;\n\nuse super::word;\n\n#[derive(Debug, PartialEq, Eq, Clone, Copy)]\npub(super) enum TriggerKind {\n    Auto,\n    TriggerChar,\n    Manual,\n}\n\n#[derive(Debug, Clone, Copy)]\npub(super) struct Trigger {\n    pub(super) pos: usize,\n    pub(super) view: ViewId,\n    pub(super) doc: DocumentId,\n    pub(super) kind: TriggerKind,\n}\n\n#[derive(Debug)]\npub struct CompletionHandler {\n    /// The currently active trigger which will cause a completion request after the timeout.\n    trigger: Option<Trigger>,\n    in_flight: Option<Trigger>,\n    task_controller: TaskController,\n    config: Arc<ArcSwap<Config>>,\n}\n\nimpl CompletionHandler {\n    pub fn new(config: Arc<ArcSwap<Config>>) -> CompletionHandler {\n        Self {\n            config,\n            task_controller: TaskController::new(),\n            trigger: None,\n            in_flight: None,\n        }\n    }\n}\n\nimpl helix_event::AsyncHook for CompletionHandler {\n    type Event = CompletionEvent;\n\n    fn handle_event(\n        &mut self,\n        event: Self::Event,\n        _old_timeout: Option<Instant>,\n    ) -> Option<Instant> {\n        if self.in_flight.is_some() && !self.task_controller.is_running() {\n            self.in_flight = None;\n        }\n        match event {\n            CompletionEvent::AutoTrigger {\n                cursor: trigger_pos,\n                doc,\n                view,\n            } => {\n                // Technically it shouldn't be possible to switch views/documents in insert mode\n                // but people may create weird keymaps/use the mouse so let's be extra careful.\n                if self\n                    .trigger\n                    .or(self.in_flight)\n                    .is_none_or(|trigger| trigger.doc != doc || trigger.view != view)\n                {\n                    self.trigger = Some(Trigger {\n                        pos: trigger_pos,\n                        view,\n                        doc,\n                        kind: TriggerKind::Auto,\n                    });\n                }\n            }\n            CompletionEvent::TriggerChar { cursor, doc, view } => {\n                // immediately request completions and drop all auto completion requests\n                self.task_controller.cancel();\n                self.trigger = Some(Trigger {\n                    pos: cursor,\n                    view,\n                    doc,\n                    kind: TriggerKind::TriggerChar,\n                });\n            }\n            CompletionEvent::ManualTrigger { cursor, doc, view } => {\n                // immediately request completions and drop all auto completion requests\n                self.trigger = Some(Trigger {\n                    pos: cursor,\n                    view,\n                    doc,\n                    kind: TriggerKind::Manual,\n                });\n                // stop debouncing immediately and request the completion\n                self.finish_debounce();\n                return None;\n            }\n            CompletionEvent::Cancel => {\n                self.trigger = None;\n                self.task_controller.cancel();\n            }\n            CompletionEvent::DeleteText { cursor } => {\n                // if we deleted the original trigger, abort the completion\n                if matches!(self.trigger.or(self.in_flight), Some(Trigger{ pos, .. }) if cursor < pos)\n                {\n                    self.trigger = None;\n                    self.task_controller.cancel();\n                }\n            }\n        }\n        self.trigger.map(|trigger| {\n            // if the current request was closed forget about it\n            // otherwise immediately restart the completion request\n            let timeout = if trigger.kind == TriggerKind::Auto {\n                self.config.load().editor.completion_timeout\n            } else {\n                // we want almost instant completions for trigger chars\n                // and restarting completion requests. The small timeout here mainly\n                // serves to better handle cases where the completion handler\n                // may fall behind (so multiple events in the channel) and macros\n                Duration::from_millis(5)\n            };\n            Instant::now() + timeout\n        })\n    }\n\n    fn finish_debounce(&mut self) {\n        let trigger = self.trigger.take().expect(\"debounce always has a trigger\");\n        self.in_flight = Some(trigger);\n        let handle = self.task_controller.restart();\n        dispatch_blocking(move |editor, compositor| {\n            request_completions(trigger, handle, editor, compositor)\n        });\n    }\n}\n\nfn request_completions(\n    mut trigger: Trigger,\n    handle: TaskHandle,\n    editor: &mut Editor,\n    compositor: &mut Compositor,\n) {\n    let (view, doc) = current_ref!(editor);\n\n    if compositor\n        .find::<ui::EditorView>()\n        .unwrap()\n        .completion\n        .is_some()\n        || editor.mode != Mode::Insert\n    {\n        return;\n    }\n\n    let text = doc.text();\n    let cursor = doc.selection(view.id).primary().cursor(text.slice(..));\n    if trigger.view != view.id || trigger.doc != doc.id() || cursor < trigger.pos {\n        return;\n    }\n    // This looks odd... Why are we not using the trigger position from the `trigger` here? Won't\n    // that mean that the trigger char doesn't get send to the language server if we type fast\n    // enough? Yes that is true but it's not actually a problem. The language server will resolve\n    // the completion to the identifier anyway (in fact sending the later position is necessary to\n    // get the right results from language servers that provide incomplete completion list). We\n    // rely on the trigger offset and primary cursor matching for multi-cursor completions so this\n    // is definitely necessary from our side too.\n    trigger.pos = cursor;\n    let doc = doc_mut!(editor, &doc.id());\n    let savepoint = doc.savepoint(view);\n    let text = doc.text();\n    let trigger_text = text.slice(..cursor);\n\n    let mut seen_language_servers = HashSet::new();\n    let language_servers: Vec<_> = doc\n        .language_servers_with_feature(LanguageServerFeature::Completion)\n        .filter(|ls| seen_language_servers.insert(ls.id()))\n        .collect();\n    let mut requests = JoinSet::new();\n    for (priority, ls) in language_servers.iter().enumerate() {\n        let context = if trigger.kind == TriggerKind::Manual {\n            lsp::CompletionContext {\n                trigger_kind: lsp::CompletionTriggerKind::INVOKED,\n                trigger_character: None,\n            }\n        } else {\n            let trigger_char =\n                ls.capabilities()\n                    .completion_provider\n                    .as_ref()\n                    .and_then(|provider| {\n                        provider\n                            .trigger_characters\n                            .as_deref()?\n                            .iter()\n                            .find(|&trigger| trigger_text.ends_with(trigger))\n                    });\n\n            if trigger_char.is_some() {\n                lsp::CompletionContext {\n                    trigger_kind: lsp::CompletionTriggerKind::TRIGGER_CHARACTER,\n                    trigger_character: trigger_char.cloned(),\n                }\n            } else {\n                lsp::CompletionContext {\n                    trigger_kind: lsp::CompletionTriggerKind::INVOKED,\n                    trigger_character: None,\n                }\n            }\n        };\n        requests.spawn(request_completions_from_language_server(\n            ls,\n            doc,\n            view.id,\n            context,\n            -(priority as i8),\n            savepoint.clone(),\n        ));\n    }\n    if let Some(path_completion_request) = path_completion(\n        doc.selection(view.id).clone(),\n        doc,\n        handle.clone(),\n        savepoint.clone(),\n    ) {\n        requests.spawn_blocking(path_completion_request);\n    }\n    if let Some(word_completion_request) =\n        word::completion(editor, trigger, handle.clone(), savepoint)\n    {\n        requests.spawn_blocking(word_completion_request);\n    }\n\n    let ui = compositor.find::<ui::EditorView>().unwrap();\n    ui.last_insert.1.push(InsertEvent::RequestCompletion);\n    let handle_ = handle.clone();\n    let request_completions = async move {\n        let mut context = HashMap::new();\n        let Some(mut response) = handle_response(&mut requests, false).await else {\n            return;\n        };\n\n        let mut items: Vec<_> = Vec::new();\n        response.take_items(&mut items);\n        context.insert(response.provider, response.context);\n        let deadline = Instant::now() + Duration::from_millis(100);\n        loop {\n            let Some(mut response) = timeout_at(deadline, handle_response(&mut requests, false))\n                .await\n                .ok()\n                .flatten()\n            else {\n                break;\n            };\n            response.take_items(&mut items);\n            context.insert(response.provider, response.context);\n        }\n        dispatch(move |editor, compositor| {\n            show_completion(editor, compositor, items, context, trigger)\n        })\n        .await;\n        if !requests.is_empty() {\n            replace_completions(handle_, requests, false).await;\n        }\n    };\n    tokio::spawn(cancelable_future(request_completions, handle));\n}\n\nfn request_completions_from_language_server(\n    ls: &helix_lsp::Client,\n    doc: &Document,\n    view: ViewId,\n    context: lsp::CompletionContext,\n    priority: i8,\n    savepoint: Arc<SavePoint>,\n) -> impl Future<Output = CompletionResponse> {\n    let provider = ls.id();\n    let offset_encoding = ls.offset_encoding();\n    let text = doc.text();\n    let cursor = doc.selection(view).primary().cursor(text.slice(..));\n    let pos = pos_to_lsp_pos(text, cursor, offset_encoding);\n    let doc_id = doc.identifier();\n\n    // it's important that this is before the async block (and that this is not an async function)\n    // to ensure the request is dispatched right away before any new edit notifications\n    let completion_response = ls.completion(doc_id, pos, None, context).unwrap();\n    async move {\n        let response: Option<lsp::CompletionResponse> = completion_response\n            .await\n            .inspect_err(|err| log::error!(\"completion request failed: {err}\"))\n            .ok()\n            .flatten();\n        let (mut items, is_incomplete) = match response {\n            Some(lsp::CompletionResponse::Array(items)) => (items, false),\n            Some(lsp::CompletionResponse::List(lsp::CompletionList {\n                is_incomplete,\n                items,\n            })) => (items, is_incomplete),\n            None => (Vec::new(), false),\n        };\n        items.sort_by(|item1, item2| {\n            let sort_text1 = item1.sort_text.as_deref().unwrap_or(&item1.label);\n            let sort_text2 = item2.sort_text.as_deref().unwrap_or(&item2.label);\n            sort_text1.cmp(sort_text2)\n        });\n        CompletionResponse {\n            items: CompletionItems::Lsp(items),\n            context: ResponseContext {\n                is_incomplete,\n                priority,\n                savepoint,\n            },\n            provider: CompletionProvider::Lsp(provider),\n        }\n    }\n}\n\npub fn request_incomplete_completion_list(editor: &mut Editor, handle: TaskHandle) {\n    let handler = &mut editor.handlers.completions;\n    let mut requests = JoinSet::new();\n    let mut savepoint = None;\n    for (&provider, context) in &handler.active_completions {\n        if !context.is_incomplete {\n            continue;\n        }\n        let CompletionProvider::Lsp(ls_id) = provider else {\n            log::error!(\"non-lsp incomplete completion lists\");\n            continue;\n        };\n        let Some(ls) = editor.language_servers.get_by_id(ls_id) else {\n            continue;\n        };\n        let (view, doc) = current!(editor);\n        let savepoint = savepoint.get_or_insert_with(|| doc.savepoint(view)).clone();\n        let request = request_completions_from_language_server(\n            ls,\n            doc,\n            view.id,\n            CompletionContext {\n                trigger_kind: CompletionTriggerKind::TRIGGER_FOR_INCOMPLETE_COMPLETIONS,\n                trigger_character: None,\n            },\n            context.priority,\n            savepoint,\n        );\n        requests.spawn(request);\n    }\n    if !requests.is_empty() {\n        tokio::spawn(replace_completions(handle, requests, true));\n    }\n}\n"
  },
  {
    "path": "helix-term/src/handlers/completion/resolve.rs",
    "content": "use std::sync::Arc;\n\nuse helix_lsp::lsp;\nuse tokio::sync::mpsc::Sender;\nuse tokio::time::{Duration, Instant};\n\nuse helix_event::{send_blocking, AsyncHook, TaskController, TaskHandle};\nuse helix_view::Editor;\n\nuse super::LspCompletionItem;\nuse crate::handlers::completion::CompletionItem;\nuse crate::job;\n\n/// A hook for resolving incomplete completion items.\n///\n/// From the [LSP spec](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion):\n///\n/// > If computing full completion items is expensive, servers can additionally provide a\n/// > handler for the completion item resolve request. ...\n/// > A typical use case is for example: the `textDocument/completion` request doesn't fill\n/// > in the `documentation` property for returned completion items since it is expensive\n/// > to compute. When the item is selected in the user interface then a\n/// > 'completionItem/resolve' request is sent with the selected completion item as a parameter.\n/// > The returned completion item should have the documentation property filled in.\npub struct ResolveHandler {\n    last_request: Option<Arc<LspCompletionItem>>,\n    resolver: Sender<ResolveRequest>,\n}\n\nimpl ResolveHandler {\n    pub fn new() -> ResolveHandler {\n        ResolveHandler {\n            last_request: None,\n            resolver: ResolveTimeout::default().spawn(),\n        }\n    }\n\n    pub fn ensure_item_resolved(&mut self, editor: &mut Editor, item: &mut LspCompletionItem) {\n        if item.resolved {\n            return;\n        }\n        // We consider an item to be fully resolved if it has non-empty, none-`None` details,\n        // docs and additional text-edits. Ideally we could use `is_some` instead of this\n        // check but some language servers send values like `Some([])` for additional text\n        // edits although the items need to be resolved. This is probably a consequence of\n        // how `null` works in the JavaScript world.\n        let is_resolved = item\n            .item\n            .documentation\n            .as_ref()\n            .is_some_and(|docs| match docs {\n                lsp::Documentation::String(text) => !text.is_empty(),\n                lsp::Documentation::MarkupContent(markup) => !markup.value.is_empty(),\n            })\n            && item\n                .item\n                .detail\n                .as_ref()\n                .is_some_and(|detail| !detail.is_empty())\n            && item\n                .item\n                .additional_text_edits\n                .as_ref()\n                .is_some_and(|edits| !edits.is_empty());\n        if is_resolved {\n            item.resolved = true;\n            return;\n        }\n        if self.last_request.as_deref().is_some_and(|it| it == item) {\n            return;\n        }\n        let Some(ls) = editor.language_servers.get_by_id(item.provider).cloned() else {\n            item.resolved = true;\n            return;\n        };\n        if matches!(\n            ls.capabilities().completion_provider,\n            Some(lsp::CompletionOptions {\n                resolve_provider: Some(true),\n                ..\n            })\n        ) {\n            let item = Arc::new(item.clone());\n            self.last_request = Some(item.clone());\n            send_blocking(&self.resolver, ResolveRequest { item, ls })\n        } else {\n            item.resolved = true;\n        }\n    }\n}\n\nstruct ResolveRequest {\n    item: Arc<LspCompletionItem>,\n    ls: Arc<helix_lsp::Client>,\n}\n\n#[derive(Default)]\nstruct ResolveTimeout {\n    next_request: Option<ResolveRequest>,\n    in_flight: Option<Arc<LspCompletionItem>>,\n    task_controller: TaskController,\n}\n\nimpl AsyncHook for ResolveTimeout {\n    type Event = ResolveRequest;\n\n    fn handle_event(\n        &mut self,\n        request: Self::Event,\n        timeout: Option<tokio::time::Instant>,\n    ) -> Option<tokio::time::Instant> {\n        if self\n            .next_request\n            .as_ref()\n            .is_some_and(|old_request| old_request.item == request.item)\n        {\n            timeout\n        } else if self\n            .in_flight\n            .as_ref()\n            .is_some_and(|old_request| old_request.item == request.item.item)\n        {\n            self.next_request = None;\n            None\n        } else {\n            self.next_request = Some(request);\n            Some(Instant::now() + Duration::from_millis(150))\n        }\n    }\n\n    fn finish_debounce(&mut self) {\n        let Some(request) = self.next_request.take() else {\n            return;\n        };\n        let token = self.task_controller.restart();\n        self.in_flight = Some(request.item.clone());\n        tokio::spawn(request.execute(token));\n    }\n}\n\nimpl ResolveRequest {\n    async fn execute(self, cancel: TaskHandle) {\n        let future = self.ls.resolve_completion_item(&self.item.item);\n        let Some(resolved_item) = helix_event::cancelable_future(future, cancel).await else {\n            return;\n        };\n        job::dispatch(move |_, compositor| {\n            if let Some(completion) = &mut compositor\n                .find::<crate::ui::EditorView>()\n                .unwrap()\n                .completion\n            {\n                let resolved_item = CompletionItem::Lsp(match resolved_item {\n                    Ok(item) => LspCompletionItem {\n                        item,\n                        resolved: true,\n                        ..*self.item\n                    },\n                    Err(err) => {\n                        log::error!(\"completion resolve request failed: {err}\");\n                        // set item to resolved so we don't request it again\n                        // we could also remove it but that oculd be odd ui\n                        let mut item = (*self.item).clone();\n                        item.resolved = true;\n                        item\n                    }\n                });\n                completion.replace_item(&*self.item, resolved_item);\n            };\n        })\n        .await\n    }\n}\n"
  },
  {
    "path": "helix-term/src/handlers/completion/word.rs",
    "content": "use std::{borrow::Cow, sync::Arc};\n\nuse helix_core::{\n    self as core, chars::char_is_word, completion::CompletionProvider, movement, Transaction,\n};\nuse helix_event::TaskHandle;\nuse helix_stdx::rope::RopeSliceExt as _;\nuse helix_view::{\n    document::SavePoint, handlers::completion::ResponseContext, Document, Editor, ViewId,\n};\n\nuse super::{request::TriggerKind, CompletionItem, CompletionItems, CompletionResponse, Trigger};\n\nconst COMPLETION_KIND: &str = \"word\";\n\npub(super) fn completion(\n    editor: &Editor,\n    trigger: Trigger,\n    handle: TaskHandle,\n    savepoint: Arc<SavePoint>,\n) -> Option<impl FnOnce() -> CompletionResponse> {\n    if !doc!(editor).word_completion_enabled() {\n        return None;\n    }\n    let config = editor.config().word_completion;\n    let doc_config = doc!(editor)\n        .language_config()\n        .and_then(|config| config.word_completion);\n    let trigger_length = doc_config\n        .and_then(|c| c.trigger_length)\n        .unwrap_or(config.trigger_length)\n        .get() as usize;\n\n    let (view, doc) = current_ref!(editor);\n    let rope = doc.text().clone();\n    let word_index = editor.handlers.word_index().clone();\n    let text = doc.text().slice(..);\n    let selection = doc.selection(view.id).clone();\n    let pos = selection.primary().cursor(text);\n\n    let cursor = movement::move_prev_word_start(text, core::Range::point(pos), 1);\n    if cursor.head == pos {\n        return None;\n    }\n    if trigger.kind != TriggerKind::Manual\n        && text\n            .slice(cursor.head..)\n            .graphemes()\n            .take(trigger_length)\n            .take_while(|g| g.chars().all(char_is_word))\n            .count()\n            != trigger_length\n    {\n        return None;\n    }\n\n    let typed_word_range = cursor.head..pos;\n    let typed_word = text.slice(typed_word_range.clone());\n    let edit_diff = if typed_word\n        .char(typed_word.len_chars().saturating_sub(1))\n        .is_whitespace()\n    {\n        0\n    } else {\n        typed_word.len_chars()\n    };\n\n    if handle.is_canceled() {\n        return None;\n    }\n\n    let future = move || {\n        let text = rope.slice(..);\n        let typed_word: Cow<_> = text.slice(typed_word_range).into();\n        let items = word_index\n            .matches(&typed_word)\n            .into_iter()\n            .filter(|word| word.as_str() != typed_word.as_ref())\n            .map(|word| {\n                let transaction = Transaction::change_by_selection(&rope, &selection, |range| {\n                    let cursor = range.cursor(text);\n                    (cursor - edit_diff, cursor, Some((&word).into()))\n                });\n                CompletionItem::Other(core::CompletionItem {\n                    transaction,\n                    label: word.into(),\n                    kind: Cow::Borrowed(COMPLETION_KIND),\n                    documentation: None,\n                    provider: CompletionProvider::Word,\n                })\n            })\n            .collect();\n\n        CompletionResponse {\n            items: CompletionItems::Other(items),\n            provider: CompletionProvider::Word,\n            context: ResponseContext {\n                is_incomplete: false,\n                priority: 0,\n                savepoint,\n            },\n        }\n    };\n\n    Some(future)\n}\n\npub(super) fn retain_valid_completions(\n    trigger: Trigger,\n    doc: &Document,\n    view_id: ViewId,\n    items: &mut Vec<CompletionItem>,\n) {\n    if trigger.kind == TriggerKind::Manual {\n        return;\n    }\n\n    let text = doc.text().slice(..);\n    let cursor = doc.selection(view_id).primary().cursor(text);\n    if text\n        .get_char(cursor.saturating_sub(1))\n        .is_some_and(|ch| ch.is_whitespace())\n    {\n        items.retain(|item| {\n            !matches!(\n                item,\n                CompletionItem::Other(core::CompletionItem {\n                    provider: CompletionProvider::Word,\n                    ..\n                })\n            )\n        });\n    }\n}\n"
  },
  {
    "path": "helix-term/src/handlers/completion.rs",
    "content": "use std::collections::HashMap;\n\nuse helix_core::chars::char_is_word;\nuse helix_core::completion::CompletionProvider;\nuse helix_core::syntax::config::LanguageServerFeature;\nuse helix_event::{register_hook, TaskHandle};\nuse helix_lsp::lsp;\nuse helix_stdx::rope::RopeSliceExt;\nuse helix_view::document::Mode;\nuse helix_view::handlers::completion::{CompletionEvent, ResponseContext};\nuse helix_view::Editor;\nuse tokio::task::JoinSet;\n\nuse crate::commands;\nuse crate::compositor::Compositor;\nuse crate::events::{OnModeSwitch, PostCommand, PostInsertChar};\nuse crate::handlers::completion::request::{request_incomplete_completion_list, Trigger};\nuse crate::job::dispatch;\nuse crate::keymap::MappableCommand;\nuse crate::ui::lsp::signature_help::SignatureHelp;\nuse crate::ui::{self, Popup};\n\nuse super::Handlers;\n\npub use item::{CompletionItem, CompletionItems, CompletionResponse, LspCompletionItem};\npub use request::CompletionHandler;\npub use resolve::ResolveHandler;\n\nmod item;\nmod path;\nmod request;\nmod resolve;\nmod word;\n\nasync fn handle_response(\n    requests: &mut JoinSet<CompletionResponse>,\n    is_incomplete: bool,\n) -> Option<CompletionResponse> {\n    loop {\n        let response = requests.join_next().await?.unwrap();\n        if !is_incomplete && !response.context.is_incomplete && response.items.is_empty() {\n            continue;\n        }\n        return Some(response);\n    }\n}\n\nasync fn replace_completions(\n    handle: TaskHandle,\n    mut requests: JoinSet<CompletionResponse>,\n    is_incomplete: bool,\n) {\n    while let Some(mut response) = handle_response(&mut requests, is_incomplete).await {\n        let handle = handle.clone();\n        dispatch(move |editor, compositor| {\n            let editor_view = compositor.find::<ui::EditorView>().unwrap();\n            let Some(completion) = &mut editor_view.completion else {\n                return;\n            };\n            if handle.is_canceled() {\n                log::info!(\"dropping outdated completion response\");\n                return;\n            }\n\n            completion.replace_provider_completions(&mut response, is_incomplete);\n            if completion.is_empty() {\n                editor_view.clear_completion(editor);\n                // clearing completions might mean we want to immediately re-request them (usually\n                // this occurs if typing a trigger char)\n                trigger_auto_completion(editor, false);\n            } else {\n                editor\n                    .handlers\n                    .completions\n                    .active_completions\n                    .insert(response.provider, response.context);\n            }\n        })\n        .await;\n    }\n}\n\nfn show_completion(\n    editor: &mut Editor,\n    compositor: &mut Compositor,\n    mut items: Vec<CompletionItem>,\n    context: HashMap<CompletionProvider, ResponseContext>,\n    trigger: Trigger,\n) {\n    let (view, doc) = current_ref!(editor);\n    // check if the completion request is stale.\n    //\n    // Completions are completed asynchronously and therefore the user could\n    //switch document/view or leave insert mode. In all of thoise cases the\n    // completion should be discarded\n    if editor.mode != Mode::Insert || view.id != trigger.view || doc.id() != trigger.doc {\n        return;\n    }\n\n    let size = compositor.size();\n    let ui = compositor.find::<ui::EditorView>().unwrap();\n    if ui.completion.is_some() {\n        return;\n    }\n    word::retain_valid_completions(trigger, doc, view.id, &mut items);\n    editor.handlers.completions.active_completions = context;\n\n    let completion_area = ui.set_completion(editor, items, trigger.pos, size);\n    let signature_help_area = compositor\n        .find_id::<Popup<SignatureHelp>>(SignatureHelp::ID)\n        .map(|signature_help| signature_help.area(size, editor));\n    // Delete the signature help popup if they intersect.\n    if matches!((completion_area, signature_help_area),(Some(a), Some(b)) if a.intersects(b)) {\n        compositor.remove(SignatureHelp::ID);\n    }\n}\n\npub fn trigger_auto_completion(editor: &Editor, trigger_char_only: bool) {\n    let config = editor.config.load();\n    if !config.auto_completion {\n        return;\n    }\n    let (view, doc): (&helix_view::View, &helix_view::Document) = current_ref!(editor);\n    let mut text = doc.text().slice(..);\n    let cursor = doc.selection(view.id).primary().cursor(text);\n    text = doc.text().slice(..cursor);\n\n    let is_trigger_char = doc\n        .language_servers_with_feature(LanguageServerFeature::Completion)\n        .any(|ls| {\n            matches!(&ls.capabilities().completion_provider, Some(lsp::CompletionOptions {\n                        trigger_characters: Some(triggers),\n                        ..\n                    }) if triggers.iter().any(|trigger| text.ends_with(trigger)))\n        });\n\n    let cursor_char = text\n        .get_bytes_at(text.len_bytes())\n        .and_then(|t| t.reversed().next());\n\n    #[cfg(windows)]\n    let is_path_completion_trigger = matches!(cursor_char, Some(b'/' | b'\\\\'));\n    #[cfg(not(windows))]\n    let is_path_completion_trigger = matches!(cursor_char, Some(b'/'));\n\n    let handler = &editor.handlers.completions;\n    if is_trigger_char || (is_path_completion_trigger && doc.path_completion_enabled()) {\n        handler.event(CompletionEvent::TriggerChar {\n            cursor,\n            doc: doc.id(),\n            view: view.id,\n        });\n        return;\n    }\n\n    let is_auto_trigger = !trigger_char_only\n        && doc\n            .text()\n            .chars_at(cursor)\n            .reversed()\n            .take(config.completion_trigger_len as usize)\n            .all(char_is_word);\n\n    if is_auto_trigger {\n        handler.event(CompletionEvent::AutoTrigger {\n            cursor,\n            doc: doc.id(),\n            view: view.id,\n        });\n    }\n}\n\nfn update_completion_filter(cx: &mut commands::Context, c: Option<char>) {\n    cx.callback.push(Box::new(move |compositor, cx| {\n        let editor_view = compositor.find::<ui::EditorView>().unwrap();\n        if let Some(completion) = &mut editor_view.completion {\n            completion.update_filter(c);\n            if completion.is_empty() || c.is_some_and(|c| !char_is_word(c)) {\n                editor_view.clear_completion(cx.editor);\n                // clearing completions might mean we want to immediately rerequest them (usually\n                // this occurs if typing a trigger char)\n                if c.is_some() {\n                    trigger_auto_completion(cx.editor, false);\n                }\n            } else {\n                let handle = cx.editor.handlers.completions.request_controller.restart();\n                request_incomplete_completion_list(cx.editor, handle)\n            }\n        }\n    }))\n}\n\nfn clear_completions(cx: &mut commands::Context) {\n    cx.callback.push(Box::new(|compositor, cx| {\n        let editor_view = compositor.find::<ui::EditorView>().unwrap();\n        editor_view.clear_completion(cx.editor);\n    }))\n}\n\nfn completion_post_command_hook(\n    PostCommand { command, cx }: &mut PostCommand<'_, '_>,\n) -> anyhow::Result<()> {\n    if cx.editor.mode == Mode::Insert {\n        if cx.editor.last_completion.is_some() {\n            match command {\n                MappableCommand::Static {\n                    name: \"delete_word_forward\" | \"delete_char_forward\" | \"completion\",\n                    ..\n                } => (),\n                MappableCommand::Static {\n                    name: \"delete_char_backward\",\n                    ..\n                } => update_completion_filter(cx, None),\n                _ => clear_completions(cx),\n            }\n        } else {\n            let event = match command {\n                MappableCommand::Static {\n                    name: \"delete_char_backward\" | \"delete_word_forward\" | \"delete_char_forward\",\n                    ..\n                } => {\n                    let (view, doc) = current!(cx.editor);\n                    let primary_cursor = doc\n                        .selection(view.id)\n                        .primary()\n                        .cursor(doc.text().slice(..));\n                    CompletionEvent::DeleteText {\n                        cursor: primary_cursor,\n                    }\n                }\n                // hacks: some commands are handeled elsewhere and we don't want to\n                // cancel in that case\n                MappableCommand::Static {\n                    name: \"completion\" | \"insert_mode\" | \"append_mode\",\n                    ..\n                } => return Ok(()),\n                _ => CompletionEvent::Cancel,\n            };\n            cx.editor.handlers.completions.event(event);\n        }\n    }\n    Ok(())\n}\n\npub(super) fn register_hooks(_handlers: &Handlers) {\n    register_hook!(move |event: &mut PostCommand<'_, '_>| completion_post_command_hook(event));\n\n    register_hook!(move |event: &mut OnModeSwitch<'_, '_>| {\n        if event.old_mode == Mode::Insert {\n            event\n                .cx\n                .editor\n                .handlers\n                .completions\n                .event(CompletionEvent::Cancel);\n            clear_completions(event.cx);\n        } else if event.new_mode == Mode::Insert {\n            trigger_auto_completion(event.cx.editor, false)\n        }\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut PostInsertChar<'_, '_>| {\n        if event.cx.editor.last_completion.is_some() {\n            update_completion_filter(event.cx, Some(event.c))\n        } else {\n            trigger_auto_completion(event.cx.editor, false);\n        }\n        Ok(())\n    });\n}\n"
  },
  {
    "path": "helix-term/src/handlers/diagnostics.rs",
    "content": "use futures_util::stream::FuturesUnordered;\nuse std::collections::HashSet;\nuse std::mem;\nuse std::time::Duration;\nuse tokio::time::Instant;\nuse tokio_stream::StreamExt;\n\nuse helix_core::diagnostic::DiagnosticProvider;\nuse helix_core::syntax::config::LanguageServerFeature;\nuse helix_core::Uri;\nuse helix_event::{cancelable_future, register_hook, send_blocking};\nuse helix_lsp::{lsp, LanguageServerId};\nuse helix_view::document::Mode;\nuse helix_view::events::{\n    DiagnosticsDidChange, DocumentDidChange, DocumentDidOpen, LanguageServerInitialized,\n};\nuse helix_view::handlers::diagnostics::DiagnosticEvent;\nuse helix_view::handlers::lsp::{PullAllDocumentsDiagnosticsEvent, PullDiagnosticsEvent};\nuse helix_view::handlers::Handlers;\nuse helix_view::{DocumentId, Editor};\n\nuse crate::events::OnModeSwitch;\nuse crate::job;\n\npub(super) fn register_hooks(handlers: &Handlers) {\n    register_hook!(move |event: &mut DiagnosticsDidChange<'_>| {\n        if event.editor.mode != Mode::Insert {\n            for (view, _) in event.editor.tree.views_mut() {\n                send_blocking(&view.diagnostics_handler.events, DiagnosticEvent::Refresh)\n            }\n        }\n        Ok(())\n    });\n    register_hook!(move |event: &mut OnModeSwitch<'_, '_>| {\n        for (view, _) in event.cx.editor.tree.views_mut() {\n            view.diagnostics_handler.active = event.new_mode != Mode::Insert;\n        }\n        Ok(())\n    });\n\n    let tx = handlers.pull_diagnostics.clone();\n    let tx_all_documents = handlers.pull_all_documents_diagnostics.clone();\n    register_hook!(move |event: &mut DocumentDidChange<'_>| {\n        if event\n            .doc\n            .has_language_server_with_feature(LanguageServerFeature::PullDiagnostics)\n            && !event.ghost_transaction\n        {\n            // Cancel the ongoing request, if present.\n            event.doc.pull_diagnostic_controller.cancel();\n            let document_id = event.doc.id();\n            send_blocking(&tx, PullDiagnosticsEvent { document_id });\n\n            let inter_file_dependencies_language_servers = event\n                .doc\n                .language_servers_with_feature(LanguageServerFeature::PullDiagnostics)\n                .filter(|language_server| {\n                    language_server\n                        .capabilities()\n                        .diagnostic_provider\n                        .as_ref()\n                        .is_some_and(|diagnostic_provider| match diagnostic_provider {\n                            lsp::DiagnosticServerCapabilities::Options(options) => {\n                                options.inter_file_dependencies\n                            }\n\n                            lsp::DiagnosticServerCapabilities::RegistrationOptions(options) => {\n                                options.diagnostic_options.inter_file_dependencies\n                            }\n                        })\n                })\n                .map(|language_server| language_server.id())\n                .collect();\n\n            send_blocking(\n                &tx_all_documents,\n                PullAllDocumentsDiagnosticsEvent {\n                    language_servers: inter_file_dependencies_language_servers,\n                },\n            );\n        }\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut DocumentDidOpen<'_>| {\n        request_document_diagnostics(event.editor, event.doc);\n\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut LanguageServerInitialized<'_>| {\n        let doc_ids: Vec<_> = event.editor.documents.keys().copied().collect();\n\n        for doc_id in doc_ids {\n            request_document_diagnostics(event.editor, doc_id);\n        }\n\n        Ok(())\n    });\n}\n\n#[derive(Debug, Default)]\npub(super) struct PullDiagnosticsHandler {\n    document_ids: HashSet<DocumentId>,\n}\n\nimpl helix_event::AsyncHook for PullDiagnosticsHandler {\n    type Event = PullDiagnosticsEvent;\n\n    fn handle_event(\n        &mut self,\n        event: Self::Event,\n        _timeout: Option<tokio::time::Instant>,\n    ) -> Option<tokio::time::Instant> {\n        self.document_ids.insert(event.document_id);\n        Some(Instant::now() + Duration::from_millis(250))\n    }\n\n    fn finish_debounce(&mut self) {\n        let document_ids = mem::take(&mut self.document_ids);\n        job::dispatch_blocking(move |editor, _| {\n            for document_id in document_ids {\n                request_document_diagnostics(editor, document_id);\n            }\n        })\n    }\n}\n\n#[derive(Debug, Default)]\npub(super) struct PullAllDocumentsDiagnosticHandler {\n    language_servers: HashSet<LanguageServerId>,\n}\n\nimpl helix_event::AsyncHook for PullAllDocumentsDiagnosticHandler {\n    type Event = PullAllDocumentsDiagnosticsEvent;\n\n    fn handle_event(\n        &mut self,\n        event: Self::Event,\n        _timeout: Option<tokio::time::Instant>,\n    ) -> Option<tokio::time::Instant> {\n        self.language_servers.extend(&event.language_servers);\n        Some(Instant::now() + Duration::from_secs(1))\n    }\n\n    fn finish_debounce(&mut self) {\n        let language_servers = mem::take(&mut self.language_servers);\n        job::dispatch_blocking(move |editor, _| {\n            let documents: Vec<_> = editor.documents.keys().copied().collect();\n\n            for document in documents {\n                request_document_diagnostics_for_language_severs(\n                    editor,\n                    document,\n                    language_servers.clone(),\n                );\n            }\n        })\n    }\n}\n\nfn request_document_diagnostics_for_language_severs(\n    editor: &mut Editor,\n    doc_id: DocumentId,\n    language_servers: HashSet<LanguageServerId>,\n) {\n    let Some(doc) = editor.document_mut(doc_id) else {\n        return;\n    };\n\n    let cancel = doc.pull_diagnostic_controller.restart();\n\n    let mut futures: FuturesUnordered<_> = language_servers\n        .iter()\n        .filter_map(|x| doc.language_servers().find(|y| &y.id() == x))\n        .filter_map(|language_server| {\n            let future = language_server\n                .text_document_diagnostic(doc.identifier(), doc.previous_diagnostic_id.clone())?;\n\n            let identifier = language_server\n                .capabilities()\n                .diagnostic_provider\n                .as_ref()\n                .and_then(|diagnostic_provider| match diagnostic_provider {\n                    lsp::DiagnosticServerCapabilities::Options(options) => {\n                        options.identifier.clone()\n                    }\n                    lsp::DiagnosticServerCapabilities::RegistrationOptions(options) => {\n                        options.diagnostic_options.identifier.clone()\n                    }\n                });\n\n            let language_server_id = language_server.id();\n            let provider = DiagnosticProvider::Lsp {\n                server_id: language_server_id,\n                identifier,\n            };\n            let uri = doc.uri()?;\n\n            Some(async move {\n                let result = future.await;\n\n                (result, provider, uri)\n            })\n        })\n        .collect();\n\n    if futures.is_empty() {\n        return;\n    }\n\n    tokio::spawn(async move {\n        let mut retry_language_servers = HashSet::new();\n        loop {\n            match cancelable_future(futures.next(), &cancel).await {\n                Some(Some((Ok(result), provider, uri))) => {\n                    job::dispatch(move |editor, _| {\n                        handle_pull_diagnostics_response(editor, result, provider, uri, doc_id);\n                    })\n                    .await;\n                }\n                Some(Some((Err(err), DiagnosticProvider::Lsp { server_id, .. }, _))) => {\n                    let parsed_cancellation_data = if let helix_lsp::Error::Rpc(error) = err {\n                        error.data.and_then(|data| {\n                            serde_json::from_value::<lsp::DiagnosticServerCancellationData>(data)\n                                .ok()\n                        })\n                    } else {\n                        log::error!(\"Pull diagnostic request failed: {err}\");\n                        continue;\n                    };\n                    if parsed_cancellation_data.is_some_and(|data| data.retrigger_request) {\n                        retry_language_servers.insert(server_id);\n                    }\n                }\n                Some(None) => break,\n                // The request was cancelled.\n                None => return,\n            }\n        }\n\n        if !retry_language_servers.is_empty() {\n            tokio::time::sleep(Duration::from_millis(500)).await;\n\n            job::dispatch(move |editor, _| {\n                request_document_diagnostics_for_language_severs(\n                    editor,\n                    doc_id,\n                    retry_language_servers,\n                );\n            })\n            .await;\n        }\n    });\n}\n\npub fn request_document_diagnostics(editor: &mut Editor, doc_id: DocumentId) {\n    let Some(doc) = editor.document(doc_id) else {\n        return;\n    };\n\n    let language_servers = doc\n        .language_servers_with_feature(LanguageServerFeature::PullDiagnostics)\n        .map(|language_servers| language_servers.id())\n        .collect();\n\n    request_document_diagnostics_for_language_severs(editor, doc_id, language_servers);\n}\n\nfn handle_pull_diagnostics_response(\n    editor: &mut Editor,\n    result: lsp::DocumentDiagnosticReportResult,\n    provider: DiagnosticProvider,\n    uri: Uri,\n    document_id: DocumentId,\n) {\n    match result {\n        lsp::DocumentDiagnosticReportResult::Report(report) => {\n            let result_id = match report {\n                lsp::DocumentDiagnosticReport::Full(report) => {\n                    editor.handle_lsp_diagnostics(\n                        &provider,\n                        uri,\n                        None,\n                        report.full_document_diagnostic_report.items,\n                    );\n\n                    report.full_document_diagnostic_report.result_id\n                }\n                lsp::DocumentDiagnosticReport::Unchanged(report) => {\n                    Some(report.unchanged_document_diagnostic_report.result_id)\n                }\n            };\n\n            if let Some(doc) = editor.document_mut(document_id) {\n                doc.previous_diagnostic_id = result_id;\n            };\n        }\n        lsp::DocumentDiagnosticReportResult::Partial(_) => {}\n    };\n}\n"
  },
  {
    "path": "helix-term/src/handlers/document_colors.rs",
    "content": "use std::{collections::HashSet, time::Duration};\n\nuse futures_util::{stream::FuturesOrdered, StreamExt};\nuse helix_core::{syntax::config::LanguageServerFeature, text_annotations::InlineAnnotation};\nuse helix_event::{cancelable_future, register_hook};\nuse helix_lsp::lsp;\nuse helix_view::{\n    document::DocumentColorSwatches,\n    events::{DocumentDidChange, DocumentDidOpen, LanguageServerExited, LanguageServerInitialized},\n    handlers::{lsp::DocumentColorsEvent, Handlers},\n    DocumentId, Editor, Theme,\n};\nuse tokio::time::Instant;\n\nuse crate::job;\n\n#[derive(Default)]\npub(super) struct DocumentColorsHandler {\n    docs: HashSet<DocumentId>,\n}\n\nconst DOCUMENT_CHANGE_DEBOUNCE: Duration = Duration::from_millis(250);\n\nimpl helix_event::AsyncHook for DocumentColorsHandler {\n    type Event = DocumentColorsEvent;\n\n    fn handle_event(&mut self, event: Self::Event, _timeout: Option<Instant>) -> Option<Instant> {\n        let DocumentColorsEvent(doc_id) = event;\n        self.docs.insert(doc_id);\n        Some(Instant::now() + DOCUMENT_CHANGE_DEBOUNCE)\n    }\n\n    fn finish_debounce(&mut self) {\n        let docs = std::mem::take(&mut self.docs);\n\n        job::dispatch_blocking(move |editor, _compositor| {\n            for doc in docs {\n                request_document_colors(editor, doc);\n            }\n        });\n    }\n}\n\nfn request_document_colors(editor: &mut Editor, doc_id: DocumentId) {\n    if !editor.config().lsp.display_color_swatches {\n        return;\n    }\n\n    let Some(doc) = editor.document_mut(doc_id) else {\n        return;\n    };\n\n    let cancel = doc.color_swatch_controller.restart();\n\n    let mut seen_language_servers = HashSet::new();\n    let mut futures: FuturesOrdered<_> = doc\n        .language_servers_with_feature(LanguageServerFeature::DocumentColors)\n        .filter(|ls| seen_language_servers.insert(ls.id()))\n        .map(|language_server| {\n            let text = doc.text().clone();\n            let offset_encoding = language_server.offset_encoding();\n            let future = language_server\n                .text_document_document_color(doc.identifier(), None)\n                .unwrap();\n\n            async move {\n                let colors: Vec<_> = future\n                    .await?\n                    .into_iter()\n                    .filter_map(|color_info| {\n                        let pos = helix_lsp::util::lsp_pos_to_pos(\n                            &text,\n                            color_info.range.start,\n                            offset_encoding,\n                        )?;\n                        Some((pos, color_info.color))\n                    })\n                    .collect();\n                anyhow::Ok(colors)\n            }\n        })\n        .collect();\n\n    if futures.is_empty() {\n        return;\n    }\n\n    tokio::spawn(async move {\n        let mut all_colors = Vec::new();\n        loop {\n            match cancelable_future(futures.next(), &cancel).await {\n                Some(Some(Ok(items))) => all_colors.extend(items),\n                Some(Some(Err(err))) => log::error!(\"document color request failed: {err}\"),\n                Some(None) => break,\n                // The request was cancelled.\n                None => return,\n            }\n        }\n        job::dispatch(move |editor, _| attach_document_colors(editor, doc_id, all_colors)).await;\n    });\n}\n\nfn attach_document_colors(\n    editor: &mut Editor,\n    doc_id: DocumentId,\n    mut doc_colors: Vec<(usize, lsp::Color)>,\n) {\n    if !editor.config().lsp.display_color_swatches {\n        return;\n    }\n\n    let Some(doc) = editor.documents.get_mut(&doc_id) else {\n        return;\n    };\n\n    if doc_colors.is_empty() {\n        doc.color_swatches.take();\n        return;\n    }\n\n    doc_colors.sort_by_key(|(pos, _)| *pos);\n\n    let mut color_swatches = Vec::with_capacity(doc_colors.len());\n    let mut color_swatches_padding = Vec::with_capacity(doc_colors.len());\n    let mut colors = Vec::with_capacity(doc_colors.len());\n\n    for (pos, color) in doc_colors {\n        color_swatches_padding.push(InlineAnnotation::new(pos, \" \"));\n        color_swatches.push(InlineAnnotation::new(pos, \"■\"));\n        colors.push(Theme::rgb_highlight(\n            (color.red * 255.) as u8,\n            (color.green * 255.) as u8,\n            (color.blue * 255.) as u8,\n        ));\n    }\n\n    doc.color_swatches = Some(DocumentColorSwatches {\n        color_swatches,\n        colors,\n        color_swatches_padding,\n    });\n}\n\npub(super) fn register_hooks(handlers: &Handlers) {\n    register_hook!(move |event: &mut DocumentDidOpen<'_>| {\n        // when a document is initially opened, request colors for it\n        request_document_colors(event.editor, event.doc);\n\n        Ok(())\n    });\n\n    let tx = handlers.document_colors.clone();\n    register_hook!(move |event: &mut DocumentDidChange<'_>| {\n        // Update the color swatch' positions, helping ensure they are displayed in the\n        // proper place.\n        let apply_color_swatch_changes = |annotations: &mut Vec<InlineAnnotation>| {\n            event.changes.update_positions(\n                annotations\n                    .iter_mut()\n                    .map(|annotation| (&mut annotation.char_idx, helix_core::Assoc::After)),\n            );\n        };\n\n        if let Some(DocumentColorSwatches {\n            color_swatches,\n            colors: _colors,\n            color_swatches_padding,\n        }) = &mut event.doc.color_swatches\n        {\n            apply_color_swatch_changes(color_swatches);\n            apply_color_swatch_changes(color_swatches_padding);\n        }\n\n        // Avoid re-requesting document colors if the change is a ghost transaction (completion)\n        // because the language server will not know about the updates to the document and will\n        // give out-of-date locations.\n        if !event.ghost_transaction {\n            // Cancel the ongoing request, if present.\n            event.doc.color_swatch_controller.cancel();\n            helix_event::send_blocking(&tx, DocumentColorsEvent(event.doc.id()));\n        }\n\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut LanguageServerInitialized<'_>| {\n        let doc_ids: Vec<_> = event.editor.documents().map(|doc| doc.id()).collect();\n\n        for doc_id in doc_ids {\n            request_document_colors(event.editor, doc_id);\n        }\n\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut LanguageServerExited<'_>| {\n        // Clear and re-request all color swatches when a server exits.\n        for doc in event.editor.documents_mut() {\n            if doc.supports_language_server(event.server_id) {\n                doc.color_swatches.take();\n            }\n        }\n\n        let doc_ids: Vec<_> = event.editor.documents().map(|doc| doc.id()).collect();\n\n        for doc_id in doc_ids {\n            request_document_colors(event.editor, doc_id);\n        }\n\n        Ok(())\n    });\n}\n"
  },
  {
    "path": "helix-term/src/handlers/document_highlight.rs",
    "content": "use helix_core::syntax::config::LanguageServerFeature;\nuse helix_event::{cancelable_future, register_hook};\nuse helix_lsp::{lsp, util::lsp_range_to_range, OffsetEncoding};\nuse helix_view::{\n    events::{\n        ConfigDidChange, DocumentDidChange, DocumentDidOpen, LanguageServerExited,\n        LanguageServerInitialized, SelectionDidChange,\n    },\n    handlers::Handlers,\n    DocumentId, Editor, ViewId,\n};\n\nuse crate::job;\n\nfn request_document_highlights(editor: &mut Editor, doc_id: DocumentId, view_id: ViewId) {\n    if !editor.config().lsp.auto_document_highlight {\n        return;\n    }\n\n    let Some(doc) = editor.document_mut(doc_id) else {\n        return;\n    };\n\n    doc.ensure_view_init(view_id);\n\n    let Some(language_server) = doc\n        .language_servers_with_feature(LanguageServerFeature::DocumentHighlight)\n        .next()\n    else {\n        doc.clear_document_highlights(view_id);\n        return;\n    };\n\n    let offset_encoding = language_server.offset_encoding();\n    let pos = doc.position(view_id, offset_encoding);\n    let Some(future) =\n        language_server.text_document_document_highlight(doc.identifier(), pos, None)\n    else {\n        doc.clear_document_highlights(view_id);\n        return;\n    };\n\n    let text = doc.text().clone();\n    let cancel = doc.document_highlight_controller(view_id).restart();\n\n    tokio::spawn(async move {\n        let response = match cancelable_future(future, &cancel).await {\n            Some(Ok(response)) => response,\n            Some(Err(err)) => {\n                log::error!(\"document highlight request failed: {err}\");\n                return;\n            }\n            None => return,\n        };\n\n        let ranges = response\n            .map(|highlights| document_highlight_ranges(&text, offset_encoding, highlights))\n            .unwrap_or_default();\n\n        job::dispatch(move |editor, _| {\n            apply_document_highlights(editor, doc_id, view_id, ranges);\n        })\n        .await;\n    });\n}\n\nfn document_highlight_ranges(\n    text: &helix_core::Rope,\n    offset_encoding: OffsetEncoding,\n    highlights: Vec<lsp::DocumentHighlight>,\n) -> Vec<std::ops::Range<usize>> {\n    let slice = text.slice(..);\n    let mut ranges: Vec<_> = highlights\n        .into_iter()\n        .filter_map(|highlight| lsp_range_to_range(text, highlight.range, offset_encoding))\n        .map(|range| range.min_width_1(slice))\n        .filter_map(|range| {\n            let start = range.from();\n            let end = range.to();\n            (start < end).then_some(start..end)\n        })\n        .collect();\n\n    ranges.sort_by(|a, b| (a.start, a.end).cmp(&(b.start, b.end)));\n\n    let mut merged: Vec<std::ops::Range<usize>> = Vec::with_capacity(ranges.len());\n    for range in ranges {\n        if let Some(last) = merged.last_mut() {\n            if range.start <= last.end {\n                if range.end > last.end {\n                    last.end = range.end;\n                }\n                continue;\n            }\n        }\n        merged.push(range);\n    }\n\n    merged\n}\n\nfn apply_document_highlights(\n    editor: &mut Editor,\n    doc_id: DocumentId,\n    view_id: ViewId,\n    ranges: Vec<std::ops::Range<usize>>,\n) {\n    if !editor.config().lsp.auto_document_highlight {\n        return;\n    }\n\n    let Some(doc) = editor.document_mut(doc_id) else {\n        return;\n    };\n\n    if !doc.has_language_server_with_feature(LanguageServerFeature::DocumentHighlight) {\n        doc.clear_document_highlights(view_id);\n        return;\n    }\n\n    if ranges.is_empty() {\n        doc.clear_document_highlights(view_id);\n        return;\n    }\n\n    doc.set_document_highlights(view_id, ranges);\n}\n\npub(super) fn register_hooks(_handlers: &Handlers) {\n    register_hook!(move |event: &mut SelectionDidChange<'_>| {\n        if event.doc.config.load().lsp.auto_document_highlight {\n            let doc_id = event.doc.id();\n            let view_id = event.view;\n            job::dispatch_blocking(move |editor, _| {\n                request_document_highlights(editor, doc_id, view_id);\n            });\n        }\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut DocumentDidOpen<'_>| {\n        if !event.editor.config().lsp.auto_document_highlight {\n            return Ok(());\n        }\n        let view_id = event.editor.tree.focus;\n        if event.editor.tree.try_get(view_id).is_none() {\n            return Ok(());\n        }\n        request_document_highlights(event.editor, event.doc, view_id);\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut DocumentDidChange<'_>| {\n        if event.doc.config.load().lsp.auto_document_highlight && !event.ghost_transaction {\n            let doc_id = event.doc.id();\n            let view_id = event.view;\n            job::dispatch_blocking(move |editor, _| {\n                request_document_highlights(editor, doc_id, view_id);\n            });\n        }\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut LanguageServerInitialized<'_>| {\n        if !event.editor.config().lsp.auto_document_highlight {\n            return Ok(());\n        }\n        let view_id = event.editor.tree.focus;\n        let Some(view) = event.editor.tree.try_get(view_id) else {\n            return Ok(());\n        };\n        let doc_id = view.doc;\n        request_document_highlights(event.editor, doc_id, view_id);\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut LanguageServerExited<'_>| {\n        for doc in event.editor.documents_mut() {\n            if doc.supports_language_server(event.server_id) {\n                doc.clear_all_document_highlights();\n            }\n        }\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut ConfigDidChange<'_>| {\n        if event.new.lsp.auto_document_highlight {\n            return Ok(());\n        }\n        for doc in event.editor.documents_mut() {\n            doc.clear_all_document_highlights();\n        }\n        Ok(())\n    });\n}\n"
  },
  {
    "path": "helix-term/src/handlers/document_links.rs",
    "content": "use std::{collections::HashSet, time::Duration};\n\nuse futures_util::{stream::FuturesOrdered, StreamExt};\nuse helix_core::{syntax::config::LanguageServerFeature, Assoc};\nuse helix_event::{cancelable_future, register_hook};\nuse helix_view::{\n    document::DocumentLink,\n    events::{DocumentDidChange, DocumentDidOpen, LanguageServerExited, LanguageServerInitialized},\n    handlers::{lsp::DocumentLinksEvent, Handlers},\n    DocumentId, Editor,\n};\nuse tokio::time::Instant;\n\nuse crate::job;\n\n#[derive(Default)]\npub(super) struct DocumentLinksHandler {\n    docs: HashSet<DocumentId>,\n}\n\nconst DOCUMENT_CHANGE_DEBOUNCE: Duration = Duration::from_millis(250);\n\nimpl helix_event::AsyncHook for DocumentLinksHandler {\n    type Event = DocumentLinksEvent;\n\n    fn handle_event(&mut self, event: Self::Event, _timeout: Option<Instant>) -> Option<Instant> {\n        let DocumentLinksEvent(doc_id) = event;\n        self.docs.insert(doc_id);\n        Some(Instant::now() + DOCUMENT_CHANGE_DEBOUNCE)\n    }\n\n    fn finish_debounce(&mut self) {\n        let docs = std::mem::take(&mut self.docs);\n\n        job::dispatch_blocking(move |editor, _compositor| {\n            for doc in docs {\n                request_document_links(editor, doc);\n            }\n        });\n    }\n}\n\n/// Request document links for a specific document and cache them for navigation.\nfn request_document_links(editor: &mut Editor, doc_id: DocumentId) {\n    let Some(doc) = editor.document_mut(doc_id) else {\n        return;\n    };\n\n    let cancel = doc.document_link_controller.restart();\n\n    let mut seen_language_servers = HashSet::new();\n    let mut futures: FuturesOrdered<_> = doc\n        .language_servers_with_feature(LanguageServerFeature::DocumentLinks)\n        .filter(|ls| seen_language_servers.insert(ls.id()))\n        .filter_map(|language_server| {\n            let text = doc.text().clone();\n            let offset_encoding = language_server.offset_encoding();\n            let language_server_id = language_server.id();\n            let future = language_server.text_document_document_link(doc.identifier(), None)?;\n\n            Some(async move {\n                let links = future.await?.unwrap_or_default();\n                let links: Vec<_> = links\n                    .into_iter()\n                    .filter_map(|link| {\n                        let start = helix_lsp::util::lsp_pos_to_pos(\n                            &text,\n                            link.range.start,\n                            offset_encoding,\n                        )?;\n                        let end = helix_lsp::util::lsp_pos_to_pos(\n                            &text,\n                            link.range.end,\n                            offset_encoding,\n                        )?;\n                        if start > end {\n                            return None;\n                        }\n                        Some(DocumentLink {\n                            start,\n                            end,\n                            link,\n                            language_server_id,\n                        })\n                    })\n                    .collect();\n                anyhow::Ok(links)\n            })\n        })\n        .collect();\n\n    if futures.is_empty() {\n        return;\n    }\n\n    tokio::spawn(async move {\n        let mut all_links = Vec::new();\n        loop {\n            match cancelable_future(futures.next(), &cancel).await {\n                Some(Some(Ok(items))) => all_links.extend(items),\n                Some(Some(Err(err))) => log::error!(\"document link request failed: {err}\"),\n                Some(None) => break,\n                None => return,\n            }\n        }\n\n        job::dispatch(move |editor, _| attach_document_links(editor, doc_id, all_links)).await;\n    });\n}\n\nfn attach_document_links(editor: &mut Editor, doc_id: DocumentId, mut links: Vec<DocumentLink>) {\n    let Some(doc) = editor.documents.get_mut(&doc_id) else {\n        return;\n    };\n\n    if links.is_empty() {\n        doc.document_links.clear();\n        return;\n    }\n\n    links.sort_by_key(|link| (link.start, link.end));\n    doc.document_links = links;\n}\n\npub(super) fn register_hooks(handlers: &Handlers) {\n    register_hook!(move |event: &mut DocumentDidOpen<'_>| {\n        request_document_links(event.editor, event.doc);\n        Ok(())\n    });\n\n    let tx = handlers.document_links.clone();\n    register_hook!(move |event: &mut DocumentDidChange<'_>| {\n        event\n            .changes\n            .update_positions(event.doc.document_links.iter_mut().flat_map(|link| {\n                std::iter::once((&mut link.start, Assoc::After))\n                    .chain(std::iter::once((&mut link.end, Assoc::After)))\n            }));\n\n        if !event.ghost_transaction {\n            event.doc.document_link_controller.cancel();\n            helix_event::send_blocking(&tx, DocumentLinksEvent(event.doc.id()));\n        }\n\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut LanguageServerInitialized<'_>| {\n        let doc_ids: Vec<_> = event.editor.documents().map(|doc| doc.id()).collect();\n\n        for doc_id in doc_ids {\n            request_document_links(event.editor, doc_id);\n        }\n\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut LanguageServerExited<'_>| {\n        for doc in event.editor.documents_mut() {\n            if doc.supports_language_server(event.server_id) {\n                doc.document_links.clear();\n            }\n        }\n\n        let doc_ids: Vec<_> = event.editor.documents().map(|doc| doc.id()).collect();\n\n        for doc_id in doc_ids {\n            request_document_links(event.editor, doc_id);\n        }\n\n        Ok(())\n    });\n}\n"
  },
  {
    "path": "helix-term/src/handlers/prompt.rs",
    "content": "use helix_event::register_hook;\nuse helix_view::events::DocumentFocusLost;\nuse helix_view::handlers::Handlers;\n\nuse crate::job::{self};\nuse crate::ui;\n\npub(super) fn register_hooks(_handlers: &Handlers) {\n    register_hook!(move |_event: &mut DocumentFocusLost<'_>| {\n        job::dispatch_blocking(move |_, compositor| {\n            if compositor.find::<ui::Prompt>().is_some() {\n                compositor.remove_type::<ui::Prompt>();\n            }\n        });\n        Ok(())\n    });\n}\n"
  },
  {
    "path": "helix-term/src/handlers/signature_help.rs",
    "content": "use std::sync::Arc;\nuse std::time::Duration;\n\nuse helix_core::syntax::config::LanguageServerFeature;\nuse helix_event::{cancelable_future, register_hook, send_blocking, TaskController, TaskHandle};\nuse helix_lsp::lsp::{self, SignatureInformation};\nuse helix_stdx::rope::RopeSliceExt;\nuse helix_view::document::Mode;\nuse helix_view::events::{DocumentDidChange, SelectionDidChange};\nuse helix_view::handlers::lsp::{SignatureHelpEvent, SignatureHelpInvoked};\nuse helix_view::Editor;\nuse tokio::sync::mpsc::Sender;\nuse tokio::time::Instant;\n\nuse crate::commands::Open;\nuse crate::compositor::Compositor;\nuse crate::events::{OnModeSwitch, PostInsertChar};\nuse crate::handlers::Handlers;\nuse crate::ui::lsp::signature_help::{Signature, SignatureHelp};\nuse crate::ui::Popup;\nuse crate::{job, ui};\n\n#[derive(Debug, PartialEq, Eq)]\nenum State {\n    Open,\n    Closed,\n    Pending,\n}\n\n/// debounce timeout in ms, value taken from VSCode\n/// TODO: make this configurable?\nconst TIMEOUT: u64 = 120;\n\n#[derive(Debug)]\npub(super) struct SignatureHelpHandler {\n    trigger: Option<SignatureHelpInvoked>,\n    state: State,\n    task_controller: TaskController,\n}\n\nimpl SignatureHelpHandler {\n    pub fn new() -> SignatureHelpHandler {\n        SignatureHelpHandler {\n            trigger: None,\n            state: State::Closed,\n            task_controller: TaskController::new(),\n        }\n    }\n}\n\nimpl helix_event::AsyncHook for SignatureHelpHandler {\n    type Event = SignatureHelpEvent;\n\n    fn handle_event(\n        &mut self,\n        event: Self::Event,\n        timeout: Option<tokio::time::Instant>,\n    ) -> Option<Instant> {\n        match event {\n            SignatureHelpEvent::Invoked => {\n                self.trigger = Some(SignatureHelpInvoked::Manual);\n                self.state = State::Closed;\n                self.finish_debounce();\n                return None;\n            }\n            SignatureHelpEvent::Trigger => {}\n            SignatureHelpEvent::ReTrigger => {\n                // don't retrigger if we aren't open/pending yet\n                if matches!(self.state, State::Closed) {\n                    return timeout;\n                }\n            }\n            SignatureHelpEvent::Cancel => {\n                self.state = State::Closed;\n                return None;\n            }\n            SignatureHelpEvent::RequestComplete { open } => {\n                // don't cancel rerequest that was already triggered\n                if self.state == State::Pending && self.task_controller.is_running() {\n                    return timeout;\n                }\n                self.state = if open { State::Open } else { State::Closed };\n                self.task_controller.cancel();\n\n                return timeout;\n            }\n        }\n        if self.trigger.is_none() {\n            self.trigger = Some(SignatureHelpInvoked::Automatic)\n        }\n        Some(Instant::now() + Duration::from_millis(TIMEOUT))\n    }\n\n    fn finish_debounce(&mut self) {\n        let invocation = self.trigger.take().unwrap();\n        self.state = State::Pending;\n        let handle = self.task_controller.restart();\n        job::dispatch_blocking(move |editor, _| request_signature_help(editor, invocation, handle))\n    }\n}\n\npub fn request_signature_help(\n    editor: &mut Editor,\n    invoked: SignatureHelpInvoked,\n    cancel: TaskHandle,\n) {\n    let (view, doc) = current!(editor);\n\n    // TODO merge multiple language server signature help into one instead of just taking the first language server that supports it\n    let future = doc\n        .language_servers_with_feature(LanguageServerFeature::SignatureHelp)\n        .find_map(|language_server| {\n            let pos = doc.position(view.id, language_server.offset_encoding());\n            language_server.text_document_signature_help(doc.identifier(), pos, None)\n        });\n\n    let Some(future) = future else {\n        // Do not show the message if signature help was invoked\n        // automatically on backspace, trigger characters, etc.\n        if invoked == SignatureHelpInvoked::Manual {\n            editor.set_error(\"No configured language server supports signature-help\");\n        }\n        return;\n    };\n\n    tokio::spawn(async move {\n        match cancelable_future(future, cancel).await {\n            Some(Ok(res)) => {\n                job::dispatch(move |editor, compositor| {\n                    show_signature_help(editor, compositor, invoked, res)\n                })\n                .await\n            }\n            Some(Err(err)) => log::error!(\"signature help request failed: {err}\"),\n            None => (),\n        }\n    });\n}\n\nfn active_param_range(\n    signature: &SignatureInformation,\n    response_active_parameter: Option<u32>,\n) -> Option<(usize, usize)> {\n    let param_idx = signature\n        .active_parameter\n        .or(response_active_parameter)\n        .unwrap_or(0) as usize;\n    let param = signature.parameters.as_ref()?.get(param_idx)?;\n    match &param.label {\n        lsp::ParameterLabel::Simple(string) => {\n            let start = signature.label.find(string.as_str())?;\n            Some((start, start + string.len()))\n        }\n        lsp::ParameterLabel::LabelOffsets([start, end]) => {\n            // LS sends offsets based on utf-16 based string representation\n            // but highlighting in helix is done using byte offset.\n            use helix_core::str_utils::char_to_byte_idx;\n            let from = char_to_byte_idx(&signature.label, *start as usize);\n            let to = char_to_byte_idx(&signature.label, *end as usize);\n            Some((from, to))\n        }\n    }\n}\n\npub fn show_signature_help(\n    editor: &mut Editor,\n    compositor: &mut Compositor,\n    invoked: SignatureHelpInvoked,\n    response: Option<lsp::SignatureHelp>,\n) {\n    let config = &editor.config();\n\n    if !(config.lsp.auto_signature_help\n        || SignatureHelp::visible_popup(compositor).is_some()\n        || invoked == SignatureHelpInvoked::Manual)\n    {\n        return;\n    }\n\n    // If the signature help invocation is automatic, don't show it outside of Insert Mode:\n    // it very probably means the server was a little slow to respond and the user has\n    // already moved on to something else, making a signature help popup will just be an\n    // annoyance, see https://github.com/helix-editor/helix/issues/3112\n    // For the most part this should not be needed as the request gets canceled automatically now\n    // but it's technically possible for the mode change to just preempt this callback so better safe than sorry\n    if invoked == SignatureHelpInvoked::Automatic && editor.mode != Mode::Insert {\n        return;\n    }\n\n    let response = match response {\n        // According to the spec the response should be None if there\n        // are no signatures, but some servers don't follow this.\n        Some(s) if !s.signatures.is_empty() => s,\n        _ => {\n            send_blocking(\n                &editor.handlers.signature_hints,\n                SignatureHelpEvent::RequestComplete { open: false },\n            );\n            compositor.remove(SignatureHelp::ID);\n            return;\n        }\n    };\n    send_blocking(\n        &editor.handlers.signature_hints,\n        SignatureHelpEvent::RequestComplete { open: true },\n    );\n\n    let doc = doc!(editor);\n    let language = doc.language_name().unwrap_or(\"\");\n\n    if response.signatures.is_empty() {\n        return;\n    }\n\n    let signatures: Vec<Signature> = response\n        .signatures\n        .into_iter()\n        .map(|s| {\n            let active_param_range = active_param_range(&s, response.active_parameter);\n\n            let signature_doc = if config.lsp.display_signature_help_docs {\n                s.documentation.map(|doc| match doc {\n                    lsp::Documentation::String(s) => s,\n                    lsp::Documentation::MarkupContent(markup) => markup.value,\n                })\n            } else {\n                None\n            };\n\n            Signature {\n                signature: s.label,\n                signature_doc,\n                active_param_range,\n            }\n        })\n        .collect();\n\n    let old_popup = compositor.find_id::<Popup<SignatureHelp>>(SignatureHelp::ID);\n    let lsp_signature = response.active_signature.map(|s| s as usize);\n\n    // take the new suggested lsp signature if changed\n    // otherwise take the old signature if possible\n    // otherwise the last one (in case there is less signatures than before)\n    let active_signature = old_popup\n        .as_ref()\n        .map(|popup| {\n            let old_lsp_sig = popup.contents().lsp_signature();\n            let old_sig = popup\n                .contents()\n                .active_signature()\n                .min(signatures.len() - 1);\n\n            if old_lsp_sig != lsp_signature {\n                lsp_signature.unwrap_or(old_sig)\n            } else {\n                old_sig\n            }\n        })\n        .unwrap_or(lsp_signature.unwrap_or_default());\n\n    let contents = SignatureHelp::new(\n        language.to_string(),\n        Arc::clone(&editor.syn_loader),\n        active_signature,\n        lsp_signature,\n        signatures,\n    );\n\n    let mut popup = Popup::new(SignatureHelp::ID, contents)\n        .position(old_popup.and_then(|p| p.get_position()))\n        .position_bias(Open::Above)\n        .ignore_escape_key(true);\n\n    // Don't create a popup if it intersects the auto-complete menu.\n    let size = compositor.size();\n    if compositor\n        .find::<ui::EditorView>()\n        .unwrap()\n        .completion\n        .as_mut()\n        .map(|completion| completion.area(size, editor))\n        .filter(|area| area.intersects(popup.area(size, editor)))\n        .is_some()\n    {\n        return;\n    }\n\n    compositor.replace_or_push(SignatureHelp::ID, popup);\n}\n\nfn signature_help_post_insert_char_hook(\n    tx: &Sender<SignatureHelpEvent>,\n    PostInsertChar { cx, .. }: &mut PostInsertChar<'_, '_>,\n) -> anyhow::Result<()> {\n    if !cx.editor.config().lsp.auto_signature_help {\n        return Ok(());\n    }\n    let (view, doc) = current!(cx.editor);\n    // TODO support multiple language servers (not just the first that is found), likely by merging UI somehow\n    let Some(language_server) = doc\n        .language_servers_with_feature(LanguageServerFeature::SignatureHelp)\n        .next()\n    else {\n        return Ok(());\n    };\n\n    let capabilities = language_server.capabilities();\n\n    if let lsp::ServerCapabilities {\n        signature_help_provider:\n            Some(lsp::SignatureHelpOptions {\n                trigger_characters: Some(triggers),\n                // TODO: retrigger_characters\n                ..\n            }),\n        ..\n    } = capabilities\n    {\n        let mut text = doc.text().slice(..);\n        let cursor = doc.selection(view.id).primary().cursor(text);\n        text = text.slice(..cursor);\n        if triggers.iter().any(|trigger| text.ends_with(trigger)) {\n            send_blocking(tx, SignatureHelpEvent::Trigger)\n        }\n    }\n    Ok(())\n}\n\npub(super) fn register_hooks(handlers: &Handlers) {\n    let tx = handlers.signature_hints.clone();\n    register_hook!(move |event: &mut OnModeSwitch<'_, '_>| {\n        match (event.old_mode, event.new_mode) {\n            (Mode::Insert, _) => {\n                send_blocking(&tx, SignatureHelpEvent::Cancel);\n                event.cx.callback.push(Box::new(|compositor, _| {\n                    compositor.remove(SignatureHelp::ID);\n                }));\n            }\n            (_, Mode::Insert) => {\n                if event.cx.editor.config().lsp.auto_signature_help {\n                    send_blocking(&tx, SignatureHelpEvent::Trigger);\n                }\n            }\n            _ => (),\n        }\n        Ok(())\n    });\n\n    let tx = handlers.signature_hints.clone();\n    register_hook!(\n        move |event: &mut PostInsertChar<'_, '_>| signature_help_post_insert_char_hook(&tx, event)\n    );\n\n    let tx = handlers.signature_hints.clone();\n    register_hook!(move |event: &mut DocumentDidChange<'_>| {\n        if event.doc.config.load().lsp.auto_signature_help && !event.ghost_transaction {\n            send_blocking(&tx, SignatureHelpEvent::ReTrigger);\n        }\n        Ok(())\n    });\n\n    let tx = handlers.signature_hints.clone();\n    register_hook!(move |event: &mut SelectionDidChange<'_>| {\n        if event.doc.config.load().lsp.auto_signature_help {\n            send_blocking(&tx, SignatureHelpEvent::ReTrigger);\n        }\n        Ok(())\n    });\n}\n"
  },
  {
    "path": "helix-term/src/handlers/snippet.rs",
    "content": "use helix_event::register_hook;\nuse helix_view::events::{DocumentDidChange, DocumentFocusLost, SelectionDidChange};\nuse helix_view::handlers::Handlers;\n\npub(super) fn register_hooks(_handlers: &Handlers) {\n    register_hook!(move |event: &mut SelectionDidChange<'_>| {\n        if let Some(snippet) = &event.doc.active_snippet {\n            if !snippet.is_valid(event.doc.selection(event.view)) {\n                event.doc.active_snippet = None;\n            }\n        }\n        Ok(())\n    });\n    register_hook!(move |event: &mut DocumentDidChange<'_>| {\n        if let Some(snippet) = &mut event.doc.active_snippet {\n            let invalid = snippet.map(event.changes);\n            if invalid {\n                event.doc.active_snippet = None;\n            }\n        }\n        Ok(())\n    });\n    register_hook!(move |event: &mut DocumentFocusLost<'_>| {\n        let editor = &mut event.editor;\n        doc_mut!(editor).active_snippet = None;\n        Ok(())\n    });\n}\n"
  },
  {
    "path": "helix-term/src/handlers.rs",
    "content": "use std::sync::Arc;\n\nuse arc_swap::ArcSwap;\nuse diagnostics::PullAllDocumentsDiagnosticHandler;\nuse helix_event::AsyncHook;\n\nuse crate::config::Config;\nuse crate::events;\nuse crate::handlers::auto_save::AutoSaveHandler;\nuse crate::handlers::diagnostics::PullDiagnosticsHandler;\nuse crate::handlers::signature_help::SignatureHelpHandler;\n\npub use helix_view::handlers::{word_index, Handlers};\n\nuse self::document_colors::DocumentColorsHandler;\nuse self::document_links::DocumentLinksHandler;\n\nmod auto_save;\npub mod completion;\npub mod diagnostics;\nmod document_colors;\nmod document_highlight;\nmod document_links;\nmod prompt;\nmod signature_help;\nmod snippet;\n\npub fn setup(config: Arc<ArcSwap<Config>>) -> Handlers {\n    events::register();\n\n    let event_tx = completion::CompletionHandler::new(config).spawn();\n    let signature_hints = SignatureHelpHandler::new().spawn();\n    let auto_save = AutoSaveHandler::new().spawn();\n    let document_colors = DocumentColorsHandler::default().spawn();\n    let document_links = DocumentLinksHandler::default().spawn();\n    let word_index = word_index::Handler::spawn();\n    let pull_diagnostics = PullDiagnosticsHandler::default().spawn();\n    let pull_all_documents_diagnostics = PullAllDocumentsDiagnosticHandler::default().spawn();\n\n    let handlers = Handlers {\n        completions: helix_view::handlers::completion::CompletionHandler::new(event_tx),\n        signature_hints,\n        auto_save,\n        document_colors,\n        document_links,\n        word_index,\n        pull_diagnostics,\n        pull_all_documents_diagnostics,\n    };\n\n    helix_view::handlers::register_hooks(&handlers);\n    completion::register_hooks(&handlers);\n    signature_help::register_hooks(&handlers);\n    document_highlight::register_hooks(&handlers);\n    auto_save::register_hooks(&handlers);\n    diagnostics::register_hooks(&handlers);\n    snippet::register_hooks(&handlers);\n    document_colors::register_hooks(&handlers);\n    document_links::register_hooks(&handlers);\n    prompt::register_hooks(&handlers);\n    handlers\n}\n"
  },
  {
    "path": "helix-term/src/health.rs",
    "content": "use crate::config::{Config, ConfigLoadError};\nuse helix_core::config::{default_lang_config, user_lang_config};\nuse helix_loader::grammar::load_runtime_file;\nuse std::{\n    collections::HashSet,\n    io::{IsTerminal, Write},\n};\nuse termina::{\n    style::{ColorSpec, StyleExt as _, Stylized},\n    Terminal as _,\n};\n\n#[derive(Copy, Clone)]\npub enum TsFeature {\n    Highlight,\n    TextObject,\n    AutoIndent,\n    Tags,\n    RainbowBracket,\n}\n\nimpl TsFeature {\n    pub fn all() -> &'static [Self] {\n        &[\n            Self::Highlight,\n            Self::TextObject,\n            Self::AutoIndent,\n            Self::Tags,\n            Self::RainbowBracket,\n        ]\n    }\n\n    pub fn runtime_filename(&self) -> &'static str {\n        match *self {\n            Self::Highlight => \"highlights.scm\",\n            Self::TextObject => \"textobjects.scm\",\n            Self::AutoIndent => \"indents.scm\",\n            Self::Tags => \"tags.scm\",\n            Self::RainbowBracket => \"rainbows.scm\",\n        }\n    }\n\n    pub fn long_title(&self) -> &'static str {\n        match *self {\n            Self::Highlight => \"Syntax Highlighting\",\n            Self::TextObject => \"Treesitter Textobjects\",\n            Self::AutoIndent => \"Auto Indent\",\n            Self::Tags => \"Code Navigation Tags\",\n            Self::RainbowBracket => \"Rainbow Brackets\",\n        }\n    }\n\n    pub fn short_title(&self) -> &'static str {\n        match *self {\n            Self::Highlight => \"Highlight\",\n            Self::TextObject => \"Textobject\",\n            Self::AutoIndent => \"Indent\",\n            Self::Tags => \"Tags\",\n            Self::RainbowBracket => \"Rainbow\",\n        }\n    }\n}\n\n/// Display general diagnostics.\npub fn general() -> std::io::Result<()> {\n    let stdout = std::io::stdout();\n    let mut stdout = stdout.lock();\n\n    let config_file = helix_loader::config_file();\n    let lang_file = helix_loader::lang_config_file();\n    let log_file = helix_loader::log_file();\n    let rt_dirs = helix_loader::runtime_dirs();\n\n    if config_file.exists() {\n        writeln!(stdout, \"Config file: {}\", config_file.display())?;\n    } else {\n        writeln!(stdout, \"Config file: default\")?;\n    }\n    if lang_file.exists() {\n        writeln!(stdout, \"Language file: {}\", lang_file.display())?;\n    } else {\n        writeln!(stdout, \"Language file: default\")?;\n    }\n    writeln!(stdout, \"Log file: {}\", log_file.display())?;\n    writeln!(\n        stdout,\n        \"Runtime directories: {}\",\n        rt_dirs\n            .iter()\n            .map(|d| d.to_string_lossy())\n            .collect::<Vec<_>>()\n            .join(\";\")\n    )?;\n    for rt_dir in rt_dirs.iter() {\n        if let Ok(path) = std::fs::read_link(rt_dir) {\n            let msg = format!(\n                \"Runtime directory {} is symlinked to: {}\",\n                rt_dir.display(),\n                path.display()\n            );\n            writeln!(stdout, \"{}\", msg.yellow())?;\n        }\n        if !rt_dir.exists() {\n            let msg = format!(\"Runtime directory does not exist: {}\", rt_dir.display());\n            writeln!(stdout, \"{}\", msg.yellow())?;\n        } else if rt_dir.read_dir().ok().map(|it| it.count()) == Some(0) {\n            let msg = format!(\"Runtime directory is empty: {}\", rt_dir.display());\n            writeln!(stdout, \"{}\", msg.yellow())?;\n        }\n    }\n\n    Ok(())\n}\n\npub fn clipboard() -> std::io::Result<()> {\n    let stdout = std::io::stdout();\n    let mut stdout = stdout.lock();\n\n    let config = match Config::load_default() {\n        Ok(config) => config,\n        Err(ConfigLoadError::Error(err)) if err.kind() == std::io::ErrorKind::NotFound => {\n            Config::default()\n        }\n        Err(err) => {\n            writeln!(stdout, \"{}\", \"Configuration file malformed\".red())?;\n            writeln!(stdout, \"{}\", err)?;\n            return Ok(());\n        }\n    };\n\n    match config.editor.clipboard_provider.name().as_ref() {\n        \"none\" => {\n            writeln!(\n                stdout,\n                \"{}\",\n                \"System clipboard provider: Not installed\".red()\n            )?;\n            writeln!(\n                stdout,\n                \"    {}\",\n                \"For troubleshooting system clipboard issues, refer\".red()\n            )?;\n            writeln!(stdout, \"    {}\",\n                \"https://github.com/helix-editor/helix/wiki/Troubleshooting#copypaste-fromto-system-clipboard-not-working\"\n            .red().underlined())?;\n        }\n        name => writeln!(stdout, \"System clipboard provider: {}\", name)?,\n    }\n\n    Ok(())\n}\n\npub fn languages_all() -> std::io::Result<()> {\n    languages(None)\n}\n\npub fn languages_selection() -> std::io::Result<()> {\n    let selection = helix_loader::grammar::get_grammar_names().unwrap_or_default();\n    languages(selection)\n}\n\nfn languages(selection: Option<HashSet<String>>) -> std::io::Result<()> {\n    let stdout = std::io::stdout();\n    let mut stdout = stdout.lock();\n\n    let mut syn_loader_conf = match user_lang_config() {\n        Ok(conf) => conf,\n        Err(err) => {\n            let stderr = std::io::stderr();\n            let mut stderr = stderr.lock();\n\n            writeln!(\n                stderr,\n                \"{}: {}\",\n                \"Error parsing user language config\".red(),\n                err\n            )?;\n            writeln!(stderr, \"{}\", \"Using default language config\".yellow())?;\n            default_lang_config()\n        }\n    };\n\n    let mut headings = vec![\"Language\", \"Language servers\", \"Debug adapter\", \"Formatter\"];\n\n    for feat in TsFeature::all() {\n        headings.push(feat.short_title())\n    }\n\n    let terminal_cols = termina::PlatformTerminal::new()\n        .and_then(|terminal| terminal.get_dimensions())\n        .map(|size| size.cols)\n        .unwrap_or(80);\n    let column_width = terminal_cols as usize / headings.len();\n    let is_terminal = std::io::stdout().is_terminal();\n\n    let fit = |s: &str| -> Stylized<'static> {\n        format!(\n            \"{:column_width$}\",\n            s.get(..column_width - 2)\n                .map(|s| format!(\"{}…\", s))\n                .unwrap_or_else(|| s.to_string())\n        )\n        .stylized()\n    };\n    let color = |s: Stylized<'static>, c: ColorSpec| if is_terminal { s.foreground(c) } else { s };\n    let bold = |s: Stylized<'static>| if is_terminal { s.bold() } else { s };\n\n    for heading in headings {\n        write!(stdout, \"{}\", bold(fit(heading)))?;\n    }\n    writeln!(stdout)?;\n\n    syn_loader_conf\n        .language\n        .sort_unstable_by_key(|l| l.language_id.clone());\n\n    let check_binary_with_name = |cmd: Option<(&str, &str)>| match cmd {\n        Some((name, cmd)) => match helix_stdx::env::which(cmd) {\n            Ok(_) => color(fit(&format!(\"✓ {}\", name)), ColorSpec::BRIGHT_GREEN),\n            Err(_) => color(fit(&format!(\"✘ {}\", name)), ColorSpec::BRIGHT_RED),\n        },\n        None => color(fit(\"None\"), ColorSpec::BRIGHT_YELLOW),\n    };\n\n    let check_binary = |cmd: Option<&str>| check_binary_with_name(cmd.map(|cmd| (cmd, cmd)));\n\n    for lang in &syn_loader_conf.language {\n        if selection\n            .as_ref()\n            .is_some_and(|s| !s.contains(&lang.language_id))\n        {\n            continue;\n        }\n\n        write!(stdout, \"{}\", fit(&lang.language_id))?;\n\n        let mut cmds = lang.language_servers.iter().filter_map(|ls| {\n            syn_loader_conf\n                .language_server\n                .get(&ls.name)\n                .map(|config| (ls.name.as_str(), config.command.as_str()))\n        });\n        write!(stdout, \"{}\", check_binary_with_name(cmds.next()))?;\n\n        let dap = lang.debugger.as_ref().map(|dap| dap.command.as_str());\n        write!(stdout, \"{}\", check_binary(dap))?;\n\n        let formatter = lang\n            .formatter\n            .as_ref()\n            .map(|formatter| formatter.command.as_str());\n        write!(stdout, \"{}\", check_binary(formatter))?;\n\n        for ts_feat in TsFeature::all() {\n            match load_runtime_file(&lang.language_id, ts_feat.runtime_filename()).is_ok() {\n                true => write!(stdout, \"{}\", color(fit(\"✓\"), ColorSpec::BRIGHT_GREEN))?,\n                false => write!(stdout, \"{}\", color(fit(\"✘\"), ColorSpec::BRIGHT_RED))?,\n            }\n        }\n\n        writeln!(stdout)?;\n\n        for cmd in cmds {\n            write!(stdout, \"{}\", fit(\"\"))?;\n            writeln!(stdout, \"{}\", check_binary_with_name(Some(cmd)))?;\n        }\n    }\n\n    if selection.is_some() {\n        writeln!(\n            stdout,\n            \"\\nThis list is filtered according to the 'use-grammars' option in languages.toml file.\\n\\\n            To see the full list, use the '--health all' or '--health all-languages' option.\"\n        )?;\n    }\n\n    Ok(())\n}\n\n/// Display diagnostics pertaining to a particular language (LSP,\n/// highlight queries, etc).\npub fn language(lang_str: String) -> std::io::Result<()> {\n    let stdout = std::io::stdout();\n    let mut stdout = stdout.lock();\n\n    let syn_loader_conf = match user_lang_config() {\n        Ok(conf) => conf,\n        Err(err) => {\n            let stderr = std::io::stderr();\n            let mut stderr = stderr.lock();\n\n            writeln!(\n                stderr,\n                \"{}: {}\",\n                \"Error parsing user language config\".red(),\n                err\n            )?;\n            writeln!(stderr, \"{}\", \"Using default language config\".yellow())?;\n            default_lang_config()\n        }\n    };\n\n    let lang = match syn_loader_conf\n        .language\n        .iter()\n        .find(|l| l.language_id == lang_str)\n    {\n        Some(l) => l,\n        None => {\n            let msg = format!(\"Language '{}' not found\", lang_str);\n            writeln!(stdout, \"{}\", msg.red())?;\n            let suggestions: Vec<&str> = syn_loader_conf\n                .language\n                .iter()\n                .filter(|l| l.language_id.starts_with(lang_str.chars().next().unwrap()))\n                .map(|l| l.language_id.as_str())\n                .collect();\n            if !suggestions.is_empty() {\n                let suggestions = suggestions.join(\", \");\n                writeln!(\n                    stdout,\n                    \"Did you mean one of these: {} ?\",\n                    suggestions.yellow()\n                )?;\n            }\n            return Ok(());\n        }\n    };\n\n    probe_protocols(\n        \"language server\",\n        lang.language_servers.iter().filter_map(|ls| {\n            syn_loader_conf\n                .language_server\n                .get(&ls.name)\n                .map(|config| (ls.name.as_str(), config.command.as_str()))\n        }),\n    )?;\n\n    probe_protocol(\n        \"debug adapter\",\n        lang.debugger.as_ref().map(|dap| dap.command.to_string()),\n    )?;\n\n    probe_protocol(\n        \"formatter\",\n        lang.formatter\n            .as_ref()\n            .map(|formatter| formatter.command.to_string()),\n    )?;\n\n    probe_parser(lang.grammar.as_ref().unwrap_or(&lang.language_id))?;\n\n    for ts_feat in TsFeature::all() {\n        probe_treesitter_feature(&lang_str, *ts_feat)?\n    }\n\n    Ok(())\n}\n\nfn probe_parser(grammar_name: &str) -> std::io::Result<()> {\n    let stdout = std::io::stdout();\n    let mut stdout = stdout.lock();\n\n    write!(stdout, \"Tree-sitter parser: \")?;\n\n    match helix_loader::grammar::get_language(grammar_name) {\n        Ok(Some(_)) => writeln!(stdout, \"{}\", \"✓\".green()),\n        Ok(None) | Err(_) => writeln!(stdout, \"{}\", \"None\".yellow()),\n    }\n}\n\n/// Display diagnostics about multiple LSPs and DAPs.\nfn probe_protocols<'a, I: Iterator<Item = (&'a str, &'a str)> + 'a>(\n    protocol_name: &str,\n    server_cmds: I,\n) -> std::io::Result<()> {\n    let stdout = std::io::stdout();\n    let mut stdout = stdout.lock();\n    let mut server_cmds = server_cmds.peekable();\n\n    write!(stdout, \"Configured {}s:\", protocol_name)?;\n    if server_cmds.peek().is_none() {\n        writeln!(stdout, \"{}\", \" None\".yellow())?;\n        return Ok(());\n    }\n    writeln!(stdout)?;\n\n    for (name, cmd) in server_cmds {\n        let (diag, icon) = match helix_stdx::env::which(cmd) {\n            Ok(path) => (path.display().to_string().green(), \"✓\".green()),\n            Err(_) => (format!(\"'{}' not found in $PATH\", cmd).red(), \"✘\".red()),\n        };\n        writeln!(stdout, \"  {} {}: {}\", icon, name, diag)?;\n    }\n\n    Ok(())\n}\n\n/// Display diagnostics about LSP and DAP.\nfn probe_protocol(protocol_name: &str, server_cmd: Option<String>) -> std::io::Result<()> {\n    let stdout = std::io::stdout();\n    let mut stdout = stdout.lock();\n\n    write!(stdout, \"Configured {}:\", protocol_name)?;\n    let Some(cmd) = server_cmd else {\n        writeln!(stdout, \"{}\", \" None\".yellow())?;\n        return Ok(());\n    };\n    writeln!(stdout)?;\n\n    let (diag, icon) = match helix_stdx::env::which(&cmd) {\n        Ok(path) => (path.display().to_string().green(), \"✓\".green()),\n        Err(_) => (format!(\"'{}' not found in $PATH\", cmd).red(), \"✘\".red()),\n    };\n    writeln!(stdout, \"  {} {}\", icon, diag)?;\n\n    Ok(())\n}\n\n/// Display diagnostics about a feature that requires tree-sitter\n/// query files (highlights, textobjects, etc).\nfn probe_treesitter_feature(lang: &str, feature: TsFeature) -> std::io::Result<()> {\n    let stdout = std::io::stdout();\n    let mut stdout = stdout.lock();\n\n    let found = match load_runtime_file(lang, feature.runtime_filename()).is_ok() {\n        true => \"✓\".green(),\n        false => \"✘\".red(),\n    };\n    writeln!(stdout, \"{} queries: {}\", feature.short_title(), found)?;\n\n    Ok(())\n}\n\npub fn print_health(health_arg: Option<String>) -> std::io::Result<()> {\n    match health_arg.as_deref() {\n        Some(\"languages\") => languages_selection()?,\n        Some(\"all-languages\") => languages_all()?,\n        Some(\"clipboard\") => clipboard()?,\n        None => {\n            general()?;\n            clipboard()?;\n            writeln!(std::io::stdout().lock())?;\n            languages_selection()?;\n        }\n        Some(\"all\") => {\n            general()?;\n            clipboard()?;\n            writeln!(std::io::stdout().lock())?;\n            languages_all()?;\n        }\n        Some(lang) => language(lang.to_string())?,\n    }\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/src/job.rs",
    "content": "use helix_event::status::StatusMessage;\nuse helix_event::{runtime_local, send_blocking};\nuse helix_view::Editor;\nuse once_cell::sync::OnceCell;\n\nuse crate::compositor::Compositor;\n\nuse futures_util::future::{BoxFuture, Future, FutureExt};\nuse futures_util::stream::{FuturesUnordered, StreamExt};\nuse tokio::sync::mpsc::{channel, Receiver, Sender};\n\npub type EditorCompositorCallback = Box<dyn FnOnce(&mut Editor, &mut Compositor) + Send>;\npub type EditorCallback = Box<dyn FnOnce(&mut Editor) + Send>;\n\nruntime_local! {\n    static JOB_QUEUE: OnceCell<Sender<Callback>> = OnceCell::new();\n}\n\npub async fn dispatch_callback(job: Callback) {\n    let _ = JOB_QUEUE.wait().send(job).await;\n}\n\npub async fn dispatch(job: impl FnOnce(&mut Editor, &mut Compositor) + Send + 'static) {\n    let _ = JOB_QUEUE\n        .wait()\n        .send(Callback::EditorCompositor(Box::new(job)))\n        .await;\n}\n\npub fn dispatch_blocking(job: impl FnOnce(&mut Editor, &mut Compositor) + Send + 'static) {\n    let jobs = JOB_QUEUE.wait();\n    send_blocking(jobs, Callback::EditorCompositor(Box::new(job)))\n}\n\npub enum Callback {\n    EditorCompositor(EditorCompositorCallback),\n    Editor(EditorCallback),\n}\n\npub type JobFuture = BoxFuture<'static, anyhow::Result<Option<Callback>>>;\n\npub struct Job {\n    pub future: BoxFuture<'static, anyhow::Result<Option<Callback>>>,\n    /// Do we need to wait for this job to finish before exiting?\n    pub wait: bool,\n}\n\npub struct Jobs {\n    /// jobs that need to complete before we exit.\n    pub wait_futures: FuturesUnordered<JobFuture>,\n    pub callbacks: Receiver<Callback>,\n    pub status_messages: Receiver<StatusMessage>,\n}\n\nimpl Job {\n    pub fn new<F: Future<Output = anyhow::Result<()>> + Send + 'static>(f: F) -> Self {\n        Self {\n            future: f.map(|r| r.map(|()| None)).boxed(),\n            wait: false,\n        }\n    }\n\n    pub fn with_callback<F: Future<Output = anyhow::Result<Callback>> + Send + 'static>(\n        f: F,\n    ) -> Self {\n        Self {\n            future: f.map(|r| r.map(Some)).boxed(),\n            wait: false,\n        }\n    }\n\n    pub fn wait_before_exiting(mut self) -> Self {\n        self.wait = true;\n        self\n    }\n}\n\nimpl Jobs {\n    #[allow(clippy::new_without_default)]\n    pub fn new() -> Self {\n        let (tx, rx) = channel(1024);\n        let _ = JOB_QUEUE.set(tx);\n        let status_messages = helix_event::status::setup();\n        Self {\n            wait_futures: FuturesUnordered::new(),\n            callbacks: rx,\n            status_messages,\n        }\n    }\n\n    pub fn spawn<F: Future<Output = anyhow::Result<()>> + Send + 'static>(&mut self, f: F) {\n        self.add(Job::new(f));\n    }\n\n    pub fn callback<F: Future<Output = anyhow::Result<Callback>> + Send + 'static>(\n        &mut self,\n        f: F,\n    ) {\n        self.add(Job::with_callback(f));\n    }\n\n    pub fn handle_callback(\n        &self,\n        editor: &mut Editor,\n        compositor: &mut Compositor,\n        call: anyhow::Result<Option<Callback>>,\n    ) {\n        match call {\n            Ok(None) => {}\n            Ok(Some(call)) => match call {\n                Callback::EditorCompositor(call) => call(editor, compositor),\n                Callback::Editor(call) => call(editor),\n            },\n            Err(e) => {\n                editor.set_error(format!(\"Async job failed: {}\", e));\n            }\n        }\n    }\n\n    pub fn add(&self, j: Job) {\n        if j.wait {\n            self.wait_futures.push(j.future);\n        } else {\n            tokio::spawn(async move {\n                match j.future.await {\n                    Ok(Some(cb)) => dispatch_callback(cb).await,\n                    Ok(None) => (),\n                    Err(err) => helix_event::status::report(err).await,\n                }\n            });\n        }\n    }\n\n    /// Blocks until all the jobs that need to be waited on are done.\n    pub async fn finish(\n        &mut self,\n        editor: &mut Editor,\n        mut compositor: Option<&mut Compositor>,\n    ) -> anyhow::Result<()> {\n        log::debug!(\"waiting on jobs...\");\n        let mut wait_futures = std::mem::take(&mut self.wait_futures);\n\n        while let (Some(job), tail) = wait_futures.into_future().await {\n            match job {\n                Ok(callback) => {\n                    wait_futures = tail;\n\n                    if let Some(callback) = callback {\n                        // clippy doesn't realize this is an error without the derefs\n                        #[allow(clippy::needless_option_as_deref)]\n                        match callback {\n                            Callback::EditorCompositor(call) if compositor.is_some() => {\n                                call(editor, compositor.as_deref_mut().unwrap())\n                            }\n                            Callback::Editor(call) => call(editor),\n\n                            // skip callbacks for which we don't have the necessary references\n                            _ => (),\n                        }\n                    }\n                }\n                Err(e) => {\n                    self.wait_futures = tail;\n                    return Err(e);\n                }\n            }\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "helix-term/src/keymap/default.rs",
    "content": "use std::collections::HashMap;\n\nuse super::macros::keymap;\nuse super::{KeyTrie, Mode};\nuse helix_core::hashmap;\n\npub fn default() -> HashMap<Mode, KeyTrie> {\n    let normal = keymap!({ \"Normal mode\"\n        \"h\" | \"left\" => move_char_left,\n        \"j\" | \"down\" => move_visual_line_down,\n        \"k\" | \"up\" => move_visual_line_up,\n        \"l\" | \"right\" => move_char_right,\n\n        \"t\" => find_till_char,\n        \"f\" => find_next_char,\n        \"T\" => till_prev_char,\n        \"F\" => find_prev_char,\n        \"r\" => replace,\n        \"R\" => replace_with_yanked,\n        \"A-.\" =>  repeat_last_motion,\n\n        \"~\" => switch_case,\n        \"`\" => switch_to_lowercase,\n        \"A-`\" => switch_to_uppercase,\n\n        \"home\" => goto_line_start,\n        \"end\" => goto_line_end,\n\n        \"w\" => move_next_word_start,\n        \"b\" => move_prev_word_start,\n        \"e\" => move_next_word_end,\n\n        \"W\" => move_next_long_word_start,\n        \"B\" => move_prev_long_word_start,\n        \"E\" => move_next_long_word_end,\n\n        \"v\" => select_mode,\n        \"G\" => goto_line,\n        \"g\" => { \"Goto\"\n            \"g\" => goto_file_start,\n            \"|\" => goto_column,\n            \"e\" => goto_last_line,\n            \"f\" => goto_file,\n            \"h\" => goto_line_start,\n            \"l\" => goto_line_end,\n            \"s\" => goto_first_nonwhitespace,\n            \"d\" => goto_definition,\n            \"D\" => goto_declaration,\n            \"y\" => goto_type_definition,\n            \"r\" => goto_reference,\n            \"i\" => goto_implementation,\n            \"t\" => goto_window_top,\n            \"c\" => goto_window_center,\n            \"b\" => goto_window_bottom,\n            \"a\" => goto_last_accessed_file,\n            \"m\" => goto_last_modified_file,\n            \"n\" => goto_next_buffer,\n            \"p\" => goto_previous_buffer,\n            \"k\" => move_line_up,\n            \"j\" => move_line_down,\n            \".\" => goto_last_modification,\n            \"w\" => goto_word,\n        },\n        \":\" => command_mode,\n\n        \"i\" => insert_mode,\n        \"I\" => insert_at_line_start,\n        \"a\" => append_mode,\n        \"A\" => insert_at_line_end,\n        \"o\" => open_below,\n        \"O\" => open_above,\n\n        \"d\" => delete_selection,\n        \"A-d\" => delete_selection_noyank,\n        \"c\" => change_selection,\n        \"A-c\" => change_selection_noyank,\n\n        \"C\" => copy_selection_on_next_line,\n        \"A-C\" => copy_selection_on_prev_line,\n\n\n        \"s\" => select_regex,\n        \"A-s\" => split_selection_on_newline,\n        \"A-minus\" => merge_selections,\n        \"A-_\" => merge_consecutive_selections,\n        \"S\" => split_selection,\n        \";\" => collapse_selection,\n        \"A-;\" => flip_selections,\n        \"A-o\" | \"A-up\" => expand_selection,\n        \"A-i\" | \"A-down\" => shrink_selection,\n        \"A-I\" | \"A-S-down\" => select_all_children,\n        \"A-p\" | \"A-left\" => select_prev_sibling,\n        \"A-n\" | \"A-right\" => select_next_sibling,\n        \"A-e\" => move_parent_node_end,\n        \"A-b\" => move_parent_node_start,\n        \"A-a\" => select_all_siblings,\n\n        \"%\" => select_all,\n        \"x\" => extend_line_below,\n        \"X\" => extend_to_line_bounds,\n        \"A-x\" => shrink_to_line_bounds,\n\n        \"m\" => { \"Match\"\n            \"m\" => match_brackets,\n            \"s\" => surround_add,\n            \"r\" => surround_replace,\n            \"d\" => surround_delete,\n            \"a\" => select_textobject_around,\n            \"i\" => select_textobject_inner,\n        },\n        \"[\" => { \"Left bracket\"\n            \"d\" => goto_prev_diag,\n            \"D\" => goto_first_diag,\n            \"g\" => goto_prev_change,\n            \"G\" => goto_first_change,\n            \"f\" => goto_prev_function,\n            \"t\" => goto_prev_class,\n            \"a\" => goto_prev_parameter,\n            \"c\" => goto_prev_comment,\n            \"e\" => goto_prev_entry,\n            \"T\" => goto_prev_test,\n            \"p\" => goto_prev_paragraph,\n            \"x\" => goto_prev_xml_element,\n            \"space\" => add_newline_above,\n        },\n        \"]\" => { \"Right bracket\"\n            \"d\" => goto_next_diag,\n            \"D\" => goto_last_diag,\n            \"g\" => goto_next_change,\n            \"G\" => goto_last_change,\n            \"f\" => goto_next_function,\n            \"t\" => goto_next_class,\n            \"a\" => goto_next_parameter,\n            \"c\" => goto_next_comment,\n            \"e\" => goto_next_entry,\n            \"T\" => goto_next_test,\n            \"p\" => goto_next_paragraph,\n            \"x\" => goto_next_xml_element,\n            \"space\" => add_newline_below,\n        },\n\n        \"/\" => search,\n        \"?\" => rsearch,\n        \"n\" => search_next,\n        \"N\" => search_prev,\n        \"*\" => search_selection_detect_word_boundaries,\n        \"A-*\" => search_selection,\n\n        \"u\" => undo,\n        \"U\" => redo,\n        \"A-u\" => earlier,\n        \"A-U\" => later,\n\n        \"y\" => yank,\n        // yank_all\n        \"p\" => paste_after,\n        // paste_all\n        \"P\" => paste_before,\n\n        \"Q\" => record_macro,\n        \"q\" => replay_macro,\n\n        \">\" => indent,\n        \"<\" => unindent,\n        \"=\" => format_selections,\n        \"J\" => join_selections,\n        \"A-J\" => join_selections_space,\n        \"K\" => keep_selections,\n        \"A-K\" => remove_selections,\n\n        \",\" => keep_primary_selection,\n        \"A-,\" => remove_primary_selection,\n\n        // \"q\" => record_macro,\n        // \"Q\" => replay_macro,\n\n        \"&\" => align_selections,\n        \"_\" => trim_selections,\n\n        \"(\" => rotate_selections_backward,\n        \")\" => rotate_selections_forward,\n        \"A-(\" => rotate_selection_contents_backward,\n        \"A-)\" => rotate_selection_contents_forward,\n\n        \"A-:\" => ensure_selections_forward,\n\n        \"esc\" => normal_mode,\n        \"C-b\" | \"pageup\" => page_up,\n        \"C-f\" | \"pagedown\" => page_down,\n        \"C-u\" => page_cursor_half_up,\n        \"C-d\" => page_cursor_half_down,\n\n        \"C-w\" => { \"Window\"\n            \"C-w\" | \"w\" => rotate_view,\n            \"C-s\" | \"s\" => hsplit,\n            \"C-v\" | \"v\" => vsplit,\n            \"C-t\" | \"t\" => transpose_view,\n            \"f\" => goto_file_hsplit,\n            \"F\" => goto_file_vsplit,\n            \"C-q\" | \"q\" => wclose,\n            \"C-o\" | \"o\" => wonly,\n            \"C-h\" | \"h\" | \"left\" => jump_view_left,\n            \"C-j\" | \"j\" | \"down\" => jump_view_down,\n            \"C-k\" | \"k\" | \"up\" => jump_view_up,\n            \"C-l\" | \"l\" | \"right\" => jump_view_right,\n            \"L\" => swap_view_right,\n            \"K\" => swap_view_up,\n            \"H\" => swap_view_left,\n            \"J\" => swap_view_down,\n            \"n\" => { \"New split scratch buffer\"\n                \"C-s\" | \"s\" => hsplit_new,\n                \"C-v\" | \"v\" => vsplit_new,\n            },\n        },\n\n        // move under <space>c\n        \"C-c\" => toggle_comments,\n\n        // z family for save/restore/combine from/to sels from register\n\n        \"C-i\" | \"tab\" => jump_forward, // tab == <C-i>\n        \"C-o\" => jump_backward,\n        \"C-s\" => save_selection,\n\n        \"space\" => { \"Space\"\n            \"f\" => file_picker,\n            \"F\" => file_picker_in_current_directory,\n            \"e\" => file_explorer,\n            \".\" => file_explorer_in_current_buffer_directory,\n            \"b\" => buffer_picker,\n            \"j\" => jumplist_picker,\n            \"s\" => lsp_or_syntax_symbol_picker,\n            \"S\" => lsp_or_syntax_workspace_symbol_picker,\n            \"d\" => diagnostics_picker,\n            \"D\" => workspace_diagnostics_picker,\n            \"g\" => changed_file_picker,\n            \"a\" => code_action,\n            \"'\" => last_picker,\n            \"G\" => { \"Debug (experimental)\" sticky=true\n                \"l\" => dap_launch,\n                \"r\" => dap_restart,\n                \"b\" => dap_toggle_breakpoint,\n                \"c\" => dap_continue,\n                \"h\" => dap_pause,\n                \"i\" => dap_step_in,\n                \"o\" => dap_step_out,\n                \"n\" => dap_next,\n                \"v\" => dap_variables,\n                \"t\" => dap_terminate,\n                \"C-c\" => dap_edit_condition,\n                \"C-l\" => dap_edit_log,\n                \"s\" => { \"Switch\"\n                    \"t\" => dap_switch_thread,\n                    \"f\" => dap_switch_stack_frame,\n                    // sl, sb\n                },\n                \"e\" => dap_enable_exceptions,\n                \"E\" => dap_disable_exceptions,\n            },\n            \"w\" => { \"Window\"\n                \"C-w\" | \"w\" => rotate_view,\n                \"C-s\" | \"s\" => hsplit,\n                \"C-v\" | \"v\" => vsplit,\n                \"C-t\" | \"t\" => transpose_view,\n                \"f\" => goto_file_hsplit,\n                \"F\" => goto_file_vsplit,\n                \"C-q\" | \"q\" => wclose,\n                \"C-o\" | \"o\" => wonly,\n                \"C-h\" | \"h\" | \"left\" => jump_view_left,\n                \"C-j\" | \"j\" | \"down\" => jump_view_down,\n                \"C-k\" | \"k\" | \"up\" => jump_view_up,\n                \"C-l\" | \"l\" | \"right\" => jump_view_right,\n                \"H\" => swap_view_left,\n                \"J\" => swap_view_down,\n                \"K\" => swap_view_up,\n                \"L\" => swap_view_right,\n                \"n\" => { \"New split scratch buffer\"\n                    \"C-s\" | \"s\" => hsplit_new,\n                    \"C-v\" | \"v\" => vsplit_new,\n                },\n            },\n            \"y\" => yank_to_clipboard,\n            \"Y\" => yank_main_selection_to_clipboard,\n            \"p\" => paste_clipboard_after,\n            \"P\" => paste_clipboard_before,\n            \"R\" => replace_selections_with_clipboard,\n            \"/\" => global_search,\n            \"k\" => hover,\n            \"r\" => rename_symbol,\n            \"h\" => select_references_to_symbol_under_cursor,\n            \"c\" => toggle_comments,\n            \"C\" => toggle_block_comments,\n            \"A-c\" => toggle_line_comments,\n            \"?\" => command_palette,\n        },\n        \"z\" => { \"View\"\n            \"z\" | \"c\" => align_view_center,\n            \"t\" => align_view_top,\n            \"b\" => align_view_bottom,\n            \"m\" => align_view_middle,\n            \"k\" | \"up\" => scroll_up,\n            \"j\" | \"down\" => scroll_down,\n            \"C-b\" | \"pageup\" => page_up,\n            \"C-f\" | \"pagedown\" => page_down,\n            \"C-u\" | \"backspace\" => page_cursor_half_up,\n            \"C-d\" | \"space\" => page_cursor_half_down,\n\n            \"/\" => search,\n            \"?\" => rsearch,\n            \"n\" => search_next,\n            \"N\" => search_prev,\n        },\n        \"Z\" => { \"View\" sticky=true\n            \"z\" | \"c\" => align_view_center,\n            \"t\" => align_view_top,\n            \"b\" => align_view_bottom,\n            \"m\" => align_view_middle,\n            \"k\" | \"up\" => scroll_up,\n            \"j\" | \"down\" => scroll_down,\n            \"C-b\" | \"pageup\" => page_up,\n            \"C-f\" | \"pagedown\" => page_down,\n            \"C-u\" | \"backspace\" => page_cursor_half_up,\n            \"C-d\" | \"space\" => page_cursor_half_down,\n\n            \"/\" => search,\n            \"?\" => rsearch,\n            \"n\" => search_next,\n            \"N\" => search_prev,\n        },\n\n        \"\\\"\" => select_register,\n        \"|\" => shell_pipe,\n        \"A-|\" => shell_pipe_to,\n        \"!\" => shell_insert_output,\n        \"A-!\" => shell_append_output,\n        \"$\" => shell_keep_pipe,\n        \"C-z\" => suspend,\n\n        \"C-a\" => increment,\n        \"C-x\" => decrement,\n    });\n    let mut select = normal.clone();\n    select.merge_nodes(keymap!({ \"Select mode\"\n        \"h\" | \"left\" => extend_char_left,\n        \"j\" | \"down\" => extend_visual_line_down,\n        \"k\" | \"up\" => extend_visual_line_up,\n        \"l\" | \"right\" => extend_char_right,\n\n        \"w\" => extend_next_word_start,\n        \"b\" => extend_prev_word_start,\n        \"e\" => extend_next_word_end,\n        \"W\" => extend_next_long_word_start,\n        \"B\" => extend_prev_long_word_start,\n        \"E\" => extend_next_long_word_end,\n\n        \"A-e\" => extend_parent_node_end,\n        \"A-b\" => extend_parent_node_start,\n\n        \"n\" => extend_search_next,\n        \"N\" => extend_search_prev,\n\n        \"t\" => extend_till_char,\n        \"f\" => extend_next_char,\n        \"T\" => extend_till_prev_char,\n        \"F\" => extend_prev_char,\n\n        \"home\" => extend_to_line_start,\n        \"end\" => extend_to_line_end,\n        \"esc\" => exit_select_mode,\n\n        \"v\" => normal_mode,\n        \"g\" => { \"Goto\"\n            \"g\" => extend_to_file_start,\n            \"|\" => extend_to_column,\n            \"e\" => extend_to_last_line,\n            \"k\" => extend_line_up,\n            \"j\" => extend_line_down,\n            \"w\" => extend_to_word,\n        },\n    }));\n    let insert = keymap!({ \"Insert mode\"\n        \"esc\" => normal_mode,\n\n        \"C-s\" => commit_undo_checkpoint,\n        \"C-x\" => completion,\n        \"C-r\" => insert_register,\n\n        \"C-w\" | \"A-backspace\" => delete_word_backward,\n        \"A-d\" | \"A-del\" => delete_word_forward,\n        \"C-u\" => kill_to_line_start,\n        \"C-k\" => kill_to_line_end,\n        \"C-h\" | \"backspace\" | \"S-backspace\" => delete_char_backward,\n        \"C-d\" | \"del\" => delete_char_forward,\n        \"C-j\" | \"ret\" => insert_newline,\n        \"tab\" => smart_tab,\n        \"S-tab\" => insert_tab,\n\n        \"up\" => move_visual_line_up,\n        \"down\" => move_visual_line_down,\n        \"left\" => move_char_left,\n        \"right\" => move_char_right,\n        \"pageup\" => page_up,\n        \"pagedown\" => page_down,\n        \"home\" => goto_line_start,\n        \"end\" => goto_line_end_newline,\n    });\n    hashmap!(\n        Mode::Normal => normal,\n        Mode::Select => select,\n        Mode::Insert => insert,\n    )\n}\n"
  },
  {
    "path": "helix-term/src/keymap/macros.rs",
    "content": "#[macro_export]\nmacro_rules! key {\n    ($key:ident) => {\n        ::helix_view::input::KeyEvent {\n            code: ::helix_view::keyboard::KeyCode::$key,\n            modifiers: ::helix_view::keyboard::KeyModifiers::NONE,\n        }\n    };\n    ($($ch:tt)*) => {\n        ::helix_view::input::KeyEvent {\n            code: ::helix_view::keyboard::KeyCode::Char($($ch)*),\n            modifiers: ::helix_view::keyboard::KeyModifiers::NONE,\n        }\n    };\n}\n\n#[macro_export]\nmacro_rules! shift {\n    ($key:ident) => {\n        ::helix_view::input::KeyEvent {\n            code: ::helix_view::keyboard::KeyCode::$key,\n            modifiers: ::helix_view::keyboard::KeyModifiers::SHIFT,\n        }\n    };\n    ($($ch:tt)*) => {\n        ::helix_view::input::KeyEvent {\n            code: ::helix_view::keyboard::KeyCode::Char($($ch)*),\n            modifiers: ::helix_view::keyboard::KeyModifiers::SHIFT,\n        }\n    };\n}\n\n#[macro_export]\nmacro_rules! ctrl {\n    ($key:ident) => {\n        ::helix_view::input::KeyEvent {\n            code: ::helix_view::keyboard::KeyCode::$key,\n            modifiers: ::helix_view::keyboard::KeyModifiers::CONTROL,\n        }\n    };\n    ($($ch:tt)*) => {\n        ::helix_view::input::KeyEvent {\n            code: ::helix_view::keyboard::KeyCode::Char($($ch)*),\n            modifiers: ::helix_view::keyboard::KeyModifiers::CONTROL,\n        }\n    };\n}\n\n#[macro_export]\nmacro_rules! alt {\n    ($key:ident) => {\n        ::helix_view::input::KeyEvent {\n            code: ::helix_view::keyboard::KeyCode::$key,\n            modifiers: ::helix_view::keyboard::KeyModifiers::ALT,\n        }\n    };\n    ($($ch:tt)*) => {\n        ::helix_view::input::KeyEvent {\n            code: ::helix_view::keyboard::KeyCode::Char($($ch)*),\n            modifiers: ::helix_view::keyboard::KeyModifiers::ALT,\n        }\n    };\n}\n\n/// Macro for defining a `KeyTrie`. Example:\n///\n/// ```\n/// # use helix_core::hashmap;\n/// # use helix_term::keymap;\n/// let normal_mode = keymap!({ \"Normal mode\"\n///     \"i\" => insert_mode,\n///     \"g\" => { \"Goto\"\n///         \"g\" => goto_file_start,\n///         \"e\" => goto_file_end,\n///     },\n///     \"j\" | \"down\" => move_line_down,\n/// });\n/// let keymap = normal_mode;\n/// ```\n#[macro_export]\nmacro_rules! keymap {\n    (@trie $cmd:ident) => {\n        $crate::keymap::KeyTrie::MappableCommand($crate::commands::MappableCommand::$cmd)\n    };\n\n    (@trie\n        { $label:literal $(sticky=$sticky:literal)? $($($key:literal)|+ => $value:tt,)+ }\n    ) => {\n        keymap!({ $label $(sticky=$sticky)? $($($key)|+ => $value,)+ })\n    };\n\n    (@trie [$($cmd:ident),* $(,)?]) => {\n        $crate::keymap::KeyTrie::Sequence(vec![$($crate::commands::MappableCommand::$cmd),*])\n    };\n\n    (\n        { $label:literal $(sticky=$sticky:literal)? $($($key:literal)|+ => $value:tt,)+ }\n    ) => {\n        // modified from the hashmap! macro\n        {\n            let _cap = hashmap!(@count $($($key),+),*);\n            let mut _map = ::std::collections::HashMap::with_capacity(_cap);\n            let mut _order = ::std::vec::Vec::with_capacity(_cap);\n            $(\n                $(\n                    let _key = $key.parse::<::helix_view::input::KeyEvent>().unwrap();\n                    let _duplicate = _map.insert(\n                        _key,\n                        keymap!(@trie $value)\n                    );\n                    assert!(_duplicate.is_none(), \"Duplicate key found: {:?}\", _duplicate.unwrap());\n                    _order.push(_key);\n                )+\n            )*\n            let mut _node = $crate::keymap::KeyTrieNode::new($label, _map, _order);\n            $( _node.is_sticky = $sticky; )?\n            $crate::keymap::KeyTrie::Node(_node)\n        }\n    };\n}\n\npub use alt;\npub use ctrl;\npub use key;\npub use keymap;\npub use shift;\n"
  },
  {
    "path": "helix-term/src/keymap.rs",
    "content": "pub mod default;\npub mod macros;\n\npub use crate::commands::MappableCommand;\nuse arc_swap::{\n    access::{DynAccess, DynGuard},\n    ArcSwap,\n};\nuse helix_view::{document::Mode, info::Info, input::KeyEvent};\nuse serde::Deserialize;\nuse std::{\n    borrow::Cow,\n    collections::{BTreeSet, HashMap},\n    ops::{Deref, DerefMut},\n    sync::Arc,\n};\n\npub use default::default;\nuse macros::key;\n\n#[derive(Debug, Clone, Default)]\npub struct KeyTrieNode {\n    /// A label for keys coming under this node, like \"Goto mode\"\n    name: String,\n    map: HashMap<KeyEvent, KeyTrie>,\n    order: Vec<KeyEvent>,\n    pub is_sticky: bool,\n}\n\nimpl<'de> Deserialize<'de> for KeyTrieNode {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        let map = HashMap::<KeyEvent, KeyTrie>::deserialize(deserializer)?;\n        let order = map.keys().copied().collect::<Vec<_>>(); // NOTE: map.keys() has arbitrary order\n        Ok(Self {\n            map,\n            order,\n            ..Default::default()\n        })\n    }\n}\n\nimpl KeyTrieNode {\n    pub fn new(name: &str, map: HashMap<KeyEvent, KeyTrie>, order: Vec<KeyEvent>) -> Self {\n        Self {\n            name: name.to_string(),\n            map,\n            order,\n            is_sticky: false,\n        }\n    }\n\n    /// Merge another Node in. Leaves and subnodes from the other node replace\n    /// corresponding keyevent in self, except when both other and self have\n    /// subnodes for same key. In that case the merge is recursive.\n    pub fn merge(&mut self, mut other: Self) {\n        for (key, trie) in std::mem::take(&mut other.map) {\n            if let Some(KeyTrie::Node(node)) = self.map.get_mut(&key) {\n                if let KeyTrie::Node(other_node) = trie {\n                    node.merge(other_node);\n                    continue;\n                }\n            }\n            self.map.insert(key, trie);\n        }\n        for &key in self.map.keys() {\n            if !self.order.contains(&key) {\n                self.order.push(key);\n            }\n        }\n    }\n\n    pub fn infobox(&self) -> Info {\n        let mut body: Vec<(BTreeSet<KeyEvent>, &str)> = Vec::with_capacity(self.len());\n        for (&key, trie) in self.iter() {\n            let desc = match trie {\n                KeyTrie::MappableCommand(cmd) => {\n                    if cmd.name() == \"no_op\" {\n                        continue;\n                    }\n                    cmd.doc()\n                }\n                KeyTrie::Node(n) => &n.name,\n                KeyTrie::Sequence(_) => \"[Multiple commands]\",\n            };\n            match body.iter().position(|(_, d)| d == &desc) {\n                Some(pos) => {\n                    body[pos].0.insert(key);\n                }\n                None => body.push((BTreeSet::from([key]), desc)),\n            }\n        }\n        body.sort_unstable_by_key(|(keys, _)| {\n            self.order\n                .iter()\n                .position(|&k| k == *keys.iter().next().unwrap())\n                .unwrap()\n        });\n\n        let body: Vec<_> = body\n            .into_iter()\n            .map(|(events, desc)| {\n                let events = events.iter().map(ToString::to_string).collect::<Vec<_>>();\n                (events.join(\", \"), desc)\n            })\n            .collect();\n        Info::new(self.name.clone(), &body)\n    }\n}\n\nimpl PartialEq for KeyTrieNode {\n    fn eq(&self, other: &Self) -> bool {\n        self.map == other.map\n    }\n}\n\nimpl Deref for KeyTrieNode {\n    type Target = HashMap<KeyEvent, KeyTrie>;\n\n    fn deref(&self) -> &Self::Target {\n        &self.map\n    }\n}\n\nimpl DerefMut for KeyTrieNode {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.map\n    }\n}\n\n#[derive(Debug, Clone, PartialEq)]\npub enum KeyTrie {\n    MappableCommand(MappableCommand),\n    Sequence(Vec<MappableCommand>),\n    Node(KeyTrieNode),\n}\n\nimpl<'de> Deserialize<'de> for KeyTrie {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        deserializer.deserialize_any(KeyTrieVisitor)\n    }\n}\n\nstruct KeyTrieVisitor;\n\nimpl<'de> serde::de::Visitor<'de> for KeyTrieVisitor {\n    type Value = KeyTrie;\n\n    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(formatter, \"a command, list of commands, or sub-keymap\")\n    }\n\n    fn visit_str<E>(self, command: &str) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        command\n            .parse::<MappableCommand>()\n            .map(KeyTrie::MappableCommand)\n            .map_err(E::custom)\n    }\n\n    fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>\n    where\n        S: serde::de::SeqAccess<'de>,\n    {\n        let mut commands = Vec::new();\n        while let Some(command) = seq.next_element::<String>()? {\n            commands.push(\n                command\n                    .parse::<MappableCommand>()\n                    .map_err(serde::de::Error::custom)?,\n            )\n        }\n\n        // Prevent macro keybindings from being used in command sequences.\n        // This is meant to be a temporary restriction pending a larger\n        // refactor of how command sequences are executed.\n        if commands\n            .iter()\n            .any(|cmd| matches!(cmd, MappableCommand::Macro { .. }))\n        {\n            return Err(serde::de::Error::custom(\n                \"macro keybindings may not be used in command sequences\",\n            ));\n        }\n\n        Ok(KeyTrie::Sequence(commands))\n    }\n\n    fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>\n    where\n        M: serde::de::MapAccess<'de>,\n    {\n        let mut mapping = HashMap::new();\n        let mut order = Vec::new();\n        while let Some((key, value)) = map.next_entry::<KeyEvent, KeyTrie>()? {\n            mapping.insert(key, value);\n            order.push(key);\n        }\n        Ok(KeyTrie::Node(KeyTrieNode::new(\"\", mapping, order)))\n    }\n}\n\nimpl KeyTrie {\n    pub fn reverse_map(&self) -> ReverseKeymap {\n        // recursively visit all nodes in keymap\n        fn map_node(cmd_map: &mut ReverseKeymap, node: &KeyTrie, keys: &mut Vec<KeyEvent>) {\n            match node {\n                KeyTrie::MappableCommand(MappableCommand::Macro { .. }) => {}\n                KeyTrie::MappableCommand(cmd) => {\n                    let name = cmd.name();\n                    if name != \"no_op\" {\n                        cmd_map.entry(name.into()).or_default().push(keys.clone())\n                    }\n                }\n                KeyTrie::Node(next) => {\n                    for (key, trie) in &next.map {\n                        keys.push(*key);\n                        map_node(cmd_map, trie, keys);\n                        keys.pop();\n                    }\n                }\n                KeyTrie::Sequence(_) => {}\n            };\n        }\n\n        let mut res = HashMap::new();\n        map_node(&mut res, self, &mut Vec::new());\n        res\n    }\n\n    pub fn node(&self) -> Option<&KeyTrieNode> {\n        match *self {\n            KeyTrie::Node(ref node) => Some(node),\n            KeyTrie::MappableCommand(_) | KeyTrie::Sequence(_) => None,\n        }\n    }\n\n    pub fn node_mut(&mut self) -> Option<&mut KeyTrieNode> {\n        match *self {\n            KeyTrie::Node(ref mut node) => Some(node),\n            KeyTrie::MappableCommand(_) | KeyTrie::Sequence(_) => None,\n        }\n    }\n\n    /// Merge another KeyTrie in, assuming that this KeyTrie and the other\n    /// are both Nodes. Panics otherwise.\n    pub fn merge_nodes(&mut self, mut other: Self) {\n        let node = std::mem::take(other.node_mut().unwrap());\n        self.node_mut().unwrap().merge(node);\n    }\n\n    pub fn search(&self, keys: &[KeyEvent]) -> Option<&KeyTrie> {\n        let mut trie = self;\n        for key in keys {\n            trie = match trie {\n                KeyTrie::Node(map) => map.get(key),\n                // leaf encountered while keys left to process\n                KeyTrie::MappableCommand(_) | KeyTrie::Sequence(_) => None,\n            }?\n        }\n        Some(trie)\n    }\n}\n\n#[derive(Debug, Clone, PartialEq)]\npub enum KeymapResult {\n    /// Needs more keys to execute a command. Contains valid keys for next keystroke.\n    Pending(KeyTrieNode),\n    Matched(MappableCommand),\n    /// Matched a sequence of commands to execute.\n    MatchedSequence(Vec<MappableCommand>),\n    /// Key was not found in the root keymap\n    NotFound,\n    /// Key is invalid in combination with previous keys. Contains keys leading upto\n    /// and including current (invalid) key.\n    Cancelled(Vec<KeyEvent>),\n}\n\n/// A map of command names to keybinds that will execute the command.\npub type ReverseKeymap = HashMap<String, Vec<Vec<KeyEvent>>>;\n\npub struct Keymaps {\n    pub map: Box<dyn DynAccess<HashMap<Mode, KeyTrie>>>,\n    /// Stores pending keys waiting for the next key. This is relative to a\n    /// sticky node if one is in use.\n    state: Vec<KeyEvent>,\n    /// Stores the sticky node if one is activated.\n    pub sticky: Option<KeyTrieNode>,\n}\n\nimpl Keymaps {\n    pub fn new(map: Box<dyn DynAccess<HashMap<Mode, KeyTrie>>>) -> Self {\n        Self {\n            map,\n            state: Vec::new(),\n            sticky: None,\n        }\n    }\n\n    pub fn map(&self) -> DynGuard<HashMap<Mode, KeyTrie>> {\n        self.map.load()\n    }\n\n    /// Returns list of keys waiting to be disambiguated in current mode.\n    pub fn pending(&self) -> &[KeyEvent] {\n        &self.state\n    }\n\n    pub fn sticky(&self) -> Option<&KeyTrieNode> {\n        self.sticky.as_ref()\n    }\n\n    pub fn contains_key(&self, mode: Mode, key: KeyEvent) -> bool {\n        let keymaps = &*self.map();\n        let keymap = &keymaps[&mode];\n        keymap\n            .search(self.pending())\n            .and_then(KeyTrie::node)\n            .is_some_and(|node| node.contains_key(&key))\n    }\n\n    /// Lookup `key` in the keymap to try and find a command to execute. Escape\n    /// key cancels pending keystrokes. If there are no pending keystrokes but a\n    /// sticky node is in use, it will be cleared.\n    pub fn get(&mut self, mode: Mode, key: KeyEvent) -> KeymapResult {\n        // TODO: remove the sticky part and look up manually\n        let keymaps = &*self.map();\n        let keymap = &keymaps[&mode];\n\n        if key!(Esc) == key {\n            if !self.state.is_empty() {\n                // Note that Esc is not included here\n                return KeymapResult::Cancelled(self.state.drain(..).collect());\n            }\n            self.sticky = None;\n        }\n\n        let first = self.state.first().unwrap_or(&key);\n        let trie_node = match self.sticky {\n            Some(ref trie) => Cow::Owned(KeyTrie::Node(trie.clone())),\n            None => Cow::Borrowed(keymap),\n        };\n\n        let trie = match trie_node.search(&[*first]) {\n            Some(KeyTrie::MappableCommand(ref cmd)) => {\n                return KeymapResult::Matched(cmd.clone());\n            }\n            Some(KeyTrie::Sequence(ref cmds)) => {\n                return KeymapResult::MatchedSequence(cmds.clone());\n            }\n            None => return KeymapResult::NotFound,\n            Some(t) => t,\n        };\n\n        self.state.push(key);\n        match trie.search(&self.state[1..]) {\n            Some(KeyTrie::Node(map)) => {\n                if map.is_sticky {\n                    self.state.clear();\n                    self.sticky = Some(map.clone());\n                }\n                KeymapResult::Pending(map.clone())\n            }\n            Some(KeyTrie::MappableCommand(cmd)) => {\n                self.state.clear();\n                KeymapResult::Matched(cmd.clone())\n            }\n            Some(KeyTrie::Sequence(cmds)) => {\n                self.state.clear();\n                KeymapResult::MatchedSequence(cmds.clone())\n            }\n            None => KeymapResult::Cancelled(self.state.drain(..).collect()),\n        }\n    }\n}\n\nimpl Default for Keymaps {\n    fn default() -> Self {\n        Self::new(Box::new(ArcSwap::new(Arc::new(default()))))\n    }\n}\n\n/// Merge default config keys with user overwritten keys for custom user config.\npub fn merge_keys(dst: &mut HashMap<Mode, KeyTrie>, mut delta: HashMap<Mode, KeyTrie>) {\n    for (mode, keys) in dst {\n        keys.merge_nodes(\n            delta\n                .remove(mode)\n                .unwrap_or_else(|| KeyTrie::Node(KeyTrieNode::default())),\n        )\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::macros::keymap;\n    use super::*;\n    use arc_swap::access::Constant;\n    use helix_core::hashmap;\n\n    #[test]\n    #[should_panic]\n    fn duplicate_keys_should_panic() {\n        keymap!({ \"Normal mode\"\n            \"i\" => normal_mode,\n            \"i\" => goto_definition,\n        });\n    }\n\n    #[test]\n    fn check_duplicate_keys_in_default_keymap() {\n        // will panic on duplicate keys, assumes that `Keymaps` uses keymap! macro\n        Keymaps::default();\n    }\n\n    #[test]\n    fn merge_partial_keys() {\n        let keymap = hashmap! {\n            Mode::Normal => keymap!({ \"Normal mode\"\n                \"i\" => normal_mode,\n                \"无\" => insert_mode,\n                \"z\" => jump_backward,\n                \"g\" => { \"Merge into goto mode\"\n                    \"$\" => goto_line_end,\n                    \"g\" => delete_char_forward,\n                },\n            })\n        };\n        let mut merged_keyamp = default();\n        merge_keys(&mut merged_keyamp, keymap.clone());\n        assert_ne!(keymap, merged_keyamp);\n\n        let mut keymap = Keymaps::new(Box::new(Constant(merged_keyamp.clone())));\n        assert_eq!(\n            keymap.get(Mode::Normal, key!('i')),\n            KeymapResult::Matched(MappableCommand::normal_mode),\n            \"Leaf should replace leaf\"\n        );\n        assert_eq!(\n            keymap.get(Mode::Normal, key!('无')),\n            KeymapResult::Matched(MappableCommand::insert_mode),\n            \"New leaf should be present in merged keymap\"\n        );\n        // Assumes that z is a node in the default keymap\n        assert_eq!(\n            keymap.get(Mode::Normal, key!('z')),\n            KeymapResult::Matched(MappableCommand::jump_backward),\n            \"Leaf should replace node\"\n        );\n\n        let keymap = merged_keyamp.get_mut(&Mode::Normal).unwrap();\n        // Assumes that `g` is a node in default keymap\n        assert_eq!(\n            keymap.search(&[key!('g'), key!('$')]).unwrap(),\n            &KeyTrie::MappableCommand(MappableCommand::goto_line_end),\n            \"Leaf should be present in merged subnode\"\n        );\n        // Assumes that `gg` is in default keymap\n        assert_eq!(\n            keymap.search(&[key!('g'), key!('g')]).unwrap(),\n            &KeyTrie::MappableCommand(MappableCommand::delete_char_forward),\n            \"Leaf should replace old leaf in merged subnode\"\n        );\n        // Assumes that `ge` is in default keymap\n        assert_eq!(\n            keymap.search(&[key!('g'), key!('e')]).unwrap(),\n            &KeyTrie::MappableCommand(MappableCommand::goto_last_line),\n            \"Old leaves in subnode should be present in merged node\"\n        );\n\n        assert!(\n            merged_keyamp\n                .get(&Mode::Normal)\n                .and_then(|key_trie| key_trie.node())\n                .unwrap()\n                .len()\n                > 1\n        );\n        assert!(!merged_keyamp\n            .get(&Mode::Insert)\n            .and_then(|key_trie| key_trie.node())\n            .unwrap()\n            .is_empty());\n    }\n\n    #[test]\n    fn order_should_be_set() {\n        let keymap = hashmap! {\n            Mode::Normal => keymap!({ \"Normal mode\"\n                \"space\" => { \"\"\n                    \"s\" => { \"\"\n                        \"v\" => vsplit,\n                        \"c\" => hsplit,\n                    },\n                },\n            })\n        };\n        let mut merged_keyamp = default();\n        merge_keys(&mut merged_keyamp, keymap.clone());\n        assert_ne!(keymap, merged_keyamp);\n        let keymap = merged_keyamp.get_mut(&Mode::Normal).unwrap();\n        // Make sure mapping works\n        assert_eq!(\n            keymap.search(&[key!(' '), key!('s'), key!('v')]).unwrap(),\n            &KeyTrie::MappableCommand(MappableCommand::vsplit),\n            \"Leaf should be present in merged subnode\"\n        );\n        // Make sure an order was set during merge\n        let node = keymap.search(&[crate::key!(' ')]).unwrap();\n        assert!(!node.node().unwrap().order.as_slice().is_empty())\n    }\n\n    #[test]\n    fn aliased_modes_are_same_in_default_keymap() {\n        let keymaps = Keymaps::default().map();\n        let root = keymaps.get(&Mode::Normal).unwrap();\n        assert_eq!(\n            root.search(&[key!(' '), key!('w')]).unwrap(),\n            root.search(&[\"C-w\".parse::<KeyEvent>().unwrap()]).unwrap(),\n            \"Mismatch for window mode on `Space-w` and `Ctrl-w`\"\n        );\n        assert_eq!(\n            root.search(&[key!('z')]).unwrap(),\n            root.search(&[key!('Z')]).unwrap(),\n            \"Mismatch for view mode on `z` and `Z`\"\n        );\n    }\n\n    #[test]\n    fn reverse_map() {\n        let normal_mode = keymap!({ \"Normal mode\"\n            \"i\" => insert_mode,\n            \"g\" => { \"Goto\"\n                \"g\" => goto_file_start,\n                \"e\" => goto_file_end,\n            },\n            \"j\" | \"k\" => move_line_down,\n        });\n        let keymap = normal_mode;\n        let mut reverse_map = keymap.reverse_map();\n\n        // sort keybindings in order to have consistent tests\n        // HashMaps can be compared but we can still get different ordering of bindings\n        // for commands that have multiple bindings assigned\n        for v in reverse_map.values_mut() {\n            v.sort()\n        }\n\n        assert_eq!(\n            reverse_map,\n            HashMap::from([\n                (\"insert_mode\".to_string(), vec![vec![key!('i')]]),\n                (\n                    \"goto_file_start\".to_string(),\n                    vec![vec![key!('g'), key!('g')]]\n                ),\n                (\n                    \"goto_file_end\".to_string(),\n                    vec![vec![key!('g'), key!('e')]]\n                ),\n                (\n                    \"move_line_down\".to_string(),\n                    vec![vec![key!('j')], vec![key!('k')]]\n                ),\n            ]),\n            \"Mismatch\"\n        )\n    }\n\n    #[test]\n    fn escaped_keymap() {\n        use crate::commands::MappableCommand;\n        use helix_view::input::{KeyCode, KeyEvent, KeyModifiers};\n\n        let keys = r#\"\n\"+\" = [\n    \"select_all\",\n    \":pipe sed -E 's/\\\\s+$//g'\",\n]\n        \"#;\n\n        let key = KeyEvent {\n            code: KeyCode::Char('+'),\n            modifiers: KeyModifiers::NONE,\n        };\n\n        let expectation = KeyTrie::Node(KeyTrieNode::new(\n            \"\",\n            hashmap! {\n                key => KeyTrie::Sequence(vec!{\n                    MappableCommand::select_all,\n                    MappableCommand::Typable {\n                        name: \"pipe\".to_string(),\n                        args: \"sed -E 's/\\\\s+$//g'\".to_string(),\n                        doc: \"\".to_string(),\n                    },\n                })\n            },\n            vec![key],\n        ));\n\n        assert_eq!(toml::from_str(keys), Ok(expectation));\n    }\n}\n"
  },
  {
    "path": "helix-term/src/lib.rs",
    "content": "#[macro_use]\nextern crate helix_view;\n\npub mod application;\npub mod args;\npub mod commands;\npub mod compositor;\npub mod config;\npub mod events;\npub mod health;\npub mod job;\npub mod keymap;\npub mod ui;\n\n#[cfg(not(windows))]\nuse std::env::var_os;\n\nuse std::path::Path;\n\nuse futures_util::Future;\nmod handlers;\n\nuse ignore::DirEntry;\nuse url::Url;\n\n#[cfg(windows)]\nfn true_color() -> bool {\n    true\n}\n\n#[cfg(not(windows))]\nfn true_color() -> bool {\n    if var_os(\"COLORTERM\").is_some_and(|v| v == \"truecolor\" || v == \"24bit\")\n        || var_os(\"WSL_DISTRO_NAME\").is_some()\n    {\n        return true;\n    }\n\n    match termini::TermInfo::from_env() {\n        Ok(t) => {\n            t.extended_cap(\"RGB\").is_some()\n                || t.extended_cap(\"Tc\").is_some()\n                || (t.extended_cap(\"setrgbf\").is_some() && t.extended_cap(\"setrgbb\").is_some())\n        }\n        Err(_) => false,\n    }\n}\n\n/// Function used for filtering dir entries in the various file pickers.\nfn filter_picker_entry(entry: &DirEntry, root: &Path, dedup_symlinks: bool) -> bool {\n    // We always want to ignore popular VCS directories, otherwise if\n    // `ignore` is turned off, we end up with a lot of noise\n    // in our picker.\n    if matches!(\n        entry.file_name().to_str(),\n        Some(\".git\" | \".pijul\" | \".jj\" | \".hg\" | \".svn\")\n    ) {\n        return false;\n    }\n\n    // We also ignore symlinks that point inside the current directory\n    // if `dedup_links` is enabled.\n    if dedup_symlinks && entry.path_is_symlink() {\n        return entry\n            .path()\n            .canonicalize()\n            .ok()\n            .is_some_and(|path| !path.starts_with(root));\n    }\n\n    true\n}\n\n/// Opens URL in external program.\nfn open_external_url_callback(\n    url: Url,\n) -> impl Future<Output = Result<job::Callback, anyhow::Error>> + Send + 'static {\n    let commands = open::commands(url.as_str());\n    async {\n        for cmd in commands {\n            let mut command: tokio::process::Command = cmd.into();\n            if command.output().await.is_ok() {\n                return Ok(job::Callback::Editor(Box::new(|_| {})));\n            }\n        }\n        Ok(job::Callback::Editor(Box::new(move |editor| {\n            editor.set_error(\"Opening URL in external program failed\")\n        })))\n    }\n}\n"
  },
  {
    "path": "helix-term/src/main.rs",
    "content": "use anyhow::{Context, Error, Result};\nuse helix_loader::VERSION_AND_GIT_HASH;\nuse helix_term::application::Application;\nuse helix_term::args::Args;\nuse helix_term::config::{Config, ConfigLoadError};\n\nfn setup_logging(verbosity: u64) -> Result<()> {\n    let mut base_config = fern::Dispatch::new();\n\n    base_config = match verbosity {\n        0 => base_config.level(log::LevelFilter::Warn),\n        1 => base_config.level(log::LevelFilter::Info),\n        2 => base_config.level(log::LevelFilter::Debug),\n        _3_or_more => base_config.level(log::LevelFilter::Trace),\n    };\n\n    // Separate file config so we can include year, month and day in file logs\n    let file_config = fern::Dispatch::new()\n        .format(|out, message, record| {\n            out.finish(format_args!(\n                \"{} {} [{}] {}\",\n                chrono::Local::now().format(\"%Y-%m-%dT%H:%M:%S%.3f\"),\n                record.target(),\n                record.level(),\n                message\n            ))\n        })\n        .chain(fern::log_file(helix_loader::log_file())?);\n\n    base_config.chain(file_config).apply()?;\n\n    Ok(())\n}\n\nfn main() -> Result<()> {\n    let exit_code = main_impl()?;\n    std::process::exit(exit_code);\n}\n\n#[tokio::main]\nasync fn main_impl() -> Result<i32> {\n    let args = Args::parse_args().context(\"could not parse arguments\")?;\n\n    helix_loader::initialize_config_file(args.config_file.clone());\n    helix_loader::initialize_log_file(args.log_file.clone());\n\n    // Help has a higher priority and should be handled separately.\n    if args.display_help {\n        print!(\n            \"\\\n{} {}\n{}\n{}\n\nUSAGE:\n    hx [FLAGS] [files]...\n\nARGS:\n    <files>...    Set the input file to use, position can also be specified via file[:row[:col]]\n\nFLAGS:\n    -h, --help                     Print help information\n    --tutor                        Load the tutorial\n    --health [CATEGORY]            Check for potential errors in editor setup\n                                   CATEGORY can be a language or one of 'clipboard', 'languages',\n                                   'all-languages' or 'all'. 'languages' is filtered according to\n                                   user config, 'all-languages' and 'all' are not. If not specified,\n                                   the default is the same as 'all', but with languages filtering.\n    -g, --grammar {{fetch|build}}    Fetch or builds tree-sitter grammars listed in languages.toml\n    -c, --config <file>            Specify a file to use for configuration\n    -v                             Increase logging verbosity each use for up to 3 times\n    --log <file>                   Specify a file to use for logging\n                                   (default file: {})\n    -V, --version                  Print version information\n    --vsplit                       Split all given files vertically into different windows\n    --hsplit                       Split all given files horizontally into different windows\n    -w, --working-dir <path>       Specify an initial working directory\n    +[N]                           Open the first given file at line number N, or the last line, if\n                                   N is not specified.\n\",\n            env!(\"CARGO_PKG_NAME\"),\n            VERSION_AND_GIT_HASH,\n            env!(\"CARGO_PKG_AUTHORS\"),\n            env!(\"CARGO_PKG_DESCRIPTION\"),\n            helix_loader::default_log_file().display(),\n        );\n        std::process::exit(0);\n    }\n\n    if args.display_version {\n        println!(\"helix {}\", VERSION_AND_GIT_HASH);\n        std::process::exit(0);\n    }\n\n    if args.health {\n        if let Err(err) = helix_term::health::print_health(args.health_arg) {\n            // Piping to for example `head -10` requires special handling:\n            // https://stackoverflow.com/a/65760807/7115678\n            if err.kind() != std::io::ErrorKind::BrokenPipe {\n                return Err(err.into());\n            }\n        }\n\n        std::process::exit(0);\n    }\n\n    if args.fetch_grammars {\n        helix_loader::grammar::fetch_grammars()?;\n        return Ok(0);\n    }\n\n    if args.build_grammars {\n        helix_loader::grammar::build_grammars(None)?;\n        return Ok(0);\n    }\n\n    setup_logging(args.verbosity).context(\"failed to initialize logging\")?;\n\n    // NOTE: Set the working directory early so the correct configuration is loaded. Be aware that\n    // Application::new() depends on this logic so it must be updated if this changes.\n    if let Some(path) = &args.working_directory {\n        helix_stdx::env::set_current_working_dir(path)?;\n    } else if let Some((path, _)) = args.files.first().filter(|p| p.0.is_dir()) {\n        // If the first file is a directory, it will be the working directory unless -w was specified\n        helix_stdx::env::set_current_working_dir(path)?;\n    }\n\n    let config = match Config::load_default() {\n        Ok(config) => config,\n        Err(ConfigLoadError::Error(err)) if err.kind() == std::io::ErrorKind::NotFound => {\n            Config::default()\n        }\n        Err(ConfigLoadError::Error(err)) => return Err(Error::new(err)),\n        Err(ConfigLoadError::BadConfig(err)) => {\n            eprintln!(\"Bad config: {}\", err);\n            eprintln!(\"Press <ENTER> to continue with default config\");\n            use std::io::Read;\n            let _ = std::io::stdin().read(&mut []);\n            Config::default()\n        }\n    };\n\n    let lang_loader = helix_core::config::user_lang_loader().unwrap_or_else(|err| {\n        eprintln!(\"{}\", err);\n        eprintln!(\"Press <ENTER> to continue with default language config\");\n        use std::io::Read;\n        // This waits for an enter press.\n        let _ = std::io::stdin().read(&mut []);\n        helix_core::config::default_lang_loader()\n    });\n\n    // TODO: use the thread local executor to spawn the application task separately from the work pool\n    let mut app = Application::new(args, config, lang_loader).context(\"unable to start Helix\")?;\n    let mut events = app.event_stream();\n\n    let exit_code = app.run(&mut events).await?;\n\n    Ok(exit_code)\n}\n"
  },
  {
    "path": "helix-term/src/ui/completion.rs",
    "content": "use crate::handlers::completion::LspCompletionItem;\nuse crate::ui::{menu, Markdown, Menu, Popup, PromptEvent};\nuse crate::{\n    compositor::{Component, Context, Event, EventResult},\n    handlers::completion::{\n        trigger_auto_completion, CompletionItem, CompletionResponse, ResolveHandler,\n    },\n};\nuse helix_core::snippets::{ActiveSnippet, RenderedSnippet, Snippet};\nuse helix_core::{self as core, chars, fuzzy::MATCHER, Change, Transaction};\nuse helix_lsp::{lsp, util, OffsetEncoding};\nuse helix_view::{\n    editor::CompleteAction,\n    handlers::lsp::SignatureHelpInvoked,\n    theme::{Color, Modifier, Style},\n    ViewId,\n};\nuse helix_view::{graphics::Rect, Document, Editor};\nuse nucleo::{\n    pattern::{Atom, AtomKind, CaseMatching, Normalization},\n    Config, Utf32Str,\n};\nuse tui::text::Spans;\nuse tui::{buffer::Buffer as Surface, text::Span};\n\nuse std::cmp::Reverse;\n\nimpl menu::Item for CompletionItem {\n    type Data = Style;\n\n    fn format(&self, dir_style: &Self::Data) -> menu::Row<'_> {\n        let deprecated = match self {\n            CompletionItem::Lsp(LspCompletionItem { item, .. }) => {\n                item.deprecated.unwrap_or_default()\n                    || item\n                        .tags\n                        .as_ref()\n                        .is_some_and(|tags| tags.contains(&lsp::CompletionItemTag::DEPRECATED))\n            }\n            CompletionItem::Other(_) => false,\n        };\n\n        let label = match self {\n            CompletionItem::Lsp(LspCompletionItem { item, .. }) => item.label.as_str(),\n            CompletionItem::Other(core::CompletionItem { label, .. }) => label,\n        };\n\n        let kind = match self {\n            CompletionItem::Lsp(LspCompletionItem { item, .. }) => match item.kind {\n                Some(lsp::CompletionItemKind::TEXT) => \"text\".into(),\n                Some(lsp::CompletionItemKind::METHOD) => \"method\".into(),\n                Some(lsp::CompletionItemKind::FUNCTION) => \"function\".into(),\n                Some(lsp::CompletionItemKind::CONSTRUCTOR) => \"constructor\".into(),\n                Some(lsp::CompletionItemKind::FIELD) => \"field\".into(),\n                Some(lsp::CompletionItemKind::VARIABLE) => \"variable\".into(),\n                Some(lsp::CompletionItemKind::CLASS) => \"class\".into(),\n                Some(lsp::CompletionItemKind::INTERFACE) => \"interface\".into(),\n                Some(lsp::CompletionItemKind::MODULE) => \"module\".into(),\n                Some(lsp::CompletionItemKind::PROPERTY) => \"property\".into(),\n                Some(lsp::CompletionItemKind::UNIT) => \"unit\".into(),\n                Some(lsp::CompletionItemKind::VALUE) => \"value\".into(),\n                Some(lsp::CompletionItemKind::ENUM) => \"enum\".into(),\n                Some(lsp::CompletionItemKind::KEYWORD) => \"keyword\".into(),\n                Some(lsp::CompletionItemKind::SNIPPET) => \"snippet\".into(),\n                Some(lsp::CompletionItemKind::COLOR) => item\n                    .documentation\n                    .as_ref()\n                    .and_then(|docs| {\n                        let text = match docs {\n                            lsp::Documentation::String(text) => text,\n                            lsp::Documentation::MarkupContent(lsp::MarkupContent {\n                                value, ..\n                            }) => value,\n                        };\n                        // Language servers which send Color completion items tend to include a 6\n                        // digit hex code at the end for the color. The extra 1 digit is for the '#'\n                        text.get(text.len().checked_sub(7)?..)\n                    })\n                    .and_then(|c| Color::from_hex(c).ok())\n                    .map_or(\"color\".into(), |color| {\n                        Spans::from(vec![\n                            Span::raw(\"color \"),\n                            Span::styled(\"■\", Style::default().fg(color)),\n                        ])\n                    }),\n                Some(lsp::CompletionItemKind::FILE) => \"file\".into(),\n                Some(lsp::CompletionItemKind::REFERENCE) => \"reference\".into(),\n                Some(lsp::CompletionItemKind::FOLDER) => \"folder\".into(),\n                Some(lsp::CompletionItemKind::ENUM_MEMBER) => \"enum_member\".into(),\n                Some(lsp::CompletionItemKind::CONSTANT) => \"constant\".into(),\n                Some(lsp::CompletionItemKind::STRUCT) => \"struct\".into(),\n                Some(lsp::CompletionItemKind::EVENT) => \"event\".into(),\n                Some(lsp::CompletionItemKind::OPERATOR) => \"operator\".into(),\n                Some(lsp::CompletionItemKind::TYPE_PARAMETER) => \"type_param\".into(),\n                Some(kind) => {\n                    log::error!(\"Received unknown completion item kind: {:?}\", kind);\n                    \"\".into()\n                }\n                None => \"\".into(),\n            },\n            CompletionItem::Other(core::CompletionItem { kind, .. }) => kind.as_ref().into(),\n        };\n\n        let label = Span::styled(\n            label,\n            if deprecated {\n                Style::default().add_modifier(Modifier::CROSSED_OUT)\n            } else if kind.0[0].content == \"folder\" {\n                *dir_style\n            } else {\n                Style::default()\n            },\n        );\n\n        menu::Row::new([menu::Cell::from(label), menu::Cell::from(kind)])\n    }\n}\n\n/// Wraps a Menu.\npub struct Completion {\n    popup: Popup<Menu<CompletionItem>>,\n    #[allow(dead_code)]\n    trigger_offset: usize,\n    filter: String,\n    // TODO: move to helix-view/central handler struct in the future\n    resolve_handler: ResolveHandler,\n}\n\nimpl Completion {\n    pub const ID: &'static str = \"completion\";\n\n    pub fn new(editor: &Editor, items: Vec<CompletionItem>, trigger_offset: usize) -> Self {\n        let preview_completion_insert = editor.config().preview_completion_insert;\n        let replace_mode = editor.config().completion_replace;\n\n        let dir_style = editor.theme.get(\"ui.text.directory\");\n\n        // Then create the menu\n        let menu = Menu::new(items, dir_style, move |editor: &mut Editor, item, event| {\n            let (view, doc) = current!(editor);\n\n            macro_rules! language_server {\n                ($item:expr) => {\n                    match editor\n                        .language_servers\n                        .get_by_id($item.provider)\n                    {\n                        Some(ls) => ls,\n                        None => {\n                            editor.set_error(\"completions are outdated\");\n                            // TODO close the completion menu somehow,\n                            // currently there is no trivial way to access the EditorView to close the completion menu\n                            return;\n                        }\n                    }\n                };\n            }\n\n            match event {\n                PromptEvent::Abort => {}\n                PromptEvent::Update if preview_completion_insert => {\n                    // Update creates \"ghost\" transactions which are not sent to the\n                    // lsp server to avoid messing up re-requesting completions. Once a\n                    // completion has been selected (with tab, c-n or c-p) it's always accepted whenever anything\n                    // is typed. The only way to avoid that is to explicitly abort the completion\n                    // with c-c. This will remove the \"ghost\" transaction.\n                    //\n                    // The ghost transaction is modeled with a transaction that is not sent to the LS.\n                    // (apply_temporary) and a savepoint. It's extremely important this savepoint is restored\n                    // (also without sending the transaction to the LS) *before any further transaction is applied*.\n                    // Otherwise incremental sync breaks (since the state of the LS doesn't match the state the transaction\n                    // is applied to).\n                    if matches!(editor.last_completion, Some(CompleteAction::Triggered)) {\n                        editor.last_completion = Some(CompleteAction::Selected {\n                            savepoint: doc.savepoint(view),\n                        })\n                    }\n                    let item = item.unwrap();\n                    let context = &editor.handlers.completions.active_completions[&item.provider()];\n                    // if more text was entered, remove it\n                    doc.restore(view, &context.savepoint, false);\n                    // always present here\n\n                    match item {\n                        CompletionItem::Lsp(item) => {\n                            let (transaction, _) = lsp_item_to_transaction(\n                                doc,\n                                view.id,\n                                &item.item,\n                                language_server!(item).offset_encoding(),\n                                trigger_offset,\n                                replace_mode,\n                            );\n                            doc.apply_temporary(&transaction, view.id)\n                        }\n                        CompletionItem::Other(core::CompletionItem { transaction, .. }) => {\n                            doc.apply_temporary(transaction, view.id)\n                        }\n                    };\n                }\n                PromptEvent::Update => {}\n                PromptEvent::Validate => {\n                    if let Some(CompleteAction::Selected { savepoint }) =\n                        editor.last_completion.take()\n                    {\n                        doc.restore(view, &savepoint, false);\n                    }\n\n                    let item = item.unwrap();\n                    let context = &editor.handlers.completions.active_completions[&item.provider()];\n                    // if more text was entered, remove it\n                    doc.restore(view, &context.savepoint, true);\n                    // save an undo checkpoint before the completion\n                    doc.append_changes_to_history(view);\n\n                    // item always present here\n                    let (transaction, additional_edits, snippet) = match item.clone() {\n                        CompletionItem::Lsp(mut item) => {\n                            let language_server = language_server!(item);\n\n                            // resolve item if not yet resolved\n                            if !item.resolved {\n                                if let Some(resolved_item) = Self::resolve_completion_item(\n                                    language_server,\n                                    item.item.clone(),\n                                ) {\n                                    item.item = resolved_item;\n                                }\n                            };\n\n                            let encoding = language_server.offset_encoding();\n                            let (transaction, snippet) = lsp_item_to_transaction(\n                                doc,\n                                view.id,\n                                &item.item,\n                                encoding,\n                                trigger_offset,\n                                replace_mode,\n                            );\n                            let add_edits = item.item.additional_text_edits;\n\n                            (\n                                transaction,\n                                add_edits.map(|edits| (edits, encoding)),\n                                snippet,\n                            )\n                        }\n                        CompletionItem::Other(core::CompletionItem { transaction, .. }) => {\n                            (transaction, None, None)\n                        }\n                    };\n\n                    doc.apply(&transaction, view.id);\n                    let placeholder = snippet.is_some();\n                    if let Some(snippet) = snippet {\n                        doc.active_snippet = match doc.active_snippet.take() {\n                            Some(active) => active.insert_subsnippet(snippet),\n                            None => ActiveSnippet::new(snippet),\n                        };\n                    }\n\n                    editor.last_completion = Some(CompleteAction::Applied {\n                        trigger_offset,\n                        changes: completion_changes(&transaction, trigger_offset),\n                        placeholder,\n                    });\n\n                    // TODO: add additional _edits to completion_changes?\n                    if let Some((additional_edits, offset_encoding)) = additional_edits {\n                        if !additional_edits.is_empty() {\n                            let transaction = util::generate_transaction_from_edits(\n                                doc.text(),\n                                additional_edits,\n                                offset_encoding, // TODO: should probably transcode in Client\n                            );\n                            doc.apply(&transaction, view.id);\n                        }\n                    }\n                    // we could have just inserted a trigger char (like a `crate::` completion for rust\n                    // so we want to retrigger immediately when accepting a completion.\n                    trigger_auto_completion(editor, true);\n                }\n            };\n\n            // In case the popup was deleted because of an intersection w/ the auto-complete menu.\n            if event != PromptEvent::Update {\n                editor\n                    .handlers\n                    .trigger_signature_help(SignatureHelpInvoked::Automatic, editor);\n            }\n        });\n\n        let popup = Popup::new(Self::ID, menu)\n            .with_scrollbar(false)\n            .ignore_escape_key(true);\n\n        let (view, doc) = current_ref!(editor);\n        let text = doc.text().slice(..);\n        let cursor = doc.selection(view.id).primary().cursor(text);\n        let offset = text\n            .chars_at(cursor)\n            .reversed()\n            .take_while(|ch| chars::char_is_word(*ch))\n            .count();\n        let start_offset = cursor.saturating_sub(offset);\n\n        let fragment = doc.text().slice(start_offset..cursor);\n        let mut completion = Self {\n            popup,\n            trigger_offset,\n            // TODO: expand nucleo api to allow moving straight to a Utf32String here\n            // and avoid allocation during matching\n            filter: String::from(fragment),\n            resolve_handler: ResolveHandler::new(),\n        };\n\n        // need to recompute immediately in case start_offset != trigger_offset\n        completion.score(false);\n\n        completion\n    }\n\n    fn score(&mut self, incremental: bool) {\n        let pattern = &self.filter;\n        let mut matcher = MATCHER.lock();\n        matcher.config = Config::DEFAULT;\n        // slight preference towards prefix matches\n        matcher.config.prefer_prefix = true;\n        let pattern = Atom::new(\n            pattern,\n            CaseMatching::Ignore,\n            Normalization::Smart,\n            AtomKind::Fuzzy,\n            false,\n        );\n        let mut buf = Vec::new();\n        let (matches, options) = self.popup.contents_mut().update_options();\n        if incremental {\n            matches.retain_mut(|(index, score)| {\n                let option = &options[*index as usize];\n                let text = option.filter_text();\n                let new_score = pattern.score(Utf32Str::new(text, &mut buf), &mut matcher);\n                match new_score {\n                    Some(new_score) => {\n                        *score = new_score as u32 / 2;\n                        true\n                    }\n                    None => false,\n                }\n            })\n        } else {\n            matches.clear();\n            matches.extend(options.iter().enumerate().filter_map(|(i, option)| {\n                let text = option.filter_text();\n                pattern\n                    .score(Utf32Str::new(text, &mut buf), &mut matcher)\n                    .map(|score| (i as u32, score as u32 / 3))\n            }));\n        }\n        // Nucleo is meant as an FZF-like fuzzy matcher and only hides matches that are truly\n        // impossible - as in the sequence of characters just doesn't appear. That doesn't work\n        // well for completions with multiple language servers where all completions of the next\n        // server are below the current one (so you would get good suggestions from the second\n        // server below those of the first). Setting a reasonable cutoff below which to move bad\n        // completions out of the way helps with that.\n        //\n        // The score computation is a heuristic derived from Nucleo internal constants that may\n        // move upstream in the future. I want to test this out here to settle on a good number.\n        let min_score = (7 + pattern.needle_text().len() as u32 * 14) / 3;\n        matches.sort_unstable_by_key(|&(i, score)| {\n            let option = &options[i as usize];\n            (\n                score <= min_score,\n                Reverse(option.preselect()),\n                option.provider_priority(),\n                Reverse(score),\n                i,\n            )\n        });\n    }\n\n    /// Synchronously resolve the given completion item. This is used when\n    /// accepting a completion.\n    fn resolve_completion_item(\n        language_server: &helix_lsp::Client,\n        completion_item: lsp::CompletionItem,\n    ) -> Option<lsp::CompletionItem> {\n        if !matches!(\n            language_server.capabilities().completion_provider,\n            Some(lsp::CompletionOptions {\n                resolve_provider: Some(true),\n                ..\n            })\n        ) {\n            return None;\n        }\n        let future = language_server.resolve_completion_item(&completion_item);\n        let response = helix_lsp::block_on(future);\n        match response {\n            Ok(item) => Some(item),\n            Err(err) => {\n                log::error!(\"Failed to resolve completion item: {}\", err);\n                None\n            }\n        }\n    }\n\n    /// Appends (`c: Some(c)`) or removes (`c: None`) a character to/from the filter\n    /// this should be called whenever the user types or deletes a character in insert mode.\n    pub fn update_filter(&mut self, c: Option<char>) {\n        // recompute menu based on matches\n        let menu = self.popup.contents_mut();\n        match c {\n            Some(c) => self.filter.push(c),\n            None => {\n                self.filter.pop();\n                if self.filter.is_empty() {\n                    menu.clear();\n                    return;\n                }\n            }\n        }\n        self.score(c.is_some());\n        self.popup.contents_mut().reset_cursor();\n    }\n\n    pub fn replace_provider_completions(\n        &mut self,\n        response: &mut CompletionResponse,\n        is_incomplete: bool,\n    ) {\n        let menu = self.popup.contents_mut();\n        let (_, options) = menu.update_options();\n        if is_incomplete {\n            options.retain(|item| item.provider() != response.provider)\n        }\n        response.take_items(options);\n        self.score(false);\n        let menu = self.popup.contents_mut();\n        menu.ensure_cursor_in_bounds();\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.popup.contents().is_empty()\n    }\n\n    pub fn replace_item(\n        &mut self,\n        old_item: &impl PartialEq<CompletionItem>,\n        new_item: CompletionItem,\n    ) {\n        self.popup.contents_mut().replace_option(old_item, new_item);\n    }\n\n    pub fn area(&mut self, viewport: Rect, editor: &Editor) -> Rect {\n        self.popup.area(viewport, editor)\n    }\n}\n\nimpl Component for Completion {\n    fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult {\n        self.popup.handle_event(event, cx)\n    }\n\n    fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {\n        self.popup.required_size(viewport)\n    }\n\n    fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        self.popup.render(area, surface, cx);\n\n        // if we have a selection, render a markdown popup on top/below with info\n        let option = match self.popup.contents_mut().selection_mut() {\n            Some(option) => option,\n            None => return,\n        };\n        if let CompletionItem::Lsp(option) = option {\n            self.resolve_handler.ensure_item_resolved(cx.editor, option);\n        }\n        // need to render:\n        // option.detail\n        // ---\n        // option.documentation\n\n        let Some(coords) = cx.editor.cursor().0 else {\n            return;\n        };\n        let cursor_pos = coords.row as u16;\n        let doc = doc!(cx.editor);\n        let language = doc.language_name().unwrap_or(\"\");\n\n        let markdowned = |lang: &str, detail: Option<&str>, doc: Option<&str>| {\n            let md = match (detail, doc) {\n                (Some(detail), Some(doc)) => format!(\"```{lang}\\n{detail}\\n```\\n{doc}\"),\n                (Some(detail), None) => format!(\"```{lang}\\n{detail}\\n```\"),\n                (None, Some(doc)) => doc.to_string(),\n                (None, None) => String::new(),\n            };\n            Markdown::new(md, cx.editor.syn_loader.clone())\n        };\n\n        let mut markdown_doc = match option {\n            CompletionItem::Lsp(option) => match &option.item.documentation {\n                Some(lsp::Documentation::String(contents))\n                | Some(lsp::Documentation::MarkupContent(lsp::MarkupContent {\n                    kind: lsp::MarkupKind::PlainText,\n                    value: contents,\n                })) => {\n                    // TODO: convert to wrapped text\n                    markdowned(language, option.item.detail.as_deref(), Some(contents))\n                }\n                Some(lsp::Documentation::MarkupContent(lsp::MarkupContent {\n                    kind: lsp::MarkupKind::Markdown,\n                    value: contents,\n                })) => {\n                    // TODO: set language based on doc scope\n                    markdowned(language, option.item.detail.as_deref(), Some(contents))\n                }\n                None if option.item.detail.is_some() => {\n                    // TODO: set language based on doc scope\n                    markdowned(language, option.item.detail.as_deref(), None)\n                }\n                None => return,\n            },\n            CompletionItem::Other(option) => {\n                let Some(doc) = option.documentation.as_deref() else {\n                    return;\n                };\n                markdowned(language, None, Some(doc))\n            }\n        };\n\n        let popup_area = self.popup.area(area, cx.editor);\n        let doc_width_available = area.width.saturating_sub(popup_area.right());\n        let doc_area = if doc_width_available > 30 {\n            let mut doc_width = doc_width_available;\n            let mut doc_height = area.height.saturating_sub(popup_area.top());\n            let x = popup_area.right();\n            let y = popup_area.top();\n\n            if let Some((rel_width, rel_height)) =\n                markdown_doc.required_size((doc_width, doc_height))\n            {\n                doc_width = rel_width.min(doc_width);\n                doc_height = rel_height.min(doc_height);\n            }\n            Rect::new(x, y, doc_width, doc_height)\n        } else {\n            // Documentation should not cover the cursor or the completion popup\n            // Completion popup could be above or below the current line\n            let avail_height_above = cursor_pos.min(popup_area.top()).saturating_sub(1);\n            let avail_height_below = area\n                .height\n                .saturating_sub(cursor_pos.max(popup_area.bottom()) + 1 /* padding */);\n            let (y, avail_height) = if avail_height_below >= avail_height_above {\n                (\n                    area.height.saturating_sub(avail_height_below),\n                    avail_height_below,\n                )\n            } else {\n                (0, avail_height_above)\n            };\n            if avail_height <= 1 {\n                return;\n            }\n\n            Rect::new(0, y, area.width, avail_height.min(15))\n        };\n\n        // clear area\n        let background = cx.editor.theme.get(\"ui.popup\");\n        surface.clear_with(doc_area, background);\n\n        if cx.editor.popup_border() {\n            use tui::widgets::{Block, Widget};\n            Widget::render(Block::bordered(), doc_area, surface);\n        }\n\n        markdown_doc.render(doc_area, surface, cx);\n    }\n}\nfn lsp_item_to_transaction(\n    doc: &Document,\n    view_id: ViewId,\n    item: &lsp::CompletionItem,\n    offset_encoding: OffsetEncoding,\n    trigger_offset: usize,\n    replace_mode: bool,\n) -> (Transaction, Option<RenderedSnippet>) {\n    let selection = doc.selection(view_id);\n    let text = doc.text().slice(..);\n    let primary_cursor = selection.primary().cursor(text);\n\n    let (edit_offset, new_text) = if let Some(edit) = &item.text_edit {\n        let edit = match edit {\n            lsp::CompletionTextEdit::Edit(edit) => edit.clone(),\n            lsp::CompletionTextEdit::InsertAndReplace(item) => {\n                let range = if replace_mode {\n                    item.replace\n                } else {\n                    item.insert\n                };\n                lsp::TextEdit::new(range, item.new_text.clone())\n            }\n        };\n\n        let Some(range) = util::lsp_range_to_range(doc.text(), edit.range, offset_encoding) else {\n            return (Transaction::new(doc.text()), None);\n        };\n\n        let start_offset = range.anchor as i128 - primary_cursor as i128;\n        let end_offset = range.head as i128 - primary_cursor as i128;\n\n        (Some((start_offset, end_offset)), edit.new_text)\n    } else {\n        let new_text = item\n            .insert_text\n            .clone()\n            .unwrap_or_else(|| item.label.clone());\n        // check that we are still at the correct savepoint\n        // we can still generate a transaction regardless but if the\n        // document changed (and not just the selection) then we will\n        // likely delete the wrong text (same if we applied an edit sent by the LS)\n        debug_assert!(primary_cursor == trigger_offset);\n        (None, new_text)\n    };\n\n    if matches!(item.kind, Some(lsp::CompletionItemKind::SNIPPET))\n        || matches!(\n            item.insert_text_format,\n            Some(lsp::InsertTextFormat::SNIPPET)\n        )\n    {\n        let Ok(snippet) = Snippet::parse(&new_text) else {\n            log::error!(\"Failed to parse snippet: {new_text:?}\",);\n            return (Transaction::new(doc.text()), None);\n        };\n        let (transaction, snippet) = util::generate_transaction_from_snippet(\n            doc.text(),\n            selection,\n            edit_offset,\n            replace_mode,\n            snippet,\n            &mut doc.snippet_ctx(),\n        );\n        (transaction, Some(snippet))\n    } else {\n        let transaction = util::generate_transaction_from_completion_edit(\n            doc.text(),\n            selection,\n            edit_offset,\n            replace_mode,\n            new_text,\n        );\n        (transaction, None)\n    }\n}\n\nfn completion_changes(transaction: &Transaction, trigger_offset: usize) -> Vec<Change> {\n    transaction\n        .changes_iter()\n        .filter(|(start, end, _)| (*start..=*end).contains(&trigger_offset))\n        .collect()\n}\n"
  },
  {
    "path": "helix-term/src/ui/document.rs",
    "content": "use std::cmp::min;\n\nuse helix_core::doc_formatter::{DocumentFormatter, FormattedGrapheme, GraphemeSource, TextFormat};\nuse helix_core::graphemes::Grapheme;\nuse helix_core::str_utils::char_to_byte_idx;\nuse helix_core::syntax::{self, HighlightEvent, Highlighter, OverlayHighlights};\nuse helix_core::text_annotations::TextAnnotations;\nuse helix_core::{visual_offset_from_block, Position, RopeSlice};\nuse helix_stdx::rope::RopeSliceExt;\nuse helix_view::editor::{WhitespaceConfig, WhitespaceRenderValue};\nuse helix_view::graphics::Rect;\nuse helix_view::theme::Style;\nuse helix_view::view::ViewPosition;\nuse helix_view::{Document, Theme};\nuse tui::buffer::Buffer as Surface;\n\nuse crate::ui::text_decorations::DecorationManager;\n\n#[derive(Debug, PartialEq, Eq, Copy, Clone)]\npub struct LinePos {\n    /// Indicates whether the given visual line\n    /// is the first visual line of the given document line\n    pub first_visual_line: bool,\n    /// The line index of the document line that contains the given visual line\n    pub doc_line: usize,\n    /// Vertical offset from the top of the inner view area\n    pub visual_line: u16,\n}\n\n#[allow(clippy::too_many_arguments)]\npub fn render_document(\n    surface: &mut Surface,\n    viewport: Rect,\n    doc: &Document,\n    offset: ViewPosition,\n    doc_annotations: &TextAnnotations,\n    syntax_highlighter: Option<Highlighter<'_>>,\n    overlay_highlights: Vec<syntax::OverlayHighlights>,\n    theme: &Theme,\n    decorations: DecorationManager,\n) {\n    let mut renderer = TextRenderer::new(\n        surface,\n        doc,\n        theme,\n        Position::new(offset.vertical_offset, offset.horizontal_offset),\n        viewport,\n    );\n    render_text(\n        &mut renderer,\n        doc.text().slice(..),\n        offset.anchor,\n        &doc.text_format(viewport.width, Some(theme)),\n        doc_annotations,\n        syntax_highlighter,\n        overlay_highlights,\n        theme,\n        decorations,\n    )\n}\n\n#[allow(clippy::too_many_arguments)]\npub fn render_text(\n    renderer: &mut TextRenderer,\n    text: RopeSlice<'_>,\n    anchor: usize,\n    text_fmt: &TextFormat,\n    text_annotations: &TextAnnotations,\n    syntax_highlighter: Option<Highlighter<'_>>,\n    overlay_highlights: Vec<syntax::OverlayHighlights>,\n    theme: &Theme,\n    mut decorations: DecorationManager,\n) {\n    let row_off = visual_offset_from_block(text, anchor, anchor, text_fmt, text_annotations)\n        .0\n        .row;\n\n    let mut formatter =\n        DocumentFormatter::new_at_prev_checkpoint(text, text_fmt, text_annotations, anchor);\n    let mut syntax_highlighter =\n        SyntaxHighlighter::new(syntax_highlighter, text, theme, renderer.text_style);\n    let mut overlay_highlighter = OverlayHighlighter::new(overlay_highlights, theme);\n\n    let mut last_line_pos = LinePos {\n        first_visual_line: false,\n        doc_line: usize::MAX,\n        visual_line: u16::MAX,\n    };\n    let mut last_line_end = 0;\n    let mut is_in_indent_area = true;\n    let mut last_line_indent_level = 0;\n    let mut reached_view_top = false;\n\n    loop {\n        let Some(mut grapheme) = formatter.next() else {\n            break;\n        };\n\n        // skip any graphemes on visual lines before the block start\n        if grapheme.visual_pos.row < row_off {\n            continue;\n        }\n        grapheme.visual_pos.row -= row_off;\n        if !reached_view_top {\n            decorations.prepare_for_rendering(grapheme.char_idx);\n            reached_view_top = true;\n        }\n\n        // if the end of the viewport is reached stop rendering\n        if grapheme.visual_pos.row as u16 >= renderer.viewport.height + renderer.offset.row as u16 {\n            break;\n        }\n\n        // apply decorations before rendering a new line\n        if grapheme.visual_pos.row as u16 != last_line_pos.visual_line {\n            // we initiate doc_line with usize::MAX because no file\n            // can reach that size (memory allocations are limited to isize::MAX)\n            // initially there is no \"previous\" line (so doc_line is set to usize::MAX)\n            // in that case we don't need to draw indent guides/virtual text\n            if last_line_pos.doc_line != usize::MAX {\n                // draw indent guides for the last line\n                renderer.draw_indent_guides(last_line_indent_level, last_line_pos.visual_line);\n                is_in_indent_area = true;\n                decorations.render_virtual_lines(renderer, last_line_pos, last_line_end)\n            }\n            last_line_pos = LinePos {\n                first_visual_line: grapheme.line_idx != last_line_pos.doc_line,\n                doc_line: grapheme.line_idx,\n                visual_line: grapheme.visual_pos.row as u16,\n            };\n            decorations.decorate_line(renderer, last_line_pos);\n        }\n\n        // acquire the correct grapheme style\n        while grapheme.char_idx >= syntax_highlighter.pos {\n            syntax_highlighter.advance();\n        }\n        while grapheme.char_idx >= overlay_highlighter.pos {\n            overlay_highlighter.advance();\n        }\n\n        let grapheme_style = if let GraphemeSource::VirtualText { highlight } = grapheme.source {\n            let mut style = renderer.text_style;\n            if let Some(highlight) = highlight {\n                style = style.patch(theme.highlight(highlight));\n            }\n            GraphemeStyle {\n                syntax_style: style,\n                overlay_style: Style::default(),\n            }\n        } else {\n            GraphemeStyle {\n                syntax_style: syntax_highlighter.style,\n                overlay_style: overlay_highlighter.style,\n            }\n        };\n        decorations.decorate_grapheme(renderer, &grapheme);\n\n        let virt = grapheme.is_virtual();\n        let grapheme_width = renderer.draw_grapheme(\n            &grapheme,\n            grapheme_style,\n            virt,\n            &mut last_line_indent_level,\n            &mut is_in_indent_area,\n            grapheme.visual_pos,\n        );\n        last_line_end = grapheme.visual_pos.col + grapheme_width;\n    }\n\n    renderer.draw_indent_guides(last_line_indent_level, last_line_pos.visual_line);\n    decorations.render_virtual_lines(renderer, last_line_pos, last_line_end)\n}\n\n#[derive(Debug)]\npub struct TextRenderer<'a> {\n    surface: &'a mut Surface,\n    pub text_style: Style,\n    pub whitespace_style: Style,\n    pub indent_guide_char: String,\n    pub indent_guide_style: Style,\n    pub newline: String,\n    pub nbsp: String,\n    pub nnbsp: String,\n    pub space: String,\n    pub tab: String,\n    pub virtual_tab: String,\n    pub indent_width: u16,\n    pub starting_indent: usize,\n    pub draw_indent_guides: bool,\n    pub viewport: Rect,\n    pub offset: Position,\n}\n\npub struct GraphemeStyle {\n    syntax_style: Style,\n    overlay_style: Style,\n}\n\nimpl<'a> TextRenderer<'a> {\n    pub fn new(\n        surface: &'a mut Surface,\n        doc: &Document,\n        theme: &Theme,\n        offset: Position,\n        viewport: Rect,\n    ) -> TextRenderer<'a> {\n        let editor_config = doc.config.load();\n        let WhitespaceConfig {\n            render: ws_render,\n            characters: ws_chars,\n        } = &editor_config.whitespace;\n\n        let tab_width = doc.tab_width();\n        let tab = if ws_render.tab() == WhitespaceRenderValue::All {\n            std::iter::once(ws_chars.tab)\n                .chain(std::iter::repeat_n(ws_chars.tabpad, tab_width - 1))\n                .collect()\n        } else {\n            \" \".repeat(tab_width)\n        };\n        let virtual_tab = \" \".repeat(tab_width);\n        let newline = if ws_render.newline() == WhitespaceRenderValue::All {\n            ws_chars.newline.into()\n        } else {\n            \" \".to_owned()\n        };\n\n        let space = if ws_render.space() == WhitespaceRenderValue::All {\n            ws_chars.space.into()\n        } else {\n            \" \".to_owned()\n        };\n        let nbsp = if ws_render.nbsp() == WhitespaceRenderValue::All {\n            ws_chars.nbsp.into()\n        } else {\n            \" \".to_owned()\n        };\n        let nnbsp = if ws_render.nnbsp() == WhitespaceRenderValue::All {\n            ws_chars.nnbsp.into()\n        } else {\n            \" \".to_owned()\n        };\n\n        let text_style = theme.get(\"ui.text\");\n\n        let indent_width = doc.indent_style.indent_width(tab_width) as u16;\n\n        TextRenderer {\n            surface,\n            indent_guide_char: editor_config.indent_guides.character.into(),\n            newline,\n            nbsp,\n            nnbsp,\n            space,\n            tab,\n            virtual_tab,\n            whitespace_style: theme.get(\"ui.virtual.whitespace\"),\n            indent_width,\n            starting_indent: offset.col / indent_width as usize\n                + !offset.col.is_multiple_of(indent_width as usize) as usize\n                + editor_config.indent_guides.skip_levels as usize,\n            indent_guide_style: text_style.patch(\n                theme\n                    .try_get(\"ui.virtual.indent-guide\")\n                    .unwrap_or_else(|| theme.get(\"ui.virtual.whitespace\")),\n            ),\n            text_style,\n            draw_indent_guides: editor_config.indent_guides.render,\n            viewport,\n            offset,\n        }\n    }\n    /// Draws a single `grapheme` at the current render position with a specified `style`.\n    pub fn draw_decoration_grapheme(\n        &mut self,\n        grapheme: Grapheme,\n        mut style: Style,\n        mut row: u16,\n        col: u16,\n    ) -> bool {\n        if (row as usize) < self.offset.row\n            || row >= self.viewport.height\n            || col >= self.viewport.width\n        {\n            return false;\n        }\n        row -= self.offset.row as u16;\n        // TODO is it correct to apply the whitspace style to all unicode white spaces?\n        if grapheme.is_whitespace() {\n            style = style.patch(self.whitespace_style);\n        }\n\n        let grapheme = match grapheme {\n            Grapheme::Tab { width } => {\n                let grapheme_tab_width = char_to_byte_idx(&self.virtual_tab, width);\n                &self.virtual_tab[..grapheme_tab_width]\n            }\n            Grapheme::Other { ref g } if g == \"\\u{00A0}\" => \" \",\n            Grapheme::Other { ref g } => g,\n            Grapheme::Newline => \" \",\n        };\n\n        self.surface.set_string(\n            self.viewport.x + col,\n            self.viewport.y + row,\n            grapheme,\n            style,\n        );\n        true\n    }\n\n    /// Draws a single `grapheme` at the current render position with a specified `style`.\n    pub fn draw_grapheme(\n        &mut self,\n        grapheme: &FormattedGrapheme,\n        grapheme_style: GraphemeStyle,\n        is_virtual: bool,\n        last_indent_level: &mut usize,\n        is_in_indent_area: &mut bool,\n        mut position: Position,\n    ) -> usize {\n        if position.row < self.offset.row {\n            return 0;\n        }\n        position.row -= self.offset.row;\n        let cut_off_start = self.offset.col.saturating_sub(position.col);\n        let is_whitespace = grapheme.is_whitespace();\n\n        // TODO is it correct to apply the whitespace style to all unicode white spaces?\n        let mut style = grapheme_style.syntax_style;\n        if is_whitespace {\n            style = style.patch(self.whitespace_style);\n        }\n        style = style.patch(grapheme_style.overlay_style);\n\n        let width = grapheme.width();\n        let space = if is_virtual { \" \" } else { &self.space };\n        let nbsp = if is_virtual { \" \" } else { &self.nbsp };\n        let nnbsp = if is_virtual { \" \" } else { &self.nnbsp };\n        let tab = if is_virtual {\n            &self.virtual_tab\n        } else {\n            &self.tab\n        };\n        let grapheme = match grapheme.raw {\n            Grapheme::Tab { width } => {\n                let grapheme_tab_width = char_to_byte_idx(tab, width);\n                &tab[..grapheme_tab_width]\n            }\n            // TODO special rendering for other whitespaces?\n            Grapheme::Other { ref g } if g == \" \" && !grapheme.source.is_eof() => space,\n            Grapheme::Other { ref g } if g == \"\\u{00A0}\" => nbsp,\n            Grapheme::Other { ref g } if g == \"\\u{202F}\" => nnbsp,\n            Grapheme::Other { ref g } => g,\n            Grapheme::Newline => &self.newline,\n        };\n\n        let in_bounds = self.column_in_bounds(position.col, width);\n\n        if in_bounds {\n            self.surface.set_string(\n                self.viewport.x + (position.col - self.offset.col) as u16,\n                self.viewport.y + position.row as u16,\n                grapheme,\n                style,\n            );\n        } else if cut_off_start != 0 && cut_off_start < width {\n            // partially on screen\n            let rect = Rect::new(\n                self.viewport.x,\n                self.viewport.y + position.row as u16,\n                (width - cut_off_start) as u16,\n                1,\n            );\n            self.surface.set_style(rect, style);\n        }\n        if *is_in_indent_area && !is_whitespace {\n            *last_indent_level = position.col;\n            *is_in_indent_area = false;\n        }\n\n        width\n    }\n\n    pub fn column_in_bounds(&self, colum: usize, width: usize) -> bool {\n        self.offset.col <= colum && colum + width <= self.offset.col + self.viewport.width as usize\n    }\n\n    /// Overlay indentation guides ontop of a rendered line\n    /// The indentation level is computed in `draw_lines`.\n    /// Therefore this function must always be called afterwards.\n    pub fn draw_indent_guides(&mut self, indent_level: usize, mut row: u16) {\n        if !self.draw_indent_guides || self.offset.row > row as usize {\n            return;\n        }\n        row -= self.offset.row as u16;\n\n        // Don't draw indent guides outside of view\n        let end_indent = min(\n            indent_level,\n            // Add indent_width - 1 to round up, since the first visible\n            // indent might be a bit after offset.col\n            self.offset.col + self.viewport.width as usize + (self.indent_width as usize - 1),\n        ) / self.indent_width as usize;\n\n        for i in self.starting_indent..end_indent {\n            let x = (self.viewport.x as usize + (i * self.indent_width as usize) - self.offset.col)\n                as u16;\n            let y = self.viewport.y + row;\n            debug_assert!(self.surface.in_bounds(x, y));\n            self.surface\n                .set_string(x, y, &self.indent_guide_char, self.indent_guide_style);\n        }\n    }\n\n    pub fn set_string(&mut self, x: u16, y: u16, string: impl AsRef<str>, style: Style) {\n        if (y as usize) < self.offset.row {\n            return;\n        }\n        self.surface\n            .set_string(x, y + self.viewport.y, string, style)\n    }\n\n    pub fn set_stringn(\n        &mut self,\n        x: u16,\n        y: u16,\n        string: impl AsRef<str>,\n        width: usize,\n        style: Style,\n    ) {\n        if (y as usize) < self.offset.row {\n            return;\n        }\n        self.surface\n            .set_stringn(x, y + self.viewport.y, string, width, style);\n    }\n\n    /// Sets the style of an area **within the text viewport* this accounts\n    /// both for the renderers vertical offset and its viewport\n    pub fn set_style(&mut self, mut area: Rect, style: Style) {\n        area = area.clip_top(self.offset.row as u16);\n        area.y += self.viewport.y;\n        self.surface.set_style(area, style);\n    }\n\n    #[allow(clippy::too_many_arguments)]\n    pub fn set_string_truncated(\n        &mut self,\n        x: u16,\n        y: u16,\n        string: &str,\n        width: usize,\n        style: impl Fn(usize) -> Style, // Map a grapheme's string offset to a style\n        ellipsis: bool,\n        truncate_start: bool,\n    ) -> (u16, u16) {\n        if (y as usize) < self.offset.row {\n            return (x, y);\n        }\n        self.surface.set_string_truncated(\n            x,\n            y + self.viewport.y,\n            string,\n            width,\n            style,\n            ellipsis,\n            truncate_start,\n        )\n    }\n}\n\nstruct SyntaxHighlighter<'h, 'r, 't> {\n    inner: Option<Highlighter<'h>>,\n    text: RopeSlice<'r>,\n    /// The character index of the next highlight event, or `usize::MAX` if the highlighter is\n    /// finished.\n    pos: usize,\n    theme: &'t Theme,\n    text_style: Style,\n    style: Style,\n}\n\nimpl<'h, 'r, 't> SyntaxHighlighter<'h, 'r, 't> {\n    fn new(\n        inner: Option<Highlighter<'h>>,\n        text: RopeSlice<'r>,\n        theme: &'t Theme,\n        text_style: Style,\n    ) -> Self {\n        let mut highlighter = Self {\n            inner,\n            text,\n            pos: 0,\n            theme,\n            style: text_style,\n            text_style,\n        };\n        highlighter.update_pos();\n        highlighter\n    }\n\n    fn update_pos(&mut self) {\n        self.pos = self\n            .inner\n            .as_ref()\n            .and_then(|highlighter| {\n                let next_byte_idx = highlighter.next_event_offset();\n                (next_byte_idx != u32::MAX).then(|| {\n                    // Move the byte index to the nearest character boundary (rounding up) and\n                    // convert it to a character index.\n                    self.text\n                        .byte_to_char(self.text.ceil_char_boundary(next_byte_idx as usize))\n                })\n            })\n            .unwrap_or(usize::MAX);\n    }\n\n    fn advance(&mut self) {\n        let Some(highlighter) = self.inner.as_mut() else {\n            return;\n        };\n\n        let (event, highlights) = highlighter.advance();\n        let base = match event {\n            HighlightEvent::Refresh => self.text_style,\n            HighlightEvent::Push => self.style,\n        };\n\n        self.style = highlights.fold(base, |acc, highlight| {\n            acc.patch(self.theme.highlight(highlight))\n        });\n        self.update_pos();\n    }\n}\n\nstruct OverlayHighlighter<'t> {\n    inner: syntax::OverlayHighlighter,\n    pos: usize,\n    theme: &'t Theme,\n    style: Style,\n}\n\nimpl<'t> OverlayHighlighter<'t> {\n    fn new(overlays: Vec<OverlayHighlights>, theme: &'t Theme) -> Self {\n        let inner = syntax::OverlayHighlighter::new(overlays);\n        let mut highlighter = Self {\n            inner,\n            pos: 0,\n            theme,\n            style: Style::default(),\n        };\n        highlighter.update_pos();\n        highlighter\n    }\n\n    fn update_pos(&mut self) {\n        self.pos = self.inner.next_event_offset();\n    }\n\n    fn advance(&mut self) {\n        let (event, highlights) = self.inner.advance();\n        let base = match event {\n            HighlightEvent::Refresh => Style::default(),\n            HighlightEvent::Push => self.style,\n        };\n\n        self.style = highlights.fold(base, |acc, highlight| {\n            acc.patch(self.theme.highlight(highlight))\n        });\n        self.update_pos();\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/editor.rs",
    "content": "use crate::{\n    commands::{self, OnKeyCallback, OnKeyCallbackKind},\n    compositor::{Component, Context, Event, EventResult},\n    events::{OnModeSwitch, PostCommand},\n    handlers::completion::CompletionItem,\n    key,\n    keymap::{KeymapResult, Keymaps},\n    ui::{\n        document::{render_document, LinePos, TextRenderer},\n        statusline,\n        text_decorations::{self, Decoration, DecorationManager, InlineDiagnostics},\n        Completion, ProgressSpinners,\n    },\n};\n\nuse helix_core::{\n    diagnostic::NumberOrString,\n    graphemes::{next_grapheme_boundary, prev_grapheme_boundary},\n    movement::Direction,\n    syntax::{self, OverlayHighlights},\n    text_annotations::TextAnnotations,\n    unicode::width::UnicodeWidthStr,\n    visual_offset_from_block, Change, Position, Range, Selection, Transaction,\n};\nuse helix_view::{\n    annotations::diagnostics::DiagnosticFilter,\n    document::{Mode, SCRATCH_BUFFER_NAME},\n    editor::{CompleteAction, CursorShapeConfig},\n    graphics::{Color, CursorKind, Modifier, Rect, Style},\n    input::{KeyEvent, MouseButton, MouseEvent, MouseEventKind},\n    keyboard::{KeyCode, KeyModifiers},\n    Document, Editor, Theme, View,\n};\nuse std::{mem::take, num::NonZeroUsize, ops, path::PathBuf, rc::Rc};\n\nuse tui::{buffer::Buffer as Surface, text::Span};\n\npub struct EditorView {\n    pub keymaps: Keymaps,\n    on_next_key: Option<(OnKeyCallback, OnKeyCallbackKind)>,\n    pseudo_pending: Vec<KeyEvent>,\n    pub(crate) last_insert: (commands::MappableCommand, Vec<InsertEvent>),\n    pub(crate) completion: Option<Completion>,\n    spinners: ProgressSpinners,\n    /// Tracks if the terminal window is focused by reaction to terminal focus events\n    terminal_focused: bool,\n}\n\n#[derive(Debug, Clone)]\npub enum InsertEvent {\n    Key(KeyEvent),\n    CompletionApply {\n        trigger_offset: usize,\n        changes: Vec<Change>,\n    },\n    TriggerCompletion,\n    RequestCompletion,\n}\n\nimpl EditorView {\n    pub fn new(keymaps: Keymaps) -> Self {\n        Self {\n            keymaps,\n            on_next_key: None,\n            pseudo_pending: Vec::new(),\n            last_insert: (commands::MappableCommand::normal_mode, Vec::new()),\n            completion: None,\n            spinners: ProgressSpinners::default(),\n            terminal_focused: true,\n        }\n    }\n\n    pub fn spinners_mut(&mut self) -> &mut ProgressSpinners {\n        &mut self.spinners\n    }\n\n    pub fn render_view(\n        &self,\n        editor: &Editor,\n        doc: &Document,\n        view: &View,\n        viewport: Rect,\n        surface: &mut Surface,\n        is_focused: bool,\n    ) {\n        let inner = view.inner_area(doc);\n        let area = view.area;\n        let theme = &editor.theme;\n        let config = editor.config();\n        let loader = editor.syn_loader.load();\n\n        let view_offset = doc.view_offset(view.id);\n\n        let text_annotations = view.text_annotations(doc, Some(theme));\n        let mut decorations = DecorationManager::default();\n\n        if is_focused && config.cursorline {\n            decorations.add_decoration(Self::cursorline(doc, view, theme));\n        }\n\n        if is_focused && config.cursorcolumn {\n            Self::highlight_cursorcolumn(doc, view, surface, theme, inner, &text_annotations);\n        }\n\n        // Set DAP highlights, if needed.\n        if let Some(frame) = editor.current_stack_frame() {\n            let dap_line = frame.line.saturating_sub(1);\n            let style = theme.get(\"ui.highlight.frameline\");\n            let line_decoration = move |renderer: &mut TextRenderer, pos: LinePos| {\n                if pos.doc_line != dap_line {\n                    return;\n                }\n                renderer.set_style(Rect::new(inner.x, pos.visual_line, inner.width, 1), style);\n            };\n\n            decorations.add_decoration(line_decoration);\n        }\n\n        let syntax_highlighter =\n            Self::doc_syntax_highlighter(doc, view_offset.anchor, inner.height, &loader);\n        let mut overlays = Vec::new();\n\n        overlays.push(Self::overlay_syntax_highlights(\n            doc,\n            view_offset.anchor,\n            inner.height,\n            &text_annotations,\n        ));\n\n        if doc\n            .language_config()\n            .and_then(|config| config.rainbow_brackets)\n            .unwrap_or(config.rainbow_brackets)\n        {\n            if let Some(overlay) =\n                Self::doc_rainbow_highlights(doc, view_offset.anchor, inner.height, theme, &loader)\n            {\n                overlays.push(overlay);\n            }\n        }\n\n        if let Some(overlay) = Self::doc_document_link_highlights(doc, theme) {\n            overlays.push(overlay);\n        }\n\n        Self::doc_diagnostics_highlights_into(doc, theme, &mut overlays);\n\n        if is_focused {\n            if config.lsp.auto_document_highlight {\n                if let Some(overlay) = Self::doc_document_highlights(doc, view, theme) {\n                    overlays.push(overlay);\n                }\n            }\n            if let Some(tabstops) = Self::tabstop_highlights(doc, theme) {\n                overlays.push(tabstops);\n            }\n            overlays.push(Self::doc_selection_highlights(\n                editor.mode(),\n                doc,\n                view,\n                theme,\n                &config.cursor_shape,\n                self.terminal_focused,\n            ));\n            if let Some(overlay) = Self::highlight_focused_view_elements(view, doc, theme) {\n                overlays.push(overlay);\n            }\n        }\n\n        let gutter_overflow = view.gutter_offset(doc) == 0;\n        if !gutter_overflow {\n            Self::render_gutter(\n                editor,\n                doc,\n                view,\n                view.area,\n                theme,\n                is_focused & self.terminal_focused,\n                &mut decorations,\n            );\n        }\n\n        Self::render_rulers(editor, doc, view, inner, surface, theme);\n\n        let primary_cursor = doc\n            .selection(view.id)\n            .primary()\n            .cursor(doc.text().slice(..));\n        if is_focused {\n            decorations.add_decoration(text_decorations::Cursor {\n                cache: &editor.cursor_cache,\n                primary_cursor,\n            });\n        }\n        let width = view.inner_width(doc);\n        let config = doc.config.load();\n        let enable_cursor_line = view\n            .diagnostics_handler\n            .show_cursorline_diagnostics(doc, view.id);\n        let inline_diagnostic_config = config.inline_diagnostics.prepare(width, enable_cursor_line);\n        decorations.add_decoration(InlineDiagnostics::new(\n            doc,\n            theme,\n            primary_cursor,\n            inline_diagnostic_config,\n            config.end_of_line_diagnostics,\n        ));\n        render_document(\n            surface,\n            inner,\n            doc,\n            view_offset,\n            &text_annotations,\n            syntax_highlighter,\n            overlays,\n            theme,\n            decorations,\n        );\n\n        // if we're not at the edge of the screen, draw a right border\n        if viewport.right() != view.area.right() {\n            let x = area.right();\n            let border_style = theme.get(\"ui.window\");\n            for y in area.top()..area.bottom() {\n                surface[(x, y)]\n                    .set_symbol(tui::symbols::line::VERTICAL)\n                    //.set_symbol(\" \")\n                    .set_style(border_style);\n            }\n        }\n\n        if config.inline_diagnostics.disabled()\n            && config.end_of_line_diagnostics == DiagnosticFilter::Disable\n        {\n            Self::render_diagnostics(doc, view, inner, surface, theme);\n        }\n\n        let statusline_area = view\n            .area\n            .clip_top(view.area.height.saturating_sub(1))\n            .clip_bottom(1); // -1 from bottom to remove commandline\n\n        let mut context =\n            statusline::RenderContext::new(editor, doc, view, is_focused, &self.spinners);\n\n        statusline::render(&mut context, statusline_area, surface);\n    }\n\n    pub fn render_rulers(\n        editor: &Editor,\n        doc: &Document,\n        view: &View,\n        viewport: Rect,\n        surface: &mut Surface,\n        theme: &Theme,\n    ) {\n        let editor_rulers = &editor.config().rulers;\n        let ruler_theme = theme\n            .try_get(\"ui.virtual.ruler\")\n            .unwrap_or_else(|| Style::default().bg(Color::Red));\n\n        let rulers = doc\n            .language_config()\n            .and_then(|config| config.rulers.as_ref())\n            .unwrap_or(editor_rulers);\n\n        let view_offset = doc.view_offset(view.id);\n\n        rulers\n            .iter()\n            // View might be horizontally scrolled, convert from absolute distance\n            // from the 1st column to relative distance from left of viewport\n            .filter_map(|ruler| ruler.checked_sub(1 + view_offset.horizontal_offset as u16))\n            .filter(|ruler| ruler < &viewport.width)\n            .map(|ruler| viewport.clip_left(ruler).with_width(1))\n            .for_each(|area| surface.set_style(area, ruler_theme))\n    }\n\n    fn viewport_byte_range(\n        text: helix_core::RopeSlice,\n        row: usize,\n        height: u16,\n    ) -> std::ops::Range<usize> {\n        // Calculate viewport byte ranges:\n        // Saturating subs to make it inclusive zero indexing.\n        let last_line = text.len_lines().saturating_sub(1);\n        let last_visible_line = (row + height as usize).saturating_sub(1).min(last_line);\n        let start = text.line_to_byte(row.min(last_line));\n        let end = text.line_to_byte(last_visible_line + 1);\n\n        start..end\n    }\n\n    /// Get the syntax highlighter for a document in a view represented by the first line\n    /// and column (`offset`) and the last line. This is done instead of using a view\n    /// directly to enable rendering syntax highlighted docs anywhere (eg. picker preview)\n    pub fn doc_syntax_highlighter<'editor>(\n        doc: &'editor Document,\n        anchor: usize,\n        height: u16,\n        loader: &'editor syntax::Loader,\n    ) -> Option<syntax::Highlighter<'editor>> {\n        let syntax = doc.syntax()?;\n        let text = doc.text().slice(..);\n        let row = text.char_to_line(anchor.min(text.len_chars()));\n        let range = Self::viewport_byte_range(text, row, height);\n        let range = range.start as u32..range.end as u32;\n\n        let highlighter = syntax.highlighter(text, loader, range);\n        Some(highlighter)\n    }\n\n    pub fn overlay_syntax_highlights(\n        doc: &Document,\n        anchor: usize,\n        height: u16,\n        text_annotations: &TextAnnotations,\n    ) -> OverlayHighlights {\n        let text = doc.text().slice(..);\n        let row = text.char_to_line(anchor.min(text.len_chars()));\n\n        let mut range = Self::viewport_byte_range(text, row, height);\n        range = text.byte_to_char(range.start)..text.byte_to_char(range.end);\n\n        text_annotations.collect_overlay_highlights(range)\n    }\n\n    pub fn doc_rainbow_highlights(\n        doc: &Document,\n        anchor: usize,\n        height: u16,\n        theme: &Theme,\n        loader: &syntax::Loader,\n    ) -> Option<OverlayHighlights> {\n        let syntax = doc.syntax()?;\n        let text = doc.text().slice(..);\n        let row = text.char_to_line(anchor.min(text.len_chars()));\n        let visible_range = Self::viewport_byte_range(text, row, height);\n        let start = syntax::child_for_byte_range(\n            &syntax.tree().root_node(),\n            visible_range.start as u32..visible_range.end as u32,\n        )\n        .map_or(visible_range.start as u32, |node| node.start_byte());\n        let range = start..visible_range.end as u32;\n\n        Some(syntax.rainbow_highlights(text, theme.rainbow_length(), loader, range))\n    }\n\n    /// Get highlight spans for document diagnostics\n    pub fn doc_diagnostics_highlights_into(\n        doc: &Document,\n        theme: &Theme,\n        overlay_highlights: &mut Vec<OverlayHighlights>,\n    ) {\n        use helix_core::diagnostic::{DiagnosticTag, Range, Severity};\n        let get_scope_of = |scope| {\n            theme\n                .find_highlight_exact(scope)\n                // get one of the themes below as fallback values\n                .or_else(|| theme.find_highlight_exact(\"diagnostic\"))\n                .or_else(|| theme.find_highlight_exact(\"ui.cursor\"))\n                .or_else(|| theme.find_highlight_exact(\"ui.selection\"))\n                .expect(\n                    \"at least one of the following scopes must be defined in the theme: `diagnostic`, `ui.cursor`, or `ui.selection`\",\n                )\n        };\n\n        // Diagnostic tags\n        let unnecessary = theme.find_highlight_exact(\"diagnostic.unnecessary\");\n        let deprecated = theme.find_highlight_exact(\"diagnostic.deprecated\");\n\n        let mut default_vec = Vec::new();\n        let mut info_vec = Vec::new();\n        let mut hint_vec = Vec::new();\n        let mut warning_vec = Vec::new();\n        let mut error_vec = Vec::new();\n        let mut unnecessary_vec = Vec::new();\n        let mut deprecated_vec = Vec::new();\n\n        let push_diagnostic = |vec: &mut Vec<ops::Range<usize>>, range: Range| {\n            // If any diagnostic overlaps ranges with the prior diagnostic,\n            // merge the two together. Otherwise push a new span.\n            match vec.last_mut() {\n                Some(existing_range) if range.start <= existing_range.end => {\n                    // This branch merges overlapping diagnostics, assuming that the current\n                    // diagnostic starts on range.start or later. If this assertion fails,\n                    // we will discard some part of `diagnostic`. This implies that\n                    // `doc.diagnostics()` is not sorted by `diagnostic.range`.\n                    debug_assert!(existing_range.start <= range.start);\n                    existing_range.end = range.end.max(existing_range.end)\n                }\n                _ => vec.push(range.start..range.end),\n            }\n        };\n\n        for diagnostic in doc.diagnostics() {\n            // Separate diagnostics into different Vecs by severity.\n            let vec = match diagnostic.severity {\n                Some(Severity::Info) => &mut info_vec,\n                Some(Severity::Hint) => &mut hint_vec,\n                Some(Severity::Warning) => &mut warning_vec,\n                Some(Severity::Error) => &mut error_vec,\n                _ => &mut default_vec,\n            };\n\n            // If the diagnostic has tags and a non-warning/error severity, skip rendering\n            // the diagnostic as info/hint/default and only render it as unnecessary/deprecated\n            // instead. For warning/error diagnostics, render both the severity highlight and\n            // the tag highlight.\n            if diagnostic.tags.is_empty()\n                || matches!(\n                    diagnostic.severity,\n                    Some(Severity::Warning | Severity::Error)\n                )\n            {\n                push_diagnostic(vec, diagnostic.range);\n            }\n\n            for tag in &diagnostic.tags {\n                match tag {\n                    DiagnosticTag::Unnecessary => {\n                        if unnecessary.is_some() {\n                            push_diagnostic(&mut unnecessary_vec, diagnostic.range)\n                        }\n                    }\n                    DiagnosticTag::Deprecated => {\n                        if deprecated.is_some() {\n                            push_diagnostic(&mut deprecated_vec, diagnostic.range)\n                        }\n                    }\n                }\n            }\n        }\n\n        overlay_highlights.push(OverlayHighlights::Homogeneous {\n            highlight: get_scope_of(\"diagnostic\"),\n            ranges: default_vec,\n        });\n        if let Some(highlight) = unnecessary {\n            overlay_highlights.push(OverlayHighlights::Homogeneous {\n                highlight,\n                ranges: unnecessary_vec,\n            });\n        }\n        if let Some(highlight) = deprecated {\n            overlay_highlights.push(OverlayHighlights::Homogeneous {\n                highlight,\n                ranges: deprecated_vec,\n            });\n        }\n        overlay_highlights.extend([\n            OverlayHighlights::Homogeneous {\n                highlight: get_scope_of(\"diagnostic.info\"),\n                ranges: info_vec,\n            },\n            OverlayHighlights::Homogeneous {\n                highlight: get_scope_of(\"diagnostic.hint\"),\n                ranges: hint_vec,\n            },\n            OverlayHighlights::Homogeneous {\n                highlight: get_scope_of(\"diagnostic.warning\"),\n                ranges: warning_vec,\n            },\n            OverlayHighlights::Homogeneous {\n                highlight: get_scope_of(\"diagnostic.error\"),\n                ranges: error_vec,\n            },\n        ]);\n    }\n\n    pub fn doc_document_highlights(\n        doc: &Document,\n        view: &View,\n        theme: &Theme,\n    ) -> Option<OverlayHighlights> {\n        let ranges = doc.document_highlights(view.id)?;\n        if ranges.is_empty() {\n            return None;\n        }\n\n        let highlight = theme\n            .find_highlight_exact(\"ui.highlight\")\n            .or_else(|| theme.find_highlight_exact(\"ui.selection\"))\n            .or_else(|| theme.find_highlight_exact(\"ui.cursor\"))?;\n\n        Some(OverlayHighlights::Homogeneous {\n            highlight,\n            ranges: ranges.to_vec(),\n        })\n    }\n\n    pub fn doc_document_link_highlights(\n        doc: &Document,\n        theme: &Theme,\n    ) -> Option<OverlayHighlights> {\n        let highlight = theme\n            .find_highlight_exact(\"markup.link.url\")\n            .or_else(|| theme.find_highlight_exact(\"markup.link\"))?;\n\n        if doc.document_links.is_empty() {\n            return None;\n        }\n\n        let mut ranges: Vec<ops::Range<usize>> = Vec::new();\n        for link in &doc.document_links {\n            if link.start >= link.end {\n                continue;\n            }\n\n            match ranges.last_mut() {\n                Some(existing_range) if link.start <= existing_range.end => {\n                    existing_range.end = existing_range.end.max(link.end);\n                }\n                _ => ranges.push(link.start..link.end),\n            }\n        }\n\n        if ranges.is_empty() {\n            return None;\n        }\n\n        Some(OverlayHighlights::Homogeneous { highlight, ranges })\n    }\n\n    /// Get highlight spans for selections in a document view.\n    pub fn doc_selection_highlights(\n        mode: Mode,\n        doc: &Document,\n        view: &View,\n        theme: &Theme,\n        cursor_shape_config: &CursorShapeConfig,\n        is_terminal_focused: bool,\n    ) -> OverlayHighlights {\n        let text = doc.text().slice(..);\n        let selection = doc.selection(view.id);\n        let primary_idx = selection.primary_index();\n\n        let cursorkind = cursor_shape_config.from_mode(mode);\n        let cursor_is_block = cursorkind == CursorKind::Block;\n\n        let selection_scope = theme\n            .find_highlight_exact(\"ui.selection\")\n            .expect(\"could not find `ui.selection` scope in the theme!\");\n        let primary_selection_scope = theme\n            .find_highlight_exact(\"ui.selection.primary\")\n            .unwrap_or(selection_scope);\n\n        let base_cursor_scope = theme\n            .find_highlight_exact(\"ui.cursor\")\n            .unwrap_or(selection_scope);\n        let base_primary_cursor_scope = theme\n            .find_highlight(\"ui.cursor.primary\")\n            .unwrap_or(base_cursor_scope);\n\n        let cursor_scope = match mode {\n            Mode::Insert => theme.find_highlight_exact(\"ui.cursor.insert\"),\n            Mode::Select => theme.find_highlight_exact(\"ui.cursor.select\"),\n            Mode::Normal => theme.find_highlight_exact(\"ui.cursor.normal\"),\n        }\n        .unwrap_or(base_cursor_scope);\n\n        let primary_cursor_scope = match mode {\n            Mode::Insert => theme.find_highlight_exact(\"ui.cursor.primary.insert\"),\n            Mode::Select => theme.find_highlight_exact(\"ui.cursor.primary.select\"),\n            Mode::Normal => theme.find_highlight_exact(\"ui.cursor.primary.normal\"),\n        }\n        .unwrap_or(base_primary_cursor_scope);\n\n        let mut spans = Vec::new();\n        for (i, range) in selection.iter().enumerate() {\n            let selection_is_primary = i == primary_idx;\n            let (cursor_scope, selection_scope) = if selection_is_primary {\n                (primary_cursor_scope, primary_selection_scope)\n            } else {\n                (cursor_scope, selection_scope)\n            };\n\n            // Special-case: cursor at end of the rope.\n            if range.head == range.anchor && range.head == text.len_chars() {\n                if !selection_is_primary || (cursor_is_block && is_terminal_focused) {\n                    // Bar and underline cursors are drawn by the terminal\n                    // BUG: If the editor area loses focus while having a bar or\n                    // underline cursor (eg. when a regex prompt has focus) then\n                    // the primary cursor will be invisible. This doesn't happen\n                    // with block cursors since we manually draw *all* cursors.\n                    spans.push((cursor_scope, range.head..range.head + 1));\n                }\n                continue;\n            }\n\n            let range = range.min_width_1(text);\n            if range.head > range.anchor {\n                // Standard case.\n                let cursor_start = prev_grapheme_boundary(text, range.head);\n                // non block cursors look like they exclude the cursor\n                let selection_end =\n                    if selection_is_primary && !cursor_is_block && mode != Mode::Insert {\n                        range.head\n                    } else {\n                        cursor_start\n                    };\n                spans.push((selection_scope, range.anchor..selection_end));\n                // add block cursors\n                // skip primary cursor if terminal is unfocused - terminal cursor is used in that case\n                if !selection_is_primary || (cursor_is_block && is_terminal_focused) {\n                    spans.push((cursor_scope, cursor_start..range.head));\n                }\n            } else {\n                // Reverse case.\n                let cursor_end = next_grapheme_boundary(text, range.head);\n                // add block cursors\n                // skip primary cursor if terminal is unfocused - terminal cursor is used in that case\n                if !selection_is_primary || (cursor_is_block && is_terminal_focused) {\n                    spans.push((cursor_scope, range.head..cursor_end));\n                }\n                // non block cursors look like they exclude the cursor\n                let selection_start = if selection_is_primary\n                    && !cursor_is_block\n                    && !(mode == Mode::Insert && cursor_end == range.anchor)\n                {\n                    range.head\n                } else {\n                    cursor_end\n                };\n                spans.push((selection_scope, selection_start..range.anchor));\n            }\n        }\n\n        OverlayHighlights::Heterogenous { highlights: spans }\n    }\n\n    /// Render brace match, etc (meant for the focused view only)\n    pub fn highlight_focused_view_elements(\n        view: &View,\n        doc: &Document,\n        theme: &Theme,\n    ) -> Option<OverlayHighlights> {\n        // Highlight matching braces\n        let syntax = doc.syntax()?;\n        let highlight = theme.find_highlight_exact(\"ui.cursor.match\")?;\n        let text = doc.text().slice(..);\n        let pos = doc.selection(view.id).primary().cursor(text);\n        let pos = helix_core::match_brackets::find_matching_bracket(syntax, text, pos)?;\n        Some(OverlayHighlights::single(highlight, pos..pos + 1))\n    }\n\n    pub fn tabstop_highlights(doc: &Document, theme: &Theme) -> Option<OverlayHighlights> {\n        let snippet = doc.active_snippet.as_ref()?;\n        let highlight = theme.find_highlight_exact(\"tabstop\")?;\n        let mut ranges = Vec::new();\n        for tabstop in snippet.tabstops() {\n            ranges.extend(tabstop.ranges.iter().map(|range| range.start..range.end));\n        }\n        Some(OverlayHighlights::Homogeneous { highlight, ranges })\n    }\n\n    /// Render bufferline at the top\n    pub fn render_bufferline(editor: &Editor, viewport: Rect, surface: &mut Surface) {\n        let scratch = PathBuf::from(SCRATCH_BUFFER_NAME); // default filename to use for scratch buffer\n        surface.clear_with(\n            viewport,\n            editor\n                .theme\n                .try_get(\"ui.bufferline.background\")\n                .unwrap_or_else(|| editor.theme.get(\"ui.statusline\")),\n        );\n\n        let bufferline_active = editor\n            .theme\n            .try_get(\"ui.bufferline.active\")\n            .unwrap_or_else(|| editor.theme.get(\"ui.statusline.active\"));\n\n        let bufferline_inactive = editor\n            .theme\n            .try_get(\"ui.bufferline\")\n            .unwrap_or_else(|| editor.theme.get(\"ui.statusline.inactive\"));\n\n        let mut x = viewport.x;\n        let current_doc = view!(editor).doc;\n\n        for doc in editor.documents() {\n            let fname = doc\n                .path()\n                .unwrap_or(&scratch)\n                .file_name()\n                .unwrap_or_default()\n                .to_str()\n                .unwrap_or_default();\n\n            let style = if current_doc == doc.id() {\n                bufferline_active\n            } else {\n                bufferline_inactive\n            };\n\n            let text = format!(\" {}{} \", fname, if doc.is_modified() { \"[+]\" } else { \"\" });\n            let used_width = viewport.x.saturating_sub(x);\n            let rem_width = surface.area.width.saturating_sub(used_width);\n\n            x = surface\n                .set_stringn(x, viewport.y, text, rem_width as usize, style)\n                .0;\n\n            if x >= surface.area.right() {\n                break;\n            }\n        }\n    }\n\n    pub fn render_gutter<'d>(\n        editor: &'d Editor,\n        doc: &'d Document,\n        view: &View,\n        viewport: Rect,\n        theme: &Theme,\n        is_focused: bool,\n        decoration_manager: &mut DecorationManager<'d>,\n    ) {\n        let text = doc.text().slice(..);\n        let cursors: Rc<[_]> = doc\n            .selection(view.id)\n            .iter()\n            .map(|range| range.cursor_line(text))\n            .collect();\n\n        let mut offset = 0;\n\n        let gutter_style = theme.get(\"ui.gutter\");\n        let gutter_selected_style = theme.get(\"ui.gutter.selected\");\n        let gutter_style_virtual = theme.get(\"ui.gutter.virtual\");\n        let gutter_selected_style_virtual = theme.get(\"ui.gutter.selected.virtual\");\n\n        for gutter_type in view.gutters() {\n            let mut gutter = gutter_type.style(editor, doc, view, theme, is_focused);\n            let width = gutter_type.width(view, doc);\n            // avoid lots of small allocations by reusing a text buffer for each line\n            let mut text = String::with_capacity(width);\n            let cursors = cursors.clone();\n            let gutter_decoration = move |renderer: &mut TextRenderer, pos: LinePos| {\n                // TODO handle softwrap in gutters\n                let selected = cursors.contains(&pos.doc_line);\n                let x = viewport.x + offset;\n                let y = pos.visual_line;\n\n                let gutter_style = match (selected, pos.first_visual_line) {\n                    (false, true) => gutter_style,\n                    (true, true) => gutter_selected_style,\n                    (false, false) => gutter_style_virtual,\n                    (true, false) => gutter_selected_style_virtual,\n                };\n\n                if let Some(style) =\n                    gutter(pos.doc_line, selected, pos.first_visual_line, &mut text)\n                {\n                    renderer.set_stringn(x, y, &text, width, gutter_style.patch(style));\n                } else {\n                    renderer.set_style(\n                        Rect {\n                            x,\n                            y,\n                            width: width as u16,\n                            height: 1,\n                        },\n                        gutter_style,\n                    );\n                }\n                text.clear();\n            };\n            decoration_manager.add_decoration(gutter_decoration);\n\n            offset += width as u16;\n        }\n    }\n\n    pub fn render_diagnostics(\n        doc: &Document,\n        view: &View,\n        viewport: Rect,\n        surface: &mut Surface,\n        theme: &Theme,\n    ) {\n        use helix_core::diagnostic::Severity;\n        use tui::{\n            layout::Alignment,\n            text::Text,\n            widgets::{Paragraph, Widget, Wrap},\n        };\n\n        let cursor = doc\n            .selection(view.id)\n            .primary()\n            .cursor(doc.text().slice(..));\n\n        let diagnostics = doc.diagnostics().iter().filter(|diagnostic| {\n            diagnostic.range.start <= cursor && diagnostic.range.end >= cursor\n        });\n\n        let warning = theme.get(\"warning\");\n        let error = theme.get(\"error\");\n        let info = theme.get(\"info\");\n        let hint = theme.get(\"hint\");\n\n        let mut lines = Vec::new();\n        let background_style = theme.get(\"ui.background\");\n        for diagnostic in diagnostics {\n            let style = Style::reset()\n                .patch(background_style)\n                .patch(match diagnostic.severity {\n                    Some(Severity::Error) => error,\n                    Some(Severity::Warning) | None => warning,\n                    Some(Severity::Info) => info,\n                    Some(Severity::Hint) => hint,\n                });\n            let text = Text::styled(&diagnostic.message, style);\n            lines.extend(text.lines);\n            let code = diagnostic.code.as_ref().map(|x| match x {\n                NumberOrString::Number(n) => format!(\"({n})\"),\n                NumberOrString::String(s) => format!(\"({s})\"),\n            });\n            if let Some(code) = code {\n                let span = Span::styled(code, style);\n                lines.push(span.into());\n            }\n        }\n\n        let text = Text::from(lines);\n        let paragraph = Paragraph::new(&text)\n            .alignment(Alignment::Right)\n            .wrap(Wrap { trim: true });\n        let width = 100.min(viewport.width);\n        let height = 15.min(viewport.height);\n        paragraph.render(\n            Rect::new(viewport.right() - width, viewport.y + 1, width, height),\n            surface,\n        );\n    }\n\n    /// Apply the highlighting on the lines where a cursor is active\n    pub fn cursorline(doc: &Document, view: &View, theme: &Theme) -> impl Decoration {\n        let text = doc.text().slice(..);\n        // TODO only highlight the visual line that contains the cursor instead of the full visual line\n        let primary_line = doc.selection(view.id).primary().cursor_line(text);\n\n        // The secondary_lines do contain the primary_line, it doesn't matter\n        // as the else-if clause in the loop later won't test for the\n        // secondary_lines if primary_line == line.\n        // It's used inside a loop so the collect isn't needless:\n        // https://github.com/rust-lang/rust-clippy/issues/6164\n        #[allow(clippy::needless_collect)]\n        let secondary_lines: Vec<_> = doc\n            .selection(view.id)\n            .iter()\n            .map(|range| range.cursor_line(text))\n            .collect();\n\n        let primary_style = theme.get(\"ui.cursorline.primary\");\n        let secondary_style = theme.get(\"ui.cursorline.secondary\");\n        let viewport = view.area;\n\n        move |renderer: &mut TextRenderer, pos: LinePos| {\n            let area = Rect::new(viewport.x, pos.visual_line, viewport.width, 1);\n            if primary_line == pos.doc_line {\n                renderer.set_style(area, primary_style);\n            } else if secondary_lines.binary_search(&pos.doc_line).is_ok() {\n                renderer.set_style(area, secondary_style);\n            }\n        }\n    }\n\n    /// Apply the highlighting on the columns where a cursor is active\n    pub fn highlight_cursorcolumn(\n        doc: &Document,\n        view: &View,\n        surface: &mut Surface,\n        theme: &Theme,\n        viewport: Rect,\n        text_annotations: &TextAnnotations,\n    ) {\n        let text = doc.text().slice(..);\n\n        // Manual fallback behaviour:\n        // ui.cursorcolumn.{p/s} -> ui.cursorcolumn -> ui.cursorline.{p/s}\n        let primary_style = theme\n            .try_get_exact(\"ui.cursorcolumn.primary\")\n            .or_else(|| theme.try_get_exact(\"ui.cursorcolumn\"))\n            .unwrap_or_else(|| theme.get(\"ui.cursorline.primary\"));\n        let secondary_style = theme\n            .try_get_exact(\"ui.cursorcolumn.secondary\")\n            .or_else(|| theme.try_get_exact(\"ui.cursorcolumn\"))\n            .unwrap_or_else(|| theme.get(\"ui.cursorline.secondary\"));\n\n        let inner_area = view.inner_area(doc);\n\n        let selection = doc.selection(view.id);\n        let view_offset = doc.view_offset(view.id);\n        let primary = selection.primary();\n        let text_format = doc.text_format(viewport.width, None);\n        for range in selection.iter() {\n            let is_primary = primary == *range;\n            let cursor = range.cursor(text);\n\n            let Position { col, .. } =\n                visual_offset_from_block(text, cursor, cursor, &text_format, text_annotations).0;\n\n            // if the cursor is horizontally in the view\n            if col >= view_offset.horizontal_offset\n                && inner_area.width > (col - view_offset.horizontal_offset) as u16\n            {\n                let area = Rect::new(\n                    inner_area.x + (col - view_offset.horizontal_offset) as u16,\n                    view.area.y,\n                    1,\n                    view.area.height,\n                );\n                if is_primary {\n                    surface.set_style(area, primary_style)\n                } else {\n                    surface.set_style(area, secondary_style)\n                }\n            }\n        }\n    }\n\n    /// Handle events by looking them up in `self.keymaps`. Returns None\n    /// if event was handled (a command was executed or a subkeymap was\n    /// activated). Only KeymapResult::{NotFound, Cancelled} is returned\n    /// otherwise.\n    fn handle_keymap_event(\n        &mut self,\n        mode: Mode,\n        cxt: &mut commands::Context,\n        event: KeyEvent,\n    ) -> Option<KeymapResult> {\n        let mut last_mode = mode;\n        self.pseudo_pending.extend(self.keymaps.pending());\n        let key_result = self.keymaps.get(mode, event);\n        cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox());\n\n        let mut execute_command = |command: &commands::MappableCommand| {\n            command.execute(cxt);\n            helix_event::dispatch(PostCommand { command, cx: cxt });\n\n            let current_mode = cxt.editor.mode();\n            if current_mode != last_mode {\n                helix_event::dispatch(OnModeSwitch {\n                    old_mode: last_mode,\n                    new_mode: current_mode,\n                    cx: cxt,\n                });\n\n                // HAXX: if we just entered insert mode from normal, clear key buf\n                // and record the command that got us into this mode.\n                if current_mode == Mode::Insert {\n                    // how we entered insert mode is important, and we should track that so\n                    // we can repeat the side effect.\n                    self.last_insert.0 = command.clone();\n                    self.last_insert.1.clear();\n                }\n            }\n\n            last_mode = current_mode;\n        };\n\n        match &key_result {\n            KeymapResult::Matched(command) => {\n                execute_command(command);\n            }\n            KeymapResult::Pending(node) => cxt.editor.autoinfo = Some(node.infobox()),\n            KeymapResult::MatchedSequence(commands) => {\n                for command in commands {\n                    execute_command(command);\n                }\n            }\n            KeymapResult::NotFound | KeymapResult::Cancelled(_) => return Some(key_result),\n        }\n        None\n    }\n\n    fn insert_mode(&mut self, cx: &mut commands::Context, event: KeyEvent) {\n        if let Some(keyresult) = self.handle_keymap_event(Mode::Insert, cx, event) {\n            match keyresult {\n                KeymapResult::NotFound => {\n                    if !self.on_next_key(OnKeyCallbackKind::Fallback, cx, event) {\n                        if let Some(ch) = event.char() {\n                            commands::insert::insert_char(cx, ch)\n                        }\n                    }\n                }\n                KeymapResult::Cancelled(pending) => {\n                    for ev in pending {\n                        match ev.char() {\n                            Some(ch) => commands::insert::insert_char(cx, ch),\n                            None => {\n                                if let KeymapResult::Matched(command) =\n                                    self.keymaps.get(Mode::Insert, ev)\n                                {\n                                    command.execute(cx);\n                                }\n                            }\n                        }\n                    }\n                }\n                _ => unreachable!(),\n            }\n        }\n    }\n\n    fn command_mode(&mut self, mode: Mode, cxt: &mut commands::Context, event: KeyEvent) {\n        match (event, cxt.editor.count) {\n            // If the count is already started and the input is a number, always continue the count.\n            (key!(i @ '0'..='9'), Some(count)) => {\n                let i = i.to_digit(10).unwrap() as usize;\n                let count = count.get() * 10 + i;\n                if count > 100_000_000 {\n                    return;\n                }\n                cxt.editor.count = NonZeroUsize::new(count);\n            }\n            // A non-zero digit will start the count if that number isn't used by a keymap.\n            (key!(i @ '1'..='9'), None) if !self.keymaps.contains_key(mode, event) => {\n                let i = i.to_digit(10).unwrap() as usize;\n                cxt.editor.count = NonZeroUsize::new(i);\n            }\n            // special handling for repeat operator\n            (key!('.'), _) if self.keymaps.pending().is_empty() => {\n                for _ in 0..cxt.editor.count.map_or(1, NonZeroUsize::into) {\n                    // first execute whatever put us into insert mode\n                    self.last_insert.0.execute(cxt);\n                    let mut last_savepoint = None;\n                    let mut last_request_savepoint = None;\n                    // then replay the inputs\n                    for key in self.last_insert.1.clone() {\n                        match key {\n                            InsertEvent::Key(key) => self.insert_mode(cxt, key),\n                            InsertEvent::CompletionApply {\n                                trigger_offset,\n                                changes,\n                            } => {\n                                let (view, doc) = current!(cxt.editor);\n\n                                if let Some(last_savepoint) = last_savepoint.as_deref() {\n                                    doc.restore(view, last_savepoint, true);\n                                }\n\n                                let text = doc.text().slice(..);\n                                let cursor = doc.selection(view.id).primary().cursor(text);\n\n                                let shift_position = |pos: usize| -> usize {\n                                    (pos + cursor).saturating_sub(trigger_offset)\n                                };\n\n                                let tx = Transaction::change(\n                                    doc.text(),\n                                    changes.iter().cloned().map(|(start, end, t)| {\n                                        (shift_position(start), shift_position(end), t)\n                                    }),\n                                );\n                                doc.apply(&tx, view.id);\n                            }\n                            InsertEvent::TriggerCompletion => {\n                                last_savepoint = take(&mut last_request_savepoint);\n                            }\n                            InsertEvent::RequestCompletion => {\n                                let (view, doc) = current!(cxt.editor);\n                                last_request_savepoint = Some(doc.savepoint(view));\n                            }\n                        }\n                    }\n                }\n                cxt.editor.count = None;\n            }\n            _ => {\n                // set the count\n                cxt.count = cxt.editor.count;\n                // TODO: edge case: 0j -> reset to 1\n                // if this fails, count was Some(0)\n                // debug_assert!(cxt.count != 0);\n\n                // set the register\n                cxt.register = cxt.editor.selected_register.take();\n\n                let res = self.handle_keymap_event(mode, cxt, event);\n                if matches!(&res, Some(KeymapResult::NotFound)) {\n                    self.on_next_key(OnKeyCallbackKind::Fallback, cxt, event);\n                }\n                if self.keymaps.pending().is_empty() {\n                    cxt.editor.count = None\n                } else {\n                    cxt.editor.selected_register = cxt.register.take();\n                }\n            }\n        }\n    }\n\n    #[allow(clippy::too_many_arguments)]\n    pub fn set_completion(\n        &mut self,\n        editor: &mut Editor,\n        items: Vec<CompletionItem>,\n        trigger_offset: usize,\n        size: Rect,\n    ) -> Option<Rect> {\n        let mut completion = Completion::new(editor, items, trigger_offset);\n\n        if completion.is_empty() {\n            // skip if we got no completion results\n            return None;\n        }\n\n        let area = completion.area(size, editor);\n        editor.last_completion = Some(CompleteAction::Triggered);\n        self.last_insert.1.push(InsertEvent::TriggerCompletion);\n\n        // TODO : propagate required size on resize to completion too\n        self.completion = Some(completion);\n        Some(area)\n    }\n\n    pub fn clear_completion(&mut self, editor: &mut Editor) -> Option<OnKeyCallback> {\n        self.completion = None;\n        let mut on_next_key: Option<OnKeyCallback> = None;\n        editor.handlers.completions.request_controller.restart();\n        editor.handlers.completions.active_completions.clear();\n        if let Some(last_completion) = editor.last_completion.take() {\n            match last_completion {\n                CompleteAction::Triggered => (),\n                CompleteAction::Applied {\n                    trigger_offset,\n                    changes,\n                    placeholder,\n                } => {\n                    self.last_insert.1.push(InsertEvent::CompletionApply {\n                        trigger_offset,\n                        changes,\n                    });\n                    on_next_key = placeholder.then_some(Box::new(|cx, key| {\n                        if let Some(c) = key.char() {\n                            let (view, doc) = current!(cx.editor);\n                            if let Some(snippet) = &doc.active_snippet {\n                                doc.apply(&snippet.delete_placeholder(doc.text()), view.id);\n                            }\n                            commands::insert::insert_char(cx, c);\n                        }\n                    }))\n                }\n                CompleteAction::Selected { savepoint } => {\n                    let (view, doc) = current!(editor);\n                    doc.restore(view, &savepoint, false);\n                }\n            }\n        }\n        on_next_key\n    }\n\n    pub fn handle_idle_timeout(&mut self, cx: &mut commands::Context) -> EventResult {\n        commands::compute_inlay_hints_for_all_views(cx.editor, cx.jobs);\n\n        EventResult::Ignored(None)\n    }\n}\n\nimpl EditorView {\n    /// must be called whenever the editor processed input that\n    /// is not a `KeyEvent`. In these cases any pending keys/on next\n    /// key callbacks must be canceled.\n    fn handle_non_key_input(&mut self, cxt: &mut commands::Context) {\n        cxt.editor.status_msg = None;\n        cxt.editor.reset_idle_timer();\n        // HACKS: create a fake key event that will never trigger any actual map\n        // and therefore simply acts as \"dismiss\"\n        let null_key_event = KeyEvent {\n            code: KeyCode::Null,\n            modifiers: KeyModifiers::empty(),\n        };\n        // dismiss any pending keys\n        if let Some((on_next_key, _)) = self.on_next_key.take() {\n            on_next_key(cxt, null_key_event);\n        }\n        self.handle_keymap_event(cxt.editor.mode, cxt, null_key_event);\n        self.pseudo_pending.clear();\n    }\n\n    fn handle_mouse_event(\n        &mut self,\n        event: &MouseEvent,\n        cxt: &mut commands::Context,\n    ) -> EventResult {\n        if event.kind != MouseEventKind::Moved {\n            self.handle_non_key_input(cxt)\n        }\n\n        let config = cxt.editor.config();\n        let MouseEvent {\n            kind,\n            row,\n            column,\n            modifiers,\n            ..\n        } = *event;\n\n        let pos_and_view = |editor: &Editor, row, column, ignore_virtual_text| {\n            editor.tree.views().find_map(|(view, _focus)| {\n                view.pos_at_screen_coords(\n                    &editor.documents[&view.doc],\n                    row,\n                    column,\n                    ignore_virtual_text,\n                )\n                .map(|pos| (pos, view.id))\n            })\n        };\n\n        let gutter_coords_and_view = |editor: &Editor, row, column| {\n            editor.tree.views().find_map(|(view, _focus)| {\n                view.gutter_coords_at_screen_coords(row, column)\n                    .map(|coords| (coords, view.id))\n            })\n        };\n\n        match kind {\n            MouseEventKind::Down(MouseButton::Left) => {\n                let editor = &mut cxt.editor;\n\n                if let Some((pos, view_id)) = pos_and_view(editor, row, column, true) {\n                    editor.focus(view_id);\n\n                    let prev_view_id = view!(editor).id;\n                    let doc = doc_mut!(editor, &view!(editor, view_id).doc);\n\n                    if modifiers == KeyModifiers::ALT {\n                        let selection = doc.selection(view_id).clone();\n                        doc.set_selection(view_id, selection.push(Range::point(pos)));\n                    } else if editor.mode == Mode::Select {\n                        // Discards non-primary selections for consistent UX with normal mode\n                        let primary = doc.selection(view_id).primary().put_cursor(\n                            doc.text().slice(..),\n                            pos,\n                            true,\n                        );\n                        editor.mouse_down_range = Some(primary);\n                        doc.set_selection(view_id, Selection::single(primary.anchor, primary.head));\n                    } else {\n                        doc.set_selection(view_id, Selection::point(pos));\n                    }\n\n                    if view_id != prev_view_id {\n                        self.clear_completion(editor);\n                    }\n\n                    editor.ensure_cursor_in_view(view_id);\n\n                    return EventResult::Consumed(None);\n                }\n\n                if let Some((coords, view_id)) = gutter_coords_and_view(editor, row, column) {\n                    editor.focus(view_id);\n\n                    let (view, doc) = current!(cxt.editor);\n\n                    let path = match doc.path() {\n                        Some(path) => path.clone(),\n                        None => return EventResult::Ignored(None),\n                    };\n\n                    if let Some(char_idx) =\n                        view.pos_at_visual_coords(doc, coords.row as u16, coords.col as u16, true)\n                    {\n                        let line = doc.text().char_to_line(char_idx);\n                        commands::dap_toggle_breakpoint_impl(cxt, path, line);\n                        return EventResult::Consumed(None);\n                    }\n                }\n\n                EventResult::Ignored(None)\n            }\n\n            MouseEventKind::Drag(MouseButton::Left) => {\n                let (view, doc) = current!(cxt.editor);\n\n                let pos = match view.pos_at_screen_coords(doc, row, column, true) {\n                    Some(pos) => pos,\n                    None => return EventResult::Ignored(None),\n                };\n\n                let mut selection = doc.selection(view.id).clone();\n                let primary = selection.primary_mut();\n                *primary = primary.put_cursor(doc.text().slice(..), pos, true);\n                doc.set_selection(view.id, selection);\n                let view_id = view.id;\n                cxt.editor.ensure_cursor_in_view(view_id);\n                EventResult::Consumed(None)\n            }\n\n            MouseEventKind::ScrollUp | MouseEventKind::ScrollDown => {\n                let current_view = cxt.editor.tree.focus;\n\n                let direction = match event.kind {\n                    MouseEventKind::ScrollUp => Direction::Backward,\n                    MouseEventKind::ScrollDown => Direction::Forward,\n                    _ => unreachable!(),\n                };\n\n                match pos_and_view(cxt.editor, row, column, false) {\n                    Some((_, view_id)) => cxt.editor.tree.focus = view_id,\n                    None => return EventResult::Ignored(None),\n                }\n\n                let offset = config.scroll_lines.unsigned_abs();\n                commands::scroll(cxt, offset, direction, false);\n\n                cxt.editor.tree.focus = current_view;\n                cxt.editor.ensure_cursor_in_view(current_view);\n\n                EventResult::Consumed(None)\n            }\n\n            MouseEventKind::Up(MouseButton::Left) => {\n                if !config.middle_click_paste {\n                    return EventResult::Ignored(None);\n                }\n\n                let (view, doc) = current!(cxt.editor);\n\n                let should_yank = match cxt.editor.mouse_down_range.take() {\n                    Some(down_range) => doc.selection(view.id).primary() != down_range,\n                    None => {\n                        // This should not happen under normal cases. We fall back to the original\n                        // behavior of yanking on non-single-char selections.\n                        doc.selection(view.id)\n                            .primary()\n                            .slice(doc.text().slice(..))\n                            .len_chars()\n                            > 1\n                    }\n                };\n\n                if should_yank {\n                    commands::yank_main_selection_to_register(\n                        cxt.editor,\n                        config.mouse_yank_register,\n                    );\n                    EventResult::Consumed(None)\n                } else {\n                    EventResult::Ignored(None)\n                }\n            }\n\n            MouseEventKind::Up(MouseButton::Right) => {\n                if let Some((pos, view_id)) = gutter_coords_and_view(cxt.editor, row, column) {\n                    cxt.editor.focus(view_id);\n\n                    if let Some((pos, _)) = pos_and_view(cxt.editor, row, column, true) {\n                        doc_mut!(cxt.editor).set_selection(view_id, Selection::point(pos));\n                    } else {\n                        let (view, doc) = current!(cxt.editor);\n\n                        if let Some(pos) = view.pos_at_visual_coords(doc, pos.row as u16, 0, true) {\n                            doc.set_selection(view_id, Selection::point(pos));\n                            match modifiers {\n                                KeyModifiers::ALT => {\n                                    commands::MappableCommand::dap_edit_log.execute(cxt)\n                                }\n                                _ => commands::MappableCommand::dap_edit_condition.execute(cxt),\n                            };\n                        }\n                    }\n\n                    cxt.editor.ensure_cursor_in_view(view_id);\n                    return EventResult::Consumed(None);\n                }\n                EventResult::Ignored(None)\n            }\n\n            MouseEventKind::Up(MouseButton::Middle) => {\n                let editor = &mut cxt.editor;\n                if !config.middle_click_paste {\n                    return EventResult::Ignored(None);\n                }\n\n                if modifiers == KeyModifiers::ALT {\n                    commands::replace_selections_with_register(\n                        cxt.editor,\n                        config.mouse_yank_register,\n                        cxt.count(),\n                    );\n\n                    return EventResult::Consumed(None);\n                }\n\n                if let Some((pos, view_id)) = pos_and_view(editor, row, column, true) {\n                    let doc = doc_mut!(editor, &view!(editor, view_id).doc);\n                    doc.set_selection(view_id, Selection::point(pos));\n                    cxt.editor.focus(view_id);\n\n                    commands::paste(\n                        cxt.editor,\n                        config.mouse_yank_register,\n                        commands::Paste::Before,\n                        cxt.count(),\n                    );\n\n                    return EventResult::Consumed(None);\n                }\n\n                EventResult::Ignored(None)\n            }\n\n            _ => EventResult::Ignored(None),\n        }\n    }\n    fn on_next_key(\n        &mut self,\n        kind: OnKeyCallbackKind,\n        ctx: &mut commands::Context,\n        event: KeyEvent,\n    ) -> bool {\n        if let Some((on_next_key, kind_)) = self.on_next_key.take() {\n            if kind == kind_ {\n                on_next_key(ctx, event);\n                true\n            } else {\n                self.on_next_key = Some((on_next_key, kind_));\n                false\n            }\n        } else {\n            false\n        }\n    }\n}\n\nimpl Component for EditorView {\n    fn handle_event(\n        &mut self,\n        event: &Event,\n        context: &mut crate::compositor::Context,\n    ) -> EventResult {\n        let mut cx = commands::Context {\n            editor: context.editor,\n            count: None,\n            register: None,\n            callback: Vec::new(),\n            on_next_key_callback: None,\n            jobs: context.jobs,\n        };\n\n        match event {\n            Event::Paste(contents) => {\n                self.handle_non_key_input(&mut cx);\n                cx.count = cx.editor.count;\n                commands::paste_bracketed_value(&mut cx, contents.clone());\n                cx.editor.count = None;\n\n                let config = cx.editor.config();\n                let mode = cx.editor.mode();\n                let (view, doc) = current!(cx.editor);\n                view.ensure_cursor_in_view(doc, config.scrolloff);\n\n                // Store a history state if not in insert mode. Otherwise wait till we exit insert\n                // to include any edits to the paste in the history state.\n                if mode != Mode::Insert {\n                    doc.append_changes_to_history(view);\n                }\n\n                EventResult::Consumed(None)\n            }\n            Event::Resize(_width, _height) => {\n                // Ignore this event, we handle resizing just before rendering to screen.\n                // Handling it here but not re-rendering will cause flashing\n                EventResult::Consumed(None)\n            }\n            Event::Key(mut key) => {\n                cx.editor.reset_idle_timer();\n                canonicalize_key(&mut key);\n\n                // clear status\n                cx.editor.status_msg = None;\n\n                let mode = cx.editor.mode();\n\n                if !self.on_next_key(OnKeyCallbackKind::PseudoPending, &mut cx, key) {\n                    match mode {\n                        Mode::Insert => {\n                            // let completion swallow the event if necessary\n                            let mut consumed = false;\n                            if let Some(completion) = &mut self.completion {\n                                let res = {\n                                    // use a fake context here\n                                    let mut cx = Context {\n                                        editor: cx.editor,\n                                        jobs: cx.jobs,\n                                        scroll: None,\n                                    };\n\n                                    if let EventResult::Consumed(callback) =\n                                        completion.handle_event(event, &mut cx)\n                                    {\n                                        consumed = true;\n                                        Some(callback)\n                                    } else if let EventResult::Consumed(callback) =\n                                        completion.handle_event(&Event::Key(key!(Enter)), &mut cx)\n                                    {\n                                        Some(callback)\n                                    } else {\n                                        None\n                                    }\n                                };\n\n                                if let Some(callback) = res {\n                                    if callback.is_some() {\n                                        // assume close_fn\n                                        if let Some(cb) = self.clear_completion(cx.editor) {\n                                            if consumed {\n                                                cx.on_next_key_callback =\n                                                    Some((cb, OnKeyCallbackKind::Fallback))\n                                            } else {\n                                                self.on_next_key =\n                                                    Some((cb, OnKeyCallbackKind::Fallback));\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n\n                            // if completion didn't take the event, we pass it onto commands\n                            if !consumed {\n                                self.insert_mode(&mut cx, key);\n\n                                // record last_insert key\n                                self.last_insert.1.push(InsertEvent::Key(key));\n                            }\n                        }\n                        mode => self.command_mode(mode, &mut cx, key),\n                    }\n                }\n\n                self.on_next_key = cx.on_next_key_callback.take();\n                match self.on_next_key {\n                    Some((_, OnKeyCallbackKind::PseudoPending)) => self.pseudo_pending.push(key),\n                    _ => self.pseudo_pending.clear(),\n                }\n\n                // appease borrowck\n                let callbacks = take(&mut cx.callback);\n\n                // if the command consumed the last view, skip the render.\n                // on the next loop cycle the Application will then terminate.\n                if cx.editor.should_close() {\n                    return EventResult::Ignored(None);\n                }\n\n                let config = cx.editor.config();\n                let mode = cx.editor.mode();\n                let (view, doc) = current!(cx.editor);\n\n                view.ensure_cursor_in_view(doc, config.scrolloff);\n\n                // Store a history state if not in insert mode. This also takes care of\n                // committing changes when leaving insert mode.\n                if mode != Mode::Insert {\n                    doc.append_changes_to_history(view);\n                }\n                let callback = if callbacks.is_empty() {\n                    None\n                } else {\n                    let callback: crate::compositor::Callback = Box::new(move |compositor, cx| {\n                        for callback in callbacks {\n                            callback(compositor, cx)\n                        }\n                    });\n                    Some(callback)\n                };\n\n                EventResult::Consumed(callback)\n            }\n\n            Event::Mouse(event) => self.handle_mouse_event(event, &mut cx),\n            Event::IdleTimeout => self.handle_idle_timeout(&mut cx),\n            Event::FocusGained => {\n                self.terminal_focused = true;\n                EventResult::Consumed(None)\n            }\n            Event::FocusLost => {\n                if context.editor.config().auto_save.focus_lost {\n                    let options = commands::WriteAllOptions {\n                        force: false,\n                        write_scratch: false,\n                        auto_format: false,\n                    };\n                    if let Err(e) = commands::typed::write_all_impl(context, options) {\n                        context.editor.set_error(format!(\"{}\", e));\n                    }\n                }\n                self.terminal_focused = false;\n                EventResult::Consumed(None)\n            }\n        }\n    }\n\n    fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        // clear with background color\n        surface.set_style(area, cx.editor.theme.get(\"ui.background\"));\n        let config = cx.editor.config();\n\n        // check if bufferline should be rendered\n        use helix_view::editor::BufferLine;\n        let use_bufferline = match config.bufferline {\n            BufferLine::Always => true,\n            BufferLine::Multiple if cx.editor.documents.len() > 1 => true,\n            _ => false,\n        };\n\n        // -1 for commandline and -1 for bufferline\n        let mut editor_area = area.clip_bottom(1);\n        if use_bufferline {\n            editor_area = editor_area.clip_top(1);\n        }\n\n        // if the terminal size suddenly changed, we need to trigger a resize\n        cx.editor.resize(editor_area);\n\n        if use_bufferline {\n            Self::render_bufferline(cx.editor, area.with_height(1), surface);\n        }\n\n        for (view, is_focused) in cx.editor.tree.views() {\n            let doc = cx.editor.document(view.doc).unwrap();\n            self.render_view(cx.editor, doc, view, area, surface, is_focused);\n        }\n\n        if config.auto_info {\n            if let Some(mut info) = cx.editor.autoinfo.take() {\n                info.render(area, surface, cx);\n                cx.editor.autoinfo = Some(info)\n            }\n        }\n\n        let key_width = 15u16; // for showing pending keys\n        let mut status_msg_width = 0;\n\n        // render status msg\n        if let Some((status_msg, severity)) = &cx.editor.status_msg {\n            status_msg_width = status_msg.width();\n            use helix_view::editor::Severity;\n            let style = if *severity == Severity::Error {\n                cx.editor.theme.get(\"error\")\n            } else {\n                cx.editor.theme.get(\"ui.text\")\n            };\n\n            surface.set_string(\n                area.x,\n                area.y + area.height.saturating_sub(1),\n                status_msg,\n                style,\n            );\n        }\n\n        if area.width.saturating_sub(status_msg_width as u16) > key_width {\n            let mut disp = String::new();\n            if let Some(count) = cx.editor.count {\n                disp.push_str(&count.to_string())\n            }\n            for key in self.keymaps.pending() {\n                disp.push_str(&key.key_sequence_format());\n            }\n            for key in &self.pseudo_pending {\n                disp.push_str(&key.key_sequence_format());\n            }\n            let style = cx.editor.theme.get(\"ui.text\");\n            let macro_width = if cx.editor.macro_recording.is_some() {\n                3\n            } else {\n                0\n            };\n            surface.set_string(\n                area.x + area.width.saturating_sub(key_width + macro_width),\n                area.y + area.height.saturating_sub(1),\n                disp.get(disp.len().saturating_sub(key_width as usize)..)\n                    .unwrap_or(&disp),\n                style,\n            );\n            if let Some((reg, _)) = cx.editor.macro_recording {\n                let disp = format!(\"[{}]\", reg);\n                let style = style\n                    .fg(helix_view::graphics::Color::Yellow)\n                    .add_modifier(Modifier::BOLD);\n                surface.set_string(\n                    area.x + area.width.saturating_sub(3),\n                    area.y + area.height.saturating_sub(1),\n                    &disp,\n                    style,\n                );\n            }\n        }\n\n        if let Some(completion) = self.completion.as_mut() {\n            completion.render(area, surface, cx);\n        }\n    }\n\n    fn cursor(&self, _area: Rect, editor: &Editor) -> (Option<Position>, CursorKind) {\n        match editor.cursor() {\n            // all block cursors are drawn manually\n            (pos, CursorKind::Block) => {\n                if self.terminal_focused {\n                    (pos, CursorKind::Hidden)\n                } else {\n                    // use terminal cursor when terminal loses focus\n                    (pos, CursorKind::Underline)\n                }\n            }\n            cursor => cursor,\n        }\n    }\n}\n\nfn canonicalize_key(key: &mut KeyEvent) {\n    if let KeyEvent {\n        code: KeyCode::Char(_),\n        modifiers: _,\n    } = key\n    {\n        key.modifiers.remove(KeyModifiers::SHIFT)\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/info.rs",
    "content": "use crate::compositor::{Component, Context};\nuse helix_view::graphics::{Margin, Rect};\nuse helix_view::info::Info;\nuse tui::buffer::Buffer as Surface;\nuse tui::text::Text;\nuse tui::widgets::{Block, Paragraph, Widget};\n\nimpl Component for Info {\n    fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {\n        let text_style = cx.editor.theme.get(\"ui.text.info\");\n        let popup_style = cx.editor.theme.get(\"ui.popup.info\");\n\n        // Calculate the area of the terminal to modify. Because we want to\n        // render at the bottom right, we use the viewport's width and height\n        // which evaluate to the most bottom right coordinate.\n        let width = self.width + 2 + 2; // +2 for border, +2 for margin\n        let height = self.height + 2; // +2 for border\n        let area = viewport.intersection(Rect::new(\n            viewport.width.saturating_sub(width),\n            viewport.height.saturating_sub(height + 2), // +2 for statusline\n            width,\n            height,\n        ));\n        surface.clear_with(area, popup_style);\n\n        let block = Block::bordered()\n            .title(self.title.as_ref())\n            .border_style(popup_style);\n\n        let margin = Margin::horizontal(1);\n        let inner = block.inner(area).inner(margin);\n        block.render(area, surface);\n\n        Paragraph::new(&Text::from(self.text.as_str()))\n            .style(text_style)\n            .render(inner, surface);\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/lsp/hover.rs",
    "content": "use std::sync::Arc;\n\nuse arc_swap::ArcSwap;\nuse helix_core::syntax;\nuse helix_lsp::lsp;\nuse helix_view::graphics::{Margin, Rect, Style};\nuse helix_view::input::Event;\nuse tui::buffer::Buffer;\nuse tui::widgets::{BorderType, Paragraph, Widget, Wrap};\n\nuse crate::compositor::{Component, Context, EventResult};\n\nuse crate::alt;\nuse crate::ui::Markdown;\n\npub struct Hover {\n    active_index: usize,\n    contents: Vec<(Option<Markdown>, Markdown)>,\n}\n\nimpl Hover {\n    pub const ID: &'static str = \"hover\";\n\n    pub fn new(\n        hovers: Vec<(String, lsp::Hover)>,\n        config_loader: Arc<ArcSwap<syntax::Loader>>,\n    ) -> Self {\n        let n_hovers = hovers.len();\n        let contents = hovers\n            .into_iter()\n            .enumerate()\n            .map(|(idx, (server_name, hover))| {\n                let header = (n_hovers > 1).then(|| {\n                    Markdown::new(\n                        format!(\"**[{}/{}] {}**\", idx + 1, n_hovers, server_name),\n                        config_loader.clone(),\n                    )\n                });\n                let body = Markdown::new(\n                    hover_contents_to_string(hover.contents),\n                    config_loader.clone(),\n                );\n                (header, body)\n            })\n            .collect();\n\n        Self {\n            active_index: usize::default(),\n            contents,\n        }\n    }\n\n    fn has_header(&self) -> bool {\n        self.contents.len() > 1\n    }\n\n    fn content(&self) -> &(Option<Markdown>, Markdown) {\n        &self.contents[self.active_index]\n    }\n\n    fn set_index(&mut self, index: usize) {\n        assert!((0..self.contents.len()).contains(&index));\n        self.active_index = index;\n    }\n}\n\nconst PADDING_HORIZONTAL: u16 = 2;\nconst PADDING_TOP: u16 = 1;\nconst PADDING_BOTTOM: u16 = 1;\nconst HEADER_HEIGHT: u16 = 1;\nconst SEPARATOR_HEIGHT: u16 = 1;\n\nimpl Component for Hover {\n    fn render(&mut self, area: Rect, surface: &mut Buffer, cx: &mut Context) {\n        let margin = Margin::all(1);\n        let area = area.inner(margin);\n\n        let (header, contents) = self.content();\n\n        // show header and border only when more than one results\n        if let Some(header) = header {\n            // header LSP Name\n            let header = header.parse(Some(&cx.editor.theme));\n            let header = Paragraph::new(&header);\n            header.render(area.with_height(HEADER_HEIGHT), surface);\n\n            // border\n            let sep_style = Style::default();\n            let borders = BorderType::line_symbols(BorderType::Plain);\n            for x in area.left()..area.right() {\n                if let Some(cell) = surface.get_mut(x, area.top() + HEADER_HEIGHT) {\n                    cell.set_symbol(borders.horizontal).set_style(sep_style);\n                }\n            }\n        }\n\n        // hover content\n        let contents = contents.parse(Some(&cx.editor.theme));\n        let contents_area = area.clip_top(if self.has_header() {\n            HEADER_HEIGHT + SEPARATOR_HEIGHT\n        } else {\n            0\n        });\n        let contents_para = Paragraph::new(&contents)\n            .wrap(Wrap { trim: false })\n            .scroll((cx.scroll.unwrap_or_default() as u16, 0));\n        contents_para.render(contents_area, surface);\n    }\n\n    fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {\n        let max_text_width = viewport.0.saturating_sub(PADDING_HORIZONTAL).clamp(10, 120);\n\n        let (header, contents) = self.content();\n\n        let header_width = header\n            .as_ref()\n            .map(|header| {\n                let header = header.parse(None);\n                let (width, _height) = crate::ui::text::required_size(&header, max_text_width);\n                width\n            })\n            .unwrap_or_default();\n\n        let contents = contents.parse(None);\n        let (content_width, content_height) =\n            crate::ui::text::required_size(&contents, max_text_width);\n\n        let width = PADDING_HORIZONTAL + header_width.max(content_width);\n        let height = if self.has_header() {\n            PADDING_TOP + HEADER_HEIGHT + SEPARATOR_HEIGHT + content_height + PADDING_BOTTOM\n        } else {\n            PADDING_TOP + content_height + PADDING_BOTTOM\n        };\n\n        Some((width, height))\n    }\n\n    fn handle_event(&mut self, event: &Event, _ctx: &mut Context) -> EventResult {\n        let Event::Key(event) = event else {\n            return EventResult::Ignored(None);\n        };\n\n        match event {\n            alt!('p') => {\n                let index = self\n                    .active_index\n                    .checked_sub(1)\n                    .unwrap_or(self.contents.len() - 1);\n                self.set_index(index);\n                EventResult::Consumed(None)\n            }\n            alt!('n') => {\n                self.set_index((self.active_index + 1) % self.contents.len());\n                EventResult::Consumed(None)\n            }\n            _ => EventResult::Ignored(None),\n        }\n    }\n}\n\nfn hover_contents_to_string(contents: lsp::HoverContents) -> String {\n    fn marked_string_to_markdown(contents: lsp::MarkedString) -> String {\n        match contents {\n            lsp::MarkedString::String(contents) => contents,\n            lsp::MarkedString::LanguageString(string) => {\n                if string.language == \"markdown\" {\n                    string.value\n                } else {\n                    format!(\"```{}\\n{}\\n```\", string.language, string.value)\n                }\n            }\n        }\n    }\n    match contents {\n        lsp::HoverContents::Scalar(contents) => marked_string_to_markdown(contents),\n        lsp::HoverContents::Array(contents) => contents\n            .into_iter()\n            .map(marked_string_to_markdown)\n            .collect::<Vec<_>>()\n            .join(\"\\n\\n\"),\n        lsp::HoverContents::Markup(contents) => contents.value,\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/lsp/signature_help.rs",
    "content": "use std::sync::Arc;\n\nuse arc_swap::ArcSwap;\nuse helix_core::syntax::{self, OverlayHighlights};\nuse helix_view::graphics::{Margin, Rect, Style};\nuse helix_view::input::Event;\nuse tui::buffer::Buffer;\nuse tui::layout::Alignment;\nuse tui::text::Text;\nuse tui::widgets::{BorderType, Paragraph, Widget, Wrap};\n\nuse crate::compositor::{Component, Compositor, Context, EventResult};\n\nuse crate::alt;\nuse crate::ui::Markdown;\n\nuse crate::ui::Popup;\n\npub struct Signature {\n    pub signature: String,\n    pub signature_doc: Option<String>,\n    /// Part of signature text\n    pub active_param_range: Option<(usize, usize)>,\n}\n\npub struct SignatureHelp {\n    language: String,\n    config_loader: Arc<ArcSwap<syntax::Loader>>,\n    active_signature: usize,\n    lsp_signature: Option<usize>,\n    signatures: Vec<Signature>,\n}\n\nimpl SignatureHelp {\n    pub const ID: &'static str = \"signature-help\";\n\n    pub fn new(\n        language: String,\n        config_loader: Arc<ArcSwap<syntax::Loader>>,\n        active_signature: usize,\n        lsp_signature: Option<usize>,\n        signatures: Vec<Signature>,\n    ) -> Self {\n        Self {\n            language,\n            config_loader,\n            active_signature,\n            lsp_signature,\n            signatures,\n        }\n    }\n\n    pub fn active_signature(&self) -> usize {\n        self.active_signature\n    }\n\n    pub fn lsp_signature(&self) -> Option<usize> {\n        self.lsp_signature\n    }\n\n    pub fn visible_popup(compositor: &mut Compositor) -> Option<&mut Popup<Self>> {\n        compositor.find_id::<Popup<Self>>(Self::ID)\n    }\n\n    fn signature_index(&self) -> String {\n        format!(\"({}/{})\", self.active_signature + 1, self.signatures.len())\n    }\n}\n\nimpl Component for SignatureHelp {\n    fn handle_event(&mut self, event: &Event, _cx: &mut Context) -> EventResult {\n        let Event::Key(event) = event else {\n            return EventResult::Ignored(None);\n        };\n\n        if self.signatures.len() <= 1 {\n            return EventResult::Ignored(None);\n        }\n\n        match event {\n            alt!('p') => {\n                self.active_signature = self\n                    .active_signature\n                    .checked_sub(1)\n                    .unwrap_or(self.signatures.len() - 1);\n                EventResult::Consumed(None)\n            }\n            alt!('n') => {\n                self.active_signature = (self.active_signature + 1) % self.signatures.len();\n                EventResult::Consumed(None)\n            }\n            _ => EventResult::Ignored(None),\n        }\n    }\n\n    fn render(&mut self, area: Rect, surface: &mut Buffer, cx: &mut Context) {\n        let margin = Margin::all(1);\n        let area = area.inner(margin);\n\n        let signature = self\n            .signatures\n            .get(self.active_signature)\n            .unwrap_or_else(|| &self.signatures[0]);\n\n        let active_param_span = signature.active_param_range.map(|(start, end)| {\n            let highlight = cx\n                .editor\n                .theme\n                .find_highlight_exact(\"ui.selection\")\n                .unwrap();\n            OverlayHighlights::single(highlight, start..end)\n        });\n\n        let signature = self\n            .signatures\n            .get(self.active_signature)\n            .unwrap_or_else(|| &self.signatures[0]);\n\n        let sig_text = crate::ui::markdown::highlighted_code_block(\n            signature.signature.as_str(),\n            &self.language,\n            Some(&cx.editor.theme),\n            &self.config_loader.load(),\n            active_param_span,\n        );\n\n        if self.signatures.len() > 1 {\n            let signature_index = self.signature_index();\n            let text = Text::from(signature_index);\n            let paragraph = Paragraph::new(&text).alignment(Alignment::Right);\n            paragraph.render(area.with_height(1).clip_right(1), surface);\n        }\n\n        let sig_text_para = Paragraph::new(&sig_text)\n            .wrap(Wrap { trim: false })\n            .scroll((cx.scroll.unwrap_or_default() as u16, 0));\n        let (_, sig_text_height) = sig_text_para.required_size(area.width);\n        let sig_text_area = area.with_height(sig_text_height.min(area.height));\n        let sig_text_area = sig_text_area.intersection(surface.area);\n        sig_text_para.render(sig_text_area, surface);\n\n        if signature.signature_doc.is_none() {\n            return;\n        }\n\n        let sep_style = Style::default();\n        let borders = BorderType::line_symbols(BorderType::Plain);\n        for x in sig_text_area.left()..sig_text_area.right() {\n            if let Some(cell) = surface.get_mut(x, sig_text_area.bottom()) {\n                cell.set_symbol(borders.horizontal).set_style(sep_style);\n            }\n        }\n\n        let sig_doc = match &signature.signature_doc {\n            None => return,\n            Some(doc) => Markdown::new(doc.clone(), Arc::clone(&self.config_loader)),\n        };\n        let sig_doc = sig_doc.parse(Some(&cx.editor.theme));\n        let sig_doc_area = area\n            .clip_top(sig_text_area.height + 2)\n            .clip_bottom(u16::from(cx.editor.popup_border()));\n        let sig_doc_para = Paragraph::new(&sig_doc)\n            .wrap(Wrap { trim: false })\n            .scroll((cx.scroll.unwrap_or_default() as u16, 0));\n        sig_doc_para.render(sig_doc_area, surface);\n    }\n\n    fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {\n        const PADDING: u16 = 2;\n        const SEPARATOR_HEIGHT: u16 = 1;\n\n        let signature = self\n            .signatures\n            .get(self.active_signature)\n            .unwrap_or_else(|| &self.signatures[0]);\n\n        let max_text_width = viewport.0.saturating_sub(PADDING).clamp(10, 120);\n\n        let signature_text = crate::ui::markdown::highlighted_code_block(\n            signature.signature.as_str(),\n            &self.language,\n            None,\n            &self.config_loader.load(),\n            None,\n        );\n        let sig_text_para = Paragraph::new(&signature_text).wrap(Wrap { trim: false });\n        let (sig_width, sig_height) = sig_text_para.required_size(max_text_width);\n\n        let (width, height) = match signature.signature_doc {\n            Some(ref doc) => {\n                let doc_md = Markdown::new(doc.clone(), Arc::clone(&self.config_loader));\n                let doc_text = doc_md.parse(None);\n                let (doc_width, doc_height) =\n                    crate::ui::text::required_size(&doc_text, max_text_width);\n                (\n                    sig_width.max(doc_width),\n                    sig_height + SEPARATOR_HEIGHT + doc_height,\n                )\n            }\n            None => (sig_width, sig_height),\n        };\n\n        let sig_index_width = if self.signatures.len() > 1 {\n            self.signature_index().len() + 1\n        } else {\n            0\n        };\n\n        Some((width + PADDING + sig_index_width as u16, height + PADDING))\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/lsp.rs",
    "content": "pub mod hover;\npub mod signature_help;\n"
  },
  {
    "path": "helix-term/src/ui/markdown.rs",
    "content": "use crate::compositor::{Component, Context};\nuse arc_swap::ArcSwap;\nuse tui::{\n    buffer::Buffer as Surface,\n    text::{Span, Spans, Text},\n};\n\nuse std::sync::Arc;\n\nuse pulldown_cmark::{CodeBlockKind, Event, HeadingLevel, Options, Parser, Tag, TagEnd};\n\nuse helix_core::{\n    syntax::{self, HighlightEvent, OverlayHighlights},\n    RopeSlice, Syntax,\n};\nuse helix_view::{\n    graphics::{Margin, Rect, Style},\n    theme::Modifier,\n    Theme,\n};\n\nfn styled_multiline_text<'a>(text: &str, style: Style) -> Text<'a> {\n    let spans: Vec<_> = text\n        .lines()\n        .map(|line| Span::styled(line.to_string(), style))\n        .map(Spans::from)\n        .collect();\n    Text::from(spans)\n}\n\npub fn highlighted_code_block<'a>(\n    text: &str,\n    language: &str,\n    theme: Option<&Theme>,\n    loader: &syntax::Loader,\n    // Optional overlay highlights to mix in with the syntax highlights.\n    //\n    // Note that `OverlayHighlights` is typically used with char indexing but the only caller\n    // which passes this parameter currently passes **byte indices** instead.\n    additional_highlight_spans: Option<OverlayHighlights>,\n) -> Text<'a> {\n    let mut spans = Vec::new();\n    let mut lines = Vec::new();\n\n    let get_theme = |key: &str| -> Style { theme.map(|t| t.get(key)).unwrap_or_default() };\n    let text_style = get_theme(Markdown::TEXT_STYLE);\n    let code_style = get_theme(Markdown::BLOCK_STYLE);\n\n    let theme = match theme {\n        Some(t) => t,\n        None => return styled_multiline_text(text, code_style),\n    };\n\n    let ropeslice = RopeSlice::from(text);\n    let Some(syntax) = loader\n        .language_for_match(RopeSlice::from(language))\n        .and_then(|lang| Syntax::new(ropeslice, lang, loader).ok())\n    else {\n        return styled_multiline_text(text, code_style);\n    };\n\n    let mut syntax_highlighter = syntax.highlighter(ropeslice, loader, ..);\n    let mut syntax_highlight_stack = Vec::new();\n    let mut overlay_highlight_stack = Vec::new();\n    let mut overlay_highlighter = syntax::OverlayHighlighter::new(additional_highlight_spans);\n    let mut pos = 0;\n\n    while pos < ropeslice.len_bytes() as u32 {\n        if pos == syntax_highlighter.next_event_offset() {\n            let (event, new_highlights) = syntax_highlighter.advance();\n            if event == HighlightEvent::Refresh {\n                syntax_highlight_stack.clear();\n            }\n            syntax_highlight_stack.extend(new_highlights);\n        } else if pos == overlay_highlighter.next_event_offset() as u32 {\n            let (event, new_highlights) = overlay_highlighter.advance();\n            if event == HighlightEvent::Refresh {\n                overlay_highlight_stack.clear();\n            }\n            overlay_highlight_stack.extend(new_highlights)\n        }\n\n        let start = pos;\n        pos = syntax_highlighter\n            .next_event_offset()\n            .min(overlay_highlighter.next_event_offset() as u32);\n        if pos == u32::MAX {\n            pos = ropeslice.len_bytes() as u32;\n        }\n        if pos == start {\n            continue;\n        }\n        // The highlighter should always move forward.\n        // If the highlighter malfunctions, bail on syntax highlighting and log an error.\n        debug_assert!(pos > start);\n        if pos < start {\n            log::error!(\"Failed to highlight '{language}': {text:?}\");\n            return styled_multiline_text(text, code_style);\n        }\n\n        let style = syntax_highlight_stack\n            .iter()\n            .chain(overlay_highlight_stack.iter())\n            .fold(text_style, |acc, highlight| {\n                acc.patch(theme.highlight(*highlight))\n            });\n\n        let mut slice = &text[start as usize..pos as usize];\n        // TODO: do we need to handle all unicode line endings\n        // here, or is just '\\n' okay?\n        while let Some(end) = slice.find('\\n') {\n            // emit span up to newline\n            let text = &slice[..end];\n            let text = text.replace('\\t', \"    \"); // replace tabs\n            let span = Span::styled(text, style);\n            spans.push(span);\n\n            // truncate slice to after newline\n            slice = &slice[end + 1..];\n\n            // make a new line\n            let spans = std::mem::take(&mut spans);\n            lines.push(Spans::from(spans));\n        }\n\n        if !slice.is_empty() {\n            let span = Span::styled(slice.replace('\\t', \"    \"), style);\n            spans.push(span);\n        }\n    }\n\n    if !spans.is_empty() {\n        let spans = std::mem::take(&mut spans);\n        lines.push(Spans::from(spans));\n    }\n\n    Text::from(lines)\n}\n\npub struct Markdown {\n    contents: String,\n\n    config_loader: Arc<ArcSwap<syntax::Loader>>,\n}\n\n// TODO: pre-render and self reference via Pin\n// better yet, just use Tendril + subtendril for references\n\nimpl Markdown {\n    const TEXT_STYLE: &'static str = \"ui.text\";\n    const BLOCK_STYLE: &'static str = \"markup.raw.inline\";\n    const RULE_STYLE: &'static str = \"punctuation.special\";\n    const UNNUMBERED_LIST_STYLE: &'static str = \"markup.list.unnumbered\";\n    const NUMBERED_LIST_STYLE: &'static str = \"markup.list.numbered\";\n    const HEADING_STYLES: [&'static str; 6] = [\n        \"markup.heading.1\",\n        \"markup.heading.2\",\n        \"markup.heading.3\",\n        \"markup.heading.4\",\n        \"markup.heading.5\",\n        \"markup.heading.6\",\n    ];\n    const INDENT: &'static str = \"  \";\n\n    pub fn new(contents: String, config_loader: Arc<ArcSwap<syntax::Loader>>) -> Self {\n        Self {\n            contents,\n            config_loader,\n        }\n    }\n\n    pub fn parse(&self, theme: Option<&Theme>) -> tui::text::Text<'_> {\n        fn push_line<'a>(spans: &mut Vec<Span<'a>>, lines: &mut Vec<Spans<'a>>) {\n            let spans = std::mem::take(spans);\n            if !spans.is_empty() {\n                lines.push(Spans::from(spans));\n            }\n        }\n\n        let mut options = Options::empty();\n        options.insert(Options::ENABLE_STRIKETHROUGH);\n        let parser = Parser::new_ext(&self.contents, options);\n\n        // TODO: if possible, render links as terminal hyperlinks: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda\n        let mut tags = Vec::new();\n        let mut spans = Vec::new();\n        let mut lines = Vec::new();\n        let mut list_stack = Vec::new();\n\n        let get_indent = |level: usize| {\n            if level < 1 {\n                String::new()\n            } else {\n                Self::INDENT.repeat(level - 1)\n            }\n        };\n\n        let get_theme = |key: &str| -> Style { theme.map(|t| t.get(key)).unwrap_or_default() };\n        let text_style = get_theme(Self::TEXT_STYLE);\n        let code_style = get_theme(Self::BLOCK_STYLE);\n        let numbered_list_style = get_theme(Self::NUMBERED_LIST_STYLE);\n        let unnumbered_list_style = get_theme(Self::UNNUMBERED_LIST_STYLE);\n        let rule_style = get_theme(Self::RULE_STYLE);\n        let heading_styles: Vec<Style> = Self::HEADING_STYLES\n            .iter()\n            .map(|key| get_theme(key))\n            .collect();\n\n        // Transform text in `<code>` blocks into `Event::Code`\n        let mut in_code = false;\n        let parser = parser.filter_map(|event| match event {\n            Event::Html(tag)\n                if tag.starts_with(\"<code\") && matches!(tag.chars().nth(5), Some(' ' | '>')) =>\n            {\n                in_code = true;\n                None\n            }\n            Event::Html(tag) if *tag == *\"</code>\" => {\n                in_code = false;\n                None\n            }\n            Event::Text(text) if in_code => Some(Event::Code(text)),\n            _ => Some(event),\n        });\n\n        for event in parser {\n            match event {\n                Event::Start(Tag::List(list)) => {\n                    // if the list stack is not empty this is a sub list, in that\n                    // case we need to push the current line before proceeding\n                    if !list_stack.is_empty() {\n                        push_line(&mut spans, &mut lines);\n                    }\n\n                    list_stack.push(list);\n                }\n                Event::End(TagEnd::List(_)) => {\n                    list_stack.pop();\n\n                    // whenever top-level list closes, empty line\n                    if list_stack.is_empty() {\n                        lines.push(Spans::default());\n                    }\n                }\n                Event::Start(Tag::Item) => {\n                    if list_stack.is_empty() {\n                        log::warn!(\"markdown parsing error, list item without list\");\n                    }\n\n                    tags.push(Tag::Item);\n\n                    // get the appropriate bullet for the current list\n                    let (bullet, bullet_style) = list_stack\n                        .last()\n                        .unwrap_or(&None) // use the '- ' bullet in case the list stack would be empty\n                        .map_or((String::from(\"• \"), unnumbered_list_style), |number| {\n                            (format!(\"{}. \", number), numbered_list_style)\n                        });\n\n                    // increment the current list number if there is one\n                    if let Some(v) = list_stack.last_mut().unwrap_or(&mut None).as_mut() {\n                        *v += 1;\n                    }\n\n                    let prefix = get_indent(list_stack.len()) + bullet.as_str();\n                    spans.push(Span::styled(prefix, bullet_style));\n                }\n                Event::Start(tag) => {\n                    tags.push(tag);\n                    if spans.is_empty() && !list_stack.is_empty() {\n                        // TODO: could push indent + 2 or 3 spaces to align with\n                        // the rest of the list.\n                        spans.push(Span::from(get_indent(list_stack.len())));\n                    }\n                }\n                Event::End(tag) => {\n                    tags.pop();\n                    match tag {\n                        TagEnd::Heading(_)\n                        | TagEnd::Paragraph\n                        | TagEnd::CodeBlock\n                        | TagEnd::Item => {\n                            push_line(&mut spans, &mut lines);\n                        }\n                        _ => (),\n                    }\n\n                    // whenever heading, code block or paragraph closes, empty line\n                    match tag {\n                        TagEnd::Heading(_) | TagEnd::Paragraph | TagEnd::CodeBlock => {\n                            lines.push(Spans::default());\n                        }\n                        _ => (),\n                    }\n                }\n                Event::Text(text) => {\n                    if let Some(Tag::CodeBlock(kind)) = tags.last() {\n                        let language = match kind {\n                            CodeBlockKind::Fenced(language) => language,\n                            CodeBlockKind::Indented => \"\",\n                        };\n                        let tui_text = highlighted_code_block(\n                            &text,\n                            language,\n                            theme,\n                            &self.config_loader.load(),\n                            None,\n                        );\n                        lines.extend(tui_text.lines.into_iter());\n                    } else {\n                        let style = match tags.last() {\n                            Some(Tag::Heading { level, .. }) => match level {\n                                HeadingLevel::H1 => heading_styles[0],\n                                HeadingLevel::H2 => heading_styles[1],\n                                HeadingLevel::H3 => heading_styles[2],\n                                HeadingLevel::H4 => heading_styles[3],\n                                HeadingLevel::H5 => heading_styles[4],\n                                HeadingLevel::H6 => heading_styles[5],\n                            },\n                            Some(Tag::Emphasis) => text_style.add_modifier(Modifier::ITALIC),\n                            Some(Tag::Strong) => text_style.add_modifier(Modifier::BOLD),\n                            Some(Tag::Strikethrough) => {\n                                text_style.add_modifier(Modifier::CROSSED_OUT)\n                            }\n                            _ => text_style,\n                        };\n                        spans.push(Span::styled(text, style));\n                    }\n                }\n                Event::Code(text) | Event::Html(text) => {\n                    spans.push(Span::styled(text, code_style));\n                }\n                Event::SoftBreak | Event::HardBreak => {\n                    push_line(&mut spans, &mut lines);\n                    if !list_stack.is_empty() {\n                        // TODO: could push indent + 2 or 3 spaces to align with\n                        // the rest of the list.\n                        spans.push(Span::from(get_indent(list_stack.len())));\n                    }\n                }\n                Event::Rule => {\n                    lines.push(Spans::from(Span::styled(\"───\", rule_style)));\n                    lines.push(Spans::default());\n                }\n                // TaskListMarker(bool) true if checked\n                _ => {\n                    log::warn!(\"unhandled markdown event {:?}\", event);\n                }\n            }\n            // build up a vec of Paragraph tui widgets\n        }\n\n        if !spans.is_empty() {\n            lines.push(Spans::from(spans));\n        }\n\n        // if last line is empty, remove it\n        if let Some(line) = lines.last() {\n            if line.0.is_empty() {\n                lines.pop();\n            }\n        }\n\n        Text::from(lines)\n    }\n}\n\nimpl Component for Markdown {\n    fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        use tui::widgets::{Paragraph, Widget, Wrap};\n\n        let text = self.parse(Some(&cx.editor.theme));\n\n        let par = Paragraph::new(&text)\n            .wrap(Wrap { trim: false })\n            .scroll((cx.scroll.unwrap_or_default() as u16, 0));\n\n        let margin = Margin::all(1);\n        par.render(area.inner(margin), surface);\n    }\n\n    fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {\n        let padding = 2;\n        let contents = self.parse(None);\n\n        // TODO: account for tab width\n        let max_text_width = (viewport.0.saturating_sub(padding)).min(120);\n        let (width, height) = crate::ui::text::required_size(&contents, max_text_width);\n\n        Some((width + padding, height + padding))\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/menu.rs",
    "content": "use crate::{\n    compositor::{Callback, Component, Compositor, Context, Event, EventResult},\n    ctrl, key, shift,\n};\nuse tui::{buffer::Buffer as Surface, widgets::Table};\n\npub use tui::widgets::{Cell, Row};\n\nuse helix_view::{editor::SmartTabConfig, graphics::Rect, Editor};\nuse tui::layout::Constraint;\n\npub trait Item: Sync + Send + 'static {\n    /// Additional editor state that is used for label calculation.\n    type Data: Sync + Send + 'static;\n\n    fn format(&self, data: &Self::Data) -> Row<'_>;\n}\n\npub type MenuCallback<T> = Box<dyn Fn(&mut Editor, Option<&T>, MenuEvent)>;\n\npub struct Menu<T: Item> {\n    options: Vec<T>,\n    editor_data: T::Data,\n\n    cursor: Option<usize>,\n\n    /// (index, score)\n    matches: Vec<(u32, u32)>,\n\n    widths: Vec<Constraint>,\n\n    callback_fn: MenuCallback<T>,\n\n    scroll: usize,\n    size: (u16, u16),\n    viewport: (u16, u16),\n    recalculate: bool,\n    auto_close: bool,\n}\n\nimpl<T: Item> Menu<T> {\n    const LEFT_PADDING: usize = 1;\n\n    // TODO: it's like a slimmed down picker, share code? (picker = menu + prompt with different\n    // rendering)\n    pub fn new(\n        options: Vec<T>,\n        editor_data: <T as Item>::Data,\n        callback_fn: impl Fn(&mut Editor, Option<&T>, MenuEvent) + 'static,\n    ) -> Self {\n        let matches = (0..options.len() as u32).map(|i| (i, 0)).collect();\n        Self {\n            options,\n            editor_data,\n            matches,\n            cursor: None,\n            widths: Vec::new(),\n            callback_fn: Box::new(callback_fn),\n            scroll: 0,\n            size: (0, 0),\n            viewport: (0, 0),\n            recalculate: true,\n            auto_close: false,\n        }\n    }\n\n    pub fn reset_cursor(&mut self) {\n        self.cursor = None;\n        self.scroll = 0;\n        self.recalculate = true;\n    }\n\n    pub fn update_options(&mut self) -> (&mut Vec<(u32, u32)>, &mut Vec<T>) {\n        self.recalculate = true;\n        (&mut self.matches, &mut self.options)\n    }\n\n    pub fn ensure_cursor_in_bounds(&mut self) {\n        if self.matches.is_empty() {\n            self.cursor = None;\n            self.scroll = 0;\n        } else {\n            self.scroll = 0;\n            self.recalculate = true;\n            if let Some(cursor) = &mut self.cursor {\n                *cursor = (*cursor).min(self.matches.len() - 1)\n            }\n        }\n    }\n\n    pub fn clear(&mut self) {\n        self.matches.clear();\n\n        // reset cursor position\n        self.cursor = None;\n        self.scroll = 0;\n    }\n\n    pub fn move_up(&mut self) {\n        let len = self.matches.len();\n        let max_index = len.saturating_sub(1);\n        let pos = self.cursor.map_or(max_index, |i| (i + max_index) % len) % len;\n        self.cursor = Some(pos);\n        self.adjust_scroll();\n    }\n\n    pub fn move_half_page_up(&mut self) {\n        let len = self.matches.len();\n        let max_index = len.saturating_sub((self.size.1 as usize / 2).max(1));\n        let pos = self.cursor.map_or(max_index, |i| (i + max_index) % len) % len;\n        self.cursor = Some(pos);\n        self.adjust_scroll();\n    }\n\n    pub fn move_down(&mut self) {\n        let len = self.matches.len();\n        let pos = self.cursor.map_or(0, |i| i + 1) % len;\n        self.cursor = Some(pos);\n        self.adjust_scroll();\n    }\n\n    pub fn move_half_page_down(&mut self) {\n        let len = self.matches.len();\n        let pos = self\n            .cursor\n            .map_or(0, |i| i + (self.size.1 as usize / 2).max(1))\n            % len;\n        self.cursor = Some(pos);\n        self.adjust_scroll();\n    }\n\n    pub fn auto_close(mut self, auto_close: bool) -> Self {\n        self.auto_close = auto_close;\n        self\n    }\n\n    fn recalculate_size(&mut self, viewport: (u16, u16)) {\n        let n = self\n            .options\n            .first()\n            .map(|option| option.format(&self.editor_data).cells.len())\n            .unwrap_or_default();\n        let max_lens = self.options.iter().fold(vec![0; n], |mut acc, option| {\n            let row = option.format(&self.editor_data);\n            // maintain max for each column\n            for (acc, cell) in acc.iter_mut().zip(row.cells.iter()) {\n                let width = cell.content.width();\n                if width > *acc {\n                    *acc = width;\n                }\n            }\n\n            acc\n        });\n\n        let height = self.matches.len().min(10).min(viewport.1 as usize);\n        // do all the matches fit on a single screen?\n        let fits = self.matches.len() <= height;\n\n        let mut len = max_lens.iter().sum::<usize>() + n;\n\n        if !fits {\n            len += 1; // +1: reserve some space for scrollbar\n        }\n\n        len += Self::LEFT_PADDING;\n        let width = len.min(viewport.0 as usize);\n\n        self.widths = max_lens\n            .into_iter()\n            .map(|len| Constraint::Length(len as u16))\n            .collect();\n\n        self.size = (width as u16, height as u16);\n\n        // adjust scroll offsets if size changed\n        self.adjust_scroll();\n        self.recalculate = false;\n    }\n\n    fn adjust_scroll(&mut self) {\n        let win_height = self.size.1 as usize;\n        if let Some(cursor) = self.cursor {\n            let mut scroll = self.scroll;\n            if cursor > (win_height + scroll).saturating_sub(1) {\n                // scroll down\n                scroll += cursor - (win_height + scroll).saturating_sub(1)\n            } else if cursor < scroll {\n                // scroll up\n                scroll = cursor\n            }\n            self.scroll = scroll;\n        }\n    }\n\n    pub fn selection(&self) -> Option<&T> {\n        self.cursor.and_then(|cursor| {\n            self.matches\n                .get(cursor)\n                .map(|(index, _score)| &self.options[*index as usize])\n        })\n    }\n\n    pub fn selection_mut(&mut self) -> Option<&mut T> {\n        self.cursor.and_then(|cursor| {\n            self.matches\n                .get(cursor)\n                .map(|(index, _score)| &mut self.options[*index as usize])\n        })\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.matches.is_empty()\n    }\n\n    pub fn len(&self) -> usize {\n        self.matches.len()\n    }\n}\n\nimpl<T: Item + PartialEq> Menu<T> {\n    pub fn replace_option(&mut self, old_option: &impl PartialEq<T>, new_option: T) {\n        for option in &mut self.options {\n            if old_option == option {\n                *option = new_option;\n                break;\n            }\n        }\n    }\n}\n\nuse super::PromptEvent as MenuEvent;\n\nimpl<T: Item + 'static> Component for Menu<T> {\n    fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult {\n        let event = match event {\n            Event::Key(event) => *event,\n            _ => return EventResult::Ignored(None),\n        };\n\n        let close_fn: Option<Callback> = Some(Box::new(|compositor: &mut Compositor, _| {\n            // remove the layer\n            compositor.pop();\n        }));\n\n        // Ignore tab key when supertab is turned on in order not to interfere\n        // with it. (Is there a better way to do this?)\n        if (event == key!(Tab) || event == shift!(Tab))\n            && cx.editor.config().auto_completion\n            && matches!(\n                cx.editor.config().smart_tab,\n                Some(SmartTabConfig {\n                    enable: true,\n                    supersede_menu: true,\n                })\n            )\n        {\n            return EventResult::Ignored(None);\n        }\n\n        match event {\n            // esc or ctrl-c aborts the completion and closes the menu\n            key!(Esc) | ctrl!('c') => {\n                (self.callback_fn)(cx.editor, self.selection(), MenuEvent::Abort);\n                return EventResult::Consumed(close_fn);\n            }\n            // arrow up/ctrl-p/shift-tab prev completion choice (including updating the doc)\n            shift!(Tab) | key!(Up) | ctrl!('p') => {\n                self.move_up();\n                (self.callback_fn)(cx.editor, self.selection(), MenuEvent::Update);\n                return EventResult::Consumed(None);\n            }\n            key!(Tab) | key!(Down) | ctrl!('n') => {\n                // arrow down/ctrl-n/tab advances completion choice (including updating the doc)\n                self.move_down();\n                (self.callback_fn)(cx.editor, self.selection(), MenuEvent::Update);\n                return EventResult::Consumed(None);\n            }\n            key!(PageUp) | ctrl!('u') => {\n                // page up moves back in the completion choice (including updating the doc)\n                self.move_half_page_up();\n                (self.callback_fn)(cx.editor, self.selection(), MenuEvent::Update);\n                return EventResult::Consumed(None);\n            }\n            key!(PageDown) | ctrl!('d') => {\n                // page down advances completion choice (including updating the doc)\n                self.move_half_page_down();\n                (self.callback_fn)(cx.editor, self.selection(), MenuEvent::Update);\n                return EventResult::Consumed(None);\n            }\n            key!(Enter) => {\n                if let Some(selection) = self.selection() {\n                    (self.callback_fn)(cx.editor, Some(selection), MenuEvent::Validate);\n                    return EventResult::Consumed(close_fn);\n                } else {\n                    return EventResult::Ignored(close_fn);\n                }\n            }\n            // KeyEvent {\n            //     code: KeyCode::Char(c),\n            //     modifiers: KeyModifiers::NONE,\n            // } => {\n            //     self.insert_char(c);\n            //     (self.callback_fn)(cx.editor, &self.line, MenuEvent::Update);\n            // }\n\n            // / -> edit_filter?\n            //\n            // enter confirms the match and closes the menu\n            // typing filters the menu\n            // if we run out of options the menu closes itself\n            _ if self.auto_close => {\n                (self.callback_fn)(cx.editor, self.selection(), MenuEvent::Abort);\n                return EventResult::Consumed(close_fn);\n            }\n            _ => (),\n        }\n        // for some events, we want to process them but send ignore, specifically all input except\n        // tab/enter/ctrl-k or whatever will confirm the selection/ ctrl-n/ctrl-p for scroll.\n        // EventResult::Consumed(None)\n        EventResult::Ignored(None)\n    }\n\n    fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {\n        if viewport != self.viewport || self.recalculate {\n            self.recalculate_size(viewport);\n        }\n\n        Some(self.size)\n    }\n\n    fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        let theme = &cx.editor.theme;\n        let style = theme\n            .try_get(\"ui.menu\")\n            .unwrap_or_else(|| theme.get(\"ui.text\"));\n        let selected = theme.get(\"ui.menu.selected\");\n\n        surface.clear_with(area, style);\n\n        let scroll = self.scroll;\n\n        let options: Vec<_> = self\n            .matches\n            .iter()\n            .map(|(index, _score)| {\n                // (index, self.options.get(*index).unwrap()) // get_unchecked\n                &self.options[*index as usize] // get_unchecked\n            })\n            .collect();\n\n        let len = options.len();\n\n        let win_height = area.height as usize;\n\n        let rows = options\n            .iter()\n            .map(|option| option.format(&self.editor_data));\n        let table = Table::new(rows)\n            .style(style)\n            .highlight_style(selected)\n            .column_spacing(1)\n            .widths(&self.widths);\n\n        use tui::widgets::TableState;\n\n        table.render_table(\n            area.clip_left(Self::LEFT_PADDING as u16).clip_right(1),\n            surface,\n            &mut TableState {\n                offset: scroll,\n                selected: self.cursor,\n            },\n            false,\n        );\n\n        let render_borders = cx.editor.menu_border();\n\n        if !render_borders {\n            if let Some(cursor) = self.cursor {\n                let offset_from_top = cursor - scroll;\n                let left = &mut surface[(area.left(), area.y + offset_from_top as u16)];\n                left.set_style(selected);\n                let right = &mut surface[(\n                    area.right().saturating_sub(1),\n                    area.y + offset_from_top as u16,\n                )];\n                right.set_style(selected);\n            }\n        }\n\n        let fits = len <= win_height;\n\n        let scroll_style = theme.get(\"ui.menu.scroll\");\n        if !fits {\n            let scroll_height = win_height.pow(2).div_ceil(len).min(win_height);\n            let scroll_line = (win_height - scroll_height) * scroll\n                / std::cmp::max(1, len.saturating_sub(win_height));\n\n            let mut cell;\n            for i in 0..win_height {\n                cell = &mut surface[(area.right() - 1, area.top() + i as u16)];\n\n                let half_block = if render_borders { \"▌\" } else { \"▐\" };\n\n                if scroll_line <= i && i < scroll_line + scroll_height {\n                    // Draw scroll thumb\n                    cell.set_symbol(half_block);\n                    cell.set_fg(scroll_style.fg.unwrap_or(helix_view::theme::Color::Reset));\n                } else if !render_borders {\n                    // Draw scroll track\n                    cell.set_symbol(half_block);\n                    cell.set_fg(scroll_style.bg.unwrap_or(helix_view::theme::Color::Reset));\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/mod.rs",
    "content": "mod completion;\nmod document;\npub(crate) mod editor;\nmod info;\npub mod lsp;\nmod markdown;\npub mod menu;\npub mod overlay;\npub mod picker;\npub mod popup;\npub mod prompt;\nmod select;\nmod spinner;\nmod statusline;\nmod text;\nmod text_decorations;\n\nuse crate::compositor::Compositor;\nuse crate::filter_picker_entry;\nuse crate::job::{self, Callback};\npub use completion::Completion;\npub use editor::EditorView;\nuse helix_stdx::rope;\nuse helix_view::theme::Style;\npub use markdown::Markdown;\npub use menu::Menu;\npub use picker::{Column as PickerColumn, FileLocation, Picker};\npub use popup::Popup;\npub use prompt::{Prompt, PromptEvent};\npub use select::Select;\npub use spinner::{ProgressSpinners, Spinner};\npub use text::Text;\n\nuse helix_view::Editor;\nuse tui::text::{Span, Spans};\n\nuse std::path::Path;\nuse std::{error::Error, path::PathBuf};\n\nstruct Utf8PathBuf {\n    path: String,\n    is_dir: bool,\n    is_symlink: bool,\n}\n\nimpl AsRef<str> for Utf8PathBuf {\n    fn as_ref(&self) -> &str {\n        &self.path\n    }\n}\n\npub fn prompt(\n    cx: &mut crate::commands::Context,\n    prompt: std::borrow::Cow<'static, str>,\n    history_register: Option<char>,\n    completion_fn: impl FnMut(&Editor, &str) -> Vec<prompt::Completion> + 'static,\n    callback_fn: impl FnMut(&mut crate::compositor::Context, &str, PromptEvent) + 'static,\n) {\n    let mut prompt = Prompt::new(prompt, history_register, completion_fn, callback_fn);\n    // Calculate the initial completion\n    prompt.recalculate_completion(cx.editor);\n    cx.push_layer(Box::new(prompt));\n}\n\npub fn prompt_with_input(\n    cx: &mut crate::commands::Context,\n    prompt: std::borrow::Cow<'static, str>,\n    input: String,\n    history_register: Option<char>,\n    completion_fn: impl FnMut(&Editor, &str) -> Vec<prompt::Completion> + 'static,\n    callback_fn: impl FnMut(&mut crate::compositor::Context, &str, PromptEvent) + 'static,\n) {\n    let prompt = Prompt::new(prompt, history_register, completion_fn, callback_fn)\n        .with_line(input, cx.editor);\n    cx.push_layer(Box::new(prompt));\n}\n\npub fn regex_prompt(\n    cx: &mut crate::commands::Context,\n    prompt: std::borrow::Cow<'static, str>,\n    history_register: Option<char>,\n    completion_fn: impl FnMut(&Editor, &str) -> Vec<prompt::Completion> + 'static,\n    fun: impl Fn(&mut crate::compositor::Context, rope::Regex, PromptEvent) + 'static,\n) {\n    raw_regex_prompt(\n        cx,\n        prompt,\n        history_register,\n        completion_fn,\n        move |cx, regex, _, event| fun(cx, regex, event),\n    );\n}\npub fn raw_regex_prompt(\n    cx: &mut crate::commands::Context,\n    prompt: std::borrow::Cow<'static, str>,\n    history_register: Option<char>,\n    completion_fn: impl FnMut(&Editor, &str) -> Vec<prompt::Completion> + 'static,\n    fun: impl Fn(&mut crate::compositor::Context, rope::Regex, &str, PromptEvent) + 'static,\n) {\n    let (view, doc) = current!(cx.editor);\n    let doc_id = view.doc;\n    let snapshot = doc.selection(view.id).clone();\n    let offset_snapshot = doc.view_offset(view.id);\n    let config = cx.editor.config();\n\n    let mut prompt = Prompt::new(\n        prompt,\n        history_register,\n        completion_fn,\n        move |cx: &mut crate::compositor::Context, input: &str, event: PromptEvent| {\n            match event {\n                PromptEvent::Abort => {\n                    let (view, doc) = current!(cx.editor);\n                    doc.set_selection(view.id, snapshot.clone());\n                    doc.set_view_offset(view.id, offset_snapshot);\n                }\n                PromptEvent::Update | PromptEvent::Validate => {\n                    // skip empty input\n                    if input.is_empty() {\n                        return;\n                    }\n\n                    let case_insensitive = if config.search.smart_case {\n                        !input.chars().any(char::is_uppercase)\n                    } else {\n                        false\n                    };\n\n                    match rope::RegexBuilder::new()\n                        .syntax(\n                            rope::Config::new()\n                                .case_insensitive(case_insensitive)\n                                .multi_line(true),\n                        )\n                        .build(input)\n                    {\n                        Ok(regex) => {\n                            let (view, doc) = current!(cx.editor);\n\n                            // revert state to what it was before the last update\n                            doc.set_selection(view.id, snapshot.clone());\n\n                            if event == PromptEvent::Validate {\n                                // Equivalent to push_jump to store selection just before jump\n                                view.jumps.push((doc_id, snapshot.clone()));\n                            }\n\n                            fun(cx, regex, input, event);\n\n                            let (view, doc) = current!(cx.editor);\n                            view.ensure_cursor_in_view(doc, config.scrolloff);\n                        }\n                        Err(err) => {\n                            let (view, doc) = current!(cx.editor);\n                            doc.set_selection(view.id, snapshot.clone());\n                            doc.set_view_offset(view.id, offset_snapshot);\n\n                            if event == PromptEvent::Validate {\n                                let callback = async move {\n                                    let call: job::Callback = Callback::EditorCompositor(Box::new(\n                                        move |_editor: &mut Editor, compositor: &mut Compositor| {\n                                            let contents = Text::new(format!(\"{}\", err));\n                                            let size = compositor.size();\n                                            let popup = Popup::new(\"invalid-regex\", contents)\n                                                .position(Some(helix_core::Position::new(\n                                                    size.height as usize - 2, // 2 = statusline + commandline\n                                                    0,\n                                                )))\n                                                .auto_close(true);\n                                            compositor.replace_or_push(\"invalid-regex\", popup);\n                                        },\n                                    ));\n                                    Ok(call)\n                                };\n\n                                cx.jobs.callback(callback);\n                            }\n                        }\n                    }\n                }\n            }\n        },\n    )\n    .with_language(\"regex\", std::sync::Arc::clone(&cx.editor.syn_loader));\n    // Calculate initial completion\n    prompt.recalculate_completion(cx.editor);\n    // prompt\n    cx.push_layer(Box::new(prompt));\n}\n\n/// We want to exclude files that the editor can't handle yet\nfn get_excluded_types() -> ignore::types::Types {\n    use ignore::types::TypesBuilder;\n    let mut type_builder = TypesBuilder::new();\n    type_builder\n        .add(\n            \"compressed\",\n            \"*.{zip,gz,bz2,zst,lzo,sz,tgz,tbz2,lz,lz4,lzma,lzo,z,Z,xz,7z,rar,cab}\",\n        )\n        .expect(\"Invalid type definition\");\n    type_builder.negate(\"all\");\n    type_builder\n        .build()\n        .expect(\"failed to build excluded_types\")\n}\n\n#[derive(Debug)]\npub struct FilePickerData {\n    root: PathBuf,\n    directory_style: Style,\n}\ntype FilePicker = Picker<PathBuf, FilePickerData>;\n\npub fn file_picker(editor: &Editor, root: PathBuf) -> FilePicker {\n    use ignore::WalkBuilder;\n    use std::time::Instant;\n\n    let config = editor.config();\n    let data = FilePickerData {\n        root: root.clone(),\n        directory_style: editor.theme.get(\"ui.text.directory\"),\n    };\n\n    let now = Instant::now();\n\n    let dedup_symlinks = config.file_picker.deduplicate_links;\n    let absolute_root = root.canonicalize().unwrap_or_else(|_| root.clone());\n\n    let mut walk_builder = WalkBuilder::new(&root);\n\n    let mut files = walk_builder\n        .hidden(config.file_picker.hidden)\n        .parents(config.file_picker.parents)\n        .ignore(config.file_picker.ignore)\n        .follow_links(config.file_picker.follow_symlinks)\n        .git_ignore(config.file_picker.git_ignore)\n        .git_global(config.file_picker.git_global)\n        .git_exclude(config.file_picker.git_exclude)\n        .sort_by_file_name(|name1, name2| name1.cmp(name2))\n        .max_depth(config.file_picker.max_depth)\n        .filter_entry(move |entry| filter_picker_entry(entry, &absolute_root, dedup_symlinks))\n        .add_custom_ignore_filename(helix_loader::config_dir().join(\"ignore\"))\n        .add_custom_ignore_filename(\".helix/ignore\")\n        .types(get_excluded_types())\n        .build()\n        .filter_map(|entry| {\n            let entry = entry.ok()?;\n            if !entry.path().is_file() {\n                return None;\n            }\n            Some(entry.into_path())\n        });\n    log::debug!(\"file_picker init {:?}\", Instant::now().duration_since(now));\n\n    let columns = [PickerColumn::new(\n        \"path\",\n        |item: &PathBuf, data: &FilePickerData| {\n            let path = item.strip_prefix(&data.root).unwrap_or(item);\n            let mut spans = Vec::with_capacity(3);\n            if let Some(dirs) = path.parent().filter(|p| !p.as_os_str().is_empty()) {\n                spans.extend([\n                    Span::styled(dirs.to_string_lossy(), data.directory_style),\n                    Span::styled(std::path::MAIN_SEPARATOR_STR, data.directory_style),\n                ]);\n            }\n            let filename = path\n                .file_name()\n                .expect(\"normalized paths can't end in `..`\")\n                .to_string_lossy();\n            spans.push(Span::raw(filename));\n            Spans::from(spans).into()\n        },\n    )];\n    let picker = Picker::new(columns, 0, [], data, move |cx, path: &PathBuf, action| {\n        if let Err(e) = cx.editor.open(path, action) {\n            let err = if let Some(err) = e.source() {\n                format!(\"{}\", err)\n            } else {\n                format!(\"unable to open \\\"{}\\\"\", path.display())\n            };\n            cx.editor.set_error(err);\n        }\n    })\n    .with_preview(|_editor, path| Some((path.as_path().into(), None)));\n    let injector = picker.injector();\n    let timeout = std::time::Instant::now() + std::time::Duration::from_millis(30);\n\n    let mut hit_timeout = false;\n    for file in &mut files {\n        if injector.push(file).is_err() {\n            break;\n        }\n        if std::time::Instant::now() >= timeout {\n            hit_timeout = true;\n            break;\n        }\n    }\n    if hit_timeout {\n        std::thread::spawn(move || {\n            for file in files {\n                if injector.push(file).is_err() {\n                    break;\n                }\n            }\n        });\n    }\n    picker\n}\n\ntype FileExplorer = Picker<(PathBuf, bool), (PathBuf, Style)>;\n\npub fn file_explorer(root: PathBuf, editor: &Editor) -> Result<FileExplorer, std::io::Error> {\n    let directory_style = editor.theme.get(\"ui.text.directory\");\n    let directory_content = directory_content(&root, editor)?;\n\n    let columns = [PickerColumn::new(\n        \"path\",\n        |(path, is_dir): &(PathBuf, bool), (root, directory_style): &(PathBuf, Style)| {\n            let name = path.strip_prefix(root).unwrap_or(path).to_string_lossy();\n            if *is_dir {\n                Span::styled(format!(\"{}/\", name), *directory_style).into()\n            } else {\n                name.into()\n            }\n        },\n    )];\n    let picker = Picker::new(\n        columns,\n        0,\n        directory_content,\n        (root, directory_style),\n        move |cx, (path, is_dir): &(PathBuf, bool), action| {\n            if *is_dir {\n                let new_root = helix_stdx::path::normalize(path);\n                let callback = Box::pin(async move {\n                    let call: Callback =\n                        Callback::EditorCompositor(Box::new(move |editor, compositor| {\n                            if let Ok(picker) = file_explorer(new_root, editor) {\n                                compositor.push(Box::new(overlay::overlaid(picker)));\n                            }\n                        }));\n                    Ok(call)\n                });\n                cx.jobs.callback(callback);\n            } else if let Err(e) = cx.editor.open(path, action) {\n                let err = if let Some(err) = e.source() {\n                    format!(\"{}\", err)\n                } else {\n                    format!(\"unable to open \\\"{}\\\"\", path.display())\n                };\n                cx.editor.set_error(err);\n            }\n        },\n    )\n    .with_preview(|_editor, (path, _is_dir)| Some((path.as_path().into(), None)));\n\n    Ok(picker)\n}\n\nfn directory_content(root: &Path, editor: &Editor) -> Result<Vec<(PathBuf, bool)>, std::io::Error> {\n    use ignore::WalkBuilder;\n\n    let config = editor.config();\n\n    let mut walk_builder = WalkBuilder::new(root);\n\n    let mut content: Vec<(PathBuf, bool)> = walk_builder\n        .hidden(config.file_explorer.hidden)\n        .parents(config.file_explorer.parents)\n        .ignore(config.file_explorer.ignore)\n        .follow_links(config.file_explorer.follow_symlinks)\n        .git_ignore(config.file_explorer.git_ignore)\n        .git_global(config.file_explorer.git_global)\n        .git_exclude(config.file_explorer.git_exclude)\n        .max_depth(Some(1))\n        .add_custom_ignore_filename(helix_loader::config_dir().join(\"ignore\"))\n        .add_custom_ignore_filename(\".helix/ignore\")\n        .types(get_excluded_types())\n        .build()\n        .filter_map(|entry| {\n            entry\n                .map(|entry| {\n                    let path = entry.path();\n                    let is_dir = path.is_dir();\n                    let mut path = path.to_path_buf();\n                    if is_dir && path != root && config.file_explorer.flatten_dirs {\n                        while let Some(single_child_directory) = get_child_if_single_dir(&path) {\n                            path = single_child_directory;\n                        }\n                    }\n                    (path, is_dir)\n                })\n                .ok()\n                .filter(|entry| entry.0 != root)\n        })\n        .collect();\n\n    content.sort_by(|(path1, is_dir1), (path2, is_dir2)| (!is_dir1, path1).cmp(&(!is_dir2, path2)));\n\n    if root.parent().is_some() {\n        content.insert(0, (root.join(\"..\"), true));\n    }\n\n    Ok(content)\n}\n\nfn get_child_if_single_dir(path: &Path) -> Option<PathBuf> {\n    let mut entries = path.read_dir().ok()?;\n    let entry = entries.next()?.ok()?;\n    let entry_path = entry.path();\n    if entries.next().is_none() && entry_path.is_dir() {\n        Some(entry_path)\n    } else {\n        None\n    }\n}\n\npub mod completers {\n    use super::Utf8PathBuf;\n    use crate::ui::prompt::Completion;\n    use helix_core::command_line::{self, Tokenizer};\n    use helix_core::fuzzy::fuzzy_match;\n    use helix_core::syntax::config::LanguageServerFeature;\n    use helix_view::document::SCRATCH_BUFFER_NAME;\n    use helix_view::theme;\n    use helix_view::{editor::Config, Editor};\n    use once_cell::sync::Lazy;\n    use std::borrow::Cow;\n    use std::collections::BTreeSet;\n    use tui::text::Span;\n\n    pub type Completer = fn(&Editor, &str) -> Vec<Completion>;\n\n    pub fn none(_editor: &Editor, _input: &str) -> Vec<Completion> {\n        Vec::new()\n    }\n\n    pub fn buffer(editor: &Editor, input: &str) -> Vec<Completion> {\n        let names = editor.documents.values().map(|doc| {\n            doc.relative_path()\n                .map(|p| p.display().to_string().into())\n                .unwrap_or_else(|| Cow::from(SCRATCH_BUFFER_NAME))\n        });\n\n        fuzzy_match(input, names, true)\n            .into_iter()\n            .map(|(name, _)| ((0..), name.into()))\n            .collect()\n    }\n\n    pub fn theme(_editor: &Editor, input: &str) -> Vec<Completion> {\n        let mut names = theme::Loader::read_names(&helix_loader::config_dir().join(\"themes\"));\n        for rt_dir in helix_loader::runtime_dirs() {\n            names.extend(theme::Loader::read_names(&rt_dir.join(\"themes\")));\n        }\n        names.push(\"default\".into());\n        names.push(\"base16_default\".into());\n        names.sort();\n        names.dedup();\n\n        fuzzy_match(input, names, false)\n            .into_iter()\n            .map(|(name, _)| ((0..), name.into()))\n            .collect()\n    }\n\n    /// Recursive function to get all keys from this value and add them to vec\n    fn get_keys(value: &serde_json::Value, vec: &mut Vec<String>, scope: Option<&str>) {\n        if let Some(map) = value.as_object() {\n            for (key, value) in map.iter() {\n                let key = match scope {\n                    Some(scope) => format!(\"{}.{}\", scope, key),\n                    None => key.clone(),\n                };\n                get_keys(value, vec, Some(&key));\n                if !value.is_object() {\n                    vec.push(key);\n                }\n            }\n        }\n    }\n\n    /// Completes names of language servers which are running for the current document.\n    pub fn active_language_servers(editor: &Editor, input: &str) -> Vec<Completion> {\n        let language_servers = doc!(editor).language_servers().map(|ls| ls.name());\n\n        fuzzy_match(input, language_servers, false)\n            .into_iter()\n            .map(|(name, _)| ((0..), Span::raw(name.to_string())))\n            .collect()\n    }\n\n    /// Completes names of language servers which are configured for the language of the current\n    /// document.\n    pub fn configured_language_servers(editor: &Editor, input: &str) -> Vec<Completion> {\n        let language_servers = doc!(editor)\n            .language_config()\n            .into_iter()\n            .flat_map(|config| &config.language_servers)\n            .map(|ls| ls.name.as_str());\n\n        fuzzy_match(input, language_servers, false)\n            .into_iter()\n            .map(|(name, _)| ((0..), Span::raw(name.to_string())))\n            .collect()\n    }\n\n    pub fn setting(_editor: &Editor, input: &str) -> Vec<Completion> {\n        static KEYS: Lazy<Vec<String>> = Lazy::new(|| {\n            let mut keys = Vec::new();\n            let json = serde_json::json!(Config::default());\n            get_keys(&json, &mut keys, None);\n            keys\n        });\n\n        fuzzy_match(input, &*KEYS, false)\n            .into_iter()\n            .map(|(name, _)| ((0..), Span::raw(name)))\n            .collect()\n    }\n\n    pub fn filename(editor: &Editor, input: &str) -> Vec<Completion> {\n        filename_with_git_ignore(editor, input, true)\n    }\n\n    pub fn filename_with_git_ignore(\n        editor: &Editor,\n        input: &str,\n        git_ignore: bool,\n    ) -> Vec<Completion> {\n        filename_impl(editor, input, git_ignore, |entry| {\n            if entry.path().is_dir() {\n                FileMatch::AcceptIncomplete\n            } else {\n                FileMatch::Accept\n            }\n        })\n    }\n\n    pub fn language(editor: &Editor, input: &str) -> Vec<Completion> {\n        let text: String = \"text\".into();\n\n        let loader = editor.syn_loader.load();\n        let language_ids = loader\n            .language_configs()\n            .map(|config| &config.language_id)\n            .chain(std::iter::once(&text));\n\n        fuzzy_match(input, language_ids, false)\n            .into_iter()\n            .map(|(name, _)| ((0..), name.to_owned().into()))\n            .collect()\n    }\n\n    pub fn lsp_workspace_command(editor: &Editor, input: &str) -> Vec<Completion> {\n        let commands = doc!(editor)\n            .language_servers_with_feature(LanguageServerFeature::WorkspaceCommand)\n            .flat_map(|ls| {\n                ls.capabilities()\n                    .execute_command_provider\n                    .iter()\n                    .flat_map(|options| options.commands.iter())\n            });\n\n        fuzzy_match(input, commands, false)\n            .into_iter()\n            .map(|(name, _)| ((0..), name.to_owned().into()))\n            .collect()\n    }\n\n    pub fn directory(editor: &Editor, input: &str) -> Vec<Completion> {\n        directory_with_git_ignore(editor, input, true)\n    }\n\n    pub fn directory_with_git_ignore(\n        editor: &Editor,\n        input: &str,\n        git_ignore: bool,\n    ) -> Vec<Completion> {\n        filename_impl(editor, input, git_ignore, |entry| {\n            if entry.path().is_dir() {\n                FileMatch::Accept\n            } else {\n                FileMatch::Reject\n            }\n        })\n    }\n\n    #[derive(Copy, Clone, PartialEq, Eq)]\n    enum FileMatch {\n        /// Entry should be ignored\n        Reject,\n        /// Entry is usable but can't be the end (for instance if the entry is a directory and we\n        /// try to match a file)\n        AcceptIncomplete,\n        /// Entry is usable and can be the end of the match\n        Accept,\n    }\n\n    // TODO: we could return an iter/lazy thing so it can fetch as many as it needs.\n    fn filename_impl<F>(\n        editor: &Editor,\n        input: &str,\n        git_ignore: bool,\n        filter_fn: F,\n    ) -> Vec<Completion>\n    where\n        F: Fn(&ignore::DirEntry) -> FileMatch,\n    {\n        // Rust's filename handling is really annoying.\n\n        use ignore::WalkBuilder;\n        use std::path::Path;\n\n        let is_tilde = input == \"~\";\n        let path = helix_stdx::path::expand_tilde(Path::new(input));\n\n        let (dir, file_name) = if input.ends_with(std::path::MAIN_SEPARATOR) {\n            (path, None)\n        } else {\n            let is_period = (input.ends_with((format!(\"{}.\", std::path::MAIN_SEPARATOR)).as_str())\n                && input.len() > 2)\n                || input == \".\";\n            let file_name = if is_period {\n                Some(String::from(\".\"))\n            } else {\n                path.file_name()\n                    .and_then(|file| file.to_str().map(|path| path.to_owned()))\n            };\n\n            let path = if is_period {\n                path\n            } else {\n                match path.parent() {\n                    Some(path) if !path.as_os_str().is_empty() => Cow::Borrowed(path),\n                    // Path::new(\"h\")'s parent is Some(\"\")...\n                    _ => Cow::Owned(helix_stdx::env::current_working_dir()),\n                }\n            };\n\n            (path, file_name)\n        };\n\n        let end = input.len()..;\n\n        let files = WalkBuilder::new(&dir)\n            .hidden(false)\n            .follow_links(false) // We're scanning over depth 1\n            .git_ignore(git_ignore)\n            .max_depth(Some(1))\n            .build()\n            .filter_map(|file| {\n                file.ok().and_then(|entry| {\n                    let fmatch = filter_fn(&entry);\n\n                    if fmatch == FileMatch::Reject {\n                        return None;\n                    }\n\n                    let path = entry.path();\n                    let is_dir = path.is_dir();\n                    let file_type = entry.file_type();\n                    let is_symlink = file_type.is_some_and(|ft| ft.is_symlink());\n                    let mut path = if is_tilde {\n                        // if it's a single tilde an absolute path is displayed so that when `TAB` is pressed on\n                        // one of the directories the tilde will be replaced with a valid path not with a relative\n                        // home directory name.\n                        // ~ -> <TAB> -> /home/user\n                        // ~/ -> <TAB> -> ~/first_entry\n                        path.to_path_buf()\n                    } else {\n                        path.strip_prefix(&dir).unwrap_or(path).to_path_buf()\n                    };\n\n                    if fmatch == FileMatch::AcceptIncomplete {\n                        path.push(\"\");\n                    }\n\n                    let path = path.into_os_string().into_string().ok()?;\n                    Some(Utf8PathBuf {\n                        path,\n                        is_dir,\n                        is_symlink,\n                    })\n                })\n            }) // TODO: unwrap or skip\n            .filter(|path| !path.path.is_empty());\n\n        let directory_color = editor.theme.get(\"ui.text.directory\");\n        let symlink_color = editor.theme.get(\"ui.text.symlink\");\n\n        let style_from_file = |file: Utf8PathBuf| {\n            if file.is_symlink {\n                Span::styled(file.path, symlink_color)\n            } else if file.is_dir {\n                Span::styled(file.path, directory_color)\n            } else {\n                Span::raw(file.path)\n            }\n        };\n\n        // if empty, return a list of dirs and files in current dir\n        if let Some(file_name) = file_name {\n            let range = (input.len().saturating_sub(file_name.len()))..;\n            fuzzy_match(&file_name, files, true)\n                .into_iter()\n                .map(|(name, _)| (range.clone(), style_from_file(name)))\n                .collect()\n\n            // TODO: complete to longest common match\n        } else {\n            let mut files: Vec<_> = files\n                .map(|file| (end.clone(), style_from_file(file)))\n                .collect();\n            files.sort_unstable_by(|(_, path1), (_, path2)| path1.content.cmp(&path2.content));\n            files\n        }\n    }\n\n    pub fn register(editor: &Editor, input: &str) -> Vec<Completion> {\n        let iter = editor\n            .registers\n            .iter_preview()\n            // Exclude special registers that shouldn't be written to\n            .filter(|(ch, _)| !matches!(ch, '%' | '#' | '.'))\n            .map(|(ch, _)| ch.to_string());\n\n        fuzzy_match(input, iter, false)\n            .into_iter()\n            .map(|(name, _)| ((0..), name.into()))\n            .collect()\n    }\n\n    pub fn program(_editor: &Editor, input: &str) -> Vec<Completion> {\n        static PROGRAMS_IN_PATH: Lazy<BTreeSet<String>> = Lazy::new(|| {\n            // Go through the entire PATH and read all files into a set.\n            let Some(path) = std::env::var_os(\"PATH\") else {\n                return Default::default();\n            };\n\n            std::env::split_paths(&path)\n                .filter_map(|path| std::fs::read_dir(path).ok())\n                .flatten()\n                .filter_map(|res| {\n                    let entry = res.ok()?;\n                    let file_type = entry.file_type().ok()?;\n                    if file_type.is_file() || file_type.is_symlink() {\n                        entry.file_name().into_string().ok()\n                    } else {\n                        None\n                    }\n                })\n                .collect()\n        });\n\n        fuzzy_match(input, PROGRAMS_IN_PATH.iter(), false)\n            .into_iter()\n            .map(|(name, _)| ((0..), name.clone().into()))\n            .collect()\n    }\n\n    /// This expects input to be a raw string of arguments, because this is what Signature's raw_after does.\n    pub fn repeating_filenames(editor: &Editor, input: &str) -> Vec<Completion> {\n        let token = match Tokenizer::new(input, false).last() {\n            Some(token) => token.unwrap(),\n            None => return filename(editor, input),\n        };\n\n        let offset = token.content_start;\n\n        let mut completions = filename(editor, &input[offset..]);\n        for completion in completions.iter_mut() {\n            completion.0.start += offset;\n        }\n        completions\n    }\n\n    pub fn shell(editor: &Editor, input: &str) -> Vec<Completion> {\n        let (command, args, complete_command) = command_line::split(input);\n\n        if complete_command {\n            return program(editor, command);\n        }\n\n        let mut completions = repeating_filenames(editor, args);\n        for completion in completions.iter_mut() {\n            // + 1 for separator between `command` and `args`\n            completion.0.start += command.len() + 1;\n        }\n\n        completions\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::fs::{create_dir, File};\n\n    use super::*;\n\n    #[test]\n    fn test_get_child_if_single_dir() {\n        let root = tempfile::tempdir().unwrap();\n\n        assert_eq!(get_child_if_single_dir(root.path()), None);\n\n        let dir = root.path().join(\"dir1\");\n        create_dir(&dir).unwrap();\n\n        assert_eq!(get_child_if_single_dir(root.path()), Some(dir));\n\n        let file = root.path().join(\"file\");\n        File::create(file).unwrap();\n\n        assert_eq!(get_child_if_single_dir(root.path()), None);\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/overlay.rs",
    "content": "use helix_core::Position;\nuse helix_view::{\n    graphics::{CursorKind, Rect},\n    Editor,\n};\nuse tui::buffer::Buffer;\n\nuse crate::compositor::{Component, Context, Event, EventResult};\n\n/// Contains a component placed in the center of the parent component\npub struct Overlay<T> {\n    /// Child component\n    pub content: T,\n    /// Function to compute the size and position of the child component\n    pub calc_child_size: Box<dyn Fn(Rect) -> Rect>,\n}\n\n/// Surrounds the component with a margin of 5% on each side, and an additional 2 rows at the bottom\npub fn overlaid<T>(content: T) -> Overlay<T> {\n    Overlay {\n        content,\n        calc_child_size: Box::new(|rect: Rect| clip_rect_relative(rect.clip_bottom(2), 90, 90)),\n    }\n}\n\nfn clip_rect_relative(rect: Rect, percent_horizontal: u8, percent_vertical: u8) -> Rect {\n    fn mul_and_cast(size: u16, factor: u8) -> u16 {\n        ((size as u32) * (factor as u32) / 100).try_into().unwrap()\n    }\n\n    let inner_w = mul_and_cast(rect.width, percent_horizontal);\n    let inner_h = mul_and_cast(rect.height, percent_vertical);\n\n    let offset_x = rect.width.saturating_sub(inner_w) / 2;\n    let offset_y = rect.height.saturating_sub(inner_h) / 2;\n\n    Rect {\n        x: rect.x + offset_x,\n        y: rect.y + offset_y,\n        width: inner_w,\n        height: inner_h,\n    }\n}\n\nimpl<T: Component + 'static> Component for Overlay<T> {\n    fn render(&mut self, area: Rect, frame: &mut Buffer, ctx: &mut Context) {\n        let dimensions = (self.calc_child_size)(area);\n        self.content.render(dimensions, frame, ctx)\n    }\n\n    fn required_size(&mut self, (width, height): (u16, u16)) -> Option<(u16, u16)> {\n        let area = Rect {\n            x: 0,\n            y: 0,\n            width,\n            height,\n        };\n        let dimensions = (self.calc_child_size)(area);\n        let viewport = (dimensions.width, dimensions.height);\n        let _ = self.content.required_size(viewport)?;\n        Some((width, height))\n    }\n\n    fn handle_event(&mut self, event: &Event, ctx: &mut Context) -> EventResult {\n        self.content.handle_event(event, ctx)\n    }\n\n    fn cursor(&self, area: Rect, ctx: &Editor) -> (Option<Position>, CursorKind) {\n        let dimensions = (self.calc_child_size)(area);\n        self.content.cursor(dimensions, ctx)\n    }\n\n    fn id(&self) -> Option<&'static str> {\n        self.content.id()\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/picker/handlers.rs",
    "content": "use std::{\n    path::Path,\n    sync::{atomic, Arc},\n    time::Duration,\n};\n\nuse helix_event::AsyncHook;\nuse tokio::time::Instant;\n\nuse crate::{job, ui::overlay::Overlay};\n\nuse super::{CachedPreview, DynQueryCallback, Picker};\n\npub(super) struct PreviewHighlightHandler<T: 'static + Send + Sync, D: 'static + Send + Sync> {\n    trigger: Option<Arc<Path>>,\n    phantom_data: std::marker::PhantomData<(T, D)>,\n}\n\nimpl<T: 'static + Send + Sync, D: 'static + Send + Sync> Default for PreviewHighlightHandler<T, D> {\n    fn default() -> Self {\n        Self {\n            trigger: None,\n            phantom_data: Default::default(),\n        }\n    }\n}\n\nimpl<T: 'static + Send + Sync, D: 'static + Send + Sync> AsyncHook\n    for PreviewHighlightHandler<T, D>\n{\n    type Event = Arc<Path>;\n\n    fn handle_event(\n        &mut self,\n        path: Self::Event,\n        timeout: Option<tokio::time::Instant>,\n    ) -> Option<tokio::time::Instant> {\n        if self\n            .trigger\n            .as_ref()\n            .is_some_and(|trigger| trigger == &path)\n        {\n            // If the path hasn't changed, don't reset the debounce\n            timeout\n        } else {\n            self.trigger = Some(path);\n            Some(Instant::now() + Duration::from_millis(150))\n        }\n    }\n\n    fn finish_debounce(&mut self) {\n        let Some(path) = self.trigger.take() else {\n            return;\n        };\n\n        job::dispatch_blocking(move |editor, compositor| {\n            let Some(Overlay {\n                content: picker, ..\n            }) = compositor.find::<Overlay<Picker<T, D>>>()\n            else {\n                return;\n            };\n\n            let Some(CachedPreview::Document(ref mut doc)) = picker.preview_cache.get_mut(&path)\n            else {\n                return;\n            };\n\n            if doc.syntax().is_some() {\n                return;\n            }\n\n            let Some(language) = doc.language_config().map(|config| config.language()) else {\n                return;\n            };\n\n            let loader = editor.syn_loader.load();\n            let text = doc.text().clone();\n\n            tokio::task::spawn_blocking(move || {\n                let syntax = match helix_core::Syntax::new(text.slice(..), language, &loader) {\n                    Ok(syntax) => syntax,\n                    Err(err) => {\n                        log::info!(\"highlighting picker preview failed: {err}\");\n                        return;\n                    }\n                };\n\n                job::dispatch_blocking(move |editor, compositor| {\n                    let Some(Overlay {\n                        content: picker, ..\n                    }) = compositor.find::<Overlay<Picker<T, D>>>()\n                    else {\n                        log::info!(\"picker closed before syntax highlighting finished\");\n                        return;\n                    };\n                    let Some(CachedPreview::Document(ref mut doc)) =\n                        picker.preview_cache.get_mut(&path)\n                    else {\n                        return;\n                    };\n                    let diagnostics = helix_view::Editor::doc_diagnostics(\n                        &editor.language_servers,\n                        &editor.diagnostics,\n                        doc,\n                    );\n                    doc.replace_diagnostics(diagnostics, &[], None);\n                    doc.syntax = Some(syntax);\n                });\n            });\n        });\n    }\n}\n\npub(super) struct DynamicQueryChange {\n    pub query: Arc<str>,\n    pub is_paste: bool,\n}\n\npub(super) struct DynamicQueryHandler<T: 'static + Send + Sync, D: 'static + Send + Sync> {\n    callback: Arc<DynQueryCallback<T, D>>,\n    // Duration used as a debounce.\n    // Defaults to 100ms if not provided via `Picker::with_dynamic_query`. Callers may want to set\n    // this higher if the dynamic query is expensive - for example global search.\n    debounce: Duration,\n    last_query: Arc<str>,\n    query: Option<Arc<str>>,\n}\n\nimpl<T: 'static + Send + Sync, D: 'static + Send + Sync> DynamicQueryHandler<T, D> {\n    pub(super) fn new(callback: DynQueryCallback<T, D>, duration_ms: Option<u64>) -> Self {\n        Self {\n            callback: Arc::new(callback),\n            debounce: Duration::from_millis(duration_ms.unwrap_or(100)),\n            last_query: \"\".into(),\n            query: None,\n        }\n    }\n}\n\nimpl<T: 'static + Send + Sync, D: 'static + Send + Sync> AsyncHook for DynamicQueryHandler<T, D> {\n    type Event = DynamicQueryChange;\n\n    fn handle_event(&mut self, change: Self::Event, _timeout: Option<Instant>) -> Option<Instant> {\n        let DynamicQueryChange { query, is_paste } = change;\n        if query == self.last_query {\n            // If the search query reverts to the last one we requested, no need to\n            // make a new request.\n            self.query = None;\n            None\n        } else {\n            self.query = Some(query);\n            if is_paste {\n                self.finish_debounce();\n                None\n            } else {\n                Some(Instant::now() + self.debounce)\n            }\n        }\n    }\n\n    fn finish_debounce(&mut self) {\n        let Some(query) = self.query.take() else {\n            return;\n        };\n        self.last_query = query.clone();\n        let callback = self.callback.clone();\n\n        job::dispatch_blocking(move |editor, compositor| {\n            let Some(Overlay {\n                content: picker, ..\n            }) = compositor.find::<Overlay<Picker<T, D>>>()\n            else {\n                return;\n            };\n            // Increment the version number to cancel any ongoing requests.\n            picker.version.fetch_add(1, atomic::Ordering::Relaxed);\n            picker.matcher.restart(false);\n            let injector = picker.injector();\n            let get_options = (callback)(&query, editor, picker.editor_data.clone(), &injector);\n            tokio::spawn(async move {\n                if let Err(err) = get_options.await {\n                    log::info!(\"Dynamic request failed: {err}\");\n                }\n                // NOTE: the Drop implementation of Injector will request a redraw when the\n                // injector falls out of scope here, clearing the \"running\" indicator.\n            });\n        })\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/picker/query.rs",
    "content": "use std::{collections::HashMap, mem, ops::Range, sync::Arc};\n\n#[derive(Debug)]\npub(super) struct PickerQuery {\n    /// The column names of the picker.\n    column_names: Box<[Arc<str>]>,\n    /// The index of the primary column in `column_names`.\n    /// The primary column is selected by default unless another\n    /// field is specified explicitly with `%fieldname`.\n    primary_column: usize,\n    /// The mapping between column names and input in the query\n    /// for those columns.\n    inner: HashMap<Arc<str>, Arc<str>>,\n    /// The byte ranges of the input text which are used as input for each column.\n    /// This is calculated at parsing time for use in [Self::active_column].\n    /// This Vec is naturally sorted in ascending order and ranges do not overlap.\n    column_ranges: Vec<(Range<usize>, Option<Arc<str>>)>,\n}\n\nimpl PartialEq<HashMap<Arc<str>, Arc<str>>> for PickerQuery {\n    fn eq(&self, other: &HashMap<Arc<str>, Arc<str>>) -> bool {\n        self.inner.eq(other)\n    }\n}\n\nimpl PickerQuery {\n    pub(super) fn new<I: Iterator<Item = Arc<str>>>(\n        column_names: I,\n        primary_column: usize,\n    ) -> Self {\n        let column_names: Box<[_]> = column_names.collect();\n        let inner = HashMap::with_capacity(column_names.len());\n        let column_ranges = vec![(0..usize::MAX, Some(column_names[primary_column].clone()))];\n        Self {\n            column_names,\n            primary_column,\n            inner,\n            column_ranges,\n        }\n    }\n\n    pub(super) fn get(&self, column: &str) -> Option<&Arc<str>> {\n        self.inner.get(column)\n    }\n\n    pub(super) fn parse(&mut self, input: &str) -> HashMap<Arc<str>, Arc<str>> {\n        let mut fields: HashMap<Arc<str>, String> = HashMap::new();\n        let primary_field = &self.column_names[self.primary_column];\n        let mut escaped = false;\n        let mut in_field = false;\n        let mut field = None;\n        let mut text = String::new();\n        self.column_ranges.clear();\n        self.column_ranges\n            .push((0..usize::MAX, Some(primary_field.clone())));\n\n        macro_rules! finish_field {\n            () => {\n                let key = field.take().unwrap_or(primary_field);\n\n                // Trims one space from the end, enabling leading and trailing\n                // spaces in search patterns, while also retaining spaces as separators\n                // between column filters.\n                let pat = text.strip_suffix(' ').unwrap_or(&text);\n\n                if let Some(pattern) = fields.get_mut(key) {\n                    pattern.push(' ');\n                    pattern.push_str(pat);\n                } else {\n                    fields.insert(key.clone(), pat.to_string());\n                }\n                text.clear();\n            };\n        }\n\n        for (idx, ch) in input.char_indices() {\n            match ch {\n                // Backslash escaping\n                _ if escaped => {\n                    // '%' is the only character that is special cased.\n                    // You can escape it to prevent parsing the text that\n                    // follows it as a field name.\n                    if ch != '%' {\n                        text.push('\\\\');\n                    }\n                    text.push(ch);\n                    escaped = false;\n                }\n                '\\\\' => escaped = !escaped,\n                '%' => {\n                    if !text.is_empty() {\n                        finish_field!();\n                    }\n                    let (range, _field) = self\n                        .column_ranges\n                        .last_mut()\n                        .expect(\"column_ranges is non-empty\");\n                    range.end = idx;\n                    in_field = true;\n                }\n                ' ' if in_field => {\n                    text.clear();\n                    in_field = false;\n                }\n                _ if in_field => {\n                    text.push(ch);\n                    // Go over all columns and their indices, find all that starts with field key,\n                    // select a column that fits key the most.\n                    field = self\n                        .column_names\n                        .iter()\n                        .filter(|col| col.starts_with(&text))\n                        // select \"fittest\" column\n                        .min_by_key(|col| col.len());\n\n                    // Update the column range for this column.\n                    if let Some((_range, current_field)) = self\n                        .column_ranges\n                        .last_mut()\n                        .filter(|(range, _)| range.end == usize::MAX)\n                    {\n                        *current_field = field.cloned();\n                    } else {\n                        self.column_ranges.push((idx..usize::MAX, field.cloned()));\n                    }\n                }\n                _ => text.push(ch),\n            }\n        }\n\n        if !in_field && !text.is_empty() {\n            finish_field!();\n        }\n\n        let new_inner: HashMap<_, _> = fields\n            .into_iter()\n            .map(|(field, query)| (field, query.as_str().into()))\n            .collect();\n\n        mem::replace(&mut self.inner, new_inner)\n    }\n\n    /// Finds the column which the cursor is 'within' in the last parse.\n    ///\n    /// The cursor is considered to be within a column when it is placed within any\n    /// of a column's text. See the `active_column_test` unit test below for examples.\n    ///\n    /// `cursor` is a byte index that represents the location of the prompt's cursor.\n    pub fn active_column(&self, cursor: usize) -> Option<&Arc<str>> {\n        let point = self\n            .column_ranges\n            .partition_point(|(range, _field)| cursor > range.end);\n\n        self.column_ranges\n            .get(point)\n            .filter(|(range, _field)| cursor >= range.start && cursor <= range.end)\n            .and_then(|(_range, field)| field.as_ref())\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use helix_core::hashmap;\n\n    use super::*;\n\n    #[test]\n    fn parse_query_test() {\n        let mut query = PickerQuery::new(\n            [\n                \"primary\".into(),\n                \"field1\".into(),\n                \"field2\".into(),\n                \"another\".into(),\n                \"anode\".into(),\n            ]\n            .into_iter(),\n            0,\n        );\n\n        // Basic field splitting\n        query.parse(\"hello world\");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello world\".into(),\n            )\n        );\n        query.parse(\"hello %field1 world %field2 !\");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello\".into(),\n                \"field1\".into() => \"world\".into(),\n                \"field2\".into() => \"!\".into(),\n            )\n        );\n        query.parse(\"%field1 abc %field2 def xyz\");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"field1\".into() => \"abc\".into(),\n                \"field2\".into() => \"def xyz\".into(),\n            )\n        );\n\n        // Trailing space is trimmed\n        query.parse(\"hello \");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello\".into(),\n            )\n        );\n\n        // Unknown fields are trimmed.\n        query.parse(\"hello %foo\");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello\".into(),\n            )\n        );\n\n        // Multiple words in a field\n        query.parse(\"hello %field1 a b c\");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello\".into(),\n                \"field1\".into() => \"a b c\".into(),\n            )\n        );\n\n        // Escaping\n        query.parse(r#\"hello\\ world\"#);\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => r#\"hello\\ world\"#.into(),\n            )\n        );\n        query.parse(r#\"hello \\%field1 world\"#);\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello %field1 world\".into(),\n            )\n        );\n        query.parse(r#\"%field1 hello\\ world\"#);\n        assert_eq!(\n            query,\n            hashmap!(\n                \"field1\".into() => r#\"hello\\ world\"#.into(),\n            )\n        );\n        query.parse(r#\"hello %field1 a\\\"b\"#);\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello\".into(),\n                \"field1\".into() => r#\"a\\\"b\"#.into(),\n            )\n        );\n        query.parse(r#\"%field1 hello\\ world\"#);\n        assert_eq!(\n            query,\n            hashmap!(\n                \"field1\".into() => r#\"hello\\ world\"#.into(),\n            )\n        );\n        query.parse(r#\"\\bfoo\\b\"#);\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => r#\"\\bfoo\\b\"#.into(),\n            )\n        );\n        query.parse(r#\"\\\\n\"#);\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => r#\"\\\\n\"#.into(),\n            )\n        );\n\n        // Only the prefix of a field is required.\n        query.parse(\"hello %anot abc\");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello\".into(),\n                \"another\".into() => \"abc\".into(),\n            )\n        );\n        // The shortest matching the prefix is selected.\n        query.parse(\"hello %ano abc\");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello\".into(),\n                \"anode\".into() => \"abc\".into()\n            )\n        );\n        // Multiple uses of a column are concatenated with space separators.\n        query.parse(\"hello %field1 xyz %fie abc\");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello\".into(),\n                \"field1\".into() => \"xyz abc\".into()\n            )\n        );\n        query.parse(\"hello %fie abc\");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello\".into(),\n                \"field1\".into() => \"abc\".into()\n            )\n        );\n        // The primary column can be explicitly qualified.\n        query.parse(\"hello %fie abc %prim world\");\n        assert_eq!(\n            query,\n            hashmap!(\n                \"primary\".into() => \"hello world\".into(),\n                \"field1\".into() => \"abc\".into()\n            )\n        );\n    }\n\n    #[test]\n    fn active_column_test() {\n        fn active_column<'a>(query: &'a mut PickerQuery, input: &str) -> Option<&'a str> {\n            let cursor = input.find('|').expect(\"cursor must be indicated with '|'\");\n            let input = input.replace('|', \"\");\n            query.parse(&input);\n            query.active_column(cursor).map(AsRef::as_ref)\n        }\n\n        let mut query = PickerQuery::new(\n            [\"primary\".into(), \"foo\".into(), \"bar\".into()].into_iter(),\n            0,\n        );\n\n        assert_eq!(active_column(&mut query, \"|\"), Some(\"primary\"));\n        assert_eq!(active_column(&mut query, \"hello| world\"), Some(\"primary\"));\n        assert_eq!(active_column(&mut query, \"|%foo hello\"), Some(\"primary\"));\n        assert_eq!(active_column(&mut query, \"%foo|\"), Some(\"foo\"));\n        assert_eq!(active_column(&mut query, \"%|\"), None);\n        assert_eq!(active_column(&mut query, \"%baz|\"), None);\n        assert_eq!(active_column(&mut query, \"%quiz%|\"), None);\n        assert_eq!(active_column(&mut query, \"%foo hello| world\"), Some(\"foo\"));\n        assert_eq!(active_column(&mut query, \"%foo hello world|\"), Some(\"foo\"));\n        assert_eq!(active_column(&mut query, \"%foo| hello world\"), Some(\"foo\"));\n        assert_eq!(active_column(&mut query, \"%|foo hello world\"), Some(\"foo\"));\n        assert_eq!(active_column(&mut query, \"%f|oo hello world\"), Some(\"foo\"));\n        assert_eq!(active_column(&mut query, \"hello %f|oo world\"), Some(\"foo\"));\n        assert_eq!(\n            active_column(&mut query, \"hello %f|oo world %bar !\"),\n            Some(\"foo\")\n        );\n        assert_eq!(\n            active_column(&mut query, \"hello %foo wo|rld %bar !\"),\n            Some(\"foo\")\n        );\n        assert_eq!(\n            active_column(&mut query, \"hello %foo world %bar !|\"),\n            Some(\"bar\")\n        );\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/picker.rs",
    "content": "mod handlers;\nmod query;\n\nuse crate::{\n    alt,\n    compositor::{self, Component, Compositor, Context, Event, EventResult},\n    ctrl, key, shift,\n    ui::{\n        self,\n        document::{render_document, LinePos, TextRenderer},\n        picker::query::PickerQuery,\n        text_decorations::DecorationManager,\n        EditorView,\n    },\n};\nuse futures_util::future::BoxFuture;\nuse helix_event::AsyncHook;\nuse nucleo::pattern::{CaseMatching, Normalization};\nuse nucleo::{Config, Nucleo};\nuse thiserror::Error;\nuse tokio::sync::mpsc::Sender;\nuse tui::{\n    buffer::Buffer as Surface,\n    layout::Constraint,\n    text::{Span, Spans},\n    widgets::{Block, BorderType, Cell, Row, Table},\n};\n\nuse tui::widgets::Widget;\n\nuse std::{\n    borrow::Cow,\n    collections::HashMap,\n    io::Read,\n    path::Path,\n    sync::{\n        atomic::{self, AtomicUsize},\n        Arc,\n    },\n};\n\nuse crate::ui::{Prompt, PromptEvent};\nuse helix_core::{\n    char_idx_at_visual_offset, fuzzy::MATCHER, movement::Direction,\n    text_annotations::TextAnnotations, unicode::segmentation::UnicodeSegmentation, Position,\n};\nuse helix_view::{\n    editor::Action,\n    graphics::{CursorKind, Margin, Modifier, Rect},\n    theme::Style,\n    view::ViewPosition,\n    Document, DocumentId, Editor,\n};\n\nuse self::handlers::{DynamicQueryChange, DynamicQueryHandler, PreviewHighlightHandler};\n\npub const ID: &str = \"picker\";\n\npub const MIN_AREA_WIDTH_FOR_PREVIEW: u16 = 72;\n/// Biggest file size to preview in bytes\npub const MAX_FILE_SIZE_FOR_PREVIEW: u64 = 10 * 1024 * 1024;\n\n#[derive(PartialEq, Eq, Hash)]\npub enum PathOrId<'a> {\n    Id(DocumentId),\n    Path(&'a Path),\n}\n\nimpl<'a> From<&'a Path> for PathOrId<'a> {\n    fn from(path: &'a Path) -> Self {\n        Self::Path(path)\n    }\n}\n\nimpl From<DocumentId> for PathOrId<'_> {\n    fn from(v: DocumentId) -> Self {\n        Self::Id(v)\n    }\n}\n\ntype FileCallback<T> = Box<dyn for<'a> Fn(&'a Editor, &'a T) -> Option<FileLocation<'a>>>;\n\n/// File path and range of lines (used to align and highlight lines)\npub type FileLocation<'a> = (PathOrId<'a>, Option<(usize, usize)>);\n\npub enum CachedPreview {\n    Document(Box<Document>),\n    Directory(Vec<(String, bool)>),\n    Binary,\n    LargeFile,\n    NotFound,\n}\n\n// We don't store this enum in the cache so as to avoid lifetime constraints\n// from borrowing a document already opened in the editor.\npub enum Preview<'picker, 'editor> {\n    Cached(&'picker CachedPreview),\n    EditorDocument(&'editor Document),\n}\n\nimpl Preview<'_, '_> {\n    fn document(&self) -> Option<&Document> {\n        match self {\n            Preview::EditorDocument(doc) => Some(doc),\n            Preview::Cached(CachedPreview::Document(doc)) => Some(doc),\n            _ => None,\n        }\n    }\n\n    fn dir_content(&self) -> Option<&Vec<(String, bool)>> {\n        match self {\n            Preview::Cached(CachedPreview::Directory(dir_content)) => Some(dir_content),\n            _ => None,\n        }\n    }\n\n    /// Alternate text to show for the preview.\n    fn placeholder(&self) -> &str {\n        match *self {\n            Self::EditorDocument(_) => \"<Invalid file location>\",\n            Self::Cached(preview) => match preview {\n                CachedPreview::Document(_) => \"<Invalid file location>\",\n                CachedPreview::Directory(_) => \"<Invalid directory location>\",\n                CachedPreview::Binary => \"<Binary file>\",\n                CachedPreview::LargeFile => \"<File too large to preview>\",\n                CachedPreview::NotFound => \"<File not found>\",\n            },\n        }\n    }\n}\n\nfn inject_nucleo_item<T, D>(\n    injector: &nucleo::Injector<T>,\n    columns: &[Column<T, D>],\n    item: T,\n    editor_data: &D,\n) {\n    injector.push(item, |item, dst| {\n        for (column, text) in columns.iter().filter(|column| column.filter).zip(dst) {\n            *text = column.format_text(item, editor_data).into()\n        }\n    });\n}\n\npub struct Injector<T, D> {\n    dst: nucleo::Injector<T>,\n    columns: Arc<[Column<T, D>]>,\n    editor_data: Arc<D>,\n    version: usize,\n    picker_version: Arc<AtomicUsize>,\n    /// A marker that requests a redraw when the injector drops.\n    /// This marker causes the \"running\" indicator to disappear when a background job\n    /// providing items is finished and drops. This could be wrapped in an [Arc] to ensure\n    /// that the redraw is only requested when all Injectors drop for a Picker (which removes\n    /// the \"running\" indicator) but the redraw handle is debounced so this is unnecessary.\n    _redraw: helix_event::RequestRedrawOnDrop,\n}\n\nimpl<I, D> Clone for Injector<I, D> {\n    fn clone(&self) -> Self {\n        Injector {\n            dst: self.dst.clone(),\n            columns: self.columns.clone(),\n            editor_data: self.editor_data.clone(),\n            version: self.version,\n            picker_version: self.picker_version.clone(),\n            _redraw: helix_event::RequestRedrawOnDrop,\n        }\n    }\n}\n\n#[derive(Error, Debug)]\n#[error(\"picker has been shut down\")]\npub struct InjectorShutdown;\n\nimpl<T, D> Injector<T, D> {\n    pub fn push(&self, item: T) -> Result<(), InjectorShutdown> {\n        if self.version != self.picker_version.load(atomic::Ordering::Relaxed) {\n            return Err(InjectorShutdown);\n        }\n\n        inject_nucleo_item(&self.dst, &self.columns, item, &self.editor_data);\n        Ok(())\n    }\n}\n\ntype ColumnFormatFn<T, D> = for<'a> fn(&'a T, &'a D) -> Cell<'a>;\n\npub struct Column<T, D> {\n    name: Arc<str>,\n    format: ColumnFormatFn<T, D>,\n    /// Whether the column should be passed to nucleo for matching and filtering.\n    /// `DynamicPicker` uses this so that the dynamic column (for example regex in\n    /// global search) is not used for filtering twice.\n    filter: bool,\n    hidden: bool,\n}\n\nimpl<T, D> Column<T, D> {\n    pub fn new(name: impl Into<Arc<str>>, format: ColumnFormatFn<T, D>) -> Self {\n        Self {\n            name: name.into(),\n            format,\n            filter: true,\n            hidden: false,\n        }\n    }\n\n    /// A column which does not display any contents\n    pub fn hidden(name: impl Into<Arc<str>>) -> Self {\n        let format = |_: &T, _: &D| unreachable!();\n\n        Self {\n            name: name.into(),\n            format,\n            filter: false,\n            hidden: true,\n        }\n    }\n\n    pub fn without_filtering(mut self) -> Self {\n        self.filter = false;\n        self\n    }\n\n    fn format<'a>(&self, item: &'a T, data: &'a D) -> Cell<'a> {\n        (self.format)(item, data)\n    }\n\n    fn format_text<'a>(&self, item: &'a T, data: &'a D) -> Cow<'a, str> {\n        let text: String = self.format(item, data).content.into();\n        text.into()\n    }\n}\n\n/// Returns a new list of options to replace the contents of the picker\n/// when called with the current picker query,\ntype DynQueryCallback<T, D> =\n    fn(&str, &mut Editor, Arc<D>, &Injector<T, D>) -> BoxFuture<'static, anyhow::Result<()>>;\n\npub struct Picker<T: 'static + Send + Sync, D: 'static> {\n    columns: Arc<[Column<T, D>]>,\n    primary_column: usize,\n    editor_data: Arc<D>,\n    version: Arc<AtomicUsize>,\n    matcher: Nucleo<T>,\n\n    /// Current height of the completions box\n    completion_height: u16,\n\n    cursor: u32,\n    prompt: Prompt,\n    query: PickerQuery,\n\n    /// Whether to show the preview panel (default true)\n    show_preview: bool,\n    /// Constraints for tabular formatting\n    widths: Vec<Constraint>,\n\n    callback_fn: PickerCallback<T>,\n    default_action: Action,\n\n    pub truncate_start: bool,\n    /// Caches paths to documents\n    preview_cache: HashMap<Arc<Path>, CachedPreview>,\n    read_buffer: Vec<u8>,\n    /// Given an item in the picker, return the file path and line number to display.\n    file_fn: Option<FileCallback<T>>,\n    /// An event handler for syntax highlighting the currently previewed file.\n    preview_highlight_handler: Sender<Arc<Path>>,\n    dynamic_query_handler: Option<Sender<DynamicQueryChange>>,\n}\n\nimpl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {\n    pub fn stream(\n        columns: impl IntoIterator<Item = Column<T, D>>,\n        editor_data: D,\n    ) -> (Nucleo<T>, Injector<T, D>) {\n        let columns: Arc<[_]> = columns.into_iter().collect();\n        let matcher_columns = columns.iter().filter(|col| col.filter).count() as u32;\n        assert!(matcher_columns > 0);\n        let matcher = Nucleo::new(\n            Config::DEFAULT,\n            Arc::new(helix_event::request_redraw),\n            None,\n            matcher_columns,\n        );\n        let streamer = Injector {\n            dst: matcher.injector(),\n            columns,\n            editor_data: Arc::new(editor_data),\n            version: 0,\n            picker_version: Arc::new(AtomicUsize::new(0)),\n            _redraw: helix_event::RequestRedrawOnDrop,\n        };\n        (matcher, streamer)\n    }\n\n    pub fn new<C, O, F>(\n        columns: C,\n        primary_column: usize,\n        options: O,\n        editor_data: D,\n        callback_fn: F,\n    ) -> Self\n    where\n        C: IntoIterator<Item = Column<T, D>>,\n        O: IntoIterator<Item = T>,\n        F: Fn(&mut Context, &T, Action) + 'static,\n    {\n        let columns: Arc<[_]> = columns.into_iter().collect();\n        let matcher_columns = columns\n            .iter()\n            .filter(|col: &&Column<T, D>| col.filter)\n            .count() as u32;\n        assert!(matcher_columns > 0);\n        let matcher = Nucleo::new(\n            Config::DEFAULT,\n            Arc::new(helix_event::request_redraw),\n            None,\n            matcher_columns,\n        );\n        let injector = matcher.injector();\n        for item in options {\n            inject_nucleo_item(&injector, &columns, item, &editor_data);\n        }\n        Self::with(\n            matcher,\n            columns,\n            primary_column,\n            Arc::new(editor_data),\n            Arc::new(AtomicUsize::new(0)),\n            callback_fn,\n        )\n    }\n\n    pub fn with_stream(\n        matcher: Nucleo<T>,\n        primary_column: usize,\n        injector: Injector<T, D>,\n        callback_fn: impl Fn(&mut Context, &T, Action) + 'static,\n    ) -> Self {\n        Self::with(\n            matcher,\n            injector.columns,\n            primary_column,\n            injector.editor_data,\n            injector.picker_version,\n            callback_fn,\n        )\n    }\n\n    fn with(\n        matcher: Nucleo<T>,\n        columns: Arc<[Column<T, D>]>,\n        default_column: usize,\n        editor_data: Arc<D>,\n        version: Arc<AtomicUsize>,\n        callback_fn: impl Fn(&mut Context, &T, Action) + 'static,\n    ) -> Self {\n        assert!(!columns.is_empty());\n\n        let prompt = Prompt::new(\n            \"\".into(),\n            None,\n            ui::completers::none,\n            |_editor: &mut Context, _pattern: &str, _event: PromptEvent| {},\n        );\n\n        let widths = columns\n            .iter()\n            .map(|column| Constraint::Length(column.name.chars().count() as u16))\n            .collect();\n\n        let query = PickerQuery::new(columns.iter().map(|col| &col.name).cloned(), default_column);\n\n        Self {\n            columns,\n            primary_column: default_column,\n            matcher,\n            editor_data,\n            version,\n            cursor: 0,\n            prompt,\n            query,\n            truncate_start: true,\n            show_preview: true,\n            callback_fn: Box::new(callback_fn),\n            default_action: Action::Replace,\n            completion_height: 0,\n            widths,\n            preview_cache: HashMap::new(),\n            read_buffer: Vec::with_capacity(1024),\n            file_fn: None,\n            preview_highlight_handler: PreviewHighlightHandler::<T, D>::default().spawn(),\n            dynamic_query_handler: None,\n        }\n    }\n\n    pub fn injector(&self) -> Injector<T, D> {\n        Injector {\n            dst: self.matcher.injector(),\n            columns: self.columns.clone(),\n            editor_data: self.editor_data.clone(),\n            version: self.version.load(atomic::Ordering::Relaxed),\n            picker_version: self.version.clone(),\n            _redraw: helix_event::RequestRedrawOnDrop,\n        }\n    }\n\n    pub fn truncate_start(mut self, truncate_start: bool) -> Self {\n        self.truncate_start = truncate_start;\n        self\n    }\n\n    pub fn with_preview(\n        mut self,\n        preview_fn: impl for<'a> Fn(&'a Editor, &'a T) -> Option<FileLocation<'a>> + 'static,\n    ) -> Self {\n        self.file_fn = Some(Box::new(preview_fn));\n        // assumption: if we have a preview we are matching paths... If this is ever\n        // not true this could be a separate builder function\n        self.matcher.update_config(Config::DEFAULT.match_paths());\n        self\n    }\n\n    pub fn with_history_register(mut self, history_register: Option<char>) -> Self {\n        self.prompt.with_history_register(history_register);\n        self\n    }\n\n    pub fn with_initial_cursor(mut self, cursor: u32) -> Self {\n        self.cursor = cursor;\n        self\n    }\n\n    pub fn with_dynamic_query(\n        mut self,\n        callback: DynQueryCallback<T, D>,\n        debounce_ms: Option<u64>,\n    ) -> Self {\n        let handler = DynamicQueryHandler::new(callback, debounce_ms).spawn();\n        let event = DynamicQueryChange {\n            query: self.primary_query(),\n            // Treat the initial query as a paste.\n            is_paste: true,\n        };\n        helix_event::send_blocking(&handler, event);\n        self.dynamic_query_handler = Some(handler);\n        self\n    }\n\n    pub fn with_default_action(mut self, action: Action) -> Self {\n        self.default_action = action;\n        self\n    }\n\n    /// Move the cursor by a number of lines, either down (`Forward`) or up (`Backward`)\n    pub fn move_by(&mut self, amount: u32, direction: Direction) {\n        let len = self.matcher.snapshot().matched_item_count();\n\n        if len == 0 {\n            // No results, can't move.\n            return;\n        }\n\n        match direction {\n            Direction::Forward => {\n                self.cursor = self.cursor.saturating_add(amount) % len;\n            }\n            Direction::Backward => {\n                self.cursor = self.cursor.saturating_add(len).saturating_sub(amount) % len;\n            }\n        }\n    }\n\n    /// Move the cursor down by exactly one page. After the last page comes the first page.\n    pub fn page_up(&mut self) {\n        self.move_by(self.completion_height as u32, Direction::Backward);\n    }\n\n    /// Move the cursor up by exactly one page. After the first page comes the last page.\n    pub fn page_down(&mut self) {\n        self.move_by(self.completion_height as u32, Direction::Forward);\n    }\n\n    /// Move the cursor to the first entry\n    pub fn to_start(&mut self) {\n        self.cursor = 0;\n    }\n\n    /// Move the cursor to the last entry\n    pub fn to_end(&mut self) {\n        self.cursor = self\n            .matcher\n            .snapshot()\n            .matched_item_count()\n            .saturating_sub(1);\n    }\n\n    pub fn selection(&self) -> Option<&T> {\n        self.matcher\n            .snapshot()\n            .get_matched_item(self.cursor)\n            .map(|item| item.data)\n    }\n\n    fn primary_query(&self) -> Arc<str> {\n        self.query\n            .get(&self.columns[self.primary_column].name)\n            .cloned()\n            .unwrap_or_else(|| \"\".into())\n    }\n\n    fn header_height(&self) -> u16 {\n        if self.columns.len() > 1 {\n            1\n        } else {\n            0\n        }\n    }\n\n    pub fn toggle_preview(&mut self) {\n        self.show_preview = !self.show_preview;\n    }\n\n    fn prompt_handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult {\n        if let EventResult::Consumed(_) = self.prompt.handle_event(event, cx) {\n            self.handle_prompt_change(matches!(event, Event::Paste(_)));\n        }\n        EventResult::Consumed(None)\n    }\n\n    fn handle_prompt_change(&mut self, is_paste: bool) {\n        // TODO: better track how the pattern has changed\n        let line = self.prompt.line();\n        let old_query = self.query.parse(line);\n        if self.query == old_query {\n            return;\n        }\n        // If the query has meaningfully changed, reset the cursor to the top of the results.\n        self.cursor = 0;\n        // Have nucleo reparse each changed column.\n        for (i, column) in self\n            .columns\n            .iter()\n            .filter(|column| column.filter)\n            .enumerate()\n        {\n            let pattern = self\n                .query\n                .get(&column.name)\n                .map(|f| &**f)\n                .unwrap_or_default();\n            let old_pattern = old_query\n                .get(&column.name)\n                .map(|f| &**f)\n                .unwrap_or_default();\n            // Fastlane: most columns will remain unchanged after each edit.\n            if pattern == old_pattern {\n                continue;\n            }\n            let is_append = pattern.starts_with(old_pattern);\n            self.matcher.pattern.reparse(\n                i,\n                pattern,\n                CaseMatching::Smart,\n                Normalization::Smart,\n                is_append,\n            );\n        }\n        // If this is a dynamic picker, notify the query hook that the primary\n        // query might have been updated.\n        if let Some(handler) = &self.dynamic_query_handler {\n            let event = DynamicQueryChange {\n                query: self.primary_query(),\n                is_paste,\n            };\n            helix_event::send_blocking(handler, event);\n        }\n    }\n\n    /// Get (cached) preview for the currently selected item. If a document corresponding\n    /// to the path is already open in the editor, it is used instead.\n    fn get_preview<'picker, 'editor>(\n        &'picker mut self,\n        editor: &'editor Editor,\n    ) -> Option<(Preview<'picker, 'editor>, Option<(usize, usize)>)> {\n        let current = self.selection()?;\n        let (path_or_id, range) = (self.file_fn.as_ref()?)(editor, current)?;\n\n        match path_or_id {\n            PathOrId::Path(path) => {\n                if let Some(doc) = editor.document_by_path(path) {\n                    return Some((Preview::EditorDocument(doc), range));\n                }\n\n                if self.preview_cache.contains_key(path) {\n                    // NOTE: we use `HashMap::get_key_value` here instead of indexing so we can\n                    // retrieve the `Arc<Path>` key. The `path` in scope here is a `&Path` and\n                    // we can cheaply clone the key for the preview highlight handler.\n                    let (path, preview) = self.preview_cache.get_key_value(path).unwrap();\n                    if matches!(preview, CachedPreview::Document(doc) if doc.syntax().is_none()) {\n                        helix_event::send_blocking(&self.preview_highlight_handler, path.clone());\n                    }\n                    return Some((Preview::Cached(preview), range));\n                }\n\n                let path: Arc<Path> = path.into();\n                let preview = std::fs::metadata(&path)\n                    .and_then(|metadata| {\n                        if metadata.is_dir() {\n                            let files = super::directory_content(&path, editor)?;\n                            let file_names: Vec<_> = files\n                                .iter()\n                                .filter_map(|(file_path, is_dir)| {\n                                    let name = file_path\n                                        .strip_prefix(&path)\n                                        .map(|p| Some(p.as_os_str()))\n                                        .unwrap_or_else(|_| file_path.file_name())?\n                                        .to_string_lossy();\n                                    if *is_dir {\n                                        Some((format!(\"{}/\", name), true))\n                                    } else {\n                                        Some((name.into_owned(), false))\n                                    }\n                                })\n                                .collect();\n                            Ok(CachedPreview::Directory(file_names))\n                        } else if metadata.is_file() {\n                            if metadata.len() > MAX_FILE_SIZE_FOR_PREVIEW {\n                                return Ok(CachedPreview::LargeFile);\n                            }\n                            let content_type = std::fs::File::open(&path).and_then(|file| {\n                                // Read up to 1kb to detect the content type\n                                let n = file.take(1024).read_to_end(&mut self.read_buffer)?;\n                                let content_type =\n                                    content_inspector::inspect(&self.read_buffer[..n]);\n                                self.read_buffer.clear();\n                                Ok(content_type)\n                            })?;\n                            if content_type.is_binary() {\n                                return Ok(CachedPreview::Binary);\n                            }\n                            let mut doc = Document::open(\n                                &path,\n                                None,\n                                false,\n                                editor.config.clone(),\n                                editor.syn_loader.clone(),\n                            )\n                            .or(Err(std::io::Error::new(\n                                std::io::ErrorKind::NotFound,\n                                \"Cannot open document\",\n                            )))?;\n                            let loader = editor.syn_loader.load();\n                            if let Some(language_config) = doc.detect_language_config(&loader) {\n                                doc.language = Some(language_config);\n                                // Asynchronously highlight the new document\n                                helix_event::send_blocking(\n                                    &self.preview_highlight_handler,\n                                    path.clone(),\n                                );\n                            }\n                            Ok(CachedPreview::Document(Box::new(doc)))\n                        } else {\n                            Err(std::io::Error::new(\n                                std::io::ErrorKind::NotFound,\n                                \"Neither a dir, nor a file\",\n                            ))\n                        }\n                    })\n                    .unwrap_or(CachedPreview::NotFound);\n                self.preview_cache.insert(path.clone(), preview);\n                Some((Preview::Cached(&self.preview_cache[&path]), range))\n            }\n            PathOrId::Id(id) => {\n                let doc = editor.documents.get(&id).unwrap();\n                Some((Preview::EditorDocument(doc), range))\n            }\n        }\n    }\n\n    fn render_picker(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        let status = self.matcher.tick(10);\n        let snapshot = self.matcher.snapshot();\n        if status.changed {\n            self.cursor = self\n                .cursor\n                .min(snapshot.matched_item_count().saturating_sub(1))\n        }\n\n        let text_style = cx.editor.theme.get(\"ui.text\");\n        let selected = cx.editor.theme.get(\"ui.text.focus\");\n        let highlight_style = cx.editor.theme.get(\"special\").add_modifier(Modifier::BOLD);\n\n        // -- Render the frame:\n        // clear area\n        let background = cx.editor.theme.get(\"ui.background\");\n        surface.clear_with(area, background);\n\n        const BLOCK: Block<'_> = Block::bordered();\n\n        // calculate the inner area inside the box\n        let inner = BLOCK.inner(area);\n\n        BLOCK.render(area, surface);\n\n        // -- Render the input bar:\n\n        let count = format!(\n            \"{}{}/{}\",\n            if status.running || self.matcher.active_injectors() > 0 {\n                \"(running) \"\n            } else {\n                \"\"\n            },\n            snapshot.matched_item_count(),\n            snapshot.item_count(),\n        );\n\n        let area = inner.clip_left(1).with_height(1);\n        let line_area = area.clip_right(count.len() as u16 + 1);\n\n        // render the prompt first since it will clear its background\n        self.prompt.render(line_area, surface, cx);\n\n        surface.set_stringn(\n            (area.x + area.width).saturating_sub(count.len() as u16 + 1),\n            area.y,\n            &count,\n            (count.len()).min(area.width as usize),\n            text_style,\n        );\n\n        // -- Separator\n        let sep_style = cx.editor.theme.get(\"ui.background.separator\");\n        let borders = BorderType::line_symbols(BorderType::Plain);\n        for x in inner.left()..inner.right() {\n            if let Some(cell) = surface.get_mut(x, inner.y + 1) {\n                cell.set_symbol(borders.horizontal).set_style(sep_style);\n            }\n        }\n\n        // -- Render the contents:\n        // subtract area of prompt from top\n        let inner = inner.clip_top(2);\n        let rows = inner.height.saturating_sub(self.header_height()) as u32;\n        let offset = self.cursor - (self.cursor % std::cmp::max(1, rows));\n        let cursor = self.cursor.saturating_sub(offset);\n        let end = offset\n            .saturating_add(rows)\n            .min(snapshot.matched_item_count());\n        let mut indices = Vec::new();\n        let mut matcher = MATCHER.lock();\n        matcher.config = Config::DEFAULT;\n        if self.file_fn.is_some() {\n            matcher.config.set_match_paths()\n        }\n\n        let options = snapshot.matched_items(offset..end).map(|item| {\n            let mut widths = self.widths.iter_mut();\n            let mut matcher_index = 0;\n\n            Row::new(self.columns.iter().map(|column| {\n                if column.hidden {\n                    return Cell::default();\n                }\n\n                let Some(Constraint::Length(max_width)) = widths.next() else {\n                    unreachable!();\n                };\n                let mut cell = column.format(item.data, &self.editor_data);\n                let width = if column.filter {\n                    snapshot.pattern().column_pattern(matcher_index).indices(\n                        item.matcher_columns[matcher_index].slice(..),\n                        &mut matcher,\n                        &mut indices,\n                    );\n                    indices.sort_unstable();\n                    indices.dedup();\n                    let mut indices = indices.drain(..);\n                    let mut next_highlight_idx = indices.next().unwrap_or(u32::MAX);\n                    let mut span_list = Vec::new();\n                    let mut current_span = String::new();\n                    let mut current_style = Style::default();\n                    let mut grapheme_idx = 0u32;\n                    let mut width = 0;\n\n                    let spans: &[Span] =\n                        cell.content.lines.first().map_or(&[], |it| it.0.as_slice());\n                    for span in spans {\n                        // this looks like a bug on first glance, we are iterating\n                        // graphemes but treating them as char indices. The reason that\n                        // this is correct is that nucleo will only ever consider the first char\n                        // of a grapheme (and discard the rest of the grapheme) so the indices\n                        // returned by nucleo are essentially grapheme indecies\n                        for grapheme in span.content.graphemes(true) {\n                            let style = if grapheme_idx == next_highlight_idx {\n                                next_highlight_idx = indices.next().unwrap_or(u32::MAX);\n                                span.style.patch(highlight_style)\n                            } else {\n                                span.style\n                            };\n                            if style != current_style {\n                                if !current_span.is_empty() {\n                                    span_list.push(Span::styled(current_span, current_style))\n                                }\n                                current_span = String::new();\n                                current_style = style;\n                            }\n                            current_span.push_str(grapheme);\n                            grapheme_idx += 1;\n                        }\n                        width += span.width();\n                    }\n\n                    span_list.push(Span::styled(current_span, current_style));\n                    cell = Cell::from(Spans::from(span_list));\n                    matcher_index += 1;\n                    width\n                } else {\n                    cell.content\n                        .lines\n                        .first()\n                        .map(|line| line.width())\n                        .unwrap_or_default()\n                };\n\n                if width as u16 > *max_width {\n                    *max_width = width as u16;\n                }\n\n                cell\n            }))\n        });\n\n        let mut table = Table::new(options)\n            .style(text_style)\n            .highlight_style(selected)\n            .highlight_symbol(\" > \")\n            .column_spacing(1)\n            .widths(&self.widths);\n\n        // -- Header\n        if self.columns.len() > 1 {\n            let active_column = self.query.active_column(self.prompt.position());\n            let header_style = cx.editor.theme.get(\"ui.picker.header\");\n            let header_column_style = cx.editor.theme.get(\"ui.picker.header.column\");\n\n            table = table.header(\n                Row::new(self.columns.iter().map(|column| {\n                    if column.hidden {\n                        Cell::default()\n                    } else {\n                        let style =\n                            if active_column.is_some_and(|name| Arc::ptr_eq(name, &column.name)) {\n                                cx.editor.theme.get(\"ui.picker.header.column.active\")\n                            } else {\n                                header_column_style\n                            };\n\n                        Cell::from(Span::styled(Cow::from(&*column.name), style))\n                    }\n                }))\n                .style(header_style),\n            );\n        }\n\n        use tui::widgets::TableState;\n\n        table.render_table(\n            inner,\n            surface,\n            &mut TableState {\n                offset: 0,\n                selected: Some(cursor as usize),\n            },\n            self.truncate_start,\n        );\n    }\n\n    fn render_preview(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        // -- Render the frame:\n        // clear area\n        let background = cx.editor.theme.get(\"ui.background\");\n        let text = cx.editor.theme.get(\"ui.text\");\n        let directory = cx.editor.theme.get(\"ui.text.directory\");\n        surface.clear_with(area, background);\n\n        const BLOCK: Block<'_> = Block::bordered();\n\n        // calculate the inner area inside the box\n        let inner = BLOCK.inner(area);\n        // 1 column gap on either side\n        let margin = Margin::horizontal(1);\n        let inner = inner.inner(margin);\n        BLOCK.render(area, surface);\n\n        if let Some((preview, range)) = self.get_preview(cx.editor) {\n            let doc = match preview.document() {\n                Some(doc)\n                    if range.is_none_or(|(start, end)| {\n                        start <= end && end <= doc.text().len_lines()\n                    }) =>\n                {\n                    doc\n                }\n                _ => {\n                    if let Some(dir_content) = preview.dir_content() {\n                        for (i, (path, is_dir)) in\n                            dir_content.iter().take(inner.height as usize).enumerate()\n                        {\n                            let style = if *is_dir { directory } else { text };\n                            surface.set_stringn(\n                                inner.x,\n                                inner.y + i as u16,\n                                path,\n                                inner.width as usize,\n                                style,\n                            );\n                        }\n                        return;\n                    }\n\n                    let alt_text = preview.placeholder();\n                    let x = inner.x + inner.width.saturating_sub(alt_text.len() as u16) / 2;\n                    let y = inner.y + inner.height / 2;\n                    surface.set_stringn(x, y, alt_text, inner.width as usize, text);\n                    return;\n                }\n            };\n\n            let mut offset = ViewPosition::default();\n            if let Some((start_line, end_line)) = range {\n                let height = end_line - start_line;\n                let text = doc.text().slice(..);\n                let start = text.line_to_char(start_line);\n                let middle = text.line_to_char(start_line + height / 2);\n                if height < inner.height as usize {\n                    let text_fmt = doc.text_format(inner.width, None);\n                    let annotations = TextAnnotations::default();\n                    (offset.anchor, offset.vertical_offset) = char_idx_at_visual_offset(\n                        text,\n                        middle,\n                        // align to middle\n                        -(inner.height as isize / 2),\n                        0,\n                        &text_fmt,\n                        &annotations,\n                    );\n                    if start < offset.anchor {\n                        offset.anchor = start;\n                        offset.vertical_offset = 0;\n                    }\n                } else {\n                    offset.anchor = start;\n                }\n            }\n\n            let loader = cx.editor.syn_loader.load();\n            let config = cx.editor.config();\n\n            let syntax_highlighter =\n                EditorView::doc_syntax_highlighter(doc, offset.anchor, area.height, &loader);\n            let mut overlay_highlights = Vec::new();\n            if doc\n                .language_config()\n                .and_then(|config| config.rainbow_brackets)\n                .unwrap_or(config.rainbow_brackets)\n            {\n                if let Some(overlay) = EditorView::doc_rainbow_highlights(\n                    doc,\n                    offset.anchor,\n                    area.height,\n                    &cx.editor.theme,\n                    &loader,\n                ) {\n                    overlay_highlights.push(overlay);\n                }\n            }\n\n            EditorView::doc_diagnostics_highlights_into(\n                doc,\n                &cx.editor.theme,\n                &mut overlay_highlights,\n            );\n\n            let mut decorations = DecorationManager::default();\n\n            if let Some((start, end)) = range {\n                let style = cx\n                    .editor\n                    .theme\n                    .try_get(\"ui.highlight\")\n                    .unwrap_or_else(|| cx.editor.theme.get(\"ui.selection\"));\n                let draw_highlight = move |renderer: &mut TextRenderer, pos: LinePos| {\n                    if (start..=end).contains(&pos.doc_line) {\n                        let area = Rect::new(\n                            renderer.viewport.x,\n                            pos.visual_line,\n                            renderer.viewport.width,\n                            1,\n                        );\n                        renderer.set_style(area, style)\n                    }\n                };\n                decorations.add_decoration(draw_highlight);\n            }\n\n            render_document(\n                surface,\n                inner,\n                doc,\n                offset,\n                // TODO: compute text annotations asynchronously here (like inlay hints)\n                &TextAnnotations::default(),\n                syntax_highlighter,\n                overlay_highlights,\n                &cx.editor.theme,\n                decorations,\n            );\n        }\n    }\n}\n\nimpl<I: 'static + Send + Sync, D: 'static + Send + Sync> Component for Picker<I, D> {\n    fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        // +---------+ +---------+\n        // |prompt   | |preview  |\n        // +---------+ |         |\n        // |picker   | |         |\n        // |         | |         |\n        // +---------+ +---------+\n\n        let render_preview =\n            self.show_preview && self.file_fn.is_some() && area.width > MIN_AREA_WIDTH_FOR_PREVIEW;\n\n        let picker_width = if render_preview {\n            area.width / 2\n        } else {\n            area.width\n        };\n\n        let picker_area = area.with_width(picker_width);\n        self.render_picker(picker_area, surface, cx);\n\n        if render_preview {\n            let preview_area = area.clip_left(picker_width);\n            self.render_preview(preview_area, surface, cx);\n        }\n    }\n\n    fn handle_event(&mut self, event: &Event, ctx: &mut Context) -> EventResult {\n        // TODO: keybinds for scrolling preview\n\n        let key_event = match event {\n            Event::Key(event) => *event,\n            Event::Paste(..) => return self.prompt_handle_event(event, ctx),\n            Event::Resize(..) => return EventResult::Consumed(None),\n            _ => return EventResult::Ignored(None),\n        };\n\n        let close_fn = |picker: &mut Self| {\n            // if the picker is very large don't store it as last_picker to avoid\n            // excessive memory consumption\n            let callback: compositor::Callback =\n                if picker.matcher.snapshot().item_count() > 1_000_000 {\n                    Box::new(|compositor: &mut Compositor, _ctx| {\n                        // remove the layer\n                        compositor.pop();\n                    })\n                } else {\n                    // stop streaming in new items in the background, really we should\n                    // be restarting the stream somehow once the picker gets\n                    // reopened instead (like for an FS crawl) that would also remove the\n                    // need for the special case above but that is pretty tricky\n                    picker.version.fetch_add(1, atomic::Ordering::Relaxed);\n                    Box::new(|compositor: &mut Compositor, _ctx| {\n                        // remove the layer\n                        compositor.last_picker = compositor.pop();\n                    })\n                };\n            EventResult::Consumed(Some(callback))\n        };\n\n        match key_event {\n            shift!(Tab) | key!(Up) | ctrl!('p') => {\n                self.move_by(1, Direction::Backward);\n            }\n            key!(Tab) | key!(Down) | ctrl!('n') => {\n                self.move_by(1, Direction::Forward);\n            }\n            key!(PageDown) | ctrl!('d') => {\n                self.page_down();\n            }\n            key!(PageUp) | ctrl!('u') => {\n                self.page_up();\n            }\n            key!(Home) => {\n                self.to_start();\n            }\n            key!(End) => {\n                self.to_end();\n            }\n            key!(Esc) | ctrl!('c') => return close_fn(self),\n            alt!(Enter) => {\n                if let Some(option) = self.selection() {\n                    (self.callback_fn)(ctx, option, self.default_action);\n                }\n            }\n            key!(Enter) => {\n                // If the prompt has a history completion and is empty, use enter to accept\n                // that completion\n                if let Some(completion) = self\n                    .prompt\n                    .first_history_completion(ctx.editor)\n                    .filter(|_| self.prompt.line().is_empty())\n                {\n                    // The percent character is used by the query language and needs to be\n                    // escaped with a backslash.\n                    let completion = if completion.contains('%') {\n                        completion.replace('%', \"\\\\%\")\n                    } else {\n                        completion.into_owned()\n                    };\n                    self.prompt.set_line(completion, ctx.editor);\n\n                    // Inserting from the history register is a paste.\n                    self.handle_prompt_change(true);\n                } else {\n                    if let Some(option) = self.selection() {\n                        (self.callback_fn)(ctx, option, self.default_action);\n                    }\n                    if let Some(history_register) = self.prompt.history_register() {\n                        if let Err(err) = ctx\n                            .editor\n                            .registers\n                            .push(history_register, self.primary_query().to_string())\n                        {\n                            ctx.editor.set_error(err.to_string());\n                        }\n                    }\n                    return close_fn(self);\n                }\n            }\n            ctrl!('s') => {\n                if let Some(option) = self.selection() {\n                    (self.callback_fn)(ctx, option, Action::HorizontalSplit);\n                }\n                return close_fn(self);\n            }\n            ctrl!('v') => {\n                if let Some(option) = self.selection() {\n                    (self.callback_fn)(ctx, option, Action::VerticalSplit);\n                }\n                return close_fn(self);\n            }\n            ctrl!('t') => {\n                self.toggle_preview();\n            }\n            _ => {\n                self.prompt_handle_event(event, ctx);\n            }\n        }\n\n        EventResult::Consumed(None)\n    }\n\n    fn cursor(&self, area: Rect, editor: &Editor) -> (Option<Position>, CursorKind) {\n        let block = Block::bordered();\n        // calculate the inner area inside the box\n        let inner = block.inner(area);\n\n        // prompt area\n        let render_preview =\n            self.show_preview && self.file_fn.is_some() && area.width > MIN_AREA_WIDTH_FOR_PREVIEW;\n\n        let picker_width = if render_preview {\n            area.width / 2\n        } else {\n            area.width\n        };\n        let area = inner.clip_left(1).with_height(1).with_width(picker_width);\n\n        self.prompt.cursor(area, editor)\n    }\n\n    fn required_size(&mut self, (width, height): (u16, u16)) -> Option<(u16, u16)> {\n        self.completion_height = height.saturating_sub(4 + self.header_height());\n        Some((width, height))\n    }\n\n    fn id(&self) -> Option<&'static str> {\n        Some(ID)\n    }\n}\nimpl<T: 'static + Send + Sync, D> Drop for Picker<T, D> {\n    fn drop(&mut self) {\n        // ensure we cancel any ongoing background threads streaming into the picker\n        self.version.fetch_add(1, atomic::Ordering::Relaxed);\n    }\n}\n\ntype PickerCallback<T> = Box<dyn Fn(&mut Context, &T, Action)>;\n"
  },
  {
    "path": "helix-term/src/ui/popup.rs",
    "content": "use crate::{\n    commands::Open,\n    compositor::{Callback, Component, Context, Event, EventResult},\n    ctrl, key,\n};\nuse tui::{\n    buffer::Buffer as Surface,\n    widgets::{Block, Widget},\n};\n\nuse helix_core::Position;\nuse helix_view::{\n    graphics::{Margin, Rect},\n    input::{MouseEvent, MouseEventKind},\n    Editor,\n};\n\nconst MIN_HEIGHT: u16 = 6;\nconst MAX_HEIGHT: u16 = 26;\nconst MAX_WIDTH: u16 = 120;\n\nstruct RenderInfo {\n    area: Rect,\n    child_height: u16,\n    render_borders: bool,\n    is_menu: bool,\n}\n\n// TODO: share logic with Menu, it's essentially Popup(render_fn), but render fn needs to return\n// a width/height hint. maybe Popup(Box<Component>)\n\npub struct Popup<T: Component> {\n    contents: T,\n    position: Option<Position>,\n    area: Rect,\n    position_bias: Open,\n    scroll_half_pages: usize,\n    auto_close: bool,\n    ignore_escape_key: bool,\n    id: &'static str,\n    has_scrollbar: bool,\n}\n\nimpl<T: Component> Popup<T> {\n    pub fn new(id: &'static str, contents: T) -> Self {\n        Self {\n            contents,\n            position: None,\n            position_bias: Open::Below,\n            area: Rect::new(0, 0, 0, 0),\n            scroll_half_pages: 0,\n            auto_close: false,\n            ignore_escape_key: false,\n            id,\n            has_scrollbar: true,\n        }\n    }\n\n    /// Set the anchor position next to which the popup should be drawn.\n    ///\n    /// Note that this is not the position of the top-left corner of the rendered popup itself,\n    /// but rather the screen-space position of the information to which the popup refers.\n    pub fn position(mut self, pos: Option<Position>) -> Self {\n        self.position = pos;\n        self\n    }\n\n    pub fn get_position(&self) -> Option<Position> {\n        self.position\n    }\n\n    /// Set the popup to prefer to render above or below the anchor position.\n    ///\n    /// This preference will be ignored if the viewport doesn't have enough space in the\n    /// chosen direction.\n    pub fn position_bias(mut self, bias: Open) -> Self {\n        self.position_bias = bias;\n        self\n    }\n\n    pub fn auto_close(mut self, auto_close: bool) -> Self {\n        self.auto_close = auto_close;\n        self\n    }\n\n    /// Ignores an escape keypress event, letting the outer layer\n    /// (usually the editor) handle it. This is useful for popups\n    /// in insert mode like completion and signature help where\n    /// the popup is closed on the mode change from insert to normal\n    /// which is done with the escape key. Otherwise the popup consumes\n    /// the escape key event and closes it, and an additional escape\n    /// would be required to exit insert mode.\n    pub fn ignore_escape_key(mut self, ignore: bool) -> Self {\n        self.ignore_escape_key = ignore;\n        self\n    }\n\n    pub fn scroll_half_page_down(&mut self) {\n        self.scroll_half_pages += 1;\n    }\n\n    pub fn scroll_half_page_up(&mut self) {\n        self.scroll_half_pages = self.scroll_half_pages.saturating_sub(1);\n    }\n\n    /// Toggles the Popup's scrollbar.\n    /// Consider disabling the scrollbar in case the child\n    /// already has its own.\n    pub fn with_scrollbar(mut self, enable_scrollbar: bool) -> Self {\n        self.has_scrollbar = enable_scrollbar;\n        self\n    }\n\n    pub fn contents(&self) -> &T {\n        &self.contents\n    }\n\n    pub fn contents_mut(&mut self) -> &mut T {\n        &mut self.contents\n    }\n\n    pub fn area(&mut self, viewport: Rect, editor: &Editor) -> Rect {\n        self.render_info(viewport, editor).area\n    }\n\n    fn render_info(&mut self, viewport: Rect, editor: &Editor) -> RenderInfo {\n        let mut position = editor.cursor().0.unwrap_or_default();\n        if let Some(old_position) = self\n            .position\n            .filter(|old_position| old_position.row == position.row)\n        {\n            position = old_position;\n        } else {\n            self.position = Some(position);\n        }\n\n        let is_menu = self\n            .contents\n            .type_name()\n            .starts_with(\"helix_term::ui::menu::Menu\");\n\n        let mut render_borders = if is_menu {\n            editor.menu_border()\n        } else {\n            editor.popup_border()\n        };\n\n        // -- make sure frame doesn't stick out of bounds\n        let mut rel_x = position.col as u16;\n        let mut rel_y = position.row as u16;\n\n        // if there's a orientation preference, use that\n        // if we're on the top part of the screen, do below\n        // if we're on the bottom part, do above\n        let can_put_below = viewport.height > rel_y + MIN_HEIGHT;\n        let can_put_above = rel_y.checked_sub(MIN_HEIGHT).is_some();\n        let final_pos = match self.position_bias {\n            Open::Below => match can_put_below {\n                true => Open::Below,\n                false => Open::Above,\n            },\n            Open::Above => match can_put_above {\n                true => Open::Above,\n                false => Open::Below,\n            },\n        };\n\n        // compute maximum space available for child\n        let mut max_height = match final_pos {\n            Open::Above => rel_y,\n            Open::Below => viewport.height.saturating_sub(1 + rel_y),\n        };\n        max_height = max_height.min(MAX_HEIGHT);\n        let mut max_width = viewport.width.saturating_sub(2).min(MAX_WIDTH);\n        render_borders = render_borders && max_height > 3 && max_width > 3;\n        if render_borders {\n            max_width -= 2;\n            max_height -= 2;\n        }\n\n        // compute required child size and reclamp\n        let (mut width, child_height) = self\n            .contents\n            .required_size((max_width, max_height))\n            .expect(\"Component needs required_size implemented in order to be embedded in a popup\");\n\n        width = width.min(MAX_WIDTH);\n        let height = if render_borders {\n            (child_height + 2).min(MAX_HEIGHT)\n        } else {\n            child_height.min(MAX_HEIGHT)\n        };\n        if render_borders {\n            width += 2;\n        }\n        if viewport.width <= rel_x + width + 2 {\n            rel_x = viewport.width.saturating_sub(width + 2);\n            width = viewport.width.saturating_sub(rel_x + 2)\n        }\n\n        let area = match final_pos {\n            Open::Above => {\n                rel_y = rel_y.saturating_sub(height);\n                Rect::new(rel_x, rel_y, width, position.row as u16 - rel_y)\n            }\n            Open::Below => {\n                rel_y += 1;\n                let y_max = viewport.bottom().min(height + rel_y);\n                Rect::new(rel_x, rel_y, width, y_max - rel_y)\n            }\n        };\n        RenderInfo {\n            area,\n            child_height,\n            render_borders,\n            is_menu,\n        }\n    }\n\n    fn handle_mouse_event(\n        &mut self,\n        &MouseEvent {\n            kind,\n            column: x,\n            row: y,\n            ..\n        }: &MouseEvent,\n    ) -> EventResult {\n        if self.auto_close && matches!(kind, MouseEventKind::Down(_)) {\n            let close_fn: Callback = Box::new(|compositor, _| {\n                // remove the layer\n                compositor.remove(self.id.as_ref());\n            });\n\n            return EventResult::Ignored(Some(close_fn));\n        }\n\n        let mouse_is_within_popup = x >= self.area.left()\n            && x < self.area.right()\n            && y >= self.area.top()\n            && y < self.area.bottom();\n\n        if !mouse_is_within_popup {\n            return EventResult::Ignored(None);\n        }\n\n        match kind {\n            MouseEventKind::ScrollDown if self.has_scrollbar => {\n                self.scroll_half_page_down();\n                EventResult::Consumed(None)\n            }\n            MouseEventKind::ScrollUp if self.has_scrollbar => {\n                self.scroll_half_page_up();\n                EventResult::Consumed(None)\n            }\n            _ => EventResult::Ignored(None),\n        }\n    }\n}\n\nimpl<T: Component> Component for Popup<T> {\n    fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult {\n        let key = match event {\n            Event::Key(event) => *event,\n            Event::Mouse(event) => return self.handle_mouse_event(event),\n            Event::Resize(_, _) => {\n                // TODO: calculate inner area, call component's handle_event with that area\n                return EventResult::Ignored(None);\n            }\n            _ => return EventResult::Ignored(None),\n        };\n\n        if key!(Esc) == key && self.ignore_escape_key {\n            return EventResult::Ignored(None);\n        }\n\n        let close_fn: Callback = Box::new(|compositor, _| {\n            // remove the layer\n            compositor.remove(self.id.as_ref());\n        });\n\n        // Code completion handles arrows and page up/down itself,\n        // but code lens does not. First check whether content knows\n        // about the key event. When not, check the default keys.\n        match self.contents.handle_event(event, cx) {\n            EventResult::Ignored(fn_once) => {\n                match key {\n                    // esc or ctrl-c aborts the completion and closes the menu\n                    key!(Esc) | ctrl!('c') => {\n                        let _ = self.contents.handle_event(event, cx);\n                        EventResult::Consumed(Some(close_fn))\n                    }\n                    key!(PageDown) | ctrl!('d') => {\n                        self.scroll_half_page_down();\n                        EventResult::Consumed(None)\n                    }\n                    key!(PageUp) | ctrl!('u') => {\n                        self.scroll_half_page_up();\n                        EventResult::Consumed(None)\n                    }\n                    _ => {\n                        // for some events, we want to process them but send ignore, specifically all input except\n                        // tab/enter/ctrl-k or whatever will confirm the selection/ ctrl-n/ctrl-p for scroll.\n\n                        if self.auto_close {\n                            EventResult::Ignored(Some(close_fn))\n                        } else {\n                            EventResult::Ignored(fn_once)\n                        }\n                    }\n                }\n            }\n            ev => ev,\n        }\n    }\n\n    fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {\n        let RenderInfo {\n            area,\n            child_height,\n            render_borders,\n            is_menu,\n        } = self.render_info(viewport, cx.editor);\n        self.area = area;\n\n        // clear area\n        let background = if is_menu {\n            // TODO: consistently style menu\n            cx.editor\n                .theme\n                .try_get(\"ui.menu\")\n                .unwrap_or_else(|| cx.editor.theme.get(\"ui.text\"))\n        } else {\n            cx.editor.theme.get(\"ui.popup\")\n        };\n        surface.clear_with(area, background);\n\n        let mut inner = area;\n        if render_borders {\n            inner = area.inner(Margin::all(1));\n            Widget::render(Block::bordered(), area, surface);\n        }\n        let border = usize::from(render_borders);\n\n        let max_offset = child_height.saturating_sub(inner.height) as usize;\n        let half_page_size = (inner.height / 2) as usize;\n        let scroll = max_offset.min(self.scroll_half_pages * half_page_size);\n        if half_page_size > 0 {\n            self.scroll_half_pages = scroll / half_page_size;\n        }\n        cx.scroll = Some(scroll);\n        self.contents.render(inner, surface, cx);\n\n        // render scrollbar if contents do not fit\n        if self.has_scrollbar {\n            let win_height = inner.height as usize;\n            let len = child_height as usize;\n            let fits = len <= win_height;\n            let scroll_style = cx.editor.theme.get(\"ui.menu.scroll\");\n\n            if !fits {\n                let scroll_height = win_height.pow(2).div_ceil(len).min(win_height);\n                let scroll_line = (win_height - scroll_height) * scroll\n                    / std::cmp::max(1, len.saturating_sub(win_height));\n\n                let mut cell;\n                for i in 0..win_height {\n                    cell =\n                        &mut surface[(inner.right() - 1 + border as u16, inner.top() + i as u16)];\n\n                    let half_block = if render_borders { \"▌\" } else { \"▐\" };\n\n                    if scroll_line <= i && i < scroll_line + scroll_height {\n                        // Draw scroll thumb\n                        cell.set_symbol(half_block);\n                        cell.set_fg(scroll_style.fg.unwrap_or(helix_view::theme::Color::Reset));\n                    } else if !render_borders {\n                        // Draw scroll track\n                        cell.set_symbol(half_block);\n                        cell.set_fg(scroll_style.bg.unwrap_or(helix_view::theme::Color::Reset));\n                    }\n                }\n            }\n        }\n    }\n\n    fn id(&self) -> Option<&'static str> {\n        Some(self.id)\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/prompt.rs",
    "content": "use crate::compositor::{Component, Compositor, Context, Event, EventResult};\nuse crate::{alt, ctrl, key, shift, ui};\nuse arc_swap::ArcSwap;\nuse helix_core::syntax;\nuse helix_view::document::Mode;\nuse helix_view::input::KeyEvent;\nuse helix_view::keyboard::KeyCode;\nuse std::sync::Arc;\nuse std::{borrow::Cow, ops::RangeFrom};\nuse tui::buffer::Buffer as Surface;\nuse tui::text::Span;\nuse tui::widgets::{Block, Widget};\n\nuse helix_core::{\n    unicode::segmentation::{GraphemeCursor, UnicodeSegmentation},\n    unicode::width::UnicodeWidthStr,\n    Position,\n};\nuse helix_view::{\n    graphics::{CursorKind, Margin, Rect},\n    Editor,\n};\n\ntype PromptCharHandler = Box<dyn Fn(&mut Prompt, char, &Context)>;\n\npub type Completion = (RangeFrom<usize>, Span<'static>);\ntype CompletionFn = Box<dyn FnMut(&Editor, &str) -> Vec<Completion>>;\ntype CallbackFn = Box<dyn FnMut(&mut Context, &str, PromptEvent)>;\npub type DocFn = Box<dyn Fn(&str) -> Option<Cow<str>>>;\n\npub struct Prompt {\n    prompt: Cow<'static, str>,\n    line: String,\n    cursor: usize,\n    // Fields used for Component callbacks and rendering:\n    line_area: Rect,\n    anchor: usize,\n    truncate_start: bool,\n    truncate_end: bool,\n    // ---\n    completion: Vec<Completion>,\n    selection: Option<usize>,\n    history_register: Option<char>,\n    history_pos: Option<usize>,\n    completion_fn: CompletionFn,\n    callback_fn: CallbackFn,\n    pub doc_fn: DocFn,\n    next_char_handler: Option<PromptCharHandler>,\n    language: Option<(&'static str, Arc<ArcSwap<syntax::Loader>>)>,\n}\n\n#[derive(Clone, Copy, PartialEq, Eq)]\npub enum PromptEvent {\n    /// The prompt input has been updated.\n    Update,\n    /// Validate and finalize the change.\n    Validate,\n    /// Abort the change, reverting to the initial state.\n    Abort,\n}\n\npub enum CompletionDirection {\n    Forward,\n    Backward,\n}\n\n#[derive(Debug, Clone, Copy)]\npub enum Movement {\n    BackwardChar(usize),\n    BackwardWord(usize),\n    ForwardChar(usize),\n    ForwardWord(usize),\n    StartOfLine,\n    EndOfLine,\n    None,\n}\n\nfn is_word_sep(c: char) -> bool {\n    c == std::path::MAIN_SEPARATOR || c.is_whitespace()\n}\n\nimpl Prompt {\n    pub fn new(\n        prompt: Cow<'static, str>,\n        history_register: Option<char>,\n        completion_fn: impl FnMut(&Editor, &str) -> Vec<Completion> + 'static,\n        callback_fn: impl FnMut(&mut Context, &str, PromptEvent) + 'static,\n    ) -> Self {\n        Self {\n            prompt,\n            line: String::new(),\n            cursor: 0,\n            line_area: Rect::default(),\n            anchor: 0,\n            truncate_start: false,\n            truncate_end: false,\n            completion: Vec::new(),\n            selection: None,\n            history_register,\n            history_pos: None,\n            completion_fn: Box::new(completion_fn),\n            callback_fn: Box::new(callback_fn),\n            doc_fn: Box::new(|_| None),\n            next_char_handler: None,\n            language: None,\n        }\n    }\n\n    /// Gets the byte index in the input representing the current cursor location.\n    #[inline]\n    pub(crate) fn position(&self) -> usize {\n        self.cursor\n    }\n\n    pub fn with_line(mut self, line: String, editor: &Editor) -> Self {\n        self.set_line(line, editor);\n        self\n    }\n\n    pub fn set_line(&mut self, line: String, editor: &Editor) {\n        let cursor = line.len();\n        self.line = line;\n        self.cursor = cursor;\n        self.recalculate_completion(editor);\n    }\n\n    pub fn with_language(\n        mut self,\n        language: &'static str,\n        loader: Arc<ArcSwap<syntax::Loader>>,\n    ) -> Self {\n        self.language = Some((language, loader));\n        self\n    }\n\n    pub fn line(&self) -> &String {\n        &self.line\n    }\n\n    pub fn with_history_register(&mut self, history_register: Option<char>) -> &mut Self {\n        self.history_register = history_register;\n        self\n    }\n\n    pub(crate) fn history_register(&self) -> Option<char> {\n        self.history_register\n    }\n\n    pub(crate) fn first_history_completion<'a>(\n        &'a self,\n        editor: &'a Editor,\n    ) -> Option<Cow<'a, str>> {\n        self.history_register\n            .and_then(|reg| editor.registers.first(reg, editor))\n    }\n\n    pub fn recalculate_completion(&mut self, editor: &Editor) {\n        self.exit_selection();\n        self.completion = (self.completion_fn)(editor, &self.line);\n    }\n\n    /// Compute the cursor position after applying movement\n    /// Taken from: <https://github.com/wez/wezterm/blob/e0b62d07ca9bf8ce69a61e30a3c20e7abc48ce7e/termwiz/src/lineedit/mod.rs#L516-L611>\n    fn eval_movement(&self, movement: Movement) -> usize {\n        match movement {\n            Movement::BackwardChar(rep) => {\n                let mut position = self.cursor;\n                for _ in 0..rep {\n                    let mut cursor = GraphemeCursor::new(position, self.line.len(), false);\n                    if let Ok(Some(pos)) = cursor.prev_boundary(&self.line, 0) {\n                        position = pos;\n                    } else {\n                        break;\n                    }\n                }\n                position\n            }\n            Movement::BackwardWord(rep) => {\n                let char_indices: Vec<(usize, char)> = self.line.char_indices().collect();\n                if char_indices.is_empty() {\n                    return self.cursor;\n                }\n                let mut char_position = char_indices\n                    .iter()\n                    .position(|(idx, _)| *idx == self.cursor)\n                    .unwrap_or(char_indices.len() - 1);\n\n                for _ in 0..rep {\n                    if char_position == 0 {\n                        break;\n                    }\n\n                    let mut found = None;\n                    for prev in (0..char_position - 1).rev() {\n                        if is_word_sep(char_indices[prev].1) {\n                            found = Some(prev + 1);\n                            break;\n                        }\n                    }\n\n                    char_position = found.unwrap_or(0);\n                }\n                char_indices[char_position].0\n            }\n            Movement::ForwardWord(rep) => {\n                let char_indices: Vec<(usize, char)> = self.line.char_indices().collect();\n                if char_indices.is_empty() {\n                    return self.cursor;\n                }\n                let mut char_position = char_indices\n                    .iter()\n                    .position(|(idx, _)| *idx == self.cursor)\n                    .unwrap_or(char_indices.len());\n\n                for _ in 0..rep {\n                    // Skip any non-whitespace characters\n                    while char_position < char_indices.len()\n                        && !is_word_sep(char_indices[char_position].1)\n                    {\n                        char_position += 1;\n                    }\n\n                    // Skip any whitespace characters\n                    while char_position < char_indices.len()\n                        && is_word_sep(char_indices[char_position].1)\n                    {\n                        char_position += 1;\n                    }\n\n                    // We are now on the start of the next word\n                }\n                char_indices\n                    .get(char_position)\n                    .map(|(i, _)| *i)\n                    .unwrap_or_else(|| self.line.len())\n            }\n            Movement::ForwardChar(rep) => {\n                let mut position = self.cursor;\n                for _ in 0..rep {\n                    let mut cursor = GraphemeCursor::new(position, self.line.len(), false);\n                    if let Ok(Some(pos)) = cursor.next_boundary(&self.line, 0) {\n                        position = pos;\n                    } else {\n                        break;\n                    }\n                }\n                position\n            }\n            Movement::StartOfLine => 0,\n            Movement::EndOfLine => self.line.len(),\n            Movement::None => self.cursor,\n        }\n    }\n\n    pub fn insert_char(&mut self, c: char, cx: &Context) {\n        if let Some(handler) = &self.next_char_handler.take() {\n            handler(self, c, cx);\n\n            self.next_char_handler = None;\n            return;\n        }\n\n        self.line.insert(self.cursor, c);\n        let mut cursor = GraphemeCursor::new(self.cursor, self.line.len(), false);\n        if let Ok(Some(pos)) = cursor.next_boundary(&self.line, 0) {\n            self.cursor = pos;\n        }\n        self.recalculate_completion(cx.editor);\n    }\n\n    pub fn insert_str(&mut self, s: &str, editor: &Editor) {\n        self.line.insert_str(self.cursor, s);\n        self.cursor += s.len();\n        self.recalculate_completion(editor);\n    }\n\n    pub fn move_cursor(&mut self, movement: Movement) {\n        let pos = self.eval_movement(movement);\n        self.cursor = pos\n    }\n\n    pub fn move_start(&mut self) {\n        self.cursor = 0;\n    }\n\n    pub fn move_end(&mut self) {\n        self.cursor = self.line.len();\n    }\n\n    pub fn delete_char_backwards(&mut self, editor: &Editor) {\n        let pos = self.eval_movement(Movement::BackwardChar(1));\n        self.line.replace_range(pos..self.cursor, \"\");\n        self.cursor = pos;\n\n        self.recalculate_completion(editor);\n    }\n\n    pub fn delete_char_forwards(&mut self, editor: &Editor) {\n        let pos = self.eval_movement(Movement::ForwardChar(1));\n        self.line.replace_range(self.cursor..pos, \"\");\n\n        self.recalculate_completion(editor);\n    }\n\n    pub fn delete_word_backwards(&mut self, editor: &Editor) {\n        let pos = self.eval_movement(Movement::BackwardWord(1));\n        self.line.replace_range(pos..self.cursor, \"\");\n        self.cursor = pos;\n\n        self.recalculate_completion(editor);\n    }\n\n    pub fn delete_word_forwards(&mut self, editor: &Editor) {\n        let pos = self.eval_movement(Movement::ForwardWord(1));\n        self.line.replace_range(self.cursor..pos, \"\");\n\n        self.recalculate_completion(editor);\n    }\n\n    pub fn kill_to_start_of_line(&mut self, editor: &Editor) {\n        let pos = self.eval_movement(Movement::StartOfLine);\n        self.line.replace_range(pos..self.cursor, \"\");\n        self.cursor = pos;\n\n        self.recalculate_completion(editor);\n    }\n\n    pub fn kill_to_end_of_line(&mut self, editor: &Editor) {\n        let pos = self.eval_movement(Movement::EndOfLine);\n        self.line.replace_range(self.cursor..pos, \"\");\n\n        self.recalculate_completion(editor);\n    }\n\n    pub fn clear(&mut self, editor: &Editor) {\n        self.line.clear();\n        self.cursor = 0;\n        self.recalculate_completion(editor);\n    }\n\n    pub fn change_history(\n        &mut self,\n        cx: &mut Context,\n        register: char,\n        direction: CompletionDirection,\n    ) {\n        (self.callback_fn)(cx, &self.line, PromptEvent::Abort);\n        let mut values = match cx.editor.registers.read(register, cx.editor) {\n            Some(values) if values.len() > 0 => values.rev(),\n            _ => return,\n        };\n\n        let end = values.len().saturating_sub(1);\n\n        let index = match direction {\n            CompletionDirection::Forward => self.history_pos.map_or(0, |i| i + 1),\n            CompletionDirection::Backward => self\n                .history_pos\n                .unwrap_or_else(|| values.len())\n                .saturating_sub(1),\n        }\n        .min(end);\n\n        self.line = values.nth(index).unwrap().to_string();\n        // Appease the borrow checker.\n        drop(values);\n\n        self.history_pos = Some(index);\n\n        self.move_end();\n        (self.callback_fn)(cx, &self.line, PromptEvent::Update);\n        self.recalculate_completion(cx.editor);\n    }\n\n    pub fn change_completion_selection(&mut self, direction: CompletionDirection) {\n        if self.completion.is_empty() {\n            return;\n        }\n\n        let index = match direction {\n            CompletionDirection::Forward => self.selection.map_or(0, |i| i + 1),\n            CompletionDirection::Backward => {\n                self.selection.unwrap_or(0) + self.completion.len() - 1\n            }\n        } % self.completion.len();\n\n        self.selection = Some(index);\n\n        let (range, item) = &self.completion[index];\n\n        self.line.replace_range(range.clone(), &item.content);\n\n        self.move_end();\n    }\n\n    pub fn exit_selection(&mut self) {\n        self.selection = None;\n    }\n}\n\nconst BASE_WIDTH: u16 = 30;\n\nimpl Prompt {\n    pub fn render_prompt(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        let theme = &cx.editor.theme;\n        let prompt_color = theme.get(\"ui.text\");\n        let completion_color = theme.get(\"ui.menu\");\n        let selected_color = theme.get(\"ui.menu.selected\");\n        let suggestion_color = theme.get(\"ui.text.inactive\");\n        let background = theme.get(\"ui.background\");\n        // completion\n\n        let max_len = self\n            .completion\n            .iter()\n            .map(|(_, completion)| completion.content.len() as u16)\n            .max()\n            .unwrap_or(BASE_WIDTH)\n            .max(BASE_WIDTH);\n\n        let cols = std::cmp::max(1, area.width / max_len);\n        let col_width = (area.width.saturating_sub(cols)) / cols;\n\n        let height = (self.completion.len() as u16)\n            .div_ceil(cols)\n            .min(10) // at most 10 rows (or less)\n            .min(area.height.saturating_sub(1));\n\n        let completion_area = Rect::new(\n            area.x,\n            (area.height - height).saturating_sub(1),\n            area.width,\n            height,\n        );\n\n        if completion_area.height > 0 && !self.completion.is_empty() {\n            let area = completion_area;\n            let background = theme.get(\"ui.menu\");\n\n            let items = height as usize * cols as usize;\n\n            let offset = self\n                .selection\n                .map(|selection| selection / items * items)\n                .unwrap_or_default();\n\n            surface.clear_with(area, background);\n\n            let mut row = 0;\n            let mut col = 0;\n\n            for (i, (_range, completion)) in\n                self.completion.iter().enumerate().skip(offset).take(items)\n            {\n                let is_selected = Some(i) == self.selection;\n\n                let completion_item_style = if is_selected {\n                    selected_color\n                } else {\n                    completion_color.patch(completion.style)\n                };\n\n                surface.set_stringn(\n                    area.x + col * (1 + col_width),\n                    area.y + row,\n                    &completion.content,\n                    col_width.saturating_sub(1) as usize,\n                    completion_item_style,\n                );\n\n                row += 1;\n                if row > area.height - 1 {\n                    row = 0;\n                    col += 1;\n                }\n            }\n        }\n\n        if let Some(doc) = (self.doc_fn)(&self.line) {\n            let mut text = ui::Text::new(doc.to_string());\n\n            let max_width = BASE_WIDTH * 3;\n            let padding = 1;\n\n            let viewport = area;\n\n            let (_width, height) = ui::text::required_size(&text.contents, max_width);\n\n            let area = viewport.intersection(Rect::new(\n                completion_area.x,\n                completion_area.y.saturating_sub(height + padding * 2),\n                max_width,\n                height + padding * 2,\n            ));\n\n            let background = theme.get(\"ui.help\");\n            surface.clear_with(area, background);\n\n            let block = Block::bordered()\n                // .title(self.title.as_str())\n                .border_style(background);\n\n            let inner = block.inner(area).inner(Margin::horizontal(1));\n\n            block.render(area, surface);\n            text.render(inner, surface, cx);\n        }\n\n        let line = area.height - 1;\n        surface.clear_with(area.clip_top(line), background);\n        // render buffer text\n        surface.set_string(area.x, area.y + line, &self.prompt, prompt_color);\n\n        self.line_area = area\n            .clip_left(self.prompt.len() as u16)\n            .clip_top(line)\n            .clip_right(2);\n\n        if self.line.is_empty() {\n            self.anchor = 0;\n            // Show the most recently entered value as a suggestion.\n            if let Some(suggestion) = self.first_history_completion(cx.editor) {\n                surface.set_string(\n                    self.line_area.x,\n                    self.line_area.y,\n                    suggestion,\n                    suggestion_color,\n                );\n            }\n        } else if let Some((language, loader)) = self.language.as_ref() {\n            let mut text: ui::text::Text = crate::ui::markdown::highlighted_code_block(\n                &self.line,\n                language,\n                Some(&cx.editor.theme),\n                &loader.load(),\n                None,\n            )\n            .into();\n            text.render(self.line_area, surface, cx);\n        } else {\n            let line_width = self.line_area.width as usize;\n\n            if self.line.width() < line_width {\n                self.anchor = 0;\n            } else if self.cursor <= self.anchor {\n                // Ensure the grapheme under the cursor is in view.\n                self.anchor = self.line[..self.cursor]\n                    .grapheme_indices(true)\n                    .next_back()\n                    .map(|(i, _)| i)\n                    .unwrap_or_default();\n            } else if self.line[self.anchor..self.cursor].width() > line_width {\n                // Set the anchor to the last grapheme cluster before the width is exceeded.\n                let mut width = 0;\n                self.anchor = self.line[..self.cursor]\n                    .grapheme_indices(true)\n                    .rev()\n                    .find_map(|(idx, g)| {\n                        width += g.width();\n                        if width > line_width {\n                            Some(idx + g.len())\n                        } else {\n                            None\n                        }\n                    })\n                    .unwrap();\n            }\n\n            self.truncate_start = self.anchor > 0;\n            self.truncate_end = self.line[self.anchor..].width() > line_width;\n\n            // if we keep inserting characters just before the end elipsis, we move the anchor\n            // so that those new characters are displayed\n            if self.truncate_end && self.line[self.anchor..self.cursor].width() >= line_width {\n                // Move the anchor forward by one non-zero-width grapheme.\n                self.anchor += self.line[self.anchor..]\n                    .grapheme_indices(true)\n                    .find_map(|(idx, g)| {\n                        if g.width() > 0 {\n                            Some(idx + g.len())\n                        } else {\n                            None\n                        }\n                    })\n                    .unwrap();\n            }\n\n            surface.set_string_anchored(\n                self.line_area.x,\n                self.line_area.y,\n                self.truncate_start,\n                self.truncate_end,\n                &self.line.as_str()[self.anchor..],\n                line_width,\n                |_| prompt_color,\n            );\n        }\n    }\n}\n\nimpl Component for Prompt {\n    fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult {\n        let event = match event {\n            Event::Paste(data) => {\n                self.insert_str(data, cx.editor);\n                self.recalculate_completion(cx.editor);\n                return EventResult::Consumed(None);\n            }\n            Event::Key(event) => *event,\n            Event::Resize(..) => return EventResult::Consumed(None),\n            _ => return EventResult::Ignored(None),\n        };\n\n        let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor, _| {\n            // remove the layer\n            compositor.pop();\n        })));\n\n        match event {\n            ctrl!('c') | key!(Esc) => {\n                (self.callback_fn)(cx, &self.line, PromptEvent::Abort);\n                return close_fn;\n            }\n            alt!('b') | ctrl!(Left) => self.move_cursor(Movement::BackwardWord(1)),\n            alt!('f') | ctrl!(Right) => self.move_cursor(Movement::ForwardWord(1)),\n            ctrl!('b') | key!(Left) => self.move_cursor(Movement::BackwardChar(1)),\n            ctrl!('f') | key!(Right) => self.move_cursor(Movement::ForwardChar(1)),\n            ctrl!('e') | key!(End) => self.move_end(),\n            ctrl!('a') | key!(Home) => self.move_start(),\n            ctrl!('w') | alt!(Backspace) | ctrl!(Backspace) => {\n                self.delete_word_backwards(cx.editor);\n                (self.callback_fn)(cx, &self.line, PromptEvent::Update);\n            }\n            alt!('d') | alt!(Delete) | ctrl!(Delete) => {\n                self.delete_word_forwards(cx.editor);\n                (self.callback_fn)(cx, &self.line, PromptEvent::Update);\n            }\n            ctrl!('k') => {\n                self.kill_to_end_of_line(cx.editor);\n                (self.callback_fn)(cx, &self.line, PromptEvent::Update);\n            }\n            ctrl!('u') => {\n                self.kill_to_start_of_line(cx.editor);\n                (self.callback_fn)(cx, &self.line, PromptEvent::Update);\n            }\n            ctrl!('h') | key!(Backspace) | shift!(Backspace) => {\n                self.delete_char_backwards(cx.editor);\n                (self.callback_fn)(cx, &self.line, PromptEvent::Update);\n            }\n            ctrl!('d') | key!(Delete) => {\n                self.delete_char_forwards(cx.editor);\n                (self.callback_fn)(cx, &self.line, PromptEvent::Update);\n            }\n            ctrl!('s') => {\n                let (view, doc) = current!(cx.editor);\n                let text = doc.text().slice(..);\n\n                use helix_core::textobject;\n                let range = textobject::textobject_word(\n                    text,\n                    doc.selection(view.id).primary(),\n                    textobject::TextObject::Inside,\n                    1,\n                    false,\n                );\n                let line = text.slice(range.from()..range.to()).to_string();\n                if !line.is_empty() {\n                    self.insert_str(line.as_str(), cx.editor);\n                    (self.callback_fn)(cx, &self.line, PromptEvent::Update);\n                }\n            }\n            key!(Enter) => {\n                if self.selection.is_some() && self.line.ends_with(std::path::MAIN_SEPARATOR) {\n                    self.recalculate_completion(cx.editor);\n                } else {\n                    let last_item = self\n                        .first_history_completion(cx.editor)\n                        .map(|entry| entry.to_string())\n                        .unwrap_or_else(|| String::from(\"\"));\n\n                    // handle executing with last command in history if nothing entered\n                    let input = if self.line.is_empty() {\n                        &last_item\n                    } else {\n                        if last_item != self.line {\n                            // store in history\n                            if let Some(register) = self.history_register {\n                                if let Err(err) =\n                                    cx.editor.registers.push(register, self.line.clone())\n                                {\n                                    cx.editor.set_error(err.to_string());\n                                }\n                            };\n                        }\n\n                        &self.line\n                    };\n\n                    (self.callback_fn)(cx, input, PromptEvent::Validate);\n\n                    return close_fn;\n                }\n            }\n            ctrl!('p') | key!(Up) => {\n                if let Some(register) = self.history_register {\n                    self.change_history(cx, register, CompletionDirection::Backward);\n                }\n            }\n            ctrl!('n') | key!(Down) => {\n                if let Some(register) = self.history_register {\n                    self.change_history(cx, register, CompletionDirection::Forward);\n                }\n            }\n            key!(Tab) => {\n                self.change_completion_selection(CompletionDirection::Forward);\n                // if single completion candidate is a directory list content in completion\n                if self.completion.len() == 1 && self.line.ends_with(std::path::MAIN_SEPARATOR) {\n                    self.recalculate_completion(cx.editor);\n                }\n                (self.callback_fn)(cx, &self.line, PromptEvent::Update)\n            }\n            shift!(Tab) => {\n                self.change_completion_selection(CompletionDirection::Backward);\n                (self.callback_fn)(cx, &self.line, PromptEvent::Update)\n            }\n            ctrl!('q') => self.exit_selection(),\n            ctrl!('r') => {\n                self.completion = cx\n                    .editor\n                    .registers\n                    .iter_preview()\n                    .map(|(ch, preview)| (0.., format!(\"{} {}\", ch, &preview).into()))\n                    .collect();\n                self.next_char_handler = Some(Box::new(|prompt, c, context| {\n                    prompt.insert_str(\n                        &context\n                            .editor\n                            .registers\n                            .first(c, context.editor)\n                            .unwrap_or_default(),\n                        context.editor,\n                    );\n                }));\n                (self.callback_fn)(cx, &self.line, PromptEvent::Update);\n                return EventResult::Consumed(None);\n            }\n            // any char event that's not mapped to any other combo\n            KeyEvent {\n                code: KeyCode::Char(c),\n                modifiers: _,\n            } => {\n                self.insert_char(c, cx);\n                (self.callback_fn)(cx, &self.line, PromptEvent::Update);\n            }\n            _ => (),\n        };\n\n        EventResult::Consumed(None)\n    }\n\n    fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        self.render_prompt(area, surface, cx)\n    }\n\n    fn cursor(&self, area: Rect, editor: &Editor) -> (Option<Position>, CursorKind) {\n        let area = area\n            .clip_left(self.prompt.len() as u16)\n            .clip_right(if self.prompt.is_empty() { 2 } else { 0 });\n\n        let mut col = area.left() as usize + self.line[self.anchor..self.cursor].width();\n\n        // ensure the cursor does not go beyond elipses\n        if self.truncate_end\n            && self.line[self.anchor..self.cursor].width() >= self.line_area.width as usize\n        {\n            col -= 1;\n        }\n\n        if self.truncate_start && self.cursor == self.anchor {\n            col += self.line[self.cursor..]\n                .graphemes(true)\n                .next()\n                .map_or(0, |g| g.width());\n        }\n\n        let line = area.height as usize - 1;\n\n        (\n            Some(Position::new(area.y as usize + line, col)),\n            editor.config().cursor_shape.from_mode(Mode::Insert),\n        )\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/select.rs",
    "content": "use std::borrow::Cow;\n\nuse helix_view::{graphics::Rect, Editor};\nuse tui::{\n    buffer::Buffer as Surface,\n    widgets::{Block, Widget as _},\n};\n\nuse crate::compositor::{Component, Context, Event, EventResult};\n\nuse super::{menu::Item, Menu, PromptEvent, Text};\n\npub struct Select<T: Item> {\n    message: Text,\n    options: Menu<T>,\n}\n\nimpl<T: Item> Select<T> {\n    pub fn new<M, I, F>(message: M, options: I, data: T::Data, callback: F) -> Self\n    where\n        M: Into<Cow<'static, str>>,\n        I: IntoIterator<Item = T>,\n        F: Fn(&mut Editor, &T, PromptEvent) + 'static,\n    {\n        let message = tui::text::Text::from(message.into()).into();\n        let options: Vec<_> = options.into_iter().collect();\n        assert!(!options.is_empty());\n        let mut menu = Menu::new(options, data, move |editor, option, event| {\n            // Options are non-empty (asserted above) and an option is selected by default,\n            // so `option` must be Some here.\n            let option = &option.unwrap();\n            callback(editor, option, event)\n        })\n        .auto_close(true);\n        // Select the first option by default.\n        menu.move_down();\n\n        Self {\n            message,\n            options: menu,\n        }\n    }\n}\n\nimpl<T: Item> Component for Select<T> {\n    fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult {\n        self.options.handle_event(event, cx)\n    }\n\n    fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {\n        let (message_width, message_height) = self.message.required_size(viewport).unwrap();\n        let (menu_width, menu_height) = self.options.required_size(viewport).unwrap();\n        Some((\n            menu_width.max(message_width + 2),\n            message_height + menu_height + 2,\n        ))\n    }\n\n    fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {\n        const BLOCK: Block<'_> = Block::bordered();\n\n        // +---------------------+\n        // | message             |\n        // +---------------------+\n        //   options menu\n        //\n        //\n\n        // Limit the text width to 80% of the screen or 80 columns, whichever is\n        // smaller.\n        let max_width = 80.min(((area.width as u32) * 80u32 / 100) as u16);\n        let (message_width, message_height) =\n            super::text::required_size(&self.message.contents, max_width);\n        let (_, menu_height) = self\n            .options\n            .required_size((max_width, area.height))\n            .unwrap();\n        // + 2 for borders and another + 2 for horizontal padding\n        let width = message_width + 4;\n        let height = message_height + 2 + menu_height;\n        let area = Rect {\n            x: (area.width / 2) - width / 2,\n            y: (area.height / 2) - height / 2,\n            width,\n            height,\n        };\n\n        // Message\n        let background = cx.editor.theme.get(\"ui.background\");\n        let text = cx.editor.theme.get(\"ui.text\");\n        let message_box = area.with_height(message_height + 2);\n        surface.clear_with(message_box, background.patch(text));\n        BLOCK.render(message_box, surface);\n        // Add horizontal padding so the message isn't too close to the border.\n        let message_area = BLOCK.inner(message_box).clip_left(1).clip_right(1);\n        self.message.render(message_area, surface, cx);\n\n        // Options menu\n        let menu_area = area.clip_top(message_height + 2);\n        self.options.render(menu_area, surface, cx);\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/spinner.rs",
    "content": "use std::{collections::HashMap, time::Instant};\n\nuse helix_lsp::LanguageServerId;\n\n#[derive(Default, Debug)]\npub struct ProgressSpinners {\n    inner: HashMap<LanguageServerId, Spinner>,\n}\n\nimpl ProgressSpinners {\n    pub fn get(&self, id: LanguageServerId) -> Option<&Spinner> {\n        self.inner.get(&id)\n    }\n\n    pub fn get_or_create(&mut self, id: LanguageServerId) -> &mut Spinner {\n        self.inner.entry(id).or_default()\n    }\n}\n\nimpl Default for Spinner {\n    fn default() -> Self {\n        Self::dots(80)\n    }\n}\n\n#[derive(Debug)]\npub struct Spinner {\n    frames: Vec<&'static str>,\n    count: usize,\n    start: Option<Instant>,\n    interval: u64,\n}\n\nimpl Spinner {\n    /// Creates a new spinner with `frames` and `interval`.\n    /// Expects the frames count and interval to be greater than 0.\n    pub fn new(frames: Vec<&'static str>, interval: u64) -> Self {\n        let count = frames.len();\n        assert!(count > 0);\n        assert!(interval > 0);\n\n        Self {\n            frames,\n            count,\n            interval,\n            start: None,\n        }\n    }\n\n    pub fn dots(interval: u64) -> Self {\n        Self::new(vec![\"⣾\", \"⣽\", \"⣻\", \"⢿\", \"⡿\", \"⣟\", \"⣯\", \"⣷\"], interval)\n    }\n\n    pub fn start(&mut self) {\n        self.start = Some(Instant::now());\n    }\n\n    pub fn frame(&self) -> Option<&str> {\n        let idx = (self\n            .start\n            .map(|time| Instant::now().duration_since(time))?\n            .as_millis()\n            / self.interval as u128) as usize\n            % self.count;\n\n        self.frames.get(idx).copied()\n    }\n\n    pub fn stop(&mut self) {\n        self.start = None;\n    }\n\n    pub fn is_stopped(&self) -> bool {\n        self.start.is_none()\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/statusline.rs",
    "content": "use helix_core::indent::IndentStyle;\nuse helix_core::{coords_at_pos, encoding, unicode::width::UnicodeWidthStr, Position};\nuse helix_lsp::lsp::DiagnosticSeverity;\nuse helix_view::document::DEFAULT_LANGUAGE_NAME;\nuse helix_view::{\n    document::{Mode, SCRATCH_BUFFER_NAME},\n    graphics::Rect,\n    theme::Style,\n    Document, Editor, View,\n};\n\nuse crate::ui::ProgressSpinners;\n\nuse helix_view::editor::StatusLineElement as StatusLineElementID;\nuse tui::buffer::Buffer as Surface;\nuse tui::text::{Span, Spans};\n\npub struct RenderContext<'a> {\n    pub editor: &'a Editor,\n    pub doc: &'a Document,\n    pub view: &'a View,\n    pub focused: bool,\n    pub spinners: &'a ProgressSpinners,\n    pub parts: RenderBuffer<'a>,\n}\n\nimpl<'a> RenderContext<'a> {\n    pub fn new(\n        editor: &'a Editor,\n        doc: &'a Document,\n        view: &'a View,\n        focused: bool,\n        spinners: &'a ProgressSpinners,\n    ) -> Self {\n        RenderContext {\n            editor,\n            doc,\n            view,\n            focused,\n            spinners,\n            parts: RenderBuffer::default(),\n        }\n    }\n}\n\n#[derive(Default)]\npub struct RenderBuffer<'a> {\n    pub left: Spans<'a>,\n    pub center: Spans<'a>,\n    pub right: Spans<'a>,\n}\n\npub fn render(context: &mut RenderContext, viewport: Rect, surface: &mut Surface) {\n    let base_style = if context.focused {\n        context.editor.theme.get(\"ui.statusline\")\n    } else {\n        context.editor.theme.get(\"ui.statusline.inactive\")\n    };\n\n    surface.set_style(viewport.with_height(1), base_style);\n\n    // Left side of the status line.\n\n    let config = context.editor.config();\n\n    for element_id in &config.statusline.left {\n        let render = get_render_function(*element_id);\n        (render)(context, |context, span| {\n            append(&mut context.parts.left, span, base_style)\n        });\n    }\n\n    surface.set_spans(\n        viewport.x,\n        viewport.y,\n        &context.parts.left,\n        context.parts.left.width() as u16,\n    );\n\n    // Right side of the status line.\n\n    for element_id in &config.statusline.right {\n        let render = get_render_function(*element_id);\n        (render)(context, |context, span| {\n            append(&mut context.parts.right, span, base_style)\n        })\n    }\n\n    surface.set_spans(\n        viewport.x\n            + viewport\n                .width\n                .saturating_sub(context.parts.right.width() as u16),\n        viewport.y,\n        &context.parts.right,\n        context.parts.right.width() as u16,\n    );\n\n    // Center of the status line.\n\n    for element_id in &config.statusline.center {\n        let render = get_render_function(*element_id);\n        (render)(context, |context, span| {\n            append(&mut context.parts.center, span, base_style)\n        })\n    }\n\n    // Width of the empty space between the left and center area and between the center and right area.\n    let spacing = 1u16;\n\n    let edge_width = context.parts.left.width().max(context.parts.right.width()) as u16;\n    let center_max_width = viewport.width.saturating_sub(2 * edge_width + 2 * spacing);\n    let center_width = center_max_width.min(context.parts.center.width() as u16);\n\n    surface.set_spans(\n        viewport.x + viewport.width / 2 - center_width / 2,\n        viewport.y,\n        &context.parts.center,\n        center_width,\n    );\n}\n\nfn append<'a>(buffer: &mut Spans<'a>, mut span: Span<'a>, base_style: Style) {\n    span.style = base_style.patch(span.style);\n    buffer.0.push(span);\n}\n\nfn get_render_function<'a, F>(element_id: StatusLineElementID) -> impl Fn(&mut RenderContext<'a>, F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    match element_id {\n        helix_view::editor::StatusLineElement::Mode => render_mode,\n        helix_view::editor::StatusLineElement::Spinner => render_lsp_spinner,\n        helix_view::editor::StatusLineElement::FileBaseName => render_file_base_name,\n        helix_view::editor::StatusLineElement::FileName => render_file_name,\n        helix_view::editor::StatusLineElement::FileAbsolutePath => render_file_absolute_path,\n        helix_view::editor::StatusLineElement::FileModificationIndicator => {\n            render_file_modification_indicator\n        }\n        helix_view::editor::StatusLineElement::ReadOnlyIndicator => render_read_only_indicator,\n        helix_view::editor::StatusLineElement::FileEncoding => render_file_encoding,\n        helix_view::editor::StatusLineElement::FileLineEnding => render_file_line_ending,\n        helix_view::editor::StatusLineElement::FileIndentStyle => render_file_indent_style,\n        helix_view::editor::StatusLineElement::FileType => render_file_type,\n        helix_view::editor::StatusLineElement::Diagnostics => render_diagnostics,\n        helix_view::editor::StatusLineElement::WorkspaceDiagnostics => render_workspace_diagnostics,\n        helix_view::editor::StatusLineElement::Selections => render_selections,\n        helix_view::editor::StatusLineElement::PrimarySelectionLength => {\n            render_primary_selection_length\n        }\n        helix_view::editor::StatusLineElement::Position => render_position,\n        helix_view::editor::StatusLineElement::PositionPercentage => render_position_percentage,\n        helix_view::editor::StatusLineElement::TotalLineNumbers => render_total_line_numbers,\n        helix_view::editor::StatusLineElement::Separator => render_separator,\n        helix_view::editor::StatusLineElement::Spacer => render_spacer,\n        helix_view::editor::StatusLineElement::VersionControl => render_version_control,\n        helix_view::editor::StatusLineElement::Register => render_register,\n        helix_view::editor::StatusLineElement::CurrentWorkingDirectory => render_cwd,\n    }\n}\n\nfn render_mode<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let visible = context.focused;\n    let config = context.editor.config();\n    let modenames = &config.statusline.mode;\n    let mode_str = match context.editor.mode() {\n        Mode::Insert => &modenames.insert,\n        Mode::Select => &modenames.select,\n        Mode::Normal => &modenames.normal,\n    };\n    let content = if visible {\n        format!(\" {mode_str} \")\n    } else {\n        // If not focused, explicitly leave an empty space instead of returning None.\n        \" \".repeat(mode_str.width() + 2)\n    };\n    let style = if visible && config.color_modes {\n        match context.editor.mode() {\n            Mode::Insert => context.editor.theme.get(\"ui.statusline.insert\"),\n            Mode::Select => context.editor.theme.get(\"ui.statusline.select\"),\n            Mode::Normal => context.editor.theme.get(\"ui.statusline.normal\"),\n        }\n    } else {\n        Style::default()\n    };\n    write(context, Span::styled(content, style));\n}\n\n// TODO think about handling multiple language servers\nfn render_lsp_spinner<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let language_server = context.doc.language_servers().next();\n    write(\n        context,\n        language_server\n            .and_then(|srv| {\n                context\n                    .spinners\n                    .get(srv.id())\n                    .and_then(|spinner| spinner.frame())\n            })\n            // Even if there's no spinner; reserve its space to avoid elements frequently shifting.\n            .unwrap_or(\" \")\n            .into(),\n    );\n}\n\nfn render_diagnostics<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    use helix_core::diagnostic::Severity;\n    let (hints, info, warnings, errors) =\n        context\n            .doc\n            .diagnostics()\n            .iter()\n            .fold((0, 0, 0, 0), |mut counts, diag| {\n                match diag.severity {\n                    Some(Severity::Hint) | None => counts.0 += 1,\n                    Some(Severity::Info) => counts.1 += 1,\n                    Some(Severity::Warning) => counts.2 += 1,\n                    Some(Severity::Error) => counts.3 += 1,\n                }\n                counts\n            });\n\n    for sev in &context.editor.config().statusline.diagnostics {\n        match sev {\n            Severity::Hint if hints > 0 => {\n                write(context, Span::styled(\"●\", context.editor.theme.get(\"hint\")));\n                write(context, format!(\" {} \", hints).into());\n            }\n            Severity::Info if info > 0 => {\n                write(context, Span::styled(\"●\", context.editor.theme.get(\"info\")));\n                write(context, format!(\" {} \", info).into());\n            }\n            Severity::Warning if warnings > 0 => {\n                write(\n                    context,\n                    Span::styled(\"●\", context.editor.theme.get(\"warning\")),\n                );\n                write(context, format!(\" {} \", warnings).into());\n            }\n            Severity::Error if errors > 0 => {\n                write(\n                    context,\n                    Span::styled(\"●\", context.editor.theme.get(\"error\")),\n                );\n                write(context, format!(\" {} \", errors).into());\n            }\n            _ => {}\n        }\n    }\n}\n\nfn render_workspace_diagnostics<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    use helix_core::diagnostic::Severity;\n    let (hints, info, warnings, errors) = context.editor.diagnostics.values().flatten().fold(\n        (0u32, 0u32, 0u32, 0u32),\n        |mut counts, (diag, _)| {\n            match diag.severity {\n                // PERF: For large workspace diagnostics, this loop can be very tight.\n                //\n                // Most often the diagnostics will be for warnings and errors.\n                // Errors should tend to be fixed fast, leaving warnings as the most common.\n                Some(DiagnosticSeverity::WARNING) => counts.2 += 1,\n                Some(DiagnosticSeverity::ERROR) => counts.3 += 1,\n                Some(DiagnosticSeverity::HINT) => counts.0 += 1,\n                Some(DiagnosticSeverity::INFORMATION) => counts.1 += 1,\n                // Fallback to `hint`.\n                _ => counts.0 += 1,\n            }\n            counts\n        },\n    );\n\n    let sevs_to_show = &context.editor.config().statusline.workspace_diagnostics;\n\n    // Avoid showing the \" W \" if no diagnostic counts will be shown.\n    if !sevs_to_show.iter().any(|sev| match sev {\n        Severity::Hint => hints != 0,\n        Severity::Info => info != 0,\n        Severity::Warning => warnings != 0,\n        Severity::Error => errors != 0,\n    }) {\n        return;\n    }\n\n    write(context, \" W \".into());\n\n    for sev in sevs_to_show {\n        match sev {\n            Severity::Hint if hints > 0 => {\n                write(context, Span::styled(\"●\", context.editor.theme.get(\"hint\")));\n                write(context, format!(\" {} \", hints).into());\n            }\n            Severity::Info if info > 0 => {\n                write(context, Span::styled(\"●\", context.editor.theme.get(\"info\")));\n                write(context, format!(\" {} \", info).into());\n            }\n            Severity::Warning if warnings > 0 => {\n                write(\n                    context,\n                    Span::styled(\"●\", context.editor.theme.get(\"warning\")),\n                );\n                write(context, format!(\" {} \", warnings).into());\n            }\n            Severity::Error if errors > 0 => {\n                write(\n                    context,\n                    Span::styled(\"●\", context.editor.theme.get(\"error\")),\n                );\n                write(context, format!(\" {} \", errors).into());\n            }\n            _ => {}\n        }\n    }\n}\n\nfn render_selections<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let selection = context.doc.selection(context.view.id);\n    let count = selection.len();\n    write(\n        context,\n        if count == 1 {\n            \" 1 sel \".into()\n        } else {\n            format!(\" {}/{count} sels \", selection.primary_index() + 1).into()\n        },\n    );\n}\n\nfn render_primary_selection_length<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let tot_sel = context.doc.selection(context.view.id).primary().len();\n    write(\n        context,\n        format!(\" {} char{} \", tot_sel, if tot_sel == 1 { \"\" } else { \"s\" }).into(),\n    );\n}\n\nfn get_position(context: &RenderContext) -> Position {\n    coords_at_pos(\n        context.doc.text().slice(..),\n        context\n            .doc\n            .selection(context.view.id)\n            .primary()\n            .cursor(context.doc.text().slice(..)),\n    )\n}\n\nfn render_position<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let position = get_position(context);\n    write(\n        context,\n        format!(\" {}:{} \", position.row + 1, position.col + 1).into(),\n    );\n}\n\nfn render_total_line_numbers<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let total_line_numbers = context.doc.text().len_lines();\n\n    write(context, format!(\" {} \", total_line_numbers).into());\n}\n\nfn render_position_percentage<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let position = get_position(context);\n    let maxrows = context.doc.text().len_lines();\n    write(\n        context,\n        format!(\"{}%\", (position.row + 1) * 100 / maxrows).into(),\n    );\n}\n\nfn render_file_encoding<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let enc = context.doc.encoding();\n\n    if enc != encoding::UTF_8 {\n        write(context, format!(\" {} \", enc.name()).into());\n    }\n}\n\nfn render_file_line_ending<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    use helix_core::LineEnding::*;\n    let line_ending = match context.doc.line_ending {\n        Crlf => \"CRLF\",\n        LF => \"LF\",\n        #[cfg(feature = \"unicode-lines\")]\n        VT => \"VT\", // U+000B -- VerticalTab\n        #[cfg(feature = \"unicode-lines\")]\n        FF => \"FF\", // U+000C -- FormFeed\n        #[cfg(feature = \"unicode-lines\")]\n        CR => \"CR\", // U+000D -- CarriageReturn\n        #[cfg(feature = \"unicode-lines\")]\n        Nel => \"NEL\", // U+0085 -- NextLine\n        #[cfg(feature = \"unicode-lines\")]\n        LS => \"LS\", // U+2028 -- Line Separator\n        #[cfg(feature = \"unicode-lines\")]\n        PS => \"PS\", // U+2029 -- ParagraphSeparator\n    };\n\n    write(context, format!(\" {} \", line_ending).into());\n}\n\nfn render_file_type<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let file_type = context.doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME);\n\n    write(context, format!(\" {} \", file_type).into());\n}\n\nfn render_file_name<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let title = {\n        let rel_path = context.doc.relative_path();\n        let path = rel_path\n            .as_ref()\n            .map(|p| p.to_string_lossy())\n            .unwrap_or_else(|| SCRATCH_BUFFER_NAME.into());\n        format!(\" {} \", path)\n    };\n\n    write(context, title.into());\n}\n\nfn render_file_absolute_path<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let title = {\n        let path = context.doc.path();\n        let path = path\n            .as_ref()\n            .map(|p| p.to_string_lossy())\n            .unwrap_or_else(|| SCRATCH_BUFFER_NAME.into());\n        format!(\" {} \", path)\n    };\n\n    write(context, title.into());\n}\n\nfn render_file_modification_indicator<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let title = if context.doc.is_modified() {\n        \"[+]\"\n    } else {\n        \"   \"\n    };\n\n    write(context, title.into());\n}\n\nfn render_read_only_indicator<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let title = if context.doc.readonly {\n        \" [readonly] \"\n    } else {\n        \"\"\n    };\n    write(context, title.into());\n}\n\nfn render_file_base_name<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let title = {\n        let rel_path = context.doc.relative_path();\n        let path = rel_path\n            .as_ref()\n            .and_then(|p| p.file_name().map(|s| s.to_string_lossy()))\n            .unwrap_or_else(|| SCRATCH_BUFFER_NAME.into());\n        format!(\" {} \", path)\n    };\n\n    write(context, title.into());\n}\n\nfn render_separator<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let sep = &context.editor.config().statusline.separator;\n    let style = context.editor.theme.get(\"ui.statusline.separator\");\n\n    write(context, Span::styled(sep.to_string(), style));\n}\n\nfn render_spacer<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    write(context, \" \".into());\n}\n\nfn render_version_control<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let head = context\n        .doc\n        .version_control_head()\n        .unwrap_or_default()\n        .to_string();\n\n    write(context, head.into());\n}\n\nfn render_register<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    if let Some(reg) = context.editor.selected_register {\n        write(context, format!(\" reg={} \", reg).into())\n    }\n}\n\nfn render_file_indent_style<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let style = context.doc.indent_style;\n\n    write(\n        context,\n        match style {\n            IndentStyle::Tabs => \" tabs \".into(),\n            IndentStyle::Spaces(indent) => {\n                format!(\" {} space{} \", indent, if indent == 1 { \"\" } else { \"s\" }).into()\n            }\n        },\n    );\n}\n\nfn render_cwd<'a, F>(context: &mut RenderContext<'a>, write: F)\nwhere\n    F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,\n{\n    let cwd = helix_stdx::env::current_working_dir();\n    let cwd = cwd\n        .file_name()\n        .unwrap_or_default()\n        .to_string_lossy()\n        .to_string();\n    write(context, cwd.into())\n}\n"
  },
  {
    "path": "helix-term/src/ui/text.rs",
    "content": "use crate::compositor::{Component, Context};\nuse tui::buffer::Buffer as Surface;\n\nuse helix_view::graphics::Rect;\n\npub struct Text {\n    pub(crate) contents: tui::text::Text<'static>,\n    size: (u16, u16),\n    viewport: (u16, u16),\n}\n\nimpl Text {\n    pub fn new(contents: String) -> Self {\n        Self {\n            contents: tui::text::Text::from(contents),\n            size: (0, 0),\n            viewport: (0, 0),\n        }\n    }\n}\n\nimpl From<tui::text::Text<'static>> for Text {\n    fn from(contents: tui::text::Text<'static>) -> Self {\n        Self {\n            contents,\n            size: (0, 0),\n            viewport: (0, 0),\n        }\n    }\n}\n\nimpl Component for Text {\n    fn render(&mut self, area: Rect, surface: &mut Surface, _cx: &mut Context) {\n        use tui::widgets::{Paragraph, Widget, Wrap};\n\n        let par = Paragraph::new(&self.contents).wrap(Wrap { trim: false });\n        // .scroll(x, y) offsets\n\n        par.render(area, surface);\n    }\n\n    fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {\n        if viewport != self.viewport {\n            let width = std::cmp::min(self.contents.width() as u16, viewport.0);\n            let height = std::cmp::min(self.contents.height() as u16, viewport.1);\n            self.size = (width, height);\n            self.viewport = viewport;\n        }\n        Some(self.size)\n    }\n}\n\npub fn required_size(text: &tui::text::Text, max_text_width: u16) -> (u16, u16) {\n    let mut text_width = 0;\n    let mut height = 0;\n    for content in &text.lines {\n        height += 1;\n        let content_width = content.width() as u16;\n        if content_width > max_text_width {\n            text_width = max_text_width;\n            height += content_width.checked_div(max_text_width).unwrap_or(0);\n        } else if content_width > text_width {\n            text_width = content_width;\n        }\n    }\n    (text_width, height)\n}\n"
  },
  {
    "path": "helix-term/src/ui/text_decorations/diagnostics.rs",
    "content": "use std::cmp::Ordering;\n\nuse helix_core::diagnostic::Severity;\nuse helix_core::doc_formatter::{DocumentFormatter, FormattedGrapheme};\nuse helix_core::graphemes::Grapheme;\nuse helix_core::text_annotations::TextAnnotations;\nuse helix_core::{Diagnostic, Position};\nuse helix_view::annotations::diagnostics::{\n    DiagnosticFilter, InlineDiagnosticAccumulator, InlineDiagnosticsConfig,\n};\n\nuse helix_view::theme::Style;\nuse helix_view::{Document, Theme};\n\nuse crate::ui::document::{LinePos, TextRenderer};\nuse crate::ui::text_decorations::Decoration;\n\n#[derive(Debug)]\nstruct Styles {\n    hint: Style,\n    info: Style,\n    warning: Style,\n    error: Style,\n}\n\nimpl Styles {\n    fn new(theme: &Theme) -> Styles {\n        Styles {\n            hint: theme.get(\"hint\"),\n            info: theme.get(\"info\"),\n            warning: theme.get(\"warning\"),\n            error: theme.get(\"error\"),\n        }\n    }\n\n    fn severity_style(&self, severity: Severity) -> Style {\n        match severity {\n            Severity::Hint => self.hint,\n            Severity::Info => self.info,\n            Severity::Warning => self.warning,\n            Severity::Error => self.error,\n        }\n    }\n}\n\npub struct InlineDiagnostics<'a> {\n    state: InlineDiagnosticAccumulator<'a>,\n    eol_diagnostics: DiagnosticFilter,\n    styles: Styles,\n}\n\nimpl<'a> InlineDiagnostics<'a> {\n    pub fn new(\n        doc: &'a Document,\n        theme: &Theme,\n        cursor: usize,\n        config: InlineDiagnosticsConfig,\n        eol_diagnostics: DiagnosticFilter,\n    ) -> Self {\n        InlineDiagnostics {\n            state: InlineDiagnosticAccumulator::new(cursor, doc, config),\n            styles: Styles::new(theme),\n            eol_diagnostics,\n        }\n    }\n}\n\nconst BL_CORNER: &str = \"┘\";\nconst TR_CORNER: &str = \"┌\";\nconst BR_CORNER: &str = \"└\";\nconst STACK: &str = \"├\";\nconst MULTI: &str = \"┴\";\nconst HOR_BAR: &str = \"─\";\nconst VER_BAR: &str = \"│\";\n\nstruct Renderer<'a, 'b> {\n    renderer: &'a mut TextRenderer<'b>,\n    first_row: u16,\n    row: u16,\n    config: &'a InlineDiagnosticsConfig,\n    styles: &'a Styles,\n}\n\nimpl Renderer<'_, '_> {\n    fn draw_decoration(&mut self, g: &'static str, severity: Severity, col: u16) {\n        self.draw_decoration_at(g, severity, col, self.row)\n    }\n\n    fn draw_decoration_at(&mut self, g: &'static str, severity: Severity, col: u16, row: u16) {\n        self.renderer.draw_decoration_grapheme(\n            Grapheme::new_decoration(g),\n            self.styles.severity_style(severity),\n            row,\n            col,\n        );\n    }\n\n    fn draw_eol_diagnostic(&mut self, diag: &Diagnostic, row: u16, col: usize) -> u16 {\n        let style = self.styles.severity_style(diag.severity());\n        let width = self.renderer.viewport.width;\n        let start_col = (col - self.renderer.offset.col) as u16;\n        let mut end_col = start_col;\n        let mut draw_col = (col + 1) as u16;\n\n        for line in diag.message.lines() {\n            if !self.renderer.column_in_bounds(draw_col as usize, 1) {\n                break;\n            }\n\n            (end_col, _) = self.renderer.set_string_truncated(\n                self.renderer.viewport.x + draw_col,\n                row,\n                line,\n                width.saturating_sub(draw_col) as usize,\n                |_| style,\n                true,\n                false,\n            );\n\n            draw_col = end_col - self.renderer.viewport.x + 2; // double space between lines\n        }\n\n        end_col - start_col\n    }\n\n    fn draw_diagnostic(&mut self, diag: &Diagnostic, col: u16, next_severity: Option<Severity>) {\n        let severity = diag.severity();\n        let (sym, sym_severity) = if let Some(next_severity) = next_severity {\n            (STACK, next_severity.max(severity))\n        } else {\n            (BR_CORNER, severity)\n        };\n        self.draw_decoration(sym, sym_severity, col);\n        for i in 0..self.config.prefix_len {\n            self.draw_decoration(HOR_BAR, severity, col + i + 1);\n        }\n\n        let text_col = col + self.config.prefix_len + 1;\n        let text_fmt = self.config.text_fmt(text_col, self.renderer.viewport.width);\n        let annotations = TextAnnotations::default();\n        let formatter = DocumentFormatter::new_at_prev_checkpoint(\n            diag.message.as_str().trim().into(),\n            &text_fmt,\n            &annotations,\n            0,\n        );\n        let mut last_row = 0;\n        let style = self.styles.severity_style(severity);\n        for grapheme in formatter {\n            last_row = grapheme.visual_pos.row;\n            self.renderer.draw_decoration_grapheme(\n                grapheme.raw,\n                style,\n                self.row + grapheme.visual_pos.row as u16,\n                text_col + grapheme.visual_pos.col as u16,\n            );\n        }\n        self.row += 1;\n        // height is last_row + 1 and extra_rows is height - 1\n        let extra_lines = last_row;\n        if let Some(next_severity) = next_severity {\n            for _ in 0..extra_lines {\n                self.draw_decoration(VER_BAR, next_severity, col);\n                self.row += 1;\n            }\n        } else {\n            self.row += extra_lines as u16;\n        }\n    }\n\n    fn draw_multi_diagnostics(&mut self, stack: &mut Vec<(&Diagnostic, u16)>) {\n        let Some(&(last_diag, last_anchor)) = stack.last() else {\n            return;\n        };\n        let start = self\n            .config\n            .max_diagnostic_start(self.renderer.viewport.width);\n\n        if last_anchor <= start {\n            return;\n        }\n        let mut severity = last_diag.severity();\n        let mut last_anchor = last_anchor;\n        self.draw_decoration(BL_CORNER, severity, last_anchor);\n        let mut stacked_diagnostics = 1;\n        for &(diag, anchor) in stack.iter().rev().skip(1) {\n            let sym = match anchor.cmp(&start) {\n                Ordering::Less => break,\n                Ordering::Equal => STACK,\n                Ordering::Greater => MULTI,\n            };\n            stacked_diagnostics += 1;\n            severity = severity.max(diag.severity());\n            let old_severity = severity;\n            if anchor == last_anchor && severity == old_severity {\n                continue;\n            }\n            for col in (anchor + 1)..last_anchor {\n                self.draw_decoration(HOR_BAR, old_severity, col)\n            }\n            self.draw_decoration(sym, severity, anchor);\n            last_anchor = anchor;\n        }\n\n        // if no diagnostic anchor was found exactly at the start of the\n        // diagnostic text  draw an upwards corner and ensure the last piece\n        // of the line is not missing\n        if last_anchor != start {\n            for col in (start + 1)..last_anchor {\n                self.draw_decoration(HOR_BAR, severity, col)\n            }\n            self.draw_decoration(TR_CORNER, severity, start)\n        }\n        self.row += 1;\n        let stacked_diagnostics = &stack[stack.len() - stacked_diagnostics..];\n\n        for (i, (diag, _)) in stacked_diagnostics.iter().rev().enumerate() {\n            let next_severity = stacked_diagnostics[..stacked_diagnostics.len() - i - 1]\n                .iter()\n                .map(|(diag, _)| diag.severity())\n                .max();\n            self.draw_diagnostic(diag, start, next_severity);\n        }\n\n        stack.truncate(stack.len() - stacked_diagnostics.len());\n    }\n\n    fn draw_diagnostics(&mut self, stack: &mut Vec<(&Diagnostic, u16)>) {\n        let mut stack = stack.drain(..).rev().peekable();\n        let mut last_anchor = self.renderer.viewport.width;\n        while let Some((diag, anchor)) = stack.next() {\n            if anchor != last_anchor {\n                for row in self.first_row..self.row {\n                    self.draw_decoration_at(VER_BAR, diag.severity(), anchor, row);\n                }\n            }\n            let next_severity = stack.peek().and_then(|&(diag, next_anchor)| {\n                (next_anchor == anchor).then_some(diag.severity())\n            });\n            self.draw_diagnostic(diag, anchor, next_severity);\n            last_anchor = anchor;\n        }\n    }\n}\n\nimpl Decoration for InlineDiagnostics<'_> {\n    fn render_virt_lines(\n        &mut self,\n        renderer: &mut TextRenderer,\n        pos: LinePos,\n        virt_off: Position,\n    ) -> Position {\n        let mut col_off = 0;\n        let filter = self.state.filter();\n        let eol_diagnostic = match self.eol_diagnostics {\n            DiagnosticFilter::Enable(eol_filter) => {\n                let eol_diganogistcs = self\n                    .state\n                    .stack\n                    .iter()\n                    .filter(|(diag, _)| eol_filter <= diag.severity());\n                match filter {\n                    DiagnosticFilter::Enable(filter) => eol_diganogistcs\n                        .filter(|(diag, _)| filter > diag.severity())\n                        .max_by_key(|(diagnostic, _)| diagnostic.severity),\n                    DiagnosticFilter::Disable => {\n                        eol_diganogistcs.max_by_key(|(diagnostic, _)| diagnostic.severity)\n                    }\n                }\n            }\n            DiagnosticFilter::Disable => None,\n        };\n        if let Some((eol_diagnostic, _)) = eol_diagnostic {\n            let mut renderer = Renderer {\n                renderer,\n                first_row: pos.visual_line,\n                row: pos.visual_line,\n                config: &self.state.config,\n                styles: &self.styles,\n            };\n            col_off = renderer.draw_eol_diagnostic(eol_diagnostic, pos.visual_line, virt_off.col);\n        }\n\n        self.state.compute_line_diagnostics();\n        let mut renderer = Renderer {\n            renderer,\n            first_row: pos.visual_line + virt_off.row as u16,\n            row: pos.visual_line + virt_off.row as u16,\n            config: &self.state.config,\n            styles: &self.styles,\n        };\n        renderer.draw_multi_diagnostics(&mut self.state.stack);\n        renderer.draw_diagnostics(&mut self.state.stack);\n        let horizontal_off = renderer.row - renderer.first_row;\n        Position::new(horizontal_off as usize, col_off as usize)\n    }\n\n    fn reset_pos(&mut self, pos: usize) -> usize {\n        self.state.reset_pos(pos)\n    }\n\n    fn skip_concealed_anchor(&mut self, conceal_end_char_idx: usize) -> usize {\n        self.state.skip_concealed(conceal_end_char_idx)\n    }\n\n    fn decorate_grapheme(\n        &mut self,\n        renderer: &mut TextRenderer,\n        grapheme: &FormattedGrapheme,\n    ) -> usize {\n        self.state\n            .proccess_anchor(grapheme, renderer.viewport.width, renderer.offset.col)\n    }\n}\n"
  },
  {
    "path": "helix-term/src/ui/text_decorations.rs",
    "content": "use std::cmp::Ordering;\n\nuse helix_core::doc_formatter::FormattedGrapheme;\nuse helix_core::Position;\nuse helix_view::editor::CursorCache;\n\nuse crate::ui::document::{LinePos, TextRenderer};\n\npub use diagnostics::InlineDiagnostics;\n\nmod diagnostics;\n\n/// Decorations are the primary mechanism for extending the text rendering.\n///\n/// Any on-screen element which is anchored to the rendered text in some form\n/// should be implemented using this trait. Translating char positions to\n/// on-screen positions can be expensive and should not be done manually in the\n/// ui loop. Instead such translations are automatically performed on the fly\n/// while the text is being rendered. The results are provided to this trait by\n/// the rendering infrastructure.\n///\n/// To reserve space for virtual text lines (which is then filled by this trait) emit appropriate\n/// [`LineAnnotation`](helix_core::text_annotations::LineAnnotation)s in [`helix_view::View::text_annotations`]\npub trait Decoration {\n    /// Called **before** a **visual** line is rendered. A visual line does not\n    /// necessarily correspond to a single line in a document as soft wrapping can\n    /// spread a single document line across multiple visual lines.\n    ///\n    /// This function is called before text is rendered as any decorations should\n    /// never overlap the document text. That means that setting the forground color\n    /// here is (essentially) useless as the text color is overwritten by the\n    /// rendered text. This _of course_ doesn't apply when rendering inside virtual lines\n    /// below the line reserved by `LineAnnotation`s as no text will be rendered here.\n    fn decorate_line(&mut self, _renderer: &mut TextRenderer, _pos: LinePos) {}\n\n    /// Called **after** a **visual** line is rendered. A visual line does not\n    /// necessarily correspond to a single line in a document as soft wrapping can\n    /// spread a single document line across multiple visual lines.\n    ///\n    /// This function is called after text is rendered so that decorations can collect\n    /// horizontal positions on the line (see [`Decoration::decorate_grapheme`]) first and\n    /// use those positions while rendering virtual text. That means that setting the foreground\n    /// color here is (essentially) useless as the text color is overwritten by the\n    /// rendered text. This _of course_ doesn't apply when rendering inside virtual lines\n    /// below the line reserved by `LineAnnotation`s. e as no text will be rendered here.\n    /// **Note**: To avoid overlapping decorations in the virtual lines, each decoration\n    /// must return the number of virtual text lines it has taken up. Each `Decoration` receives\n    /// an offset `virt_off` based on these return values where it can render virtual text:\n    ///\n    /// That means that a `render_line` implementation that returns `X` can render virtual text\n    /// in the following area:\n    ///\n    /// ```ignore\n    /// let start = inner.y + pos.virtual_line + virt_off;\n    /// start .. start + X\n    /// ````\n    fn render_virt_lines(\n        &mut self,\n        _renderer: &mut TextRenderer,\n        _pos: LinePos,\n        _virt_off: Position,\n    ) -> Position {\n        Position::new(0, 0)\n    }\n\n    fn reset_pos(&mut self, _pos: usize) -> usize {\n        usize::MAX\n    }\n\n    fn skip_concealed_anchor(&mut self, conceal_end_char_idx: usize) -> usize {\n        self.reset_pos(conceal_end_char_idx)\n    }\n\n    /// This function is called **before** the grapheme at `char_idx` is rendered.\n    ///\n    /// # Returns\n    ///\n    /// The char idx of the next grapheme that  this function should be called for\n    fn decorate_grapheme(\n        &mut self,\n        _renderer: &mut TextRenderer,\n        _grapheme: &FormattedGrapheme,\n    ) -> usize {\n        usize::MAX\n    }\n}\n\nimpl<F: FnMut(&mut TextRenderer, LinePos)> Decoration for F {\n    fn decorate_line(&mut self, renderer: &mut TextRenderer, pos: LinePos) {\n        self(renderer, pos);\n    }\n}\n\n#[derive(Default)]\npub struct DecorationManager<'a> {\n    decorations: Vec<(Box<dyn Decoration + 'a>, usize)>,\n}\n\nimpl<'a> DecorationManager<'a> {\n    pub fn add_decoration(&mut self, decoration: impl Decoration + 'a) {\n        self.decorations.push((Box::new(decoration), 0));\n    }\n\n    pub fn prepare_for_rendering(&mut self, first_visible_char: usize) {\n        for (decoration, next_position) in &mut self.decorations {\n            *next_position = decoration.reset_pos(first_visible_char)\n        }\n    }\n\n    pub fn decorate_grapheme(&mut self, renderer: &mut TextRenderer, grapheme: &FormattedGrapheme) {\n        for (decoration, hook_char_idx) in &mut self.decorations {\n            loop {\n                match (*hook_char_idx).cmp(&grapheme.char_idx) {\n                    // this grapheme has been concealed or we are at the first grapheme\n                    Ordering::Less => {\n                        *hook_char_idx = decoration.skip_concealed_anchor(grapheme.char_idx)\n                    }\n                    Ordering::Equal => {\n                        *hook_char_idx = decoration.decorate_grapheme(renderer, grapheme)\n                    }\n                    Ordering::Greater => break,\n                }\n            }\n        }\n    }\n\n    pub fn decorate_line(&mut self, renderer: &mut TextRenderer, pos: LinePos) {\n        for (decoration, _) in &mut self.decorations {\n            decoration.decorate_line(renderer, pos);\n        }\n    }\n\n    pub fn render_virtual_lines(\n        &mut self,\n        renderer: &mut TextRenderer,\n        pos: LinePos,\n        line_width: usize,\n    ) {\n        let mut virt_off = Position::new(1, line_width); // start at 1 so the line is never overwritten\n        for (decoration, _) in &mut self.decorations {\n            virt_off += decoration.render_virt_lines(renderer, pos, virt_off);\n        }\n    }\n}\n\n/// Cursor rendering is done externally so all the cursor decoration\n/// does is save the position of primary cursor\npub struct Cursor<'a> {\n    pub cache: &'a CursorCache,\n    pub primary_cursor: usize,\n}\nimpl Decoration for Cursor<'_> {\n    fn reset_pos(&mut self, pos: usize) -> usize {\n        if pos <= self.primary_cursor {\n            self.primary_cursor\n        } else {\n            usize::MAX\n        }\n    }\n\n    fn decorate_grapheme(\n        &mut self,\n        renderer: &mut TextRenderer,\n        grapheme: &FormattedGrapheme,\n    ) -> usize {\n        if renderer.column_in_bounds(grapheme.visual_pos.col, grapheme.width())\n            && renderer.offset.row < grapheme.visual_pos.row\n        {\n            let position = grapheme.visual_pos - renderer.offset;\n            self.cache.set(Some(position));\n        }\n        usize::MAX\n    }\n}\n"
  },
  {
    "path": "helix-term/tests/integration.rs",
    "content": "#[cfg(feature = \"integration\")]\nmod test {\n    mod helpers;\n\n    use helix_core::{syntax::config::AutoPairConfig, Selection};\n    use helix_term::config::Config;\n\n    use indoc::indoc;\n\n    use self::helpers::*;\n\n    #[tokio::test(flavor = \"multi_thread\")]\n    async fn hello_world() -> anyhow::Result<()> {\n        test((\"#[\\n|]#\", \"ihello world<esc>\", \"hello world#[|\\n]#\")).await?;\n        Ok(())\n    }\n\n    mod auto_indent;\n    mod auto_pairs;\n    mod command_line;\n    mod commands;\n    mod languages;\n    mod movement;\n    mod splits;\n}\n"
  },
  {
    "path": "helix-term/tests/test/auto_indent.rs",
    "content": "use super::*;\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn auto_indent_c() -> anyhow::Result<()> {\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.c\", None),\n        // switches to append mode?\n        (\n            \"void foo() {#[|}]#\",\n            \"i<ret><esc>\",\n            indoc! {\"\\\n                void foo() {\n                  #[|\\n]#\\\n                }\n            \"},\n        ),\n    )\n    .await?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/auto_pairs.rs",
    "content": "use helix_core::{auto_pairs::DEFAULT_PAIRS, hashmap};\n\nuse super::*;\n\nconst LINE_END: &str = helix_core::NATIVE_LINE_ENDING.as_str();\n\nfn differing_pairs() -> impl Iterator<Item = &'static (char, char)> {\n    DEFAULT_PAIRS.iter().filter(|(open, close)| open != close)\n}\n\nfn matching_pairs() -> impl Iterator<Item = &'static (char, char)> {\n    DEFAULT_PAIRS.iter().filter(|(open, close)| open == close)\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_basic() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\"#[{}|]#\", LINE_END),\n            format!(\"i{}\", pair.0),\n            format!(\"{}#[|{}]#{}\", pair.0, pair.1, LINE_END),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_configured_multi_byte_chars() -> anyhow::Result<()> {\n    // NOTE: these are multi-byte Unicode characters\n    let pairs = hashmap!('„' => '“', '‚' => '‘', '「' => '」');\n\n    let config = Config {\n        editor: helix_view::editor::Config {\n            auto_pairs: AutoPairConfig::Pairs(pairs.clone()),\n            ..Default::default()\n        },\n        ..Default::default()\n    };\n\n    for (open, close) in pairs.iter() {\n        test_with_config(\n            AppBuilder::new().with_config(config.clone()),\n            (\n                format!(\"#[{}|]#\", LINE_END),\n                format!(\"i{}\", open),\n                format!(\"{}#[|{}]#{}\", open, close, LINE_END),\n                LineFeedHandling::AsIs,\n            ),\n        )\n        .await?;\n\n        test_with_config(\n            AppBuilder::new().with_config(config.clone()),\n            (\n                format!(\"{}#[{}|]#{}\", open, close, LINE_END),\n                format!(\"i{}\", close),\n                format!(\"{}{}#[|{}]#\", open, close, LINE_END),\n                LineFeedHandling::AsIs,\n            ),\n        )\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_after_word() -> anyhow::Result<()> {\n    for pair in differing_pairs() {\n        test((\n            format!(\"foo#[{}|]#\", LINE_END),\n            format!(\"i{}\", pair.0),\n            format!(\"foo{}#[|{}]#{}\", pair.0, pair.1, LINE_END),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    for pair in matching_pairs() {\n        test((\n            format!(\"foo#[{}|]#\", LINE_END),\n            format!(\"i{}\", pair.0),\n            format!(\"foo{}#[|{}]#\", pair.0, LINE_END),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_before_word() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\"#[f|]#oo{}\", LINE_END),\n            format!(\"i{}\", pair.0),\n            format!(\"{}#[|f]#oo{}\", pair.0, LINE_END),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_before_word_selection() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\"#[foo|]#{}\", LINE_END),\n            format!(\"i{}\", pair.0),\n            format!(\"{}#[|foo]#{}\", pair.0, LINE_END),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_before_word_selection_trailing_word() -> anyhow::Result<()> {\n    for pair in differing_pairs() {\n        test((\n            format!(\"foo#[ wor|]#{}\", LINE_END),\n            format!(\"i{}\", pair.0),\n            format!(\"foo{}#[|{} wor]#{}\", pair.0, pair.1, LINE_END),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_closer_selection_trailing_word() -> anyhow::Result<()> {\n    for pair in differing_pairs() {\n        test((\n            format!(\"foo{}#[|{} wor]#{}\", pair.0, pair.1, LINE_END),\n            format!(\"i{}\", pair.1),\n            format!(\"foo{}{}#[| wor]#{}\", pair.0, pair.1, LINE_END),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_before_eol() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\"{0}#[{0}|]#\", LINE_END),\n            format!(\"i{}\", pair.0),\n            format!(\n                \"{eol}{open}#[|{close}]#{eol}\",\n                eol = LINE_END,\n                open = pair.0,\n                close = pair.1\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_auto_pairs_disabled() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test_with_config(\n            AppBuilder::new().with_config(Config {\n                editor: helix_view::editor::Config {\n                    auto_pairs: AutoPairConfig::Enable(false),\n                    ..Default::default()\n                },\n                ..Default::default()\n            }),\n            (\n                format!(\"#[{}|]#\", LINE_END),\n                format!(\"i{}\", pair.0),\n                format!(\"{}#[|{}]#\", pair.0, LINE_END),\n                LineFeedHandling::AsIs,\n            ),\n        )\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_multi_range() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\"#[{eol}|]##({eol}|)##({eol}|)#\", eol = LINE_END),\n            format!(\"i{}\", pair.0),\n            format!(\n                \"{open}#[|{close}]#{eol}{open}#(|{close})#{eol}{open}#(|{close})#{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_before_multi_code_point_graphemes() -> anyhow::Result<()> {\n    for pair in differing_pairs() {\n        test((\n            format!(\"hello #[👨‍👩‍👧‍👦|]# goodbye{}\", LINE_END),\n            format!(\"i{}\", pair.1),\n            format!(\"hello {}#[|👨‍👩‍👧‍👦]# goodbye{}\", pair.1, LINE_END),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_at_end_of_document() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test(TestCase {\n            in_text: String::from(LINE_END),\n            in_selection: Selection::single(LINE_END.len(), LINE_END.len()),\n            in_keys: format!(\"i{}\", pair.0),\n            out_text: format!(\"{}{}{}\", LINE_END, pair.0, pair.1),\n            out_selection: Selection::single(LINE_END.len() + 1, LINE_END.len() + 2),\n            line_feed_handling: LineFeedHandling::AsIs,\n        })\n        .await?;\n\n        test(TestCase {\n            in_text: format!(\"foo{}\", LINE_END),\n            in_selection: Selection::single(3 + LINE_END.len(), 3 + LINE_END.len()),\n            in_keys: format!(\"i{}\", pair.0),\n            out_text: format!(\"foo{}{}{}\", LINE_END, pair.0, pair.1),\n            out_selection: Selection::single(LINE_END.len() + 4, LINE_END.len() + 5),\n            line_feed_handling: LineFeedHandling::AsIs,\n        })\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_close_inside_pair() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\n                \"{open}#[{close}|]#{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            format!(\"i{}\", pair.1),\n            format!(\n                \"{open}{close}#[|{eol}]#\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_close_inside_pair_multi() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\n                \"{open}#[{close}|]#{eol}{open}#({close}|)#{eol}{open}#({close}|)#{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            format!(\"i{}\", pair.1),\n            format!(\n                \"{open}{close}#[|{eol}]#{open}{close}#(|{eol})#{open}{close}#(|{eol})#\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_nested_open_inside_pair() -> anyhow::Result<()> {\n    for pair in differing_pairs() {\n        test((\n            format!(\n                \"{open}#[{close}|]#{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            format!(\"i{}\", pair.0),\n            format!(\n                \"{open}{open}#[|{close}]#{close}{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_nested_open_inside_pair_multi() -> anyhow::Result<()> {\n    for outer_pair in DEFAULT_PAIRS {\n        for inner_pair in DEFAULT_PAIRS {\n            if inner_pair.0 == outer_pair.0 {\n                continue;\n            }\n\n            test((\n                format!(\n                    \"{outer_open}#[{outer_close}|]#{eol}{outer_open}#({outer_close}|)#{eol}{outer_open}#({outer_close}|)#{eol}\",\n                    outer_open = outer_pair.0,\n                    outer_close = outer_pair.1,\n                    eol = LINE_END\n                ),\n                format!(\"i{}\", inner_pair.0),\n                format!(\n                    \"{outer_open}{inner_open}#[|{inner_close}]#{outer_close}{eol}{outer_open}{inner_open}#(|{inner_close})#{outer_close}{eol}{outer_open}{inner_open}#(|{inner_close})#{outer_close}{eol}\",\n                    outer_open = outer_pair.0,\n                    outer_close = outer_pair.1,\n                    inner_open = inner_pair.0,\n                    inner_close = inner_pair.1,\n                    eol = LINE_END\n                ),\n                LineFeedHandling::AsIs,\n            ))\n            .await?;\n        }\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn append_basic() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\"#[{}|]#\", LINE_END),\n            format!(\"a{}\", pair.0),\n            format!(\n                \"#[{eol}{open}{close}|]#{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn append_multi_range() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\"#[ |]#{eol}#( |)#{eol}#( |)#{eol}\", eol = LINE_END),\n            format!(\"a{}\", pair.0),\n            format!(\n                \"#[ {open}{close}|]#{eol}#( {open}{close}|)#{eol}#( {open}{close}|)#{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn append_close_inside_pair() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\n                \"#[{open}|]#{close}{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            format!(\"a{}\", pair.1),\n            format!(\n                \"#[{open}{close}{eol}|]#\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn append_close_inside_pair_multi() -> anyhow::Result<()> {\n    for pair in DEFAULT_PAIRS {\n        test((\n            format!(\n                \"#[{open}|]#{close}{eol}#({open}|)#{close}{eol}#({open}|)#{close}{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            format!(\"a{}\", pair.1),\n            format!(\n                \"#[{open}{close}{eol}|]##({open}{close}{eol}|)##({open}{close}{eol}|)#\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn append_end_of_word() -> anyhow::Result<()> {\n    for pair in differing_pairs() {\n        test((\n            format!(\"fo#[o|]#{}\", LINE_END),\n            format!(\"a{}\", pair.0),\n            format!(\n                \"fo#[o{open}{close}|]#{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn append_middle_of_word() -> anyhow::Result<()> {\n    for pair in differing_pairs() {\n        test((\n            format!(\"#[wo|]#rd{}\", LINE_END),\n            format!(\"a{}\", pair.1),\n            format!(\"#[wo{}r|]#d{}\", pair.1, LINE_END),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn append_end_of_word_multi() -> anyhow::Result<()> {\n    for pair in differing_pairs() {\n        test((\n            format!(\"fo#[o|]#{eol}fo#(o|)#{eol}fo#(o|)#{eol}\", eol = LINE_END),\n            format!(\"a{}\", pair.0),\n            format!(\n                \"fo#[o{open}{close}|]#{eol}fo#(o{open}{close}|)#{eol}fo#(o{open}{close}|)#{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn append_inside_nested_pair() -> anyhow::Result<()> {\n    for pair in differing_pairs() {\n        test((\n            format!(\n                \"f#[oo{open}|]#{close}{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            format!(\"a{}\", pair.0),\n            format!(\n                \"f#[oo{open}{open}{close}|]#{close}{eol}\",\n                open = pair.0,\n                close = pair.1,\n                eol = LINE_END\n            ),\n            LineFeedHandling::AsIs,\n        ))\n        .await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn append_inside_nested_pair_multi() -> anyhow::Result<()> {\n    for outer_pair in DEFAULT_PAIRS {\n        for inner_pair in DEFAULT_PAIRS {\n            if inner_pair.0 == outer_pair.0 {\n                continue;\n            }\n\n            test((\n                format!(\n                    \"f#[oo{outer_open}|]#{outer_close}{eol}f#(oo{outer_open}|)#{outer_close}{eol}f#(oo{outer_open}|)#{outer_close}{eol}\",\n                    outer_open = outer_pair.0,\n                    outer_close = outer_pair.1,\n                    eol = LINE_END\n                ),\n                format!(\"a{}\", inner_pair.0),\n                format!(\n                    \"f#[oo{outer_open}{inner_open}{inner_close}|]#{outer_close}{eol}f#(oo{outer_open}{inner_open}{inner_close}|)#{outer_close}{eol}f#(oo{outer_open}{inner_open}{inner_close}|)#{outer_close}{eol}\",\n                    outer_open = outer_pair.0,\n                    outer_close = outer_pair.1,\n                    inner_open = inner_pair.0,\n                    inner_close = inner_pair.1,\n                    eol = LINE_END\n                ),\n                LineFeedHandling::AsIs,\n            ))\n            .await?;\n        }\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/command_line.rs",
    "content": "use super::*;\n\nuse helix_core::diagnostic::Severity;\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn history_completion() -> anyhow::Result<()> {\n    test_key_sequence(\n        &mut AppBuilder::new().build()?,\n        Some(\":asdf<ret>:theme d<C-n><tab>\"),\n        Some(&|app| {\n            assert!(!app.editor.is_err());\n        }),\n        false,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn prompt_reset_anchor() -> anyhow::Result<()> {\n    test_key_sequence(\n        &mut AppBuilder::new().build()?,\n        Some(\":string wider than the terminal window causing the anchor location to be non zero which would panic when the line is deleted<C-u>\"),\n        Some(&|app| {\n            assert!(!app.editor.is_err());\n        }),\n        false,\n    )\n    .await?;\n\n    Ok(())\n}\n\nasync fn test_statusline(\n    line: &str,\n    expected_status: &str,\n    expected_severity: Severity,\n) -> anyhow::Result<()> {\n    test_key_sequence(\n        &mut AppBuilder::new().build()?,\n        Some(&format!(\"{line}<ret>\")),\n        Some(&|app| {\n            let (status, &severity) = app.editor.get_status().unwrap();\n            assert_eq!(\n                severity, expected_severity,\n                \"'{line}' printed {severity:?}: {status}\"\n            );\n            assert_eq!(status.as_ref(), expected_status);\n        }),\n        false,\n    )\n    .await\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn variable_expansion() -> anyhow::Result<()> {\n    test_statusline(r#\":echo %{cursor_line}\"#, \"1\", Severity::Info).await?;\n    // Double quotes can be used with expansions:\n    test_statusline(\n        r#\":echo \"line%{cursor_line}line\"\"#,\n        \"line1line\",\n        Severity::Info,\n    )\n    .await?;\n    // Within double quotes you can escape the percent token for an expansion by doubling it.\n    test_statusline(\n        r#\":echo \"%%{cursor_line}\"\"#,\n        \"%{cursor_line}\",\n        Severity::Info,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn unicode_expansion() -> anyhow::Result<()> {\n    test_statusline(r#\":echo %u{20}\"#, \" \", Severity::Info).await?;\n    test_statusline(r#\":echo %u{0020}\"#, \" \", Severity::Info).await?;\n    test_statusline(r#\":echo %u{25CF}\"#, \"●\", Severity::Info).await?;\n    // Not a valid Unicode codepoint:\n    test_statusline(\n        r#\":echo %u{deadbeef}\"#,\n        \"'echo': could not interpret 'deadbeef' as a Unicode character code\",\n        Severity::Error,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[cfg(unix)]\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn shell_expansion() -> anyhow::Result<()> {\n    test_statusline(\n        r#\":echo %sh{echo \"hello world\"}\"#,\n        \"hello world\",\n        Severity::Info,\n    )\n    .await?;\n\n    // Shell expansion is recursive.\n    test_statusline(\":echo %sh{echo '%{cursor_line}'}\", \"1\", Severity::Info).await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn percent_escaping() -> anyhow::Result<()> {\n    test_statusline(\n        r#\":sh echo hello 10%\"#,\n        \"'run-shell-command': '%' was not properly escaped. Please use '%%'\",\n        Severity::Error,\n    )\n    .await?;\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/commands/insert.rs",
    "content": "use super::*;\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn change_line_above_comment() -> anyhow::Result<()> {\n    // <https://github.com/helix-editor/helix/issues/12570>\n    test((\n        indoc! {\"\\\n        #[fn main() {}\n        |]#// a comment\n        \"},\n        \":lang rust<ret>c\",\n        indoc! {\"\\\n        #[\n        |]#// a comment\n        \"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_newline_many_selections() -> anyhow::Result<()> {\n    test((\n        indoc! {\"\\\n            #(|o)#ne\n            #(|t)#wo\n            #[|t]#hree\n            \"},\n        \"i<ret>\",\n        indoc! {\"\\\n            \\n#(|o)#ne\n\n            #(|t)#wo\n\n            #[|t]#hree\n            \"},\n    ))\n    .await?;\n\n    // In this case the global offset that adjusts selections for inserted and deleted text\n    // should become negative because more text is deleted than is inserted.\n    test((\n        indoc! {\"\\\n            #[|🏴‍☠️]#          #(|🏴‍☠️)#          #(|🏴‍☠️)#\n            #(|🏴‍☠️)#          #(|🏴‍☠️)#          #(|🏴‍☠️)#\n            \"},\n        \"i<ret>\",\n        indoc! {\"\\\n            \\n#[|🏴‍☠️]#\n            #(|🏴‍☠️)#\n            #(|🏴‍☠️)#\n\n            #(|🏴‍☠️)#\n            #(|🏴‍☠️)#\n            #(|🏴‍☠️)#\n            \"},\n    ))\n    .await?;\n\n    // <https://github.com/helix-editor/helix/issues/12495>\n    test((\n        indoc! {\"\\\n            id #(|1)#,Item #(|1)#,cost #(|1)#,location #(|1)#\n            id #(|2)#,Item #(|2)#,cost #(|2)#,location #(|2)#\n            id #(|1)##(|0)#,Item #(|1)##(|0)#,cost #(|1)##(|0)#,location #(|1)##[|0]#\"},\n        \"i<ret>\",\n        indoc! {\"\\\n            id\n            #(|1)#,Item\n            #(|1)#,cost\n            #(|1)#,location\n            #(|1)#\n            id\n            #(|2)#,Item\n            #(|2)#,cost\n            #(|2)#,location\n            #(|2)#\n            id\n            #(|1)#\n            #(|0)#,Item\n            #(|1)#\n            #(|0)#,cost\n            #(|1)#\n            #(|0)#,location\n            #(|1)#\n            #[|0]#\"},\n    ))\n    .await?;\n\n    // <https://github.com/helix-editor/helix/issues/12461>\n    test((\n        indoc! {\"\\\n            real R〉 #(||)# 〈real R〉 @ 〈real R〉\n            #(||)# 〈real R〉 + 〈ureal R〉 i #(||)# 〈real R〉 - 〈ureal R〉 i\n            #(||)# 〈real R〉 + i #(||)# 〈real R〉 - i #(||)# 〈real R〉 〈infnan〉 i\n            #(||)# + 〈ureal R〉 i #(||)# - 〈ureal R〉 i\n            #(||)# 〈infnan〉 i #(||)# + i #[||]# - i\"},\n        \"i<ret>\",\n        indoc! {\"\\\n            real R〉\n            #(||)# 〈real R〉 @ 〈real R〉\n\n            #(||)# 〈real R〉 + 〈ureal R〉 i\n            #(||)# 〈real R〉 - 〈ureal R〉 i\n\n            #(||)# 〈real R〉 + i\n            #(||)# 〈real R〉 - i\n            #(||)# 〈real R〉 〈infnan〉 i\n\n            #(||)# + 〈ureal R〉 i\n            #(||)# - 〈ureal R〉 i\n\n            #(||)# 〈infnan〉 i\n            #(||)# + i\n            #[||]# - i\"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_newline_trim_trailing_whitespace() -> anyhow::Result<()> {\n    // Trailing whitespace is trimmed.\n    test((\n        indoc! {\"\\\n            hello·······#[|\n            ]#world\n            \"}\n        .replace('·', \" \"),\n        \"i<ret>\",\n        indoc! {\"\\\n            hello\n            #[|\n            ]#world\n            \"}\n        .replace('·', \" \"),\n    ))\n    .await?;\n\n    // Whitespace that would become trailing is trimmed too.\n    test((\n        indoc! {\"\\\n            hello········#[|w]#orld\n            \"}\n        .replace('·', \" \"),\n        \"i<ret>\",\n        indoc! {\"\\\n            hello\n            #[|w]#orld\n            \"}\n        .replace('·', \" \"),\n    ))\n    .await?;\n\n    // Only whitespace before the cursor is trimmed.\n    test((\n        indoc! {\"\\\n            hello········#[|·]#····world\n            \"}\n        .replace('·', \" \"),\n        \"i<ret>\",\n        indoc! {\"\\\n            hello\n            #[|·]#····world\n            \"}\n        .replace('·', \" \"),\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_newline_trim_whitespace_to_previous_selection() -> anyhow::Result<()> {\n    test((\n        indoc! {\"\\\"#[a|]# #(a|)# #(a|)#\\\"\"},\n        \"c<ret>\",\n        indoc! {\"\\\"\\n#[\\n|]##(\\n|)##(\\\"|)#\"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_newline_continue_line_comment() -> anyhow::Result<()> {\n    // `insert_newline` continues a single line comment\n    test((\n        indoc! {\"\\\n            // Hello world!#[|\n            ]#\n            \"},\n        \":lang rust<ret>i<ret>\",\n        indoc! {\"\\\n            // Hello world!\n            // #[|\n            ]#\n            \"},\n    ))\n    .await?;\n\n    // The comment is not continued if the cursor is before the comment token. (Note that we\n    // are entering insert-mode with `I`.)\n    test((\n        indoc! {\"\\\n            // Hello world!#[|\n            ]#\n            \"},\n        \":lang rust<ret>I<ret>\",\n        indoc! {\"\\\n            \\n#[/|]#/ Hello world!\n            \"},\n    ))\n    .await?;\n\n    // `insert_newline` again clears the whitespace on the first continued comment and continues\n    // the comment again.\n    test((\n        indoc! {\"\\\n            // Hello world!\n            // #[|\n            ]#\n            \"},\n        \":lang rust<ret>i<ret>\",\n        indoc! {\"\\\n            // Hello world!\n            //\n            // #[|\n            ]#\n            \"},\n    ))\n    .await?;\n\n    // Line comment continuation and trailing whitespace is also trimmed when using\n    // `insert_newline` in the middle of a comment.\n    test((\n        indoc! {\"\\\n            //·hello····#[|·]#····world\n            \"}\n        .replace('·', \" \"),\n        \":lang rust<ret>i<ret>\",\n        indoc! {\"\\\n            //·hello\n            //·#[|·]#····world\n            \"}\n        .replace('·', \" \"),\n    ))\n    .await?;\n\n    // Comment continuation should work on multiple selections.\n    // <https://github.com/helix-editor/helix/issues/12539>\n    test((\n        indoc! {\"\\\n            ///·Docs#[|·]#\n            pub·struct·A;\n\n            ///·Docs#(|·)#\n            pub·struct·B;\n            \"}\n        .replace('·', \" \"),\n        \":lang rust<ret>i<ret><ret>\",\n        indoc! {\"\\\n            ///·Docs\n            ///\n            ///·#[|·]#\n            pub·struct·A;\n\n            ///·Docs\n            ///\n            ///·#(|·)#\n            pub·struct·B;\n            \"}\n        .replace('·', \" \"),\n    ))\n    .await?;\n\n    Ok(())\n}\n\n/// NOTE: Language is set to markdown to check if the indentation is correct for the new line\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_open_above() -> anyhow::Result<()> {\n    // `O` is pressed in the first line\n    test((\n        indoc! {\"Helix #[is|]# cool\"},\n        \":lang markdown<ret>O\",\n        indoc! {\"\\\n            #[\\n|]#\n            Helix is cool\n        \"},\n    ))\n    .await?;\n\n    // `O` is pressed in the first line, but the current line has some indentation\n    test((\n        indoc! {\"\\\n            ··This line has 2 spaces in front of it#[\\n|]#\n        \"}\n        .replace('·', \" \"),\n        \":lang markdown<ret>Oa\",\n        indoc! {\"\\\n            ··a#[\\n|]#\n            ··This line has 2 spaces in front of it\n        \"}\n        .replace('·', \" \"),\n    ))\n    .await?;\n\n    // `O` is pressed but *not* in the first line\n    test((\n        indoc! {\"\\\n            I use\n            b#[t|]#w.\n        \"},\n        \":lang markdown<ret>Oarch\",\n        indoc! {\"\\\n            I use\n            arch#[\\n|]#\n            btw.\n        \"},\n    ))\n    .await?;\n\n    // `O` is pressed but *not* in the first line and the line has some indentation\n    test((\n        indoc! {\"\\\n            I use\n            ····b#[t|]#w.\n        \"}\n        .replace(\"·\", \" \"),\n        \":lang markdown<ret>Ohelix\",\n        indoc! {\"\\\n            I use\n            ····helix#[\\n|]#\n            ····btw.\n        \"}\n        .replace(\"·\", \" \"),\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_open_above_with_multiple_cursors() -> anyhow::Result<()> {\n    // the primary cursor is also in the top line\n    test((\n        indoc! {\"#[H|]#elix\n            #(i|)#s\n            #(c|)#ool\"},\n        \"O\",\n        indoc! {\n            \"#[\\n|]#\n            Helix\n            #(\\n|)#\n            is\n            #(\\n|)#\n            cool\n            \"\n        },\n    ))\n    .await?;\n\n    // now with some additional indentation\n    test((\n        indoc! {\"····#[H|]#elix\n            ····#(i|)#s\n            ····#(c|)#ool\"}\n        .replace(\"·\", \" \"),\n        \":indent-style 4<ret>O\",\n        indoc! {\n            \"····#[\\n|]#\n            ····Helix\n            ····#(\\n|)#\n            ····is\n            ····#(\\n|)#\n            ····cool\n            \"\n        }\n        .replace(\"·\", \" \"),\n    ))\n    .await?;\n\n    // the first line is within a comment, the second not.\n    // However, if we open above, the first newly added line should start within a comment\n    // while the other should be a normal line\n    test((\n        indoc! {\"fn main() {\n                // #[VIP|]# comment\n                l#(e|)#t yes = false;\n            }\"},\n        \":lang rust<ret>O\",\n        indoc! {\"fn main() {\n                // #[\\n|]#\n                // VIP comment\n                #(\\n|)#\n                let yes = false;\n            }\"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_open_below_with_multiple_cursors() -> anyhow::Result<()> {\n    // the primary cursor is also in the top line\n    test((\n        indoc! {\"#[H|]#elix\n            #(i|)#s\n            #(c|)#ool\"},\n        \"o\",\n        indoc! {\"Helix\n            #[\\n|]#\n            is\n            #(\\n|)#\n            cool\n            #(\\n|)#\n            \"\n        },\n    ))\n    .await?;\n\n    // now with some additional indentation\n    test((\n        indoc! {\"····#[H|]#elix\n            ····#(i|)#s\n            ····#(c|)#ool\"}\n        .replace(\"·\", \" \"),\n        \":indent-style 4<ret>o\",\n        indoc! {\n            \"····Helix\n            ····#[\\n|]#\n            ····is\n            ····#(\\n|)#\n            ····cool\n            ····#(\\n|)#\n            \"\n        }\n        .replace(\"·\", \" \"),\n    ))\n    .await?;\n\n    // the first line is within a comment, the second not.\n    // However, if we open below, the first newly added line should start within a comment\n    // while the other should be a normal line\n    test((\n        indoc! {\"fn main() {\n                // #[VIP|]# comment\n                l#(e|)#t yes = false;\n            }\"},\n        \":lang rust<ret>o\",\n        indoc! {\"fn main() {\n                // VIP comment\n                // #[\\n|]#\n                let yes = false;\n                #(\\n|)#\n            }\"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n/// NOTE: To make the `open_above` comment-aware, we're setting the language for each test to rust.\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_open_above_with_comments() -> anyhow::Result<()> {\n    // `O` is pressed in the first line inside a line comment\n    test((\n        indoc! {\"// a commen#[t|]#\"},\n        \":lang rust<ret>O\",\n        indoc! {\"\\\n            // #[\\n|]#\n            // a comment\n        \"},\n    ))\n    .await?;\n\n    // `O` is pressed in the first line inside a line comment, but with indentation\n    test((\n        indoc! {\"····// a comm#[e|]#nt\"}.replace(\"·\", \" \"),\n        \":lang rust<ret>O\",\n        indoc! {\"\\\n            ····// #[\\n|]#\n            ····// a comment\n        \"}\n        .replace(\"·\", \" \"),\n    ))\n    .await?;\n\n    // `O` is pressed but not in the first line but inside a line comment\n    test((\n        indoc! {\"\\\n            fn main() { }\n            // yeetus deletus#[\\n|]#\n        \"},\n        \":lang rust<ret>O\",\n        indoc! {\"\\\n            fn main() { }\n            // #[\\n|]#\n            // yeetus deletus\n        \"},\n    ))\n    .await?;\n\n    // `O` is pressed but not in the first line but inside a line comment and with indentation\n    test((\n        indoc! {\"\\\n            fn main() { }\n            ····// yeetus deletus#[\\n|]#\n        \"}\n        .replace(\"·\", \" \"),\n        \":lang rust<ret>O\",\n        indoc! {\"\\\n            fn main() { }\n            ····// #[\\n|]#\n            ····// yeetus deletus\n        \"}\n        .replace(\"·\", \" \"),\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn try_restore_indent() -> anyhow::Result<()> {\n    // Assert that `helix_view::editor::try_restore_indent` handles line endings correctly\n    // endings.\n    test((\n        indoc! {\"\\\n        if true #[|{]#\n        }\n        \"},\n        // `try_restore_indent` should remove the indentation when adding a blank line.\n        \":lang rust<ret>o<esc>\",\n        indoc! {\"\\\n        if true {\n        #[\n        |]#}\n        \"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n// Tests being able to jump in insert mode, then undo the write performed by the jump\n// https://github.com/helix-editor/helix/issues/13480\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_jump_undo_redo() -> anyhow::Result<()> {\n    use helix_core::hashmap;\n    use helix_term::keymap;\n    use helix_view::document::Mode;\n\n    let mut config = Config::default();\n    config.keys.insert(\n        Mode::Insert,\n        keymap!({\"Insert Mode\"\n            \"C-i\" => goto_file_start,\n            \"C-o\" => goto_file_end,\n        }),\n    );\n\n    // Undo\n    test_with_config(\n        AppBuilder::new().with_config(config.clone()),\n        (\"#[|]#\", \"iworld<C-i>Hello, <esc>u\", \"#[w|]#orld\"),\n    )\n    .await?;\n\n    // Redo\n    test_with_config(\n        AppBuilder::new().with_config(config),\n        (\n            \"#[|]#\",\n            \"iworld<C-i>Hello, <esc>ui<C-o><esc>U\",\n            \"Hello, #[w|]#orld\",\n        ),\n    )\n    .await?;\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_indent_with_spaces() -> anyhow::Result<()> {\n    let tests = vec![\n        // at start of line\n        (\n            indoc! {\"\\\n                SELECT *\n                  #[|FROM table]#\n                 #(|WHERE condition)#\n            \"},\n            \"i<tab>\",\n            indoc! {\"\\\n                SELECT *\n                    #[|FROM table]#\n                    #(|WHERE condition)#\n            \"},\n        ),\n        // in the middle of line\n        (\n            indoc! {\"\\\n                SELECT #[*|]#\n                FROM #(table|)#\n                WHERE #(condition|)#\n            \"},\n            \"i<S-tab>\",\n            indoc! {\"\\\n                SELECT  #[|*]#\n                FROM    #(|table)#\n                WHERE   #(|condition)#\n            \"},\n        ),\n        // indentation in normal mode\n        (\n            indoc! {\"\\\n                -- comment\n                #[|SELECT *\n                  FROM table\n                 WHERE condition]#\n            \"},\n            \"<gt>\",\n            indoc! {\"\\\n                -- comment\n                    #[|SELECT *\n                    FROM table\n                    WHERE condition]#\n            \"},\n        ),\n    ];\n\n    for test in tests {\n        test_with_config(AppBuilder::new().with_file(\"foo.rs\", None), test).await?;\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/commands/movement.rs",
    "content": "use super::*;\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_move_parent_node_end() -> anyhow::Result<()> {\n    let tests = vec![\n        // single cursor stays single cursor, first goes to end of current\n        // node, then parent\n        (\n            indoc! {r##\"\n                fn foo() {\n                    let result = if true {\n                        \"yes\"\n                    } else {\n                        \"no#[\"|]#\n                    }\n                }\n            \"##},\n            \"<A-e>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        \\\"no\\\"#[\\n|]#\n                    }\n                }\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        \\\"no\\\"#[\\n|]#\n                    }\n                }\n            \"},\n            \"<A-e>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        \\\"no\\\"\n                    }#[\\n|]#\n                }\n            \"},\n        ),\n        // select mode extends\n        (\n            indoc! {r##\"\n                fn foo() {\n                    let result = if true {\n                        \"yes\"\n                    } else {\n                        #[\"no\"|]#\n                    }\n                }\n            \"##},\n            \"v<A-e><A-e>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        #[\\\"no\\\"\n                    }\\n|]#\n                }\n            \"},\n        ),\n    ];\n\n    for test in tests {\n        test_with_config(AppBuilder::new().with_file(\"foo.rs\", None), test).await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_move_parent_node_start() -> anyhow::Result<()> {\n    let tests = vec![\n        // single cursor stays single cursor, first goes to end of current\n        // node, then parent\n        (\n            indoc! {r##\"\n                fn foo() {\n                    let result = if true {\n                        \"yes\"\n                    } else {\n                        \"no#[\"|]#\n                    }\n                }\n            \"##},\n            \"<A-b>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        #[\\\"|]#no\\\"\n                    }\n                }\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        \\\"no\\\"#[\\n|]#\n                    }\n                }\n            \"},\n            \"<A-b>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else #[{|]#\n                        \\\"no\\\"\n                    }\n                }\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else #[{|]#\n                        \\\"no\\\"\n                    }\n                }\n            \"},\n            \"<A-b>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } #[e|]#lse {\n                        \\\"no\\\"\n                    }\n                }\n            \"},\n        ),\n        // select mode extends\n        (\n            indoc! {r##\"\n                fn foo() {\n                    let result = if true {\n                        \"yes\"\n                    } else {\n                        #[\"no\"|]#\n                    }\n                }\n            \"##},\n            \"v<A-b><A-b>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else #[|{\n                        ]#\\\"no\\\"\n                    }\n                }\n            \"},\n        ),\n        (\n            indoc! {r##\"\n                fn foo() {\n                    let result = if true {\n                        \"yes\"\n                    } else {\n                        #[\"no\"|]#\n                    }\n                }\n            \"##},\n            \"v<A-b><A-b><A-b>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } #[|else {\n                        ]#\\\"no\\\"\n                    }\n                }\n            \"},\n        ),\n    ];\n\n    for test in tests {\n        test_with_config(AppBuilder::new().with_file(\"foo.rs\", None), test).await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {\n    let tests = vec![\n        // single cursor stays single cursor, first goes to end of current\n        // node, then parent\n        (\n            indoc! {r##\"\n                fn foo() {\n                    let result = if true {\n                        \"yes\"\n                    } else {\n                        \"no#[\"|]#\n                    }\n                }\n            \"##},\n            \"i<tab>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        \\\"no\\\"#[|\\n]#\n                    }\n                }\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        \\\"no\\\"#[\\n|]#\n                    }\n                }\n            \"},\n            \"i<tab>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        \\\"no\\\"\n                    }#[|\\n]#\n                }\n            \"},\n        ),\n        // appending to the end of a line should still look at the current\n        // line, not the next one\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        \\\"no#[\\\"|]#\n                    }\n                }\n            \"},\n            \"a<tab>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        \\\"no\\\"\n                    }#[\\n|]#\n                }\n            \"},\n        ),\n        // before cursor is all whitespace, so insert tab\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        #[\\\"no\\\"|]#\n                    }\n                }\n            \"},\n            \"i<tab>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                            #[|\\\"no\\\"]#\n                    }\n                }\n            \"},\n        ),\n        // if selection spans multiple lines, it should still only look at the\n        // line on which the head is\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        #[\\\"yes\\\"\n                    } else {\n                        \\\"no\\\"|]#\n                    }\n                }\n            \"},\n            \"a<tab>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    } else {\n                        \\\"no\\\"\n                    }#[\\n|]#\n                }\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        #[\\\"yes\\\"\n                    } else {\n                        \\\"no\\\"|]#\n                    }\n                }\n            \"},\n            \"i<tab>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                            #[|\\\"yes\\\"\n                    } else {\n                        \\\"no\\\"]#\n                    }\n                }\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                fn foo() {\n                    #[l|]#et result = if true {\n                        #(\\\"yes\\\"\n                    } else {\n                        \\\"no\\\"|)#\n                    }\n                }\n            \"},\n            \"i<tab>\",\n            indoc! {\"\\\n                fn foo() {\n                        #[|l]#et result = if true {\n                            #(|\\\"yes\\\"\n                    } else {\n                        \\\"no\\\")#\n                    }\n                }\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"#[\\n|]#\n                    } else {\n                        \\\"no\\\"#(\\n|)#\n                    }\n                }\n            \"},\n            \"i<tab>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    }#[| ]#else {\n                        \\\"no\\\"\n                    }#(|\\n)#\n                }\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        #[\\\"yes\\\"|]#\n                    } else {\n                        #(\\\"no\\\"|)#\n                    }\n                }\n            \"},\n            \"i<tab>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                            #[|\\\"yes\\\"]#\n                    } else {\n                            #(|\\\"no\\\")#\n                    }\n                }\n            \"},\n        ),\n        // if any cursors are not preceded by all whitespace, then do the\n        // smart_tab action\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        #[\\\"yes\\\"\\n|]#\n                    } else {\n                        \\\"no#(\\\"\\n|)#\n                    }\n                }\n            \"},\n            \"i<tab>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        \\\"yes\\\"\n                    }#[| ]#else {\n                        \\\"no\\\"\n                    }#(|\\n)#\n                }\n            \"},\n        ),\n        // Ctrl-tab always inserts a tab\n        (\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                        #[\\\"yes\\\"\\n|]#\n                    } else {\n                        \\\"no#(\\\"\\n|)#\n                    }\n                }\n            \"},\n            \"i<S-tab>\",\n            indoc! {\"\\\n                fn foo() {\n                    let result = if true {\n                            #[|\\\"yes\\\"\\n]#\n                    } else {\n                        \\\"no #(|\\\"\\n)#\n                    }\n                }\n            \"},\n        ),\n    ];\n\n    for test in tests {\n        test_with_config(AppBuilder::new().with_file(\"foo.rs\", None), test).await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn select_all_siblings() -> anyhow::Result<()> {\n    let tests = vec![\n        // basic tests\n        (\n            indoc! {r##\"\n                let foo = bar(#[a|]#, b, c);\n            \"##},\n            \"<A-a>\",\n            indoc! {r##\"\n                let foo = bar(#[a|]#, #(b|)#, #(c|)#);\n            \"##},\n        ),\n        (\n            indoc! {r##\"\n                let a = [\n                    #[1|]#,\n                    2,\n                    3,\n                    4,\n                    5,\n                ];\n            \"##},\n            \"<A-a>\",\n            indoc! {r##\"\n                let a = [\n                    #[1|]#,\n                    #(2|)#,\n                    #(3|)#,\n                    #(4|)#,\n                    #(5|)#,\n                ];\n            \"##},\n        ),\n        // direction is preserved\n        (\n            indoc! {r##\"\n                let a = [\n                    #[|1]#,\n                    2,\n                    3,\n                    4,\n                    5,\n                ];\n            \"##},\n            \"<A-a>\",\n            indoc! {r##\"\n                let a = [\n                    #[|1]#,\n                    #(|2)#,\n                    #(|3)#,\n                    #(|4)#,\n                    #(|5)#,\n                ];\n            \"##},\n        ),\n        // can't pick any more siblings - selection stays the same\n        (\n            indoc! {r##\"\n                let a = [\n                    #[1|]#,\n                    #(2|)#,\n                    #(3|)#,\n                    #(4|)#,\n                    #(5|)#,\n                ];\n            \"##},\n            \"<A-a>\",\n            indoc! {r##\"\n                let a = [\n                    #[1|]#,\n                    #(2|)#,\n                    #(3|)#,\n                    #(4|)#,\n                    #(5|)#,\n                ];\n            \"##},\n        ),\n        // each cursor does the sibling select independently\n        (\n            indoc! {r##\"\n                let a = [\n                    #[1|]#,\n                    2,\n                    3,\n                    4,\n                    5,\n                ];\n\n                let b = [\n                    #(\"one\"|)#,\n                    \"two\",\n                    \"three\",\n                    \"four\",\n                    \"five\",\n                ];\n            \"##},\n            \"<A-a>\",\n            indoc! {r##\"\n                let a = [\n                    #[1|]#,\n                    #(2|)#,\n                    #(3|)#,\n                    #(4|)#,\n                    #(5|)#,\n                ];\n\n                let b = [\n                    #(\"one\"|)#,\n                    #(\"two\"|)#,\n                    #(\"three\"|)#,\n                    #(\"four\"|)#,\n                    #(\"five\"|)#,\n                ];\n            \"##},\n        ),\n        // conflicting sibling selections get normalized. Here, the primary\n        // selection would choose every list item, but because the secondary\n        // range covers more than one item, the descendent is the entire list,\n        // which means the sibling is the assignment. The list item ranges just\n        // get normalized out since the list itself becomes selected.\n        (\n            indoc! {r##\"\n                let a = [\n                    #[1|]#,\n                    2,\n                    #(3,\n                    4|)#,\n                    5,\n                ];\n            \"##},\n            \"<A-a>\",\n            indoc! {r##\"\n                let #(a|)# = #[[\n                    1,\n                    2,\n                    3,\n                    4,\n                    5,\n                ]|]#;\n            \"##},\n        ),\n    ];\n\n    for test in tests {\n        test_with_config(AppBuilder::new().with_file(\"foo.rs\", None), test).await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn select_all_children() -> anyhow::Result<()> {\n    let tests = vec![\n        // basic tests\n        (\n            indoc! {r##\"\n                let foo = bar#[(a, b, c)|]#;\n            \"##},\n            \"<A-I>\",\n            indoc! {r##\"\n                let foo = bar(#[a|]#, #(b|)#, #(c|)#);\n            \"##},\n        ),\n        (\n            indoc! {r##\"\n                let a = #[[\n                    1,\n                    2,\n                    3,\n                    4,\n                    5,\n                ]|]#;\n            \"##},\n            \"<A-I>\",\n            indoc! {r##\"\n                let a = [\n                    #[1|]#,\n                    #(2|)#,\n                    #(3|)#,\n                    #(4|)#,\n                    #(5|)#,\n                ];\n            \"##},\n        ),\n        // direction is preserved\n        (\n            indoc! {r##\"\n                let a = #[|[\n                    1,\n                    2,\n                    3,\n                    4,\n                    5,\n                ]]#;\n            \"##},\n            \"<A-I>\",\n            indoc! {r##\"\n                let a = [\n                    #[|1]#,\n                    #(|2)#,\n                    #(|3)#,\n                    #(|4)#,\n                    #(|5)#,\n                ];\n            \"##},\n        ),\n        // can't pick any more children - selection stays the same\n        (\n            indoc! {r##\"\n                let a = [\n                    #[1|]#,\n                    #(2|)#,\n                    #(3|)#,\n                    #(4|)#,\n                    #(5|)#,\n                ];\n            \"##},\n            \"<A-I>\",\n            indoc! {r##\"\n                let a = [\n                    #[1|]#,\n                    #(2|)#,\n                    #(3|)#,\n                    #(4|)#,\n                    #(5|)#,\n                ];\n            \"##},\n        ),\n        // each cursor does the sibling select independently\n        (\n            indoc! {r##\"\n                let a = #[|[\n                    1,\n                    2,\n                    3,\n                    4,\n                    5,\n                ]]#;\n\n                let b = #([\n                    \"one\",\n                    \"two\",\n                    \"three\",\n                    \"four\",\n                    \"five\",\n                ]|)#;\n            \"##},\n            \"<A-I>\",\n            indoc! {r##\"\n                let a = [\n                    #[|1]#,\n                    #(|2)#,\n                    #(|3)#,\n                    #(|4)#,\n                    #(|5)#,\n                ];\n\n                let b = [\n                    #(\"one\"|)#,\n                    #(\"two\"|)#,\n                    #(\"three\"|)#,\n                    #(\"four\"|)#,\n                    #(\"five\"|)#,\n                ];\n            \"##},\n        ),\n    ];\n\n    for test in tests {\n        test_with_config(AppBuilder::new().with_file(\"foo.rs\", None), test).await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_select_next_sibling() -> anyhow::Result<()> {\n    let tests = vec![\n        // basic test\n        (\n            indoc! {r##\"\n                fn inc(x: usize) -> usize { x + 1 #[}|]#\n                fn dec(x: usize) -> usize { x - 1 }\n                fn ident(x: usize) -> usize { x }\n            \"##},\n            \"<A-n>\",\n            indoc! {r##\"\n                fn inc(x: usize) -> usize { x + 1 }\n                #[fn dec(x: usize) -> usize { x - 1 }|]#\n                fn ident(x: usize) -> usize { x }\n            \"##},\n        ),\n        // direction is not preserved and is always forward.\n        (\n            indoc! {r##\"\n                fn inc(x: usize) -> usize { x + 1 #[}|]#\n                fn dec(x: usize) -> usize { x - 1 }\n                fn ident(x: usize) -> usize { x }\n            \"##},\n            \"<A-n><A-;><A-n>\",\n            indoc! {r##\"\n                fn inc(x: usize) -> usize { x + 1 }\n                fn dec(x: usize) -> usize { x - 1 }\n                #[fn ident(x: usize) -> usize { x }|]#\n            \"##},\n        ),\n    ];\n\n    for test in tests {\n        test_with_config(AppBuilder::new().with_file(\"foo.rs\", None), test).await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_select_prev_sibling() -> anyhow::Result<()> {\n    let tests = vec![\n        // basic test\n        (\n            indoc! {r##\"\n                fn inc(x: usize) -> usize { x + 1 }\n                fn dec(x: usize) -> usize { x - 1 }\n                #[|f]#n ident(x: usize) -> usize { x }\n            \"##},\n            \"<A-p>\",\n            indoc! {r##\"\n                fn inc(x: usize) -> usize { x + 1 }\n                #[|fn dec(x: usize) -> usize { x - 1 }]#\n                fn ident(x: usize) -> usize { x }\n            \"##},\n        ),\n        // direction is not preserved and is always backward.\n        (\n            indoc! {r##\"\n                fn inc(x: usize) -> usize { x + 1 }\n                fn dec(x: usize) -> usize { x - 1 }\n                #[|f]#n ident(x: usize) -> usize { x }\n            \"##},\n            \"<A-p><A-;><A-p>\",\n            indoc! {r##\"\n                #[|fn inc(x: usize) -> usize { x + 1 }]#\n                fn dec(x: usize) -> usize { x - 1 }\n                fn ident(x: usize) -> usize { x }\n            \"##},\n        ),\n    ];\n\n    for test in tests {\n        test_with_config(AppBuilder::new().with_file(\"foo.rs\", None), test).await?;\n    }\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn match_bracket() -> anyhow::Result<()> {\n    let rust_tests = vec![\n        // fwd\n        (\n            indoc! {r##\"\n                fn foo(x: usize) -> usize { #[x|]# + 1 }\n            \"##},\n            \"mm\",\n            indoc! {r##\"\n                fn foo(x: usize) -> usize { x + 1 #[}|]#\n            \"##},\n        ),\n        // backward\n        (\n            indoc! {r##\"\n                fn foo(x: usize) -> usize { #[x|]# + 1 }\n            \"##},\n            \"mmmm\",\n            indoc! {r##\"\n                fn foo(x: usize) -> usize #[{|]# x + 1 }\n            \"##},\n        ),\n        // avoid false positive inside string literal\n        (\n            indoc! {r##\"\n                fn foo() -> &'static str { \"(hello#[ |]#world)\" }\n            \"##},\n            \"mm\",\n            indoc! {r##\"\n                fn foo() -> &'static str { \"(hello world)#[\"|]# }\n            \"##},\n        ),\n        // make sure matching on quotes works\n        (\n            indoc! {r##\"\n                fn foo() -> &'static str { \"(hello#[ |]#world)\" }\n            \"##},\n            \"mm\",\n            indoc! {r##\"\n                fn foo() -> &'static str { \"(hello world)#[\"|]# }\n            \"##},\n        ),\n        // .. on both ends\n        (\n            indoc! {r##\"\n                fn foo() -> &'static str { \"(hello#[ |]#world)\" }\n            \"##},\n            \"mmmm\",\n            indoc! {r##\"\n                fn foo() -> &'static str { #[\"|]#(hello world)\" }\n            \"##},\n        ),\n        // match on siblings nodes\n        (\n            indoc! {r##\"\n                fn foo(bar: Option<usize>) -> usize {\n                    match bar {\n                        Some(b#[a|]#r) => bar,\n                        None => 42,\n                    } \n                }\n            \"##},\n            \"mmmm\",\n            indoc! {r##\"\n                fn foo(bar: Option<usize>) -> usize {\n                    match bar {\n                        Some#[(|]#bar) => bar,\n                        None => 42,\n                    } \n                }\n            \"##},\n        ),\n        // gracefully handle multiple sibling brackets (usally for errors/incomplete syntax trees)\n        // in the past we selected the first > instead of the second > here\n        (\n            indoc! {r##\"\n                fn foo() {\n                    foo::<b#[a|]#r<>> \n                }\n            \"##},\n            \"mm\",\n            indoc! {r##\"\n                fn foo() {\n                    foo::<bar<>#[>|]# \n                }\n            \"##},\n        ),\n        // named node with 2 or more children\n        (\n            indoc! {r##\"\n                use a::#[{|]#\n                    b::{c, d, e, f, g},\n                    h, i, j, k, l, m, n,\n                };\n            \"##},\n            \"mm\",\n            indoc! {r##\"\n                use a::{\n                    b::{c, d, e, f, g},\n                    h, i, j, k, l, m, n,\n                #[}|]#;\n            \"##},\n        ),\n    ];\n\n    let python_tests = vec![\n        // python quotes have a slightly more complex syntax tree\n        // that triggerd a bug in an old implementation so we test\n        // them here\n        (\n            indoc! {r##\"\n                foo_python = \"mm does not#[ |]#work on this string\"\n            \"##},\n            \"mm\",\n            indoc! {r##\"\n                foo_python = \"mm does not work on this string#[\"|]#\n            \"##},\n        ),\n        (\n            indoc! {r##\"\n                foo_python = \"mm does not#[ |]#work on this string\"\n            \"##},\n            \"mmmm\",\n            indoc! {r##\"\n                foo_python = #[\"|]#mm does not work on this string\"\n            \"##},\n        ),\n    ];\n\n    for test in rust_tests {\n        println!(\"{test:?}\");\n        test_with_config(AppBuilder::new().with_file(\"foo.rs\", None), test).await?;\n    }\n    for test in python_tests {\n        println!(\"{test:?}\");\n        test_with_config(AppBuilder::new().with_file(\"foo.py\", None), test).await?;\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/commands/reverse_selection_contents.rs",
    "content": "use super::*;\n\nconst A: &str = indoc! {\"\n    #(a|)#\n    #(b|)#\n    #(c|)#\n    #[d|]#\n    #(e|)#\"\n};\nconst A_REV: &str = indoc! {\"\n    #(e|)#\n    #[d|]#\n    #(c|)#\n    #(b|)#\n    #(a|)#\"\n};\nconst B: &str = indoc! {\"\n    #(a|)#\n    #(b|)#\n    #[c|]#\n    #(d|)#\n    #(e|)#\"\n};\nconst B_REV: &str = indoc! {\"\n    #(e|)#\n    #(d|)#\n    #[c|]#\n    #(b|)#\n    #(a|)#\"\n};\n\nconst CMD: &str = \"<space>?reverse_selection_contents<ret>\";\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn reverse_selection_contents() -> anyhow::Result<()> {\n    test((A, CMD, A_REV)).await?;\n    test((B, CMD, B_REV)).await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn reverse_selection_contents_with_count() -> anyhow::Result<()> {\n    test((B, format!(\"2{CMD}\"), B)).await?;\n    test((B, format!(\"3{CMD}\"), B_REV)).await?;\n    test((B, format!(\"4{CMD}\"), B)).await?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/commands/rotate_selection_contents.rs",
    "content": "use super::*;\n\n// Progression: A -> B -> C -> D\n//              as we press `A-)`\nconst A: &str = indoc! {\"\n    #(a|)#\n    #(b|)#\n    #(c|)#\n    #[d|]#\n    #(e|)#\"\n};\n\nconst B: &str = indoc! {\"\n    #(e|)#\n    #(a|)#\n    #(b|)#\n    #(c|)#\n    #[d|]#\"\n};\n\nconst C: &str = indoc! {\"\n    #[d|]#\n    #(e|)#\n    #(a|)#\n    #(b|)#\n    #(c|)#\"\n};\n\nconst D: &str = indoc! {\"\n    #(c|)#\n    #[d|]#\n    #(e|)#\n    #(a|)#\n    #(b|)#\"\n};\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn rotate_selection_contents_forward_repeated() -> anyhow::Result<()> {\n    test((A, \"<A-)>\", B)).await?;\n    test((B, \"<A-)>\", C)).await?;\n    test((C, \"<A-)>\", D)).await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn rotate_selection_contents_forward_with_count() -> anyhow::Result<()> {\n    test((A, \"2<A-)>\", C)).await?;\n    test((A, \"3<A-)>\", D)).await?;\n    test((B, \"2<A-)>\", D)).await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn rotate_selection_contents_backward_repeated() -> anyhow::Result<()> {\n    test((D, \"<A-(>\", C)).await?;\n    test((C, \"<A-(>\", B)).await?;\n    test((B, \"<A-(>\", A)).await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn rotate_selection_contents_backward_with_count() -> anyhow::Result<()> {\n    test((D, \"2<A-(>\", B)).await?;\n    test((D, \"3<A-(>\", A)).await?;\n    test((C, \"2<A-(>\", A)).await?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/commands/write.rs",
    "content": "use std::{\n    io::{Read, Seek, Write},\n    ops::RangeInclusive,\n};\n\nuse helix_core::diagnostic::Severity;\nuse helix_stdx::path;\nuse helix_view::doc;\n\nuse super::*;\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_exit_w_buffer_w_path() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n    // Check for write operation on given path and edited buffer\n    test_key_sequence(\n        &mut app,\n        Some(\"iBecause of the obvious threat to untold numbers of citizens due to the crisis that is even now developing, this radio station will remain on the air day and night.<ret><esc>:x<ret>\"),\n        None,\n        true,\n    )\n    .await?;\n\n    reload_file(&mut file).unwrap();\n    let mut file_content = String::new();\n    file.as_file_mut().read_to_string(&mut file_content)?;\n\n    assert_eq!(\n        LineFeedHandling::Native.apply(\"Because of the obvious threat to untold numbers of citizens due to the crisis that is even now developing, this radio station will remain on the air day and night.\\n\"),\n        file_content\n    );\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_exit_wo_buffer_w_path() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n\n    helpers::run_event_loop_until_idle(&mut app).await;\n\n    file.as_file_mut()\n        .write_all(\"extremely important content\".as_bytes())?;\n    file.as_file_mut().flush()?;\n    file.as_file_mut().sync_all()?;\n\n    test_key_sequence(&mut app, Some(\":x<ret>\"), None, true).await?;\n\n    reload_file(&mut file).unwrap();\n    let mut file_content = String::new();\n    file.read_to_string(&mut file_content)?;\n    // check that nothing is written to file\n    assert_eq!(\"extremely important content\", file_content);\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_exit_wo_buffer_wo_path() -> anyhow::Result<()> {\n    test_key_sequence(\n        &mut AppBuilder::new().build()?,\n        Some(\":x<ret>\"),\n        Some(&|app| {\n            assert!(!app.editor.is_err());\n        }),\n        true,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_exit_w_buffer_wo_file() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    test_key_sequence(\n        // try to write without destination\n        &mut AppBuilder::new().build()?,\n        Some(\"itest<esc>:x<ret>\"),\n        None,\n        false,\n    )\n    .await?;\n    test_key_sequence(\n        // try to write with path succeeds\n        &mut AppBuilder::new().build()?,\n        Some(format!(\"iMicCheck<esc>:x {}<ret>\", file.path().to_string_lossy()).as_ref()),\n        Some(&|app| {\n            assert!(!app.editor.is_err());\n        }),\n        true,\n    )\n    .await?;\n\n    helpers::assert_file_has_content(&mut file, &LineFeedHandling::Native.apply(\"MicCheck\"))?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_quit_fail() -> anyhow::Result<()> {\n    let file = helpers::new_readonly_tempfile()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(\"ihello<esc>:wq<ret>\"),\n        Some(&|app| {\n            let mut docs: Vec<_> = app.editor.documents().collect();\n            assert_eq!(1, docs.len());\n\n            let doc = docs.pop().unwrap();\n            assert_eq!(Some(&path::normalize(file.path())), doc.path());\n            assert_eq!(&Severity::Error, app.editor.get_status().unwrap().1);\n        }),\n        false,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_buffer_close_concurrent() -> anyhow::Result<()> {\n    test_key_sequences(\n        &mut helpers::AppBuilder::new().build()?,\n        vec![\n            (\n                None,\n                Some(&|app| {\n                    assert_eq!(1, app.editor.documents().count());\n                    assert!(!app.editor.is_err());\n                }),\n            ),\n            (\n                Some(\"ihello<esc>:new<ret>\"),\n                Some(&|app| {\n                    assert_eq!(2, app.editor.documents().count());\n                    assert!(!app.editor.is_err());\n                }),\n            ),\n            (\n                Some(\":buffer<minus>close<ret>\"),\n                Some(&|app| {\n                    assert_eq!(1, app.editor.documents().count());\n                    assert!(!app.editor.is_err());\n                }),\n            ),\n        ],\n        false,\n    )\n    .await?;\n\n    // verify if writes are queued up, it finishes them before closing the buffer\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut command = String::new();\n    const RANGE: RangeInclusive<i32> = 1..=1000;\n\n    for i in RANGE {\n        let cmd = format!(\"%c{}<esc>:w!<ret>\", i);\n        command.push_str(&cmd);\n    }\n\n    command.push_str(\":buffer<minus>close<ret>\");\n\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(&command),\n        Some(&|app| {\n            assert!(!app.editor.is_err(), \"error: {:?}\", app.editor.get_status());\n\n            let doc = app.editor.document_by_path(file.path());\n            assert!(doc.is_none(), \"found doc: {:?}\", doc);\n        }),\n        false,\n    )\n    .await?;\n\n    helpers::assert_file_has_content(\n        &mut file,\n        &LineFeedHandling::Native.apply(&RANGE.end().to_string()),\n    )?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(\"ithe gostak distims the doshes<ret><esc>:w<ret>\"),\n        None,\n        false,\n    )\n    .await?;\n\n    reload_file(&mut file).unwrap();\n    let mut file_content = String::new();\n    file.as_file_mut().read_to_string(&mut file_content)?;\n\n    assert_eq!(\n        LineFeedHandling::Native.apply(\"the gostak distims the doshes\"),\n        file_content\n    );\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_overwrite_protection() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n\n    helpers::run_event_loop_until_idle(&mut app).await;\n\n    file.as_file_mut()\n        .write_all(\"extremely important content\".as_bytes())?;\n\n    file.as_file_mut().flush()?;\n    file.as_file_mut().sync_all()?;\n\n    test_key_sequence(&mut app, Some(\"iOverwriteData<esc>:x<ret>\"), None, false).await?;\n\n    reload_file(&mut file).unwrap();\n    let mut file_content = String::new();\n    file.read_to_string(&mut file_content)?;\n\n    assert_eq!(\"extremely important content\", file_content);\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_quit() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(\"ithe gostak distims the doshes<ret><esc>:wq<ret>\"),\n        None,\n        true,\n    )\n    .await?;\n\n    reload_file(&mut file).unwrap();\n\n    let mut file_content = String::new();\n    file.read_to_string(&mut file_content)?;\n\n    assert_eq!(\n        LineFeedHandling::Native.apply(\"the gostak distims the doshes\"),\n        file_content\n    );\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_concurrent() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut command = String::new();\n    const RANGE: RangeInclusive<i32> = 1..=1000;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n\n    for i in RANGE {\n        let cmd = format!(\"%c{}<esc>:w!<ret>\", i);\n        command.push_str(&cmd);\n    }\n\n    test_key_sequence(&mut app, Some(&command), None, false).await?;\n\n    reload_file(&mut file).unwrap();\n    let mut file_content = String::new();\n    file.read_to_string(&mut file_content)?;\n    assert_eq!(\n        LineFeedHandling::Native.apply(&RANGE.end().to_string()),\n        file_content\n    );\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_fail_mod_flag() -> anyhow::Result<()> {\n    let file = helpers::new_readonly_tempfile()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n\n    test_key_sequences(\n        &mut app,\n        vec![\n            (\n                None,\n                Some(&|app| {\n                    let doc = doc!(app.editor);\n                    assert!(!doc.is_modified());\n                }),\n            ),\n            (\n                Some(\"ihello<esc>\"),\n                Some(&|app| {\n                    let doc = doc!(app.editor);\n                    assert!(doc.is_modified());\n                }),\n            ),\n            (\n                Some(\":w<ret>\"),\n                Some(&|app| {\n                    assert_eq!(&Severity::Error, app.editor.get_status().unwrap().1);\n\n                    let doc = doc!(app.editor);\n                    assert!(doc.is_modified());\n                }),\n            ),\n        ],\n        false,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_scratch_to_new_path() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n\n    test_key_sequence(\n        &mut AppBuilder::new().build()?,\n        Some(format!(\"ihello<esc>:w {}<ret>\", file.path().to_string_lossy()).as_ref()),\n        Some(&|app| {\n            assert!(!app.editor.is_err());\n\n            let mut docs: Vec<_> = app.editor.documents().collect();\n            assert_eq!(1, docs.len());\n\n            let doc = docs.pop().unwrap();\n            assert_eq!(Some(&path::normalize(file.path())), doc.path());\n        }),\n        false,\n    )\n    .await?;\n\n    helpers::assert_file_has_content(&mut file, &LineFeedHandling::Native.apply(\"hello\"))?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_scratch_to_new_path_force_creates_file() -> anyhow::Result<()> {\n    let dir = tempfile::tempdir()?;\n    let new_path = dir.path().join(\"new-file.txt\");\n\n    test_key_sequence(\n        &mut AppBuilder::new().build()?,\n        Some(format!(\"ihello<esc>:w! {}<ret>\", new_path.to_string_lossy()).as_ref()),\n        Some(&|app| {\n            assert!(!app.editor.is_err());\n\n            let mut docs: Vec<_> = app.editor.documents().collect();\n            assert_eq!(1, docs.len());\n\n            let doc = docs.pop().unwrap();\n            assert_eq!(Some(&path::normalize(&new_path)), doc.path());\n        }),\n        false,\n    )\n    .await?;\n\n    let file_content = std::fs::read_to_string(&new_path)?;\n    assert_eq!(file_content, LineFeedHandling::Native.apply(\"hello\"));\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_scratch_no_path_fails() -> anyhow::Result<()> {\n    helpers::test_key_sequence_with_input_text(\n        None,\n        (\"#[\\n|]#\", \"ihello<esc>:w<ret>\", \"hello#[\\n|]#\"),\n        &|app| {\n            assert!(app.editor.is_err());\n\n            let mut docs: Vec<_> = app.editor.documents().collect();\n            assert_eq!(1, docs.len());\n\n            let doc = docs.pop().unwrap();\n            assert_eq!(None, doc.path());\n        },\n        false,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_auto_format_fails_still_writes() -> anyhow::Result<()> {\n    let mut file = tempfile::Builder::new().suffix(\".rs\").tempfile()?;\n\n    let lang_conf = indoc! {r#\"\n            [[language]]\n            name = \"rust\"\n            formatter = { command = \"bash\", args = [ \"-c\", \"exit 1\" ] }\n        \"#};\n\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .with_input_text(\"#[l|]#et foo = 0;\\n\")\n        .with_lang_loader(helpers::test_syntax_loader(Some(lang_conf.into())))\n        .build()?;\n\n    test_key_sequences(&mut app, vec![(Some(\":w<ret>\"), None)], false).await?;\n\n    // file still saves\n    helpers::assert_file_has_content(&mut file, \"let foo = 0;\\n\")?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_new_path() -> anyhow::Result<()> {\n    let mut file1 = tempfile::NamedTempFile::new().unwrap();\n    let mut file2 = tempfile::NamedTempFile::new().unwrap();\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file1.path(), None)\n        .build()?;\n\n    test_key_sequences(\n        &mut app,\n        vec![\n            (\n                Some(\"ii can eat glass, it will not hurt me<ret><esc>:w<ret>\"),\n                Some(&|app| {\n                    let doc = doc!(app.editor);\n                    assert!(!app.editor.is_err());\n                    assert_eq!(&path::normalize(file1.path()), doc.path().unwrap());\n                }),\n            ),\n            (\n                Some(&format!(\":w {}<ret>\", file2.path().to_string_lossy())),\n                Some(&|app| {\n                    let doc = doc!(app.editor);\n                    assert!(!app.editor.is_err());\n                    assert_eq!(&path::normalize(file2.path()), doc.path().unwrap());\n                    assert!(app.editor.document_by_path(file1.path()).is_none());\n                }),\n            ),\n        ],\n        false,\n    )\n    .await?;\n\n    helpers::assert_file_has_content(\n        &mut file1,\n        &LineFeedHandling::Native.apply(\"i can eat glass, it will not hurt me\\n\"),\n    )?;\n\n    helpers::assert_file_has_content(\n        &mut file2,\n        &LineFeedHandling::Native.apply(\"i can eat glass, it will not hurt me\\n\"),\n    )?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_fail_new_path() -> anyhow::Result<()> {\n    let file = helpers::new_readonly_tempfile()?;\n\n    test_key_sequences(\n        &mut AppBuilder::new().build()?,\n        vec![\n            (\n                None,\n                Some(&|app| {\n                    let doc = doc!(app.editor);\n                    assert_ne!(\n                        Some(&Severity::Error),\n                        app.editor.get_status().map(|status| status.1)\n                    );\n                    assert_eq!(None, doc.path());\n                }),\n            ),\n            (\n                Some(&format!(\":w {}<ret>\", file.path().to_string_lossy())),\n                Some(&|app| {\n                    let doc = doc!(app.editor);\n                    assert_eq!(\n                        Some(&Severity::Error),\n                        app.editor.get_status().map(|status| status.1)\n                    );\n                    assert_eq!(None, doc.path());\n                }),\n            ),\n        ],\n        false,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_utf_bom_file() -> anyhow::Result<()> {\n    // \"ABC\" with utf8 bom\n    const UTF8_FILE: [u8; 6] = [0xef, 0xbb, 0xbf, b'A', b'B', b'C'];\n\n    // \"ABC\" in UTF16 with bom\n    const UTF16LE_FILE: [u8; 8] = [0xff, 0xfe, b'A', 0x00, b'B', 0x00, b'C', 0x00];\n    const UTF16BE_FILE: [u8; 8] = [0xfe, 0xff, 0x00, b'A', 0x00, b'B', 0x00, b'C'];\n\n    edit_file_with_content(&UTF8_FILE).await?;\n    edit_file_with_content(&UTF16LE_FILE).await?;\n    edit_file_with_content(&UTF16BE_FILE).await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_trim_trailing_whitespace() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_config(Config {\n            editor: helix_view::editor::Config {\n                trim_trailing_whitespace: true,\n                ..Default::default()\n            },\n            ..Default::default()\n        })\n        .with_file(file.path(), None)\n        .with_input_text(LineFeedHandling::Native.apply(\"#[f|]#oo      \\n\\n \\nbar      \"))\n        .build()?;\n\n    test_key_sequence(&mut app, Some(\":w<ret>\"), None, false).await?;\n\n    helpers::assert_file_has_content(&mut file, &LineFeedHandling::Native.apply(\"foo\\n\\n\\nbar\"))?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_trim_final_newlines() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_config(Config {\n            editor: helix_view::editor::Config {\n                trim_final_newlines: true,\n                ..Default::default()\n            },\n            ..Default::default()\n        })\n        .with_file(file.path(), None)\n        .with_input_text(LineFeedHandling::Native.apply(\"#[f|]#oo\\n \\n\\n\\n\"))\n        .build()?;\n\n    test_key_sequence(&mut app, Some(\":w<ret>\"), None, false).await?;\n\n    helpers::assert_file_has_content(&mut file, &LineFeedHandling::Native.apply(\"foo\\n \\n\"))?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_insert_final_newline_added_if_missing() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .with_input_text(\"#[h|]#ave you tried chamomile tea?\")\n        .build()?;\n\n    test_key_sequence(&mut app, Some(\":w<ret>\"), None, false).await?;\n\n    helpers::assert_file_has_content(\n        &mut file,\n        &LineFeedHandling::Native.apply(\"have you tried chamomile tea?\\n\"),\n    )?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_insert_final_newline_unchanged_if_empty() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .with_input_text(\"#[|]#\")\n        .build()?;\n\n    test_key_sequence(&mut app, Some(\":w<ret>\"), None, false).await?;\n\n    helpers::assert_file_has_content(&mut file, \"\")?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_insert_final_newline_unchanged_if_not_missing() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .with_input_text(LineFeedHandling::Native.apply(\"#[t|]#en minutes, please\\n\"))\n        .build()?;\n\n    test_key_sequence(&mut app, Some(\":w<ret>\"), None, false).await?;\n\n    helpers::assert_file_has_content(\n        &mut file,\n        &LineFeedHandling::Native.apply(\"ten minutes, please\\n\"),\n    )?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_insert_final_newline_unchanged_if_missing_and_false() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_config(Config {\n            editor: helix_view::editor::Config {\n                insert_final_newline: false,\n                ..Default::default()\n            },\n            ..Default::default()\n        })\n        .with_file(file.path(), None)\n        .with_input_text(\"#[t|]#he quiet rain continued through the night\")\n        .build()?;\n\n    test_key_sequence(&mut app, Some(\":w<ret>\"), None, false).await?;\n\n    reload_file(&mut file).unwrap();\n    helpers::assert_file_has_content(&mut file, \"the quiet rain continued through the night\")?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_all_insert_final_newline_add_if_missing_and_modified() -> anyhow::Result<()> {\n    let mut file1 = tempfile::NamedTempFile::new()?;\n    let mut file2 = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file1.path(), None)\n        .with_input_text(\"#[w|]#e don't serve time travelers here\")\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(&format!(\n            \":o {}<ret>ia time traveler walks into a bar<esc>:wa<ret>\",\n            file2.path().to_string_lossy()\n        )),\n        None,\n        false,\n    )\n    .await?;\n\n    helpers::assert_file_has_content(\n        &mut file1,\n        &LineFeedHandling::Native.apply(\"we don't serve time travelers here\\n\"),\n    )?;\n\n    helpers::assert_file_has_content(\n        &mut file2,\n        &LineFeedHandling::Native.apply(\"a time traveler walks into a bar\\n\"),\n    )?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_write_all_insert_final_newline_do_not_add_if_unmodified() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n\n    file.write_all(b\"i lost on Jeopardy!\")?;\n    file.rewind()?;\n\n    test_key_sequence(&mut app, Some(\":wa<ret>\"), None, false).await?;\n\n    helpers::assert_file_has_content(&mut file, \"i lost on Jeopardy!\")?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_symlink_write() -> anyhow::Result<()> {\n    #[cfg(unix)]\n    use std::os::unix::fs::symlink;\n    #[cfg(not(unix))]\n    use std::os::windows::fs::symlink_file as symlink;\n\n    let dir = tempfile::tempdir()?;\n\n    let mut file = tempfile::NamedTempFile::new_in(&dir)?;\n    let symlink_path = dir.path().join(\"linked\");\n    symlink(file.path(), &symlink_path)?;\n\n    let mut app = helpers::AppBuilder::new()\n        .with_file(&symlink_path, None)\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(\"ithe gostak distims the doshes<ret><esc>:w<ret>\"),\n        None,\n        false,\n    )\n    .await?;\n\n    reload_file(&mut file).unwrap();\n    let mut file_content = String::new();\n    file.as_file_mut().read_to_string(&mut file_content)?;\n\n    assert_eq!(\n        LineFeedHandling::Native.apply(\"the gostak distims the doshes\"),\n        file_content\n    );\n    assert!(symlink_path.is_symlink());\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_symlink_write_fail() -> anyhow::Result<()> {\n    #[cfg(unix)]\n    use std::os::unix::fs::symlink;\n    #[cfg(not(unix))]\n    use std::os::windows::fs::symlink_file as symlink;\n\n    let dir = tempfile::tempdir()?;\n\n    let file = helpers::new_readonly_tempfile_in_dir(&dir)?;\n    let symlink_path = dir.path().join(\"linked\");\n    symlink(file.path(), &symlink_path)?;\n\n    let mut app = helpers::AppBuilder::new()\n        .with_file(&symlink_path, None)\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(\"ihello<esc>:wq<ret>\"),\n        Some(&|app| {\n            let mut docs: Vec<_> = app.editor.documents().collect();\n            assert_eq!(1, docs.len());\n\n            let doc = docs.pop().unwrap();\n            assert_eq!(Some(&path::normalize(&symlink_path)), doc.path());\n            assert_eq!(&Severity::Error, app.editor.get_status().unwrap().1);\n        }),\n        false,\n    )\n    .await?;\n\n    assert!(symlink_path.is_symlink());\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_symlink_write_relative() -> anyhow::Result<()> {\n    #[cfg(unix)]\n    use std::os::unix::fs::symlink;\n    #[cfg(not(unix))]\n    use std::os::windows::fs::symlink_file as symlink;\n\n    // tempdir\n    // |- - b\n    // |  |- file\n    // |- linked (symlink to file)\n    let dir = tempfile::tempdir()?;\n    let inner_dir = dir.path().join(\"b\");\n    std::fs::create_dir(&inner_dir)?;\n\n    let mut file = tempfile::NamedTempFile::new_in(&inner_dir)?;\n    let symlink_path = dir.path().join(\"linked\");\n    let relative_path = std::path::PathBuf::from(\"b\").join(file.path().file_name().unwrap());\n    symlink(relative_path, &symlink_path)?;\n\n    let mut app = helpers::AppBuilder::new()\n        .with_file(&symlink_path, None)\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(\"ithe gostak distims the doshes<ret><esc>:w<ret>\"),\n        None,\n        false,\n    )\n    .await?;\n\n    reload_file(&mut file).unwrap();\n    let mut file_content = String::new();\n    file.as_file_mut().read_to_string(&mut file_content)?;\n\n    assert_eq!(\n        LineFeedHandling::Native.apply(\"the gostak distims the doshes\"),\n        file_content\n    );\n    assert!(symlink_path.is_symlink());\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\n#[cfg(not(target_os = \"android\"))]\nasync fn test_hardlink_write() -> anyhow::Result<()> {\n    let dir = tempfile::tempdir()?;\n\n    let mut file = tempfile::NamedTempFile::new_in(&dir)?;\n    let hardlink_path = dir.path().join(\"linked\");\n    std::fs::hard_link(file.path(), &hardlink_path)?;\n\n    let mut app = helpers::AppBuilder::new()\n        .with_file(&hardlink_path, None)\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(\"ithe gostak distims the doshes<ret><esc>:w<ret>\"),\n        None,\n        false,\n    )\n    .await?;\n\n    reload_file(&mut file).unwrap();\n    let mut file_content = String::new();\n    file.as_file_mut().read_to_string(&mut file_content)?;\n\n    assert_eq!(\n        LineFeedHandling::Native.apply(\"the gostak distims the doshes\"),\n        file_content\n    );\n    assert!(helix_stdx::faccess::hardlink_count(&hardlink_path)? > 1);\n    assert!(same_file::is_same_file(file.path(), &hardlink_path)?);\n\n    Ok(())\n}\n\nasync fn edit_file_with_content(file_content: &[u8]) -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n\n    file.as_file_mut().write_all(&file_content)?;\n\n    helpers::test_key_sequence(\n        &mut helpers::AppBuilder::new()\n            .with_config(Config {\n                editor: helix_view::editor::Config {\n                    insert_final_newline: false,\n                    ..Default::default()\n                },\n                ..Default::default()\n            })\n            .build()?,\n        Some(&format!(\":o {}<ret>:x<ret>\", file.path().to_string_lossy())),\n        None,\n        true,\n    )\n    .await?;\n\n    reload_file(&mut file).unwrap();\n    let mut new_file_content: Vec<u8> = Vec::new();\n    file.read_to_end(&mut new_file_content)?;\n\n    assert_eq!(file_content, new_file_content);\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_move_file_when_given_dir_and_filename() -> anyhow::Result<()> {\n    let dir = tempfile::tempdir()?;\n    let source_file = tempfile::NamedTempFile::new_in(&dir)?;\n    let target_file = dir.path().join(\"new_name.ext\");\n\n    let mut app = helpers::AppBuilder::new()\n        .with_file(source_file.path(), None)\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(format!(\":move {}<ret>\", target_file.to_string_lossy()).as_ref()),\n        None,\n        false,\n    )\n    .await?;\n\n    assert!(\n        target_file.is_file(),\n        \"target file '{}' should have been created\",\n        target_file.display()\n    );\n    assert!(\n        !source_file.path().exists(),\n        \"Source file '{}' should have been removed\",\n        source_file.path().display()\n    );\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_move_file_when_given_dir_only() -> anyhow::Result<()> {\n    let source_dir = tempfile::tempdir()?;\n    let target_dir = tempfile::tempdir()?;\n    let source_file = source_dir.path().join(\"file.ext\");\n    std::fs::File::create(&source_file)?;\n\n    let mut app = helpers::AppBuilder::new()\n        .with_file(&source_file, None)\n        .build()?;\n\n    test_key_sequence(\n        &mut app,\n        Some(format!(\":move {}<ret>\", target_dir.path().to_string_lossy()).as_ref()),\n        None,\n        false,\n    )\n    .await?;\n\n    let target_file = target_dir.path().join(\"file.ext\");\n\n    assert!(\n        target_file.is_file(),\n        \"target file '{}' should have been created\",\n        target_file.display()\n    );\n    assert!(\n        !source_file.exists(),\n        \"Source file '{}' should have been removed\",\n        source_file.display()\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/commands.rs",
    "content": "use helix_term::application::Application;\n\nuse super::*;\n\nmod insert;\nmod movement;\nmod reverse_selection_contents;\nmod rotate_selection_contents;\nmod write;\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn search_selection_detect_word_boundaries_at_eof() -> anyhow::Result<()> {\n    // <https://github.com/helix-editor/helix/issues/12609>\n    test((\n        indoc! {\"\\\n            #[o|]#ne\n            two\n            three\"},\n        \"gej*h\",\n        indoc! {\"\\\n            one\n            two\n            three#[\n            |]#\"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_selection_duplication() -> anyhow::Result<()> {\n    // Forward\n    test((\n        indoc! {\"\\\n            #[lo|]#rem\n            ipsum\n            dolor\n            \"},\n        \"CC\",\n        indoc! {\"\\\n            #(lo|)#rem\n            #(ip|)#sum\n            #[do|]#lor\n            \"},\n    ))\n    .await?;\n\n    // Backward\n    test((\n        indoc! {\"\\\n            #[|lo]#rem\n            ipsum\n            dolor\n            \"},\n        \"CC\",\n        indoc! {\"\\\n            #(|lo)#rem\n            #(|ip)#sum\n            #[|do]#lor\n            \"},\n    ))\n    .await?;\n\n    // Copy the selection to previous line, skipping the first line in the file\n    test((\n        indoc! {\"\\\n            test\n            #[testitem|]#\n            \"},\n        \"<A-C>\",\n        indoc! {\"\\\n            test\n            #[testitem|]#\n            \"},\n    ))\n    .await?;\n\n    // Copy the selection to previous line, including the first line in the file\n    test((\n        indoc! {\"\\\n            test\n            #[test|]#\n            \"},\n        \"<A-C>\",\n        indoc! {\"\\\n            #[test|]#\n            #(test|)#\n            \"},\n    ))\n    .await?;\n\n    // Copy the selection to next line, skipping the last line in the file\n    test((\n        indoc! {\"\\\n            #[testitem|]#\n            test\n            \"},\n        \"C\",\n        indoc! {\"\\\n            #[testitem|]#\n            test\n            \"},\n    ))\n    .await?;\n\n    // Copy the selection to next line, including the last line in the file\n    test((\n        indoc! {\"\\\n            #[test|]#\n            test\n            \"},\n        \"C\",\n        indoc! {\"\\\n            #(test|)#\n            #[test|]#\n            \"},\n    ))\n    .await?;\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_goto_file_impl() -> anyhow::Result<()> {\n    let file = tempfile::NamedTempFile::new()?;\n\n    fn match_paths(app: &Application, matches: Vec<&str>) -> usize {\n        app.editor\n            .documents()\n            .filter_map(|d| d.path()?.file_name())\n            .filter(|n| matches.iter().any(|m| *m == n.to_string_lossy()))\n            .count()\n    }\n\n    // Single selection\n    test_key_sequence(\n        &mut AppBuilder::new().with_file(file.path(), None).build()?,\n        Some(\"ione.js<esc>%gf\"),\n        Some(&|app| {\n            assert_eq!(1, match_paths(app, vec![\"one.js\"]));\n        }),\n        false,\n    )\n    .await?;\n\n    // Multiple selection\n    test_key_sequence(\n        &mut AppBuilder::new().with_file(file.path(), None).build()?,\n        Some(\"ione.js<ret>two.js<esc>%<A-s>gf\"),\n        Some(&|app| {\n            assert_eq!(2, match_paths(app, vec![\"one.js\", \"two.js\"]));\n        }),\n        false,\n    )\n    .await?;\n\n    // Cursor on first quote\n    test_key_sequence(\n        &mut AppBuilder::new().with_file(file.path(), None).build()?,\n        Some(\"iimport 'one.js'<esc>B;gf\"),\n        Some(&|app| {\n            assert_eq!(1, match_paths(app, vec![\"one.js\"]));\n        }),\n        false,\n    )\n    .await?;\n\n    // Cursor on last quote\n    test_key_sequence(\n        &mut AppBuilder::new().with_file(file.path(), None).build()?,\n        Some(\"iimport 'one.js'<esc>bgf\"),\n        Some(&|app| {\n            assert_eq!(1, match_paths(app, vec![\"one.js\"]));\n        }),\n        false,\n    )\n    .await?;\n\n    // ';' is behind the path\n    test_key_sequence(\n        &mut AppBuilder::new().with_file(file.path(), None).build()?,\n        Some(\"iimport 'one.js';<esc>B;gf\"),\n        Some(&|app| {\n            assert_eq!(1, match_paths(app, vec![\"one.js\"]));\n        }),\n        false,\n    )\n    .await?;\n\n    // allow numeric values in path\n    test_key_sequence(\n        &mut AppBuilder::new().with_file(file.path(), None).build()?,\n        Some(\"iimport 'one123.js'<esc>B;gf\"),\n        Some(&|app| {\n            assert_eq!(1, match_paths(app, vec![\"one123.js\"]));\n        }),\n        false,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_multi_selection_paste() -> anyhow::Result<()> {\n    test((\n        indoc! {\"\\\n            #[|lorem]#\n            #(|ipsum)#\n            #(|dolor)#\n            \"},\n        \"yp\",\n        indoc! {\"\\\n            lorem#[|lorem]#\n            ipsum#(|ipsum)#\n            dolor#(|dolor)#\n            \"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_multi_selection_shell_commands() -> anyhow::Result<()> {\n    // pipe\n    test((\n        indoc! {\"\\\n            #[|lorem]#\n            #(|ipsum)#\n            #(|dolor)#\n            \"},\n        \"|echo foo<ret>\",\n        indoc! {\"\\\n            #[|foo]#\n            #(|foo)#\n            #(|foo)#\"\n        },\n    ))\n    .await?;\n\n    // insert-output\n    test((\n        indoc! {\"\\\n            #[|lorem]#\n            #(|ipsum)#\n            #(|dolor)#\n            \"},\n        \"!echo foo<ret>\",\n        indoc! {\"\\\n            #[|foo]#lorem\n            #(|foo)#ipsum\n            #(|foo)#dolor\n            \"},\n    ))\n    .await?;\n\n    // append-output\n    test((\n        indoc! {\"\\\n            #[|lorem]#\n            #(|ipsum)#\n            #(|dolor)#\n            \"},\n        \"<A-!>echo foo<ret>\",\n        indoc! {\"\\\n            lorem#[|foo]#\n            ipsum#(|foo)#\n            dolor#(|foo)#\n            \"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_undo_redo() -> anyhow::Result<()> {\n    // A jumplist selection is created at a point which is undone.\n    //\n    // * 2[<space>   Add two newlines at line start. We're now on line 3.\n    // * <C-s>       Save the selection on line 3 in the jumplist.\n    // * u           Undo the two newlines. We're now on line 1.\n    // * <C-o><C-i>  Jump forward an back again in the jumplist. This would panic\n    //               if the jumplist were not being updated correctly.\n    test((\n        \"#[|]#\",\n        \"2[<space><C-s>u<C-o><C-i>\",\n        \"#[|]#\",\n        LineFeedHandling::AsIs,\n    ))\n    .await?;\n\n    // A jumplist selection is passed through an edit and then an undo and then a redo.\n    //\n    // * [<space>    Add a newline at line start. We're now on line 2.\n    // * <C-s>       Save the selection on line 2 in the jumplist.\n    // * kd          Delete line 1. The jumplist selection should be adjusted to the new line 1.\n    // * uU          Undo and redo the `kd` edit.\n    // * <C-o>       Jump back in the jumplist. This would panic if the jumplist were not being\n    //               updated correctly.\n    // * <C-i>       Jump forward to line 1.\n    test((\n        \"#[|]#\",\n        \"[<space><C-s>kduU<C-o><C-i>\",\n        \"#[|]#\",\n        LineFeedHandling::AsIs,\n    ))\n    .await?;\n\n    // In this case we 'redo' manually to ensure that the transactions are composing correctly.\n    test((\n        \"#[|]#\",\n        \"[<space>u[<space>u\",\n        \"#[|]#\",\n        LineFeedHandling::AsIs,\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_extend_line() -> anyhow::Result<()> {\n    // extend with line selected then count\n    test((\n        indoc! {\"\\\n            #[l|]#orem\n            ipsum\n            dolor\n            \n            \"},\n        \"x2x\",\n        indoc! {\"\\\n            #[lorem\n            ipsum\n            dolor\\n|]#\n            \n            \"},\n    ))\n    .await?;\n\n    // extend with count on partial selection\n    test((\n        indoc! {\"\\\n            #[l|]#orem\n            ipsum\n            \n            \"},\n        \"2x\",\n        indoc! {\"\\\n            #[lorem\n            ipsum\\n|]#\n            \n            \"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_character_info() -> anyhow::Result<()> {\n    // UTF-8, single byte\n    test_key_sequence(\n        &mut helpers::AppBuilder::new().build()?,\n        Some(\"ih<esc>h:char<ret>\"),\n        Some(&|app| {\n            assert_eq!(\n                r#\"\"h\" (U+0068) Dec 104 Hex 68\"#,\n                app.editor.get_status().unwrap().0\n            );\n        }),\n        false,\n    )\n    .await?;\n\n    // UTF-8, multi-byte\n    test_key_sequence(\n        &mut helpers::AppBuilder::new().build()?,\n        Some(\"ië<esc>h:char<ret>\"),\n        Some(&|app| {\n            assert_eq!(\n                r#\"\"ë\" (U+0065 U+0308) Hex 65 + cc 88\"#,\n                app.editor.get_status().unwrap().0\n            );\n        }),\n        false,\n    )\n    .await?;\n\n    // Multiple characters displayed as one, escaped characters\n    test_key_sequence(\n        &mut helpers::AppBuilder::new().build()?,\n        Some(\":line<minus>ending crlf<ret>:char<ret>\"),\n        Some(&|app| {\n            assert_eq!(\n                r#\"\"\\r\\n\" (U+000d U+000a) Hex 0d + 0a\"#,\n                app.editor.get_status().unwrap().0\n            );\n        }),\n        false,\n    )\n    .await?;\n\n    // Non-UTF-8\n    test_key_sequence(\n        &mut helpers::AppBuilder::new().build()?,\n        Some(\":encoding ascii<ret>ih<esc>h:char<ret>\"),\n        Some(&|app| {\n            assert_eq!(r#\"\"h\" Dec 104 Hex 68\"#, app.editor.get_status().unwrap().0);\n        }),\n        false,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_delete_char_backward() -> anyhow::Result<()> {\n    // don't panic when deleting overlapping ranges\n    test((\"#(x|)# #[x|]#\", \"c<space><backspace><esc>\", \"#[\\n|]#\")).await?;\n    test((\n        \"#( |)##( |)#a#( |)#axx#[x|]#a\",\n        \"li<backspace><esc>\",\n        \"#(a|)##(|a)#xx#[|a]#\",\n    ))\n    .await?;\n\n    Ok(())\n}\n\n// Cursor behavior is different when the text is created in the buffer vs loaded from a file.\n// This test will not work for reproducing the crash or verifying the result after the fix.\n// // #[tokio::test(flavor = \"multi_thread\")]\n// async fn test_try_restore_indent() -> anyhow::Result<()> {\n//     test((\" #[ |]#foo\\na#( |)#bar\\n\", \"o<C-u><esc>\", \" foo\\n#[\\n|]#a bar\\n#(\\n|)#\")).await?;\n//     Ok(())\n// }\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_try_restore_indent() -> anyhow::Result<()> {\n    // Bug: 15228 try_restore_indent uses primary cursor position for all selections,\n    // causing invalid range errors when multiple cursors are on different lines\n    let file = temp_file_with_contents(\"  foo\\na bar\\n\")?;\n    test_key_sequence(\n        &mut AppBuilder::new().with_file(file.path(), None).build()?,\n        Some(\"jl<A-C>o<C-u><esc>\"),\n        None,\n        false,\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_delete_word_backward() -> anyhow::Result<()> {\n    // don't panic when deleting overlapping ranges\n    test((\"fo#[o|]#ba#(r|)#\", \"a<C-w><esc>\", \"#[\\n|]#\")).await?;\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_delete_word_forward() -> anyhow::Result<()> {\n    // don't panic when deleting overlapping ranges\n    test((\"fo#[o|]#b#(|ar)#\", \"i<A-d><esc>\", \"fo#[\\n|]#\")).await?;\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_delete_char_forward() -> anyhow::Result<()> {\n    test((\n        indoc! {\"\\\n                #[abc|]#def\n                #(abc|)#ef\n                #(abc|)#f\n                #(abc|)#\n            \"},\n        \"a<del><esc>\",\n        indoc! {\"\\\n                #[abc|]#ef\n                #(abc|)#f\n                #(abc|)#\n                #(abc|)#\n            \"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_insert_with_indent() -> anyhow::Result<()> {\n    const INPUT: &str = indoc! { \"\n        #[f|]#n foo() {\n            if let Some(_) = None {\n\n            }\n         \n        }\n\n        fn bar() {\n\n        }\n        \"\n    };\n\n    // insert_at_line_start\n    test((\n        INPUT,\n        \":lang rust<ret>%<A-s>I\",\n        indoc! { \"\n            #[f|]#n foo() {\n                #(i|)#f let Some(_) = None {\n                    #(\\n|)#\n                #(}|)#\n            #( |)#\n            #(}|)#\n            #(\\n|)#\n            #(f|)#n bar() {\n                #(\\n|)#\n            #(}|)#\n            \"\n        },\n    ))\n    .await?;\n\n    // insert_at_line_end\n    test((\n        INPUT,\n        \":lang rust<ret>%<A-s>A\",\n        indoc! { \"\n            fn foo() {#[\\n|]#\n                if let Some(_) = None {#(\\n|)#\n                    #(\\n|)#\n                }#(\\n|)#\n             #(\\n|)#\n            }#(\\n|)#\n            #(\\n|)#\n            fn bar() {#(\\n|)#\n                #(\\n|)#\n            }#(\\n|)#\n            \"\n        },\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_join_selections() -> anyhow::Result<()> {\n    // normal join\n    test((\n        indoc! {\"\\\n            #[a|]#bc\n            def\n        \"},\n        \"J\",\n        indoc! {\"\\\n            #[a|]#bc def\n        \"},\n    ))\n    .await?;\n\n    // join with empty line\n    test((\n        indoc! {\"\\\n            #[a|]#bc\n\n            def\n        \"},\n        \"JJ\",\n        indoc! {\"\\\n            #[a|]#bc def\n        \"},\n    ))\n    .await?;\n\n    // join with additional space in non-empty line\n    test((\n        indoc! {\"\\\n            #[a|]#bc\n\n                def\n        \"},\n        \"JJ\",\n        indoc! {\"\\\n            #[a|]#bc def\n        \"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_join_selections_space() -> anyhow::Result<()> {\n    // join with empty lines panic\n    test((\n        indoc! {\"\\\n            #[a\n\n            b\n\n            c\n\n            d\n\n            e|]#\n        \"},\n        \"<A-J>\",\n        indoc! {\"\\\n            a#[ |]#b#( |)#c#( |)#d#( |)#e\n        \"},\n    ))\n    .await?;\n\n    // normal join\n    test((\n        indoc! {\"\\\n            #[a|]#bc\n            def\n        \"},\n        \"<A-J>\",\n        indoc! {\"\\\n            abc#[ |]#def\n        \"},\n    ))\n    .await?;\n\n    // join with empty line\n    test((\n        indoc! {\"\\\n            #[a|]#bc\n\n            def\n        \"},\n        \"<A-J>\",\n        indoc! {\"\\\n            #[a|]#bc\n            def\n        \"},\n    ))\n    .await?;\n\n    // join with additional space in non-empty line\n    test((\n        indoc! {\"\\\n            #[a|]#bc\n\n                def\n        \"},\n        \"<A-J><A-J>\",\n        indoc! {\"\\\n            abc#[ |]#def\n        \"},\n    ))\n    .await?;\n\n    // join with retained trailing spaces\n    test((\n        indoc! {\"\\\n            #[aaa   \n\n            bb  \n\n            c |]#\n        \"},\n        \"<A-J>\",\n        indoc! {\"\\\n            aaa   #[ |]#bb  #( |)#c \n        \"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_join_selections_comment() -> anyhow::Result<()> {\n    test((\n        indoc! {\"\\\n            /// #[a|]#bc\n            /// def\n        \"},\n        \":lang rust<ret>J\",\n        indoc! {\"\\\n            /// #[a|]#bc def\n        \"},\n    ))\n    .await?;\n\n    // Only join if the comment token matches the previous line.\n    test((\n        indoc! {\"\\\n            #[| // a\n            // b\n            /// c\n            /// d\n            e\n            /// f\n            // g]#\n        \"},\n        \":lang rust<ret>J\",\n        indoc! {\"\\\n            #[| // a b /// c d e f // g]#\n        \"},\n    ))\n    .await?;\n\n    test((\n        \"#[|\\t// Join comments\n\\t// with indent]#\",\n        \":lang go<ret>J\",\n        \"#[|\\t// Join comments with indent]#\",\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_read_file() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let contents_to_read = \"some contents\";\n    let output_file = helpers::temp_file_with_contents(contents_to_read)?;\n\n    test_key_sequence(\n        &mut helpers::AppBuilder::new()\n            .with_file(file.path(), None)\n            .build()?,\n        Some(&format!(\":r {:?}<ret><esc>:w<ret>\", output_file.path())),\n        Some(&|app| {\n            assert!(!app.editor.is_err(), \"error: {:?}\", app.editor.get_status());\n        }),\n        false,\n    )\n    .await?;\n\n    let expected_contents = LineFeedHandling::Native.apply(contents_to_read);\n    helpers::assert_file_has_content(&mut file, &expected_contents)?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn surround_delete() -> anyhow::Result<()> {\n    // Test `surround_delete` when head < anchor\n    test((\"(#[|  ]#)\", \"mdm\", \"#[|  ]#\")).await?;\n    test((\"(#[|  ]#)\", \"md(\", \"#[|  ]#\")).await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn surround_replace_ts() -> anyhow::Result<()> {\n    const INPUT: &str = r#\"\\\nfn foo() {\n    if let Some(_) = None {\n        testing!(\"f#[|o]#o)\");\n    }\n}\n\"#;\n    test((\n        INPUT,\n        \":lang rust<ret>mrm'\",\n        r#\"\\\nfn foo() {\n    if let Some(_) = None {\n        testing!('f#[|o]#o)');\n    }\n}\n\"#,\n    ))\n    .await?;\n\n    test((\n        INPUT,\n        \":lang rust<ret>3mrm[\",\n        r#\"\\\nfn foo() {\n    if let Some(_) = None [\n        testing!(\"f#[|o]#o)\");\n    ]\n}\n\"#,\n    ))\n    .await?;\n\n    test((\n        INPUT,\n        \":lang rust<ret>2mrm{\",\n        r#\"\\\nfn foo() {\n    if let Some(_) = None {\n        testing!{\"f#[|o]#o)\"};\n    }\n}\n\"#,\n    ))\n    .await?;\n\n    test((\n        indoc! {\"\\\n            #[a\n            b\n            c\n            d\n            e|]#\n            f\n            \"},\n        \"s\\\\n<ret>r,\",\n        \"a#[,|]#b#(,|)#c#(,|)#d#(,|)#e\\nf\\n\",\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn macro_play_within_macro_record() -> anyhow::Result<()> {\n    // <https://github.com/helix-editor/helix/issues/12697>\n    //\n    // * `\"aQihello<esc>Q` record a macro to register 'a' which inserts \"hello\"\n    // * `Q\"aq<space>world<esc>Q` record a macro to the default macro register which plays the\n    //   macro in register 'a' and then inserts \" world\"\n    // * `%d` clear the buffer\n    // * `q` replay the macro in the default macro register\n    // * `i<ret>` add a newline at the end\n    //\n    // The inner macro in register 'a' should replay within the outer macro exactly once to insert\n    // \"hello world\".\n    test((\n        indoc! {\"\\\n            #[|]#\n        \"},\n        r#\"\"aQihello<esc>QQ\"aqi<space>world<esc>Q%dqi<ret>\"#,\n        indoc! {\"\\\n            hello world\n            #[|]#\"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn global_search_with_multibyte_chars() -> anyhow::Result<()> {\n    // Assert that `helix_term::commands::global_search` handles multibyte characters correctly.\n    test((\n        indoc! {\"\\\n            // Hello world!\n            // #[|\n            ]#\n            \"},\n        // start global search\n        \" /«十分に長い マルチバイトキャラクター列» で検索<ret><esc>\",\n        indoc! {\"\\\n            // Hello world!\n            // #[|\n            ]#\n            \"},\n    ))\n    .await?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/helpers.rs",
    "content": "use std::{\n    io::{Read, Write},\n    mem::replace,\n    path::PathBuf,\n    time::Duration,\n};\n\nuse anyhow::bail;\nuse helix_core::{diagnostic::Severity, test, Selection, Transaction};\nuse helix_term::{application::Application, args::Args, config::Config, keymap::merge_keys};\nuse helix_view::{current_ref, doc, editor::LspConfig, input::parse_macro, Editor};\nuse tempfile::NamedTempFile;\nuse tokio_stream::wrappers::UnboundedReceiverStream;\n\n#[cfg(windows)]\nuse crossterm::event::{Event, KeyEvent};\n#[cfg(not(windows))]\nuse termina::event::{Event, KeyEvent};\n\n/// Specify how to set up the input text with line feeds\n#[derive(Clone, Debug)]\npub enum LineFeedHandling {\n    /// Replaces all LF chars with the system's appropriate line feed character,\n    /// and if one doesn't exist already, appends the system's appropriate line\n    /// ending to the end of a string.\n    Native,\n\n    /// Do not modify the input text in any way. What you give is what you test.\n    AsIs,\n}\n\nimpl LineFeedHandling {\n    /// Apply the line feed handling to the input string, yielding a set of\n    /// resulting texts with the appropriate line feed substitutions.\n    pub fn apply(&self, text: &str) -> String {\n        let line_end = match self {\n            LineFeedHandling::Native => helix_core::NATIVE_LINE_ENDING,\n            LineFeedHandling::AsIs => return text.into(),\n        }\n        .as_str();\n\n        // we can assume that the source files in this code base will always\n        // be LF, so indoc strings will always insert LF\n        let mut output = text.replace('\\n', line_end);\n\n        if !output.ends_with(line_end) {\n            output.push_str(line_end);\n        }\n\n        output\n    }\n}\n\nimpl Default for LineFeedHandling {\n    fn default() -> Self {\n        Self::Native\n    }\n}\n\n#[derive(Clone, Debug)]\npub struct TestCase {\n    pub in_text: String,\n    pub in_selection: Selection,\n    pub in_keys: String,\n    pub out_text: String,\n    pub out_selection: Selection,\n\n    pub line_feed_handling: LineFeedHandling,\n}\n\nimpl<S, R, V> From<(S, R, V)> for TestCase\nwhere\n    S: Into<String>,\n    R: Into<String>,\n    V: Into<String>,\n{\n    fn from((input, keys, output): (S, R, V)) -> Self {\n        TestCase::from((input, keys, output, LineFeedHandling::default()))\n    }\n}\n\nimpl<S, R, V> From<(S, R, V, LineFeedHandling)> for TestCase\nwhere\n    S: Into<String>,\n    R: Into<String>,\n    V: Into<String>,\n{\n    fn from((input, keys, output, line_feed_handling): (S, R, V, LineFeedHandling)) -> Self {\n        let (in_text, in_selection) = test::print(&line_feed_handling.apply(&input.into()));\n        let (out_text, out_selection) = test::print(&line_feed_handling.apply(&output.into()));\n\n        TestCase {\n            in_text,\n            in_selection,\n            in_keys: keys.into(),\n            out_text,\n            out_selection,\n            line_feed_handling,\n        }\n    }\n}\n\n#[inline]\npub async fn test_key_sequence(\n    app: &mut Application,\n    in_keys: Option<&str>,\n    test_fn: Option<&dyn Fn(&Application)>,\n    should_exit: bool,\n) -> anyhow::Result<()> {\n    test_key_sequences(app, vec![(in_keys, test_fn)], should_exit).await\n}\n\n#[allow(clippy::type_complexity)]\npub async fn test_key_sequences(\n    app: &mut Application,\n    inputs: Vec<(Option<&str>, Option<&dyn Fn(&Application)>)>,\n    should_exit: bool,\n) -> anyhow::Result<()> {\n    const TIMEOUT: Duration = Duration::from_millis(500);\n    let (tx, rx) = tokio::sync::mpsc::unbounded_channel();\n    let mut rx_stream = UnboundedReceiverStream::new(rx);\n    let num_inputs = inputs.len();\n\n    for (i, (in_keys, test_fn)) in inputs.into_iter().enumerate() {\n        let (view, doc) = current_ref!(app.editor);\n        let state = test::plain(doc.text().slice(..), doc.selection(view.id));\n\n        log::debug!(\"executing test with document state:\\n\\n-----\\n\\n{}\", state);\n\n        if let Some(in_keys) = in_keys {\n            for key_event in parse_macro(in_keys)?.into_iter() {\n                let key = Event::Key(KeyEvent::from(key_event));\n                log::trace!(\"sending key: {:?}\", key);\n                tx.send(Ok(key))?;\n            }\n        }\n\n        let app_exited = !app.event_loop_until_idle(&mut rx_stream).await;\n\n        if !app_exited {\n            let (view, doc) = current_ref!(app.editor);\n            let state = test::plain(doc.text().slice(..), doc.selection(view.id));\n\n            log::debug!(\n                \"finished running test with document state:\\n\\n-----\\n\\n{}\",\n                state\n            );\n        }\n\n        // the app should not exit from any test until the last one\n        if i < num_inputs - 1 && app_exited {\n            bail!(\"application exited before test function could run\");\n        }\n\n        // verify if it exited on the last iteration if it should have and\n        // the inverse\n        if i == num_inputs - 1 && app_exited != should_exit {\n            bail!(\"expected app to exit: {} != {}\", should_exit, app_exited);\n        }\n\n        if let Some(test) = test_fn {\n            test(app);\n        };\n    }\n\n    if !should_exit {\n        for key_event in parse_macro(\"<esc>:q!<ret>\")?.into_iter() {\n            tx.send(Ok(Event::Key(KeyEvent::from(key_event))))?;\n        }\n\n        let event_loop = app.event_loop(&mut rx_stream);\n        tokio::time::timeout(TIMEOUT, event_loop).await?;\n    }\n\n    let errs = app.close().await;\n\n    if !errs.is_empty() {\n        log::error!(\"Errors closing app\");\n\n        for err in errs {\n            log::error!(\"{}\", err);\n        }\n\n        bail!(\"Error closing app\");\n    }\n\n    Ok(())\n}\n\npub async fn test_key_sequence_with_input_text<T: Into<TestCase>>(\n    app: Option<Application>,\n    test_case: T,\n    test_fn: &dyn Fn(&Application),\n    should_exit: bool,\n) -> anyhow::Result<()> {\n    let test_case = test_case.into();\n\n    let mut app = match app {\n        Some(app) => app,\n        None => Application::new(Args::default(), test_config(), test_syntax_loader(None))?,\n    };\n\n    let (view, doc) = helix_view::current!(app.editor);\n    let sel = doc.selection(view.id).clone();\n\n    // replace the initial text with the input text\n    let transaction = Transaction::change_by_selection(doc.text(), &sel, |_| {\n        (0, doc.text().len_chars(), Some((&test_case.in_text).into()))\n    })\n    .with_selection(test_case.in_selection.clone());\n\n    doc.apply(&transaction, view.id);\n\n    test_key_sequence(\n        &mut app,\n        Some(&test_case.in_keys),\n        Some(test_fn),\n        should_exit,\n    )\n    .await\n}\n\n/// Generates language config loader that merge in overrides, like a user language\n/// config. The argument string must be a raw TOML document.\npub fn test_syntax_loader(overrides: Option<String>) -> helix_core::syntax::Loader {\n    let mut lang = helix_loader::config::default_lang_config();\n\n    if let Some(overrides) = overrides {\n        let override_toml = toml::from_str(&overrides).unwrap();\n        lang = helix_loader::merge_toml_values(lang, override_toml, 3);\n    }\n\n    helix_core::syntax::Loader::new(lang.try_into().unwrap()).unwrap()\n}\n\n/// Use this for very simple test cases where there is one input\n/// document, selection, and sequence of key presses, and you just\n/// want to verify the resulting document and selection.\npub async fn test_with_config<T: Into<TestCase>>(\n    app_builder: AppBuilder,\n    test_case: T,\n) -> anyhow::Result<()> {\n    let test_case = test_case.into();\n    let app = app_builder.build()?;\n\n    test_key_sequence_with_input_text(\n        Some(app),\n        test_case.clone(),\n        &|app| {\n            let doc = doc!(app.editor);\n            assert_eq!(&test_case.out_text, doc.text());\n\n            let mut selections: Vec<_> = doc.selections().values().cloned().collect();\n            assert_eq!(1, selections.len());\n\n            let sel = selections.pop().unwrap();\n            assert_eq!(test_case.out_selection, sel);\n        },\n        false,\n    )\n    .await\n}\n\npub async fn test<T: Into<TestCase>>(test_case: T) -> anyhow::Result<()> {\n    test_with_config(AppBuilder::default(), test_case).await\n}\n\npub fn temp_file_with_contents<S: AsRef<str>>(\n    content: S,\n) -> anyhow::Result<tempfile::NamedTempFile> {\n    let mut temp_file = tempfile::NamedTempFile::new()?;\n\n    temp_file\n        .as_file_mut()\n        .write_all(content.as_ref().as_bytes())?;\n\n    temp_file.flush()?;\n    temp_file.as_file_mut().sync_all()?;\n    Ok(temp_file)\n}\n\n/// Generates a config with defaults more suitable for integration tests\npub fn test_config() -> Config {\n    Config {\n        editor: test_editor_config(),\n        keys: helix_term::keymap::default(),\n        ..Default::default()\n    }\n}\n\npub fn test_editor_config() -> helix_view::editor::Config {\n    helix_view::editor::Config {\n        lsp: LspConfig {\n            enable: false,\n            ..Default::default()\n        },\n        ..Default::default()\n    }\n}\n\n/// Creates a new temporary file that is set to read only. Useful for\n/// testing write failures.\npub fn new_readonly_tempfile() -> anyhow::Result<NamedTempFile> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let metadata = file.as_file().metadata()?;\n    let mut perms = metadata.permissions();\n    perms.set_readonly(true);\n    file.as_file_mut().set_permissions(perms)?;\n    Ok(file)\n}\n\n/// Creates a new temporary file in the directory that is set to read only. Useful for\n/// testing write failures.\npub fn new_readonly_tempfile_in_dir(\n    dir: impl AsRef<std::path::Path>,\n) -> anyhow::Result<NamedTempFile> {\n    let mut file = tempfile::NamedTempFile::new_in(dir)?;\n    let metadata = file.as_file().metadata()?;\n    let mut perms = metadata.permissions();\n    perms.set_readonly(true);\n    file.as_file_mut().set_permissions(perms)?;\n    Ok(file)\n}\npub struct AppBuilder {\n    args: Args,\n    config: Config,\n    syn_loader: helix_core::syntax::Loader,\n    input: Option<(String, Selection)>,\n}\n\nimpl Default for AppBuilder {\n    fn default() -> Self {\n        Self {\n            args: Args::default(),\n            config: test_config(),\n            syn_loader: test_syntax_loader(None),\n            input: None,\n        }\n    }\n}\n\nimpl AppBuilder {\n    pub fn new() -> Self {\n        AppBuilder::default()\n    }\n\n    pub fn with_file<P: Into<PathBuf>>(\n        mut self,\n        path: P,\n        pos: Option<helix_core::Position>,\n    ) -> Self {\n        self.args\n            .files\n            .insert(path.into(), vec![pos.unwrap_or_default()]);\n\n        self\n    }\n\n    // Remove this attribute once `with_config` is used in a test:\n    #[allow(dead_code)]\n    pub fn with_config(mut self, mut config: Config) -> Self {\n        let keys = replace(&mut config.keys, helix_term::keymap::default());\n        merge_keys(&mut config.keys, keys);\n        self.config = config;\n        self\n    }\n\n    pub fn with_input_text<S: Into<String>>(mut self, input_text: S) -> Self {\n        self.input = Some(test::print(&input_text.into()));\n        self\n    }\n\n    pub fn with_lang_loader(mut self, syn_loader: helix_core::syntax::Loader) -> Self {\n        self.syn_loader = syn_loader;\n        self\n    }\n\n    pub fn build(self) -> anyhow::Result<Application> {\n        if let Some(path) = &self.args.working_directory {\n            bail!(\"Changing the working directory to {path:?} is not yet supported for integration tests\");\n        }\n\n        if let Some((path, _)) = self.args.files.first().filter(|p| p.0.is_dir()) {\n            bail!(\"Having the directory {path:?} in args.files[0] is not yet supported for integration tests\");\n        }\n\n        let mut app = Application::new(self.args, self.config, self.syn_loader)?;\n\n        if let Some((text, selection)) = self.input {\n            let (view, doc) = helix_view::current!(app.editor);\n            let sel = doc.selection(view.id).clone();\n            let trans = Transaction::change_by_selection(doc.text(), &sel, |_| {\n                (0, doc.text().len_chars(), Some((text.clone()).into()))\n            })\n            .with_selection(selection);\n\n            // replace the initial text with the input text\n            doc.apply(&trans, view.id);\n        }\n\n        Ok(app)\n    }\n}\n\npub async fn run_event_loop_until_idle(app: &mut Application) {\n    let (_, rx) = tokio::sync::mpsc::unbounded_channel();\n    let mut rx_stream = UnboundedReceiverStream::new(rx);\n    app.event_loop_until_idle(&mut rx_stream).await;\n}\n\npub fn assert_file_has_content(file: &mut NamedTempFile, content: &str) -> anyhow::Result<()> {\n    reload_file(file)?;\n\n    let mut file_content = String::new();\n    file.read_to_string(&mut file_content)?;\n    assert_eq!(file_content, content);\n\n    Ok(())\n}\n\npub fn assert_status_not_error(editor: &Editor) {\n    if let Some((_, sev)) = editor.get_status() {\n        assert_ne!(&Severity::Error, sev);\n    }\n}\n\npub fn reload_file(file: &mut NamedTempFile) -> anyhow::Result<()> {\n    let path = file.path();\n    let f = std::fs::OpenOptions::new()\n        .write(true)\n        .read(true)\n        .open(&path)?;\n    *file.as_file_mut() = f;\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/languages/go.rs",
    "content": "use super::*;\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn auto_indent() -> anyhow::Result<()> {\n    let app = || AppBuilder::new().with_file(\"foo.go\", None);\n\n    let enter_tests = [\n        (\n            indoc! {r##\"\n                type Test struct {#[}|]#\n            \"##},\n            \"i<ret>\",\n            indoc! {\"\\\n                type Test struct {\n                \\t#[|\\n]#\n                }\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                func main() {\n                \\tswitch nil {#[}|]#\n                }\n             \"},\n            \"i<ret>\",\n            indoc! {\"\\\n                func main() {\n                \\tswitch nil {\n                \\t\\t#[|\\n]#\n                \\t}\n                }\n            \"},\n        ),\n    ];\n\n    for test in enter_tests {\n        test_with_config(app(), test).await?;\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/languages/mod.rs",
    "content": "use super::*;\n\nmod go;\nmod yaml;\n"
  },
  {
    "path": "helix-term/tests/test/languages/yaml.rs",
    "content": "use super::*;\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn auto_indent() -> anyhow::Result<()> {\n    let app = || AppBuilder::new().with_file(\"foo.yaml\", None);\n\n    let below_tests = [\n        (\n            indoc! {r##\"\n                #[t|]#op:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"##},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  #[\\n|]#\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {r##\"\n                top:\n                  b#[a|]#z: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"##},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  #[\\n|]#\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {r##\"\n                top:\n                  baz: foo\n                  bazi#[:|]#\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"##},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    #[\\n|]#\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {r##\"\n                top:\n                  baz: foo\n                  bazi:\n                    more: #[yes|]#\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"##},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    #[\\n|]#\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {r##\"\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: becaus#[e|]#\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"##},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                    #[\\n|]#\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:#[\\n|]#\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    #[\\n|]#\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1#[\\n|]#\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    #[\\n|]#\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:#[\\n|]#\n            \"},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n                  #[\\n|]#\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: |\n                    some\n                    multi\n                    line\n                    string#[\\n|]#\n                fook:\n            \"},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: |\n                    some\n                    multi\n                    line\n                    string\n                    #[\\n|]#\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: >\n                    some\n                    multi\n                    line#[\\n|]#\n                    string\n                fook:\n            \"},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: >\n                    some\n                    multi\n                    line\n                    #[\\n|]#\n                    string\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: >#[\\n|]#\n                fook:\n            \"},\n            \"o\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: >\n                    #[\\n|]#\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              - top:#[\\n|]#\n                  baz: foo\n                  bax: foox\n                fook:\n            \"},\n            \"o\",\n            indoc! {\"\\\n              - top:\n                  #[\\n|]#\n                  baz: foo\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              - top:\n                  baz: foo#[\\n|]#\n                  bax: foox\n                fook:\n            \"},\n            \"o\",\n            indoc! {\"\\\n              - top:\n                  baz: foo\n                  #[\\n|]#\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              - top:\n                  baz: foo\n                  bax: foox#[\\n|]#\n                fook:\n            \"},\n            \"o\",\n            indoc! {\"\\\n              - top:\n                  baz: foo\n                  bax: foox\n                  #[\\n|]#\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              top:\n                baz:\n                  - one: two#[\\n|]#\n                    three: four\n                  - top:\n                      baz: foo\n                      bax: foox\n            \"},\n            \"o\",\n            indoc! {\"\\\n              top:\n                baz:\n                  - one: two\n                    #[\\n|]#\n                    three: four\n                  - top:\n                      baz: foo\n                      bax: foox\n            \"},\n        ),\n        // yaml map without a key\n        (\n            indoc! {\"\\\n              top:#[\\n|]#\n            \"},\n            \"o\",\n            indoc! {\"\\\n              top:\n                #[\\n|]#\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              top#[:|]#\n              bottom: withvalue\n            \"},\n            \"o\",\n            indoc! {\"\\\n              top:\n                #[\\n|]#\n              bottom: withvalue\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              bottom: withvalue\n              top#[:|]#\n            \"},\n            \"o\",\n            indoc! {\"\\\n              bottom: withvalue\n              top:\n                #[\\n|]#\n            \"},\n        ),\n    ];\n\n    for test in below_tests {\n        test_with_config(app(), test).await?;\n    }\n\n    let above_tests = [\n        (\n            indoc! {r##\"\n                #[t|]#op:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"##},\n            \"O\",\n            indoc! {\"\\\n                #[\\n|]#\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {r##\"\n                top:\n                  b#[a|]#z: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"##},\n            \"O\",\n            indoc! {\"\\\n                top:\n                  #[\\n|]#\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {r##\"\n                top:\n                  baz: foo\n                  bazi#[:|]#\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"##},\n            \"O\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  #[\\n|]#\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {r##\"\n                top:\n                  baz: foo\n                  bazi:\n                    more: #[yes|]#\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"##},\n            \"O\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    #[\\n|]#\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {r##\"\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: becaus#[e|]#\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"##},\n            \"O\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    #[\\n|]#\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:#[\\n|]#\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n            \"O\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                    #[\\n|]#\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1#[\\n|]#\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n            \"O\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    #[\\n|]#\n                    - 1\n                    - 2\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                fook:#[\\n|]#\n            \"},\n            \"O\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bazi:\n                    more: yes\n                    why: because\n                  quux:\n                    - 1\n                    - 2\n                  bax: foox\n                  #[\\n|]#\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: |\n                    some\n                    multi\n                    line\n                    string#[\\n|]#\n                fook:\n            \"},\n            \"O\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: |\n                    some\n                    multi\n                    line\n                    #[\\n|]#\n                    string\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: >\n                    some#[\\n|]#\n                    multi\n                    line\n                    string\n                fook:\n            \"},\n            \"O\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: >\n                    #[\\n|]#\n                    some\n                    multi\n                    line\n                    string\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: >\n                fook:#[\\n|]#\n            \"},\n            \"O\",\n            indoc! {\"\\\n                top:\n                  baz: foo\n                  bax: >\n                    #[\\n|]#\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              - top:\n                  baz: foo#[\\n|]#\n                  bax: foox\n                fook:\n            \"},\n            \"O\",\n            indoc! {\"\\\n              - top:\n                  #[\\n|]#\n                  baz: foo\n                  bax: foox\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              - top:\n                  baz: foo\n                  bax: foox\n                fook:#[\\n|]#\n            \"},\n            \"O\",\n            indoc! {\"\\\n              - top:\n                  baz: foo\n                  bax: foox\n                  #[\\n|]#\n                fook:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              top:\n                baz:\n                  - one: two#[\\n|]#\n                    three: four\n                  - top:\n                      baz: foo\n                      bax: foox\n            \"},\n            \"O\",\n            indoc! {\"\\\n              top:\n                baz:\n                  #[\\n|]#\n                  - one: two\n                    three: four\n                  - top:\n                      baz: foo\n                      bax: foox\n            \"},\n        ),\n        // yaml map without a key\n        (\n            indoc! {\"\\\n              top:#[\\n|]#\n            \"},\n            \"O\",\n            indoc! {\"\\\n              #[\\n|]#\n              top:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              bottom: withvalue\n              top#[:|]#\n            \"},\n            \"O\",\n            indoc! {\"\\\n              bottom: withvalue\n              #[\\n|]#\n              top:\n            \"},\n        ),\n        (\n            indoc! {\"\\\n              top:\n              bottom:#[ |]#withvalue\n            \"},\n            \"O\",\n            indoc! {\"\\\n              top:\n                #[\\n|]#\n              bottom: withvalue\n            \"},\n        ),\n    ];\n\n    for test in above_tests {\n        test_with_config(app(), test).await?;\n    }\n\n    let enter_tests = [\n        (\n            indoc! {r##\"\n                foo: #[b|]#ar\n            \"##},\n            \"i<ret>\",\n            indoc! {\"\\\n                foo:\n                  #[|b]#ar\n            \"},\n        ),\n        (\n            indoc! {\"\\\n                foo:#[\\n|]#\n            \"},\n            \"i<ret>\",\n            indoc! {\"\\\n                foo:\n                  #[|\\n]#\n            \"},\n        ),\n    ];\n\n    for test in enter_tests {\n        test_with_config(app(), test).await?;\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/movement.rs",
    "content": "use super::*;\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_mode_cursor_position() -> anyhow::Result<()> {\n    test(TestCase {\n        in_text: String::new(),\n        in_selection: Selection::single(0, 0),\n        in_keys: \"i\".into(),\n        out_text: String::new(),\n        out_selection: Selection::single(0, 0),\n        line_feed_handling: LineFeedHandling::AsIs,\n    })\n    .await?;\n\n    test((\"#[\\n|]#\", \"i\", \"#[|\\n]#\")).await?;\n    test((\"#[\\n|]#\", \"i<esc>\", \"#[|\\n]#\")).await?;\n    test((\"#[\\n|]#\", \"i<esc>i\", \"#[|\\n]#\")).await?;\n\n    Ok(())\n}\n\n/// Range direction is preserved when escaping insert mode to normal\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn insert_to_normal_mode_cursor_position() -> anyhow::Result<()> {\n    test((\"#[f|]#oo\\n\", \"vll<A-;><esc>\", \"#[|foo]#\\n\")).await?;\n    test((\n        indoc! {\"\\\n                #[f|]#oo\n                #(b|)#ar\"\n        },\n        \"vll<A-;><esc>\",\n        indoc! {\"\\\n                #[|foo]#\n                #(|bar)#\"\n        },\n    ))\n    .await?;\n\n    test((\n        indoc! {\"\\\n                #[f|]#oo\n                #(b|)#ar\"\n        },\n        \"a\",\n        indoc! {\"\\\n                #[fo|]#o\n                #(ba|)#r\"\n        },\n    ))\n    .await?;\n\n    test((\n        indoc! {\"\\\n                #[f|]#oo\n                #(b|)#ar\"\n        },\n        \"a<esc>\",\n        indoc! {\"\\\n                #[f|]#oo\n                #(b|)#ar\"\n        },\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn surround_by_character() -> anyhow::Result<()> {\n    // Only pairs matching the passed character count\n    test((\n        \"(so [many {go#[o|]#d} text] here)\",\n        \"mi{\",\n        \"(so [many {#[good|]#} text] here)\",\n    ))\n    .await?;\n    test((\n        \"(so [many {go#[o|]#d} text] here)\",\n        \"mi[\",\n        \"(so [#[many {good} text|]#] here)\",\n    ))\n    .await?;\n    test((\n        \"(so [many {go#[o|]#d} text] here)\",\n        \"mi(\",\n        \"(#[so [many {good} text] here|]#)\",\n    ))\n    .await?;\n\n    // Works with characters that aren't pairs too\n    test((\n        \"'so 'many 'go#[o|]#d' text' here'\",\n        \"mi'\",\n        \"'so 'many '#[good|]#' text' here'\",\n    ))\n    .await?;\n    test((\n        \"'so 'many 'go#[o|]#d' text' here'\",\n        \"2mi'\",\n        \"'so '#[many 'good' text|]#' here'\",\n    ))\n    .await?;\n    test((\n        \"'so \\\"many 'go#[o|]#d' text\\\" here'\",\n        \"mi\\\"\",\n        \"'so \\\"#[many 'good' text|]#\\\" here'\",\n    ))\n    .await?;\n\n    // Selection direction is preserved\n    test((\n        \"(so [many {go#[|od]#} text] here)\",\n        \"mi{\",\n        \"(so [many {#[|good]#} text] here)\",\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn surround_inside_pair() -> anyhow::Result<()> {\n    // Works at first character of buffer\n    // TODO: Adjust test when opening pair failure is fixed\n    test((\"#[(|]#something)\", \"mim\", \"#[(|]#something)\")).await?;\n\n    // Inside a valid pair selects pair\n    test((\"some (#[t|]#ext) here\", \"mim\", \"some (#[text|]#) here\")).await?;\n\n    // On pair character selects pair\n    // TODO: Opening pair character is a known failure case that needs addressing\n    // test((\"some #[(|]#text) here\", \"mim\", \"some (#[text|]#) here\")).await?;\n    test((\"some (text#[)|]# here\", \"mim\", \"some (#[text|]#) here\")).await?;\n\n    // No valid pair does nothing\n    test((\"so#[m|]#e (text) here\", \"mim\", \"so#[m|]#e (text) here\")).await?;\n\n    // Count skips to outer pairs\n    test((\n        \"(so (many (go#[o|]#d) text) here)\",\n        \"1mim\",\n        \"(so (many (#[good|]#) text) here)\",\n    ))\n    .await?;\n    test((\n        \"(so (many (go#[o|]#d) text) here)\",\n        \"2mim\",\n        \"(so (#[many (good) text|]#) here)\",\n    ))\n    .await?;\n    test((\n        \"(so (many (go#[o|]#d) text) here)\",\n        \"3mim\",\n        \"(#[so (many (good) text) here|]#)\",\n    ))\n    .await?;\n\n    // Matching pairs outside selection don't match\n    test((\n        \"((so)((many) go#[o|]#d (text))(here))\",\n        \"mim\",\n        \"((so)(#[(many) good (text)|]#)(here))\",\n    ))\n    .await?;\n    test((\n        \"((so)((many) go#[o|]#d (text))(here))\",\n        \"2mim\",\n        \"(#[(so)((many) good (text))(here)|]#)\",\n    ))\n    .await?;\n\n    // Works with mixed braces\n    test((\n        \"(so [many {go#[o|]#d} text] here)\",\n        \"mim\",\n        \"(so [many {#[good|]#} text] here)\",\n    ))\n    .await?;\n    test((\n        \"(so [many {go#[o|]#d} text] here)\",\n        \"2mim\",\n        \"(so [#[many {good} text|]#] here)\",\n    ))\n    .await?;\n    test((\n        \"(so [many {go#[o|]#d} text] here)\",\n        \"3mim\",\n        \"(#[so [many {good} text] here|]#)\",\n    ))\n    .await?;\n\n    // Selection direction is preserved\n    test((\n        \"(so [many {go#[|od]#} text] here)\",\n        \"mim\",\n        \"(so [many {#[|good]#} text] here)\",\n    ))\n    .await?;\n    test((\n        \"(so [many {go#[|od]#} text] here)\",\n        \"2mim\",\n        \"(so [#[|many {good} text]#] here)\",\n    ))\n    .await?;\n    test((\n        \"(so [many {go#[|od]#} text] here)\",\n        \"3mim\",\n        \"(#[|so [many {good} text] here]#)\",\n    ))\n    .await?;\n\n    // Only pairs outside of full selection range are considered\n    test((\n        \"(so (many (go#[od) |]#text) here)\",\n        \"mim\",\n        \"(so (#[many (good) text|]#) here)\",\n    ))\n    .await?;\n    test((\n        \"(so (many#[ (go|]#od) text) here)\",\n        \"mim\",\n        \"(so (#[many (good) text|]#) here)\",\n    ))\n    .await?;\n    test((\n        \"(so#[ (many (go|]#od) text) here)\",\n        \"mim\",\n        \"(#[so (many (good) text) here|]#)\",\n    ))\n    .await?;\n    test((\n        \"(so (many (go#[od) text) |]#here)\",\n        \"mim\",\n        \"(#[so (many (good) text) here|]#)\",\n    ))\n    .await?;\n\n    // Works with multiple cursors\n    test((\n        \"(so (many (good) text) #[he|]#re\\nso (many (good) text) #(|he)#re)\",\n        \"mim\",\n        \"(#[so (many (good) text) here\\nso (many (good) text) here|]#)\",\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn surround_around_pair() -> anyhow::Result<()> {\n    // Works at first character of buffer\n    // TODO: Adjust test when opening pair failure is fixed\n    test((\"#[(|]#something)\", \"mam\", \"#[(|]#something)\")).await?;\n\n    // Inside a valid pair selects pair\n    test((\"some (#[t|]#ext) here\", \"mam\", \"some #[(text)|]# here\")).await?;\n\n    // On pair character selects pair\n    // TODO: Opening pair character is a known failure case that needs addressing\n    // test((\"some #[(|]#text) here\", \"mam\", \"some #[(text)|]# here\")).await?;\n    test((\"some (text#[)|]# here\", \"mam\", \"some #[(text)|]# here\")).await?;\n\n    // No valid pair does nothing\n    test((\"so#[m|]#e (text) here\", \"mam\", \"so#[m|]#e (text) here\")).await?;\n\n    // Count skips to outer pairs\n    test((\n        \"(so (many (go#[o|]#d) text) here)\",\n        \"1mam\",\n        \"(so (many #[(good)|]# text) here)\",\n    ))\n    .await?;\n    test((\n        \"(so (many (go#[o|]#d) text) here)\",\n        \"2mam\",\n        \"(so #[(many (good) text)|]# here)\",\n    ))\n    .await?;\n    test((\n        \"(so (many (go#[o|]#d) text) here)\",\n        \"3mam\",\n        \"#[(so (many (good) text) here)|]#\",\n    ))\n    .await?;\n\n    // Matching pairs outside selection don't match\n    test((\n        \"((so)((many) go#[o|]#d (text))(here))\",\n        \"mam\",\n        \"((so)#[((many) good (text))|]#(here))\",\n    ))\n    .await?;\n    test((\n        \"((so)((many) go#[o|]#d (text))(here))\",\n        \"2mam\",\n        \"#[((so)((many) good (text))(here))|]#\",\n    ))\n    .await?;\n\n    // Works with mixed braces\n    test((\n        \"(so [many {go#[o|]#d} text] here)\",\n        \"mam\",\n        \"(so [many #[{good}|]# text] here)\",\n    ))\n    .await?;\n    test((\n        \"(so [many {go#[o|]#d} text] here)\",\n        \"2mam\",\n        \"(so #[[many {good} text]|]# here)\",\n    ))\n    .await?;\n    test((\n        \"(so [many {go#[o|]#d} text] here)\",\n        \"3mam\",\n        \"#[(so [many {good} text] here)|]#\",\n    ))\n    .await?;\n\n    // Selection direction is preserved\n    test((\n        \"(so [many {go#[|od]#} text] here)\",\n        \"mam\",\n        \"(so [many #[|{good}]# text] here)\",\n    ))\n    .await?;\n    test((\n        \"(so [many {go#[|od]#} text] here)\",\n        \"2mam\",\n        \"(so #[|[many {good} text]]# here)\",\n    ))\n    .await?;\n    test((\n        \"(so [many {go#[|od]#} text] here)\",\n        \"3mam\",\n        \"#[|(so [many {good} text] here)]#\",\n    ))\n    .await?;\n\n    // Only pairs outside of full selection range are considered\n    test((\n        \"(so (many (go#[od) |]#text) here)\",\n        \"mam\",\n        \"(so #[(many (good) text)|]# here)\",\n    ))\n    .await?;\n    test((\n        \"(so (many#[ (go|]#od) text) here)\",\n        \"mam\",\n        \"(so #[(many (good) text)|]# here)\",\n    ))\n    .await?;\n    test((\n        \"(so#[ (many (go|]#od) text) here)\",\n        \"mam\",\n        \"#[(so (many (good) text) here)|]#\",\n    ))\n    .await?;\n    test((\n        \"(so (many (go#[od) text) |]#here)\",\n        \"mam\",\n        \"#[(so (many (good) text) here)|]#\",\n    ))\n    .await?;\n\n    // Works with multiple cursors\n    test((\n        \"(so (many (good) text) #[he|]#re\\nso (many (good) text) #(|he)#re)\",\n        \"mam\",\n        \"#[(so (many (good) text) here\\nso (many (good) text) here)|]#\",\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn match_around_closest_ts() -> anyhow::Result<()> {\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.rs\", None),\n        (\n            r#\"fn main() {testing!{\"f#[|oo]#)\"};}\"#,\n            \"mam\",\n            r#\"fn main() {testing!{#[|\"foo)\"]#};}\"#,\n        ),\n    )\n    .await?;\n\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.rs\", None),\n        (\n            r##\"fn main() { let _ = (\"#[|1]#23\", \"#(|1)#23\"); } \"##,\n            \"3mam\",\n            r##\"fn main() #[|{ let _ = (\"123\", \"123\"); }]# \"##,\n        ),\n    )\n    .await?;\n\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.rs\", None),\n        (\n            r##\" fn main() { let _ = (\"12#[|3\", \"12]#3\"); } \"##,\n            \"1mam\",\n            r##\" fn main() { let _ = #[|(\"123\", \"123\")]#; } \"##,\n        ),\n    )\n    .await?;\n\n    Ok(())\n}\n\n/// Ensure the very initial cursor in an opened file is the width of\n/// the first grapheme\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn cursor_position_newly_opened_file() -> anyhow::Result<()> {\n    let test = |content: &str, expected_sel: Selection| -> anyhow::Result<()> {\n        let file = helpers::temp_file_with_contents(content)?;\n        let mut app = helpers::AppBuilder::new()\n            .with_file(file.path(), None)\n            .build()?;\n\n        let (view, doc) = helix_view::current!(app.editor);\n        let sel = doc.selection(view.id).clone();\n        assert_eq!(expected_sel, sel);\n\n        Ok(())\n    };\n\n    test(\"foo\", Selection::single(0, 1))?;\n    test(\"👨‍👩‍👧‍👦 foo\", Selection::single(0, 7))?;\n    test(\"\", Selection::single(0, 0))?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn cursor_position_append_eof() -> anyhow::Result<()> {\n    // Selection is forwards\n    test((\"#[foo|]#\", \"abar<esc>\", \"#[foobar|]#\\n\")).await?;\n\n    // Selection is backwards\n    test((\"#[|foo]#\", \"abar<esc>\", \"#[foobar|]#\\n\")).await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow::Result<()> {\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.rs\", None),\n        (\n            indoc! {\"\\\n                #[/|]#// Increments\n                fn inc(x: usize) -> usize { x + 1 }\n                /// Decrements\n                fn dec(x: usize) -> usize { x - 1 }\n            \"},\n            \"]fv]f\",\n            indoc! {\"\\\n                /// Increments\n                #[fn inc(x: usize) -> usize { x + 1 }\n                /// Decrements\n                fn dec(x: usize) -> usize { x - 1 }|]#\n            \"},\n        ),\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn select_mode_tree_sitter_prev_function_unselects_object() -> anyhow::Result<()> {\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.rs\", None),\n        (\n            indoc! {\"\\\n                /// Increments\n                #[fn inc(x: usize) -> usize { x + 1 }\n                /// Decrements\n                fn dec(x: usize) -> usize { x - 1 }|]#\n            \"},\n            \"v[f\",\n            indoc! {\"\\\n                /// Increments\n                #[fn inc(x: usize) -> usize { x + 1 }|]#\n                /// Decrements\n                fn dec(x: usize) -> usize { x - 1 }\n            \"},\n        ),\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn select_mode_tree_sitter_prev_function_goes_backwards_to_object() -> anyhow::Result<()> {\n    // Note: the anchor stays put and the head moves back.\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.rs\", None),\n        (\n            indoc! {\"\\\n                /// Increments\n                fn inc(x: usize) -> usize { x + 1 }\n                /// Decrements\n                fn dec(x: usize) -> usize { x - 1 }\n                /// Identity\n                #[fn ident(x: usize) -> usize { x }|]#\n            \"},\n            \"v[f\",\n            indoc! {\"\\\n                /// Increments\n                fn inc(x: usize) -> usize { x + 1 }\n                /// Decrements\n                #[|fn dec(x: usize) -> usize { x - 1 }\n                /// Identity\n                ]#fn ident(x: usize) -> usize { x }\n            \"},\n        ),\n    )\n    .await?;\n\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.rs\", None),\n        (\n            indoc! {\"\\\n                /// Increments\n                fn inc(x: usize) -> usize { x + 1 }\n                /// Decrements\n                fn dec(x: usize) -> usize { x - 1 }\n                /// Identity\n                #[fn ident(x: usize) -> usize { x }|]#\n            \"},\n            \"v[f[f\",\n            indoc! {\"\\\n                /// Increments\n                #[|fn inc(x: usize) -> usize { x + 1 }\n                /// Decrements\n                fn dec(x: usize) -> usize { x - 1 }\n                /// Identity\n                ]#fn ident(x: usize) -> usize { x }\n            \"},\n        ),\n    )\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn find_char() -> anyhow::Result<()> {\n    test((\"he#[l|]#lo\\nhello\", \"fl\", \"he#[ll|]#o\\nhello\")).await?;\n    test((\"hel#[l|]#o\\nhello\", \"fl\", \"hel#[lo\\nhel|]#lo\")).await?;\n    test((\"hel#[l|]#o\\nhello\", \"fx\", \"hel#[l|]#o\\nhello\")).await?;\n    test((\"he#[l|]#lo\\nhello\", \"2fl\", \"he#[llo\\nhel|]#lo\")).await?;\n    test((\"#[h|]#ello\\nhello\", \"9fl\", \"#[h|]#ello\\nhello\")).await?;\n\n    test((\"h#[e|]#llo\\nhello\", \"tl\", \"h#[el|]#lo\\nhello\")).await?;\n    test((\"he#[l|]#lo\\nhello\", \"tl\", \"he#[llo\\nhe|]#llo\")).await?;\n    test((\"hel#[l|]#o\\nhello\", \"tl\", \"hel#[lo\\nhe|]#llo\")).await?;\n    test((\"hel#[l|]#o\\nhello\", \"tx\", \"hel#[l|]#o\\nhello\")).await?;\n    test((\"he#[l|]#lo\\nhello\", \"2tl\", \"he#[llo\\nhel|]#lo\")).await?;\n    test((\"#[h|]#ello\\nhello\", \"9tl\", \"#[h|]#ello\\nhello\")).await?;\n\n    test((\"hello\\nhel#[l|]#o\", \"Fl\", \"hello\\nhe#[|ll]#o\")).await?;\n    test((\"hello\\nhe#[l|]#lo\", \"Fl\", \"hel#[|lo\\nhel]#lo\")).await?;\n    test((\"hello\\n#[h|]#ello\", \"Fx\", \"hello\\n#[h|]#ello\")).await?;\n    test((\"hello\\nhel#[l|]#o\", \"2Fl\", \"hel#[|lo\\nhell]#o\")).await?;\n    test((\"hello\\nhell#[o|]#\", \"9Fl\", \"hello\\nhell#[o|]#\")).await?;\n\n    test((\"hello\\nhell#[o|]#\", \"Tl\", \"hello\\nhel#[|lo]#\")).await?;\n    test((\"hello\\nhel#[l|]#o\", \"Tl\", \"hell#[|o\\nhell]#o\")).await?;\n    test((\"hello\\nhe#[l|]#lo\", \"Tl\", \"hell#[|o\\nhel]#lo\")).await?;\n    test((\"hello\\n#[h|]#ello\", \"Tx\", \"hello\\n#[h|]#ello\")).await?;\n    test((\"hello\\nhel#[l|]#o\", \"2Tl\", \"hel#[|lo\\nhell]#o\")).await?;\n    test((\"hello\\nhell#[o|]#\", \"9Tl\", \"hello\\nhell#[o|]#\")).await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn find_char_line_ending() -> anyhow::Result<()> {\n    test((\"on#[e|]#\\ntwo\\n\", \"f<ret>\", \"on#[e\\n|]#two\\n\")).await?;\n    test((\"one#[\\n|]#two\\n\", \"f<ret>\", \"one#[\\ntwo\\n|]#\")).await?;\n    test((\"one\\n#[t|]#wo\\n\", \"f<ret>\", \"one\\n#[two\\n|]#\")).await?;\n    test((\"one#[\\n|]#\", \"f<ret>\", \"one#[\\n|]#\")).await?;\n    test((\"#[o|]#ne\\ntwo\\n\", \"2f<ret>\", \"#[one\\ntwo\\n|]#\")).await?;\n    test((\"#[o|]#ne\\ntwo\\n\", \"9f<ret>\", \"#[o|]#ne\\ntwo\\n\")).await?;\n\n    test((\"o#[n|]#e\\ntwo\\n\", \"t<ret>\", \"o#[ne|]#\\ntwo\\n\")).await?;\n    test((\"on#[e|]#\\ntwo\\n\", \"t<ret>\", \"on#[e\\ntwo|]#\\n\")).await?;\n    test((\"one#[\\n|]#two\\n\", \"t<ret>\", \"one#[\\ntwo|]#\\n\")).await?;\n    test((\"one#[\\n|]#\", \"t<ret>\", \"one#[\\n|]#\")).await?;\n    test((\"on#[e|]#\\n\", \"t<ret>\", \"on#[e|]#\\n\")).await?;\n    test((\"#[o|]#ne\\ntwo\\n\", \"2t<ret>\", \"#[one\\ntwo|]#\\n\")).await?;\n    test((\"#[o|]#ne\\ntwo\\n\", \"9t<ret>\", \"#[o|]#ne\\ntwo\\n\")).await?;\n\n    test((\"one\\ntwo\\n#[t|]#hree\\n\", \"F<ret>\", \"one\\ntwo#[|\\nt]#hree\\n\")).await?;\n    test((\"one\\ntwo#[\\n|]#three\\n\", \"F<ret>\", \"one#[|\\ntwo\\n]#three\\n\")).await?;\n    test((\"one\\ntw#[o|]#\\nthree\\n\", \"F<ret>\", \"one#[|\\ntwo]#\\nthree\\n\")).await?;\n    test((\"o#[n|]#e\\n\", \"F<ret>\", \"o#[n|]#e\\n\")).await?;\n    test((\"#[o|]#ne\\n\", \"F<ret>\", \"#[o|]#ne\\n\")).await?;\n    test((\"one\\ntwo\\nth#[r|]#ee\\n\", \"2F\\n\", \"one#[|\\ntwo\\nthr]#ee\\n\")).await?;\n    test((\"one\\ntwo\\nth#[r|]#ee\\n\", \"9F\\n\", \"one\\ntwo\\nth#[r|]#ee\\n\")).await?;\n\n    test((\"one\\ntwo\\nth#[r|]#ee\\n\", \"T<ret>\", \"one\\ntwo\\n#[|thr]#ee\\n\")).await?;\n    test((\"one\\ntwo\\n#[t|]#hree\\n\", \"T<ret>\", \"one\\n#[|two\\nt]#hree\\n\")).await?;\n    test((\"one\\ntwo#[\\n|]#three\\n\", \"T<ret>\", \"one\\n#[|two\\n]#three\\n\")).await?;\n    test((\"o#[n|]#e\\n\", \"T<ret>\", \"o#[n|]#e\\n\")).await?;\n    test((\"#[o|]#ne\\n\", \"T<ret>\", \"#[o|]#ne\\n\")).await?;\n    test((\"one\\ntwo\\nth#[r|]#ee\\n\", \"2T\\n\", \"one\\n#[|two\\nthr]#ee\\n\")).await?;\n    test((\"one\\ntwo\\nth#[r|]#ee\\n\", \"9T\\n\", \"one\\ntwo\\nth#[r|]#ee\\n\")).await?;\n\n    test((\n        indoc! {\n            \"\\\n            one\n            #[|t]#wo\n            three\"\n        },\n        \"T<ret>gll2f<ret>\",\n        indoc! {\n            \"\\\n            one\n            two#[\n            |]#three\"\n        },\n    ))\n    .await?;\n\n    test((\n        indoc! {\n            \"\\\n            #[|o]#ne\n            two\n            three\"\n        },\n        \"f<ret>2t<ret>ghT<ret>F<ret>\",\n        indoc! {\n            \"\\\n            one#[|\n            t]#wo\n            three\"\n        },\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn repeat_find_char() -> anyhow::Result<()> {\n    test((\n        indoc! {\n            \"\\\n            #[o|]#ne two\n            one two\"\n        },\n        \"ft<A-.>\",\n        indoc! {\n            \"\\\n            one #[two\n            one t|]#wo\"\n        },\n    ))\n    .await?;\n\n    test((\n        indoc! {\n            \"\\\n            #[o|]#ne two\n            one two\n            \"\n        },\n        \"f<ret><A-.>\",\n        indoc! {\n            \"\\\n            one two#[\n            one two\n            |]#\"\n        },\n    ))\n    .await?;\n\n    test((\n        indoc! {\n            \"\\\n            #[o|]#ne two\n            one two\n            \"\n        },\n        \"ftf<ret><A-.>\",\n        indoc! {\n            \"\\\n            one two#[\n            one two\n            |]#\"\n        },\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_surround_replace() -> anyhow::Result<()> {\n    test((\n        indoc! {\"\\\n            (#[|a]#)\n            \"},\n        \"mrm{\",\n        indoc! {\"\\\n            {#[|a]#}\n            \"},\n    ))\n    .await?;\n\n    test((\n        indoc! {\"\\\n            (#[a|]#)\n            \"},\n        \"mrm{\",\n        indoc! {\"\\\n            {#[a|]#}\n            \"},\n    ))\n    .await?;\n\n    test((\n        indoc! {\"\\\n            {{\n\n            #(}|)#\n            #[}|]#\n            \"},\n        \"mrm)\",\n        indoc! {\"\\\n            ((\n\n            #()|)#\n            #[)|]#\n            \"},\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_surround_delete() -> anyhow::Result<()> {\n    test((\n        indoc! {\"\\\n            (#[|a]#)\n            \"},\n        \"mdm\",\n        indoc! {\"\\\n            #[|a]#\n            \"},\n    ))\n    .await?;\n\n    test((\n        indoc! {\"\\\n            (#[a|]#)\n            \"},\n        \"mdm\",\n        indoc! {\"\\\n            #[a|]#\n            \"},\n    ))\n    .await?;\n\n    test((\n        indoc! {\"\\\n            {{\n\n            #(}|)#\n            #[}|]#\n            \"},\n        \"mdm\",\n        \"\\n\\n#(\\n|)##[\\n|]#\",\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn tree_sitter_motions_work_across_injections() -> anyhow::Result<()> {\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.html\", None),\n        (\n            \"<script>let #[|x]# = 1;</script>\",\n            \"<A-o>\",\n            \"<script>let #[|x = 1]#;</script>\",\n        ),\n    )\n    .await?;\n\n    // When the full injected layer is selected, expand_selection jumps to\n    // a more shallow layer.\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.html\", None),\n        (\n            \"<script>#[|let x = 1;]#</script>\",\n            \"<A-o>\",\n            \"#[|<script>let x = 1;</script>]#\",\n        ),\n    )\n    .await?;\n\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.html\", None),\n        (\n            \"<script>let #[|x = 1]#;</script>\",\n            \"<A-i>\",\n            \"<script>let #[|x]# = 1;</script>\",\n        ),\n    )\n    .await?;\n\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.html\", None),\n        (\n            \"<script>let #[|x]# = 1;</script>\",\n            \"<A-n>\",\n            \"<script>let x #[=|]# 1;</script>\",\n        ),\n    )\n    .await?;\n\n    test_with_config(\n        AppBuilder::new().with_file(\"foo.html\", None),\n        (\n            \"<script>let #[|x]# = 1;</script>\",\n            \"<A-p>\",\n            \"<script>#[|let]# x = 1;</script>\",\n        ),\n    )\n    .await?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-term/tests/test/splits.rs",
    "content": "use super::*;\n\nuse helix_stdx::path;\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_split_write_quit_all() -> anyhow::Result<()> {\n    let mut file1 = tempfile::NamedTempFile::new()?;\n    let mut file2 = tempfile::NamedTempFile::new()?;\n    let mut file3 = tempfile::NamedTempFile::new()?;\n\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file1.path(), None)\n        .build()?;\n\n    test_key_sequences(\n        &mut app,\n        vec![\n            (\n                Some(&format!(\n                    \"ihello1<esc>:sp<ret>:o {}<ret>ihello2<esc>:sp<ret>:o {}<ret>ihello3<esc>\",\n                    file2.path().to_string_lossy(),\n                    file3.path().to_string_lossy()\n                )),\n                Some(&|app| {\n                    let docs: Vec<_> = app.editor.documents().collect();\n                    assert_eq!(3, docs.len());\n\n                    let doc1 = docs\n                        .iter()\n                        .find(|doc| doc.path().unwrap() == &path::normalize(file1.path()))\n                        .unwrap();\n\n                    assert_eq!(\"hello1\", doc1.text().to_string());\n\n                    let doc2 = docs\n                        .iter()\n                        .find(|doc| doc.path().unwrap() == &path::normalize(file2.path()))\n                        .unwrap();\n\n                    assert_eq!(\"hello2\", doc2.text().to_string());\n\n                    let doc3 = docs\n                        .iter()\n                        .find(|doc| doc.path().unwrap() == &path::normalize(file3.path()))\n                        .unwrap();\n\n                    assert_eq!(\"hello3\", doc3.text().to_string());\n\n                    helpers::assert_status_not_error(&app.editor);\n                    assert_eq!(3, app.editor.tree.views().count());\n                }),\n            ),\n            (\n                Some(\":wqa<ret>\"),\n                Some(&|app| {\n                    helpers::assert_status_not_error(&app.editor);\n                    assert_eq!(0, app.editor.tree.views().count());\n                }),\n            ),\n        ],\n        true,\n    )\n    .await?;\n\n    helpers::assert_file_has_content(&mut file1, &LineFeedHandling::Native.apply(\"hello1\"))?;\n    helpers::assert_file_has_content(&mut file2, &LineFeedHandling::Native.apply(\"hello2\"))?;\n    helpers::assert_file_has_content(&mut file3, &LineFeedHandling::Native.apply(\"hello3\"))?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_split_write_quit_same_file() -> anyhow::Result<()> {\n    let mut file = tempfile::NamedTempFile::new()?;\n    let mut app = helpers::AppBuilder::new()\n        .with_file(file.path(), None)\n        .build()?;\n\n    test_key_sequences(\n        &mut app,\n        vec![\n            (\n                Some(\"O<esc>ihello<esc>:sp<ret>ogoodbye<esc>\"),\n                Some(&|app| {\n                    assert_eq!(2, app.editor.tree.views().count());\n                    helpers::assert_status_not_error(&app.editor);\n\n                    let mut docs: Vec<_> = app.editor.documents().collect();\n                    assert_eq!(1, docs.len());\n\n                    let doc = docs.pop().unwrap();\n\n                    assert_eq!(\n                        LineFeedHandling::Native.apply(\"hello\\ngoodbye\"),\n                        doc.text().to_string()\n                    );\n\n                    assert!(doc.is_modified());\n                }),\n            ),\n            (\n                Some(\":wq<ret>\"),\n                Some(&|app| {\n                    helpers::assert_status_not_error(&app.editor);\n                    assert_eq!(1, app.editor.tree.views().count());\n\n                    let mut docs: Vec<_> = app.editor.documents().collect();\n                    assert_eq!(1, docs.len());\n\n                    let doc = docs.pop().unwrap();\n\n                    assert_eq!(\n                        LineFeedHandling::Native.apply(\"hello\\ngoodbye\"),\n                        doc.text().to_string()\n                    );\n\n                    assert!(!doc.is_modified());\n                }),\n            ),\n        ],\n        false,\n    )\n    .await?;\n\n    helpers::assert_file_has_content(&mut file, &LineFeedHandling::Native.apply(\"hello\\ngoodbye\"))?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_changes_in_splits_apply_to_all_views() -> anyhow::Result<()> {\n    // See <https://github.com/helix-editor/helix/issues/4732>.\n    // Transactions must be applied to any view that has the changed document open.\n    // This sequence would panic since the jumplist entry would be modified in one\n    // window but not the other. Attempting to update the changelist in the other\n    // window would cause a panic since it would point outside of the document.\n\n    // The key sequence here:\n    // * <C-w>v       Create a vertical split of the current buffer.\n    //                Both views look at the same doc.\n    // * [<space>     Add a line ending to the beginning of the document.\n    //                The cursor is now at line 2 in window 2.\n    // * <C-s>        Save that selection to the jumplist in window 2.\n    // * <C-w>w       Switch to window 1.\n    // * kd           Delete line 1 in window 1.\n    // * <C-w>q       Close window 1, focusing window 2.\n    // * d            Delete line 1 in window 2.\n    //\n    // This panicked in the past because the jumplist entry on line 2 of window 2\n    // was not updated and after the `kd` step, pointed outside of the document.\n    test((\n        \"#[|]#\",\n        \"<C-w>v[<space><C-s><C-w>wkd<C-w>qd\",\n        \"#[|]#\",\n        LineFeedHandling::AsIs,\n    ))\n    .await?;\n\n    // Transactions are applied to the views for windows lazily when they are focused.\n    // This case panics if the transactions and inversions are not applied in the\n    // correct order as we switch between windows.\n    test((\n        \"#[|]#\",\n        \"[<space>[<space>[<space><C-w>vuuu<C-w>wUUU<C-w>quuu\",\n        \"#[|]#\",\n        LineFeedHandling::AsIs,\n    ))\n    .await?;\n\n    // See <https://github.com/helix-editor/helix/issues/4957>.\n    // This sequence undoes part of the history and then adds new changes, creating a\n    // new branch in the history tree. `View::sync_changes` applies transactions down\n    // and up to the lowest common ancestor in the path between old and new revision\n    // numbers. If we apply these up/down transactions in the wrong order, this case\n    // panics.\n    // The key sequence:\n    // * 3[<space>    Create three empty lines so we are at the end of the document.\n    // * <C-w>v<C-s>  Create a split and save that point at the end of the document\n    //                in the jumplist.\n    // * <C-w>w       Switch back to the first window.\n    // * uu           Undo twice (not three times which would bring us back to the\n    //                root of the tree).\n    // * 3[<space>    Create three empty lines. Now the end of the document is past\n    //                where it was on step 1.\n    // * <C-w>q       Close window 1, focusing window 2 and causing a sync. This step\n    //                panics if we don't apply in the right order.\n    // * %d           Clean up the buffer.\n    test((\n        \"#[|]#\",\n        \"3[<space><C-w>v<C-s><C-w>wuu3[<space><C-w>q%d\",\n        \"#[|]#\",\n        LineFeedHandling::AsIs,\n    ))\n    .await?;\n\n    Ok(())\n}\n\n#[tokio::test(flavor = \"multi_thread\")]\nasync fn test_changes_in_splits_jumplist_sync() -> anyhow::Result<()> {\n    // See <https://github.com/helix-editor/helix/issues/9833>\n    // When jumping backwards (<C-o>) switches between two documents, we need to\n    // ensure that the current view has been synced with all changes to the\n    // document that occurred since the last time the view focused this document.\n    // If the view isn't synced then this case panics since we try to form a\n    // selection on \"test\" (which was deleted in the other view).\n    test((\n        \"#[test|]#\",\n        \"<C-w>sgf<C-w>wd<C-w>w<C-o><C-w>qd\",\n        \"#[|]#\",\n        LineFeedHandling::AsIs,\n    ))\n    .await?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "helix-tui/.gitignore",
    "content": "target\nCargo.lock\n*.log\n*.rs.rustfmt\n.gdb_history\n.idea/\n"
  },
  {
    "path": "helix-tui/Cargo.toml",
    "content": "[package]\nname = \"helix-tui\"\ndescription = \"\"\"A library to build rich terminal user interfaces or dashboards\"\"\"\ninclude = [\"src/**/*\", \"README.md\"]\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n[features]\ndefault = [\"termina\", \"crossterm\"]\n\n[dependencies]\nhelix-view = { path = \"../helix-view\", features = [\"term\"] }\nhelix-core = { path = \"../helix-core\" }\n\nbitflags.workspace = true\ncassowary = \"0.3\"\nunicode-segmentation.workspace = true\ntermina = { workspace = true, optional = true }\ntermini = \"1.0\"\nonce_cell = \"1.21\"\nlog = \"~0.4\"\n\n[target.'cfg(windows)'.dependencies]\ncrossterm = { version = \"0.28\", optional = true }\n"
  },
  {
    "path": "helix-tui/README.md",
    "content": "# helix-tui\n\nThis library is a fork of the great library\n[tui-rs](https://github.com/fdehau/tui-rs/). We've mainly relied on the double\nbuffer implementation and render diffing, side-stepping its widget and\nlayouting.\n"
  },
  {
    "path": "helix-tui/src/backend/crossterm.rs",
    "content": "use crate::{backend::Backend, buffer::Cell, terminal::Config};\nuse crossterm::{\n    cursor::{Hide, MoveTo, SetCursorStyle, Show},\n    event::{\n        DisableBracketedPaste, DisableFocusChange, DisableMouseCapture, EnableBracketedPaste,\n        EnableFocusChange, EnableMouseCapture, KeyboardEnhancementFlags,\n        PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,\n    },\n    execute, queue,\n    style::{\n        Attribute as CAttribute, Color as CColor, Colors, Print, SetAttribute, SetBackgroundColor,\n        SetColors, SetForegroundColor,\n    },\n    terminal::{self, Clear, ClearType},\n    Command,\n};\nuse helix_view::graphics::{Color, CursorKind, Modifier, Rect, UnderlineStyle};\nuse once_cell::sync::OnceCell;\nuse std::{\n    fmt,\n    io::{self, Write},\n};\nuse termini::TermInfo;\n\nfn term_program() -> Option<String> {\n    // Some terminals don't set $TERM_PROGRAM\n    match std::env::var(\"TERM_PROGRAM\") {\n        Err(_) => std::env::var(\"TERM\").ok(),\n        Ok(term_program) => Some(term_program),\n    }\n}\nfn vte_version() -> Option<usize> {\n    std::env::var(\"VTE_VERSION\").ok()?.parse().ok()\n}\nfn reset_cursor_approach(terminfo: TermInfo) -> String {\n    let mut reset_str = String::new();\n\n    if let Some(termini::Value::Utf8String(se_str)) = terminfo.extended_cap(\"Se\") {\n        reset_str.push_str(se_str);\n    };\n\n    reset_str.push_str(\n        terminfo\n            .utf8_string_cap(termini::StringCapability::CursorNormal)\n            .unwrap_or(\"\"),\n    );\n\n    reset_str.push_str(\"\\x1B[0 q\");\n\n    reset_str\n}\n\n/// Describes terminal capabilities like extended underline, truecolor, etc.\n#[derive(Clone, Debug)]\nstruct Capabilities {\n    /// Support for undercurled, underdashed, etc.\n    has_extended_underlines: bool,\n    /// Support for resetting the cursor style back to normal.\n    reset_cursor_command: String,\n}\n\nimpl Default for Capabilities {\n    fn default() -> Self {\n        Self {\n            has_extended_underlines: false,\n            reset_cursor_command: \"\\x1B[0 q\".to_string(),\n        }\n    }\n}\n\nimpl Capabilities {\n    /// Detect capabilities from the terminfo database located based\n    /// on the $TERM environment variable. If detection fails, returns\n    /// a default value where no capability is supported, or just undercurl\n    /// if config.undercurl is set.\n    pub fn from_env_or_default(config: &Config) -> Self {\n        match termini::TermInfo::from_env() {\n            Err(_) => Capabilities {\n                has_extended_underlines: config.force_enable_extended_underlines,\n                ..Capabilities::default()\n            },\n            Ok(t) => Capabilities {\n                // Smulx, VTE: https://unix.stackexchange.com/a/696253/246284\n                // Su (used by kitty): https://sw.kovidgoyal.net/kitty/underlines\n                // WezTerm supports underlines but a lot of distros don't properly install its terminfo\n                has_extended_underlines: config.force_enable_extended_underlines\n                    || t.extended_cap(\"Smulx\").is_some()\n                    || t.extended_cap(\"Su\").is_some()\n                    || vte_version() >= Some(5102)\n                    || matches!(term_program().as_deref(), Some(\"WezTerm\")),\n                reset_cursor_command: reset_cursor_approach(t),\n            },\n        }\n    }\n}\n\n/// Terminal backend supporting a wide variety of terminals\npub struct CrosstermBackend<W: Write> {\n    buffer: W,\n    config: Config,\n    capabilities: Capabilities,\n    supports_keyboard_enhancement_protocol: OnceCell<bool>,\n    mouse_capture_enabled: bool,\n    supports_bracketed_paste: bool,\n}\n\nimpl<W> CrosstermBackend<W>\nwhere\n    W: Write,\n{\n    pub fn new(buffer: W, config: Config) -> CrosstermBackend<W> {\n        // helix is not usable without colors, but crossterm will disable\n        // them by default if NO_COLOR is set in the environment. Override\n        // this behaviour.\n        crossterm::style::force_color_output(true);\n        CrosstermBackend {\n            buffer,\n            capabilities: Capabilities::from_env_or_default(&config),\n            config,\n            supports_keyboard_enhancement_protocol: OnceCell::new(),\n            mouse_capture_enabled: false,\n            supports_bracketed_paste: true,\n        }\n    }\n\n    #[inline]\n    fn supports_keyboard_enhancement_protocol(&self) -> bool {\n        *self.supports_keyboard_enhancement_protocol\n            .get_or_init(|| {\n                use std::time::Instant;\n\n                let now = Instant::now();\n                let supported = matches!(terminal::supports_keyboard_enhancement(), Ok(true));\n                log::debug!(\n                    \"The keyboard enhancement protocol is {}supported in this terminal (checked in {:?})\",\n                    if supported { \"\" } else { \"not \" },\n                    Instant::now().duration_since(now)\n                );\n                supported\n            })\n    }\n}\n\nimpl<W> Write for CrosstermBackend<W>\nwhere\n    W: Write,\n{\n    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n        self.buffer.write(buf)\n    }\n\n    fn flush(&mut self) -> io::Result<()> {\n        self.buffer.flush()\n    }\n}\n\nimpl<W> Backend for CrosstermBackend<W>\nwhere\n    W: Write,\n{\n    fn claim(&mut self) -> io::Result<()> {\n        terminal::enable_raw_mode()?;\n        execute!(\n            self.buffer,\n            terminal::EnterAlternateScreen,\n            EnableFocusChange\n        )?;\n        match execute!(self.buffer, EnableBracketedPaste,) {\n            Err(err) if err.kind() == io::ErrorKind::Unsupported => {\n                log::warn!(\"Bracketed paste is not supported on this terminal.\");\n                self.supports_bracketed_paste = false;\n            }\n            Err(err) => return Err(err),\n            Ok(_) => (),\n        };\n        execute!(self.buffer, terminal::Clear(terminal::ClearType::All))?;\n        if self.config.enable_mouse_capture {\n            execute!(self.buffer, EnableMouseCapture)?;\n            self.mouse_capture_enabled = true;\n        }\n        if self.supports_keyboard_enhancement_protocol() {\n            execute!(\n                self.buffer,\n                PushKeyboardEnhancementFlags(\n                    KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES\n                        | KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS\n                )\n            )?;\n        }\n        Ok(())\n    }\n\n    fn reconfigure(&mut self, config: Config) -> io::Result<()> {\n        if self.mouse_capture_enabled != config.enable_mouse_capture {\n            if config.enable_mouse_capture {\n                execute!(self.buffer, EnableMouseCapture)?;\n            } else {\n                execute!(self.buffer, DisableMouseCapture)?;\n            }\n            self.mouse_capture_enabled = config.enable_mouse_capture;\n        }\n        self.config = config;\n\n        Ok(())\n    }\n\n    fn restore(&mut self) -> io::Result<()> {\n        // reset cursor shape\n        self.buffer\n            .write_all(self.capabilities.reset_cursor_command.as_bytes())?;\n        if self.config.enable_mouse_capture {\n            execute!(self.buffer, DisableMouseCapture)?;\n        }\n        if self.supports_keyboard_enhancement_protocol() {\n            execute!(self.buffer, PopKeyboardEnhancementFlags)?;\n        }\n        if self.supports_bracketed_paste {\n            execute!(self.buffer, DisableBracketedPaste,)?;\n        }\n        execute!(\n            self.buffer,\n            DisableFocusChange,\n            terminal::LeaveAlternateScreen\n        )?;\n        terminal::disable_raw_mode()\n    }\n\n    fn draw<'a, I>(&mut self, content: I) -> io::Result<()>\n    where\n        I: Iterator<Item = (u16, u16, &'a Cell)>,\n    {\n        let mut fg = Color::Reset;\n        let mut bg = Color::Reset;\n        let mut underline_color = Color::Reset;\n        let mut underline_style = UnderlineStyle::Reset;\n        let mut modifier = Modifier::empty();\n        let mut last_pos: Option<(u16, u16)> = None;\n        for (x, y, cell) in content {\n            // Move the cursor if the previous location was not (x - 1, y)\n            if !matches!(last_pos, Some(p) if x == p.0 + 1 && y == p.1) {\n                queue!(self.buffer, MoveTo(x, y))?;\n            }\n            last_pos = Some((x, y));\n            if cell.modifier != modifier {\n                let diff = ModifierDiff {\n                    from: modifier,\n                    to: cell.modifier,\n                };\n                diff.queue(&mut self.buffer)?;\n                modifier = cell.modifier;\n            }\n            if cell.fg != fg || cell.bg != bg {\n                queue!(\n                    self.buffer,\n                    SetColors(Colors::new(cell.fg.into(), cell.bg.into()))\n                )?;\n                fg = cell.fg;\n                bg = cell.bg;\n            }\n\n            let mut new_underline_style = cell.underline_style;\n            if self.capabilities.has_extended_underlines {\n                if cell.underline_color != underline_color {\n                    let color = CColor::from(cell.underline_color);\n                    queue!(self.buffer, SetUnderlineColor(color))?;\n                    underline_color = cell.underline_color;\n                }\n            } else {\n                match new_underline_style {\n                    UnderlineStyle::Reset | UnderlineStyle::Line => (),\n                    _ => new_underline_style = UnderlineStyle::Line,\n                }\n            }\n\n            if new_underline_style != underline_style {\n                let attr = CAttribute::from(new_underline_style);\n                queue!(self.buffer, SetAttribute(attr))?;\n                underline_style = new_underline_style;\n            }\n\n            queue!(self.buffer, Print(&cell.symbol))?;\n        }\n\n        queue!(\n            self.buffer,\n            SetUnderlineColor(CColor::Reset),\n            SetForegroundColor(CColor::Reset),\n            SetBackgroundColor(CColor::Reset),\n            SetAttribute(CAttribute::Reset)\n        )\n    }\n\n    fn hide_cursor(&mut self) -> io::Result<()> {\n        execute!(self.buffer, Hide)\n    }\n\n    fn show_cursor(&mut self, kind: CursorKind) -> io::Result<()> {\n        let shape = match kind {\n            CursorKind::Block => SetCursorStyle::SteadyBlock,\n            CursorKind::Bar => SetCursorStyle::SteadyBar,\n            CursorKind::Underline => SetCursorStyle::SteadyUnderScore,\n            CursorKind::Hidden => unreachable!(),\n        };\n        execute!(self.buffer, Show, shape)\n    }\n\n    fn set_cursor(&mut self, x: u16, y: u16) -> io::Result<()> {\n        execute!(self.buffer, MoveTo(x, y))\n    }\n\n    fn clear(&mut self) -> io::Result<()> {\n        execute!(self.buffer, Clear(ClearType::All))\n    }\n\n    fn size(&self) -> io::Result<Rect> {\n        let (width, height) =\n            terminal::size().map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;\n\n        Ok(Rect::new(0, 0, width, height))\n    }\n\n    fn flush(&mut self) -> io::Result<()> {\n        self.buffer.flush()\n    }\n\n    fn supports_true_color(&self) -> bool {\n        false\n    }\n\n    fn get_theme_mode(&self) -> Option<helix_view::theme::Mode> {\n        None\n    }\n\n    fn set_background_color(&mut self, _color: Option<helix_view::theme::Color>) -> io::Result<()> {\n        Ok(())\n    }\n}\n\n#[derive(Debug)]\nstruct ModifierDiff {\n    pub from: Modifier,\n    pub to: Modifier,\n}\n\nimpl ModifierDiff {\n    fn queue<W>(&self, mut w: W) -> io::Result<()>\n    where\n        W: io::Write,\n    {\n        //use crossterm::Attribute;\n        let removed = self.from - self.to;\n        if removed.contains(Modifier::REVERSED) {\n            queue!(w, SetAttribute(CAttribute::NoReverse))?;\n        }\n        if removed.contains(Modifier::BOLD) {\n            queue!(w, SetAttribute(CAttribute::NormalIntensity))?;\n            if self.to.contains(Modifier::DIM) {\n                queue!(w, SetAttribute(CAttribute::Dim))?;\n            }\n        }\n        if removed.contains(Modifier::ITALIC) {\n            queue!(w, SetAttribute(CAttribute::NoItalic))?;\n        }\n        if removed.contains(Modifier::DIM) {\n            queue!(w, SetAttribute(CAttribute::NormalIntensity))?;\n        }\n        if removed.contains(Modifier::CROSSED_OUT) {\n            queue!(w, SetAttribute(CAttribute::NotCrossedOut))?;\n        }\n        if removed.contains(Modifier::SLOW_BLINK) || removed.contains(Modifier::RAPID_BLINK) {\n            queue!(w, SetAttribute(CAttribute::NoBlink))?;\n        }\n        if removed.contains(Modifier::HIDDEN) {\n            queue!(w, SetAttribute(CAttribute::NoHidden))?;\n        }\n\n        let added = self.to - self.from;\n        if added.contains(Modifier::REVERSED) {\n            queue!(w, SetAttribute(CAttribute::Reverse))?;\n        }\n        if added.contains(Modifier::BOLD) {\n            queue!(w, SetAttribute(CAttribute::Bold))?;\n        }\n        if added.contains(Modifier::ITALIC) {\n            queue!(w, SetAttribute(CAttribute::Italic))?;\n        }\n        if added.contains(Modifier::DIM) {\n            queue!(w, SetAttribute(CAttribute::Dim))?;\n        }\n        if added.contains(Modifier::CROSSED_OUT) {\n            queue!(w, SetAttribute(CAttribute::CrossedOut))?;\n        }\n        if added.contains(Modifier::SLOW_BLINK) {\n            queue!(w, SetAttribute(CAttribute::SlowBlink))?;\n        }\n        if added.contains(Modifier::RAPID_BLINK) {\n            queue!(w, SetAttribute(CAttribute::RapidBlink))?;\n        }\n        if added.contains(Modifier::HIDDEN) {\n            queue!(w, SetAttribute(CAttribute::Hidden))?;\n        }\n\n        Ok(())\n    }\n}\n\n/// Crossterm uses semicolon as a separator for colors\n/// this is actually not spec compliant (although commonly supported)\n/// However the correct approach is to use colons as a separator.\n/// This usually doesn't make a difference for emulators that do support colored underlines.\n/// However terminals that do not support colored underlines will ignore underlines colors with colons\n/// while escape sequences with semicolons are always processed which leads to weird visual artifacts.\n/// See [this nvim issue](https://github.com/neovim/neovim/issues/9270) for details\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub struct SetUnderlineColor(pub CColor);\n\nimpl Command for SetUnderlineColor {\n    fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {\n        let color = self.0;\n\n        if color == CColor::Reset {\n            write!(f, \"\\x1b[59m\")?;\n            return Ok(());\n        }\n        f.write_str(\"\\x1b[58:\")?;\n\n        let res = match color {\n            CColor::Black => f.write_str(\"5:0\"),\n            CColor::DarkGrey => f.write_str(\"5:8\"),\n            CColor::Red => f.write_str(\"5:9\"),\n            CColor::DarkRed => f.write_str(\"5:1\"),\n            CColor::Green => f.write_str(\"5:10\"),\n            CColor::DarkGreen => f.write_str(\"5:2\"),\n            CColor::Yellow => f.write_str(\"5:11\"),\n            CColor::DarkYellow => f.write_str(\"5:3\"),\n            CColor::Blue => f.write_str(\"5:12\"),\n            CColor::DarkBlue => f.write_str(\"5:4\"),\n            CColor::Magenta => f.write_str(\"5:13\"),\n            CColor::DarkMagenta => f.write_str(\"5:5\"),\n            CColor::Cyan => f.write_str(\"5:14\"),\n            CColor::DarkCyan => f.write_str(\"5:6\"),\n            CColor::White => f.write_str(\"5:15\"),\n            CColor::Grey => f.write_str(\"5:7\"),\n            CColor::Rgb { r, g, b } => write!(f, \"2::{}:{}:{}\", r, g, b),\n            CColor::AnsiValue(val) => write!(f, \"5:{}\", val),\n            _ => Ok(()),\n        };\n        res?;\n        write!(f, \"m\")?;\n        Ok(())\n    }\n\n    #[cfg(windows)]\n    fn execute_winapi(&self) -> io::Result<()> {\n        Err(std::io::Error::new(\n            std::io::ErrorKind::Other,\n            \"SetUnderlineColor not supported by winapi.\",\n        ))\n    }\n}\n"
  },
  {
    "path": "helix-tui/src/backend/mod.rs",
    "content": "//! Provides interface for controlling the terminal\n\nuse std::io;\n\nuse crate::{buffer::Cell, terminal::Config};\n\nuse helix_view::{\n    graphics::{CursorKind, Rect},\n    theme::Color,\n};\n\n#[cfg(all(feature = \"termina\", not(windows)))]\nmod termina;\n#[cfg(all(feature = \"termina\", not(windows)))]\npub use self::termina::TerminaBackend;\n\n#[cfg(all(feature = \"termina\", windows))]\nmod crossterm;\n#[cfg(all(feature = \"termina\", windows))]\npub use self::crossterm::CrosstermBackend;\n\nmod test;\npub use self::test::TestBackend;\n\n/// Representation of a terminal backend.\npub trait Backend {\n    /// Claims the terminal for TUI use.\n    fn claim(&mut self) -> Result<(), io::Error>;\n    /// Update terminal configuration.\n    fn reconfigure(&mut self, config: Config) -> Result<(), io::Error>;\n    /// Restores the terminal to a normal state, undoes `claim`\n    fn restore(&mut self) -> Result<(), io::Error>;\n    /// Draws styled text to the terminal\n    fn draw<'a, I>(&mut self, content: I) -> Result<(), io::Error>\n    where\n        I: Iterator<Item = (u16, u16, &'a Cell)>;\n    /// Hides the cursor\n    fn hide_cursor(&mut self) -> Result<(), io::Error>;\n    /// Sets the cursor to the given shape\n    fn show_cursor(&mut self, kind: CursorKind) -> Result<(), io::Error>;\n    /// Sets the cursor to the given position\n    fn set_cursor(&mut self, x: u16, y: u16) -> Result<(), io::Error>;\n    /// Clears the terminal\n    fn clear(&mut self) -> Result<(), io::Error>;\n    /// Gets the size of the terminal in cells\n    fn size(&self) -> Result<Rect, io::Error>;\n    /// Flushes the terminal buffer\n    fn flush(&mut self) -> Result<(), io::Error>;\n    fn supports_true_color(&self) -> bool;\n    fn get_theme_mode(&self) -> Option<helix_view::theme::Mode>;\n    fn set_background_color(&mut self, color: Option<Color>) -> io::Result<()>;\n}\n"
  },
  {
    "path": "helix-tui/src/backend/termina.rs",
    "content": "use std::io::{self, Write as _};\n\nuse helix_view::{\n    editor::KittyKeyboardProtocolConfig,\n    graphics::{CursorKind, Rect, UnderlineStyle},\n    theme::{self, Color, Modifier},\n};\nuse termina::{\n    escape::{\n        csi::{self, Csi, SgrAttributes, SgrModifiers},\n        dcs::{self, Dcs},\n        osc::{self, Osc},\n    },\n    style::{CursorStyle, RgbColor},\n    Event, OneBased, PlatformTerminal, Terminal as _, WindowSize,\n};\n\nuse crate::{buffer::Cell, terminal::Config};\n\nuse super::Backend;\n\n// These macros are helpers to set/unset modes like bracketed paste or enter/exit the alternate\n// screen.\nmacro_rules! decset {\n    ($mode:ident) => {\n        Csi::Mode(csi::Mode::SetDecPrivateMode(csi::DecPrivateMode::Code(\n            csi::DecPrivateModeCode::$mode,\n        )))\n    };\n}\nmacro_rules! decreset {\n    ($mode:ident) => {\n        Csi::Mode(csi::Mode::ResetDecPrivateMode(csi::DecPrivateMode::Code(\n            csi::DecPrivateModeCode::$mode,\n        )))\n    };\n}\n\nfn term_program() -> Option<String> {\n    // Some terminals don't set $TERM_PROGRAM\n    match std::env::var(\"TERM_PROGRAM\") {\n        Err(_) => std::env::var(\"TERM\").ok(),\n        Ok(term_program) => Some(term_program),\n    }\n}\nfn vte_version() -> Option<usize> {\n    std::env::var(\"VTE_VERSION\").ok()?.parse().ok()\n}\n\n#[derive(Debug, Default, Clone, Copy)]\nstruct Capabilities {\n    kitty_keyboard: KittyKeyboardSupport,\n    synchronized_output: bool,\n    true_color: bool,\n    extended_underlines: bool,\n    theme_mode: Option<theme::Mode>,\n}\n\n#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]\nenum KittyKeyboardSupport {\n    /// The terminal doesn't support the protocol.\n    #[default]\n    None,\n    /// The terminal supports the protocol but we haven't checked yet whether it has full or\n    /// partial support for the flags we require.\n    Some,\n    /// The terminal only supports some of the flags we require.\n    Partial,\n    /// The terminal supports all flags require.\n    Full,\n}\n\n#[derive(Debug)]\npub struct TerminaBackend {\n    terminal: PlatformTerminal,\n    config: Config,\n    capabilities: Capabilities,\n    reset_cursor_command: String,\n    is_synchronized_output_set: bool,\n}\n\nimpl TerminaBackend {\n    pub fn new(config: Config) -> io::Result<Self> {\n        let mut terminal = PlatformTerminal::new()?;\n        let (capabilities, reset_cursor_command) =\n            Self::detect_capabilities(&mut terminal, &config)?;\n\n        // In the case of a panic, reset the terminal eagerly. If we didn't do this and instead\n        // relied on `Drop`, the backtrace would be lost because it is printed before we would\n        // clear and exit the alternate screen.\n        let hook_reset_cursor_command = reset_cursor_command.clone();\n        terminal.set_panic_hook(move |term| {\n            let _ = write!(\n                term,\n                \"{}{}{}{}{}{}{}{}{}{}{}{}\",\n                Csi::Keyboard(csi::Keyboard::PopFlags(1)),\n                decreset!(MouseTracking),\n                decreset!(ButtonEventMouse),\n                decreset!(AnyEventMouse),\n                decreset!(RXVTMouse),\n                decreset!(SGRMouse),\n                &hook_reset_cursor_command,\n                decreset!(BracketedPaste),\n                decreset!(FocusTracking),\n                Osc::ResetDynamicColor(osc::DynamicColorNumber::TextBackgroundColor),\n                Csi::Edit(csi::Edit::EraseInDisplay(csi::EraseInDisplay::EraseDisplay)),\n                decreset!(ClearAndEnableAlternateScreen),\n            );\n        });\n\n        Ok(Self {\n            terminal,\n            config,\n            capabilities,\n            reset_cursor_command,\n            is_synchronized_output_set: false,\n        })\n    }\n\n    pub fn terminal(&self) -> &PlatformTerminal {\n        &self.terminal\n    }\n\n    fn detect_capabilities(\n        terminal: &mut PlatformTerminal,\n        config: &Config,\n    ) -> io::Result<(Capabilities, String)> {\n        use std::time::{Duration, Instant};\n\n        // Colibri \"midnight\"\n        const TEST_COLOR: RgbColor = RgbColor::new(59, 34, 76);\n\n        terminal.enter_raw_mode()?;\n\n        let mut capabilities = Capabilities::default();\n        let start = Instant::now();\n\n        capabilities.kitty_keyboard = match config.kitty_keyboard_protocol {\n            KittyKeyboardProtocolConfig::Disabled => KittyKeyboardSupport::None,\n            KittyKeyboardProtocolConfig::Enabled => KittyKeyboardSupport::Full,\n            KittyKeyboardProtocolConfig::Auto => {\n                write!(terminal, \"{}\", Csi::Keyboard(csi::Keyboard::QueryFlags))?;\n                KittyKeyboardSupport::None\n            }\n        };\n\n        // Many terminal extensions can be detected by querying the terminal for the state of the\n        // extension and then sending a request for the primary device attributes (which is\n        // consistently supported by all terminals). If we receive the status of the feature (for\n        // example the current Kitty keyboard flags) then we know that the feature is supported.\n        // If we only receive the device attributes then we know it is not.\n        write!(\n            terminal,\n            \"{}{}{}{}{}{}{}\",\n            // Synchronized output\n            Csi::Mode(csi::Mode::QueryDecPrivateMode(csi::DecPrivateMode::Code(\n                csi::DecPrivateModeCode::SynchronizedOutput\n            ))),\n            // Mode 2031 theme updates. Query the current theme.\n            Csi::Mode(csi::Mode::QueryTheme),\n            // True color and while we're at it, extended underlines:\n            // <https://github.com/termstandard/colors?tab=readme-ov-file#querying-the-terminal>\n            Csi::Sgr(csi::Sgr::Background(TEST_COLOR.into())),\n            Csi::Sgr(csi::Sgr::UnderlineColor(TEST_COLOR.into())),\n            Dcs::Request(dcs::DcsRequest::GraphicRendition),\n            Csi::Sgr(csi::Sgr::Reset),\n            // Finally request the primary device attributes\n            Csi::Device(csi::Device::RequestPrimaryDeviceAttributes),\n        )?;\n        terminal.flush()?;\n\n        let device_attributes = |event: &Event| {\n            matches!(\n                event,\n                Event::Csi(Csi::Device(csi::Device::DeviceAttributes(_)))\n            )\n        };\n        // TODO: tune this poll constant? Does it need to be longer when on an SSH connection?\n        let poll_duration = Duration::from_millis(100);\n        if terminal.poll(device_attributes, Some(poll_duration))? {\n            while terminal.poll(Event::is_escape, Some(Duration::ZERO))? {\n                match terminal.read(Event::is_escape)? {\n                    Event::Csi(Csi::Keyboard(csi::Keyboard::ReportFlags(_))) => {\n                        capabilities.kitty_keyboard = KittyKeyboardSupport::Some;\n                    }\n                    Event::Csi(Csi::Mode(csi::Mode::ReportDecPrivateMode {\n                        mode: csi::DecPrivateMode::Code(csi::DecPrivateModeCode::SynchronizedOutput),\n                        setting: csi::DecModeSetting::Set | csi::DecModeSetting::Reset,\n                    })) => {\n                        capabilities.synchronized_output = true;\n                    }\n                    Event::Csi(Csi::Mode(csi::Mode::ReportTheme(mode))) => {\n                        capabilities.theme_mode = Some(mode.into());\n                    }\n                    Event::Dcs(dcs::Dcs::Response {\n                        value: dcs::DcsResponse::GraphicRendition(sgrs),\n                        ..\n                    }) => {\n                        capabilities.true_color =\n                            sgrs.contains(&csi::Sgr::Background(TEST_COLOR.into()));\n                        capabilities.extended_underlines =\n                            sgrs.contains(&csi::Sgr::UnderlineColor(TEST_COLOR.into()));\n                    }\n                    _ => (),\n                }\n            }\n\n            let end = Instant::now();\n            log::debug!(\n                \"Detected terminal capabilities in {:?}: {capabilities:?}\",\n                end.duration_since(start)\n            );\n        } else {\n            log::debug!(\"Failed to detect terminal capabilities within {poll_duration:?}. Using default capabilities only\");\n        }\n\n        capabilities.extended_underlines |= config.force_enable_extended_underlines;\n\n        let mut reset_cursor_command = String::new();\n        if let Ok(t) = termini::TermInfo::from_env() {\n            capabilities.extended_underlines |= t.extended_cap(\"Smulx\").is_some()\n                || t.extended_cap(\"Su\").is_some()\n                || vte_version() >= Some(5102)\n                // HACK: once WezTerm can support DECRQSS/DECRPSS for SGR we can remove this line.\n                // <https://github.com/wezterm/wezterm/pull/6856>\n                || matches!(term_program().as_deref(), Some(\"WezTerm\"));\n\n            if let Some(termini::Value::Utf8String(se_str)) = t.extended_cap(\"Se\") {\n                reset_cursor_command.push_str(se_str);\n            };\n            reset_cursor_command.push_str(\n                t.utf8_string_cap(termini::StringCapability::CursorNormal)\n                    .unwrap_or(\"\"),\n            );\n            log::debug!(\n                \"Cursor reset escape sequence detected from terminfo: {reset_cursor_command:?}\"\n            );\n        } else {\n            log::debug!(\"terminfo could not be read, using default cursor reset escape sequence: {reset_cursor_command:?}\");\n        }\n        reset_cursor_command\n            .push_str(&Csi::Cursor(csi::Cursor::CursorStyle(CursorStyle::Default)).to_string());\n\n        terminal.enter_cooked_mode()?;\n\n        Ok((capabilities, reset_cursor_command))\n    }\n\n    fn enable_mouse_capture(&mut self) -> io::Result<()> {\n        if self.config.enable_mouse_capture {\n            write!(\n                self.terminal,\n                \"{}{}{}{}{}\",\n                decset!(MouseTracking),\n                decset!(ButtonEventMouse),\n                decset!(AnyEventMouse),\n                decset!(RXVTMouse),\n                decset!(SGRMouse),\n            )?;\n        }\n        Ok(())\n    }\n\n    fn disable_mouse_capture(&mut self) -> io::Result<()> {\n        if self.config.enable_mouse_capture {\n            write!(\n                self.terminal,\n                \"{}{}{}{}{}\",\n                decreset!(MouseTracking),\n                decreset!(ButtonEventMouse),\n                decreset!(AnyEventMouse),\n                decreset!(RXVTMouse),\n                decreset!(SGRMouse),\n            )?;\n        }\n        Ok(())\n    }\n\n    fn enable_extensions(&mut self) -> io::Result<()> {\n        const KEYBOARD_FLAGS: csi::KittyKeyboardFlags =\n            csi::KittyKeyboardFlags::DISAMBIGUATE_ESCAPE_CODES\n                .union(csi::KittyKeyboardFlags::REPORT_ALTERNATE_KEYS);\n\n        match self.capabilities.kitty_keyboard {\n            KittyKeyboardSupport::None | KittyKeyboardSupport::Partial => (),\n            KittyKeyboardSupport::Full => {\n                write!(\n                    self.terminal,\n                    \"{}\",\n                    Csi::Keyboard(csi::Keyboard::PushFlags(KEYBOARD_FLAGS))\n                )?;\n            }\n            KittyKeyboardSupport::Some => {\n                write!(\n                    self.terminal,\n                    \"{}{}\",\n                    // Enable the flags we need.\n                    Csi::Keyboard(csi::Keyboard::PushFlags(KEYBOARD_FLAGS)),\n                    // Then request the current flags. We need to check if the terminal enabled\n                    // all of the flags we require.\n                    Csi::Keyboard(csi::Keyboard::QueryFlags),\n                )?;\n                self.terminal.flush()?;\n\n                let event = self.terminal.read(|event| {\n                    matches!(\n                        event,\n                        Event::Csi(Csi::Keyboard(csi::Keyboard::ReportFlags(_)))\n                    )\n                })?;\n                let Event::Csi(Csi::Keyboard(csi::Keyboard::ReportFlags(flags))) = event else {\n                    unreachable!();\n                };\n                if flags != KEYBOARD_FLAGS {\n                    log::info!(\"Turning off enhanced keyboard support because the terminal enabled different flags. Requested {KEYBOARD_FLAGS:?} but got {flags:?}\");\n                    write!(\n                        self.terminal,\n                        \"{}\",\n                        Csi::Keyboard(csi::Keyboard::PopFlags(1))\n                    )?;\n                    self.terminal.flush()?;\n                    self.capabilities.kitty_keyboard = KittyKeyboardSupport::Partial;\n                } else {\n                    log::debug!(\n                        \"The terminal fully supports the requested keyboard enhancement flags\"\n                    );\n                    self.capabilities.kitty_keyboard = KittyKeyboardSupport::Full;\n                }\n            }\n        }\n\n        if self.capabilities.theme_mode.is_some() {\n            // Enable mode 2031 theme mode notifications:\n            write!(self.terminal, \"{}\", decset!(Theme))?;\n        }\n\n        Ok(())\n    }\n\n    fn disable_extensions(&mut self) -> io::Result<()> {\n        if self.capabilities.kitty_keyboard == KittyKeyboardSupport::Full {\n            write!(\n                self.terminal,\n                \"{}\",\n                Csi::Keyboard(csi::Keyboard::PopFlags(1))\n            )?;\n        }\n\n        if self.capabilities.theme_mode.is_some() {\n            // Mode 2031 theme notifications.\n            write!(self.terminal, \"{}\", decreset!(Theme))?;\n        }\n\n        Ok(())\n    }\n\n    // See <https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036>.\n    // Synchronized output sequences tell the terminal when we are \"starting to render\" and\n    // stopping, enabling to make better choices about when it draws a frame. This avoids all\n    // kinds of ugly visual artifacts like tearing and flashing (i.e. the background color\n    // after clearing the terminal).\n\n    fn start_synchronized_render(&mut self) -> io::Result<()> {\n        if self.capabilities.synchronized_output && !self.is_synchronized_output_set {\n            write!(self.terminal, \"{}\", decset!(SynchronizedOutput))?;\n            self.is_synchronized_output_set = true;\n        }\n        Ok(())\n    }\n\n    fn end_sychronized_render(&mut self) -> io::Result<()> {\n        if self.is_synchronized_output_set {\n            write!(self.terminal, \"{}\", decreset!(SynchronizedOutput))?;\n            self.is_synchronized_output_set = false;\n        }\n        Ok(())\n    }\n}\n\nimpl Backend for TerminaBackend {\n    fn claim(&mut self) -> io::Result<()> {\n        self.terminal.enter_raw_mode()?;\n\n        write!(\n            self.terminal,\n            \"{}{}{}{}\",\n            // Enter an alternate screen.\n            decset!(ClearAndEnableAlternateScreen),\n            decset!(BracketedPaste),\n            decset!(FocusTracking),\n            // Clear the buffer. `ClearAndEnableAlternateScreen` **should** do this but some\n            // things like mosh are buggy. See <https://github.com/helix-editor/helix/pull/1944>.\n            Csi::Edit(csi::Edit::EraseInDisplay(csi::EraseInDisplay::EraseDisplay)),\n        )?;\n        self.enable_mouse_capture()?;\n        self.enable_extensions()?;\n\n        Ok(())\n    }\n\n    fn reconfigure(&mut self, mut config: Config) -> io::Result<()> {\n        std::mem::swap(&mut self.config, &mut config);\n        if self.config.enable_mouse_capture != config.enable_mouse_capture {\n            if self.config.enable_mouse_capture {\n                self.enable_mouse_capture()?;\n            } else {\n                self.disable_mouse_capture()?;\n            }\n        }\n        self.capabilities.extended_underlines |= self.config.force_enable_extended_underlines;\n        Ok(())\n    }\n\n    fn restore(&mut self) -> io::Result<()> {\n        self.disable_extensions()?;\n        self.disable_mouse_capture()?;\n        write!(\n            self.terminal,\n            \"{}{}{}{}\",\n            &self.reset_cursor_command,\n            decreset!(BracketedPaste),\n            decreset!(FocusTracking),\n            decreset!(ClearAndEnableAlternateScreen),\n        )?;\n        self.terminal.flush()?;\n        self.terminal.enter_cooked_mode()?;\n        Ok(())\n    }\n\n    fn draw<'a, I>(&mut self, content: I) -> io::Result<()>\n    where\n        I: Iterator<Item = (u16, u16, &'a Cell)>,\n    {\n        self.start_synchronized_render()?;\n\n        let mut fg = Color::Reset;\n        let mut bg = Color::Reset;\n        let mut underline_color = Color::Reset;\n        let mut underline_style = UnderlineStyle::Reset;\n        let mut modifier = Modifier::empty();\n        let mut last_pos: Option<(u16, u16)> = None;\n        for (x, y, cell) in content {\n            // Move the cursor if the previous location was not (x - 1, y)\n            if !matches!(last_pos, Some(p) if x == p.0 + 1 && y == p.1) {\n                write!(\n                    self.terminal,\n                    \"{}\",\n                    Csi::Cursor(csi::Cursor::Position {\n                        col: OneBased::from_zero_based(x),\n                        line: OneBased::from_zero_based(y),\n                    })\n                )?;\n            }\n            last_pos = Some((x, y));\n\n            let mut attributes = SgrAttributes::default();\n            if cell.fg != fg {\n                attributes.foreground = Some(cell.fg.into());\n                fg = cell.fg;\n            }\n            if cell.bg != bg {\n                attributes.background = Some(cell.bg.into());\n                bg = cell.bg;\n            }\n            if cell.modifier != modifier {\n                attributes.modifiers = diff_modifiers(modifier, cell.modifier);\n                modifier = cell.modifier;\n            }\n\n            // Set underline style and color separately from SgrAttributes. Some terminals seem\n            // to not like underline colors and styles being intermixed with other SGRs.\n            let mut new_underline_style = cell.underline_style;\n            if self.capabilities.extended_underlines {\n                if cell.underline_color != underline_color {\n                    write!(\n                        self.terminal,\n                        \"{}\",\n                        Csi::Sgr(csi::Sgr::UnderlineColor(cell.underline_color.into()))\n                    )?;\n                    underline_color = cell.underline_color;\n                }\n            } else {\n                match new_underline_style {\n                    UnderlineStyle::Reset | UnderlineStyle::Line => (),\n                    _ => new_underline_style = UnderlineStyle::Line,\n                }\n            }\n            if new_underline_style != underline_style {\n                write!(\n                    self.terminal,\n                    \"{}\",\n                    Csi::Sgr(csi::Sgr::Underline(new_underline_style.into()))\n                )?;\n                underline_style = new_underline_style;\n            }\n\n            // `attributes` will be empty if nothing changed between two cells. Empty\n            // `SgrAttributes` behave the same as a `Sgr::Reset` rather than a 'no-op' though so\n            // we should avoid writing them if they're empty.\n            if !attributes.is_empty() {\n                write!(\n                    self.terminal,\n                    \"{}\",\n                    Csi::Sgr(csi::Sgr::Attributes(attributes))\n                )?;\n            }\n\n            write!(self.terminal, \"{}\", &cell.symbol)?;\n        }\n\n        write!(self.terminal, \"{}\", Csi::Sgr(csi::Sgr::Reset))?;\n\n        self.end_sychronized_render()?;\n\n        Ok(())\n    }\n\n    fn hide_cursor(&mut self) -> io::Result<()> {\n        write!(self.terminal, \"{}\", decreset!(ShowCursor))?;\n        self.flush()\n    }\n\n    fn show_cursor(&mut self, kind: CursorKind) -> io::Result<()> {\n        let style = match kind {\n            CursorKind::Block => CursorStyle::SteadyBlock,\n            CursorKind::Bar => CursorStyle::SteadyBar,\n            CursorKind::Underline => CursorStyle::SteadyUnderline,\n            CursorKind::Hidden => unreachable!(),\n        };\n        write!(\n            self.terminal,\n            \"{}{}\",\n            decset!(ShowCursor),\n            Csi::Cursor(csi::Cursor::CursorStyle(style)),\n        )?;\n        self.flush()\n    }\n\n    fn set_cursor(&mut self, x: u16, y: u16) -> io::Result<()> {\n        let col = OneBased::from_zero_based(x);\n        let line = OneBased::from_zero_based(y);\n        write!(\n            self.terminal,\n            \"{}\",\n            Csi::Cursor(csi::Cursor::Position { line, col })\n        )?;\n        self.flush()\n    }\n\n    fn clear(&mut self) -> io::Result<()> {\n        self.start_synchronized_render()?;\n        write!(\n            self.terminal,\n            \"{}\",\n            Csi::Edit(csi::Edit::EraseInDisplay(csi::EraseInDisplay::EraseDisplay))\n        )?;\n        self.flush()\n    }\n\n    fn size(&self) -> io::Result<Rect> {\n        let WindowSize { rows, cols, .. } = self.terminal.get_dimensions()?;\n        Ok(Rect::new(0, 0, cols, rows))\n    }\n\n    fn flush(&mut self) -> io::Result<()> {\n        self.terminal.flush()\n    }\n\n    fn supports_true_color(&self) -> bool {\n        self.capabilities.true_color\n    }\n\n    fn get_theme_mode(&self) -> Option<theme::Mode> {\n        self.capabilities.theme_mode\n    }\n\n    fn set_background_color(&mut self, color: Option<Color>) -> io::Result<()> {\n        write!(\n            self.terminal,\n            \"{}\",\n            match color {\n                Some(Color::Rgb(r, g, b)) => Osc::ChangeDynamicColors(\n                    osc::DynamicColorNumber::TextBackgroundColor,\n                    vec![RgbColor::new(r, g, b).into()]\n                ),\n                _ => Osc::ResetDynamicColor(osc::DynamicColorNumber::TextBackgroundColor),\n            }\n        )\n    }\n}\n\nimpl Drop for TerminaBackend {\n    fn drop(&mut self) {\n        // Avoid resetting the terminal while panicking because we set a panic hook above in\n        // `Self::new`.\n        if !std::thread::panicking() {\n            let _ = self.disable_extensions();\n            let _ = self.disable_mouse_capture();\n            let _ = write!(\n                self.terminal,\n                \"{}{}{}{}{}\",\n                &self.reset_cursor_command,\n                decreset!(BracketedPaste),\n                decreset!(FocusTracking),\n                Osc::ResetDynamicColor(osc::DynamicColorNumber::TextBackgroundColor),\n                decreset!(ClearAndEnableAlternateScreen),\n            );\n            // NOTE: Drop for Platform terminal resets the mode and flushes the buffer when not\n            // panicking.\n        }\n    }\n}\n\nfn diff_modifiers(from: Modifier, to: Modifier) -> SgrModifiers {\n    let mut modifiers = SgrModifiers::default();\n\n    let removed = from - to;\n    if removed.contains(Modifier::REVERSED) {\n        modifiers |= SgrModifiers::NO_REVERSE;\n    }\n    if removed.contains(Modifier::BOLD) {\n        modifiers |= SgrModifiers::INTENSITY_NORMAL;\n        if to.contains(Modifier::DIM) {\n            modifiers |= SgrModifiers::INTENSITY_DIM\n        }\n    }\n    if removed.contains(Modifier::DIM) {\n        modifiers |= SgrModifiers::INTENSITY_NORMAL;\n    }\n    if removed.contains(Modifier::ITALIC) {\n        modifiers |= SgrModifiers::NO_ITALIC;\n    }\n    if removed.contains(Modifier::CROSSED_OUT) {\n        modifiers |= SgrModifiers::NO_STRIKE_THROUGH;\n    }\n    if removed.contains(Modifier::HIDDEN) {\n        modifiers |= SgrModifiers::NO_INVISIBLE;\n    }\n    if removed.contains(Modifier::SLOW_BLINK) || removed.contains(Modifier::RAPID_BLINK) {\n        modifiers |= SgrModifiers::BLINK_NONE;\n    }\n\n    let added = to - from;\n    if added.contains(Modifier::REVERSED) {\n        modifiers |= SgrModifiers::REVERSE;\n    }\n    if added.contains(Modifier::BOLD) {\n        modifiers |= SgrModifiers::INTENSITY_BOLD;\n    }\n    if added.contains(Modifier::DIM) {\n        modifiers |= SgrModifiers::INTENSITY_DIM;\n    }\n    if added.contains(Modifier::ITALIC) {\n        modifiers |= SgrModifiers::ITALIC;\n    }\n    if added.contains(Modifier::CROSSED_OUT) {\n        modifiers |= SgrModifiers::STRIKE_THROUGH;\n    }\n    if added.contains(Modifier::HIDDEN) {\n        modifiers |= SgrModifiers::INVISIBLE;\n    }\n    if added.contains(Modifier::SLOW_BLINK) {\n        modifiers |= SgrModifiers::BLINK_SLOW;\n    }\n    if added.contains(Modifier::RAPID_BLINK) {\n        modifiers |= SgrModifiers::BLINK_RAPID;\n    }\n\n    modifiers\n}\n"
  },
  {
    "path": "helix-tui/src/backend/test.rs",
    "content": "use crate::{\n    backend::Backend,\n    buffer::{Buffer, Cell},\n    terminal::Config,\n};\nuse helix_core::unicode::width::UnicodeWidthStr;\nuse helix_view::graphics::{CursorKind, Rect};\nuse std::{fmt::Write, io};\n\n/// A backend used for the integration tests.\n#[derive(Debug)]\npub struct TestBackend {\n    width: u16,\n    buffer: Buffer,\n    height: u16,\n    cursor: bool,\n    pos: (u16, u16),\n}\n\n/// Returns a string representation of the given buffer for debugging purpose.\nfn buffer_view(buffer: &Buffer) -> String {\n    let mut view = String::with_capacity(buffer.content.len() + buffer.area.height as usize * 3);\n    for cells in buffer.content.chunks(buffer.area.width as usize) {\n        let mut overwritten = vec![];\n        let mut skip: usize = 0;\n        view.push('\"');\n        for (x, c) in cells.iter().enumerate() {\n            if skip == 0 {\n                view.push_str(&c.symbol);\n            } else {\n                overwritten.push((x, &c.symbol))\n            }\n            skip = std::cmp::max(skip, c.symbol.width()).saturating_sub(1);\n        }\n        view.push('\"');\n        if !overwritten.is_empty() {\n            write!(\n                &mut view,\n                \" Hidden by multi-width symbols: {:?}\",\n                overwritten\n            )\n            .unwrap();\n        }\n        view.push('\\n');\n    }\n    view\n}\n\nimpl TestBackend {\n    pub fn new(width: u16, height: u16) -> TestBackend {\n        TestBackend {\n            width,\n            height,\n            buffer: Buffer::empty(Rect::new(0, 0, width, height)),\n            cursor: false,\n            pos: (0, 0),\n        }\n    }\n\n    pub fn buffer(&self) -> &Buffer {\n        &self.buffer\n    }\n\n    pub fn resize(&mut self, width: u16, height: u16) {\n        self.buffer.resize(Rect::new(0, 0, width, height));\n        self.width = width;\n        self.height = height;\n    }\n\n    pub fn assert_buffer(&self, expected: &Buffer) {\n        assert_eq!(expected.area, self.buffer.area);\n        let diff = expected.diff(&self.buffer);\n        if diff.is_empty() {\n            return;\n        }\n\n        let mut debug_info = String::from(\"Buffers are not equal\");\n        debug_info.push('\\n');\n        debug_info.push_str(\"Expected:\");\n        debug_info.push('\\n');\n        let expected_view = buffer_view(expected);\n        debug_info.push_str(&expected_view);\n        debug_info.push('\\n');\n        debug_info.push_str(\"Got:\");\n        debug_info.push('\\n');\n        let view = buffer_view(&self.buffer);\n        debug_info.push_str(&view);\n        debug_info.push('\\n');\n\n        debug_info.push_str(\"Diff:\");\n        debug_info.push('\\n');\n        let nice_diff = diff\n            .iter()\n            .enumerate()\n            .map(|(i, (x, y, cell))| {\n                let expected_cell = expected.get(*x, *y);\n                format!(\n                    \"{}: at ({}, {}) expected {:?} got {:?}\",\n                    i, x, y, expected_cell, cell\n                )\n            })\n            .collect::<Vec<String>>()\n            .join(\"\\n\");\n        debug_info.push_str(&nice_diff);\n        panic!(\"{}\", debug_info);\n    }\n}\n\nimpl Backend for TestBackend {\n    fn claim(&mut self) -> Result<(), io::Error> {\n        Ok(())\n    }\n\n    fn reconfigure(&mut self, _config: Config) -> Result<(), io::Error> {\n        Ok(())\n    }\n\n    fn restore(&mut self) -> Result<(), io::Error> {\n        Ok(())\n    }\n\n    fn draw<'a, I>(&mut self, content: I) -> Result<(), io::Error>\n    where\n        I: Iterator<Item = (u16, u16, &'a Cell)>,\n    {\n        for (x, y, c) in content {\n            self.buffer[(x, y)] = c.clone();\n        }\n        Ok(())\n    }\n\n    fn hide_cursor(&mut self) -> Result<(), io::Error> {\n        self.cursor = false;\n        Ok(())\n    }\n\n    fn show_cursor(&mut self, _kind: CursorKind) -> Result<(), io::Error> {\n        self.cursor = true;\n        Ok(())\n    }\n\n    fn set_cursor(&mut self, x: u16, y: u16) -> Result<(), io::Error> {\n        self.pos = (x, y);\n        Ok(())\n    }\n\n    fn clear(&mut self) -> Result<(), io::Error> {\n        self.buffer.reset();\n        Ok(())\n    }\n\n    fn size(&self) -> Result<Rect, io::Error> {\n        Ok(Rect::new(0, 0, self.width, self.height))\n    }\n\n    fn flush(&mut self) -> Result<(), io::Error> {\n        Ok(())\n    }\n\n    fn supports_true_color(&self) -> bool {\n        false\n    }\n\n    fn get_theme_mode(&self) -> Option<helix_view::theme::Mode> {\n        None\n    }\n\n    fn set_background_color(&mut self, _color: Option<helix_view::theme::Color>) -> io::Result<()> {\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "helix-tui/src/buffer.rs",
    "content": "//! Contents of a terminal screen. A [Buffer] is made up of [Cell]s.\nuse crate::text::{Span, Spans};\nuse helix_core::unicode::width::UnicodeWidthStr;\nuse std::cmp::min;\nuse unicode_segmentation::UnicodeSegmentation;\n\nuse helix_view::graphics::{Color, Modifier, Rect, Style, UnderlineStyle};\n\n/// One cell of the terminal. Contains one stylized grapheme.\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct Cell {\n    pub symbol: String,\n    pub fg: Color,\n    pub bg: Color,\n    pub underline_color: Color,\n    pub underline_style: UnderlineStyle,\n    pub modifier: Modifier,\n}\n\nimpl Cell {\n    /// Set the cell's grapheme\n    pub fn set_symbol(&mut self, symbol: &str) -> &mut Cell {\n        self.symbol.clear();\n        self.symbol.push_str(symbol);\n        self\n    }\n\n    /// Set the cell's grapheme to a [char]\n    pub fn set_char(&mut self, ch: char) -> &mut Cell {\n        self.symbol.clear();\n        self.symbol.push(ch);\n        self\n    }\n\n    /// Set the foreground [Color]\n    pub fn set_fg(&mut self, color: Color) -> &mut Cell {\n        self.fg = color;\n        self\n    }\n\n    /// Set the background [Color]\n    pub fn set_bg(&mut self, color: Color) -> &mut Cell {\n        self.bg = color;\n        self\n    }\n\n    /// Set the [Style] of the cell\n    pub fn set_style(&mut self, style: Style) -> &mut Cell {\n        if let Some(c) = style.fg {\n            self.fg = c;\n        }\n        if let Some(c) = style.bg {\n            self.bg = c;\n        }\n        if let Some(c) = style.underline_color {\n            self.underline_color = c;\n        }\n        if let Some(style) = style.underline_style {\n            self.underline_style = style;\n        }\n\n        self.modifier.insert(style.add_modifier);\n        self.modifier.remove(style.sub_modifier);\n        self\n    }\n\n    /// Returns the current style of the cell\n    pub fn style(&self) -> Style {\n        Style::default()\n            .fg(self.fg)\n            .bg(self.bg)\n            .underline_color(self.underline_color)\n            .underline_style(self.underline_style)\n            .add_modifier(self.modifier)\n    }\n\n    /// Resets the cell to a default blank state\n    pub fn reset(&mut self) {\n        self.symbol.clear();\n        self.symbol.push(' ');\n        self.fg = Color::Reset;\n        self.bg = Color::Reset;\n        self.underline_color = Color::Reset;\n        self.underline_style = UnderlineStyle::Reset;\n        self.modifier = Modifier::empty();\n    }\n}\n\nimpl Default for Cell {\n    fn default() -> Cell {\n        Cell {\n            symbol: \" \".into(),\n            fg: Color::Reset,\n            bg: Color::Reset,\n            underline_color: Color::Reset,\n            underline_style: UnderlineStyle::Reset,\n            modifier: Modifier::empty(),\n        }\n    }\n}\n\n/// A buffer that maps to the desired content of the terminal after the draw call\n///\n/// No widget in the library interacts directly with the terminal. Instead each of them is required\n/// to draw their state to an intermediate buffer. It is basically a grid where each cell contains\n/// a grapheme, a foreground color and a background color. This grid will then be used to output\n/// the appropriate escape sequences and characters to draw the UI as the user has defined it.\n///\n/// # Examples:\n///\n/// ```\n/// use helix_tui::buffer::{Buffer, Cell};\n/// use helix_view::graphics::{Rect, Color, UnderlineStyle, Style, Modifier};\n///\n/// let mut buf = Buffer::empty(Rect{x: 0, y: 0, width: 10, height: 5});\n/// buf[(0, 2)].set_symbol(\"x\");\n/// assert_eq!(buf[(0, 2)].symbol, \"x\");\n/// buf.set_string(3, 0, \"string\", Style::default().fg(Color::Red).bg(Color::White));\n/// assert_eq!(buf[(5, 0)], Cell{\n///     symbol: String::from(\"r\"),\n///     fg: Color::Red,\n///     bg: Color::White,\n///     underline_color: Color::Reset,\n///     underline_style: UnderlineStyle::Reset,\n///     modifier: Modifier::empty(),\n/// });\n/// buf[(5, 0)].set_char('x');\n/// assert_eq!(buf[(5, 0)].symbol, \"x\");\n/// ```\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct Buffer {\n    /// The area represented by this buffer\n    pub area: Rect,\n    /// The content of the buffer. The length of this Vec should always be equal to area.width *\n    /// area.height\n    pub content: Vec<Cell>,\n}\n\nimpl Buffer {\n    /// Returns a Buffer with all cells set to the default one\n    #[must_use]\n    pub fn empty(area: Rect) -> Buffer {\n        Buffer::filled(area, &Cell::default())\n    }\n\n    /// Returns a Buffer with all cells initialized with the attributes of the given Cell\n    #[must_use]\n    pub fn filled(area: Rect, cell: &Cell) -> Buffer {\n        let size = area.area();\n        let content = vec![cell.clone(); size];\n        Buffer { area, content }\n    }\n\n    /// Returns a Buffer containing the given lines\n    #[must_use]\n    pub fn with_lines<S>(lines: Vec<S>) -> Buffer\n    where\n        S: AsRef<str>,\n    {\n        let height = lines.len() as u16;\n        let width = lines\n            .iter()\n            .map(|i| i.as_ref().width() as u16)\n            .max()\n            .unwrap_or_default();\n        let mut buffer = Buffer::empty(Rect {\n            x: 0,\n            y: 0,\n            width,\n            height,\n        });\n        for (y, line) in lines.iter().enumerate() {\n            buffer.set_string(0, y as u16, line, Style::default());\n        }\n        buffer\n    }\n\n    /// Returns the content of the buffer as a slice\n    pub fn content(&self) -> &[Cell] {\n        &self.content\n    }\n\n    /// Returns the area covered by this buffer\n    pub fn area(&self) -> &Rect {\n        &self.area\n    }\n\n    /// Returns a reference to Cell at the given coordinates\n    pub fn get(&self, x: u16, y: u16) -> Option<&Cell> {\n        self.index_of_opt(x, y).map(|i| &self.content[i])\n    }\n\n    /// Returns a mutable reference to Cell at the given coordinates\n    pub fn get_mut(&mut self, x: u16, y: u16) -> Option<&mut Cell> {\n        self.index_of_opt(x, y).map(|i| &mut self.content[i])\n    }\n\n    /// Tells whether the global (x, y) coordinates are inside the Buffer's area.\n    ///\n    /// Global coordinates are offset by the Buffer's area offset (`x`/`y`).\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use helix_tui::buffer::Buffer;\n    /// # use helix_view::graphics::Rect;\n    /// let rect = Rect::new(200, 100, 10, 10);\n    /// let buffer = Buffer::empty(rect);\n    /// // Global coordinates inside the Buffer's area\n    /// assert!(buffer.in_bounds(209, 100));\n    /// // Global coordinates outside the Buffer's area\n    /// assert!(!buffer.in_bounds(210, 100));\n    /// ```\n    ///\n    /// Global coordinates are offset by the Buffer's area offset (`x`/`y`).\n    pub fn in_bounds(&self, x: u16, y: u16) -> bool {\n        x >= self.area.left()\n            && x < self.area.right()\n            && y >= self.area.top()\n            && y < self.area.bottom()\n    }\n\n    /// Returns the index in the `Vec<Cell>` for the given global (x, y) coordinates.\n    ///\n    /// Global coordinates are offset by the Buffer's area offset (`x`/`y`).\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use helix_tui::buffer::Buffer;\n    /// # use helix_view::graphics::Rect;\n    /// let rect = Rect::new(200, 100, 10, 10);\n    /// let buffer = Buffer::empty(rect);\n    /// // Global coordinates to the top corner of this Buffer's area\n    /// assert_eq!(buffer.index_of(200, 100), 0);\n    /// ```\n    ///\n    /// # Panics\n    ///\n    /// Panics when given an coordinate that is outside of this Buffer's area.\n    pub fn index_of(&self, x: u16, y: u16) -> usize {\n        debug_assert!(\n            self.in_bounds(x, y),\n            \"Trying to access position outside the buffer: x={}, y={}, area={:?}\",\n            x,\n            y,\n            self.area\n        );\n        ((y - self.area.y) as usize) * (self.area.width as usize) + ((x - self.area.x) as usize)\n    }\n\n    /// Returns the index in the `Vec<Cell>` for the given global (x, y) coordinates,\n    /// or `None` if the coordinates are outside the buffer's area.\n    fn index_of_opt(&self, x: u16, y: u16) -> Option<usize> {\n        if self.in_bounds(x, y) {\n            Some(self.index_of(x, y))\n        } else {\n            None\n        }\n    }\n\n    /// Returns the (global) coordinates of a cell given its index\n    ///\n    /// Global coordinates are offset by the Buffer's area offset (`x`/`y`).\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use helix_tui::buffer::Buffer;\n    /// # use helix_view::graphics::Rect;\n    /// let rect = Rect::new(200, 100, 10, 10);\n    /// let buffer = Buffer::empty(rect);\n    /// assert_eq!(buffer.pos_of(0), (200, 100));\n    /// assert_eq!(buffer.pos_of(14), (204, 101));\n    /// ```\n    ///\n    /// # Panics\n    ///\n    /// Panics when given an index that is outside the Buffer's content.\n    pub fn pos_of(&self, i: usize) -> (u16, u16) {\n        debug_assert!(\n            i < self.content.len(),\n            \"Trying to get the coords of a cell outside the buffer: i={} len={}\",\n            i,\n            self.content.len()\n        );\n        (\n            (self.area.x as usize + (i % self.area.width as usize)) as u16,\n            (self.area.y as usize + (i / self.area.width as usize)) as u16,\n        )\n    }\n\n    /// Print a string, starting at the position (x, y)\n    pub fn set_string<S>(&mut self, x: u16, y: u16, string: S, style: Style)\n    where\n        S: AsRef<str>,\n    {\n        self.set_stringn(x, y, string, usize::MAX, style);\n    }\n\n    /// Print at most the first n characters of a string if enough space is available\n    /// until the end of the line\n    pub fn set_stringn<S>(\n        &mut self,\n        x: u16,\n        y: u16,\n        string: S,\n        width: usize,\n        style: Style,\n    ) -> (u16, u16)\n    where\n        S: AsRef<str>,\n    {\n        self.set_string_truncated_at_end(x, y, string.as_ref(), width, style)\n    }\n\n    /// Print at most the first `width` characters of a string if enough space is available\n    /// until the end of the line.\n    /// If `ellipsis` is true appends a `…` at the end of truncated lines.\n    /// If `truncate_start` is `true`, adds a `…` at the beginning of truncated lines.\n    #[allow(clippy::too_many_arguments)]\n    pub fn set_string_anchored(\n        &mut self,\n        x: u16,\n        y: u16,\n        truncate_start: bool,\n        truncate_end: bool,\n        string: &str,\n        width: usize,\n        style: impl Fn(usize) -> Style, // Map a grapheme's string offset to a style\n    ) -> (u16, u16) {\n        // prevent panic if out of range\n        if !self.in_bounds(x, y) || width == 0 {\n            return (x, y);\n        }\n\n        let mut index = self.index_of(x, y);\n        let mut rendered_width = 0;\n        let mut graphemes = string.grapheme_indices(true);\n\n        if truncate_start {\n            for _ in 0..graphemes.next().map(|(_, g)| g.width()).unwrap_or_default() {\n                self.content[index].set_symbol(\"…\");\n                index += 1;\n                rendered_width += 1;\n            }\n        }\n\n        for (byte_offset, s) in graphemes {\n            let grapheme_width = s.width();\n            if truncate_end && rendered_width + grapheme_width >= width {\n                break;\n            }\n            if grapheme_width == 0 {\n                continue;\n            }\n\n            self.content[index].set_symbol(s);\n            self.content[index].set_style(style(byte_offset));\n\n            // Reset following cells if multi-width (they would be hidden by the grapheme):\n            for i in index + 1..index + grapheme_width {\n                self.content[i].reset();\n            }\n\n            index += grapheme_width;\n            rendered_width += grapheme_width;\n        }\n\n        if truncate_end {\n            for _ in 0..width.saturating_sub(rendered_width) {\n                self.content[index].set_symbol(\"…\");\n                index += 1;\n            }\n        }\n\n        (x, y)\n    }\n\n    /// Print at most the first `width` characters of a string if enough space is available\n    /// until the end of the line. If `ellipsis` is true appends a `…` at the end of\n    /// truncated lines. If `truncate_start` is `true`, truncate the beginning of the string\n    /// instead of the end.\n    #[allow(clippy::too_many_arguments)]\n    pub fn set_string_truncated(\n        &mut self,\n        x: u16,\n        y: u16,\n        string: &str,\n        width: usize,\n        style: impl Fn(usize) -> Style, // Map a grapheme's string offset to a style\n        ellipsis: bool,\n        truncate_start: bool,\n    ) -> (u16, u16) {\n        // prevent panic if out of range\n        if !self.in_bounds(x, y) || width == 0 {\n            return (x, y);\n        }\n\n        let mut index = self.index_of(x, y);\n        let mut x_offset = x as usize;\n        let width = if ellipsis { width - 1 } else { width };\n        let graphemes = string.grapheme_indices(true);\n        let max_offset = min(self.area.right() as usize, width.saturating_add(x as usize));\n        if !truncate_start {\n            for (byte_offset, s) in graphemes {\n                let width = s.width();\n                if width == 0 {\n                    continue;\n                }\n                // `x_offset + width > max_offset` could be integer overflow on 32-bit machines if we\n                // change dimensions to usize or u32 and someone resizes the terminal to 1x2^32.\n                if width > max_offset.saturating_sub(x_offset) {\n                    break;\n                }\n\n                self.content[index].set_symbol(s);\n                self.content[index].set_style(style(byte_offset));\n                // Reset following cells if multi-width (they would be hidden by the grapheme),\n                for i in index + 1..index + width {\n                    self.content[i].reset();\n                }\n                index += width;\n                x_offset += width;\n            }\n            if ellipsis && x_offset - (x as usize) < string.width() {\n                self.content[index].set_symbol(\"…\");\n            }\n        } else {\n            let mut start_index = self.index_of(x, y);\n            let mut index = self.index_of(max_offset as u16, y);\n\n            let content_width = string.width();\n            let truncated = content_width > width;\n            if ellipsis && truncated {\n                self.content[start_index].set_symbol(\"…\");\n                start_index += 1;\n            }\n            if !truncated {\n                index -= width - content_width;\n            }\n            for (byte_offset, s) in graphemes.rev() {\n                let width = s.width();\n                if width == 0 {\n                    continue;\n                }\n                let start = index - width;\n                if start < start_index {\n                    break;\n                }\n                self.content[start].set_symbol(s);\n                self.content[start].set_style(style(byte_offset));\n                for i in start + 1..index {\n                    self.content[i].reset();\n                }\n                index -= width;\n                x_offset += width;\n            }\n        }\n        (x_offset as u16, y)\n    }\n\n    /// Print at most the first `width` characters of a string if enough space is available\n    /// until the end of the line.\n    pub fn set_string_truncated_at_end(\n        &mut self,\n        x: u16,\n        y: u16,\n        string: &str,\n        width: usize,\n        style: Style,\n    ) -> (u16, u16) {\n        // prevent panic if out of range\n        if !self.in_bounds(x, y) {\n            return (x, y);\n        }\n\n        let mut index = self.index_of(x, y);\n        let mut x_offset = x as usize;\n        let max_x_offset = min(self.area.right() as usize, width.saturating_add(x as usize));\n\n        for s in string.graphemes(true) {\n            let width = s.width();\n            if width == 0 {\n                continue;\n            }\n            // `x_offset + width > max_offset` could be integer overflow on 32-bit machines if we\n            // change dimensions to usize or u32 and someone resizes the terminal to 1x2^32.\n            if width > max_x_offset.saturating_sub(x_offset) {\n                break;\n            }\n\n            self.content[index].set_symbol(s);\n            self.content[index].set_style(style);\n            // Reset following cells if multi-width (they would be hidden by the grapheme),\n            for i in index + 1..index + width {\n                self.content[i].reset();\n            }\n            index += width;\n            x_offset += width;\n        }\n\n        (x_offset as u16, y)\n    }\n\n    /// Print at most the first `width` characters of a [Spans]  if enough space is available\n    /// until the end of the line. Appends a `…` at the end of truncated lines.\n    pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {\n        // prevent panic if out of range\n        if !self.in_bounds(x, y) || width == 0 {\n            return (x, y);\n        }\n\n        let mut x_offset = x as usize;\n        let max_offset = min(self.area.right(), width.saturating_add(x));\n        let mut start_index = self.index_of(x, y);\n        let mut index = self.index_of(max_offset, y);\n\n        let content_width = spans.width();\n        let truncated = content_width > width as usize;\n        if truncated {\n            self.content[start_index].set_symbol(\"…\");\n            start_index += 1;\n        } else {\n            index -= width as usize - content_width;\n        }\n        for span in spans.0.iter().rev() {\n            for s in span.content.graphemes(true).rev() {\n                let width = s.width();\n                if width == 0 {\n                    continue;\n                }\n                let start = index - width;\n                if start < start_index {\n                    break;\n                }\n                self.content[start].set_symbol(s);\n                self.content[start].set_style(span.style);\n                for i in start + 1..index {\n                    self.content[i].reset();\n                }\n                index -= width;\n                x_offset += width;\n            }\n        }\n        (x_offset as u16, y)\n    }\n\n    /// Print at most the first `width` characters of a [Spans] if enough space is available\n    /// until the end of the line\n    pub fn set_spans(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {\n        let mut remaining_width = width;\n        let mut x = x;\n        for span in &spans.0 {\n            if remaining_width == 0 {\n                break;\n            }\n            let pos = self.set_stringn(\n                x,\n                y,\n                span.content.as_ref(),\n                remaining_width as usize,\n                span.style,\n            );\n            let w = pos.0.saturating_sub(x);\n            x = pos.0;\n            remaining_width = remaining_width.saturating_sub(w);\n        }\n        (x, y)\n    }\n\n    /// Print at most the first `width` characters of a [Span] if enough space is available\n    /// until the end of the line\n    pub fn set_span(&mut self, x: u16, y: u16, span: &Span, width: u16) -> (u16, u16) {\n        self.set_stringn(x, y, span.content.as_ref(), width as usize, span.style)\n    }\n\n    #[deprecated(\n        since = \"0.10.0\",\n        note = \"You should use styling capabilities of `Buffer::set_style`\"\n    )]\n    pub fn set_background(&mut self, area: Rect, color: Color) {\n        for y in area.top()..area.bottom() {\n            for x in area.left()..area.right() {\n                self[(x, y)].set_bg(color);\n            }\n        }\n    }\n\n    /// Set all cells in the [area](Rect) to the given [Style]\n    pub fn set_style(&mut self, area: Rect, style: Style) {\n        for y in area.top()..area.bottom() {\n            for x in area.left()..area.right() {\n                self[(x, y)].set_style(style);\n            }\n        }\n    }\n\n    /// Resize the buffer so that the mapped area matches the given area and that the buffer\n    /// length is equal to area.width * area.height\n    pub fn resize(&mut self, area: Rect) {\n        let length = area.area();\n        if self.content.len() > length {\n            self.content.truncate(length);\n        } else {\n            self.content.resize(length, Default::default());\n        }\n        self.area = area;\n    }\n\n    /// Reset all cells in the buffer\n    pub fn reset(&mut self) {\n        for c in &mut self.content {\n            c.reset();\n        }\n    }\n\n    /// Clear an area in the buffer\n    pub fn clear(&mut self, area: Rect) {\n        for x in area.left()..area.right() {\n            for y in area.top()..area.bottom() {\n                self[(x, y)].reset();\n            }\n        }\n    }\n\n    /// Clear an area in the buffer with a default style.\n    pub fn clear_with(&mut self, area: Rect, style: Style) {\n        for x in area.left()..area.right() {\n            for y in area.top()..area.bottom() {\n                let cell = &mut self[(x, y)];\n                cell.reset();\n                cell.set_style(style);\n            }\n        }\n    }\n\n    /// Merge an other buffer into this one\n    pub fn merge(&mut self, other: &Buffer) {\n        let area = self.area.union(other.area);\n        let cell: Cell = Default::default();\n        self.content.resize(area.area(), cell.clone());\n\n        // Move original content to the appropriate space\n        let size = self.area.area();\n        for i in (0..size).rev() {\n            let (x, y) = self.pos_of(i);\n            // New index in content\n            let k = ((y - area.y) * area.width + x - area.x) as usize;\n            if i != k {\n                self.content[k] = self.content[i].clone();\n                self.content[i] = cell.clone();\n            }\n        }\n\n        // Push content of the other buffer into this one (may erase previous\n        // data)\n        let size = other.area.area();\n        for i in 0..size {\n            let (x, y) = other.pos_of(i);\n            // New index in content\n            let k = ((y - area.y) * area.width + x - area.x) as usize;\n            self.content[k] = other.content[i].clone();\n        }\n        self.area = area;\n    }\n\n    /// Builds a minimal sequence of coordinates and Cells necessary to update the UI from\n    /// self to other.\n    ///\n    /// We're assuming that buffers are well-formed, that is no double-width cell is followed by\n    /// a non-blank cell.\n    ///\n    /// # Multi-width characters handling:\n    ///\n    /// ```text\n    /// (Index:) `01`\n    /// Prev:    `コ`\n    /// Next:    `aa`\n    /// Updates: `0: a, 1: a'\n    /// ```\n    ///\n    /// ```text\n    /// (Index:) `01`\n    /// Prev:    `a `\n    /// Next:    `コ`\n    /// Updates: `0: コ` (double width symbol at index 0 - skip index 1)\n    /// ```\n    ///\n    /// ```text\n    /// (Index:) `012`\n    /// Prev:    `aaa`\n    /// Next:    `aコ`\n    /// Updates: `0: a, 1: コ` (double width symbol at index 1 - skip index 2)\n    /// ```\n    pub fn diff<'a>(&self, other: &'a Buffer) -> Vec<(u16, u16, &'a Cell)> {\n        let previous_buffer = &self.content;\n        let next_buffer = &other.content;\n        let width = self.area.width;\n\n        let mut updates: Vec<(u16, u16, &Cell)> = vec![];\n        // Cells invalidated by drawing/replacing preceding multi-width characters:\n        let mut invalidated: usize = 0;\n        // Cells from the current buffer to skip due to preceding multi-width characters taking their\n        // place (the skipped cells should be blank anyway):\n        let mut to_skip: usize = 0;\n        for (i, (current, previous)) in next_buffer.iter().zip(previous_buffer.iter()).enumerate() {\n            if (current != previous || invalidated > 0) && to_skip == 0 {\n                let x = (i % width as usize) as u16;\n                let y = (i / width as usize) as u16;\n                updates.push((x, y, &next_buffer[i]));\n            }\n\n            let current_width = current.symbol.width();\n            to_skip = current_width.saturating_sub(1);\n\n            let affected_width = std::cmp::max(current_width, previous.symbol.width());\n            invalidated = std::cmp::max(affected_width, invalidated).saturating_sub(1);\n        }\n        updates\n    }\n}\n\nimpl std::ops::Index<(u16, u16)> for Buffer {\n    type Output = Cell;\n\n    fn index(&self, (x, y): (u16, u16)) -> &Self::Output {\n        let i = self.index_of(x, y);\n        &self.content[i]\n    }\n}\n\nimpl std::ops::IndexMut<(u16, u16)> for Buffer {\n    fn index_mut(&mut self, (x, y): (u16, u16)) -> &mut Self::Output {\n        let i = self.index_of(x, y);\n        &mut self.content[i]\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    fn cell(s: &str) -> Cell {\n        let mut cell = Cell::default();\n        cell.set_symbol(s);\n        cell\n    }\n\n    #[test]\n    fn it_translates_to_and_from_coordinates() {\n        let rect = Rect::new(200, 100, 50, 80);\n        let buf = Buffer::empty(rect);\n\n        // First cell is at the upper left corner.\n        assert_eq!(buf.pos_of(0), (200, 100));\n        assert_eq!(buf.index_of(200, 100), 0);\n\n        // Last cell is in the lower right.\n        assert_eq!(buf.pos_of(buf.content.len() - 1), (249, 179));\n        assert_eq!(buf.index_of(249, 179), buf.content.len() - 1);\n    }\n\n    #[test]\n    #[should_panic(expected = \"outside the buffer\")]\n    #[cfg(debug_assertions)]\n    fn pos_of_panics_on_out_of_bounds() {\n        let rect = Rect::new(0, 0, 10, 10);\n        let buf = Buffer::empty(rect);\n\n        // There are a total of 100 cells; zero-indexed means that 100 would be the 101st cell.\n        buf.pos_of(100);\n    }\n\n    #[test]\n    #[should_panic(expected = \"outside the buffer\")]\n    #[cfg(debug_assertions)]\n    fn index_of_panics_on_out_of_bounds() {\n        let rect = Rect::new(0, 0, 10, 10);\n        let buf = Buffer::empty(rect);\n\n        // width is 10; zero-indexed means that 10 would be the 11th cell.\n        buf.index_of(10, 0);\n    }\n\n    #[test]\n    fn buffer_set_string() {\n        let area = Rect::new(0, 0, 5, 1);\n        let mut buffer = Buffer::empty(area);\n\n        // Zero-width\n        buffer.set_stringn(0, 0, \"aaa\", 0, Style::default());\n        assert_eq!(buffer, Buffer::with_lines(vec![\"     \"]));\n\n        buffer.set_string(0, 0, \"aaa\", Style::default());\n        assert_eq!(buffer, Buffer::with_lines(vec![\"aaa  \"]));\n\n        // Width limit:\n        buffer.set_stringn(0, 0, \"bbbbbbbbbbbbbb\", 4, Style::default());\n        assert_eq!(buffer, Buffer::with_lines(vec![\"bbbb \"]));\n\n        buffer.set_string(0, 0, \"12345\", Style::default());\n        assert_eq!(buffer, Buffer::with_lines(vec![\"12345\"]));\n\n        // Width truncation:\n        buffer.set_string(0, 0, \"123456\", Style::default());\n        assert_eq!(buffer, Buffer::with_lines(vec![\"12345\"]));\n    }\n\n    #[test]\n    fn buffer_set_string_zero_width() {\n        let area = Rect::new(0, 0, 1, 1);\n        let mut buffer = Buffer::empty(area);\n\n        // U+200B is the zero-width space codepoint\n        assert_eq!(\"\\u{200B}\".width(), 0);\n\n        // Leading grapheme with zero width\n        let s = \"\\u{200B}a\";\n        buffer.set_stringn(0, 0, s, 1, Style::default());\n        assert_eq!(buffer, Buffer::with_lines(vec![\"a\"]));\n\n        // Trailing grapheme with zero width\n        let s = \"a\\u{200B}\";\n        buffer.set_stringn(0, 0, s, 1, Style::default());\n        assert_eq!(buffer, Buffer::with_lines(vec![\"a\"]));\n    }\n\n    #[test]\n    fn buffer_set_string_double_width() {\n        let area = Rect::new(0, 0, 5, 1);\n        let mut buffer = Buffer::empty(area);\n        buffer.set_string(0, 0, \"コン\", Style::default());\n        assert_eq!(buffer, Buffer::with_lines(vec![\"コン \"]));\n\n        // Only 1 space left.\n        buffer.set_string(0, 0, \"コンピ\", Style::default());\n        assert_eq!(buffer, Buffer::with_lines(vec![\"コン \"]));\n    }\n\n    #[test]\n    fn buffer_with_lines() {\n        let buffer =\n            Buffer::with_lines(vec![\"┌────────┐\", \"│コンピュ│\", \"│ーa 上で│\", \"└────────┘\"]);\n        assert_eq!(buffer.area.x, 0);\n        assert_eq!(buffer.area.y, 0);\n        assert_eq!(buffer.area.width, 10);\n        assert_eq!(buffer.area.height, 4);\n    }\n\n    #[test]\n    fn buffer_diffing_empty_empty() {\n        let area = Rect::new(0, 0, 40, 40);\n        let prev = Buffer::empty(area);\n        let next = Buffer::empty(area);\n        let diff = prev.diff(&next);\n        assert_eq!(diff, vec![]);\n    }\n\n    #[test]\n    fn buffer_diffing_empty_filled() {\n        let area = Rect::new(0, 0, 40, 40);\n        let prev = Buffer::empty(area);\n        let next = Buffer::filled(area, Cell::default().set_symbol(\"a\"));\n        let diff = prev.diff(&next);\n        assert_eq!(diff.len(), 40 * 40);\n    }\n\n    #[test]\n    fn buffer_diffing_filled_filled() {\n        let area = Rect::new(0, 0, 40, 40);\n        let prev = Buffer::filled(area, Cell::default().set_symbol(\"a\"));\n        let next = Buffer::filled(area, Cell::default().set_symbol(\"a\"));\n        let diff = prev.diff(&next);\n        assert_eq!(diff, vec![]);\n    }\n\n    #[test]\n    fn buffer_diffing_single_width() {\n        let prev = Buffer::with_lines(vec![\n            \"          \",\n            \"┌Title─┐  \",\n            \"│      │  \",\n            \"│      │  \",\n            \"└──────┘  \",\n        ]);\n        let next = Buffer::with_lines(vec![\n            \"          \",\n            \"┌TITLE─┐  \",\n            \"│      │  \",\n            \"│      │  \",\n            \"└──────┘  \",\n        ]);\n        let diff = prev.diff(&next);\n        assert_eq!(\n            diff,\n            vec![\n                (2, 1, &cell(\"I\")),\n                (3, 1, &cell(\"T\")),\n                (4, 1, &cell(\"L\")),\n                (5, 1, &cell(\"E\")),\n            ]\n        );\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn buffer_diffing_multi_width() {\n        let prev = Buffer::with_lines(vec![\n            \"┌Title─┐  \",\n            \"└──────┘  \",\n        ]);\n        let next = Buffer::with_lines(vec![\n            \"┌称号──┐  \",\n            \"└──────┘  \",\n        ]);\n        let diff = prev.diff(&next);\n        assert_eq!(\n            diff,\n            vec![\n                (1, 0, &cell(\"称\")),\n                // Skipped \"i\"\n                (3, 0, &cell(\"号\")),\n                // Skipped \"l\"\n                (5, 0, &cell(\"─\")),\n            ]\n        );\n    }\n\n    #[test]\n    fn buffer_diffing_multi_width_offset() {\n        let prev = Buffer::with_lines(vec![\"┌称号──┐\"]);\n        let next = Buffer::with_lines(vec![\"┌─称号─┐\"]);\n\n        let diff = prev.diff(&next);\n        assert_eq!(\n            diff,\n            vec![(1, 0, &cell(\"─\")), (2, 0, &cell(\"称\")), (4, 0, &cell(\"号\")),]\n        );\n    }\n\n    #[test]\n    fn buffer_merge() {\n        let mut one = Buffer::filled(\n            Rect {\n                x: 0,\n                y: 0,\n                width: 2,\n                height: 2,\n            },\n            Cell::default().set_symbol(\"1\"),\n        );\n        let two = Buffer::filled(\n            Rect {\n                x: 0,\n                y: 2,\n                width: 2,\n                height: 2,\n            },\n            Cell::default().set_symbol(\"2\"),\n        );\n        one.merge(&two);\n        assert_eq!(one, Buffer::with_lines(vec![\"11\", \"11\", \"22\", \"22\"]));\n    }\n\n    #[test]\n    fn buffer_merge2() {\n        let mut one = Buffer::filled(\n            Rect {\n                x: 2,\n                y: 2,\n                width: 2,\n                height: 2,\n            },\n            Cell::default().set_symbol(\"1\"),\n        );\n        let two = Buffer::filled(\n            Rect {\n                x: 0,\n                y: 0,\n                width: 2,\n                height: 2,\n            },\n            Cell::default().set_symbol(\"2\"),\n        );\n        one.merge(&two);\n        assert_eq!(\n            one,\n            Buffer::with_lines(vec![\"22  \", \"22  \", \"  11\", \"  11\"])\n        );\n    }\n\n    #[test]\n    fn buffer_merge3() {\n        let mut one = Buffer::filled(\n            Rect {\n                x: 3,\n                y: 3,\n                width: 2,\n                height: 2,\n            },\n            Cell::default().set_symbol(\"1\"),\n        );\n        let two = Buffer::filled(\n            Rect {\n                x: 1,\n                y: 1,\n                width: 3,\n                height: 4,\n            },\n            Cell::default().set_symbol(\"2\"),\n        );\n        one.merge(&two);\n        let mut merged = Buffer::with_lines(vec![\"222 \", \"222 \", \"2221\", \"2221\"]);\n        merged.area = Rect {\n            x: 1,\n            y: 1,\n            width: 4,\n            height: 4,\n        };\n        assert_eq!(one, merged);\n    }\n}\n"
  },
  {
    "path": "helix-tui/src/layout.rs",
    "content": "//! Layout engine for terminal\n\nuse std::cell::RefCell;\nuse std::collections::HashMap;\n\nuse cassowary::strength::{REQUIRED, WEAK};\nuse cassowary::WeightedRelation::*;\nuse cassowary::{Constraint as CassowaryConstraint, Expression, Solver, Variable};\n\nuse helix_view::graphics::{Margin, Rect};\n\n/// Enum of all corners\n#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]\npub enum Corner {\n    TopLeft,\n    TopRight,\n    BottomRight,\n    BottomLeft,\n}\n\n/// Direction a [Rect] should be split\n#[derive(Debug, Hash, Clone, PartialEq, Eq)]\npub enum Direction {\n    Horizontal,\n    Vertical,\n}\n\n/// Describes requirements of a [Rect] to be split\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]\npub enum Constraint {\n    // TODO: enforce range 0 - 100\n    Percentage(u16),\n    Ratio(u32, u32),\n    Length(u16),\n    Max(u16),\n    Min(u16),\n}\n\nimpl Constraint {\n    pub fn apply(&self, length: u16) -> u16 {\n        match *self {\n            Constraint::Percentage(p) => length * p / 100,\n            Constraint::Ratio(num, den) => {\n                let r = num * u32::from(length) / den;\n                r as u16\n            }\n            Constraint::Length(l) => length.min(l),\n            Constraint::Max(m) => length.min(m),\n            Constraint::Min(m) => length.max(m),\n        }\n    }\n}\n\n/// How content should be aligned\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum Alignment {\n    Left,\n    Center,\n    Right,\n}\n\n/// Description of a how a [Rect] should be split\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub struct Layout {\n    direction: Direction,\n    margin: Margin,\n    constraints: Vec<Constraint>,\n}\n\nthread_local! {\n    static LAYOUT_CACHE: RefCell<HashMap<(Rect, Layout), Vec<Rect>>> = RefCell::new(HashMap::new());\n}\n\nimpl Default for Layout {\n    fn default() -> Layout {\n        Layout {\n            direction: Direction::Vertical,\n            margin: Margin::none(),\n            constraints: Vec::new(),\n        }\n    }\n}\n\nimpl Layout {\n    /// Returns a layout with the given [Constraint]s.\n    pub fn constraints<C>(mut self, constraints: C) -> Layout\n    where\n        C: Into<Vec<Constraint>>,\n    {\n        self.constraints = constraints.into();\n        self\n    }\n\n    /// Returns a layout wit the given margins on all sides.\n    pub const fn margin(mut self, margin: u16) -> Layout {\n        self.margin = Margin::all(margin);\n        self\n    }\n\n    /// Returns a layout with the given horizontal margins.\n    pub const fn horizontal_margin(mut self, horizontal: u16) -> Layout {\n        self.margin.horizontal = horizontal;\n        self\n    }\n\n    /// Returns a layout with the given vertical margins.\n    pub const fn vertical_margin(mut self, vertical: u16) -> Layout {\n        self.margin.vertical = vertical;\n        self\n    }\n\n    /// Returns a layout with the given [Direction].\n    pub const fn direction(mut self, direction: Direction) -> Layout {\n        self.direction = direction;\n        self\n    }\n\n    /// Wrapper function around the cassowary-rs solver to be able to split a given\n    /// area into smaller ones based on the preferred widths or heights and the direction.\n    ///\n    /// # Examples\n    /// ```\n    /// # use helix_tui::layout::{Constraint, Direction, Layout};\n    /// # use helix_view::graphics::Rect;\n    /// let chunks = Layout::default()\n    ///     .direction(Direction::Vertical)\n    ///     .constraints([Constraint::Length(5), Constraint::Min(0)].as_ref())\n    ///     .split(Rect {\n    ///         x: 2,\n    ///         y: 2,\n    ///         width: 10,\n    ///         height: 10,\n    ///     });\n    /// assert_eq!(\n    ///     chunks,\n    ///     vec![\n    ///         Rect {\n    ///             x: 2,\n    ///             y: 2,\n    ///             width: 10,\n    ///             height: 5\n    ///         },\n    ///         Rect {\n    ///             x: 2,\n    ///             y: 7,\n    ///             width: 10,\n    ///             height: 5\n    ///         }\n    ///     ]\n    /// );\n    ///\n    /// let chunks = Layout::default()\n    ///     .direction(Direction::Horizontal)\n    ///     .constraints([Constraint::Ratio(1, 3), Constraint::Ratio(2, 3)].as_ref())\n    ///     .split(Rect {\n    ///         x: 0,\n    ///         y: 0,\n    ///         width: 9,\n    ///         height: 2,\n    ///     });\n    /// assert_eq!(\n    ///     chunks,\n    ///     vec![\n    ///         Rect {\n    ///             x: 0,\n    ///             y: 0,\n    ///             width: 3,\n    ///             height: 2\n    ///         },\n    ///         Rect {\n    ///             x: 3,\n    ///             y: 0,\n    ///             width: 6,\n    ///             height: 2\n    ///         }\n    ///     ]\n    /// );\n    /// ```\n    pub fn split(&self, area: Rect) -> Vec<Rect> {\n        // TODO: Maybe use a fixed size cache ?\n        LAYOUT_CACHE.with(|c| {\n            c.borrow_mut()\n                .entry((area, self.clone()))\n                .or_insert_with(|| split(area, self))\n                .clone()\n        })\n    }\n}\n\nfn split(area: Rect, layout: &Layout) -> Vec<Rect> {\n    let mut solver = Solver::new();\n    let mut vars: HashMap<Variable, (usize, usize)> = HashMap::new();\n    let elements = layout\n        .constraints\n        .iter()\n        .map(|_| Element::new())\n        .collect::<Vec<Element>>();\n    let mut results = layout\n        .constraints\n        .iter()\n        .map(|_| Rect::default())\n        .collect::<Vec<Rect>>();\n\n    let dest_area = area.inner(layout.margin);\n    for (i, e) in elements.iter().enumerate() {\n        vars.insert(e.x, (i, 0));\n        vars.insert(e.y, (i, 1));\n        vars.insert(e.width, (i, 2));\n        vars.insert(e.height, (i, 3));\n    }\n    let mut ccs: Vec<CassowaryConstraint> =\n        Vec::with_capacity(elements.len() * 4 + layout.constraints.len() * 6);\n    for elt in &elements {\n        ccs.push(elt.width | GE(REQUIRED) | 0f64);\n        ccs.push(elt.height | GE(REQUIRED) | 0f64);\n        ccs.push(elt.left() | GE(REQUIRED) | f64::from(dest_area.left()));\n        ccs.push(elt.top() | GE(REQUIRED) | f64::from(dest_area.top()));\n        ccs.push(elt.right() | LE(REQUIRED) | f64::from(dest_area.right()));\n        ccs.push(elt.bottom() | LE(REQUIRED) | f64::from(dest_area.bottom()));\n    }\n    if let Some(first) = elements.first() {\n        ccs.push(match layout.direction {\n            Direction::Horizontal => first.left() | EQ(REQUIRED) | f64::from(dest_area.left()),\n            Direction::Vertical => first.top() | EQ(REQUIRED) | f64::from(dest_area.top()),\n        });\n    }\n    if let Some(last) = elements.last() {\n        ccs.push(match layout.direction {\n            Direction::Horizontal => last.right() | EQ(REQUIRED) | f64::from(dest_area.right()),\n            Direction::Vertical => last.bottom() | EQ(REQUIRED) | f64::from(dest_area.bottom()),\n        });\n    }\n    match layout.direction {\n        Direction::Horizontal => {\n            for pair in elements.windows(2) {\n                ccs.push((pair[0].x + pair[0].width) | EQ(REQUIRED) | pair[1].x);\n            }\n            for (i, size) in layout.constraints.iter().enumerate() {\n                ccs.push(elements[i].y | EQ(REQUIRED) | f64::from(dest_area.y));\n                ccs.push(elements[i].height | EQ(REQUIRED) | f64::from(dest_area.height));\n                ccs.push(match *size {\n                    Constraint::Length(v) => elements[i].width | EQ(WEAK) | f64::from(v),\n                    Constraint::Percentage(v) => {\n                        elements[i].width | EQ(WEAK) | (f64::from(v * dest_area.width) / 100.0)\n                    }\n                    Constraint::Ratio(n, d) => {\n                        elements[i].width\n                            | EQ(WEAK)\n                            | (f64::from(dest_area.width) * f64::from(n) / f64::from(d))\n                    }\n                    Constraint::Min(v) => elements[i].width | GE(WEAK) | f64::from(v),\n                    Constraint::Max(v) => elements[i].width | LE(WEAK) | f64::from(v),\n                });\n            }\n        }\n        Direction::Vertical => {\n            for pair in elements.windows(2) {\n                ccs.push((pair[0].y + pair[0].height) | EQ(REQUIRED) | pair[1].y);\n            }\n            for (i, size) in layout.constraints.iter().enumerate() {\n                ccs.push(elements[i].x | EQ(REQUIRED) | f64::from(dest_area.x));\n                ccs.push(elements[i].width | EQ(REQUIRED) | f64::from(dest_area.width));\n                ccs.push(match *size {\n                    Constraint::Length(v) => elements[i].height | EQ(WEAK) | f64::from(v),\n                    Constraint::Percentage(v) => {\n                        elements[i].height | EQ(WEAK) | (f64::from(v * dest_area.height) / 100.0)\n                    }\n                    Constraint::Ratio(n, d) => {\n                        elements[i].height\n                            | EQ(WEAK)\n                            | (f64::from(dest_area.height) * f64::from(n) / f64::from(d))\n                    }\n                    Constraint::Min(v) => elements[i].height | GE(WEAK) | f64::from(v),\n                    Constraint::Max(v) => elements[i].height | LE(WEAK) | f64::from(v),\n                });\n            }\n        }\n    }\n    solver.add_constraints(&ccs).unwrap();\n    for &(var, value) in solver.fetch_changes() {\n        let (index, attr) = vars[&var];\n        let value = if value.is_sign_negative() {\n            0\n        } else {\n            value as u16\n        };\n        match attr {\n            0 => {\n                results[index].x = value;\n            }\n            1 => {\n                results[index].y = value;\n            }\n            2 => {\n                results[index].width = value;\n            }\n            3 => {\n                results[index].height = value;\n            }\n            _ => {}\n        }\n    }\n\n    // Fix imprecision by extending the last item a bit if necessary\n    if let Some(last) = results.last_mut() {\n        match layout.direction {\n            Direction::Vertical => {\n                last.height = dest_area.bottom() - last.y;\n            }\n            Direction::Horizontal => {\n                last.width = dest_area.right() - last.x;\n            }\n        }\n    }\n    results\n}\n\n/// A container used by the solver inside split\nstruct Element {\n    x: Variable,\n    y: Variable,\n    width: Variable,\n    height: Variable,\n}\n\nimpl Element {\n    fn new() -> Element {\n        Element {\n            x: Variable::new(),\n            y: Variable::new(),\n            width: Variable::new(),\n            height: Variable::new(),\n        }\n    }\n\n    fn left(&self) -> Variable {\n        self.x\n    }\n\n    fn top(&self) -> Variable {\n        self.y\n    }\n\n    fn right(&self) -> Expression {\n        self.x + self.width\n    }\n\n    fn bottom(&self) -> Expression {\n        self.y + self.height\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_vertical_split_by_height() {\n        let target = Rect {\n            x: 2,\n            y: 2,\n            width: 10,\n            height: 10,\n        };\n\n        let chunks = Layout::default()\n            .direction(Direction::Vertical)\n            .constraints(\n                [\n                    Constraint::Percentage(10),\n                    Constraint::Max(5),\n                    Constraint::Min(1),\n                ]\n                .as_ref(),\n            )\n            .split(target);\n\n        assert_eq!(target.height, chunks.iter().map(|r| r.height).sum::<u16>());\n        chunks.windows(2).for_each(|w| assert!(w[0].y <= w[1].y));\n    }\n}\n"
  },
  {
    "path": "helix-tui/src/lib.rs",
    "content": "pub mod backend;\npub mod buffer;\npub mod layout;\npub mod symbols;\npub mod terminal;\npub mod text;\npub mod widgets;\n\npub use self::terminal::{Terminal, TerminalOptions, Viewport};\n"
  },
  {
    "path": "helix-tui/src/symbols.rs",
    "content": "//! Common TUI symbols including blocks, bars, braille, lines\n\npub mod block {\n    pub const FULL: &str = \"█\";\n    pub const SEVEN_EIGHTHS: &str = \"▉\";\n    pub const THREE_QUARTERS: &str = \"▊\";\n    pub const FIVE_EIGHTHS: &str = \"▋\";\n    pub const HALF: &str = \"▌\";\n    pub const THREE_EIGHTHS: &str = \"▍\";\n    pub const ONE_QUARTER: &str = \"▎\";\n    pub const ONE_EIGHTH: &str = \"▏\";\n\n    #[derive(Debug, Clone)]\n    pub struct Set {\n        pub full: &'static str,\n        pub seven_eighths: &'static str,\n        pub three_quarters: &'static str,\n        pub five_eighths: &'static str,\n        pub half: &'static str,\n        pub three_eighths: &'static str,\n        pub one_quarter: &'static str,\n        pub one_eighth: &'static str,\n        pub empty: &'static str,\n    }\n\n    pub const THREE_LEVELS: Set = Set {\n        full: FULL,\n        seven_eighths: FULL,\n        three_quarters: HALF,\n        five_eighths: HALF,\n        half: HALF,\n        three_eighths: HALF,\n        one_quarter: HALF,\n        one_eighth: \" \",\n        empty: \" \",\n    };\n\n    pub const NINE_LEVELS: Set = Set {\n        full: FULL,\n        seven_eighths: SEVEN_EIGHTHS,\n        three_quarters: THREE_QUARTERS,\n        five_eighths: FIVE_EIGHTHS,\n        half: HALF,\n        three_eighths: THREE_EIGHTHS,\n        one_quarter: ONE_QUARTER,\n        one_eighth: ONE_EIGHTH,\n        empty: \" \",\n    };\n}\n\npub mod bar {\n    pub const FULL: &str = \"█\";\n    pub const SEVEN_EIGHTHS: &str = \"▇\";\n    pub const THREE_QUARTERS: &str = \"▆\";\n    pub const FIVE_EIGHTHS: &str = \"▅\";\n    pub const HALF: &str = \"▄\";\n    pub const THREE_EIGHTHS: &str = \"▃\";\n    pub const ONE_QUARTER: &str = \"▂\";\n    pub const ONE_EIGHTH: &str = \"▁\";\n\n    #[derive(Debug, Clone)]\n    pub struct Set {\n        pub full: &'static str,\n        pub seven_eighths: &'static str,\n        pub three_quarters: &'static str,\n        pub five_eighths: &'static str,\n        pub half: &'static str,\n        pub three_eighths: &'static str,\n        pub one_quarter: &'static str,\n        pub one_eighth: &'static str,\n        pub empty: &'static str,\n    }\n\n    pub const THREE_LEVELS: Set = Set {\n        full: FULL,\n        seven_eighths: FULL,\n        three_quarters: HALF,\n        five_eighths: HALF,\n        half: HALF,\n        three_eighths: HALF,\n        one_quarter: HALF,\n        one_eighth: \" \",\n        empty: \" \",\n    };\n\n    pub const NINE_LEVELS: Set = Set {\n        full: FULL,\n        seven_eighths: SEVEN_EIGHTHS,\n        three_quarters: THREE_QUARTERS,\n        five_eighths: FIVE_EIGHTHS,\n        half: HALF,\n        three_eighths: THREE_EIGHTHS,\n        one_quarter: ONE_QUARTER,\n        one_eighth: ONE_EIGHTH,\n        empty: \" \",\n    };\n}\n\npub mod line {\n    pub const VERTICAL: &str = \"│\";\n    pub const DOUBLE_VERTICAL: &str = \"║\";\n    pub const THICK_VERTICAL: &str = \"┃\";\n\n    pub const HORIZONTAL: &str = \"─\";\n    pub const DOUBLE_HORIZONTAL: &str = \"═\";\n    pub const THICK_HORIZONTAL: &str = \"━\";\n\n    pub const TOP_RIGHT: &str = \"┐\";\n    pub const ROUNDED_TOP_RIGHT: &str = \"╮\";\n    pub const DOUBLE_TOP_RIGHT: &str = \"╗\";\n    pub const THICK_TOP_RIGHT: &str = \"┓\";\n\n    pub const TOP_LEFT: &str = \"┌\";\n    pub const ROUNDED_TOP_LEFT: &str = \"╭\";\n    pub const DOUBLE_TOP_LEFT: &str = \"╔\";\n    pub const THICK_TOP_LEFT: &str = \"┏\";\n\n    pub const BOTTOM_RIGHT: &str = \"┘\";\n    pub const ROUNDED_BOTTOM_RIGHT: &str = \"╯\";\n    pub const DOUBLE_BOTTOM_RIGHT: &str = \"╝\";\n    pub const THICK_BOTTOM_RIGHT: &str = \"┛\";\n\n    pub const BOTTOM_LEFT: &str = \"└\";\n    pub const ROUNDED_BOTTOM_LEFT: &str = \"╰\";\n    pub const DOUBLE_BOTTOM_LEFT: &str = \"╚\";\n    pub const THICK_BOTTOM_LEFT: &str = \"┗\";\n\n    pub const VERTICAL_LEFT: &str = \"┤\";\n    pub const DOUBLE_VERTICAL_LEFT: &str = \"╣\";\n    pub const THICK_VERTICAL_LEFT: &str = \"┫\";\n\n    pub const VERTICAL_RIGHT: &str = \"├\";\n    pub const DOUBLE_VERTICAL_RIGHT: &str = \"╠\";\n    pub const THICK_VERTICAL_RIGHT: &str = \"┣\";\n\n    pub const HORIZONTAL_DOWN: &str = \"┬\";\n    pub const DOUBLE_HORIZONTAL_DOWN: &str = \"╦\";\n    pub const THICK_HORIZONTAL_DOWN: &str = \"┳\";\n\n    pub const HORIZONTAL_UP: &str = \"┴\";\n    pub const DOUBLE_HORIZONTAL_UP: &str = \"╩\";\n    pub const THICK_HORIZONTAL_UP: &str = \"┻\";\n\n    pub const CROSS: &str = \"┼\";\n    pub const DOUBLE_CROSS: &str = \"╬\";\n    pub const THICK_CROSS: &str = \"╋\";\n\n    #[derive(Debug, Clone)]\n    pub struct Set {\n        pub vertical: &'static str,\n        pub horizontal: &'static str,\n        pub top_right: &'static str,\n        pub top_left: &'static str,\n        pub bottom_right: &'static str,\n        pub bottom_left: &'static str,\n        pub vertical_left: &'static str,\n        pub vertical_right: &'static str,\n        pub horizontal_down: &'static str,\n        pub horizontal_up: &'static str,\n        pub cross: &'static str,\n    }\n\n    pub const NORMAL: Set = Set {\n        vertical: VERTICAL,\n        horizontal: HORIZONTAL,\n        top_right: TOP_RIGHT,\n        top_left: TOP_LEFT,\n        bottom_right: BOTTOM_RIGHT,\n        bottom_left: BOTTOM_LEFT,\n        vertical_left: VERTICAL_LEFT,\n        vertical_right: VERTICAL_RIGHT,\n        horizontal_down: HORIZONTAL_DOWN,\n        horizontal_up: HORIZONTAL_UP,\n        cross: CROSS,\n    };\n\n    pub const ROUNDED: Set = Set {\n        top_right: ROUNDED_TOP_RIGHT,\n        top_left: ROUNDED_TOP_LEFT,\n        bottom_right: ROUNDED_BOTTOM_RIGHT,\n        bottom_left: ROUNDED_BOTTOM_LEFT,\n        ..NORMAL\n    };\n\n    pub const DOUBLE: Set = Set {\n        vertical: DOUBLE_VERTICAL,\n        horizontal: DOUBLE_HORIZONTAL,\n        top_right: DOUBLE_TOP_RIGHT,\n        top_left: DOUBLE_TOP_LEFT,\n        bottom_right: DOUBLE_BOTTOM_RIGHT,\n        bottom_left: DOUBLE_BOTTOM_LEFT,\n        vertical_left: DOUBLE_VERTICAL_LEFT,\n        vertical_right: DOUBLE_VERTICAL_RIGHT,\n        horizontal_down: DOUBLE_HORIZONTAL_DOWN,\n        horizontal_up: DOUBLE_HORIZONTAL_UP,\n        cross: DOUBLE_CROSS,\n    };\n\n    pub const THICK: Set = Set {\n        vertical: THICK_VERTICAL,\n        horizontal: THICK_HORIZONTAL,\n        top_right: THICK_TOP_RIGHT,\n        top_left: THICK_TOP_LEFT,\n        bottom_right: THICK_BOTTOM_RIGHT,\n        bottom_left: THICK_BOTTOM_LEFT,\n        vertical_left: THICK_VERTICAL_LEFT,\n        vertical_right: THICK_VERTICAL_RIGHT,\n        horizontal_down: THICK_HORIZONTAL_DOWN,\n        horizontal_up: THICK_HORIZONTAL_UP,\n        cross: THICK_CROSS,\n    };\n}\n\npub const DOT: &str = \"•\";\n\npub mod braille {\n    pub const BLANK: u16 = 0x2800;\n    pub const DOTS: [[u16; 2]; 4] = [\n        [0x0001, 0x0008],\n        [0x0002, 0x0010],\n        [0x0004, 0x0020],\n        [0x0040, 0x0080],\n    ];\n}\n\n/// Marker to use when plotting data points\n#[derive(Debug, Clone, Copy)]\npub enum Marker {\n    /// One point per cell in shape of dot\n    Dot,\n    /// One point per cell in shape of a block\n    Block,\n    /// Up to 8 points per cell\n    Braille,\n}\n"
  },
  {
    "path": "helix-tui/src/terminal.rs",
    "content": "//! Terminal interface provided through the [Terminal] type.\n//! Frontend for [Backend]\n\nuse crate::{backend::Backend, buffer::Buffer};\nuse helix_view::editor::{Config as EditorConfig, KittyKeyboardProtocolConfig};\nuse helix_view::graphics::{CursorKind, Rect};\nuse std::io;\n\n#[derive(Debug, Clone, PartialEq)]\n/// UNSTABLE\nenum ResizeBehavior {\n    Fixed,\n    Auto,\n}\n\n#[derive(Debug, Clone, PartialEq)]\n/// UNSTABLE\npub struct Viewport {\n    area: Rect,\n    resize_behavior: ResizeBehavior,\n}\n\n/// Terminal configuration\n#[derive(Debug)]\npub struct Config {\n    pub enable_mouse_capture: bool,\n    pub force_enable_extended_underlines: bool,\n    pub kitty_keyboard_protocol: KittyKeyboardProtocolConfig,\n}\n\nimpl From<&EditorConfig> for Config {\n    fn from(config: &EditorConfig) -> Self {\n        Self {\n            enable_mouse_capture: config.mouse,\n            force_enable_extended_underlines: config.undercurl,\n            kitty_keyboard_protocol: config.kitty_keyboard_protocol,\n        }\n    }\n}\n\nimpl Viewport {\n    /// UNSTABLE\n    pub fn fixed(area: Rect) -> Viewport {\n        Viewport {\n            area,\n            resize_behavior: ResizeBehavior::Fixed,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq)]\n/// Options to pass to [`Terminal::with_options`]\npub struct TerminalOptions {\n    /// Viewport used to draw to the terminal\n    pub viewport: Viewport,\n}\n\n/// Interface to the terminal backed by crossterm\n#[derive(Debug)]\npub struct Terminal<B>\nwhere\n    B: Backend,\n{\n    backend: B,\n    /// Holds the results of the current and previous draw calls. The two are compared at the end\n    /// of each draw pass to output the necessary updates to the terminal\n    buffers: [Buffer; 2],\n    /// Index of the current buffer in the previous array\n    current: usize,\n    /// Kind of cursor (hidden or others)\n    cursor_kind: CursorKind,\n    /// Viewport\n    viewport: Viewport,\n}\n\n/// Default terminal size: 80 columns, 24 lines\npub const DEFAULT_TERMINAL_SIZE: Rect = Rect {\n    x: 0,\n    y: 0,\n    width: 80,\n    height: 24,\n};\n\nimpl<B> Terminal<B>\nwhere\n    B: Backend,\n{\n    /// Wrapper around Terminal initialization. Each buffer is initialized with a blank string and\n    /// default colors for the foreground and the background\n    pub fn new(backend: B) -> io::Result<Terminal<B>> {\n        let size = backend.size().unwrap_or(DEFAULT_TERMINAL_SIZE);\n        Terminal::with_options(\n            backend,\n            TerminalOptions {\n                viewport: Viewport {\n                    area: size,\n                    resize_behavior: ResizeBehavior::Auto,\n                },\n            },\n        )\n    }\n\n    /// UNSTABLE\n    pub fn with_options(backend: B, options: TerminalOptions) -> io::Result<Terminal<B>> {\n        Ok(Terminal {\n            backend,\n            buffers: [\n                Buffer::empty(options.viewport.area),\n                Buffer::empty(options.viewport.area),\n            ],\n            current: 0,\n            cursor_kind: CursorKind::Block,\n            viewport: options.viewport,\n        })\n    }\n\n    pub fn claim(&mut self) -> io::Result<()> {\n        self.backend.claim()\n    }\n\n    pub fn reconfigure(&mut self, config: Config) -> io::Result<()> {\n        self.backend.reconfigure(config)\n    }\n\n    pub fn restore(&mut self) -> io::Result<()> {\n        self.backend.restore()\n    }\n\n    // /// Get a Frame object which provides a consistent view into the terminal state for rendering.\n    // pub fn get_frame(&mut self) -> Frame<B> {\n    //     Frame {\n    //         terminal: self,\n    //         cursor_position: None,\n    //     }\n    // }\n\n    pub fn current_buffer_mut(&mut self) -> &mut Buffer {\n        &mut self.buffers[self.current]\n    }\n\n    pub fn backend(&self) -> &B {\n        &self.backend\n    }\n\n    pub fn backend_mut(&mut self) -> &mut B {\n        &mut self.backend\n    }\n\n    /// Obtains a difference between the previous and the current buffer and passes it to the\n    /// current backend for drawing.\n    pub fn flush(&mut self) -> io::Result<()> {\n        let previous_buffer = &self.buffers[1 - self.current];\n        let current_buffer = &self.buffers[self.current];\n        let updates = previous_buffer.diff(current_buffer);\n        self.backend.draw(updates.into_iter())\n    }\n\n    /// Updates the Terminal so that internal buffers match the requested size. Requested size will\n    /// be saved so the size can remain consistent when rendering.\n    /// This leads to a full clear of the screen.\n    pub fn resize(&mut self, area: Rect) -> io::Result<()> {\n        self.buffers[self.current].resize(area);\n        self.buffers[1 - self.current].resize(area);\n        self.viewport.area = area;\n        self.clear()\n    }\n\n    /// Queries the backend for size and resizes if it doesn't match the previous size.\n    pub fn autoresize(&mut self) -> io::Result<Rect> {\n        let size = self.size();\n        if size != self.viewport.area {\n            self.resize(size)?;\n        };\n        Ok(size)\n    }\n\n    /// Synchronizes terminal size, calls the rendering closure, flushes the current internal state\n    /// and prepares for the next draw call.\n    pub fn draw(\n        &mut self,\n        cursor_position: Option<(u16, u16)>,\n        cursor_kind: CursorKind,\n    ) -> io::Result<()> {\n        // // Autoresize - otherwise we get glitches if shrinking or potential desync between widgets\n        // // and the terminal (if growing), which may OOB.\n        // self.autoresize()?;\n\n        // let mut frame = self.get_frame();\n        // f(&mut frame);\n        // // We can't change the cursor position right away because we have to flush the frame to\n        // // stdout first. But we also can't keep the frame around, since it holds a &mut to\n        // // Terminal. Thus, we're taking the important data out of the Frame and dropping it.\n        // let cursor_position = frame.cursor_position;\n\n        // Draw to stdout\n        self.flush()?;\n\n        if let Some((x, y)) = cursor_position {\n            self.set_cursor(x, y)?;\n        }\n\n        match cursor_kind {\n            CursorKind::Hidden => self.hide_cursor()?,\n            kind => self.show_cursor(kind)?,\n        }\n\n        // Swap buffers\n        self.buffers[1 - self.current].reset();\n        self.current = 1 - self.current;\n\n        // Flush\n        self.backend.flush()?;\n        Ok(())\n    }\n\n    #[inline]\n    pub fn cursor_kind(&self) -> CursorKind {\n        self.cursor_kind\n    }\n\n    pub fn hide_cursor(&mut self) -> io::Result<()> {\n        self.backend.hide_cursor()?;\n        self.cursor_kind = CursorKind::Hidden;\n        Ok(())\n    }\n\n    pub fn show_cursor(&mut self, kind: CursorKind) -> io::Result<()> {\n        self.backend.show_cursor(kind)?;\n        self.cursor_kind = kind;\n        Ok(())\n    }\n\n    pub fn set_cursor(&mut self, x: u16, y: u16) -> io::Result<()> {\n        self.backend.set_cursor(x, y)\n    }\n\n    /// Clear the terminal and force a full redraw on the next draw call.\n    pub fn clear(&mut self) -> io::Result<()> {\n        self.backend.clear()?;\n        // Reset the back buffer to make sure the next update will redraw everything.\n        self.buffers[1 - self.current].reset();\n        Ok(())\n    }\n\n    /// Queries the real size of the backend.\n    pub fn size(&self) -> Rect {\n        self.backend.size().unwrap_or(DEFAULT_TERMINAL_SIZE)\n    }\n}\n"
  },
  {
    "path": "helix-tui/src/text.rs",
    "content": "//! Primitives for styled text.\n//!\n//! A terminal UI is at its root a lot of strings. In order to make it accessible and stylish,\n//! those strings may be associated to a set of styles. `tui` has three ways to represent them:\n//! - A single line string where all graphemes have the same style is represented by a [`Span`].\n//! - A single line string where each grapheme may have its own style is represented by [`Spans`].\n//! - A multiple line string where each grapheme may have its own style is represented by a\n//!   [`Text`].\n//!\n//! These types form a hierarchy: [`Spans`] is a collection of [`Span`] and each line of [`Text`]\n//! is a [`Spans`].\n//!\n//! Keep in mind that a lot of widgets will use those types to advertise what kind of string is\n//! supported for their properties. Moreover, `tui` provides convenient `From` implementations so\n//! that you can start by using simple `String` or `&str` and then promote them to the previous\n//! primitives when you need additional styling capabilities.\n//!\n//! For example, for the [`crate::widgets::Block`] widget, all the following calls are valid to set\n//! its `title` property (which is a [`Spans`] under the hood):\n//!\n//! ```rust\n//! # use helix_tui::widgets::Block;\n//! # use helix_tui::text::{Span, Spans};\n//! # use helix_view::graphics::{Color, Style};\n//! // A simple string with no styling.\n//! // Converted to Spans(vec![\n//! //   Span { content: Cow::Borrowed(\"My title\"), style: Style { .. } }\n//! // ])\n//! let block = Block::default().title(\"My title\");\n//!\n//! // A simple string with a unique style.\n//! // Converted to Spans(vec![\n//! //   Span { content: Cow::Borrowed(\"My title\"), style: Style { fg: Some(Color::Yellow), .. }\n//! // ])\n//! let block = Block::default().title(\n//!     Span::styled(\"My title\", Style::default().fg(Color::Yellow))\n//! );\n//!\n//! // A string with multiple styles.\n//! // Converted to Spans(vec![\n//! //   Span { content: Cow::Borrowed(\"My\"), style: Style { fg: Some(Color::Yellow), .. } },\n//! //   Span { content: Cow::Borrowed(\" title\"), .. }\n//! // ])\n//! let block = Block::default().title(vec![\n//!     Span::styled(\"My\", Style::default().fg(Color::Yellow)),\n//!     Span::raw(\" title\"),\n//! ]);\n//! ```\nuse helix_core::line_ending::str_is_line_ending;\nuse helix_core::unicode::width::UnicodeWidthStr;\nuse helix_view::graphics::Style;\nuse std::borrow::Cow;\nuse unicode_segmentation::UnicodeSegmentation;\n\n/// A grapheme associated to a style.\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct StyledGrapheme<'a> {\n    pub symbol: &'a str,\n    pub style: Style,\n}\n\n/// A string where all graphemes have the same style.\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct Span<'a> {\n    pub content: Cow<'a, str>,\n    pub style: Style,\n}\n\nimpl<'a> Span<'a> {\n    /// Create a span with no style.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_tui::text::Span;\n    /// Span::raw(\"My text\");\n    /// Span::raw(String::from(\"My text\"));\n    /// ```\n    pub fn raw<T>(content: T) -> Span<'a>\n    where\n        T: Into<Cow<'a, str>>,\n    {\n        Span {\n            content: content.into(),\n            style: Style::default(),\n        }\n    }\n\n    /// Create a span with a style.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// # use helix_tui::text::Span;\n    /// # use helix_view::graphics::{Color, Modifier, Style};\n    /// let style = Style::default().fg(Color::Yellow).add_modifier(Modifier::ITALIC);\n    /// Span::styled(\"My text\", style);\n    /// Span::styled(String::from(\"My text\"), style);\n    /// ```\n    pub fn styled<T>(content: T, style: Style) -> Span<'a>\n    where\n        T: Into<Cow<'a, str>>,\n    {\n        Span {\n            content: content.into(),\n            style,\n        }\n    }\n\n    /// Returns the width of the content held by this span.\n    pub fn width(&self) -> usize {\n        self.content.width()\n    }\n\n    /// Returns an iterator over the graphemes held by this span.\n    ///\n    /// `base_style` is the [`Style`] that will be patched with each grapheme [`Style`] to get\n    /// the resulting [`Style`].\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_tui::text::{Span, StyledGrapheme};\n    /// # use helix_view::graphics::{Color, Modifier, Style};\n    /// # use std::iter::Iterator;\n    /// let style = Style::default().fg(Color::Yellow);\n    /// let span = Span::styled(\"Text\", style);\n    /// let style = Style::default().fg(Color::Green).bg(Color::Black);\n    /// let styled_graphemes = span.styled_graphemes(style);\n    /// assert_eq!(\n    ///     vec![\n    ///         StyledGrapheme {\n    ///             symbol: \"T\",\n    ///             style: Style {\n    ///                 fg: Some(Color::Yellow),\n    ///                 bg: Some(Color::Black),\n    ///                 underline_color: None,\n    ///                 underline_style: None,\n    ///                 add_modifier: Modifier::empty(),\n    ///                 sub_modifier: Modifier::empty(),\n    ///             },\n    ///         },\n    ///         StyledGrapheme {\n    ///             symbol: \"e\",\n    ///             style: Style {\n    ///                 fg: Some(Color::Yellow),\n    ///                 bg: Some(Color::Black),\n    ///                 underline_color: None,\n    ///                 underline_style: None,\n    ///                 add_modifier: Modifier::empty(),\n    ///                 sub_modifier: Modifier::empty(),\n    ///             },\n    ///         },\n    ///         StyledGrapheme {\n    ///             symbol: \"x\",\n    ///             style: Style {\n    ///                 fg: Some(Color::Yellow),\n    ///                 bg: Some(Color::Black),\n    ///                 underline_color: None,\n    ///                 underline_style: None,\n    ///                 add_modifier: Modifier::empty(),\n    ///                 sub_modifier: Modifier::empty(),\n    ///             },\n    ///         },\n    ///         StyledGrapheme {\n    ///             symbol: \"t\",\n    ///             style: Style {\n    ///                 fg: Some(Color::Yellow),\n    ///                 bg: Some(Color::Black),\n    ///                 underline_color: None,\n    ///                 underline_style: None,\n    ///                 add_modifier: Modifier::empty(),\n    ///                 sub_modifier: Modifier::empty(),\n    ///             },\n    ///         },\n    ///     ],\n    ///     styled_graphemes.collect::<Vec<StyledGrapheme>>()\n    /// );\n    /// ```\n    pub fn styled_graphemes(\n        &'a self,\n        base_style: Style,\n    ) -> impl Iterator<Item = StyledGrapheme<'a>> {\n        UnicodeSegmentation::graphemes(self.content.as_ref(), true)\n            .map(move |g| StyledGrapheme {\n                symbol: g,\n                style: base_style.patch(self.style),\n            })\n            .filter(|s| !str_is_line_ending(s.symbol))\n    }\n}\n\nimpl<'a> From<String> for Span<'a> {\n    fn from(s: String) -> Span<'a> {\n        Span::raw(s)\n    }\n}\n\nimpl<'a> From<&'a str> for Span<'a> {\n    fn from(s: &'a str) -> Span<'a> {\n        Span::raw(s)\n    }\n}\n\nimpl<'a> From<Cow<'a, str>> for Span<'a> {\n    fn from(s: Cow<'a, str>) -> Span<'a> {\n        Span::raw(s)\n    }\n}\n\n/// A string composed of clusters of graphemes, each with their own style.\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct Spans<'a>(pub Vec<Span<'a>>);\n\nimpl Spans<'_> {\n    /// Returns the width of the underlying string.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_tui::text::{Span, Spans};\n    /// # use helix_view::graphics::{Color, Style};\n    /// let spans = Spans::from(vec![\n    ///     Span::styled(\"My\", Style::default().fg(Color::Yellow)),\n    ///     Span::raw(\" text\"),\n    /// ]);\n    /// assert_eq!(7, spans.width());\n    /// ```\n    pub fn width(&self) -> usize {\n        self.0.iter().map(Span::width).sum()\n    }\n}\n\nimpl<'a> From<String> for Spans<'a> {\n    fn from(s: String) -> Spans<'a> {\n        Spans(vec![Span::from(s)])\n    }\n}\n\nimpl<'a> From<&'a str> for Spans<'a> {\n    fn from(s: &'a str) -> Spans<'a> {\n        Spans(vec![Span::from(s)])\n    }\n}\n\nimpl<'a> From<Cow<'a, str>> for Spans<'a> {\n    fn from(s: Cow<'a, str>) -> Spans<'a> {\n        Spans(vec![Span::raw(s)])\n    }\n}\n\nimpl<'a> From<Vec<Span<'a>>> for Spans<'a> {\n    fn from(spans: Vec<Span<'a>>) -> Spans<'a> {\n        Spans(spans)\n    }\n}\n\nimpl<'a> From<Span<'a>> for Spans<'a> {\n    fn from(span: Span<'a>) -> Spans<'a> {\n        Spans(vec![span])\n    }\n}\n\nimpl<'a> From<Spans<'a>> for String {\n    fn from(line: Spans<'a>) -> String {\n        line.0.iter().map(|s| &*s.content).collect()\n    }\n}\n\nimpl<'a> From<&Spans<'a>> for String {\n    fn from(line: &Spans<'a>) -> String {\n        line.0.iter().map(|s| &*s.content).collect()\n    }\n}\n\n/// A string split over multiple lines where each line is composed of several clusters, each with\n/// their own style.\n///\n/// A [`Text`], like a [`Span`], can be constructed using one of the many `From` implementations\n/// or via the [`Text::raw`] and [`Text::styled`] methods. Helpfully, [`Text`] also implements\n/// [`core::iter::Extend`] which enables the concatenation of several [`Text`] blocks.\n///\n/// ```rust\n/// # use helix_tui::text::Text;\n/// # use helix_view::graphics::{Color, Modifier, Style};\n/// let style = Style::default().fg(Color::Yellow).add_modifier(Modifier::ITALIC);\n///\n/// // An initial two lines of `Text` built from a `&str`\n/// let mut text = Text::from(\"The first line\\nThe second line\");\n/// assert_eq!(2, text.height());\n///\n/// // Adding two more unstyled lines\n/// text.extend(Text::raw(\"These are two\\nmore lines!\"));\n/// assert_eq!(4, text.height());\n///\n/// // Adding a final two styled lines\n/// text.extend(Text::styled(\"Some more lines\\nnow with more style!\", style));\n/// assert_eq!(6, text.height());\n/// ```\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct Text<'a> {\n    pub lines: Vec<Spans<'a>>,\n}\n\nimpl<'a> Text<'a> {\n    /// Create some text (potentially multiple lines) with no style.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_tui::text::Text;\n    /// Text::raw(\"The first line\\nThe second line\");\n    /// Text::raw(String::from(\"The first line\\nThe second line\"));\n    /// ```\n    pub fn raw<T>(content: T) -> Text<'a>\n    where\n        T: Into<Cow<'a, str>>,\n    {\n        Text {\n            lines: match content.into() {\n                Cow::Borrowed(s) => s.lines().map(Spans::from).collect(),\n                Cow::Owned(s) => s.lines().map(|l| Spans::from(l.to_owned())).collect(),\n            },\n        }\n    }\n\n    /// Create some text (potentially multiple lines) with a style.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// # use helix_tui::text::Text;\n    /// # use helix_view::graphics::{Color, Modifier, Style};\n    /// let style = Style::default().fg(Color::Yellow).add_modifier(Modifier::ITALIC);\n    /// Text::styled(\"The first line\\nThe second line\", style);\n    /// Text::styled(String::from(\"The first line\\nThe second line\"), style);\n    /// ```\n    pub fn styled<T>(content: T, style: Style) -> Text<'a>\n    where\n        T: Into<Cow<'a, str>>,\n    {\n        let mut text = Text::raw(content);\n        text.patch_style(style);\n        text\n    }\n\n    /// Returns the max width of all the lines.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// use helix_tui::text::Text;\n    /// let text = Text::from(\"The first line\\nThe second line\");\n    /// assert_eq!(15, text.width());\n    /// ```\n    pub fn width(&self) -> usize {\n        self.lines\n            .iter()\n            .map(Spans::width)\n            .max()\n            .unwrap_or_default()\n    }\n\n    /// Returns the height.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// use helix_tui::text::Text;\n    /// let text = Text::from(\"The first line\\nThe second line\");\n    /// assert_eq!(2, text.height());\n    /// ```\n    pub fn height(&self) -> usize {\n        self.lines.len()\n    }\n\n    /// Patch text with a new style. Only updates fields that are in the new style.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// # use helix_tui::text::Text;\n    /// # use helix_view::graphics::{Color,  Style};\n    /// let style1 = Style::default().fg(Color::Yellow);\n    /// let style2 = Style::default().fg(Color::Yellow).bg(Color::Black);\n    /// let mut half_styled_text = Text::styled(String::from(\"The first line\\nThe second line\"), style1);\n    /// let full_styled_text = Text::styled(String::from(\"The first line\\nThe second line\"), style2);\n    /// assert_ne!(half_styled_text, full_styled_text);\n    ///\n    /// half_styled_text.patch_style(Style::default().bg(Color::Black));\n    /// assert_eq!(half_styled_text, full_styled_text);\n    /// ```\n    pub fn patch_style(&mut self, style: Style) {\n        for line in &mut self.lines {\n            for span in &mut line.0 {\n                span.style = span.style.patch(style);\n            }\n        }\n    }\n\n    /// Apply a new style to existing text.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// # use helix_tui::text::Text;\n    /// # use helix_view::graphics::{Color, Modifier, Style};\n    /// let style = Style::default().fg(Color::Yellow).add_modifier(Modifier::ITALIC);\n    /// let mut raw_text = Text::raw(\"The first line\\nThe second line\");\n    /// let styled_text = Text::styled(String::from(\"The first line\\nThe second line\"), style);\n    /// assert_ne!(raw_text, styled_text);\n    ///\n    /// raw_text.set_style(style);\n    /// assert_eq!(raw_text, styled_text);\n    /// ```\n    pub fn set_style(&mut self, style: Style) {\n        for line in &mut self.lines {\n            for span in &mut line.0 {\n                span.style = style;\n            }\n        }\n    }\n}\n\nimpl<'a> From<String> for Text<'a> {\n    fn from(s: String) -> Text<'a> {\n        Text::raw(s)\n    }\n}\n\nimpl<'a> From<&'a str> for Text<'a> {\n    fn from(s: &'a str) -> Text<'a> {\n        Text::raw(s)\n    }\n}\n\nimpl<'a> From<Cow<'a, str>> for Text<'a> {\n    fn from(s: Cow<'a, str>) -> Text<'a> {\n        Text::raw(s)\n    }\n}\n\nimpl<'a> From<Span<'a>> for Text<'a> {\n    fn from(span: Span<'a>) -> Text<'a> {\n        Text {\n            lines: vec![Spans::from(span)],\n        }\n    }\n}\n\nimpl<'a> From<Spans<'a>> for Text<'a> {\n    fn from(spans: Spans<'a>) -> Text<'a> {\n        Text { lines: vec![spans] }\n    }\n}\n\nimpl<'a> From<Vec<Spans<'a>>> for Text<'a> {\n    fn from(lines: Vec<Spans<'a>>) -> Text<'a> {\n        Text { lines }\n    }\n}\n\nimpl<'a> From<Text<'a>> for String {\n    fn from(text: Text<'a>) -> String {\n        String::from(&text)\n    }\n}\n\nimpl<'a> From<&Text<'a>> for String {\n    fn from(text: &Text<'a>) -> String {\n        let size = text\n            .lines\n            .iter()\n            .flat_map(|spans| spans.0.iter().map(|span| span.content.len()))\n            .sum::<usize>()\n            + text.lines.len().saturating_sub(1); // for newline after each line\n        let mut output = String::with_capacity(size);\n\n        for spans in &text.lines {\n            if !output.is_empty() {\n                output.push('\\n');\n            }\n            for span in &spans.0 {\n                output.push_str(&span.content);\n            }\n        }\n        output\n    }\n}\n\nimpl<'a> IntoIterator for Text<'a> {\n    type Item = Spans<'a>;\n    type IntoIter = std::vec::IntoIter<Self::Item>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        self.lines.into_iter()\n    }\n}\n\nimpl<'a> Extend<Spans<'a>> for Text<'a> {\n    fn extend<T: IntoIterator<Item = Spans<'a>>>(&mut self, iter: T) {\n        self.lines.extend(iter);\n    }\n}\n"
  },
  {
    "path": "helix-tui/src/widgets/block.rs",
    "content": "use crate::{\n    buffer::Buffer,\n    symbols::line,\n    text::Spans,\n    widgets::{Borders, Widget},\n};\nuse helix_view::graphics::{Rect, Style};\n\n/// Border render type. Defaults to [`BorderType::Plain`].\n#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]\npub enum BorderType {\n    #[default]\n    Plain,\n    Rounded,\n    Double,\n    Thick,\n}\n\nimpl BorderType {\n    pub fn line_symbols(border_type: Self) -> line::Set {\n        match border_type {\n            Self::Plain => line::NORMAL,\n            Self::Rounded => line::ROUNDED,\n            Self::Double => line::DOUBLE,\n            Self::Thick => line::THICK,\n        }\n    }\n}\n\n/// Base widget to be used with all upper level ones. It may be used to display a box border around\n/// the widget and/or add a title.\n///\n/// # Examples\n///\n/// ```\n/// # use helix_tui::widgets::{Block, BorderType, Borders};\n/// # use helix_view::graphics::{Style, Color};\n/// Block::default()\n///     .title(\"Block\")\n///     .borders(Borders::LEFT | Borders::RIGHT)\n///     .border_style(Style::default().fg(Color::White))\n///     .border_type(BorderType::Rounded)\n///     .style(Style::default().bg(Color::Black));\n/// ```\n#[derive(Debug, Default, Clone, PartialEq, Eq)]\npub struct Block<'a> {\n    /// Optional title place on the upper left of the block\n    title: Option<Spans<'a>>,\n    /// Visible borders\n    borders: Borders,\n    /// Border style\n    border_style: Style,\n    /// Type of the border. The default is plain lines but one can choose to have rounded corners\n    /// or doubled lines instead.\n    border_type: BorderType,\n    /// Widget style\n    style: Style,\n}\n\nimpl<'a> Block<'a> {\n    pub const fn new() -> Self {\n        Self {\n            title: None,\n            borders: Borders::empty(),\n            border_style: Style::new(),\n            border_type: BorderType::Plain,\n            style: Style::new(),\n        }\n    }\n\n    pub const fn bordered() -> Self {\n        let mut block = Self::new();\n        block.borders = Borders::ALL;\n        block\n    }\n\n    pub fn title<T>(mut self, title: T) -> Block<'a>\n    where\n        T: Into<Spans<'a>>,\n    {\n        self.title = Some(title.into());\n        self\n    }\n\n    pub const fn border_style(mut self, style: Style) -> Block<'a> {\n        self.border_style = style;\n        self\n    }\n\n    pub const fn style(mut self, style: Style) -> Block<'a> {\n        self.style = style;\n        self\n    }\n\n    pub const fn borders(mut self, flag: Borders) -> Block<'a> {\n        self.borders = flag;\n        self\n    }\n\n    pub const fn border_type(mut self, border_type: BorderType) -> Block<'a> {\n        self.border_type = border_type;\n        self\n    }\n\n    /// Compute the inner area of a block based on its border visibility rules.\n    pub fn inner(&self, area: Rect) -> Rect {\n        let mut inner = area;\n        if self.borders.intersects(Borders::LEFT) {\n            inner.x = inner.x.saturating_add(1).min(inner.right());\n            inner.width = inner.width.saturating_sub(1);\n        }\n        if self.borders.intersects(Borders::TOP) || self.title.is_some() {\n            inner.y = inner.y.saturating_add(1).min(inner.bottom());\n            inner.height = inner.height.saturating_sub(1);\n        }\n        if self.borders.intersects(Borders::RIGHT) {\n            inner.width = inner.width.saturating_sub(1);\n        }\n        if self.borders.intersects(Borders::BOTTOM) {\n            inner.height = inner.height.saturating_sub(1);\n        }\n        inner\n    }\n}\n\nimpl Widget for Block<'_> {\n    fn render(self, area: Rect, buf: &mut Buffer) {\n        if area.area() == 0 {\n            return;\n        }\n        buf.set_style(area, self.style);\n        let symbols = BorderType::line_symbols(self.border_type);\n\n        // Sides\n        if self.borders.intersects(Borders::LEFT) {\n            for y in area.top()..area.bottom() {\n                buf[(area.left(), y)]\n                    .set_symbol(symbols.vertical)\n                    .set_style(self.border_style);\n            }\n        }\n        if self.borders.intersects(Borders::TOP) {\n            for x in area.left()..area.right() {\n                buf[(x, area.top())]\n                    .set_symbol(symbols.horizontal)\n                    .set_style(self.border_style);\n            }\n        }\n        if self.borders.intersects(Borders::RIGHT) {\n            let x = area.right() - 1;\n            for y in area.top()..area.bottom() {\n                buf[(x, y)]\n                    .set_symbol(symbols.vertical)\n                    .set_style(self.border_style);\n            }\n        }\n        if self.borders.intersects(Borders::BOTTOM) {\n            let y = area.bottom() - 1;\n            for x in area.left()..area.right() {\n                buf[(x, y)]\n                    .set_symbol(symbols.horizontal)\n                    .set_style(self.border_style);\n            }\n        }\n\n        // Corners\n        if self.borders.contains(Borders::RIGHT | Borders::BOTTOM) {\n            buf[(area.right() - 1, area.bottom() - 1)]\n                .set_symbol(symbols.bottom_right)\n                .set_style(self.border_style);\n        }\n        if self.borders.contains(Borders::RIGHT | Borders::TOP) {\n            buf[(area.right() - 1, area.top())]\n                .set_symbol(symbols.top_right)\n                .set_style(self.border_style);\n        }\n        if self.borders.contains(Borders::LEFT | Borders::BOTTOM) {\n            buf[(area.left(), area.bottom() - 1)]\n                .set_symbol(symbols.bottom_left)\n                .set_style(self.border_style);\n        }\n        if self.borders.contains(Borders::LEFT | Borders::TOP) {\n            buf[(area.left(), area.top())]\n                .set_symbol(symbols.top_left)\n                .set_style(self.border_style);\n        }\n\n        if let Some(title) = self.title {\n            let lx = u16::from(self.borders.intersects(Borders::LEFT));\n            let rx = u16::from(self.borders.intersects(Borders::RIGHT));\n            let width = area.width.saturating_sub(lx).saturating_sub(rx);\n            buf.set_spans(area.left() + lx, area.top(), &title, width);\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn inner_takes_into_account_the_borders() {\n        // No borders\n        assert_eq!(\n            Block::default().inner(Rect::default()),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 0,\n                height: 0\n            },\n            \"no borders, width=0, height=0\"\n        );\n        assert_eq!(\n            Block::default().inner(Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 1\n            }),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 1\n            },\n            \"no borders, width=1, height=1\"\n        );\n\n        // Left border\n        assert_eq!(\n            Block::default().borders(Borders::LEFT).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 0,\n                height: 1\n            }),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 0,\n                height: 1\n            },\n            \"left, width=0\"\n        );\n        assert_eq!(\n            Block::default().borders(Borders::LEFT).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 1\n            }),\n            Rect {\n                x: 1,\n                y: 0,\n                width: 0,\n                height: 1\n            },\n            \"left, width=1\"\n        );\n        assert_eq!(\n            Block::default().borders(Borders::LEFT).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 2,\n                height: 1\n            }),\n            Rect {\n                x: 1,\n                y: 0,\n                width: 1,\n                height: 1\n            },\n            \"left, width=2\"\n        );\n\n        // Top border\n        assert_eq!(\n            Block::default().borders(Borders::TOP).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 0\n            }),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 0\n            },\n            \"top, height=0\"\n        );\n        assert_eq!(\n            Block::default().borders(Borders::TOP).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 1\n            }),\n            Rect {\n                x: 0,\n                y: 1,\n                width: 1,\n                height: 0\n            },\n            \"top, height=1\"\n        );\n        assert_eq!(\n            Block::default().borders(Borders::TOP).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 2\n            }),\n            Rect {\n                x: 0,\n                y: 1,\n                width: 1,\n                height: 1\n            },\n            \"top, height=2\"\n        );\n\n        // Right border\n        assert_eq!(\n            Block::default().borders(Borders::RIGHT).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 0,\n                height: 1\n            }),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 0,\n                height: 1\n            },\n            \"right, width=0\"\n        );\n        assert_eq!(\n            Block::default().borders(Borders::RIGHT).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 1\n            }),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 0,\n                height: 1\n            },\n            \"right, width=1\"\n        );\n        assert_eq!(\n            Block::default().borders(Borders::RIGHT).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 2,\n                height: 1\n            }),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 1\n            },\n            \"right, width=2\"\n        );\n\n        // Bottom border\n        assert_eq!(\n            Block::default().borders(Borders::BOTTOM).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 0\n            }),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 0\n            },\n            \"bottom, height=0\"\n        );\n        assert_eq!(\n            Block::default().borders(Borders::BOTTOM).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 1\n            }),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 0\n            },\n            \"bottom, height=1\"\n        );\n        assert_eq!(\n            Block::default().borders(Borders::BOTTOM).inner(Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 2\n            }),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 1\n            },\n            \"bottom, height=2\"\n        );\n\n        // All borders\n        assert_eq!(\n            Block::bordered().inner(Rect::default()),\n            Rect {\n                x: 0,\n                y: 0,\n                width: 0,\n                height: 0\n            },\n            \"all borders, width=0, height=0\"\n        );\n        assert_eq!(\n            Block::bordered().inner(Rect {\n                x: 0,\n                y: 0,\n                width: 1,\n                height: 1\n            }),\n            Rect {\n                x: 1,\n                y: 1,\n                width: 0,\n                height: 0,\n            },\n            \"all borders, width=1, height=1\"\n        );\n        assert_eq!(\n            Block::bordered().inner(Rect {\n                x: 0,\n                y: 0,\n                width: 2,\n                height: 2,\n            }),\n            Rect {\n                x: 1,\n                y: 1,\n                width: 0,\n                height: 0,\n            },\n            \"all borders, width=2, height=2\"\n        );\n        assert_eq!(\n            Block::bordered().inner(Rect {\n                x: 0,\n                y: 0,\n                width: 3,\n                height: 3,\n            }),\n            Rect {\n                x: 1,\n                y: 1,\n                width: 1,\n                height: 1,\n            },\n            \"all borders, width=3, height=3\"\n        );\n    }\n\n    #[test]\n    fn inner_takes_into_account_the_title() {\n        assert_eq!(\n            Block::default().title(\"Test\").inner(Rect {\n                x: 0,\n                y: 0,\n                width: 0,\n                height: 1,\n            }),\n            Rect {\n                x: 0,\n                y: 1,\n                width: 0,\n                height: 0,\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "helix-tui/src/widgets/list.rs",
    "content": "use crate::{\n    buffer::Buffer,\n    layout::{Corner, Rect},\n    style::Style,\n    text::Text,\n    widgets::{Block, StatefulWidget, Widget},\n};\nuse std::iter::{self, Iterator};\nuse unicode_width::UnicodeWidthStr;\n\n#[derive(Debug, Clone)]\npub struct ListState {\n    offset: usize,\n    selected: Option<usize>,\n}\n\nimpl Default for ListState {\n    fn default() -> ListState {\n        ListState {\n            offset: 0,\n            selected: None,\n        }\n    }\n}\n\nimpl ListState {\n    pub fn selected(&self) -> Option<usize> {\n        self.selected\n    }\n\n    pub fn select(&mut self, index: Option<usize>) {\n        self.selected = index;\n        if index.is_none() {\n            self.offset = 0;\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq)]\npub struct ListItem<'a> {\n    content: Text<'a>,\n    style: Style,\n}\n\nimpl<'a> ListItem<'a> {\n    pub fn new<T>(content: T) -> ListItem<'a>\n    where\n        T: Into<Text<'a>>,\n    {\n        ListItem {\n            content: content.into(),\n            style: Style::default(),\n        }\n    }\n\n    pub fn style(mut self, style: Style) -> ListItem<'a> {\n        self.style = style;\n        self\n    }\n\n    pub fn height(&self) -> usize {\n        self.content.height()\n    }\n}\n\n/// A widget to display several items among which one can be selected (optional)\n///\n/// # Examples\n///\n/// ```\n/// # use helix_tui::widgets::{Block, Borders, List, ListItem};\n/// # use helix_tui::style::{Style, Color, Modifier};\n/// let items = [ListItem::new(\"Item 1\"), ListItem::new(\"Item 2\"), ListItem::new(\"Item 3\")];\n/// List::new(items)\n///     .block(Block::bordered().title(\"List\"))\n///     .style(Style::default().fg(Color::White))\n///     .highlight_style(Style::default().add_modifier(Modifier::ITALIC))\n///     .highlight_symbol(\">>\");\n/// ```\n#[derive(Debug, Clone)]\npub struct List<'a> {\n    block: Option<Block<'a>>,\n    items: Vec<ListItem<'a>>,\n    /// Style used as a base style for the widget\n    style: Style,\n    start_corner: Corner,\n    /// Style used to render selected item\n    highlight_style: Style,\n    /// Symbol in front of the selected item (Shift all items to the right)\n    highlight_symbol: Option<&'a str>,\n}\n\nimpl<'a> List<'a> {\n    pub fn new<T>(items: T) -> List<'a>\n    where\n        T: Into<Vec<ListItem<'a>>>,\n    {\n        List {\n            block: None,\n            style: Style::default(),\n            items: items.into(),\n            start_corner: Corner::TopLeft,\n            highlight_style: Style::default(),\n            highlight_symbol: None,\n        }\n    }\n\n    pub fn block(mut self, block: Block<'a>) -> List<'a> {\n        self.block = Some(block);\n        self\n    }\n\n    pub fn style(mut self, style: Style) -> List<'a> {\n        self.style = style;\n        self\n    }\n\n    pub fn highlight_symbol(mut self, highlight_symbol: &'a str) -> List<'a> {\n        self.highlight_symbol = Some(highlight_symbol);\n        self\n    }\n\n    pub fn highlight_style(mut self, style: Style) -> List<'a> {\n        self.highlight_style = style;\n        self\n    }\n\n    pub fn start_corner(mut self, corner: Corner) -> List<'a> {\n        self.start_corner = corner;\n        self\n    }\n}\n\nimpl<'a> StatefulWidget for List<'a> {\n    type State = ListState;\n\n    fn render(mut self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {\n        buf.set_style(area, self.style);\n        let list_area = match self.block.take() {\n            Some(b) => {\n                let inner_area = b.inner(area);\n                b.render(area, buf);\n                inner_area\n            }\n            None => area,\n        };\n\n        if list_area.width < 1 || list_area.height < 1 {\n            return;\n        }\n\n        if self.items.is_empty() {\n            return;\n        }\n        let list_height = list_area.height as usize;\n\n        let mut start = state.offset;\n        let mut end = state.offset;\n        let mut height = 0;\n        for item in self.items.iter().skip(state.offset) {\n            if height + item.height() > list_height {\n                break;\n            }\n            height += item.height();\n            end += 1;\n        }\n\n        let selected = state.selected.unwrap_or(0).min(self.items.len() - 1);\n        while selected >= end {\n            height = height.saturating_add(self.items[end].height());\n            end += 1;\n            while height > list_height {\n                height = height.saturating_sub(self.items[start].height());\n                start += 1;\n            }\n        }\n        while selected < start {\n            start -= 1;\n            height = height.saturating_add(self.items[start].height());\n            while height > list_height {\n                end -= 1;\n                height = height.saturating_sub(self.items[end].height());\n            }\n        }\n        state.offset = start;\n\n        let highlight_symbol = self.highlight_symbol.unwrap_or(\"\");\n        let blank_symbol = iter::repeat(\" \")\n            .take(highlight_symbol.width())\n            .collect::<String>();\n\n        let mut current_height = 0;\n        let has_selection = state.selected.is_some();\n        for (i, item) in self\n            .items\n            .iter_mut()\n            .enumerate()\n            .skip(state.offset)\n            .take(end - start)\n        {\n            let (x, y) = match self.start_corner {\n                Corner::BottomLeft => {\n                    current_height += item.height() as u16;\n                    (list_area.left(), list_area.bottom() - current_height)\n                }\n                _ => {\n                    let pos = (list_area.left(), list_area.top() + current_height);\n                    current_height += item.height() as u16;\n                    pos\n                }\n            };\n            let area = Rect {\n                x,\n                y,\n                width: list_area.width,\n                height: item.height() as u16,\n            };\n            let item_style = self.style.patch(item.style);\n            buf.set_style(area, item_style);\n\n            let is_selected = state.selected.map(|s| s == i).unwrap_or(false);\n            let elem_x = if has_selection {\n                let symbol = if is_selected {\n                    highlight_symbol\n                } else {\n                    &blank_symbol\n                };\n                let (x, _) = buf.set_stringn(x, y, symbol, list_area.width as usize, item_style);\n                x\n            } else {\n                x\n            };\n            let max_element_width = (list_area.width - (elem_x - x)) as usize;\n            for (j, line) in item.content.lines.iter().enumerate() {\n                buf.set_spans(elem_x, y + j as u16, line, max_element_width as u16);\n            }\n            if is_selected {\n                buf.set_style(area, self.highlight_style);\n            }\n        }\n    }\n}\n\nimpl<'a> Widget for List<'a> {\n    fn render(self, area: Rect, buf: &mut Buffer) {\n        let mut state = ListState::default();\n        StatefulWidget::render(self, area, buf, &mut state);\n    }\n}\n"
  },
  {
    "path": "helix-tui/src/widgets/mod.rs",
    "content": "//! `widgets` is a collection of types that implement [`Widget`].\n//!\n//! All widgets are implemented using the builder pattern and are consumable objects. They are not\n//! meant to be stored but used as *commands* to draw common figures in the UI.\n//!\n//! The available widgets are:\n//! - [`Block`]\n// //! - [`List`]\n// //! - [`Table`]\n//! - [`Paragraph`]\n\nmod block;\n// mod list;\nmod paragraph;\nmod reflow;\nmod table;\n\npub use self::block::{Block, BorderType};\n// pub use self::list::{List, ListItem, ListState};\npub use self::paragraph::{Paragraph, Wrap};\npub use self::table::{Cell, Row, Table, TableState};\n\nuse crate::buffer::Buffer;\nuse bitflags::bitflags;\n\nuse helix_view::graphics::Rect;\n\nbitflags! {\n    /// Bitflags that can be composed to set the visible borders essentially on the block widget.\n    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]\n    pub struct Borders: u8 {\n        /// Show the top border\n        const TOP = 0b0000_0001;\n        /// Show the right border\n        const RIGHT = 0b0000_0010;\n        /// Show the bottom border\n        const BOTTOM = 0b000_0100;\n        /// Show the left border\n        const LEFT = 0b0000_1000;\n        /// Show all borders\n        const ALL = Self::TOP.bits() | Self::RIGHT.bits() | Self::BOTTOM.bits() | Self::LEFT.bits();\n    }\n}\n\n/// Base requirements for a Widget\npub trait Widget {\n    /// Draws the current state of the widget in the given buffer. That the only method required to\n    /// implement a custom widget.\n    fn render(self, area: Rect, buf: &mut Buffer);\n}\n"
  },
  {
    "path": "helix-tui/src/widgets/paragraph.rs",
    "content": "use crate::{\n    buffer::Buffer,\n    layout::Alignment,\n    text::{StyledGrapheme, Text},\n    widgets::{\n        reflow::{LineComposer, LineTruncator, WordWrapper},\n        Block, Widget,\n    },\n};\nuse helix_core::unicode::width::UnicodeWidthStr;\nuse helix_view::graphics::{Rect, Style};\nuse std::iter;\n\nfn get_line_offset(line_width: u16, text_area_width: u16, alignment: Alignment) -> u16 {\n    match alignment {\n        Alignment::Center => (text_area_width / 2).saturating_sub(line_width / 2),\n        Alignment::Right => text_area_width.saturating_sub(line_width),\n        Alignment::Left => 0,\n    }\n}\n\n/// A widget to display some text.\n///\n/// # Examples\n///\n/// ```\n/// # use helix_tui::text::{Text, Spans, Span};\n/// # use helix_tui::widgets::{Block, Borders, Paragraph, Wrap};\n/// # use helix_tui::layout::{Alignment};\n/// # use helix_view::graphics::{Style, Color, Modifier};\n/// let text = Text::from(vec![\n///     Spans::from(vec![\n///         Span::raw(\"First\"),\n///         Span::styled(\"line\",Style::default().add_modifier(Modifier::ITALIC)),\n///         Span::raw(\".\"),\n///     ]),\n///     Spans::from(Span::styled(\"Second line\", Style::default().fg(Color::Red))),\n/// ]);\n/// Paragraph::new(&text)\n///     .block(Block::bordered().title(\"Paragraph\"))\n///     .style(Style::default().fg(Color::White).bg(Color::Black))\n///     .alignment(Alignment::Center)\n///     .wrap(Wrap { trim: true });\n/// ```\n#[derive(Debug, Clone)]\npub struct Paragraph<'a> {\n    /// A block to wrap the widget in\n    block: Option<Block<'a>>,\n    /// Widget style\n    style: Style,\n    /// How to wrap the text\n    wrap: Option<Wrap>,\n    /// The text to display\n    text: &'a Text<'a>,\n    /// Scroll\n    scroll: (u16, u16),\n    /// Alignment of the text\n    alignment: Alignment,\n}\n\n/// Describes how to wrap text across lines.\n///\n/// ## Examples\n///\n/// ```\n/// # use helix_tui::widgets::{Paragraph, Wrap};\n/// # use helix_tui::text::Text;\n/// let bullet_points = Text::from(r#\"Some indented points:\n///     - First thing goes here and is long so that it wraps\n///     - Here is another point that is long enough to wrap\"#);\n///\n/// // With leading spaces trimmed (window width of 30 chars):\n/// Paragraph::new(&bullet_points).wrap(Wrap { trim: true });\n/// // Some indented points:\n/// // - First thing goes here and is\n/// // long so that it wraps\n/// // - Here is another point that\n/// // is long enough to wrap\n///\n/// // But without trimming, indentation is preserved:\n/// Paragraph::new(&bullet_points).wrap(Wrap { trim: false });\n/// // Some indented points:\n/// //     - First thing goes here\n/// // and is long so that it wraps\n/// //     - Here is another point\n/// // that is long enough to wrap\n/// ```\n#[derive(Debug, Clone, Copy)]\npub struct Wrap {\n    /// Should leading whitespace be trimmed\n    pub trim: bool,\n}\n\nimpl<'a> Paragraph<'a> {\n    pub fn new(text: &'a Text) -> Paragraph<'a> {\n        Paragraph {\n            block: None,\n            style: Default::default(),\n            wrap: None,\n            text,\n            scroll: (0, 0),\n            alignment: Alignment::Left,\n        }\n    }\n\n    pub fn block(mut self, block: Block<'a>) -> Paragraph<'a> {\n        self.block = Some(block);\n        self\n    }\n\n    pub fn style(mut self, style: Style) -> Paragraph<'a> {\n        self.style = style;\n        self\n    }\n\n    pub fn wrap(mut self, wrap: Wrap) -> Paragraph<'a> {\n        self.wrap = Some(wrap);\n        self\n    }\n\n    pub fn scroll(mut self, offset: (u16, u16)) -> Paragraph<'a> {\n        self.scroll = offset;\n        self\n    }\n\n    pub fn alignment(mut self, alignment: Alignment) -> Paragraph<'a> {\n        self.alignment = alignment;\n        self\n    }\n\n    pub fn required_size(&self, max_text_width: u16) -> (u16, u16) {\n        let style = self.style;\n        let mut styled = self.text.lines.iter().flat_map(|spans| {\n            spans\n                .0\n                .iter()\n                .flat_map(|span| span.styled_graphemes(style))\n                // Required given the way composers work but might be refactored out if we change\n                // composers to operate on lines instead of a stream of graphemes.\n                .chain(iter::once(StyledGrapheme {\n                    symbol: \"\\n\",\n                    style: self.style,\n                }))\n        });\n        let mut line_composer: Box<dyn LineComposer> = if let Some(Wrap { trim }) = self.wrap {\n            Box::new(WordWrapper::new(&mut styled, max_text_width, trim))\n        } else {\n            let mut line_composer = Box::new(LineTruncator::new(&mut styled, max_text_width));\n            if self.alignment == Alignment::Left {\n                line_composer.set_horizontal_offset(self.scroll.1);\n            }\n            line_composer\n        };\n        let mut text_width = 0;\n        let mut text_height = 0;\n        while let Some((_, line_width)) = line_composer.next_line() {\n            text_width = line_width.max(text_width);\n            text_height += 1;\n        }\n        (text_width, text_height)\n    }\n}\n\nimpl Widget for Paragraph<'_> {\n    fn render(mut self, area: Rect, buf: &mut Buffer) {\n        buf.set_style(area, self.style);\n        let text_area = match self.block.take() {\n            Some(b) => {\n                let inner_area = b.inner(area);\n                b.render(area, buf);\n                inner_area\n            }\n            None => area,\n        };\n\n        if text_area.height < 1 {\n            return;\n        }\n\n        let style = self.style;\n        let mut styled = self.text.lines.iter().flat_map(|spans| {\n            spans\n                .0\n                .iter()\n                .flat_map(|span| span.styled_graphemes(style))\n                // Required given the way composers work but might be refactored out if we change\n                // composers to operate on lines instead of a stream of graphemes.\n                .chain(iter::once(StyledGrapheme {\n                    symbol: \"\\n\",\n                    style: self.style,\n                }))\n        });\n\n        let mut line_composer: Box<dyn LineComposer> = if let Some(Wrap { trim }) = self.wrap {\n            Box::new(WordWrapper::new(&mut styled, text_area.width, trim))\n        } else {\n            let mut line_composer = Box::new(LineTruncator::new(&mut styled, text_area.width));\n            if self.alignment == Alignment::Left {\n                line_composer.set_horizontal_offset(self.scroll.1);\n            }\n            line_composer\n        };\n        let mut y = 0;\n        while let Some((current_line, current_line_width)) = line_composer.next_line() {\n            if y >= self.scroll.0 {\n                let mut x = get_line_offset(current_line_width, text_area.width, self.alignment);\n                for StyledGrapheme { symbol, style } in current_line {\n                    buf[(text_area.left() + x, text_area.top() + y - self.scroll.0)]\n                        .set_symbol(if symbol.is_empty() {\n                            // If the symbol is empty, the last char which rendered last time will\n                            // leave on the line. It's a quick fix.\n                            \" \"\n                        } else {\n                            symbol\n                        })\n                        .set_style(*style);\n                    x += symbol.width() as u16;\n                }\n            }\n            y += 1;\n            if y >= text_area.height + self.scroll.0 {\n                break;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "helix-tui/src/widgets/reflow.rs",
    "content": "use crate::text::StyledGrapheme;\nuse helix_core::line_ending::str_is_line_ending;\nuse helix_core::unicode::width::UnicodeWidthStr;\nuse unicode_segmentation::UnicodeSegmentation;\n\nconst NBSP: &str = \"\\u{00a0}\";\nconst NNBSP: &str = \"\\u{202f}\";\n\n/// A state machine to pack styled symbols into lines.\n/// Cannot implement it as Iterator since it yields slices of the internal buffer (need streaming\n/// iterators for that).\npub trait LineComposer<'a> {\n    fn next_line(&mut self) -> Option<(&[StyledGrapheme<'a>], u16)>;\n}\n\n/// A state machine that wraps lines on word boundaries.\npub struct WordWrapper<'a, 'b> {\n    symbols: &'b mut dyn Iterator<Item = StyledGrapheme<'a>>,\n    max_line_width: u16,\n    current_line: Vec<StyledGrapheme<'a>>,\n    next_line: Vec<StyledGrapheme<'a>>,\n    /// Removes the leading whitespace from lines\n    trim: bool,\n}\n\nimpl<'a, 'b> WordWrapper<'a, 'b> {\n    pub fn new(\n        symbols: &'b mut dyn Iterator<Item = StyledGrapheme<'a>>,\n        max_line_width: u16,\n        trim: bool,\n    ) -> WordWrapper<'a, 'b> {\n        WordWrapper {\n            symbols,\n            max_line_width,\n            current_line: vec![],\n            next_line: vec![],\n            trim,\n        }\n    }\n}\n\nimpl<'a> LineComposer<'a> for WordWrapper<'a, '_> {\n    fn next_line(&mut self) -> Option<(&[StyledGrapheme<'a>], u16)> {\n        if self.max_line_width == 0 {\n            return None;\n        }\n        std::mem::swap(&mut self.current_line, &mut self.next_line);\n        self.next_line.truncate(0);\n\n        let mut current_line_width = self\n            .current_line\n            .iter()\n            .map(|StyledGrapheme { symbol, .. }| symbol.width() as u16)\n            .sum();\n\n        let mut symbols_to_last_word_end: usize = 0;\n        let mut width_to_last_word_end: u16 = 0;\n        let mut prev_whitespace = false;\n        let mut symbols_exhausted = true;\n        for StyledGrapheme { symbol, style } in &mut self.symbols {\n            symbols_exhausted = false;\n            let symbol_whitespace =\n                symbol.chars().all(&char::is_whitespace) && symbol != NBSP && symbol != NNBSP;\n\n            // Ignore characters wider that the total max width.\n            if symbol.width() as u16 > self.max_line_width\n                // Skip leading whitespace when trim is enabled.\n                || self.trim && symbol_whitespace && !str_is_line_ending(symbol) && current_line_width == 0\n            {\n                continue;\n            }\n\n            // Break on newline and discard it.\n            if str_is_line_ending(symbol) {\n                if prev_whitespace {\n                    current_line_width = width_to_last_word_end;\n                    self.current_line.truncate(symbols_to_last_word_end);\n                }\n                break;\n            }\n\n            // Mark the previous symbol as word end.\n            if symbol_whitespace && !prev_whitespace {\n                symbols_to_last_word_end = self.current_line.len();\n                width_to_last_word_end = current_line_width;\n            }\n\n            self.current_line.push(StyledGrapheme { symbol, style });\n            current_line_width += symbol.width() as u16;\n\n            if current_line_width > self.max_line_width {\n                // If there was no word break in the text, wrap at the end of the line.\n                let (truncate_at, truncated_width) = if symbols_to_last_word_end != 0 {\n                    (symbols_to_last_word_end, width_to_last_word_end)\n                } else {\n                    (self.current_line.len() - 1, self.max_line_width)\n                };\n\n                // Push the remainder to the next line but strip leading whitespace:\n                {\n                    let remainder = &self.current_line[truncate_at..];\n                    if let Some(remainder_nonwhite) =\n                        remainder.iter().position(|StyledGrapheme { symbol, .. }| {\n                            !symbol.chars().all(&char::is_whitespace)\n                        })\n                    {\n                        self.next_line\n                            .extend_from_slice(&remainder[remainder_nonwhite..]);\n                    }\n                }\n                self.current_line.truncate(truncate_at);\n                current_line_width = truncated_width;\n                break;\n            }\n\n            prev_whitespace = symbol_whitespace;\n        }\n\n        // Even if the iterator is exhausted, pass the previous remainder.\n        if symbols_exhausted && self.current_line.is_empty() {\n            None\n        } else {\n            Some((&self.current_line[..], current_line_width))\n        }\n    }\n}\n\n/// A state machine that truncates overhanging lines.\npub struct LineTruncator<'a, 'b> {\n    symbols: &'b mut dyn Iterator<Item = StyledGrapheme<'a>>,\n    max_line_width: u16,\n    current_line: Vec<StyledGrapheme<'a>>,\n    /// Record the offset to skip render\n    horizontal_offset: u16,\n}\n\nimpl<'a, 'b> LineTruncator<'a, 'b> {\n    pub fn new(\n        symbols: &'b mut dyn Iterator<Item = StyledGrapheme<'a>>,\n        max_line_width: u16,\n    ) -> LineTruncator<'a, 'b> {\n        LineTruncator {\n            symbols,\n            max_line_width,\n            horizontal_offset: 0,\n            current_line: vec![],\n        }\n    }\n\n    pub fn set_horizontal_offset(&mut self, horizontal_offset: u16) {\n        self.horizontal_offset = horizontal_offset;\n    }\n}\n\nimpl<'a> LineComposer<'a> for LineTruncator<'a, '_> {\n    fn next_line(&mut self) -> Option<(&[StyledGrapheme<'a>], u16)> {\n        if self.max_line_width == 0 {\n            return None;\n        }\n\n        self.current_line.truncate(0);\n        let mut current_line_width = 0;\n\n        let mut skip_rest = false;\n        let mut symbols_exhausted = true;\n        let mut horizontal_offset = self.horizontal_offset as usize;\n        for StyledGrapheme { symbol, style } in &mut self.symbols {\n            symbols_exhausted = false;\n\n            // Ignore characters wider that the total max width.\n            if symbol.width() as u16 > self.max_line_width {\n                continue;\n            }\n\n            // Break on newline and discard it.\n            if str_is_line_ending(symbol) {\n                break;\n            }\n\n            if current_line_width + symbol.width() as u16 > self.max_line_width {\n                // Exhaust the remainder of the line.\n                skip_rest = true;\n                break;\n            }\n\n            let symbol = if horizontal_offset == 0 {\n                symbol\n            } else {\n                let w = symbol.width();\n                if w > horizontal_offset {\n                    let t = trim_offset(symbol, horizontal_offset);\n                    horizontal_offset = 0;\n                    t\n                } else {\n                    horizontal_offset -= w;\n                    \"\"\n                }\n            };\n            current_line_width += symbol.width() as u16;\n            self.current_line.push(StyledGrapheme { symbol, style });\n        }\n\n        if skip_rest {\n            for StyledGrapheme { symbol, .. } in &mut self.symbols {\n                if str_is_line_ending(symbol) {\n                    break;\n                }\n            }\n        }\n\n        if symbols_exhausted && self.current_line.is_empty() {\n            None\n        } else {\n            Some((&self.current_line[..], current_line_width))\n        }\n    }\n}\n\n/// This function will return a str slice which start at specified offset.\n/// As src is a unicode str, start offset has to be calculated with each character.\nfn trim_offset(src: &str, mut offset: usize) -> &str {\n    let mut start = 0;\n    for c in UnicodeSegmentation::graphemes(src, true) {\n        let w = c.width();\n        if w <= offset {\n            offset -= w;\n            start += c.len();\n        } else {\n            break;\n        }\n    }\n    &src[start..]\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use unicode_segmentation::UnicodeSegmentation;\n\n    enum Composer {\n        WordWrapper { trim: bool },\n        LineTruncator,\n    }\n\n    fn run_composer(which: Composer, text: &str, text_area_width: u16) -> (Vec<String>, Vec<u16>) {\n        let style = Default::default();\n        let mut styled =\n            UnicodeSegmentation::graphemes(text, true).map(|g| StyledGrapheme { symbol: g, style });\n        let mut composer: Box<dyn LineComposer> = match which {\n            Composer::WordWrapper { trim } => {\n                Box::new(WordWrapper::new(&mut styled, text_area_width, trim))\n            }\n            Composer::LineTruncator => Box::new(LineTruncator::new(&mut styled, text_area_width)),\n        };\n        let mut lines = vec![];\n        let mut widths = vec![];\n        while let Some((styled, width)) = composer.next_line() {\n            let line = styled\n                .iter()\n                .map(|StyledGrapheme { symbol, .. }| *symbol)\n                .collect::<String>();\n            assert!(width <= text_area_width);\n            lines.push(line);\n            widths.push(width);\n        }\n        (lines, widths)\n    }\n\n    #[test]\n    fn line_composer_one_line() {\n        let width = 40;\n        for i in 1..width {\n            let text = \"a\".repeat(i);\n            let (word_wrapper, _) =\n                run_composer(Composer::WordWrapper { trim: true }, &text, width as u16);\n            let (line_truncator, _) = run_composer(Composer::LineTruncator, &text, width as u16);\n            let expected = vec![text];\n            assert_eq!(word_wrapper, expected);\n            assert_eq!(line_truncator, expected);\n        }\n    }\n\n    #[test]\n    fn line_composer_short_lines() {\n        let width = 20;\n        let text =\n            \"abcdefg\\nhijklmno\\npabcdefg\\nhijklmn\\nopabcdefghijk\\nlmnopabcd\\n\\n\\nefghijklmno\";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);\n        let (line_truncator, _) = run_composer(Composer::LineTruncator, text, width);\n\n        let wrapped: Vec<&str> = text.split('\\n').collect();\n        assert_eq!(word_wrapper, wrapped);\n        assert_eq!(line_truncator, wrapped);\n    }\n\n    #[test]\n    fn line_composer_long_word() {\n        let width = 20;\n        let text = \"abcdefghijklmnopabcdefghijklmnopabcdefghijklmnopabcdefghijklmno\";\n        let (word_wrapper, _) =\n            run_composer(Composer::WordWrapper { trim: true }, text, width as u16);\n        let (line_truncator, _) = run_composer(Composer::LineTruncator, text, width as u16);\n\n        let wrapped = vec![\n            &text[..width],\n            &text[width..width * 2],\n            &text[width * 2..width * 3],\n            &text[width * 3..],\n        ];\n        assert_eq!(\n            word_wrapper, wrapped,\n            \"WordWrapper should detect the line cannot be broken on word boundary and \\\n             break it at line width limit.\"\n        );\n        assert_eq!(line_truncator, vec![&text[..width]]);\n    }\n\n    #[test]\n    fn line_composer_long_sentence() {\n        let width = 20;\n        let text =\n            \"abcd efghij klmnopabcd efgh ijklmnopabcdefg hijkl mnopab c d e f g h i j k l m n o\";\n        let text_multi_space =\n            \"abcd efghij    klmnopabcd efgh     ijklmnopabcdefg hijkl mnopab c d e f g h i j k l \\\n             m n o\";\n        let (word_wrapper_single_space, _) =\n            run_composer(Composer::WordWrapper { trim: true }, text, width as u16);\n        let (word_wrapper_multi_space, _) = run_composer(\n            Composer::WordWrapper { trim: true },\n            text_multi_space,\n            width as u16,\n        );\n        let (line_truncator, _) = run_composer(Composer::LineTruncator, text, width as u16);\n\n        let word_wrapped = vec![\n            \"abcd efghij\",\n            \"klmnopabcd efgh\",\n            \"ijklmnopabcdefg\",\n            \"hijkl mnopab c d e f\",\n            \"g h i j k l m n o\",\n        ];\n        assert_eq!(word_wrapper_single_space, word_wrapped);\n        assert_eq!(word_wrapper_multi_space, word_wrapped);\n\n        assert_eq!(line_truncator, vec![&text[..width]]);\n    }\n\n    #[test]\n    fn line_composer_zero_width() {\n        let width = 0;\n        let text = \"abcd efghij klmnopabcd efgh ijklmnopabcdefg hijkl mnopab \";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);\n        let (line_truncator, _) = run_composer(Composer::LineTruncator, text, width);\n\n        let expected: Vec<&str> = Vec::new();\n        assert_eq!(word_wrapper, expected);\n        assert_eq!(line_truncator, expected);\n    }\n\n    #[test]\n    fn line_composer_max_line_width_of_1() {\n        let width = 1;\n        let text = \"abcd efghij klmnopabcd efgh ijklmnopabcdefg hijkl mnopab \";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);\n        let (line_truncator, _) = run_composer(Composer::LineTruncator, text, width);\n\n        let expected: Vec<&str> = UnicodeSegmentation::graphemes(text, true)\n            .filter(|g| g.chars().any(|c| !c.is_whitespace()))\n            .collect();\n        assert_eq!(word_wrapper, expected);\n        assert_eq!(line_truncator, vec![\"a\"]);\n    }\n\n    #[test]\n    fn line_composer_max_line_width_of_1_double_width_characters() {\n        let width = 1;\n        let text = \"コンピュータ上で文字を扱う場合、典型的には文字\\naaaによる通信を行う場合にその\\\n                    両端点では、\";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);\n        let (line_truncator, _) = run_composer(Composer::LineTruncator, text, width);\n        assert_eq!(word_wrapper, vec![\"\", \"a\", \"a\", \"a\"]);\n        assert_eq!(line_truncator, vec![\"\", \"a\"]);\n    }\n\n    /// Tests WordWrapper with words some of which exceed line length and some not.\n    #[test]\n    fn line_composer_word_wrapper_mixed_length() {\n        let width = 20;\n        let text = \"abcd efghij klmnopabcdefghijklmnopabcdefghijkl mnopab cdefghi j klmno\";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);\n        assert_eq!(\n            word_wrapper,\n            vec![\n                \"abcd efghij\",\n                \"klmnopabcdefghijklmn\",\n                \"opabcdefghijkl\",\n                \"mnopab cdefghi j\",\n                \"klmno\",\n            ]\n        )\n    }\n\n    #[test]\n    fn line_composer_double_width_chars() {\n        let width = 20;\n        let text = \"コンピュータ上で文字を扱う場合、典型的には文字による通信を行う場合にその両端点\\\n                    では、\";\n        let (word_wrapper, word_wrapper_width) =\n            run_composer(Composer::WordWrapper { trim: true }, text, width);\n        let (line_truncator, _) = run_composer(Composer::LineTruncator, text, width);\n        assert_eq!(line_truncator, vec![\"コンピュータ上で文字\"]);\n        let wrapped = vec![\n            \"コンピュータ上で文字\",\n            \"を扱う場合、典型的に\",\n            \"は文字による通信を行\",\n            \"う場合にその両端点で\",\n            \"は、\",\n        ];\n        assert_eq!(word_wrapper, wrapped);\n        assert_eq!(word_wrapper_width, vec![width, width, width, width, 4]);\n    }\n\n    #[test]\n    fn line_composer_leading_whitespace_removal() {\n        let width = 20;\n        let text = \"AAAAAAAAAAAAAAAAAAAA    AAA\";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);\n        let (line_truncator, _) = run_composer(Composer::LineTruncator, text, width);\n        assert_eq!(word_wrapper, vec![\"AAAAAAAAAAAAAAAAAAAA\", \"AAA\",]);\n        assert_eq!(line_truncator, vec![\"AAAAAAAAAAAAAAAAAAAA\"]);\n    }\n\n    /// Tests truncation of leading whitespace.\n    #[test]\n    fn line_composer_lots_of_spaces() {\n        let width = 20;\n        let text = \"                                                                     \";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);\n        let (line_truncator, _) = run_composer(Composer::LineTruncator, text, width);\n        assert_eq!(word_wrapper, vec![\"\"]);\n        assert_eq!(line_truncator, vec![\"                    \"]);\n    }\n\n    /// Tests an input starting with a letter, followed by spaces - some of the behaviour is\n    /// incidental.\n    #[test]\n    fn line_composer_char_plus_lots_of_spaces() {\n        let width = 20;\n        let text = \"a                                                                     \";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);\n        let (line_truncator, _) = run_composer(Composer::LineTruncator, text, width);\n        // What's happening below is: the first line gets consumed, trailing spaces discarded,\n        // after 20 of which a word break occurs (probably shouldn't). The second line break\n        // discards all whitespace. The result should probably be vec![\"a\"] but it doesn't matter\n        // that much.\n        assert_eq!(word_wrapper, vec![\"a\", \"\"]);\n        assert_eq!(line_truncator, vec![\"a                   \"]);\n    }\n\n    #[test]\n    fn line_composer_word_wrapper_double_width_chars_mixed_with_spaces() {\n        let width = 20;\n        // Japanese seems not to use spaces but we should break on spaces anyway... We're using it\n        // to test double-width chars.\n        // You are more than welcome to add word boundary detection based of alterations of\n        // hiragana and katakana...\n        // This happens to also be a test case for mixed width because regular spaces are single width.\n        let text = \"コンピュ ータ上で文字を扱う場合、 典型的には文 字による 通信を行 う場合にその両端点では、\";\n        let (word_wrapper, word_wrapper_width) =\n            run_composer(Composer::WordWrapper { trim: true }, text, width);\n        assert_eq!(\n            word_wrapper,\n            vec![\n                \"コンピュ\",\n                \"ータ上で文字を扱う場\",\n                \"合、 典型的には文\",\n                \"字による 通信を行\",\n                \"う場合にその両端点で\",\n                \"は、\",\n            ]\n        );\n        // Odd-sized lines have a space in them.\n        assert_eq!(word_wrapper_width, vec![8, 20, 17, 17, 20, 4]);\n    }\n\n    /// Ensure words separated by nbsp are wrapped as if they were a single one.\n    #[test]\n    fn line_composer_word_wrapper_nbsp() {\n        let width = 20;\n        let text = \"AAAAAAAAAAAAAAA AAAA\\u{00a0}AAA\";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);\n        assert_eq!(word_wrapper, vec![\"AAAAAAAAAAAAAAA\", \"AAAA\\u{00a0}AAA\",]);\n\n        // Ensure that if the character was a regular space, it would be wrapped differently.\n        let text_space = text.replace('\\u{00a0}', \" \");\n        let (word_wrapper_space, _) =\n            run_composer(Composer::WordWrapper { trim: true }, &text_space, width);\n        assert_eq!(word_wrapper_space, vec![\"AAAAAAAAAAAAAAA AAAA\", \"AAA\",]);\n    }\n\n    #[test]\n    fn line_composer_word_wrapper_nnbsp() {\n        let width = 20;\n        let text = \"AAAAAAAAAAAAAAA AAAA\\u{202f}AAA\";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: true }, text, width);\n        assert_eq!(word_wrapper, vec![\"AAAAAAAAAAAAAAA\", \"AAAA\\u{202f}AAA\",]);\n\n        // Ensure that if the character was a regular space, it would be wrapped differently.\n        let text_space = text.replace('\\u{202f}', \" \");\n        let (word_wrapper_space, _) =\n            run_composer(Composer::WordWrapper { trim: true }, &text_space, width);\n        assert_eq!(word_wrapper_space, vec![\"AAAAAAAAAAAAAAA AAAA\", \"AAA\",]);\n    }\n\n    #[test]\n    fn line_composer_word_wrapper_preserve_indentation() {\n        let width = 20;\n        let text = \"AAAAAAAAAAAAAAAAAAAA    AAA\";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: false }, text, width);\n        assert_eq!(word_wrapper, vec![\"AAAAAAAAAAAAAAAAAAAA\", \"   AAA\",]);\n    }\n\n    #[test]\n    fn line_composer_word_wrapper_preserve_indentation_with_wrap() {\n        let width = 10;\n        let text = \"AAA AAA AAAAA AA AAAAAA\\n B\\n  C\\n   D\";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: false }, text, width);\n        assert_eq!(\n            word_wrapper,\n            vec![\"AAA AAA\", \"AAAAA AA\", \"AAAAAA\", \" B\", \"  C\", \"   D\"]\n        );\n    }\n\n    #[test]\n    fn line_composer_word_wrapper_preserve_indentation_lots_of_whitespace() {\n        let width = 10;\n        let text = \"               4 Indent\\n                 must wrap!\";\n        let (word_wrapper, _) = run_composer(Composer::WordWrapper { trim: false }, text, width);\n        assert_eq!(\n            word_wrapper,\n            vec![\n                \"          \",\n                \"    4\",\n                \"Indent\",\n                \"          \",\n                \"      must\",\n                \"wrap!\"\n            ]\n        );\n    }\n}\n"
  },
  {
    "path": "helix-tui/src/widgets/table.rs",
    "content": "use crate::{\n    buffer::Buffer,\n    layout::Constraint,\n    text::Text,\n    widgets::{Block, Widget},\n};\nuse helix_core::unicode::width::UnicodeWidthStr;\nuse helix_view::graphics::{Rect, Style};\n\n/// A [`Cell`] contains the [`Text`] to be displayed in a [`Row`] of a [`Table`].\n///\n/// It can be created from anything that can be converted to a [`Text`].\n/// ```rust\n/// # use helix_tui::widgets::Cell;\n/// # use helix_tui::text::{Span, Spans, Text};\n/// # use helix_view::graphics::{Style, Modifier};\n/// Cell::from(\"simple string\");\n///\n/// Cell::from(Span::from(\"span\"));\n///\n/// Cell::from(Spans::from(vec![\n///     Span::raw(\"a vec of \"),\n///     Span::styled(\"spans\", Style::default().add_modifier(Modifier::BOLD))\n/// ]));\n///\n/// Cell::from(Text::from(\"a text\"));\n/// ```\n///\n/// You can apply a [`Style`] on the entire [`Cell`] using [`Cell::style`] or rely on the styling\n/// capabilities of [`Text`].\n#[derive(Debug, Clone, PartialEq, Eq, Default)]\npub struct Cell<'a> {\n    pub content: Text<'a>,\n    style: Style,\n}\n\nimpl Cell<'_> {\n    /// Set the `Style` of this cell.\n    pub fn style(mut self, style: Style) -> Self {\n        self.set_style(style);\n        self\n    }\n\n    /// Set the `Style` of this cell.\n    pub fn set_style(&mut self, style: Style) {\n        self.style = style;\n        self.content.patch_style(style);\n    }\n}\n\nimpl<'a, T> From<T> for Cell<'a>\nwhere\n    T: Into<Text<'a>>,\n{\n    fn from(content: T) -> Cell<'a> {\n        Cell {\n            content: content.into(),\n            style: Style::default(),\n        }\n    }\n}\n\n/// Holds data to be displayed in a [`Table`] widget.\n///\n/// A [`Row`] is a collection of cells. It can be created from simple strings:\n/// ```rust\n/// # use helix_tui::widgets::Row;\n/// Row::new(vec![\"Cell1\", \"Cell2\", \"Cell3\"]);\n/// ```\n///\n/// But if you need a bit more control over individual cells, you can explicitly create [`Cell`]s:\n/// ```rust\n/// # use helix_tui::widgets::{Row, Cell};\n/// # use helix_view::graphics::{Style, Color};\n/// Row::new(vec![\n///     Cell::from(\"Cell1\"),\n///     Cell::from(\"Cell2\").style(Style::default().fg(Color::Yellow)),\n/// ]);\n/// ```\n///\n/// By default, a row has a height of 1 but you can change this using [`Row::height`].\n#[derive(Debug, Clone, PartialEq, Eq, Default)]\npub struct Row<'a> {\n    pub cells: Vec<Cell<'a>>,\n    height: u16,\n    style: Style,\n    bottom_margin: u16,\n}\n\nimpl<'a> Row<'a> {\n    /// Creates a new [`Row`] from an iterator where items can be converted to a [`Cell`].\n    pub fn new<T>(cells: T) -> Self\n    where\n        T: IntoIterator,\n        T::Item: Into<Cell<'a>>,\n    {\n        Self {\n            height: 1,\n            cells: cells.into_iter().map(|c| c.into()).collect(),\n            style: Style::default(),\n            bottom_margin: 0,\n        }\n    }\n\n    /// Set the fixed height of the [`Row`]. Any [`Cell`] whose content has more lines than this\n    /// height will see its content truncated.\n    pub fn height(mut self, height: u16) -> Self {\n        self.height = height;\n        self\n    }\n\n    /// Set the [`Style`] of the entire row. This [`Style`] can be overridden by the [`Style`] of a\n    /// any individual [`Cell`] or event by their [`Text`] content.\n    pub fn style(mut self, style: Style) -> Self {\n        self.style = style;\n        self\n    }\n\n    /// Set the bottom margin. By default, the bottom margin is `0`.\n    pub fn bottom_margin(mut self, margin: u16) -> Self {\n        self.bottom_margin = margin;\n        self\n    }\n\n    /// Returns the total height of the row.\n    fn total_height(&self) -> u16 {\n        self.height.saturating_add(self.bottom_margin)\n    }\n\n    /// Returns the contents of cells as plain text, without styles and colors.\n    pub fn cell_text(&self) -> impl Iterator<Item = String> + '_ {\n        self.cells.iter().map(|cell| String::from(&cell.content))\n    }\n}\n\nimpl<'a, T: Into<Cell<'a>>> From<T> for Row<'a> {\n    fn from(cell: T) -> Self {\n        Row::new(vec![cell.into()])\n    }\n}\n\n/// A widget to display data in formatted columns.\n///\n/// It is a collection of [`Row`]s, themselves composed of [`Cell`]s:\n/// ```rust\n/// # use helix_tui::widgets::{Block, Borders, Table, Row, Cell};\n/// # use helix_tui::layout::Constraint;\n/// # use helix_view::graphics::{Style, Color, Modifier};\n/// # use helix_tui::text::{Text, Spans, Span};\n/// Table::new(vec![\n///     // Row can be created from simple strings.\n///     Row::new(vec![\"Row11\", \"Row12\", \"Row13\"]),\n///     // You can style the entire row.\n///     Row::new(vec![\"Row21\", \"Row22\", \"Row23\"]).style(Style::default().fg(Color::Blue)),\n///     // If you need more control over the styling you may need to create Cells directly\n///     Row::new(vec![\n///         Cell::from(\"Row31\"),\n///         Cell::from(\"Row32\").style(Style::default().fg(Color::Yellow)),\n///         Cell::from(Spans::from(vec![\n///             Span::raw(\"Row\"),\n///             Span::styled(\"33\", Style::default().fg(Color::Green))\n///         ])),\n///     ]),\n///     // If a Row need to display some content over multiple lines, you just have to change\n///     // its height.\n///     Row::new(vec![\n///         Cell::from(\"Row\\n41\"),\n///         Cell::from(\"Row\\n42\"),\n///         Cell::from(\"Row\\n43\"),\n///     ]).height(2),\n/// ])\n/// // You can set the style of the entire Table.\n/// .style(Style::default().fg(Color::White))\n/// // It has an optional header, which is simply a Row always visible at the top.\n/// .header(\n///     Row::new(vec![\"Col1\", \"Col2\", \"Col3\"])\n///         .style(Style::default().fg(Color::Yellow))\n///         // If you want some space between the header and the rest of the rows, you can always\n///         // specify some margin at the bottom.\n///         .bottom_margin(1)\n/// )\n/// // As any other widget, a Table can be wrapped in a Block.\n/// .block(Block::default().title(\"Table\"))\n/// // Columns widths are constrained in the same way as Layout...\n/// .widths(&[Constraint::Length(5), Constraint::Length(5), Constraint::Length(10)])\n/// // ...and they can be separated by a fixed spacing.\n/// .column_spacing(1)\n/// // If you wish to highlight a row in any specific way when it is selected...\n/// .highlight_style(Style::default().add_modifier(Modifier::BOLD))\n/// // ...and potentially show a symbol in front of the selection.\n/// .highlight_symbol(\">>\");\n/// ```\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct Table<'a> {\n    /// A block to wrap the widget in\n    block: Option<Block<'a>>,\n    /// Base style for the widget\n    style: Style,\n    /// Width constraints for each column\n    widths: &'a [Constraint],\n    /// Space between each column\n    column_spacing: u16,\n    /// Style used to render the selected row\n    highlight_style: Style,\n    /// Symbol in front of the selected rom\n    highlight_symbol: Option<&'a str>,\n    /// Optional header\n    header: Option<Row<'a>>,\n    /// Data to display in each row\n    rows: Vec<Row<'a>>,\n}\n\nimpl<'a> Table<'a> {\n    pub fn new<T>(rows: T) -> Self\n    where\n        T: IntoIterator<Item = Row<'a>>,\n    {\n        Self {\n            block: None,\n            style: Style::default(),\n            widths: &[],\n            column_spacing: 1,\n            highlight_style: Style::default(),\n            highlight_symbol: None,\n            header: None,\n            rows: rows.into_iter().collect(),\n        }\n    }\n\n    pub fn block(mut self, block: Block<'a>) -> Self {\n        self.block = Some(block);\n        self\n    }\n\n    pub fn header(mut self, header: Row<'a>) -> Self {\n        self.header = Some(header);\n        self\n    }\n\n    pub fn widths(mut self, widths: &'a [Constraint]) -> Self {\n        let between_0_and_100 = |&w| match w {\n            Constraint::Percentage(p) => p <= 100,\n            _ => true,\n        };\n        assert!(\n            widths.iter().all(between_0_and_100),\n            \"Percentages should be between 0 and 100 inclusively.\"\n        );\n        self.widths = widths;\n        self\n    }\n\n    pub fn style(mut self, style: Style) -> Self {\n        self.style = style;\n        self\n    }\n\n    pub fn highlight_symbol(mut self, highlight_symbol: &'a str) -> Self {\n        self.highlight_symbol = Some(highlight_symbol);\n        self\n    }\n\n    pub fn highlight_style(mut self, highlight_style: Style) -> Self {\n        self.highlight_style = highlight_style;\n        self\n    }\n\n    pub fn column_spacing(mut self, spacing: u16) -> Self {\n        self.column_spacing = spacing;\n        self\n    }\n\n    fn get_columns_widths(&self, max_width: u16, has_selection: bool) -> Vec<u16> {\n        let mut constraints = Vec::with_capacity(self.widths.len() * 2 + 1);\n        if has_selection {\n            let highlight_symbol_width =\n                self.highlight_symbol.map(|s| s.width() as u16).unwrap_or(0);\n            constraints.push(Constraint::Length(highlight_symbol_width));\n        }\n        for constraint in self.widths {\n            constraints.push(*constraint);\n            constraints.push(Constraint::Length(self.column_spacing));\n        }\n        if !self.widths.is_empty() {\n            constraints.pop();\n        }\n        let mut chunks = crate::layout::Layout::default()\n            .direction(crate::layout::Direction::Horizontal)\n            .constraints(constraints)\n            .split(Rect {\n                x: 0,\n                y: 0,\n                width: max_width,\n                height: 1,\n            });\n        if has_selection {\n            chunks.remove(0);\n        }\n        chunks.iter().step_by(2).map(|c| c.width).collect()\n    }\n\n    fn get_row_bounds(\n        &self,\n        selected: Option<usize>,\n        offset: usize,\n        max_height: u16,\n    ) -> (usize, usize) {\n        let mut start = offset;\n        let mut end = offset;\n        let mut height = 0;\n        for item in self.rows.iter().skip(offset) {\n            if height + item.height > max_height {\n                break;\n            }\n            height += item.total_height();\n            end += 1;\n        }\n\n        let selected = selected.unwrap_or(0).min(self.rows.len() - 1);\n        while selected >= end {\n            height = height.saturating_add(self.rows[end].total_height());\n            end += 1;\n            while height > max_height {\n                height = height.saturating_sub(self.rows[start].total_height());\n                start += 1;\n            }\n        }\n        while selected < start {\n            start -= 1;\n            height = height.saturating_add(self.rows[start].total_height());\n            while height > max_height {\n                end -= 1;\n                height = height.saturating_sub(self.rows[end].total_height());\n            }\n        }\n        (start, end)\n    }\n}\n\n/// Track [Table] scroll offset and selection\n#[derive(Debug, Default, Clone)]\npub struct TableState {\n    pub offset: usize,\n    pub selected: Option<usize>,\n}\n\nimpl TableState {\n    pub fn selected(&self) -> Option<usize> {\n        self.selected\n    }\n\n    pub fn select(&mut self, index: Option<usize>) {\n        self.selected = index;\n        if index.is_none() {\n            self.offset = 0;\n        }\n    }\n}\n\n// impl<'a> StatefulWidget for Table<'a> {\nimpl Table<'_> {\n    // type State = TableState;\n\n    pub fn render_table(\n        mut self,\n        area: Rect,\n        buf: &mut Buffer,\n        state: &mut TableState,\n        truncate: bool,\n    ) {\n        if area.area() == 0 {\n            return;\n        }\n        buf.set_style(area, self.style);\n        let table_area = match self.block.take() {\n            Some(b) => {\n                let inner_area = b.inner(area);\n                b.render(area, buf);\n                inner_area\n            }\n            None => area,\n        };\n\n        let has_selection = state.selected.is_some();\n        let columns_widths = self.get_columns_widths(table_area.width, has_selection);\n        let highlight_symbol = self.highlight_symbol.unwrap_or(\"\");\n        let blank_symbol = \" \".repeat(highlight_symbol.width());\n        let mut current_height = 0;\n        let mut rows_height = table_area.height;\n\n        // Draw header\n        if let Some(ref header) = self.header {\n            let max_header_height = table_area.height.min(header.total_height());\n            buf.set_style(\n                Rect {\n                    x: table_area.left(),\n                    y: table_area.top(),\n                    width: table_area.width,\n                    height: table_area.height.min(header.height),\n                },\n                header.style,\n            );\n            let mut col = table_area.left();\n            if has_selection {\n                col += (highlight_symbol.width() as u16).min(table_area.width);\n            }\n            for (width, cell) in columns_widths.iter().zip(header.cells.iter()) {\n                render_cell(\n                    buf,\n                    cell,\n                    Rect {\n                        x: col,\n                        y: table_area.top(),\n                        width: *width,\n                        height: max_header_height,\n                    },\n                    truncate,\n                );\n                col += *width + self.column_spacing;\n            }\n            current_height += max_header_height;\n            rows_height = rows_height.saturating_sub(max_header_height);\n        }\n\n        // Draw rows\n        if self.rows.is_empty() {\n            return;\n        }\n        let (start, end) = self.get_row_bounds(state.selected, state.offset, rows_height);\n        state.offset = start;\n        for (i, table_row) in self\n            .rows\n            .iter_mut()\n            .enumerate()\n            .skip(state.offset)\n            .take(end - start)\n        {\n            let (row, col) = (table_area.top() + current_height, table_area.left());\n            current_height += table_row.total_height();\n            let table_row_area = Rect {\n                x: col,\n                y: row,\n                width: table_area.width,\n                height: table_row.height,\n            };\n            buf.set_style(table_row_area, table_row.style);\n            let is_selected = state.selected.map(|s| s == i).unwrap_or(false);\n            let table_row_start_col = if has_selection {\n                let symbol = if is_selected {\n                    highlight_symbol\n                } else {\n                    &blank_symbol\n                };\n                let (col, _) =\n                    buf.set_stringn(col, row, symbol, table_area.width as usize, table_row.style);\n                col\n            } else {\n                col\n            };\n            if is_selected {\n                buf.set_style(table_row_area, self.highlight_style);\n                for cell in &mut table_row.cells {\n                    cell.set_style(self.highlight_style);\n                }\n            }\n            let mut col = table_row_start_col;\n            for (width, cell) in columns_widths.iter().zip(table_row.cells.iter()) {\n                render_cell(\n                    buf,\n                    cell,\n                    Rect {\n                        x: col,\n                        y: row,\n                        width: *width,\n                        height: table_row.height,\n                    },\n                    truncate,\n                );\n                col += *width + self.column_spacing;\n            }\n        }\n    }\n}\n\nfn render_cell(buf: &mut Buffer, cell: &Cell, area: Rect, truncate: bool) {\n    buf.set_style(area, cell.style);\n    for (i, spans) in cell.content.lines.iter().enumerate() {\n        if i as u16 >= area.height {\n            break;\n        }\n        if truncate {\n            buf.set_spans_truncated(area.x, area.y + i as u16, spans, area.width);\n        } else {\n            buf.set_spans(area.x, area.y + i as u16, spans, area.width);\n        }\n    }\n}\n\nimpl Widget for Table<'_> {\n    fn render(self, area: Rect, buf: &mut Buffer) {\n        let mut state = TableState::default();\n        Table::render_table(self, area, buf, &mut state, false);\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    #[should_panic]\n    fn table_invalid_percentages() {\n        Table::new(vec![]).widths(&[Constraint::Percentage(110)]);\n    }\n}\n"
  },
  {
    "path": "helix-tui/tests/terminal.rs",
    "content": "use helix_tui::{\n    backend::{Backend, TestBackend},\n    Terminal,\n};\n\n#[test]\nfn terminal_buffer_size_should_not_be_limited() {\n    let backend = TestBackend::new(400, 400);\n    let terminal = Terminal::new(backend).unwrap();\n    let size = terminal.backend().size().unwrap();\n    assert_eq!(size.width, 400);\n    assert_eq!(size.height, 400);\n}\n\n// #[test]\n// fn terminal_draw_returns_the_completed_frame() -> Result<(), Box<dyn Error>> {\n//     let backend = TestBackend::new(10, 10);\n//     let mut terminal = Terminal::new(backend)?;\n//     let frame = terminal.draw(|f| {\n//         let text = Text::from(\"Test\");\n//         let paragraph = Paragraph::new(&text);\n//         f.render_widget(paragraph, f.size());\n//     })?;\n//     assert_eq!(frame.buffer.get(0, 0).symbol, \"T\");\n//     assert_eq!(frame.area, Rect::new(0, 0, 10, 10));\n//     terminal.backend_mut().resize(8, 8);\n//     let frame = terminal.draw(|f| {\n//         let text = Text::from(\"test\");\n//         let paragraph = Paragraph::new(&text);\n//         f.render_widget(paragraph, f.size());\n//     })?;\n//     assert_eq!(frame.buffer.get(0, 0).symbol, \"t\");\n//     assert_eq!(frame.area, Rect::new(0, 0, 8, 8));\n//     Ok(())\n// }\n"
  },
  {
    "path": "helix-tui/tests/text.rs",
    "content": "use helix_tui::text::{Span, Spans, StyledGrapheme, Text};\nuse helix_view::graphics::{Color, Modifier, Style};\n\n// Text\n#[test]\nfn text_width() {\n    let text = Text::from(\"The first line\\nThe second line\");\n    assert_eq!(15, text.width());\n}\n\n#[test]\nfn text_height() {\n    let text = Text::from(\"The first line\\nThe second line\");\n    assert_eq!(2, text.height());\n}\n\n#[test]\nfn patch_style() {\n    let style1 = Style::default().fg(Color::Yellow);\n    let style2 = Style::default().fg(Color::Yellow).bg(Color::Black);\n    let mut half_styled_text =\n        Text::styled(String::from(\"The first line\\nThe second line\"), style1);\n    let full_styled_text = Text::styled(String::from(\"The first line\\nThe second line\"), style2);\n    assert_ne!(half_styled_text, full_styled_text);\n\n    half_styled_text.patch_style(Style::default().bg(Color::Black));\n    assert_eq!(half_styled_text, full_styled_text);\n}\n\n#[test]\nfn set_style() {\n    let style = Style::default()\n        .fg(Color::Yellow)\n        .add_modifier(Modifier::ITALIC);\n    let mut raw_text = Text::raw(\"The first line\\nThe second line\");\n    let styled_text = Text::styled(String::from(\"The first line\\nThe second line\"), style);\n    assert_ne!(raw_text, styled_text);\n\n    raw_text.set_style(style);\n    assert_eq!(raw_text, styled_text);\n}\n\n#[test]\nfn text_extend() {\n    let style = Style::default()\n        .fg(Color::Yellow)\n        .add_modifier(Modifier::ITALIC);\n    let mut text = Text::from(\"The first line\\nThe second line\");\n    assert_eq!(2, text.height());\n\n    // Adding two more unstyled lines\n    text.extend(Text::raw(\"These are two\\nmore lines!\"));\n    assert_eq!(4, text.height());\n\n    // Adding a final two styled lines\n    text.extend(Text::styled(\"Some more lines\\nnow with more style!\", style));\n    assert_eq!(6, text.height());\n}\n\n// Span\n\n#[test]\nfn styled_graphemes() {\n    let style = Style::default().fg(Color::Yellow);\n    let span = Span::styled(\"Text\", style);\n    let style = Style::default().fg(Color::Green).bg(Color::Black);\n    let styled_graphemes = span.styled_graphemes(style);\n    assert_eq!(\n        vec![\n            StyledGrapheme {\n                symbol: \"T\",\n                style: Style {\n                    fg: Some(Color::Yellow),\n                    bg: Some(Color::Black),\n                    underline_color: None,\n                    underline_style: None,\n                    add_modifier: Modifier::empty(),\n                    sub_modifier: Modifier::empty(),\n                },\n            },\n            StyledGrapheme {\n                symbol: \"e\",\n                style: Style {\n                    fg: Some(Color::Yellow),\n                    bg: Some(Color::Black),\n                    underline_color: None,\n                    underline_style: None,\n                    add_modifier: Modifier::empty(),\n                    sub_modifier: Modifier::empty(),\n                },\n            },\n            StyledGrapheme {\n                symbol: \"x\",\n                style: Style {\n                    fg: Some(Color::Yellow),\n                    bg: Some(Color::Black),\n                    underline_color: None,\n                    underline_style: None,\n                    add_modifier: Modifier::empty(),\n                    sub_modifier: Modifier::empty(),\n                },\n            },\n            StyledGrapheme {\n                symbol: \"t\",\n                style: Style {\n                    fg: Some(Color::Yellow),\n                    bg: Some(Color::Black),\n                    underline_color: None,\n                    underline_style: None,\n                    add_modifier: Modifier::empty(),\n                    sub_modifier: Modifier::empty(),\n                },\n            },\n        ],\n        styled_graphemes.collect::<Vec<StyledGrapheme>>()\n    );\n}\n\n// Spans\n\n#[test]\nfn spans_width() {\n    let spans = Spans::from(vec![\n        Span::styled(\"My\", Style::default().fg(Color::Yellow)),\n        Span::raw(\" text\"),\n    ]);\n    assert_eq!(7, spans.width());\n}\n"
  },
  {
    "path": "helix-tui/tests/widgets_block.rs",
    "content": "// use helix_tui::{\n//     backend::TestBackend,\n//     buffer::Buffer,\n//     layout::Rect,\n//     style::{Color, Style},\n//     text::Span,\n//     widgets::{Block, Borders},\n//     Terminal,\n// };\n\n// #[test]\n// fn widgets_block_renders() {\n//     let backend = TestBackend::new(10, 10);\n//     let mut terminal = Terminal::new(backend).unwrap();\n//     terminal\n//         .draw(|f| {\n//             let block = Block::default()\n//                 .title(Span::styled(\"Title\", Style::default().fg(Color::LightBlue)))\n//                 .borders(Borders::ALL);\n//             f.render_widget(\n//                 block,\n//                 Rect {\n//                     x: 0,\n//                     y: 0,\n//                     width: 8,\n//                     height: 8,\n//                 },\n//             );\n//         })\n//         .unwrap();\n//     let mut expected = Buffer::with_lines(vec![\n//         \"┌Title─┐  \",\n//         \"│      │  \",\n//         \"│      │  \",\n//         \"│      │  \",\n//         \"│      │  \",\n//         \"│      │  \",\n//         \"│      │  \",\n//         \"└──────┘  \",\n//         \"          \",\n//         \"          \",\n//     ]);\n//     for x in 1..=5 {\n//         expected.get_mut(x, 0).set_fg(Color::LightBlue);\n//     }\n//     terminal.backend().assert_buffer(&expected);\n// }\n\n// #[test]\n// fn widgets_block_renders_on_small_areas() {\n//     let test_case = |block, area: Rect, expected| {\n//         let backend = TestBackend::new(area.width, area.height);\n//         let mut terminal = Terminal::new(backend).unwrap();\n//         terminal\n//             .draw(|f| {\n//                 f.render_widget(block, area);\n//             })\n//             .unwrap();\n//         terminal.backend().assert_buffer(&expected);\n//     };\n\n//     let one_cell_test_cases = [\n//         (Borders::NONE, \"T\"),\n//         (Borders::LEFT, \"│\"),\n//         (Borders::TOP, \"T\"),\n//         (Borders::RIGHT, \"│\"),\n//         (Borders::BOTTOM, \"T\"),\n//         (Borders::ALL, \"┌\"),\n//     ];\n//     for (borders, symbol) in one_cell_test_cases.iter().cloned() {\n//         test_case(\n//             Block::default().title(\"Test\").borders(borders),\n//             Rect {\n//                 x: 0,\n//                 y: 0,\n//                 width: 0,\n//                 height: 0,\n//             },\n//             Buffer::empty(Rect {\n//                 x: 0,\n//                 y: 0,\n//                 width: 0,\n//                 height: 0,\n//             }),\n//         );\n//         test_case(\n//             Block::default().title(\"Test\").borders(borders),\n//             Rect {\n//                 x: 0,\n//                 y: 0,\n//                 width: 1,\n//                 height: 0,\n//             },\n//             Buffer::empty(Rect {\n//                 x: 0,\n//                 y: 0,\n//                 width: 1,\n//                 height: 0,\n//             }),\n//         );\n//         test_case(\n//             Block::default().title(\"Test\").borders(borders),\n//             Rect {\n//                 x: 0,\n//                 y: 0,\n//                 width: 0,\n//                 height: 1,\n//             },\n//             Buffer::empty(Rect {\n//                 x: 0,\n//                 y: 0,\n//                 width: 0,\n//                 height: 1,\n//             }),\n//         );\n//         test_case(\n//             Block::default().title(\"Test\").borders(borders),\n//             Rect {\n//                 x: 0,\n//                 y: 0,\n//                 width: 1,\n//                 height: 1,\n//             },\n//             Buffer::with_lines(vec![symbol]),\n//         );\n//     }\n//     test_case(\n//         Block::default().title(\"Test\").borders(Borders::LEFT),\n//         Rect {\n//             x: 0,\n//             y: 0,\n//             width: 4,\n//             height: 1,\n//         },\n//         Buffer::with_lines(vec![\"│Tes\"]),\n//     );\n//     test_case(\n//         Block::default().title(\"Test\").borders(Borders::RIGHT),\n//         Rect {\n//             x: 0,\n//             y: 0,\n//             width: 4,\n//             height: 1,\n//         },\n//         Buffer::with_lines(vec![\"Tes│\"]),\n//     );\n//     test_case(\n//         Block::default().title(\"Test\").borders(Borders::RIGHT),\n//         Rect {\n//             x: 0,\n//             y: 0,\n//             width: 4,\n//             height: 1,\n//         },\n//         Buffer::with_lines(vec![\"Tes│\"]),\n//     );\n//     test_case(\n//         Block::default()\n//             .title(\"Test\")\n//             .borders(Borders::LEFT | Borders::RIGHT),\n//         Rect {\n//             x: 0,\n//             y: 0,\n//             width: 4,\n//             height: 1,\n//         },\n//         Buffer::with_lines(vec![\"│Te│\"]),\n//     );\n//     test_case(\n//         Block::default().title(\"Test\").borders(Borders::TOP),\n//         Rect {\n//             x: 0,\n//             y: 0,\n//             width: 4,\n//             height: 1,\n//         },\n//         Buffer::with_lines(vec![\"Test\"]),\n//     );\n//     test_case(\n//         Block::default().title(\"Test\").borders(Borders::TOP),\n//         Rect {\n//             x: 0,\n//             y: 0,\n//             width: 5,\n//             height: 1,\n//         },\n//         Buffer::with_lines(vec![\"Test─\"]),\n//     );\n//     test_case(\n//         Block::default()\n//             .title(\"Test\")\n//             .borders(Borders::LEFT | Borders::TOP),\n//         Rect {\n//             x: 0,\n//             y: 0,\n//             width: 5,\n//             height: 1,\n//         },\n//         Buffer::with_lines(vec![\"┌Test\"]),\n//     );\n//     test_case(\n//         Block::default()\n//             .title(\"Test\")\n//             .borders(Borders::LEFT | Borders::TOP),\n//         Rect {\n//             x: 0,\n//             y: 0,\n//             width: 6,\n//             height: 1,\n//         },\n//         Buffer::with_lines(vec![\"┌Test─\"]),\n//     );\n// }\n"
  },
  {
    "path": "helix-tui/tests/widgets_list.rs",
    "content": "// use helix_tui::{\n//     backend::TestBackend,\n//     buffer::Buffer,\n//     layout::Rect,\n//     style::{Color, Style},\n//     symbols,\n//     widgets::{Block, Borders, List, ListItem, ListState},\n//     Terminal,\n// };\n\n// #[test]\n// fn widgets_list_should_highlight_the_selected_item() {\n//     let backend = TestBackend::new(10, 3);\n//     let mut terminal = Terminal::new(backend).unwrap();\n//     let mut state = ListState::default();\n//     state.select(Some(1));\n//     terminal\n//         .draw(|f| {\n//             let size = f.size();\n//             let items = vec![\n//                 ListItem::new(\"Item 1\"),\n//                 ListItem::new(\"Item 2\"),\n//                 ListItem::new(\"Item 3\"),\n//             ];\n//             let list = List::new(items)\n//                 .highlight_style(Style::default().bg(Color::Yellow))\n//                 .highlight_symbol(\">> \");\n//             f.render_stateful_widget(list, size, &mut state);\n//         })\n//         .unwrap();\n//     let mut expected = Buffer::with_lines(vec![\"   Item 1 \", \">> Item 2 \", \"   Item 3 \"]);\n//     for x in 0..10 {\n//         expected.get_mut(x, 1).set_bg(Color::Yellow);\n//     }\n//     terminal.backend().assert_buffer(&expected);\n// }\n\n// #[test]\n// fn widgets_list_should_truncate_items() {\n//     let backend = TestBackend::new(10, 2);\n//     let mut terminal = Terminal::new(backend).unwrap();\n\n//     struct TruncateTestCase<'a> {\n//         selected: Option<usize>,\n//         items: Vec<ListItem<'a>>,\n//         expected: Buffer,\n//     }\n\n//     let cases = vec![\n//         // An item is selected\n//         TruncateTestCase {\n//             selected: Some(0),\n//             items: vec![\n//                 ListItem::new(\"A very long line\"),\n//                 ListItem::new(\"A very long line\"),\n//             ],\n//             expected: Buffer::with_lines(vec![\n//                 format!(\">> A ve{}  \", symbols::line::VERTICAL),\n//                 format!(\"   A ve{}  \", symbols::line::VERTICAL),\n//             ]),\n//         },\n//         // No item is selected\n//         TruncateTestCase {\n//             selected: None,\n//             items: vec![\n//                 ListItem::new(\"A very long line\"),\n//                 ListItem::new(\"A very long line\"),\n//             ],\n//             expected: Buffer::with_lines(vec![\n//                 format!(\"A very {}  \", symbols::line::VERTICAL),\n//                 format!(\"A very {}  \", symbols::line::VERTICAL),\n//             ]),\n//         },\n//     ];\n//     for case in cases {\n//         let mut state = ListState::default();\n//         state.select(case.selected);\n//         terminal\n//             .draw(|f| {\n//                 let list = List::new(case.items.clone())\n//                     .block(Block::default().borders(Borders::RIGHT))\n//                     .highlight_symbol(\">> \");\n//                 f.render_stateful_widget(list, Rect::new(0, 0, 8, 2), &mut state);\n//             })\n//             .unwrap();\n//         terminal.backend().assert_buffer(&case.expected);\n//     }\n// }\n"
  },
  {
    "path": "helix-tui/tests/widgets_paragraph.rs",
    "content": "// use helix_tui::{\n//     backend::TestBackend,\n//     buffer::Buffer,\n//     layout::Alignment,\n//     text::{Span, Spans, Text},\n//     widgets::{Block, Borders, Paragraph, Wrap},\n//     Terminal,\n// };\n\n// const SAMPLE_STRING: &str = \"The library is based on the principle of immediate rendering with \\\n//      intermediate buffers. This means that at each new frame you should build all widgets that are \\\n//      supposed to be part of the UI. While providing a great flexibility for rich and \\\n//      interactive UI, this may introduce overhead for highly dynamic content.\";\n\n// #[test]\n// fn widgets_paragraph_can_wrap_its_content() {\n//     let test_case = |alignment, expected| {\n//         let backend = TestBackend::new(20, 10);\n//         let mut terminal = Terminal::new(backend).unwrap();\n\n//         terminal\n//             .draw(|f| {\n//                 let size = f.size();\n//                 let text = Text::from(SAMPLE_STRING);\n//                 let paragraph = Paragraph::new(&text)\n//                     .block(Block::bordered())\n//                     .alignment(alignment)\n//                     .wrap(Wrap { trim: true });\n//                 f.render_widget(paragraph, size);\n//             })\n//             .unwrap();\n//         terminal.backend().assert_buffer(&expected);\n//     };\n\n//     test_case(\n//         Alignment::Left,\n//         Buffer::with_lines(vec![\n//             \"┌──────────────────┐\",\n//             \"│The library is    │\",\n//             \"│based on the      │\",\n//             \"│principle of      │\",\n//             \"│immediate         │\",\n//             \"│rendering with    │\",\n//             \"│intermediate      │\",\n//             \"│buffers. This     │\",\n//             \"│means that at each│\",\n//             \"└──────────────────┘\",\n//         ]),\n//     );\n//     test_case(\n//         Alignment::Right,\n//         Buffer::with_lines(vec![\n//             \"┌──────────────────┐\",\n//             \"│    The library is│\",\n//             \"│      based on the│\",\n//             \"│      principle of│\",\n//             \"│         immediate│\",\n//             \"│    rendering with│\",\n//             \"│      intermediate│\",\n//             \"│     buffers. This│\",\n//             \"│means that at each│\",\n//             \"└──────────────────┘\",\n//         ]),\n//     );\n//     test_case(\n//         Alignment::Center,\n//         Buffer::with_lines(vec![\n//             \"┌──────────────────┐\",\n//             \"│  The library is  │\",\n//             \"│   based on the   │\",\n//             \"│   principle of   │\",\n//             \"│     immediate    │\",\n//             \"│  rendering with  │\",\n//             \"│   intermediate   │\",\n//             \"│   buffers. This  │\",\n//             \"│means that at each│\",\n//             \"└──────────────────┘\",\n//         ]),\n//     );\n// }\n\n// #[test]\n// fn widgets_paragraph_renders_double_width_graphemes() {\n//     let backend = TestBackend::new(10, 10);\n//     let mut terminal = Terminal::new(backend).unwrap();\n\n//     let s = \"コンピュータ上で文字を扱う場合、典型的には文字による通信を行う場合にその両端点では、\";\n//     terminal\n//         .draw(|f| {\n//             let size = f.size();\n//             let text = Text::from(s);\n//             let paragraph = Paragraph::new(&text)\n//                 .block(Block::bordered())\n//                 .wrap(Wrap { trim: true });\n//             f.render_widget(paragraph, size);\n//         })\n//         .unwrap();\n\n//     let expected = Buffer::with_lines(vec![\n//         \"┌────────┐\",\n//         \"│コンピュ│\",\n//         \"│ータ上で│\",\n//         \"│文字を扱│\",\n//         \"│う場合、│\",\n//         \"│典型的に│\",\n//         \"│は文字に│\",\n//         \"│よる通信│\",\n//         \"│を行う場│\",\n//         \"└────────┘\",\n//     ]);\n//     terminal.backend().assert_buffer(&expected);\n// }\n\n// #[test]\n// fn widgets_paragraph_renders_mixed_width_graphemes() {\n//     let backend = TestBackend::new(10, 7);\n//     let mut terminal = Terminal::new(backend).unwrap();\n\n//     let s = \"aコンピュータ上で文字を扱う場合、\";\n//     terminal\n//         .draw(|f| {\n//             let size = f.size();\n//             let text = Text::from(s);\n//             let paragraph = Paragraph::new(&text)\n//                 .block(Block::bordered())\n//                 .wrap(Wrap { trim: true });\n//             f.render_widget(paragraph, size);\n//         })\n//         .unwrap();\n\n//     let expected = Buffer::with_lines(vec![\n//         // The internal width is 8 so only 4 slots for double-width characters.\n//         \"┌────────┐\",\n//         \"│aコンピ │\", // Here we have 1 latin character so only 3 double-width ones can fit.\n//         \"│ュータ上│\",\n//         \"│で文字を│\",\n//         \"│扱う場合│\",\n//         \"│、      │\",\n//         \"└────────┘\",\n//     ]);\n//     terminal.backend().assert_buffer(&expected);\n// }\n\n// #[test]\n// fn widgets_paragraph_can_wrap_with_a_trailing_nbsp() {\n//     let nbsp: &str = \"\\u{00a0}\";\n//     let line = Spans::from(vec![Span::raw(\"NBSP\"), Span::raw(nbsp)]);\n//     let backend = TestBackend::new(20, 3);\n//     let mut terminal = Terminal::new(backend).unwrap();\n//     let expected = Buffer::with_lines(vec![\n//         \"┌──────────────────┐\",\n//         \"│NBSP\\u{00a0}             │\",\n//         \"└──────────────────┘\",\n//     ]);\n//     terminal\n//         .draw(|f| {\n//             let size = f.size();\n//             let text = Text::from(line);\n//             let paragraph = Paragraph::new(&text).block(Block::bordered());\n//             f.render_widget(paragraph, size);\n//         })\n//         .unwrap();\n//     terminal.backend().assert_buffer(&expected);\n// }\n// #[test]\n// fn widgets_paragraph_can_scroll_horizontally() {\n//     let test_case = |alignment, scroll, expected| {\n//         let backend = TestBackend::new(20, 10);\n//         let mut terminal = Terminal::new(backend).unwrap();\n\n//         terminal\n//             .draw(|f| {\n//                 let size = f.size();\n//                 let text = Text::from(\n//                     \"段落现在可以水平滚动了！\\nParagraph can scroll horizontally!\\nShort line\",\n//                 );\n//                 let paragraph = Paragraph::new(&text)\n//                     .block(Block::bordered())\n//                     .alignment(alignment)\n//                     .scroll(scroll);\n//                 f.render_widget(paragraph, size);\n//             })\n//             .unwrap();\n//         terminal.backend().assert_buffer(&expected);\n//     };\n\n//     test_case(\n//         Alignment::Left,\n//         (0, 7),\n//         Buffer::with_lines(vec![\n//             \"┌──────────────────┐\",\n//             \"│在可以水平滚动了！│\",\n//             \"│ph can scroll hori│\",\n//             \"│ine               │\",\n//             \"│                  │\",\n//             \"│                  │\",\n//             \"│                  │\",\n//             \"│                  │\",\n//             \"│                  │\",\n//             \"└──────────────────┘\",\n//         ]),\n//     );\n//     // only support Alignment::Left\n//     test_case(\n//         Alignment::Right,\n//         (0, 7),\n//         Buffer::with_lines(vec![\n//             \"┌──────────────────┐\",\n//             \"│段落现在可以水平滚│\",\n//             \"│Paragraph can scro│\",\n//             \"│        Short line│\",\n//             \"│                  │\",\n//             \"│                  │\",\n//             \"│                  │\",\n//             \"│                  │\",\n//             \"│                  │\",\n//             \"└──────────────────┘\",\n//         ]),\n//     );\n// }\n"
  },
  {
    "path": "helix-tui/tests/widgets_table.rs",
    "content": "// use helix_tui::{\n//     backend::TestBackend,\n//     buffer::Buffer,\n//     layout::Constraint,\n//     style::{Color, Modifier, Style},\n//     text::{Span, Spans},\n//     widgets::{Block, Borders, Cell, Row, Table, TableState},\n//     Terminal,\n// };\n\n// #[test]\n// fn widgets_table_column_spacing_can_be_changed() {\n//     let test_case = |column_spacing, expected| {\n//         let backend = TestBackend::new(30, 10);\n//         let mut terminal = Terminal::new(backend).unwrap();\n\n//         terminal\n//             .draw(|f| {\n//                 let size = f.size();\n//                 let table = Table::new(vec![\n//                     Row::new(vec![\"Row11\", \"Row12\", \"Row13\"]),\n//                     Row::new(vec![\"Row21\", \"Row22\", \"Row23\"]),\n//                     Row::new(vec![\"Row31\", \"Row32\", \"Row33\"]),\n//                     Row::new(vec![\"Row41\", \"Row42\", \"Row43\"]),\n//                 ])\n//                 .header(Row::new(vec![\"Head1\", \"Head2\", \"Head3\"]).bottom_margin(1))\n//                 .block(Block::bordered())\n//                 .widths(&[\n//                     Constraint::Length(5),\n//                     Constraint::Length(5),\n//                     Constraint::Length(5),\n//                 ])\n//                 .column_spacing(column_spacing);\n//                 f.render_widget(table, size);\n//             })\n//             .unwrap();\n//         terminal.backend().assert_buffer(&expected);\n//     };\n\n//     // no space between columns\n//     test_case(\n//         0,\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1Head2Head3             │\",\n//             \"│                            │\",\n//             \"│Row11Row12Row13             │\",\n//             \"│Row21Row22Row23             │\",\n//             \"│Row31Row32Row33             │\",\n//             \"│Row41Row42Row43             │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // one space between columns\n//     test_case(\n//         1,\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1 Head2 Head3           │\",\n//             \"│                            │\",\n//             \"│Row11 Row12 Row13           │\",\n//             \"│Row21 Row22 Row23           │\",\n//             \"│Row31 Row32 Row33           │\",\n//             \"│Row41 Row42 Row43           │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // enough space to just not hide the third column\n//     test_case(\n//         6,\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1      Head2      Head3 │\",\n//             \"│                            │\",\n//             \"│Row11      Row12      Row13 │\",\n//             \"│Row21      Row22      Row23 │\",\n//             \"│Row31      Row32      Row33 │\",\n//             \"│Row41      Row42      Row43 │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // enough space to hide part of the third column\n//     test_case(\n//         7,\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1       Head2       Head│\",\n//             \"│                            │\",\n//             \"│Row11       Row12       Row1│\",\n//             \"│Row21       Row22       Row2│\",\n//             \"│Row31       Row32       Row3│\",\n//             \"│Row41       Row42       Row4│\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n// }\n\n// #[test]\n// fn widgets_table_columns_widths_can_use_fixed_length_constraints() {\n//     let test_case = |widths, expected| {\n//         let backend = TestBackend::new(30, 10);\n//         let mut terminal = Terminal::new(backend).unwrap();\n\n//         terminal\n//             .draw(|f| {\n//                 let size = f.size();\n//                 let table = Table::new(vec![\n//                     Row::new(vec![\"Row11\", \"Row12\", \"Row13\"]),\n//                     Row::new(vec![\"Row21\", \"Row22\", \"Row23\"]),\n//                     Row::new(vec![\"Row31\", \"Row32\", \"Row33\"]),\n//                     Row::new(vec![\"Row41\", \"Row42\", \"Row43\"]),\n//                 ])\n//                 .header(Row::new(vec![\"Head1\", \"Head2\", \"Head3\"]).bottom_margin(1))\n//                 .block(Block::bordered())\n//                 .widths(widths);\n//                 f.render_widget(table, size);\n//             })\n//             .unwrap();\n//         terminal.backend().assert_buffer(&expected);\n//     };\n\n//     // columns of zero width show nothing\n//     test_case(\n//         &[\n//             Constraint::Length(0),\n//             Constraint::Length(0),\n//             Constraint::Length(0),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // columns of 1 width trim\n//     test_case(\n//         &[\n//             Constraint::Length(1),\n//             Constraint::Length(1),\n//             Constraint::Length(1),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│H H H                       │\",\n//             \"│                            │\",\n//             \"│R R R                       │\",\n//             \"│R R R                       │\",\n//             \"│R R R                       │\",\n//             \"│R R R                       │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // columns of large width just before pushing a column off\n//     test_case(\n//         &[\n//             Constraint::Length(8),\n//             Constraint::Length(8),\n//             Constraint::Length(8),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1    Head2    Head3     │\",\n//             \"│                            │\",\n//             \"│Row11    Row12    Row13     │\",\n//             \"│Row21    Row22    Row23     │\",\n//             \"│Row31    Row32    Row33     │\",\n//             \"│Row41    Row42    Row43     │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n// }\n\n// #[test]\n// fn widgets_table_columns_widths_can_use_percentage_constraints() {\n//     let test_case = |widths, expected| {\n//         let backend = TestBackend::new(30, 10);\n//         let mut terminal = Terminal::new(backend).unwrap();\n\n//         terminal\n//             .draw(|f| {\n//                 let size = f.size();\n//                 let table = Table::new(vec![\n//                     Row::new(vec![\"Row11\", \"Row12\", \"Row13\"]),\n//                     Row::new(vec![\"Row21\", \"Row22\", \"Row23\"]),\n//                     Row::new(vec![\"Row31\", \"Row32\", \"Row33\"]),\n//                     Row::new(vec![\"Row41\", \"Row42\", \"Row43\"]),\n//                 ])\n//                 .header(Row::new(vec![\"Head1\", \"Head2\", \"Head3\"]).bottom_margin(1))\n//                 .block(Block::bordered())\n//                 .widths(widths)\n//                 .column_spacing(0);\n//                 f.render_widget(table, size);\n//             })\n//             .unwrap();\n//         terminal.backend().assert_buffer(&expected);\n//     };\n\n//     // columns of zero width show nothing\n//     test_case(\n//         &[\n//             Constraint::Percentage(0),\n//             Constraint::Percentage(0),\n//             Constraint::Percentage(0),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // columns of not enough width trims the data\n//     test_case(\n//         &[\n//             Constraint::Percentage(11),\n//             Constraint::Percentage(11),\n//             Constraint::Percentage(11),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│HeaHeaHea                   │\",\n//             \"│                            │\",\n//             \"│RowRowRow                   │\",\n//             \"│RowRowRow                   │\",\n//             \"│RowRowRow                   │\",\n//             \"│RowRowRow                   │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // columns of large width just before pushing a column off\n//     test_case(\n//         &[\n//             Constraint::Percentage(33),\n//             Constraint::Percentage(33),\n//             Constraint::Percentage(33),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1    Head2    Head3     │\",\n//             \"│                            │\",\n//             \"│Row11    Row12    Row13     │\",\n//             \"│Row21    Row22    Row23     │\",\n//             \"│Row31    Row32    Row33     │\",\n//             \"│Row41    Row42    Row43     │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // percentages summing to 100 should give equal widths\n//     test_case(\n//         &[Constraint::Percentage(50), Constraint::Percentage(50)],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1         Head2         │\",\n//             \"│                            │\",\n//             \"│Row11         Row12         │\",\n//             \"│Row21         Row22         │\",\n//             \"│Row31         Row32         │\",\n//             \"│Row41         Row42         │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n// }\n\n// #[test]\n// fn widgets_table_columns_widths_can_use_mixed_constraints() {\n//     let test_case = |widths, expected| {\n//         let backend = TestBackend::new(30, 10);\n//         let mut terminal = Terminal::new(backend).unwrap();\n\n//         terminal\n//             .draw(|f| {\n//                 let size = f.size();\n//                 let table = Table::new(vec![\n//                     Row::new(vec![\"Row11\", \"Row12\", \"Row13\"]),\n//                     Row::new(vec![\"Row21\", \"Row22\", \"Row23\"]),\n//                     Row::new(vec![\"Row31\", \"Row32\", \"Row33\"]),\n//                     Row::new(vec![\"Row41\", \"Row42\", \"Row43\"]),\n//                 ])\n//                 .header(Row::new(vec![\"Head1\", \"Head2\", \"Head3\"]).bottom_margin(1))\n//                 .block(Block::bordered())\n//                 .widths(widths);\n//                 f.render_widget(table, size);\n//             })\n//             .unwrap();\n//         terminal.backend().assert_buffer(&expected);\n//     };\n\n//     // columns of zero width show nothing\n//     test_case(\n//         &[\n//             Constraint::Percentage(0),\n//             Constraint::Length(0),\n//             Constraint::Percentage(0),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // columns of not enough width trims the data\n//     test_case(\n//         &[\n//             Constraint::Percentage(11),\n//             Constraint::Length(20),\n//             Constraint::Percentage(11),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Hea Head2                Hea│\",\n//             \"│                            │\",\n//             \"│Row Row12                Row│\",\n//             \"│Row Row22                Row│\",\n//             \"│Row Row32                Row│\",\n//             \"│Row Row42                Row│\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // columns of large width just before pushing a column off\n//     test_case(\n//         &[\n//             Constraint::Percentage(33),\n//             Constraint::Length(10),\n//             Constraint::Percentage(33),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1     Head2      Head3  │\",\n//             \"│                            │\",\n//             \"│Row11     Row12      Row13  │\",\n//             \"│Row21     Row22      Row23  │\",\n//             \"│Row31     Row32      Row33  │\",\n//             \"│Row41     Row42      Row43  │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // columns of large size (>100% total) hide the last column\n//     test_case(\n//         &[\n//             Constraint::Percentage(60),\n//             Constraint::Length(10),\n//             Constraint::Percentage(60),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1            Head2      │\",\n//             \"│                            │\",\n//             \"│Row11            Row12      │\",\n//             \"│Row21            Row22      │\",\n//             \"│Row31            Row32      │\",\n//             \"│Row41            Row42      │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n// }\n\n// #[test]\n// fn widgets_table_columns_widths_can_use_ratio_constraints() {\n//     let test_case = |widths, expected| {\n//         let backend = TestBackend::new(30, 10);\n//         let mut terminal = Terminal::new(backend).unwrap();\n\n//         terminal\n//             .draw(|f| {\n//                 let size = f.size();\n//                 let table = Table::new(vec![\n//                     Row::new(vec![\"Row11\", \"Row12\", \"Row13\"]),\n//                     Row::new(vec![\"Row21\", \"Row22\", \"Row23\"]),\n//                     Row::new(vec![\"Row31\", \"Row32\", \"Row33\"]),\n//                     Row::new(vec![\"Row41\", \"Row42\", \"Row43\"]),\n//                 ])\n//                 .header(Row::new(vec![\"Head1\", \"Head2\", \"Head3\"]).bottom_margin(1))\n//                 .block(Block::bordered())\n//                 .widths(widths)\n//                 .column_spacing(0);\n//                 f.render_widget(table, size);\n//             })\n//             .unwrap();\n//         terminal.backend().assert_buffer(&expected);\n//     };\n\n//     // columns of zero width show nothing\n//     test_case(\n//         &[\n//             Constraint::Ratio(0, 1),\n//             Constraint::Ratio(0, 1),\n//             Constraint::Ratio(0, 1),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // columns of not enough width trims the data\n//     test_case(\n//         &[\n//             Constraint::Ratio(1, 9),\n//             Constraint::Ratio(1, 9),\n//             Constraint::Ratio(1, 9),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│HeaHeaHea                   │\",\n//             \"│                            │\",\n//             \"│RowRowRow                   │\",\n//             \"│RowRowRow                   │\",\n//             \"│RowRowRow                   │\",\n//             \"│RowRowRow                   │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // columns of large width just before pushing a column off\n//     test_case(\n//         &[\n//             Constraint::Ratio(1, 3),\n//             Constraint::Ratio(1, 3),\n//             Constraint::Ratio(1, 3),\n//         ],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1    Head2    Head3     │\",\n//             \"│                            │\",\n//             \"│Row11    Row12    Row13     │\",\n//             \"│Row21    Row22    Row23     │\",\n//             \"│Row31    Row32    Row33     │\",\n//             \"│Row41    Row42    Row43     │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // percentages summing to 100 should give equal widths\n//     test_case(\n//         &[Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)],\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1         Head2         │\",\n//             \"│                            │\",\n//             \"│Row11         Row12         │\",\n//             \"│Row21         Row22         │\",\n//             \"│Row31         Row32         │\",\n//             \"│Row41         Row42         │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n// }\n\n// #[test]\n// fn widgets_table_can_have_rows_with_multi_lines() {\n//     let test_case = |state: &mut TableState, expected: Buffer| {\n//         let backend = TestBackend::new(30, 8);\n//         let mut terminal = Terminal::new(backend).unwrap();\n//         terminal\n//             .draw(|f| {\n//                 let size = f.size();\n//                 let table = Table::new(vec![\n//                     Row::new(vec![\"Row11\", \"Row12\", \"Row13\"]),\n//                     Row::new(vec![\"Row21\", \"Row22\", \"Row23\"]).height(2),\n//                     Row::new(vec![\"Row31\", \"Row32\", \"Row33\"]),\n//                     Row::new(vec![\"Row41\", \"Row42\", \"Row43\"]).height(2),\n//                 ])\n//                 .header(Row::new(vec![\"Head1\", \"Head2\", \"Head3\"]).bottom_margin(1))\n//                 .block(Block::bordered())\n//                 .highlight_symbol(\">> \")\n//                 .widths(&[\n//                     Constraint::Length(5),\n//                     Constraint::Length(5),\n//                     Constraint::Length(5),\n//                 ])\n//                 .column_spacing(1);\n//                 f.render_stateful_widget(table, size, state);\n//             })\n//             .unwrap();\n//         terminal.backend().assert_buffer(&expected);\n//     };\n\n//     let mut state = TableState::default();\n//     // no selection\n//     test_case(\n//         &mut state,\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│Head1 Head2 Head3           │\",\n//             \"│                            │\",\n//             \"│Row11 Row12 Row13           │\",\n//             \"│Row21 Row22 Row23           │\",\n//             \"│                            │\",\n//             \"│Row31 Row32 Row33           │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // select first\n//     state.select(Some(0));\n//     test_case(\n//         &mut state,\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│   Head1 Head2 Head3        │\",\n//             \"│                            │\",\n//             \"│>> Row11 Row12 Row13        │\",\n//             \"│   Row21 Row22 Row23        │\",\n//             \"│                            │\",\n//             \"│   Row31 Row32 Row33        │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // select second (we don't show partially the 4th row)\n//     state.select(Some(1));\n//     test_case(\n//         &mut state,\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│   Head1 Head2 Head3        │\",\n//             \"│                            │\",\n//             \"│   Row11 Row12 Row13        │\",\n//             \"│>> Row21 Row22 Row23        │\",\n//             \"│                            │\",\n//             \"│   Row31 Row32 Row33        │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n\n//     // select 4th (we don't show partially the 1st row)\n//     state.select(Some(3));\n//     test_case(\n//         &mut state,\n//         Buffer::with_lines(vec![\n//             \"┌────────────────────────────┐\",\n//             \"│   Head1 Head2 Head3        │\",\n//             \"│                            │\",\n//             \"│   Row31 Row32 Row33        │\",\n//             \"│>> Row41 Row42 Row43        │\",\n//             \"│                            │\",\n//             \"│                            │\",\n//             \"└────────────────────────────┘\",\n//         ]),\n//     );\n// }\n\n// #[test]\n// fn widgets_table_can_have_elements_styled_individually() {\n//     let backend = TestBackend::new(30, 4);\n//     let mut terminal = Terminal::new(backend).unwrap();\n//     let mut state = TableState::default();\n//     state.select(Some(0));\n//     terminal\n//         .draw(|f| {\n//             let size = f.size();\n//             let table = Table::new(vec![\n//                 Row::new(vec![\"Row11\", \"Row12\", \"Row13\"]).style(Style::default().fg(Color::Green)),\n//                 Row::new(vec![\n//                     Cell::from(\"Row21\"),\n//                     Cell::from(\"Row22\").style(Style::default().fg(Color::Yellow)),\n//                     Cell::from(Spans::from(vec![\n//                         Span::raw(\"Row\"),\n//                         Span::styled(\"23\", Style::default().fg(Color::Blue)),\n//                     ]))\n//                     .style(Style::default().fg(Color::Red)),\n//                 ])\n//                 .style(Style::default().fg(Color::LightGreen)),\n//             ])\n//             .header(Row::new(vec![\"Head1\", \"Head2\", \"Head3\"]).bottom_margin(1))\n//             .block(Block::default().borders(Borders::LEFT | Borders::RIGHT))\n//             .highlight_symbol(\">> \")\n//             .highlight_style(Style::default().add_modifier(Modifier::BOLD))\n//             .widths(&[\n//                 Constraint::Length(6),\n//                 Constraint::Length(6),\n//                 Constraint::Length(6),\n//             ])\n//             .column_spacing(1);\n//             f.render_stateful_widget(table, size, &mut state);\n//         })\n//         .unwrap();\n\n//     let mut expected = Buffer::with_lines(vec![\n//         \"│   Head1  Head2  Head3      │\",\n//         \"│                            │\",\n//         \"│>> Row11  Row12  Row13      │\",\n//         \"│   Row21  Row22  Row23      │\",\n//     ]);\n//     // First row = row color + highlight style\n//     for col in 1..=28 {\n//         expected.get_mut(col, 2).set_style(\n//             Style::default()\n//                 .fg(Color::Green)\n//                 .add_modifier(Modifier::BOLD),\n//         );\n//     }\n//     // Second row:\n//     // 1. row color\n//     for col in 1..=28 {\n//         expected\n//             .get_mut(col, 3)\n//             .set_style(Style::default().fg(Color::LightGreen));\n//     }\n//     // 2. cell color\n//     for col in 11..=16 {\n//         expected\n//             .get_mut(col, 3)\n//             .set_style(Style::default().fg(Color::Yellow));\n//     }\n//     for col in 18..=23 {\n//         expected\n//             .get_mut(col, 3)\n//             .set_style(Style::default().fg(Color::Red));\n//     }\n//     // 3. text color\n//     for col in 21..=22 {\n//         expected\n//             .get_mut(col, 3)\n//             .set_style(Style::default().fg(Color::Blue));\n//     }\n//     terminal.backend().assert_buffer(&expected);\n// }\n\n// #[test]\n// fn widgets_table_should_render_even_if_empty() {\n//     let backend = TestBackend::new(30, 4);\n//     let mut terminal = Terminal::new(backend).unwrap();\n//     terminal\n//         .draw(|f| {\n//             let size = f.size();\n//             let table = Table::new(vec![])\n//                 .header(Row::new(vec![\"Head1\", \"Head2\", \"Head3\"]))\n//                 .block(Block::default().borders(Borders::LEFT | Borders::RIGHT))\n//                 .widths(&[\n//                     Constraint::Length(6),\n//                     Constraint::Length(6),\n//                     Constraint::Length(6),\n//                 ])\n//                 .column_spacing(1);\n//             f.render_widget(table, size);\n//         })\n//         .unwrap();\n\n//     let expected = Buffer::with_lines(vec![\n//         \"│Head1  Head2  Head3         │\",\n//         \"│                            │\",\n//         \"│                            │\",\n//         \"│                            │\",\n//     ]);\n\n//     terminal.backend().assert_buffer(&expected);\n// }\n"
  },
  {
    "path": "helix-vcs/Cargo.toml",
    "content": "[package]\nname = \"helix-vcs\"\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n[dependencies]\nhelix-core = { path = \"../helix-core\" }\nhelix-event = { path = \"../helix-event\" }\n\ntokio = { version = \"1\", features = [\"rt\", \"rt-multi-thread\", \"time\", \"sync\", \"parking_lot\", \"macros\"] }\nparking_lot.workspace = true\narc-swap.workspace = true\n\ngix = { version = \"0.80.0\", features = [\"attributes\", \"status\", \"max-performance\"], default-features = false, optional = true }\nimara-diff =  \"0.2.0\"\nanyhow = \"1\"\n\nlog = \"0.4\"\n\n[features]\ngit = [\"gix\"]\n\n[dev-dependencies]\ntempfile.workspace = true\n"
  },
  {
    "path": "helix-vcs/src/diff/line_cache.rs",
    "content": "//! This modules encapsulates a tiny bit of unsafe code that\n//! makes diffing significantly faster and more ergonomic to implement.\n//! This code is necessary because diffing requires quick random\n//! access to the lines of the text that is being diffed.\n//!\n//! Therefore it is best to collect the `Rope::lines` iterator into a vec\n//! first because access to the vec is `O(1)` where `Rope::line` is `O(log N)`.\n//! However this process can allocate a (potentially quite large) vector.\n//!\n//! To avoid reallocation for every diff, the vector is reused.\n//! However the RopeSlice references the original rope and therefore forms a self-referential data structure.\n//! A transmute is used to change the lifetime of the slice to static to circumvent that project.\nuse std::mem::transmute;\n\nuse helix_core::{Rope, RopeSlice};\nuse imara_diff::{InternedInput, Interner};\n\nuse super::{MAX_DIFF_BYTES, MAX_DIFF_LINES};\n\n/// A cache that stores the `lines` of a rope as a vector.\n/// It allows safely reusing the allocation of the vec when updating the rope\npub(crate) struct InternedRopeLines {\n    diff_base: Box<Rope>,\n    doc: Box<Rope>,\n    num_tokens_diff_base: u32,\n    interned: InternedInput<RopeSlice<'static>>,\n}\n\nimpl InternedRopeLines {\n    pub fn new(diff_base: Rope, doc: Rope) -> InternedRopeLines {\n        let mut res = InternedRopeLines {\n            interned: InternedInput {\n                before: Vec::with_capacity(diff_base.len_lines()),\n                after: Vec::with_capacity(doc.len_lines()),\n                interner: Interner::new(diff_base.len_lines() + doc.len_lines()),\n            },\n            diff_base: Box::new(diff_base),\n            doc: Box::new(doc),\n            // will be populated by update_diff_base_impl\n            num_tokens_diff_base: 0,\n        };\n        res.update_diff_base_impl();\n        res\n    }\n\n    pub fn doc(&self) -> Rope {\n        Rope::clone(&*self.doc)\n    }\n\n    pub fn diff_base(&self) -> Rope {\n        Rope::clone(&*self.diff_base)\n    }\n\n    /// Updates the `diff_base` and optionally the document if `doc` is not None\n    pub fn update_diff_base(&mut self, diff_base: Rope, doc: Option<Rope>) {\n        self.interned.clear();\n        *self.diff_base = diff_base;\n        if let Some(doc) = doc {\n            *self.doc = doc\n        }\n        if !self.is_too_large() {\n            self.update_diff_base_impl();\n        }\n    }\n\n    /// Updates the `doc` without reinterning the `diff_base`, this function\n    /// is therefore significantly faster than `update_diff_base` when only the document changes.\n    pub fn update_doc(&mut self, doc: Rope) {\n        // Safety: we clear any tokens that were added after\n        // the interning of `self.diff_base` finished so\n        // all lines that refer to `self.doc` have been purged.\n\n        self.interned\n            .interner\n            .erase_tokens_after(self.num_tokens_diff_base.into());\n\n        *self.doc = doc;\n        if self.is_too_large() {\n            self.interned.after.clear();\n        } else {\n            self.update_doc_impl();\n        }\n    }\n\n    fn update_diff_base_impl(&mut self) {\n        // Safety: This transmute is safe because it only transmutes a lifetime, which has no effect.\n        // The backing storage for the RopeSlices referred to by the lifetime is stored in `self.diff_base`.\n        // Therefore as long as `self.diff_base` is not dropped/replaced this memory remains valid.\n        // `self.diff_base` is only changed in `self.update_diff_base`, which clears the interner.\n        // When the interned lines are exposed to consumer in `self.diff_input`, the lifetime is bounded to a reference to self.\n        // That means that on calls to update there exist no references to `self.interned`.\n        let before = self\n            .diff_base\n            .lines()\n            .map(|line: RopeSlice| -> RopeSlice<'static> { unsafe { transmute(line) } });\n        self.interned.update_before(before);\n        self.num_tokens_diff_base = self.interned.interner.num_tokens();\n        // the has to be interned again because the interner was fully cleared\n        self.update_doc_impl()\n    }\n\n    fn update_doc_impl(&mut self) {\n        // Safety: This transmute is save because it only transmutes a lifetime, which has no effect.\n        // The backing storage for the RopeSlices referred to by the lifetime is stored in `self.doc`.\n        // Therefore as long as `self.doc` is not dropped/replaced this memory remains valid.\n        // `self.doc` is only changed in `self.update_doc`, which clears the interner.\n        // When the interned lines are exposed to consumer in `self.diff_input`, the lifetime is bounded to a reference to self.\n        // That means that on calls to update there exist no references to `self.interned`.\n        let after = self\n            .doc\n            .lines()\n            .map(|line: RopeSlice| -> RopeSlice<'static> { unsafe { transmute(line) } });\n        self.interned.update_after(after);\n    }\n\n    fn is_too_large(&self) -> bool {\n        // bound both lines and bytes to avoid huge files with few (but huge) lines\n        // or huge file with tiny lines. While this makes no difference to\n        // diff itself (the diff performance only depends on the number of tokens)\n        // the interning runtime depends mostly on filesize and is actually dominant\n        // for large files\n        self.doc.len_lines() > MAX_DIFF_LINES\n            || self.diff_base.len_lines() > MAX_DIFF_LINES\n            || self.doc.len_bytes() > MAX_DIFF_BYTES\n            || self.diff_base.len_bytes() > MAX_DIFF_BYTES\n    }\n\n    /// Returns the `InternedInput` for performing the diff.\n    /// If `diff_base` or `doc` is so large that performing a diff could slow the editor\n    /// this function returns `None`.\n    pub fn interned_lines(&self) -> Option<&InternedInput<RopeSlice<'_>>> {\n        if self.is_too_large() {\n            None\n        } else {\n            Some(&self.interned)\n        }\n    }\n}\n"
  },
  {
    "path": "helix-vcs/src/diff/worker/test.rs",
    "content": "use helix_core::Rope;\nuse tokio::task::JoinHandle;\n\nuse crate::diff::{DiffHandle, Hunk};\n\nimpl DiffHandle {\n    fn new_test(diff_base: &str, doc: &str) -> (DiffHandle, JoinHandle<()>) {\n        DiffHandle::new_with_handle(Rope::from_str(diff_base), Rope::from_str(doc))\n    }\n    async fn into_diff(self, handle: JoinHandle<()>) -> Vec<Hunk> {\n        let diff = self.diff;\n        // dropping the channel terminates the task\n        drop(self.channel);\n        handle.await.unwrap();\n        let diff = diff.read();\n        Vec::clone(&diff.hunks)\n    }\n}\n\n#[tokio::test]\nasync fn append_line() {\n    let (differ, handle) = DiffHandle::new_test(\"foo\\n\", \"foo\\nbar\\n\");\n    let line_diffs = differ.into_diff(handle).await;\n    assert_eq!(\n        &line_diffs,\n        &[Hunk {\n            before: 1..1,\n            after: 1..2\n        }]\n    )\n}\n\n#[tokio::test]\nasync fn prepend_line() {\n    let (differ, handle) = DiffHandle::new_test(\"foo\\n\", \"bar\\nfoo\\n\");\n    let line_diffs = differ.into_diff(handle).await;\n    assert_eq!(\n        &line_diffs,\n        &[Hunk {\n            before: 0..0,\n            after: 0..1\n        }]\n    )\n}\n\n#[tokio::test]\nasync fn modify() {\n    let (differ, handle) = DiffHandle::new_test(\"foo\\nbar\\n\", \"foo bar\\nbar\\n\");\n    let line_diffs = differ.into_diff(handle).await;\n    assert_eq!(\n        &line_diffs,\n        &[Hunk {\n            before: 0..1,\n            after: 0..1\n        }]\n    )\n}\n\n#[tokio::test]\nasync fn delete_line() {\n    let (differ, handle) = DiffHandle::new_test(\"foo\\nfoo bar\\nbar\\n\", \"foo\\nbar\\n\");\n    let line_diffs = differ.into_diff(handle).await;\n    assert_eq!(\n        &line_diffs,\n        &[Hunk {\n            before: 1..2,\n            after: 1..1\n        }]\n    )\n}\n\n#[tokio::test]\nasync fn delete_line_and_modify() {\n    let (differ, handle) = DiffHandle::new_test(\"foo\\nbar\\ntest\\nfoo\", \"foo\\ntest\\nfoo bar\");\n    let line_diffs = differ.into_diff(handle).await;\n    assert_eq!(\n        &line_diffs,\n        &[\n            Hunk {\n                before: 1..2,\n                after: 1..1\n            },\n            Hunk {\n                before: 3..4,\n                after: 2..3\n            },\n        ]\n    )\n}\n\n#[tokio::test]\nasync fn add_use() {\n    let (differ, handle) = DiffHandle::new_test(\n        \"use ropey::Rope;\\nuse tokio::task::JoinHandle;\\n\",\n        \"use ropey::Rope;\\nuse ropey::RopeSlice;\\nuse tokio::task::JoinHandle;\\n\",\n    );\n    let line_diffs = differ.into_diff(handle).await;\n    assert_eq!(\n        &line_diffs,\n        &[Hunk {\n            before: 1..1,\n            after: 1..2\n        },]\n    )\n}\n\n#[tokio::test]\nasync fn update_document() {\n    let (differ, handle) = DiffHandle::new_test(\"foo\\nbar\\ntest\\nfoo\", \"foo\\nbar\\ntest\\nfoo\");\n    differ.update_document(Rope::from_str(\"foo\\ntest\\nfoo bar\"), false);\n    let line_diffs = differ.into_diff(handle).await;\n    assert_eq!(\n        &line_diffs,\n        &[\n            Hunk {\n                before: 1..2,\n                after: 1..1\n            },\n            Hunk {\n                before: 3..4,\n                after: 2..3\n            },\n        ]\n    )\n}\n\n#[tokio::test]\nasync fn update_base() {\n    let (differ, handle) = DiffHandle::new_test(\"foo\\ntest\\nfoo bar\", \"foo\\ntest\\nfoo bar\");\n    differ.update_diff_base(Rope::from_str(\"foo\\nbar\\ntest\\nfoo\"));\n    let line_diffs = differ.into_diff(handle).await;\n    assert_eq!(\n        &line_diffs,\n        &[\n            Hunk {\n                before: 1..2,\n                after: 1..1\n            },\n            Hunk {\n                before: 3..4,\n                after: 2..3\n            },\n        ]\n    )\n}\n"
  },
  {
    "path": "helix-vcs/src/diff/worker.rs",
    "content": "use std::sync::Arc;\n\nuse helix_core::{Rope, RopeSlice};\nuse imara_diff::{IndentHeuristic, IndentLevel, InternedInput};\nuse parking_lot::RwLock;\nuse tokio::sync::mpsc::UnboundedReceiver;\nuse tokio::sync::Notify;\nuse tokio::time::{timeout, timeout_at, Duration};\n\nuse crate::diff::{\n    DiffInner, Event, RenderLock, ALGORITHM, DIFF_DEBOUNCE_TIME_ASYNC, DIFF_DEBOUNCE_TIME_SYNC,\n};\n\nuse super::line_cache::InternedRopeLines;\n\n#[cfg(test)]\nmod test;\n\npub(super) struct DiffWorker {\n    pub channel: UnboundedReceiver<Event>,\n    pub diff: Arc<RwLock<DiffInner>>,\n    pub diff_finished_notify: Arc<Notify>,\n    pub diff_alloc: imara_diff::Diff,\n}\n\nimpl DiffWorker {\n    async fn accumulate_events(&mut self, event: Event) -> (Option<Rope>, Option<Rope>) {\n        let mut accumulator = EventAccumulator::new();\n        accumulator.handle_event(event).await;\n        accumulator\n            .accumulate_debounced_events(&mut self.channel, self.diff_finished_notify.clone())\n            .await;\n        (accumulator.doc, accumulator.diff_base)\n    }\n\n    pub async fn run(mut self, diff_base: Rope, doc: Rope) {\n        let mut interner = InternedRopeLines::new(diff_base, doc);\n        if let Some(lines) = interner.interned_lines() {\n            self.perform_diff(lines);\n        }\n        self.apply_hunks(interner.diff_base(), interner.doc());\n        while let Some(event) = self.channel.recv().await {\n            let (doc, diff_base) = self.accumulate_events(event).await;\n\n            let process_accumulated_events = || {\n                if let Some(new_base) = diff_base {\n                    interner.update_diff_base(new_base, doc)\n                } else {\n                    interner.update_doc(doc.unwrap())\n                }\n\n                if let Some(lines) = interner.interned_lines() {\n                    self.perform_diff(lines)\n                }\n            };\n\n            // Calculating diffs is computationally expensive and should\n            // not run inside an async function to avoid blocking other futures.\n            // Note: tokio::task::block_in_place does not work during tests\n            #[cfg(test)]\n            process_accumulated_events();\n            #[cfg(not(test))]\n            tokio::task::block_in_place(process_accumulated_events);\n\n            self.apply_hunks(interner.diff_base(), interner.doc());\n        }\n    }\n\n    /// update the hunks (used by the gutter) by replacing it with `self.new_hunks`.\n    /// `self.new_hunks` is always empty after this function runs.\n    /// To improve performance this function tries to reuse the allocation of the old diff previously stored in `self.line_diffs`\n    fn apply_hunks(&mut self, diff_base: Rope, doc: Rope) {\n        let mut diff = self.diff.write();\n        diff.diff_base = diff_base;\n        diff.doc = doc;\n        diff.hunks.clear();\n        diff.hunks.extend(self.diff_alloc.hunks());\n        drop(diff);\n        self.diff_finished_notify.notify_waiters();\n    }\n\n    fn perform_diff(&mut self, input: &InternedInput<RopeSlice>) {\n        self.diff_alloc.compute_with(\n            ALGORITHM,\n            &input.before,\n            &input.after,\n            input.interner.num_tokens(),\n        );\n        self.diff_alloc.postprocess_with(\n            &input.before,\n            &input.after,\n            IndentHeuristic::new(|token| {\n                IndentLevel::for_ascii_line(input.interner[token].bytes(), 4)\n            }),\n        );\n    }\n}\n\nstruct EventAccumulator {\n    diff_base: Option<Rope>,\n    doc: Option<Rope>,\n    render_lock: Option<RenderLock>,\n}\n\nimpl EventAccumulator {\n    fn new() -> EventAccumulator {\n        EventAccumulator {\n            diff_base: None,\n            doc: None,\n            render_lock: None,\n        }\n    }\n\n    async fn handle_event(&mut self, event: Event) {\n        let dst = if event.is_base {\n            &mut self.diff_base\n        } else {\n            &mut self.doc\n        };\n\n        *dst = Some(event.text);\n\n        // always prefer the most synchronous requested render mode\n        if let Some(render_lock) = event.render_lock {\n            match &mut self.render_lock {\n                Some(RenderLock { timeout, .. }) => {\n                    // A timeout of `None` means that the render should\n                    // always wait for the diff to complete (so no timeout)\n                    // remove the existing timeout, otherwise keep the previous timeout\n                    // because it will be shorter then the current timeout\n                    if render_lock.timeout.is_none() {\n                        timeout.take();\n                    }\n                }\n                None => self.render_lock = Some(render_lock),\n            }\n        }\n    }\n\n    async fn accumulate_debounced_events(\n        &mut self,\n        channel: &mut UnboundedReceiver<Event>,\n        diff_finished_notify: Arc<Notify>,\n    ) {\n        let async_debounce = Duration::from_millis(DIFF_DEBOUNCE_TIME_ASYNC);\n        let sync_debounce = Duration::from_millis(DIFF_DEBOUNCE_TIME_SYNC);\n        loop {\n            // if we are not blocking rendering use a much longer timeout\n            let debounce = if self.render_lock.is_none() {\n                async_debounce\n            } else {\n                sync_debounce\n            };\n\n            if let Ok(Some(event)) = timeout(debounce, channel.recv()).await {\n                self.handle_event(event).await;\n            } else {\n                break;\n            }\n        }\n\n        // setup task to trigger the rendering\n        match self.render_lock.take() {\n            // diff is performed outside of the rendering loop\n            // request a redraw after the diff is done\n            None => {\n                tokio::spawn(async move {\n                    diff_finished_notify.notified().await;\n                    helix_event::request_redraw();\n                });\n            }\n            // diff is performed inside the rendering loop\n            // block redraw until the diff is done or the timeout is expired\n            Some(RenderLock {\n                lock,\n                timeout: Some(timeout),\n            }) => {\n                tokio::spawn(async move {\n                    let res = {\n                        // Acquire a lock on the redraw handle.\n                        // The lock will block the rendering from occurring while held.\n                        // The rendering waits for the diff if it doesn't time out\n                        timeout_at(timeout, diff_finished_notify.notified()).await\n                    };\n                    // we either reached the timeout or the diff is finished, release the render lock\n                    drop(lock);\n                    if res.is_ok() {\n                        // Diff finished in time we are done.\n                        return;\n                    }\n                    // Diff failed to complete in time log the event\n                    // and wait until the diff occurs to trigger an async redraw\n                    log::info!(\"Diff computation timed out, update of diffs might appear delayed\");\n                    diff_finished_notify.notified().await;\n                    helix_event::request_redraw()\n                });\n            }\n            // a blocking diff is performed inside the rendering loop\n            // block redraw until the diff is done\n            Some(RenderLock {\n                lock,\n                timeout: None,\n            }) => {\n                tokio::spawn(async move {\n                    diff_finished_notify.notified().await;\n                    // diff is done release the lock\n                    drop(lock)\n                });\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "helix-vcs/src/diff.rs",
    "content": "use std::iter::Peekable;\nuse std::sync::Arc;\n\nuse helix_core::Rope;\nuse helix_event::RenderLockGuard;\nuse imara_diff::Algorithm;\nuse parking_lot::{RwLock, RwLockReadGuard};\nuse tokio::sync::mpsc::{unbounded_channel, UnboundedSender};\nuse tokio::task::JoinHandle;\nuse tokio::time::Instant;\n\nuse crate::diff::worker::DiffWorker;\n\npub use imara_diff::Hunk;\n\nmod line_cache;\nmod worker;\n\n/// A rendering lock passed to the differ the prevents redraws from occurring\nstruct RenderLock {\n    pub lock: RenderLockGuard,\n    pub timeout: Option<Instant>,\n}\n\nstruct Event {\n    text: Rope,\n    is_base: bool,\n    render_lock: Option<RenderLock>,\n}\n\n#[derive(Clone, Debug, Default)]\nstruct DiffInner {\n    diff_base: Rope,\n    doc: Rope,\n    hunks: Vec<Hunk>,\n}\n\n/// Representation of a diff that can be updated.\n#[derive(Clone, Debug)]\npub struct DiffHandle {\n    channel: UnboundedSender<Event>,\n    diff: Arc<RwLock<DiffInner>>,\n    inverted: bool,\n}\n\nimpl DiffHandle {\n    pub fn new(diff_base: Rope, doc: Rope) -> DiffHandle {\n        DiffHandle::new_with_handle(diff_base, doc).0\n    }\n\n    fn new_with_handle(diff_base: Rope, doc: Rope) -> (DiffHandle, JoinHandle<()>) {\n        let (sender, receiver) = unbounded_channel();\n        let diff: Arc<RwLock<DiffInner>> = Arc::default();\n        let worker = DiffWorker {\n            channel: receiver,\n            diff: diff.clone(),\n            diff_finished_notify: Arc::default(),\n            diff_alloc: imara_diff::Diff::default(),\n        };\n        let handle = tokio::spawn(worker.run(diff_base, doc));\n        let differ = DiffHandle {\n            channel: sender,\n            diff,\n            inverted: false,\n        };\n        (differ, handle)\n    }\n\n    /// Switch base and modified texts' roles\n    pub fn invert(&mut self) {\n        self.inverted = !self.inverted;\n    }\n\n    /// Load the actual diff\n    pub fn load(&self) -> Diff<'_> {\n        Diff {\n            diff: self.diff.read(),\n            inverted: self.inverted,\n        }\n    }\n\n    /// Updates the document associated with this redraw handle\n    /// This function is only intended to be called from within the rendering loop\n    /// if called from elsewhere it may fail to acquire the render lock and panic\n    pub fn update_document(&self, doc: Rope, block: bool) -> bool {\n        let lock = helix_event::lock_frame();\n        let timeout = if block {\n            None\n        } else {\n            Some(Instant::now() + tokio::time::Duration::from_millis(SYNC_DIFF_TIMEOUT))\n        };\n        self.update_document_impl(doc, self.inverted, Some(RenderLock { lock, timeout }))\n    }\n\n    /// Updates the base text of the diff. Returns if the update was successful.\n    pub fn update_diff_base(&self, diff_base: Rope) -> bool {\n        self.update_document_impl(diff_base, !self.inverted, None)\n    }\n\n    fn update_document_impl(\n        &self,\n        text: Rope,\n        is_base: bool,\n        render_lock: Option<RenderLock>,\n    ) -> bool {\n        let event = Event {\n            text,\n            is_base,\n            render_lock,\n        };\n        self.channel.send(event).is_ok()\n    }\n}\n\n/// synchronous debounce value should be low\n/// so we can update synchronously most of the time\nconst DIFF_DEBOUNCE_TIME_SYNC: u64 = 1;\n/// maximum time that rendering should be blocked until the diff finishes\nconst SYNC_DIFF_TIMEOUT: u64 = 12;\nconst DIFF_DEBOUNCE_TIME_ASYNC: u64 = 96;\nconst ALGORITHM: Algorithm = Algorithm::Histogram;\nconst MAX_DIFF_LINES: usize = 64 * u16::MAX as usize;\n// cap average line length to 128 for files with MAX_DIFF_LINES\nconst MAX_DIFF_BYTES: usize = MAX_DIFF_LINES * 128;\n\n/// A list of changes in a file sorted in ascending\n/// non-overlapping order\n#[derive(Debug)]\npub struct Diff<'a> {\n    diff: RwLockReadGuard<'a, DiffInner>,\n    inverted: bool,\n}\n\nimpl Diff<'_> {\n    /// Returns the base [Rope] of the [Diff]\n    pub fn diff_base(&self) -> &Rope {\n        if self.inverted {\n            &self.diff.doc\n        } else {\n            &self.diff.diff_base\n        }\n    }\n\n    /// Returns the [Rope] being compared against\n    pub fn doc(&self) -> &Rope {\n        if self.inverted {\n            &self.diff.diff_base\n        } else {\n            &self.diff.doc\n        }\n    }\n\n    pub fn is_inverted(&self) -> bool {\n        self.inverted\n    }\n\n    /// Returns the `Hunk` for the `n`th change in this file.\n    /// if there is no `n`th change  `Hunk::NONE` is returned instead.\n    pub fn nth_hunk(&self, n: u32) -> Hunk {\n        match self.diff.hunks.get(n as usize) {\n            Some(hunk) if self.inverted => hunk.invert(),\n            Some(hunk) => hunk.clone(),\n            None => Hunk::NONE,\n        }\n    }\n\n    pub fn len(&self) -> u32 {\n        self.diff.hunks.len() as u32\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.len() == 0\n    }\n\n    /// Gives the index of the first hunk after the given line, if one exists.\n    pub fn next_hunk(&self, line: u32) -> Option<u32> {\n        let hunk_range = if self.inverted {\n            |hunk: &Hunk| hunk.before.clone()\n        } else {\n            |hunk: &Hunk| hunk.after.clone()\n        };\n\n        let res = self\n            .diff\n            .hunks\n            .binary_search_by_key(&line, |hunk| hunk_range(hunk).start);\n\n        match res {\n            // Search found a hunk that starts exactly at this line, return the next hunk if it exists.\n            Ok(pos) if pos + 1 == self.diff.hunks.len() => None,\n            Ok(pos) => Some(pos as u32 + 1),\n\n            // No hunk starts exactly at this line, so the search returns\n            // the position where a hunk starting at this line should be inserted.\n            // That position is exactly the position of the next hunk or the end\n            // of the list if no such hunk exists\n            Err(pos) if pos == self.diff.hunks.len() => None,\n            Err(pos) => Some(pos as u32),\n        }\n    }\n\n    /// Gives the index of the first hunk before the given line, if one exists.\n    pub fn prev_hunk(&self, line: u32) -> Option<u32> {\n        let hunk_range = if self.inverted {\n            |hunk: &Hunk| hunk.before.clone()\n        } else {\n            |hunk: &Hunk| hunk.after.clone()\n        };\n        let res = self\n            .diff\n            .hunks\n            .binary_search_by_key(&line, |hunk| hunk_range(hunk).end);\n\n        match res {\n            // Search found a hunk that ends exactly at this line (so it does not include the current line).\n            // We can usually just return that hunk, however a special case for empty hunk is necessary\n            // which represents a pure removal.\n            // Removals are technically empty but are still shown as single line hunks\n            // and as such we must jump to the previous hunk (if it exists) if we are already inside the removal\n            Ok(pos) if !hunk_range(&self.diff.hunks[pos]).is_empty() => Some(pos as u32),\n\n            // No hunk ends exactly at this line, so the search returns\n            // the position where a hunk ending at this line should be inserted.\n            // That position before this one is exactly the position of the previous hunk\n            Err(0) | Ok(0) => None,\n            Err(pos) | Ok(pos) => Some(pos as u32 - 1),\n        }\n    }\n\n    /// Iterates over all hunks that intersect with the given line ranges.\n    ///\n    /// Hunks are returned at most once even when intersecting with multiple of the line\n    /// ranges.\n    pub fn hunks_intersecting_line_ranges<I>(&self, line_ranges: I) -> impl Iterator<Item = &Hunk>\n    where\n        I: Iterator<Item = (usize, usize)>,\n    {\n        HunksInLineRangesIter {\n            hunks: &self.diff.hunks,\n            line_ranges: line_ranges.peekable(),\n            inverted: self.inverted,\n            cursor: 0,\n        }\n    }\n\n    /// Returns the index of the hunk containing the given line if it exists.\n    pub fn hunk_at(&self, line: u32, include_removal: bool) -> Option<u32> {\n        let hunk_range = if self.inverted {\n            |hunk: &Hunk| hunk.before.clone()\n        } else {\n            |hunk: &Hunk| hunk.after.clone()\n        };\n\n        let res = self\n            .diff\n            .hunks\n            .binary_search_by_key(&line, |hunk| hunk_range(hunk).start);\n\n        match res {\n            // Search found a hunk that starts exactly at this line, return it\n            Ok(pos) => Some(pos as u32),\n\n            // No hunk starts exactly at this line, so the search returns\n            // the position where a hunk starting at this line should be inserted.\n            // The previous hunk contains this hunk if it exists and doesn't end before this line\n            Err(0) => None,\n            Err(pos) => {\n                let hunk = hunk_range(&self.diff.hunks[pos - 1]);\n                if hunk.end > line || include_removal && hunk.start == line && hunk.is_empty() {\n                    Some(pos as u32 - 1)\n                } else {\n                    None\n                }\n            }\n        }\n    }\n}\n\npub struct HunksInLineRangesIter<'a, I: Iterator<Item = (usize, usize)>> {\n    hunks: &'a [Hunk],\n    line_ranges: Peekable<I>,\n    inverted: bool,\n    cursor: usize,\n}\n\nimpl<'a, I: Iterator<Item = (usize, usize)>> Iterator for HunksInLineRangesIter<'a, I> {\n    type Item = &'a Hunk;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let hunk_range = if self.inverted {\n            |hunk: &Hunk| hunk.before.clone()\n        } else {\n            |hunk: &Hunk| hunk.after.clone()\n        };\n\n        loop {\n            let (start_line, end_line) = self.line_ranges.peek()?;\n            let hunk = self.hunks.get(self.cursor)?;\n\n            if (hunk_range(hunk).end as usize) < *start_line {\n                // If the hunk under the cursor comes before this range, jump the cursor\n                // ahead to the next hunk that overlaps with the line range.\n                self.cursor += self.hunks[self.cursor..]\n                    .partition_point(|hunk| (hunk_range(hunk).end as usize) < *start_line);\n            } else if (hunk_range(hunk).start as usize) <= *end_line {\n                // If the hunk under the cursor overlaps with this line range, emit it\n                // and move the cursor up so that the hunk cannot be emitted twice.\n                self.cursor += 1;\n                return Some(hunk);\n            } else {\n                // Otherwise, go to the next line range.\n                self.line_ranges.next();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "helix-vcs/src/git/test.rs",
    "content": "use std::{fs::File, io::Write, path::Path, process::Command};\n\nuse tempfile::TempDir;\n\nuse crate::git;\n\nfn exec_git_cmd(args: &str, git_dir: &Path) {\n    let res = Command::new(\"git\")\n        .arg(\"-C\")\n        .arg(git_dir) // execute the git command in this directory\n        .args(args.split_whitespace())\n        .env_remove(\"GIT_DIR\")\n        .env_remove(\"GIT_ASKPASS\")\n        .env_remove(\"SSH_ASKPASS\")\n        .env(\"GIT_TERMINAL_PROMPT\", \"false\")\n        .env(\"GIT_AUTHOR_DATE\", \"2000-01-01 00:00:00 +0000\")\n        .env(\"GIT_AUTHOR_EMAIL\", \"author@example.com\")\n        .env(\"GIT_AUTHOR_NAME\", \"author\")\n        .env(\"GIT_COMMITTER_DATE\", \"2000-01-02 00:00:00 +0000\")\n        .env(\"GIT_COMMITTER_EMAIL\", \"committer@example.com\")\n        .env(\"GIT_COMMITTER_NAME\", \"committer\")\n        .env(\"GIT_CONFIG_COUNT\", \"2\")\n        .env(\"GIT_CONFIG_KEY_0\", \"commit.gpgsign\")\n        .env(\"GIT_CONFIG_VALUE_0\", \"false\")\n        .env(\"GIT_CONFIG_KEY_1\", \"init.defaultBranch\")\n        .env(\"GIT_CONFIG_VALUE_1\", \"main\")\n        .output()\n        .unwrap_or_else(|_| panic!(\"`git {args}` failed\"));\n    if !res.status.success() {\n        println!(\"{}\", String::from_utf8_lossy(&res.stdout));\n        eprintln!(\"{}\", String::from_utf8_lossy(&res.stderr));\n        panic!(\"`git {args}` failed (see output above)\")\n    }\n}\n\nfn create_commit(repo: &Path, add_modified: bool) {\n    if add_modified {\n        exec_git_cmd(\"add -A\", repo);\n    }\n    exec_git_cmd(\"commit -m message\", repo);\n}\n\nfn empty_git_repo() -> TempDir {\n    let tmp = tempfile::tempdir().expect(\"create temp dir for git testing\");\n    exec_git_cmd(\"init\", tmp.path());\n    exec_git_cmd(\"config user.email test@helix.org\", tmp.path());\n    exec_git_cmd(\"config user.name helix-test\", tmp.path());\n    tmp\n}\n\n#[test]\nfn missing_file() {\n    let temp_git = empty_git_repo();\n    let file = temp_git.path().join(\"file.txt\");\n    File::create(&file).unwrap().write_all(b\"foo\").unwrap();\n\n    assert!(git::get_diff_base(&file).is_err());\n}\n\n#[test]\nfn unmodified_file() {\n    let temp_git = empty_git_repo();\n    let file = temp_git.path().join(\"file.txt\");\n    let contents = b\"foo\".as_slice();\n    File::create(&file).unwrap().write_all(contents).unwrap();\n    create_commit(temp_git.path(), true);\n    assert_eq!(git::get_diff_base(&file).unwrap(), Vec::from(contents));\n}\n\n#[test]\nfn modified_file() {\n    let temp_git = empty_git_repo();\n    let file = temp_git.path().join(\"file.txt\");\n    let contents = b\"foo\".as_slice();\n    File::create(&file).unwrap().write_all(contents).unwrap();\n    create_commit(temp_git.path(), true);\n    File::create(&file).unwrap().write_all(b\"bar\").unwrap();\n\n    assert_eq!(git::get_diff_base(&file).unwrap(), Vec::from(contents));\n}\n\n/// Test that `get_file_head` does not return content for a directory.\n/// This is important to correctly cover cases where a directory is removed and replaced by a file.\n/// If the contents of the directory object were returned a diff between a path and the directory children would be produced.\n#[test]\nfn directory() {\n    let temp_git = empty_git_repo();\n    let dir = temp_git.path().join(\"file.txt\");\n    std::fs::create_dir(&dir).expect(\"\");\n    let file = dir.join(\"file.txt\");\n    let contents = b\"foo\".as_slice();\n    File::create(file).unwrap().write_all(contents).unwrap();\n\n    create_commit(temp_git.path(), true);\n\n    std::fs::remove_dir_all(&dir).unwrap();\n    File::create(&dir).unwrap().write_all(b\"bar\").unwrap();\n    assert!(git::get_diff_base(&dir).is_err());\n}\n\n/// Test that `get_diff_base` resolves symlinks so that the same diff base is\n/// used as the target file.\n///\n/// This is important to correctly cover cases where a symlink is removed and\n/// replaced by a file. If the contents of the symlink object were returned\n/// a diff between a literal file path and the actual file content would be\n/// produced (bad ui).\n#[cfg(any(unix, windows))]\n#[test]\nfn symlink() {\n    #[cfg(unix)]\n    use std::os::unix::fs::symlink;\n    #[cfg(not(unix))]\n    use std::os::windows::fs::symlink_file as symlink;\n\n    let temp_git = empty_git_repo();\n    let file = temp_git.path().join(\"file.txt\");\n    let contents = Vec::from(b\"foo\");\n    File::create(&file).unwrap().write_all(&contents).unwrap();\n    let file_link = temp_git.path().join(\"file_link.txt\");\n\n    symlink(\"file.txt\", &file_link).unwrap();\n    create_commit(temp_git.path(), true);\n\n    assert_eq!(git::get_diff_base(&file_link).unwrap(), contents);\n    assert_eq!(git::get_diff_base(&file).unwrap(), contents);\n}\n\n/// Test that `get_diff_base` returns content when the file is a symlink to\n/// another file that is in a git repo, but the symlink itself is not.\n#[cfg(any(unix, windows))]\n#[test]\nfn symlink_to_git_repo() {\n    #[cfg(unix)]\n    use std::os::unix::fs::symlink;\n    #[cfg(not(unix))]\n    use std::os::windows::fs::symlink_file as symlink;\n\n    let temp_dir = tempfile::tempdir().expect(\"create temp dir\");\n    let temp_git = empty_git_repo();\n\n    let file = temp_git.path().join(\"file.txt\");\n    let contents = Vec::from(b\"foo\");\n    File::create(&file).unwrap().write_all(&contents).unwrap();\n    create_commit(temp_git.path(), true);\n\n    let file_link = temp_dir.path().join(\"file_link.txt\");\n    symlink(&file, &file_link).unwrap();\n\n    assert_eq!(git::get_diff_base(&file_link).unwrap(), contents);\n    assert_eq!(git::get_diff_base(&file).unwrap(), contents);\n}\n"
  },
  {
    "path": "helix-vcs/src/git.rs",
    "content": "use anyhow::{bail, Context, Result};\nuse arc_swap::ArcSwap;\nuse gix::filter::plumbing::driver::apply::Delay;\nuse std::io::Read;\nuse std::path::Path;\nuse std::sync::Arc;\n\nuse gix::bstr::ByteSlice;\nuse gix::diff::Rewrites;\nuse gix::dir::entry::Status;\nuse gix::objs::tree::EntryKind;\nuse gix::sec::trust::DefaultForLevel;\nuse gix::status::{\n    index_worktree::Item,\n    plumbing::index_as_worktree::{Change, EntryStatus},\n    UntrackedFiles,\n};\nuse gix::{Commit, ObjectId, Repository, ThreadSafeRepository};\n\nuse crate::FileChange;\n\n#[cfg(test)]\nmod test;\n\n#[inline]\nfn get_repo_dir(file: &Path) -> Result<&Path> {\n    file.parent().context(\"file has no parent directory\")\n}\n\npub fn get_diff_base(file: &Path) -> Result<Vec<u8>> {\n    debug_assert!(!file.exists() || file.is_file());\n    debug_assert!(file.is_absolute());\n    let file = gix::path::realpath(file).context(\"resolve symlinks\")?;\n\n    // TODO cache repository lookup\n\n    let repo_dir = get_repo_dir(&file)?;\n    let repo = open_repo(repo_dir)\n        .context(\"failed to open git repo\")?\n        .to_thread_local();\n    let head = repo.head_commit()?;\n    let file_oid = find_file_in_commit(&repo, &head, &file)?;\n\n    let file_object = repo.find_object(file_oid)?;\n    let data = file_object.detach().data;\n    // Get the actual data that git would make out of the git object.\n    // This will apply the user's git config or attributes like crlf conversions.\n    if let Some(work_dir) = repo.workdir() {\n        let rela_path = file.strip_prefix(work_dir)?;\n        let rela_path = gix::path::try_into_bstr(rela_path)?;\n        let (mut pipeline, _) = repo.filter_pipeline(None)?;\n        let mut worktree_outcome =\n            pipeline.convert_to_worktree(&data, rela_path.as_ref(), Delay::Forbid)?;\n        let mut buf = Vec::with_capacity(data.len());\n        worktree_outcome.read_to_end(&mut buf)?;\n        Ok(buf)\n    } else {\n        Ok(data)\n    }\n}\n\npub fn get_current_head_name(file: &Path) -> Result<Arc<ArcSwap<Box<str>>>> {\n    debug_assert!(!file.exists() || file.is_file());\n    debug_assert!(file.is_absolute());\n    let file = gix::path::realpath(file).context(\"resolve symlinks\")?;\n\n    let repo_dir = get_repo_dir(&file)?;\n    let repo = open_repo(repo_dir)\n        .context(\"failed to open git repo\")?\n        .to_thread_local();\n    let head_ref = repo.head_ref()?;\n    let head_commit = repo.head_commit()?;\n\n    let name = match head_ref {\n        Some(reference) => reference.name().shorten().to_string(),\n        None => head_commit.id.to_hex_with_len(8).to_string(),\n    };\n\n    Ok(Arc::new(ArcSwap::from_pointee(name.into_boxed_str())))\n}\n\npub fn for_each_changed_file(cwd: &Path, f: impl Fn(Result<FileChange>) -> bool) -> Result<()> {\n    status(&open_repo(cwd)?.to_thread_local(), f)\n}\n\nfn open_repo(path: &Path) -> Result<ThreadSafeRepository> {\n    // custom open options\n    let mut git_open_opts_map = gix::sec::trust::Mapping::<gix::open::Options>::default();\n\n    // On windows various configuration options are bundled as part of the installations\n    // This path depends on the install location of git and therefore requires some overhead to lookup\n    // This is basically only used on windows and has some overhead hence it's disabled on other platforms.\n    // `gitoxide` doesn't use this as default\n    let config = gix::open::permissions::Config {\n        system: true,\n        git: true,\n        user: true,\n        env: true,\n        includes: true,\n        git_binary: cfg!(windows),\n    };\n    // change options for config permissions without touching anything else\n    git_open_opts_map.reduced = git_open_opts_map\n        .reduced\n        .permissions(gix::open::Permissions {\n            config,\n            ..gix::open::Permissions::default_for_level(gix::sec::Trust::Reduced)\n        });\n    git_open_opts_map.full = git_open_opts_map.full.permissions(gix::open::Permissions {\n        config,\n        ..gix::open::Permissions::default_for_level(gix::sec::Trust::Full)\n    });\n\n    let open_options = gix::discover::upwards::Options {\n        dot_git_only: true,\n        ..Default::default()\n    };\n\n    let res = ThreadSafeRepository::discover_with_environment_overrides_opts(\n        path,\n        open_options,\n        git_open_opts_map,\n    )?;\n\n    Ok(res)\n}\n\n/// Emulates the result of running `git status` from the command line.\nfn status(repo: &Repository, f: impl Fn(Result<FileChange>) -> bool) -> Result<()> {\n    let work_dir = repo\n        .workdir()\n        .ok_or_else(|| anyhow::anyhow!(\"working tree not found\"))?\n        .to_path_buf();\n\n    let status_platform = repo\n        .status(gix::progress::Discard)?\n        // Here we discard the `status.showUntrackedFiles` config, as it makes little sense in\n        // our case to not list new (untracked) files. We could have respected this config\n        // if the default value weren't `Collapsed` though, as this default value would render\n        // the feature unusable to many.\n        .untracked_files(UntrackedFiles::Files)\n        // Turn on file rename detection, which is off by default.\n        .index_worktree_rewrites(Some(Rewrites {\n            copies: None,\n            percentage: Some(0.5),\n            limit: 1000,\n            ..Default::default()\n        }));\n\n    // No filtering based on path\n    let empty_patterns = vec![];\n\n    let status_iter = status_platform.into_index_worktree_iter(empty_patterns)?;\n\n    for item in status_iter {\n        let Ok(item) = item.map_err(|err| f(Err(err.into()))) else {\n            continue;\n        };\n        let change = match item {\n            Item::Modification {\n                rela_path, status, ..\n            } => {\n                let path = work_dir.join(rela_path.to_path()?);\n                match status {\n                    EntryStatus::Conflict { .. } => FileChange::Conflict { path },\n                    EntryStatus::Change(Change::Removed) => FileChange::Deleted { path },\n                    EntryStatus::Change(Change::Modification { .. }) => {\n                        FileChange::Modified { path }\n                    }\n                    // Files marked with `git add --intent-to-add`. Such files\n                    // still show up as new in `git status`, so it's appropriate\n                    // to show them the same way as untracked files in the\n                    // \"changed file\" picker. One example of this being used\n                    // is Jujutsu, a Git-compatible VCS. It marks all new files\n                    // with `--intent-to-add` automatically.\n                    EntryStatus::IntentToAdd => FileChange::Untracked { path },\n                    _ => continue,\n                }\n            }\n            Item::DirectoryContents { entry, .. } if entry.status == Status::Untracked => {\n                FileChange::Untracked {\n                    path: work_dir.join(entry.rela_path.to_path()?),\n                }\n            }\n            Item::Rewrite {\n                source,\n                dirwalk_entry,\n                ..\n            } => FileChange::Renamed {\n                from_path: work_dir.join(source.rela_path().to_path()?),\n                to_path: work_dir.join(dirwalk_entry.rela_path.to_path()?),\n            },\n            _ => continue,\n        };\n        if !f(Ok(change)) {\n            break;\n        }\n    }\n\n    Ok(())\n}\n\n/// Finds the object that contains the contents of a file at a specific commit.\nfn find_file_in_commit(repo: &Repository, commit: &Commit, file: &Path) -> Result<ObjectId> {\n    let repo_dir = repo.workdir().context(\"repo has no worktree\")?;\n    let rel_path = file.strip_prefix(repo_dir)?;\n    let tree = commit.tree()?;\n    let tree_entry = tree\n        .lookup_entry_by_path(rel_path)?\n        .context(\"file is untracked\")?;\n    match tree_entry.mode().kind() {\n        // not a file, everything is new, do not show diff\n        mode @ (EntryKind::Tree | EntryKind::Commit | EntryKind::Link) => {\n            bail!(\"entry at {} is not a file but a {mode:?}\", file.display())\n        }\n        // found a file\n        EntryKind::Blob | EntryKind::BlobExecutable => Ok(tree_entry.object_id()),\n    }\n}\n"
  },
  {
    "path": "helix-vcs/src/lib.rs",
    "content": "//! `helix_vcs` provides types for working with diffs from a Version Control System (VCS).\n//! Currently `git` is the only supported provider for diffs, but this architecture allows\n//! for other providers to be added in the future.\n\nuse anyhow::{anyhow, bail, Result};\nuse arc_swap::ArcSwap;\nuse std::{\n    path::{Path, PathBuf},\n    sync::Arc,\n};\n\n#[cfg(feature = \"git\")]\nmod git;\n\nmod diff;\n\npub use diff::{DiffHandle, Hunk};\n\nmod status;\n\npub use status::FileChange;\n\n/// Contains all active diff providers. Diff providers are compiled in via features. Currently\n/// only `git` is supported.\n#[derive(Clone)]\npub struct DiffProviderRegistry {\n    providers: Vec<DiffProvider>,\n}\n\nimpl DiffProviderRegistry {\n    /// Get the given file from the VCS. This provides the unedited document as a \"base\"\n    /// for a diff to be created.\n    pub fn get_diff_base(&self, file: &Path) -> Option<Vec<u8>> {\n        self.providers\n            .iter()\n            .find_map(|provider| match provider.get_diff_base(file) {\n                Ok(res) => Some(res),\n                Err(err) => {\n                    log::debug!(\"{err:#?}\");\n                    log::debug!(\"failed to open diff base for {}\", file.display());\n                    None\n                }\n            })\n    }\n\n    /// Get the current name of the current [HEAD](https://stackoverflow.com/questions/2304087/what-is-head-in-git).\n    pub fn get_current_head_name(&self, file: &Path) -> Option<Arc<ArcSwap<Box<str>>>> {\n        self.providers\n            .iter()\n            .find_map(|provider| match provider.get_current_head_name(file) {\n                Ok(res) => Some(res),\n                Err(err) => {\n                    log::debug!(\"{err:#?}\");\n                    log::debug!(\"failed to obtain current head name for {}\", file.display());\n                    None\n                }\n            })\n    }\n\n    /// Fire-and-forget changed file iteration. Runs everything in a background task. Keeps\n    /// iteration until `on_change` returns `false`.\n    pub fn for_each_changed_file(\n        self,\n        cwd: PathBuf,\n        f: impl Fn(Result<FileChange>) -> bool + Send + 'static,\n    ) {\n        tokio::task::spawn_blocking(move || {\n            if self\n                .providers\n                .iter()\n                .find_map(|provider| provider.for_each_changed_file(&cwd, &f).ok())\n                .is_none()\n            {\n                f(Err(anyhow!(\"no diff provider returns success\")));\n            }\n        });\n    }\n}\n\nimpl Default for DiffProviderRegistry {\n    fn default() -> Self {\n        // currently only git is supported\n        // TODO make this configurable when more providers are added\n        let providers = vec![\n            #[cfg(feature = \"git\")]\n            DiffProvider::Git,\n            DiffProvider::None,\n        ];\n        DiffProviderRegistry { providers }\n    }\n}\n\n/// A union type that includes all types that implement [DiffProvider]. We need this type to allow\n/// cloning [DiffProviderRegistry] as `Clone` cannot be used in trait objects.\n///\n/// `Copy` is simply to ensure the `clone()` call is the simplest it can be.\n#[derive(Copy, Clone)]\nenum DiffProvider {\n    #[cfg(feature = \"git\")]\n    Git,\n    None,\n}\n\nimpl DiffProvider {\n    fn get_diff_base(&self, file: &Path) -> Result<Vec<u8>> {\n        match self {\n            #[cfg(feature = \"git\")]\n            Self::Git => git::get_diff_base(file),\n            Self::None => bail!(\"No diff support compiled in\"),\n        }\n    }\n\n    fn get_current_head_name(&self, file: &Path) -> Result<Arc<ArcSwap<Box<str>>>> {\n        match self {\n            #[cfg(feature = \"git\")]\n            Self::Git => git::get_current_head_name(file),\n            Self::None => bail!(\"No diff support compiled in\"),\n        }\n    }\n\n    fn for_each_changed_file(\n        &self,\n        cwd: &Path,\n        f: impl Fn(Result<FileChange>) -> bool,\n    ) -> Result<()> {\n        match self {\n            #[cfg(feature = \"git\")]\n            Self::Git => git::for_each_changed_file(cwd, f),\n            Self::None => bail!(\"No diff support compiled in\"),\n        }\n    }\n}\n"
  },
  {
    "path": "helix-vcs/src/status.rs",
    "content": "use std::path::{Path, PathBuf};\n\n/// States for a file having been changed.\npub enum FileChange {\n    /// Not tracked by the VCS.\n    Untracked { path: PathBuf },\n    /// File has been modified.\n    Modified { path: PathBuf },\n    /// File modification is in conflict with a different update.\n    Conflict { path: PathBuf },\n    /// File has been deleted.\n    Deleted { path: PathBuf },\n    /// File has been renamed.\n    Renamed {\n        from_path: PathBuf,\n        to_path: PathBuf,\n    },\n}\n\nimpl FileChange {\n    pub fn path(&self) -> &Path {\n        match self {\n            Self::Untracked { path } => path,\n            Self::Modified { path } => path,\n            Self::Conflict { path } => path,\n            Self::Deleted { path } => path,\n            Self::Renamed { to_path, .. } => to_path,\n        }\n    }\n}\n"
  },
  {
    "path": "helix-view/Cargo.toml",
    "content": "[package]\nname = \"helix-view\"\ndescription = \"UI abstractions for use in backends\"\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n[features]\ndefault = []\nterm = [\"termina\", \"crossterm\"]\nunicode-lines = []\n\n[dependencies]\nhelix-stdx = { path = \"../helix-stdx\" }\nhelix-core = { path = \"../helix-core\" }\nhelix-event = { path = \"../helix-event\" }\nhelix-loader = { path = \"../helix-loader\" }\nhelix-lsp = { path = \"../helix-lsp\" }\nhelix-dap = { path = \"../helix-dap\" }\nhelix-vcs = { path = \"../helix-vcs\" }\n\nbitflags.workspace = true\nanyhow = \"1\"\ntermina = { workspace = true, optional = true }\n\ntempfile.workspace = true\n\n# Conversion traits\nonce_cell = \"1.21\"\nurl = \"2.5.4\"\n\narc-swap.workspace = true\n\ntokio = { version = \"1\", features = [\"rt\", \"rt-multi-thread\", \"io-util\", \"io-std\", \"time\", \"process\", \"macros\", \"fs\", \"parking_lot\"] }\ntokio-stream = \"0.1\"\nfutures-util = { version = \"0.3\", features = [\"std\", \"async-await\"], default-features = false }\n\nslotmap.workspace = true\n\nchardetng = \"0.1\"\n\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0\"\ntoml.workspace = true\nlog = \"~0.4\"\n\nparking_lot.workspace = true\nthiserror.workspace = true\n\nkstring = \"2.0\"\n\n[target.'cfg(windows)'.dependencies]\nclipboard-win = { version = \"5.4\", features = [\"std\"] }\ncrossterm = { version = \"0.28\", optional = true }\n\n[target.'cfg(unix)'.dependencies]\nlibc = \"0.2\"\nrustix = { version = \"1.1\", features = [\"fs\"] }\n\n[dev-dependencies]\nhelix-tui = { path = \"../helix-tui\" }\n"
  },
  {
    "path": "helix-view/src/annotations/diagnostics.rs",
    "content": "use helix_core::diagnostic::Severity;\nuse helix_core::doc_formatter::{FormattedGrapheme, TextFormat};\nuse helix_core::text_annotations::LineAnnotation;\nuse helix_core::{softwrapped_dimensions, Diagnostic, Position};\nuse serde::{Deserialize, Serialize};\n\nuse crate::Document;\n\n/// Describes the severity level of a [`Diagnostic`].\n#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]\npub enum DiagnosticFilter {\n    Disable,\n    Enable(Severity),\n}\n\nimpl<'de> Deserialize<'de> for DiagnosticFilter {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        match &*String::deserialize(deserializer)? {\n            \"disable\" => Ok(DiagnosticFilter::Disable),\n            \"hint\" => Ok(DiagnosticFilter::Enable(Severity::Hint)),\n            \"info\" => Ok(DiagnosticFilter::Enable(Severity::Info)),\n            \"warning\" => Ok(DiagnosticFilter::Enable(Severity::Warning)),\n            \"error\" => Ok(DiagnosticFilter::Enable(Severity::Error)),\n            variant => Err(serde::de::Error::unknown_variant(\n                variant,\n                &[\"disable\", \"hint\", \"info\", \"warning\", \"error\"],\n            )),\n        }\n    }\n}\n\nimpl Serialize for DiagnosticFilter {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        let filter = match self {\n            DiagnosticFilter::Disable => \"disable\",\n            DiagnosticFilter::Enable(Severity::Hint) => \"hint\",\n            DiagnosticFilter::Enable(Severity::Info) => \"info\",\n            DiagnosticFilter::Enable(Severity::Warning) => \"warning\",\n            DiagnosticFilter::Enable(Severity::Error) => \"error\",\n        };\n        filter.serialize(serializer)\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(default, rename_all = \"kebab-case\", deny_unknown_fields)]\npub struct InlineDiagnosticsConfig {\n    pub cursor_line: DiagnosticFilter,\n    pub other_lines: DiagnosticFilter,\n    pub min_diagnostic_width: u16,\n    pub prefix_len: u16,\n    pub max_wrap: u16,\n    pub max_diagnostics: usize,\n}\n\nimpl InlineDiagnosticsConfig {\n    pub fn disabled(&self) -> bool {\n        matches!(\n            self,\n            Self {\n                cursor_line: DiagnosticFilter::Disable,\n                other_lines: DiagnosticFilter::Disable,\n                ..\n            }\n        )\n    }\n\n    pub fn prepare(&self, width: u16, enable_cursor_line: bool) -> Self {\n        let mut config = self.clone();\n        if width < self.min_diagnostic_width + self.prefix_len {\n            config.cursor_line = DiagnosticFilter::Disable;\n            config.other_lines = DiagnosticFilter::Disable;\n        } else if !enable_cursor_line {\n            config.cursor_line = self.cursor_line.min(self.other_lines);\n        }\n        config\n    }\n\n    pub fn max_diagnostic_start(&self, width: u16) -> u16 {\n        width - self.min_diagnostic_width - self.prefix_len\n    }\n\n    pub fn text_fmt(&self, anchor_col: u16, width: u16) -> TextFormat {\n        let width = if anchor_col > self.max_diagnostic_start(width) {\n            self.min_diagnostic_width\n        } else {\n            width - anchor_col - self.prefix_len\n        };\n\n        TextFormat {\n            soft_wrap: true,\n            tab_width: 4,\n            max_wrap: self.max_wrap.min(width / 4),\n            max_indent_retain: 0,\n            wrap_indicator: \"\".into(),\n            wrap_indicator_highlight: None,\n            viewport_width: width,\n            soft_wrap_at_text_width: true,\n        }\n    }\n}\n\nimpl Default for InlineDiagnosticsConfig {\n    fn default() -> Self {\n        InlineDiagnosticsConfig {\n            cursor_line: DiagnosticFilter::Enable(Severity::Warning),\n            other_lines: DiagnosticFilter::Disable,\n            min_diagnostic_width: 40,\n            prefix_len: 1,\n            max_wrap: 20,\n            max_diagnostics: 10,\n        }\n    }\n}\n\npub struct InlineDiagnosticAccumulator<'a> {\n    idx: usize,\n    doc: &'a Document,\n    pub stack: Vec<(&'a Diagnostic, u16)>,\n    pub config: InlineDiagnosticsConfig,\n    cursor: usize,\n    cursor_line: bool,\n}\n\nimpl<'a> InlineDiagnosticAccumulator<'a> {\n    pub fn new(cursor: usize, doc: &'a Document, config: InlineDiagnosticsConfig) -> Self {\n        InlineDiagnosticAccumulator {\n            idx: 0,\n            doc,\n            stack: Vec::new(),\n            config,\n            cursor,\n            cursor_line: false,\n        }\n    }\n\n    pub fn reset_pos(&mut self, char_idx: usize) -> usize {\n        self.idx = 0;\n        self.clear();\n        self.skip_concealed(char_idx)\n    }\n\n    pub fn skip_concealed(&mut self, conceal_end_char_idx: usize) -> usize {\n        let diagnostics = &self.doc.diagnostics[self.idx..];\n        let idx = diagnostics.partition_point(|diag| diag.range.start < conceal_end_char_idx);\n        self.idx += idx;\n        self.next_anchor(conceal_end_char_idx)\n    }\n\n    pub fn next_anchor(&self, current_char_idx: usize) -> usize {\n        let next_diag_start = self\n            .doc\n            .diagnostics\n            .get(self.idx)\n            .map_or(usize::MAX, |diag| diag.range.start);\n        if (current_char_idx..next_diag_start).contains(&self.cursor) {\n            self.cursor\n        } else {\n            next_diag_start\n        }\n    }\n\n    pub fn clear(&mut self) {\n        self.cursor_line = false;\n        self.stack.clear();\n    }\n\n    fn process_anchor_impl(\n        &mut self,\n        grapheme: &FormattedGrapheme,\n        width: u16,\n        horizontal_off: usize,\n    ) -> bool {\n        // TODO: doing the cursor tracking here works well but is somewhat\n        // duplicate effort/tedious maybe centralize this somewhere?\n        // In the DocFormatter?\n        if grapheme.char_idx == self.cursor {\n            self.cursor_line = true;\n            if self\n                .doc\n                .diagnostics\n                .get(self.idx)\n                .is_none_or(|diag| diag.range.start != grapheme.char_idx)\n            {\n                return false;\n            }\n        }\n\n        let Some(anchor_col) = grapheme.visual_pos.col.checked_sub(horizontal_off) else {\n            return true;\n        };\n        if anchor_col >= width as usize {\n            return true;\n        }\n\n        for diag in &self.doc.diagnostics[self.idx..] {\n            if diag.range.start != grapheme.char_idx {\n                break;\n            }\n            self.stack.push((diag, anchor_col as u16));\n            self.idx += 1;\n        }\n        false\n    }\n\n    pub fn proccess_anchor(\n        &mut self,\n        grapheme: &FormattedGrapheme,\n        width: u16,\n        horizontal_off: usize,\n    ) -> usize {\n        if self.process_anchor_impl(grapheme, width, horizontal_off) {\n            self.idx += self.doc.diagnostics[self.idx..]\n                .iter()\n                .take_while(|diag| diag.range.start == grapheme.char_idx)\n                .count();\n        }\n        self.next_anchor(grapheme.char_idx + 1)\n    }\n\n    pub fn filter(&self) -> DiagnosticFilter {\n        if self.cursor_line {\n            self.config.cursor_line\n        } else {\n            self.config.other_lines\n        }\n    }\n\n    pub fn compute_line_diagnostics(&mut self) {\n        let filter = if self.cursor_line {\n            self.cursor_line = false;\n            self.config.cursor_line\n        } else {\n            self.config.other_lines\n        };\n        let DiagnosticFilter::Enable(filter) = filter else {\n            self.stack.clear();\n            return;\n        };\n        self.stack.retain(|(diag, _)| diag.severity() >= filter);\n        self.stack.truncate(self.config.max_diagnostics)\n    }\n\n    pub fn has_multi(&self, width: u16) -> bool {\n        self.stack\n            .last()\n            .is_some_and(|&(_, anchor)| anchor > self.config.max_diagnostic_start(width))\n    }\n}\n\npub(crate) struct InlineDiagnostics<'a> {\n    state: InlineDiagnosticAccumulator<'a>,\n    width: u16,\n    horizontal_off: usize,\n}\n\nimpl<'a> InlineDiagnostics<'a> {\n    #[allow(clippy::new_ret_no_self)]\n    pub(crate) fn new(\n        doc: &'a Document,\n        cursor: usize,\n        width: u16,\n        horizontal_off: usize,\n        config: InlineDiagnosticsConfig,\n    ) -> Box<dyn LineAnnotation + 'a> {\n        Box::new(InlineDiagnostics {\n            state: InlineDiagnosticAccumulator::new(cursor, doc, config),\n            width,\n            horizontal_off,\n        })\n    }\n}\n\nimpl LineAnnotation for InlineDiagnostics<'_> {\n    fn reset_pos(&mut self, char_idx: usize) -> usize {\n        self.state.reset_pos(char_idx)\n    }\n\n    fn skip_concealed_anchors(&mut self, conceal_end_char_idx: usize) -> usize {\n        self.state.skip_concealed(conceal_end_char_idx)\n    }\n\n    fn process_anchor(&mut self, grapheme: &FormattedGrapheme) -> usize {\n        self.state\n            .proccess_anchor(grapheme, self.width, self.horizontal_off)\n    }\n\n    fn insert_virtual_lines(\n        &mut self,\n        _line_end_char_idx: usize,\n        _line_end_visual_pos: Position,\n        _doc_line: usize,\n    ) -> Position {\n        self.state.compute_line_diagnostics();\n        let multi = self.state.has_multi(self.width);\n        let diagostic_height: usize = self\n            .state\n            .stack\n            .drain(..)\n            .map(|(diag, anchor)| {\n                let text_fmt = self.state.config.text_fmt(anchor, self.width);\n                softwrapped_dimensions(diag.message.as_str().trim().into(), &text_fmt).0\n            })\n            .sum();\n        Position::new(multi as usize + diagostic_height, 0)\n    }\n}\n"
  },
  {
    "path": "helix-view/src/annotations.rs",
    "content": "pub mod diagnostics;\n"
  },
  {
    "path": "helix-view/src/clipboard.rs",
    "content": "// Implementation reference: https://github.com/neovim/neovim/blob/f2906a4669a2eef6d7bf86a29648793d63c98949/runtime/autoload/provider/clipboard.vim#L68-L152\n\nuse serde::{Deserialize, Serialize};\nuse std::borrow::Cow;\nuse thiserror::Error;\n\n#[derive(Clone, Copy)]\npub enum ClipboardType {\n    Clipboard,\n    Selection,\n}\n\n#[derive(Debug, Error)]\npub enum ClipboardError {\n    #[error(transparent)]\n    IoError(#[from] std::io::Error),\n    #[error(\"could not convert terminal output to UTF-8: {0}\")]\n    FromUtf8Error(#[from] std::string::FromUtf8Error),\n    #[cfg(windows)]\n    #[error(\"Windows API error: {0}\")]\n    WinAPI(#[from] clipboard_win::ErrorCode),\n    #[error(\"clipboard provider command failed\")]\n    CommandFailed,\n    #[error(\"failed to write to clipboard provider's stdin\")]\n    StdinWriteFailed,\n    #[error(\"clipboard provider did not return any contents\")]\n    MissingStdout,\n    #[error(\"This clipboard provider does not support reading\")]\n    ReadingNotSupported,\n}\n\ntype Result<T> = std::result::Result<T, ClipboardError>;\n\n#[cfg(not(target_arch = \"wasm32\"))]\npub use external::ClipboardProvider;\n#[cfg(target_arch = \"wasm32\")]\npub use noop::ClipboardProvider;\n\n// Clipboard not supported for wasm\n#[cfg(target_arch = \"wasm32\")]\nmod noop {\n    use super::*;\n\n    #[derive(Debug, Clone)]\n    pub enum ClipboardProvider {}\n\n    impl ClipboardProvider {\n        pub fn detect() -> Self {\n            Self\n        }\n\n        pub fn name(&self) -> Cow<str> {\n            \"none\".into()\n        }\n\n        pub fn get_contents(&self, _clipboard_type: ClipboardType) -> Result<String> {\n            Err(ClipboardError::ReadingNotSupported)\n        }\n\n        pub fn set_contents(&self, _content: &str, _clipboard_type: ClipboardType) -> Result<()> {\n            Ok(())\n        }\n    }\n}\n\n#[cfg(not(target_arch = \"wasm32\"))]\nmod external {\n    use super::*;\n\n    #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]\n    pub struct Command {\n        command: Cow<'static, str>,\n        #[serde(default)]\n        args: Cow<'static, [Cow<'static, str>]>,\n    }\n\n    #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]\n    #[serde(rename_all = \"kebab-case\")]\n    pub struct CommandProvider {\n        yank: Command,\n        paste: Command,\n        yank_primary: Option<Command>,\n        paste_primary: Option<Command>,\n    }\n\n    #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]\n    #[serde(rename_all = \"kebab-case\")]\n    #[allow(clippy::large_enum_variant)]\n    pub enum ClipboardProvider {\n        Pasteboard,\n        Wayland,\n        XClip,\n        XSel,\n        Win32Yank,\n        Tmux,\n        #[cfg(windows)]\n        Windows,\n        Termux,\n        #[cfg(feature = \"term\")]\n        Termcode,\n        Custom(CommandProvider),\n        None,\n    }\n\n    impl Default for ClipboardProvider {\n        #[cfg(windows)]\n        fn default() -> Self {\n            use helix_stdx::env::binary_exists;\n\n            if binary_exists(\"win32yank.exe\") {\n                Self::Win32Yank\n            } else {\n                Self::Windows\n            }\n        }\n\n        #[cfg(target_os = \"macos\")]\n        fn default() -> Self {\n            use helix_stdx::env::{binary_exists, env_var_is_set};\n\n            if env_var_is_set(\"TMUX\") && binary_exists(\"tmux\") {\n                Self::Tmux\n            } else if binary_exists(\"pbcopy\") && binary_exists(\"pbpaste\") {\n                Self::Pasteboard\n            } else {\n                #[cfg(feature = \"term\")]\n                return Self::Termcode;\n                #[cfg(not(feature = \"term\"))]\n                return Self::None;\n            }\n        }\n\n        #[cfg(not(any(windows, target_os = \"macos\")))]\n        fn default() -> Self {\n            use helix_stdx::env::{binary_exists, env_var_is_set};\n\n            fn is_exit_success(program: &str, args: &[&str]) -> bool {\n                std::process::Command::new(program)\n                    .args(args)\n                    .output()\n                    .ok()\n                    .and_then(|out| out.status.success().then_some(()))\n                    .is_some()\n            }\n\n            if env_var_is_set(\"WAYLAND_DISPLAY\")\n                && binary_exists(\"wl-copy\")\n                && binary_exists(\"wl-paste\")\n            {\n                Self::Wayland\n            } else if env_var_is_set(\"DISPLAY\") && binary_exists(\"xclip\") {\n                Self::XClip\n            } else if env_var_is_set(\"DISPLAY\")\n                && binary_exists(\"xsel\")\n                // FIXME: check performance of is_exit_success\n                && is_exit_success(\"xsel\", &[\"-o\", \"-b\"])\n            {\n                Self::XSel\n            } else if binary_exists(\"termux-clipboard-set\") && binary_exists(\"termux-clipboard-get\")\n            {\n                Self::Termux\n            } else if env_var_is_set(\"TMUX\") && binary_exists(\"tmux\") {\n                Self::Tmux\n            } else if binary_exists(\"win32yank.exe\") {\n                Self::Win32Yank\n            } else if cfg!(feature = \"term\") {\n                Self::Termcode\n            } else {\n                Self::None\n            }\n        }\n    }\n\n    impl ClipboardProvider {\n        pub fn name(&self) -> Cow<'_, str> {\n            fn builtin_name<'a>(\n                name: &'static str,\n                provider: &'static CommandProvider,\n            ) -> Cow<'a, str> {\n                if provider.yank.command != provider.paste.command {\n                    Cow::Owned(format!(\n                        \"{} ({}+{})\",\n                        name, provider.yank.command, provider.paste.command\n                    ))\n                } else {\n                    Cow::Owned(format!(\"{} ({})\", name, provider.yank.command))\n                }\n            }\n\n            match self {\n                // These names should match the config option names from Serde\n                Self::Pasteboard => builtin_name(\"pasteboard\", &PASTEBOARD),\n                Self::Wayland => builtin_name(\"wayland\", &WL_CLIPBOARD),\n                Self::XClip => builtin_name(\"x-clip\", &XCLIP),\n                Self::XSel => builtin_name(\"x-sel\", &XSEL),\n                Self::Win32Yank => builtin_name(\"win32-yank\", &WIN32),\n                Self::Tmux => builtin_name(\"tmux\", &TMUX),\n                Self::Termux => builtin_name(\"termux\", &TERMUX),\n                #[cfg(windows)]\n                Self::Windows => \"windows\".into(),\n                #[cfg(feature = \"term\")]\n                Self::Termcode => \"termcode\".into(),\n                Self::Custom(command_provider) => Cow::Owned(format!(\n                    \"custom ({}+{})\",\n                    command_provider.yank.command, command_provider.paste.command\n                )),\n                Self::None => \"none\".into(),\n            }\n        }\n\n        pub fn get_contents(&self, clipboard_type: &ClipboardType) -> Result<String> {\n            fn yank_from_builtin(\n                provider: CommandProvider,\n                clipboard_type: &ClipboardType,\n            ) -> Result<String> {\n                match clipboard_type {\n                    ClipboardType::Clipboard => execute_command(&provider.yank, None, true)?\n                        .ok_or(ClipboardError::MissingStdout),\n                    ClipboardType::Selection => {\n                        if let Some(cmd) = provider.yank_primary.as_ref() {\n                            return execute_command(cmd, None, true)?\n                                .ok_or(ClipboardError::MissingStdout);\n                        }\n\n                        Ok(String::new())\n                    }\n                }\n            }\n\n            match self {\n                Self::Pasteboard => yank_from_builtin(PASTEBOARD, clipboard_type),\n                Self::Wayland => yank_from_builtin(WL_CLIPBOARD, clipboard_type),\n                Self::XClip => yank_from_builtin(XCLIP, clipboard_type),\n                Self::XSel => yank_from_builtin(XSEL, clipboard_type),\n                Self::Win32Yank => yank_from_builtin(WIN32, clipboard_type),\n                Self::Tmux => yank_from_builtin(TMUX, clipboard_type),\n                Self::Termux => yank_from_builtin(TERMUX, clipboard_type),\n                #[cfg(target_os = \"windows\")]\n                Self::Windows => match clipboard_type {\n                    ClipboardType::Clipboard => {\n                        let contents =\n                            clipboard_win::get_clipboard(clipboard_win::formats::Unicode)?;\n                        Ok(contents)\n                    }\n                    ClipboardType::Selection => Ok(String::new()),\n                },\n                #[cfg(feature = \"term\")]\n                Self::Termcode => Err(ClipboardError::ReadingNotSupported),\n                Self::Custom(command_provider) => {\n                    execute_command(&command_provider.yank, None, true)?\n                        .ok_or(ClipboardError::MissingStdout)\n                }\n                Self::None => Err(ClipboardError::ReadingNotSupported),\n            }\n        }\n\n        pub fn set_contents(&self, content: &str, clipboard_type: ClipboardType) -> Result<()> {\n            fn paste_to_builtin(\n                provider: CommandProvider,\n                content: &str,\n                clipboard_type: ClipboardType,\n            ) -> Result<()> {\n                let cmd = match clipboard_type {\n                    ClipboardType::Clipboard => &provider.paste,\n                    ClipboardType::Selection => {\n                        if let Some(cmd) = provider.paste_primary.as_ref() {\n                            cmd\n                        } else {\n                            return Ok(());\n                        }\n                    }\n                };\n\n                execute_command(cmd, Some(content), false).map(|_| ())\n            }\n\n            match self {\n                Self::Pasteboard => paste_to_builtin(PASTEBOARD, content, clipboard_type),\n                Self::Wayland => paste_to_builtin(WL_CLIPBOARD, content, clipboard_type),\n                Self::XClip => paste_to_builtin(XCLIP, content, clipboard_type),\n                Self::XSel => paste_to_builtin(XSEL, content, clipboard_type),\n                Self::Win32Yank => paste_to_builtin(WIN32, content, clipboard_type),\n                Self::Tmux => paste_to_builtin(TMUX, content, clipboard_type),\n                Self::Termux => paste_to_builtin(TERMUX, content, clipboard_type),\n                #[cfg(target_os = \"windows\")]\n                Self::Windows => match clipboard_type {\n                    ClipboardType::Clipboard => {\n                        clipboard_win::set_clipboard(clipboard_win::formats::Unicode, content)?;\n                        Ok(())\n                    }\n                    ClipboardType::Selection => Ok(()),\n                },\n                #[cfg(feature = \"term\")]\n                Self::Termcode => {\n                    use std::io::Write;\n                    use termina::escape::osc::{self, Osc};\n                    let selection = match clipboard_type {\n                        ClipboardType::Clipboard => osc::Selection::CLIPBOARD,\n                        ClipboardType::Selection => osc::Selection::PRIMARY,\n                    };\n                    // NOTE: it would be ideal to have the terminal execute this but it _should_\n                    // work to send this over stdout instead.\n                    let mut stdout = std::io::stdout().lock();\n                    write!(stdout, \"{}\", Osc::SetSelection(selection, content))?;\n                    stdout.flush()?;\n                    Ok(())\n                }\n                Self::Custom(command_provider) => match clipboard_type {\n                    ClipboardType::Clipboard => {\n                        execute_command(&command_provider.paste, Some(content), false).map(|_| ())\n                    }\n                    ClipboardType::Selection => {\n                        if let Some(cmd) = &command_provider.paste_primary {\n                            execute_command(cmd, Some(content), false).map(|_| ())\n                        } else {\n                            Ok(())\n                        }\n                    }\n                },\n                Self::None => Ok(()),\n            }\n        }\n    }\n\n    macro_rules! command_provider {\n        ($name:ident,\n         yank => $yank_cmd:literal $( , $yank_arg:literal )* ;\n         paste => $paste_cmd:literal $( , $paste_arg:literal )* ; ) => {\n            const $name: CommandProvider = CommandProvider {\n                yank: Command {\n                    command: Cow::Borrowed($yank_cmd),\n                    args: Cow::Borrowed(&[ $( Cow::Borrowed($yank_arg) ),* ])\n                },\n                paste: Command {\n                    command: Cow::Borrowed($paste_cmd),\n                    args: Cow::Borrowed(&[ $( Cow::Borrowed($paste_arg) ),* ])\n                },\n                yank_primary: None,\n                paste_primary: None,\n            };\n        };\n        ($name:ident,\n         yank => $yank_cmd:literal $( , $yank_arg:literal )* ;\n         paste => $paste_cmd:literal $( , $paste_arg:literal )* ;\n         yank_primary => $yank_primary_cmd:literal $( , $yank_primary_arg:literal )* ;\n         paste_primary => $paste_primary_cmd:literal $( , $paste_primary_arg:literal )* ; ) => {\n            const $name: CommandProvider = CommandProvider {\n                yank: Command {\n                    command: Cow::Borrowed($yank_cmd),\n                    args: Cow::Borrowed(&[ $( Cow::Borrowed($yank_arg) ),* ])\n                },\n                paste: Command {\n                    command: Cow::Borrowed($paste_cmd),\n                    args: Cow::Borrowed(&[ $( Cow::Borrowed($paste_arg) ),* ])\n                },\n                yank_primary: Some(Command {\n                    command: Cow::Borrowed($yank_primary_cmd),\n                    args: Cow::Borrowed(&[ $( Cow::Borrowed($yank_primary_arg) ),* ])\n                }),\n                paste_primary: Some(Command {\n                    command: Cow::Borrowed($paste_primary_cmd),\n                    args: Cow::Borrowed(&[ $( Cow::Borrowed($paste_primary_arg) ),* ])\n                }),\n            };\n        };\n    }\n\n    command_provider! {\n        TMUX,\n        yank => \"tmux\", \"save-buffer\", \"-\";\n        paste => \"tmux\", \"load-buffer\", \"-w\", \"-\";\n    }\n    command_provider! {\n        PASTEBOARD,\n        yank => \"pbpaste\";\n        paste => \"pbcopy\";\n    }\n    command_provider! {\n        WL_CLIPBOARD,\n        yank => \"wl-paste\", \"--no-newline\";\n        paste => \"wl-copy\", \"--type\", \"text/plain\";\n        yank_primary => \"wl-paste\", \"-p\", \"--no-newline\";\n        paste_primary => \"wl-copy\", \"-p\", \"--type\", \"text/plain\";\n    }\n    command_provider! {\n        XCLIP,\n        yank => \"xclip\", \"-o\", \"-selection\", \"clipboard\";\n        paste => \"xclip\", \"-i\", \"-selection\", \"clipboard\";\n        yank_primary => \"xclip\", \"-o\";\n        paste_primary => \"xclip\", \"-i\";\n    }\n    command_provider! {\n        XSEL,\n        yank => \"xsel\", \"-o\", \"-b\";\n        paste => \"xsel\", \"-i\", \"-b\";\n        yank_primary => \"xsel\", \"-o\";\n        paste_primary => \"xsel\", \"-i\";\n    }\n    command_provider! {\n        WIN32,\n        yank => \"win32yank.exe\", \"-o\", \"--lf\";\n        paste => \"win32yank.exe\", \"-i\", \"--crlf\";\n    }\n    command_provider! {\n        TERMUX,\n        yank => \"termux-clipboard-get\";\n        paste => \"termux-clipboard-set\";\n    }\n\n    fn execute_command(\n        cmd: &Command,\n        input: Option<&str>,\n        pipe_output: bool,\n    ) -> Result<Option<String>> {\n        use std::io::Write;\n        use std::process::{Command, Stdio};\n\n        let stdin = input.map(|_| Stdio::piped()).unwrap_or_else(Stdio::null);\n        let stdout = pipe_output.then(Stdio::piped).unwrap_or_else(Stdio::null);\n\n        let mut command: Command = Command::new(cmd.command.as_ref());\n\n        #[allow(unused_mut)]\n        let mut command_mut: &mut Command = command\n            .args(cmd.args.iter().map(AsRef::as_ref))\n            .stdin(stdin)\n            .stdout(stdout)\n            .stderr(Stdio::null());\n\n        // Fix for https://github.com/helix-editor/helix/issues/5424\n        #[cfg(unix)]\n        {\n            use std::os::unix::process::CommandExt;\n\n            unsafe {\n                command_mut = command_mut.pre_exec(|| match libc::setsid() {\n                    -1 => Err(std::io::Error::last_os_error()),\n                    _ => Ok(()),\n                });\n            }\n        }\n\n        let mut child = command_mut.spawn()?;\n\n        if let Some(input) = input {\n            let mut stdin = child.stdin.take().ok_or(ClipboardError::StdinWriteFailed)?;\n            stdin\n                .write_all(input.as_bytes())\n                .map_err(|_| ClipboardError::StdinWriteFailed)?;\n        }\n\n        // TODO: add timer?\n        let output = child.wait_with_output()?;\n\n        if !output.status.success() {\n            log::error!(\n                \"clipboard provider {} failed with stderr: \\\"{}\\\"\",\n                cmd.command,\n                String::from_utf8_lossy(&output.stderr)\n            );\n            return Err(ClipboardError::CommandFailed);\n        }\n\n        if pipe_output {\n            Ok(Some(String::from_utf8(output.stdout)?))\n        } else {\n            Ok(None)\n        }\n    }\n}\n"
  },
  {
    "path": "helix-view/src/document.rs",
    "content": "use anyhow::{anyhow, bail, Error};\nuse arc_swap::access::DynAccess;\nuse arc_swap::ArcSwap;\nuse futures_util::future::BoxFuture;\nuse futures_util::FutureExt;\nuse helix_core::auto_pairs::AutoPairs;\nuse helix_core::chars::char_is_word;\nuse helix_core::command_line::Token;\nuse helix_core::diagnostic::DiagnosticProvider;\nuse helix_core::doc_formatter::TextFormat;\nuse helix_core::encoding::Encoding;\nuse helix_core::snippets::{ActiveSnippet, SnippetRenderCtx};\nuse helix_core::syntax::config::LanguageServerFeature;\nuse helix_core::text_annotations::{InlineAnnotation, Overlay};\nuse helix_event::TaskController;\nuse helix_lsp::util::lsp_pos_to_pos;\nuse helix_stdx::faccess::{copy_metadata, readonly};\nuse helix_vcs::{DiffHandle, DiffProviderRegistry};\nuse once_cell::sync::OnceCell;\nuse thiserror;\n\nuse ::parking_lot::Mutex;\nuse serde::de::{self, Deserialize, Deserializer};\nuse serde::Serialize;\nuse std::borrow::Cow;\nuse std::cell::Cell;\nuse std::collections::HashMap;\nuse std::fmt::Display;\nuse std::future::Future;\nuse std::io;\nuse std::path::{Path, PathBuf};\nuse std::str::FromStr;\nuse std::sync::{Arc, Weak};\nuse std::time::SystemTime;\n\nuse helix_core::{\n    editor_config::EditorConfig,\n    encoding,\n    history::{History, State, UndoKind},\n    indent::{auto_detect_indent_style, IndentStyle},\n    line_ending::auto_detect_line_ending,\n    syntax::{self, config::LanguageConfiguration},\n    ChangeSet, Diagnostic, LineEnding, Range, Rope, RopeBuilder, Selection, Syntax, Transaction,\n};\n\nuse crate::{\n    editor::Config,\n    events::{DocumentDidChange, SelectionDidChange},\n    expansion,\n    view::ViewPosition,\n    DocumentId, Editor, Theme, View, ViewId,\n};\n\n/// 8kB of buffer space for encoding and decoding `Rope`s.\nconst BUF_SIZE: usize = 8192;\n\nconst DEFAULT_INDENT: IndentStyle = IndentStyle::Tabs;\nconst DEFAULT_TAB_WIDTH: usize = 4;\n\npub const DEFAULT_LANGUAGE_NAME: &str = \"text\";\n\npub const SCRATCH_BUFFER_NAME: &str = \"[scratch]\";\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub enum Mode {\n    Normal = 0,\n    Select = 1,\n    Insert = 2,\n}\n\nimpl Display for Mode {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Mode::Normal => f.write_str(\"normal\"),\n            Mode::Select => f.write_str(\"select\"),\n            Mode::Insert => f.write_str(\"insert\"),\n        }\n    }\n}\n\nimpl FromStr for Mode {\n    type Err = Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        match s {\n            \"normal\" => Ok(Mode::Normal),\n            \"select\" => Ok(Mode::Select),\n            \"insert\" => Ok(Mode::Insert),\n            _ => bail!(\"Invalid mode '{}'\", s),\n        }\n    }\n}\n\n// toml deserializer doesn't seem to recognize string as enum\nimpl<'de> Deserialize<'de> for Mode {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let s = String::deserialize(deserializer)?;\n        s.parse().map_err(de::Error::custom)\n    }\n}\n\nimpl Serialize for Mode {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        serializer.collect_str(self)\n    }\n}\n/// A snapshot of the text of a document that we want to write out to disk\n#[derive(Debug, Clone)]\npub struct DocumentSavedEvent {\n    pub revision: usize,\n    pub save_time: SystemTime,\n    pub doc_id: DocumentId,\n    pub path: PathBuf,\n    pub text: Rope,\n}\n\npub type DocumentSavedEventResult = Result<DocumentSavedEvent, anyhow::Error>;\npub type DocumentSavedEventFuture = BoxFuture<'static, DocumentSavedEventResult>;\n\n#[derive(Debug)]\npub struct SavePoint {\n    /// The view this savepoint is associated with\n    pub view: ViewId,\n    revert: Mutex<Transaction>,\n}\n\n#[derive(Debug, thiserror::Error)]\npub enum DocumentOpenError {\n    #[error(\"path must be a regular file, symlink, or directory\")]\n    IrregularFile,\n    #[error(transparent)]\n    IoError(#[from] io::Error),\n}\n\npub struct Document {\n    pub(crate) id: DocumentId,\n    text: Rope,\n    selections: HashMap<ViewId, Selection>,\n    view_data: HashMap<ViewId, ViewData>,\n    pub active_snippet: Option<ActiveSnippet>,\n\n    /// Inlay hints annotations for the document, by view.\n    ///\n    /// To know if they're up-to-date, check the `id` field in `DocumentInlayHints`.\n    pub(crate) inlay_hints: HashMap<ViewId, DocumentInlayHints>,\n    /// Jump label overlays for each view.\n    pub(crate) jump_labels: HashMap<ViewId, Vec<Overlay>>,\n    /// LSP document highlights for each view, stored as char ranges.\n    pub(crate) document_highlights: HashMap<ViewId, DocumentHighlights>,\n    /// Set to `true` when the document is updated, reset to `false` on the next inlay hints\n    /// update from the LSP\n    pub inlay_hints_oudated: bool,\n\n    path: Option<PathBuf>,\n    relative_path: OnceCell<Option<PathBuf>>,\n    encoding: &'static encoding::Encoding,\n    has_bom: bool,\n\n    pub restore_cursor: bool,\n\n    /// Current indent style.\n    pub indent_style: IndentStyle,\n    editor_config: EditorConfig,\n\n    /// The document's default line ending.\n    pub line_ending: LineEnding,\n\n    pub syntax: Option<Syntax>,\n    /// Corresponding language scope name. Usually `source.<lang>`.\n    pub language: Option<Arc<LanguageConfiguration>>,\n\n    /// Pending changes since last history commit.\n    changes: ChangeSet,\n    /// State at last commit. Used for calculating reverts.\n    old_state: Option<State>,\n    /// Undo tree.\n    // It can be used as a cell where we will take it out to get some parts of the history and put\n    // it back as it separated from the edits. We could split out the parts manually but that will\n    // be more troublesome.\n    pub history: Cell<History>,\n    pub config: Arc<dyn DynAccess<Config>>,\n\n    savepoints: Vec<Weak<SavePoint>>,\n\n    // Last time we wrote to the file. This will carry the time the file was last opened if there\n    // were no saves.\n    last_saved_time: SystemTime,\n\n    last_saved_revision: usize,\n    version: i32, // should be usize?\n    pub(crate) modified_since_accessed: bool,\n\n    pub(crate) diagnostics: Vec<Diagnostic>,\n    pub(crate) language_servers: HashMap<LanguageServerName, Arc<Client>>,\n\n    diff_handle: Option<DiffHandle>,\n    version_control_head: Option<Arc<ArcSwap<Box<str>>>>,\n\n    // when document was used for most-recent-used buffer picker\n    pub focused_at: std::time::Instant,\n\n    pub readonly: bool,\n\n    pub previous_diagnostic_id: Option<String>,\n\n    /// Annotations for LSP document color swatches\n    pub color_swatches: Option<DocumentColorSwatches>,\n    /// Cached LSP document links for navigation (e.g. goto_file).\n    pub document_links: Vec<DocumentLink>,\n    // NOTE: ideally this would live on the handler for color swatches. This is blocked on a\n    // large refactor that would make `&mut Editor` available on the `DocumentDidChange` event.\n    pub color_swatch_controller: TaskController,\n    /// Per-view task controllers for canceling in-flight document highlight requests.\n    pub document_highlight_controllers: HashMap<ViewId, TaskController>,\n    pub pull_diagnostic_controller: TaskController,\n    pub document_link_controller: TaskController,\n\n    // NOTE: this field should eventually go away - we should use the Editor's syn_loader instead\n    // of storing a copy on every doc. Then we can remove the surrounding `Arc` and use the\n    // `ArcSwap` directly.\n    syn_loader: Arc<ArcSwap<syntax::Loader>>,\n}\n\n#[derive(Debug, Clone, Default)]\npub struct DocumentColorSwatches {\n    pub color_swatches: Vec<InlineAnnotation>,\n    pub colors: Vec<syntax::Highlight>,\n    pub color_swatches_padding: Vec<InlineAnnotation>,\n}\n\n/// Highlight ranges returned by LSP `textDocument/documentHighlight` for a view.\n#[derive(Debug, Clone, Default)]\npub struct DocumentHighlights {\n    pub ranges: Vec<std::ops::Range<usize>>,\n}\n\n#[derive(Debug, Clone)]\npub struct DocumentLink {\n    /// Character offsets in the document for the link range.\n    pub start: usize,\n    pub end: usize,\n    pub link: lsp::DocumentLink,\n    pub language_server_id: LanguageServerId,\n}\n\n/// Inlay hints for a single `(Document, View)` combo.\n///\n/// There are `*_inlay_hints` field for each kind of hints an LSP can send since we offer the\n/// option to style theme differently in the theme according to the (currently supported) kinds\n/// (`type`, `parameter` and the rest).\n///\n/// Inlay hints are always `InlineAnnotation`s, not overlays or line-ones: LSP may choose to place\n/// them anywhere in the text and will sometime offer config options to move them where the user\n/// wants them but it shouldn't be Helix who decides that so we use the most precise positioning.\n///\n/// The padding for inlay hints needs to be stored separately for before and after (the LSP spec\n/// uses 'left' and 'right' but not all text is left to right so let's be correct) padding because\n/// the 'before' padding must be added to a layer *before* the regular inlay hints and the 'after'\n/// padding comes ... after.\n#[derive(Debug, Clone)]\npub struct DocumentInlayHints {\n    /// Identifier for the inlay hints stored in this structure. To be checked to know if they have\n    /// to be recomputed on idle or not.\n    pub id: DocumentInlayHintsId,\n\n    /// Inlay hints of `TYPE` kind, if any.\n    pub type_inlay_hints: Vec<InlineAnnotation>,\n\n    /// Inlay hints of `PARAMETER` kind, if any.\n    pub parameter_inlay_hints: Vec<InlineAnnotation>,\n\n    /// Inlay hints that are neither `TYPE` nor `PARAMETER`.\n    ///\n    /// LSPs are not required to associate a kind to their inlay hints, for example Rust-Analyzer\n    /// currently never does (February 2023) and the LSP spec may add new kinds in the future that\n    /// we want to display even if we don't have some special highlighting for them.\n    pub other_inlay_hints: Vec<InlineAnnotation>,\n\n    /// Inlay hint padding. When creating the final `TextAnnotations`, the `before` padding must be\n    /// added first, then the regular inlay hints, then the `after` padding.\n    pub padding_before_inlay_hints: Vec<InlineAnnotation>,\n    pub padding_after_inlay_hints: Vec<InlineAnnotation>,\n}\n\nimpl DocumentInlayHints {\n    /// Generate an empty list of inlay hints with the given ID.\n    pub fn empty_with_id(id: DocumentInlayHintsId) -> Self {\n        Self {\n            id,\n            type_inlay_hints: Vec::new(),\n            parameter_inlay_hints: Vec::new(),\n            other_inlay_hints: Vec::new(),\n            padding_before_inlay_hints: Vec::new(),\n            padding_after_inlay_hints: Vec::new(),\n        }\n    }\n}\n\n/// Associated with a [`Document`] and [`ViewId`], uniquely identifies the state of inlay hints for\n/// for that document and view: if this changed since the last save, the inlay hints for the view\n/// should be recomputed.\n///\n/// We can't store the `ViewOffset` instead of the first and last asked-for lines because if\n/// softwrapping changes, the `ViewOffset` may not change while the displayed lines will.\n#[derive(Copy, Clone, PartialEq, Eq)]\npub struct DocumentInlayHintsId {\n    /// First line for which the inlay hints were requested.\n    pub first_line: usize,\n    /// Last line for which the inlay hints were requested.\n    pub last_line: usize,\n}\n\nuse std::{fmt, mem};\nimpl fmt::Debug for Document {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"Document\")\n            .field(\"id\", &self.id)\n            .field(\"text\", &self.text)\n            .field(\"selections\", &self.selections)\n            .field(\"inlay_hints_oudated\", &self.inlay_hints_oudated)\n            .field(\"text_annotations\", &self.inlay_hints)\n            .field(\"view_data\", &self.view_data)\n            .field(\"path\", &self.path)\n            .field(\"encoding\", &self.encoding)\n            .field(\"restore_cursor\", &self.restore_cursor)\n            .field(\"syntax\", &self.syntax)\n            .field(\"language\", &self.language)\n            .field(\"changes\", &self.changes)\n            .field(\"old_state\", &self.old_state)\n            // .field(\"history\", &self.history)\n            .field(\"last_saved_time\", &self.last_saved_time)\n            .field(\"last_saved_revision\", &self.last_saved_revision)\n            .field(\"version\", &self.version)\n            .field(\"modified_since_accessed\", &self.modified_since_accessed)\n            .field(\"diagnostics\", &self.diagnostics)\n            // .field(\"language_server\", &self.language_server)\n            .finish()\n    }\n}\n\nimpl fmt::Debug for DocumentInlayHintsId {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        // Much more agreable to read when debugging\n        f.debug_struct(\"DocumentInlayHintsId\")\n            .field(\"lines\", &(self.first_line..self.last_line))\n            .finish()\n    }\n}\n\nimpl Editor {\n    pub(crate) fn clear_doc_relative_paths(&mut self) {\n        for doc in self.documents_mut() {\n            doc.relative_path.take();\n        }\n    }\n}\n\nenum Encoder {\n    Utf16Be,\n    Utf16Le,\n    EncodingRs(encoding::Encoder),\n}\n\nimpl Encoder {\n    fn from_encoding(encoding: &'static encoding::Encoding) -> Self {\n        if encoding == encoding::UTF_16BE {\n            Self::Utf16Be\n        } else if encoding == encoding::UTF_16LE {\n            Self::Utf16Le\n        } else {\n            Self::EncodingRs(encoding.new_encoder())\n        }\n    }\n\n    fn encode_from_utf8(\n        &mut self,\n        src: &str,\n        dst: &mut [u8],\n        is_empty: bool,\n    ) -> (encoding::CoderResult, usize, usize) {\n        if src.is_empty() {\n            return (encoding::CoderResult::InputEmpty, 0, 0);\n        }\n        let mut write_to_buf = |convert: fn(u16) -> [u8; 2]| {\n            let to_write = src.char_indices().map(|(indice, char)| {\n                let mut encoded: [u16; 2] = [0, 0];\n                (\n                    indice,\n                    char.encode_utf16(&mut encoded)\n                        .iter_mut()\n                        .flat_map(|char| convert(*char))\n                        .collect::<Vec<u8>>(),\n                )\n            });\n\n            let mut total_written = 0usize;\n\n            for (indice, utf16_bytes) in to_write {\n                let character_size = utf16_bytes.len();\n\n                if dst.len() <= (total_written + character_size) {\n                    return (encoding::CoderResult::OutputFull, indice, total_written);\n                }\n\n                for character in utf16_bytes {\n                    dst[total_written] = character;\n                    total_written += 1;\n                }\n            }\n\n            (encoding::CoderResult::InputEmpty, src.len(), total_written)\n        };\n\n        match self {\n            Self::Utf16Be => write_to_buf(u16::to_be_bytes),\n            Self::Utf16Le => write_to_buf(u16::to_le_bytes),\n            Self::EncodingRs(encoder) => {\n                let (code_result, read, written, ..) = encoder.encode_from_utf8(src, dst, is_empty);\n\n                (code_result, read, written)\n            }\n        }\n    }\n}\n\n// Apply BOM if encoding permit it, return the number of bytes written at the start of buf\nfn apply_bom(encoding: &'static encoding::Encoding, buf: &mut [u8; BUF_SIZE]) -> usize {\n    if encoding == encoding::UTF_8 {\n        buf[0] = 0xef;\n        buf[1] = 0xbb;\n        buf[2] = 0xbf;\n        3\n    } else if encoding == encoding::UTF_16BE {\n        buf[0] = 0xfe;\n        buf[1] = 0xff;\n        2\n    } else if encoding == encoding::UTF_16LE {\n        buf[0] = 0xff;\n        buf[1] = 0xfe;\n        2\n    } else {\n        0\n    }\n}\n\n// The documentation and implementation of this function should be up-to-date with\n// its sibling function, `to_writer()`.\n//\n/// Decodes a stream of bytes into UTF-8, returning a `Rope` and the\n/// encoding it was decoded as with BOM information. The optional `encoding`\n/// parameter can be used to override encoding auto-detection.\npub fn from_reader<R: std::io::Read + ?Sized>(\n    reader: &mut R,\n    encoding: Option<&'static Encoding>,\n) -> Result<(Rope, &'static Encoding, bool), io::Error> {\n    // These two buffers are 8192 bytes in size each and are used as\n    // intermediaries during the decoding process. Text read into `buf`\n    // from `reader` is decoded into `buf_out` as UTF-8. Once either\n    // `buf_out` is full or the end of the reader was reached, the\n    // contents are appended to `builder`.\n    let mut buf = [0u8; BUF_SIZE];\n    let mut buf_out = [0u8; BUF_SIZE];\n    let mut builder = RopeBuilder::new();\n\n    let (encoding, has_bom, mut decoder, read) =\n        read_and_detect_encoding(reader, encoding, &mut buf)?;\n\n    let mut slice = &buf[..read];\n    let mut is_empty = read == 0;\n\n    // `RopeBuilder::append()` expects a `&str`, so this is the \"real\"\n    // output buffer. When decoding, the number of bytes in the output\n    // buffer will often exceed the number of bytes in the input buffer.\n    // The `result` returned by `decode_to_str()` will state whether or\n    // not that happened. The contents of `buf_str` is appended to\n    // `builder` and it is reused for the next iteration of the decoding\n    // loop.\n    //\n    // As it is possible to read less than the buffer's maximum from `read()`\n    // even when the end of the reader has yet to be reached, the end of\n    // the reader is determined only when a `read()` call returns `0`.\n    //\n    // SAFETY: `buf_out` is a zero-initialized array, thus it will always\n    // contain valid UTF-8.\n    let buf_str = unsafe { std::str::from_utf8_unchecked_mut(&mut buf_out[..]) };\n    let mut total_written = 0usize;\n    loop {\n        let mut total_read = 0usize;\n\n        // An inner loop is necessary as it is possible that the input buffer\n        // may not be completely decoded on the first `decode_to_str()` call\n        // which would happen in cases where the output buffer is filled to\n        // capacity.\n        loop {\n            let (result, read, written, ..) = decoder.decode_to_str(\n                &slice[total_read..],\n                &mut buf_str[total_written..],\n                is_empty,\n            );\n\n            // These variables act as the read and write cursors of `buf` and `buf_str` respectively.\n            // They are necessary in case the output buffer fills before decoding of the entire input\n            // loop is complete. Otherwise, the loop would endlessly iterate over the same `buf` and\n            // the data inside the output buffer would be overwritten.\n            total_read += read;\n            total_written += written;\n            match result {\n                encoding::CoderResult::InputEmpty => {\n                    debug_assert_eq!(slice.len(), total_read);\n                    break;\n                }\n                encoding::CoderResult::OutputFull => {\n                    debug_assert!(slice.len() > total_read);\n                    builder.append(&buf_str[..total_written]);\n                    total_written = 0;\n                }\n            }\n        }\n        // Once the end of the stream is reached, the output buffer is\n        // flushed and the loop terminates.\n        if is_empty {\n            debug_assert_eq!(reader.read(&mut buf)?, 0);\n            builder.append(&buf_str[..total_written]);\n            break;\n        }\n\n        // Once the previous input has been processed and decoded, the next set of\n        // data is fetched from the reader. The end of the reader is determined to\n        // be when exactly `0` bytes were read from the reader, as per the invariants\n        // of the `Read` trait.\n        let read = reader.read(&mut buf)?;\n        slice = &buf[..read];\n        is_empty = read == 0;\n    }\n    let rope = builder.finish();\n    Ok((rope, encoding, has_bom))\n}\n\npub fn read_to_string<R: std::io::Read + ?Sized>(\n    reader: &mut R,\n    encoding: Option<&'static Encoding>,\n) -> Result<(String, &'static Encoding, bool), Error> {\n    let mut buf = [0u8; BUF_SIZE];\n\n    let (encoding, has_bom, mut decoder, read) =\n        read_and_detect_encoding(reader, encoding, &mut buf)?;\n\n    let mut slice = &buf[..read];\n    let mut is_empty = read == 0;\n    let mut buf_string = String::with_capacity(buf.len());\n\n    loop {\n        let mut total_read = 0usize;\n\n        loop {\n            let (result, read, ..) =\n                decoder.decode_to_string(&slice[total_read..], &mut buf_string, is_empty);\n\n            total_read += read;\n\n            match result {\n                encoding::CoderResult::InputEmpty => {\n                    debug_assert_eq!(slice.len(), total_read);\n                    break;\n                }\n                encoding::CoderResult::OutputFull => {\n                    debug_assert!(slice.len() > total_read);\n                    buf_string.reserve(buf.len())\n                }\n            }\n        }\n\n        if is_empty {\n            debug_assert_eq!(reader.read(&mut buf)?, 0);\n            break;\n        }\n\n        let read = reader.read(&mut buf)?;\n        slice = &buf[..read];\n        is_empty = read == 0;\n    }\n    Ok((buf_string, encoding, has_bom))\n}\n\n/// Reads the first chunk from a Reader into the given buffer\n/// and detects the encoding.\n///\n/// By default, the encoding of the text is auto-detected by\n/// `encoding_rs` for_bom, and if it fails, from `chardetng`\n/// crate which requires sample data from the reader.\n/// As a manual override to this auto-detection is possible, the\n/// same data is read into `buf` to ensure symmetry in the upcoming\n/// loop.\nfn read_and_detect_encoding<R: std::io::Read + ?Sized>(\n    reader: &mut R,\n    encoding: Option<&'static Encoding>,\n    buf: &mut [u8],\n) -> Result<(&'static Encoding, bool, encoding::Decoder, usize), io::Error> {\n    let read = reader.read(buf)?;\n    let is_empty = read == 0;\n    let (encoding, has_bom) = encoding\n        .map(|encoding| (encoding, false))\n        .or_else(|| encoding::Encoding::for_bom(buf).map(|(encoding, _bom_size)| (encoding, true)))\n        .unwrap_or_else(|| {\n            let mut encoding_detector = chardetng::EncodingDetector::new();\n            encoding_detector.feed(buf, is_empty);\n            (encoding_detector.guess(None, true), false)\n        });\n    let decoder = encoding.new_decoder();\n\n    Ok((encoding, has_bom, decoder, read))\n}\n\n// The documentation and implementation of this function should be up-to-date with\n// its sibling function, `from_reader()`.\n//\n/// Encodes the text inside `rope` into the given `encoding` and writes the\n/// encoded output into `writer.` As a `Rope` can only contain valid UTF-8,\n/// replacement characters may appear in the encoded text.\npub async fn to_writer<'a, W: tokio::io::AsyncWriteExt + Unpin + ?Sized>(\n    writer: &'a mut W,\n    encoding_with_bom_info: (&'static Encoding, bool),\n    rope: &'a Rope,\n) -> Result<(), Error> {\n    // Text inside a `Rope` is stored as non-contiguous blocks of data called\n    // chunks. The absolute size of each chunk is unknown, thus it is impossible\n    // to predict the end of the chunk iterator ahead of time. Instead, it is\n    // determined by filtering the iterator to remove all empty chunks and then\n    // appending an empty chunk to it. This is valuable for detecting when all\n    // chunks in the `Rope` have been iterated over in the subsequent loop.\n    let (encoding, has_bom) = encoding_with_bom_info;\n\n    let iter = rope\n        .chunks()\n        .filter(|c| !c.is_empty())\n        .chain(std::iter::once(\"\"));\n    let mut buf = [0u8; BUF_SIZE];\n\n    let mut total_written = if has_bom {\n        apply_bom(encoding, &mut buf)\n    } else {\n        0\n    };\n\n    let mut encoder = Encoder::from_encoding(encoding);\n\n    for chunk in iter {\n        let is_empty = chunk.is_empty();\n        let mut total_read = 0usize;\n\n        // An inner loop is necessary as it is possible that the input buffer\n        // may not be completely encoded on the first `encode_from_utf8()` call\n        // which would happen in cases where the output buffer is filled to\n        // capacity.\n        loop {\n            let (result, read, written, ..) =\n                encoder.encode_from_utf8(&chunk[total_read..], &mut buf[total_written..], is_empty);\n\n            // These variables act as the read and write cursors of `chunk` and `buf` respectively.\n            // They are necessary in case the output buffer fills before encoding of the entire input\n            // loop is complete. Otherwise, the loop would endlessly iterate over the same `chunk` and\n            // the data inside the output buffer would be overwritten.\n            total_read += read;\n            total_written += written;\n            match result {\n                encoding::CoderResult::InputEmpty => {\n                    debug_assert_eq!(chunk.len(), total_read);\n                    debug_assert!(buf.len() >= total_written);\n                    break;\n                }\n                encoding::CoderResult::OutputFull => {\n                    debug_assert!(chunk.len() > total_read);\n                    writer.write_all(&buf[..total_written]).await?;\n                    total_written = 0;\n                }\n            }\n        }\n\n        // Once the end of the iterator is reached, the output buffer is\n        // flushed and the outer loop terminates.\n        if is_empty {\n            writer.write_all(&buf[..total_written]).await?;\n            writer.flush().await?;\n            break;\n        }\n    }\n\n    Ok(())\n}\n\nfn take_with<T, F>(mut_ref: &mut T, f: F)\nwhere\n    T: Default,\n    F: FnOnce(T) -> T,\n{\n    *mut_ref = f(mem::take(mut_ref));\n}\n\nuse helix_lsp::{lsp, Client, LanguageServerId, LanguageServerName};\nuse url::Url;\n\nimpl Document {\n    pub fn from(\n        text: Rope,\n        encoding_with_bom_info: Option<(&'static Encoding, bool)>,\n        config: Arc<dyn DynAccess<Config>>,\n        syn_loader: Arc<ArcSwap<syntax::Loader>>,\n    ) -> Self {\n        let (encoding, has_bom) = encoding_with_bom_info.unwrap_or((encoding::UTF_8, false));\n        let line_ending = config.load().default_line_ending.into();\n        let changes = ChangeSet::new(text.slice(..));\n        let old_state = None;\n\n        Self {\n            id: DocumentId::default(),\n            active_snippet: None,\n            path: None,\n            relative_path: OnceCell::new(),\n            encoding,\n            has_bom,\n            text,\n            selections: HashMap::default(),\n            inlay_hints: HashMap::default(),\n            inlay_hints_oudated: false,\n            view_data: Default::default(),\n            indent_style: DEFAULT_INDENT,\n            editor_config: EditorConfig::default(),\n            line_ending,\n            restore_cursor: false,\n            syntax: None,\n            language: None,\n            changes,\n            old_state,\n            diagnostics: Vec::new(),\n            version: 0,\n            history: Cell::new(History::default()),\n            savepoints: Vec::new(),\n            last_saved_time: SystemTime::now(),\n            last_saved_revision: 0,\n            modified_since_accessed: false,\n            language_servers: HashMap::new(),\n            diff_handle: None,\n            config,\n            version_control_head: None,\n            focused_at: std::time::Instant::now(),\n            readonly: false,\n            jump_labels: HashMap::new(),\n            document_highlights: HashMap::new(),\n            color_swatches: None,\n            document_links: Vec::new(),\n            color_swatch_controller: TaskController::new(),\n            document_highlight_controllers: HashMap::new(),\n            syn_loader,\n            previous_diagnostic_id: None,\n            pull_diagnostic_controller: TaskController::new(),\n            document_link_controller: TaskController::new(),\n        }\n    }\n\n    pub fn default(\n        config: Arc<dyn DynAccess<Config>>,\n        syn_loader: Arc<ArcSwap<syntax::Loader>>,\n    ) -> Self {\n        let line_ending: LineEnding = config.load().default_line_ending.into();\n        let text = Rope::from(line_ending.as_str());\n        Self::from(text, None, config, syn_loader)\n    }\n\n    // TODO: async fn?\n    /// Create a new document from `path`. Encoding is auto-detected, but it can be manually\n    /// overwritten with the `encoding` parameter.\n    pub fn open(\n        path: &Path,\n        mut encoding: Option<&'static Encoding>,\n        detect_language: bool,\n        config: Arc<dyn DynAccess<Config>>,\n        syn_loader: Arc<ArcSwap<syntax::Loader>>,\n    ) -> Result<Self, DocumentOpenError> {\n        // If the path is not a regular file (e.g.: /dev/random) it should not be opened.\n        if path.metadata().is_ok_and(|metadata| !metadata.is_file()) {\n            return Err(DocumentOpenError::IrregularFile);\n        }\n\n        let editor_config = if config.load().editor_config {\n            EditorConfig::find(path)\n        } else {\n            EditorConfig::default()\n        };\n        encoding = encoding.or(editor_config.encoding);\n\n        // Open the file if it exists, otherwise assume it is a new file (and thus empty).\n        let (rope, encoding, has_bom) = if path.exists() {\n            let mut file = std::fs::File::open(path)?;\n            from_reader(&mut file, encoding)?\n        } else {\n            let line_ending = editor_config\n                .line_ending\n                .unwrap_or_else(|| config.load().default_line_ending.into());\n            let encoding = encoding.unwrap_or(encoding::UTF_8);\n            (Rope::from(line_ending.as_str()), encoding, false)\n        };\n\n        let loader = syn_loader.load();\n        let mut doc = Self::from(rope, Some((encoding, has_bom)), config, syn_loader);\n\n        // set the path and try detecting the language\n        doc.set_path(Some(path));\n        if detect_language {\n            doc.detect_language(&loader);\n        }\n\n        doc.editor_config = editor_config;\n        doc.detect_indent_and_line_ending();\n\n        Ok(doc)\n    }\n\n    /// The same as [`format`], but only returns formatting changes if auto-formatting\n    /// is configured.\n    pub fn auto_format(\n        &self,\n        editor: &Editor,\n    ) -> Option<BoxFuture<'static, Result<Transaction, FormatterError>>> {\n        if self.language_config()?.auto_format {\n            self.format(editor)\n        } else {\n            None\n        }\n    }\n\n    /// If supported, returns the changes that should be applied to this document in order\n    /// to format it nicely.\n    // We can't use anyhow::Result here since the output of the future has to be\n    // clonable to be used as shared future. So use a custom error type.\n    pub fn format(\n        &self,\n        editor: &Editor,\n    ) -> Option<BoxFuture<'static, Result<Transaction, FormatterError>>> {\n        if let Some((fmt_cmd, fmt_args)) = self\n            .language_config()\n            .and_then(|c| c.formatter.as_ref())\n            .and_then(|formatter| {\n                Some((\n                    helix_stdx::env::which(&formatter.command).ok()?,\n                    &formatter.args,\n                ))\n            })\n        {\n            log::debug!(\n                \"formatting '{}' with command '{}', args {fmt_args:?}\",\n                self.display_name(),\n                fmt_cmd.display(),\n            );\n            use std::process::Stdio;\n            let text = self.text().clone();\n\n            let mut process = tokio::process::Command::new(&fmt_cmd);\n\n            if let Some(doc_dir) = self.path.as_ref().and_then(|path| path.parent()) {\n                process.current_dir(doc_dir);\n            }\n\n            let args = match fmt_args\n                .iter()\n                .map(|content| expansion::expand(editor, Token::expand(content)))\n                .collect::<Result<Vec<_>, _>>()\n            {\n                Ok(args) => args,\n                Err(err) => {\n                    log::error!(\"Failed to expand formatter arguments: {err}\");\n                    return None;\n                }\n            };\n\n            process\n                .args(args.iter().map(AsRef::as_ref))\n                .stdin(Stdio::piped())\n                .stdout(Stdio::piped())\n                .stderr(Stdio::piped());\n\n            let formatting_future = async move {\n                let mut process = process\n                    .spawn()\n                    .map_err(|e| FormatterError::SpawningFailed {\n                        command: fmt_cmd.to_string_lossy().into(),\n                        error: e.kind(),\n                    })?;\n\n                let mut stdin = process.stdin.take().ok_or(FormatterError::BrokenStdin)?;\n                let input_text = text.clone();\n                let input_task = tokio::spawn(async move {\n                    to_writer(&mut stdin, (encoding::UTF_8, false), &input_text).await\n                    // Note that `stdin` is dropped here, causing the pipe to close. This can\n                    // avoid a deadlock with `wait_with_output` below if the process is waiting on\n                    // stdin to close before exiting.\n                });\n                let (input_result, output_result) = tokio::join! {\n                    input_task,\n                    process.wait_with_output(),\n                };\n                let _ = input_result.map_err(|_| FormatterError::BrokenStdin)?;\n                let output = output_result.map_err(|_| FormatterError::WaitForOutputFailed)?;\n\n                if !output.status.success() {\n                    if !output.stderr.is_empty() {\n                        let err = String::from_utf8_lossy(&output.stderr).to_string();\n                        log::error!(\"Formatter error: {}\", err);\n                        return Err(FormatterError::NonZeroExitStatus(Some(err)));\n                    }\n\n                    return Err(FormatterError::NonZeroExitStatus(None));\n                } else if !output.stderr.is_empty() {\n                    log::debug!(\n                        \"Formatter printed to stderr: {}\",\n                        String::from_utf8_lossy(&output.stderr)\n                    );\n                }\n\n                let str = std::str::from_utf8(&output.stdout)\n                    .map_err(|_| FormatterError::InvalidUtf8Output)?;\n\n                Ok(helix_core::diff::compare_ropes(&text, &Rope::from(str)))\n            };\n            return Some(formatting_future.boxed());\n        };\n\n        let text = self.text.clone();\n        // finds first language server that supports formatting and then formats\n        let language_server = self\n            .language_servers_with_feature(LanguageServerFeature::Format)\n            .next()?;\n        let offset_encoding = language_server.offset_encoding();\n        let request = language_server.text_document_formatting(\n            self.identifier(),\n            lsp::FormattingOptions {\n                tab_size: self.tab_width() as u32,\n                insert_spaces: matches!(self.indent_style, IndentStyle::Spaces(_)),\n                ..Default::default()\n            },\n            None,\n        )?;\n\n        let fut = async move {\n            let edits = request\n                .await\n                .unwrap_or_else(|e| {\n                    log::warn!(\"LSP formatting failed: {}\", e);\n                    Default::default()\n                })\n                .unwrap_or_default();\n            Ok(helix_lsp::util::generate_transaction_from_edits(\n                &text,\n                edits,\n                offset_encoding,\n            ))\n        };\n        Some(fut.boxed())\n    }\n\n    pub fn save<P: Into<PathBuf>>(\n        &mut self,\n        path: Option<P>,\n        force: bool,\n    ) -> Result<\n        impl Future<Output = Result<DocumentSavedEvent, anyhow::Error>> + 'static + Send,\n        anyhow::Error,\n    > {\n        let path = path.map(|path| path.into());\n        self.save_impl(path, force)\n\n        // futures_util::future::Ready<_>,\n    }\n\n    /// The `Document`'s text is encoded according to its encoding and written to the file located\n    /// at its `path()`.\n    fn save_impl(\n        &mut self,\n        path: Option<PathBuf>,\n        force: bool,\n    ) -> Result<\n        impl Future<Output = Result<DocumentSavedEvent, anyhow::Error>> + 'static + Send,\n        anyhow::Error,\n    > {\n        log::debug!(\n            \"submitting save of doc '{:?}'\",\n            self.path().map(|path| path.to_string_lossy())\n        );\n\n        // we clone and move text + path into the future so that we asynchronously save the current\n        // state without blocking any further edits.\n        let text = self.text().clone();\n\n        let path = match path {\n            Some(path) => helix_stdx::path::canonicalize(path),\n            None => {\n                if self.path.is_none() {\n                    bail!(\"Can't save with no path set!\");\n                }\n                self.path.as_ref().unwrap().clone()\n            }\n        };\n\n        let identifier = self.path().map(|_| self.identifier());\n        let language_servers: Vec<_> = self.language_servers.values().cloned().collect();\n\n        // mark changes up to now as saved\n        let current_rev = self.get_current_revision();\n        let doc_id = self.id();\n        let atomic_save = self.config.load().atomic_save;\n\n        let encoding_with_bom_info = (self.encoding, self.has_bom);\n        let last_saved_time = self.last_saved_time;\n\n        // We encode the file according to the `Document`'s encoding.\n        let future = async move {\n            use tokio::fs;\n            if let Some(parent) = path.parent() {\n                // TODO: display a prompt asking the user if the directories should be created\n                if !parent.exists() {\n                    if force {\n                        std::fs::DirBuilder::new().recursive(true).create(parent)?;\n                    } else {\n                        bail!(\"can't save file, parent directory does not exist (use :w! to create it)\");\n                    }\n                }\n            }\n\n            // Protect against overwriting changes made externally\n            if !force {\n                if let Ok(metadata) = fs::metadata(&path).await {\n                    if let Ok(mtime) = metadata.modified() {\n                        if last_saved_time < mtime {\n                            bail!(\"file modified by an external process, use :w! to overwrite\");\n                        }\n                    }\n                }\n            }\n            let write_path = tokio::fs::read_link(&path)\n                .await\n                .ok()\n                .and_then(|p| {\n                    if p.is_relative() {\n                        path.parent().map(|parent| parent.join(p))\n                    } else {\n                        Some(p)\n                    }\n                })\n                .unwrap_or_else(|| path.clone());\n\n            if readonly(&write_path) {\n                bail!(std::io::Error::new(\n                    std::io::ErrorKind::PermissionDenied,\n                    \"Path is read only\"\n                ));\n            }\n\n            // Assume it is a hardlink to prevent data loss if the metadata cant be read (e.g. on certain Windows configurations)\n            let is_hardlink = helix_stdx::faccess::hardlink_count(&write_path).unwrap_or(2) > 1;\n            let is_symlink = match tokio::fs::symlink_metadata(&write_path).await {\n                Ok(meta) => meta.is_symlink(),\n                Err(err) if err.kind() == std::io::ErrorKind::NotFound => false,\n                Err(err) => return Err(err.into()),\n            };\n            let must_copy = is_hardlink || is_symlink;\n            let backup = if path.exists() && atomic_save {\n                let path_ = write_path.clone();\n                // hacks: we use tempfile to handle the complex task of creating\n                // non clobbered temporary path for us we don't want\n                // the whole automatically delete path on drop thing\n                // since the path doesn't exist yet, we just want\n                // the path\n                tokio::task::spawn_blocking(move || -> Option<PathBuf> {\n                    let mut builder = tempfile::Builder::new();\n                    builder.prefix(path_.file_name()?).suffix(\".bck\");\n\n                    let backup_path = if must_copy {\n                        builder\n                            .make_in(path_.parent()?, |backup| std::fs::copy(&path_, backup))\n                            .ok()?\n                            .into_temp_path()\n                    } else {\n                        builder\n                            .make_in(path_.parent()?, |backup| std::fs::rename(&path_, backup))\n                            .ok()?\n                            .into_temp_path()\n                    };\n\n                    backup_path.keep().ok()\n                })\n                .await\n                .ok()\n                .flatten()\n            } else {\n                None\n            };\n\n            let write_result: anyhow::Result<_> = async {\n                let mut dst = tokio::fs::File::create(&write_path).await?;\n                to_writer(&mut dst, encoding_with_bom_info, &text).await?;\n                dst.sync_all().await?;\n                Ok(())\n            }\n            .await;\n\n            let save_time = match fs::metadata(&write_path).await {\n                Ok(metadata) => metadata.modified().map_or(SystemTime::now(), |mtime| mtime),\n                Err(_) => SystemTime::now(),\n            };\n\n            if let Some(backup) = backup {\n                if must_copy {\n                    let mut delete = true;\n                    if write_result.is_err() {\n                        // Restore backup\n                        let _ = tokio::fs::copy(&backup, &write_path).await.map_err(|e| {\n                            delete = false;\n                            log::error!(\"Failed to restore backup on write failure: {e}\")\n                        });\n                    }\n\n                    if delete {\n                        // Delete backup\n                        let _ = tokio::fs::remove_file(backup)\n                            .await\n                            .map_err(|e| log::error!(\"Failed to remove backup file on write: {e}\"));\n                    }\n                } else if write_result.is_err() {\n                    // restore backup\n                    let _ = tokio::fs::rename(&backup, &write_path)\n                        .await\n                        .map_err(|e| log::error!(\"Failed to restore backup on write failure: {e}\"));\n                } else {\n                    // copy metadata and delete backup\n                    let _ = tokio::task::spawn_blocking(move || {\n                        let _ = copy_metadata(&backup, &write_path)\n                            .map_err(|e| log::error!(\"Failed to copy metadata on write: {e}\"));\n                        let _ = std::fs::remove_file(backup)\n                            .map_err(|e| log::error!(\"Failed to remove backup file on write: {e}\"));\n                    })\n                    .await;\n                }\n            }\n\n            write_result?;\n\n            let event = DocumentSavedEvent {\n                revision: current_rev,\n                save_time,\n                doc_id,\n                path,\n                text: text.clone(),\n            };\n\n            for language_server in language_servers {\n                if !language_server.is_initialized() {\n                    continue;\n                }\n                if let Some(id) = identifier.clone() {\n                    language_server.text_document_did_save(id, &text);\n                }\n            }\n\n            Ok(event)\n        };\n\n        Ok(future)\n    }\n\n    /// Detect the programming language based on the file type.\n    pub fn detect_language(&mut self, loader: &syntax::Loader) {\n        self.set_language(self.detect_language_config(loader), loader);\n    }\n\n    /// Detect the programming language based on the file type.\n    pub fn detect_language_config(\n        &self,\n        loader: &syntax::Loader,\n    ) -> Option<Arc<syntax::config::LanguageConfiguration>> {\n        let language = loader\n            .language_for_filename(self.path.as_ref()?)\n            .or_else(|| loader.language_for_shebang(self.text().slice(..)))?;\n\n        Some(loader.language(language).config().clone())\n    }\n\n    /// Detect the indentation used in the file, or otherwise defaults to the language indentation\n    /// configured in `languages.toml`, with a fallback to tabs if it isn't specified. Line ending\n    /// is likewise auto-detected, and will remain unchanged if no line endings were detected.\n    pub fn detect_indent_and_line_ending(&mut self) {\n        self.indent_style = if let Some(indent_style) = self.editor_config.indent_style {\n            indent_style\n        } else {\n            auto_detect_indent_style(&self.text).unwrap_or_else(|| {\n                self.language_config()\n                    .and_then(|config| config.indent.as_ref())\n                    .map_or(DEFAULT_INDENT, |config| IndentStyle::from_str(&config.unit))\n            })\n        };\n        if let Some(line_ending) = self\n            .editor_config\n            .line_ending\n            .or_else(|| auto_detect_line_ending(&self.text))\n        {\n            self.line_ending = line_ending;\n        }\n    }\n\n    pub fn detect_editor_config(&mut self) {\n        if self.config.load().editor_config {\n            if let Some(path) = self.path.as_ref() {\n                self.editor_config = EditorConfig::find(path);\n            }\n        }\n    }\n\n    pub fn pickup_last_saved_time(&mut self) {\n        self.last_saved_time = match self.path() {\n            Some(path) => match path.metadata() {\n                Ok(metadata) => match metadata.modified() {\n                    Ok(mtime) => mtime,\n                    Err(err) => {\n                        log::debug!(\"Could not fetch file system's mtime, falling back to current system time: {}\", err);\n                        SystemTime::now()\n                    }\n                },\n                Err(err) => {\n                    log::debug!(\"Could not fetch file system's mtime, falling back to current system time: {}\", err);\n                    SystemTime::now()\n                }\n            },\n            None => SystemTime::now(),\n        };\n    }\n\n    // Detect if the file is readonly and change the readonly field if necessary (unix only)\n    pub fn detect_readonly(&mut self) {\n        // Allows setting the flag for files the user cannot modify, like root files\n        self.readonly = match &self.path {\n            None => false,\n            Some(p) => readonly(p),\n        };\n    }\n\n    /// Reload the document from its path.\n    pub fn reload(\n        &mut self,\n        view: &mut View,\n        provider_registry: &DiffProviderRegistry,\n    ) -> Result<(), Error> {\n        let encoding = self.encoding;\n        let path = match self.path() {\n            None => return Ok(()),\n            Some(path) => match path.exists() {\n                true => path.to_owned(),\n                false => bail!(\"can't find file to reload from {:?}\", self.display_name()),\n            },\n        };\n\n        // Once we have a valid path we check if its readonly status has changed\n        self.detect_readonly();\n\n        let mut file = std::fs::File::open(&path)?;\n        let (rope, ..) = from_reader(&mut file, Some(encoding))?;\n\n        // Calculate the difference between the buffer and source text, and apply it.\n        // This is not considered a modification of the contents of the file regardless\n        // of the encoding.\n        let transaction = helix_core::diff::compare_ropes(self.text(), &rope);\n        self.apply(&transaction, view.id);\n        self.append_changes_to_history(view);\n        self.reset_modified();\n        self.pickup_last_saved_time();\n        self.detect_indent_and_line_ending();\n\n        match provider_registry.get_diff_base(&path) {\n            Some(diff_base) => self.set_diff_base(diff_base),\n            None => self.diff_handle = None,\n        }\n\n        self.version_control_head = provider_registry.get_current_head_name(&path);\n\n        Ok(())\n    }\n\n    /// Sets the [`Document`]'s encoding with the encoding correspondent to `label`.\n    pub fn set_encoding(&mut self, label: &str) -> Result<(), Error> {\n        let encoding =\n            Encoding::for_label(label.as_bytes()).ok_or_else(|| anyhow!(\"unknown encoding\"))?;\n\n        self.encoding = encoding;\n\n        Ok(())\n    }\n\n    /// Returns the [`Document`]'s current encoding.\n    pub fn encoding(&self) -> &'static Encoding {\n        self.encoding\n    }\n\n    /// sets the document path without sending events to various\n    /// observers (like LSP), in most cases `Editor::set_doc_path`\n    /// should be used instead\n    pub fn set_path(&mut self, path: Option<&Path>) {\n        let path = path.map(helix_stdx::path::canonicalize);\n\n        // `take` to remove any prior relative path that may have existed.\n        // This will get set in `relative_path()`.\n        self.relative_path.take();\n\n        // if parent doesn't exist we still want to open the document\n        // and error out when document is saved\n        self.path = path;\n\n        self.detect_readonly();\n        self.pickup_last_saved_time();\n    }\n\n    /// Set the programming language for the file and load associated data (e.g. highlighting)\n    /// if it exists.\n    pub fn set_language(\n        &mut self,\n        language_config: Option<Arc<syntax::config::LanguageConfiguration>>,\n        loader: &syntax::Loader,\n    ) {\n        self.language = language_config;\n        self.syntax = self.language.as_ref().and_then(|config| {\n            Syntax::new(self.text.slice(..), config.language(), loader)\n                .map_err(|err| {\n                    // `NoRootConfig` means that there was an issue loading the language/syntax\n                    // config for the root language of the document. An error must have already\n                    // been logged by `LanguageData::syntax_config`.\n                    if err != syntax::HighlighterError::NoRootConfig {\n                        log::warn!(\"Error building syntax for '{}': {err}\", self.display_name());\n                    }\n                })\n                .ok()\n        });\n    }\n\n    /// Set the programming language for the file if you know the language but don't have the\n    /// [`syntax::config::LanguageConfiguration`] for it.\n    pub fn set_language_by_language_id(\n        &mut self,\n        language_id: &str,\n        loader: &syntax::Loader,\n    ) -> anyhow::Result<()> {\n        let language = loader\n            .language_for_name(language_id)\n            .ok_or_else(|| anyhow!(\"invalid language id: {}\", language_id))?;\n        let config = loader.language(language).config().clone();\n        self.set_language(Some(config), loader);\n        Ok(())\n    }\n\n    /// Select text within the [`Document`].\n    pub fn set_selection(&mut self, view_id: ViewId, selection: Selection) {\n        // TODO: use a transaction?\n        self.selections\n            .insert(view_id, selection.ensure_invariants(self.text().slice(..)));\n        helix_event::dispatch(SelectionDidChange {\n            doc: self,\n            view: view_id,\n        })\n    }\n\n    /// Find the origin selection of the text in a document, i.e. where\n    /// a single cursor would go if it were on the first grapheme. If\n    /// the text is empty, returns (0, 0).\n    pub fn origin(&self) -> Range {\n        if self.text().len_chars() == 0 {\n            return Range::new(0, 0);\n        }\n\n        Range::new(0, 1).grapheme_aligned(self.text().slice(..))\n    }\n\n    /// Reset the view's selection on this document to the\n    /// [origin](Document::origin) cursor.\n    pub fn reset_selection(&mut self, view_id: ViewId) {\n        let origin = self.origin();\n        self.set_selection(view_id, Selection::single(origin.anchor, origin.head));\n    }\n\n    /// Initializes a new selection and view_data for the given view\n    /// if it does not already have them.\n    pub fn ensure_view_init(&mut self, view_id: ViewId) {\n        if !self.selections.contains_key(&view_id) {\n            self.reset_selection(view_id);\n        }\n\n        self.view_data_mut(view_id);\n    }\n\n    /// Mark document as recent used for MRU sorting\n    pub fn mark_as_focused(&mut self) {\n        self.focused_at = std::time::Instant::now();\n    }\n\n    /// Remove a view's selection and inlay hints from this document.\n    pub fn remove_view(&mut self, view_id: ViewId) {\n        self.selections.remove(&view_id);\n        self.inlay_hints.remove(&view_id);\n        self.jump_labels.remove(&view_id);\n        self.document_highlights.remove(&view_id);\n        self.document_highlight_controllers.remove(&view_id);\n    }\n\n    /// Apply a [`Transaction`] to the [`Document`] to change its text.\n    fn apply_impl(\n        &mut self,\n        transaction: &Transaction,\n        view_id: ViewId,\n        emit_lsp_notification: bool,\n    ) -> bool {\n        use helix_core::Assoc;\n\n        let old_doc = self.text().clone();\n        let changes = transaction.changes();\n        if !changes.apply(&mut self.text) {\n            return false;\n        }\n\n        if changes.is_empty() {\n            if let Some(selection) = transaction.selection() {\n                self.selections.insert(\n                    view_id,\n                    selection.clone().ensure_invariants(self.text.slice(..)),\n                );\n                helix_event::dispatch(SelectionDidChange {\n                    doc: self,\n                    view: view_id,\n                });\n            }\n            return true;\n        }\n\n        self.modified_since_accessed = true;\n        self.version += 1;\n\n        for selection in self.selections.values_mut() {\n            *selection = selection\n                .clone()\n                // Map through changes\n                .map(transaction.changes())\n                // Ensure all selections across all views still adhere to invariants.\n                .ensure_invariants(self.text.slice(..));\n        }\n\n        for view_data in self.view_data.values_mut() {\n            view_data.view_position.anchor = transaction\n                .changes()\n                .map_pos(view_data.view_position.anchor, Assoc::Before);\n        }\n\n        // generate revert to savepoint\n        if !self.savepoints.is_empty() {\n            let revert = transaction.invert(&old_doc);\n            self.savepoints\n                .retain_mut(|save_point| match save_point.upgrade() {\n                    Some(savepoint) => {\n                        let mut revert_to_savepoint = savepoint.revert.lock();\n                        *revert_to_savepoint =\n                            revert.clone().compose(mem::take(&mut revert_to_savepoint));\n                        true\n                    }\n                    None => false,\n                })\n        }\n\n        // update tree-sitter syntax tree\n        if let Some(syntax) = &mut self.syntax {\n            let loader = self.syn_loader.load();\n            if let Err(err) = syntax.update(\n                old_doc.slice(..),\n                self.text.slice(..),\n                transaction.changes(),\n                &loader,\n            ) {\n                log::error!(\"TS parser failed, disabling TS for the current buffer: {err}\");\n                self.syntax = None;\n            }\n        }\n\n        // TODO: all of that should likely just be hooks\n        // start computing the diff in parallel\n        if let Some(diff_handle) = &self.diff_handle {\n            diff_handle.update_document(self.text.clone(), false);\n        }\n\n        // map diagnostics over changes too\n        changes.update_positions(self.diagnostics.iter_mut().map(|diagnostic| {\n            let assoc = if diagnostic.starts_at_word {\n                Assoc::BeforeWord\n            } else {\n                Assoc::After\n            };\n            (&mut diagnostic.range.start, assoc)\n        }));\n        changes.update_positions(self.diagnostics.iter_mut().filter_map(|diagnostic| {\n            if diagnostic.zero_width {\n                // for zero width diagnostics treat the diagnostic as a point\n                // rather than a range\n                return None;\n            }\n            let assoc = if diagnostic.ends_at_word {\n                Assoc::AfterWord\n            } else {\n                Assoc::Before\n            };\n            Some((&mut diagnostic.range.end, assoc))\n        }));\n        self.diagnostics.retain_mut(|diagnostic| {\n            if diagnostic.zero_width {\n                diagnostic.range.end = diagnostic.range.start\n            } else if diagnostic.range.start >= diagnostic.range.end {\n                return false;\n            }\n            diagnostic.line = self.text.char_to_line(diagnostic.range.start);\n            true\n        });\n\n        self.diagnostics.sort_by_key(|diagnostic| {\n            (\n                diagnostic.range,\n                diagnostic.severity,\n                diagnostic.provider.clone(),\n            )\n        });\n\n        // Update the inlay hint annotations' positions, helping ensure they are displayed in the proper place\n        let apply_inlay_hint_changes = |annotations: &mut Vec<InlineAnnotation>| {\n            changes.update_positions(\n                annotations\n                    .iter_mut()\n                    .map(|annotation| (&mut annotation.char_idx, Assoc::After)),\n            );\n        };\n\n        self.inlay_hints_oudated = true;\n        for text_annotation in self.inlay_hints.values_mut() {\n            let DocumentInlayHints {\n                id: _,\n                type_inlay_hints,\n                parameter_inlay_hints,\n                other_inlay_hints,\n                padding_before_inlay_hints,\n                padding_after_inlay_hints,\n            } = text_annotation;\n\n            apply_inlay_hint_changes(padding_before_inlay_hints);\n            apply_inlay_hint_changes(type_inlay_hints);\n            apply_inlay_hint_changes(parameter_inlay_hints);\n            apply_inlay_hint_changes(other_inlay_hints);\n            apply_inlay_hint_changes(padding_after_inlay_hints);\n        }\n\n        for highlights in self.document_highlights.values_mut() {\n            let text_len = self.text.len_chars();\n            let mut updated = Vec::with_capacity(highlights.ranges.len());\n            for mut range in highlights.ranges.drain(..) {\n                changes.update_positions(\n                    [\n                        (&mut range.start, Assoc::After),\n                        (&mut range.end, Assoc::After),\n                    ]\n                    .into_iter(),\n                );\n                if range.start >= text_len {\n                    continue;\n                }\n                let end = range.end.min(text_len);\n                if range.start < end {\n                    updated.push(range.start..end);\n                }\n            }\n            highlights.ranges = updated;\n        }\n\n        helix_event::dispatch(DocumentDidChange {\n            doc: self,\n            view: view_id,\n            old_text: &old_doc,\n            changes,\n            ghost_transaction: !emit_lsp_notification,\n        });\n\n        // if specified, the current selection should instead be replaced by transaction.selection\n        if let Some(selection) = transaction.selection() {\n            self.selections.insert(\n                view_id,\n                selection.clone().ensure_invariants(self.text.slice(..)),\n            );\n            helix_event::dispatch(SelectionDidChange {\n                doc: self,\n                view: view_id,\n            });\n        }\n\n        true\n    }\n\n    fn apply_inner(\n        &mut self,\n        transaction: &Transaction,\n        view_id: ViewId,\n        emit_lsp_notification: bool,\n    ) -> bool {\n        // store the state just before any changes are made. This allows us to undo to the\n        // state just before a transaction was applied.\n        if self.changes.is_empty() && !transaction.changes().is_empty() {\n            self.old_state = Some(State {\n                doc: self.text.clone(),\n                selection: self.selection(view_id).clone(),\n            });\n        }\n\n        let success = self.apply_impl(transaction, view_id, emit_lsp_notification);\n\n        if !transaction.changes().is_empty() {\n            // Compose this transaction with the previous one\n            take_with(&mut self.changes, |changes| {\n                changes.compose(transaction.changes().clone())\n            });\n        }\n        success\n    }\n    /// Apply a [`Transaction`] to the [`Document`] to change its text.\n    pub fn apply(&mut self, transaction: &Transaction, view_id: ViewId) -> bool {\n        self.apply_inner(transaction, view_id, true)\n    }\n\n    /// Apply a [`Transaction`] to the [`Document`] to change its text\n    /// without notifying the language servers. This is useful for temporary transactions\n    /// that must not influence the server.\n    pub fn apply_temporary(&mut self, transaction: &Transaction, view_id: ViewId) -> bool {\n        self.apply_inner(transaction, view_id, false)\n    }\n\n    fn undo_redo_impl(&mut self, view: &mut View, undo: bool) -> bool {\n        if undo {\n            self.append_changes_to_history(view);\n        } else if !self.changes.is_empty() {\n            return false;\n        }\n        let mut history = self.history.take();\n        let txn = if undo { history.undo() } else { history.redo() };\n        let success = if let Some(txn) = txn {\n            self.apply_impl(txn, view.id, true)\n        } else {\n            false\n        };\n        self.history.set(history);\n\n        if success {\n            // reset changeset to fix len\n            self.changes = ChangeSet::new(self.text().slice(..));\n            // Sync with changes with the jumplist selections.\n            view.sync_changes(self);\n        }\n        success\n    }\n\n    /// Undo the last modification to the [`Document`]. Returns whether the undo was successful.\n    pub fn undo(&mut self, view: &mut View) -> bool {\n        self.undo_redo_impl(view, true)\n    }\n\n    /// Redo the last modification to the [`Document`]. Returns whether the redo was successful.\n    pub fn redo(&mut self, view: &mut View) -> bool {\n        self.undo_redo_impl(view, false)\n    }\n\n    /// Creates a reference counted snapshot (called savpepoint) of the document.\n    ///\n    /// The snapshot will remain valid (and updated) idenfinitly as long as ereferences to it exist.\n    /// Restoring the snapshot will restore the selection and the contents of the document to\n    /// the state it had when this function was called.\n    pub fn savepoint(&mut self, view: &View) -> Arc<SavePoint> {\n        let revert = Transaction::new(self.text()).with_selection(self.selection(view.id).clone());\n        // check if there is already an existing (identical) savepoint around\n        if let Some(savepoint) = self\n            .savepoints\n            .iter()\n            .rev()\n            .find_map(|savepoint| savepoint.upgrade())\n        {\n            let transaction = savepoint.revert.lock();\n            if savepoint.view == view.id\n                && transaction.changes().is_empty()\n                && transaction.selection() == revert.selection()\n            {\n                drop(transaction);\n                return savepoint;\n            }\n        }\n        let savepoint = Arc::new(SavePoint {\n            view: view.id,\n            revert: Mutex::new(revert),\n        });\n        self.savepoints.push(Arc::downgrade(&savepoint));\n        savepoint\n    }\n\n    pub fn restore(&mut self, view: &mut View, savepoint: &SavePoint, emit_lsp_notification: bool) {\n        assert_eq!(\n            savepoint.view, view.id,\n            \"Savepoint must not be used with a different view!\"\n        );\n        // search and remove savepoint using a ptr comparison\n        // this avoids a deadlock as we need to lock the mutex\n        let savepoint_idx = self\n            .savepoints\n            .iter()\n            .position(|savepoint_ref| std::ptr::eq(savepoint_ref.as_ptr(), savepoint))\n            .expect(\"Savepoint must belong to this document\");\n\n        let savepoint_ref = self.savepoints.remove(savepoint_idx);\n        let mut revert = savepoint.revert.lock();\n        self.apply_inner(&revert, view.id, emit_lsp_notification);\n        *revert = Transaction::new(self.text()).with_selection(self.selection(view.id).clone());\n        self.savepoints.push(savepoint_ref)\n    }\n\n    fn earlier_later_impl(&mut self, view: &mut View, uk: UndoKind, earlier: bool) -> bool {\n        if earlier {\n            self.append_changes_to_history(view);\n        } else if !self.changes.is_empty() {\n            return false;\n        }\n        let txns = if earlier {\n            self.history.get_mut().earlier(uk)\n        } else {\n            self.history.get_mut().later(uk)\n        };\n        let mut success = false;\n        for txn in txns {\n            if self.apply_impl(&txn, view.id, true) {\n                success = true;\n            }\n        }\n        if success {\n            // reset changeset to fix len\n            self.changes = ChangeSet::new(self.text().slice(..));\n            // Sync with changes with the jumplist selections.\n            view.sync_changes(self);\n        }\n        success\n    }\n\n    /// Undo modifications to the [`Document`] according to `uk`.\n    pub fn earlier(&mut self, view: &mut View, uk: UndoKind) -> bool {\n        self.earlier_later_impl(view, uk, true)\n    }\n\n    /// Redo modifications to the [`Document`] according to `uk`.\n    pub fn later(&mut self, view: &mut View, uk: UndoKind) -> bool {\n        self.earlier_later_impl(view, uk, false)\n    }\n\n    /// Commit pending changes to history\n    pub fn append_changes_to_history(&mut self, view: &mut View) {\n        if self.changes.is_empty() {\n            return;\n        }\n\n        let new_changeset = ChangeSet::new(self.text().slice(..));\n        let changes = std::mem::replace(&mut self.changes, new_changeset);\n        // Instead of doing this messy merge we could always commit, and based on transaction\n        // annotations either add a new layer or compose into the previous one.\n        let transaction =\n            Transaction::from(changes).with_selection(self.selection(view.id).clone());\n\n        // HAXX: we need to reconstruct the state as it was before the changes..\n        let old_state = self.old_state.take().expect(\"no old_state available\");\n\n        let mut history = self.history.take();\n        history.commit_revision(&transaction, &old_state);\n        self.history.set(history);\n\n        // Update jumplist entries in the view.\n        view.apply(&transaction, self);\n    }\n\n    pub fn id(&self) -> DocumentId {\n        self.id\n    }\n\n    /// If there are unsaved modifications.\n    pub fn is_modified(&self) -> bool {\n        let history = self.history.take();\n        let current_revision = history.current_revision();\n        self.history.set(history);\n        log::debug!(\n            \"id {} modified - last saved: {}, current: {}\",\n            self.id,\n            self.last_saved_revision,\n            current_revision\n        );\n        current_revision != self.last_saved_revision || !self.changes.is_empty()\n    }\n\n    /// Save modifications to history, and so [`Self::is_modified`] will return false.\n    pub fn reset_modified(&mut self) {\n        let history = self.history.take();\n        let current_revision = history.current_revision();\n        self.history.set(history);\n        self.last_saved_revision = current_revision;\n    }\n\n    /// Set the document's latest saved revision to the given one.\n    pub fn set_last_saved_revision(&mut self, rev: usize, save_time: SystemTime) {\n        log::debug!(\n            \"doc {} revision updated {} -> {}\",\n            self.id,\n            self.last_saved_revision,\n            rev\n        );\n        self.last_saved_revision = rev;\n        self.last_saved_time = save_time;\n    }\n\n    /// Get the document's latest saved revision.\n    pub fn get_last_saved_revision(&mut self) -> usize {\n        self.last_saved_revision\n    }\n\n    /// Get the current revision number\n    pub fn get_current_revision(&mut self) -> usize {\n        let history = self.history.take();\n        let current_revision = history.current_revision();\n        self.history.set(history);\n        current_revision\n    }\n\n    /// Corresponding language scope name. Usually `source.<lang>`.\n    pub fn language_scope(&self) -> Option<&str> {\n        self.language\n            .as_ref()\n            .map(|language| language.scope.as_str())\n    }\n\n    /// Language name for the document. Corresponds to the `name` key in\n    /// `languages.toml` configuration.\n    pub fn language_name(&self) -> Option<&str> {\n        self.language\n            .as_ref()\n            .map(|language| language.language_id.as_str())\n    }\n\n    /// Language ID for the document. Either the `language-id`,\n    /// or the document language name if no `language-id` has been specified.\n    pub fn language_id(&self) -> Option<&str> {\n        self.language_config()?\n            .language_server_language_id\n            .as_deref()\n            .or_else(|| self.language_name())\n    }\n\n    /// Corresponding [`LanguageConfiguration`].\n    pub fn language_config(&self) -> Option<&LanguageConfiguration> {\n        self.language.as_deref()\n    }\n\n    /// Current document version, incremented at each change.\n    pub fn version(&self) -> i32 {\n        self.version\n    }\n\n    pub fn word_completion_enabled(&self) -> bool {\n        self.language_config()\n            .and_then(|lang_config| lang_config.word_completion.and_then(|c| c.enable))\n            .unwrap_or_else(|| self.config.load().word_completion.enable)\n    }\n\n    pub fn path_completion_enabled(&self) -> bool {\n        self.language_config()\n            .and_then(|lang_config| lang_config.path_completion)\n            .unwrap_or_else(|| self.config.load().path_completion)\n    }\n\n    /// maintains the order as configured in the language_servers TOML array\n    pub fn language_servers(&self) -> impl Iterator<Item = &helix_lsp::Client> {\n        self.language_config().into_iter().flat_map(move |config| {\n            config.language_servers.iter().filter_map(move |features| {\n                let ls = &**self.language_servers.get(&features.name)?;\n                if ls.is_initialized() {\n                    Some(ls)\n                } else {\n                    None\n                }\n            })\n        })\n    }\n\n    pub fn remove_language_server_by_name(&mut self, name: &str) -> Option<Arc<Client>> {\n        self.language_servers.remove(name)\n    }\n\n    pub fn language_servers_with_feature(\n        &self,\n        feature: LanguageServerFeature,\n    ) -> impl Iterator<Item = &helix_lsp::Client> {\n        self.language_config().into_iter().flat_map(move |config| {\n            config.language_servers.iter().filter_map(move |features| {\n                let ls = &**self.language_servers.get(&features.name)?;\n                if ls.is_initialized()\n                    && ls.supports_feature(feature)\n                    && features.has_feature(feature)\n                {\n                    Some(ls)\n                } else {\n                    None\n                }\n            })\n        })\n    }\n\n    pub fn supports_language_server(&self, id: LanguageServerId) -> bool {\n        self.language_servers().any(|l| l.id() == id)\n    }\n\n    pub fn diff_handle(&self) -> Option<&DiffHandle> {\n        self.diff_handle.as_ref()\n    }\n\n    /// Intialize/updates the differ for this document with a new base.\n    pub fn set_diff_base(&mut self, diff_base: Vec<u8>) {\n        if let Ok((diff_base, ..)) = from_reader(&mut diff_base.as_slice(), Some(self.encoding)) {\n            if let Some(differ) = &self.diff_handle {\n                differ.update_diff_base(diff_base);\n                return;\n            }\n            self.diff_handle = Some(DiffHandle::new(diff_base, self.text.clone()))\n        } else {\n            self.diff_handle = None;\n        }\n    }\n\n    pub fn version_control_head(&self) -> Option<Arc<Box<str>>> {\n        self.version_control_head.as_ref().map(|a| a.load_full())\n    }\n\n    pub fn set_version_control_head(\n        &mut self,\n        version_control_head: Option<Arc<ArcSwap<Box<str>>>>,\n    ) {\n        self.version_control_head = version_control_head;\n    }\n\n    #[inline]\n    /// Tree-sitter AST tree\n    pub fn syntax(&self) -> Option<&Syntax> {\n        self.syntax.as_ref()\n    }\n\n    /// The width that the tab character is rendered at\n    pub fn tab_width(&self) -> usize {\n        self.editor_config\n            .tab_width\n            .map(|n| n.get() as usize)\n            .unwrap_or_else(|| {\n                self.language_config()\n                    .and_then(|config| config.indent.as_ref())\n                    .map_or(DEFAULT_TAB_WIDTH, |config| config.tab_width)\n            })\n    }\n\n    // The width (in spaces) of a level of indentation.\n    pub fn indent_width(&self) -> usize {\n        self.indent_style.indent_width(self.tab_width())\n    }\n\n    /// Whether the document should have a trailing line ending appended on save.\n    pub fn insert_final_newline(&self) -> bool {\n        self.editor_config\n            .insert_final_newline\n            .unwrap_or_else(|| self.config.load().insert_final_newline)\n    }\n\n    /// Whether the document should trim whitespace preceding line endings on save.\n    pub fn trim_trailing_whitespace(&self) -> bool {\n        self.editor_config\n            .trim_trailing_whitespace\n            .unwrap_or_else(|| self.config.load().trim_trailing_whitespace)\n    }\n\n    pub fn changes(&self) -> &ChangeSet {\n        &self.changes\n    }\n\n    #[inline]\n    /// File path on disk.\n    pub fn path(&self) -> Option<&PathBuf> {\n        self.path.as_ref()\n    }\n\n    /// File path as a URL.\n    pub fn url(&self) -> Option<Url> {\n        Url::from_file_path(self.path()?).ok()\n    }\n\n    pub fn uri(&self) -> Option<helix_core::Uri> {\n        Some(self.path()?.clone().into())\n    }\n\n    #[inline]\n    pub fn text(&self) -> &Rope {\n        &self.text\n    }\n\n    #[inline]\n    pub fn selection(&self, view_id: ViewId) -> &Selection {\n        &self.selections[&view_id]\n    }\n\n    #[inline]\n    pub fn selections(&self) -> &HashMap<ViewId, Selection> {\n        &self.selections\n    }\n\n    fn view_data(&self, view_id: ViewId) -> &ViewData {\n        self.view_data\n            .get(&view_id)\n            .expect(\"This should only be called after ensure_view_init\")\n    }\n\n    fn view_data_mut(&mut self, view_id: ViewId) -> &mut ViewData {\n        self.view_data.entry(view_id).or_default()\n    }\n\n    pub(crate) fn get_view_offset(&self, view_id: ViewId) -> Option<ViewPosition> {\n        Some(self.view_data.get(&view_id)?.view_position)\n    }\n\n    pub fn view_offset(&self, view_id: ViewId) -> ViewPosition {\n        self.view_data(view_id).view_position\n    }\n\n    pub fn set_view_offset(&mut self, view_id: ViewId, new_offset: ViewPosition) {\n        self.view_data_mut(view_id).view_position = new_offset;\n    }\n\n    pub fn relative_path(&self) -> Option<&Path> {\n        self.relative_path\n            .get_or_init(|| {\n                self.path\n                    .as_ref()\n                    .map(|path| helix_stdx::path::get_relative_path(path).to_path_buf())\n            })\n            .as_deref()\n    }\n\n    pub fn display_name(&self) -> Cow<'_, str> {\n        self.relative_path()\n            .map_or_else(|| SCRATCH_BUFFER_NAME.into(), |path| path.to_string_lossy())\n    }\n\n    // transact(Fn) ?\n\n    // -- LSP methods\n\n    #[inline]\n    pub fn identifier(&self) -> lsp::TextDocumentIdentifier {\n        lsp::TextDocumentIdentifier::new(self.url().unwrap())\n    }\n\n    pub fn versioned_identifier(&self) -> lsp::VersionedTextDocumentIdentifier {\n        lsp::VersionedTextDocumentIdentifier::new(self.url().unwrap(), self.version)\n    }\n\n    pub fn position(\n        &self,\n        view_id: ViewId,\n        offset_encoding: helix_lsp::OffsetEncoding,\n    ) -> lsp::Position {\n        let text = self.text();\n\n        helix_lsp::util::pos_to_lsp_pos(\n            text,\n            self.selection(view_id).primary().cursor(text.slice(..)),\n            offset_encoding,\n        )\n    }\n\n    pub fn lsp_diagnostic_to_diagnostic(\n        text: &Rope,\n        language_config: Option<&LanguageConfiguration>,\n        diagnostic: &helix_lsp::lsp::Diagnostic,\n        provider: DiagnosticProvider,\n        offset_encoding: helix_lsp::OffsetEncoding,\n    ) -> Option<Diagnostic> {\n        use helix_core::diagnostic::{Range, Severity::*};\n\n        // TODO: convert inside server\n        let start =\n            if let Some(start) = lsp_pos_to_pos(text, diagnostic.range.start, offset_encoding) {\n                start\n            } else {\n                log::warn!(\"lsp position out of bounds - {:?}\", diagnostic);\n                return None;\n            };\n\n        let end = if let Some(end) = lsp_pos_to_pos(text, diagnostic.range.end, offset_encoding) {\n            end\n        } else {\n            log::warn!(\"lsp position out of bounds - {:?}\", diagnostic);\n            return None;\n        };\n\n        let severity = diagnostic.severity.and_then(|severity| match severity {\n            lsp::DiagnosticSeverity::ERROR => Some(Error),\n            lsp::DiagnosticSeverity::WARNING => Some(Warning),\n            lsp::DiagnosticSeverity::INFORMATION => Some(Info),\n            lsp::DiagnosticSeverity::HINT => Some(Hint),\n            severity => {\n                log::error!(\"unrecognized diagnostic severity: {:?}\", severity);\n                None\n            }\n        });\n\n        if let Some(lang_conf) = language_config {\n            if let Some(severity) = severity {\n                if severity < lang_conf.diagnostic_severity {\n                    return None;\n                }\n            }\n        };\n        use helix_core::diagnostic::{DiagnosticTag, NumberOrString};\n\n        let code = match diagnostic.code.clone() {\n            Some(x) => match x {\n                lsp::NumberOrString::Number(x) => Some(NumberOrString::Number(x)),\n                lsp::NumberOrString::String(x) => Some(NumberOrString::String(x)),\n            },\n            None => None,\n        };\n\n        let tags = if let Some(tags) = &diagnostic.tags {\n            let new_tags = tags\n                .iter()\n                .filter_map(|tag| match *tag {\n                    lsp::DiagnosticTag::DEPRECATED => Some(DiagnosticTag::Deprecated),\n                    lsp::DiagnosticTag::UNNECESSARY => Some(DiagnosticTag::Unnecessary),\n                    _ => None,\n                })\n                .collect();\n\n            new_tags\n        } else {\n            Vec::new()\n        };\n\n        let ends_at_word =\n            start != end && end != 0 && text.get_char(end - 1).is_some_and(char_is_word);\n        let starts_at_word = start != end && text.get_char(start).is_some_and(char_is_word);\n\n        Some(Diagnostic {\n            range: Range { start, end },\n            ends_at_word,\n            starts_at_word,\n            zero_width: start == end,\n            line: diagnostic.range.start.line as usize,\n            message: diagnostic.message.clone(),\n            severity,\n            code,\n            tags,\n            source: diagnostic.source.clone(),\n            data: diagnostic.data.clone(),\n            provider,\n        })\n    }\n\n    #[inline]\n    pub fn diagnostics(&self) -> &[Diagnostic] {\n        &self.diagnostics\n    }\n\n    pub fn replace_diagnostics(\n        &mut self,\n        diagnostics: impl IntoIterator<Item = Diagnostic>,\n        unchanged_sources: &[String],\n        provider: Option<&DiagnosticProvider>,\n    ) {\n        if unchanged_sources.is_empty() {\n            if let Some(provider) = provider {\n                self.diagnostics\n                    .retain(|diagnostic| &diagnostic.provider != provider);\n            } else {\n                self.diagnostics.clear();\n            }\n        } else {\n            self.diagnostics.retain(|d| {\n                if provider.is_some_and(|provider| provider != &d.provider) {\n                    return true;\n                }\n\n                if let Some(source) = &d.source {\n                    unchanged_sources.contains(source)\n                } else {\n                    false\n                }\n            });\n        }\n        self.diagnostics.extend(diagnostics);\n        self.diagnostics.sort_by_key(|diagnostic| {\n            (\n                diagnostic.range,\n                diagnostic.severity,\n                diagnostic.provider.clone(),\n            )\n        });\n    }\n\n    /// clears diagnostics for a given language server id if set, otherwise all diagnostics are cleared\n    pub fn clear_diagnostics_for_language_server(&mut self, id: LanguageServerId) {\n        self.diagnostics\n            .retain(|d| d.provider.language_server_id() != Some(id));\n    }\n\n    /// Get the document's auto pairs. If the document has a recognized\n    /// language config with auto pairs configured, returns that;\n    /// otherwise, falls back to the global auto pairs config. If the global\n    /// config is false, then ignore language settings.\n    pub fn auto_pairs<'a>(\n        &'a self,\n        editor: &'a Editor,\n        loader: &'a syntax::Loader,\n        view: &View,\n    ) -> Option<&'a AutoPairs> {\n        let global_config = (editor.auto_pairs).as_ref();\n\n        // NOTE: If the user specifies the global auto pairs config as false, then\n        //       we want to disable it globally regardless of language settings\n        #[allow(clippy::question_mark)]\n        {\n            if global_config.is_none() {\n                return None;\n            }\n        }\n\n        self.syntax\n            .as_ref()\n            .and_then(|syntax| {\n                let selection = self.selection(view.id).primary();\n                let (start, end) = selection.into_byte_range(self.text().slice(..));\n                let layer = syntax.layer_for_byte_range(start as u32, end as u32);\n\n                let lang_config = loader.language(syntax.layer(layer).language).config();\n                lang_config.auto_pairs.as_ref()\n            })\n            .or(global_config)\n    }\n\n    pub fn snippet_ctx(&self) -> SnippetRenderCtx {\n        SnippetRenderCtx {\n            // TODO snippet variable resolution\n            resolve_var: Box::new(|_| None),\n            tab_width: self.tab_width(),\n            indent_style: self.indent_style,\n            line_ending: self.line_ending.as_str(),\n        }\n    }\n\n    pub fn text_width(&self) -> usize {\n        self.editor_config\n            .max_line_length\n            .map(|n| n.get() as usize)\n            .or_else(|| self.language_config().and_then(|config| config.text_width))\n            .unwrap_or_else(|| self.config.load().text_width)\n    }\n\n    pub fn text_format(&self, mut viewport_width: u16, theme: Option<&Theme>) -> TextFormat {\n        let config = self.config.load();\n        let text_width = self.text_width();\n        let mut soft_wrap_at_text_width = self\n            .language_config()\n            .and_then(|config| {\n                config\n                    .soft_wrap\n                    .as_ref()\n                    .and_then(|soft_wrap| soft_wrap.wrap_at_text_width)\n            })\n            .or(config.soft_wrap.wrap_at_text_width)\n            .unwrap_or(false);\n        if soft_wrap_at_text_width {\n            // if the viewport is smaller than the specified\n            // width then this setting has no effcet\n            if text_width >= viewport_width as usize {\n                soft_wrap_at_text_width = false;\n            } else {\n                viewport_width = text_width as u16;\n            }\n        }\n        let config = self.config.load();\n        let editor_soft_wrap = &config.soft_wrap;\n        let language_soft_wrap = self\n            .language\n            .as_ref()\n            .and_then(|config| config.soft_wrap.as_ref());\n        let enable_soft_wrap = language_soft_wrap\n            .and_then(|soft_wrap| soft_wrap.enable)\n            .or(editor_soft_wrap.enable)\n            .unwrap_or(false);\n        let max_wrap = language_soft_wrap\n            .and_then(|soft_wrap| soft_wrap.max_wrap)\n            .or(config.soft_wrap.max_wrap)\n            .unwrap_or(20);\n        let max_indent_retain = language_soft_wrap\n            .and_then(|soft_wrap| soft_wrap.max_indent_retain)\n            .or(editor_soft_wrap.max_indent_retain)\n            .unwrap_or(40);\n        let wrap_indicator = language_soft_wrap\n            .and_then(|soft_wrap| soft_wrap.wrap_indicator.clone())\n            .or_else(|| config.soft_wrap.wrap_indicator.clone())\n            .unwrap_or_else(|| \"↪ \".into());\n        let tab_width = self.tab_width() as u16;\n        TextFormat {\n            soft_wrap: enable_soft_wrap && viewport_width > 10,\n            tab_width,\n            max_wrap: max_wrap.min(viewport_width / 4),\n            max_indent_retain: max_indent_retain.min(viewport_width * 2 / 5),\n            // avoid spinning forever when the window manager\n            // sets the size to something tiny\n            viewport_width,\n            wrap_indicator: wrap_indicator.into_boxed_str(),\n            wrap_indicator_highlight: theme\n                .and_then(|theme| theme.find_highlight(\"ui.virtual.wrap\")),\n            soft_wrap_at_text_width,\n        }\n    }\n\n    /// Set the inlay hints for this document and `view_id`.\n    pub fn set_inlay_hints(&mut self, view_id: ViewId, inlay_hints: DocumentInlayHints) {\n        self.inlay_hints.insert(view_id, inlay_hints);\n    }\n\n    pub fn set_jump_labels(&mut self, view_id: ViewId, labels: Vec<Overlay>) {\n        self.jump_labels.insert(view_id, labels);\n    }\n\n    pub fn remove_jump_labels(&mut self, view_id: ViewId) {\n        self.jump_labels.remove(&view_id);\n    }\n\n    pub fn set_document_highlights(\n        &mut self,\n        view_id: ViewId,\n        ranges: Vec<std::ops::Range<usize>>,\n    ) {\n        if ranges.is_empty() {\n            self.document_highlights.remove(&view_id);\n        } else {\n            self.document_highlights\n                .insert(view_id, DocumentHighlights { ranges });\n        }\n    }\n\n    pub fn clear_document_highlights(&mut self, view_id: ViewId) {\n        self.document_highlights.remove(&view_id);\n    }\n\n    pub fn clear_all_document_highlights(&mut self) {\n        self.document_highlights.clear();\n        self.document_highlight_controllers.clear();\n    }\n\n    pub fn document_highlights(&self, view_id: ViewId) -> Option<&[std::ops::Range<usize>]> {\n        self.document_highlights\n            .get(&view_id)\n            .map(|highlights| highlights.ranges.as_slice())\n    }\n\n    pub fn document_highlight_controller(&mut self, view_id: ViewId) -> &mut TaskController {\n        self.document_highlight_controllers\n            .entry(view_id)\n            .or_default()\n    }\n\n    /// Get the inlay hints for this document and `view_id`.\n    pub fn inlay_hints(&self, view_id: ViewId) -> Option<&DocumentInlayHints> {\n        self.inlay_hints.get(&view_id)\n    }\n\n    /// Completely removes all the inlay hints saved for the document, dropping them to free memory\n    /// (since it often means inlay hints have been fully deactivated).\n    pub fn reset_all_inlay_hints(&mut self) {\n        self.inlay_hints = Default::default();\n    }\n\n    pub fn has_language_server_with_feature(&self, feature: LanguageServerFeature) -> bool {\n        self.language_servers_with_feature(feature).next().is_some()\n    }\n}\n\n#[derive(Debug, Default)]\npub struct ViewData {\n    view_position: ViewPosition,\n}\n\n#[derive(Clone, Debug)]\npub enum FormatterError {\n    SpawningFailed {\n        command: String,\n        error: std::io::ErrorKind,\n    },\n    BrokenStdin,\n    WaitForOutputFailed,\n    InvalidUtf8Output,\n    NonZeroExitStatus(Option<String>),\n}\n\nimpl std::error::Error for FormatterError {}\n\nimpl Display for FormatterError {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::SpawningFailed { command, error } => {\n                write!(f, \"Failed to spawn formatter {}: {:?}\", command, error)\n            }\n            Self::BrokenStdin => write!(f, \"Could not write to formatter stdin\"),\n            Self::WaitForOutputFailed => write!(f, \"Waiting for formatter output failed\"),\n            Self::InvalidUtf8Output => write!(f, \"Invalid UTF-8 formatter output\"),\n            Self::NonZeroExitStatus(Some(output)) => write!(f, \"Formatter error: {}\", output),\n            Self::NonZeroExitStatus(None) => {\n                write!(f, \"Formatter exited with non zero exit status\")\n            }\n        }\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use arc_swap::ArcSwap;\n\n    use super::*;\n\n    #[test]\n    fn changeset_to_changes_ignore_line_endings() {\n        use helix_lsp::{lsp, Client, OffsetEncoding};\n        let text = Rope::from(\"hello\\r\\nworld\");\n        let mut doc = Document::from(\n            text,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n        let view = ViewId::default();\n        doc.set_selection(view, Selection::single(0, 0));\n\n        let transaction =\n            Transaction::change(doc.text(), vec![(5, 7, Some(\"\\n\".into()))].into_iter());\n        let old_doc = doc.text().clone();\n        doc.apply(&transaction, view);\n        let changes = Client::changeset_to_changes(\n            &old_doc,\n            doc.text(),\n            transaction.changes(),\n            OffsetEncoding::Utf8,\n        );\n\n        assert_eq!(doc.text(), \"hello\\nworld\");\n\n        assert_eq!(\n            changes,\n            &[lsp::TextDocumentContentChangeEvent {\n                range: Some(lsp::Range::new(\n                    lsp::Position::new(0, 5),\n                    lsp::Position::new(1, 0)\n                )),\n                text: \"\\n\".into(),\n                range_length: None,\n            }]\n        );\n    }\n\n    #[test]\n    fn changeset_to_changes() {\n        use helix_lsp::{lsp, Client, OffsetEncoding};\n        let text = Rope::from(\"hello\");\n        let mut doc = Document::from(\n            text,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n        let view = ViewId::default();\n        doc.set_selection(view, Selection::single(5, 5));\n\n        // insert\n\n        let transaction = Transaction::insert(doc.text(), doc.selection(view), \" world\".into());\n        let old_doc = doc.text().clone();\n        doc.apply(&transaction, view);\n        let changes = Client::changeset_to_changes(\n            &old_doc,\n            doc.text(),\n            transaction.changes(),\n            OffsetEncoding::Utf8,\n        );\n\n        assert_eq!(\n            changes,\n            &[lsp::TextDocumentContentChangeEvent {\n                range: Some(lsp::Range::new(\n                    lsp::Position::new(0, 5),\n                    lsp::Position::new(0, 5)\n                )),\n                text: \" world\".into(),\n                range_length: None,\n            }]\n        );\n\n        // delete\n\n        let transaction = transaction.invert(&old_doc);\n        let old_doc = doc.text().clone();\n        doc.apply(&transaction, view);\n        let changes = Client::changeset_to_changes(\n            &old_doc,\n            doc.text(),\n            transaction.changes(),\n            OffsetEncoding::Utf8,\n        );\n\n        // line: 0-based.\n        // col: 0-based, gaps between chars.\n        // 0 1 2 3 4 5 6 7 8 9 0 1\n        // |h|e|l|l|o| |w|o|r|l|d|\n        //           -------------\n        // (0, 5)-(0, 11)\n        assert_eq!(\n            changes,\n            &[lsp::TextDocumentContentChangeEvent {\n                range: Some(lsp::Range::new(\n                    lsp::Position::new(0, 5),\n                    lsp::Position::new(0, 11)\n                )),\n                text: \"\".into(),\n                range_length: None,\n            }]\n        );\n\n        // replace\n\n        // also tests that changes are layered, positions depend on previous changes.\n\n        doc.set_selection(view, Selection::single(0, 5));\n        let transaction = Transaction::change(\n            doc.text(),\n            vec![(0, 2, Some(\"aei\".into())), (3, 5, Some(\"ou\".into()))].into_iter(),\n        );\n        // aeilou\n        let old_doc = doc.text().clone();\n        doc.apply(&transaction, view);\n        let changes = Client::changeset_to_changes(\n            &old_doc,\n            doc.text(),\n            transaction.changes(),\n            OffsetEncoding::Utf8,\n        );\n\n        assert_eq!(\n            changes,\n            &[\n                // 0 1 2 3 4 5\n                // |h|e|l|l|o|\n                // ----\n                //\n                // aeillo\n                lsp::TextDocumentContentChangeEvent {\n                    range: Some(lsp::Range::new(\n                        lsp::Position::new(0, 0),\n                        lsp::Position::new(0, 2)\n                    )),\n                    text: \"aei\".into(),\n                    range_length: None,\n                },\n                // 0 1 2 3 4 5 6\n                // |a|e|i|l|l|o|\n                //         -----\n                //\n                // aeilou\n                lsp::TextDocumentContentChangeEvent {\n                    range: Some(lsp::Range::new(\n                        lsp::Position::new(0, 4),\n                        lsp::Position::new(0, 6)\n                    )),\n                    text: \"ou\".into(),\n                    range_length: None,\n                }\n            ]\n        );\n    }\n\n    #[test]\n    fn test_line_ending() {\n        assert_eq!(\n            Document::default(\n                Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n                Arc::new(ArcSwap::from_pointee(syntax::Loader::default()))\n            )\n            .text()\n            .to_string(),\n            helix_core::NATIVE_LINE_ENDING.as_str()\n        );\n    }\n\n    macro_rules! decode {\n        ($name:ident, $label:expr, $label_override:expr) => {\n            #[test]\n            fn $name() {\n                let encoding = encoding::Encoding::for_label($label_override.as_bytes()).unwrap();\n                let base_path = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\")).join(\"tests/encoding\");\n                let path = base_path.join(format!(\"{}_in.txt\", $label));\n                let ref_path = base_path.join(format!(\"{}_in_ref.txt\", $label));\n                assert!(path.exists());\n                assert!(ref_path.exists());\n\n                let mut file = std::fs::File::open(path).unwrap();\n                let text = from_reader(&mut file, Some(encoding.into()))\n                    .unwrap()\n                    .0\n                    .to_string();\n                let expectation = std::fs::read_to_string(ref_path).unwrap();\n                assert_eq!(text[..], expectation[..]);\n            }\n        };\n        ($name:ident, $label:expr) => {\n            decode!($name, $label, $label);\n        };\n    }\n\n    macro_rules! encode {\n        ($name:ident, $label:expr, $label_override:expr) => {\n            #[test]\n            fn $name() {\n                let encoding = encoding::Encoding::for_label($label_override.as_bytes()).unwrap();\n                let base_path = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\")).join(\"tests/encoding\");\n                let path = base_path.join(format!(\"{}_out.txt\", $label));\n                let ref_path = base_path.join(format!(\"{}_out_ref.txt\", $label));\n                assert!(path.exists());\n                assert!(ref_path.exists());\n\n                let text = Rope::from_str(&std::fs::read_to_string(path).unwrap());\n                let mut buf: Vec<u8> = Vec::new();\n                helix_lsp::block_on(to_writer(&mut buf, (encoding, false), &text)).unwrap();\n\n                let expectation = std::fs::read(ref_path).unwrap();\n                assert_eq!(buf, expectation);\n            }\n        };\n        ($name:ident, $label:expr) => {\n            encode!($name, $label, $label);\n        };\n    }\n\n    decode!(big5_decode, \"big5\");\n    encode!(big5_encode, \"big5\");\n    decode!(euc_kr_decode, \"euc_kr\", \"EUC-KR\");\n    encode!(euc_kr_encode, \"euc_kr\", \"EUC-KR\");\n    decode!(gb18030_decode, \"gb18030\");\n    encode!(gb18030_encode, \"gb18030\");\n    decode!(iso_2022_jp_decode, \"iso_2022_jp\", \"ISO-2022-JP\");\n    encode!(iso_2022_jp_encode, \"iso_2022_jp\", \"ISO-2022-JP\");\n    decode!(jis0208_decode, \"jis0208\", \"EUC-JP\");\n    encode!(jis0208_encode, \"jis0208\", \"EUC-JP\");\n    decode!(jis0212_decode, \"jis0212\", \"EUC-JP\");\n    decode!(shift_jis_decode, \"shift_jis\");\n    encode!(shift_jis_encode, \"shift_jis\");\n}\n"
  },
  {
    "path": "helix-view/src/editor.rs",
    "content": "use crate::{\n    annotations::diagnostics::{DiagnosticFilter, InlineDiagnosticsConfig},\n    clipboard::ClipboardProvider,\n    document::{\n        DocumentOpenError, DocumentSavedEventFuture, DocumentSavedEventResult, Mode, SavePoint,\n    },\n    events::{DocumentDidClose, DocumentDidOpen, DocumentFocusLost},\n    graphics::{CursorKind, Rect},\n    handlers::Handlers,\n    info::Info,\n    input::KeyEvent,\n    register::Registers,\n    theme::{self, Theme},\n    tree::{self, Tree},\n    Document, DocumentId, View, ViewId,\n};\nuse helix_event::dispatch;\nuse helix_vcs::DiffProviderRegistry;\n\nuse futures_util::stream::select_all::SelectAll;\nuse futures_util::{future, StreamExt};\nuse helix_lsp::{Call, LanguageServerId};\nuse tokio_stream::wrappers::UnboundedReceiverStream;\n\nuse std::{\n    borrow::Cow,\n    cell::Cell,\n    collections::{BTreeMap, HashMap, HashSet, VecDeque},\n    fs,\n    io::{self, stdin},\n    num::{NonZeroU8, NonZeroUsize},\n    path::{Path, PathBuf},\n    pin::Pin,\n    sync::Arc,\n};\n\nuse tokio::{\n    sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},\n    time::{sleep, Duration, Instant, Sleep},\n};\n\nuse anyhow::{anyhow, bail, Error};\n\npub use helix_core::diagnostic::Severity;\nuse helix_core::{\n    auto_pairs::AutoPairs,\n    diagnostic::DiagnosticProvider,\n    syntax::{\n        self,\n        config::{AutoPairConfig, IndentationHeuristic, LanguageServerFeature, SoftWrap},\n    },\n    Change, LineEnding, Position, Range, Selection, Uri, NATIVE_LINE_ENDING,\n};\nuse helix_dap::{self as dap, registry::DebugAdapterId};\nuse helix_lsp::lsp;\nuse helix_stdx::path::canonicalize;\n\nuse serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};\n\nuse arc_swap::{\n    access::{DynAccess, DynGuard},\n    ArcSwap,\n};\n\npub const DIR_STACK_CAP: usize = 10;\npub const DEFAULT_AUTO_SAVE_DELAY: u64 = 3000;\n\nfn deserialize_duration_millis<'de, D>(deserializer: D) -> Result<Duration, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    let millis = u64::deserialize(deserializer)?;\n    Ok(Duration::from_millis(millis))\n}\n\nfn serialize_duration_millis<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>\nwhere\n    S: Serializer,\n{\n    serializer.serialize_u64(\n        duration\n            .as_millis()\n            .try_into()\n            .map_err(|_| serde::ser::Error::custom(\"duration value overflowed u64\"))?,\n    )\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\", default, deny_unknown_fields)]\npub struct GutterConfig {\n    /// Gutter Layout\n    pub layout: Vec<GutterType>,\n    /// Options specific to the \"line-numbers\" gutter\n    pub line_numbers: GutterLineNumbersConfig,\n}\n\nimpl Default for GutterConfig {\n    fn default() -> Self {\n        Self {\n            layout: vec![\n                GutterType::Diagnostics,\n                GutterType::Spacer,\n                GutterType::LineNumbers,\n                GutterType::Spacer,\n                GutterType::Diff,\n            ],\n            line_numbers: GutterLineNumbersConfig::default(),\n        }\n    }\n}\n\nimpl From<Vec<GutterType>> for GutterConfig {\n    fn from(x: Vec<GutterType>) -> Self {\n        GutterConfig {\n            layout: x,\n            ..Default::default()\n        }\n    }\n}\n\nfn deserialize_gutter_seq_or_struct<'de, D>(deserializer: D) -> Result<GutterConfig, D::Error>\nwhere\n    D: Deserializer<'de>,\n{\n    struct GutterVisitor;\n\n    impl<'de> serde::de::Visitor<'de> for GutterVisitor {\n        type Value = GutterConfig;\n\n        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {\n            write!(\n                formatter,\n                \"an array of gutter names or a detailed gutter configuration\"\n            )\n        }\n\n        fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>\n        where\n            S: serde::de::SeqAccess<'de>,\n        {\n            let mut gutters = Vec::new();\n            while let Some(gutter) = seq.next_element::<String>()? {\n                gutters.push(\n                    gutter\n                        .parse::<GutterType>()\n                        .map_err(serde::de::Error::custom)?,\n                )\n            }\n\n            Ok(gutters.into())\n        }\n\n        fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>\n        where\n            M: serde::de::MapAccess<'de>,\n        {\n            let deserializer = serde::de::value::MapAccessDeserializer::new(map);\n            Deserialize::deserialize(deserializer)\n        }\n    }\n\n    deserializer.deserialize_any(GutterVisitor)\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\", default, deny_unknown_fields)]\npub struct GutterLineNumbersConfig {\n    /// Minimum number of characters to use for line number gutter. Defaults to 3.\n    pub min_width: usize,\n}\n\nimpl Default for GutterLineNumbersConfig {\n    fn default() -> Self {\n        Self { min_width: 3 }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\", default, deny_unknown_fields)]\npub struct FilePickerConfig {\n    /// IgnoreOptions\n    /// Enables ignoring hidden files.\n    /// Whether to hide hidden files in file picker and global search results. Defaults to true.\n    pub hidden: bool,\n    /// Enables following symlinks.\n    /// Whether to follow symbolic links in file picker and file or directory completions. Defaults to true.\n    pub follow_symlinks: bool,\n    /// Hides symlinks that point into the current directory. Defaults to true.\n    pub deduplicate_links: bool,\n    /// Enables reading ignore files from parent directories. Defaults to true.\n    pub parents: bool,\n    /// Enables reading `.ignore` files.\n    /// Whether to hide files listed in .ignore in file picker and global search results. Defaults to true.\n    pub ignore: bool,\n    /// Enables reading `.gitignore` files.\n    /// Whether to hide files listed in .gitignore in file picker and global search results. Defaults to true.\n    pub git_ignore: bool,\n    /// Enables reading global .gitignore, whose path is specified in git's config: `core.excludefile` option.\n    /// Whether to hide files listed in global .gitignore in file picker and global search results. Defaults to true.\n    pub git_global: bool,\n    /// Enables reading `.git/info/exclude` files.\n    /// Whether to hide files listed in .git/info/exclude in file picker and global search results. Defaults to true.\n    pub git_exclude: bool,\n    /// WalkBuilder options\n    /// Maximum Depth to recurse directories in file picker and global search. Defaults to `None`.\n    pub max_depth: Option<usize>,\n}\n\nimpl Default for FilePickerConfig {\n    fn default() -> Self {\n        Self {\n            hidden: true,\n            follow_symlinks: true,\n            deduplicate_links: true,\n            parents: true,\n            ignore: true,\n            git_ignore: true,\n            git_global: true,\n            git_exclude: true,\n            max_depth: None,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\", default, deny_unknown_fields)]\npub struct FileExplorerConfig {\n    /// IgnoreOptions\n    /// Enables ignoring hidden files.\n    /// Whether to hide hidden files in file explorer and global search results. Defaults to false.\n    pub hidden: bool,\n    /// Enables following symlinks.\n    /// Whether to follow symbolic links in file picker and file or directory completions. Defaults to false.\n    pub follow_symlinks: bool,\n    /// Enables reading ignore files from parent directories. Defaults to false.\n    pub parents: bool,\n    /// Enables reading `.ignore` files.\n    /// Whether to hide files listed in .ignore in file picker and global search results. Defaults to false.\n    pub ignore: bool,\n    /// Enables reading `.gitignore` files.\n    /// Whether to hide files listed in .gitignore in file picker and global search results. Defaults to false.\n    pub git_ignore: bool,\n    /// Enables reading global .gitignore, whose path is specified in git's config: `core.excludefile` option.\n    /// Whether to hide files listed in global .gitignore in file picker and global search results. Defaults to false.\n    pub git_global: bool,\n    /// Enables reading `.git/info/exclude` files.\n    /// Whether to hide files listed in .git/info/exclude in file picker and global search results. Defaults to false.\n    pub git_exclude: bool,\n    /// Whether to flatten single-child directories in file explorer. Defaults to true.\n    pub flatten_dirs: bool,\n}\n\nimpl Default for FileExplorerConfig {\n    fn default() -> Self {\n        Self {\n            hidden: false,\n            follow_symlinks: false,\n            parents: false,\n            ignore: false,\n            git_ignore: false,\n            git_global: false,\n            git_exclude: false,\n            flatten_dirs: true,\n        }\n    }\n}\n\nfn serialize_alphabet<S>(alphabet: &[char], serializer: S) -> Result<S::Ok, S::Error>\nwhere\n    S: Serializer,\n{\n    let alphabet: String = alphabet.iter().collect();\n    serializer.serialize_str(&alphabet)\n}\n\nfn deserialize_alphabet<'de, D>(deserializer: D) -> Result<Vec<char>, D::Error>\nwhere\n    D: Deserializer<'de>,\n{\n    use serde::de::Error;\n\n    let str = String::deserialize(deserializer)?;\n    let chars: Vec<_> = str.chars().collect();\n    let unique_chars: HashSet<_> = chars.iter().copied().collect();\n    if unique_chars.len() != chars.len() {\n        return Err(<D::Error as Error>::custom(\n            \"jump-label-alphabet must contain unique characters\",\n        ));\n    }\n    Ok(chars)\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\", default, deny_unknown_fields)]\npub struct Config {\n    /// Padding to keep between the edge of the screen and the cursor when scrolling. Defaults to 5.\n    pub scrolloff: usize,\n    /// Number of lines to scroll at once. Defaults to 3\n    pub scroll_lines: isize,\n    /// Mouse support. Defaults to true.\n    pub mouse: bool,\n    /// Which register to use for mouse yank.\n    pub mouse_yank_register: char,\n    /// Shell to use for shell commands. Defaults to [\"cmd\", \"/C\"] on Windows and [\"sh\", \"-c\"] otherwise.\n    pub shell: Vec<String>,\n    /// Line number mode.\n    pub line_number: LineNumber,\n    /// Highlight the lines cursors are currently on. Defaults to false.\n    pub cursorline: bool,\n    /// Highlight the columns cursors are currently on. Defaults to false.\n    pub cursorcolumn: bool,\n    #[serde(deserialize_with = \"deserialize_gutter_seq_or_struct\")]\n    pub gutters: GutterConfig,\n    /// Middle click paste support. Defaults to true.\n    pub middle_click_paste: bool,\n    /// Automatic insertion of pairs to parentheses, brackets,\n    /// etc. Optionally, this can be a list of 2-tuples to specify a\n    /// global list of characters to pair. Defaults to true.\n    pub auto_pairs: AutoPairConfig,\n    /// Automatic auto-completion, automatically pop up without user trigger. Defaults to true.\n    pub auto_completion: bool,\n    /// Enable filepath completion.\n    /// Show files and directories if an existing path at the cursor was recognized,\n    /// either absolute or relative to the current opened document or current working directory (if the buffer is not yet saved).\n    /// Defaults to true.\n    pub path_completion: bool,\n    /// Configures completion of words from open buffers.\n    /// Defaults to enabled with a trigger length of 7.\n    pub word_completion: WordCompletion,\n    /// Automatic formatting on save. Defaults to true.\n    pub auto_format: bool,\n    /// Default register used for yank/paste. Defaults to '\"'\n    pub default_yank_register: char,\n    /// Automatic save on focus lost and/or after delay.\n    /// Time delay in milliseconds since last edit after which auto save timer triggers.\n    /// Time delay defaults to false with 3000ms delay. Focus lost defaults to false.\n    #[serde(deserialize_with = \"deserialize_auto_save\")]\n    pub auto_save: AutoSave,\n    /// Set a global text_width\n    pub text_width: usize,\n    /// Time in milliseconds since last keypress before idle timers trigger.\n    /// Used for various UI timeouts. Defaults to 250ms.\n    #[serde(\n        serialize_with = \"serialize_duration_millis\",\n        deserialize_with = \"deserialize_duration_millis\"\n    )]\n    pub idle_timeout: Duration,\n    /// Time in milliseconds after typing a word character before auto completions\n    /// are shown, set to 5 for instant. Defaults to 250ms.\n    #[serde(\n        serialize_with = \"serialize_duration_millis\",\n        deserialize_with = \"deserialize_duration_millis\"\n    )]\n    pub completion_timeout: Duration,\n    /// Whether to insert the completion suggestion on hover. Defaults to true.\n    pub preview_completion_insert: bool,\n    pub completion_trigger_len: u8,\n    /// Whether to instruct the LSP to replace the entire word when applying a completion\n    /// or to only insert new text\n    pub completion_replace: bool,\n    /// `true` if helix should automatically add a line comment token if you're currently in a comment\n    /// and press `enter`.\n    pub continue_comments: bool,\n    /// Whether to display infoboxes. Defaults to true.\n    pub auto_info: bool,\n    pub file_picker: FilePickerConfig,\n    pub file_explorer: FileExplorerConfig,\n    /// Configuration of the statusline elements\n    pub statusline: StatusLineConfig,\n    /// Shape for cursor in each mode\n    pub cursor_shape: CursorShapeConfig,\n    /// Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. Defaults to `false`.\n    pub true_color: bool,\n    /// Set to `true` to override automatic detection of terminal undercurl support in the event of a false negative. Defaults to `false`.\n    pub undercurl: bool,\n    /// Search configuration.\n    #[serde(default)]\n    pub search: SearchConfig,\n    pub lsp: LspConfig,\n    pub terminal: Option<TerminalConfig>,\n    /// Column numbers at which to draw the rulers. Defaults to `[]`, meaning no rulers.\n    pub rulers: Vec<u16>,\n    #[serde(default)]\n    pub whitespace: WhitespaceConfig,\n    /// Persistently display open buffers along the top\n    pub bufferline: BufferLine,\n    /// Vertical indent width guides.\n    pub indent_guides: IndentGuidesConfig,\n    /// Whether to color modes with different colors. Defaults to `false`.\n    pub color_modes: bool,\n    pub soft_wrap: SoftWrap,\n    /// Workspace specific lsp ceiling dirs\n    pub workspace_lsp_roots: Vec<PathBuf>,\n    /// Which line ending to choose for new documents. Defaults to `native`. i.e. `crlf` on Windows, otherwise `lf`.\n    pub default_line_ending: LineEndingConfig,\n    /// Whether to automatically insert a trailing line-ending on write if missing. Defaults to `true`.\n    pub insert_final_newline: bool,\n    /// Whether to use atomic operations to write documents to disk.\n    /// This prevents data loss if the editor is interrupted while writing the file, but may\n    /// confuse some file watching/hot reloading programs. Defaults to `true`.\n    pub atomic_save: bool,\n    /// Whether to automatically remove all trailing line-endings after the final one on write.\n    /// Defaults to `false`.\n    pub trim_final_newlines: bool,\n    /// Whether to automatically remove all whitespace characters preceding line-endings on write.\n    /// Defaults to `false`.\n    pub trim_trailing_whitespace: bool,\n    /// Enables smart tab\n    pub smart_tab: Option<SmartTabConfig>,\n    /// Draw border around popups.\n    pub popup_border: PopupBorderConfig,\n    /// Which indent heuristic to use when a new line is inserted\n    #[serde(default)]\n    pub indent_heuristic: IndentationHeuristic,\n    /// labels characters used in jumpmode\n    #[serde(\n        serialize_with = \"serialize_alphabet\",\n        deserialize_with = \"deserialize_alphabet\"\n    )]\n    pub jump_label_alphabet: Vec<char>,\n    /// Display diagnostic below the line they occur.\n    pub inline_diagnostics: InlineDiagnosticsConfig,\n    pub end_of_line_diagnostics: DiagnosticFilter,\n    // Set to override the default clipboard provider\n    pub clipboard_provider: ClipboardProvider,\n    /// Whether to read settings from [EditorConfig](https://editorconfig.org) files. Defaults to\n    /// `true`.\n    pub editor_config: bool,\n    /// Whether to render rainbow colors for matching brackets. Defaults to `false`.\n    pub rainbow_brackets: bool,\n    /// Whether to enable Kitty Keyboard Protocol\n    pub kitty_keyboard_protocol: KittyKeyboardProtocolConfig,\n    pub buffer_picker: BufferPickerConfig,\n}\n\n#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, Clone, Copy)]\n#[serde(rename_all = \"kebab-case\")]\npub struct BufferPickerConfig {\n    pub start_position: PickerStartPosition,\n}\n\n#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, Clone, Copy)]\n#[serde(rename_all = \"kebab-case\")]\npub enum PickerStartPosition {\n    #[default]\n    Current,\n    Previous,\n}\n\nimpl PickerStartPosition {\n    #[must_use]\n    pub fn is_previous(self) -> bool {\n        matches!(self, Self::Previous)\n    }\n\n    #[must_use]\n    pub fn is_current(self) -> bool {\n        matches!(self, Self::Current)\n    }\n}\n\n#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, Clone, Copy)]\n#[serde(rename_all = \"kebab-case\")]\npub enum KittyKeyboardProtocolConfig {\n    #[default]\n    Auto,\n    Disabled,\n    Enabled,\n}\n\n#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)]\n#[serde(default, rename_all = \"kebab-case\", deny_unknown_fields)]\npub struct SmartTabConfig {\n    pub enable: bool,\n    pub supersede_menu: bool,\n}\n\nimpl Default for SmartTabConfig {\n    fn default() -> Self {\n        SmartTabConfig {\n            enable: true,\n            supersede_menu: false,\n        }\n    }\n}\n\n#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(default, rename_all = \"kebab-case\", deny_unknown_fields)]\npub struct TerminalConfig {\n    pub command: String,\n    #[serde(default)]\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub args: Vec<String>,\n}\n\n#[cfg(windows)]\npub fn get_terminal_provider() -> Option<TerminalConfig> {\n    use helix_stdx::env::binary_exists;\n\n    if binary_exists(\"wt\") {\n        return Some(TerminalConfig {\n            command: \"wt\".to_string(),\n            args: vec![\n                \"new-tab\".to_string(),\n                \"--title\".to_string(),\n                \"DEBUG\".to_string(),\n                \"cmd\".to_string(),\n                \"/C\".to_string(),\n            ],\n        });\n    }\n\n    Some(TerminalConfig {\n        command: \"conhost\".to_string(),\n        args: vec![\"cmd\".to_string(), \"/C\".to_string()],\n    })\n}\n\n#[cfg(not(any(windows, target_arch = \"wasm32\")))]\npub fn get_terminal_provider() -> Option<TerminalConfig> {\n    use helix_stdx::env::{binary_exists, env_var_is_set};\n\n    if env_var_is_set(\"TMUX\") && binary_exists(\"tmux\") {\n        return Some(TerminalConfig {\n            command: \"tmux\".to_string(),\n            args: vec![\"split-window\".to_string()],\n        });\n    }\n\n    if env_var_is_set(\"WEZTERM_UNIX_SOCKET\") && binary_exists(\"wezterm\") {\n        return Some(TerminalConfig {\n            command: \"wezterm\".to_string(),\n            args: vec![\"cli\".to_string(), \"split-pane\".to_string()],\n        });\n    }\n\n    None\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(default, rename_all = \"kebab-case\", deny_unknown_fields)]\npub struct LspConfig {\n    /// Enables LSP\n    pub enable: bool,\n    /// Display LSP messagess from $/progress below statusline\n    pub display_progress_messages: bool,\n    /// Display LSP messages from window/showMessage below statusline\n    pub display_messages: bool,\n    /// Enable automatic pop up of signature help (parameter hints)\n    pub auto_signature_help: bool,\n    /// Display docs under signature help popup\n    pub display_signature_help_docs: bool,\n    /// Display inlay hints\n    pub display_inlay_hints: bool,\n    /// Automatically highlight symbol references at the cursor.\n    pub auto_document_highlight: bool,\n    /// Maximum displayed length of inlay hints (excluding the added trailing `…`).\n    /// If it's `None`, there's no limit\n    pub inlay_hints_length_limit: Option<NonZeroU8>,\n    /// Display document color swatches\n    pub display_color_swatches: bool,\n    /// Whether to enable snippet support\n    pub snippets: bool,\n    /// Whether to include declaration in the goto reference query\n    pub goto_reference_include_declaration: bool,\n}\n\nimpl Default for LspConfig {\n    fn default() -> Self {\n        Self {\n            enable: true,\n            display_progress_messages: false,\n            display_messages: true,\n            auto_signature_help: true,\n            display_signature_help_docs: true,\n            display_inlay_hints: false,\n            auto_document_highlight: false,\n            inlay_hints_length_limit: None,\n            snippets: true,\n            goto_reference_include_declaration: true,\n            display_color_swatches: true,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\", default, deny_unknown_fields)]\npub struct SearchConfig {\n    /// Smart case: Case insensitive searching unless pattern contains upper case characters. Defaults to true.\n    pub smart_case: bool,\n    /// Whether the search should wrap after depleting the matches. Default to true.\n    pub wrap_around: bool,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\", default, deny_unknown_fields)]\npub struct StatusLineConfig {\n    pub left: Vec<StatusLineElement>,\n    pub center: Vec<StatusLineElement>,\n    pub right: Vec<StatusLineElement>,\n    pub separator: String,\n    pub mode: ModeConfig,\n    pub diagnostics: Vec<Severity>,\n    pub workspace_diagnostics: Vec<Severity>,\n}\n\nimpl Default for StatusLineConfig {\n    fn default() -> Self {\n        use StatusLineElement as E;\n\n        Self {\n            left: vec![\n                E::Mode,\n                E::Spinner,\n                E::FileName,\n                E::ReadOnlyIndicator,\n                E::FileModificationIndicator,\n            ],\n            center: vec![],\n            right: vec![\n                E::Diagnostics,\n                E::Selections,\n                E::Register,\n                E::Position,\n                E::FileEncoding,\n            ],\n            separator: String::from(\"│\"),\n            mode: ModeConfig::default(),\n            diagnostics: vec![Severity::Warning, Severity::Error],\n            workspace_diagnostics: vec![Severity::Warning, Severity::Error],\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\", default, deny_unknown_fields)]\npub struct ModeConfig {\n    pub normal: String,\n    pub insert: String,\n    pub select: String,\n}\n\nimpl Default for ModeConfig {\n    fn default() -> Self {\n        Self {\n            normal: String::from(\"NOR\"),\n            insert: String::from(\"INS\"),\n            select: String::from(\"SEL\"),\n        }\n    }\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub enum StatusLineElement {\n    /// The editor mode (Normal, Insert, Visual/Selection)\n    Mode,\n\n    /// The LSP activity spinner\n    Spinner,\n\n    /// The file basename (the leaf of the open file's path)\n    FileBaseName,\n\n    /// The relative file path\n    FileName,\n\n    /// The file absolute path\n    FileAbsolutePath,\n\n    // The file modification indicator\n    FileModificationIndicator,\n\n    /// An indicator that shows `\"[readonly]\"` when a file cannot be written\n    ReadOnlyIndicator,\n\n    /// The file encoding\n    FileEncoding,\n\n    /// The file line endings (CRLF or LF)\n    FileLineEnding,\n\n    /// The file indentation style\n    FileIndentStyle,\n\n    /// The file type (language ID or \"text\")\n    FileType,\n\n    /// A summary of the number of errors and warnings\n    Diagnostics,\n\n    /// A summary of the number of errors and warnings on file and workspace\n    WorkspaceDiagnostics,\n\n    /// The number of selections (cursors)\n    Selections,\n\n    /// The number of characters currently in primary selection\n    PrimarySelectionLength,\n\n    /// The cursor position\n    Position,\n\n    /// The separator string\n    Separator,\n\n    /// The cursor position as a percent of the total file\n    PositionPercentage,\n\n    /// The total line numbers of the current file\n    TotalLineNumbers,\n\n    /// A single space\n    Spacer,\n\n    /// Current version control information\n    VersionControl,\n\n    /// Indicator for selected register\n    Register,\n\n    /// The base of current working directory\n    CurrentWorkingDirectory,\n}\n\n// Cursor shape is read and used on every rendered frame and so needs\n// to be fast. Therefore we avoid a hashmap and use an enum indexed array.\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct CursorShapeConfig([CursorKind; 3]);\n\nimpl CursorShapeConfig {\n    pub fn from_mode(&self, mode: Mode) -> CursorKind {\n        self.get(mode as usize).copied().unwrap_or_default()\n    }\n}\n\nimpl<'de> Deserialize<'de> for CursorShapeConfig {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let m = HashMap::<Mode, CursorKind>::deserialize(deserializer)?;\n        let into_cursor = |mode: Mode| m.get(&mode).copied().unwrap_or_default();\n        Ok(CursorShapeConfig([\n            into_cursor(Mode::Normal),\n            into_cursor(Mode::Select),\n            into_cursor(Mode::Insert),\n        ]))\n    }\n}\n\nimpl Serialize for CursorShapeConfig {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        let mut map = serializer.serialize_map(Some(self.len()))?;\n        let modes = [Mode::Normal, Mode::Select, Mode::Insert];\n        for mode in modes {\n            map.serialize_entry(&mode, &self.from_mode(mode))?;\n        }\n        map.end()\n    }\n}\n\nimpl std::ops::Deref for CursorShapeConfig {\n    type Target = [CursorKind; 3];\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl Default for CursorShapeConfig {\n    fn default() -> Self {\n        Self([CursorKind::Block; 3])\n    }\n}\n\n/// bufferline render modes\n#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub enum BufferLine {\n    /// Don't render bufferline\n    #[default]\n    Never,\n    /// Always render\n    Always,\n    /// Only if multiple buffers are open\n    Multiple,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub enum LineNumber {\n    /// Show absolute line number\n    Absolute,\n\n    /// If focused and in normal/select mode, show relative line number to the primary cursor.\n    /// If unfocused or in insert mode, show absolute line number.\n    Relative,\n}\n\nimpl std::str::FromStr for LineNumber {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        match s.to_lowercase().as_str() {\n            \"absolute\" | \"abs\" => Ok(Self::Absolute),\n            \"relative\" | \"rel\" => Ok(Self::Relative),\n            _ => anyhow::bail!(\"Line number can only be `absolute` or `relative`.\"),\n        }\n    }\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub enum GutterType {\n    /// Show diagnostics and other features like breakpoints\n    Diagnostics,\n    /// Show line numbers\n    LineNumbers,\n    /// Show one blank space\n    Spacer,\n    /// Highlight local changes\n    Diff,\n}\n\nimpl std::str::FromStr for GutterType {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        match s.to_lowercase().as_str() {\n            \"diagnostics\" => Ok(Self::Diagnostics),\n            \"spacer\" => Ok(Self::Spacer),\n            \"line-numbers\" => Ok(Self::LineNumbers),\n            \"diff\" => Ok(Self::Diff),\n            _ => anyhow::bail!(\n                \"Gutter type can only be `diagnostics`, `spacer`, `line-numbers` or `diff`.\"\n            ),\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(default)]\npub struct WhitespaceConfig {\n    pub render: WhitespaceRender,\n    pub characters: WhitespaceCharacters,\n}\n\nimpl Default for WhitespaceConfig {\n    fn default() -> Self {\n        Self {\n            render: WhitespaceRender::Basic(WhitespaceRenderValue::None),\n            characters: WhitespaceCharacters::default(),\n        }\n    }\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(untagged, rename_all = \"kebab-case\")]\npub enum WhitespaceRender {\n    Basic(WhitespaceRenderValue),\n    Specific {\n        default: Option<WhitespaceRenderValue>,\n        space: Option<WhitespaceRenderValue>,\n        nbsp: Option<WhitespaceRenderValue>,\n        nnbsp: Option<WhitespaceRenderValue>,\n        tab: Option<WhitespaceRenderValue>,\n        newline: Option<WhitespaceRenderValue>,\n    },\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub enum WhitespaceRenderValue {\n    None,\n    // TODO\n    // Selection,\n    All,\n}\n\nimpl WhitespaceRender {\n    pub fn space(&self) -> WhitespaceRenderValue {\n        match *self {\n            Self::Basic(val) => val,\n            Self::Specific { default, space, .. } => {\n                space.or(default).unwrap_or(WhitespaceRenderValue::None)\n            }\n        }\n    }\n    pub fn nbsp(&self) -> WhitespaceRenderValue {\n        match *self {\n            Self::Basic(val) => val,\n            Self::Specific { default, nbsp, .. } => {\n                nbsp.or(default).unwrap_or(WhitespaceRenderValue::None)\n            }\n        }\n    }\n    pub fn nnbsp(&self) -> WhitespaceRenderValue {\n        match *self {\n            Self::Basic(val) => val,\n            Self::Specific { default, nnbsp, .. } => {\n                nnbsp.or(default).unwrap_or(WhitespaceRenderValue::None)\n            }\n        }\n    }\n    pub fn tab(&self) -> WhitespaceRenderValue {\n        match *self {\n            Self::Basic(val) => val,\n            Self::Specific { default, tab, .. } => {\n                tab.or(default).unwrap_or(WhitespaceRenderValue::None)\n            }\n        }\n    }\n    pub fn newline(&self) -> WhitespaceRenderValue {\n        match *self {\n            Self::Basic(val) => val,\n            Self::Specific {\n                default, newline, ..\n            } => newline.or(default).unwrap_or(WhitespaceRenderValue::None),\n        }\n    }\n}\n\n#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]\n#[serde(rename_all = \"kebab-case\")]\npub struct AutoSave {\n    /// Auto save after a delay in milliseconds. Defaults to disabled.\n    #[serde(default)]\n    pub after_delay: AutoSaveAfterDelay,\n    /// Auto save on focus lost. Defaults to false.\n    #[serde(default)]\n    pub focus_lost: bool,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]\n#[serde(deny_unknown_fields)]\npub struct AutoSaveAfterDelay {\n    #[serde(default)]\n    /// Enable auto save after delay. Defaults to false.\n    pub enable: bool,\n    #[serde(default = \"default_auto_save_delay\")]\n    /// Time delay in milliseconds. Defaults to [DEFAULT_AUTO_SAVE_DELAY].\n    pub timeout: u64,\n}\n\nimpl Default for AutoSaveAfterDelay {\n    fn default() -> Self {\n        Self {\n            enable: false,\n            timeout: DEFAULT_AUTO_SAVE_DELAY,\n        }\n    }\n}\n\nfn default_auto_save_delay() -> u64 {\n    DEFAULT_AUTO_SAVE_DELAY\n}\n\nfn deserialize_auto_save<'de, D>(deserializer: D) -> Result<AutoSave, D::Error>\nwhere\n    D: serde::Deserializer<'de>,\n{\n    #[derive(Deserialize, Serialize)]\n    #[serde(untagged, deny_unknown_fields, rename_all = \"kebab-case\")]\n    enum AutoSaveToml {\n        EnableFocusLost(bool),\n        AutoSave(AutoSave),\n    }\n\n    match AutoSaveToml::deserialize(deserializer)? {\n        AutoSaveToml::EnableFocusLost(focus_lost) => Ok(AutoSave {\n            focus_lost,\n            ..Default::default()\n        }),\n        AutoSaveToml::AutoSave(auto_save) => Ok(auto_save),\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(default)]\npub struct WhitespaceCharacters {\n    pub space: char,\n    pub nbsp: char,\n    pub nnbsp: char,\n    pub tab: char,\n    pub tabpad: char,\n    pub newline: char,\n}\n\nimpl Default for WhitespaceCharacters {\n    fn default() -> Self {\n        Self {\n            space: '·',   // U+00B7\n            nbsp: '⍽',    // U+237D\n            nnbsp: '␣',   // U+2423\n            tab: '→',     // U+2192\n            newline: '⏎', // U+23CE\n            tabpad: ' ',\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(default, rename_all = \"kebab-case\")]\npub struct IndentGuidesConfig {\n    pub render: bool,\n    pub character: char,\n    pub skip_levels: u8,\n}\n\nimpl Default for IndentGuidesConfig {\n    fn default() -> Self {\n        Self {\n            skip_levels: 0,\n            render: false,\n            character: '│',\n        }\n    }\n}\n\n/// Line ending configuration.\n#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"lowercase\")]\npub enum LineEndingConfig {\n    /// The platform's native line ending.\n    ///\n    /// `crlf` on Windows, otherwise `lf`.\n    #[default]\n    Native,\n    /// Line feed.\n    LF,\n    /// Carriage return followed by line feed.\n    Crlf,\n    /// Form feed.\n    #[cfg(feature = \"unicode-lines\")]\n    FF,\n    /// Carriage return.\n    #[cfg(feature = \"unicode-lines\")]\n    CR,\n    /// Next line.\n    #[cfg(feature = \"unicode-lines\")]\n    Nel,\n}\n\nimpl From<LineEndingConfig> for LineEnding {\n    fn from(line_ending: LineEndingConfig) -> Self {\n        match line_ending {\n            LineEndingConfig::Native => NATIVE_LINE_ENDING,\n            LineEndingConfig::LF => LineEnding::LF,\n            LineEndingConfig::Crlf => LineEnding::Crlf,\n            #[cfg(feature = \"unicode-lines\")]\n            LineEndingConfig::FF => LineEnding::FF,\n            #[cfg(feature = \"unicode-lines\")]\n            LineEndingConfig::CR => LineEnding::CR,\n            #[cfg(feature = \"unicode-lines\")]\n            LineEndingConfig::Nel => LineEnding::Nel,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"kebab-case\")]\npub enum PopupBorderConfig {\n    None,\n    All,\n    Popup,\n    Menu,\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(default, rename_all = \"kebab-case\", deny_unknown_fields)]\npub struct WordCompletion {\n    pub enable: bool,\n    pub trigger_length: NonZeroU8,\n}\n\nimpl Default for WordCompletion {\n    fn default() -> Self {\n        Self {\n            enable: true,\n            trigger_length: NonZeroU8::new(7).unwrap(),\n        }\n    }\n}\n\nimpl Default for Config {\n    fn default() -> Self {\n        Self {\n            scrolloff: 5,\n            scroll_lines: 3,\n            mouse: true,\n            mouse_yank_register: '*',\n            shell: if cfg!(windows) {\n                vec![\"cmd\".to_owned(), \"/C\".to_owned()]\n            } else {\n                vec![\"sh\".to_owned(), \"-c\".to_owned()]\n            },\n            line_number: LineNumber::Absolute,\n            cursorline: false,\n            cursorcolumn: false,\n            gutters: GutterConfig::default(),\n            middle_click_paste: true,\n            auto_pairs: AutoPairConfig::default(),\n            auto_completion: true,\n            path_completion: true,\n            word_completion: WordCompletion::default(),\n            auto_format: true,\n            default_yank_register: '\"',\n            auto_save: AutoSave::default(),\n            idle_timeout: Duration::from_millis(250),\n            completion_timeout: Duration::from_millis(250),\n            preview_completion_insert: true,\n            completion_trigger_len: 2,\n            auto_info: true,\n            file_picker: FilePickerConfig::default(),\n            file_explorer: FileExplorerConfig::default(),\n            statusline: StatusLineConfig::default(),\n            cursor_shape: CursorShapeConfig::default(),\n            true_color: false,\n            undercurl: false,\n            search: SearchConfig::default(),\n            lsp: LspConfig::default(),\n            terminal: get_terminal_provider(),\n            rulers: Vec::new(),\n            whitespace: WhitespaceConfig::default(),\n            bufferline: BufferLine::default(),\n            indent_guides: IndentGuidesConfig::default(),\n            color_modes: false,\n            soft_wrap: SoftWrap {\n                enable: Some(false),\n                ..SoftWrap::default()\n            },\n            text_width: 80,\n            completion_replace: false,\n            continue_comments: true,\n            workspace_lsp_roots: Vec::new(),\n            default_line_ending: LineEndingConfig::default(),\n            insert_final_newline: true,\n            atomic_save: true,\n            trim_final_newlines: false,\n            trim_trailing_whitespace: false,\n            smart_tab: Some(SmartTabConfig::default()),\n            popup_border: PopupBorderConfig::None,\n            indent_heuristic: IndentationHeuristic::default(),\n            jump_label_alphabet: ('a'..='z').collect(),\n            inline_diagnostics: InlineDiagnosticsConfig::default(),\n            end_of_line_diagnostics: DiagnosticFilter::Enable(Severity::Hint),\n            clipboard_provider: ClipboardProvider::default(),\n            editor_config: true,\n            rainbow_brackets: false,\n            kitty_keyboard_protocol: Default::default(),\n            buffer_picker: BufferPickerConfig::default(),\n        }\n    }\n}\n\nimpl Default for SearchConfig {\n    fn default() -> Self {\n        Self {\n            wrap_around: true,\n            smart_case: true,\n        }\n    }\n}\n\n#[derive(Debug, Clone, Default)]\npub struct Breakpoint {\n    pub id: Option<usize>,\n    pub verified: bool,\n    pub message: Option<String>,\n\n    pub line: usize,\n    pub column: Option<usize>,\n    pub condition: Option<String>,\n    pub hit_condition: Option<String>,\n    pub log_message: Option<String>,\n}\n\nuse futures_util::stream::{Flatten, Once};\n\ntype Diagnostics = BTreeMap<Uri, Vec<(lsp::Diagnostic, DiagnosticProvider)>>;\n\npub struct Editor {\n    /// Current editing mode.\n    pub mode: Mode,\n    pub tree: Tree,\n    pub next_document_id: DocumentId,\n    pub documents: BTreeMap<DocumentId, Document>,\n\n    // We Flatten<> to resolve the inner DocumentSavedEventFuture. For that we need a stream of streams, hence the Once<>.\n    // https://stackoverflow.com/a/66875668\n    pub saves: HashMap<DocumentId, UnboundedSender<Once<DocumentSavedEventFuture>>>,\n    pub save_queue: SelectAll<Flatten<UnboundedReceiverStream<Once<DocumentSavedEventFuture>>>>,\n    pub write_count: usize,\n\n    pub count: Option<std::num::NonZeroUsize>,\n    pub selected_register: Option<char>,\n    pub registers: Registers,\n    pub macro_recording: Option<(char, Vec<KeyEvent>)>,\n    pub macro_replaying: Vec<char>,\n    pub language_servers: helix_lsp::Registry,\n    pub diagnostics: Diagnostics,\n    pub diff_providers: DiffProviderRegistry,\n\n    pub debug_adapters: dap::registry::Registry,\n    pub breakpoints: HashMap<PathBuf, Vec<Breakpoint>>,\n\n    pub syn_loader: Arc<ArcSwap<syntax::Loader>>,\n    pub theme_loader: Arc<theme::Loader>,\n    /// last_theme is used for theme previews. We store the current theme here,\n    /// and if previewing is cancelled, we can return to it.\n    pub last_theme: Option<Theme>,\n    /// The currently applied editor theme. While previewing a theme, the previewed theme\n    /// is set here.\n    pub theme: Theme,\n\n    /// The primary Selection prior to starting a goto_line_number preview. This is\n    /// restored when the preview is aborted, or added to the jumplist when it is\n    /// confirmed.\n    pub last_selection: Option<Selection>,\n\n    pub status_msg: Option<(Cow<'static, str>, Severity)>,\n    pub autoinfo: Option<Info>,\n\n    pub config: Arc<dyn DynAccess<Config>>,\n    pub auto_pairs: Option<AutoPairs>,\n\n    pub idle_timer: Pin<Box<Sleep>>,\n    redraw_timer: Pin<Box<Sleep>>,\n    last_motion: Option<Motion>,\n    pub last_completion: Option<CompleteAction>,\n    pub last_cwd: Option<PathBuf>,\n    pub dir_stack: VecDeque<PathBuf>,\n\n    pub exit_code: i32,\n\n    pub config_events: (UnboundedSender<ConfigEvent>, UnboundedReceiver<ConfigEvent>),\n    pub needs_redraw: bool,\n    /// Cached position of the cursor calculated during rendering.\n    /// The content of `cursor_cache` is returned by `Editor::cursor` if\n    /// set to `Some(_)`. The value will be cleared after it's used.\n    /// If `cursor_cache` is `None` then the `Editor::cursor` function will\n    /// calculate the cursor position.\n    ///\n    /// `Some(None)` represents a cursor position outside of the visible area.\n    /// This will just cause `Editor::cursor` to return `None`.\n    ///\n    /// This cache is only a performance optimization to\n    /// avoid calculating the cursor position multiple\n    /// times during rendering and should not be set by other functions.\n    pub handlers: Handlers,\n\n    pub mouse_down_range: Option<Range>,\n    pub cursor_cache: CursorCache,\n}\n\npub type Motion = Box<dyn Fn(&mut Editor)>;\n\n#[derive(Debug)]\npub enum EditorEvent {\n    DocumentSaved(DocumentSavedEventResult),\n    ConfigEvent(ConfigEvent),\n    LanguageServerMessage((LanguageServerId, Call)),\n    DebuggerEvent((DebugAdapterId, dap::Payload)),\n    IdleTimer,\n    Redraw,\n}\n\n#[derive(Debug, Clone)]\npub enum ConfigEvent {\n    Refresh,\n    Update(Box<Config>),\n    ThemeChanged,\n}\n\nenum ThemeAction {\n    Set,\n    Preview,\n}\n\n#[derive(Debug, Clone)]\npub enum CompleteAction {\n    Triggered,\n    /// A savepoint of the currently selected completion. The savepoint\n    /// MUST be restored before sending any event to the LSP\n    Selected {\n        savepoint: Arc<SavePoint>,\n    },\n    Applied {\n        trigger_offset: usize,\n        changes: Vec<Change>,\n        placeholder: bool,\n    },\n}\n\n#[derive(Debug, Copy, Clone)]\npub enum Action {\n    Load,\n    Replace,\n    HorizontalSplit,\n    VerticalSplit,\n}\n\nimpl Action {\n    /// Whether to align the view to the cursor after executing this action\n    pub fn align_view(&self, view: &View, new_doc: DocumentId) -> bool {\n        !matches!((self, view.doc == new_doc), (Action::Load, false))\n    }\n}\n\n/// Error thrown on failed document closed\npub enum CloseError {\n    /// Document doesn't exist\n    DoesNotExist,\n    /// Buffer is modified\n    BufferModified(String),\n    /// Document failed to save\n    SaveError(anyhow::Error),\n}\n\nimpl Editor {\n    pub fn new(\n        mut area: Rect,\n        theme_loader: Arc<theme::Loader>,\n        syn_loader: Arc<ArcSwap<syntax::Loader>>,\n        config: Arc<dyn DynAccess<Config>>,\n        handlers: Handlers,\n    ) -> Self {\n        let language_servers = helix_lsp::Registry::new(syn_loader.clone());\n        let conf = config.load();\n        let auto_pairs = (&conf.auto_pairs).into();\n\n        // HAXX: offset the render area height by 1 to account for prompt/commandline\n        area.height -= 1;\n\n        Self {\n            mode: Mode::Normal,\n            tree: Tree::new(area),\n            next_document_id: DocumentId::default(),\n            documents: BTreeMap::new(),\n            saves: HashMap::new(),\n            save_queue: SelectAll::new(),\n            write_count: 0,\n            count: None,\n            selected_register: None,\n            macro_recording: None,\n            macro_replaying: Vec::new(),\n            theme: theme_loader.default(),\n            language_servers,\n            diagnostics: Diagnostics::new(),\n            diff_providers: DiffProviderRegistry::default(),\n            debug_adapters: dap::registry::Registry::new(),\n            breakpoints: HashMap::new(),\n            syn_loader,\n            theme_loader,\n            last_theme: None,\n            last_selection: None,\n            registers: Registers::new(Box::new(arc_swap::access::Map::new(\n                Arc::clone(&config),\n                |config: &Config| &config.clipboard_provider,\n            ))),\n            status_msg: None,\n            autoinfo: None,\n            idle_timer: Box::pin(sleep(conf.idle_timeout)),\n            redraw_timer: Box::pin(sleep(Duration::MAX)),\n            last_motion: None,\n            last_completion: None,\n            last_cwd: None,\n            config,\n            auto_pairs,\n            exit_code: 0,\n            config_events: unbounded_channel(),\n            needs_redraw: false,\n            handlers,\n            mouse_down_range: None,\n            cursor_cache: CursorCache::default(),\n            dir_stack: VecDeque::with_capacity(DIR_STACK_CAP),\n        }\n    }\n\n    pub fn popup_border(&self) -> bool {\n        self.config().popup_border == PopupBorderConfig::All\n            || self.config().popup_border == PopupBorderConfig::Popup\n    }\n\n    pub fn menu_border(&self) -> bool {\n        self.config().popup_border == PopupBorderConfig::All\n            || self.config().popup_border == PopupBorderConfig::Menu\n    }\n\n    pub fn apply_motion<F: Fn(&mut Self) + 'static>(&mut self, motion: F) {\n        motion(self);\n        self.last_motion = Some(Box::new(motion));\n    }\n\n    pub fn repeat_last_motion(&mut self, count: usize) {\n        if let Some(motion) = self.last_motion.take() {\n            for _ in 0..count {\n                motion(self);\n            }\n            self.last_motion = Some(motion);\n        }\n    }\n    /// Current editing mode for the [`Editor`].\n    pub fn mode(&self) -> Mode {\n        self.mode\n    }\n\n    pub fn config(&self) -> DynGuard<Config> {\n        self.config.load()\n    }\n\n    /// Call if the config has changed to let the editor update all\n    /// relevant members.\n    pub fn refresh_config(&mut self, old_config: &Config) {\n        let config = self.config();\n        self.auto_pairs = (&config.auto_pairs).into();\n        self.reset_idle_timer();\n        self._refresh();\n        helix_event::dispatch(crate::events::ConfigDidChange {\n            editor: self,\n            old: old_config,\n            new: &config,\n        })\n    }\n\n    pub fn clear_idle_timer(&mut self) {\n        // equivalent to internal Instant::far_future() (30 years)\n        self.idle_timer\n            .as_mut()\n            .reset(Instant::now() + Duration::from_secs(86400 * 365 * 30));\n    }\n\n    pub fn reset_idle_timer(&mut self) {\n        let config = self.config();\n        self.idle_timer\n            .as_mut()\n            .reset(Instant::now() + config.idle_timeout);\n    }\n\n    pub fn clear_status(&mut self) {\n        self.status_msg = None;\n    }\n\n    #[inline]\n    pub fn set_status<T: Into<Cow<'static, str>>>(&mut self, status: T) {\n        let status = status.into();\n        log::debug!(\"editor status: {}\", status);\n        self.status_msg = Some((status, Severity::Info));\n    }\n\n    #[inline]\n    pub fn set_error<T: Into<Cow<'static, str>>>(&mut self, error: T) {\n        let error = error.into();\n        log::debug!(\"editor error: {}\", error);\n        self.status_msg = Some((error, Severity::Error));\n    }\n\n    #[inline]\n    pub fn set_warning<T: Into<Cow<'static, str>>>(&mut self, warning: T) {\n        let warning = warning.into();\n        log::warn!(\"editor warning: {}\", warning);\n        self.status_msg = Some((warning, Severity::Warning));\n    }\n\n    #[inline]\n    pub fn get_status(&self) -> Option<(&Cow<'static, str>, &Severity)> {\n        self.status_msg.as_ref().map(|(status, sev)| (status, sev))\n    }\n\n    /// Returns true if the current status is an error\n    #[inline]\n    pub fn is_err(&self) -> bool {\n        self.status_msg\n            .as_ref()\n            .map(|(_, sev)| *sev == Severity::Error)\n            .unwrap_or(false)\n    }\n\n    pub fn unset_theme_preview(&mut self) {\n        if let Some(last_theme) = self.last_theme.take() {\n            self.set_theme(last_theme);\n        }\n        // None likely occurs when the user types \":theme\" and then exits before previewing\n    }\n\n    pub fn set_theme_preview(&mut self, theme: Theme) {\n        self.set_theme_impl(theme, ThemeAction::Preview);\n    }\n\n    pub fn set_theme(&mut self, theme: Theme) {\n        self.set_theme_impl(theme, ThemeAction::Set);\n    }\n\n    fn set_theme_impl(&mut self, theme: Theme, preview: ThemeAction) {\n        // `ui.selection` is the only scope required to be able to render a theme.\n        if theme.find_highlight_exact(\"ui.selection\").is_none() {\n            self.set_error(\"Invalid theme: `ui.selection` required\");\n            return;\n        }\n\n        let scopes = theme.scopes();\n        (*self.syn_loader).load().set_scopes(scopes.to_vec());\n\n        match preview {\n            ThemeAction::Preview => {\n                let last_theme = std::mem::replace(&mut self.theme, theme);\n                // only insert on first preview: this will be the last theme the user has saved\n                self.last_theme.get_or_insert(last_theme);\n            }\n            ThemeAction::Set => {\n                self.last_theme = None;\n                self.theme = theme;\n            }\n        }\n\n        self._refresh();\n    }\n\n    #[inline]\n    pub fn language_server_by_id(\n        &self,\n        language_server_id: LanguageServerId,\n    ) -> Option<&helix_lsp::Client> {\n        self.language_servers\n            .get_by_id(language_server_id)\n            .map(|client| &**client)\n    }\n\n    /// Refreshes the language server for a given document\n    pub fn refresh_language_servers(&mut self, doc_id: DocumentId) {\n        self.launch_language_servers(doc_id)\n    }\n\n    /// moves/renames a path, invoking any event handlers (currently only lsp)\n    /// and calling `set_doc_path` if the file is open in the editor\n    pub fn move_path(&mut self, old_path: &Path, new_path: &Path) -> io::Result<()> {\n        let new_path = canonicalize(new_path);\n        // sanity check\n        if old_path == new_path {\n            return Ok(());\n        }\n        let is_dir = old_path.is_dir();\n        let language_servers: Vec<_> = self\n            .language_servers\n            .iter_clients()\n            .filter(|client| client.is_initialized())\n            .cloned()\n            .collect();\n        for language_server in language_servers {\n            let Some(request) = language_server.will_rename(old_path, &new_path, is_dir) else {\n                continue;\n            };\n            let edit = match helix_lsp::block_on(request) {\n                Ok(edit) => edit.unwrap_or_default(),\n                Err(err) => {\n                    log::error!(\"invalid willRename response: {err:?}\");\n                    continue;\n                }\n            };\n            if let Err(err) = self.apply_workspace_edit(language_server.offset_encoding(), &edit) {\n                log::error!(\"failed to apply workspace edit: {err:?}\")\n            }\n        }\n\n        if old_path.exists() {\n            fs::rename(old_path, &new_path)?;\n        }\n\n        if let Some(doc) = self.document_by_path(old_path) {\n            self.set_doc_path(doc.id(), &new_path);\n        }\n        let is_dir = new_path.is_dir();\n        for ls in self.language_servers.iter_clients() {\n            // A new language server might have been started in `set_doc_path` and won't\n            // be initialized yet. Skip the `did_rename` notification for this server.\n            if !ls.is_initialized() {\n                continue;\n            }\n            ls.did_rename(old_path, &new_path, is_dir);\n        }\n        self.language_servers\n            .file_event_handler\n            .file_changed(old_path.to_owned());\n        self.language_servers\n            .file_event_handler\n            .file_changed(new_path);\n        Ok(())\n    }\n\n    pub fn set_doc_path(&mut self, doc_id: DocumentId, path: &Path) {\n        let doc = doc_mut!(self, &doc_id);\n        let old_path = doc.path();\n\n        if let Some(old_path) = old_path {\n            // sanity check, should not occur but some callers (like an LSP) may\n            // create bogus calls\n            if old_path == path {\n                return;\n            }\n            // if we are open in LSPs send did_close notification\n            for language_server in doc.language_servers() {\n                language_server.text_document_did_close(doc.identifier());\n            }\n        }\n        // we need to clear the list of language servers here so that\n        // refresh_doc_language/refresh_language_servers doesn't resend\n        // text_document_did_close. Since we called `text_document_did_close`\n        // we have fully unregistered this document from its LS\n        doc.language_servers.clear();\n        doc.set_path(Some(path));\n        doc.detect_editor_config();\n        self.refresh_doc_language(doc_id)\n    }\n\n    pub fn refresh_doc_language(&mut self, doc_id: DocumentId) {\n        let loader = self.syn_loader.load();\n        let doc = doc_mut!(self, &doc_id);\n        doc.detect_language(&loader);\n        doc.detect_editor_config();\n        doc.detect_indent_and_line_ending();\n        self.refresh_language_servers(doc_id);\n        let doc = doc_mut!(self, &doc_id);\n        let diagnostics = Editor::doc_diagnostics(&self.language_servers, &self.diagnostics, doc);\n        doc.replace_diagnostics(diagnostics, &[], None);\n        doc.reset_all_inlay_hints();\n    }\n\n    /// Launch a language server for a given document\n    fn launch_language_servers(&mut self, doc_id: DocumentId) {\n        if !self.config().lsp.enable {\n            return;\n        }\n        // if doc doesn't have a URL it's a scratch buffer, ignore it\n        let Some(doc) = self.documents.get_mut(&doc_id) else {\n            return;\n        };\n        let Some(doc_url) = doc.url() else {\n            return;\n        };\n        let (lang, path) = (doc.language.clone(), doc.path().cloned());\n        let config = doc.config.load();\n        let root_dirs = &config.workspace_lsp_roots;\n\n        // store only successfully started language servers\n        let language_servers = lang.as_ref().map_or_else(HashMap::default, |language| {\n            self.language_servers\n                .get(language, path.as_ref(), root_dirs, config.lsp.snippets)\n                .filter_map(|(lang, client)| match client {\n                    Ok(client) => Some((lang, client)),\n                    Err(err) => {\n                        if let helix_lsp::Error::ExecutableNotFound(err) = err {\n                            // Silence by default since some language servers might just not be installed\n                            log::debug!(\n                                \"Language server not found for `{}` {} {}\", language.scope, lang, err,\n                            );\n                        } else {\n                            log::error!(\n                                \"Failed to initialize the language servers for `{}` - `{}` {{ {} }}\",\n                                language.scope,\n                                lang,\n                                err\n                            );\n                        }\n                        None\n                    }\n                })\n                .collect::<HashMap<_, _>>()\n        });\n\n        if language_servers.is_empty() && doc.language_servers.is_empty() {\n            return;\n        }\n\n        let language_id = doc.language_id().map(ToOwned::to_owned).unwrap_or_default();\n\n        // only spawn new language servers if the servers aren't the same\n        let doc_language_servers_not_in_registry =\n            doc.language_servers.iter().filter(|(name, doc_ls)| {\n                language_servers\n                    .get(*name)\n                    .is_none_or(|ls| ls.id() != doc_ls.id())\n            });\n\n        for (_, language_server) in doc_language_servers_not_in_registry {\n            language_server.text_document_did_close(doc.identifier());\n        }\n\n        let language_servers_not_in_doc = language_servers.iter().filter(|(name, ls)| {\n            doc.language_servers\n                .get(*name)\n                .is_none_or(|doc_ls| ls.id() != doc_ls.id())\n        });\n\n        for (_, language_server) in language_servers_not_in_doc {\n            // TODO: this now races with on_init code if the init happens too quickly\n            language_server.text_document_did_open(\n                doc_url.clone(),\n                doc.version(),\n                doc.text(),\n                language_id.clone(),\n            );\n        }\n\n        doc.language_servers = language_servers;\n    }\n\n    fn _refresh(&mut self) {\n        let config = self.config();\n\n        // Reset the inlay hints annotations *before* updating the views, that way we ensure they\n        // will disappear during the `.sync_change(doc)` call below.\n        //\n        // We can't simply check this config when rendering because inlay hints are only parts of\n        // the possible annotations, and others could still be active, so we need to selectively\n        // drop the inlay hints.\n        if !config.lsp.display_inlay_hints {\n            for doc in self.documents_mut() {\n                doc.reset_all_inlay_hints();\n            }\n        }\n\n        for (view, _) in self.tree.views_mut() {\n            let doc = doc_mut!(self, &view.doc);\n            view.sync_changes(doc);\n            view.gutters = config.gutters.clone();\n            view.ensure_cursor_in_view(doc, config.scrolloff)\n        }\n    }\n\n    fn replace_document_in_view(&mut self, current_view: ViewId, doc_id: DocumentId) {\n        let scrolloff = self.config().scrolloff;\n        let view = self.tree.get_mut(current_view);\n\n        view.doc = doc_id;\n        let doc = doc_mut!(self, &doc_id);\n\n        doc.ensure_view_init(view.id);\n        view.sync_changes(doc);\n        doc.mark_as_focused();\n\n        view.ensure_cursor_in_view(doc, scrolloff)\n    }\n\n    pub fn switch(&mut self, id: DocumentId, action: Action) {\n        use crate::tree::Layout;\n\n        if !self.documents.contains_key(&id) {\n            log::error!(\"cannot switch to document that does not exist (anymore)\");\n            return;\n        }\n\n        if !matches!(action, Action::Load) {\n            self.enter_normal_mode();\n        }\n\n        let focust_lost = match action {\n            Action::Replace => {\n                let (view, doc) = current_ref!(self);\n                // If the current view is an empty scratch buffer and is not displayed in any other views, delete it.\n                // Boolean value is determined before the call to `view_mut` because the operation requires a borrow\n                // of `self.tree`, which is mutably borrowed when `view_mut` is called.\n                let remove_empty_scratch = !doc.is_modified()\n                    // If the buffer has no path and is not modified, it is an empty scratch buffer.\n                    && doc.path().is_none()\n                    // If the buffer we are changing to is not this buffer\n                    && id != doc.id\n                    // Ensure the buffer is not displayed in any other splits.\n                    && !self\n                        .tree\n                        .traverse()\n                        .any(|(_, v)| v.doc == doc.id && v.id != view.id);\n\n                let (view, doc) = current!(self);\n                let view_id = view.id;\n\n                // Append any outstanding changes to history in the old document.\n                doc.append_changes_to_history(view);\n\n                if remove_empty_scratch {\n                    // Copy `doc.id` into a variable before calling `self.documents.remove`, which requires a mutable\n                    // borrow, invalidating direct access to `doc.id`.\n                    let id = doc.id;\n                    self.documents.remove(&id);\n\n                    // Remove the scratch buffer from any jumplists\n                    for (view, _) in self.tree.views_mut() {\n                        view.remove_document(&id);\n                    }\n                } else {\n                    let jump = (view.doc, doc.selection(view.id).clone());\n                    view.jumps.push(jump);\n                    // Set last accessed doc if it is a different document\n                    if doc.id != id {\n                        view.add_to_history(view.doc);\n                        // Set last modified doc if modified and last modified doc is different\n                        if std::mem::take(&mut doc.modified_since_accessed)\n                            && view.last_modified_docs[0] != Some(view.doc)\n                        {\n                            view.last_modified_docs = [Some(view.doc), view.last_modified_docs[0]];\n                        }\n                    }\n                }\n\n                self.replace_document_in_view(view_id, id);\n\n                dispatch(DocumentFocusLost {\n                    editor: self,\n                    doc: id,\n                });\n                return;\n            }\n            Action::Load => {\n                let view_id = view!(self).id;\n                let doc = doc_mut!(self, &id);\n                doc.ensure_view_init(view_id);\n                doc.mark_as_focused();\n                return;\n            }\n            Action::HorizontalSplit | Action::VerticalSplit => {\n                let focus_lost = self.tree.try_get(self.tree.focus).map(|view| view.doc);\n                // copy the current view, unless there is no view yet\n                let view = self\n                    .tree\n                    .try_get(self.tree.focus)\n                    .filter(|v| id == v.doc) // Different Document\n                    .cloned()\n                    .unwrap_or_else(|| View::new(id, self.config().gutters.clone()));\n                let view_id = self.tree.split(\n                    view,\n                    match action {\n                        Action::HorizontalSplit => Layout::Horizontal,\n                        Action::VerticalSplit => Layout::Vertical,\n                        _ => unreachable!(),\n                    },\n                );\n                // initialize selection for view\n                let doc = doc_mut!(self, &id);\n                doc.ensure_view_init(view_id);\n                doc.mark_as_focused();\n                focus_lost\n            }\n        };\n\n        self._refresh();\n        if let Some(focus_lost) = focust_lost {\n            dispatch(DocumentFocusLost {\n                editor: self,\n                doc: focus_lost,\n            });\n        }\n    }\n\n    /// Generate an id for a new document and register it.\n    fn new_document(&mut self, mut doc: Document) -> DocumentId {\n        let id = self.next_document_id;\n        // Safety: adding 1 from 1 is fine, practically impossible to reach usize max\n        self.next_document_id =\n            DocumentId(unsafe { NonZeroUsize::new_unchecked(self.next_document_id.0.get() + 1) });\n        doc.id = id;\n        self.documents.insert(id, doc);\n\n        let (save_sender, save_receiver) = tokio::sync::mpsc::unbounded_channel();\n        self.saves.insert(id, save_sender);\n\n        let stream = UnboundedReceiverStream::new(save_receiver).flatten();\n        self.save_queue.push(stream);\n\n        id\n    }\n\n    fn new_file_from_document(&mut self, action: Action, doc: Document) -> DocumentId {\n        let id = self.new_document(doc);\n        self.switch(id, action);\n        id\n    }\n\n    pub fn new_file(&mut self, action: Action) -> DocumentId {\n        self.new_file_from_document(\n            action,\n            Document::default(self.config.clone(), self.syn_loader.clone()),\n        )\n    }\n\n    pub fn new_file_from_stdin(&mut self, action: Action) -> Result<DocumentId, Error> {\n        let (stdin, encoding, has_bom) = crate::document::read_to_string(&mut stdin(), None)?;\n        let doc = Document::from(\n            helix_core::Rope::default(),\n            Some((encoding, has_bom)),\n            self.config.clone(),\n            self.syn_loader.clone(),\n        );\n        let doc_id = self.new_file_from_document(action, doc);\n        let doc = doc_mut!(self, &doc_id);\n        let view = view_mut!(self);\n        doc.ensure_view_init(view.id);\n        let transaction =\n            helix_core::Transaction::insert(doc.text(), doc.selection(view.id), stdin.into())\n                .with_selection(Selection::point(0));\n        doc.apply(&transaction, view.id);\n        doc.append_changes_to_history(view);\n        Ok(doc_id)\n    }\n\n    pub fn document_id_by_path(&self, path: &Path) -> Option<DocumentId> {\n        self.document_by_path(path).map(|doc| doc.id)\n    }\n\n    // ??? possible use for integration tests\n    pub fn open(&mut self, path: &Path, action: Action) -> Result<DocumentId, DocumentOpenError> {\n        let path = helix_stdx::path::canonicalize(path);\n        let id = self.document_id_by_path(&path);\n\n        let id = if let Some(id) = id {\n            id\n        } else {\n            let mut doc = Document::open(\n                &path,\n                None,\n                true,\n                self.config.clone(),\n                self.syn_loader.clone(),\n            )?;\n\n            let diagnostics =\n                Editor::doc_diagnostics(&self.language_servers, &self.diagnostics, &doc);\n            doc.replace_diagnostics(diagnostics, &[], None);\n\n            if let Some(diff_base) = self.diff_providers.get_diff_base(&path) {\n                doc.set_diff_base(diff_base);\n            }\n            doc.set_version_control_head(self.diff_providers.get_current_head_name(&path));\n\n            let id = self.new_document(doc);\n            self.launch_language_servers(id);\n\n            helix_event::dispatch(DocumentDidOpen {\n                editor: self,\n                doc: id,\n            });\n\n            id\n        };\n\n        self.switch(id, action);\n\n        Ok(id)\n    }\n\n    pub fn close(&mut self, id: ViewId) {\n        // Remove selections for the closed view on all documents.\n        for doc in self.documents_mut() {\n            doc.remove_view(id);\n        }\n        self.tree.remove(id);\n        self._refresh();\n    }\n\n    pub fn close_document(&mut self, doc_id: DocumentId, force: bool) -> Result<(), CloseError> {\n        let doc = match self.documents.get(&doc_id) {\n            Some(doc) => doc,\n            None => return Err(CloseError::DoesNotExist),\n        };\n        if !force && doc.is_modified() {\n            return Err(CloseError::BufferModified(doc.display_name().into_owned()));\n        }\n\n        // This will also disallow any follow-up writes\n        self.saves.remove(&doc_id);\n\n        enum Action {\n            Close(ViewId),\n            ReplaceDoc(ViewId, DocumentId),\n        }\n\n        let actions: Vec<Action> = self\n            .tree\n            .views_mut()\n            .filter_map(|(view, _focus)| {\n                view.remove_document(&doc_id);\n\n                if view.doc == doc_id {\n                    // something was previously open in the view, switch to previous doc\n                    if let Some(prev_doc) = view.docs_access_history.pop() {\n                        Some(Action::ReplaceDoc(view.id, prev_doc))\n                    } else {\n                        // only the document that is being closed was in the view, close it\n                        Some(Action::Close(view.id))\n                    }\n                } else {\n                    None\n                }\n            })\n            .collect();\n\n        for action in actions {\n            match action {\n                Action::Close(view_id) => {\n                    self.close(view_id);\n                }\n                Action::ReplaceDoc(view_id, doc_id) => {\n                    self.replace_document_in_view(view_id, doc_id);\n                }\n            }\n        }\n\n        let doc = self.documents.remove(&doc_id).unwrap();\n\n        // If the document we removed was visible in all views, we will have no more views. We don't\n        // want to close the editor just for a simple buffer close, so we need to create a new view\n        // containing either an existing document, or a brand new document.\n        if self.tree.views().next().is_none() {\n            let doc_id = self\n                .documents\n                .iter()\n                .map(|(&doc_id, _)| doc_id)\n                .next()\n                .unwrap_or_else(|| {\n                    self.new_document(Document::default(\n                        self.config.clone(),\n                        self.syn_loader.clone(),\n                    ))\n                });\n            let view = View::new(doc_id, self.config().gutters.clone());\n            let view_id = self.tree.insert(view);\n            let doc = doc_mut!(self, &doc_id);\n            doc.ensure_view_init(view_id);\n            doc.mark_as_focused();\n        }\n\n        self._refresh();\n\n        helix_event::dispatch(DocumentDidClose { editor: self, doc });\n\n        Ok(())\n    }\n\n    pub fn save<P: Into<PathBuf>>(\n        &mut self,\n        doc_id: DocumentId,\n        path: Option<P>,\n        force: bool,\n    ) -> anyhow::Result<()> {\n        // convert a channel of futures to pipe into main queue one by one\n        // via stream.then() ? then push into main future\n\n        let path = path.map(|path| path.into());\n        let doc = doc_mut!(self, &doc_id);\n        let doc_save_future = doc.save(path, force)?;\n\n        // When a file is written to, notify the file event handler.\n        // Note: This can be removed once proper file watching is implemented.\n        let handler = self.language_servers.file_event_handler.clone();\n        let future = async move {\n            let res = doc_save_future.await;\n            if let Ok(event) = &res {\n                handler.file_changed(event.path.clone());\n            }\n            res\n        };\n\n        use futures_util::stream;\n\n        self.saves\n            .get(&doc_id)\n            .ok_or_else(|| anyhow::format_err!(\"saves are closed for this document!\"))?\n            .send(stream::once(Box::pin(future)))\n            .map_err(|err| anyhow!(\"failed to send save event: {}\", err))?;\n\n        self.write_count += 1;\n\n        Ok(())\n    }\n\n    pub fn resize(&mut self, area: Rect) {\n        if self.tree.resize(area) {\n            self._refresh();\n        };\n    }\n\n    pub fn focus(&mut self, view_id: ViewId) {\n        if self.tree.focus == view_id {\n            return;\n        }\n\n        // Reset mode to normal and ensure any pending changes are committed in the old document.\n        self.enter_normal_mode();\n        let (view, doc) = current!(self);\n        doc.append_changes_to_history(view);\n        self.ensure_cursor_in_view(view_id);\n        // Update jumplist selections with new document changes.\n        for (view, _focused) in self.tree.views_mut() {\n            let doc = doc_mut!(self, &view.doc);\n            view.sync_changes(doc);\n        }\n\n        let prev_id = std::mem::replace(&mut self.tree.focus, view_id);\n        doc_mut!(self).mark_as_focused();\n\n        let focus_lost = self.tree.get(prev_id).doc;\n        dispatch(DocumentFocusLost {\n            editor: self,\n            doc: focus_lost,\n        });\n    }\n\n    pub fn focus_next(&mut self) {\n        self.focus(self.tree.next());\n    }\n\n    pub fn focus_prev(&mut self) {\n        self.focus(self.tree.prev());\n    }\n\n    pub fn focus_direction(&mut self, direction: tree::Direction) {\n        let current_view = self.tree.focus;\n        if let Some(id) = self.tree.find_split_in_direction(current_view, direction) {\n            self.focus(id)\n        }\n    }\n\n    pub fn swap_split_in_direction(&mut self, direction: tree::Direction) {\n        self.tree.swap_split_in_direction(direction);\n    }\n\n    pub fn transpose_view(&mut self) {\n        self.tree.transpose();\n    }\n\n    pub fn should_close(&self) -> bool {\n        self.tree.is_empty()\n    }\n\n    pub fn ensure_cursor_in_view(&mut self, id: ViewId) {\n        let config = self.config();\n        let view = self.tree.get(id);\n        let doc = doc_mut!(self, &view.doc);\n        view.ensure_cursor_in_view(doc, config.scrolloff)\n    }\n\n    #[inline]\n    pub fn document(&self, id: DocumentId) -> Option<&Document> {\n        self.documents.get(&id)\n    }\n\n    #[inline]\n    pub fn document_mut(&mut self, id: DocumentId) -> Option<&mut Document> {\n        self.documents.get_mut(&id)\n    }\n\n    #[inline]\n    pub fn documents(&self) -> impl Iterator<Item = &Document> {\n        self.documents.values()\n    }\n\n    #[inline]\n    pub fn documents_mut(&mut self) -> impl Iterator<Item = &mut Document> {\n        self.documents.values_mut()\n    }\n\n    pub fn document_by_path<P: AsRef<Path>>(&self, path: P) -> Option<&Document> {\n        self.documents()\n            .find(|doc| doc.path().map(|p| p == path.as_ref()).unwrap_or(false))\n    }\n\n    pub fn document_by_path_mut<P: AsRef<Path>>(&mut self, path: P) -> Option<&mut Document> {\n        self.documents_mut()\n            .find(|doc| doc.path().map(|p| p == path.as_ref()).unwrap_or(false))\n    }\n\n    /// Returns all supported diagnostics for the document\n    pub fn doc_diagnostics<'a>(\n        language_servers: &'a helix_lsp::Registry,\n        diagnostics: &'a Diagnostics,\n        document: &Document,\n    ) -> impl Iterator<Item = helix_core::Diagnostic> + 'a {\n        Editor::doc_diagnostics_with_filter(language_servers, diagnostics, document, |_, _| true)\n    }\n\n    /// Returns all supported diagnostics for the document\n    /// filtered by `filter` which is invocated with the raw `lsp::Diagnostic` and the language server id it came from\n    pub fn doc_diagnostics_with_filter<'a>(\n        language_servers: &'a helix_lsp::Registry,\n        diagnostics: &'a Diagnostics,\n        document: &Document,\n        filter: impl Fn(&lsp::Diagnostic, &DiagnosticProvider) -> bool + 'a,\n    ) -> impl Iterator<Item = helix_core::Diagnostic> + 'a {\n        let text = document.text().clone();\n        let language_config = document.language.clone();\n        document\n            .uri()\n            .and_then(|uri| diagnostics.get(&uri))\n            .map(|diags| {\n                diags.iter().filter_map(move |(diagnostic, provider)| {\n                    let server_id = provider.language_server_id()?;\n                    let ls = language_servers.get_by_id(server_id)?;\n                    language_config\n                        .as_ref()\n                        .and_then(|c| {\n                            c.language_servers.iter().find(|features| {\n                                features.name == ls.name()\n                                    && features.has_feature(LanguageServerFeature::Diagnostics)\n                            })\n                        })\n                        .and_then(|_| {\n                            if filter(diagnostic, provider) {\n                                Document::lsp_diagnostic_to_diagnostic(\n                                    &text,\n                                    language_config.as_deref(),\n                                    diagnostic,\n                                    provider.clone(),\n                                    ls.offset_encoding(),\n                                )\n                            } else {\n                                None\n                            }\n                        })\n                })\n            })\n            .into_iter()\n            .flatten()\n    }\n\n    /// Gets the primary cursor position in screen coordinates,\n    /// or `None` if the primary cursor is not visible on screen.\n    pub fn cursor(&self) -> (Option<Position>, CursorKind) {\n        let config = self.config();\n        let (view, doc) = current_ref!(self);\n        if let Some(mut pos) = self.cursor_cache.get(view, doc) {\n            let inner = view.inner_area(doc);\n            pos.col += inner.x as usize;\n            pos.row += inner.y as usize;\n            let cursorkind = config.cursor_shape.from_mode(self.mode);\n            (Some(pos), cursorkind)\n        } else {\n            (None, CursorKind::default())\n        }\n    }\n\n    /// Closes language servers with timeout. The default timeout is 10000 ms, use\n    /// `timeout` parameter to override this.\n    pub async fn close_language_servers(\n        &self,\n        timeout: Option<u64>,\n    ) -> Result<(), tokio::time::error::Elapsed> {\n        // Remove all language servers from the file event handler.\n        // Note: this is non-blocking.\n        for client in self.language_servers.iter_clients() {\n            self.language_servers\n                .file_event_handler\n                .remove_client(client.id());\n        }\n\n        tokio::time::timeout(\n            Duration::from_millis(timeout.unwrap_or(3000)),\n            future::join_all(\n                self.language_servers\n                    .iter_clients()\n                    .map(|client| client.force_shutdown()),\n            ),\n        )\n        .await\n        .map(|_| ())\n    }\n\n    pub async fn wait_event(&mut self) -> EditorEvent {\n        // the loop only runs once or twice and would be better implemented with a recursion + const generic\n        // however due to limitations with async functions that can not be implemented right now\n        loop {\n            tokio::select! {\n                biased;\n\n                Some(event) = self.save_queue.next() => {\n                    self.write_count -= 1;\n                    return EditorEvent::DocumentSaved(event)\n                }\n                Some(config_event) = self.config_events.1.recv() => {\n                    return EditorEvent::ConfigEvent(config_event)\n                }\n                Some(message) = self.language_servers.incoming.next() => {\n                    return EditorEvent::LanguageServerMessage(message)\n                }\n                Some(event) = self.debug_adapters.incoming.next() => {\n                    return EditorEvent::DebuggerEvent(event)\n                }\n\n                _ = helix_event::redraw_requested() => {\n                    if  !self.needs_redraw{\n                        self.needs_redraw = true;\n                        let timeout = Instant::now() + Duration::from_millis(33);\n                        if timeout < self.idle_timer.deadline() && timeout < self.redraw_timer.deadline(){\n                            self.redraw_timer.as_mut().reset(timeout)\n                        }\n                    }\n                }\n\n                _ = &mut self.redraw_timer  => {\n                    self.redraw_timer.as_mut().reset(Instant::now() + Duration::from_secs(86400 * 365 * 30));\n                    return EditorEvent::Redraw\n                }\n                _ = &mut self.idle_timer  => {\n                    return EditorEvent::IdleTimer\n                }\n            }\n        }\n    }\n\n    pub async fn flush_writes(&mut self) -> anyhow::Result<()> {\n        while self.write_count > 0 {\n            if let Some(save_event) = self.save_queue.next().await {\n                self.write_count -= 1;\n\n                let save_event = match save_event {\n                    Ok(event) => event,\n                    Err(err) => {\n                        self.set_error(err.to_string());\n                        bail!(err);\n                    }\n                };\n\n                let doc = doc_mut!(self, &save_event.doc_id);\n                doc.set_last_saved_revision(save_event.revision, save_event.save_time);\n            }\n        }\n\n        Ok(())\n    }\n\n    /// Switches the editor into normal mode.\n    pub fn enter_normal_mode(&mut self) {\n        use helix_core::graphemes;\n\n        if self.mode == Mode::Normal {\n            return;\n        }\n\n        self.mode = Mode::Normal;\n        let (view, doc) = current!(self);\n\n        try_restore_indent(doc, view);\n\n        // if leaving append mode, move cursor back by 1\n        if doc.restore_cursor {\n            let text = doc.text().slice(..);\n            let selection = doc.selection(view.id).clone().transform(|range| {\n                let mut head = range.to();\n                if range.head > range.anchor {\n                    head = graphemes::prev_grapheme_boundary(text, head);\n                }\n\n                Range::new(range.from(), head)\n            });\n\n            doc.set_selection(view.id, selection);\n            doc.restore_cursor = false;\n        }\n    }\n\n    pub fn current_stack_frame(&self) -> Option<&dap::StackFrame> {\n        self.debug_adapters.current_stack_frame()\n    }\n\n    /// Returns the id of a view that this doc contains a selection for,\n    /// making sure it is synced with the current changes\n    /// if possible or there are no selections returns current_view\n    /// otherwise uses an arbitrary view\n    pub fn get_synced_view_id(&mut self, id: DocumentId) -> ViewId {\n        let current_view = view_mut!(self);\n        let doc = self.documents.get_mut(&id).unwrap();\n        if doc.selections().contains_key(&current_view.id) {\n            // only need to sync current view if this is not the current doc\n            if current_view.doc != id {\n                current_view.sync_changes(doc);\n            }\n            current_view.id\n        } else if let Some(view_id) = doc.selections().keys().next() {\n            let view_id = *view_id;\n            let view = self.tree.get_mut(view_id);\n            view.sync_changes(doc);\n            view_id\n        } else {\n            doc.ensure_view_init(current_view.id);\n            current_view.id\n        }\n    }\n\n    pub fn set_cwd(&mut self, path: &Path) -> std::io::Result<()> {\n        self.last_cwd = helix_stdx::env::set_current_working_dir(path)?;\n        self.clear_doc_relative_paths();\n        Ok(())\n    }\n\n    pub fn get_last_cwd(&mut self) -> Option<&Path> {\n        self.last_cwd.as_deref()\n    }\n\n    pub fn jump_forward(&mut self, view_id: ViewId, count: usize) {\n        if let Some((doc_id, selection)) = view_mut!(self, view_id).jumps.forward(count).cloned() {\n            self.jump_to(view_id, doc_id, selection);\n        }\n    }\n\n    pub fn jump_backward(&mut self, view_id: ViewId, count: usize) {\n        let view = view_mut!(self, view_id);\n        if let Some((doc_id, selection)) = view\n            .jumps\n            .backward(view_id, doc_mut!(self, &view.doc), count)\n            .cloned()\n        {\n            self.jump_to(view_id, doc_id, selection);\n        }\n    }\n\n    fn jump_to(&mut self, view_id: ViewId, dest_doc_id: DocumentId, mut selection: Selection) {\n        let view = view_mut!(self, view_id);\n        let old_doc_id = view.doc;\n        if old_doc_id != dest_doc_id {\n            let new_doc = doc_mut!(self, &dest_doc_id);\n            if let Some(transaction) = view.changes_to_sync(new_doc) {\n                let text = new_doc.text().slice(..);\n                selection = selection.map(transaction.changes()).ensure_invariants(text);\n            }\n            self.replace_document_in_view(view_id, dest_doc_id);\n            dispatch(DocumentFocusLost {\n                editor: self,\n                doc: old_doc_id,\n            });\n        }\n        let (view, doc) = current!(self);\n        doc.set_selection(view_id, selection);\n        view.ensure_cursor_in_view_center(doc, self.config.load().scrolloff);\n    }\n}\n\nfn try_restore_indent(doc: &mut Document, view: &mut View) {\n    use helix_core::{\n        chars::char_is_whitespace,\n        line_ending::{line_end_char_index, str_is_line_ending},\n        unicode::segmentation::UnicodeSegmentation,\n        Operation, Transaction,\n    };\n\n    fn inserted_a_new_blank_line(changes: &[Operation], pos: usize, line_end_pos: usize) -> bool {\n        if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] =\n            changes\n        {\n            let mut graphemes = inserted_str.graphemes(true);\n            move_pos + inserted_str.len() == pos\n                && graphemes.next().is_some_and(str_is_line_ending)\n                && graphemes.all(|g| g.chars().all(char_is_whitespace))\n                && pos == line_end_pos // ensure no characters exists after current position\n        } else {\n            false\n        }\n    }\n\n    let doc_changes = doc.changes().changes();\n    let text = doc.text().slice(..);\n    let range = doc.selection(view.id).primary();\n    let pos = range.cursor(text);\n    let line_end_pos = line_end_char_index(&text, range.cursor_line(text));\n\n    if inserted_a_new_blank_line(doc_changes, pos, line_end_pos) {\n        // Removes tailing whitespaces for the primary selection only, preserving existing behavior\n        let line_start_pos = text.line_to_char(range.cursor_line(text));\n        let transaction =\n            Transaction::change(doc.text(), [(line_start_pos, pos, None)].into_iter());\n        doc.apply(&transaction, view.id);\n    }\n}\n\n#[derive(Default)]\npub struct CursorCache(Cell<Option<Option<Position>>>);\n\nimpl CursorCache {\n    pub fn get(&self, view: &View, doc: &Document) -> Option<Position> {\n        if let Some(pos) = self.0.get() {\n            return pos;\n        }\n\n        let text = doc.text().slice(..);\n        let cursor = doc.selection(view.id).primary().cursor(text);\n        let res = view.screen_coords_at_pos(doc, text, cursor);\n        self.set(res);\n        res\n    }\n\n    pub fn set(&self, cursor_pos: Option<Position>) {\n        self.0.set(Some(cursor_pos))\n    }\n\n    pub fn reset(&self) {\n        self.0.set(None)\n    }\n}\n"
  },
  {
    "path": "helix-view/src/events.rs",
    "content": "use helix_core::{ChangeSet, Rope};\nuse helix_event::events;\nuse helix_lsp::LanguageServerId;\n\nuse crate::{editor::Config, Document, DocumentId, Editor, ViewId};\n\nevents! {\n    DocumentDidOpen<'a> {\n        editor: &'a mut Editor,\n        doc: DocumentId\n    }\n    DocumentDidChange<'a> {\n        doc: &'a mut Document,\n        view: ViewId,\n        old_text: &'a Rope,\n        changes: &'a ChangeSet,\n        ghost_transaction: bool\n    }\n    DocumentDidClose<'a> {\n        editor: &'a mut Editor,\n        doc: Document\n    }\n    SelectionDidChange<'a> { doc: &'a mut Document, view: ViewId }\n    DiagnosticsDidChange<'a> { editor: &'a mut Editor, doc: DocumentId }\n    // called **after** a document loses focus (but not when its closed)\n    DocumentFocusLost<'a> { editor: &'a mut Editor, doc: DocumentId }\n\n    LanguageServerInitialized<'a> {\n        editor: &'a mut Editor,\n        server_id: LanguageServerId\n    }\n    LanguageServerExited<'a> {\n        editor: &'a mut Editor,\n        server_id: LanguageServerId\n    }\n\n    // NOTE: this event is simple for now and is expected to change as the config system evolves.\n    // Ideally it would say what changed.\n    ConfigDidChange<'a> {\n        editor: &'a mut Editor,\n        old: &'a Config,\n        new: &'a Config\n    }\n}\n"
  },
  {
    "path": "helix-view/src/expansion.rs",
    "content": "use std::borrow::Cow;\n\nuse helix_core::command_line::{ExpansionKind, Token, TokenKind, Tokenizer};\n\nuse anyhow::{anyhow, bail, Result};\n\nuse crate::Editor;\n\n/// Variables that can be expanded in the command mode (`:`) via the expansion syntax.\n///\n/// For example `%{cursor_line}`.\n//\n// To add a new variable follow these steps:\n//\n// * Add the new enum member to `Variable` below.\n// * Add an item to the `VARIANTS` constant - this enables completion.\n// * Add a branch in `Variable::as_str`, converting the name from TitleCase to snake_case.\n// * Add a branch in `Variable::from_name` with the reverse association.\n// * Add a branch in the `expand_variable` function to read the value from the editor.\n// * Add the new variable to the documentation in `book/src/command-line.md`.\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum Variable {\n    /// The one-indexed line number of the primary cursor in the currently focused document.\n    CursorLine,\n    /// The one-indexed column number of the primary cursor in the currently focused document.\n    ///\n    /// Note that this is the count of grapheme clusters from the start of the line (regardless of\n    /// softwrap) - the same as the `position` element in the statusline.\n    CursorColumn,\n    /// The display name of the currently focused document.\n    ///\n    /// This corresponds to `crate::Document::display_name`.\n    BufferName,\n    /// The absolute path of the currently focused document. For scratch buffers this will default\n    /// to the current working directory.\n    FilePathAbsolute,\n    /// A string containing the line-ending of the currently focused document.\n    LineEnding,\n    /// Curreng working directory\n    CurrentWorkingDirectory,\n    /// Nearest ancestor directory of the current working directory that contains `.git`, `.svn`, `jj` or `.helix`\n    WorkspaceDirectory,\n    // The name of current buffers language as set in `languages.toml`\n    Language,\n    // Primary selection\n    Selection,\n    // The one-indexed line number of the start of the primary selection in the currently focused document.\n    SelectionLineStart,\n    // The one-indexed line number of the end of the primary selection in the currently focused document.\n    SelectionLineEnd,\n}\n\nimpl Variable {\n    pub const VARIANTS: &'static [Self] = &[\n        Self::CursorLine,\n        Self::CursorColumn,\n        Self::BufferName,\n        Self::FilePathAbsolute,\n        Self::LineEnding,\n        Self::CurrentWorkingDirectory,\n        Self::WorkspaceDirectory,\n        Self::Language,\n        Self::Selection,\n        Self::SelectionLineStart,\n        Self::SelectionLineEnd,\n    ];\n\n    pub const fn as_str(&self) -> &'static str {\n        match self {\n            Self::CursorLine => \"cursor_line\",\n            Self::CursorColumn => \"cursor_column\",\n            Self::BufferName => \"buffer_name\",\n            Self::FilePathAbsolute => \"file_path_absolute\",\n            Self::LineEnding => \"line_ending\",\n            Self::CurrentWorkingDirectory => \"current_working_directory\",\n            Self::WorkspaceDirectory => \"workspace_directory\",\n            Self::Language => \"language\",\n            Self::Selection => \"selection\",\n            Self::SelectionLineStart => \"selection_line_start\",\n            Self::SelectionLineEnd => \"selection_line_end\",\n        }\n    }\n\n    pub fn from_name(s: &str) -> Option<Self> {\n        match s {\n            \"cursor_line\" => Some(Self::CursorLine),\n            \"cursor_column\" => Some(Self::CursorColumn),\n            \"buffer_name\" => Some(Self::BufferName),\n            \"file_path_absolute\" => Some(Self::FilePathAbsolute),\n            \"line_ending\" => Some(Self::LineEnding),\n            \"workspace_directory\" => Some(Self::WorkspaceDirectory),\n            \"current_working_directory\" => Some(Self::CurrentWorkingDirectory),\n            \"language\" => Some(Self::Language),\n            \"selection\" => Some(Self::Selection),\n            \"selection_line_start\" => Some(Self::SelectionLineStart),\n            \"selection_line_end\" => Some(Self::SelectionLineEnd),\n            _ => None,\n        }\n    }\n}\n\n/// Expands the given command line token.\n///\n/// Note that the lifetime of the expanded variable is only bound to the input token and not the\n/// `Editor`. See `expand_variable` below for more discussion of lifetimes.\npub fn expand<'a>(editor: &Editor, token: Token<'a>) -> Result<Cow<'a, str>> {\n    // Note: see the `TokenKind` documentation for more details on how each branch should expand.\n    match token.kind {\n        TokenKind::Unquoted | TokenKind::Quoted(_) => Ok(token.content),\n        TokenKind::Expansion(ExpansionKind::Variable) => {\n            let var = Variable::from_name(&token.content)\n                .ok_or_else(|| anyhow!(\"unknown variable '{}'\", token.content))?;\n\n            expand_variable(editor, var)\n        }\n        TokenKind::Expansion(ExpansionKind::Unicode) => {\n            if let Some(ch) = u32::from_str_radix(token.content.as_ref(), 16)\n                .ok()\n                .and_then(char::from_u32)\n            {\n                Ok(Cow::Owned(ch.to_string()))\n            } else {\n                Err(anyhow!(\n                    \"could not interpret '{}' as a Unicode character code\",\n                    token.content\n                ))\n            }\n        }\n        TokenKind::Expand => expand_inner(editor, token.content),\n        TokenKind::Expansion(ExpansionKind::Shell) => expand_shell(editor, token.content),\n        // Note: see the docs for this variant.\n        TokenKind::ExpansionKind => unreachable!(\n            \"expansion name tokens cannot be emitted when command line validation is enabled\"\n        ),\n    }\n}\n\n/// Expand a shell command.\npub fn expand_shell<'a>(editor: &Editor, content: Cow<'a, str>) -> Result<Cow<'a, str>> {\n    use std::process::{Command, Stdio};\n\n    // Recursively expand the expansion's content before executing the shell command.\n    let content = expand_inner(editor, content)?;\n\n    let config = editor.config();\n    let shell = &config.shell;\n    let mut process = Command::new(&shell[0]);\n    process\n        .args(&shell[1..])\n        .arg(content.as_ref())\n        .stdin(Stdio::null())\n        .stdout(Stdio::piped())\n        .stderr(Stdio::piped());\n\n    // TODO: there is no protection here against a shell command taking a long time.\n    // Ideally you should be able to hit `<ret>` in command mode and then be able to\n    // cancel the invocation (for example with `<C-c>`) if it takes longer than you'd\n    // like.\n    let output = match process.spawn() {\n        Ok(process) => process.wait_with_output()?,\n        Err(err) => {\n            bail!(\"Failed to start shell: {err}\");\n        }\n    };\n\n    let mut text = String::from_utf8_lossy(&output.stdout).into_owned();\n\n    if !output.stderr.is_empty() {\n        log::warn!(\n            \"Shell expansion command `{content}` failed: {}\",\n            String::from_utf8_lossy(&output.stderr)\n        );\n    }\n\n    // Trim exactly one trailing line ending if it exists.\n    if text.ends_with('\\n') {\n        text.pop();\n        if text.ends_with('\\r') {\n            text.pop();\n        }\n    }\n\n    Ok(Cow::Owned(text))\n}\n\n/// Expand a token's contents recursively.\nfn expand_inner<'a>(editor: &Editor, content: Cow<'a, str>) -> Result<Cow<'a, str>> {\n    let mut escaped = String::new();\n    let mut start = 0;\n\n    while let Some(offset) = content[start..].find('%') {\n        let idx = start + offset;\n        if content.as_bytes().get(idx + '%'.len_utf8()).copied() == Some(b'%') {\n            // Treat two percents in a row as an escaped percent.\n            escaped.push_str(&content[start..=idx]);\n            // Skip over both percents.\n            start = idx + ('%'.len_utf8() * 2);\n        } else {\n            // Otherwise interpret the percent as an expansion. Push up to (but not\n            // including) the percent token.\n            escaped.push_str(&content[start..idx]);\n            // Then parse the expansion,\n            let mut tokenizer = Tokenizer::new(&content[idx..], true);\n            let token = tokenizer\n                .parse_percent_token()\n                .unwrap()\n                .map_err(|err| anyhow!(\"{err}\"))?;\n            // expand it (this is the recursive part),\n            let expanded = expand(editor, token)?;\n            escaped.push_str(expanded.as_ref());\n            // and move forward to the end of the expansion.\n            start = idx + tokenizer.pos();\n        }\n    }\n\n    if escaped.is_empty() {\n        Ok(content)\n    } else {\n        escaped.push_str(&content[start..]);\n        Ok(Cow::Owned(escaped))\n    }\n}\n\n// Note: the lifetime of the expanded variable (the `Cow`) must not be tied to the lifetime of\n// the borrow of `Editor`. That would prevent commands from mutating the `Editor` until the\n// command consumed or cloned all arguments - this is poor ergonomics. A sensible thing for this\n// function to return then, instead, would normally be a `String`. We can return some statically\n// known strings like the scratch buffer name or line ending strings though, so this function\n// returns a `Cow<'static, str>` instead.\nfn expand_variable(editor: &Editor, variable: Variable) -> Result<Cow<'static, str>> {\n    let (view, doc) = current_ref!(editor);\n    let text = doc.text().slice(..);\n\n    match variable {\n        Variable::CursorLine => {\n            let cursor_line = doc.selection(view.id).primary().cursor_line(text);\n            Ok(Cow::Owned((cursor_line + 1).to_string()))\n        }\n        Variable::CursorColumn => {\n            let cursor = doc.selection(view.id).primary().cursor(text);\n            let position = helix_core::coords_at_pos(text, cursor);\n            Ok(Cow::Owned((position.col + 1).to_string()))\n        }\n        Variable::BufferName => {\n            // Note: usually we would use `Document::display_name` but we can statically borrow\n            // the scratch buffer name by partially reimplementing `display_name`.\n            if let Some(path) = doc.relative_path() {\n                Ok(Cow::Owned(path.to_string_lossy().into_owned()))\n            } else {\n                Ok(Cow::Borrowed(crate::document::SCRATCH_BUFFER_NAME))\n            }\n        }\n        Variable::FilePathAbsolute => {\n            let path = match doc.path() {\n                Some(path) => path.to_owned(),\n                None => helix_stdx::env::current_working_dir(),\n            }\n            .to_string_lossy()\n            .to_string();\n            Ok(Cow::Owned(path))\n        }\n        Variable::LineEnding => Ok(Cow::Borrowed(doc.line_ending.as_str())),\n        Variable::CurrentWorkingDirectory => Ok(std::borrow::Cow::Owned(\n            helix_stdx::env::current_working_dir()\n                .to_string_lossy()\n                .to_string(),\n        )),\n        Variable::WorkspaceDirectory => Ok(std::borrow::Cow::Owned(\n            helix_loader::find_workspace()\n                .0\n                .to_string_lossy()\n                .to_string(),\n        )),\n        Variable::Language => Ok(match doc.language_name() {\n            Some(lang) => Cow::Owned(lang.to_owned()),\n            None => Cow::Borrowed(\"text\"),\n        }),\n        Variable::Selection => Ok(Cow::Owned(\n            doc.selection(view.id).primary().fragment(text).to_string(),\n        )),\n        Variable::SelectionLineStart => {\n            let start_line = doc.selection(view.id).primary().line_range(text).0;\n            Ok(Cow::Owned((start_line + 1).to_string()))\n        }\n        Variable::SelectionLineEnd => {\n            let end_line = doc.selection(view.id).primary().line_range(text).1;\n            Ok(Cow::Owned((end_line + 1).to_string()))\n        }\n    }\n}\n"
  },
  {
    "path": "helix-view/src/graphics.rs",
    "content": "use bitflags::bitflags;\nuse serde::{Deserialize, Serialize};\nuse std::{\n    cmp::{max, min},\n    fmt,\n    str::FromStr,\n};\n\n#[must_use]\nconst fn from_nibble(h: u8) -> u8 {\n    match h {\n        b'A'..=b'F' => h - b'A' + 10,\n        b'a'..=b'f' => h - b'a' + 10,\n        b'0'..=b'9' => h - b'0',\n        _ => 0xff, // Err\n    }\n}\n\n/// Decodes nibble, repeating its value on each half,\n/// i.e. the value is its own padding.\n///\n/// # Errors\n/// If `h` isn't a nibble\n#[must_use]\nconst fn dupe_from_nibble(mut h: u8) -> Option<u8> {\n    h = from_nibble(h);\n    if h > 0xf {\n        return None;\n    }\n    Some((h << 4) | h)\n}\n\n/// Decodes big-endian nibble-pair.\n///\n/// # Errors\n/// If any byte isn't a nibble\nconst fn byte_from_hex(mut h: [u8; 2]) -> Option<u8> {\n    // reuse memory\n    h[0] = from_nibble(h[0]);\n    h[1] = from_nibble(h[1]);\n    // we could split this in 2 `if`s,\n    // to avoid calling `from_nibble`,\n    // but that might be slower\n    if h[0] > 0xf || h[1] > 0xf {\n        return None;\n    }\n    Some((h[0] << 4) | h[1])\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]\n#[serde(rename_all = \"lowercase\")]\n/// UNSTABLE\n#[derive(Default)]\npub enum CursorKind {\n    /// █\n    #[default]\n    Block,\n    /// |\n    Bar,\n    /// _\n    Underline,\n    /// Hidden cursor, can set cursor position with this to let IME have correct cursor position.\n    Hidden,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct Margin {\n    pub horizontal: u16,\n    pub vertical: u16,\n}\n\nimpl Margin {\n    pub fn none() -> Self {\n        Self {\n            horizontal: 0,\n            vertical: 0,\n        }\n    }\n\n    /// Set uniform margin for all sides.\n    pub const fn all(value: u16) -> Self {\n        Self {\n            horizontal: value,\n            vertical: value,\n        }\n    }\n\n    /// Set the margin of left and right sides to specified value.\n    pub const fn horizontal(value: u16) -> Self {\n        Self {\n            horizontal: value,\n            vertical: 0,\n        }\n    }\n\n    /// Set the margin of top and bottom sides to specified value.\n    pub const fn vertical(value: u16) -> Self {\n        Self {\n            horizontal: 0,\n            vertical: value,\n        }\n    }\n\n    /// Get the total width of the margin (left + right)\n    pub const fn width(&self) -> u16 {\n        self.horizontal * 2\n    }\n\n    /// Get the total height of the margin (top + bottom)\n    pub const fn height(&self) -> u16 {\n        self.vertical * 2\n    }\n}\n\n/// A simple rectangle used in the computation of the layout and to give widgets an hint about the\n/// area they are supposed to render to. (x, y) = (0, 0) is at the top left corner of the screen.\n#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]\npub struct Rect {\n    pub x: u16,\n    pub y: u16,\n    pub width: u16,\n    pub height: u16,\n}\n\nimpl Rect {\n    /// Creates a new rect, with width and height\n    pub fn new(x: u16, y: u16, width: u16, height: u16) -> Rect {\n        Rect {\n            x,\n            y,\n            width,\n            height,\n        }\n    }\n\n    #[inline]\n    pub fn area(self) -> usize {\n        (self.width as usize) * (self.height as usize)\n    }\n\n    #[inline]\n    pub fn left(self) -> u16 {\n        self.x\n    }\n\n    #[inline]\n    pub fn right(self) -> u16 {\n        self.x.saturating_add(self.width)\n    }\n\n    #[inline]\n    pub fn top(self) -> u16 {\n        self.y\n    }\n\n    #[inline]\n    pub fn bottom(self) -> u16 {\n        self.y.saturating_add(self.height)\n    }\n\n    // Returns a new Rect with width reduced from the left side.\n    // This changes the `x` coordinate and clamps it to the right\n    // edge of the original Rect.\n    pub fn clip_left(self, width: u16) -> Rect {\n        let width = std::cmp::min(width, self.width);\n        Rect {\n            x: self.x.saturating_add(width),\n            width: self.width.saturating_sub(width),\n            ..self\n        }\n    }\n\n    // Returns a new Rect with width reduced from the right side.\n    // This does _not_ change the `x` coordinate.\n    pub fn clip_right(self, width: u16) -> Rect {\n        Rect {\n            width: self.width.saturating_sub(width),\n            ..self\n        }\n    }\n\n    // Returns a new Rect with height reduced from the top.\n    // This changes the `y` coordinate and clamps it to the bottom\n    // edge of the original Rect.\n    pub fn clip_top(self, height: u16) -> Rect {\n        let height = std::cmp::min(height, self.height);\n        Rect {\n            y: self.y.saturating_add(height),\n            height: self.height.saturating_sub(height),\n            ..self\n        }\n    }\n\n    // Returns a new Rect with height reduced from the bottom.\n    // This does _not_ change the `y` coordinate.\n    pub fn clip_bottom(self, height: u16) -> Rect {\n        Rect {\n            height: self.height.saturating_sub(height),\n            ..self\n        }\n    }\n\n    pub fn with_height(self, height: u16) -> Rect {\n        // new height may make area > u16::max_value, so use new()\n        Self::new(self.x, self.y, self.width, height)\n    }\n\n    pub fn with_width(self, width: u16) -> Rect {\n        Self::new(self.x, self.y, width, self.height)\n    }\n\n    pub fn inner(self, margin: Margin) -> Rect {\n        if self.width < margin.width() || self.height < margin.height() {\n            Rect::default()\n        } else {\n            Rect {\n                x: self.x + margin.horizontal,\n                y: self.y + margin.vertical,\n                width: self.width - margin.width(),\n                height: self.height - margin.height(),\n            }\n        }\n    }\n\n    /// Calculate the union between two [`Rect`]s.\n    pub fn union(self, other: Rect) -> Rect {\n        // Example:\n        //\n        // If `Rect` A is positioned at `(0, 0)` with a width and height of `5`,\n        // and `Rect` B is positioned at `(5, 0)` with a width and height of `2`,\n        // then this is the resulting union:\n        //\n        // x1 = min(0, 5) => x1 = 0\n        // y1 = min(0, 0) => y1 = 0\n        // x2 = max(0 + 5, 5 + 2) => x2 = 7\n        // y2 = max(0 + 5, 0 + 2) => y2 = 5\n        let x1 = min(self.x, other.x);\n        let y1 = min(self.y, other.y);\n        let x2 = max(self.x + self.width, other.x + other.width);\n        let y2 = max(self.y + self.height, other.y + other.height);\n        Rect {\n            x: x1,\n            y: y1,\n            width: x2 - x1,\n            height: y2 - y1,\n        }\n    }\n\n    /// Calculate the intersection between two [`Rect`]s.\n    pub fn intersection(self, other: Rect) -> Rect {\n        // Example:\n        //\n        // If `Rect` A is positioned at `(0, 0)` with a width and height of `5`,\n        // and `Rect` B is positioned at `(5, 0)` with a width and height of `2`,\n        // then this is the resulting intersection:\n        //\n        // x1 = max(0, 5) => x1 = 5\n        // y1 = max(0, 0) => y1 = 0\n        // x2 = min(0 + 5, 5 + 2) => x2 = 5\n        // y2 = min(0 + 5, 0 + 2) => y2 = 2\n        let x1 = max(self.x, other.x);\n        let y1 = max(self.y, other.y);\n        let x2 = min(self.x + self.width, other.x + other.width);\n        let y2 = min(self.y + self.height, other.y + other.height);\n        Rect {\n            x: x1,\n            y: y1,\n            width: x2.saturating_sub(x1),\n            height: y2.saturating_sub(y1),\n        }\n    }\n\n    pub fn intersects(self, other: Rect) -> bool {\n        self.x < other.x + other.width\n            && self.x + self.width > other.x\n            && self.y < other.y + other.height\n            && self.y + self.height > other.y\n    }\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum Color {\n    Reset,\n    Black,\n    Red,\n    Green,\n    Yellow,\n    Blue,\n    Magenta,\n    Cyan,\n    Gray,\n    LightRed,\n    LightGreen,\n    LightYellow,\n    LightBlue,\n    LightMagenta,\n    LightCyan,\n    LightGray,\n    White,\n    Rgb(u8, u8, u8),\n    Indexed(u8),\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum MalformedHex {\n    NoHash,\n    LenOOB,\n    NotANibble,\n}\nimpl fmt::Display for MalformedHex {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(\n            f,\n            \"Malformed hex color code: {}\",\n            match self {\n                Self::NoHash => \"Missing hash prefix\",\n                Self::LenOOB => \"Must be 12 or 24 bit RGB\",\n                Self::NotANibble => \"One or more chars is not hex digit (nibble)\",\n            }\n        )\n    }\n}\n\nimpl Color {\n    /// Creates a `Color` from a hex string of the form\n    /// \"#RRGGBB\" or \"#RGB\"\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use helix_view::theme::Color;\n    ///\n    /// let color1 = Color::from_hex(\"#c0ffee\").unwrap();\n    /// let color2 = Color::Rgb(192, 255, 238);\n    ///\n    /// assert_eq!(color1, color2);\n    ///\n    /// let color3 = Color::from_hex(\"#012\").unwrap();\n    /// assert_eq!(color3, Color::Rgb(0, 17, 34));\n    /// ```\n    pub fn from_hex(h: &str) -> Result<Self, MalformedHex> {\n        let h = h.as_bytes();\n        if !h.starts_with(b\"#\") {\n            return Err(MalformedHex::NoHash);\n        }\n\n        use byte_from_hex as pair;\n        use dupe_from_nibble as nibble;\n\n        match h.len() {\n            7 => match (|| {\n                Some(Self::Rgb(\n                    pair([h[1], h[2]])?,\n                    pair([h[3], h[4]])?,\n                    pair([h[5], h[6]])?,\n                ))\n            })() {\n                Some(c) => Ok(c),\n                None => Err(MalformedHex::NotANibble),\n            },\n            4 => match (|| Some(Self::Rgb(nibble(h[1])?, nibble(h[2])?, nibble(h[3])?)))() {\n                Some(c) => Ok(c),\n                None => Err(MalformedHex::NotANibble),\n            },\n            _ => Err(MalformedHex::LenOOB),\n        }\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<Color> for termina::style::ColorSpec {\n    fn from(color: Color) -> Self {\n        match color {\n            Color::Reset => Self::Reset,\n            Color::Black => Self::BLACK,\n            Color::Red => Self::RED,\n            Color::Green => Self::GREEN,\n            Color::Yellow => Self::YELLOW,\n            Color::Blue => Self::BLUE,\n            Color::Magenta => Self::MAGENTA,\n            Color::Cyan => Self::CYAN,\n            Color::Gray => Self::BRIGHT_BLACK,\n            Color::White => Self::BRIGHT_WHITE,\n            Color::LightRed => Self::BRIGHT_RED,\n            Color::LightGreen => Self::BRIGHT_GREEN,\n            Color::LightBlue => Self::BRIGHT_BLUE,\n            Color::LightYellow => Self::BRIGHT_YELLOW,\n            Color::LightMagenta => Self::BRIGHT_MAGENTA,\n            Color::LightCyan => Self::BRIGHT_CYAN,\n            Color::LightGray => Self::WHITE,\n            Color::Indexed(i) => Self::PaletteIndex(i),\n            Color::Rgb(r, g, b) => termina::style::RgbColor::new(r, g, b).into(),\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<Color> for crossterm::style::Color {\n    fn from(color: Color) -> Self {\n        use crossterm::style::Color as CColor;\n\n        match color {\n            Color::Reset => CColor::Reset,\n            Color::Black => CColor::Black,\n            Color::Red => CColor::DarkRed,\n            Color::Green => CColor::DarkGreen,\n            Color::Yellow => CColor::DarkYellow,\n            Color::Blue => CColor::DarkBlue,\n            Color::Magenta => CColor::DarkMagenta,\n            Color::Cyan => CColor::DarkCyan,\n            Color::Gray => CColor::DarkGrey,\n            Color::LightRed => CColor::Red,\n            Color::LightGreen => CColor::Green,\n            Color::LightBlue => CColor::Blue,\n            Color::LightYellow => CColor::Yellow,\n            Color::LightMagenta => CColor::Magenta,\n            Color::LightCyan => CColor::Cyan,\n            Color::LightGray => CColor::Grey,\n            Color::White => CColor::White,\n            Color::Indexed(i) => CColor::AnsiValue(i),\n            Color::Rgb(r, g, b) => CColor::Rgb { r, g, b },\n        }\n    }\n}\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum UnderlineStyle {\n    Reset,\n    Line,\n    Curl,\n    Dotted,\n    Dashed,\n    DoubleLine,\n}\n\nimpl FromStr for UnderlineStyle {\n    type Err = &'static str;\n\n    fn from_str(modifier: &str) -> Result<Self, Self::Err> {\n        match modifier {\n            \"line\" => Ok(Self::Line),\n            \"curl\" => Ok(Self::Curl),\n            \"dotted\" => Ok(Self::Dotted),\n            \"dashed\" => Ok(Self::Dashed),\n            \"double_line\" => Ok(Self::DoubleLine),\n            _ => Err(\"Invalid underline style\"),\n        }\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<UnderlineStyle> for termina::style::Underline {\n    fn from(style: UnderlineStyle) -> Self {\n        match style {\n            UnderlineStyle::Reset => Self::None,\n            UnderlineStyle::Line => Self::Single,\n            UnderlineStyle::Curl => Self::Curly,\n            UnderlineStyle::Dotted => Self::Dotted,\n            UnderlineStyle::Dashed => Self::Dashed,\n            UnderlineStyle::DoubleLine => Self::Double,\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<UnderlineStyle> for crossterm::style::Attribute {\n    fn from(style: UnderlineStyle) -> Self {\n        match style {\n            UnderlineStyle::Line => crossterm::style::Attribute::Underlined,\n            UnderlineStyle::Curl => crossterm::style::Attribute::Undercurled,\n            UnderlineStyle::Dotted => crossterm::style::Attribute::Underdotted,\n            UnderlineStyle::Dashed => crossterm::style::Attribute::Underdashed,\n            UnderlineStyle::DoubleLine => crossterm::style::Attribute::DoubleUnderlined,\n            UnderlineStyle::Reset => crossterm::style::Attribute::NoUnderline,\n        }\n    }\n}\n\nbitflags! {\n    /// Modifier changes the way a piece of text is displayed.\n    ///\n    /// They are bitflags so they can easily be composed.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_view::graphics::Modifier;\n    ///\n    /// let m = Modifier::BOLD | Modifier::ITALIC;\n    /// ```\n    #[derive(PartialEq, Eq, Debug, Clone, Copy)]\n    pub struct Modifier: u16 {\n        const BOLD              = 0b0000_0000_0001;\n        const DIM               = 0b0000_0000_0010;\n        const ITALIC            = 0b0000_0000_0100;\n        const SLOW_BLINK        = 0b0000_0001_0000;\n        const RAPID_BLINK       = 0b0000_0010_0000;\n        const REVERSED          = 0b0000_0100_0000;\n        const HIDDEN            = 0b0000_1000_0000;\n        const CROSSED_OUT       = 0b0001_0000_0000;\n    }\n}\n\nimpl FromStr for Modifier {\n    type Err = &'static str;\n\n    fn from_str(modifier: &str) -> Result<Self, Self::Err> {\n        match modifier {\n            \"bold\" => Ok(Self::BOLD),\n            \"dim\" => Ok(Self::DIM),\n            \"italic\" => Ok(Self::ITALIC),\n            \"slow_blink\" => Ok(Self::SLOW_BLINK),\n            \"rapid_blink\" => Ok(Self::RAPID_BLINK),\n            \"reversed\" => Ok(Self::REVERSED),\n            \"hidden\" => Ok(Self::HIDDEN),\n            \"crossed_out\" => Ok(Self::CROSSED_OUT),\n            _ => Err(\"Invalid modifier\"),\n        }\n    }\n}\n\n/// Style let you control the main characteristics of the displayed elements.\n///\n/// ```rust\n/// # use helix_view::graphics::{Color, Modifier, Style};\n/// Style::default()\n///     .fg(Color::Black)\n///     .bg(Color::Green)\n///     .add_modifier(Modifier::ITALIC | Modifier::BOLD);\n/// ```\n///\n/// It represents an incremental change. If you apply the styles S1, S2, S3 to a cell of the\n/// terminal buffer, the style of this cell will be the result of the merge of S1, S2 and S3, not\n/// just S3.\n///\n/// ```rust\n/// # use helix_view::graphics::{Rect, Color, UnderlineStyle, Modifier, Style};\n/// # use helix_tui::buffer::Buffer;\n/// let styles = [\n///     Style::default().fg(Color::Blue).add_modifier(Modifier::BOLD | Modifier::ITALIC),\n///     Style::default().bg(Color::Red),\n///     Style::default().fg(Color::Yellow).remove_modifier(Modifier::ITALIC),\n/// ];\n/// let mut buffer = Buffer::empty(Rect::new(0, 0, 1, 1));\n/// for style in &styles {\n///   buffer[(0, 0)].set_style(*style);\n/// }\n/// assert_eq!(\n///     Style {\n///         fg: Some(Color::Yellow),\n///         bg: Some(Color::Red),\n///         add_modifier: Modifier::BOLD,\n///         underline_color: Some(Color::Reset),\n///         underline_style: Some(UnderlineStyle::Reset),\n///         sub_modifier: Modifier::empty(),\n///     },\n///     buffer[(0, 0)].style(),\n/// );\n/// ```\n///\n/// The default implementation returns a `Style` that does not modify anything. If you wish to\n/// reset all properties until that point use [`Style::reset`].\n///\n/// ```\n/// # use helix_view::graphics::{Rect, Color, UnderlineStyle, Modifier, Style};\n/// # use helix_tui::buffer::Buffer;\n/// let styles = [\n///     Style::default().fg(Color::Blue).add_modifier(Modifier::BOLD | Modifier::ITALIC),\n///     Style::reset().fg(Color::Yellow),\n/// ];\n/// let mut buffer = Buffer::empty(Rect::new(0, 0, 1, 1));\n/// for style in &styles {\n///   buffer[(0, 0)].set_style(*style);\n/// }\n/// assert_eq!(\n///     Style {\n///         fg: Some(Color::Yellow),\n///         bg: Some(Color::Reset),\n///         underline_color: Some(Color::Reset),\n///         underline_style: Some(UnderlineStyle::Reset),\n///         add_modifier: Modifier::empty(),\n///         sub_modifier: Modifier::empty(),\n///     },\n///     buffer[(0, 0)].style(),\n/// );\n/// ```\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub struct Style {\n    pub fg: Option<Color>,\n    pub bg: Option<Color>,\n    pub underline_color: Option<Color>,\n    pub underline_style: Option<UnderlineStyle>,\n    pub add_modifier: Modifier,\n    pub sub_modifier: Modifier,\n}\n\nimpl Default for Style {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl Style {\n    pub const fn new() -> Self {\n        Style {\n            fg: None,\n            bg: None,\n            underline_color: None,\n            underline_style: None,\n            add_modifier: Modifier::empty(),\n            sub_modifier: Modifier::empty(),\n        }\n    }\n\n    /// Returns a `Style` resetting all properties.\n    pub const fn reset() -> Self {\n        Self {\n            fg: Some(Color::Reset),\n            bg: Some(Color::Reset),\n            underline_color: None,\n            underline_style: None,\n            add_modifier: Modifier::empty(),\n            sub_modifier: Modifier::all(),\n        }\n    }\n\n    /// Changes the foreground color.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_view::graphics::{Color, Style};\n    /// let style = Style::default().fg(Color::Blue);\n    /// let diff = Style::default().fg(Color::Red);\n    /// assert_eq!(style.patch(diff), Style::default().fg(Color::Red));\n    /// ```\n    pub const fn fg(mut self, color: Color) -> Style {\n        self.fg = Some(color);\n        self\n    }\n\n    /// Changes the background color.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_view::graphics::{Color, Style};\n    /// let style = Style::default().bg(Color::Blue);\n    /// let diff = Style::default().bg(Color::Red);\n    /// assert_eq!(style.patch(diff), Style::default().bg(Color::Red));\n    /// ```\n    pub const fn bg(mut self, color: Color) -> Style {\n        self.bg = Some(color);\n        self\n    }\n\n    /// Changes the underline color.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_view::graphics::{Color, Style};\n    /// let style = Style::default().underline_color(Color::Blue);\n    /// let diff = Style::default().underline_color(Color::Red);\n    /// assert_eq!(style.patch(diff), Style::default().underline_color(Color::Red));\n    /// ```\n    pub const fn underline_color(mut self, color: Color) -> Style {\n        self.underline_color = Some(color);\n        self\n    }\n\n    /// Changes the underline style.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_view::graphics::{UnderlineStyle, Style};\n    /// let style = Style::default().underline_style(UnderlineStyle::Line);\n    /// let diff = Style::default().underline_style(UnderlineStyle::Curl);\n    /// assert_eq!(style.patch(diff), Style::default().underline_style(UnderlineStyle::Curl));\n    /// ```\n    pub const fn underline_style(mut self, style: UnderlineStyle) -> Style {\n        self.underline_style = Some(style);\n        self\n    }\n\n    /// Changes the text emphasis.\n    ///\n    /// When applied, it adds the given modifier to the `Style` modifiers.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_view::graphics::{Color, Modifier, Style};\n    /// let style = Style::default().add_modifier(Modifier::BOLD);\n    /// let diff = Style::default().add_modifier(Modifier::ITALIC);\n    /// let patched = style.patch(diff);\n    /// assert_eq!(patched.add_modifier, Modifier::BOLD | Modifier::ITALIC);\n    /// assert_eq!(patched.sub_modifier, Modifier::empty());\n    /// ```\n    pub fn add_modifier(mut self, modifier: Modifier) -> Style {\n        self.sub_modifier.remove(modifier);\n        self.add_modifier.insert(modifier);\n        self\n    }\n\n    /// Changes the text emphasis.\n    ///\n    /// When applied, it removes the given modifier from the `Style` modifiers.\n    ///\n    /// ## Examples\n    ///\n    /// ```rust\n    /// # use helix_view::graphics::{Color, Modifier, Style};\n    /// let style = Style::default().add_modifier(Modifier::BOLD | Modifier::ITALIC);\n    /// let diff = Style::default().remove_modifier(Modifier::ITALIC);\n    /// let patched = style.patch(diff);\n    /// assert_eq!(patched.add_modifier, Modifier::BOLD);\n    /// assert_eq!(patched.sub_modifier, Modifier::ITALIC);\n    /// ```\n    pub fn remove_modifier(mut self, modifier: Modifier) -> Style {\n        self.add_modifier.remove(modifier);\n        self.sub_modifier.insert(modifier);\n        self\n    }\n\n    /// Results in a combined style that is equivalent to applying the two individual styles to\n    /// a style one after the other.\n    ///\n    /// ## Examples\n    /// ```\n    /// # use helix_view::graphics::{Color, Modifier, Style};\n    /// let style_1 = Style::default().fg(Color::Yellow);\n    /// let style_2 = Style::default().bg(Color::Red);\n    /// let combined = style_1.patch(style_2);\n    /// assert_eq!(\n    ///     Style::default().patch(style_1).patch(style_2),\n    ///     Style::default().patch(combined));\n    /// ```\n    pub fn patch(mut self, other: Style) -> Style {\n        self.fg = other.fg.or(self.fg);\n        self.bg = other.bg.or(self.bg);\n        self.underline_color = other.underline_color.or(self.underline_color);\n        self.underline_style = other.underline_style.or(self.underline_style);\n\n        self.add_modifier.remove(other.sub_modifier);\n        self.add_modifier.insert(other.add_modifier);\n        self.sub_modifier.remove(other.add_modifier);\n        self.sub_modifier.insert(other.sub_modifier);\n\n        self\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_rect_size_preservation() {\n        for width in 0..256u16 {\n            for height in 0..256u16 {\n                let rect = Rect::new(0, 0, width, height);\n                rect.area(); // Should not panic.\n                assert_eq!(rect.width, width);\n                assert_eq!(rect.height, height);\n            }\n        }\n\n        // One dimension below 255, one above. Area below max u16.\n        let rect = Rect::new(0, 0, 300, 100);\n        assert_eq!(rect.width, 300);\n        assert_eq!(rect.height, 100);\n    }\n\n    #[test]\n    fn test_rect_chop_from_left() {\n        let rect = Rect::new(0, 0, 20, 30);\n        assert_eq!(Rect::new(10, 0, 10, 30), rect.clip_left(10));\n        assert_eq!(\n            Rect::new(20, 0, 0, 30),\n            rect.clip_left(40),\n            \"x should be clamped to original width if new width is bigger\"\n        );\n    }\n\n    #[test]\n    fn test_rect_chop_from_right() {\n        let rect = Rect::new(0, 0, 20, 30);\n        assert_eq!(Rect::new(0, 0, 10, 30), rect.clip_right(10));\n    }\n\n    #[test]\n    fn test_rect_chop_from_top() {\n        let rect = Rect::new(0, 0, 20, 30);\n        assert_eq!(Rect::new(0, 10, 20, 20), rect.clip_top(10));\n        assert_eq!(\n            Rect::new(0, 30, 20, 0),\n            rect.clip_top(50),\n            \"y should be clamped to original height if new height is bigger\"\n        );\n    }\n\n    #[test]\n    fn test_rect_chop_from_bottom() {\n        let rect = Rect::new(0, 0, 20, 30);\n        assert_eq!(Rect::new(0, 0, 20, 20), rect.clip_bottom(10));\n    }\n\n    fn styles() -> Vec<Style> {\n        vec![\n            Style::default(),\n            Style::default().fg(Color::Yellow),\n            Style::default().bg(Color::Yellow),\n            Style::default().add_modifier(Modifier::BOLD),\n            Style::default().remove_modifier(Modifier::BOLD),\n            Style::default().add_modifier(Modifier::ITALIC),\n            Style::default().remove_modifier(Modifier::ITALIC),\n            Style::default().add_modifier(Modifier::ITALIC | Modifier::BOLD),\n            Style::default().remove_modifier(Modifier::ITALIC | Modifier::BOLD),\n        ]\n    }\n\n    #[test]\n    fn combined_patch_gives_same_result_as_individual_patch() {\n        let styles = styles();\n        for &a in &styles {\n            for &b in &styles {\n                for &c in &styles {\n                    for &d in &styles {\n                        let combined = a.patch(b.patch(c.patch(d)));\n\n                        assert_eq!(\n                            Style::default().patch(a).patch(b).patch(c).patch(d),\n                            Style::default().patch(combined)\n                        );\n                    }\n                }\n            }\n        }\n    }\n\n    #[test]\n    fn sanity_nibble_lowercase() {\n        for i in 0..0x10_u8 {\n            let c = format!(\"{:x}\", i);\n            assert_eq!(c.len(), 1);\n            assert_eq!(\n                u8::from_str_radix(&c, 0x10).unwrap(),\n                from_nibble(c.as_bytes()[0])\n            );\n        }\n    }\n    #[test]\n    fn sanity_nibble_uppercase() {\n        for i in 0..0x10_u8 {\n            let c = format!(\"{:X}\", i);\n            assert_eq!(c.len(), 1);\n            assert_eq!(\n                u8::from_str_radix(&c, 0x10).unwrap(),\n                from_nibble(c.as_bytes()[0])\n            );\n        }\n    }\n\n    #[test]\n    fn sanity_nibble2() {\n        assert_eq!(dupe_from_nibble(b'0'), Some(0));\n        assert_eq!(dupe_from_nibble(b'1'), Some(0x11));\n        assert_eq!(dupe_from_nibble(b'7'), Some(0x77));\n        assert_eq!(dupe_from_nibble(b'a'), Some(0xaa));\n        assert_eq!(dupe_from_nibble(b'f'), Some(0xff));\n    }\n\n    #[test]\n    fn invalid_nibble() {\n        for c in *b\"gGzZ+-\" {\n            assert_eq!(from_nibble(c), 0xff);\n        }\n    }\n\n    #[test]\n    fn pair_endian() {\n        assert_eq!(byte_from_hex(*b\"00\"), Some(0));\n        assert_eq!(byte_from_hex(*b\"fF\"), Some(0xff));\n        assert_eq!(byte_from_hex(*b\"c3\"), Some(0xc3));\n    }\n    #[test]\n    fn invalid_pair() {\n        assert!(byte_from_hex(*b\"+1\").is_none());\n        assert!(byte_from_hex(*b\"-1\").is_none());\n        assert!(byte_from_hex(*b\"Gg\").is_none());\n        assert!(byte_from_hex(*b\"0x\").is_none());\n    }\n\n    #[test]\n    fn hex_color_no_regress() {\n        assert_eq!(Color::from_hex(\"#+a+b+c\"), Err(MalformedHex::NotANibble));\n        assert_eq!(Color::from_hex(\"#+0+1+2\"), Err(MalformedHex::NotANibble));\n    }\n    #[test]\n    fn hex_color_sanity() {\n        assert_eq!(Color::from_hex(\"#01fe3a\"), Ok(Color::Rgb(0x01, 0xfe, 0x3a)));\n        assert_eq!(Color::from_hex(\"#abc\"), Ok(Color::Rgb(0xaa, 0xbb, 0xcc)));\n    }\n    #[test]\n    fn hex_color_invalid_len() {\n        for h in [\n            \"#0\",\n            \"#00\",\n            \"#0000\",\n            \"#00000\",\n            \"#0000000\",\n            \"#00000000\",\n            \"#000000000\",\n            \"#0000000000\",\n        ] {\n            assert_eq!(Color::from_hex(h), Err(MalformedHex::LenOOB));\n        }\n    }\n}\n"
  },
  {
    "path": "helix-view/src/gutter.rs",
    "content": "use std::fmt::Write;\n\nuse helix_core::syntax::config::LanguageServerFeature;\n\nuse crate::{\n    editor::GutterType,\n    graphics::{Style, UnderlineStyle},\n    Document, Editor, Theme, View,\n};\n\nfn count_digits(n: usize) -> usize {\n    (usize::checked_ilog10(n).unwrap_or(0) + 1) as usize\n}\n\npub type GutterFn<'doc> = Box<dyn FnMut(usize, bool, bool, &mut String) -> Option<Style> + 'doc>;\npub type Gutter =\n    for<'doc> fn(&'doc Editor, &'doc Document, &View, &Theme, bool, usize) -> GutterFn<'doc>;\n\nimpl GutterType {\n    pub fn style<'doc>(\n        self,\n        editor: &'doc Editor,\n        doc: &'doc Document,\n        view: &View,\n        theme: &Theme,\n        is_focused: bool,\n    ) -> GutterFn<'doc> {\n        match self {\n            GutterType::Diagnostics => {\n                diagnostics_or_breakpoints(editor, doc, view, theme, is_focused)\n            }\n            GutterType::LineNumbers => line_numbers(editor, doc, view, theme, is_focused),\n            GutterType::Spacer => padding(editor, doc, view, theme, is_focused),\n            GutterType::Diff => diff(editor, doc, view, theme, is_focused),\n        }\n    }\n\n    pub fn width(self, view: &View, doc: &Document) -> usize {\n        match self {\n            GutterType::Diagnostics => 1,\n            GutterType::LineNumbers => line_numbers_width(view, doc),\n            GutterType::Spacer => 1,\n            GutterType::Diff => 1,\n        }\n    }\n}\n\npub fn diagnostic<'doc>(\n    _editor: &'doc Editor,\n    doc: &'doc Document,\n    _view: &View,\n    theme: &Theme,\n    _is_focused: bool,\n) -> GutterFn<'doc> {\n    let warning = theme.get(\"warning\");\n    let error = theme.get(\"error\");\n    let info = theme.get(\"info\");\n    let hint = theme.get(\"hint\");\n    let diagnostics = &doc.diagnostics;\n\n    Box::new(\n        move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| {\n            if !first_visual_line {\n                return None;\n            }\n            use helix_core::diagnostic::Severity;\n            let first_diag_idx_maybe_on_line = diagnostics.partition_point(|d| d.line < line);\n            let diagnostics_on_line = diagnostics[first_diag_idx_maybe_on_line..]\n                .iter()\n                .take_while(|d| {\n                    d.line == line\n                        && d.provider.language_server_id().is_none_or(|id| {\n                            doc.language_servers_with_feature(LanguageServerFeature::Diagnostics)\n                                .any(|ls| ls.id() == id)\n                        })\n                });\n            diagnostics_on_line.max_by_key(|d| d.severity).map(|d| {\n                write!(out, \"●\").ok();\n                match d.severity {\n                    Some(Severity::Error) => error,\n                    Some(Severity::Warning) | None => warning,\n                    Some(Severity::Info) => info,\n                    Some(Severity::Hint) => hint,\n                }\n            })\n        },\n    )\n}\n\npub fn diff<'doc>(\n    _editor: &'doc Editor,\n    doc: &'doc Document,\n    _view: &View,\n    theme: &Theme,\n    _is_focused: bool,\n) -> GutterFn<'doc> {\n    let added = theme.get(\"diff.plus.gutter\");\n    let deleted = theme.get(\"diff.minus.gutter\");\n    let modified = theme.get(\"diff.delta.gutter\");\n    if let Some(diff_handle) = doc.diff_handle() {\n        let hunks = diff_handle.load();\n        let mut hunk_i = 0;\n        let mut hunk = hunks.nth_hunk(hunk_i);\n        Box::new(\n            move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| {\n                // truncating the line is fine here because we don't compute diffs\n                // for files with more lines than i32::MAX anyways\n                // we need to special case removals here\n                // these technically do not have a range of lines to highlight (`hunk.after.start == hunk.after.end`).\n                // However we still want to display these hunks correctly we must not yet skip to the next hunk here\n                while hunk.after.end < line as u32\n                    || !hunk.is_pure_removal() && line as u32 == hunk.after.end\n                {\n                    hunk_i += 1;\n                    hunk = hunks.nth_hunk(hunk_i);\n                }\n\n                if hunk.after.start > line as u32 {\n                    return None;\n                }\n\n                let (icon, style) = if hunk.is_pure_insertion() {\n                    (\"▍\", added)\n                } else if hunk.is_pure_removal() {\n                    if !first_visual_line {\n                        return None;\n                    }\n                    (\"▔\", deleted)\n                } else {\n                    (\"▍\", modified)\n                };\n\n                write!(out, \"{}\", icon).unwrap();\n                Some(style)\n            },\n        )\n    } else {\n        Box::new(move |_, _, _, _| None)\n    }\n}\n\npub fn line_numbers<'doc>(\n    editor: &'doc Editor,\n    doc: &'doc Document,\n    view: &View,\n    theme: &Theme,\n    is_focused: bool,\n) -> GutterFn<'doc> {\n    let text = doc.text().slice(..);\n    let width = line_numbers_width(view, doc);\n\n    let last_line_in_view = view.estimate_last_doc_line(doc);\n\n    // Whether to draw the line number for the last line of the\n    // document or not.  We only draw it if it's not an empty line.\n    let draw_last = text.line_to_byte(last_line_in_view) < text.len_bytes();\n\n    let linenr = theme.get(\"ui.linenr\");\n    let linenr_select = theme.get(\"ui.linenr.selected\");\n\n    let current_line = doc\n        .text()\n        .char_to_line(doc.selection(view.id).primary().cursor(text));\n\n    let line_number = editor.config().line_number;\n    let mode = editor.mode;\n\n    Box::new(\n        move |line: usize, selected: bool, first_visual_line: bool, out: &mut String| {\n            if line == last_line_in_view && !draw_last {\n                write!(out, \"{:>1$}\", '~', width).unwrap();\n                Some(linenr)\n            } else {\n                use crate::{document::Mode, editor::LineNumber};\n\n                let relative = line_number == LineNumber::Relative\n                    && mode != Mode::Insert\n                    && is_focused\n                    && current_line != line;\n\n                let display_num = if relative {\n                    current_line.abs_diff(line)\n                } else {\n                    line + 1\n                };\n\n                let style = if selected && is_focused {\n                    linenr_select\n                } else {\n                    linenr\n                };\n\n                if first_visual_line {\n                    write!(out, \"{:>1$}\", display_num, width).unwrap();\n                } else {\n                    write!(out, \"{:>1$}\", \" \", width).unwrap();\n                }\n\n                first_visual_line.then_some(style)\n            }\n        },\n    )\n}\n\n/// The width of a \"line-numbers\" gutter\n///\n/// The width of the gutter depends on the number of lines in the document,\n/// whether there is content on the last line (the `~` line), and the\n/// `editor.gutters.line-numbers.min-width` settings.\nfn line_numbers_width(view: &View, doc: &Document) -> usize {\n    let text = doc.text();\n    let last_line = text.len_lines().saturating_sub(1);\n    let draw_last = text.line_to_byte(last_line) < text.len_bytes();\n    let last_drawn = if draw_last { last_line + 1 } else { last_line };\n    let digits = count_digits(last_drawn);\n    let n_min = view.gutters.line_numbers.min_width;\n    digits.max(n_min)\n}\n\npub fn padding<'doc>(\n    _editor: &'doc Editor,\n    _doc: &'doc Document,\n    _view: &View,\n    _theme: &Theme,\n    _is_focused: bool,\n) -> GutterFn<'doc> {\n    Box::new(|_line: usize, _selected: bool, _first_visual_line: bool, _out: &mut String| None)\n}\n\npub fn breakpoints<'doc>(\n    editor: &'doc Editor,\n    doc: &'doc Document,\n    _view: &View,\n    theme: &Theme,\n    _is_focused: bool,\n) -> GutterFn<'doc> {\n    let error = theme.get(\"error\");\n    let info = theme.get(\"info\");\n    let breakpoint_style = theme.get(\"ui.debug.breakpoint\");\n\n    let breakpoints = doc.path().and_then(|path| editor.breakpoints.get(path));\n\n    let breakpoints = match breakpoints {\n        Some(breakpoints) => breakpoints,\n        None => return Box::new(move |_, _, _, _| None),\n    };\n\n    Box::new(\n        move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| {\n            if !first_visual_line {\n                return None;\n            }\n            let breakpoint = breakpoints\n                .iter()\n                .find(|breakpoint| breakpoint.line == line)?;\n\n            let style = if breakpoint.condition.is_some() && breakpoint.log_message.is_some() {\n                error.underline_style(UnderlineStyle::Line)\n            } else if breakpoint.condition.is_some() {\n                error\n            } else if breakpoint.log_message.is_some() {\n                info\n            } else {\n                breakpoint_style\n            };\n\n            let sym = if breakpoint.verified { \"●\" } else { \"◯\" };\n            write!(out, \"{}\", sym).unwrap();\n            Some(style)\n        },\n    )\n}\n\nfn execution_pause_indicator<'doc>(\n    editor: &'doc Editor,\n    doc: &'doc Document,\n    theme: &Theme,\n    is_focused: bool,\n) -> GutterFn<'doc> {\n    let style = theme.get(\"ui.debug.active\");\n    let current_stack_frame = editor.current_stack_frame();\n    let frame_line = current_stack_frame.map(|frame| frame.line.saturating_sub(1));\n    let frame_source_path = current_stack_frame.map(|frame| {\n        frame\n            .source\n            .as_ref()\n            .and_then(|source| source.path.as_ref())\n    });\n    let should_display_for_current_doc =\n        doc.path().is_some() && frame_source_path.unwrap_or(None) == doc.path();\n\n    Box::new(\n        move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| {\n            if !first_visual_line\n                || !is_focused\n                || line != frame_line?\n                || !should_display_for_current_doc\n            {\n                return None;\n            }\n\n            let sym = \"▶\";\n            write!(out, \"{}\", sym).unwrap();\n            Some(style)\n        },\n    )\n}\n\npub fn diagnostics_or_breakpoints<'doc>(\n    editor: &'doc Editor,\n    doc: &'doc Document,\n    view: &View,\n    theme: &Theme,\n    is_focused: bool,\n) -> GutterFn<'doc> {\n    let mut diagnostics = diagnostic(editor, doc, view, theme, is_focused);\n    let mut breakpoints = breakpoints(editor, doc, view, theme, is_focused);\n    let mut execution_pause_indicator = execution_pause_indicator(editor, doc, theme, is_focused);\n\n    Box::new(move |line, selected, first_visual_line: bool, out| {\n        execution_pause_indicator(line, selected, first_visual_line, out)\n            .or_else(|| breakpoints(line, selected, first_visual_line, out))\n            .or_else(|| diagnostics(line, selected, first_visual_line, out))\n    })\n}\n\n#[cfg(test)]\nmod tests {\n    use std::sync::Arc;\n\n    use super::*;\n    use crate::document::Document;\n    use crate::editor::{Config, GutterConfig, GutterLineNumbersConfig};\n    use crate::graphics::Rect;\n    use crate::DocumentId;\n    use arc_swap::ArcSwap;\n    use helix_core::{syntax, Rope};\n\n    #[test]\n    fn test_default_gutter_widths() {\n        let mut view = View::new(DocumentId::default(), GutterConfig::default());\n        view.area = Rect::new(40, 40, 40, 40);\n\n        let rope = Rope::from_str(\"abc\\n\\tdef\");\n        let doc = Document::from(\n            rope,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n\n        assert_eq!(view.gutters.layout.len(), 5);\n        assert_eq!(view.gutters.layout[0].width(&view, &doc), 1);\n        assert_eq!(view.gutters.layout[1].width(&view, &doc), 1);\n        assert_eq!(view.gutters.layout[2].width(&view, &doc), 3);\n        assert_eq!(view.gutters.layout[3].width(&view, &doc), 1);\n        assert_eq!(view.gutters.layout[4].width(&view, &doc), 1);\n    }\n\n    #[test]\n    fn test_configured_gutter_widths() {\n        let gutters = GutterConfig {\n            layout: vec![GutterType::Diagnostics],\n            ..Default::default()\n        };\n\n        let mut view = View::new(DocumentId::default(), gutters);\n        view.area = Rect::new(40, 40, 40, 40);\n\n        let rope = Rope::from_str(\"abc\\n\\tdef\");\n        let doc = Document::from(\n            rope,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n\n        assert_eq!(view.gutters.layout.len(), 1);\n        assert_eq!(view.gutters.layout[0].width(&view, &doc), 1);\n\n        let gutters = GutterConfig {\n            layout: vec![GutterType::Diagnostics, GutterType::LineNumbers],\n            line_numbers: GutterLineNumbersConfig { min_width: 10 },\n        };\n\n        let mut view = View::new(DocumentId::default(), gutters);\n        view.area = Rect::new(40, 40, 40, 40);\n\n        let rope = Rope::from_str(\"abc\\n\\tdef\");\n        let doc = Document::from(\n            rope,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n\n        assert_eq!(view.gutters.layout.len(), 2);\n        assert_eq!(view.gutters.layout[0].width(&view, &doc), 1);\n        assert_eq!(view.gutters.layout[1].width(&view, &doc), 10);\n    }\n\n    #[test]\n    fn test_line_numbers_gutter_width_resizes() {\n        let gutters = GutterConfig {\n            layout: vec![GutterType::Diagnostics, GutterType::LineNumbers],\n            line_numbers: GutterLineNumbersConfig { min_width: 1 },\n        };\n\n        let mut view = View::new(DocumentId::default(), gutters);\n        view.area = Rect::new(40, 40, 40, 40);\n\n        let rope = Rope::from_str(\"a\\nb\");\n        let doc_short = Document::from(\n            rope,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n\n        let rope = Rope::from_str(\"a\\nb\\nc\\nd\\ne\\nf\\ng\\nh\\ni\\nj\\nk\\nl\\nm\\nn\\no\\np\");\n        let doc_long = Document::from(\n            rope,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n\n        assert_eq!(view.gutters.layout.len(), 2);\n        assert_eq!(view.gutters.layout[1].width(&view, &doc_short), 1);\n        assert_eq!(view.gutters.layout[1].width(&view, &doc_long), 2);\n    }\n}\n"
  },
  {
    "path": "helix-view/src/handlers/completion.rs",
    "content": "use std::{collections::HashMap, sync::Arc};\n\nuse helix_core::completion::CompletionProvider;\nuse helix_event::{send_blocking, TaskController};\n\nuse crate::{document::SavePoint, DocumentId, ViewId};\n\nuse tokio::sync::mpsc::Sender;\n\npub struct CompletionHandler {\n    event_tx: Sender<CompletionEvent>,\n    pub active_completions: HashMap<CompletionProvider, ResponseContext>,\n    pub request_controller: TaskController,\n}\n\nimpl CompletionHandler {\n    pub fn new(event_tx: Sender<CompletionEvent>) -> Self {\n        Self {\n            event_tx,\n            active_completions: HashMap::new(),\n            request_controller: TaskController::new(),\n        }\n    }\n\n    pub fn event(&self, event: CompletionEvent) {\n        send_blocking(&self.event_tx, event);\n    }\n}\n\npub struct ResponseContext {\n    /// Whether the completion response is marked as \"incomplete.\"\n    ///\n    /// This is used by LSP. When completions are \"incomplete\" and you continue typing, the\n    /// completions should be recomputed by the server instead of filtered.\n    pub is_incomplete: bool,\n    pub priority: i8,\n    pub savepoint: Arc<SavePoint>,\n}\n\npub enum CompletionEvent {\n    /// Auto completion was triggered by typing a word char\n    AutoTrigger {\n        cursor: usize,\n        doc: DocumentId,\n        view: ViewId,\n    },\n    /// Auto completion was triggered by typing a trigger char\n    /// specified by the LSP\n    TriggerChar {\n        cursor: usize,\n        doc: DocumentId,\n        view: ViewId,\n    },\n    /// A completion was manually requested (c-x)\n    ManualTrigger {\n        cursor: usize,\n        doc: DocumentId,\n        view: ViewId,\n    },\n    /// Some text was deleted and the cursor is now at `pos`\n    DeleteText { cursor: usize },\n    /// Invalidate the current auto completion trigger\n    Cancel,\n}\n"
  },
  {
    "path": "helix-view/src/handlers/dap.rs",
    "content": "use crate::editor::{Action, Breakpoint};\nuse crate::{align_view, Align, Editor};\nuse anyhow::bail;\nuse dap::requests::DisconnectArguments;\nuse dap::requests::ThreadsArguments;\nuse helix_core::Selection;\nuse helix_dap::{\n    self as dap, registry::DebugAdapterId, Client, ConnectionType, Payload, Request, ThreadId,\n};\nuse helix_lsp::block_on;\nuse log::{error, warn};\nuse serde_json::{json, Value};\nuse std::fmt::Write;\nuse std::path::PathBuf;\n\n#[macro_export]\nmacro_rules! debugger {\n    ($editor:expr) => {{\n        let Some(debugger) = $editor.debug_adapters.get_active_client_mut() else {\n            return;\n        };\n        debugger\n    }};\n}\n\n// general utils:\npub fn dap_pos_to_pos(doc: &helix_core::Rope, line: usize, column: usize) -> Option<usize> {\n    // 1-indexing to 0 indexing\n    let line = doc.try_line_to_char(line - 1).ok()?;\n    let pos = line + column.saturating_sub(1);\n    // TODO: this is probably utf-16 offsets\n    Some(pos)\n}\n\npub async fn select_thread_id(editor: &mut Editor, thread_id: ThreadId, force: bool) {\n    let debugger = debugger!(editor);\n\n    if !force && debugger.thread_id.is_some() {\n        return;\n    }\n\n    debugger.thread_id = Some(thread_id);\n    fetch_stack_trace(debugger, thread_id).await;\n\n    let frame = debugger.stack_frames[&thread_id].first().cloned();\n    if let Some(frame) = &frame {\n        jump_to_stack_frame(editor, frame);\n    }\n}\n\npub async fn fetch_stack_trace(debugger: &mut Client, thread_id: ThreadId) {\n    let (frames, _) = match debugger.stack_trace(thread_id).await {\n        Ok(frames) => frames,\n        Err(_) => return,\n    };\n    debugger.stack_frames.insert(thread_id, frames);\n    debugger.active_frame = Some(0);\n}\n\npub fn jump_to_stack_frame(editor: &mut Editor, frame: &helix_dap::StackFrame) {\n    let path = if let Some(helix_dap::Source {\n        path: Some(ref path),\n        ..\n    }) = frame.source\n    {\n        path.clone()\n    } else {\n        return;\n    };\n\n    if let Err(e) = editor.open(&path, Action::Replace) {\n        editor.set_error(format!(\"Unable to jump to stack frame: {}\", e));\n        return;\n    }\n\n    let (view, doc) = current!(editor);\n\n    let text_end = doc.text().len_chars().saturating_sub(1);\n    let start = dap_pos_to_pos(doc.text(), frame.line, frame.column).unwrap_or(0);\n    let end = frame\n        .end_line\n        .and_then(|end_line| dap_pos_to_pos(doc.text(), end_line, frame.end_column.unwrap_or(0)))\n        .unwrap_or(start);\n\n    let selection = Selection::single(start.min(text_end), end.min(text_end));\n    doc.set_selection(view.id, selection);\n    align_view(doc, view, Align::Center);\n}\n\npub fn breakpoints_changed(\n    debugger: &mut dap::Client,\n    path: PathBuf,\n    breakpoints: &mut [Breakpoint],\n) -> Result<(), anyhow::Error> {\n    if let Some(caps) = debugger.caps.as_ref() {\n        if breakpoints.iter().any(|b| b.condition.is_some())\n            && !caps.supports_conditional_breakpoints.unwrap_or_default()\n        {\n            bail!(\"Can't edit breakpoint: debugger does not support conditional breakpoints\")\n        }\n        if breakpoints.iter().any(|b| b.hit_condition.is_some())\n            && !caps\n                .supports_hit_conditional_breakpoints\n                .unwrap_or_default()\n        {\n            bail!(\"Can't edit breakpoint: debugger does not support hit conditional breakpoints\")\n        }\n        if breakpoints.iter().any(|b| b.log_message.is_some())\n            && !caps.supports_log_points.unwrap_or_default()\n        {\n            bail!(\"Can't edit breakpoint: debugger does not support logpoints\")\n        }\n    }\n    let source_breakpoints = breakpoints\n        .iter()\n        .map(|breakpoint| helix_dap::SourceBreakpoint {\n            line: breakpoint.line + 1, // convert from 0-indexing to 1-indexing (TODO: could set debugger to 0-indexing on init)\n            column: breakpoint.column,\n            condition: breakpoint.condition.clone(),\n            hit_condition: breakpoint.hit_condition.clone(),\n            log_message: breakpoint.log_message.clone(),\n        })\n        .collect::<Vec<_>>();\n\n    let request = debugger.set_breakpoints(path, source_breakpoints);\n    match block_on(request) {\n        Ok(Some(dap_breakpoints)) => {\n            for (breakpoint, dap_breakpoint) in breakpoints.iter_mut().zip(dap_breakpoints) {\n                breakpoint.id = dap_breakpoint.id;\n                breakpoint.verified = dap_breakpoint.verified;\n                breakpoint.message = dap_breakpoint.message;\n                // TODO: handle breakpoint.message\n                // TODO: verify source matches\n                breakpoint.line = dap_breakpoint.line.unwrap_or(0).saturating_sub(1); // convert to 0-indexing\n                                                                                      // TODO: no unwrap\n                breakpoint.column = dap_breakpoint.column;\n                // TODO: verify end_linef/col instruction reference, offset\n            }\n        }\n        Err(e) => anyhow::bail!(\"Failed to set breakpoints: {}\", e),\n        _ => {}\n    };\n    Ok(())\n}\n\nimpl Editor {\n    pub async fn handle_debugger_message(\n        &mut self,\n        id: DebugAdapterId,\n        payload: helix_dap::Payload,\n    ) -> bool {\n        use helix_dap::{events, Event};\n\n        match payload {\n            Payload::Event(event) => {\n                let event = match Event::parse(&event.event, event.body) {\n                    Ok(event) => event,\n                    Err(dap::Error::Unhandled) => {\n                        log::info!(\"Discarding unknown DAP event '{}'\", event.event);\n                        return false;\n                    }\n                    Err(err) => {\n                        log::warn!(\"Discarding invalid DAP event '{}': {err}\", event.event);\n                        return false;\n                    }\n                };\n                match event {\n                    Event::Stopped(events::StoppedBody {\n                        thread_id,\n                        description,\n                        text,\n                        reason,\n                        all_threads_stopped,\n                        ..\n                    }) => {\n                        let debugger = match self.debug_adapters.get_client_mut(id) {\n                            Some(debugger) => debugger,\n                            None => return false,\n                        };\n\n                        let all_threads_stopped = all_threads_stopped.unwrap_or_default();\n\n                        if all_threads_stopped {\n                            if let Ok(response) = debugger\n                                .request::<dap::requests::Threads>(Some(ThreadsArguments {}))\n                                .await\n                            {\n                                for thread in response.threads {\n                                    fetch_stack_trace(debugger, thread.id).await;\n                                }\n                                select_thread_id(self, thread_id.unwrap_or_default(), false).await;\n                            }\n                        } else if let Some(thread_id) = thread_id {\n                            debugger.thread_states.insert(thread_id, reason.clone()); // TODO: dap uses \"type\" || \"reason\" here\n\n                            fetch_stack_trace(debugger, thread_id).await;\n                            // whichever thread stops is made \"current\" (if no previously selected thread).\n                            select_thread_id(self, thread_id, false).await;\n                        }\n\n                        let scope = match thread_id {\n                            Some(id) => format!(\"Thread {}\", id),\n                            None => \"Target\".to_owned(),\n                        };\n\n                        let mut status = format!(\"{} stopped because of {}\", scope, reason);\n                        if let Some(desc) = description {\n                            write!(status, \" {}\", desc).unwrap();\n                        }\n                        if let Some(text) = text {\n                            write!(status, \" {}\", text).unwrap();\n                        }\n                        if all_threads_stopped {\n                            status.push_str(\" (all threads stopped)\");\n                        }\n\n                        self.set_status(status);\n                    }\n                    Event::Continued(events::ContinuedBody { thread_id, .. }) => {\n                        let debugger = match self.debug_adapters.get_client_mut(id) {\n                            Some(debugger) => debugger,\n                            None => return false,\n                        };\n\n                        debugger\n                            .thread_states\n                            .insert(thread_id, \"running\".to_owned());\n                        if debugger.thread_id == Some(thread_id) {\n                            debugger.resume_application();\n                        }\n                    }\n                    Event::Thread(thread) => {\n                        self.set_status(format!(\"Thread {}: {}\", thread.thread_id, thread.reason));\n                        let debugger = match self.debug_adapters.get_client_mut(id) {\n                            Some(debugger) => debugger,\n                            None => return false,\n                        };\n\n                        debugger.thread_id = Some(thread.thread_id);\n                        // set the stack frame for the thread\n                    }\n                    Event::Breakpoint(events::BreakpointBody { reason, breakpoint }) => {\n                        match &reason[..] {\n                            \"new\" => {\n                                if let Some(source) = breakpoint.source {\n                                    let Some(path) = source.path else {\n                                        warn!(\"DAP breakpoint event missing source path\");\n                                        return false;\n                                    };\n                                    let Some(line) = breakpoint.line else {\n                                        warn!(\"DAP breakpoint event missing line\");\n                                        return false;\n                                    };\n                                    self.breakpoints.entry(path).or_default().push(Breakpoint {\n                                        id: breakpoint.id,\n                                        verified: breakpoint.verified,\n                                        message: breakpoint.message.clone(),\n                                        line: line.saturating_sub(1),\n                                        column: breakpoint.column,\n                                        ..Default::default()\n                                    });\n                                    if let Some(message) = &breakpoint.message {\n                                        self.set_status(format!(\"Breakpoint: {}\", message));\n                                    }\n                                }\n                            }\n                            \"changed\" => {\n                                let Some(id) = breakpoint.id else {\n                                    warn!(\"DAP breakpoint event missing id\");\n                                    return false;\n                                };\n                                if let Some(source) = &breakpoint.source {\n                                    if source.path.is_none() {\n                                        warn!(\"DAP breakpoint event missing source path\");\n                                    }\n                                }\n                                if breakpoint.line.is_none() {\n                                    warn!(\"DAP breakpoint event missing line\");\n                                }\n                                for breakpoints in self.breakpoints.values_mut() {\n                                    if let Some(i) =\n                                        breakpoints.iter().position(|b| b.id == Some(id))\n                                    {\n                                        breakpoints[i].verified = breakpoint.verified;\n                                        breakpoints[i].message = breakpoint\n                                            .message\n                                            .clone()\n                                            .or_else(|| breakpoints[i].message.take());\n                                        breakpoints[i].line =\n                                            breakpoint.line.map_or(breakpoints[i].line, |line| {\n                                                line.saturating_sub(1)\n                                            });\n                                        breakpoints[i].column =\n                                            breakpoint.column.or(breakpoints[i].column);\n                                    }\n                                }\n                                if let Some(message) = &breakpoint.message {\n                                    self.set_status(format!(\"Breakpoint: {}\", message));\n                                }\n                            }\n                            \"removed\" => {\n                                let Some(id) = breakpoint.id else {\n                                    warn!(\"DAP breakpoint event missing id\");\n                                    return false;\n                                };\n                                for breakpoints in self.breakpoints.values_mut() {\n                                    if let Some(i) =\n                                        breakpoints.iter().position(|b| b.id == Some(id))\n                                    {\n                                        breakpoints.remove(i);\n                                    }\n                                }\n                            }\n                            reason => {\n                                warn!(\"Unknown breakpoint event: {}\", reason);\n                            }\n                        }\n                    }\n                    Event::Output(events::OutputBody {\n                        category, output, ..\n                    }) => {\n                        let prefix = match category {\n                            Some(category) => {\n                                if &category == \"telemetry\" {\n                                    return false;\n                                }\n                                format!(\"Debug ({}):\", category)\n                            }\n                            None => \"Debug:\".to_owned(),\n                        };\n\n                        log::info!(\"{}\", output);\n                        self.set_status(format!(\"{} {}\", prefix, output));\n                    }\n                    Event::Initialized(_) => {\n                        self.set_status(\"Debugger initialized...\");\n                        let debugger = match self.debug_adapters.get_client_mut(id) {\n                            Some(debugger) => debugger,\n                            None => return false,\n                        };\n\n                        // send existing breakpoints\n                        for (path, breakpoints) in &mut self.breakpoints {\n                            // TODO: call futures in parallel, await all\n                            let _ = breakpoints_changed(debugger, path.clone(), breakpoints);\n                        }\n                        // TODO: fetch breakpoints (in case we're attaching)\n\n                        if let Err(err) = debugger.configuration_done().await {\n                            self.set_error(format!(\"Debugger configuration failed: {}\", err));\n                        } else {\n                            self.set_status(\"Debugged application started\");\n                        }\n\n                        self.debug_adapters.set_active_client(id);\n                    }\n                    Event::Terminated(terminated) => {\n                        let debugger = match self.debug_adapters.get_client_mut(id) {\n                            Some(debugger) => debugger,\n                            None => return false,\n                        };\n\n                        let restart_arg = if let Some(terminated) = terminated {\n                            terminated.restart\n                        } else {\n                            None\n                        };\n\n                        let restart_bool = restart_arg\n                            .as_ref()\n                            .and_then(|v| v.as_bool())\n                            .unwrap_or(false);\n                        let disconnect_args = Some(DisconnectArguments {\n                            restart: Some(restart_bool),\n                            terminate_debuggee: None,\n                            suspend_debuggee: None,\n                        });\n\n                        if let Err(err) = debugger.disconnect(disconnect_args).await {\n                            self.set_error(format!(\n                                \"Cannot disconnect debugger upon terminated event receival {:?}\",\n                                err\n                            ));\n                            return false;\n                        }\n\n                        match restart_arg {\n                            Some(Value::Bool(false)) | None => {\n                                self.debug_adapters.remove_client(id);\n                                self.debug_adapters.unset_active_client();\n                                self.set_status(\n                                    \"Terminated debugging session and disconnected debugger.\",\n                                );\n\n                                // Go through all breakpoints and set verfified to false\n                                // this should update the UI to show the breakpoints are no longer connected\n                                for breakpoints in self.breakpoints.values_mut() {\n                                    for breakpoint in breakpoints.iter_mut() {\n                                        breakpoint.verified = false;\n                                    }\n                                }\n                            }\n                            Some(val) => {\n                                log::info!(\"Attempting to restart debug session.\");\n                                let connection_type = match debugger.connection_type() {\n                                    Some(connection_type) => connection_type,\n                                    None => {\n                                        self.set_error(\"No starting request found, to be used in restarting the debugging session.\");\n                                        return false;\n                                    }\n                                };\n\n                                let relaunch_resp = if let ConnectionType::Launch = connection_type\n                                {\n                                    debugger.launch(val).await\n                                } else {\n                                    debugger.attach(val).await\n                                };\n\n                                if let Err(err) = relaunch_resp {\n                                    self.set_error(format!(\n                                        \"Failed to restart debugging session: {:?}\",\n                                        err\n                                    ));\n                                }\n                            }\n                        }\n                    }\n                    Event::Exited(resp) => {\n                        let exit_code = resp.exit_code;\n                        if exit_code != 0 {\n                            self.set_error(format!(\n                                \"Debuggee failed to exit successfully (exit code: {exit_code}).\"\n                            ));\n                        }\n                    }\n                    ev => {\n                        log::warn!(\"Unhandled event {:?}\", ev);\n                        return false; // return early to skip render\n                    }\n                }\n            }\n            Payload::Response(_) => unreachable!(),\n            Payload::Request(request) => {\n                let reply = match Request::parse(&request.command, request.arguments) {\n                    Ok(Request::RunInTerminal(arguments)) => {\n                        let config = self.config();\n                        let Some(config) = config.terminal.as_ref() else {\n                            self.set_error(\"No external terminal defined\");\n                            return true;\n                        };\n\n                        let process = match std::process::Command::new(&config.command)\n                            .args(&config.args)\n                            .arg(arguments.args.join(\" \"))\n                            .spawn()\n                        {\n                            Ok(process) => process,\n                            Err(err) => {\n                                self.set_error(format!(\n                                    \"Error starting external terminal: {}\",\n                                    err\n                                ));\n                                return true;\n                            }\n                        };\n\n                        Ok(json!(dap::requests::RunInTerminalResponse {\n                            process_id: Some(process.id()),\n                            shell_process_id: None,\n                        }))\n                    }\n                    Ok(Request::StartDebugging(arguments)) => {\n                        let debugger = match self.debug_adapters.get_client_mut(id) {\n                            Some(debugger) => debugger,\n                            None => {\n                                self.set_error(\"No active debugger found.\");\n                                return true;\n                            }\n                        };\n                        // Currently we only support starting a child debugger if the parent is using the TCP transport\n                        let socket = match debugger.socket {\n                            Some(socket) => socket,\n                            None => {\n                                self.set_error(\"Child debugger can only be started if the parent debugger is using TCP transport.\");\n                                return true;\n                            }\n                        };\n\n                        let config = match debugger.config.clone() {\n                            Some(config) => config,\n                            None => {\n                                error!(\"No configuration found for the debugger.\");\n                                return true;\n                            }\n                        };\n\n                        let result = self.debug_adapters.start_client(Some(socket), &config);\n\n                        let client_id = match result {\n                            Ok(child) => child,\n                            Err(err) => {\n                                self.set_error(format!(\n                                    \"Failed to create child debugger: {:?}\",\n                                    err\n                                ));\n                                return true;\n                            }\n                        };\n\n                        let client = match self.debug_adapters.get_client_mut(client_id) {\n                            Some(child) => child,\n                            None => {\n                                self.set_error(\"Failed to get child debugger.\");\n                                return true;\n                            }\n                        };\n\n                        let relaunch_resp = if let ConnectionType::Launch = arguments.request {\n                            client.launch(arguments.configuration).await\n                        } else {\n                            client.attach(arguments.configuration).await\n                        };\n                        if let Err(err) = relaunch_resp {\n                            self.set_error(format!(\"Failed to start debugging session: {:?}\", err));\n                            return true;\n                        }\n\n                        Ok(json!({\n                            \"success\": true,\n                        }))\n                    }\n                    Err(err) => Err(err),\n                };\n\n                if let Some(debugger) = self.debug_adapters.get_client_mut(id) {\n                    debugger\n                        .reply(request.seq, &request.command, reply)\n                        .await\n                        .ok();\n                }\n            }\n        }\n        true\n    }\n}\n"
  },
  {
    "path": "helix-view/src/handlers/diagnostics.rs",
    "content": "use std::cell::Cell;\nuse std::num::NonZeroUsize;\nuse std::sync::atomic::{self, AtomicUsize};\nuse std::sync::Arc;\nuse std::time::Duration;\n\nuse helix_event::{request_redraw, send_blocking, AsyncHook};\nuse tokio::sync::mpsc::Sender;\nuse tokio::time::Instant;\n\nuse crate::{Document, DocumentId, ViewId};\n\n#[derive(Debug)]\npub enum DiagnosticEvent {\n    CursorLineChanged { generation: usize },\n    Refresh,\n}\n\nstruct DiagnosticTimeout {\n    active_generation: Arc<AtomicUsize>,\n    generation: usize,\n}\n\nconst TIMEOUT: Duration = Duration::from_millis(350);\n\nimpl AsyncHook for DiagnosticTimeout {\n    type Event = DiagnosticEvent;\n\n    fn handle_event(\n        &mut self,\n        event: DiagnosticEvent,\n        timeout: Option<Instant>,\n    ) -> Option<Instant> {\n        match event {\n            DiagnosticEvent::CursorLineChanged { generation } => {\n                if generation > self.generation {\n                    self.generation = generation;\n                    Some(Instant::now() + TIMEOUT)\n                } else {\n                    timeout\n                }\n            }\n            DiagnosticEvent::Refresh if timeout.is_some() => Some(Instant::now() + TIMEOUT),\n            DiagnosticEvent::Refresh => None,\n        }\n    }\n\n    fn finish_debounce(&mut self) {\n        if self.active_generation.load(atomic::Ordering::Relaxed) < self.generation {\n            self.active_generation\n                .store(self.generation, atomic::Ordering::Relaxed);\n            request_redraw();\n        }\n    }\n}\n\npub struct DiagnosticsHandler {\n    active_generation: Arc<AtomicUsize>,\n    generation: Cell<usize>,\n    last_doc: Cell<DocumentId>,\n    last_cursor_line: Cell<usize>,\n    pub active: bool,\n    pub events: Sender<DiagnosticEvent>,\n}\n\n// make sure we never share handlers across multiple views this is a stop\n// gap solution. We just shouldn't be cloneing a view to begin with (we do\n// for :hsplit/vsplit) and really this should not be view specific to begin with\n// but to fix that larger architecutre changes are needed\nimpl Clone for DiagnosticsHandler {\n    fn clone(&self) -> Self {\n        Self::new()\n    }\n}\n\nimpl DiagnosticsHandler {\n    #[allow(clippy::new_without_default)]\n    pub fn new() -> Self {\n        let active_generation = Arc::new(AtomicUsize::new(0));\n        let events = DiagnosticTimeout {\n            active_generation: active_generation.clone(),\n            generation: 0,\n        }\n        .spawn();\n        Self {\n            active_generation,\n            generation: Cell::new(0),\n            events,\n            last_doc: Cell::new(DocumentId(NonZeroUsize::new(usize::MAX).unwrap())),\n            last_cursor_line: Cell::new(usize::MAX),\n            active: true,\n        }\n    }\n}\n\nimpl DiagnosticsHandler {\n    pub fn immediately_show_diagnostic(&self, doc: &Document, view: ViewId) {\n        self.last_doc.set(doc.id());\n        let cursor_line = doc\n            .selection(view)\n            .primary()\n            .cursor_line(doc.text().slice(..));\n        self.last_cursor_line.set(cursor_line);\n        self.active_generation\n            .store(self.generation.get(), atomic::Ordering::Relaxed);\n    }\n    pub fn show_cursorline_diagnostics(&self, doc: &Document, view: ViewId) -> bool {\n        if !self.active {\n            return false;\n        }\n        let cursor_line = doc\n            .selection(view)\n            .primary()\n            .cursor_line(doc.text().slice(..));\n        if self.last_cursor_line.get() == cursor_line && self.last_doc.get() == doc.id() {\n            let active_generation = self.active_generation.load(atomic::Ordering::Relaxed);\n            self.generation.get() == active_generation\n        } else {\n            self.last_doc.set(doc.id());\n            self.last_cursor_line.set(cursor_line);\n            self.generation.set(self.generation.get() + 1);\n            send_blocking(\n                &self.events,\n                DiagnosticEvent::CursorLineChanged {\n                    generation: self.generation.get(),\n                },\n            );\n            false\n        }\n    }\n}\n"
  },
  {
    "path": "helix-view/src/handlers/lsp.rs",
    "content": "use std::collections::btree_map::Entry;\nuse std::collections::HashSet;\nuse std::fmt::Display;\n\nuse crate::editor::Action;\nuse crate::events::{\n    DiagnosticsDidChange, DocumentDidChange, DocumentDidClose, LanguageServerInitialized,\n};\nuse crate::{DocumentId, Editor};\nuse helix_core::diagnostic::DiagnosticProvider;\nuse helix_core::Uri;\nuse helix_event::register_hook;\nuse helix_lsp::util::generate_transaction_from_edits;\nuse helix_lsp::{lsp, LanguageServerId, OffsetEncoding};\n\nuse super::Handlers;\n\npub struct DocumentColorsEvent(pub DocumentId);\npub struct DocumentLinksEvent(pub DocumentId);\n\n#[derive(Debug, PartialEq, Eq, Clone, Copy)]\npub enum SignatureHelpInvoked {\n    Automatic,\n    Manual,\n}\n\npub enum SignatureHelpEvent {\n    Invoked,\n    Trigger,\n    ReTrigger,\n    Cancel,\n    RequestComplete { open: bool },\n}\n\npub struct PullDiagnosticsEvent {\n    pub document_id: DocumentId,\n}\n\npub struct PullAllDocumentsDiagnosticsEvent {\n    pub language_servers: HashSet<LanguageServerId>,\n}\n\n#[derive(Debug)]\npub struct ApplyEditError {\n    pub kind: ApplyEditErrorKind,\n    pub failed_change_idx: usize,\n}\n\n#[derive(Debug)]\npub enum ApplyEditErrorKind {\n    DocumentChanged,\n    FileNotFound,\n    InvalidUrl(helix_core::uri::UrlConversionError),\n    IoError(std::io::Error),\n    // TODO: check edits before applying and propagate failure\n    // InvalidEdit,\n}\n\nimpl From<std::io::Error> for ApplyEditErrorKind {\n    fn from(err: std::io::Error) -> Self {\n        ApplyEditErrorKind::IoError(err)\n    }\n}\n\nimpl From<helix_core::uri::UrlConversionError> for ApplyEditErrorKind {\n    fn from(err: helix_core::uri::UrlConversionError) -> Self {\n        ApplyEditErrorKind::InvalidUrl(err)\n    }\n}\n\nimpl Display for ApplyEditErrorKind {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            ApplyEditErrorKind::DocumentChanged => f.write_str(\"document has changed\"),\n            ApplyEditErrorKind::FileNotFound => f.write_str(\"file not found\"),\n            ApplyEditErrorKind::InvalidUrl(err) => f.write_str(&format!(\"{err}\")),\n            ApplyEditErrorKind::IoError(err) => f.write_str(&format!(\"{err}\")),\n        }\n    }\n}\n\nimpl Editor {\n    fn apply_text_edits(\n        &mut self,\n        url: &helix_lsp::Url,\n        version: Option<i32>,\n        text_edits: Vec<lsp::TextEdit>,\n        offset_encoding: OffsetEncoding,\n    ) -> Result<(), ApplyEditErrorKind> {\n        let uri = match Uri::try_from(url) {\n            Ok(uri) => uri,\n            Err(err) => {\n                log::error!(\"{err}\");\n                return Err(err.into());\n            }\n        };\n        let path = uri.as_path().expect(\"URIs are valid paths\");\n\n        let doc_id = match self.open(path, Action::Load) {\n            Ok(doc_id) => doc_id,\n            Err(err) => {\n                let err = format!(\n                    \"failed to open document: {}: {}\",\n                    path.to_string_lossy(),\n                    err\n                );\n                log::error!(\"{}\", err);\n                self.set_error(err);\n                return Err(ApplyEditErrorKind::FileNotFound);\n            }\n        };\n\n        let doc = doc_mut!(self, &doc_id);\n        if let Some(version) = version {\n            if version != doc.version() {\n                let err = format!(\"outdated workspace edit for {path:?}\");\n                log::error!(\"{err}, expected {} but got {version}\", doc.version());\n                self.set_error(err);\n                return Err(ApplyEditErrorKind::DocumentChanged);\n            }\n        }\n\n        // Need to determine a view for apply/append_changes_to_history\n        let view_id = self.get_synced_view_id(doc_id);\n        let doc = doc_mut!(self, &doc_id);\n\n        let transaction = generate_transaction_from_edits(doc.text(), text_edits, offset_encoding);\n        let view = view_mut!(self, view_id);\n        doc.apply(&transaction, view.id);\n        doc.append_changes_to_history(view);\n        Ok(())\n    }\n\n    // TODO make this transactional (and set failureMode to transactional)\n    pub fn apply_workspace_edit(\n        &mut self,\n        offset_encoding: OffsetEncoding,\n        workspace_edit: &lsp::WorkspaceEdit,\n    ) -> Result<(), ApplyEditError> {\n        if let Some(ref document_changes) = workspace_edit.document_changes {\n            match document_changes {\n                lsp::DocumentChanges::Edits(document_edits) => {\n                    for (i, document_edit) in document_edits.iter().enumerate() {\n                        let edits = document_edit\n                            .edits\n                            .iter()\n                            .map(|edit| match edit {\n                                lsp::OneOf::Left(text_edit) => text_edit,\n                                lsp::OneOf::Right(annotated_text_edit) => {\n                                    &annotated_text_edit.text_edit\n                                }\n                            })\n                            .cloned()\n                            .collect();\n                        self.apply_text_edits(\n                            &document_edit.text_document.uri,\n                            document_edit.text_document.version,\n                            edits,\n                            offset_encoding,\n                        )\n                        .map_err(|kind| ApplyEditError {\n                            kind,\n                            failed_change_idx: i,\n                        })?;\n                    }\n                }\n                lsp::DocumentChanges::Operations(operations) => {\n                    log::debug!(\"document changes - operations: {:?}\", operations);\n                    for (i, operation) in operations.iter().enumerate() {\n                        match operation {\n                            lsp::DocumentChangeOperation::Op(op) => {\n                                self.apply_document_resource_op(op).map_err(|err| {\n                                    ApplyEditError {\n                                        kind: err,\n                                        failed_change_idx: i,\n                                    }\n                                })?;\n                            }\n\n                            lsp::DocumentChangeOperation::Edit(document_edit) => {\n                                let edits = document_edit\n                                    .edits\n                                    .iter()\n                                    .map(|edit| match edit {\n                                        lsp::OneOf::Left(text_edit) => text_edit,\n                                        lsp::OneOf::Right(annotated_text_edit) => {\n                                            &annotated_text_edit.text_edit\n                                        }\n                                    })\n                                    .cloned()\n                                    .collect();\n                                self.apply_text_edits(\n                                    &document_edit.text_document.uri,\n                                    document_edit.text_document.version,\n                                    edits,\n                                    offset_encoding,\n                                )\n                                .map_err(|kind| {\n                                    ApplyEditError {\n                                        kind,\n                                        failed_change_idx: i,\n                                    }\n                                })?;\n                            }\n                        }\n                    }\n                }\n            }\n\n            return Ok(());\n        }\n\n        if let Some(ref changes) = workspace_edit.changes {\n            log::debug!(\"workspace changes: {:?}\", changes);\n            for (i, (uri, text_edits)) in changes.iter().enumerate() {\n                let text_edits = text_edits.to_vec();\n                self.apply_text_edits(uri, None, text_edits, offset_encoding)\n                    .map_err(|kind| ApplyEditError {\n                        kind,\n                        failed_change_idx: i,\n                    })?;\n            }\n        }\n\n        Ok(())\n    }\n\n    fn apply_document_resource_op(\n        &mut self,\n        op: &lsp::ResourceOp,\n    ) -> Result<(), ApplyEditErrorKind> {\n        use lsp::ResourceOp;\n        use std::fs;\n        // NOTE: If `Uri` gets another variant than `Path`, the below `expect`s\n        // may no longer be valid.\n        match op {\n            ResourceOp::Create(op) => {\n                let uri = Uri::try_from(&op.uri)?;\n                let path = uri.as_path().expect(\"URIs are valid paths\");\n                let ignore_if_exists = op.options.as_ref().is_some_and(|options| {\n                    !options.overwrite.unwrap_or(false) && options.ignore_if_exists.unwrap_or(false)\n                });\n                if !ignore_if_exists || !path.exists() {\n                    // Create directory if it does not exist\n                    if let Some(dir) = path.parent() {\n                        if !dir.is_dir() {\n                            fs::create_dir_all(dir)?;\n                        }\n                    }\n\n                    fs::write(path, [])?;\n                    self.language_servers\n                        .file_event_handler\n                        .file_changed(path.to_path_buf());\n                }\n            }\n            ResourceOp::Delete(op) => {\n                let uri = Uri::try_from(&op.uri)?;\n                let path = uri.as_path().expect(\"URIs are valid paths\");\n                if path.is_dir() {\n                    let recursive = op\n                        .options\n                        .as_ref()\n                        .and_then(|options| options.recursive)\n                        .unwrap_or(false);\n\n                    if recursive {\n                        fs::remove_dir_all(path)?\n                    } else {\n                        fs::remove_dir(path)?\n                    }\n                    self.language_servers\n                        .file_event_handler\n                        .file_changed(path.to_path_buf());\n                } else if path.is_file() {\n                    fs::remove_file(path)?;\n                }\n            }\n            ResourceOp::Rename(op) => {\n                let from_uri = Uri::try_from(&op.old_uri)?;\n                let from = from_uri.as_path().expect(\"URIs are valid paths\");\n                let to_uri = Uri::try_from(&op.new_uri)?;\n                let to = to_uri.as_path().expect(\"URIs are valid paths\");\n                let ignore_if_exists = op.options.as_ref().is_some_and(|options| {\n                    !options.overwrite.unwrap_or(false) && options.ignore_if_exists.unwrap_or(false)\n                });\n                if !ignore_if_exists || !to.exists() {\n                    self.move_path(from, to)?;\n                }\n            }\n        }\n        Ok(())\n    }\n\n    pub fn handle_lsp_diagnostics(\n        &mut self,\n        provider: &DiagnosticProvider,\n        uri: Uri,\n        version: Option<i32>,\n        mut diagnostics: Vec<lsp::Diagnostic>,\n    ) {\n        let doc = self\n            .documents\n            .values_mut()\n            .find(|doc| doc.uri().is_some_and(|u| u == uri));\n\n        if let Some((version, doc)) = version.zip(doc.as_ref()) {\n            if version != doc.version() {\n                log::info!(\"Version ({version}) is out of date for {uri:?} (expected ({})), dropping PublishDiagnostic notification\", doc.version());\n                return;\n            }\n        }\n\n        let mut unchanged_diag_sources = Vec::new();\n        if let Some((lang_conf, old_diagnostics)) = doc\n            .as_ref()\n            .and_then(|doc| Some((doc.language_config()?, self.diagnostics.get(&uri)?)))\n        {\n            if !lang_conf.persistent_diagnostic_sources.is_empty() {\n                // Sort diagnostics first by severity and then by line numbers.\n                // Note: The `lsp::DiagnosticSeverity` enum is already defined in decreasing order\n                diagnostics.sort_by_key(|d| (d.severity, d.range.start));\n            }\n            for source in &lang_conf.persistent_diagnostic_sources {\n                let new_diagnostics = diagnostics\n                    .iter()\n                    .filter(|d| d.source.as_ref() == Some(source));\n                let old_diagnostics = old_diagnostics\n                    .iter()\n                    .filter(|(d, d_provider)| {\n                        d_provider == provider && d.source.as_ref() == Some(source)\n                    })\n                    .map(|(d, _)| d);\n                if new_diagnostics.eq(old_diagnostics) {\n                    unchanged_diag_sources.push(source.clone())\n                }\n            }\n        }\n\n        let diagnostics = diagnostics.into_iter().map(|d| (d, provider.clone()));\n\n        // Insert the original lsp::Diagnostics here because we may have no open document\n        // for diagnostic message and so we can't calculate the exact position.\n        // When using them later in the diagnostics picker, we calculate them on-demand.\n        let diagnostics = match self.diagnostics.entry(uri) {\n            Entry::Occupied(o) => {\n                let current_diagnostics = o.into_mut();\n                // there may entries of other language servers, which is why we can't overwrite the whole entry\n                current_diagnostics.retain(|(_, d_provider)| d_provider != provider);\n                current_diagnostics.extend(diagnostics);\n                current_diagnostics\n                // Sort diagnostics first by severity and then by line numbers.\n            }\n            Entry::Vacant(v) => v.insert(diagnostics.collect()),\n        };\n\n        // Sort diagnostics first by severity and then by line numbers.\n        // Note: The `lsp::DiagnosticSeverity` enum is already defined in decreasing order\n        diagnostics.sort_by_key(|(d, provider)| (d.severity, d.range.start, provider.clone()));\n\n        if let Some(doc) = doc {\n            let diagnostic_of_language_server_and_not_in_unchanged_sources =\n                |diagnostic: &lsp::Diagnostic, d_provider: &DiagnosticProvider| {\n                    d_provider == provider\n                        && diagnostic\n                            .source\n                            .as_ref()\n                            .is_none_or(|source| !unchanged_diag_sources.contains(source))\n                };\n            let diagnostics = Self::doc_diagnostics_with_filter(\n                &self.language_servers,\n                &self.diagnostics,\n                doc,\n                diagnostic_of_language_server_and_not_in_unchanged_sources,\n            );\n            doc.replace_diagnostics(diagnostics, &unchanged_diag_sources, Some(provider));\n\n            let doc = doc.id();\n            helix_event::dispatch(DiagnosticsDidChange { editor: self, doc });\n        }\n    }\n\n    pub fn execute_lsp_command(&mut self, command: lsp::Command, server_id: LanguageServerId) {\n        // the command is executed on the server and communicated back\n        // to the client asynchronously using workspace edits\n        let Some(future) = self\n            .language_server_by_id(server_id)\n            .and_then(|server| server.command(command))\n        else {\n            self.set_error(\"Language server does not support executing commands\");\n            return;\n        };\n\n        tokio::spawn(async move {\n            if let Err(err) = future.await {\n                log::error!(\"Error executing LSP command: {err}\");\n            }\n        });\n    }\n}\n\npub fn register_hooks(_handlers: &Handlers) {\n    register_hook!(move |event: &mut LanguageServerInitialized<'_>| {\n        let language_server = event.editor.language_server_by_id(event.server_id).unwrap();\n\n        for doc in event\n            .editor\n            .documents()\n            .filter(|doc| doc.supports_language_server(event.server_id))\n        {\n            let Some(url) = doc.url() else {\n                continue;\n            };\n\n            let language_id = doc.language_id().map(ToOwned::to_owned).unwrap_or_default();\n\n            language_server.text_document_did_open(url, doc.version(), doc.text(), language_id);\n        }\n\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut DocumentDidChange<'_>| {\n        // Send textDocument/didChange notifications.\n        if !event.ghost_transaction {\n            for language_server in event.doc.language_servers() {\n                language_server.text_document_did_change(\n                    event.doc.versioned_identifier(),\n                    event.old_text,\n                    event.doc.text(),\n                    event.changes,\n                );\n            }\n        }\n\n        Ok(())\n    });\n\n    register_hook!(move |event: &mut DocumentDidClose<'_>| {\n        // Send textDocument/didClose notifications.\n        for language_server in event.doc.language_servers() {\n            language_server.text_document_did_close(event.doc.identifier());\n        }\n\n        Ok(())\n    });\n}\n"
  },
  {
    "path": "helix-view/src/handlers/word_index.rs",
    "content": "//! Indexing of words from open buffers.\n//!\n//! This provides an eventually consistent set of words used in any open buffers. This set is\n//! later used for lexical completion.\n\nuse std::{borrow::Cow, collections::HashMap, iter, mem, sync::Arc, time::Duration};\n\nuse helix_core::{\n    chars::char_is_word, fuzzy::fuzzy_match, movement, ChangeSet, Range, Rope, RopeSlice,\n};\nuse helix_event::{register_hook, AsyncHook};\nuse helix_stdx::rope::RopeSliceExt as _;\nuse parking_lot::RwLock;\nuse tokio::{sync::mpsc, time::Instant};\n\nuse crate::{\n    events::{ConfigDidChange, DocumentDidChange, DocumentDidClose, DocumentDidOpen},\n    DocumentId,\n};\n\nuse super::Handlers;\n\n#[derive(Debug)]\nstruct Change {\n    old_text: Rope,\n    text: Rope,\n    changes: ChangeSet,\n}\n\n#[derive(Debug)]\nenum Event {\n    Insert(Rope),\n    Update(DocumentId, Change),\n    Delete(DocumentId, Rope),\n    /// Clear the entire word index.\n    /// This is used to clear memory when the feature is turned off.\n    Clear,\n}\n\n#[derive(Debug)]\npub struct Handler {\n    pub(super) index: WordIndex,\n    /// A sender into an async hook which debounces updates to the index.\n    hook: mpsc::Sender<Event>,\n    /// A sender to a tokio task which coordinates the indexing of documents.\n    ///\n    /// See [WordIndex::run]. A supervisor-like task is in charge of spawning tasks to update the\n    /// index. This ensures that consecutive edits to a document trigger the correct order of\n    /// insertions and deletions into the word set.\n    coordinator: mpsc::UnboundedSender<Event>,\n}\n\nimpl Handler {\n    pub fn spawn() -> Self {\n        let index = WordIndex::default();\n        let (tx, rx) = mpsc::unbounded_channel();\n        tokio::spawn(index.clone().run(rx));\n        Self {\n            hook: Hook {\n                changes: HashMap::default(),\n                coordinator: tx.clone(),\n            }\n            .spawn(),\n            index,\n            coordinator: tx,\n        }\n    }\n}\n\n#[derive(Debug)]\nstruct Hook {\n    changes: HashMap<DocumentId, Change>,\n    coordinator: mpsc::UnboundedSender<Event>,\n}\n\nconst DEBOUNCE: Duration = Duration::from_secs(1);\n\nimpl AsyncHook for Hook {\n    type Event = Event;\n\n    fn handle_event(&mut self, event: Self::Event, timeout: Option<Instant>) -> Option<Instant> {\n        match event {\n            Event::Insert(_) => unreachable!(\"inserts are sent to the worker directly\"),\n            Event::Update(doc, change) => {\n                if let Some(pending_change) = self.changes.get_mut(&doc) {\n                    // If there is already a change waiting for this document, merge the two\n                    // changes together by composing the changesets and saving the new `text`.\n                    pending_change.changes =\n                        mem::take(&mut pending_change.changes).compose(change.changes);\n                    pending_change.text = change.text;\n                    Some(Instant::now() + DEBOUNCE)\n                } else if !is_changeset_significant(&change.changes) {\n                    // If the changeset is fairly large, debounce before updating the index.\n                    self.changes.insert(doc, change);\n                    Some(Instant::now() + DEBOUNCE)\n                } else {\n                    // Otherwise if the change is small, queue the update to the index immediately.\n                    self.coordinator.send(Event::Update(doc, change)).unwrap();\n                    timeout\n                }\n            }\n            Event::Delete(doc, text) => {\n                // If there are pending changes that haven't been indexed since the last debounce,\n                // forget them and delete the old text.\n                if let Some(change) = self.changes.remove(&doc) {\n                    self.coordinator\n                        .send(Event::Delete(doc, change.old_text))\n                        .unwrap();\n                } else {\n                    self.coordinator.send(Event::Delete(doc, text)).unwrap();\n                }\n                timeout\n            }\n            Event::Clear => unreachable!(\"clear is sent to the worker directly\"),\n        }\n    }\n\n    fn finish_debounce(&mut self) {\n        for (doc, change) in self.changes.drain() {\n            self.coordinator.send(Event::Update(doc, change)).unwrap();\n        }\n    }\n}\n\n/// Minimum number of grapheme clusters required to include a word in the index\nconst MIN_WORD_GRAPHEMES: usize = 3;\n/// Maximum word length allowed (in chars)\nconst MAX_WORD_LEN: usize = 50;\n\ntype Word = kstring::KString;\n\n#[derive(Debug, Default)]\nstruct WordIndexInner {\n    /// Reference counted storage for words.\n    ///\n    /// Words are very likely to be reused many times. Instead of storing duplicates we keep a\n    /// reference count of times a word is used. When the reference count drops to zero the word\n    /// is removed from the index.\n    words: HashMap<Word, u32>,\n}\n\nimpl WordIndexInner {\n    fn words(&self) -> impl Iterator<Item = &Word> {\n        self.words.keys()\n    }\n\n    fn insert(&mut self, word: RopeSlice) {\n        let word: Cow<str> = word.into();\n        if let Some(rc) = self.words.get_mut(word.as_ref()) {\n            *rc = rc.saturating_add(1);\n        } else {\n            let word = match word {\n                Cow::Owned(s) => Word::from_string(s),\n                Cow::Borrowed(s) => Word::from_ref(s),\n            };\n            self.words.insert(word, 1);\n        }\n    }\n\n    fn remove(&mut self, word: RopeSlice) {\n        let word: Cow<str> = word.into();\n        match self.words.get_mut(word.as_ref()) {\n            Some(1) => {\n                self.words.remove(word.as_ref());\n            }\n            Some(n) => *n -= 1,\n            None => (),\n        }\n    }\n\n    fn clear(&mut self) {\n        std::mem::take(&mut self.words);\n    }\n}\n\n#[derive(Debug, Default, Clone)]\npub struct WordIndex {\n    inner: Arc<RwLock<WordIndexInner>>,\n}\n\nimpl WordIndex {\n    pub fn matches(&self, pattern: &str) -> Vec<String> {\n        let inner = self.inner.read();\n        let mut matches = fuzzy_match(pattern, inner.words(), false);\n        matches.sort_unstable_by_key(|(_, score)| *score);\n        matches\n            .into_iter()\n            .map(|(word, _)| word.to_string())\n            .collect()\n    }\n\n    fn add_document(&self, text: &Rope) {\n        let mut inner = self.inner.write();\n        for word in words(text.slice(..)) {\n            inner.insert(word);\n        }\n    }\n\n    fn update_document(&self, old_text: &Rope, text: &Rope, changes: &ChangeSet) {\n        let mut inner = self.inner.write();\n        for (old_window, new_window) in changed_windows(old_text.slice(..), text.slice(..), changes)\n        {\n            for word in words(new_window) {\n                inner.insert(word);\n            }\n            for word in words(old_window) {\n                inner.remove(word);\n            }\n        }\n    }\n\n    fn remove_document(&self, text: &Rope) {\n        let mut inner = self.inner.write();\n        for word in words(text.slice(..)) {\n            inner.remove(word);\n        }\n    }\n\n    fn clear(&self) {\n        let mut inner = self.inner.write();\n        inner.clear();\n    }\n\n    /// Coordinate the indexing of documents.\n    ///\n    /// This task wraps a MPSC queue and spawns blocking tasks which update the index. Updates\n    /// are applied one-by-one to ensure that changes to the index are **serialized**:\n    /// updates to each document must be applied in-order.\n    async fn run(self, mut events: mpsc::UnboundedReceiver<Event>) {\n        while let Some(event) = events.recv().await {\n            let this = self.clone();\n            tokio::task::spawn_blocking(move || match event {\n                Event::Insert(text) => {\n                    this.add_document(&text);\n                }\n                Event::Update(\n                    _doc,\n                    Change {\n                        old_text,\n                        text,\n                        changes,\n                        ..\n                    },\n                ) => {\n                    this.update_document(&old_text, &text, &changes);\n                }\n                Event::Delete(_doc, text) => {\n                    this.remove_document(&text);\n                }\n                Event::Clear => {\n                    this.clear();\n                }\n            })\n            .await\n            .unwrap();\n        }\n    }\n}\n\nfn words(text: RopeSlice) -> impl Iterator<Item = RopeSlice> {\n    let mut cursor = Range::point(0);\n    if text\n        .get_char(cursor.anchor)\n        .is_some_and(|ch| !ch.is_whitespace())\n    {\n        let cursor_word_end = movement::move_next_word_end(text, cursor, 1);\n        if cursor_word_end.anchor == 0 {\n            cursor = cursor_word_end;\n        }\n    }\n\n    iter::from_fn(move || {\n        while cursor.head <= text.len_chars() {\n            let mut word = None;\n            if text\n                .slice(..cursor.head)\n                .graphemes_rev()\n                .take(MIN_WORD_GRAPHEMES)\n                .take_while(|g| g.chars().all(char_is_word))\n                .count()\n                == MIN_WORD_GRAPHEMES\n            {\n                cursor.anchor += text\n                    .chars_at(cursor.anchor)\n                    .take_while(|&c| !char_is_word(c))\n                    .count();\n                let slice = cursor.slice(text);\n                if slice.len_chars() <= MAX_WORD_LEN {\n                    word = Some(slice);\n                }\n            }\n            let head = cursor.head;\n            cursor = movement::move_next_word_end(text, cursor, 1);\n            if cursor.head == head {\n                cursor.head = usize::MAX;\n            }\n            if word.is_some() {\n                return word;\n            }\n        }\n        None\n    })\n}\n\n/// Finds areas of the old and new texts around each operation in `changes`.\n///\n/// The window is larger than the changed area and can encompass multiple insert/delete operations\n/// if they are grouped closely together.\n///\n/// The ranges of the old and new text should usually be of different sizes. For example a\n/// deletion of \"foo\" surrounded by large retain sections would give a longer window into the\n/// `old_text` and shorter window of `new_text`. Vice-versa for an insertion. A full replacement\n/// of a word though would give two slices of the same size.\nfn changed_windows<'a>(\n    old_text: RopeSlice<'a>,\n    new_text: RopeSlice<'a>,\n    changes: &'a ChangeSet,\n) -> impl Iterator<Item = (RopeSlice<'a>, RopeSlice<'a>)> {\n    use helix_core::Operation::*;\n\n    let mut operations = changes.changes().iter().peekable();\n    let mut old_pos = 0;\n    let mut new_pos = 0;\n    iter::from_fn(move || loop {\n        let operation = operations.next()?;\n        let old_start = old_pos;\n        let new_start = new_pos;\n        let len = operation.len_chars();\n        match operation {\n            Retain(_) => {\n                old_pos += len;\n                new_pos += len;\n                continue;\n            }\n            Insert(_) => new_pos += len,\n            Delete(_) => old_pos += len,\n        }\n\n        // Scan ahead until a `Retain` is found which would end a window.\n        while let Some(o) = operations.next_if(|op| !matches!(op, Retain(n) if *n > MAX_WORD_LEN)) {\n            let len = o.len_chars();\n            match o {\n                Retain(_) => {\n                    old_pos += len;\n                    new_pos += len;\n                }\n                Delete(_) => old_pos += len,\n                Insert(_) => new_pos += len,\n            }\n        }\n\n        let old_window = old_start.saturating_sub(MAX_WORD_LEN)\n            ..(old_pos + MAX_WORD_LEN).min(old_text.len_chars());\n        let new_window = new_start.saturating_sub(MAX_WORD_LEN)\n            ..(new_pos + MAX_WORD_LEN).min(new_text.len_chars());\n\n        return Some((old_text.slice(old_window), new_text.slice(new_window)));\n    })\n}\n\n/// Estimates whether a changeset is significant or small.\nfn is_changeset_significant(changes: &ChangeSet) -> bool {\n    use helix_core::Operation::*;\n\n    let mut diff = 0;\n    for operation in changes.changes() {\n        match operation {\n            Retain(_) => continue,\n            Delete(_) | Insert(_) => diff += operation.len_chars(),\n        }\n    }\n\n    // This is arbitrary and could be tuned further:\n    diff > 1_000\n}\n\npub(crate) fn register_hooks(handlers: &Handlers) {\n    let coordinator = handlers.word_index.coordinator.clone();\n    register_hook!(move |event: &mut DocumentDidOpen<'_>| {\n        let doc = doc!(event.editor, &event.doc);\n        if doc.word_completion_enabled() {\n            coordinator.send(Event::Insert(doc.text().clone())).unwrap();\n        }\n        Ok(())\n    });\n\n    let tx = handlers.word_index.hook.clone();\n    register_hook!(move |event: &mut DocumentDidChange<'_>| {\n        if !event.ghost_transaction && event.doc.word_completion_enabled() {\n            helix_event::send_blocking(\n                &tx,\n                Event::Update(\n                    event.doc.id(),\n                    Change {\n                        old_text: event.old_text.clone(),\n                        text: event.doc.text().clone(),\n                        changes: event.changes.clone(),\n                    },\n                ),\n            );\n        }\n        Ok(())\n    });\n\n    let tx = handlers.word_index.hook.clone();\n    register_hook!(move |event: &mut DocumentDidClose<'_>| {\n        if event.doc.word_completion_enabled() {\n            helix_event::send_blocking(\n                &tx,\n                Event::Delete(event.doc.id(), event.doc.text().clone()),\n            );\n        }\n        Ok(())\n    });\n\n    let coordinator = handlers.word_index.coordinator.clone();\n    register_hook!(move |event: &mut ConfigDidChange<'_>| {\n        // The feature has been turned off. Clear the index and reclaim any used memory.\n        if event.old.word_completion.enable && !event.new.word_completion.enable {\n            coordinator.send(Event::Clear).unwrap();\n        }\n\n        // The feature has been turned on. Index open documents.\n        if !event.old.word_completion.enable && event.new.word_completion.enable {\n            for doc in event.editor.documents() {\n                if doc.word_completion_enabled() {\n                    coordinator.send(Event::Insert(doc.text().clone())).unwrap();\n                }\n            }\n        }\n\n        Ok(())\n    });\n}\n\n#[cfg(test)]\nmod tests {\n    use std::collections::HashSet;\n\n    use super::*;\n    use helix_core::diff::compare_ropes;\n\n    impl WordIndex {\n        fn words(&self) -> HashSet<String> {\n            let inner = self.inner.read();\n            inner.words().map(|w| w.to_string()).collect()\n        }\n    }\n\n    #[track_caller]\n    fn assert_words<I: ToString, T: IntoIterator<Item = I>>(text: &str, expected: T) {\n        let text = Rope::from_str(text);\n        let index = WordIndex::default();\n        index.add_document(&text);\n        let actual = index.words();\n        let expected: HashSet<_> = expected.into_iter().map(|i| i.to_string()).collect();\n        assert_eq!(expected, actual);\n    }\n\n    #[test]\n    fn parse() {\n        assert_words(\"one two three\", [\"one\", \"two\", \"three\"]);\n        assert_words(\"a foo c\", [\"foo\"]);\n    }\n\n    #[track_caller]\n    fn assert_diff<S, R, I>(before: &str, after: &str, expect_removed: R, expect_inserted: I)\n    where\n        S: ToString,\n        R: IntoIterator<Item = S>,\n        I: IntoIterator<Item = S>,\n    {\n        let before = Rope::from_str(before);\n        let after = Rope::from_str(after);\n        let diff = compare_ropes(&before, &after);\n        let expect_removed: HashSet<_> =\n            expect_removed.into_iter().map(|i| i.to_string()).collect();\n        let expect_inserted: HashSet<_> =\n            expect_inserted.into_iter().map(|i| i.to_string()).collect();\n\n        let index = WordIndex::default();\n        index.add_document(&before);\n        let words_before = index.words();\n        index.update_document(&before, &after, diff.changes());\n        let words_after = index.words();\n\n        let actual_removed = words_before.difference(&words_after).cloned().collect();\n        let actual_inserted = words_after.difference(&words_before).cloned().collect();\n\n        eprintln!(\"\\\"{before}\\\" {words_before:?} => \\\"{after}\\\" {words_after:?}\");\n        assert_eq!(\n            expect_removed, actual_removed,\n            \"expected {expect_removed:?} to be removed, instead {actual_removed:?} was\"\n        );\n        assert_eq!(\n            expect_inserted, actual_inserted,\n            \"expected {expect_inserted:?} to be inserted, instead {actual_inserted:?} was\"\n        );\n    }\n\n    #[test]\n    fn diff() {\n        assert_diff(\"one two three\", \"one five three\", [\"two\"], [\"five\"]);\n        assert_diff(\"one two three\", \"one to three\", [\"two\"], []);\n        assert_diff(\"one two three\", \"one three\", [\"two\"], []);\n        assert_diff(\"one two three\", \"one t{o three\", [\"two\"], []);\n        assert_diff(\"one foo three\", \"one fooo three\", [\"foo\"], [\"fooo\"]);\n    }\n}\n"
  },
  {
    "path": "helix-view/src/handlers.rs",
    "content": "use completion::{CompletionEvent, CompletionHandler};\nuse helix_event::send_blocking;\nuse tokio::sync::mpsc::Sender;\n\nuse crate::handlers::lsp::SignatureHelpInvoked;\nuse crate::{DocumentId, Editor, ViewId};\n\npub mod completion;\npub mod dap;\npub mod diagnostics;\npub mod lsp;\npub mod word_index;\n\n#[derive(Debug)]\npub enum AutoSaveEvent {\n    DocumentChanged { save_after: u64 },\n    LeftInsertMode,\n}\n\npub struct Handlers {\n    // only public because most of the actual implementation is in helix-term right now :/\n    pub completions: CompletionHandler,\n    pub signature_hints: Sender<lsp::SignatureHelpEvent>,\n    pub auto_save: Sender<AutoSaveEvent>,\n    pub document_colors: Sender<lsp::DocumentColorsEvent>,\n    pub document_links: Sender<lsp::DocumentLinksEvent>,\n    pub word_index: word_index::Handler,\n    pub pull_diagnostics: Sender<lsp::PullDiagnosticsEvent>,\n    pub pull_all_documents_diagnostics: Sender<lsp::PullAllDocumentsDiagnosticsEvent>,\n}\n\nimpl Handlers {\n    /// Manually trigger completion (c-x)\n    pub fn trigger_completions(&self, trigger_pos: usize, doc: DocumentId, view: ViewId) {\n        self.completions.event(CompletionEvent::ManualTrigger {\n            cursor: trigger_pos,\n            doc,\n            view,\n        });\n    }\n\n    pub fn trigger_signature_help(&self, invocation: SignatureHelpInvoked, editor: &Editor) {\n        let event = match invocation {\n            SignatureHelpInvoked::Automatic => {\n                if !editor.config().lsp.auto_signature_help {\n                    return;\n                }\n                lsp::SignatureHelpEvent::Trigger\n            }\n            SignatureHelpInvoked::Manual => lsp::SignatureHelpEvent::Invoked,\n        };\n        send_blocking(&self.signature_hints, event)\n    }\n\n    pub fn word_index(&self) -> &word_index::WordIndex {\n        &self.word_index.index\n    }\n}\n\npub fn register_hooks(handlers: &Handlers) {\n    lsp::register_hooks(handlers);\n    word_index::register_hooks(handlers);\n}\n"
  },
  {
    "path": "helix-view/src/info.rs",
    "content": "use crate::register::Registers;\nuse helix_core::unicode::width::UnicodeWidthStr;\nuse std::{borrow::Cow, fmt::Write};\n\n#[derive(Debug)]\n/// Info box used in editor. Rendering logic will be in other crate.\npub struct Info {\n    /// Title shown at top.\n    pub title: Cow<'static, str>,\n    /// Text body, should contain newlines.\n    pub text: String,\n    /// Body width.\n    pub width: u16,\n    /// Body height.\n    pub height: u16,\n}\n\nimpl Info {\n    pub fn new<T, K, V>(title: T, body: &[(K, V)]) -> Self\n    where\n        T: Into<Cow<'static, str>>,\n        K: AsRef<str>,\n        V: AsRef<str>,\n    {\n        let title = title.into();\n        if body.is_empty() {\n            return Self {\n                height: 1,\n                width: title.len() as u16,\n                text: \"\".to_string(),\n                title,\n            };\n        }\n\n        let item_width = body\n            .iter()\n            .map(|(item, _)| item.as_ref().width())\n            .max()\n            .unwrap();\n        let mut text = String::new();\n\n        for (item, desc) in body {\n            let _ = writeln!(\n                text,\n                \"{:width$}  {}\",\n                item.as_ref(),\n                desc.as_ref(),\n                width = item_width\n            );\n        }\n\n        Self {\n            title,\n            width: text.lines().map(|l| l.width()).max().unwrap() as u16,\n            height: body.len() as u16,\n            text,\n        }\n    }\n\n    pub fn from_registers(title: impl Into<Cow<'static, str>>, registers: &Registers) -> Self {\n        let body: Vec<_> = registers\n            .iter_preview()\n            .map(|(ch, preview)| (ch.to_string(), preview))\n            .collect();\n\n        let mut infobox = Self::new(title, &body);\n        infobox.width = 30; // copied content could be very long\n        infobox\n    }\n}\n"
  },
  {
    "path": "helix-view/src/input.rs",
    "content": "//! Input event handling, currently backed by termina.\nuse anyhow::{anyhow, Error};\nuse helix_core::unicode::{segmentation::UnicodeSegmentation, width::UnicodeWidthStr};\nuse serde::de::{self, Deserialize, Deserializer};\nuse std::fmt;\n\npub use crate::keyboard::{KeyCode, KeyModifiers, MediaKeyCode, ModifierKeyCode};\n\n#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Hash)]\npub enum Event {\n    FocusGained,\n    FocusLost,\n    Key(KeyEvent),\n    Mouse(MouseEvent),\n    Paste(String),\n    Resize(u16, u16),\n    IdleTimeout,\n}\n\n#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]\npub struct MouseEvent {\n    /// The kind of mouse event that was caused.\n    pub kind: MouseEventKind,\n    /// The column that the event occurred on.\n    pub column: u16,\n    /// The row that the event occurred on.\n    pub row: u16,\n    /// The key modifiers active when the event occurred.\n    pub modifiers: KeyModifiers,\n}\n\n#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]\npub enum MouseEventKind {\n    /// Pressed mouse button. Contains the button that was pressed.\n    Down(MouseButton),\n    /// Released mouse button. Contains the button that was released.\n    Up(MouseButton),\n    /// Moved the mouse cursor while pressing the contained mouse button.\n    Drag(MouseButton),\n    /// Moved the mouse cursor while not pressing a mouse button.\n    Moved,\n    /// Scrolled mouse wheel downwards (towards the user).\n    ScrollDown,\n    /// Scrolled mouse wheel upwards (away from the user).\n    ScrollUp,\n    /// Scrolled mouse wheel leftwards.\n    ScrollLeft,\n    /// Scrolled mouse wheel rightwards.\n    ScrollRight,\n}\n\n/// Represents a mouse button.\n#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]\npub enum MouseButton {\n    /// Left mouse button.\n    Left,\n    /// Right mouse button.\n    Right,\n    /// Middle mouse button.\n    Middle,\n}\n/// Represents a key event.\n// We use a newtype here because we want to customize Deserialize and Display.\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]\npub struct KeyEvent {\n    pub code: KeyCode,\n    pub modifiers: KeyModifiers,\n    // TODO: termina now supports kind & state if terminal supports kitty's extended protocol\n}\n\nimpl KeyEvent {\n    /// If a character was pressed, return it.\n    pub fn char(&self) -> Option<char> {\n        match self.code {\n            KeyCode::Char(ch) => Some(ch),\n            _ => None,\n        }\n    }\n\n    /// Format the key in such a way that a concatenated sequence\n    /// of keys can be read easily.\n    ///\n    /// ```\n    /// # use std::str::FromStr;\n    /// # use helix_view::input::KeyEvent;\n    ///\n    /// let k = KeyEvent::from_str(\"w\").unwrap().key_sequence_format();\n    /// assert_eq!(k, \"w\");\n    ///\n    /// let k = KeyEvent::from_str(\"C-w\").unwrap().key_sequence_format();\n    /// assert_eq!(k, \"<C-w>\");\n    ///\n    /// let k = KeyEvent::from_str(\" \").unwrap().key_sequence_format();\n    /// assert_eq!(k, \"<space>\");\n    /// ```\n    pub fn key_sequence_format(&self) -> String {\n        let s = self.to_string();\n        if s.graphemes(true).count() > 1 {\n            format!(\"<{}>\", s)\n        } else {\n            s\n        }\n    }\n}\n\npub(crate) mod keys {\n    pub(crate) const BACKSPACE: &str = \"backspace\";\n    pub(crate) const ENTER: &str = \"ret\";\n    pub(crate) const LEFT: &str = \"left\";\n    pub(crate) const RIGHT: &str = \"right\";\n    pub(crate) const UP: &str = \"up\";\n    pub(crate) const DOWN: &str = \"down\";\n    pub(crate) const HOME: &str = \"home\";\n    pub(crate) const END: &str = \"end\";\n    pub(crate) const PAGEUP: &str = \"pageup\";\n    pub(crate) const PAGEDOWN: &str = \"pagedown\";\n    pub(crate) const TAB: &str = \"tab\";\n    pub(crate) const DELETE: &str = \"del\";\n    pub(crate) const INSERT: &str = \"ins\";\n    pub(crate) const NULL: &str = \"null\";\n    pub(crate) const ESC: &str = \"esc\";\n    pub(crate) const SPACE: &str = \"space\";\n    pub(crate) const MINUS: &str = \"minus\";\n    pub(crate) const LESS_THAN: &str = \"lt\";\n    pub(crate) const GREATER_THAN: &str = \"gt\";\n    pub(crate) const CAPS_LOCK: &str = \"capslock\";\n    pub(crate) const SCROLL_LOCK: &str = \"scrolllock\";\n    pub(crate) const NUM_LOCK: &str = \"numlock\";\n    pub(crate) const PRINT_SCREEN: &str = \"printscreen\";\n    pub(crate) const PAUSE: &str = \"pause\";\n    pub(crate) const MENU: &str = \"menu\";\n    pub(crate) const KEYPAD_BEGIN: &str = \"keypadbegin\";\n    pub(crate) const PLAY: &str = \"play\";\n    pub(crate) const PAUSE_MEDIA: &str = \"pausemedia\";\n    pub(crate) const PLAY_PAUSE: &str = \"playpause\";\n    pub(crate) const REVERSE: &str = \"reverse\";\n    pub(crate) const STOP: &str = \"stop\";\n    pub(crate) const FAST_FORWARD: &str = \"fastforward\";\n    pub(crate) const REWIND: &str = \"rewind\";\n    pub(crate) const TRACK_NEXT: &str = \"tracknext\";\n    pub(crate) const TRACK_PREVIOUS: &str = \"trackprevious\";\n    pub(crate) const RECORD: &str = \"record\";\n    pub(crate) const LOWER_VOLUME: &str = \"lowervolume\";\n    pub(crate) const RAISE_VOLUME: &str = \"raisevolume\";\n    pub(crate) const MUTE_VOLUME: &str = \"mutevolume\";\n    pub(crate) const LEFT_SHIFT: &str = \"leftshift\";\n    pub(crate) const LEFT_CONTROL: &str = \"leftcontrol\";\n    pub(crate) const LEFT_ALT: &str = \"leftalt\";\n    pub(crate) const LEFT_SUPER: &str = \"leftsuper\";\n    pub(crate) const LEFT_HYPER: &str = \"lefthyper\";\n    pub(crate) const LEFT_META: &str = \"leftmeta\";\n    pub(crate) const RIGHT_SHIFT: &str = \"rightshift\";\n    pub(crate) const RIGHT_CONTROL: &str = \"rightcontrol\";\n    pub(crate) const RIGHT_ALT: &str = \"rightalt\";\n    pub(crate) const RIGHT_SUPER: &str = \"rightsuper\";\n    pub(crate) const RIGHT_HYPER: &str = \"righthyper\";\n    pub(crate) const RIGHT_META: &str = \"rightmeta\";\n    pub(crate) const ISO_LEVEL_3_SHIFT: &str = \"isolevel3shift\";\n    pub(crate) const ISO_LEVEL_5_SHIFT: &str = \"isolevel5shift\";\n}\n\nimpl fmt::Display for KeyEvent {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {\n        f.write_fmt(format_args!(\n            \"{}{}{}{}\",\n            if self.modifiers.contains(KeyModifiers::SUPER) {\n                \"Meta-\"\n            } else {\n                \"\"\n            },\n            if self.modifiers.contains(KeyModifiers::SHIFT) {\n                \"S-\"\n            } else {\n                \"\"\n            },\n            if self.modifiers.contains(KeyModifiers::ALT) {\n                \"A-\"\n            } else {\n                \"\"\n            },\n            if self.modifiers.contains(KeyModifiers::CONTROL) {\n                \"C-\"\n            } else {\n                \"\"\n            },\n        ))?;\n        match self.code {\n            KeyCode::Backspace => f.write_str(keys::BACKSPACE)?,\n            KeyCode::Enter => f.write_str(keys::ENTER)?,\n            KeyCode::Left => f.write_str(keys::LEFT)?,\n            KeyCode::Right => f.write_str(keys::RIGHT)?,\n            KeyCode::Up => f.write_str(keys::UP)?,\n            KeyCode::Down => f.write_str(keys::DOWN)?,\n            KeyCode::Home => f.write_str(keys::HOME)?,\n            KeyCode::End => f.write_str(keys::END)?,\n            KeyCode::PageUp => f.write_str(keys::PAGEUP)?,\n            KeyCode::PageDown => f.write_str(keys::PAGEDOWN)?,\n            KeyCode::Tab => f.write_str(keys::TAB)?,\n            KeyCode::Delete => f.write_str(keys::DELETE)?,\n            KeyCode::Insert => f.write_str(keys::INSERT)?,\n            KeyCode::Null => f.write_str(keys::NULL)?,\n            KeyCode::Esc => f.write_str(keys::ESC)?,\n            KeyCode::Char(' ') => f.write_str(keys::SPACE)?,\n            KeyCode::Char('-') => f.write_str(keys::MINUS)?,\n            KeyCode::Char('<') => f.write_str(keys::LESS_THAN)?,\n            KeyCode::Char('>') => f.write_str(keys::GREATER_THAN)?,\n            KeyCode::F(i) => f.write_fmt(format_args!(\"F{}\", i))?,\n            KeyCode::Char(c) => f.write_fmt(format_args!(\"{}\", c))?,\n            KeyCode::CapsLock => f.write_str(keys::CAPS_LOCK)?,\n            KeyCode::ScrollLock => f.write_str(keys::SCROLL_LOCK)?,\n            KeyCode::NumLock => f.write_str(keys::NUM_LOCK)?,\n            KeyCode::PrintScreen => f.write_str(keys::PRINT_SCREEN)?,\n            KeyCode::Pause => f.write_str(keys::PAUSE)?,\n            KeyCode::Menu => f.write_str(keys::MENU)?,\n            KeyCode::KeypadBegin => f.write_str(keys::KEYPAD_BEGIN)?,\n            KeyCode::Media(MediaKeyCode::Play) => f.write_str(keys::PLAY)?,\n            KeyCode::Media(MediaKeyCode::Pause) => f.write_str(keys::PAUSE_MEDIA)?,\n            KeyCode::Media(MediaKeyCode::PlayPause) => f.write_str(keys::PLAY_PAUSE)?,\n            KeyCode::Media(MediaKeyCode::Stop) => f.write_str(keys::STOP)?,\n            KeyCode::Media(MediaKeyCode::Reverse) => f.write_str(keys::REVERSE)?,\n            KeyCode::Media(MediaKeyCode::FastForward) => f.write_str(keys::FAST_FORWARD)?,\n            KeyCode::Media(MediaKeyCode::Rewind) => f.write_str(keys::REWIND)?,\n            KeyCode::Media(MediaKeyCode::TrackNext) => f.write_str(keys::TRACK_NEXT)?,\n            KeyCode::Media(MediaKeyCode::TrackPrevious) => f.write_str(keys::TRACK_PREVIOUS)?,\n            KeyCode::Media(MediaKeyCode::Record) => f.write_str(keys::RECORD)?,\n            KeyCode::Media(MediaKeyCode::LowerVolume) => f.write_str(keys::LOWER_VOLUME)?,\n            KeyCode::Media(MediaKeyCode::RaiseVolume) => f.write_str(keys::RAISE_VOLUME)?,\n            KeyCode::Media(MediaKeyCode::MuteVolume) => f.write_str(keys::MUTE_VOLUME)?,\n            KeyCode::Modifier(ModifierKeyCode::LeftShift) => f.write_str(keys::LEFT_SHIFT)?,\n            KeyCode::Modifier(ModifierKeyCode::LeftControl) => f.write_str(keys::LEFT_CONTROL)?,\n            KeyCode::Modifier(ModifierKeyCode::LeftAlt) => f.write_str(keys::LEFT_ALT)?,\n            KeyCode::Modifier(ModifierKeyCode::LeftSuper) => f.write_str(keys::LEFT_SUPER)?,\n            KeyCode::Modifier(ModifierKeyCode::LeftHyper) => f.write_str(keys::LEFT_HYPER)?,\n            KeyCode::Modifier(ModifierKeyCode::LeftMeta) => f.write_str(keys::LEFT_META)?,\n            KeyCode::Modifier(ModifierKeyCode::RightShift) => f.write_str(keys::RIGHT_SHIFT)?,\n            KeyCode::Modifier(ModifierKeyCode::RightControl) => f.write_str(keys::RIGHT_CONTROL)?,\n            KeyCode::Modifier(ModifierKeyCode::RightAlt) => f.write_str(keys::RIGHT_ALT)?,\n            KeyCode::Modifier(ModifierKeyCode::RightSuper) => f.write_str(keys::RIGHT_SUPER)?,\n            KeyCode::Modifier(ModifierKeyCode::RightHyper) => f.write_str(keys::RIGHT_HYPER)?,\n            KeyCode::Modifier(ModifierKeyCode::RightMeta) => f.write_str(keys::RIGHT_META)?,\n            KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift) => {\n                f.write_str(keys::ISO_LEVEL_3_SHIFT)?\n            }\n            KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift) => {\n                f.write_str(keys::ISO_LEVEL_5_SHIFT)?\n            }\n        };\n        Ok(())\n    }\n}\n\nimpl UnicodeWidthStr for KeyEvent {\n    fn width(&self) -> usize {\n        use helix_core::unicode::width::UnicodeWidthChar;\n        let mut width = match self.code {\n            KeyCode::Backspace => keys::BACKSPACE.len(),\n            KeyCode::Enter => keys::ENTER.len(),\n            KeyCode::Left => keys::LEFT.len(),\n            KeyCode::Right => keys::RIGHT.len(),\n            KeyCode::Up => keys::UP.len(),\n            KeyCode::Down => keys::DOWN.len(),\n            KeyCode::Home => keys::HOME.len(),\n            KeyCode::End => keys::END.len(),\n            KeyCode::PageUp => keys::PAGEUP.len(),\n            KeyCode::PageDown => keys::PAGEDOWN.len(),\n            KeyCode::Tab => keys::TAB.len(),\n            KeyCode::Delete => keys::DELETE.len(),\n            KeyCode::Insert => keys::INSERT.len(),\n            KeyCode::Null => keys::NULL.len(),\n            KeyCode::Esc => keys::ESC.len(),\n            KeyCode::Char(' ') => keys::SPACE.len(),\n            KeyCode::Char('-') => keys::MINUS.len(),\n            KeyCode::F(1..=9) => 2,\n            KeyCode::F(_) => 3,\n            KeyCode::Char(c) => c.width().unwrap_or(0),\n            KeyCode::CapsLock => keys::CAPS_LOCK.len(),\n            KeyCode::ScrollLock => keys::SCROLL_LOCK.len(),\n            KeyCode::NumLock => keys::NUM_LOCK.len(),\n            KeyCode::PrintScreen => keys::PRINT_SCREEN.len(),\n            KeyCode::Pause => keys::PAUSE.len(),\n            KeyCode::Menu => keys::MENU.len(),\n            KeyCode::KeypadBegin => keys::KEYPAD_BEGIN.len(),\n            KeyCode::Media(MediaKeyCode::Play) => keys::PLAY.len(),\n            KeyCode::Media(MediaKeyCode::Pause) => keys::PAUSE_MEDIA.len(),\n            KeyCode::Media(MediaKeyCode::PlayPause) => keys::PLAY_PAUSE.len(),\n            KeyCode::Media(MediaKeyCode::Stop) => keys::STOP.len(),\n            KeyCode::Media(MediaKeyCode::Reverse) => keys::REVERSE.len(),\n            KeyCode::Media(MediaKeyCode::FastForward) => keys::FAST_FORWARD.len(),\n            KeyCode::Media(MediaKeyCode::Rewind) => keys::REWIND.len(),\n            KeyCode::Media(MediaKeyCode::TrackNext) => keys::TRACK_NEXT.len(),\n            KeyCode::Media(MediaKeyCode::TrackPrevious) => keys::TRACK_PREVIOUS.len(),\n            KeyCode::Media(MediaKeyCode::Record) => keys::RECORD.len(),\n            KeyCode::Media(MediaKeyCode::LowerVolume) => keys::LOWER_VOLUME.len(),\n            KeyCode::Media(MediaKeyCode::RaiseVolume) => keys::RAISE_VOLUME.len(),\n            KeyCode::Media(MediaKeyCode::MuteVolume) => keys::MUTE_VOLUME.len(),\n            KeyCode::Modifier(ModifierKeyCode::LeftShift) => keys::LEFT_SHIFT.len(),\n            KeyCode::Modifier(ModifierKeyCode::LeftControl) => keys::LEFT_CONTROL.len(),\n            KeyCode::Modifier(ModifierKeyCode::LeftAlt) => keys::LEFT_ALT.len(),\n            KeyCode::Modifier(ModifierKeyCode::LeftSuper) => keys::LEFT_SUPER.len(),\n            KeyCode::Modifier(ModifierKeyCode::LeftHyper) => keys::LEFT_HYPER.len(),\n            KeyCode::Modifier(ModifierKeyCode::LeftMeta) => keys::LEFT_META.len(),\n            KeyCode::Modifier(ModifierKeyCode::RightShift) => keys::RIGHT_SHIFT.len(),\n            KeyCode::Modifier(ModifierKeyCode::RightControl) => keys::RIGHT_CONTROL.len(),\n            KeyCode::Modifier(ModifierKeyCode::RightAlt) => keys::RIGHT_ALT.len(),\n            KeyCode::Modifier(ModifierKeyCode::RightSuper) => keys::RIGHT_SUPER.len(),\n            KeyCode::Modifier(ModifierKeyCode::RightHyper) => keys::RIGHT_HYPER.len(),\n            KeyCode::Modifier(ModifierKeyCode::RightMeta) => keys::RIGHT_META.len(),\n            KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift) => keys::ISO_LEVEL_3_SHIFT.len(),\n            KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift) => keys::ISO_LEVEL_5_SHIFT.len(),\n        };\n        if self.modifiers.contains(KeyModifiers::SHIFT) {\n            width += 2;\n        }\n        if self.modifiers.contains(KeyModifiers::ALT) {\n            width += 2;\n        }\n        if self.modifiers.contains(KeyModifiers::CONTROL) {\n            width += 2;\n        }\n        if self.modifiers.contains(KeyModifiers::SUPER) {\n            // \"-Meta\"\n            width += 5;\n        }\n        width\n    }\n\n    fn width_cjk(&self) -> usize {\n        self.width()\n    }\n}\n\nimpl std::str::FromStr for KeyEvent {\n    type Err = Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let mut tokens: Vec<_> = s.split('-').collect();\n        let mut code = match tokens.pop().ok_or_else(|| anyhow!(\"Missing key code\"))? {\n            keys::BACKSPACE => KeyCode::Backspace,\n            keys::ENTER => KeyCode::Enter,\n            keys::LEFT => KeyCode::Left,\n            keys::RIGHT => KeyCode::Right,\n            keys::UP => KeyCode::Up,\n            keys::DOWN => KeyCode::Down,\n            keys::HOME => KeyCode::Home,\n            keys::END => KeyCode::End,\n            keys::PAGEUP => KeyCode::PageUp,\n            keys::PAGEDOWN => KeyCode::PageDown,\n            keys::TAB => KeyCode::Tab,\n            keys::DELETE => KeyCode::Delete,\n            keys::INSERT => KeyCode::Insert,\n            keys::NULL => KeyCode::Null,\n            keys::ESC => KeyCode::Esc,\n            keys::SPACE => KeyCode::Char(' '),\n            keys::MINUS => KeyCode::Char('-'),\n            keys::LESS_THAN => KeyCode::Char('<'),\n            keys::GREATER_THAN => KeyCode::Char('>'),\n            keys::CAPS_LOCK => KeyCode::CapsLock,\n            keys::SCROLL_LOCK => KeyCode::ScrollLock,\n            keys::NUM_LOCK => KeyCode::NumLock,\n            keys::PRINT_SCREEN => KeyCode::PrintScreen,\n            keys::PAUSE => KeyCode::Pause,\n            keys::MENU => KeyCode::Menu,\n            keys::KEYPAD_BEGIN => KeyCode::KeypadBegin,\n            keys::PLAY => KeyCode::Media(MediaKeyCode::Play),\n            keys::PAUSE_MEDIA => KeyCode::Media(MediaKeyCode::Pause),\n            keys::PLAY_PAUSE => KeyCode::Media(MediaKeyCode::PlayPause),\n            keys::STOP => KeyCode::Media(MediaKeyCode::Stop),\n            keys::REVERSE => KeyCode::Media(MediaKeyCode::Reverse),\n            keys::FAST_FORWARD => KeyCode::Media(MediaKeyCode::FastForward),\n            keys::REWIND => KeyCode::Media(MediaKeyCode::Rewind),\n            keys::TRACK_NEXT => KeyCode::Media(MediaKeyCode::TrackNext),\n            keys::TRACK_PREVIOUS => KeyCode::Media(MediaKeyCode::TrackPrevious),\n            keys::RECORD => KeyCode::Media(MediaKeyCode::Record),\n            keys::LOWER_VOLUME => KeyCode::Media(MediaKeyCode::LowerVolume),\n            keys::RAISE_VOLUME => KeyCode::Media(MediaKeyCode::RaiseVolume),\n            keys::MUTE_VOLUME => KeyCode::Media(MediaKeyCode::MuteVolume),\n            keys::LEFT_SHIFT => KeyCode::Modifier(ModifierKeyCode::LeftShift),\n            keys::LEFT_CONTROL => KeyCode::Modifier(ModifierKeyCode::LeftControl),\n            keys::LEFT_ALT => KeyCode::Modifier(ModifierKeyCode::LeftAlt),\n            keys::LEFT_SUPER => KeyCode::Modifier(ModifierKeyCode::LeftSuper),\n            keys::LEFT_HYPER => KeyCode::Modifier(ModifierKeyCode::LeftHyper),\n            keys::LEFT_META => KeyCode::Modifier(ModifierKeyCode::LeftMeta),\n            keys::RIGHT_SHIFT => KeyCode::Modifier(ModifierKeyCode::RightShift),\n            keys::RIGHT_CONTROL => KeyCode::Modifier(ModifierKeyCode::RightControl),\n            keys::RIGHT_ALT => KeyCode::Modifier(ModifierKeyCode::RightAlt),\n            keys::RIGHT_SUPER => KeyCode::Modifier(ModifierKeyCode::RightSuper),\n            keys::RIGHT_HYPER => KeyCode::Modifier(ModifierKeyCode::RightHyper),\n            keys::RIGHT_META => KeyCode::Modifier(ModifierKeyCode::RightMeta),\n            keys::ISO_LEVEL_3_SHIFT => KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift),\n            keys::ISO_LEVEL_5_SHIFT => KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift),\n            single if single.chars().count() == 1 => KeyCode::Char(single.chars().next().unwrap()),\n            function if function.len() > 1 && function.starts_with('F') => {\n                let function: String = function.chars().skip(1).collect();\n                let function = str::parse::<u8>(&function)?;\n                (function > 0 && function < 25)\n                    .then_some(KeyCode::F(function))\n                    .ok_or_else(|| anyhow!(\"Invalid function key '{}'\", function))?\n            }\n            // Checking that the last token is empty ensures that this branch is only taken if\n            // `-` is used as a code. For example this branch will not be taken for `S-` (which is\n            // missing a code).\n            _ if s.ends_with('-') && tokens.last().is_some_and(|t| t.is_empty()) => {\n                if s == \"-\" {\n                    return Ok(KeyEvent {\n                        code: KeyCode::Char('-'),\n                        modifiers: KeyModifiers::empty(),\n                    });\n                } else {\n                    let suggestion = format!(\"{}-{}\", s.trim_end_matches('-'), keys::MINUS);\n                    return Err(anyhow!(\n                        \"Key '-' cannot be used with modifiers, use '{}' instead\",\n                        suggestion\n                    ));\n                }\n            }\n            invalid => return Err(anyhow!(\"Invalid key code '{}'\", invalid)),\n        };\n\n        let mut modifiers = KeyModifiers::empty();\n        for token in tokens {\n            let flag = match token {\n                \"S\" => KeyModifiers::SHIFT,\n                \"A\" => KeyModifiers::ALT,\n                \"C\" => KeyModifiers::CONTROL,\n                \"Meta\" | \"Cmd\" | \"Win\" => KeyModifiers::SUPER,\n                _ => return Err(anyhow!(\"Invalid key modifier '{}-'\", token)),\n            };\n\n            if modifiers.contains(flag) {\n                return Err(anyhow!(\"Repeated key modifier '{}-'\", token));\n            }\n            modifiers.insert(flag);\n        }\n\n        // Normalize character keys so that characters like C-S-r and C-R\n        // are represented by equal KeyEvents.\n        match code {\n            KeyCode::Char(ch)\n                if ch.is_ascii_lowercase() && modifiers.contains(KeyModifiers::SHIFT) =>\n            {\n                code = KeyCode::Char(ch.to_ascii_uppercase());\n                modifiers.remove(KeyModifiers::SHIFT);\n            }\n            _ => (),\n        }\n\n        Ok(KeyEvent { code, modifiers })\n    }\n}\n\nimpl<'de> Deserialize<'de> for KeyEvent {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let s = String::deserialize(deserializer)?;\n        s.parse().map_err(de::Error::custom)\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<termina::event::Event> for Event {\n    fn from(event: termina::event::Event) -> Self {\n        match event {\n            termina::event::Event::Key(key) => Self::Key(key.into()),\n            termina::event::Event::Mouse(mouse) => Self::Mouse(mouse.into()),\n            termina::event::Event::WindowResized(termina::WindowSize { rows, cols, .. }) => {\n                Self::Resize(cols, rows)\n            }\n            termina::event::Event::FocusIn => Self::FocusGained,\n            termina::event::Event::FocusOut => Self::FocusLost,\n            termina::event::Event::Paste(s) => Self::Paste(s),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<termina::event::MouseEvent> for MouseEvent {\n    fn from(\n        termina::event::MouseEvent {\n            kind,\n            column,\n            row,\n            modifiers,\n        }: termina::event::MouseEvent,\n    ) -> Self {\n        Self {\n            kind: kind.into(),\n            column,\n            row,\n            modifiers: modifiers.into(),\n        }\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<termina::event::MouseEventKind> for MouseEventKind {\n    fn from(kind: termina::event::MouseEventKind) -> Self {\n        match kind {\n            termina::event::MouseEventKind::Down(button) => Self::Down(button.into()),\n            termina::event::MouseEventKind::Up(button) => Self::Up(button.into()),\n            termina::event::MouseEventKind::Drag(button) => Self::Drag(button.into()),\n            termina::event::MouseEventKind::Moved => Self::Moved,\n            termina::event::MouseEventKind::ScrollDown => Self::ScrollDown,\n            termina::event::MouseEventKind::ScrollUp => Self::ScrollUp,\n            termina::event::MouseEventKind::ScrollLeft => Self::ScrollLeft,\n            termina::event::MouseEventKind::ScrollRight => Self::ScrollRight,\n        }\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<termina::event::MouseButton> for MouseButton {\n    fn from(button: termina::event::MouseButton) -> Self {\n        match button {\n            termina::event::MouseButton::Left => MouseButton::Left,\n            termina::event::MouseButton::Right => MouseButton::Right,\n            termina::event::MouseButton::Middle => MouseButton::Middle,\n        }\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<termina::event::KeyEvent> for KeyEvent {\n    fn from(\n        termina::event::KeyEvent {\n            code, modifiers, ..\n        }: termina::event::KeyEvent,\n    ) -> Self {\n        if code == termina::event::KeyCode::BackTab {\n            // special case for BackTab -> Shift-Tab\n            let mut modifiers: KeyModifiers = modifiers.into();\n            modifiers.insert(KeyModifiers::SHIFT);\n            Self {\n                code: KeyCode::Tab,\n                modifiers,\n            }\n        } else {\n            Self {\n                code: code.into(),\n                modifiers: modifiers.into(),\n            }\n        }\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<KeyEvent> for termina::event::KeyEvent {\n    fn from(KeyEvent { code, modifiers }: KeyEvent) -> Self {\n        if code == KeyCode::Tab && modifiers.contains(KeyModifiers::SHIFT) {\n            // special case for Shift-Tab -> BackTab\n            let mut modifiers = modifiers;\n            modifiers.remove(KeyModifiers::SHIFT);\n            termina::event::KeyEvent {\n                code: termina::event::KeyCode::BackTab,\n                modifiers: modifiers.into(),\n                kind: termina::event::KeyEventKind::Press,\n                state: termina::event::KeyEventState::NONE,\n            }\n        } else {\n            termina::event::KeyEvent {\n                code: code.into(),\n                modifiers: modifiers.into(),\n                kind: termina::event::KeyEventKind::Press,\n                state: termina::event::KeyEventState::NONE,\n            }\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<crossterm::event::Event> for Event {\n    fn from(event: crossterm::event::Event) -> Self {\n        match event {\n            crossterm::event::Event::Key(key) => Self::Key(key.into()),\n            crossterm::event::Event::Mouse(mouse) => Self::Mouse(mouse.into()),\n            crossterm::event::Event::Resize(w, h) => Self::Resize(w, h),\n            crossterm::event::Event::FocusGained => Self::FocusGained,\n            crossterm::event::Event::FocusLost => Self::FocusLost,\n            crossterm::event::Event::Paste(s) => Self::Paste(s),\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<crossterm::event::MouseEvent> for MouseEvent {\n    fn from(\n        crossterm::event::MouseEvent {\n            kind,\n            column,\n            row,\n            modifiers,\n        }: crossterm::event::MouseEvent,\n    ) -> Self {\n        Self {\n            kind: kind.into(),\n            column,\n            row,\n            modifiers: modifiers.into(),\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<crossterm::event::MouseEventKind> for MouseEventKind {\n    fn from(kind: crossterm::event::MouseEventKind) -> Self {\n        match kind {\n            crossterm::event::MouseEventKind::Down(button) => Self::Down(button.into()),\n            crossterm::event::MouseEventKind::Up(button) => Self::Up(button.into()),\n            crossterm::event::MouseEventKind::Drag(button) => Self::Drag(button.into()),\n            crossterm::event::MouseEventKind::Moved => Self::Moved,\n            crossterm::event::MouseEventKind::ScrollDown => Self::ScrollDown,\n            crossterm::event::MouseEventKind::ScrollUp => Self::ScrollUp,\n            crossterm::event::MouseEventKind::ScrollLeft => Self::ScrollLeft,\n            crossterm::event::MouseEventKind::ScrollRight => Self::ScrollRight,\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<crossterm::event::MouseButton> for MouseButton {\n    fn from(button: crossterm::event::MouseButton) -> Self {\n        match button {\n            crossterm::event::MouseButton::Left => MouseButton::Left,\n            crossterm::event::MouseButton::Right => MouseButton::Right,\n            crossterm::event::MouseButton::Middle => MouseButton::Middle,\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<crossterm::event::KeyEvent> for KeyEvent {\n    fn from(\n        crossterm::event::KeyEvent {\n            code, modifiers, ..\n        }: crossterm::event::KeyEvent,\n    ) -> Self {\n        if code == crossterm::event::KeyCode::BackTab {\n            // special case for BackTab -> Shift-Tab\n            let mut modifiers: KeyModifiers = modifiers.into();\n            modifiers.insert(KeyModifiers::SHIFT);\n            Self {\n                code: KeyCode::Tab,\n                modifiers,\n            }\n        } else {\n            Self {\n                code: code.into(),\n                modifiers: modifiers.into(),\n            }\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<KeyEvent> for crossterm::event::KeyEvent {\n    fn from(KeyEvent { code, modifiers }: KeyEvent) -> Self {\n        if code == KeyCode::Tab && modifiers.contains(KeyModifiers::SHIFT) {\n            // special case for Shift-Tab -> BackTab\n            let mut modifiers = modifiers;\n            modifiers.remove(KeyModifiers::SHIFT);\n            crossterm::event::KeyEvent {\n                code: crossterm::event::KeyCode::BackTab,\n                modifiers: modifiers.into(),\n                kind: crossterm::event::KeyEventKind::Press,\n                state: crossterm::event::KeyEventState::NONE,\n            }\n        } else {\n            crossterm::event::KeyEvent {\n                code: code.into(),\n                modifiers: modifiers.into(),\n                kind: crossterm::event::KeyEventKind::Press,\n                state: crossterm::event::KeyEventState::NONE,\n            }\n        }\n    }\n}\npub fn parse_macro(keys_str: &str) -> anyhow::Result<Vec<KeyEvent>> {\n    use anyhow::Context;\n    let mut keys_res: anyhow::Result<_> = Ok(Vec::new());\n    let mut i = 0;\n    while let Ok(keys) = &mut keys_res {\n        if i >= keys_str.len() {\n            break;\n        }\n        if !keys_str.is_char_boundary(i) {\n            i += 1;\n            continue;\n        }\n\n        let s = &keys_str[i..];\n        let mut end_i = 1;\n        while !s.is_char_boundary(end_i) {\n            end_i += 1;\n        }\n        let c = &s[..end_i];\n        if c == \">\" {\n            keys_res = Err(anyhow!(\"Unmatched '>'\"));\n        } else if c != \"<\" {\n            keys.push(if c == \"-\" { keys::MINUS } else { c });\n            i += end_i;\n        } else {\n            match s.find('>').context(\"'>' expected\") {\n                Ok(end_i) => {\n                    keys.push(&s[1..end_i]);\n                    i += end_i + 1;\n                }\n                Err(err) => keys_res = Err(err),\n            }\n        }\n    }\n    keys_res.and_then(|keys| keys.into_iter().map(str::parse).collect())\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn parsing_unmodified_keys() {\n        assert_eq!(\n            str::parse::<KeyEvent>(\"backspace\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Backspace,\n                modifiers: KeyModifiers::NONE\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"left\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Left,\n                modifiers: KeyModifiers::NONE\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\",\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char(','),\n                modifiers: KeyModifiers::NONE\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"w\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('w'),\n                modifiers: KeyModifiers::NONE\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"F12\").unwrap(),\n            KeyEvent {\n                code: KeyCode::F(12),\n                modifiers: KeyModifiers::NONE\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"%\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('%'),\n                modifiers: KeyModifiers::NONE\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\";\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char(';'),\n                modifiers: KeyModifiers::NONE\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\">\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('>'),\n                modifiers: KeyModifiers::NONE\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"<\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('<'),\n                modifiers: KeyModifiers::NONE\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"+\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('+'),\n                modifiers: KeyModifiers::NONE\n            }\n        );\n        assert_eq!(\n            str::parse::<KeyEvent>(\"-\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('-'),\n                modifiers: KeyModifiers::NONE,\n            }\n        );\n    }\n\n    #[test]\n    fn parsing_modified_keys() {\n        assert_eq!(\n            str::parse::<KeyEvent>(\"S-minus\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('-'),\n                modifiers: KeyModifiers::SHIFT\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"C-A-S-F12\").unwrap(),\n            KeyEvent {\n                code: KeyCode::F(12),\n                modifiers: KeyModifiers::SHIFT | KeyModifiers::CONTROL | KeyModifiers::ALT\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"S-C-2\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('2'),\n                modifiers: KeyModifiers::SHIFT | KeyModifiers::CONTROL\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"A-C-+\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('+'),\n                modifiers: KeyModifiers::ALT | KeyModifiers::CONTROL\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"C-S-r\").unwrap(),\n            str::parse::<KeyEvent>(\"C-R\").unwrap(),\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"S-w\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('W'),\n                modifiers: KeyModifiers::NONE\n            }\n        );\n\n        assert_eq!(\n            str::parse::<KeyEvent>(\"Meta-c\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('c'),\n                modifiers: KeyModifiers::SUPER\n            }\n        );\n        assert_eq!(\n            str::parse::<KeyEvent>(\"Win-s\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('s'),\n                modifiers: KeyModifiers::SUPER\n            }\n        );\n        assert_eq!(\n            str::parse::<KeyEvent>(\"Cmd-d\").unwrap(),\n            KeyEvent {\n                code: KeyCode::Char('d'),\n                modifiers: KeyModifiers::SUPER\n            }\n        );\n    }\n\n    #[test]\n    fn parsing_nonsensical_keys_fails() {\n        assert!(str::parse::<KeyEvent>(\"F25\").is_err());\n        assert!(str::parse::<KeyEvent>(\"F0\").is_err());\n        assert!(str::parse::<KeyEvent>(\"aaa\").is_err());\n        assert!(str::parse::<KeyEvent>(\"S-S-a\").is_err());\n        assert!(str::parse::<KeyEvent>(\"C-A-S-C-1\").is_err());\n        assert!(str::parse::<KeyEvent>(\"FU\").is_err());\n        assert!(str::parse::<KeyEvent>(\"123\").is_err());\n        assert!(str::parse::<KeyEvent>(\"S--\").is_err());\n        assert!(str::parse::<KeyEvent>(\"S-\").is_err());\n        assert!(str::parse::<KeyEvent>(\"S-percent\").is_err());\n    }\n\n    #[test]\n    fn parsing_unsupported_named_keys() {\n        assert!(str::parse::<KeyEvent>(\"plus\").is_err());\n        assert!(str::parse::<KeyEvent>(\"percent\").is_err());\n        assert!(str::parse::<KeyEvent>(\"semicolon\").is_err());\n    }\n\n    #[test]\n    fn parsing_valid_macros() {\n        assert_eq!(\n            parse_macro(\"xdo\").ok(),\n            Some(vec![\n                KeyEvent {\n                    code: KeyCode::Char('x'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('d'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('o'),\n                    modifiers: KeyModifiers::NONE,\n                },\n            ]),\n        );\n\n        assert_eq!(\n            parse_macro(\"<C-w>v<C-w>h<C-o>xx<A-s>\").ok(),\n            Some(vec![\n                KeyEvent {\n                    code: KeyCode::Char('w'),\n                    modifiers: KeyModifiers::CONTROL,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('v'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('w'),\n                    modifiers: KeyModifiers::CONTROL,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('h'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('o'),\n                    modifiers: KeyModifiers::CONTROL,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('x'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('x'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('s'),\n                    modifiers: KeyModifiers::ALT,\n                },\n            ])\n        );\n\n        assert_eq!(\n            parse_macro(\":o foo.bar<ret>\").ok(),\n            Some(vec![\n                KeyEvent {\n                    code: KeyCode::Char(':'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('o'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char(' '),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('f'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('o'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('o'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('.'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('b'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('a'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('r'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Enter,\n                    modifiers: KeyModifiers::NONE,\n                },\n            ])\n        );\n\n        assert_eq!(\n            parse_macro(\":w aa-bb.txt<ret>\").ok(),\n            Some(vec![\n                KeyEvent {\n                    code: KeyCode::Char(':'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('w'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char(' '),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('a'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('a'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('-'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('b'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('b'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('.'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('t'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('x'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Char('t'),\n                    modifiers: KeyModifiers::NONE,\n                },\n                KeyEvent {\n                    code: KeyCode::Enter,\n                    modifiers: KeyModifiers::NONE,\n                },\n            ])\n        );\n    }\n\n    #[test]\n    fn parsing_invalid_macros_fails() {\n        assert!(parse_macro(\"abc<C-\").is_err());\n        assert!(parse_macro(\"abc>123\").is_err());\n        assert!(parse_macro(\"wd<foo>\").is_err());\n    }\n}\n"
  },
  {
    "path": "helix-view/src/keyboard.rs",
    "content": "use bitflags::bitflags;\n\nbitflags! {\n    /// Represents key modifiers (shift, control, alt).\n    #[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]\n    pub struct KeyModifiers: u8 {\n        const SHIFT = 0b0000_0001;\n        const CONTROL = 0b0000_0010;\n        const ALT = 0b0000_0100;\n        const SUPER = 0b0000_1000;\n        const NONE = 0b0000_0000;\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<KeyModifiers> for termina::event::Modifiers {\n    fn from(key_modifiers: KeyModifiers) -> Self {\n        use termina::event::Modifiers as CKeyModifiers;\n\n        let mut result = CKeyModifiers::NONE;\n\n        if key_modifiers.contains(KeyModifiers::SHIFT) {\n            result.insert(CKeyModifiers::SHIFT);\n        }\n        if key_modifiers.contains(KeyModifiers::CONTROL) {\n            result.insert(CKeyModifiers::CONTROL);\n        }\n        if key_modifiers.contains(KeyModifiers::ALT) {\n            result.insert(CKeyModifiers::ALT);\n        }\n        if key_modifiers.contains(KeyModifiers::SUPER) {\n            result.insert(CKeyModifiers::SUPER);\n        }\n\n        result\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<termina::event::Modifiers> for KeyModifiers {\n    fn from(val: termina::event::Modifiers) -> Self {\n        use termina::event::Modifiers as CKeyModifiers;\n\n        let mut result = KeyModifiers::NONE;\n\n        if val.contains(CKeyModifiers::SHIFT) {\n            result.insert(KeyModifiers::SHIFT);\n        }\n        if val.contains(CKeyModifiers::CONTROL) {\n            result.insert(KeyModifiers::CONTROL);\n        }\n        if val.contains(CKeyModifiers::ALT) {\n            result.insert(KeyModifiers::ALT);\n        }\n        if val.contains(CKeyModifiers::SUPER) {\n            result.insert(KeyModifiers::SUPER);\n        }\n\n        result\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<KeyModifiers> for crossterm::event::KeyModifiers {\n    fn from(key_modifiers: KeyModifiers) -> Self {\n        use crossterm::event::KeyModifiers as CKeyModifiers;\n\n        let mut result = CKeyModifiers::NONE;\n\n        if key_modifiers.contains(KeyModifiers::SHIFT) {\n            result.insert(CKeyModifiers::SHIFT);\n        }\n        if key_modifiers.contains(KeyModifiers::CONTROL) {\n            result.insert(CKeyModifiers::CONTROL);\n        }\n        if key_modifiers.contains(KeyModifiers::ALT) {\n            result.insert(CKeyModifiers::ALT);\n        }\n        if key_modifiers.contains(KeyModifiers::SUPER) {\n            result.insert(CKeyModifiers::SUPER);\n        }\n\n        result\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<crossterm::event::KeyModifiers> for KeyModifiers {\n    fn from(val: crossterm::event::KeyModifiers) -> Self {\n        use crossterm::event::KeyModifiers as CKeyModifiers;\n\n        let mut result = KeyModifiers::NONE;\n\n        if val.contains(CKeyModifiers::SHIFT) {\n            result.insert(KeyModifiers::SHIFT);\n        }\n        if val.contains(CKeyModifiers::CONTROL) {\n            result.insert(KeyModifiers::CONTROL);\n        }\n        if val.contains(CKeyModifiers::ALT) {\n            result.insert(KeyModifiers::ALT);\n        }\n        if val.contains(CKeyModifiers::SUPER) {\n            result.insert(KeyModifiers::SUPER);\n        }\n\n        result\n    }\n}\n/// Represents a media key (as part of [`KeyCode::Media`]).\n#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]\npub enum MediaKeyCode {\n    /// Play media key.\n    Play,\n    /// Pause media key.\n    Pause,\n    /// Play/Pause media key.\n    PlayPause,\n    /// Reverse media key.\n    Reverse,\n    /// Stop media key.\n    Stop,\n    /// Fast-forward media key.\n    FastForward,\n    /// Rewind media key.\n    Rewind,\n    /// Next-track media key.\n    TrackNext,\n    /// Previous-track media key.\n    TrackPrevious,\n    /// Record media key.\n    Record,\n    /// Lower-volume media key.\n    LowerVolume,\n    /// Raise-volume media key.\n    RaiseVolume,\n    /// Mute media key.\n    MuteVolume,\n}\n\n#[cfg(feature = \"term\")]\nimpl From<MediaKeyCode> for termina::event::MediaKeyCode {\n    fn from(media_key_code: MediaKeyCode) -> Self {\n        use termina::event::MediaKeyCode as CMediaKeyCode;\n\n        match media_key_code {\n            MediaKeyCode::Play => CMediaKeyCode::Play,\n            MediaKeyCode::Pause => CMediaKeyCode::Pause,\n            MediaKeyCode::PlayPause => CMediaKeyCode::PlayPause,\n            MediaKeyCode::Reverse => CMediaKeyCode::Reverse,\n            MediaKeyCode::Stop => CMediaKeyCode::Stop,\n            MediaKeyCode::FastForward => CMediaKeyCode::FastForward,\n            MediaKeyCode::Rewind => CMediaKeyCode::Rewind,\n            MediaKeyCode::TrackNext => CMediaKeyCode::TrackNext,\n            MediaKeyCode::TrackPrevious => CMediaKeyCode::TrackPrevious,\n            MediaKeyCode::Record => CMediaKeyCode::Record,\n            MediaKeyCode::LowerVolume => CMediaKeyCode::LowerVolume,\n            MediaKeyCode::RaiseVolume => CMediaKeyCode::RaiseVolume,\n            MediaKeyCode::MuteVolume => CMediaKeyCode::MuteVolume,\n        }\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<termina::event::MediaKeyCode> for MediaKeyCode {\n    fn from(val: termina::event::MediaKeyCode) -> Self {\n        use termina::event::MediaKeyCode as CMediaKeyCode;\n\n        match val {\n            CMediaKeyCode::Play => MediaKeyCode::Play,\n            CMediaKeyCode::Pause => MediaKeyCode::Pause,\n            CMediaKeyCode::PlayPause => MediaKeyCode::PlayPause,\n            CMediaKeyCode::Reverse => MediaKeyCode::Reverse,\n            CMediaKeyCode::Stop => MediaKeyCode::Stop,\n            CMediaKeyCode::FastForward => MediaKeyCode::FastForward,\n            CMediaKeyCode::Rewind => MediaKeyCode::Rewind,\n            CMediaKeyCode::TrackNext => MediaKeyCode::TrackNext,\n            CMediaKeyCode::TrackPrevious => MediaKeyCode::TrackPrevious,\n            CMediaKeyCode::Record => MediaKeyCode::Record,\n            CMediaKeyCode::LowerVolume => MediaKeyCode::LowerVolume,\n            CMediaKeyCode::RaiseVolume => MediaKeyCode::RaiseVolume,\n            CMediaKeyCode::MuteVolume => MediaKeyCode::MuteVolume,\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<MediaKeyCode> for crossterm::event::MediaKeyCode {\n    fn from(media_key_code: MediaKeyCode) -> Self {\n        use crossterm::event::MediaKeyCode as CMediaKeyCode;\n\n        match media_key_code {\n            MediaKeyCode::Play => CMediaKeyCode::Play,\n            MediaKeyCode::Pause => CMediaKeyCode::Pause,\n            MediaKeyCode::PlayPause => CMediaKeyCode::PlayPause,\n            MediaKeyCode::Reverse => CMediaKeyCode::Reverse,\n            MediaKeyCode::Stop => CMediaKeyCode::Stop,\n            MediaKeyCode::FastForward => CMediaKeyCode::FastForward,\n            MediaKeyCode::Rewind => CMediaKeyCode::Rewind,\n            MediaKeyCode::TrackNext => CMediaKeyCode::TrackNext,\n            MediaKeyCode::TrackPrevious => CMediaKeyCode::TrackPrevious,\n            MediaKeyCode::Record => CMediaKeyCode::Record,\n            MediaKeyCode::LowerVolume => CMediaKeyCode::LowerVolume,\n            MediaKeyCode::RaiseVolume => CMediaKeyCode::RaiseVolume,\n            MediaKeyCode::MuteVolume => CMediaKeyCode::MuteVolume,\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<crossterm::event::MediaKeyCode> for MediaKeyCode {\n    fn from(val: crossterm::event::MediaKeyCode) -> Self {\n        use crossterm::event::MediaKeyCode as CMediaKeyCode;\n\n        match val {\n            CMediaKeyCode::Play => MediaKeyCode::Play,\n            CMediaKeyCode::Pause => MediaKeyCode::Pause,\n            CMediaKeyCode::PlayPause => MediaKeyCode::PlayPause,\n            CMediaKeyCode::Reverse => MediaKeyCode::Reverse,\n            CMediaKeyCode::Stop => MediaKeyCode::Stop,\n            CMediaKeyCode::FastForward => MediaKeyCode::FastForward,\n            CMediaKeyCode::Rewind => MediaKeyCode::Rewind,\n            CMediaKeyCode::TrackNext => MediaKeyCode::TrackNext,\n            CMediaKeyCode::TrackPrevious => MediaKeyCode::TrackPrevious,\n            CMediaKeyCode::Record => MediaKeyCode::Record,\n            CMediaKeyCode::LowerVolume => MediaKeyCode::LowerVolume,\n            CMediaKeyCode::RaiseVolume => MediaKeyCode::RaiseVolume,\n            CMediaKeyCode::MuteVolume => MediaKeyCode::MuteVolume,\n        }\n    }\n}\n/// Represents a media key (as part of [`KeyCode::Modifier`]).\n#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]\npub enum ModifierKeyCode {\n    /// Left Shift key.\n    LeftShift,\n    /// Left Control key.\n    LeftControl,\n    /// Left Alt key.\n    LeftAlt,\n    /// Left Super key.\n    LeftSuper,\n    /// Left Hyper key.\n    LeftHyper,\n    /// Left Meta key.\n    LeftMeta,\n    /// Right Shift key.\n    RightShift,\n    /// Right Control key.\n    RightControl,\n    /// Right Alt key.\n    RightAlt,\n    /// Right Super key.\n    RightSuper,\n    /// Right Hyper key.\n    RightHyper,\n    /// Right Meta key.\n    RightMeta,\n    /// Iso Level3 Shift key.\n    IsoLevel3Shift,\n    /// Iso Level5 Shift key.\n    IsoLevel5Shift,\n}\n\n#[cfg(feature = \"term\")]\nimpl From<ModifierKeyCode> for termina::event::ModifierKeyCode {\n    fn from(modifier_key_code: ModifierKeyCode) -> Self {\n        use termina::event::ModifierKeyCode as CModifierKeyCode;\n\n        match modifier_key_code {\n            ModifierKeyCode::LeftShift => CModifierKeyCode::LeftShift,\n            ModifierKeyCode::LeftControl => CModifierKeyCode::LeftControl,\n            ModifierKeyCode::LeftAlt => CModifierKeyCode::LeftAlt,\n            ModifierKeyCode::LeftSuper => CModifierKeyCode::LeftSuper,\n            ModifierKeyCode::LeftHyper => CModifierKeyCode::LeftHyper,\n            ModifierKeyCode::LeftMeta => CModifierKeyCode::LeftMeta,\n            ModifierKeyCode::RightShift => CModifierKeyCode::RightShift,\n            ModifierKeyCode::RightControl => CModifierKeyCode::RightControl,\n            ModifierKeyCode::RightAlt => CModifierKeyCode::RightAlt,\n            ModifierKeyCode::RightSuper => CModifierKeyCode::RightSuper,\n            ModifierKeyCode::RightHyper => CModifierKeyCode::RightHyper,\n            ModifierKeyCode::RightMeta => CModifierKeyCode::RightMeta,\n            ModifierKeyCode::IsoLevel3Shift => CModifierKeyCode::IsoLevel3Shift,\n            ModifierKeyCode::IsoLevel5Shift => CModifierKeyCode::IsoLevel5Shift,\n        }\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<termina::event::ModifierKeyCode> for ModifierKeyCode {\n    fn from(val: termina::event::ModifierKeyCode) -> Self {\n        use termina::event::ModifierKeyCode as CModifierKeyCode;\n\n        match val {\n            CModifierKeyCode::LeftShift => ModifierKeyCode::LeftShift,\n            CModifierKeyCode::LeftControl => ModifierKeyCode::LeftControl,\n            CModifierKeyCode::LeftAlt => ModifierKeyCode::LeftAlt,\n            CModifierKeyCode::LeftSuper => ModifierKeyCode::LeftSuper,\n            CModifierKeyCode::LeftHyper => ModifierKeyCode::LeftHyper,\n            CModifierKeyCode::LeftMeta => ModifierKeyCode::LeftMeta,\n            CModifierKeyCode::RightShift => ModifierKeyCode::RightShift,\n            CModifierKeyCode::RightControl => ModifierKeyCode::RightControl,\n            CModifierKeyCode::RightAlt => ModifierKeyCode::RightAlt,\n            CModifierKeyCode::RightSuper => ModifierKeyCode::RightSuper,\n            CModifierKeyCode::RightHyper => ModifierKeyCode::RightHyper,\n            CModifierKeyCode::RightMeta => ModifierKeyCode::RightMeta,\n            CModifierKeyCode::IsoLevel3Shift => ModifierKeyCode::IsoLevel3Shift,\n            CModifierKeyCode::IsoLevel5Shift => ModifierKeyCode::IsoLevel5Shift,\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<ModifierKeyCode> for crossterm::event::ModifierKeyCode {\n    fn from(modifier_key_code: ModifierKeyCode) -> Self {\n        use crossterm::event::ModifierKeyCode as CModifierKeyCode;\n\n        match modifier_key_code {\n            ModifierKeyCode::LeftShift => CModifierKeyCode::LeftShift,\n            ModifierKeyCode::LeftControl => CModifierKeyCode::LeftControl,\n            ModifierKeyCode::LeftAlt => CModifierKeyCode::LeftAlt,\n            ModifierKeyCode::LeftSuper => CModifierKeyCode::LeftSuper,\n            ModifierKeyCode::LeftHyper => CModifierKeyCode::LeftHyper,\n            ModifierKeyCode::LeftMeta => CModifierKeyCode::LeftMeta,\n            ModifierKeyCode::RightShift => CModifierKeyCode::RightShift,\n            ModifierKeyCode::RightControl => CModifierKeyCode::RightControl,\n            ModifierKeyCode::RightAlt => CModifierKeyCode::RightAlt,\n            ModifierKeyCode::RightSuper => CModifierKeyCode::RightSuper,\n            ModifierKeyCode::RightHyper => CModifierKeyCode::RightHyper,\n            ModifierKeyCode::RightMeta => CModifierKeyCode::RightMeta,\n            ModifierKeyCode::IsoLevel3Shift => CModifierKeyCode::IsoLevel3Shift,\n            ModifierKeyCode::IsoLevel5Shift => CModifierKeyCode::IsoLevel5Shift,\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<crossterm::event::ModifierKeyCode> for ModifierKeyCode {\n    fn from(val: crossterm::event::ModifierKeyCode) -> Self {\n        use crossterm::event::ModifierKeyCode as CModifierKeyCode;\n\n        match val {\n            CModifierKeyCode::LeftShift => ModifierKeyCode::LeftShift,\n            CModifierKeyCode::LeftControl => ModifierKeyCode::LeftControl,\n            CModifierKeyCode::LeftAlt => ModifierKeyCode::LeftAlt,\n            CModifierKeyCode::LeftSuper => ModifierKeyCode::LeftSuper,\n            CModifierKeyCode::LeftHyper => ModifierKeyCode::LeftHyper,\n            CModifierKeyCode::LeftMeta => ModifierKeyCode::LeftMeta,\n            CModifierKeyCode::RightShift => ModifierKeyCode::RightShift,\n            CModifierKeyCode::RightControl => ModifierKeyCode::RightControl,\n            CModifierKeyCode::RightAlt => ModifierKeyCode::RightAlt,\n            CModifierKeyCode::RightSuper => ModifierKeyCode::RightSuper,\n            CModifierKeyCode::RightHyper => ModifierKeyCode::RightHyper,\n            CModifierKeyCode::RightMeta => ModifierKeyCode::RightMeta,\n            CModifierKeyCode::IsoLevel3Shift => ModifierKeyCode::IsoLevel3Shift,\n            CModifierKeyCode::IsoLevel5Shift => ModifierKeyCode::IsoLevel5Shift,\n        }\n    }\n}\n/// Represents a key.\n#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]\npub enum KeyCode {\n    /// Backspace key.\n    Backspace,\n    /// Enter key.\n    Enter,\n    /// Left arrow key.\n    Left,\n    /// Right arrow key.\n    Right,\n    /// Up arrow key.\n    Up,\n    /// Down arrow key.\n    Down,\n    /// Home key.\n    Home,\n    /// End key.\n    End,\n    /// Page up key.\n    PageUp,\n    /// Page down key.\n    PageDown,\n    /// Tab key.\n    Tab,\n    /// Delete key.\n    Delete,\n    /// Insert key.\n    Insert,\n    /// F key.\n    ///\n    /// `KeyCode::F(1)` represents F1 key, etc.\n    F(u8),\n    /// A character.\n    ///\n    /// `KeyCode::Char('c')` represents `c` character, etc.\n    Char(char),\n    /// Null.\n    Null,\n    /// Escape key.\n    Esc,\n    /// CapsLock key.\n    CapsLock,\n    /// ScrollLock key.\n    ScrollLock,\n    /// NumLock key.\n    NumLock,\n    /// PrintScreen key.\n    PrintScreen,\n    /// Pause key.\n    Pause,\n    /// Menu key.\n    Menu,\n    /// KeypadBegin key.\n    KeypadBegin,\n    /// A media key.\n    Media(MediaKeyCode),\n    /// A modifier key.\n    Modifier(ModifierKeyCode),\n}\n\n#[cfg(feature = \"term\")]\nimpl From<KeyCode> for termina::event::KeyCode {\n    fn from(key_code: KeyCode) -> Self {\n        use termina::event::KeyCode as CKeyCode;\n\n        match key_code {\n            KeyCode::Backspace => CKeyCode::Backspace,\n            KeyCode::Enter => CKeyCode::Enter,\n            KeyCode::Left => CKeyCode::Left,\n            KeyCode::Right => CKeyCode::Right,\n            KeyCode::Up => CKeyCode::Up,\n            KeyCode::Down => CKeyCode::Down,\n            KeyCode::Home => CKeyCode::Home,\n            KeyCode::End => CKeyCode::End,\n            KeyCode::PageUp => CKeyCode::PageUp,\n            KeyCode::PageDown => CKeyCode::PageDown,\n            KeyCode::Tab => CKeyCode::Tab,\n            KeyCode::Delete => CKeyCode::Delete,\n            KeyCode::Insert => CKeyCode::Insert,\n            KeyCode::F(f_number) => CKeyCode::Function(f_number),\n            KeyCode::Char(character) => CKeyCode::Char(character),\n            KeyCode::Null => CKeyCode::Null,\n            KeyCode::Esc => CKeyCode::Escape,\n            KeyCode::CapsLock => CKeyCode::CapsLock,\n            KeyCode::ScrollLock => CKeyCode::ScrollLock,\n            KeyCode::NumLock => CKeyCode::NumLock,\n            KeyCode::PrintScreen => CKeyCode::PrintScreen,\n            KeyCode::Pause => CKeyCode::Pause,\n            KeyCode::Menu => CKeyCode::Menu,\n            KeyCode::KeypadBegin => CKeyCode::KeypadBegin,\n            KeyCode::Media(media_key_code) => CKeyCode::Media(media_key_code.into()),\n            KeyCode::Modifier(modifier_key_code) => CKeyCode::Modifier(modifier_key_code.into()),\n        }\n    }\n}\n\n#[cfg(feature = \"term\")]\nimpl From<termina::event::KeyCode> for KeyCode {\n    fn from(val: termina::event::KeyCode) -> Self {\n        use termina::event::KeyCode as CKeyCode;\n\n        match val {\n            CKeyCode::Backspace => KeyCode::Backspace,\n            CKeyCode::Enter => KeyCode::Enter,\n            CKeyCode::Left => KeyCode::Left,\n            CKeyCode::Right => KeyCode::Right,\n            CKeyCode::Up => KeyCode::Up,\n            CKeyCode::Down => KeyCode::Down,\n            CKeyCode::Home => KeyCode::Home,\n            CKeyCode::End => KeyCode::End,\n            CKeyCode::PageUp => KeyCode::PageUp,\n            CKeyCode::PageDown => KeyCode::PageDown,\n            CKeyCode::Tab => KeyCode::Tab,\n            CKeyCode::BackTab => unreachable!(\"BackTab should have been handled on KeyEvent level\"),\n            CKeyCode::Delete => KeyCode::Delete,\n            CKeyCode::Insert => KeyCode::Insert,\n            CKeyCode::Function(f_number) => KeyCode::F(f_number),\n            CKeyCode::Char(character) => KeyCode::Char(character),\n            CKeyCode::Null => KeyCode::Null,\n            CKeyCode::Escape => KeyCode::Esc,\n            CKeyCode::CapsLock => KeyCode::CapsLock,\n            CKeyCode::ScrollLock => KeyCode::ScrollLock,\n            CKeyCode::NumLock => KeyCode::NumLock,\n            CKeyCode::PrintScreen => KeyCode::PrintScreen,\n            CKeyCode::Pause => KeyCode::Pause,\n            CKeyCode::Menu => KeyCode::Menu,\n            CKeyCode::KeypadBegin => KeyCode::KeypadBegin,\n            CKeyCode::Media(media_key_code) => KeyCode::Media(media_key_code.into()),\n            CKeyCode::Modifier(modifier_key_code) => KeyCode::Modifier(modifier_key_code.into()),\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<KeyCode> for crossterm::event::KeyCode {\n    fn from(key_code: KeyCode) -> Self {\n        use crossterm::event::KeyCode as CKeyCode;\n\n        match key_code {\n            KeyCode::Backspace => CKeyCode::Backspace,\n            KeyCode::Enter => CKeyCode::Enter,\n            KeyCode::Left => CKeyCode::Left,\n            KeyCode::Right => CKeyCode::Right,\n            KeyCode::Up => CKeyCode::Up,\n            KeyCode::Down => CKeyCode::Down,\n            KeyCode::Home => CKeyCode::Home,\n            KeyCode::End => CKeyCode::End,\n            KeyCode::PageUp => CKeyCode::PageUp,\n            KeyCode::PageDown => CKeyCode::PageDown,\n            KeyCode::Tab => CKeyCode::Tab,\n            KeyCode::Delete => CKeyCode::Delete,\n            KeyCode::Insert => CKeyCode::Insert,\n            KeyCode::F(f_number) => CKeyCode::F(f_number),\n            KeyCode::Char(character) => CKeyCode::Char(character),\n            KeyCode::Null => CKeyCode::Null,\n            KeyCode::Esc => CKeyCode::Esc,\n            KeyCode::CapsLock => CKeyCode::CapsLock,\n            KeyCode::ScrollLock => CKeyCode::ScrollLock,\n            KeyCode::NumLock => CKeyCode::NumLock,\n            KeyCode::PrintScreen => CKeyCode::PrintScreen,\n            KeyCode::Pause => CKeyCode::Pause,\n            KeyCode::Menu => CKeyCode::Menu,\n            KeyCode::KeypadBegin => CKeyCode::KeypadBegin,\n            KeyCode::Media(media_key_code) => CKeyCode::Media(media_key_code.into()),\n            KeyCode::Modifier(modifier_key_code) => CKeyCode::Modifier(modifier_key_code.into()),\n        }\n    }\n}\n\n#[cfg(all(feature = \"term\", windows))]\nimpl From<crossterm::event::KeyCode> for KeyCode {\n    fn from(val: crossterm::event::KeyCode) -> Self {\n        use crossterm::event::KeyCode as CKeyCode;\n\n        match val {\n            CKeyCode::Backspace => KeyCode::Backspace,\n            CKeyCode::Enter => KeyCode::Enter,\n            CKeyCode::Left => KeyCode::Left,\n            CKeyCode::Right => KeyCode::Right,\n            CKeyCode::Up => KeyCode::Up,\n            CKeyCode::Down => KeyCode::Down,\n            CKeyCode::Home => KeyCode::Home,\n            CKeyCode::End => KeyCode::End,\n            CKeyCode::PageUp => KeyCode::PageUp,\n            CKeyCode::PageDown => KeyCode::PageDown,\n            CKeyCode::Tab => KeyCode::Tab,\n            CKeyCode::BackTab => unreachable!(\"BackTab should have been handled on KeyEvent level\"),\n            CKeyCode::Delete => KeyCode::Delete,\n            CKeyCode::Insert => KeyCode::Insert,\n            CKeyCode::F(f_number) => KeyCode::F(f_number),\n            CKeyCode::Char(character) => KeyCode::Char(character),\n            CKeyCode::Null => KeyCode::Null,\n            CKeyCode::Esc => KeyCode::Esc,\n            CKeyCode::CapsLock => KeyCode::CapsLock,\n            CKeyCode::ScrollLock => KeyCode::ScrollLock,\n            CKeyCode::NumLock => KeyCode::NumLock,\n            CKeyCode::PrintScreen => KeyCode::PrintScreen,\n            CKeyCode::Pause => KeyCode::Pause,\n            CKeyCode::Menu => KeyCode::Menu,\n            CKeyCode::KeypadBegin => KeyCode::KeypadBegin,\n            CKeyCode::Media(media_key_code) => KeyCode::Media(media_key_code.into()),\n            CKeyCode::Modifier(modifier_key_code) => KeyCode::Modifier(modifier_key_code.into()),\n        }\n    }\n}\n"
  },
  {
    "path": "helix-view/src/lib.rs",
    "content": "#[macro_use]\npub mod macros;\n\npub mod annotations;\npub mod clipboard;\npub mod document;\npub mod editor;\npub mod events;\npub mod expansion;\npub mod graphics;\npub mod gutter;\npub mod handlers;\npub mod info;\npub mod input;\npub mod keyboard;\npub mod register;\npub mod theme;\npub mod tree;\npub mod view;\n\nuse std::num::NonZeroUsize;\n\n// uses NonZeroUsize so Option<DocumentId> use a byte rather than two\n#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]\npub struct DocumentId(NonZeroUsize);\n\nimpl Default for DocumentId {\n    fn default() -> DocumentId {\n        DocumentId(NonZeroUsize::new(1).unwrap())\n    }\n}\n\nimpl std::fmt::Display for DocumentId {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.write_fmt(format_args!(\"{}\", self.0))\n    }\n}\n\nslotmap::new_key_type! {\n    pub struct ViewId;\n}\n\npub enum Align {\n    Top,\n    Center,\n    Bottom,\n}\n\npub fn align_view(doc: &mut Document, view: &View, align: Align) {\n    let doc_text = doc.text().slice(..);\n    let cursor = doc.selection(view.id).primary().cursor(doc_text);\n    let viewport = view.inner_area(doc);\n    let last_line_height = viewport.height.saturating_sub(1);\n    let mut view_offset = doc.view_offset(view.id);\n\n    let relative = match align {\n        Align::Center => last_line_height / 2,\n        Align::Top => 0,\n        Align::Bottom => last_line_height,\n    };\n\n    let text_fmt = doc.text_format(viewport.width, None);\n    (view_offset.anchor, view_offset.vertical_offset) = char_idx_at_visual_offset(\n        doc_text,\n        cursor,\n        -(relative as isize),\n        0,\n        &text_fmt,\n        &view.text_annotations(doc, None),\n    );\n    doc.set_view_offset(view.id, view_offset);\n}\n\npub use document::Document;\npub use editor::Editor;\nuse helix_core::char_idx_at_visual_offset;\npub use theme::Theme;\npub use view::View;\n"
  },
  {
    "path": "helix-view/src/macros.rs",
    "content": "//! These are macros to make getting very nested fields in the `Editor` struct easier\n//! These are macros instead of functions because functions will have to take `&mut self`\n//! However, rust doesn't know that you only want a partial borrow instead of borrowing the\n//! entire struct which `&mut self` says.  This makes it impossible to do other mutable\n//! stuff to the struct because it is already borrowed. Because macros are expanded,\n//! this circumvents the problem because it is just like indexing fields by hand and then\n//! putting a `&mut` in front of it. This way rust can see that we are only borrowing a\n//! part of the struct and not the entire thing.\n\n/// Get the current view and document mutably as a tuple.\n/// Returns `(&mut View, &mut Document)`\n#[macro_export]\nmacro_rules! current {\n    ($editor:expr) => {{\n        let view = $crate::view_mut!($editor);\n        let id = view.doc;\n        let doc = $crate::doc_mut!($editor, &id);\n        (view, doc)\n    }};\n}\n\n#[macro_export]\nmacro_rules! current_ref {\n    ($editor:expr) => {{\n        let view = $editor.tree.get($editor.tree.focus);\n        let doc = &$editor.documents[&view.doc];\n        (view, doc)\n    }};\n}\n\n/// Get the current document mutably.\n/// Returns `&mut Document`\n#[macro_export]\nmacro_rules! doc_mut {\n    ($editor:expr, $id:expr) => {{\n        $editor.documents.get_mut($id).unwrap()\n    }};\n    ($editor:expr) => {{\n        $crate::current!($editor).1\n    }};\n}\n\n/// Get the current view mutably.\n/// Returns `&mut View`\n#[macro_export]\nmacro_rules! view_mut {\n    ($editor:expr, $id:expr) => {{\n        $editor.tree.get_mut($id)\n    }};\n    ($editor:expr) => {{\n        $editor.tree.get_mut($editor.tree.focus)\n    }};\n}\n\n/// Get the current view immutably\n/// Returns `&View`\n#[macro_export]\nmacro_rules! view {\n    ($editor:expr, $id:expr) => {{\n        $editor.tree.get($id)\n    }};\n    ($editor:expr) => {{\n        $editor.tree.get($editor.tree.focus)\n    }};\n}\n\n#[macro_export]\nmacro_rules! doc {\n    ($editor:expr, $id:expr) => {{\n        &$editor.documents[$id]\n    }};\n    ($editor:expr) => {{\n        $crate::current_ref!($editor).1\n    }};\n}\n"
  },
  {
    "path": "helix-view/src/register.rs",
    "content": "use std::{borrow::Cow, collections::HashMap, iter};\n\nuse anyhow::Result;\nuse arc_swap::access::DynAccess;\nuse helix_core::NATIVE_LINE_ENDING;\n\nuse crate::{\n    clipboard::{ClipboardError, ClipboardProvider, ClipboardType},\n    Editor,\n};\n\n/// A key-value store for saving sets of values.\n///\n/// Each register corresponds to a `char`. Most chars can be used to store any set of\n/// values but a few chars are \"special registers\". Special registers have unique\n/// behaviors when read or written to:\n///\n/// * Black hole (`_`): all values read and written are discarded\n/// * Selection indices (`#`): index number of each selection starting at 1\n/// * Selection contents (`.`)\n/// * Document path (`%`): filename of the current buffer\n/// * System clipboard (`*`)\n/// * Primary clipboard (`+`)\npub struct Registers {\n    /// The mapping of register to values.\n    /// Values are stored in reverse order when inserted with `Registers::write`.\n    /// The order is reversed again in `Registers::read`. This allows us to\n    /// efficiently prepend new values in `Registers::push`.\n    inner: HashMap<char, Vec<String>>,\n    clipboard_provider: Box<dyn DynAccess<ClipboardProvider>>,\n    pub last_search_register: char,\n}\n\nimpl Registers {\n    pub fn new(clipboard_provider: Box<dyn DynAccess<ClipboardProvider>>) -> Self {\n        Self {\n            inner: Default::default(),\n            clipboard_provider,\n            last_search_register: '/',\n        }\n    }\n\n    pub fn read<'a>(&'a self, name: char, editor: &'a Editor) -> Option<RegisterValues<'a>> {\n        match name {\n            '_' => Some(RegisterValues::new(iter::empty())),\n            '#' => {\n                let (view, doc) = current_ref!(editor);\n                let selections = doc.selection(view.id).len();\n                // ExactSizeIterator is implemented for Range<usize> but\n                // not RangeInclusive<usize>.\n                Some(RegisterValues::new(\n                    (0..selections).map(|i| (i + 1).to_string().into()),\n                ))\n            }\n            '.' => {\n                let (view, doc) = current_ref!(editor);\n                let text = doc.text().slice(..);\n                Some(RegisterValues::new(doc.selection(view.id).fragments(text)))\n            }\n            '%' => {\n                let path = doc!(editor).display_name();\n                Some(RegisterValues::new(iter::once(path)))\n            }\n            '*' | '+' => Some(read_from_clipboard(\n                &self.clipboard_provider.load(),\n                self.inner.get(&name),\n                match name {\n                    '+' => ClipboardType::Clipboard,\n                    '*' => ClipboardType::Selection,\n                    _ => unreachable!(),\n                },\n            )),\n            _ => self\n                .inner\n                .get(&name)\n                .map(|values| RegisterValues::new(values.iter().map(Cow::from).rev())),\n        }\n    }\n\n    pub fn write(&mut self, name: char, mut values: Vec<String>) -> Result<()> {\n        match name {\n            '_' => Ok(()),\n            '#' | '.' | '%' => Err(anyhow::anyhow!(\"Register {name} does not support writing\")),\n            '*' | '+' => {\n                self.clipboard_provider.load().set_contents(\n                    &values.join(NATIVE_LINE_ENDING.as_str()),\n                    match name {\n                        '+' => ClipboardType::Clipboard,\n                        '*' => ClipboardType::Selection,\n                        _ => unreachable!(),\n                    },\n                )?;\n                values.reverse();\n                self.inner.insert(name, values);\n                Ok(())\n            }\n            _ => {\n                values.reverse();\n                self.inner.insert(name, values);\n                Ok(())\n            }\n        }\n    }\n\n    pub fn push(&mut self, name: char, mut value: String) -> Result<()> {\n        match name {\n            '_' => Ok(()),\n            '#' | '.' | '%' => Err(anyhow::anyhow!(\"Register {name} does not support pushing\")),\n            '*' | '+' => {\n                let clipboard_type = match name {\n                    '+' => ClipboardType::Clipboard,\n                    '*' => ClipboardType::Selection,\n                    _ => unreachable!(),\n                };\n                let contents = self\n                    .clipboard_provider\n                    .load()\n                    .get_contents(&clipboard_type)?;\n                let saved_values = self.inner.entry(name).or_default();\n\n                if !contents_are_saved(saved_values, &contents) {\n                    anyhow::bail!(\"Failed to push to register {name}: clipboard does not match register contents\");\n                }\n\n                saved_values.push(value.clone());\n                if !contents.is_empty() {\n                    value.push_str(NATIVE_LINE_ENDING.as_str());\n                }\n                value.push_str(&contents);\n                self.clipboard_provider\n                    .load()\n                    .set_contents(&value, clipboard_type)?;\n\n                Ok(())\n            }\n            _ => {\n                self.inner.entry(name).or_default().push(value);\n                Ok(())\n            }\n        }\n    }\n\n    pub fn first<'a>(&'a self, name: char, editor: &'a Editor) -> Option<Cow<'a, str>> {\n        self.read(name, editor).and_then(|mut values| values.next())\n    }\n\n    pub fn last<'a>(&'a self, name: char, editor: &'a Editor) -> Option<Cow<'a, str>> {\n        self.read(name, editor)\n            .and_then(|mut values| values.next_back())\n    }\n\n    pub fn iter_preview(&self) -> impl Iterator<Item = (char, &str)> {\n        self.inner\n            .iter()\n            .filter(|(name, _)| !matches!(name, '*' | '+'))\n            .map(|(name, values)| {\n                let preview = values\n                    .last()\n                    .and_then(|s| s.lines().next())\n                    .unwrap_or(\"<empty>\");\n\n                (*name, preview)\n            })\n            .chain(\n                [\n                    ('_', \"<empty>\"),\n                    ('#', \"<selection indices>\"),\n                    ('.', \"<selection contents>\"),\n                    ('%', \"<document path>\"),\n                    ('+', \"<system clipboard>\"),\n                    ('*', \"<primary clipboard>\"),\n                ]\n                .iter()\n                .copied(),\n            )\n    }\n\n    pub fn clear(&mut self) {\n        self.clear_clipboard(ClipboardType::Clipboard);\n        self.clear_clipboard(ClipboardType::Selection);\n        self.inner.clear()\n    }\n\n    pub fn remove(&mut self, name: char) -> bool {\n        match name {\n            '*' | '+' => {\n                self.clear_clipboard(match name {\n                    '+' => ClipboardType::Clipboard,\n                    '*' => ClipboardType::Selection,\n                    _ => unreachable!(),\n                });\n                self.inner.remove(&name);\n\n                true\n            }\n            '_' | '#' | '.' | '%' => false,\n            _ => self.inner.remove(&name).is_some(),\n        }\n    }\n\n    fn clear_clipboard(&mut self, clipboard_type: ClipboardType) {\n        if let Err(err) = self\n            .clipboard_provider\n            .load()\n            .set_contents(\"\", clipboard_type)\n        {\n            log::error!(\n                \"Failed to clear {} clipboard: {err}\",\n                match clipboard_type {\n                    ClipboardType::Clipboard => \"system\",\n                    ClipboardType::Selection => \"primary\",\n                }\n            )\n        }\n    }\n\n    pub fn clipboard_provider_name(&self) -> String {\n        self.clipboard_provider.load().name().into_owned()\n    }\n}\n\nfn read_from_clipboard<'a>(\n    provider: &ClipboardProvider,\n    saved_values: Option<&'a Vec<String>>,\n    clipboard_type: ClipboardType,\n) -> RegisterValues<'a> {\n    match provider.get_contents(&clipboard_type) {\n        Ok(contents) => {\n            // If we're pasting the same values that we just yanked, re-use\n            // the saved values. This allows pasting multiple selections\n            // even when yanked to a clipboard.\n            let Some(values) = saved_values else {\n                return RegisterValues::new(iter::once(contents.into()));\n            };\n\n            if contents_are_saved(values, &contents) {\n                RegisterValues::new(values.iter().map(Cow::from).rev())\n            } else {\n                RegisterValues::new(iter::once(contents.into()))\n            }\n        }\n        Err(ClipboardError::ReadingNotSupported) => match saved_values {\n            Some(values) => RegisterValues::new(values.iter().map(Cow::from).rev()),\n            None => RegisterValues::new(iter::empty()),\n        },\n        Err(err) => {\n            log::error!(\n                \"Failed to read {} clipboard: {err}\",\n                match clipboard_type {\n                    ClipboardType::Clipboard => \"system\",\n                    ClipboardType::Selection => \"primary\",\n                }\n            );\n\n            RegisterValues::new(iter::empty())\n        }\n    }\n}\n\nfn contents_are_saved(saved_values: &[String], mut contents: &str) -> bool {\n    let line_ending = NATIVE_LINE_ENDING.as_str();\n    let mut values = saved_values.iter().rev();\n\n    match values.next() {\n        Some(first) if contents.starts_with(first) => {\n            contents = &contents[first.len()..];\n        }\n        None if contents.is_empty() => return true,\n        _ => return false,\n    }\n\n    for value in values {\n        if contents.starts_with(line_ending) && contents[line_ending.len()..].starts_with(value) {\n            contents = &contents[line_ending.len() + value.len()..];\n        } else {\n            return false;\n        }\n    }\n\n    true\n}\n\n// This is a wrapper of an iterator that is both double ended and exact size,\n// and can return either owned or borrowed values. Regular registers can\n// return borrowed values while some special registers need to return owned\n// values.\npub struct RegisterValues<'a> {\n    iter: Box<dyn DoubleEndedExactSizeIterator<Item = Cow<'a, str>> + 'a>,\n}\n\nimpl<'a> RegisterValues<'a> {\n    fn new(\n        iter: impl DoubleEndedIterator<Item = Cow<'a, str>>\n            + ExactSizeIterator<Item = Cow<'a, str>>\n            + 'a,\n    ) -> Self {\n        Self {\n            iter: Box::new(iter),\n        }\n    }\n}\n\nimpl<'a> Iterator for RegisterValues<'a> {\n    type Item = Cow<'a, str>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.iter.next()\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.iter.size_hint()\n    }\n}\n\nimpl DoubleEndedIterator for RegisterValues<'_> {\n    fn next_back(&mut self) -> Option<Self::Item> {\n        self.iter.next_back()\n    }\n}\n\nimpl ExactSizeIterator for RegisterValues<'_> {\n    fn len(&self) -> usize {\n        self.iter.len()\n    }\n}\n\n// Each RegisterValues iterator is both double ended and exact size. We can't\n// type RegisterValues as `Box<dyn DoubleEndedIterator + ExactSizeIterator>`\n// because only one non-auto trait is allowed in trait objects. So we need to\n// create a new trait that covers both. `RegisterValues` wraps that type so that\n// trait only needs to live in this module and not be imported for all register\n// callsites.\ntrait DoubleEndedExactSizeIterator: DoubleEndedIterator + ExactSizeIterator {}\n\nimpl<I: DoubleEndedIterator + ExactSizeIterator> DoubleEndedExactSizeIterator for I {}\n"
  },
  {
    "path": "helix-view/src/theme.rs",
    "content": "use std::{\n    collections::{HashMap, HashSet},\n    path::{Path, PathBuf},\n    str,\n};\n\nuse anyhow::{anyhow, Result};\nuse helix_core::{hashmap, syntax::Highlight};\nuse helix_loader::merge_toml_values;\nuse log::warn;\nuse once_cell::sync::Lazy;\nuse serde::{Deserialize, Deserializer};\nuse toml::{map::Map, Value};\n\nuse crate::graphics::UnderlineStyle;\npub use crate::graphics::{Color, Modifier, Style};\n\npub static DEFAULT_THEME_DATA: Lazy<Value> = Lazy::new(|| {\n    let bytes = include_bytes!(\"../../theme.toml\");\n    toml::from_str(str::from_utf8(bytes).unwrap()).expect(\"Failed to parse base default theme\")\n});\n\npub static BASE16_DEFAULT_THEME_DATA: Lazy<Value> = Lazy::new(|| {\n    let bytes = include_bytes!(\"../../base16_theme.toml\");\n    toml::from_str(str::from_utf8(bytes).unwrap()).expect(\"Failed to parse base 16 default theme\")\n});\n\npub static DEFAULT_THEME: Lazy<Theme> = Lazy::new(|| Theme {\n    name: \"default\".into(),\n    ..Theme::from(DEFAULT_THEME_DATA.clone())\n});\n\npub static BASE16_DEFAULT_THEME: Lazy<Theme> = Lazy::new(|| Theme {\n    name: \"base16_default\".into(),\n    ..Theme::from(BASE16_DEFAULT_THEME_DATA.clone())\n});\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub enum Mode {\n    Dark,\n    Light,\n}\n\n#[cfg(feature = \"term\")]\nimpl From<termina::escape::csi::ThemeMode> for Mode {\n    fn from(mode: termina::escape::csi::ThemeMode) -> Self {\n        match mode {\n            termina::escape::csi::ThemeMode::Dark => Self::Dark,\n            termina::escape::csi::ThemeMode::Light => Self::Light,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct Config {\n    light: String,\n    dark: String,\n    /// A theme to choose when the terminal did not declare either light or dark mode.\n    /// When not specified the dark theme is preferred.\n    fallback: Option<String>,\n}\n\nimpl Config {\n    pub fn choose(&self, preference: Option<Mode>) -> &str {\n        match preference {\n            Some(Mode::Light) => &self.light,\n            Some(Mode::Dark) => &self.dark,\n            None => self.fallback.as_ref().unwrap_or(&self.dark),\n        }\n    }\n}\n\nimpl<'de> Deserialize<'de> for Config {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        #[derive(Deserialize)]\n        #[serde(untagged, deny_unknown_fields, rename_all = \"kebab-case\")]\n        enum InnerConfig {\n            Constant(String),\n            Adaptive {\n                dark: String,\n                light: String,\n                fallback: Option<String>,\n            },\n        }\n\n        let inner = InnerConfig::deserialize(deserializer)?;\n\n        let (light, dark, fallback) = match inner {\n            InnerConfig::Constant(theme) => (theme.clone(), theme.clone(), None),\n            InnerConfig::Adaptive {\n                light,\n                dark,\n                fallback,\n            } => (light, dark, fallback),\n        };\n\n        Ok(Self {\n            light,\n            dark,\n            fallback,\n        })\n    }\n}\n#[derive(Clone, Debug)]\npub struct Loader {\n    /// Theme directories to search from highest to lowest priority\n    theme_dirs: Vec<PathBuf>,\n}\nimpl Loader {\n    /// Creates a new loader that can load themes from multiple directories.\n    ///\n    /// The provided directories should be ordered from highest to lowest priority.\n    /// The directories will have their \"themes\" subdirectory searched.\n    pub fn new(dirs: &[PathBuf]) -> Self {\n        Self {\n            theme_dirs: dirs.iter().map(|p| p.join(\"themes\")).collect(),\n        }\n    }\n\n    /// Loads a theme searching directories in priority order.\n    pub fn load(&self, name: &str) -> Result<Theme> {\n        let (theme, warnings) = self.load_with_warnings(name)?;\n\n        for warning in warnings {\n            warn!(\"Theme '{}': {}\", name, warning);\n        }\n\n        Ok(theme)\n    }\n\n    /// Loads a theme searching directories in priority order, returning any warnings\n    pub fn load_with_warnings(&self, name: &str) -> Result<(Theme, Vec<String>)> {\n        if name == \"default\" {\n            return Ok((self.default(), Vec::new()));\n        }\n        if name == \"base16_default\" {\n            return Ok((self.base16_default(), Vec::new()));\n        }\n\n        let mut visited_paths = HashSet::new();\n        let (theme, warnings) = self\n            .load_theme(name, &mut visited_paths)\n            .map(Theme::from_toml)?;\n\n        let theme = Theme {\n            name: name.into(),\n            ..theme\n        };\n        Ok((theme, warnings))\n    }\n\n    /// Recursively load a theme, merging with any inherited parent themes.\n    ///\n    /// The paths that have been visited in the inheritance hierarchy are tracked\n    /// to detect and avoid cycling.\n    ///\n    /// It is possible for one file to inherit from another file with the same name\n    /// so long as the second file is in a themes directory with lower priority.\n    /// However, it is not recommended that users do this as it will make tracing\n    /// errors more difficult.\n    fn load_theme(&self, name: &str, visited_paths: &mut HashSet<PathBuf>) -> Result<Value> {\n        let path = self.path(name, visited_paths)?;\n\n        let theme_toml = self.load_toml(path)?;\n\n        let inherits = theme_toml.get(\"inherits\");\n\n        let theme_toml = if let Some(parent_theme_name) = inherits {\n            let parent_theme_name = parent_theme_name.as_str().ok_or_else(|| {\n                anyhow!(\"Expected 'inherits' to be a string: {}\", parent_theme_name)\n            })?;\n\n            let parent_theme_toml = match parent_theme_name {\n                // load default themes's toml from const.\n                \"default\" => DEFAULT_THEME_DATA.clone(),\n                \"base16_default\" => BASE16_DEFAULT_THEME_DATA.clone(),\n                _ => self.load_theme(parent_theme_name, visited_paths)?,\n            };\n\n            self.merge_themes(parent_theme_toml, theme_toml)\n        } else {\n            theme_toml\n        };\n\n        Ok(theme_toml)\n    }\n\n    pub fn read_names(path: &Path) -> Vec<String> {\n        std::fs::read_dir(path)\n            .map(|entries| {\n                entries\n                    .filter_map(|entry| {\n                        let entry = entry.ok()?;\n                        let path = entry.path();\n                        (path.extension()? == \"toml\")\n                            .then(|| path.file_stem().unwrap().to_string_lossy().into_owned())\n                    })\n                    .collect()\n            })\n            .unwrap_or_default()\n    }\n\n    // merge one theme into the parent theme\n    fn merge_themes(&self, parent_theme_toml: Value, theme_toml: Value) -> Value {\n        let parent_palette = parent_theme_toml.get(\"palette\");\n        let palette = theme_toml.get(\"palette\");\n\n        // handle the table separately since it needs a `merge_depth` of 2\n        // this would conflict with the rest of the theme merge strategy\n        let palette_values = match (parent_palette, palette) {\n            (Some(parent_palette), Some(palette)) => {\n                merge_toml_values(parent_palette.clone(), palette.clone(), 2)\n            }\n            (Some(parent_palette), None) => parent_palette.clone(),\n            (None, Some(palette)) => palette.clone(),\n            (None, None) => Map::new().into(),\n        };\n\n        // add the palette correctly as nested table\n        let mut palette = Map::new();\n        palette.insert(String::from(\"palette\"), palette_values);\n\n        // merge the theme into the parent theme\n        let theme = merge_toml_values(parent_theme_toml, theme_toml, 1);\n        // merge the before specially handled palette into the theme\n        merge_toml_values(theme, palette.into(), 1)\n    }\n\n    // Loads the theme data as `toml::Value`\n    fn load_toml(&self, path: PathBuf) -> Result<Value> {\n        let data = std::fs::read_to_string(path)?;\n        let value = toml::from_str(&data)?;\n\n        Ok(value)\n    }\n\n    /// Returns the path to the theme with the given name\n    ///\n    /// Ignores paths already visited and follows directory priority order.\n    fn path(&self, name: &str, visited_paths: &mut HashSet<PathBuf>) -> Result<PathBuf> {\n        let filename = format!(\"{}.toml\", name);\n\n        let mut cycle_found = false; // track if there was a path, but it was in a cycle\n        self.theme_dirs\n            .iter()\n            .find_map(|dir| {\n                let path = dir.join(&filename);\n                if !path.exists() {\n                    None\n                } else if visited_paths.contains(&path) {\n                    // Avoiding cycle, continuing to look in lower priority directories\n                    cycle_found = true;\n                    None\n                } else {\n                    visited_paths.insert(path.clone());\n                    Some(path)\n                }\n            })\n            .ok_or_else(|| {\n                if cycle_found {\n                    anyhow!(\"Cycle found in inheriting: {}\", name)\n                } else {\n                    anyhow!(\"File not found for: {}\", name)\n                }\n            })\n    }\n\n    pub fn default_theme(&self, true_color: bool) -> Theme {\n        if true_color {\n            self.default()\n        } else {\n            self.base16_default()\n        }\n    }\n\n    /// Returns the default theme\n    pub fn default(&self) -> Theme {\n        DEFAULT_THEME.clone()\n    }\n\n    /// Returns the alternative 16-color default theme\n    pub fn base16_default(&self) -> Theme {\n        BASE16_DEFAULT_THEME.clone()\n    }\n}\n\n#[derive(Clone, Debug, Default)]\npub struct Theme {\n    name: String,\n\n    // UI styles are stored in a HashMap\n    styles: HashMap<String, Style>,\n    // tree-sitter highlight styles are stored in a Vec to optimize lookups\n    scopes: Vec<String>,\n    highlights: Vec<Style>,\n    rainbow_length: usize,\n}\n\nimpl From<Value> for Theme {\n    fn from(value: Value) -> Self {\n        let (theme, warnings) = Theme::from_toml(value);\n        for warning in warnings {\n            warn!(\"{}\", warning);\n        }\n        theme\n    }\n}\n\nimpl<'de> Deserialize<'de> for Theme {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let values = Map::<String, Value>::deserialize(deserializer)?;\n        let (theme, warnings) = Theme::from_keys(values);\n        for warning in warnings {\n            warn!(\"{}\", warning);\n        }\n        Ok(theme)\n    }\n}\n\n#[allow(clippy::type_complexity)]\nfn build_theme_values(\n    mut values: Map<String, Value>,\n) -> (\n    HashMap<String, Style>,\n    Vec<String>,\n    Vec<Style>,\n    usize,\n    Vec<String>,\n) {\n    let mut styles = HashMap::new();\n    let mut scopes = Vec::new();\n    let mut highlights = Vec::new();\n    let mut rainbow_length = 0;\n\n    let mut warnings = Vec::new();\n\n    // TODO: alert user of parsing failures in editor\n    let palette = values\n        .remove(\"palette\")\n        .map(|value| {\n            ThemePalette::try_from(value).unwrap_or_else(|err| {\n                warnings.push(err);\n                ThemePalette::default()\n            })\n        })\n        .unwrap_or_default();\n    // remove inherits from value to prevent errors\n    let _ = values.remove(\"inherits\");\n    styles.reserve(values.len());\n    scopes.reserve(values.len());\n    highlights.reserve(values.len());\n\n    for (i, style) in values\n        .remove(\"rainbow\")\n        .and_then(|value| match palette.parse_style_array(value) {\n            Ok(styles) => Some(styles),\n            Err(err) => {\n                warnings.push(err);\n                None\n            }\n        })\n        .unwrap_or_else(default_rainbow)\n        .into_iter()\n        .enumerate()\n    {\n        let name = format!(\"rainbow.{i}\");\n        styles.insert(name.clone(), style);\n        scopes.push(name);\n        highlights.push(style);\n        rainbow_length += 1;\n    }\n\n    for (name, style_value) in values {\n        let mut style = Style::default();\n        if let Err(err) = palette.parse_style(&mut style, style_value) {\n            warnings.push(format!(\"Failed to parse style for key {name:?}. {err}\"));\n        }\n\n        // these are used both as UI and as highlights\n        styles.insert(name.clone(), style);\n        scopes.push(name);\n        highlights.push(style);\n    }\n\n    (styles, scopes, highlights, rainbow_length, warnings)\n}\n\nfn default_rainbow() -> Vec<Style> {\n    vec![\n        Style::default().fg(Color::Red),\n        Style::default().fg(Color::Yellow),\n        Style::default().fg(Color::Green),\n        Style::default().fg(Color::Blue),\n        Style::default().fg(Color::Cyan),\n        Style::default().fg(Color::Magenta),\n    ]\n}\nimpl Theme {\n    /// To allow `Highlight` to represent arbitrary RGB colors without turning it into an enum,\n    /// we interpret the last 256^3 numbers as RGB.\n    const RGB_START: u32 = (u32::MAX << (8 + 8 + 8)) - 1 - (u32::MAX - Highlight::MAX);\n\n    /// Interpret a Highlight with the RGB foreground\n    fn decode_rgb_highlight(highlight: Highlight) -> Option<(u8, u8, u8)> {\n        (highlight.get() > Self::RGB_START).then(|| {\n            let [b, g, r, ..] = (highlight.get() + 1).to_le_bytes();\n            (r, g, b)\n        })\n    }\n\n    /// Create a Highlight that represents an RGB color\n    pub fn rgb_highlight(r: u8, g: u8, b: u8) -> Highlight {\n        // -1 because highlight is \"non-max\": u32::MAX is reserved for the null pointer\n        // optimization.\n        Highlight::new(u32::from_le_bytes([b, g, r, u8::MAX]) - 1)\n    }\n\n    #[inline]\n    pub fn highlight(&self, highlight: Highlight) -> Style {\n        if let Some((red, green, blue)) = Self::decode_rgb_highlight(highlight) {\n            Style::new().fg(Color::Rgb(red, green, blue))\n        } else {\n            self.highlights[highlight.idx()]\n        }\n    }\n\n    #[inline]\n    pub fn scope(&self, highlight: Highlight) -> &str {\n        &self.scopes[highlight.idx()]\n    }\n\n    pub fn name(&self) -> &str {\n        &self.name\n    }\n\n    pub fn get(&self, scope: &str) -> Style {\n        self.try_get(scope).unwrap_or_default()\n    }\n\n    /// Get the style of a scope, falling back to dot separated broader\n    /// scopes. For example if `ui.text.focus` is not defined in the theme,\n    /// `ui.text` is tried and then `ui` is tried.\n    pub fn try_get(&self, scope: &str) -> Option<Style> {\n        std::iter::successors(Some(scope), |s| Some(s.rsplit_once('.')?.0))\n            .find_map(|s| self.styles.get(s).copied())\n    }\n\n    /// Get the style of a scope, without falling back to dot separated broader\n    /// scopes. For example if `ui.text.focus` is not defined in the theme, it\n    /// will return `None`, even if `ui.text` is.\n    pub fn try_get_exact(&self, scope: &str) -> Option<Style> {\n        self.styles.get(scope).copied()\n    }\n\n    #[inline]\n    pub fn scopes(&self) -> &[String] {\n        &self.scopes\n    }\n\n    pub fn find_highlight_exact(&self, scope: &str) -> Option<Highlight> {\n        self.scopes()\n            .iter()\n            .position(|s| s == scope)\n            .map(|idx| Highlight::new(idx as u32))\n    }\n\n    pub fn find_highlight(&self, mut scope: &str) -> Option<Highlight> {\n        loop {\n            if let Some(highlight) = self.find_highlight_exact(scope) {\n                return Some(highlight);\n            }\n            if let Some(new_end) = scope.rfind('.') {\n                scope = &scope[..new_end];\n            } else {\n                return None;\n            }\n        }\n    }\n\n    pub fn is_16_color(&self) -> bool {\n        self.styles.iter().all(|(_, style)| {\n            [style.fg, style.bg]\n                .into_iter()\n                .all(|color| !matches!(color, Some(Color::Rgb(..))))\n        })\n    }\n\n    pub fn rainbow_length(&self) -> usize {\n        self.rainbow_length\n    }\n\n    fn from_toml(value: Value) -> (Self, Vec<String>) {\n        if let Value::Table(table) = value {\n            Theme::from_keys(table)\n        } else {\n            warn!(\"Expected theme TOML value to be a table, found {:?}\", value);\n            Default::default()\n        }\n    }\n\n    fn from_keys(toml_keys: Map<String, Value>) -> (Self, Vec<String>) {\n        let (styles, scopes, highlights, rainbow_length, load_errors) =\n            build_theme_values(toml_keys);\n\n        let theme = Self {\n            styles,\n            scopes,\n            highlights,\n            rainbow_length,\n            ..Default::default()\n        };\n        (theme, load_errors)\n    }\n}\n\nstruct ThemePalette {\n    palette: HashMap<String, Color>,\n}\n\nimpl Default for ThemePalette {\n    fn default() -> Self {\n        Self {\n            palette: hashmap! {\n                \"default\".to_string() => Color::Reset,\n                \"black\".to_string() => Color::Black,\n                \"red\".to_string() => Color::Red,\n                \"green\".to_string() => Color::Green,\n                \"yellow\".to_string() => Color::Yellow,\n                \"blue\".to_string() => Color::Blue,\n                \"magenta\".to_string() => Color::Magenta,\n                \"cyan\".to_string() => Color::Cyan,\n                \"gray\".to_string() => Color::Gray,\n                \"light-red\".to_string() => Color::LightRed,\n                \"light-green\".to_string() => Color::LightGreen,\n                \"light-yellow\".to_string() => Color::LightYellow,\n                \"light-blue\".to_string() => Color::LightBlue,\n                \"light-magenta\".to_string() => Color::LightMagenta,\n                \"light-cyan\".to_string() => Color::LightCyan,\n                \"light-gray\".to_string() => Color::LightGray,\n                \"white\".to_string() => Color::White,\n            },\n        }\n    }\n}\n\nimpl ThemePalette {\n    pub fn new(palette: HashMap<String, Color>) -> Self {\n        let ThemePalette {\n            palette: mut default,\n        } = ThemePalette::default();\n\n        default.extend(palette);\n        Self { palette: default }\n    }\n\n    pub fn string_to_rgb(s: &str) -> Result<Color, String> {\n        if s.starts_with('#') {\n            Color::from_hex(s).map_err(|e| format!(\"{e}: {s}\"))\n        } else {\n            Self::ansi_string_to_rgb(s)\n        }\n    }\n\n    fn ansi_string_to_rgb(s: &str) -> Result<Color, String> {\n        if let Ok(index) = s.parse::<u8>() {\n            return Ok(Color::Indexed(index));\n        }\n        Err(format!(\"Malformed ANSI: {}\", s))\n    }\n\n    fn parse_value_as_str(value: &Value) -> Result<&str, String> {\n        value\n            .as_str()\n            .ok_or(format!(\"Unrecognized value: {}\", value))\n    }\n\n    pub fn parse_color(&self, value: Value) -> Result<Color, String> {\n        let value = Self::parse_value_as_str(&value)?;\n\n        self.palette\n            .get(value)\n            .copied()\n            .ok_or(\"\")\n            .or_else(|_| Self::string_to_rgb(value))\n    }\n\n    pub fn parse_modifier(value: &Value) -> Result<Modifier, String> {\n        value\n            .as_str()\n            .and_then(|s| s.parse().ok())\n            .ok_or(format!(\"Invalid modifier: {}\", value))\n    }\n\n    pub fn parse_underline_style(value: &Value) -> Result<UnderlineStyle, String> {\n        value\n            .as_str()\n            .and_then(|s| s.parse().ok())\n            .ok_or(format!(\"Invalid underline style: {}\", value))\n    }\n\n    pub fn parse_style(&self, style: &mut Style, value: Value) -> Result<(), String> {\n        if let Value::Table(entries) = value {\n            for (name, mut value) in entries {\n                match name.as_str() {\n                    \"fg\" => *style = style.fg(self.parse_color(value)?),\n                    \"bg\" => *style = style.bg(self.parse_color(value)?),\n                    \"underline\" => {\n                        let table = value.as_table_mut().ok_or(\"Underline must be table\")?;\n                        if let Some(value) = table.remove(\"color\") {\n                            *style = style.underline_color(self.parse_color(value)?);\n                        }\n                        if let Some(value) = table.remove(\"style\") {\n                            *style = style.underline_style(Self::parse_underline_style(&value)?);\n                        }\n\n                        if let Some(attr) = table.keys().next() {\n                            return Err(format!(\"Invalid underline attribute: {attr}\"));\n                        }\n                    }\n                    \"modifiers\" => {\n                        let modifiers = value.as_array().ok_or(\"Modifiers should be an array\")?;\n\n                        for modifier in modifiers {\n                            if modifier.as_str() == Some(\"underlined\") {\n                                *style = style.underline_style(UnderlineStyle::Line);\n                            } else {\n                                *style = style.add_modifier(Self::parse_modifier(modifier)?);\n                            }\n                        }\n                    }\n                    _ => return Err(format!(\"Invalid style attribute: {}\", name)),\n                }\n            }\n        } else {\n            *style = style.fg(self.parse_color(value)?);\n        }\n        Ok(())\n    }\n\n    fn parse_style_array(&self, value: Value) -> Result<Vec<Style>, String> {\n        let mut styles = Vec::new();\n\n        for v in value\n            .as_array()\n            .ok_or_else(|| format!(\"Could not parse value as an array: '{value}'\"))?\n        {\n            let mut style = Style::default();\n            self.parse_style(&mut style, v.clone())?;\n            styles.push(style);\n        }\n\n        Ok(styles)\n    }\n}\n\nimpl TryFrom<Value> for ThemePalette {\n    type Error = String;\n\n    fn try_from(value: Value) -> Result<Self, Self::Error> {\n        let map = match value {\n            Value::Table(entries) => entries,\n            _ => return Ok(Self::default()),\n        };\n\n        let mut palette = HashMap::with_capacity(map.len());\n        for (name, value) in map {\n            let value = Self::parse_value_as_str(&value)?;\n            let color = Self::string_to_rgb(value)?;\n            palette.insert(name, color);\n        }\n\n        Ok(Self::new(palette))\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_parse_style_string() {\n        let fg = Value::String(\"#ffffff\".to_string());\n\n        let mut style = Style::default();\n        let palette = ThemePalette::default();\n        palette.parse_style(&mut style, fg).unwrap();\n\n        assert_eq!(style, Style::default().fg(Color::Rgb(255, 255, 255)));\n    }\n\n    #[test]\n    fn test_palette() {\n        use helix_core::hashmap;\n        let fg = Value::String(\"my_color\".to_string());\n\n        let mut style = Style::default();\n        let palette =\n            ThemePalette::new(hashmap! { \"my_color\".to_string() => Color::Rgb(255, 255, 255) });\n        palette.parse_style(&mut style, fg).unwrap();\n\n        assert_eq!(style, Style::default().fg(Color::Rgb(255, 255, 255)));\n    }\n\n    #[test]\n    fn test_parse_style_table() {\n        let table = toml::toml! {\n            \"keyword\" = {\n                fg = \"#ffffff\",\n                bg = \"#000000\",\n                modifiers = [\"bold\"],\n            }\n        };\n\n        let mut style = Style::default();\n        let palette = ThemePalette::default();\n        for (_name, value) in table {\n            palette.parse_style(&mut style, value).unwrap();\n        }\n\n        assert_eq!(\n            style,\n            Style::default()\n                .fg(Color::Rgb(255, 255, 255))\n                .bg(Color::Rgb(0, 0, 0))\n                .add_modifier(Modifier::BOLD)\n        );\n    }\n\n    // tests for parsing an RGB `Highlight`\n\n    #[test]\n    fn convert_to_and_from() {\n        let (r, g, b) = (0xFF, 0xFE, 0xFA);\n        let highlight = Theme::rgb_highlight(r, g, b);\n        assert_eq!(Theme::decode_rgb_highlight(highlight), Some((r, g, b)));\n    }\n\n    /// make sure we can store all the colors at the end\n    #[test]\n    fn full_numeric_range() {\n        assert_eq!(Highlight::MAX - Theme::RGB_START, 256_u32.pow(3));\n    }\n\n    #[test]\n    fn retrieve_color() {\n        // color in the middle\n        let (r, g, b) = (0x14, 0xAA, 0xF7);\n        assert_eq!(\n            Theme::default().highlight(Theme::rgb_highlight(r, g, b)),\n            Style::new().fg(Color::Rgb(r, g, b))\n        );\n        // pure black\n        let (r, g, b) = (0x00, 0x00, 0x00);\n        assert_eq!(\n            Theme::default().highlight(Theme::rgb_highlight(r, g, b)),\n            Style::new().fg(Color::Rgb(r, g, b))\n        );\n        // pure white\n        let (r, g, b) = (0xff, 0xff, 0xff);\n        assert_eq!(\n            Theme::default().highlight(Theme::rgb_highlight(r, g, b)),\n            Style::new().fg(Color::Rgb(r, g, b))\n        );\n    }\n\n    #[test]\n    #[should_panic(expected = \"index out of bounds: the len is 0 but the index is 4278190078\")]\n    fn out_of_bounds() {\n        let highlight = Highlight::new(Theme::rgb_highlight(0, 0, 0).get() - 1);\n        Theme::default().highlight(highlight);\n    }\n}\n"
  },
  {
    "path": "helix-view/src/tree.rs",
    "content": "use crate::{graphics::Rect, View, ViewId};\nuse slotmap::SlotMap;\n\n// the dimensions are recomputed on window resize/tree change.\n//\n#[derive(Debug)]\npub struct Tree {\n    root: ViewId,\n    // (container, index inside the container)\n    pub focus: ViewId,\n    // fullscreen: bool,\n    area: Rect,\n\n    nodes: SlotMap<ViewId, Node>,\n\n    // used for traversals\n    stack: Vec<(ViewId, Rect)>,\n}\n\n#[derive(Debug)]\npub struct Node {\n    parent: ViewId,\n    content: Content,\n}\n\n#[derive(Debug)]\npub enum Content {\n    View(Box<View>),\n    Container(Box<Container>),\n}\n\nimpl Node {\n    pub fn container(layout: Layout) -> Self {\n        Self {\n            parent: ViewId::default(),\n            content: Content::Container(Box::new(Container::new(layout))),\n        }\n    }\n\n    pub fn view(view: View) -> Self {\n        Self {\n            parent: ViewId::default(),\n            content: Content::View(Box::new(view)),\n        }\n    }\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum Layout {\n    Horizontal,\n    Vertical,\n    // could explore stacked/tabbed\n}\n\n#[derive(Debug, Clone, Copy)]\npub enum Direction {\n    Up,\n    Down,\n    Left,\n    Right,\n}\n\n#[derive(Debug)]\npub struct Container {\n    layout: Layout,\n    children: Vec<ViewId>,\n    area: Rect,\n}\n\nimpl Container {\n    pub fn new(layout: Layout) -> Self {\n        Self {\n            layout,\n            children: Vec::new(),\n            area: Rect::default(),\n        }\n    }\n}\n\nimpl Default for Container {\n    fn default() -> Self {\n        Self::new(Layout::Vertical)\n    }\n}\n\nimpl Tree {\n    pub fn new(area: Rect) -> Self {\n        let root = Node::container(Layout::Vertical);\n\n        let mut nodes = SlotMap::with_key();\n        let root = nodes.insert(root);\n\n        // root is it's own parent\n        nodes[root].parent = root;\n\n        Self {\n            root,\n            focus: root,\n            // fullscreen: false,\n            area,\n            nodes,\n            stack: Vec::new(),\n        }\n    }\n\n    pub fn insert(&mut self, view: View) -> ViewId {\n        let focus = self.focus;\n        let parent = self.nodes[focus].parent;\n        let mut node = Node::view(view);\n        node.parent = parent;\n        let node = self.nodes.insert(node);\n        self.get_mut(node).id = node;\n\n        let container = match &mut self.nodes[parent] {\n            Node {\n                content: Content::Container(container),\n                ..\n            } => container,\n            _ => unreachable!(),\n        };\n\n        // insert node after the current item if there is children already\n        let pos = if container.children.is_empty() {\n            0\n        } else {\n            let pos = container\n                .children\n                .iter()\n                .position(|&child| child == focus)\n                .unwrap();\n            pos + 1\n        };\n\n        container.children.insert(pos, node);\n        // focus the new node\n        self.focus = node;\n\n        // recalculate all the sizes\n        self.recalculate();\n\n        node\n    }\n\n    pub fn split(&mut self, view: View, layout: Layout) -> ViewId {\n        let focus = self.focus;\n        let parent = self.nodes[focus].parent;\n\n        let node = Node::view(view);\n        let node = self.nodes.insert(node);\n        self.get_mut(node).id = node;\n\n        let container = match &mut self.nodes[parent] {\n            Node {\n                content: Content::Container(container),\n                ..\n            } => container,\n            _ => unreachable!(),\n        };\n        if container.layout == layout {\n            // insert node after the current item if there is children already\n            let pos = if container.children.is_empty() {\n                0\n            } else {\n                let pos = container\n                    .children\n                    .iter()\n                    .position(|&child| child == focus)\n                    .unwrap();\n                pos + 1\n            };\n            container.children.insert(pos, node);\n            self.nodes[node].parent = parent;\n        } else {\n            let mut split = Node::container(layout);\n            split.parent = parent;\n            let split = self.nodes.insert(split);\n\n            let container = match &mut self.nodes[split] {\n                Node {\n                    content: Content::Container(container),\n                    ..\n                } => container,\n                _ => unreachable!(),\n            };\n            container.children.push(focus);\n            container.children.push(node);\n            self.nodes[focus].parent = split;\n            self.nodes[node].parent = split;\n\n            let container = match &mut self.nodes[parent] {\n                Node {\n                    content: Content::Container(container),\n                    ..\n                } => container,\n                _ => unreachable!(),\n            };\n\n            let pos = container\n                .children\n                .iter()\n                .position(|&child| child == focus)\n                .unwrap();\n\n            // replace focus on parent with split\n            container.children[pos] = split;\n        }\n\n        // focus the new node\n        self.focus = node;\n\n        // recalculate all the sizes\n        self.recalculate();\n\n        node\n    }\n\n    /// Get a mutable reference to a [Container] by index.\n    /// # Panics\n    /// Panics if `index` is not in self.nodes, or if the node's content is not a [Content::Container].\n    fn container_mut(&mut self, index: ViewId) -> &mut Container {\n        match &mut self.nodes[index] {\n            Node {\n                content: Content::Container(container),\n                ..\n            } => container,\n            _ => unreachable!(),\n        }\n    }\n\n    fn remove_or_replace(&mut self, child: ViewId, replacement: Option<ViewId>) {\n        let parent = self.nodes[child].parent;\n\n        self.nodes.remove(child);\n\n        let container = self.container_mut(parent);\n        let pos = container\n            .children\n            .iter()\n            .position(|&item| item == child)\n            .unwrap();\n\n        if let Some(new) = replacement {\n            container.children[pos] = new;\n            self.nodes[new].parent = parent;\n        } else {\n            container.children.remove(pos);\n        }\n    }\n\n    pub fn remove(&mut self, index: ViewId) {\n        if self.focus == index {\n            // focus on something else\n            self.focus = self.prev();\n        }\n\n        let parent = self.nodes[index].parent;\n        let parent_is_root = parent == self.root;\n\n        self.remove_or_replace(index, None);\n\n        let parent_container = self.container_mut(parent);\n        if parent_container.children.len() == 1 && !parent_is_root {\n            // Lets merge the only child back to its grandparent so that Views\n            // are equally spaced.\n            let sibling = parent_container.children.pop().unwrap();\n            self.remove_or_replace(parent, Some(sibling));\n        }\n\n        self.recalculate()\n    }\n\n    pub fn views(&self) -> impl Iterator<Item = (&View, bool)> {\n        let focus = self.focus;\n        self.nodes.iter().filter_map(move |(key, node)| match node {\n            Node {\n                content: Content::View(view),\n                ..\n            } => Some((view.as_ref(), focus == key)),\n            _ => None,\n        })\n    }\n\n    pub fn views_mut(&mut self) -> impl Iterator<Item = (&mut View, bool)> {\n        let focus = self.focus;\n        self.nodes\n            .iter_mut()\n            .filter_map(move |(key, node)| match node {\n                Node {\n                    content: Content::View(view),\n                    ..\n                } => Some((view.as_mut(), focus == key)),\n                _ => None,\n            })\n    }\n\n    /// Get reference to a [View] by index.\n    /// # Panics\n    ///\n    /// Panics if `index` is not in self.nodes, or if the node's content is not [Content::View]. This can be checked with [Self::contains].\n    pub fn get(&self, index: ViewId) -> &View {\n        self.try_get(index).unwrap()\n    }\n\n    /// Try to get reference to a [View] by index. Returns `None` if node content is not a [`Content::View`].\n    ///\n    /// Does not panic if the view does not exists anymore.\n    pub fn try_get(&self, index: ViewId) -> Option<&View> {\n        match self.nodes.get(index) {\n            Some(Node {\n                content: Content::View(view),\n                ..\n            }) => Some(view),\n            _ => None,\n        }\n    }\n\n    /// Get a mutable reference to a [View] by index.\n    /// # Panics\n    ///\n    /// Panics if `index` is not in self.nodes, or if the node's content is not [Content::View]. This can be checked with [Self::contains].\n    pub fn get_mut(&mut self, index: ViewId) -> &mut View {\n        match &mut self.nodes[index] {\n            Node {\n                content: Content::View(view),\n                ..\n            } => view,\n            _ => unreachable!(),\n        }\n    }\n\n    /// Check if tree contains a [Node] with a given index.\n    pub fn contains(&self, index: ViewId) -> bool {\n        self.nodes.contains_key(index)\n    }\n\n    pub fn is_empty(&self) -> bool {\n        match &self.nodes[self.root] {\n            Node {\n                content: Content::Container(container),\n                ..\n            } => container.children.is_empty(),\n            _ => unreachable!(),\n        }\n    }\n\n    pub fn resize(&mut self, area: Rect) -> bool {\n        if self.area != area {\n            self.area = area;\n            self.recalculate();\n            return true;\n        }\n        false\n    }\n\n    pub fn recalculate(&mut self) {\n        if self.is_empty() {\n            // There are no more views, so the tree should focus itself again.\n            self.focus = self.root;\n\n            return;\n        }\n\n        self.stack.push((self.root, self.area));\n\n        // take the area\n        // fetch the node\n        // a) node is view, give it whole area\n        // b) node is container, calculate areas for each child and push them on the stack\n\n        while let Some((key, area)) = self.stack.pop() {\n            let node = &mut self.nodes[key];\n\n            match &mut node.content {\n                Content::View(view) => {\n                    // debug!!(\"setting view area {:?}\", area);\n                    view.area = area;\n                } // TODO: call f()\n                Content::Container(container) => {\n                    // debug!!(\"setting container area {:?}\", area);\n                    container.area = area;\n\n                    match container.layout {\n                        Layout::Horizontal => {\n                            let len = container.children.len();\n\n                            let height = area.height / len as u16;\n\n                            let mut child_y = area.y;\n\n                            for (i, child) in container.children.iter().enumerate() {\n                                let mut area = Rect::new(\n                                    container.area.x,\n                                    child_y,\n                                    container.area.width,\n                                    height,\n                                );\n                                child_y += height;\n\n                                // last child takes the remaining width because we can get uneven\n                                // space from rounding\n                                if i == len - 1 {\n                                    area.height = container.area.y + container.area.height - area.y;\n                                }\n\n                                self.stack.push((*child, area));\n                            }\n                        }\n                        Layout::Vertical => {\n                            let len = container.children.len();\n                            let len_u16 = len as u16;\n\n                            let inner_gap = 1u16;\n                            let total_gap = inner_gap * len_u16.saturating_sub(2);\n\n                            let used_area = area.width.saturating_sub(total_gap);\n                            let width = used_area / len_u16;\n\n                            let mut child_x = area.x;\n\n                            for (i, child) in container.children.iter().enumerate() {\n                                let mut area = Rect::new(\n                                    child_x,\n                                    container.area.y,\n                                    width,\n                                    container.area.height,\n                                );\n                                child_x += width + inner_gap;\n\n                                // last child takes the remaining width because we can get uneven\n                                // space from rounding\n                                if i == len - 1 {\n                                    area.width = container.area.x + container.area.width - area.x;\n                                }\n\n                                self.stack.push((*child, area));\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    pub fn traverse(&self) -> Traverse<'_> {\n        Traverse::new(self)\n    }\n\n    // Finds the split in the given direction if it exists\n    pub fn find_split_in_direction(&self, id: ViewId, direction: Direction) -> Option<ViewId> {\n        let parent = self.nodes[id].parent;\n        // Base case, we found the root of the tree\n        if parent == id {\n            return None;\n        }\n        // Parent must always be a container\n        let parent_container = match &self.nodes[parent].content {\n            Content::Container(container) => container,\n            Content::View(_) => unreachable!(),\n        };\n\n        match (direction, parent_container.layout) {\n            (Direction::Up, Layout::Vertical)\n            | (Direction::Left, Layout::Horizontal)\n            | (Direction::Right, Layout::Horizontal)\n            | (Direction::Down, Layout::Vertical) => {\n                // The desired direction of movement is not possible within\n                // the parent container so the search must continue closer to\n                // the root of the split tree.\n                self.find_split_in_direction(parent, direction)\n            }\n            (Direction::Up, Layout::Horizontal)\n            | (Direction::Down, Layout::Horizontal)\n            | (Direction::Left, Layout::Vertical)\n            | (Direction::Right, Layout::Vertical) => {\n                // It's possible to move in the desired direction within\n                // the parent container so an attempt is made to find the\n                // correct child.\n                match self.find_child(id, &parent_container.children, direction) {\n                    // Child is found, search is ended\n                    Some(id) => Some(id),\n                    // A child is not found. This could be because of either two scenarios\n                    // 1. Its not possible to move in the desired direction, and search should end\n                    // 2. A layout like the following with focus at X and desired direction Right\n                    // | _ | x |   |\n                    // | _ _ _ |   |\n                    // | _ _ _ |   |\n                    // The container containing X ends at X so no rightward movement is possible\n                    // however there still exists another view/container to the right that hasn't\n                    // been explored. Thus another search is done here in the parent container\n                    // before concluding it's not possible to move in the desired direction.\n                    None => self.find_split_in_direction(parent, direction),\n                }\n            }\n        }\n    }\n\n    fn find_child(&self, id: ViewId, children: &[ViewId], direction: Direction) -> Option<ViewId> {\n        let mut child_id = match direction {\n            // index wise in the child list the Up and Left represents a -1\n            // thus reversed iterator.\n            Direction::Up | Direction::Left => children\n                .iter()\n                .rev()\n                .skip_while(|i| **i != id)\n                .copied()\n                .nth(1)?,\n            // Down and Right => +1 index wise in the child list\n            Direction::Down | Direction::Right => {\n                children.iter().skip_while(|i| **i != id).copied().nth(1)?\n            }\n        };\n        let (current_x, current_y) = match &self.nodes[self.focus].content {\n            Content::View(current_view) => (current_view.area.left(), current_view.area.top()),\n            Content::Container(_) => unreachable!(),\n        };\n\n        // If the child is a container the search finds the closest container child\n        // visually based on screen location.\n        while let Content::Container(container) = &self.nodes[child_id].content {\n            match (direction, container.layout) {\n                (_, Layout::Vertical) => {\n                    // find closest split based on x because y is irrelevant\n                    // in a vertical container (and already correct based on previous search)\n                    child_id = *container.children.iter().min_by_key(|id| {\n                        let x = match &self.nodes[**id].content {\n                            Content::View(view) => view.area.left(),\n                            Content::Container(container) => container.area.left(),\n                        };\n                        (current_x as i16 - x as i16).abs()\n                    })?;\n                }\n                (_, Layout::Horizontal) => {\n                    // find closest split based on y because x is irrelevant\n                    // in a horizontal container (and already correct based on previous search)\n                    child_id = *container.children.iter().min_by_key(|id| {\n                        let y = match &self.nodes[**id].content {\n                            Content::View(view) => view.area.top(),\n                            Content::Container(container) => container.area.top(),\n                        };\n                        (current_y as i16 - y as i16).abs()\n                    })?;\n                }\n            }\n        }\n        Some(child_id)\n    }\n\n    pub fn prev(&self) -> ViewId {\n        // This function is very dumb, but that's because we don't store any parent links.\n        // (we'd be able to go parent.prev_sibling() recursively until we find something)\n        // For now that's okay though, since it's unlikely you'll be able to open a large enough\n        // number of splits to notice.\n\n        let mut views = self\n            .traverse()\n            .rev()\n            .skip_while(|&(id, _view)| id != self.focus)\n            .skip(1); // Skip focused value\n        if let Some((id, _)) = views.next() {\n            id\n        } else {\n            // extremely crude, take the last item\n            let (key, _) = self.traverse().next_back().unwrap();\n            key\n        }\n    }\n\n    pub fn next(&self) -> ViewId {\n        // This function is very dumb, but that's because we don't store any parent links.\n        // (we'd be able to go parent.next_sibling() recursively until we find something)\n        // For now that's okay though, since it's unlikely you'll be able to open a large enough\n        // number of splits to notice.\n\n        let mut views = self\n            .traverse()\n            .skip_while(|&(id, _view)| id != self.focus)\n            .skip(1); // Skip focused value\n        if let Some((id, _)) = views.next() {\n            id\n        } else {\n            // extremely crude, take the first item again\n            let (key, _) = self.traverse().next().unwrap();\n            key\n        }\n    }\n\n    pub fn transpose(&mut self) {\n        let focus = self.focus;\n        let parent = self.nodes[focus].parent;\n        if let Content::Container(container) = &mut self.nodes[parent].content {\n            container.layout = match container.layout {\n                Layout::Vertical => Layout::Horizontal,\n                Layout::Horizontal => Layout::Vertical,\n            };\n            self.recalculate();\n        }\n    }\n\n    pub fn swap_split_in_direction(&mut self, direction: Direction) -> Option<()> {\n        let focus = self.focus;\n        let target = self.find_split_in_direction(focus, direction)?;\n        let focus_parent = self.nodes[focus].parent;\n        let target_parent = self.nodes[target].parent;\n\n        if focus_parent == target_parent {\n            let parent = focus_parent;\n            let [parent, focus, target] = self.nodes.get_disjoint_mut([parent, focus, target])?;\n            match (&mut parent.content, &mut focus.content, &mut target.content) {\n                (\n                    Content::Container(parent),\n                    Content::View(focus_view),\n                    Content::View(target_view),\n                ) => {\n                    let focus_pos = parent.children.iter().position(|id| focus_view.id == *id)?;\n                    let target_pos = parent\n                        .children\n                        .iter()\n                        .position(|id| target_view.id == *id)?;\n                    // swap node positions so that traversal order is kept\n                    parent.children[focus_pos] = target_view.id;\n                    parent.children[target_pos] = focus_view.id;\n                    // swap area so that views rendered at the correct location\n                    std::mem::swap(&mut focus_view.area, &mut target_view.area);\n\n                    Some(())\n                }\n                _ => unreachable!(),\n            }\n        } else {\n            let [focus_parent, target_parent, focus, target] =\n                self.nodes\n                    .get_disjoint_mut([focus_parent, target_parent, focus, target])?;\n            match (\n                &mut focus_parent.content,\n                &mut target_parent.content,\n                &mut focus.content,\n                &mut target.content,\n            ) {\n                (\n                    Content::Container(focus_parent),\n                    Content::Container(target_parent),\n                    Content::View(focus_view),\n                    Content::View(target_view),\n                ) => {\n                    let focus_pos = focus_parent\n                        .children\n                        .iter()\n                        .position(|id| focus_view.id == *id)?;\n                    let target_pos = target_parent\n                        .children\n                        .iter()\n                        .position(|id| target_view.id == *id)?;\n                    // re-parent target and focus nodes\n                    std::mem::swap(\n                        &mut focus_parent.children[focus_pos],\n                        &mut target_parent.children[target_pos],\n                    );\n                    std::mem::swap(&mut focus.parent, &mut target.parent);\n                    // swap area so that views rendered at the correct location\n                    std::mem::swap(&mut focus_view.area, &mut target_view.area);\n\n                    Some(())\n                }\n                _ => unreachable!(),\n            }\n        }\n    }\n\n    pub fn area(&self) -> Rect {\n        self.area\n    }\n}\n\n#[derive(Debug)]\npub struct Traverse<'a> {\n    tree: &'a Tree,\n    stack: Vec<ViewId>, // TODO: reuse the one we use on update\n}\n\nimpl<'a> Traverse<'a> {\n    fn new(tree: &'a Tree) -> Self {\n        Self {\n            tree,\n            stack: vec![tree.root],\n        }\n    }\n}\n\nimpl<'a> Iterator for Traverse<'a> {\n    type Item = (ViewId, &'a View);\n\n    fn next(&mut self) -> Option<Self::Item> {\n        loop {\n            let key = self.stack.pop()?;\n\n            let node = &self.tree.nodes[key];\n\n            match &node.content {\n                Content::View(view) => return Some((key, view)),\n                Content::Container(container) => {\n                    self.stack.extend(container.children.iter().rev());\n                }\n            }\n        }\n    }\n}\n\nimpl DoubleEndedIterator for Traverse<'_> {\n    fn next_back(&mut self) -> Option<Self::Item> {\n        loop {\n            let key = self.stack.pop()?;\n\n            let node = &self.tree.nodes[key];\n\n            match &node.content {\n                Content::View(view) => return Some((key, view)),\n                Content::Container(container) => {\n                    self.stack.extend(container.children.iter());\n                }\n            }\n        }\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::editor::GutterConfig;\n    use crate::DocumentId;\n\n    #[test]\n    fn find_split_in_direction() {\n        let mut tree = Tree::new(Rect {\n            x: 0,\n            y: 0,\n            width: 180,\n            height: 80,\n        });\n        let mut view = View::new(DocumentId::default(), GutterConfig::default());\n        view.area = Rect::new(0, 0, 180, 80);\n        tree.insert(view);\n\n        let l0 = tree.focus;\n        let view = View::new(DocumentId::default(), GutterConfig::default());\n        tree.split(view, Layout::Vertical);\n        let r0 = tree.focus;\n\n        tree.focus = l0;\n        let view = View::new(DocumentId::default(), GutterConfig::default());\n        tree.split(view, Layout::Horizontal);\n        let l1 = tree.focus;\n\n        tree.focus = l0;\n        let view = View::new(DocumentId::default(), GutterConfig::default());\n        tree.split(view, Layout::Vertical);\n\n        // Tree in test\n        // | L0  | L2 |    |\n        // |    L1    | R0 |\n        let l2 = tree.focus;\n        assert_eq!(Some(l0), tree.find_split_in_direction(l2, Direction::Left));\n        assert_eq!(Some(l1), tree.find_split_in_direction(l2, Direction::Down));\n        assert_eq!(Some(r0), tree.find_split_in_direction(l2, Direction::Right));\n        assert_eq!(None, tree.find_split_in_direction(l2, Direction::Up));\n\n        tree.focus = l1;\n        assert_eq!(None, tree.find_split_in_direction(l1, Direction::Left));\n        assert_eq!(None, tree.find_split_in_direction(l1, Direction::Down));\n        assert_eq!(Some(r0), tree.find_split_in_direction(l1, Direction::Right));\n        assert_eq!(Some(l0), tree.find_split_in_direction(l1, Direction::Up));\n\n        tree.focus = l0;\n        assert_eq!(None, tree.find_split_in_direction(l0, Direction::Left));\n        assert_eq!(Some(l1), tree.find_split_in_direction(l0, Direction::Down));\n        assert_eq!(Some(l2), tree.find_split_in_direction(l0, Direction::Right));\n        assert_eq!(None, tree.find_split_in_direction(l0, Direction::Up));\n\n        tree.focus = r0;\n        assert_eq!(Some(l2), tree.find_split_in_direction(r0, Direction::Left));\n        assert_eq!(None, tree.find_split_in_direction(r0, Direction::Down));\n        assert_eq!(None, tree.find_split_in_direction(r0, Direction::Right));\n        assert_eq!(None, tree.find_split_in_direction(r0, Direction::Up));\n    }\n\n    #[test]\n    fn swap_split_in_direction() {\n        let mut tree = Tree::new(Rect {\n            x: 0,\n            y: 0,\n            width: 180,\n            height: 80,\n        });\n\n        let doc_l0 = DocumentId::default();\n        let mut view = View::new(doc_l0, GutterConfig::default());\n        view.area = Rect::new(0, 0, 180, 80);\n        tree.insert(view);\n\n        let l0 = tree.focus;\n\n        let doc_r0 = DocumentId::default();\n        let view = View::new(doc_r0, GutterConfig::default());\n        tree.split(view, Layout::Vertical);\n        let r0 = tree.focus;\n\n        tree.focus = l0;\n\n        let doc_l1 = DocumentId::default();\n        let view = View::new(doc_l1, GutterConfig::default());\n        tree.split(view, Layout::Horizontal);\n        let l1 = tree.focus;\n\n        tree.focus = l0;\n\n        let doc_l2 = DocumentId::default();\n        let view = View::new(doc_l2, GutterConfig::default());\n        tree.split(view, Layout::Vertical);\n        let l2 = tree.focus;\n\n        // Views in test\n        // | L0  | L2 |    |\n        // |    L1    | R0 |\n\n        // Document IDs in test\n        // | l0  | l2 |    |\n        // |    l1    | r0 |\n\n        fn doc_id(tree: &Tree, view_id: ViewId) -> Option<DocumentId> {\n            if let Content::View(view) = &tree.nodes[view_id].content {\n                Some(view.doc)\n            } else {\n                None\n            }\n        }\n\n        tree.focus = l0;\n        // `*` marks the view in focus from view table (here L0)\n        // | l0*  | l2 |    |\n        // |    l1     | r0 |\n        tree.swap_split_in_direction(Direction::Down);\n        // | l1   | l2 |    |\n        // |    l0*    | r0 |\n        assert_eq!(tree.focus, l0);\n        assert_eq!(doc_id(&tree, l0), Some(doc_l1));\n        assert_eq!(doc_id(&tree, l1), Some(doc_l0));\n        assert_eq!(doc_id(&tree, l2), Some(doc_l2));\n        assert_eq!(doc_id(&tree, r0), Some(doc_r0));\n\n        tree.swap_split_in_direction(Direction::Right);\n\n        // | l1  | l2 |     |\n        // |    r0    | l0* |\n        assert_eq!(tree.focus, l0);\n        assert_eq!(doc_id(&tree, l0), Some(doc_l1));\n        assert_eq!(doc_id(&tree, l1), Some(doc_r0));\n        assert_eq!(doc_id(&tree, l2), Some(doc_l2));\n        assert_eq!(doc_id(&tree, r0), Some(doc_l0));\n\n        // cannot swap, nothing changes\n        tree.swap_split_in_direction(Direction::Up);\n        // | l1  | l2 |     |\n        // |    r0    | l0* |\n        assert_eq!(tree.focus, l0);\n        assert_eq!(doc_id(&tree, l0), Some(doc_l1));\n        assert_eq!(doc_id(&tree, l1), Some(doc_r0));\n        assert_eq!(doc_id(&tree, l2), Some(doc_l2));\n        assert_eq!(doc_id(&tree, r0), Some(doc_l0));\n\n        // cannot swap, nothing changes\n        tree.swap_split_in_direction(Direction::Down);\n        // | l1  | l2 |     |\n        // |    r0    | l0* |\n        assert_eq!(tree.focus, l0);\n        assert_eq!(doc_id(&tree, l0), Some(doc_l1));\n        assert_eq!(doc_id(&tree, l1), Some(doc_r0));\n        assert_eq!(doc_id(&tree, l2), Some(doc_l2));\n        assert_eq!(doc_id(&tree, r0), Some(doc_l0));\n\n        tree.focus = l2;\n        // | l1  | l2* |    |\n        // |    r0     | l0 |\n\n        tree.swap_split_in_direction(Direction::Down);\n        // | l1  | r0  |    |\n        // |    l2*    | l0 |\n        assert_eq!(tree.focus, l2);\n        assert_eq!(doc_id(&tree, l0), Some(doc_l1));\n        assert_eq!(doc_id(&tree, l1), Some(doc_l2));\n        assert_eq!(doc_id(&tree, l2), Some(doc_r0));\n        assert_eq!(doc_id(&tree, r0), Some(doc_l0));\n\n        tree.swap_split_in_direction(Direction::Up);\n        // | l2* | r0 |    |\n        // |    l1    | l0 |\n        assert_eq!(tree.focus, l2);\n        assert_eq!(doc_id(&tree, l0), Some(doc_l2));\n        assert_eq!(doc_id(&tree, l1), Some(doc_l1));\n        assert_eq!(doc_id(&tree, l2), Some(doc_r0));\n        assert_eq!(doc_id(&tree, r0), Some(doc_l0));\n    }\n\n    #[test]\n    fn all_vertical_views_have_same_width() {\n        let tree_area_width = 180;\n        let mut tree = Tree::new(Rect {\n            x: 0,\n            y: 0,\n            width: tree_area_width,\n            height: 80,\n        });\n        let mut view = View::new(DocumentId::default(), GutterConfig::default());\n        view.area = Rect::new(0, 0, 180, 80);\n        tree.insert(view);\n\n        let view = View::new(DocumentId::default(), GutterConfig::default());\n        tree.split(view, Layout::Vertical);\n\n        let view = View::new(DocumentId::default(), GutterConfig::default());\n        tree.split(view, Layout::Horizontal);\n\n        tree.remove(tree.focus);\n\n        let view = View::new(DocumentId::default(), GutterConfig::default());\n        tree.split(view, Layout::Vertical);\n\n        // Make sure that we only have one level in the tree.\n        assert_eq!(3, tree.views().count());\n        assert_eq!(\n            vec![\n                tree_area_width / 3 - 1, // gap here\n                tree_area_width / 3 - 1, // gap here\n                tree_area_width / 3\n            ],\n            tree.views()\n                .map(|(view, _)| view.area.width)\n                .collect::<Vec<_>>()\n        );\n    }\n\n    #[test]\n    fn vsplit_gap_rounding() {\n        let (tree_area_width, tree_area_height) = (80, 24);\n        let mut tree = Tree::new(Rect {\n            x: 0,\n            y: 0,\n            width: tree_area_width,\n            height: tree_area_height,\n        });\n        let mut view = View::new(DocumentId::default(), GutterConfig::default());\n        view.area = Rect::new(0, 0, tree_area_width, tree_area_height);\n        tree.insert(view);\n\n        for _ in 0..9 {\n            let view = View::new(DocumentId::default(), GutterConfig::default());\n            tree.split(view, Layout::Vertical);\n        }\n\n        assert_eq!(10, tree.views().count());\n        assert_eq!(\n            std::iter::repeat_n(7, 9)\n                .chain(Some(8)) // Rounding in `recalculate`.\n                .collect::<Vec<_>>(),\n            tree.views()\n                .map(|(view, _)| view.area.width)\n                .collect::<Vec<_>>()\n        );\n    }\n}\n"
  },
  {
    "path": "helix-view/src/view.rs",
    "content": "use crate::{\n    align_view,\n    annotations::diagnostics::InlineDiagnostics,\n    document::{DocumentColorSwatches, DocumentInlayHints},\n    editor::{GutterConfig, GutterType},\n    graphics::Rect,\n    handlers::diagnostics::DiagnosticsHandler,\n    Align, Document, DocumentId, Theme, ViewId,\n};\n\nuse helix_core::{\n    char_idx_at_visual_offset,\n    doc_formatter::TextFormat,\n    text_annotations::TextAnnotations,\n    visual_offset_from_anchor, visual_offset_from_block, Position, RopeSlice, Selection,\n    Transaction,\n    VisualOffsetError::{PosAfterMaxRow, PosBeforeAnchorRow},\n};\n\nuse std::{\n    collections::{HashMap, VecDeque},\n    fmt,\n};\n\nconst JUMP_LIST_CAPACITY: usize = 30;\n\ntype Jump = (DocumentId, Selection);\n\n#[derive(Debug, Clone)]\npub struct JumpList {\n    jumps: VecDeque<Jump>,\n    current: usize,\n}\n\nimpl JumpList {\n    pub fn new(initial: Jump) -> Self {\n        let mut jumps = VecDeque::with_capacity(JUMP_LIST_CAPACITY);\n        jumps.push_back(initial);\n        Self { jumps, current: 0 }\n    }\n\n    fn push_impl(&mut self, jump: Jump) -> usize {\n        let mut num_removed_from_front = 0;\n        self.jumps.truncate(self.current);\n        // don't push duplicates\n        if self.jumps.back() != Some(&jump) {\n            // If the jumplist is full, drop the oldest item.\n            while self.jumps.len() >= JUMP_LIST_CAPACITY {\n                self.jumps.pop_front();\n                num_removed_from_front += 1;\n            }\n\n            self.jumps.push_back(jump);\n            self.current = self.jumps.len();\n        }\n        num_removed_from_front\n    }\n\n    pub fn push(&mut self, jump: Jump) {\n        self.push_impl(jump);\n    }\n\n    pub(crate) fn forward(&mut self, count: usize) -> Option<&Jump> {\n        if self.current + count < self.jumps.len() {\n            self.current += count;\n            self.jumps.get(self.current)\n        } else {\n            None\n        }\n    }\n\n    // Taking view and doc to prevent unnecessary cloning when jump is not required.\n    pub(crate) fn backward(\n        &mut self,\n        view_id: ViewId,\n        doc: &mut Document,\n        count: usize,\n    ) -> Option<&Jump> {\n        if let Some(mut current) = self.current.checked_sub(count) {\n            if self.current == self.jumps.len() {\n                let jump = (doc.id(), doc.selection(view_id).clone());\n                let num_removed = self.push_impl(jump);\n                current = current.saturating_sub(num_removed);\n            }\n            self.current = current;\n\n            // Avoid jumping to the current location.\n            let (doc_id, selection) = self.jumps.get(self.current)?;\n            if doc.id() == *doc_id && doc.selection(view_id) == selection {\n                self.current = self.current.checked_sub(1)?;\n            }\n            self.jumps.get(self.current)\n        } else {\n            None\n        }\n    }\n\n    pub fn remove(&mut self, doc_id: &DocumentId) {\n        self.jumps.retain(|(other_id, _)| other_id != doc_id);\n    }\n\n    pub fn iter(&self) -> impl DoubleEndedIterator<Item = &Jump> {\n        self.jumps.iter()\n    }\n\n    /// Applies a [`Transaction`] of changes to the jumplist.\n    /// This is necessary to ensure that changes to documents do not leave jump-list\n    /// selections pointing to parts of the text which no longer exist.\n    fn apply(&mut self, transaction: &Transaction, doc: &Document) {\n        let text = doc.text().slice(..);\n\n        for (doc_id, selection) in &mut self.jumps {\n            if doc.id() == *doc_id {\n                *selection = selection\n                    .clone()\n                    .map(transaction.changes())\n                    .ensure_invariants(text);\n            }\n        }\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, Copy, Default)]\npub struct ViewPosition {\n    pub anchor: usize,\n    pub horizontal_offset: usize,\n    pub vertical_offset: usize,\n}\n\n#[derive(Clone)]\npub struct View {\n    pub id: ViewId,\n    pub area: Rect,\n    pub doc: DocumentId,\n    pub jumps: JumpList,\n    // documents accessed from this view from the oldest one to last viewed one\n    pub docs_access_history: Vec<DocumentId>,\n    /// the last modified files before the current one\n    /// ordered from most frequent to least frequent\n    // uses two docs because we want to be able to swap between the\n    // two last modified docs which we need to manually keep track of\n    pub last_modified_docs: [Option<DocumentId>; 2],\n    /// used to store previous selections of tree-sitter objects\n    pub object_selections: Vec<Selection>,\n    /// all gutter-related configuration settings, used primarily for gutter rendering\n    pub gutters: GutterConfig,\n    /// A mapping between documents and the last history revision the view was updated at.\n    /// Changes between documents and views are synced lazily when switching windows. This\n    /// mapping keeps track of the last applied history revision so that only new changes\n    /// are applied.\n    doc_revisions: HashMap<DocumentId, usize>,\n    // HACKS: there should really only be a global diagnostics handler (the\n    // non-focused views should just not have different handling for the cursor\n    // line). For that we would need accces to editor everywhere (we want to use\n    // the positioning code) so this can only happen by refactoring View and\n    // Document into entity component like structure. That is a huge refactor\n    // left to future work. For now we treat all views as focused and give them\n    // each their own handler.\n    pub diagnostics_handler: DiagnosticsHandler,\n}\n\nimpl fmt::Debug for View {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"View\")\n            .field(\"id\", &self.id)\n            .field(\"area\", &self.area)\n            .field(\"doc\", &self.doc)\n            .finish()\n    }\n}\n\nimpl View {\n    pub fn new(doc: DocumentId, gutters: GutterConfig) -> Self {\n        Self {\n            id: ViewId::default(),\n            doc,\n            area: Rect::default(), // will get calculated upon inserting into tree\n            jumps: JumpList::new((doc, Selection::point(0))), // TODO: use actual sel\n            docs_access_history: Vec::new(),\n            last_modified_docs: [None, None],\n            object_selections: Vec::new(),\n            gutters,\n            doc_revisions: HashMap::new(),\n            diagnostics_handler: DiagnosticsHandler::new(),\n        }\n    }\n\n    pub fn add_to_history(&mut self, id: DocumentId) {\n        if let Some(pos) = self.docs_access_history.iter().position(|&doc| doc == id) {\n            self.docs_access_history.remove(pos);\n        }\n        self.docs_access_history.push(id);\n    }\n\n    pub fn inner_area(&self, doc: &Document) -> Rect {\n        self.area.clip_left(self.gutter_offset(doc)).clip_bottom(1) // -1 for statusline\n    }\n\n    pub fn inner_height(&self) -> usize {\n        self.area.clip_bottom(1).height.into() // -1 for statusline\n    }\n\n    pub fn inner_width(&self, doc: &Document) -> u16 {\n        self.area.clip_left(self.gutter_offset(doc)).width\n    }\n\n    pub fn gutters(&self) -> &[GutterType] {\n        &self.gutters.layout\n    }\n\n    pub fn gutter_offset(&self, doc: &Document) -> u16 {\n        let total_width = self\n            .gutters\n            .layout\n            .iter()\n            .map(|gutter| gutter.width(self, doc) as u16)\n            .sum();\n        if total_width < self.area.width {\n            total_width\n        } else {\n            0\n        }\n    }\n\n    //\n    pub fn offset_coords_to_in_view(\n        &self,\n        doc: &Document,\n        scrolloff: usize,\n    ) -> Option<ViewPosition> {\n        self.offset_coords_to_in_view_center::<false>(doc, scrolloff)\n    }\n\n    pub fn offset_coords_to_in_view_center<const CENTERING: bool>(\n        &self,\n        doc: &Document,\n        scrolloff: usize,\n    ) -> Option<ViewPosition> {\n        let view_offset = doc.get_view_offset(self.id)?;\n        let doc_text = doc.text().slice(..);\n        let viewport = self.inner_area(doc);\n        let vertical_viewport_end = view_offset.vertical_offset + viewport.height as usize;\n        let text_fmt = doc.text_format(viewport.width, None);\n        let annotations = self.text_annotations(doc, None);\n\n        let (scrolloff_top, scrolloff_bottom) = if CENTERING {\n            (0, 0)\n        } else {\n            (\n                // - 1 from the top so we have at least one gap in the middle.\n                scrolloff.min(viewport.height.saturating_sub(1) as usize / 2),\n                scrolloff.min(viewport.height as usize / 2),\n            )\n        };\n        let (scrolloff_left, scrolloff_right) = if CENTERING {\n            (0, 0)\n        } else {\n            (\n                // - 1 from the left so we have at least one gap in the middle.\n                scrolloff.min(viewport.width.saturating_sub(1) as usize / 2),\n                scrolloff.min(viewport.width as usize / 2),\n            )\n        };\n\n        let cursor = doc.selection(self.id).primary().cursor(doc_text);\n        let mut offset = view_offset;\n        let off = visual_offset_from_anchor(\n            doc_text,\n            offset.anchor,\n            cursor,\n            &text_fmt,\n            &annotations,\n            vertical_viewport_end,\n        );\n\n        let (new_anchor, at_top) = match off {\n            Ok((visual_pos, _)) if visual_pos.row < scrolloff_top + offset.vertical_offset => {\n                if CENTERING {\n                    // cursor out of view\n                    return None;\n                }\n                (true, true)\n            }\n            Ok((visual_pos, _)) if visual_pos.row + scrolloff_bottom >= vertical_viewport_end => {\n                (true, false)\n            }\n            Ok((_, _)) => (false, false),\n            Err(_) if CENTERING => return None,\n            Err(PosBeforeAnchorRow) => (true, true),\n            Err(PosAfterMaxRow) => (true, false),\n        };\n\n        if new_anchor {\n            let v_off = if at_top {\n                scrolloff_top as isize\n            } else {\n                viewport.height as isize - scrolloff_bottom as isize - 1\n            };\n            (offset.anchor, offset.vertical_offset) =\n                char_idx_at_visual_offset(doc_text, cursor, -v_off, 0, &text_fmt, &annotations);\n        }\n\n        if text_fmt.soft_wrap {\n            offset.horizontal_offset = 0;\n        } else {\n            // determine the current visual column of the text\n            let col = off\n                .unwrap_or_else(|_| {\n                    visual_offset_from_block(\n                        doc_text,\n                        offset.anchor,\n                        cursor,\n                        &text_fmt,\n                        &annotations,\n                    )\n                })\n                .0\n                .col;\n\n            let last_col = offset.horizontal_offset + viewport.width.saturating_sub(1) as usize;\n            if col > last_col.saturating_sub(scrolloff_right) {\n                // scroll right\n                offset.horizontal_offset += col - (last_col.saturating_sub(scrolloff_right))\n            } else if col < offset.horizontal_offset + scrolloff_left {\n                // scroll left\n                offset.horizontal_offset = col.saturating_sub(scrolloff_left)\n            };\n        }\n\n        // if we are not centering return None if view position is unchanged\n        if !CENTERING && offset == view_offset {\n            return None;\n        }\n\n        Some(offset)\n    }\n\n    pub fn ensure_cursor_in_view(&self, doc: &mut Document, scrolloff: usize) {\n        if let Some(offset) = self.offset_coords_to_in_view_center::<false>(doc, scrolloff) {\n            doc.set_view_offset(self.id, offset);\n        }\n    }\n\n    pub fn ensure_cursor_in_view_center(&self, doc: &mut Document, scrolloff: usize) {\n        if let Some(offset) = self.offset_coords_to_in_view_center::<true>(doc, scrolloff) {\n            doc.set_view_offset(self.id, offset);\n        } else {\n            align_view(doc, self, Align::Center);\n        }\n    }\n\n    pub fn is_cursor_in_view(&mut self, doc: &Document, scrolloff: usize) -> bool {\n        self.offset_coords_to_in_view(doc, scrolloff).is_none()\n    }\n\n    /// Estimates the last visible document line on screen.\n    /// This estimate is an upper bound obtained by calculating the first\n    /// visible line and adding the viewport height.\n    /// The actual last visible line may be smaller if softwrapping occurs\n    /// or virtual text lines are visible\n    #[inline]\n    pub fn estimate_last_doc_line(&self, doc: &Document) -> usize {\n        let doc_text = doc.text().slice(..);\n        let line = doc_text.char_to_line(doc.view_offset(self.id).anchor.min(doc_text.len_chars()));\n        // Saturating subs to make it inclusive zero indexing.\n        (line + self.inner_height())\n            .min(doc_text.len_lines())\n            .saturating_sub(1)\n    }\n\n    /// Calculates the last non-empty visual line on screen\n    #[inline]\n    pub fn last_visual_line(&self, doc: &Document) -> usize {\n        let doc_text = doc.text().slice(..);\n        let viewport = self.inner_area(doc);\n        let text_fmt = doc.text_format(viewport.width, None);\n        let annotations = self.text_annotations(doc, None);\n        let view_offset = doc.view_offset(self.id);\n\n        // last visual line in view is trivial to compute\n        let visual_height = doc.view_offset(self.id).vertical_offset + viewport.height as usize;\n\n        // fast path when the EOF is not visible on the screen,\n        if self.estimate_last_doc_line(doc) < doc_text.len_lines() - 1 {\n            return visual_height.saturating_sub(1);\n        }\n\n        // translate to document line\n        let pos = visual_offset_from_anchor(\n            doc_text,\n            view_offset.anchor,\n            usize::MAX,\n            &text_fmt,\n            &annotations,\n            visual_height,\n        );\n\n        match pos {\n            Ok((Position { row, .. }, _)) => row.saturating_sub(view_offset.vertical_offset),\n            Err(PosAfterMaxRow) => visual_height.saturating_sub(1),\n            Err(PosBeforeAnchorRow) => 0,\n        }\n    }\n\n    /// Translates a document position to an absolute position in the terminal.\n    /// Returns a (line, col) position if the position is visible on screen.\n    // TODO: Could return width as well for the character width at cursor.\n    pub fn screen_coords_at_pos(\n        &self,\n        doc: &Document,\n        text: RopeSlice,\n        pos: usize,\n    ) -> Option<Position> {\n        let view_offset = doc.view_offset(self.id);\n\n        let viewport = self.inner_area(doc);\n        let text_fmt = doc.text_format(viewport.width, None);\n        let annotations = self.text_annotations(doc, None);\n\n        let mut pos = visual_offset_from_anchor(\n            text,\n            view_offset.anchor,\n            pos,\n            &text_fmt,\n            &annotations,\n            viewport.height as usize,\n        )\n        .ok()?\n        .0;\n        if pos.row < view_offset.vertical_offset {\n            return None;\n        }\n        pos.row -= view_offset.vertical_offset;\n        if pos.row >= viewport.height as usize {\n            return None;\n        }\n        pos.col = pos.col.saturating_sub(view_offset.horizontal_offset);\n\n        Some(pos)\n    }\n\n    /// Get the text annotations to display in the current view for the given document and theme.\n    pub fn text_annotations<'a>(\n        &self,\n        doc: &'a Document,\n        theme: Option<&Theme>,\n    ) -> TextAnnotations<'a> {\n        let mut text_annotations = TextAnnotations::default();\n\n        if let Some(labels) = doc.jump_labels.get(&self.id) {\n            let style = theme.and_then(|t| t.find_highlight(\"ui.virtual.jump-label\"));\n            text_annotations.add_overlay(labels, style);\n        }\n\n        if let Some(DocumentInlayHints {\n            id: _,\n            type_inlay_hints,\n            parameter_inlay_hints,\n            other_inlay_hints,\n            padding_before_inlay_hints,\n            padding_after_inlay_hints,\n        }) = doc.inlay_hints.get(&self.id)\n        {\n            let type_style = theme.and_then(|t| t.find_highlight(\"ui.virtual.inlay-hint.type\"));\n            let parameter_style =\n                theme.and_then(|t| t.find_highlight(\"ui.virtual.inlay-hint.parameter\"));\n            let other_style = theme.and_then(|t| t.find_highlight(\"ui.virtual.inlay-hint\"));\n\n            // Overlapping annotations are ignored apart from the first so the order here is not random:\n            // types -> parameters -> others should hopefully be the \"correct\" order for most use cases,\n            // with the padding coming before and after as expected.\n            text_annotations\n                .add_inline_annotations(padding_before_inlay_hints, None)\n                .add_inline_annotations(type_inlay_hints, type_style)\n                .add_inline_annotations(parameter_inlay_hints, parameter_style)\n                .add_inline_annotations(other_inlay_hints, other_style)\n                .add_inline_annotations(padding_after_inlay_hints, None);\n        };\n        let config = doc.config.load();\n\n        if config.lsp.display_color_swatches {\n            if let Some(DocumentColorSwatches {\n                color_swatches,\n                colors,\n                color_swatches_padding,\n            }) = &doc.color_swatches\n            {\n                for (color_swatch, color) in color_swatches.iter().zip(colors) {\n                    text_annotations\n                        .add_inline_annotations(std::slice::from_ref(color_swatch), Some(*color));\n                }\n\n                text_annotations.add_inline_annotations(color_swatches_padding, None);\n            }\n        }\n\n        let width = self.inner_width(doc);\n        let enable_cursor_line = self\n            .diagnostics_handler\n            .show_cursorline_diagnostics(doc, self.id);\n        let config = config.inline_diagnostics.prepare(width, enable_cursor_line);\n        if !config.disabled() {\n            let cursor = doc\n                .selection(self.id)\n                .primary()\n                .cursor(doc.text().slice(..));\n            text_annotations.add_line_annotation(InlineDiagnostics::new(\n                doc,\n                cursor,\n                width,\n                doc.view_offset(self.id).horizontal_offset,\n                config,\n            ));\n        }\n\n        text_annotations\n    }\n\n    pub fn text_pos_at_screen_coords(\n        &self,\n        doc: &Document,\n        row: u16,\n        column: u16,\n        fmt: TextFormat,\n        annotations: &TextAnnotations,\n        ignore_virtual_text: bool,\n    ) -> Option<usize> {\n        let inner = self.inner_area(doc);\n        // 1 for status\n        if row < inner.top() || row >= inner.bottom() {\n            return None;\n        }\n\n        if column < inner.left() || column > inner.right() {\n            return None;\n        }\n\n        self.text_pos_at_visual_coords(\n            doc,\n            row - inner.y,\n            column - inner.x,\n            fmt,\n            annotations,\n            ignore_virtual_text,\n        )\n    }\n\n    pub fn text_pos_at_visual_coords(\n        &self,\n        doc: &Document,\n        row: u16,\n        column: u16,\n        text_fmt: TextFormat,\n        annotations: &TextAnnotations,\n        ignore_virtual_text: bool,\n    ) -> Option<usize> {\n        let text = doc.text().slice(..);\n        let view_offset = doc.view_offset(self.id);\n\n        let text_row = row as usize + view_offset.vertical_offset;\n        let text_col = column as usize + view_offset.horizontal_offset;\n\n        let (char_idx, virt_lines) = char_idx_at_visual_offset(\n            text,\n            view_offset.anchor,\n            text_row as isize,\n            text_col,\n            &text_fmt,\n            annotations,\n        );\n\n        // if the cursor is on a line with only virtual text return None\n        if virt_lines != 0 && ignore_virtual_text {\n            return None;\n        }\n        Some(char_idx)\n    }\n\n    /// Translates a screen position to position in the text document.\n    /// Returns a usize typed position in bounds of the text if found in this view, None if out of view.\n    pub fn pos_at_screen_coords(\n        &self,\n        doc: &Document,\n        row: u16,\n        column: u16,\n        ignore_virtual_text: bool,\n    ) -> Option<usize> {\n        self.text_pos_at_screen_coords(\n            doc,\n            row,\n            column,\n            doc.text_format(self.inner_width(doc), None),\n            &self.text_annotations(doc, None),\n            ignore_virtual_text,\n        )\n    }\n\n    pub fn pos_at_visual_coords(\n        &self,\n        doc: &Document,\n        row: u16,\n        column: u16,\n        ignore_virtual_text: bool,\n    ) -> Option<usize> {\n        self.text_pos_at_visual_coords(\n            doc,\n            row,\n            column,\n            doc.text_format(self.inner_width(doc), None),\n            &self.text_annotations(doc, None),\n            ignore_virtual_text,\n        )\n    }\n\n    /// Translates screen coordinates into coordinates on the gutter of the view.\n    /// Returns a tuple of usize typed line and column numbers starting with 0.\n    /// Returns None if coordinates are not on the gutter.\n    pub fn gutter_coords_at_screen_coords(&self, row: u16, column: u16) -> Option<Position> {\n        // 1 for status\n        if row < self.area.top() || row >= self.area.bottom() {\n            return None;\n        }\n\n        if column < self.area.left() || column > self.area.right() {\n            return None;\n        }\n\n        Some(Position::new(\n            (row - self.area.top()) as usize,\n            (column - self.area.left()) as usize,\n        ))\n    }\n\n    pub fn remove_document(&mut self, doc_id: &DocumentId) {\n        self.jumps.remove(doc_id);\n        self.docs_access_history.retain(|doc| doc != doc_id);\n    }\n\n    // pub fn traverse<F>(&self, text: RopeSlice, start: usize, end: usize, fun: F)\n    // where\n    //     F: Fn(usize, usize),\n    // {\n    //     let start = self.screen_coords_at_pos(text, start);\n    //     let end = self.screen_coords_at_pos(text, end);\n\n    //     match (start, end) {\n    //         // fully on screen\n    //         (Some(start), Some(end)) => {\n    //             // we want to calculate ends of lines for each char..\n    //         }\n    //         // from start to end of screen\n    //         (Some(start), None) => {}\n    //         // from start of screen to end\n    //         (None, Some(end)) => {}\n    //         // not on screen\n    //         (None, None) => return,\n    //     }\n    // }\n\n    /// Applies a [`Transaction`] to the view.\n    pub fn apply(&mut self, transaction: &Transaction, doc: &mut Document) {\n        self.jumps.apply(transaction, doc);\n        self.doc_revisions\n            .insert(doc.id(), doc.get_current_revision());\n    }\n\n    pub fn sync_changes(&mut self, doc: &mut Document) {\n        if let Some(transaction) = self.changes_to_sync(doc) {\n            self.apply(&transaction, doc);\n        }\n    }\n\n    pub(crate) fn changes_to_sync(&mut self, doc: &mut Document) -> Option<Transaction> {\n        let latest_revision = doc.get_current_revision();\n        let current_revision = *self\n            .doc_revisions\n            .entry(doc.id())\n            .or_insert(latest_revision);\n\n        if current_revision == latest_revision {\n            return None;\n        }\n\n        doc.history.get_mut().changes_since(current_revision)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::sync::Arc;\n\n    use super::*;\n    use arc_swap::ArcSwap;\n    use helix_core::{syntax, Rope};\n\n    // 1 diagnostic + 1 spacer + 3 linenr (< 1000 lines) + 1 spacer + 1 diff\n    const DEFAULT_GUTTER_OFFSET: u16 = 7;\n\n    // 1 diagnostics + 1 spacer + 1 gutter\n    const DEFAULT_GUTTER_OFFSET_ONLY_DIAGNOSTICS: u16 = 3;\n\n    use crate::document::Document;\n    use crate::editor::{Config, GutterConfig, GutterLineNumbersConfig, GutterType};\n\n    #[test]\n    fn test_text_pos_at_screen_coords() {\n        let mut view = View::new(DocumentId::default(), GutterConfig::default());\n        view.area = Rect::new(40, 40, 40, 40);\n        let rope = Rope::from_str(\"abc\\n\\tdef\");\n        let mut doc = Document::from(\n            rope,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n        doc.ensure_view_init(view.id);\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                2,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            None\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                41,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            None\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                0,\n                2,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            None\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                0,\n                49,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            None\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                0,\n                41,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            None\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                81,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            None\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                78,\n                41,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            None\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET + 3,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(3)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                80,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(3)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                41,\n                40 + DEFAULT_GUTTER_OFFSET + 1,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(4)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                41,\n                40 + DEFAULT_GUTTER_OFFSET + 4,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(5)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                41,\n                40 + DEFAULT_GUTTER_OFFSET + 7,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(8)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                41,\n                80,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(8)\n        );\n    }\n\n    #[test]\n    fn test_text_pos_at_screen_coords_without_line_numbers_gutter() {\n        let mut view = View::new(\n            DocumentId::default(),\n            GutterConfig {\n                layout: vec![GutterType::Diagnostics],\n                line_numbers: GutterLineNumbersConfig::default(),\n            },\n        );\n        view.area = Rect::new(40, 40, 40, 40);\n        let rope = Rope::from_str(\"abc\\n\\tdef\");\n        let mut doc = Document::from(\n            rope,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n        doc.ensure_view_init(view.id);\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                41,\n                40 + DEFAULT_GUTTER_OFFSET_ONLY_DIAGNOSTICS + 1,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(4)\n        );\n    }\n\n    #[test]\n    fn test_text_pos_at_screen_coords_without_any_gutters() {\n        let mut view = View::new(\n            DocumentId::default(),\n            GutterConfig {\n                layout: vec![],\n                line_numbers: GutterLineNumbersConfig::default(),\n            },\n        );\n        view.area = Rect::new(40, 40, 40, 40);\n        let rope = Rope::from_str(\"abc\\n\\tdef\");\n        let mut doc = Document::from(\n            rope,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n        doc.ensure_view_init(view.id);\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                41,\n                40 + 1,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(4)\n        );\n    }\n\n    #[test]\n    fn test_text_pos_at_screen_coords_cjk() {\n        let mut view = View::new(DocumentId::default(), GutterConfig::default());\n        view.area = Rect::new(40, 40, 40, 40);\n        let rope = Rope::from_str(\"Hi! こんにちは皆さん\");\n        let mut doc = Document::from(\n            rope,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n        doc.ensure_view_init(view.id);\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(0)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET + 4,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(4)\n        );\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET + 5,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(4)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET + 6,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(5)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET + 7,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(5)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET + 8,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(6)\n        );\n    }\n\n    #[test]\n    fn test_text_pos_at_screen_coords_graphemes() {\n        let mut view = View::new(DocumentId::default(), GutterConfig::default());\n        view.area = Rect::new(40, 40, 40, 40);\n        let rope = Rope::from_str(\"Hèl̀l̀ò world!\");\n        let mut doc = Document::from(\n            rope,\n            None,\n            Arc::new(ArcSwap::new(Arc::new(Config::default()))),\n            Arc::new(ArcSwap::from_pointee(syntax::Loader::default())),\n        );\n        doc.ensure_view_init(view.id);\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(0)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET + 1,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(1)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET + 2,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(3)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET + 3,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(5)\n        );\n\n        assert_eq!(\n            view.text_pos_at_screen_coords(\n                &doc,\n                40,\n                40 + DEFAULT_GUTTER_OFFSET + 4,\n                TextFormat::default(),\n                &TextAnnotations::default(),\n                true\n            ),\n            Some(7)\n        );\n    }\n}\n"
  },
  {
    "path": "helix-view/tests/encoding/LICENSE-WHATWG",
    "content": "Copyright © WHATWG (Apple, Google, Mozilla, Microsoft).\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "helix-view/tests/encoding/big5_in.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n¡\n¢\n£\n¤\n¥\n¦\n§\n¨\n©\nª\n«\n¬\n­\n®\n¯\n°\n±\n²\n³\n´\nµ\n¶\n·\n¸\n¹\nº\n»\n¼\n½\n¾\n¿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\ná\nâ\nã\nä\nå\næ\nç\nè\né\nê\në\nì\ní\nî\nï\nð\nñ\nò\nó\nô\nõ\nö\n÷\nø\nù\nú\nû\nü\ný\nþ\nÿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nġ\nĢ\nģ\nĤ\nĥ\nĦ\nħ\nĨ\nĩ\nĪ\nī\nĬ\nĭ\nĮ\nį\nİ\nı\nĲ\nĳ\nĴ\nĵ\nĶ\nķ\nĸ\nĹ\nĺ\nĻ\nļ\nĽ\nľ\nĿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nš\nŢ\nţ\nŤ\nť\nŦ\nŧ\nŨ\nũ\nŪ\nū\nŬ\nŭ\nŮ\nů\nŰ\nű\nŲ\nų\nŴ\nŵ\nŶ\nŷ\nŸ\nŹ\nź\nŻ\nż\nŽ\nž\nſ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nơ\nƢ\nƣ\nƤ\nƥ\nƦ\nƧ\nƨ\nƩ\nƪ\nƫ\nƬ\nƭ\nƮ\nƯ\nư\nƱ\nƲ\nƳ\nƴ\nƵ\nƶ\nƷ\nƸ\nƹ\nƺ\nƻ\nƼ\nƽ\nƾ\nƿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nǡ\nǢ\nǣ\nǤ\nǥ\nǦ\nǧ\nǨ\nǩ\nǪ\nǫ\nǬ\nǭ\nǮ\nǯ\nǰ\nǱ\nǲ\nǳ\nǴ\nǵ\nǶ\nǷ\nǸ\nǹ\nǺ\nǻ\nǼ\nǽ\nǾ\nǿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nȡ\nȢ\nȣ\nȤ\nȥ\nȦ\nȧ\nȨ\nȩ\nȪ\nȫ\nȬ\nȭ\nȮ\nȯ\nȰ\nȱ\nȲ\nȳ\nȴ\nȵ\nȶ\nȷ\nȸ\nȹ\nȺ\nȻ\nȼ\nȽ\nȾ\nȿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nɡ\nɢ\nɣ\nɤ\nɥ\nɦ\nɧ\nɨ\nɩ\nɪ\nɫ\nɬ\nɭ\nɮ\nɯ\nɰ\nɱ\nɲ\nɳ\nɴ\nɵ\nɶ\nɷ\nɸ\nɹ\nɺ\nɻ\nɼ\nɽ\nɾ\nɿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nʡ\nʢ\nʣ\nʤ\nʥ\nʦ\nʧ\nʨ\nʩ\nʪ\nʫ\nʬ\nʭ\nʮ\nʯ\nʰ\nʱ\nʲ\nʳ\nʴ\nʵ\nʶ\nʷ\nʸ\nʹ\nʺ\nʻ\nʼ\nʽ\nʾ\nʿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nˡ\nˢ\nˣ\nˤ\n˥\n˦\n˧\n˨\n˩\n˪\n˫\nˬ\n˭\nˮ\n˯\n˰\n˱\n˲\n˳\n˴\n˵\n˶\n˷\n˸\n˹\n˺\n˻\n˼\n˽\n˾\n˿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n̡\n̢\ṇ\n̤\n̥\n̦\ņ\n̨\n̩\n̪\n̫\n̬\ṋ\n̮\n̯\n̰\ṉ\n̲\n̳\n̴\n̵\n̶\n̷\n̸\n̹\n̺\n̻\n̼\n̽\n̾\n̿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n͡\n͢\nͣ\nͤ\nͥ\nͦ\nͧ\nͨ\nͩ\nͪ\nͫ\nͬ\nͭ\nͮ\nͯ\nͰ\nͱ\nͲ\nͳ\nʹ\n͵\nͶ\nͷ\n͸\n͹\nͺ\nͻ\nͼ\nͽ\n;\nͿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nΡ\n΢\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nΪ\nΫ\nά\nέ\nή\nί\nΰ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nϡ\nϢ\nϣ\nϤ\nϥ\nϦ\nϧ\nϨ\nϩ\nϪ\nϫ\nϬ\nϭ\nϮ\nϯ\nϰ\nϱ\nϲ\nϳ\nϴ\nϵ\n϶\nϷ\nϸ\nϹ\nϺ\nϻ\nϼ\nϽ\nϾ\nϿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nѡ\nѢ\nѣ\nѤ\nѥ\nѦ\nѧ\nѨ\nѩ\nѪ\nѫ\nѬ\nѭ\nѮ\nѯ\nѰ\nѱ\nѲ\nѳ\nѴ\nѵ\nѶ\nѷ\nѸ\nѹ\nѺ\nѻ\nѼ\nѽ\nѾ\nѿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nҡ\nҢ\nң\nҤ\nҥ\nҦ\nҧ\nҨ\nҩ\nҪ\nҫ\nҬ\nҭ\nҮ\nү\nҰ\nұ\nҲ\nҳ\nҴ\nҵ\nҶ\nҷ\nҸ\nҹ\nҺ\nһ\nҼ\nҽ\nҾ\nҿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nӡ\nӢ\nӣ\nӤ\nӥ\nӦ\nӧ\nӨ\nө\nӪ\nӫ\nӬ\nӭ\nӮ\nӯ\nӰ\nӱ\nӲ\nӳ\nӴ\nӵ\nӶ\nӷ\nӸ\nӹ\nӺ\nӻ\nӼ\nӽ\nӾ\nӿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nԡ\nԢ\nԣ\nԤ\nԥ\nԦ\nԧ\nԨ\nԩ\nԪ\nԫ\nԬ\nԭ\nԮ\nԯ\n԰\nԱ\nԲ\nԳ\nԴ\nԵ\nԶ\nԷ\nԸ\nԹ\nԺ\nԻ\nԼ\nԽ\nԾ\nԿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nա\nբ\nգ\nդ\nե\nզ\nէ\nը\nթ\nժ\nի\nլ\nխ\nծ\nկ\nհ\nձ\nղ\nճ\nմ\nյ\nն\nշ\nո\nչ\nպ\nջ\nռ\nս\nվ\nտ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n֡\n֢\n֣\n֤\n֥\n֦\n֧\n֨\n֩\n֪\n֫\n֬\n֭\n֮\n֯\nְ\nֱ\nֲ\nֳ\nִ\nֵ\nֶ\nַ\nָ\nֹ\nֺ\nֻ\nּ\nֽ\n־\nֿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nס\nע\nף\nפ\nץ\nצ\nק\nר\nש\nת\n׫\n׬\n׭\n׮\nׯ\nװ\nױ\nײ\n׳\n״\n׵\n׶\n׷\n׸\n׹\n׺\n׻\n׼\n׽\n׾\n׿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nء\nآ\nأ\nؤ\nإ\nئ\nا\nب\nة\nت\nث\nج\nح\nخ\nد\nذ\nر\nز\nس\nش\nص\nض\nط\nظ\nع\nغ\nػ\nؼ\nؽ\nؾ\nؿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n١\n٢\n٣\n٤\n٥\n٦\n٧\n٨\n٩\n٪\n٫\n٬\n٭\nٮ\nٯ\nٰ\nٱ\nٲ\nٳ\nٴ\nٵ\nٶ\nٷ\nٸ\nٹ\nٺ\nٻ\nټ\nٽ\nپ\nٿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nڡ\nڢ\nڣ\nڤ\nڥ\nڦ\nڧ\nڨ\nک\nڪ\nګ\nڬ\nڭ\nڮ\nگ\nڰ\nڱ\nڲ\nڳ\nڴ\nڵ\nڶ\nڷ\nڸ\nڹ\nں\nڻ\nڼ\nڽ\nھ\nڿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nۡ\nۢ\nۣ\nۤ\nۥ\nۦ\nۧ\nۨ\n۩\n۪\n۫\n۬\nۭ\nۮ\nۯ\n۰\n۱\n۲\n۳\n۴\n۵\n۶\n۷\n۸\n۹\nۺ\nۻ\nۼ\n۽\n۾\nۿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nܡ\nܢ\nܣ\nܤ\nܥ\nܦ\nܧ\nܨ\nܩ\nܪ\nܫ\nܬ\nܭ\nܮ\nܯ\nܰ\nܱ\nܲ\nܳ\nܴ\nܵ\nܶ\nܷ\nܸ\nܹ\nܺ\nܻ\nܼ\nܽ\nܾ\nܿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nݡ\nݢ\nݣ\nݤ\nݥ\nݦ\nݧ\nݨ\nݩ\nݪ\nݫ\nݬ\nݭ\nݮ\nݯ\nݰ\nݱ\nݲ\nݳ\nݴ\nݵ\nݶ\nݷ\nݸ\nݹ\nݺ\nݻ\nݼ\nݽ\nݾ\nݿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nޡ\nޢ\nޣ\nޤ\nޥ\nަ\nާ\nި\nީ\nު\nޫ\nެ\nޭ\nޮ\nޯ\nް\nޱ\n޲\n޳\n޴\n޵\n޶\n޷\n޸\n޹\n޺\n޻\n޼\n޽\n޾\n޿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nߡ\nߢ\nߣ\nߤ\nߥ\nߦ\nߧ\nߨ\nߩ\nߪ\n߫\n߬\n߭\n߮\n߯\n߰\n߱\n߲\n߳\nߴ\nߵ\n߶\n߷\n߸\n߹\nߺ\n߻\n߼\n߽\n߾\n߿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/big5_in_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n䏰\n䰲\n䘃\n䖦\n䕸\n𧉧\n䵷\n䖳\n𧲱\n䳢\n𧳅\n㮕\n䜶\n䝄\n䱇\n䱀\n𤊿\n𣘗\n𧍒\n𦺋\n𧃒\n䱗\n𪍑\n䝏\n䗚\n䲅\n𧱬\n䴇\n䪤\n䚡\n𦬣\n爥\n𥩔\n𡩣\n𣸆\n𣽡\n晍\n囻\n�f\n綕\n夝\n𨮹\n㷴\n霴\n𧯯\n寛\n𡵞\n媤\n㘥\n𩺰\n嫑\n宷\n峼\n杮\n薓\n𩥅\n瑡\n璝\n㡵\n𡵓\n𣚞\n𦀡\n㻬\n𥣞\n㫵\n竼\n龗\n𤅡\n𨤍\n𣇪\n𠪊\n𣉞\n䌊\n蒄\n龖\n鐯\n䤰\n蘓\n墖\n靊\n鈘\n秐\n稲\n晠\n権\n袝\n瑌\n篅\n枂\n稬\n剏\n遆\n㓦\n珄\n𥶹\n瓆\n鿇\n垳\n䤯\n呌\n䄱\n𣚎\n堘\n穲\n𧭥\n讏\n䚮\n𦺈\n䆁\n𥶙\n箮\n𢒼\n鿈\n𢓁\n𢓉\n𢓌\n鿉\n蔄\n𣖻\n䂴\n鿊\n䓡\n𪷿\n拁\n灮\n鿋\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n㇀\n㇁\n㇂\n㇃\n㇄\n𠄌\n㇅\n𠃑\n𠃍\n㇆\n㇇\n𠃋\n𡿨\n㇈\n𠃊\n㇉\n㇊\n㇋\n㇌\n𠄎\n㇍\n㇎\nĀ\nÁ\nǍ\nÀ\nĒ\nÉ\nĚ\nÈ\nŌ\nÓ\nǑ\nÒ\nÊ̄\nẾ\nÊ̌\nỀ\nÊ\nā\ná\nǎ\nà\nɑ\nē\né\ně\nè\nī\ní\nǐ\nì\nō\nó\nǒ\nò\nū\nú\nǔ\nù\nǖ\nǘ\nǚ\nǜ\nü\nê̄\nế\nê̌\nề\nê\nɡ\n⏚\n⏛\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n𪎩\n𡅅\n�B\n攊\n�D\n�E\n丽\n滝\n鵎\n釟\n�J\n�K\n𧜵\n撑\n会\n伨\n侨\n兖\n兴\n农\n凤\n务\n动\n医\n华\n发\n变\n团\n声\n处\n备\n夲\n头\n学\n实\n実\n岚\n庆\n总\n斉\n柾\n栄\n桥\n济\n炼\n电\n纤\n纬\n纺\n织\n经\n统\n缆\n缷\n艺\n苏\n药\n视\n设\n询\n车\n轧\n轮\n琑\n糼\n緍\n楆\n竉\n刧\n�\n�\n�\n�\n醌\n碸\n酞\n肼\n�\n贋\n胶\n𠧧\n�\n�\n肟\n黇\n䳍\n鷉\n鸌\n䰾\n𩷶\n𧀎\n鸊\n𪄳\n㗁\n�\n溚\n舾\n甙\n�\n䤑\n马\n骏\n龙\n禇\n𨑬\n𡷊\n𠗐\n𢫦\n两\n亁\n亀\n亇\n亿\n仫\n伷\n㑌\n侽\n㹈\n倃\n傈\n㑽\n㒓\n㒥\n円\n夅\n凛\n凼\n刅\n争\n剹\n劐\n匧\n㗇\n厩\n㕑\n厰\n㕓\n参\n吣\n㕭\n㕲\n㚁\n咓\n咣\n咴\n咹\n哐\n哯\n唘\n唣\n唨\n㖘\n唿\n㖥\n㖿\n嗗\n㗅\n𧶄\n唥\n�B\n𠱂\n𠴕\n𥄫\n喐\n𢳆\n㧬\n𠍁\n蹆\n𤶸\n𩓥\n䁓\n𨂾\n睺\n𢰸\n㨴\n䟕\n𨅝\n𦧲\n𤷪\n擝\n𠵼\n𠾴\n𠳕\n𡃴\n撍\n蹾\n𠺖\n𠰋\n𠽤\n𢲩\n𨉖\n𤓓\n�c\n𠵆\n𩩍\n𨃩\n䟴\n𤺧\n𢳂\n骲\n㩧\n𩗴\n㿭\n㔆\n𥋇\n𩟔\n𧣈\n𢵄\n鵮\n頕\n�u\n䏙\n𦂥\n撴\n哣\n𢵌\n𢯊\n𡁷\n㧻\n𡁯\n𦛚\n𦜖\n𧦠\n擪\n𥁒\n𠱃\n蹨\n𢆡\n𨭌\n𠜱\n�\n䠋\n𠆩\n㿺\n塳\n𢶍\n�\n𤗈\n𠓼\n𦂗\n𠽌\n𠶖\n啹\n䂻\n䎺\n�\n䪴\n𢩦\n𡂝\n膪\n飵\n𠶜\n捹\n㧾\n𢝵\n跀\n嚡\n摼\n㹃\n�\n𪘁\n𠸉\n𢫏\n𢳉\n�\n𡃈\n𣧂\n㦒\n㨆\n𨊛\n㕸\n𥹉\n𢃇\n噒\n𠼱\n𢲲\n𩜠\n㒼\n氽\n𤸻\n�\n�\n𧕴\n𢺋\n𢈈\n𪙛\n𨳍\n𠹺\n𠰴\n𦠜\n羓\n𡃏\n𢠃\n𢤹\n㗻\n𥇣\n𠺌\n𠾍\n𠺪\n㾓\n𠼰\n𠵇\n𡅏\n𠹌\n�\n𠺫\n𠮩\n𠵈\n𡃀\n𡄽\n㿹\n𢚖\n搲\n𠾭\n𣏴\n𧘹\n𢯎\n𠵾\n𠵿\n𢱑\n𢱕\n㨘\n𠺘\n𡃇\n𠼮\n𪘲\n𦭐\n𨳒\n𨶙\n𨳊\n閪\n哌\n苄\n喹\n�T\n𩻃\n鰦\n骶\n𧝞\n𢷮\n煀\n腭\n胬\n尜\n𦕲\n脴\n㞗\n卟\n𨂽\n醶\n𠻺\n𠸏\n𠹷\n𠻻\n㗝\n𤷫\n㘉\n𠳖\n嚯\n𢞵\n𡃉\n𠸐\n𠹸\n𡁸\n𡅈\n𨈇\n𡑕\n𠹹\n𤹐\n𢶤\n婔\n𡀝\n𡀞\n𡃵\n𡃶\n垜\n𠸑\n𧚔\n𨋍\n𠾵\n𠹻\n𥅾\n㜃\n𠾶\n𡆀\n𥋘\n𪊽\n𤧚\n𡠺\n𤅷\n𨉼\n墙\n剨\n㘚\n𥜽\n箲\n孨\n䠀\n䬬\n鼧\n䧧\n鰟\n鮍\n𥭴\n𣄽\n嗻\n㗲\n嚉\n丨\n夂\n𡯁\n屮\n靑\n𠂆\n乛\n亻\n㔾\n尣\n彑\n忄\n㣺\n扌\n攵\n歺\n氵\n氺\n灬\n爫\n丬\n犭\n𤣩\n罒\n礻\n糹\n罓\n𦉪\n㓁\n�\n𦍋\n耂\n肀\n𦘒\n𦥑\n卝\n衤\n见\n𧢲\n讠\n贝\n钅\n镸\n长\n门\n𨸏\n韦\n页\n风\n飞\n饣\n𩠐\n鱼\n鸟\n黄\n歯\n龜\n丷\n𠂇\n阝\n户\n钢\n�\n倻\n淾\n𩱳\n龦\n㷉\n袏\n𤅎\n灷\n峵\n䬠\n𥇍\n㕙\n𥴰\n愢\n𨨲\n辧\n釶\n熑\n朙\n玺\n𣊁\n𪄇\n㲋\n𡦀\n䬐\n磤\n琂\n冮\n𨜏\n䀉\n橣\n𪊺\n䈣\n蘏\n𠩯\n稪\n𩥇\n𨫪\n靕\n灍\n匤\n𢁾\n鏴\n盙\n𨧣\n龧\n矝\n亣\n俰\n傼\n丯\n众\n龨\n吴\n綋\n墒\n壐\n𡶶\n庒\n庙\n忂\n𢜒\n斋\n𣏹\n椙\n橃\n𣱣\n泿\n�\n爀\n𤔅\n玌\n㻛\n𤨓\n嬕\n璹\n讃\n𥲤\n𥚕\n窓\n篬\n糃\n繬\n苸\n薗\n龩\n袐\n龪\n躹\n龫\n迏\n蕟\n駠\n鈡\n龬\n𨶹\n𡐿\n䁱\n䊢\n娚\n�\n�\n�\n顨\n杫\n䉶\n圽\n�\n藖\n𤥻\n芿\n𧄍\n䲁\n𦵴\n嵻\n𦬕\n𦾾\n龭\n龮\n宖\n龯\n曧\n繛\n湗\n秊\n㶈\n䓃\n𣉖\n𢞖\n䎚\n䔶\n�\n峕\n𣬚\n諹\n屸\n㴒\n𣕑\n嵸\n龲\n煗\n䕘\n𤃬\n𡸣\n䱷\n㥸\n㑊\n𠆤\n𦱁\n諌\n侴\n𠈹\n妿\n腬\n顖\n𩣺\n弻\n𠮟\n�A\n𢇁\n𨥭\n䄂\n䚻\n𩁹\n㼇\n龳\n𪆵\n䃸\n㟖\n䛷\n𦱆\n䅼\n𨚲\n𧏿\n䕭\n㣔\n𥒚\n䕡\n䔛\n䶉\n䱻\n䵶\n䗪\n㿈\n𤬏\n㙡\n䓞\n䒽\n䇭\n崾\n嵈\n嵖\n㷼\n㠏\n嶤\n嶹\n㠠\n㠸\n幂\n庽\n弥\n徃\n㤈\n㤔\n㤿\n㥍\n惗\n愽\n峥\n㦉\n憷\n憹\n懏\n㦸\n戬\n抐\n拥\n挘\n㧸\n嚱\n㨃\n揢\n揻\n搇\n摚\n㩋\n擀\n崕\n嘡\n龟\n㪗\n斆\n㪽\n旿\n晓\n㫲\n暒\n㬢\n朖\n㭂\n枤\n栀\n㭘\n桊\n梄\n㭲\n㭱\n㭻\n椉\n楃\n牜\n楤\n榟\n榅\n㮼\n槖\n㯝\n橥\n橴\n橱\n檂\n㯬\n檙\n㯲\n檫\n檵\n櫔\n櫶\n殁\n毁\n毪\n汵\n沪\n㳋\n洂\n洆\n洦\n涁\n㳯\n涤\n涱\n渕\n渘\n温\n溆\n𨧀\n溻\n滢\n滚\n齿\n滨\n滩\n漤\n漴\n㵆\n𣽁\n澁\n澾\n㵪\n㵵\n熷\n岙\n㶊\n瀬\n㶑\n灐\n灔\n灯\n灿\n炉\n𠌥\n䏁\n㗱\n𠻘\n𣻗\n垾\n𦻓\n焾\n𥟠\n㙎\n榢\n𨯩\n孴\n穉\n𥣡\n𩓙\n穥\n穽\n𥦬\n窻\n窰\n竂\n竃\n燑\n𦒍\n䇊\n竚\n竝\n竪\n䇯\n咲\n𥰁\n笋\n筕\n笩\n𥌎\n𥳾\n箢\n筯\n莜\n𥮴\n𦱿\n篐\n萡\n箒\n箸\n𥴠\n㶭\n𥱥\n蒒\n篺\n簆\n簵\n𥳁\n籄\n粃\n𤢂\n粦\n晽\n𤕸\n糉\n糇\n糦\n籴\n糳\n糵\n糎\n繧\n䔝\n𦹄\n絝\n𦻖\n璍\n綉\n綫\n焵\n綳\n緒\n𤁗\n𦀩\n緤\n㴓\n緵\n𡟹\n緥\n𨍭\n縝\n𦄡\n𦅚\n繮\n纒\n䌫\n鑬\n縧\n罀\n罁\n罇\n礶\n𦋐\n駡\n羗\n𦍑\n羣\n𡙡\n𠁨\n䕜\n𣝦\n䔃\n𨌺\n翺\n𦒉\n者\n耈\n耝\n耨\n耯\n𪂇\n𦳃\n耻\n耼\n聡\n𢜔\n䦉\n𦘦\n𣷣\n𦛨\n朥\n肧\n𨩈\n脇\n脚\n墰\n𢛶\n汿\n𦒘\n𤾸\n擧\n𡒊\n舘\n𡡞\n橓\n𤩥\n𤪕\n䑺\n舩\n𠬍\n𦩒\n𣵾\n俹\n𡓽\n蓢\n荢\n𦬊\n𤦧\n𣔰\n𡝳\n𣷸\n芪\n椛\n芳\n䇛\n蕋\n苐\n茚\n𠸖\n𡞴\n㛁\n𣅽\n𣕚\n艻\n苢\n茘\n𣺋\n𦶣\n𦬅\n𦮗\n𣗎\n㶿\n茝\n嗬\n莅\n䔋\n𦶥\n莬\n菁\n菓\n㑾\n𦻔\n橗\n蕚\n㒖\n𦹂\n𢻯\n葘\n𥯤\n葱\n㷓\n䓤\n檧\n葊\n𣲵\n祘\n蒨\n𦮖\n𦹷\n𦹃\n蓞\n萏\n莑\n䒠\n蒓\n蓤\n𥲑\n䉀\n𥳀\n䕃\n蔴\n嫲\n𦺙\n䔧\n蕳\n䔖\n枿\n蘖\n𨘥\n𨘻\n藁\n𧂈\n蘂\n𡖂\n𧃍\n䕫\n䕪\n蘨\n㙈\n𡢢\n号\n𧎚\n虾\n蝱\n𪃸\n蟮\n𢰧\n螱\n蟚\n蠏\n噡\n虬\n桖\n䘏\n衅\n衆\n𧗠\n𣶹\n𧗤\n衞\n袜\n䙛\n袴\n袵\n揁\n装\n睷\n𧜏\n覇\n覊\n覦\n覩\n覧\n覼\n𨨥\n觧\n𧤤\n𧪽\n誜\n瞓\n釾\n誐\n𧩙\n竩\n𧬺\n𣾏\n䜓\n𧬸\n煼\n謌\n謟\n𥐰\n𥕥\n謿\n譌\n譍\n誩\n𤩺\n讐\n讛\n誯\n𡛟\n䘕\n衏\n貛\n𧵔\n𧶏\n貫\n㜥\n𧵓\n賖\n𧶘\n𧶽\n贒\n贃\n𡤐\n賛\n灜\n贑\n𤳉\n㻐\n起\n趩\n𨀂\n𡀔\n𤦊\n㭼\n𨆼\n𧄌\n竧\n躭\n躶\n軃\n鋔\n輙\n輭\n𨍥\n𨐒\n辥\n錃\n𪊟\n𠩐\n辳\n䤪\n𨧞\n𨔽\n𣶻\n廸\n𣉢\n迹\n𪀔\n𨚼\n𨔁\n𢌥\n㦀\n𦻗\n逷\n𨔼\n𧪾\n遡\n𨕬\n𨘋\n邨\n𨜓\n郄\n𨛦\n邮\n都\n酧\n㫰\n醩\n釄\n粬\n𨤳\n𡺉\n鈎\n沟\n鉁\n鉢\n𥖹\n銹\n𨫆\n𣲛\n𨬌\n𥗛\n𠴱\n錬\n鍫\n𨫡\n𨯫\n炏\n嫃\n𨫢\n𨫥\n䥥\n鉄\n𨯬\n𨰹\n𨯿\n鍳\n鑛\n躼\n閅\n閦\n鐦\n閠\n濶\n䊹\n𢙺\n𨛘\n𡉼\n𣸮\n䧟\n氜\n陻\n隖\n䅬\n隣\n𦻕\n懚\n隶\n磵\n𨫠\n隽\n双\n䦡\n𦲸\n𠉴\n𦐐\n𩂯\n𩃥\n𤫑\n𡤕\n𣌊\n霱\n虂\n霶\n䨏\n䔽\n䖅\n𤫩\n灵\n孁\n霛\n靜\n𩇕\n靗\n孊\n𩇫\n靟\n鐥\n僐\n𣂷\n𣂼\n鞉\n鞟\n鞱\n鞾\n韀\n韒\n韠\n𥑬\n韮\n琜\n𩐳\n響\n韵\n𩐝\n𧥺\n䫑\n頴\n頳\n顋\n顦\n㬎\n𧅵\n㵑\n𠘰\n𤅜\n𥜆\n飊\n颷\n飈\n飇\n䫿\n𦴧\n𡛓\n喰\n飡\n飦\n飬\n鍸\n餹\n𤨩\n䭲\n𩡗\n𩤅\n駵\n騌\n騻\n騐\n驘\n𥜥\n㛄\n𩂱\n𩯕\n髠\n髢\n𩬅\n髴\n䰎\n鬔\n鬭\n𨘀\n倴\n鬴\n𦦨\n㣃\n𣁽\n魐\n魀\n𩴾\n婅\n𡡣\n鮎\n𤉋\n鰂\n鯿\n鰌\n𩹨\n鷔\n𩾷\n𪆒\n𪆫\n𪃡\n𪄣\n𪇟\n鵾\n鶃\n𪄴\n鸎\n梈\n鷄\n𢅛\n𪆓\n𪈠\n𡤻\n𪈳\n鴹\n𪂹\n𪊴\n麐\n麕\n麞\n麢\n䴴\n麪\n麯\n𤍤\n黁\n㭠\n㧥\n㴝\n伲\n㞾\n𨰫\n鼂\n鼈\n䮖\n鐤\n𦶢\n鼗\n鼖\n鼹\n嚟\n嚊\n齅\n馸\n𩂋\n韲\n葿\n齢\n齩\n竜\n龎\n爖\n䮾\n𤥵\n𤦻\n煷\n𤧸\n𤍈\n𤩑\n玞\n𨯚\n𡣺\n禟\n𨥾\n𨸶\n鍩\n鏳\n𨩄\n鋬\n鎁\n鏋\n𨥬\n𤒹\n爗\n㻫\n睲\n穃\n烐\n𤑳\n𤏸\n煾\n𡟯\n炣\n𡢾\n𣖙\n㻇\n𡢅\n𥐯\n𡟸\n㜢\n𡛻\n𡠹\n㛡\n𡝴\n𡣑\n𥽋\n㜣\n𡛀\n坛\n𤨥\n𡏾\n𡊨\n𡏆\n𡒶\n蔃\n𣚦\n蔃\n葕\n𤦔\n𧅥\n𣸱\n𥕜\n𣻻\n𧁒\n䓴\n𣛮\n𩦝\n𦼦\n柹\n㜳\n㰕\n㷧\n塬\n𡤢\n栐\n䁗\n𣜿\n𤃡\n𤂋\n𤄏\n𦰡\n哋\n嚞\n𦚱\n嚒\n𠿟\n𠮨\n𠸍\n鏆\n𨬓\n鎜\n仸\n儫\n㠙\n𤐶\n亼\n𠑥\n𠍿\n佋\n侊\n𥙑\n婨\n𠆫\n𠏋\n㦙\n𠌊\n𠐔\n㐵\n伩\n𠋀\n𨺳\n𠉵\n諚\n𠈌\n亘\n働\n儍\n侢\n伃\n𤨎\n𣺊\n佂\n倮\n偬\n傁\n俌\n俥\n偘\n僼\n兙\n兛\n兝\n兞\n湶\n𣖕\n𣸹\n𣺿\n浲\n𡢄\n𣺉\n冨\n凃\n𠗠\n䓝\n𠒣\n𠒒\n𠒑\n赺\n𨪜\n𠜎\n剙\n劤\n𠡳\n勡\n鍮\n䙺\n熌\n𤎌\n𠰠\n𤦬\n𡃤\n槑\n𠸝\n瑹\n㻞\n璙\n琔\n瑖\n玘\n䮎\n𤪼\n𤂍\n叐\n㖄\n爏\n𤃉\n喴\n𠍅\n响\n𠯆\n圝\n鉝\n雴\n鍦\n埝\n垍\n坿\n㘾\n壋\n媙\n𨩆\n𡛺\n𡝯\n𡜐\n娬\n妸\n銏\n婾\n嫏\n娒\n𥥆\n𡧳\n𡡡\n𤊕\n㛵\n洅\n瑃\n娡\n𥺃\n媁\n𨯗\n𠐓\n鏠\n璌\n𡌃\n焅\n䥲\n鐈\n𨧻\n鎽\n㞠\n尞\n岞\n幞\n幈\n𡦖\n𡥼\n𣫮\n廍\n孏\n𡤃\n𡤄\n㜁\n𡢠\n㛝\n𡛾\n㛓\n脪\n𨩇\n𡶺\n𣑲\n𨦨\n弌\n弎\n𡤧\n𡞫\n婫\n𡜻\n孄\n蘔\n𧗽\n衠\n恾\n𢡠\n𢘫\n忛\n㺸\n𢖯\n𢖾\n𩂈\n𦽳\n懀\n𠀾\n𠁆\n𢘛\n憙\n憘\n恵\n𢲛\n𢴇\n𤛔\n𩅍\n摱\n𤙥\n𢭪\n㨩\n𢬢\n𣑐\n𩣪\n𢹸\n挷\n𪑛\n撶\n挱\n揑\n𤧣\n𢵧\n护\n𢲡\n搻\n敫\n楲\n㯴\n𣂎\n𣊭\n𤦉\n𣊫\n唍\n𣋠\n𡣙\n𩐿\n曎\n𣊉\n𣆳\n㫠\n䆐\n𥖄\n𨬢\n𥖏\n𡛼\n𥕛\n𥐥\n磮\n𣄃\n𡠪\n𣈴\n㑤\n𣈏\n𣆂\n𤋉\n暎\n𦴤\n晫\n䮓\n昰\n𧡰\n𡷫\n晣\n𣋒\n𣋡\n昞\n𥡲\n㣑\n𣠺\n𣞼\n㮙\n𣞢\n𣏾\n瓐\n㮖\n枏\n𤘪\n梶\n栞\n㯄\n檾\n㡣\n𣟕\n𤒇\n樳\n橒\n櫉\n欅\n𡤒\n攑\n梘\n橌\n㯗\n橺\n歗\n𣿀\n𣲚\n鎠\n鋲\n𨯪\n𨫋\n銉\n𨀞\n𨧜\n鑧\n涥\n漋\n𤧬\n浧\n𣽿\n㶏\n渄\n𤀼\n娽\n渊\n塇\n洤\n硂\n焻\n𤌚\n𤉶\n烱\n牐\n犇\n犔\n𤞏\n𤜥\n兹\n𤪤\n𠗫\n瑺\n𣻸\n𣙟\n𤩊\n𤤗\n𥿡\n㼆\n㺱\n𤫟\n𨰣\n𣼵\n悧\n㻳\n瓌\n琼\n鎇\n琷\n䒟\n𦷪\n䕑\n疃\n㽣\n𤳙\n𤴆\n㽘\n畕\n癳\n𪗆\n㬙\n瑨\n𨫌\n𤦫\n𤦎\n㫻\n㷍\n𤩎\n㻿\n𤧅\n𤣳\n釺\n圲\n鍂\n𨫣\n𡡤\n僟\n𥈡\n𥇧\n睸\n𣈲\n眎\n眏\n睻\n𤚗\n𣞁\n㩞\n𤣰\n琸\n璛\n㺿\n𤪺\n𤫇\n䃈\n𤪖\n𦆮\n錇\n𥖁\n砞\n碍\n碈\n磒\n珐\n祙\n𧝁\n𥛣\n䄎\n禛\n蒖\n禥\n樭\n𣻺\n稺\n秴\n䅮\n𡛦\n䄲\n鈵\n秱\n𠵌\n𤦌\n𠊙\n𣶺\n𡝮\n㖗\n啫\n㕰\n㚪\n𠇔\n𠰍\n竢\n婙\n𢛵\n𥪯\n𥪜\n娍\n𠉛\n磰\n娪\n𥯆\n竾\n䇹\n籝\n籭\n䈑\n𥮳\n𥺼\n𥺦\n糍\n𤧹\n𡞰\n粎\n籼\n粮\n檲\n緜\n縇\n緓\n罎\n𦉡\n𦅜\n𧭈\n綗\n𥺂\n䉪\n𦭵\n𠤖\n柖\n𠁎\n𣗏\n埄\n𦐒\n𦏸\n𤥢\n翝\n笧\n𠠬\n𥫩\n𥵃\n笌\n𥸎\n駦\n虅\n驣\n樜\n𣐿\n㧢\n𤧷\n𦖭\n騟\n𦖠\n蒀\n𧄧\n𦳑\n䓪\n脷\n䐂\n胆\n脉\n腂\n𦞴\n飃\n𦩂\n艢\n艥\n𦩑\n葓\n𦶧\n蘐\n𧈛\n媆\n䅿\n𡡀\n嬫\n𡢡\n嫤\n𡣘\n蚠\n蜨\n𣶏\n蠭\n𧐢\n娂\n衮\n佅\n袇\n袿\n裦\n襥\n襍\n𥚃\n襔\n𧞅\n𧞄\n𨯵\n𨯙\n𨮜\n𨧹\n㺭\n蒣\n䛵\n䛏\n㟲\n訽\n訜\n𩑈\n彍\n鈫\n𤊄\n旔\n焩\n烄\n𡡅\n鵭\n貟\n賩\n𧷜\n妚\n矃\n姰\n䍮\n㛔\n踪\n躧\n𤰉\n輰\n轊\n䋴\n汘\n澻\n𢌡\n䢛\n潹\n溋\n𡟚\n鯩\n㚵\n𤤯\n邻\n邗\n啱\n䤆\n醻\n鐄\n𨩋\n䁢\n𨫼\n鐧\n𨰝\n𨰻\n蓥\n訫\n閙\n閧\n閗\n閖\n𨴴\n瑅\n㻂\n𤣿\n𤩂\n𤏪\n㻧\n𣈥\n随\n𨻧\n𨹦\n𨹥\n㻌\n𤧭\n𤩸\n𣿮\n琒\n瑫\n㻼\n靁\n𩂰\n桇\n䨝\n𩂓\n𥟟\n靝\n鍨\n𨦉\n𨰦\n𨬯\n𦎾\n銺\n嬑\n譩\n䤼\n珹\n𤈛\n鞛\n靱\n餸\n𠼦\n巁\n𨯅\n𤪲\n頟\n𩓚\n鋶\n𩗗\n釥\n䓀\n𨭐\n𤩧\n𨭤\n飜\n𨩅\n㼀\n鈪\n䤥\n萔\n餻\n饍\n𧬆\n㷽\n馛\n䭯\n馪\n驜\n𨭥\n𥣈\n檏\n騡\n嫾\n騯\n𩣱\n䮐\n𩥈\n馼\n䮽\n䮗\n鍽\n塲\n𡌂\n堢\n𤦸\n𡓨\n硄\n𢜟\n𣶸\n棅\n㵽\n鑘\n㤧\n慐\n𢞁\n𢥫\n愇\n鱏\n鱓\n鱻\n鰵\n鰐\n魿\n鯏\n𩸭\n鮟\n𪇵\n𪃾\n鴡\n䲮\n𤄄\n鸘\n䲰\n鴌\n𪆴\n𪃭\n𪃳\n𩤯\n鶥\n蒽\n𦸒\n𦿟\n𦮂\n藼\n䔳\n𦶤\n𦺄\n𦷰\n萠\n藮\n𦸀\n𣟗\n𦁤\n秢\n𣖜\n𣙀\n䤭\n𤧞\n㵢\n鏛\n銾\n鍈\n𠊿\n碹\n鉷\n鑍\n俤\n㑀\n遤\n𥕝\n砽\n硔\n碶\n硋\n𡝗\n𣇉\n𤥁\n㚚\n佲\n濚\n濙\n瀞\n瀞\n吔\n𤆵\n垻\n壳\n垊\n鴖\n埗\n焴\n㒯\n𤆬\n燫\n𦱀\n𤾗\n嬨\n𡞵\n𨩉\n愌\n嫎\n娋\n䊼\n𤒈\n㜬\n䭻\n𨧼\n鎻\n鎸\n𡣖\n𠼝\n葲\n𦳀\n𡐓\n𤋺\n𢰦\n𤏁\n妔\n𣶷\n𦝁\n綨\n𦅛\n𦂤\n𤦹\n𤦋\n𨧺\n鋥\n珢\n㻩\n璴\n𨭣\n𡢟\n㻡\n𤪳\n櫘\n珳\n珻\n㻖\n𤨾\n𤪔\n𡟙\n𤩦\n𠎧\n𡐤\n𤧥\n瑈\n𤤖\n炥\n𤥶\n銄\n珦\n鍟\n𠓾\n錱\n𨫎\n𨨖\n鎆\n𨯧\n𥗕\n䤵\n𨪂\n煫\n𤥃\n𠳿\n嚤\n𠘚\n𠯫\n𠲸\n唂\n秄\n𡟺\n緾\n𡛂\n𤩐\n𡡒\n䔮\n鐁\n㜊\n𨫀\n𤦭\n妰\n𡢿\n𡢃\n𧒄\n媡\n㛢\n𣵛\n㚰\n鉟\n婹\n𨪁\n𡡢\n鍴\n㳍\n𠪴\n䪖\n㦊\n僴\n㵩\n㵌\n𡎜\n煵\n䋻\n𨈘\n渏\n𩃤\n䓫\n浗\n𧹏\n灧\n沯\n㳖\n𣿭\n𣸭\n渂\n漌\n㵯\n𠏵\n畑\n㚼\n㓈\n䚀\n㻚\n䡱\n姄\n鉮\n䤾\n轁\n𨰜\n𦯀\n堒\n埈\n㛖\n𡑒\n烾\n𤍢\n𤩱\n𢿣\n𡊰\n𢎽\n梹\n楧\n𡎘\n𣓥\n𧯴\n𣛟\n𨪃\n𣟖\n𣏺\n𤲟\n樚\n𣚭\n𦲷\n萾\n䓟\n䓎\n𦴦\n𦵑\n𦲂\n𦿞\n漗\n𧄉\n茽\n𡜺\n菭\n𦲀\n𧁓\n𡟛\n妉\n媂\n𡞳\n婡\n婱\n𡤅\n𤇼\n㜭\n姯\n𡜼\n㛇\n熎\n鎐\n暚\n𤊥\n婮\n娫\n𤊓\n樫\n𣻹\n𧜶\n𤑛\n𤋊\n焝\n𤉙\n𨧡\n侰\n𦴨\n峂\n𤓎\n𧹍\n𤎽\n樌\n𤉖\n𡌄\n炦\n焳\n𤏩\n㶥\n泟\n勇\n𤩏\n繥\n姫\n崯\n㷳\n彜\n𤩝\n𡟟\n綤\n萦\n咅\n𣫺\n𣌀\n𠈔\n坾\n𠣕\n𠘙\n㿥\n𡾞\n𪊶\n瀃\n𩅛\n嵰\n玏\n糓\n𨩙\n𩐠\n俈\n翧\n狍\n猐\n𧫴\n猸\n猹\n𥛶\n獁\n獈\n㺩\n𧬘\n遬\n燵\n𤣲\n珡\n臶\n㻊\n県\n㻑\n沢\n国\n琙\n琞\n琟\n㻢\n㻰\n㻴\n㻺\n瓓\n㼎\n㽓\n畂\n畭\n畲\n疍\n㽼\n痈\n痜\n㿀\n癍\n㿗\n癴\n㿜\n発\n𤽜\n熈\n嘣\n覀\n塩\n䀝\n睃\n䀹\n条\n䁅\n㗛\n瞘\n䁪\n䁯\n属\n瞾\n矋\n売\n砘\n点\n砜\n䂨\n砹\n硇\n硑\n硦\n葈\n𥔵\n礳\n栃\n礲\n䄃\n䄉\n禑\n禙\n辻\n稆\n込\n䅧\n窑\n䆲\n窼\n艹\n䇄\n竏\n竛\n䇏\n両\n筢\n筬\n筻\n簒\n簛\n䉠\n䉺\n类\n粜\n䊌\n粸\n䊔\n糭\n输\n烀\n𠳏\n総\n緔\n緐\n緽\n羮\n羴\n犟\n䎗\n耠\n耥\n笹\n耮\n耱\n联\n㷌\n垴\n炠\n肷\n胩\n䏭\n脌\n猪\n脎\n脒\n畠\n脔\n䐁\n㬹\n腖\n腙\n腚\n䐓\n堺\n腼\n膄\n䐥\n膓\n䐭\n膥\n埯\n臁\n臤\n艔\n䒏\n芦\n艶\n苊\n苘\n苿\n䒰\n荗\n险\n榊\n萅\n烵\n葤\n惣\n蒈\n䔄\n蒾\n蓡\n蓸\n蔐\n蔸\n蕒\n䔻\n蕯\n蕰\n藠\n䕷\n虲\n蚒\n蚲\n蛯\n际\n螋\n䘆\n䘗\n袮\n裿\n褤\n襇\n覑\n𧥧\n訩\n訸\n誔\n誴\n豑\n賔\n賲\n贜\n䞘\n塟\n跃\n䟭\n仮\n踺\n嗘\n坔\n蹱\n嗵\n躰\n䠷\n軎\n転\n軤\n軭\n軲\n辷\n迁\n迊\n迌\n逳\n駄\n䢭\n飠\n鈓\n䤞\n鈨\n鉘\n鉫\n銱\n銮\n銿\n鋣\n鋫\n鋳\n鋴\n鋽\n鍃\n鎄\n鎭\n䥅\n䥑\n麿\n鐗\n匁\n鐝\n鐭\n鐾\n䥪\n鑔\n鑹\n锭\n関\n䦧\n间\n阳\n䧥\n枠\n䨤\n靀\n䨵\n鞲\n韂\n噔\n䫤\n惨\n颹\n䬙\n飱\n塄\n餎\n餙\n冴\n餜\n餷\n饂\n饝\n饢\n䭰\n駅\n䮝\n騼\n鬏\n窃\n魩\n鮁\n鯝\n鯱\n鯴\n䱭\n鰠\n㝯\n𡯂\n鵉\n鰺\n黾\n噐\n鶓\n鶽\n鷀\n鷼\n银\n辶\n鹻\n麬\n麱\n麽\n黆\n铜\n黢\n黱\n黸\n竈\n齄\n𠂔\n𠊷\n𠎠\n椚\n铃\n妬\n𠓗\n塀\n铁\n㞹\n𠗕\n𠘕\n𠙶\n𡚺\n块\n煳\n𠫂\n𠫍\n𠮿\n呪\n吆\n𠯋\n咞\n𠯻\n𠰻\n𠱓\n𠱥\n𠱼\n惧\n𠲍\n噺\n𠲵\n𠳝\n𠳭\n𠵯\n𠶲\n𠷈\n楕\n鰯\n螥\n𠸄\n𠸎\n𠻗\n𠾐\n𠼭\n𠹳\n尠\n𠾼\n帋\n𡁜\n𡁏\n𡁶\n朞\n𡁻\n𡂈\n𡂖\n㙇\n𡂿\n𡃓\n𡄯\n𡄻\n卤\n蒭\n𡋣\n𡍵\n𡌶\n讁\n𡕷\n𡘙\n𡟃\n𡟇\n乸\n炻\n𡠭\n𡥪\n𡨭\n𡩅\n𡰪\n𡱰\n𡲬\n𡻈\n拃\n𡻕\n𡼕\n熘\n桕\n𢁅\n槩\n㛈\n𢉼\n𢏗\n𢏺\n𢜪\n𢡱\n𢥏\n苽\n𢥧\n𢦓\n𢫕\n覥\n𢫨\n辠\n𢬎\n鞸\n𢬿\n顇\n骽\n𢱌\n�a\n𢲈\n𢲷\n𥯨\n𢴈\n𢴒\n𢶷\n𢶕\n𢹂\n𢽴\n𢿌\n𣀳\n𣁦\n𣌟\n𣏞\n徱\n晈\n暿\n𧩹\n𣕧\n𣗳\n爁\n𤦺\n矗\n𣘚\n𣜖\n纇\n𠍆\n墵\n朎\n椘\n𣪧\n𧙗\n𥿢\n𣸑\n𣺹\n𧗾\n𢂚\n䣐\n䪸\n𤄙\n𨪚\n𤋮\n𤌍\n𤀻\n𤌴\n𤎖\n𤩅\n𠗊\n凒\n𠘑\n妟\n𡺨\n㮾\n𣳿\n𤐄\n𤓖\n垈\n𤙴\n㦛\n𤜯\n𨗨\n𩧉\n㝢\n𢇃\n譞\n𨭎\n駖\n𤠒\n𤣻\n𤨕\n爉\n𤫀\n𠱸\n奥\n𤺥\n𤾆\n𠝹\n軚\n𥀬\n劏\n圿\n煱\n𥊙\n𥐙\n𣽊\n𤪧\n喼\n𥑆\n𥑮\n𦭒\n釔\n㑳\n𥔿\n𧘲\n𥕞\n䜘\n𥕢\n𥕦\n𥟇\n𤤿\n𥡝\n偦\n㓻\n𣏌\n惞\n𥤃\n䝼\n𨥈\n𥪮\n𥮉\n𥰆\n𡶐\n垡\n煑\n澶\n𦄂\n𧰒\n遖\n𦆲\n𤾚\n譢\n𦐂\n𦑊\n嵛\n𦯷\n輶\n𦒄\n𡤜\n諪\n𤧶\n𦒈\n𣿯\n𦔒\n䯀\n𦖿\n𦚵\n𢜛\n鑥\n𥟡\n憕\n娧\n晉\n侻\n嚹\n𤔡\n𦛼\n乪\n𤤴\n陖\n涏\n𦲽\n㘘\n襷\n𦞙\n𦡮\n𦐑\n𦡞\n營\n𦣇\n筂\n𩃀\n𠨑\n𦤦\n鄄\n𦤹\n穅\n鷰\n𦧺\n騦\n𦨭\n㙟\n𦑩\n𠀡\n禃\n𦨴\n𦭛\n崬\n𣔙\n菏\n𦮝\n䛐\n𦲤\n画\n补\n𦶮\n墶\n㜜\n𢖍\n𧁋\n𧇍\n㱔\n𧊀\n𧊅\n銁\n𢅺\n𧊋\n錰\n𧋦\n𤧐\n氹\n钟\n𧑐\n𠻸\n蠧\n裵\n𢤦\n𨑳\n𡞱\n溸\n𤨪\n𡠠\n㦤\n㚹\n尐\n秣\n䔿\n暶\n𩲭\n𩢤\n襃\n𧟌\n𧡘\n囖\n䃟\n𡘊\n㦡\n𣜯\n𨃨\n𡏅\n熭\n荦\n𧧝\n𩆨\n婧\n䲷\n𧂯\n𨦫\n𧧽\n𧨊\n𧬋\n𧵦\n𤅺\n筃\n祾\n𨀉\n澵\n𪋟\n樃\n𨌘\n厢\n𦸇\n鎿\n栶\n靝\n𨅯\n𨀣\n𦦵\n𡏭\n𣈯\n𨁈\n嶅\n𨰰\n𨂃\n圕\n頣\n𨥉\n嶫\n𤦈\n斾\n槕\n叒\n𤪥\n𣾁\n㰑\n朶\n𨂐\n𨃴\n𨄮\n𡾡\n𨅏\n𨆉\n𨆯\n𨈚\n𨌆\n𨌯\n𨎊\n㗊\n𨑨\n𨚪\n䣺\n揦\n𨥖\n砈\n鉕\n𨦸\n䏲\n𨧧\n䏟\n𨧨\n𨭆\n𨯔\n姸\n𨰉\n輋\n𨿅\n𩃬\n筑\n𩄐\n𩄼\n㷷\n𩅞\n𤫊\n运\n犏\n嚋\n𩓧\n𩗩\n𩖰\n𩖸\n𩜲\n𩣑\n𩥉\n𩥪\n𩧃\n𩨨\n𩬎\n𩵚\n𩶛\n纟\n𩻸\n𩼣\n䲤\n镇\n𪊓\n熢\n𪋿\n䶑\n递\n𪗋\n䶜\n𠲜\n达\n嗁\n辺\n𢒰\n边\n𤪓\n䔉\n繿\n潖\n檱\n仪\n㓤\n𨬬\n𧢝\n㜺\n躀\n𡟵\n𨀤\n𨭬\n𨮙\n𧨾\n𦚯\n㷫\n𧙕\n𣲷\n𥘵\n𥥖\n亚\n𥺁\n𦉘\n嚿\n𠹭\n踎\n孭\n𣺈\n𤲞\n揞\n拐\n𡟶\n𡡻\n攰\n嘭\n𥱊\n吚\n𥌑\n㷆\n𩶘\n䱽\n嘢\n嘞\n罉\n𥻘\n奵\n𣵀\n蝰\n东\n𠿪\n𠵉\n𣚺\n脗\n鵞\n贘\n瘻\n鱅\n癎\n瞹\n鍅\n吲\n腈\n苷\n嘥\n脲\n萘\n肽\n嗪\n祢\n噃\n吖\n𠺝\n㗎\n嘅\n嗱\n曱\n𨋢\n㘭\n甴\n嗰\n喺\n咗\n啲\n𠱁\n𠲖\n廐\n𥅈\n𠹶\n𢱢\n𠺢\n麫\n絚\n嗞\n𡁵\n抝\n靭\n咔\n賍\n燶\n酶\n揼\n掹\n揾\n啩\n𢭃\n鱲\n𢺳\n冚\n㓟\n𠶧\n冧\n呍\n唞\n唓\n癦\n踭\n𦢊\n疱\n肶\n蠄\n螆\n裇\n膶\n萜\n𡃁\n䓬\n猄\n𤜆\n宐\n茋\n𦢓\n噻\n𢛴\n𧴯\n𤆣\n𧵳\n𦻐\n𧊶\n酰\n𡇙\n鈈\n𣳼\n𪚩\n𠺬\n𠻹\n牦\n𡲢\n䝎\n𤿂\n𧿹\n𠿫\n䃺\n鱝\n攟\n𢶠\n䣳\n𤟠\n𩵼\n𠿬\n𠸊\n恢\n𧖣\n𠿭\n�\n𦁈\n𡆇\n熣\n纎\n鵐\n业\n丄\n㕷\n嬍\n沲\n卧\n㚬\n㧜\n卽\n㚥\n𤘘\n墚\n𤭮\n舭\n呋\n垪\n𥪕\n𠥹\n�\n㩒\n𢑥\n獴\n𩺬\n䴉\n鯭\n𣳾\n𩼰\n䱛\n𤾩\n𩖞\n𩿞\n葜\n𣶶\n𧊲\n𦞳\n𣜠\n挮\n紥\n𣻷\n𣸬\n㨪\n逈\n勌\n㹴\n㙺\n䗩\n𠒎\n癀\n嫰\n𠺶\n硺\n𧼮\n墧\n䂿\n噼\n鮋\n嵴\n癔\n𪐴\n麅\n䳡\n痹\n㟻\n愙\n𣃚\n𤏲\n�\n噝\n𡊩\n垧\n𤥣\n𩸆\n刴\n𧂮\n㖭\n汊\n鵼\n籖\n鬹\n埞\n𡝬\n屓\n擓\n𩓐\n𦌵\n𧅤\n蚭\n𠴨\n𦴢\n𤫢\n𠵱\n�N\n凾\n𡼏\n嶎\n霃\n𡷑\n麁\n遌\n笟\n鬂\n峑\n箣\n扨\n挵\n髿\n篏\n鬪\n籾\n鬮\n籂\n粆\n鰕\n篼\n鬉\n鼗\n鰛\n𤤾\n齚\n啳\n寃\n俽\n麘\n俲\n剠\n㸆\n勑\n坧\n偖\n妷\n帒\n韈\n鶫\n轜\n呩\n鞴\n饀\n鞺\n匬\n愰\n椬\n叚\n鰊\n鴂\n䰻\n陁\n榀\n傦\n畆\n𡝭\n駚\n剳\n�\n酙\n隁\n酜\n�\n酑\n𨺗\n捿\n𦴣\n櫊\n嘑\n醎\n畺\n抅\n𠏼\n獏\n籰\n𥰡\n𣳽\n�\n𤤙\n盖\n鮝\n个\n𠳔\n莾\n衂\n�\n届\n槀\n僭\n坺\n刟\n巵\n从\n氱\n𠇲\n伹\n咜\n哚\n劚\n趂\n㗾\n弌\n㗳\n�\n歒\n酼\n龥\n鮗\n頮\n颴\n骺\n麨\n麄\n煺\n笔\n�\n毺\n蠘\n罸\n�\n嘠\n𪙊\n蹷\n齓\n�\n跔\n蹏\n鸜\n踁\n抂\n𨍽\n踨\n蹵\n竓\n𤩷\n稾\n磘\n泪\n詧\n瘇\n𨩚\n鼦\n泎\n蟖\n痃\n𪊲\n硓\n咢\n贌\n狢\n獱\n謭\n猂\n瓱\n賫\n𤪻\n蘯\n徺\n袠\n䒷\n�T\n𡠻\n𦸅\n�W\n詾\n𢔛\n�Z\n惽\n癧\n髗\n鵄\n鍮\n鮏\n蟵\n�b\n蠏\n賷\n猬\n霡\n鮰\n㗖\n犲\n䰇\n籑\n饊\n𦅙\n慙\n䰄\n麖\n慽\n�r\n坟\n慯\n抦\n戹\n拎\n㩜\n懢\n厪\n𣏵\n捤\n栂\n㗒\n嵗\n𨯂\n迚\n𨸹\n�\n僙\n𡵆\n礆\n匲\n阸\n𠼻\n䁥\n�\n矾\n�\n糂\n𥼚\n糚\n稭\n聦\n聣\n絍\n甅\n瓲\n覔\n舚\n朌\n聢\n𧒆\n聛\n瓰\n脃\n眤\n覉\n𦟌\n畓\n𦻑\n螩\n蟎\n臈\n螌\n詉\n貭\n譃\n眫\n瓸\n蓚\n㘵\n榲\n趦\n�\n覩\n瑨\n涹\n蟁\n𤀑\n瓧\n㷛\n煶\n悤\n憜\n㳑\n煢\n恷\n�\n罱\n𨬭\n牐\n惩\n䭾\n删\n㰘\n𣳇\n𥻗\n𧙖\n𥔱\n𡥄\n𡋾\n𩤃\n𦷜\n𧂭\n峁\n𦆭\n𨨏\n𣙷\n𠃮\n𦡆\n𤼎\n䕢\n嬟\n𦍌\n齐\n麦\n𦉫\n　\n，\n、\n。\n．\n‧\n；\n：\n？\n！\n︰\n…\n‥\n﹐\n﹑\n﹒\n·\n﹔\n﹕\n﹖\n﹗\n｜\n–\n︱\n—\n︳\n╴\n︴\n﹏\n（\n）\n︵\n︶\n｛\n｝\n︷\n︸\n〔\n〕\n︹\n︺\n【\n】\n︻\n︼\n《\n》\n︽\n︾\n〈\n〉\n︿\n﹀\n「\n」\n﹁\n﹂\n『\n』\n﹃\n﹄\n﹙\n﹚\n﹛\n﹜\n﹝\n﹞\n‘\n’\n“\n”\n〝\n〞\n‵\n′\n＃\n＆\n＊\n※\n§\n〃\n○\n●\n△\n▲\n◎\n☆\n★\n◇\n◆\n□\n■\n▽\n▼\n㊣\n℅\n¯\n￣\n＿\nˍ\n﹉\n﹊\n﹍\n﹎\n﹋\n﹌\n﹟\n﹠\n﹡\n＋\n－\n×\n÷\n±\n√\n＜\n＞\n＝\n≦\n≧\n≠\n∞\n≒\n≡\n﹢\n﹣\n﹤\n﹥\n﹦\n～\n∩\n∪\n⊥\n∠\n∟\n⊿\n㏒\n㏑\n∫\n∮\n∵\n∴\n♀\n♂\n⊕\n⊙\n↑\n↓\n←\n→\n↖\n↗\n↙\n↘\n∥\n∣\n／\n＼\n∕\n﹨\n＄\n￥\n〒\n￠\n￡\n％\n＠\n℃\n℉\n﹩\n﹪\n﹫\n㏕\n㎜\n㎝\n㎞\n㏎\n㎡\n㎎\n㎏\n㏄\n°\n兙\n兛\n兞\n兝\n兡\n兣\n嗧\n瓩\n糎\n▁\n▂\n▃\n▄\n▅\n▆\n▇\n█\n▏\n▎\n▍\n▌\n▋\n▊\n▉\n┼\n┴\n┬\n┤\n├\n▔\n─\n│\n▕\n┌\n┐\n└\n┘\n╭\n╮\n╰\n╯\n═\n╞\n╪\n╡\n◢\n◣\n◥\n◤\n╱\n╲\n╳\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n〡\n〢\n〣\n〤\n〥\n〦\n〧\n〨\n〩\n十\n卄\n卅\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\nㄅ\nㄆ\nㄇ\nㄈ\nㄉ\nㄊ\nㄋ\nㄌ\nㄍ\nㄎ\nㄏ\nㄐ\nㄑ\nㄒ\nㄓ\nㄔ\nㄕ\nㄖ\nㄗ\nㄘ\nㄙ\nㄚ\nㄛ\nㄜ\nㄝ\nㄞ\nㄟ\nㄠ\nㄡ\nㄢ\nㄣ\nㄤ\nㄥ\nㄦ\nㄧ\nㄨ\nㄩ\n˙\nˉ\nˊ\nˇ\nˋ\n␀\n␁\n␂\n␃\n␄\n␅\n␆\n␇\n␈\n␉\n␊\n␋\n␌\n␍\n␎\n␏\n␐\n␑\n␒\n␓\n␔\n␕\n␖\n␗\n␘\n␙\n␚\n␛\n␜\n␝\n␞\n␟\n␡\n€\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n一\n乙\n丁\n七\n乃\n九\n了\n二\n人\n儿\n入\n八\n几\n刀\n刁\n力\n匕\n十\n卜\n又\n三\n下\n丈\n上\n丫\n丸\n凡\n久\n么\n也\n乞\n于\n亡\n兀\n刃\n勺\n千\n叉\n口\n土\n士\n夕\n大\n女\n子\n孑\n孓\n寸\n小\n尢\n尸\n山\n川\n工\n己\n已\n巳\n巾\n干\n廾\n弋\n弓\n才\n丑\n丐\n不\n中\n丰\n丹\n之\n尹\n予\n云\n井\n互\n五\n亢\n仁\n什\n仃\n仆\n仇\n仍\n今\n介\n仄\n元\n允\n內\n六\n兮\n公\n冗\n凶\n分\n切\n刈\n勻\n勾\n勿\n化\n匹\n午\n升\n卅\n卞\n厄\n友\n及\n反\n壬\n天\n夫\n太\n夭\n孔\n少\n尤\n尺\n屯\n巴\n幻\n廿\n弔\n引\n心\n戈\n戶\n手\n扎\n支\n文\n斗\n斤\n方\n日\n曰\n月\n木\n欠\n止\n歹\n毋\n比\n毛\n氏\n水\n火\n爪\n父\n爻\n片\n牙\n牛\n犬\n王\n丙\n世\n丕\n且\n丘\n主\n乍\n乏\n乎\n以\n付\n仔\n仕\n他\n仗\n代\n令\n仙\n仞\n充\n兄\n冉\n冊\n冬\n凹\n出\n凸\n刊\n加\n功\n包\n匆\n北\n匝\n仟\n半\n卉\n卡\n占\n卯\n卮\n去\n可\n古\n右\n召\n叮\n叩\n叨\n叼\n司\n叵\n叫\n另\n只\n史\n叱\n台\n句\n叭\n叻\n四\n囚\n外\n央\n失\n奴\n奶\n孕\n它\n尼\n巨\n巧\n左\n市\n布\n平\n幼\n弁\n弘\n弗\n必\n戊\n打\n扔\n扒\n扑\n斥\n旦\n朮\n本\n未\n末\n札\n正\n母\n民\n氐\n永\n汁\n汀\n氾\n犯\n玄\n玉\n瓜\n瓦\n甘\n生\n用\n甩\n田\n由\n甲\n申\n疋\n白\n皮\n皿\n目\n矛\n矢\n石\n示\n禾\n穴\n立\n丞\n丟\n乒\n乓\n乩\n亙\n交\n亦\n亥\n仿\n伉\n伙\n伊\n伕\n伍\n伐\n休\n伏\n仲\n件\n任\n仰\n仳\n份\n企\n伋\n光\n兇\n兆\n先\n全\n共\n再\n冰\n列\n刑\n划\n刎\n刖\n劣\n匈\n匡\n匠\n印\n危\n吉\n吏\n同\n吊\n吐\n吁\n吋\n各\n向\n名\n合\n吃\n后\n吆\n吒\n因\n回\n囝\n圳\n地\n在\n圭\n圬\n圯\n圩\n夙\n多\n夷\n夸\n妄\n奸\n妃\n好\n她\n如\n妁\n字\n存\n宇\n守\n宅\n安\n寺\n尖\n屹\n州\n帆\n并\n年\n式\n弛\n忙\n忖\n戎\n戌\n戍\n成\n扣\n扛\n托\n收\n早\n旨\n旬\n旭\n曲\n曳\n有\n朽\n朴\n朱\n朵\n次\n此\n死\n氖\n汝\n汗\n汙\n江\n池\n汐\n汕\n污\n汛\n汍\n汎\n灰\n牟\n牝\n百\n竹\n米\n糸\n缶\n羊\n羽\n老\n考\n而\n耒\n耳\n聿\n肉\n肋\n肌\n臣\n自\n至\n臼\n舌\n舛\n舟\n艮\n色\n艾\n虫\n血\n行\n衣\n西\n阡\n串\n亨\n位\n住\n佇\n佗\n佞\n伴\n佛\n何\n估\n佐\n佑\n伽\n伺\n伸\n佃\n佔\n似\n但\n佣\n作\n你\n伯\n低\n伶\n余\n佝\n佈\n佚\n兌\n克\n免\n兵\n冶\n冷\n別\n判\n利\n刪\n刨\n劫\n助\n努\n劬\n匣\n即\n卵\n吝\n吭\n吞\n吾\n否\n呎\n吧\n呆\n呃\n吳\n呈\n呂\n君\n吩\n告\n吹\n吻\n吸\n吮\n吵\n吶\n吠\n吼\n呀\n吱\n含\n吟\n听\n囪\n困\n囤\n囫\n坊\n坑\n址\n坍\n均\n坎\n圾\n坐\n坏\n圻\n壯\n夾\n妝\n妒\n妨\n妞\n妣\n妙\n妖\n妍\n妤\n妓\n妊\n妥\n孝\n孜\n孚\n孛\n完\n宋\n宏\n尬\n局\n屁\n尿\n尾\n岐\n岑\n岔\n岌\n巫\n希\n序\n庇\n床\n廷\n弄\n弟\n彤\n形\n彷\n役\n忘\n忌\n志\n忍\n忱\n快\n忸\n忪\n戒\n我\n抄\n抗\n抖\n技\n扶\n抉\n扭\n把\n扼\n找\n批\n扳\n抒\n扯\n折\n扮\n投\n抓\n抑\n抆\n改\n攻\n攸\n旱\n更\n束\n李\n杏\n材\n村\n杜\n杖\n杞\n杉\n杆\n杠\n杓\n杗\n步\n每\n求\n汞\n沙\n沁\n沈\n沉\n沅\n沛\n汪\n決\n沐\n汰\n沌\n汨\n沖\n沒\n汽\n沃\n汲\n汾\n汴\n沆\n汶\n沍\n沔\n沘\n沂\n灶\n灼\n災\n灸\n牢\n牡\n牠\n狄\n狂\n玖\n甬\n甫\n男\n甸\n皂\n盯\n矣\n私\n秀\n禿\n究\n系\n罕\n肖\n肓\n肝\n肘\n肛\n肚\n育\n良\n芒\n芋\n芍\n見\n角\n言\n谷\n豆\n豕\n貝\n赤\n走\n足\n身\n車\n辛\n辰\n迂\n迆\n迅\n迄\n巡\n邑\n邢\n邪\n邦\n那\n酉\n釆\n里\n防\n阮\n阱\n阪\n阬\n並\n乖\n乳\n事\n些\n亞\n享\n京\n佯\n依\n侍\n佳\n使\n佬\n供\n例\n來\n侃\n佰\n併\n侈\n佩\n佻\n侖\n佾\n侏\n侑\n佺\n兔\n兒\n兕\n兩\n具\n其\n典\n冽\n函\n刻\n券\n刷\n刺\n到\n刮\n制\n剁\n劾\n劻\n卒\n協\n卓\n卑\n卦\n卷\n卸\n卹\n取\n叔\n受\n味\n呵\n咖\n呸\n咕\n咀\n呻\n呷\n咄\n咒\n咆\n呼\n咐\n呱\n呶\n和\n咚\n呢\n周\n咋\n命\n咎\n固\n垃\n坷\n坪\n坩\n坡\n坦\n坤\n坼\n夜\n奉\n奇\n奈\n奄\n奔\n妾\n妻\n委\n妹\n妮\n姑\n姆\n姐\n姍\n始\n姓\n姊\n妯\n妳\n姒\n姅\n孟\n孤\n季\n宗\n定\n官\n宜\n宙\n宛\n尚\n屈\n居\n屆\n岷\n岡\n岸\n岩\n岫\n岱\n岳\n帘\n帚\n帖\n帕\n帛\n帑\n幸\n庚\n店\n府\n底\n庖\n延\n弦\n弧\n弩\n往\n征\n彿\n彼\n忝\n忠\n忽\n念\n忿\n怏\n怔\n怯\n怵\n怖\n怪\n怕\n怡\n性\n怩\n怫\n怛\n或\n戕\n房\n戾\n所\n承\n拉\n拌\n拄\n抿\n拂\n抹\n拒\n招\n披\n拓\n拔\n拋\n拈\n抨\n抽\n押\n拐\n拙\n拇\n拍\n抵\n拚\n抱\n拘\n拖\n拗\n拆\n抬\n拎\n放\n斧\n於\n旺\n昔\n易\n昌\n昆\n昂\n明\n昀\n昏\n昕\n昊\n昇\n服\n朋\n杭\n枋\n枕\n東\n果\n杳\n杷\n枇\n枝\n林\n杯\n杰\n板\n枉\n松\n析\n杵\n枚\n枓\n杼\n杪\n杲\n欣\n武\n歧\n歿\n氓\n氛\n泣\n注\n泳\n沱\n泌\n泥\n河\n沽\n沾\n沼\n波\n沫\n法\n泓\n沸\n泄\n油\n況\n沮\n泗\n泅\n泱\n沿\n治\n泡\n泛\n泊\n沬\n泯\n泜\n泖\n泠\n炕\n炎\n炒\n炊\n炙\n爬\n爭\n爸\n版\n牧\n物\n狀\n狎\n狙\n狗\n狐\n玩\n玨\n玟\n玫\n玥\n甽\n疝\n疙\n疚\n的\n盂\n盲\n直\n知\n矽\n社\n祀\n祁\n秉\n秈\n空\n穹\n竺\n糾\n罔\n羌\n羋\n者\n肺\n肥\n肢\n肱\n股\n肫\n肩\n肴\n肪\n肯\n臥\n臾\n舍\n芳\n芝\n芙\n芭\n芽\n芟\n芹\n花\n芬\n芥\n芯\n芸\n芣\n芰\n芾\n芷\n虎\n虱\n初\n表\n軋\n迎\n返\n近\n邵\n邸\n邱\n邶\n采\n金\n長\n門\n阜\n陀\n阿\n阻\n附\n陂\n隹\n雨\n青\n非\n亟\n亭\n亮\n信\n侵\n侯\n便\n俠\n俑\n俏\n保\n促\n侶\n俘\n俟\n俊\n俗\n侮\n俐\n俄\n係\n俚\n俎\n俞\n侷\n兗\n冒\n冑\n冠\n剎\n剃\n削\n前\n剌\n剋\n則\n勇\n勉\n勃\n勁\n匍\n南\n卻\n厚\n叛\n咬\n哀\n咨\n哎\n哉\n咸\n咦\n咳\n哇\n哂\n咽\n咪\n品\n哄\n哈\n咯\n咫\n咱\n咻\n咩\n咧\n咿\n囿\n垂\n型\n垠\n垣\n垢\n城\n垮\n垓\n奕\n契\n奏\n奎\n奐\n姜\n姘\n姿\n姣\n姨\n娃\n姥\n姪\n姚\n姦\n威\n姻\n孩\n宣\n宦\n室\n客\n宥\n封\n屎\n屏\n屍\n屋\n峙\n峒\n巷\n帝\n帥\n帟\n幽\n庠\n度\n建\n弈\n弭\n彥\n很\n待\n徊\n律\n徇\n後\n徉\n怒\n思\n怠\n急\n怎\n怨\n恍\n恰\n恨\n恢\n恆\n恃\n恬\n恫\n恪\n恤\n扁\n拜\n挖\n按\n拼\n拭\n持\n拮\n拽\n指\n拱\n拷\n拯\n括\n拾\n拴\n挑\n挂\n政\n故\n斫\n施\n既\n春\n昭\n映\n昧\n是\n星\n昨\n昱\n昤\n曷\n柿\n染\n柱\n柔\n某\n柬\n架\n枯\n柵\n柩\n柯\n柄\n柑\n枴\n柚\n查\n枸\n柏\n柞\n柳\n枰\n柙\n柢\n柝\n柒\n歪\n殃\n殆\n段\n毒\n毗\n氟\n泉\n洋\n洲\n洪\n流\n津\n洌\n洱\n洞\n洗\n活\n洽\n派\n洶\n洛\n泵\n洹\n洧\n洸\n洩\n洮\n洵\n洎\n洫\n炫\n為\n炳\n炬\n炯\n炭\n炸\n炮\n炤\n爰\n牲\n牯\n牴\n狩\n狠\n狡\n玷\n珊\n玻\n玲\n珍\n珀\n玳\n甚\n甭\n畏\n界\n畎\n畋\n疫\n疤\n疥\n疢\n疣\n癸\n皆\n皇\n皈\n盈\n盆\n盃\n盅\n省\n盹\n相\n眉\n看\n盾\n盼\n眇\n矜\n砂\n研\n砌\n砍\n祆\n祉\n祈\n祇\n禹\n禺\n科\n秒\n秋\n穿\n突\n竿\n竽\n籽\n紂\n紅\n紀\n紉\n紇\n約\n紆\n缸\n美\n羿\n耄\n耐\n耍\n耑\n耶\n胖\n胥\n胚\n胃\n胄\n背\n胡\n胛\n胎\n胞\n胤\n胝\n致\n舢\n苧\n范\n茅\n苣\n苛\n苦\n茄\n若\n茂\n茉\n苒\n苗\n英\n茁\n苜\n苔\n苑\n苞\n苓\n苟\n苯\n茆\n虐\n虹\n虻\n虺\n衍\n衫\n要\n觔\n計\n訂\n訃\n貞\n負\n赴\n赳\n趴\n軍\n軌\n述\n迦\n迢\n迪\n迥\n迭\n迫\n迤\n迨\n郊\n郎\n郁\n郃\n酋\n酊\n重\n閂\n限\n陋\n陌\n降\n面\n革\n韋\n韭\n音\n頁\n風\n飛\n食\n首\n香\n乘\n亳\n倌\n倍\n倣\n俯\n倦\n倥\n俸\n倩\n倖\n倆\n值\n借\n倚\n倒\n們\n俺\n倀\n倔\n倨\n俱\n倡\n個\n候\n倘\n俳\n修\n倭\n倪\n俾\n倫\n倉\n兼\n冤\n冥\n冢\n凍\n凌\n准\n凋\n剖\n剜\n剔\n剛\n剝\n匪\n卿\n原\n厝\n叟\n哨\n唐\n唁\n唷\n哼\n哥\n哲\n唆\n哺\n唔\n哩\n哭\n員\n唉\n哮\n哪\n哦\n唧\n唇\n哽\n唏\n圃\n圄\n埂\n埔\n埋\n埃\n堉\n夏\n套\n奘\n奚\n娑\n娘\n娜\n娟\n娛\n娓\n姬\n娠\n娣\n娩\n娥\n娌\n娉\n孫\n屘\n宰\n害\n家\n宴\n宮\n宵\n容\n宸\n射\n屑\n展\n屐\n峭\n峽\n峻\n峪\n峨\n峰\n島\n崁\n峴\n差\n席\n師\n庫\n庭\n座\n弱\n徒\n徑\n徐\n恙\n恣\n恥\n恐\n恕\n恭\n恩\n息\n悄\n悟\n悚\n悍\n悔\n悌\n悅\n悖\n扇\n拳\n挈\n拿\n捎\n挾\n振\n捕\n捂\n捆\n捏\n捉\n挺\n捐\n挽\n挪\n挫\n挨\n捍\n捌\n效\n敉\n料\n旁\n旅\n時\n晉\n晏\n晃\n晒\n晌\n晅\n晁\n書\n朔\n朕\n朗\n校\n核\n案\n框\n桓\n根\n桂\n桔\n栩\n梳\n栗\n桌\n桑\n栽\n柴\n桐\n桀\n格\n桃\n株\n桅\n栓\n栘\n桁\n殊\n殉\n殷\n氣\n氧\n氨\n氦\n氤\n泰\n浪\n涕\n消\n涇\n浦\n浸\n海\n浙\n涓\n浬\n涉\n浮\n浚\n浴\n浩\n涌\n涊\n浹\n涅\n浥\n涔\n烊\n烘\n烤\n烙\n烈\n烏\n爹\n特\n狼\n狹\n狽\n狸\n狷\n玆\n班\n琉\n珮\n珠\n珪\n珞\n畔\n畝\n畜\n畚\n留\n疾\n病\n症\n疲\n疳\n疽\n疼\n疹\n痂\n疸\n皋\n皰\n益\n盍\n盎\n眩\n真\n眠\n眨\n矩\n砰\n砧\n砸\n砝\n破\n砷\n砥\n砭\n砠\n砟\n砲\n祕\n祐\n祠\n祟\n祖\n神\n祝\n祗\n祚\n秤\n秣\n秧\n租\n秦\n秩\n秘\n窄\n窈\n站\n笆\n笑\n粉\n紡\n紗\n紋\n紊\n素\n索\n純\n紐\n紕\n級\n紜\n納\n紙\n紛\n缺\n罟\n羔\n翅\n翁\n耆\n耘\n耕\n耙\n耗\n耽\n耿\n胱\n脂\n胰\n脅\n胭\n胴\n脆\n胸\n胳\n脈\n能\n脊\n胼\n胯\n臭\n臬\n舀\n舐\n航\n舫\n舨\n般\n芻\n茫\n荒\n荔\n荊\n茸\n荐\n草\n茵\n茴\n荏\n茲\n茹\n茶\n茗\n荀\n茱\n茨\n荃\n虔\n蚊\n蚪\n蚓\n蚤\n蚩\n蚌\n蚣\n蚜\n衰\n衷\n袁\n袂\n衽\n衹\n記\n訐\n討\n訌\n訕\n訊\n託\n訓\n訖\n訏\n訑\n豈\n豺\n豹\n財\n貢\n起\n躬\n軒\n軔\n軏\n辱\n送\n逆\n迷\n退\n迺\n迴\n逃\n追\n逅\n迸\n邕\n郡\n郝\n郢\n酒\n配\n酌\n釘\n針\n釗\n釜\n釙\n閃\n院\n陣\n陡\n陛\n陝\n除\n陘\n陞\n隻\n飢\n馬\n骨\n高\n鬥\n鬲\n鬼\n乾\n偺\n偽\n停\n假\n偃\n偌\n做\n偉\n健\n偶\n偎\n偕\n偵\n側\n偷\n偏\n倏\n偯\n偭\n兜\n冕\n凰\n剪\n副\n勒\n務\n勘\n動\n匐\n匏\n匙\n匿\n區\n匾\n參\n曼\n商\n啪\n啦\n啄\n啞\n啡\n啃\n啊\n唱\n啖\n問\n啕\n唯\n啤\n唸\n售\n啜\n唬\n啣\n唳\n啁\n啗\n圈\n國\n圉\n域\n堅\n堊\n堆\n埠\n埤\n基\n堂\n堵\n執\n培\n夠\n奢\n娶\n婁\n婉\n婦\n婪\n婀\n娼\n婢\n婚\n婆\n婊\n孰\n寇\n寅\n寄\n寂\n宿\n密\n尉\n專\n將\n屠\n屜\n屝\n崇\n崆\n崎\n崛\n崖\n崢\n崑\n崩\n崔\n崙\n崤\n崧\n崗\n巢\n常\n帶\n帳\n帷\n康\n庸\n庶\n庵\n庾\n張\n強\n彗\n彬\n彩\n彫\n得\n徙\n從\n徘\n御\n徠\n徜\n恿\n患\n悉\n悠\n您\n惋\n悴\n惦\n悽\n情\n悻\n悵\n惜\n悼\n惘\n惕\n惆\n惟\n悸\n惚\n惇\n戚\n戛\n扈\n掠\n控\n捲\n掖\n探\n接\n捷\n捧\n掘\n措\n捱\n掩\n掉\n掃\n掛\n捫\n推\n掄\n授\n掙\n採\n掬\n排\n掏\n掀\n捻\n捩\n捨\n捺\n敝\n敖\n救\n教\n敗\n啟\n敏\n敘\n敕\n敔\n斜\n斛\n斬\n族\n旋\n旌\n旎\n晝\n晚\n晤\n晨\n晦\n晞\n曹\n勗\n望\n梁\n梯\n梢\n梓\n梵\n桿\n桶\n梱\n梧\n梗\n械\n梃\n棄\n梭\n梆\n梅\n梔\n條\n梨\n梟\n梡\n梂\n欲\n殺\n毫\n毬\n氫\n涎\n涼\n淳\n淙\n液\n淡\n淌\n淤\n添\n淺\n清\n淇\n淋\n涯\n淑\n涮\n淞\n淹\n涸\n混\n淵\n淅\n淒\n渚\n涵\n淚\n淫\n淘\n淪\n深\n淮\n淨\n淆\n淄\n涪\n淬\n涿\n淦\n烹\n焉\n焊\n烽\n烯\n爽\n牽\n犁\n猜\n猛\n猖\n猓\n猙\n率\n琅\n琊\n球\n理\n現\n琍\n瓠\n瓶\n瓷\n甜\n產\n略\n畦\n畢\n異\n疏\n痔\n痕\n疵\n痊\n痍\n皎\n盔\n盒\n盛\n眷\n眾\n眼\n眶\n眸\n眺\n硫\n硃\n硎\n祥\n票\n祭\n移\n窒\n窕\n笠\n笨\n笛\n第\n符\n笙\n笞\n笮\n粒\n粗\n粕\n絆\n絃\n統\n紮\n紹\n紼\n絀\n細\n紳\n組\n累\n終\n紲\n紱\n缽\n羞\n羚\n翌\n翎\n習\n耜\n聊\n聆\n脯\n脖\n脣\n脫\n脩\n脰\n脤\n舂\n舵\n舷\n舶\n船\n莎\n莞\n莘\n荸\n莢\n莖\n莽\n莫\n莒\n莊\n莓\n莉\n莠\n荷\n荻\n荼\n莆\n莧\n處\n彪\n蛇\n蛀\n蚶\n蛄\n蚵\n蛆\n蛋\n蚱\n蚯\n蛉\n術\n袞\n袈\n被\n袒\n袖\n袍\n袋\n覓\n規\n訪\n訝\n訣\n訥\n許\n設\n訟\n訛\n訢\n豉\n豚\n販\n責\n貫\n貨\n貪\n貧\n赧\n赦\n趾\n趺\n軛\n軟\n這\n逍\n通\n逗\n連\n速\n逝\n逐\n逕\n逞\n造\n透\n逢\n逖\n逛\n途\n部\n郭\n都\n酗\n野\n釵\n釦\n釣\n釧\n釭\n釩\n閉\n陪\n陵\n陳\n陸\n陰\n陴\n陶\n陷\n陬\n雀\n雪\n雩\n章\n竟\n頂\n頃\n魚\n鳥\n鹵\n鹿\n麥\n麻\n傢\n傍\n傅\n備\n傑\n傀\n傖\n傘\n傚\n最\n凱\n割\n剴\n創\n剩\n勞\n勝\n勛\n博\n厥\n啻\n喀\n喧\n啼\n喊\n喝\n喘\n喂\n喜\n喪\n喔\n喇\n喋\n喃\n喳\n單\n喟\n唾\n喲\n喚\n喻\n喬\n喱\n啾\n喉\n喫\n喙\n圍\n堯\n堪\n場\n堤\n堰\n報\n堡\n堝\n堠\n壹\n壺\n奠\n婷\n媚\n婿\n媒\n媛\n媧\n孳\n孱\n寒\n富\n寓\n寐\n尊\n尋\n就\n嵌\n嵐\n崴\n嵇\n巽\n幅\n帽\n幀\n幃\n幾\n廊\n廁\n廂\n廄\n弼\n彭\n復\n循\n徨\n惑\n惡\n悲\n悶\n惠\n愜\n愣\n惺\n愕\n惰\n惻\n惴\n慨\n惱\n愎\n惶\n愉\n愀\n愒\n戟\n扉\n掣\n掌\n描\n揀\n揩\n揉\n揆\n揍\n插\n揣\n提\n握\n揖\n揭\n揮\n捶\n援\n揪\n換\n摒\n揚\n揹\n敞\n敦\n敢\n散\n斑\n斐\n斯\n普\n晰\n晴\n晶\n景\n暑\n智\n晾\n晷\n曾\n替\n期\n朝\n棺\n棕\n棠\n棘\n棗\n椅\n棟\n棵\n森\n棧\n棹\n棒\n棲\n棣\n棋\n棍\n植\n椒\n椎\n棉\n棚\n楮\n棻\n款\n欺\n欽\n殘\n殖\n殼\n毯\n氮\n氯\n氬\n港\n游\n湔\n渡\n渲\n湧\n湊\n渠\n渥\n渣\n減\n湛\n湘\n渤\n湖\n湮\n渭\n渦\n湯\n渴\n湍\n渺\n測\n湃\n渝\n渾\n滋\n溉\n渙\n湎\n湣\n湄\n湲\n湩\n湟\n焙\n焚\n焦\n焰\n無\n然\n煮\n焜\n牌\n犄\n犀\n猶\n猥\n猴\n猩\n琺\n琪\n琳\n琢\n琥\n琵\n琶\n琴\n琯\n琛\n琦\n琨\n甥\n甦\n畫\n番\n痢\n痛\n痣\n痙\n痘\n痞\n痠\n登\n發\n皖\n皓\n皴\n盜\n睏\n短\n硝\n硬\n硯\n稍\n稈\n程\n稅\n稀\n窘\n窗\n窖\n童\n竣\n等\n策\n筆\n筐\n筒\n答\n筍\n筋\n筏\n筑\n粟\n粥\n絞\n結\n絨\n絕\n紫\n絮\n絲\n絡\n給\n絢\n絰\n絳\n善\n翔\n翕\n耋\n聒\n肅\n腕\n腔\n腋\n腑\n腎\n脹\n腆\n脾\n腌\n腓\n腴\n舒\n舜\n菩\n萃\n菸\n萍\n菠\n菅\n萋\n菁\n華\n菱\n菴\n著\n萊\n菰\n萌\n菌\n菽\n菲\n菊\n萸\n萎\n萄\n菜\n萇\n菔\n菟\n虛\n蛟\n蛙\n蛭\n蛔\n蛛\n蛤\n蛐\n蛞\n街\n裁\n裂\n袱\n覃\n視\n註\n詠\n評\n詞\n証\n詁\n詔\n詛\n詐\n詆\n訴\n診\n訶\n詖\n象\n貂\n貯\n貼\n貳\n貽\n賁\n費\n賀\n貴\n買\n貶\n貿\n貸\n越\n超\n趁\n跎\n距\n跋\n跚\n跑\n跌\n跛\n跆\n軻\n軸\n軼\n辜\n逮\n逵\n週\n逸\n進\n逶\n鄂\n郵\n鄉\n郾\n酣\n酥\n量\n鈔\n鈕\n鈣\n鈉\n鈞\n鈍\n鈐\n鈇\n鈑\n閔\n閏\n開\n閑\n間\n閒\n閎\n隊\n階\n隋\n陽\n隅\n隆\n隍\n陲\n隄\n雁\n雅\n雄\n集\n雇\n雯\n雲\n韌\n項\n順\n須\n飧\n飪\n飯\n飩\n飲\n飭\n馮\n馭\n黃\n黍\n黑\n亂\n傭\n債\n傲\n傳\n僅\n傾\n催\n傷\n傻\n傯\n僇\n剿\n剷\n剽\n募\n勦\n勤\n勢\n勣\n匯\n嗟\n嗨\n嗓\n嗦\n嗎\n嗜\n嗇\n嗑\n嗣\n嗤\n嗯\n嗚\n嗡\n嗅\n嗆\n嗥\n嗉\n園\n圓\n塞\n塑\n塘\n塗\n塚\n塔\n填\n塌\n塭\n塊\n塢\n塒\n塋\n奧\n嫁\n嫉\n嫌\n媾\n媽\n媼\n媳\n嫂\n媲\n嵩\n嵯\n幌\n幹\n廉\n廈\n弒\n彙\n徬\n微\n愚\n意\n慈\n感\n想\n愛\n惹\n愁\n愈\n慎\n慌\n慄\n慍\n愾\n愴\n愧\n愍\n愆\n愷\n戡\n戢\n搓\n搾\n搞\n搪\n搭\n搽\n搬\n搏\n搜\n搔\n損\n搶\n搖\n搗\n搆\n敬\n斟\n新\n暗\n暉\n暇\n暈\n暖\n暄\n暘\n暍\n會\n榔\n業\n楚\n楷\n楠\n楔\n極\n椰\n概\n楊\n楨\n楫\n楞\n楓\n楹\n榆\n楝\n楣\n楛\n歇\n歲\n毀\n殿\n毓\n毽\n溢\n溯\n滓\n溶\n滂\n源\n溝\n滇\n滅\n溥\n溘\n溼\n溺\n溫\n滑\n準\n溜\n滄\n滔\n溪\n溧\n溴\n煎\n煙\n煩\n煤\n煉\n照\n煜\n煬\n煦\n煌\n煥\n煞\n煆\n煨\n煖\n爺\n牒\n猷\n獅\n猿\n猾\n瑯\n瑚\n瑕\n瑟\n瑞\n瑁\n琿\n瑙\n瑛\n瑜\n當\n畸\n瘀\n痰\n瘁\n痲\n痱\n痺\n痿\n痴\n痳\n盞\n盟\n睛\n睫\n睦\n睞\n督\n睹\n睪\n睬\n睜\n睥\n睨\n睢\n矮\n碎\n碰\n碗\n碘\n碌\n碉\n硼\n碑\n碓\n硿\n祺\n祿\n禁\n萬\n禽\n稜\n稚\n稠\n稔\n稟\n稞\n窟\n窠\n筷\n節\n筠\n筮\n筧\n粱\n粳\n粵\n經\n絹\n綑\n綁\n綏\n絛\n置\n罩\n罪\n署\n義\n羨\n群\n聖\n聘\n肆\n肄\n腱\n腰\n腸\n腥\n腮\n腳\n腫\n腹\n腺\n腦\n舅\n艇\n蒂\n葷\n落\n萱\n葵\n葦\n葫\n葉\n葬\n葛\n萼\n萵\n葡\n董\n葩\n葭\n葆\n虞\n虜\n號\n蛹\n蜓\n蜈\n蜇\n蜀\n蛾\n蛻\n蜂\n蜃\n蜆\n蜊\n衙\n裟\n裔\n裙\n補\n裘\n裝\n裡\n裊\n裕\n裒\n覜\n解\n詫\n該\n詳\n試\n詩\n詰\n誇\n詼\n詣\n誠\n話\n誅\n詭\n詢\n詮\n詬\n詹\n詻\n訾\n詨\n豢\n貊\n貉\n賊\n資\n賈\n賄\n貲\n賃\n賂\n賅\n跡\n跟\n跨\n路\n跳\n跺\n跪\n跤\n跦\n躲\n較\n載\n軾\n輊\n辟\n農\n運\n遊\n道\n遂\n達\n逼\n違\n遐\n遇\n遏\n過\n遍\n遑\n逾\n遁\n鄒\n鄗\n酬\n酪\n酩\n釉\n鈷\n鉗\n鈸\n鈽\n鉀\n鈾\n鉛\n鉋\n鉤\n鉑\n鈴\n鉉\n鉍\n鉅\n鈹\n鈿\n鉚\n閘\n隘\n隔\n隕\n雍\n雋\n雉\n雊\n雷\n電\n雹\n零\n靖\n靴\n靶\n預\n頑\n頓\n頊\n頒\n頌\n飼\n飴\n飽\n飾\n馳\n馱\n馴\n髡\n鳩\n麂\n鼎\n鼓\n鼠\n僧\n僮\n僥\n僖\n僭\n僚\n僕\n像\n僑\n僱\n僎\n僩\n兢\n凳\n劃\n劂\n匱\n厭\n嗾\n嘀\n嘛\n嘗\n嗽\n嘔\n嘆\n嘉\n嘍\n嘎\n嗷\n嘖\n嘟\n嘈\n嘐\n嗶\n團\n圖\n塵\n塾\n境\n墓\n墊\n塹\n墅\n塽\n壽\n夥\n夢\n夤\n奪\n奩\n嫡\n嫦\n嫩\n嫗\n嫖\n嫘\n嫣\n孵\n寞\n寧\n寡\n寥\n實\n寨\n寢\n寤\n察\n對\n屢\n嶄\n嶇\n幛\n幣\n幕\n幗\n幔\n廓\n廖\n弊\n彆\n彰\n徹\n慇\n愿\n態\n慷\n慢\n慣\n慟\n慚\n慘\n慵\n截\n撇\n摘\n摔\n撤\n摸\n摟\n摺\n摑\n摧\n搴\n摭\n摻\n敲\n斡\n旗\n旖\n暢\n暨\n暝\n榜\n榨\n榕\n槁\n榮\n槓\n構\n榛\n榷\n榻\n榫\n榴\n槐\n槍\n榭\n槌\n榦\n槃\n榣\n歉\n歌\n氳\n漳\n演\n滾\n漓\n滴\n漩\n漾\n漠\n漬\n漏\n漂\n漢\n滿\n滯\n漆\n漱\n漸\n漲\n漣\n漕\n漫\n漯\n澈\n漪\n滬\n漁\n滲\n滌\n滷\n熔\n熙\n煽\n熊\n熄\n熒\n爾\n犒\n犖\n獄\n獐\n瑤\n瑣\n瑪\n瑰\n瑭\n甄\n疑\n瘧\n瘍\n瘋\n瘉\n瘓\n盡\n監\n瞄\n睽\n睿\n睡\n磁\n碟\n碧\n碳\n碩\n碣\n禎\n福\n禍\n種\n稱\n窪\n窩\n竭\n端\n管\n箕\n箋\n筵\n算\n箝\n箔\n箏\n箸\n箇\n箄\n粹\n粽\n精\n綻\n綰\n綜\n綽\n綾\n綠\n緊\n綴\n網\n綱\n綺\n綢\n綿\n綵\n綸\n維\n緒\n緇\n綬\n罰\n翠\n翡\n翟\n聞\n聚\n肇\n腐\n膀\n膏\n膈\n膊\n腿\n膂\n臧\n臺\n與\n舔\n舞\n艋\n蓉\n蒿\n蓆\n蓄\n蒙\n蒞\n蒲\n蒜\n蓋\n蒸\n蓀\n蓓\n蒐\n蒼\n蓑\n蓊\n蜿\n蜜\n蜻\n蜢\n蜥\n蜴\n蜘\n蝕\n蜷\n蜩\n裳\n褂\n裴\n裹\n裸\n製\n裨\n褚\n裯\n誦\n誌\n語\n誣\n認\n誡\n誓\n誤\n說\n誥\n誨\n誘\n誑\n誚\n誧\n豪\n貍\n貌\n賓\n賑\n賒\n赫\n趙\n趕\n跼\n輔\n輒\n輕\n輓\n辣\n遠\n遘\n遜\n遣\n遙\n遞\n遢\n遝\n遛\n鄙\n鄘\n鄞\n酵\n酸\n酷\n酴\n鉸\n銀\n銅\n銘\n銖\n鉻\n銓\n銜\n銨\n鉼\n銑\n閡\n閨\n閩\n閣\n閥\n閤\n隙\n障\n際\n雌\n雒\n需\n靼\n鞅\n韶\n頗\n領\n颯\n颱\n餃\n餅\n餌\n餉\n駁\n骯\n骰\n髦\n魁\n魂\n鳴\n鳶\n鳳\n麼\n鼻\n齊\n億\n儀\n僻\n僵\n價\n儂\n儈\n儉\n儅\n凜\n劇\n劈\n劉\n劍\n劊\n勰\n厲\n嘮\n嘻\n嘹\n嘲\n嘿\n嘴\n嘩\n噓\n噎\n噗\n噴\n嘶\n嘯\n嘰\n墀\n墟\n增\n墳\n墜\n墮\n墩\n墦\n奭\n嬉\n嫻\n嬋\n嫵\n嬌\n嬈\n寮\n寬\n審\n寫\n層\n履\n嶝\n嶔\n幢\n幟\n幡\n廢\n廚\n廟\n廝\n廣\n廠\n彈\n影\n德\n徵\n慶\n慧\n慮\n慝\n慕\n憂\n慼\n慰\n慫\n慾\n憧\n憐\n憫\n憎\n憬\n憚\n憤\n憔\n憮\n戮\n摩\n摯\n摹\n撞\n撲\n撈\n撐\n撰\n撥\n撓\n撕\n撩\n撒\n撮\n播\n撫\n撚\n撬\n撙\n撢\n撳\n敵\n敷\n數\n暮\n暫\n暴\n暱\n樣\n樟\n槨\n樁\n樞\n標\n槽\n模\n樓\n樊\n槳\n樂\n樅\n槭\n樑\n歐\n歎\n殤\n毅\n毆\n漿\n潼\n澄\n潑\n潦\n潔\n澆\n潭\n潛\n潸\n潮\n澎\n潺\n潰\n潤\n澗\n潘\n滕\n潯\n潠\n潟\n熟\n熬\n熱\n熨\n牖\n犛\n獎\n獗\n瑩\n璋\n璃\n瑾\n璀\n畿\n瘠\n瘩\n瘟\n瘤\n瘦\n瘡\n瘢\n皚\n皺\n盤\n瞎\n瞇\n瞌\n瞑\n瞋\n磋\n磅\n確\n磊\n碾\n磕\n碼\n磐\n稿\n稼\n穀\n稽\n稷\n稻\n窯\n窮\n箭\n箱\n範\n箴\n篆\n篇\n篁\n箠\n篌\n糊\n締\n練\n緯\n緻\n緘\n緬\n緝\n編\n緣\n線\n緞\n緩\n綞\n緙\n緲\n緹\n罵\n罷\n羯\n翩\n耦\n膛\n膜\n膝\n膠\n膚\n膘\n蔗\n蔽\n蔚\n蓮\n蔬\n蔭\n蔓\n蔑\n蔣\n蔡\n蔔\n蓬\n蔥\n蓿\n蔆\n螂\n蝴\n蝶\n蝠\n蝦\n蝸\n蝨\n蝙\n蝗\n蝌\n蝓\n衛\n衝\n褐\n複\n褒\n褓\n褕\n褊\n誼\n諒\n談\n諄\n誕\n請\n諸\n課\n諉\n諂\n調\n誰\n論\n諍\n誶\n誹\n諛\n豌\n豎\n豬\n賠\n賞\n賦\n賤\n賬\n賭\n賢\n賣\n賜\n質\n賡\n赭\n趟\n趣\n踫\n踐\n踝\n踢\n踏\n踩\n踟\n踡\n踞\n躺\n輝\n輛\n輟\n輩\n輦\n輪\n輜\n輞\n輥\n適\n遮\n遨\n遭\n遷\n鄰\n鄭\n鄧\n鄱\n醇\n醉\n醋\n醃\n鋅\n銻\n銷\n鋪\n銬\n鋤\n鋁\n銳\n銼\n鋒\n鋇\n鋰\n銲\n閭\n閱\n霄\n霆\n震\n霉\n靠\n鞍\n鞋\n鞏\n頡\n頫\n頜\n颳\n養\n餓\n餒\n餘\n駝\n駐\n駟\n駛\n駑\n駕\n駒\n駙\n骷\n髮\n髯\n鬧\n魅\n魄\n魷\n魯\n鴆\n鴉\n鴃\n麩\n麾\n黎\n墨\n齒\n儒\n儘\n儔\n儐\n儕\n冀\n冪\n凝\n劑\n劓\n勳\n噙\n噫\n噹\n噩\n噤\n噸\n噪\n器\n噥\n噱\n噯\n噬\n噢\n噶\n壁\n墾\n壇\n壅\n奮\n嬝\n嬴\n學\n寰\n導\n彊\n憲\n憑\n憩\n憊\n懍\n憶\n憾\n懊\n懈\n戰\n擅\n擁\n擋\n撻\n撼\n據\n擄\n擇\n擂\n操\n撿\n擒\n擔\n撾\n整\n曆\n曉\n暹\n曄\n曇\n暸\n樽\n樸\n樺\n橙\n橫\n橘\n樹\n橄\n橢\n橡\n橋\n橇\n樵\n機\n橈\n歙\n歷\n氅\n濂\n澱\n澡\n濃\n澤\n濁\n澧\n澳\n激\n澹\n澶\n澦\n澠\n澴\n熾\n燉\n燐\n燒\n燈\n燕\n熹\n燎\n燙\n燜\n燃\n燄\n獨\n璜\n璣\n璘\n璟\n璞\n瓢\n甌\n甍\n瘴\n瘸\n瘺\n盧\n盥\n瞠\n瞞\n瞟\n瞥\n磨\n磚\n磬\n磧\n禦\n積\n穎\n穆\n穌\n穋\n窺\n篙\n簑\n築\n篤\n篛\n篡\n篩\n篦\n糕\n糖\n縊\n縑\n縈\n縛\n縣\n縞\n縝\n縉\n縐\n罹\n羲\n翰\n翱\n翮\n耨\n膳\n膩\n膨\n臻\n興\n艘\n艙\n蕊\n蕙\n蕈\n蕨\n蕩\n蕃\n蕉\n蕭\n蕪\n蕞\n螃\n螟\n螞\n螢\n融\n衡\n褪\n褲\n褥\n褫\n褡\n親\n覦\n諦\n諺\n諫\n諱\n謀\n諜\n諧\n諮\n諾\n謁\n謂\n諷\n諭\n諳\n諶\n諼\n豫\n豭\n貓\n賴\n蹄\n踱\n踴\n蹂\n踹\n踵\n輻\n輯\n輸\n輳\n辨\n辦\n遵\n遴\n選\n遲\n遼\n遺\n鄴\n醒\n錠\n錶\n鋸\n錳\n錯\n錢\n鋼\n錫\n錄\n錚\n錐\n錦\n錡\n錕\n錮\n錙\n閻\n隧\n隨\n險\n雕\n霎\n霑\n霖\n霍\n霓\n霏\n靛\n靜\n靦\n鞘\n頰\n頸\n頻\n頷\n頭\n頹\n頤\n餐\n館\n餞\n餛\n餡\n餚\n駭\n駢\n駱\n骸\n骼\n髻\n髭\n鬨\n鮑\n鴕\n鴣\n鴦\n鴨\n鴒\n鴛\n默\n黔\n龍\n龜\n優\n償\n儡\n儲\n勵\n嚎\n嚀\n嚐\n嚅\n嚇\n嚏\n壕\n壓\n壑\n壎\n嬰\n嬪\n嬤\n孺\n尷\n屨\n嶼\n嶺\n嶽\n嶸\n幫\n彌\n徽\n應\n懂\n懇\n懦\n懋\n戲\n戴\n擎\n擊\n擘\n擠\n擰\n擦\n擬\n擱\n擢\n擭\n斂\n斃\n曙\n曖\n檀\n檔\n檄\n檢\n檜\n櫛\n檣\n橾\n檗\n檐\n檠\n歜\n殮\n毚\n氈\n濘\n濱\n濟\n濠\n濛\n濤\n濫\n濯\n澀\n濬\n濡\n濩\n濕\n濮\n濰\n燧\n營\n燮\n燦\n燥\n燭\n燬\n燴\n燠\n爵\n牆\n獰\n獲\n璩\n環\n璦\n璨\n癆\n療\n癌\n盪\n瞳\n瞪\n瞰\n瞬\n瞧\n瞭\n矯\n磷\n磺\n磴\n磯\n礁\n禧\n禪\n穗\n窿\n簇\n簍\n篾\n篷\n簌\n篠\n糠\n糜\n糞\n糢\n糟\n糙\n糝\n縮\n績\n繆\n縷\n縲\n繃\n縫\n總\n縱\n繅\n繁\n縴\n縹\n繈\n縵\n縿\n縯\n罄\n翳\n翼\n聱\n聲\n聰\n聯\n聳\n臆\n臃\n膺\n臂\n臀\n膿\n膽\n臉\n膾\n臨\n舉\n艱\n薪\n薄\n蕾\n薜\n薑\n薔\n薯\n薛\n薇\n薨\n薊\n虧\n蟀\n蟑\n螳\n蟒\n蟆\n螫\n螻\n螺\n蟈\n蟋\n褻\n褶\n襄\n褸\n褽\n覬\n謎\n謗\n謙\n講\n謊\n謠\n謝\n謄\n謐\n豁\n谿\n豳\n賺\n賽\n購\n賸\n賻\n趨\n蹉\n蹋\n蹈\n蹊\n轄\n輾\n轂\n轅\n輿\n避\n遽\n還\n邁\n邂\n邀\n鄹\n醣\n醞\n醜\n鍍\n鎂\n錨\n鍵\n鍊\n鍥\n鍋\n錘\n鍾\n鍬\n鍛\n鍰\n鍚\n鍔\n闊\n闋\n闌\n闈\n闆\n隱\n隸\n雖\n霜\n霞\n鞠\n韓\n顆\n颶\n餵\n騁\n駿\n鮮\n鮫\n鮪\n鮭\n鴻\n鴿\n麋\n黏\n點\n黜\n黝\n黛\n鼾\n齋\n叢\n嚕\n嚮\n壙\n壘\n嬸\n彝\n懣\n戳\n擴\n擲\n擾\n攆\n擺\n擻\n擷\n斷\n曜\n朦\n檳\n檬\n櫃\n檻\n檸\n櫂\n檮\n檯\n歟\n歸\n殯\n瀉\n瀋\n濾\n瀆\n濺\n瀑\n瀏\n燻\n燼\n燾\n燸\n獷\n獵\n璧\n璿\n甕\n癖\n癘\n癒\n瞽\n瞿\n瞻\n瞼\n礎\n禮\n穡\n穢\n穠\n竄\n竅\n簫\n簧\n簪\n簞\n簣\n簡\n糧\n織\n繕\n繞\n繚\n繡\n繒\n繙\n罈\n翹\n翻\n職\n聶\n臍\n臏\n舊\n藏\n薩\n藍\n藐\n藉\n薰\n薺\n薹\n薦\n蟯\n蟬\n蟲\n蟠\n覆\n覲\n觴\n謨\n謹\n謬\n謫\n豐\n贅\n蹙\n蹣\n蹦\n蹤\n蹟\n蹕\n軀\n轉\n轍\n邇\n邃\n邈\n醫\n醬\n釐\n鎔\n鎊\n鎖\n鎢\n鎳\n鎮\n鎬\n鎰\n鎘\n鎚\n鎗\n闔\n闖\n闐\n闕\n離\n雜\n雙\n雛\n雞\n霤\n鞣\n鞦\n鞭\n韹\n額\n顏\n題\n顎\n顓\n颺\n餾\n餿\n餽\n餮\n馥\n騎\n髁\n鬃\n鬆\n魏\n魎\n魍\n鯊\n鯉\n鯽\n鯈\n鯀\n鵑\n鵝\n鵠\n黠\n鼕\n鼬\n儳\n嚥\n壞\n壟\n壢\n寵\n龐\n廬\n懲\n懷\n懶\n懵\n攀\n攏\n曠\n曝\n櫥\n櫝\n櫚\n櫓\n瀛\n瀟\n瀨\n瀚\n瀝\n瀕\n瀘\n爆\n爍\n牘\n犢\n獸\n獺\n璽\n瓊\n瓣\n疇\n疆\n癟\n癡\n矇\n礙\n禱\n穫\n穩\n簾\n簿\n簸\n簽\n簷\n籀\n繫\n繭\n繹\n繩\n繪\n羅\n繳\n羶\n羹\n羸\n臘\n藩\n藝\n藪\n藕\n藤\n藥\n藷\n蟻\n蠅\n蠍\n蟹\n蟾\n襠\n襟\n襖\n襞\n譁\n譜\n識\n證\n譚\n譎\n譏\n譆\n譙\n贈\n贊\n蹼\n蹲\n躇\n蹶\n蹬\n蹺\n蹴\n轔\n轎\n辭\n邊\n邋\n醱\n醮\n鏡\n鏑\n鏟\n鏃\n鏈\n鏜\n鏝\n鏖\n鏢\n鏍\n鏘\n鏤\n鏗\n鏨\n關\n隴\n難\n霪\n霧\n靡\n韜\n韻\n類\n願\n顛\n颼\n饅\n饉\n騖\n騙\n鬍\n鯨\n鯧\n鯖\n鯛\n鶉\n鵡\n鵲\n鵪\n鵬\n麒\n麗\n麓\n麴\n勸\n嚨\n嚷\n嚶\n嚴\n嚼\n壤\n孀\n孃\n孽\n寶\n巉\n懸\n懺\n攘\n攔\n攙\n曦\n朧\n櫬\n瀾\n瀰\n瀲\n爐\n獻\n瓏\n癢\n癥\n礦\n礪\n礬\n礫\n竇\n競\n籌\n籃\n籍\n糯\n糰\n辮\n繽\n繼\n纂\n罌\n耀\n臚\n艦\n藻\n藹\n蘑\n藺\n蘆\n蘋\n蘇\n蘊\n蠔\n蠕\n襤\n覺\n觸\n議\n譬\n警\n譯\n譟\n譫\n贏\n贍\n躉\n躁\n躅\n躂\n醴\n釋\n鐘\n鐃\n鏽\n闡\n霰\n飄\n饒\n饑\n馨\n騫\n騰\n騷\n騵\n鰓\n鰍\n鹹\n麵\n黨\n鼯\n齟\n齣\n齡\n儷\n儸\n囁\n囀\n囂\n夔\n屬\n巍\n懼\n懾\n攝\n攜\n斕\n曩\n櫻\n欄\n櫺\n殲\n灌\n爛\n犧\n瓖\n瓔\n癩\n矓\n籐\n纏\n續\n羼\n蘗\n蘭\n蘚\n蠣\n蠢\n蠡\n蠟\n襪\n襬\n覽\n譴\n護\n譽\n贓\n躊\n躍\n躋\n轟\n辯\n醺\n鐮\n鐳\n鐵\n鐺\n鐸\n鐲\n鐫\n闢\n霸\n霹\n露\n響\n顧\n顥\n饗\n驅\n驃\n驀\n騾\n髏\n魔\n魑\n鰭\n鰥\n鶯\n鶴\n鷂\n鶸\n麝\n黯\n鼙\n齜\n齦\n齧\n儼\n儻\n囈\n囊\n囉\n孿\n巔\n巒\n彎\n懿\n攤\n權\n歡\n灑\n灘\n玀\n瓤\n疊\n癮\n癬\n禳\n籠\n籟\n聾\n聽\n臟\n襲\n襯\n觼\n讀\n贖\n贗\n躑\n躓\n轡\n酈\n鑄\n鑑\n鑒\n霽\n霾\n韃\n韁\n顫\n饕\n驕\n驍\n髒\n鬚\n鱉\n鰱\n鰾\n鰻\n鷓\n鷗\n鼴\n齬\n齪\n龔\n囌\n巖\n戀\n攣\n攫\n攪\n曬\n欐\n瓚\n竊\n籤\n籣\n籥\n纓\n纖\n纔\n臢\n蘸\n蘿\n蠱\n變\n邐\n邏\n鑣\n鑠\n鑤\n靨\n顯\n饜\n驚\n驛\n驗\n髓\n體\n髑\n鱔\n鱗\n鱖\n鷥\n麟\n黴\n囑\n壩\n攬\n灞\n癱\n癲\n矗\n罐\n羈\n蠶\n蠹\n衢\n讓\n讒\n讖\n艷\n贛\n釀\n鑪\n靂\n靈\n靄\n韆\n顰\n驟\n鬢\n魘\n鱟\n鷹\n鷺\n鹼\n鹽\n鼇\n齷\n齲\n廳\n欖\n灣\n籬\n籮\n蠻\n觀\n躡\n釁\n鑲\n鑰\n顱\n饞\n髖\n鬣\n黌\n灤\n矚\n讚\n鑷\n韉\n驢\n驥\n纜\n讜\n躪\n釅\n鑽\n鑾\n鑼\n鱷\n鱸\n黷\n豔\n鑿\n鸚\n爨\n驪\n鬱\n鸛\n鸞\n籲\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n⑴\n⑵\n⑶\n⑷\n⑸\n⑹\n⑺\n⑻\n⑼\n⑽\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\n丶\n丿\n亅\n亠\n冂\n冖\n冫\n勹\n匸\n卩\n厶\n夊\n宀\n巛\n⼳\n广\n廴\n彐\n彡\n攴\n无\n疒\n癶\n辵\n隶\n¨\nˆ\nヽ\nヾ\nゝ\nゞ\n〃\n仝\n々\n〆\n〇\nー\n［\n］\n✽\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n⇧\n↸\n↹\n㇏\n𠃌\n乚\n𠂊\n刂\n䒑\n龰\n冈\n龱\n𧘇\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n￢\n￤\n＇\n＂\n㈱\n№\n℡\n゛\n゜\n⺀\n⺄\n⺆\n⺇\n⺈\n⺊\n⺌\n⺍\n⺕\n⺜\n⺝\n⺥\n⺧\n⺪\n⺬\n⺮\n⺶\n⺼\n⺾\n⻆\n⻊\n⻌\n⻍\n⻏\n⻖\n⻗\n⻞\n⻣\n�\n�\n�\nʃ\nɐ\nɛ\nɔ\nɵ\nœ\nø\nŋ\nʊ\nɪ\n乂\n乜\n凵\n匚\n厂\n万\n丌\n乇\n亍\n囗\n兀\n屮\n彳\n丏\n冇\n与\n丮\n亓\n仂\n仉\n仈\n冘\n勼\n卬\n厹\n圠\n夃\n夬\n尐\n巿\n旡\n殳\n毌\n气\n爿\n丱\n丼\n仨\n仜\n仩\n仡\n仝\n仚\n刌\n匜\n卌\n圢\n圣\n夗\n夯\n宁\n宄\n尒\n尻\n屴\n屳\n帄\n庀\n庂\n忉\n戉\n扐\n氕\n氶\n汃\n氿\n氻\n犮\n犰\n玊\n禸\n肊\n阞\n伎\n优\n伬\n仵\n伔\n仱\n伀\n价\n伈\n伝\n伂\n伅\n伢\n伓\n伄\n仴\n伒\n冱\n刓\n刉\n刐\n劦\n匢\n匟\n卍\n厊\n吇\n囡\n囟\n圮\n圪\n圴\n夼\n妀\n奼\n妅\n奻\n奾\n奷\n奿\n孖\n尕\n尥\n屼\n屺\n屻\n屾\n巟\n幵\n庄\n异\n弚\n彴\n忕\n忔\n忏\n扜\n扞\n扤\n扡\n扦\n扢\n扙\n扠\n扚\n扥\n旯\n旮\n朾\n朹\n朸\n朻\n机\n朿\n朼\n朳\n氘\n汆\n汒\n汜\n汏\n汊\n汔\n汋\n汌\n灱\n牞\n犴\n犵\n玎\n甪\n癿\n穵\n网\n艸\n艼\n芀\n艽\n艿\n虍\n襾\n邙\n邗\n邘\n邛\n邔\n阢\n阤\n阠\n阣\n佖\n伻\n佢\n佉\n体\n佤\n伾\n佧\n佒\n佟\n佁\n佘\n伭\n伳\n伿\n佡\n冏\n冹\n刜\n刞\n刡\n劭\n劮\n匉\n卣\n卲\n厎\n厏\n吰\n吷\n吪\n呔\n呅\n吙\n吜\n吥\n吘\n吽\n呏\n呁\n吨\n吤\n呇\n囮\n囧\n囥\n坁\n坅\n坌\n坉\n坋\n坒\n夆\n奀\n妦\n妘\n妠\n妗\n妎\n妢\n妐\n妏\n妧\n妡\n宎\n宒\n尨\n尪\n岍\n岏\n岈\n岋\n岉\n岒\n岊\n岆\n岓\n岕\n巠\n帊\n帎\n庋\n庉\n庌\n庈\n庍\n弅\n弝\n彸\n彶\n忒\n忑\n忐\n忭\n忨\n忮\n忳\n忡\n忤\n忣\n忺\n忯\n忷\n忻\n怀\n忴\n戺\n抃\n抌\n抎\n抏\n抔\n抇\n扱\n扻\n扺\n扰\n抁\n抈\n扷\n扽\n扲\n扴\n攷\n旰\n旴\n旳\n旲\n旵\n杅\n杇\n杙\n杕\n杌\n杈\n杝\n杍\n杚\n杋\n毐\n氙\n氚\n汸\n汧\n汫\n沄\n沋\n沏\n汱\n汯\n汩\n沚\n汭\n沇\n沕\n沜\n汦\n汳\n汥\n汻\n沎\n灴\n灺\n牣\n犿\n犽\n狃\n狆\n狁\n犺\n狅\n玕\n玗\n玓\n玔\n玒\n町\n甹\n疔\n疕\n皁\n礽\n耴\n肕\n肙\n肐\n肒\n肜\n芐\n芏\n芅\n芎\n芑\n芓\n芊\n芃\n芄\n豸\n迉\n辿\n邟\n邡\n邥\n邞\n邧\n邠\n阰\n阨\n阯\n阭\n丳\n侘\n佼\n侅\n佽\n侀\n侇\n佶\n佴\n侉\n侄\n佷\n佌\n侗\n佪\n侚\n佹\n侁\n佸\n侐\n侜\n侔\n侞\n侒\n侂\n侕\n佫\n佮\n冞\n冼\n冾\n刵\n刲\n刳\n剆\n刱\n劼\n匊\n匋\n匼\n厒\n厔\n咇\n呿\n咁\n咑\n咂\n咈\n呫\n呺\n呾\n呥\n呬\n呴\n呦\n咍\n呯\n呡\n呠\n咘\n呣\n呧\n呤\n囷\n囹\n坯\n坲\n坭\n坫\n坱\n坰\n坶\n垀\n坵\n坻\n坳\n坴\n坢\n坨\n坽\n夌\n奅\n妵\n妺\n姏\n姎\n妲\n姌\n姁\n妶\n妼\n姃\n姖\n妱\n妽\n姀\n姈\n妴\n姇\n孢\n孥\n宓\n宕\n屄\n屇\n岮\n岤\n岠\n岵\n岯\n岨\n岬\n岟\n岣\n岭\n岢\n岪\n岧\n岝\n岥\n岶\n岰\n岦\n帗\n帔\n帙\n弨\n弢\n弣\n弤\n彔\n徂\n彾\n彽\n忞\n忥\n怭\n怦\n怙\n怲\n怋\n怴\n怊\n怗\n怳\n怚\n怞\n怬\n怢\n怍\n怐\n怮\n怓\n怑\n怌\n怉\n怜\n戔\n戽\n抭\n抴\n拑\n抾\n抪\n抶\n拊\n抮\n抳\n抯\n抻\n抩\n抰\n抸\n攽\n斨\n斻\n昉\n旼\n昄\n昒\n昈\n旻\n昃\n昋\n昍\n昅\n旽\n昑\n昐\n曶\n朊\n枅\n杬\n枎\n枒\n杶\n杻\n枘\n枆\n构\n杴\n枍\n枌\n杺\n枟\n枑\n枙\n枃\n杽\n极\n杸\n杹\n枔\n欥\n殀\n歾\n毞\n氝\n沓\n泬\n泫\n泮\n泙\n沶\n泔\n沭\n泧\n沷\n泐\n泂\n沺\n泃\n泆\n泭\n泲\n泒\n泝\n沴\n沊\n沝\n沀\n泞\n泀\n洰\n泍\n泇\n沰\n泹\n泏\n泩\n泑\n炔\n炘\n炅\n炓\n炆\n炄\n炑\n炖\n炂\n炚\n炃\n牪\n狖\n狋\n狘\n狉\n狜\n狒\n狔\n狚\n狌\n狑\n玤\n玡\n玭\n玦\n玢\n玠\n玬\n玝\n瓝\n瓨\n甿\n畀\n甾\n疌\n疘\n皯\n盳\n盱\n盰\n盵\n矸\n矼\n矹\n矻\n矺\n矷\n祂\n礿\n秅\n穸\n穻\n竻\n籵\n糽\n耵\n肏\n肮\n肣\n肸\n肵\n肭\n舠\n芠\n苀\n芫\n芚\n芘\n芛\n芵\n芧\n芮\n芼\n芞\n芺\n芴\n芨\n芡\n芩\n苂\n芤\n苃\n芶\n芢\n虰\n虯\n虭\n虮\n豖\n迒\n迋\n迓\n迍\n迖\n迕\n迗\n邲\n邴\n邯\n邳\n邰\n阹\n阽\n阼\n阺\n陃\n俍\n俅\n俓\n侲\n俉\n俋\n俁\n俔\n俜\n俙\n侻\n侳\n俛\n俇\n俖\n侺\n俀\n侹\n俬\n剄\n剉\n勀\n勂\n匽\n卼\n厗\n厖\n厙\n厘\n咺\n咡\n咭\n咥\n哏\n哃\n茍\n咷\n咮\n哖\n咶\n哅\n哆\n咠\n呰\n咼\n咢\n咾\n呲\n哞\n咰\n垵\n垞\n垟\n垤\n垌\n垗\n垝\n垛\n垔\n垘\n垏\n垙\n垥\n垚\n垕\n壴\n复\n奓\n姡\n姞\n姮\n娀\n姱\n姝\n姺\n姽\n姼\n姶\n姤\n姲\n姷\n姛\n姩\n姳\n姵\n姠\n姾\n姴\n姭\n宨\n屌\n峐\n峘\n峌\n峗\n峋\n峛\n峞\n峚\n峉\n峇\n峊\n峖\n峓\n峔\n峏\n峈\n峆\n峎\n峟\n峸\n巹\n帡\n帢\n帣\n帠\n帤\n庰\n庤\n庢\n庛\n庣\n庥\n弇\n弮\n彖\n徆\n怷\n怹\n恔\n恲\n恞\n恅\n恓\n恇\n恉\n恛\n恌\n恀\n恂\n恟\n怤\n恄\n恘\n恦\n恮\n扂\n扃\n拏\n挍\n挋\n拵\n挎\n挃\n拫\n拹\n挏\n挌\n拸\n拶\n挀\n挓\n挔\n拺\n挕\n拻\n拰\n敁\n敃\n斪\n斿\n昶\n昡\n昲\n昵\n昜\n昦\n昢\n昳\n昫\n昺\n昝\n昴\n昹\n昮\n朏\n朐\n柁\n柲\n柈\n枺\n柜\n枻\n柸\n柘\n柀\n枷\n柅\n柫\n柤\n柟\n枵\n柍\n枳\n柷\n柶\n柮\n柣\n柂\n枹\n柎\n柧\n柰\n枲\n柼\n柆\n柭\n柌\n枮\n柦\n柛\n柺\n柉\n柊\n柃\n柪\n柋\n欨\n殂\n殄\n殶\n毖\n毘\n毠\n氠\n氡\n洨\n洴\n洭\n洟\n洼\n洿\n洒\n洊\n泚\n洳\n洄\n洙\n洺\n洚\n洑\n洀\n洝\n浂\n洁\n洘\n洷\n洃\n洏\n浀\n洇\n洠\n洬\n洈\n洢\n洉\n洐\n炷\n炟\n炾\n炱\n炰\n炡\n炴\n炵\n炩\n牁\n牉\n牊\n牬\n牰\n牳\n牮\n狊\n狤\n狨\n狫\n狟\n狪\n狦\n狣\n玅\n珌\n珂\n珈\n珅\n玹\n玶\n玵\n玴\n珫\n玿\n珇\n玾\n珃\n珆\n玸\n珋\n瓬\n瓮\n甮\n畇\n畈\n疧\n疪\n癹\n盄\n眈\n眃\n眄\n眅\n眊\n盷\n盻\n盺\n矧\n矨\n砆\n砑\n砒\n砅\n砐\n砏\n砎\n砉\n砃\n砓\n祊\n祌\n祋\n祅\n祄\n秕\n种\n秏\n秖\n秎\n窀\n穾\n竑\n笀\n笁\n籺\n籸\n籹\n籿\n粀\n粁\n紃\n紈\n紁\n罘\n羑\n羍\n羾\n耇\n耎\n耏\n耔\n耷\n胘\n胇\n胠\n胑\n胈\n胂\n胐\n胅\n胣\n胙\n胜\n胊\n胕\n胉\n胏\n胗\n胦\n胍\n臿\n舡\n芔\n苙\n苾\n苹\n茇\n苨\n茀\n苕\n茺\n苫\n苖\n苴\n苬\n苡\n苲\n苵\n茌\n苻\n苶\n苰\n苪\n苤\n苠\n苺\n苳\n苭\n虷\n虴\n虼\n虳\n衁\n衎\n衧\n衪\n衩\n觓\n訄\n訇\n赲\n迣\n迡\n迮\n迠\n郱\n邽\n邿\n郕\n郅\n邾\n郇\n郋\n郈\n釔\n釓\n陔\n陏\n陑\n陓\n陊\n陎\n倞\n倅\n倇\n倓\n倢\n倰\n倛\n俵\n俴\n倳\n倷\n倬\n俶\n俷\n倗\n倜\n倠\n倧\n倵\n倯\n倱\n倎\n党\n冔\n冓\n凊\n凄\n凅\n凈\n凎\n剡\n剚\n剒\n剞\n剟\n剕\n剢\n勍\n匎\n厞\n唦\n哢\n唗\n唒\n哧\n哳\n哤\n唚\n哿\n唄\n唈\n哫\n唑\n唅\n哱\n唊\n哻\n哷\n哸\n哠\n唎\n唃\n唋\n圁\n圂\n埌\n堲\n埕\n埒\n垺\n埆\n垽\n垼\n垸\n垶\n垿\n埇\n埐\n垹\n埁\n夎\n奊\n娙\n娖\n娭\n娮\n娕\n娏\n娗\n娊\n娞\n娳\n孬\n宧\n宭\n宬\n尃\n屖\n屔\n峬\n峿\n峮\n峱\n峷\n崀\n峹\n帩\n帨\n庨\n庮\n庪\n庬\n弳\n弰\n彧\n恝\n恚\n恧\n恁\n悢\n悈\n悀\n悒\n悁\n悝\n悃\n悕\n悛\n悗\n悇\n悜\n悎\n戙\n扆\n拲\n挐\n捖\n挬\n捄\n捅\n挶\n捃\n揤\n挹\n捋\n捊\n挼\n挩\n捁\n挴\n捘\n捔\n捙\n挭\n捇\n挳\n捚\n捑\n挸\n捗\n捀\n捈\n敊\n敆\n旆\n旃\n旄\n旂\n晊\n晟\n晇\n晑\n朒\n朓\n栟\n栚\n桉\n栲\n栳\n栻\n桋\n桏\n栖\n栱\n栜\n栵\n栫\n栭\n栯\n桎\n桄\n栴\n栝\n栒\n栔\n栦\n栨\n栮\n桍\n栺\n栥\n栠\n欬\n欯\n欭\n欱\n欴\n歭\n肂\n殈\n毦\n毤\n毨\n毣\n毢\n毧\n氥\n浺\n浣\n浤\n浶\n洍\n浡\n涒\n浘\n浢\n浭\n浯\n涑\n涍\n淯\n浿\n涆\n浞\n浧\n浠\n涗\n浰\n浼\n浟\n涂\n涘\n洯\n浨\n涋\n浾\n涀\n涄\n洖\n涃\n浻\n浽\n浵\n涐\n烜\n烓\n烑\n烝\n烋\n缹\n烢\n烗\n烒\n烞\n烠\n烔\n烍\n烅\n烆\n烇\n烚\n烎\n烡\n牂\n牸\n牷\n牶\n猀\n狺\n狴\n狾\n狶\n狳\n狻\n猁\n珓\n珙\n珥\n珖\n玼\n珧\n珣\n珩\n珜\n珒\n珛\n珔\n珝\n珚\n珗\n珘\n珨\n瓞\n瓟\n瓴\n瓵\n甡\n畛\n畟\n疰\n痁\n疻\n痄\n痀\n疿\n疶\n疺\n皊\n盉\n眝\n眛\n眐\n眓\n眒\n眣\n眑\n眕\n眙\n眚\n眢\n眧\n砣\n砬\n砢\n砵\n砯\n砨\n砮\n砫\n砡\n砩\n砳\n砪\n砱\n祔\n祛\n祏\n祜\n祓\n祒\n祑\n秫\n秬\n秠\n秮\n秭\n秪\n秜\n秞\n秝\n窆\n窉\n窅\n窋\n窌\n窊\n窇\n竘\n笐\n笄\n笓\n笅\n笏\n笈\n笊\n笎\n笉\n笒\n粄\n粑\n粊\n粌\n粈\n粍\n粅\n紞\n紝\n紑\n紎\n紘\n紖\n紓\n紟\n紒\n紏\n紌\n罜\n罡\n罞\n罠\n罝\n罛\n羖\n羒\n翃\n翂\n翀\n耖\n耾\n耹\n胺\n胲\n胹\n胵\n脁\n胻\n脀\n舁\n舯\n舥\n茳\n茭\n荄\n茙\n荑\n茥\n荖\n茿\n荁\n茦\n茜\n茢\n荂\n荎\n茛\n茪\n茈\n茼\n荍\n茖\n茤\n茠\n茷\n茯\n茩\n荇\n荅\n荌\n荓\n茞\n茬\n荋\n茧\n荈\n虓\n虒\n蚢\n蚨\n蚖\n蚍\n蚑\n蚞\n蚇\n蚗\n蚆\n蚋\n蚚\n蚅\n蚥\n蚙\n蚡\n蚧\n蚕\n蚘\n蚎\n蚝\n蚐\n蚔\n衃\n衄\n衭\n衵\n衶\n衲\n袀\n衱\n衿\n衯\n袃\n衾\n衴\n衼\n訒\n豇\n豗\n豻\n貤\n貣\n赶\n赸\n趵\n趷\n趶\n軑\n軓\n迾\n迵\n适\n迿\n迻\n逄\n迼\n迶\n郖\n郠\n郙\n郚\n郣\n郟\n郥\n郘\n郛\n郗\n郜\n郤\n酐\n酎\n酏\n釕\n釢\n釚\n陜\n陟\n隼\n飣\n髟\n鬯\n乿\n偰\n偪\n偡\n偞\n偠\n偓\n偋\n偝\n偲\n偈\n偍\n偁\n偛\n偊\n偢\n倕\n偅\n偟\n偩\n偫\n偣\n偤\n偆\n偀\n偮\n偳\n偗\n偑\n凐\n剫\n剭\n剬\n剮\n勖\n勓\n匭\n厜\n啵\n啶\n唼\n啍\n啐\n唴\n唪\n啑\n啢\n唶\n唵\n唰\n啒\n啅\n唌\n唲\n啥\n啎\n唹\n啈\n唭\n唻\n啀\n啋\n圊\n圇\n埻\n堔\n埢\n埶\n埜\n埴\n堀\n埭\n埽\n堈\n埸\n堋\n埳\n埏\n堇\n埮\n埣\n埲\n埥\n埬\n埡\n堎\n埼\n堐\n埧\n堁\n堌\n埱\n埩\n埰\n堍\n堄\n奜\n婠\n婘\n婕\n婧\n婞\n娸\n娵\n婭\n婐\n婟\n婥\n婬\n婓\n婤\n婗\n婃\n婝\n婒\n婄\n婛\n婈\n媎\n娾\n婍\n娹\n婌\n婰\n婩\n婇\n婑\n婖\n婂\n婜\n孲\n孮\n寁\n寀\n屙\n崞\n崋\n崝\n崚\n崠\n崌\n崨\n崍\n崦\n崥\n崏\n崰\n崒\n崣\n崟\n崮\n帾\n帴\n庱\n庴\n庹\n庲\n庳\n弶\n弸\n徛\n徖\n徟\n悊\n悐\n悆\n悾\n悰\n悺\n惓\n惔\n惏\n惤\n惙\n惝\n惈\n悱\n惛\n悷\n惊\n悿\n惃\n惍\n惀\n挲\n捥\n掊\n掂\n捽\n掽\n掞\n掭\n掝\n掗\n掫\n掎\n捯\n掇\n掐\n据\n掯\n捵\n掜\n捭\n掮\n捼\n掤\n挻\n掟\n捸\n掅\n掁\n掑\n掍\n捰\n敓\n旍\n晥\n晡\n晛\n晙\n晜\n晢\n朘\n桹\n梇\n梐\n梜\n桭\n桮\n梮\n梫\n楖\n桯\n梣\n梬\n梩\n桵\n桴\n梲\n梏\n桷\n梒\n桼\n桫\n桲\n梪\n梀\n桱\n桾\n梛\n梖\n梋\n梠\n梉\n梤\n桸\n桻\n梑\n梌\n梊\n桽\n欶\n欳\n欷\n欸\n殑\n殏\n殍\n殎\n殌\n氪\n淀\n涫\n涴\n涳\n湴\n涬\n淩\n淢\n涷\n淶\n淔\n渀\n淈\n淠\n淟\n淖\n涾\n淥\n淜\n淝\n淛\n淴\n淊\n涽\n淭\n淰\n涺\n淕\n淂\n淏\n淉\n淐\n淲\n淓\n淽\n淗\n淍\n淣\n涻\n烺\n焍\n烷\n焗\n烴\n焌\n烰\n焄\n烳\n焐\n烼\n烿\n焆\n焓\n焀\n烸\n烶\n焋\n焂\n焎\n牾\n牻\n牼\n牿\n猝\n猗\n猇\n猑\n猘\n猊\n猈\n狿\n猏\n猞\n玈\n珶\n珸\n珵\n琄\n琁\n珽\n琇\n琀\n珺\n珼\n珿\n琌\n琋\n珴\n琈\n畤\n畣\n痎\n痒\n痏\n痋\n痌\n痑\n痐\n皏\n皉\n盓\n眹\n眯\n眭\n眱\n眲\n眴\n眳\n眽\n眥\n眻\n眵\n硈\n硒\n硉\n硍\n硊\n硌\n砦\n硅\n硐\n祤\n祧\n祩\n祪\n祣\n祫\n祡\n离\n秺\n秸\n秶\n秷\n窏\n窔\n窐\n笵\n筇\n笴\n笥\n笰\n笢\n笤\n笳\n笘\n笪\n笝\n笱\n笫\n笭\n笯\n笲\n笸\n笚\n笣\n粔\n粘\n粖\n粣\n紵\n紽\n紸\n紶\n紺\n絅\n紬\n紩\n絁\n絇\n紾\n紿\n絊\n紻\n紨\n罣\n羕\n羜\n羝\n羛\n翊\n翋\n翍\n翐\n翑\n翇\n翏\n翉\n耟\n耞\n耛\n聇\n聃\n聈\n脘\n脥\n脙\n脛\n脭\n脟\n脬\n脞\n脡\n脕\n脧\n脝\n脢\n舑\n舸\n舳\n舺\n舴\n舲\n艴\n莐\n莣\n莨\n莍\n荺\n荳\n莤\n荴\n莏\n莁\n莕\n莙\n荵\n莔\n莩\n荽\n莃\n莌\n莝\n莛\n莪\n莋\n荾\n莥\n莯\n莈\n莗\n莰\n荿\n莦\n莇\n莮\n荶\n莚\n虙\n虖\n蚿\n蚷\n蛂\n蛁\n蛅\n蚺\n蚰\n蛈\n蚹\n蚳\n蚸\n蛌\n蚴\n蚻\n蚼\n蛃\n蚽\n蚾\n衒\n袉\n袕\n袨\n袢\n袪\n袚\n袑\n袡\n袟\n袘\n袧\n袙\n袛\n袗\n袤\n袬\n袌\n袓\n袎\n覂\n觖\n觙\n觕\n訰\n訧\n訬\n訞\n谹\n谻\n豜\n豝\n豽\n貥\n赽\n赻\n赹\n趼\n跂\n趹\n趿\n跁\n軘\n軞\n軝\n軜\n軗\n軠\n軡\n逤\n逋\n逑\n逜\n逌\n逡\n郯\n郪\n郰\n郴\n郲\n郳\n郔\n郫\n郬\n郩\n酖\n酘\n酚\n酓\n酕\n釬\n釴\n釱\n釳\n釸\n釤\n釹\n釪\n釫\n釷\n釨\n釮\n镺\n閆\n閈\n陼\n陭\n陫\n陱\n陯\n隿\n靪\n頄\n飥\n馗\n傛\n傕\n傔\n傞\n傋\n傣\n傃\n傌\n傎\n傝\n偨\n傜\n傒\n傂\n傇\n兟\n凔\n匒\n匑\n厤\n厧\n喑\n喨\n喥\n喭\n啷\n噅\n喢\n喓\n喈\n喏\n喵\n喁\n喣\n喒\n喤\n啽\n喌\n喦\n啿\n喕\n喡\n喎\n圌\n堩\n堷\n堙\n堞\n堧\n堣\n堨\n埵\n塈\n堥\n堜\n堛\n堳\n堿\n堶\n堮\n堹\n堸\n堭\n堬\n堻\n奡\n媯\n媔\n媟\n婺\n媢\n媞\n婸\n媦\n婼\n媥\n媬\n媕\n媮\n娷\n媄\n媊\n媗\n媃\n媋\n媩\n婻\n婽\n媌\n媜\n媏\n媓\n媝\n寪\n寍\n寋\n寔\n寑\n寊\n寎\n尌\n尰\n崷\n嵃\n嵫\n嵁\n嵋\n崿\n崵\n嵑\n嵎\n嵕\n崳\n崺\n嵒\n崽\n崱\n嵙\n嵂\n崹\n嵉\n崸\n崼\n崲\n崶\n嵀\n嵅\n幄\n幁\n彘\n徦\n徥\n徫\n惉\n悹\n惌\n惢\n惎\n惄\n愔\n惲\n愊\n愖\n愅\n惵\n愓\n惸\n惼\n惾\n惁\n愃\n愘\n愝\n愐\n惿\n愄\n愋\n扊\n掔\n掱\n掰\n揎\n揥\n揨\n揯\n揃\n撝\n揳\n揊\n揠\n揶\n揕\n揲\n揵\n摡\n揟\n掾\n揝\n揜\n揄\n揘\n揓\n揂\n揇\n揌\n揋\n揈\n揰\n揗\n揙\n攲\n敧\n敪\n敤\n敜\n敨\n敥\n斌\n斝\n斞\n斮\n旐\n旒\n晼\n晬\n晻\n暀\n晱\n晹\n晪\n晲\n朁\n椌\n棓\n椄\n棜\n椪\n棬\n棪\n棱\n椏\n棖\n棷\n棫\n棤\n棶\n椓\n椐\n棳\n棡\n椇\n棌\n椈\n楰\n梴\n椑\n棯\n棆\n椔\n棸\n棐\n棽\n棼\n棨\n椋\n椊\n椗\n棎\n棈\n棝\n棞\n棦\n棴\n棑\n椆\n棔\n棩\n椕\n椥\n棇\n欹\n欻\n欿\n欼\n殔\n殗\n殙\n殕\n殽\n毰\n毲\n毳\n氰\n淼\n湆\n湇\n渟\n湉\n溈\n渼\n渽\n湅\n湢\n渫\n渿\n湁\n湝\n湳\n渜\n渳\n湋\n湀\n湑\n渻\n渃\n渮\n湞\n湨\n湜\n湡\n渱\n渨\n湠\n湱\n湫\n渹\n渢\n渰\n湓\n湥\n渧\n湸\n湤\n湷\n湕\n湹\n湒\n湦\n渵\n渶\n湚\n焠\n焞\n焯\n烻\n焮\n焱\n焣\n焥\n焢\n焲\n焟\n焨\n焺\n焛\n牋\n牚\n犈\n犉\n犆\n犅\n犋\n猒\n猋\n猰\n猢\n猱\n猳\n猧\n猲\n猭\n猦\n猣\n猵\n猌\n琮\n琬\n琰\n琫\n琖\n琚\n琡\n琭\n琱\n琤\n琣\n琝\n琩\n琠\n琲\n瓻\n甯\n畯\n畬\n痧\n痚\n痡\n痦\n痝\n痟\n痤\n痗\n皕\n皒\n盚\n睆\n睇\n睄\n睍\n睅\n睊\n睎\n睋\n睌\n矞\n矬\n硠\n硤\n硥\n硜\n硭\n硱\n硪\n确\n硰\n硩\n硨\n硞\n硢\n祴\n祳\n祲\n祰\n稂\n稊\n稃\n稌\n稄\n窙\n竦\n竤\n筊\n笻\n筄\n筈\n筌\n筎\n筀\n筘\n筅\n粢\n粞\n粨\n粡\n絘\n絯\n絣\n絓\n絖\n絧\n絪\n絏\n絭\n絜\n絫\n絒\n絔\n絩\n絑\n絟\n絎\n缾\n缿\n罥\n罦\n羢\n羠\n羡\n翗\n聑\n聏\n聐\n胾\n胔\n腃\n腊\n腒\n腏\n腇\n脽\n腍\n脺\n臦\n臮\n臷\n臸\n臹\n舄\n舼\n舽\n舿\n艵\n茻\n菏\n菹\n萣\n菀\n菨\n萒\n菧\n菤\n菼\n菶\n萐\n菆\n菈\n菫\n菣\n莿\n萁\n菝\n菥\n菘\n菿\n菡\n菋\n菎\n菖\n菵\n菉\n萉\n萏\n菞\n萑\n萆\n菂\n菳\n菕\n菺\n菇\n菑\n菪\n萓\n菃\n菬\n菮\n菄\n菻\n菗\n菢\n萛\n菛\n菾\n蛘\n蛢\n蛦\n蛓\n蛣\n蛚\n蛪\n蛝\n蛫\n蛜\n蛬\n蛩\n蛗\n蛨\n蛑\n衈\n衖\n衕\n袺\n裗\n袹\n袸\n裀\n袾\n袶\n袼\n袷\n袽\n袲\n褁\n裉\n覕\n覘\n覗\n觝\n觚\n觛\n詎\n詍\n訹\n詙\n詀\n詗\n詘\n詄\n詅\n詒\n詈\n詑\n詊\n詌\n詏\n豟\n貁\n貀\n貺\n貾\n貰\n貹\n貵\n趄\n趀\n趉\n跘\n跓\n跍\n跇\n跖\n跜\n跏\n跕\n跙\n跈\n跗\n跅\n軯\n軷\n軺\n軹\n軦\n軮\n軥\n軵\n軧\n軨\n軶\n軫\n軱\n軬\n軴\n軩\n逭\n逴\n逯\n鄆\n鄬\n鄄\n郿\n郼\n鄈\n郹\n郻\n鄁\n鄀\n鄇\n鄅\n鄃\n酡\n酤\n酟\n酢\n酠\n鈁\n鈊\n鈥\n鈃\n鈚\n鈦\n鈏\n鈌\n鈀\n鈒\n釿\n釽\n鈆\n鈄\n鈧\n鈂\n鈜\n鈤\n鈙\n鈗\n鈅\n鈖\n镻\n閍\n閌\n閐\n隇\n陾\n隈\n隉\n隃\n隀\n雂\n雈\n雃\n雱\n雰\n靬\n靰\n靮\n頇\n颩\n飫\n鳦\n黹\n亃\n亄\n亶\n傽\n傿\n僆\n傮\n僄\n僊\n傴\n僈\n僂\n傰\n僁\n傺\n傱\n僋\n僉\n傶\n傸\n凗\n剺\n剸\n剻\n剼\n嗃\n嗛\n嗌\n嗐\n嗋\n嗊\n嗝\n嗀\n嗔\n嗄\n嗩\n喿\n嗒\n喍\n嗏\n嗕\n嗢\n嗖\n嗈\n嗲\n嗍\n嗙\n嗂\n圔\n塓\n塨\n塤\n塏\n塍\n塉\n塯\n塕\n塎\n塝\n塙\n塥\n塛\n堽\n塣\n塱\n壼\n嫇\n嫄\n嫋\n媺\n媸\n媱\n媵\n媰\n媿\n嫈\n媻\n嫆\n媷\n嫀\n嫊\n媴\n媶\n嫍\n媹\n媐\n寖\n寘\n寙\n尟\n尳\n嵱\n嵣\n嵊\n嵥\n嵲\n嵬\n嵞\n嵨\n嵧\n嵢\n巰\n幏\n幎\n幊\n幍\n幋\n廅\n廌\n廆\n廋\n廇\n彀\n徯\n徭\n惷\n慉\n慊\n愫\n慅\n愶\n愲\n愮\n慆\n愯\n慏\n愩\n慀\n戠\n酨\n戣\n戥\n戤\n揅\n揱\n揫\n搐\n搒\n搉\n搠\n搤\n搳\n摃\n搟\n搕\n搘\n搹\n搷\n搢\n搣\n搌\n搦\n搰\n搨\n摁\n搵\n搯\n搊\n搚\n摀\n搥\n搧\n搋\n揧\n搛\n搮\n搡\n搎\n敯\n斒\n旓\n暆\n暌\n暕\n暐\n暋\n暊\n暙\n暔\n晸\n朠\n楦\n楟\n椸\n楎\n楢\n楱\n椿\n楅\n楪\n椹\n楂\n楗\n楙\n楺\n楈\n楉\n椵\n楬\n椳\n椽\n楥\n棰\n楸\n椴\n楩\n楀\n楯\n楄\n楶\n楘\n楁\n楴\n楌\n椻\n楋\n椷\n楜\n楏\n楑\n椲\n楒\n椯\n楻\n椼\n歆\n歅\n歃\n歂\n歈\n歁\n殛\n嗀\n毻\n毼\n毹\n毷\n毸\n溛\n滖\n滈\n溏\n滀\n溟\n溓\n溔\n溠\n溱\n溹\n滆\n滒\n溽\n滁\n溞\n滉\n溷\n溰\n滍\n溦\n滏\n溲\n溾\n滃\n滜\n滘\n溙\n溒\n溎\n溍\n溤\n溡\n溿\n溳\n滐\n滊\n溗\n溮\n溣\n煇\n煔\n煒\n煣\n煠\n煁\n煝\n煢\n煲\n煸\n煪\n煡\n煂\n煘\n煃\n煋\n煰\n煟\n煐\n煓\n煄\n煍\n煚\n牏\n犍\n犌\n犑\n犐\n犎\n猼\n獂\n猻\n猺\n獀\n獊\n獉\n瑄\n瑊\n瑋\n瑒\n瑑\n瑗\n瑀\n瑏\n瑐\n瑎\n瑂\n瑆\n瑍\n瑔\n瓡\n瓿\n瓾\n瓽\n甝\n畹\n畷\n榃\n痯\n瘏\n瘃\n痷\n痾\n痼\n痹\n痸\n瘐\n痻\n痶\n痭\n痵\n痽\n皙\n皵\n盝\n睕\n睟\n睠\n睒\n睖\n睚\n睩\n睧\n睔\n睙\n睭\n矠\n碇\n碚\n碔\n碏\n碄\n碕\n碅\n碆\n碡\n碃\n硹\n碙\n碀\n碖\n硻\n祼\n禂\n祽\n祹\n稑\n稘\n稙\n稒\n稗\n稕\n稢\n稓\n稛\n稐\n窣\n窢\n窞\n竫\n筦\n筤\n筭\n筴\n筩\n筲\n筥\n筳\n筱\n筰\n筡\n筸\n筶\n筣\n粲\n粴\n粯\n綈\n綆\n綀\n綍\n絿\n綅\n絺\n綎\n絻\n綃\n絼\n綌\n綔\n綄\n絽\n綒\n罭\n罫\n罧\n罨\n罬\n羦\n羥\n羧\n翛\n翜\n耡\n腤\n腠\n腷\n腜\n腩\n腛\n腢\n腲\n朡\n腞\n腶\n腧\n腯\n腄\n腡\n舝\n艉\n艄\n艀\n艂\n艅\n蓱\n萿\n葖\n葶\n葹\n蒏\n蒍\n葥\n葑\n葀\n蒆\n葧\n萰\n葍\n葽\n葚\n葙\n葴\n葳\n葝\n蔇\n葞\n萷\n萺\n萴\n葺\n葃\n葸\n萲\n葅\n萩\n菙\n葋\n萯\n葂\n萭\n葟\n葰\n萹\n葎\n葌\n葒\n葯\n蓅\n蒎\n萻\n葇\n萶\n萳\n葨\n葾\n葄\n萫\n葠\n葔\n葮\n葐\n蜋\n蜄\n蛷\n蜌\n蛺\n蛖\n蛵\n蝍\n蛸\n蜎\n蜉\n蜁\n蛶\n蜍\n蜅\n裖\n裋\n裍\n裎\n裞\n裛\n裚\n裌\n裐\n覅\n覛\n觟\n觥\n觤\n觡\n觠\n觢\n觜\n触\n詶\n誆\n詿\n詡\n訿\n詷\n誂\n誄\n詵\n誃\n誁\n詴\n詺\n谼\n豋\n豊\n豥\n豤\n豦\n貆\n貄\n貅\n賌\n赨\n赩\n趑\n趌\n趎\n趏\n趍\n趓\n趔\n趐\n趒\n跰\n跠\n跬\n跱\n跮\n跐\n跩\n跣\n跢\n跧\n跲\n跫\n跴\n輆\n軿\n輁\n輀\n輅\n輇\n輈\n輂\n輋\n遒\n逿\n遄\n遉\n逽\n鄐\n鄍\n鄏\n鄑\n鄖\n鄔\n鄋\n鄎\n酮\n酯\n鉈\n鉒\n鈰\n鈺\n鉦\n鈳\n鉥\n鉞\n銃\n鈮\n鉊\n鉆\n鉭\n鉬\n鉏\n鉠\n鉧\n鉯\n鈶\n鉡\n鉰\n鈱\n鉔\n鉣\n鉐\n鉲\n鉎\n鉓\n鉌\n鉖\n鈲\n閟\n閜\n閞\n閛\n隒\n隓\n隑\n隗\n雎\n雺\n雽\n雸\n雵\n靳\n靷\n靸\n靲\n頏\n頍\n頎\n颬\n飶\n飹\n馯\n馲\n馰\n馵\n骭\n骫\n魛\n鳪\n鳭\n鳧\n麀\n黽\n僦\n僔\n僗\n僨\n僳\n僛\n僪\n僝\n僤\n僓\n僬\n僰\n僯\n僣\n僠\n凘\n劀\n劁\n勩\n勫\n匰\n厬\n嘧\n嘕\n嘌\n嘒\n嗼\n嘏\n嘜\n嘁\n嘓\n嘂\n嗺\n嘝\n嘄\n嗿\n嗹\n墉\n塼\n墐\n墘\n墆\n墁\n塿\n塴\n墋\n塺\n墇\n墑\n墎\n塶\n墂\n墈\n塻\n墔\n墏\n壾\n奫\n嫜\n嫮\n嫥\n嫕\n嫪\n嫚\n嫭\n嫫\n嫳\n嫢\n嫠\n嫛\n嫬\n嫞\n嫝\n嫙\n嫨\n嫟\n孷\n寠\n寣\n屣\n嶂\n嶀\n嵽\n嶆\n嵺\n嶁\n嵷\n嶊\n嶉\n嶈\n嵾\n嵼\n嶍\n嵹\n嵿\n幘\n幙\n幓\n廘\n廑\n廗\n廎\n廜\n廕\n廙\n廒\n廔\n彄\n彃\n彯\n徶\n愬\n愨\n慁\n慞\n慱\n慳\n慒\n慓\n慲\n慬\n憀\n慴\n慔\n慺\n慛\n慥\n愻\n慪\n慡\n慖\n戩\n戧\n戫\n搫\n摍\n摛\n摝\n摴\n摶\n摲\n摳\n摽\n摵\n摦\n撦\n摎\n撂\n摞\n摜\n摋\n摓\n摠\n摐\n摿\n搿\n摬\n摫\n摙\n摥\n摷\n敳\n斠\n暡\n暠\n暟\n朅\n朄\n朢\n榱\n榶\n槉\n榠\n槎\n榖\n榰\n榬\n榼\n榑\n榙\n榎\n榧\n榍\n榩\n榾\n榯\n榿\n槄\n榽\n榤\n槔\n榹\n槊\n榚\n槏\n榳\n榓\n榪\n榡\n榞\n槙\n榗\n榐\n槂\n榵\n榥\n槆\n歊\n歍\n歋\n殞\n殟\n殠\n毃\n毄\n毾\n滎\n滵\n滱\n漃\n漥\n滸\n漷\n滻\n漮\n漉\n潎\n漙\n漚\n漧\n漘\n漻\n漒\n滭\n漊\n漶\n潳\n滹\n滮\n漭\n潀\n漰\n漼\n漵\n滫\n漇\n漎\n潃\n漅\n滽\n滶\n漹\n漜\n滼\n漺\n漟\n漍\n漞\n漈\n漡\n熇\n熐\n熉\n熀\n熅\n熂\n熏\n煻\n熆\n熁\n熗\n牄\n牓\n犗\n犕\n犓\n獃\n獍\n獑\n獌\n瑢\n瑳\n瑱\n瑵\n瑲\n瑧\n瑮\n甀\n甂\n甃\n畽\n疐\n瘖\n瘈\n瘌\n瘕\n瘑\n瘊\n瘔\n皸\n瞁\n睼\n瞅\n瞂\n睮\n瞀\n睯\n睾\n瞃\n碲\n碪\n碴\n碭\n碨\n硾\n碫\n碞\n碥\n碠\n碬\n碢\n碤\n禘\n禊\n禋\n禖\n禕\n禔\n禓\n禗\n禈\n禒\n禐\n稫\n穊\n稰\n稯\n稨\n稦\n窨\n窫\n窬\n竮\n箈\n箜\n箊\n箑\n箐\n箖\n箍\n箌\n箛\n箎\n箅\n箘\n劄\n箙\n箤\n箂\n粻\n粿\n粼\n粺\n綧\n綷\n緂\n綣\n綪\n緁\n緀\n緅\n綝\n緎\n緄\n緆\n緋\n緌\n綯\n綹\n綖\n綼\n綟\n綦\n綮\n綩\n綡\n緉\n罳\n翢\n翣\n翥\n翞\n耤\n聝\n聜\n膉\n膆\n膃\n膇\n膍\n膌\n膋\n舕\n蒗\n蒤\n蒡\n蒟\n蒺\n蓎\n蓂\n蒬\n蒮\n蒫\n蒹\n蒴\n蓁\n蓍\n蒪\n蒚\n蒱\n蓐\n蒝\n蒧\n蒻\n蒢\n蒔\n蓇\n蓌\n蒛\n蒩\n蒯\n蒨\n蓖\n蒘\n蒶\n蓏\n蒠\n蓗\n蓔\n蓒\n蓛\n蒰\n蒑\n虡\n蜳\n蜣\n蜨\n蝫\n蝀\n蜮\n蜞\n蜡\n蜙\n蜛\n蝃\n蜬\n蝁\n蜾\n蝆\n蜠\n蜲\n蜪\n蜭\n蜼\n蜒\n蜺\n蜱\n蜵\n蝂\n蜦\n蜧\n蜸\n蜤\n蜚\n蜰\n蜑\n裷\n裧\n裱\n裲\n裺\n裾\n裮\n裼\n裶\n裻\n裰\n裬\n裫\n覝\n覡\n覟\n覞\n觩\n觫\n觨\n誫\n誙\n誋\n誒\n誏\n誖\n谽\n豨\n豩\n賕\n賏\n賗\n趖\n踉\n踂\n跿\n踍\n跽\n踊\n踃\n踇\n踆\n踅\n跾\n踀\n踄\n輐\n輑\n輎\n輍\n鄣\n鄜\n鄠\n鄢\n鄟\n鄝\n鄚\n鄤\n鄡\n鄛\n酺\n酲\n酹\n酳\n銥\n銤\n鉶\n銛\n鉺\n銠\n銔\n銪\n銍\n銦\n銚\n銫\n鉹\n銗\n鉿\n銣\n鋮\n銎\n銂\n銕\n銢\n鉽\n銈\n銡\n銊\n銆\n銌\n銙\n銧\n鉾\n銇\n銩\n銝\n銋\n鈭\n隞\n隡\n雿\n靘\n靽\n靺\n靾\n鞃\n鞀\n鞂\n靻\n鞄\n鞁\n靿\n韎\n韍\n頖\n颭\n颮\n餂\n餀\n餇\n馝\n馜\n駃\n馹\n馻\n馺\n駂\n馽\n駇\n骱\n髣\n髧\n鬾\n鬿\n魠\n魡\n魟\n鳱\n鳲\n鳵\n麧\n僿\n儃\n儰\n僸\n儆\n儇\n僶\n僾\n儋\n儌\n僽\n儊\n劋\n劌\n勱\n勯\n噈\n噂\n噌\n嘵\n噁\n噊\n噉\n噆\n噘\n噚\n噀\n嘳\n嘽\n嘬\n嘾\n嘸\n嘪\n嘺\n圚\n墫\n墝\n墱\n墠\n墣\n墯\n墬\n墥\n墡\n壿\n嫿\n嫴\n嫽\n嫷\n嫶\n嬃\n嫸\n嬂\n嫹\n嬁\n嬇\n嬅\n嬏\n屧\n嶙\n嶗\n嶟\n嶒\n嶢\n嶓\n嶕\n嶠\n嶜\n嶡\n嶚\n嶞\n幩\n幝\n幠\n幜\n緳\n廛\n廞\n廡\n彉\n徲\n憋\n憃\n慹\n憱\n憰\n憢\n憉\n憛\n憓\n憯\n憭\n憟\n憒\n憪\n憡\n憍\n慦\n憳\n戭\n摮\n摰\n撖\n撠\n撅\n撗\n撜\n撏\n撋\n撊\n撌\n撣\n撟\n摨\n撱\n撘\n敶\n敺\n敹\n敻\n斲\n斳\n暵\n暰\n暩\n暲\n暷\n暪\n暯\n樀\n樆\n樗\n槥\n槸\n樕\n槱\n槤\n樠\n槿\n槬\n槢\n樛\n樝\n槾\n樧\n槲\n槮\n樔\n槷\n槧\n橀\n樈\n槦\n槻\n樍\n槼\n槫\n樉\n樄\n樘\n樥\n樏\n槶\n樦\n樇\n槴\n樖\n歑\n殥\n殣\n殢\n殦\n氁\n氀\n毿\n氂\n潁\n漦\n潾\n澇\n濆\n澒\n澍\n澉\n澌\n潢\n潏\n澅\n潚\n澖\n潶\n潬\n澂\n潕\n潲\n潒\n潐\n潗\n澔\n澓\n潝\n漀\n潡\n潫\n潽\n潧\n澐\n潓\n澋\n潩\n潿\n澕\n潣\n潷\n潪\n潻\n熲\n熯\n熛\n熰\n熠\n熚\n熩\n熵\n熝\n熥\n熞\n熤\n熡\n熪\n熜\n熧\n熳\n犘\n犚\n獘\n獒\n獞\n獟\n獠\n獝\n獛\n獡\n獚\n獙\n獢\n璇\n璉\n璊\n璆\n璁\n瑽\n璅\n璈\n瑼\n瑹\n甈\n甇\n畾\n瘥\n瘞\n瘙\n瘝\n瘜\n瘣\n瘚\n瘨\n瘛\n皜\n皝\n皞\n皛\n瞍\n瞏\n瞉\n瞈\n磍\n碻\n磏\n磌\n磑\n磎\n磔\n磈\n磃\n磄\n磉\n禚\n禡\n禠\n禜\n禢\n禛\n歶\n稹\n窲\n窴\n窳\n箷\n篋\n箾\n箬\n篎\n箯\n箹\n篊\n箵\n糅\n糈\n糌\n糋\n緷\n緛\n緪\n緧\n緗\n緡\n縃\n緺\n緦\n緶\n緱\n緰\n緮\n緟\n罶\n羬\n羰\n羭\n翭\n翫\n翪\n翬\n翦\n翨\n聤\n聧\n膣\n膟\n膞\n膕\n膢\n膙\n膗\n舖\n艏\n艓\n艒\n艐\n艎\n艑\n蔤\n蔻\n蔏\n蔀\n蔩\n蔎\n蔉\n蔍\n蔟\n蔊\n蔧\n蔜\n蓻\n蔫\n蓺\n蔈\n蔌\n蓴\n蔪\n蓲\n蔕\n蓷\n蓫\n蓳\n蓼\n蔒\n蓪\n蓩\n蔖\n蓾\n蔨\n蔝\n蔮\n蔂\n蓽\n蔞\n蓶\n蔱\n蔦\n蓧\n蓨\n蓰\n蓯\n蓹\n蔘\n蔠\n蔰\n蔋\n蔙\n蔯\n虢\n蝖\n蝣\n蝤\n蝷\n蟡\n蝳\n蝘\n蝔\n蝛\n蝒\n蝡\n蝚\n蝑\n蝞\n蝭\n蝪\n蝐\n蝎\n蝟\n蝝\n蝯\n蝬\n蝺\n蝮\n蝜\n蝥\n蝏\n蝻\n蝵\n蝢\n蝧\n蝩\n衚\n褅\n褌\n褔\n褋\n褗\n褘\n褙\n褆\n褖\n褑\n褎\n褉\n覢\n覤\n覣\n觭\n觰\n觬\n諏\n諆\n誸\n諓\n諑\n諔\n諕\n誻\n諗\n誾\n諀\n諅\n諘\n諃\n誺\n誽\n諙\n谾\n豍\n貏\n賥\n賟\n賙\n賨\n賚\n賝\n賧\n趠\n趜\n趡\n趛\n踠\n踣\n踥\n踤\n踮\n踕\n踛\n踖\n踑\n踙\n踦\n踧\n踔\n踒\n踘\n踓\n踜\n踗\n踚\n輬\n輤\n輘\n輚\n輠\n輣\n輖\n輗\n遳\n遰\n遯\n遧\n遫\n鄯\n鄫\n鄩\n鄪\n鄲\n鄦\n鄮\n醅\n醆\n醊\n醁\n醂\n醄\n醀\n鋐\n鋃\n鋄\n鋀\n鋙\n銶\n鋏\n鋱\n鋟\n鋘\n鋩\n鋗\n鋝\n鋌\n鋯\n鋂\n鋨\n鋊\n鋈\n鋎\n鋦\n鋍\n鋕\n鋉\n鋠\n鋞\n鋧\n鋑\n鋓\n銵\n鋡\n鋆\n銴\n镼\n閬\n閫\n閮\n閰\n隤\n隢\n雓\n霅\n霈\n霂\n靚\n鞊\n鞎\n鞈\n韐\n韏\n頞\n頝\n頦\n頩\n頨\n頠\n頛\n頧\n颲\n餈\n飺\n餑\n餔\n餖\n餗\n餕\n駜\n駍\n駏\n駓\n駔\n駎\n駉\n駖\n駘\n駋\n駗\n駌\n骳\n髬\n髫\n髳\n髲\n髱\n魆\n魃\n魧\n魴\n魱\n魦\n魶\n魵\n魰\n魨\n魤\n魬\n鳼\n鳺\n鳽\n鳿\n鳷\n鴇\n鴀\n鳹\n鳻\n鴈\n鴅\n鴄\n麃\n黓\n鼏\n鼐\n儜\n儓\n儗\n儚\n儑\n凞\n匴\n叡\n噰\n噠\n噮\n噳\n噦\n噣\n噭\n噲\n噞\n噷\n圜\n圛\n壈\n墽\n壉\n墿\n墺\n壂\n墼\n壆\n嬗\n嬙\n嬛\n嬡\n嬔\n嬓\n嬐\n嬖\n嬨\n嬚\n嬠\n嬞\n寯\n嶬\n嶱\n嶩\n嶧\n嶵\n嶰\n嶮\n嶪\n嶨\n嶲\n嶭\n嶯\n嶴\n幧\n幨\n幦\n幯\n廩\n廧\n廦\n廨\n廥\n彋\n徼\n憝\n憨\n憖\n懅\n憴\n懆\n懁\n懌\n憺\n憿\n憸\n憌\n擗\n擖\n擐\n擏\n擉\n撽\n撉\n擃\n擛\n擳\n擙\n攳\n敿\n敼\n斢\n曈\n暾\n曀\n曊\n曋\n曏\n暽\n暻\n暺\n曌\n朣\n樴\n橦\n橉\n橧\n樲\n橨\n樾\n橝\n橭\n橶\n橛\n橑\n樨\n橚\n樻\n樿\n橁\n橪\n橤\n橐\n橏\n橔\n橯\n橩\n橠\n樼\n橞\n橖\n橕\n橍\n橎\n橆\n歕\n歔\n歖\n殧\n殪\n殫\n毈\n毇\n氄\n氃\n氆\n澭\n濋\n澣\n濇\n澼\n濎\n濈\n潞\n濄\n澽\n澞\n濊\n澨\n瀄\n澥\n澮\n澺\n澬\n澪\n濏\n澿\n澸\n澢\n濉\n澫\n濍\n澯\n澲\n澰\n燅\n燂\n熿\n熸\n燖\n燀\n燁\n燋\n燔\n燊\n燇\n燏\n熽\n燘\n熼\n燆\n燚\n燛\n犝\n犞\n獩\n獦\n獧\n獬\n獥\n獫\n獪\n瑿\n璚\n璠\n璔\n璒\n璕\n璡\n甋\n疀\n瘯\n瘭\n瘱\n瘽\n瘳\n瘼\n瘵\n瘲\n瘰\n皻\n盦\n瞚\n瞝\n瞡\n瞜\n瞛\n瞢\n瞣\n瞕\n瞙\n瞗\n磝\n磩\n磥\n磪\n磞\n磣\n磛\n磡\n磢\n磭\n磟\n磠\n禤\n穄\n穈\n穇\n窶\n窸\n窵\n窱\n窷\n篞\n篣\n篧\n篝\n篕\n篥\n篚\n篨\n篹\n篔\n篪\n篢\n篜\n篫\n篘\n篟\n糒\n糔\n糗\n糐\n糑\n縒\n縡\n縗\n縌\n縟\n縠\n縓\n縎\n縜\n縕\n縚\n縢\n縋\n縏\n縖\n縍\n縔\n縥\n縤\n罃\n罻\n罼\n罺\n羱\n翯\n耪\n耩\n聬\n膱\n膦\n膮\n膹\n膵\n膫\n膰\n膬\n膴\n膲\n膷\n膧\n臲\n艕\n艖\n艗\n蕖\n蕅\n蕫\n蕍\n蕓\n蕡\n蕘\n蕀\n蕆\n蕤\n蕁\n蕢\n蕄\n蕑\n蕇\n蕣\n蔾\n蕛\n蕱\n蕎\n蕮\n蕵\n蕕\n蕧\n蕠\n薌\n蕦\n蕝\n蕔\n蕥\n蕬\n虣\n虥\n虤\n螛\n螏\n螗\n螓\n螒\n螈\n螁\n螖\n螘\n蝹\n螇\n螣\n螅\n螐\n螑\n螝\n螄\n螔\n螜\n螚\n螉\n褞\n褦\n褰\n褭\n褮\n褧\n褱\n褢\n褩\n褣\n褯\n褬\n褟\n觱\n諠\n諢\n諲\n諴\n諵\n諝\n謔\n諤\n諟\n諰\n諈\n諞\n諡\n諨\n諿\n諯\n諻\n貑\n貒\n貐\n賵\n賮\n賱\n賰\n賳\n赬\n赮\n趥\n趧\n踳\n踾\n踸\n蹀\n蹅\n踶\n踼\n踽\n蹁\n踰\n踿\n躽\n輶\n輮\n輵\n輲\n輹\n輷\n輴\n遶\n遹\n遻\n邆\n郺\n鄳\n鄵\n鄶\n醓\n醐\n醑\n醍\n醏\n錧\n錞\n錈\n錟\n錆\n錏\n鍺\n錸\n錼\n錛\n錣\n錒\n錁\n鍆\n錭\n錎\n錍\n鋋\n錝\n鋺\n錥\n錓\n鋹\n鋷\n錴\n錂\n錤\n鋿\n錩\n錹\n錵\n錪\n錔\n錌\n錋\n鋾\n錉\n錀\n鋻\n錖\n閼\n闍\n閾\n閹\n閺\n閶\n閿\n閵\n閽\n隩\n雔\n霋\n霒\n霐\n鞙\n鞗\n鞔\n韰\n韸\n頵\n頯\n頲\n餤\n餟\n餧\n餩\n馞\n駮\n駬\n駥\n駤\n駰\n駣\n駪\n駩\n駧\n骹\n骿\n骴\n骻\n髶\n髺\n髹\n髷\n鬳\n鮀\n鮅\n鮇\n魼\n魾\n魻\n鮂\n鮓\n鮒\n鮐\n魺\n鮕\n魽\n鮈\n鴥\n鴗\n鴠\n鴞\n鴔\n鴩\n鴝\n鴘\n鴢\n鴐\n鴙\n鴟\n麈\n麆\n麇\n麮\n麭\n黕\n黖\n黺\n鼒\n鼽\n儦\n儥\n儢\n儤\n儠\n儩\n勴\n嚓\n嚌\n嚍\n嚆\n嚄\n嚃\n噾\n嚂\n噿\n嚁\n壖\n壔\n壏\n壒\n嬭\n嬥\n嬲\n嬣\n嬬\n嬧\n嬦\n嬯\n嬮\n孻\n寱\n寲\n嶷\n幬\n幪\n徾\n徻\n懃\n憵\n憼\n懧\n懠\n懥\n懤\n懨\n懞\n擯\n擩\n擣\n擫\n擤\n擨\n斁\n斀\n斶\n旚\n曒\n檍\n檖\n檁\n檥\n檉\n檟\n檛\n檡\n檞\n檇\n檓\n檎\n檕\n檃\n檨\n檤\n檑\n橿\n檦\n檚\n檅\n檌\n檒\n歛\n殭\n氉\n濌\n澩\n濴\n濔\n濣\n濜\n濭\n濧\n濦\n濞\n濲\n濝\n濢\n濨\n燡\n燱\n燨\n燲\n燤\n燰\n燢\n獳\n獮\n獯\n璗\n璲\n璫\n璐\n璪\n璭\n璱\n璥\n璯\n甐\n甑\n甒\n甏\n疄\n癃\n癈\n癉\n癇\n皤\n盩\n瞵\n瞫\n瞲\n瞷\n瞶\n瞴\n瞱\n瞨\n矰\n磳\n磽\n礂\n磻\n磼\n磲\n礅\n磹\n磾\n礄\n禫\n禨\n穜\n穛\n穖\n穘\n穔\n穚\n窾\n竀\n竁\n簅\n簏\n篲\n簀\n篿\n篻\n簎\n篴\n簋\n篳\n簂\n簉\n簃\n簁\n篸\n篽\n簆\n篰\n篱\n簐\n簊\n糨\n縭\n縼\n繂\n縳\n顈\n縸\n縪\n繉\n繀\n繇\n縩\n繌\n縰\n縻\n縶\n繄\n縺\n罅\n罿\n罾\n罽\n翴\n翲\n耬\n膻\n臄\n臌\n臊\n臅\n臇\n膼\n臩\n艛\n艚\n艜\n薃\n薀\n薏\n薧\n薕\n薠\n薋\n薣\n蕻\n薤\n薚\n薞\n蕷\n蕼\n薉\n薡\n蕺\n蕸\n蕗\n薎\n薖\n薆\n薍\n薙\n薝\n薁\n薢\n薂\n薈\n薅\n蕹\n蕶\n薘\n薐\n薟\n虨\n螾\n螪\n螭\n蟅\n螰\n螬\n螹\n螵\n螼\n螮\n蟉\n蟃\n蟂\n蟌\n螷\n螯\n蟄\n蟊\n螴\n螶\n螿\n螸\n螽\n蟞\n螲\n褵\n褳\n褼\n褾\n襁\n襒\n褷\n襂\n覭\n覯\n覮\n觲\n觳\n謞\n謘\n謖\n謑\n謅\n謋\n謢\n謏\n謒\n謕\n謇\n謍\n謈\n謆\n謜\n謓\n謚\n豏\n豰\n豲\n豱\n豯\n貕\n貔\n賹\n赯\n蹎\n蹍\n蹓\n蹐\n蹌\n蹇\n轃\n轀\n邅\n遾\n鄸\n醚\n醢\n醛\n醙\n醟\n醡\n醝\n醠\n鎡\n鎃\n鎯\n鍤\n鍖\n鍇\n鍼\n鍘\n鍜\n鍶\n鍉\n鍐\n鍑\n鍠\n鍭\n鎏\n鍌\n鍪\n鍹\n鍗\n鍕\n鍒\n鍏\n鍱\n鍷\n鍻\n鍡\n鍞\n鍣\n鍧\n鎀\n鍎\n鍙\n闇\n闀\n闉\n闃\n闅\n閷\n隮\n隰\n隬\n霠\n霟\n霘\n霝\n霙\n鞚\n鞡\n鞜\n鞞\n鞝\n韕\n韔\n韱\n顁\n顄\n顊\n顉\n顅\n顃\n餥\n餫\n餬\n餪\n餳\n餲\n餯\n餭\n餱\n餰\n馘\n馣\n馡\n騂\n駺\n駴\n駷\n駹\n駸\n駶\n駻\n駽\n駾\n駼\n騃\n骾\n髾\n髽\n鬁\n髼\n魈\n鮚\n鮨\n鮞\n鮛\n鮦\n鮡\n鮥\n鮤\n鮆\n鮢\n鮠\n鮯\n鴳\n鵁\n鵧\n鴶\n鴮\n鴯\n鴱\n鴸\n鴰\n鵅\n鵂\n鵃\n鴾\n鴷\n鵀\n鴽\n翵\n鴭\n麊\n麉\n麍\n麰\n黈\n黚\n黻\n黿\n鼤\n鼣\n鼢\n齔\n龠\n儱\n儭\n儮\n嚘\n嚜\n嚗\n嚚\n嚝\n嚙\n奰\n嬼\n屩\n屪\n巀\n幭\n幮\n懘\n懟\n懭\n懮\n懱\n懪\n懰\n懫\n懖\n懩\n擿\n攄\n擽\n擸\n攁\n攃\n擼\n斔\n旛\n曚\n曛\n曘\n櫅\n檹\n檽\n櫡\n櫆\n檺\n檶\n檷\n櫇\n檴\n檭\n歞\n毉\n氋\n瀇\n瀌\n瀍\n瀁\n瀅\n瀔\n瀎\n濿\n瀀\n濻\n瀦\n濼\n濷\n瀊\n爁\n燿\n燹\n爃\n燽\n獶\n璸\n瓀\n璵\n瓁\n璾\n璶\n璻\n瓂\n甔\n甓\n癜\n癤\n癙\n癐\n癓\n癗\n癚\n皦\n皽\n盬\n矂\n瞺\n磿\n礌\n礓\n礔\n礉\n礐\n礒\n礑\n禭\n禬\n穟\n簜\n簩\n簙\n簠\n簟\n簭\n簝\n簦\n簨\n簢\n簥\n簰\n繜\n繐\n繖\n繣\n繘\n繢\n繟\n繑\n繠\n繗\n繓\n羵\n羳\n翷\n翸\n聵\n臑\n臒\n臐\n艟\n艞\n薴\n藆\n藀\n藃\n藂\n薳\n薵\n薽\n藇\n藄\n薿\n藋\n藎\n藈\n藅\n薱\n薶\n藒\n蘤\n薸\n薷\n薾\n虩\n蟧\n蟦\n蟢\n蟛\n蟫\n蟪\n蟥\n蟟\n蟳\n蟤\n蟔\n蟜\n蟓\n蟭\n蟘\n蟣\n螤\n蟗\n蟙\n蠁\n蟴\n蟨\n蟝\n襓\n襋\n襏\n襌\n襆\n襐\n襑\n襉\n謪\n謧\n謣\n謳\n謰\n謵\n譇\n謯\n謼\n謾\n謱\n謥\n謷\n謦\n謶\n謮\n謤\n謻\n謽\n謺\n豂\n豵\n貙\n貘\n貗\n賾\n贄\n贂\n贀\n蹜\n蹢\n蹠\n蹗\n蹖\n蹞\n蹥\n蹧\n蹛\n蹚\n蹡\n蹝\n蹩\n蹔\n轆\n轇\n轈\n轋\n鄨\n鄺\n鄻\n鄾\n醨\n醥\n醧\n醯\n醪\n鎵\n鎌\n鎒\n鎷\n鎛\n鎝\n鎉\n鎧\n鎎\n鎪\n鎞\n鎦\n鎕\n鎈\n鎙\n鎟\n鎍\n鎱\n鎑\n鎲\n鎤\n鎨\n鎴\n鎣\n鎥\n闒\n闓\n闑\n隳\n雗\n雚\n巂\n雟\n雘\n雝\n霣\n霢\n霥\n鞬\n鞮\n鞨\n鞫\n鞤\n鞪\n鞢\n鞥\n韗\n韙\n韖\n韘\n韺\n顐\n顑\n顒\n颸\n饁\n餼\n餺\n騏\n騋\n騉\n騍\n騄\n騑\n騊\n騅\n騇\n騆\n髀\n髜\n鬈\n鬄\n鬅\n鬩\n鬵\n魊\n魌\n魋\n鯇\n鯆\n鯃\n鮿\n鯁\n鮵\n鮸\n鯓\n鮶\n鯄\n鮹\n鮽\n鵜\n鵓\n鵏\n鵊\n鵛\n鵋\n鵙\n鵖\n鵌\n鵗\n鵒\n鵔\n鵟\n鵘\n鵚\n麎\n麌\n黟\n鼁\n鼀\n鼖\n鼥\n鼫\n鼪\n鼩\n鼨\n齌\n齕\n儴\n儵\n劖\n勷\n厴\n嚫\n嚭\n嚦\n嚧\n嚪\n嚬\n壚\n壝\n壛\n夒\n嬽\n嬾\n嬿\n巃\n幰\n徿\n懻\n攇\n攐\n攍\n攉\n攌\n攎\n斄\n旞\n旝\n曞\n櫧\n櫠\n櫌\n櫑\n櫙\n櫋\n櫟\n櫜\n櫐\n櫫\n櫏\n櫍\n櫞\n歠\n殰\n氌\n瀙\n瀧\n瀠\n瀖\n瀫\n瀡\n瀢\n瀣\n瀩\n瀗\n瀤\n瀜\n瀪\n爌\n爊\n爇\n爂\n爅\n犥\n犦\n犤\n犣\n犡\n瓋\n瓅\n璷\n瓃\n甖\n癠\n矉\n矊\n矄\n矱\n礝\n礛\n礡\n礜\n礗\n礞\n禰\n穧\n穨\n簳\n簼\n簹\n簬\n簻\n糬\n糪\n繶\n繵\n繸\n繰\n繷\n繯\n繺\n繲\n繴\n繨\n罋\n罊\n羃\n羆\n羷\n翽\n翾\n聸\n臗\n臕\n艤\n艡\n艣\n藫\n藱\n藭\n藙\n藡\n藨\n藚\n藗\n藬\n藲\n藸\n藘\n藟\n藣\n藜\n藑\n藰\n藦\n藯\n藞\n藢\n蠀\n蟺\n蠃\n蟶\n蟷\n蠉\n蠌\n蠋\n蠆\n蟼\n蠈\n蟿\n蠊\n蠂\n襢\n襚\n襛\n襗\n襡\n襜\n襘\n襝\n襙\n覈\n覷\n覶\n觶\n譐\n譈\n譊\n譀\n譓\n譖\n譔\n譋\n譕\n譑\n譂\n譒\n譗\n豃\n豷\n豶\n貚\n贆\n贇\n贉\n趬\n趪\n趭\n趫\n蹭\n蹸\n蹳\n蹪\n蹯\n蹻\n軂\n轒\n轑\n轏\n轐\n轓\n辴\n酀\n鄿\n醰\n醭\n鏞\n鏇\n鏏\n鏂\n鏚\n鏐\n鏹\n鏬\n鏌\n鏙\n鎩\n鏦\n鏊\n鏔\n鏮\n鏣\n鏕\n鏄\n鏎\n鏀\n鏒\n鏧\n镽\n闚\n闛\n雡\n霩\n霫\n霬\n霨\n霦\n鞳\n鞷\n鞶\n韝\n韞\n韟\n顜\n顙\n顝\n顗\n颿\n颽\n颻\n颾\n饈\n饇\n饃\n馦\n馧\n騚\n騕\n騥\n騝\n騤\n騛\n騢\n騠\n騧\n騣\n騞\n騜\n騔\n髂\n鬋\n鬊\n鬎\n鬌\n鬷\n鯪\n鯫\n鯠\n鯞\n鯤\n鯦\n鯢\n鯰\n鯔\n鯗\n鯬\n鯜\n鯙\n鯥\n鯕\n鯡\n鯚\n鵷\n鶁\n鶊\n鶄\n鶈\n鵱\n鶀\n鵸\n鶆\n鶋\n鶌\n鵽\n鵫\n鵴\n鵵\n鵰\n鵩\n鶅\n鵳\n鵻\n鶂\n鵯\n鵹\n鵿\n鶇\n鵨\n麔\n麑\n黀\n黼\n鼭\n齀\n齁\n齍\n齖\n齗\n齘\n匷\n嚲\n嚵\n嚳\n壣\n孅\n巆\n巇\n廮\n廯\n忀\n忁\n懹\n攗\n攖\n攕\n攓\n旟\n曨\n曣\n曤\n櫳\n櫰\n櫪\n櫨\n櫹\n櫱\n櫮\n櫯\n瀼\n瀵\n瀯\n瀷\n瀴\n瀱\n灂\n瀸\n瀿\n瀺\n瀹\n灀\n瀻\n瀳\n灁\n爓\n爔\n犨\n獽\n獼\n璺\n皫\n皪\n皾\n盭\n矌\n矎\n矏\n矍\n矲\n礥\n礣\n礧\n礨\n礤\n礩\n禲\n穮\n穬\n穭\n竷\n籉\n籈\n籊\n籇\n籅\n糮\n繻\n繾\n纁\n纀\n羺\n翿\n聹\n臛\n臙\n舋\n艨\n艩\n蘢\n藿\n蘁\n藾\n蘛\n蘀\n藶\n蘄\n蘉\n蘅\n蘌\n藽\n蠙\n蠐\n蠑\n蠗\n蠓\n蠖\n襣\n襦\n覹\n觷\n譠\n譪\n譝\n譨\n譣\n譥\n譧\n譭\n趮\n躆\n躈\n躄\n轙\n轖\n轗\n轕\n轘\n轚\n邍\n酃\n酁\n醷\n醵\n醲\n醳\n鐋\n鐓\n鏻\n鐠\n鐏\n鐔\n鏾\n鐕\n鐐\n鐨\n鐙\n鐍\n鏵\n鐀\n鏷\n鐇\n鐎\n鐖\n鐒\n鏺\n鐉\n鏸\n鐊\n鏿\n鏼\n鐌\n鏶\n鐑\n鐆\n闞\n闠\n闟\n霮\n霯\n鞹\n鞻\n韽\n韾\n顠\n顢\n顣\n顟\n飁\n飂\n饐\n饎\n饙\n饌\n饋\n饓\n騲\n騴\n騱\n騬\n騪\n騶\n騩\n騮\n騸\n騭\n髇\n髊\n髆\n鬐\n鬒\n鬑\n鰋\n鰈\n鯷\n鰅\n鰒\n鯸\n鱀\n鰇\n鰎\n鰆\n鰗\n鰔\n鰉\n鶟\n鶙\n鶤\n鶝\n鶒\n鶘\n鶐\n鶛\n鶠\n鶔\n鶜\n鶪\n鶗\n鶡\n鶚\n鶢\n鶨\n鶞\n鶣\n鶿\n鶩\n鶖\n鶦\n鶧\n麙\n麛\n麚\n黥\n黤\n黧\n黦\n鼰\n鼮\n齛\n齠\n齞\n齝\n齙\n龑\n儺\n儹\n劘\n劗\n囃\n嚽\n嚾\n孈\n孇\n巋\n巏\n廱\n懽\n攛\n欂\n櫼\n欃\n櫸\n欀\n灃\n灄\n灊\n灈\n灉\n灅\n灆\n爝\n爚\n爙\n獾\n甗\n癪\n矐\n礭\n礱\n礯\n籔\n籓\n糲\n纊\n纇\n纈\n纋\n纆\n纍\n罍\n羻\n耰\n臝\n蘘\n蘪\n蘦\n蘟\n蘣\n蘜\n蘙\n蘧\n蘮\n蘡\n蘠\n蘩\n蘞\n蘥\n蠩\n蠝\n蠛\n蠠\n蠤\n蠜\n蠫\n衊\n襭\n襩\n襮\n襫\n觺\n譹\n譸\n譅\n譺\n譻\n贐\n贔\n趯\n躎\n躌\n轞\n轛\n轝\n酆\n酄\n酅\n醹\n鐿\n鐻\n鐶\n鐩\n鐽\n鐼\n鐰\n鐹\n鐪\n鐷\n鐬\n鑀\n鐱\n闥\n闤\n闣\n霵\n霺\n鞿\n韡\n顤\n飉\n飆\n飀\n饘\n饖\n騹\n騽\n驆\n驄\n驂\n驁\n騺\n騿\n髍\n鬕\n鬗\n鬘\n鬖\n鬺\n魒\n鰫\n鰝\n鰜\n鰬\n鰣\n鰨\n鰩\n鰤\n鰡\n鶷\n鶶\n鶼\n鷁\n鷇\n鷊\n鷏\n鶾\n鷅\n鷃\n鶻\n鶵\n鷎\n鶹\n鶺\n鶬\n鷈\n鶱\n鶭\n鷌\n鶳\n鷍\n鶲\n鹺\n麜\n黫\n黮\n黭\n鼛\n鼘\n鼚\n鼱\n齎\n齥\n齤\n龒\n亹\n囆\n囅\n囋\n奱\n孋\n孌\n巕\n巑\n廲\n攡\n攠\n攦\n攢\n欋\n欈\n欉\n氍\n灕\n灖\n灗\n灒\n爞\n爟\n犩\n獿\n瓘\n瓕\n瓙\n瓗\n癭\n皭\n礵\n禴\n穰\n穱\n籗\n籜\n籙\n籛\n籚\n糴\n糱\n纑\n罏\n羇\n臞\n艫\n蘴\n蘵\n蘳\n蘬\n蘲\n蘶\n蠬\n蠨\n蠦\n蠪\n蠥\n襱\n覿\n覾\n觻\n譾\n讄\n讂\n讆\n讅\n譿\n贕\n躕\n躔\n躚\n躒\n躐\n躖\n躗\n轠\n轢\n酇\n鑌\n鑐\n鑊\n鑋\n鑏\n鑇\n鑅\n鑈\n鑉\n鑆\n霿\n韣\n顪\n顩\n飋\n饔\n饛\n驎\n驓\n驔\n驌\n驏\n驈\n驊\n驉\n驒\n驐\n髐\n鬙\n鬫\n鬻\n魖\n魕\n鱆\n鱈\n鰿\n鱄\n鰹\n鰳\n鱁\n鰼\n鰷\n鰴\n鰲\n鰽\n鰶\n鷛\n鷒\n鷞\n鷚\n鷋\n鷐\n鷜\n鷑\n鷟\n鷩\n鷙\n鷘\n鷖\n鷵\n鷕\n鷝\n麶\n黰\n鼵\n鼳\n鼲\n齂\n齫\n龕\n龢\n儽\n劙\n壨\n壧\n奲\n孍\n巘\n蠯\n彏\n戁\n戃\n戄\n攩\n攥\n斖\n曫\n欑\n欒\n欏\n毊\n灛\n灚\n爢\n玂\n玁\n玃\n癰\n矔\n籧\n籦\n纕\n艬\n蘺\n虀\n蘹\n蘼\n蘱\n蘻\n蘾\n蠰\n蠲\n蠮\n蠳\n襶\n襴\n襳\n觾\n讌\n讎\n讋\n讈\n豅\n贙\n躘\n轤\n轣\n醼\n鑢\n鑕\n鑝\n鑗\n鑞\n韄\n韅\n頀\n驖\n驙\n鬞\n鬟\n鬠\n鱒\n鱘\n鱐\n鱊\n鱍\n鱋\n鱕\n鱙\n鱌\n鱎\n鷻\n鷷\n鷯\n鷣\n鷫\n鷸\n鷤\n鷶\n鷡\n鷮\n鷦\n鷲\n鷰\n鷢\n鷬\n鷴\n鷳\n鷨\n鷭\n黂\n黐\n黲\n黳\n鼆\n鼜\n鼸\n鼷\n鼶\n齃\n齏\n齱\n齰\n齮\n齯\n囓\n囍\n孎\n屭\n攭\n曭\n曮\n欓\n灟\n灡\n灝\n灠\n爣\n瓛\n瓥\n矕\n礸\n禷\n禶\n籪\n纗\n羉\n艭\n虃\n蠸\n蠷\n蠵\n衋\n讔\n讕\n躞\n躟\n躠\n躝\n醾\n醽\n釂\n鑫\n鑨\n鑩\n雥\n靆\n靃\n靇\n韇\n韥\n驞\n髕\n魙\n鱣\n鱧\n鱦\n鱢\n鱞\n鱠\n鸂\n鷾\n鸇\n鸃\n鸆\n鸅\n鸀\n鸁\n鸉\n鷿\n鷽\n鸄\n麠\n鼞\n齆\n齴\n齵\n齶\n囔\n攮\n斸\n欘\n欙\n欗\n欚\n灢\n爦\n犪\n矘\n矙\n礹\n籩\n籫\n糶\n纚\n纘\n纛\n纙\n臠\n臡\n虆\n虇\n虈\n襹\n襺\n襼\n襻\n觿\n讘\n讙\n躥\n躤\n躣\n鑮\n鑭\n鑯\n鑱\n鑳\n靉\n顲\n饟\n鱨\n鱮\n鱭\n鸋\n鸍\n鸐\n鸏\n鸒\n鸑\n麡\n黵\n鼉\n齇\n齸\n齻\n齺\n齹\n圞\n灦\n籯\n蠼\n趲\n躦\n釃\n鑴\n鑸\n鑶\n鑵\n驠\n鱴\n鱳\n鱱\n鱵\n鸔\n鸓\n黶\n鼊\n龤\n灨\n灥\n糷\n虪\n蠾\n蠽\n蠿\n讞\n貜\n躩\n軉\n靋\n顳\n顴\n飌\n饡\n馫\n驤\n驦\n驧\n鬤\n鸕\n鸗\n齈\n戇\n欞\n爧\n虌\n躨\n钂\n钀\n钁\n驩\n驨\n鬮\n鸙\n爩\n虋\n讟\n钃\n鱹\n麷\n癵\n驫\n鱺\n鸝\n灩\n灪\n麤\n齾\n齉\n龘\n碁\n銹\n裏\n墻\n恒\n粧\n嫺\n╔\n╦\n╗\n╠\n╬\n╣\n╚\n╩\n╝\n╒\n╤\n╕\n╞\n╪\n╡\n╘\n╧\n╛\n╓\n╥\n╖\n╟\n╫\n╢\n╙\n╨\n╜\n║\n═\n╭\n╮\n╰\n╯\n￭\n𠕇\n鋛\n𠗟\n𣿅\n蕌\n䊵\n珯\n况\n㙉\n𤥂\n𨧤\n鍄\n𡧛\n苮\n𣳈\n砼\n杄\n拟\n𤤳\n𨦪\n𠊠\n𦮳\n𡌅\n侫\n𢓭\n倈\n𦴩\n𧪄\n𣘀\n𤪱\n𢔓\n倩\n𠍾\n徤\n𠎀\n𠍇\n滛\n𠐟\n偽\n儁\n㑺\n儎\n顬\n㝃\n萖\n𤦤\n𠒇\n兠\n𣎴\n兪\n𠯿\n𢃼\n𠋥\n𢔰\n𠖎\n𣈳\n𡦃\n宂\n蝽\n𠖳\n𣲙\n冲\n冸\n鴴\n凉\n减\n凑\n㳜\n凓\n𤪦\n决\n凢\n卂\n凭\n菍\n椾\n𣜭\n彻\n刋\n刦\n刼\n劵\n剗\n劔\n効\n勅\n簕\n蕂\n勠\n蘍\n𦬓\n包\n𨫞\n啉\n滙\n𣾀\n𠥔\n𣿬\n匳\n卄\n𠯢\n泋\n𡜦\n栛\n珕\n恊\n㺪\n㣌\n𡛨\n燝\n䒢\n卭\n却\n𨚫\n卾\n卿\n𡖖\n𡘓\n矦\n厓\n𨪛\n厠\n厫\n厮\n玧\n𥝲\n㽙\n玜\n叁\n叅\n汉\n义\n埾\n叙\n㪫\n𠮏\n叠\n𣿫\n𢶣\n叶\n𠱷\n吓\n灹\n唫\n晗\n浛\n呭\n𦭓\n𠵴\n啝\n咏\n咤\n䞦\n𡜍\n𠻝\n㶴\n𠵍\n𨦼\n𢚘\n啇\n䳭\n启\n琗\n喆\n喩\n嘅\n𡣗\n𤀺\n䕒\n𤐵\n暳\n𡂴\n嘷\n曍\n𣊊\n暤\n暭\n噍\n噏\n磱\n囱\n鞇\n叾\n圀\n囯\n园\n𨭦\n㘣\n𡉏\n坆\n𤆥\n汮\n炋\n坂\n㚱\n𦱾\n埦\n𡐖\n堃\n𡑔\n𤍣\n堦\n𤯵\n塜\n墪\n㕡\n壠\n壜\n𡈼\n壻\n寿\n坃\n𪅐\n𤉸\n鏓\n㖡\n够\n梦\n㛃\n湙\n𡘾\n娤\n啓\n𡚒\n蔅\n姉\n𠵎\n𦲁\n𦴪\n𡟜\n姙\n𡟻\n𡞲\n𦶦\n浱\n𡠨\n𡛕\n姹\n𦹅\n媫\n婣\n㛦\n𤦩\n婷\n㜈\n媖\n瑥\n嫓\n𦾡\n𢕔\n㶅\n𡤑\n㜲\n𡚸\n広\n勐\n孶\n斈\n孼\n𧨎\n䀄\n䡝\n𠈄\n寕\n慠\n𡨴\n𥧌\n𠖥\n寳\n宝\n䴐\n尅\n𡭄\n尓\n珎\n尔\n𡲥\n𦬨\n屉\n䣝\n岅\n峩\n峯\n嶋\n𡷹\n𡸷\n崐\n崘\n嵆\n𡺤\n岺\n巗\n苼\n㠭\n𤤁\n𢁉\n𢅳\n芇\n㠶\n㯂\n帮\n檊\n幵\n幺\n𤒼\n𠳓\n厦\n亷\n廐\n厨\n𡝱\n帉\n廴\n𨒂\n廹\n廻\n㢠\n廼\n栾\n鐛\n弍\n𠇁\n弢\n㫞\n䢮\n𡌺\n强\n𦢈\n𢏐\n彘\n𢑱\n彣\n鞽\n𦹮\n彲\n鍀\n𨨶\n徧\n嶶\n㵟\n𥉐\n𡽪\n𧃸\n𢙨\n釖\n𠊞\n𨨩\n怱\n暅\n𡡷\n㥣\n㷇\n㘹\n垐\n𢞴\n祱\n㹀\n悞\n悤\n悳\n𤦂\n𤦏\n𧩓\n璤\n僡\n媠\n慤\n萤\n慂\n慈\n𦻒\n憁\n凴\n𠙖\n憇\n宪\n𣾷\n𢡟\n懓\n𨮝\n𩥝\n懐\n㤲\n𢦀\n𢣁\n怣\n慜\n攞\n掋\n𠄘\n担\n𡝰\n拕\n𢸍\n捬\n𤧟\n㨗\n搸\n揸\n𡎎\n𡟼\n撐\n澊\n𢸶\n頔\n𤂌\n𥜝\n擡\n擥\n鑻\n㩦\n携\n㩗\n敍\n漖\n𤨨\n𤨣\n斅\n敭\n敟\n𣁾\n斵\n𤥀\n䬷\n旑\n䃘\n𡠩\n无\n旣\n忟\n𣐀\n昘\n𣇷\n𣇸\n晄\n𣆤\n𣆥\n晋\n𠹵\n晧\n𥇦\n晳\n晴\n𡸽\n𣈱\n𨗴\n𣇈\n𥌓\n矅\n𢣷\n馤\n朂\n𤎜\n𤨡\n㬫\n槺\n𣟂\n杞\n杧\n杢\n𤇍\n𩃭\n柗\n䓩\n栢\n湐\n鈼\n栁\n𣏦\n𦶠\n桝\n𣑯\n槡\n樋\n𨫟\n楳\n棃\n𣗍\n椁\n椀\n㴲\n㨁\n𣘼\n㮀\n枬\n楡\n𨩊\n䋼\n椶\n榘\n㮡\n𠏉\n荣\n傐\n槹\n𣙙\n𢄪\n橅\n𣜃\n檝\n㯳\n枱\n櫈\n𩆜\n㰍\n欝\n𠤣\n惞\n欵\n歴\n𢟍\n溵\n𣫛\n𠎵\n𡥘\n㝀\n吡\n𣭚\n毡\n𣻼\n毜\n氷\n𢒋\n𤣱\n𦭑\n汚\n舦\n汹\n𣶼\n䓅\n𣶽\n𤆤\n𤤌\n𤤀\n𣳉\n㛥\n㳫\n𠴲\n鮃\n𣇹\n𢒑\n羏\n样\n𦴥\n𦶡\n𦷫\n涖\n浜\n湼\n漄\n𤥿\n𤂅\n𦹲\n蔳\n𦽴\n凇\n沜\n渝\n萮\n𨬡\n港\n𣸯\n瑓\n𣾂\n秌\n湏\n媑\n𣁋\n濸\n㜍\n澝\n𣸰\n滺\n𡒗\n𤀽\n䕕\n鏰\n潄\n潜\n㵎\n潴\n𩅰\n㴻\n澟\n𤅄\n濓\n𤂑\n𤅕\n𤀹\n𣿰\n𣾴\n𤄿\n凟\n𤅖\n𤅗\n𤅀\n𦇝\n灋\n灾\n炧\n炁\n烌\n烕\n烖\n烟\n䄄\n㷨\n熴\n熖\n𤉷\n焫\n煅\n媈\n煊\n煮\n岜\n𤍥\n煏\n鍢\n𤋁\n焬\n𤑚\n𤨧\n𤨢\n熺\n𨯨\n炽\n爎\n鑂\n爕\n夑\n鑃\n爤\n鍁\n𥘅\n爮\n牀\n𤥴\n梽\n牕\n牗\n㹕\n𣁄\n栍\n漽\n犂\n猪\n猫\n𤠣\n𨠫\n䣭\n𨠄\n猨\n献\n珏\n玪\n𠰺\n𦨮\n珉\n瑉\n𤇢\n𡛧\n𤨤\n昣\n㛅\n𤦷\n𤦍\n𤧻\n珷\n琕\n椃\n𤨦\n琹\n𠗃\n㻗\n瑜\n𢢭\n瑠\n𨺲\n瑇\n珤\n瑶\n莹\n瑬\n㜰\n瑴\n鏱\n樬\n璂\n䥓\n𤪌\n𤅟\n𤩹\n𨮏\n孆\n𨰃\n𡢞\n瓈\n𡦈\n甎\n瓩\n甞\n𨻙\n𡩋\n寗\n𨺬\n鎅\n畍\n畊\n畧\n畮\n𤾂\n㼄\n𤴓\n疎\n瑝\n疞\n疴\n瘂\n瘬\n癑\n癏\n癯\n癶\n𦏵\n皐\n臯\n㟸\n𦤑\n𦤎\n皡\n皥\n皷\n盌\n𦾟\n葢\n𥂝\n𥅽\n𡸜\n眞\n眦\n着\n撯\n𥈠\n睘\n𣊬\n瞯\n𨥤\n𨥨\n𡛁\n矴\n砉\n𡍶\n𤨒\n棊\n碯\n磇\n磓\n隥\n礮\n𥗠\n磗\n礴\n碱\n𧘌\n辸\n袄\n𨬫\n𦂃\n𢘜\n禆\n褀\n椂\n禀\n𥡗\n禝\n𧬹\n礼\n禩\n渪\n𧄦\n㺨\n秆\n𩄍\n秔\n"
  },
  {
    "path": "helix-view/tests/encoding/big5_out.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n　\n，\n、\n。\n．\n‧\n；\n：\n？\n！\n︰\n…\n‥\n﹐\n﹑\n﹒\n·\n﹔\n﹕\n﹖\n﹗\n｜\n–\n︱\n—\n︳\n╴\n︴\n﹏\n（\n）\n︵\n︶\n｛\n｝\n︷\n︸\n〔\n〕\n︹\n︺\n【\n】\n︻\n︼\n《\n》\n︽\n︾\n〈\n〉\n︿\n﹀\n「\n」\n﹁\n﹂\n『\n』\n﹃\n﹄\n﹙\n﹚\n﹛\n﹜\n﹝\n﹞\n‘\n’\n“\n”\n〝\n〞\n‵\n′\n＃\n＆\n＊\n※\n§\n〃\n○\n●\n△\n▲\n◎\n☆\n★\n◇\n◆\n□\n■\n▽\n▼\n㊣\n℅\n¯\n￣\n＿\nˍ\n﹉\n﹊\n﹍\n﹎\n﹋\n﹌\n﹟\n﹠\n﹡\n＋\n－\n×\n÷\n±\n√\n＜\n＞\n＝\n≦\n≧\n≠\n∞\n≒\n≡\n﹢\n﹣\n﹤\n﹥\n﹦\n～\n∩\n∪\n⊥\n∠\n∟\n⊿\n㏒\n㏑\n∫\n∮\n∵\n∴\n♀\n♂\n⊕\n⊙\n↑\n↓\n←\n→\n↖\n↗\n↙\n↘\n∥\n∣\n／\n＼\n∕\n﹨\n＄\n￥\n〒\n￠\n￡\n％\n＠\n℃\n℉\n﹩\n﹪\n﹫\n㏕\n㎜\n㎝\n㎞\n㏎\n㎡\n㎎\n㎏\n㏄\n°\n兡\n兣\n嗧\n瓩\n▁\n▂\n▃\n▄\n▅\n▆\n▇\n█\n▏\n▎\n▍\n▌\n▋\n▊\n▉\n┼\n┴\n┬\n┤\n├\n▔\n─\n│\n▕\n┌\n┐\n└\n┘\n╭\n╮\n╰\n╯\n◢\n◣\n◥\n◤\n╱\n╲\n╳\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n〡\n〢\n〣\n〤\n〥\n〦\n〧\n〨\n〩\n卄\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\nㄅ\nㄆ\nㄇ\nㄈ\nㄉ\nㄊ\nㄋ\nㄌ\nㄍ\nㄎ\nㄏ\nㄐ\nㄑ\nㄒ\nㄓ\nㄔ\nㄕ\nㄖ\nㄗ\nㄘ\nㄙ\nㄚ\nㄛ\nㄜ\nㄝ\nㄞ\nㄟ\nㄠ\nㄡ\nㄢ\nㄣ\nㄤ\nㄥ\nㄦ\nㄧ\nㄨ\nㄩ\n˙\nˉ\nˊ\nˇ\nˋ\n␀\n␁\n␂\n␃\n␄\n␅\n␆\n␇\n␈\n␉\n␊\n␋\n␌\n␍\n␎\n␏\n␐\n␑\n␒\n␓\n␔\n␕\n␖\n␗\n␘\n␙\n␚\n␛\n␜\n␝\n␞\n␟\n␡\n€\n一\n乙\n丁\n七\n乃\n九\n了\n二\n人\n儿\n入\n八\n几\n刀\n刁\n力\n匕\n十\n卜\n又\n三\n下\n丈\n上\n丫\n丸\n凡\n久\n么\n也\n乞\n于\n亡\n兀\n刃\n勺\n千\n叉\n口\n土\n士\n夕\n大\n女\n子\n孑\n孓\n寸\n小\n尢\n尸\n山\n川\n工\n己\n已\n巳\n巾\n干\n廾\n弋\n弓\n才\n丑\n丐\n不\n中\n丰\n丹\n之\n尹\n予\n云\n井\n互\n五\n亢\n仁\n什\n仃\n仆\n仇\n仍\n今\n介\n仄\n元\n允\n內\n六\n兮\n公\n冗\n凶\n分\n切\n刈\n勻\n勾\n勿\n化\n匹\n午\n升\n卅\n卞\n厄\n友\n及\n反\n壬\n天\n夫\n太\n夭\n孔\n少\n尤\n尺\n屯\n巴\n幻\n廿\n弔\n引\n心\n戈\n戶\n手\n扎\n支\n文\n斗\n斤\n方\n日\n曰\n月\n木\n欠\n止\n歹\n毋\n比\n毛\n氏\n水\n火\n爪\n父\n爻\n片\n牙\n牛\n犬\n王\n丙\n世\n丕\n且\n丘\n主\n乍\n乏\n乎\n以\n付\n仔\n仕\n他\n仗\n代\n令\n仙\n仞\n充\n兄\n冉\n冊\n冬\n凹\n出\n凸\n刊\n加\n功\n包\n匆\n北\n匝\n仟\n半\n卉\n卡\n占\n卯\n卮\n去\n可\n古\n右\n召\n叮\n叩\n叨\n叼\n司\n叵\n叫\n另\n只\n史\n叱\n台\n句\n叭\n叻\n四\n囚\n外\n央\n失\n奴\n奶\n孕\n它\n尼\n巨\n巧\n左\n市\n布\n平\n幼\n弁\n弘\n弗\n必\n戊\n打\n扔\n扒\n扑\n斥\n旦\n朮\n本\n未\n末\n札\n正\n母\n民\n氐\n永\n汁\n汀\n氾\n犯\n玄\n玉\n瓜\n瓦\n甘\n生\n用\n甩\n田\n由\n甲\n申\n疋\n白\n皮\n皿\n目\n矛\n矢\n石\n示\n禾\n穴\n立\n丞\n丟\n乒\n乓\n乩\n亙\n交\n亦\n亥\n仿\n伉\n伙\n伊\n伕\n伍\n伐\n休\n伏\n仲\n件\n任\n仰\n仳\n份\n企\n伋\n光\n兇\n兆\n先\n全\n共\n再\n冰\n列\n刑\n划\n刎\n刖\n劣\n匈\n匡\n匠\n印\n危\n吉\n吏\n同\n吊\n吐\n吁\n吋\n各\n向\n名\n合\n吃\n后\n吆\n吒\n因\n回\n囝\n圳\n地\n在\n圭\n圬\n圯\n圩\n夙\n多\n夷\n夸\n妄\n奸\n妃\n好\n她\n如\n妁\n字\n存\n宇\n守\n宅\n安\n寺\n尖\n屹\n州\n帆\n并\n年\n式\n弛\n忙\n忖\n戎\n戌\n戍\n成\n扣\n扛\n托\n收\n早\n旨\n旬\n旭\n曲\n曳\n有\n朽\n朴\n朱\n朵\n次\n此\n死\n氖\n汝\n汗\n汙\n江\n池\n汐\n汕\n污\n汛\n汍\n汎\n灰\n牟\n牝\n百\n竹\n米\n糸\n缶\n羊\n羽\n老\n考\n而\n耒\n耳\n聿\n肉\n肋\n肌\n臣\n自\n至\n臼\n舌\n舛\n舟\n艮\n色\n艾\n虫\n血\n行\n衣\n西\n阡\n串\n亨\n位\n住\n佇\n佗\n佞\n伴\n佛\n何\n估\n佐\n佑\n伽\n伺\n伸\n佃\n佔\n似\n但\n佣\n作\n你\n伯\n低\n伶\n余\n佝\n佈\n佚\n兌\n克\n免\n兵\n冶\n冷\n別\n判\n利\n刪\n刨\n劫\n助\n努\n劬\n匣\n即\n卵\n吝\n吭\n吞\n吾\n否\n呎\n吧\n呆\n呃\n吳\n呈\n呂\n君\n吩\n告\n吹\n吻\n吸\n吮\n吵\n吶\n吠\n吼\n呀\n吱\n含\n吟\n听\n囪\n困\n囤\n囫\n坊\n坑\n址\n坍\n均\n坎\n圾\n坐\n坏\n圻\n壯\n夾\n妝\n妒\n妨\n妞\n妣\n妙\n妖\n妍\n妤\n妓\n妊\n妥\n孝\n孜\n孚\n孛\n完\n宋\n宏\n尬\n局\n屁\n尿\n尾\n岐\n岑\n岔\n岌\n巫\n希\n序\n庇\n床\n廷\n弄\n弟\n彤\n形\n彷\n役\n忘\n忌\n志\n忍\n忱\n快\n忸\n忪\n戒\n我\n抄\n抗\n抖\n技\n扶\n抉\n扭\n把\n扼\n找\n批\n扳\n抒\n扯\n折\n扮\n投\n抓\n抑\n抆\n改\n攻\n攸\n旱\n更\n束\n李\n杏\n材\n村\n杜\n杖\n杞\n杉\n杆\n杠\n杓\n杗\n步\n每\n求\n汞\n沙\n沁\n沈\n沉\n沅\n沛\n汪\n決\n沐\n汰\n沌\n汨\n沖\n沒\n汽\n沃\n汲\n汾\n汴\n沆\n汶\n沍\n沔\n沘\n沂\n灶\n灼\n災\n灸\n牢\n牡\n牠\n狄\n狂\n玖\n甬\n甫\n男\n甸\n皂\n盯\n矣\n私\n秀\n禿\n究\n系\n罕\n肖\n肓\n肝\n肘\n肛\n肚\n育\n良\n芒\n芋\n芍\n見\n角\n言\n谷\n豆\n豕\n貝\n赤\n走\n足\n身\n車\n辛\n辰\n迂\n迆\n迅\n迄\n巡\n邑\n邢\n邪\n邦\n那\n酉\n釆\n里\n防\n阮\n阱\n阪\n阬\n並\n乖\n乳\n事\n些\n亞\n享\n京\n佯\n依\n侍\n佳\n使\n佬\n供\n例\n來\n侃\n佰\n併\n侈\n佩\n佻\n侖\n佾\n侏\n侑\n佺\n兔\n兒\n兕\n兩\n具\n其\n典\n冽\n函\n刻\n券\n刷\n刺\n到\n刮\n制\n剁\n劾\n劻\n卒\n協\n卓\n卑\n卦\n卷\n卸\n卹\n取\n叔\n受\n味\n呵\n咖\n呸\n咕\n咀\n呻\n呷\n咄\n咒\n咆\n呼\n咐\n呱\n呶\n和\n咚\n呢\n周\n咋\n命\n咎\n固\n垃\n坷\n坪\n坩\n坡\n坦\n坤\n坼\n夜\n奉\n奇\n奈\n奄\n奔\n妾\n妻\n委\n妹\n妮\n姑\n姆\n姐\n姍\n始\n姓\n姊\n妯\n妳\n姒\n姅\n孟\n孤\n季\n宗\n定\n官\n宜\n宙\n宛\n尚\n屈\n居\n屆\n岷\n岡\n岸\n岩\n岫\n岱\n岳\n帘\n帚\n帖\n帕\n帛\n帑\n幸\n庚\n店\n府\n底\n庖\n延\n弦\n弧\n弩\n往\n征\n彿\n彼\n忝\n忠\n忽\n念\n忿\n怏\n怔\n怯\n怵\n怖\n怪\n怕\n怡\n性\n怩\n怫\n怛\n或\n戕\n房\n戾\n所\n承\n拉\n拌\n拄\n抿\n拂\n抹\n拒\n招\n披\n拓\n拔\n拋\n拈\n抨\n抽\n押\n拙\n拇\n拍\n抵\n拚\n抱\n拘\n拖\n拗\n拆\n抬\n放\n斧\n於\n旺\n昔\n易\n昌\n昆\n昂\n明\n昀\n昏\n昕\n昊\n昇\n服\n朋\n杭\n枋\n枕\n東\n果\n杳\n杷\n枇\n枝\n林\n杯\n杰\n板\n枉\n松\n析\n杵\n枚\n枓\n杼\n杪\n杲\n欣\n武\n歧\n歿\n氓\n氛\n泣\n注\n泳\n沱\n泌\n泥\n河\n沽\n沾\n沼\n波\n沫\n法\n泓\n沸\n泄\n油\n況\n沮\n泗\n泅\n泱\n沿\n治\n泡\n泛\n泊\n沬\n泯\n泜\n泖\n泠\n炕\n炎\n炒\n炊\n炙\n爬\n爭\n爸\n版\n牧\n物\n狀\n狎\n狙\n狗\n狐\n玩\n玨\n玟\n玫\n玥\n甽\n疝\n疙\n疚\n的\n盂\n盲\n直\n知\n矽\n社\n祀\n祁\n秉\n秈\n空\n穹\n竺\n糾\n罔\n羌\n羋\n肺\n肥\n肢\n肱\n股\n肫\n肩\n肴\n肪\n肯\n臥\n臾\n舍\n芳\n芝\n芙\n芭\n芽\n芟\n芹\n花\n芬\n芥\n芯\n芸\n芣\n芰\n芾\n芷\n虎\n虱\n初\n表\n軋\n迎\n返\n近\n邵\n邸\n邱\n邶\n采\n金\n長\n門\n阜\n陀\n阿\n阻\n附\n陂\n隹\n雨\n青\n非\n亟\n亭\n亮\n信\n侵\n侯\n便\n俠\n俑\n俏\n保\n促\n侶\n俘\n俟\n俊\n俗\n侮\n俐\n俄\n係\n俚\n俎\n俞\n侷\n兗\n冒\n冑\n冠\n剎\n剃\n削\n前\n剌\n剋\n則\n勇\n勉\n勃\n勁\n匍\n南\n卻\n厚\n叛\n咬\n哀\n咨\n哎\n哉\n咸\n咦\n咳\n哇\n哂\n咽\n咪\n品\n哄\n哈\n咯\n咫\n咱\n咻\n咩\n咧\n咿\n囿\n垂\n型\n垠\n垣\n垢\n城\n垮\n垓\n奕\n契\n奏\n奎\n奐\n姜\n姘\n姿\n姣\n姨\n娃\n姥\n姪\n姚\n姦\n威\n姻\n孩\n宣\n宦\n室\n客\n宥\n封\n屎\n屏\n屍\n屋\n峙\n峒\n巷\n帝\n帥\n帟\n幽\n庠\n度\n建\n弈\n弭\n彥\n很\n待\n徊\n律\n徇\n後\n徉\n怒\n思\n怠\n急\n怎\n怨\n恍\n恰\n恨\n恆\n恃\n恬\n恫\n恪\n恤\n扁\n拜\n挖\n按\n拼\n拭\n持\n拮\n拽\n指\n拱\n拷\n拯\n括\n拾\n拴\n挑\n挂\n政\n故\n斫\n施\n既\n春\n昭\n映\n昧\n是\n星\n昨\n昱\n昤\n曷\n柿\n染\n柱\n柔\n某\n柬\n架\n枯\n柵\n柩\n柯\n柄\n柑\n枴\n柚\n查\n枸\n柏\n柞\n柳\n枰\n柙\n柢\n柝\n柒\n歪\n殃\n殆\n段\n毒\n毗\n氟\n泉\n洋\n洲\n洪\n流\n津\n洌\n洱\n洞\n洗\n活\n洽\n派\n洶\n洛\n泵\n洹\n洧\n洸\n洩\n洮\n洵\n洎\n洫\n炫\n為\n炳\n炬\n炯\n炭\n炸\n炮\n炤\n爰\n牲\n牯\n牴\n狩\n狠\n狡\n玷\n珊\n玻\n玲\n珍\n珀\n玳\n甚\n甭\n畏\n界\n畎\n畋\n疫\n疤\n疥\n疢\n疣\n癸\n皆\n皇\n皈\n盈\n盆\n盃\n盅\n省\n盹\n相\n眉\n看\n盾\n盼\n眇\n矜\n砂\n研\n砌\n砍\n祆\n祉\n祈\n祇\n禹\n禺\n科\n秒\n秋\n穿\n突\n竿\n竽\n籽\n紂\n紅\n紀\n紉\n紇\n約\n紆\n缸\n美\n羿\n耄\n耐\n耍\n耑\n耶\n胖\n胥\n胚\n胃\n胄\n背\n胡\n胛\n胎\n胞\n胤\n胝\n致\n舢\n苧\n范\n茅\n苣\n苛\n苦\n茄\n若\n茂\n茉\n苒\n苗\n英\n茁\n苜\n苔\n苑\n苞\n苓\n苟\n苯\n茆\n虐\n虹\n虻\n虺\n衍\n衫\n要\n觔\n計\n訂\n訃\n貞\n負\n赴\n赳\n趴\n軍\n軌\n述\n迦\n迢\n迪\n迥\n迭\n迫\n迤\n迨\n郊\n郎\n郁\n郃\n酋\n酊\n重\n閂\n限\n陋\n陌\n降\n面\n革\n韋\n韭\n音\n頁\n風\n飛\n食\n首\n香\n乘\n亳\n倌\n倍\n倣\n俯\n倦\n倥\n俸\n倩\n倖\n倆\n值\n借\n倚\n倒\n們\n俺\n倀\n倔\n倨\n俱\n倡\n個\n候\n倘\n俳\n修\n倭\n倪\n俾\n倫\n倉\n兼\n冤\n冥\n冢\n凍\n凌\n准\n凋\n剖\n剜\n剔\n剛\n剝\n匪\n卿\n原\n厝\n叟\n哨\n唐\n唁\n唷\n哼\n哥\n哲\n唆\n哺\n唔\n哩\n哭\n員\n唉\n哮\n哪\n哦\n唧\n唇\n哽\n唏\n圃\n圄\n埂\n埔\n埋\n埃\n堉\n夏\n套\n奘\n奚\n娑\n娘\n娜\n娟\n娛\n娓\n姬\n娠\n娣\n娩\n娥\n娌\n娉\n孫\n屘\n宰\n害\n家\n宴\n宮\n宵\n容\n宸\n射\n屑\n展\n屐\n峭\n峽\n峻\n峪\n峨\n峰\n島\n崁\n峴\n差\n席\n師\n庫\n庭\n座\n弱\n徒\n徑\n徐\n恙\n恣\n恥\n恐\n恕\n恭\n恩\n息\n悄\n悟\n悚\n悍\n悔\n悌\n悅\n悖\n扇\n拳\n挈\n拿\n捎\n挾\n振\n捕\n捂\n捆\n捏\n捉\n挺\n捐\n挽\n挪\n挫\n挨\n捍\n捌\n效\n敉\n料\n旁\n旅\n時\n晉\n晏\n晃\n晒\n晌\n晅\n晁\n書\n朔\n朕\n朗\n校\n核\n案\n框\n桓\n根\n桂\n桔\n栩\n梳\n栗\n桌\n桑\n栽\n柴\n桐\n桀\n格\n桃\n株\n桅\n栓\n栘\n桁\n殊\n殉\n殷\n氣\n氧\n氨\n氦\n氤\n泰\n浪\n涕\n消\n涇\n浦\n浸\n海\n浙\n涓\n浬\n涉\n浮\n浚\n浴\n浩\n涌\n涊\n浹\n涅\n浥\n涔\n烊\n烘\n烤\n烙\n烈\n烏\n爹\n特\n狼\n狹\n狽\n狸\n狷\n玆\n班\n琉\n珮\n珠\n珪\n珞\n畔\n畝\n畜\n畚\n留\n疾\n病\n症\n疲\n疳\n疽\n疼\n疹\n痂\n疸\n皋\n皰\n益\n盍\n盎\n眩\n真\n眠\n眨\n矩\n砰\n砧\n砸\n砝\n破\n砷\n砥\n砭\n砠\n砟\n砲\n祕\n祐\n祠\n祟\n祖\n神\n祝\n祗\n祚\n秤\n秧\n租\n秦\n秩\n秘\n窄\n窈\n站\n笆\n笑\n粉\n紡\n紗\n紋\n紊\n素\n索\n純\n紐\n紕\n級\n紜\n納\n紙\n紛\n缺\n罟\n羔\n翅\n翁\n耆\n耘\n耕\n耙\n耗\n耽\n耿\n胱\n脂\n胰\n脅\n胭\n胴\n脆\n胸\n胳\n脈\n能\n脊\n胼\n胯\n臭\n臬\n舀\n舐\n航\n舫\n舨\n般\n芻\n茫\n荒\n荔\n荊\n茸\n荐\n草\n茵\n茴\n荏\n茲\n茹\n茶\n茗\n荀\n茱\n茨\n荃\n虔\n蚊\n蚪\n蚓\n蚤\n蚩\n蚌\n蚣\n蚜\n衰\n衷\n袁\n袂\n衽\n衹\n記\n訐\n討\n訌\n訕\n訊\n託\n訓\n訖\n訏\n訑\n豈\n豺\n豹\n財\n貢\n躬\n軒\n軔\n軏\n辱\n送\n逆\n迷\n退\n迺\n迴\n逃\n追\n逅\n迸\n邕\n郡\n郝\n郢\n酒\n配\n酌\n釘\n針\n釗\n釜\n釙\n閃\n院\n陣\n陡\n陛\n陝\n除\n陘\n陞\n隻\n飢\n馬\n骨\n高\n鬥\n鬲\n鬼\n乾\n偺\n偽\n停\n假\n偃\n偌\n做\n偉\n健\n偶\n偎\n偕\n偵\n側\n偷\n偏\n倏\n偯\n偭\n兜\n冕\n凰\n剪\n副\n勒\n務\n勘\n動\n匐\n匏\n匙\n匿\n區\n匾\n參\n曼\n商\n啪\n啦\n啄\n啞\n啡\n啃\n啊\n唱\n啖\n問\n啕\n唯\n啤\n唸\n售\n啜\n唬\n啣\n唳\n啁\n啗\n圈\n國\n圉\n域\n堅\n堊\n堆\n埠\n埤\n基\n堂\n堵\n執\n培\n夠\n奢\n娶\n婁\n婉\n婦\n婪\n婀\n娼\n婢\n婚\n婆\n婊\n孰\n寇\n寅\n寄\n寂\n宿\n密\n尉\n專\n將\n屠\n屜\n屝\n崇\n崆\n崎\n崛\n崖\n崢\n崑\n崩\n崔\n崙\n崤\n崧\n崗\n巢\n常\n帶\n帳\n帷\n康\n庸\n庶\n庵\n庾\n張\n強\n彗\n彬\n彩\n彫\n得\n徙\n從\n徘\n御\n徠\n徜\n恿\n患\n悉\n悠\n您\n惋\n悴\n惦\n悽\n情\n悻\n悵\n惜\n悼\n惘\n惕\n惆\n惟\n悸\n惚\n惇\n戚\n戛\n扈\n掠\n控\n捲\n掖\n探\n接\n捷\n捧\n掘\n措\n捱\n掩\n掉\n掃\n掛\n捫\n推\n掄\n授\n掙\n採\n掬\n排\n掏\n掀\n捻\n捩\n捨\n捺\n敝\n敖\n救\n教\n敗\n啟\n敏\n敘\n敕\n敔\n斜\n斛\n斬\n族\n旋\n旌\n旎\n晝\n晚\n晤\n晨\n晦\n晞\n曹\n勗\n望\n梁\n梯\n梢\n梓\n梵\n桿\n桶\n梱\n梧\n梗\n械\n梃\n棄\n梭\n梆\n梅\n梔\n條\n梨\n梟\n梡\n梂\n欲\n殺\n毫\n毬\n氫\n涎\n涼\n淳\n淙\n液\n淡\n淌\n淤\n添\n淺\n清\n淇\n淋\n涯\n淑\n涮\n淞\n淹\n涸\n混\n淵\n淅\n淒\n渚\n涵\n淚\n淫\n淘\n淪\n深\n淮\n淨\n淆\n淄\n涪\n淬\n涿\n淦\n烹\n焉\n焊\n烽\n烯\n爽\n牽\n犁\n猜\n猛\n猖\n猓\n猙\n率\n琅\n琊\n球\n理\n現\n琍\n瓠\n瓶\n瓷\n甜\n產\n略\n畦\n畢\n異\n疏\n痔\n痕\n疵\n痊\n痍\n皎\n盔\n盒\n盛\n眷\n眾\n眼\n眶\n眸\n眺\n硫\n硃\n硎\n祥\n票\n祭\n移\n窒\n窕\n笠\n笨\n笛\n第\n符\n笙\n笞\n笮\n粒\n粗\n粕\n絆\n絃\n統\n紮\n紹\n紼\n絀\n細\n紳\n組\n累\n終\n紲\n紱\n缽\n羞\n羚\n翌\n翎\n習\n耜\n聊\n聆\n脯\n脖\n脣\n脫\n脩\n脰\n脤\n舂\n舵\n舷\n舶\n船\n莎\n莞\n莘\n荸\n莢\n莖\n莽\n莫\n莒\n莊\n莓\n莉\n莠\n荷\n荻\n荼\n莆\n莧\n處\n彪\n蛇\n蛀\n蚶\n蛄\n蚵\n蛆\n蛋\n蚱\n蚯\n蛉\n術\n袞\n袈\n被\n袒\n袖\n袍\n袋\n覓\n規\n訪\n訝\n訣\n訥\n許\n設\n訟\n訛\n訢\n豉\n豚\n販\n責\n貫\n貨\n貪\n貧\n赧\n赦\n趾\n趺\n軛\n軟\n這\n逍\n通\n逗\n連\n速\n逝\n逐\n逕\n逞\n造\n透\n逢\n逖\n逛\n途\n部\n郭\n酗\n野\n釵\n釦\n釣\n釧\n釭\n釩\n閉\n陪\n陵\n陳\n陸\n陰\n陴\n陶\n陷\n陬\n雀\n雪\n雩\n章\n竟\n頂\n頃\n魚\n鳥\n鹵\n鹿\n麥\n麻\n傢\n傍\n傅\n備\n傑\n傀\n傖\n傘\n傚\n最\n凱\n割\n剴\n創\n剩\n勞\n勝\n勛\n博\n厥\n啻\n喀\n喧\n啼\n喊\n喝\n喘\n喂\n喜\n喪\n喔\n喇\n喋\n喃\n喳\n單\n喟\n唾\n喲\n喚\n喻\n喬\n喱\n啾\n喉\n喫\n喙\n圍\n堯\n堪\n場\n堤\n堰\n報\n堡\n堝\n堠\n壹\n壺\n奠\n婷\n媚\n婿\n媒\n媛\n媧\n孳\n孱\n寒\n富\n寓\n寐\n尊\n尋\n就\n嵌\n嵐\n崴\n嵇\n巽\n幅\n帽\n幀\n幃\n幾\n廊\n廁\n廂\n廄\n弼\n彭\n復\n循\n徨\n惑\n惡\n悲\n悶\n惠\n愜\n愣\n惺\n愕\n惰\n惻\n惴\n慨\n惱\n愎\n惶\n愉\n愀\n愒\n戟\n扉\n掣\n掌\n描\n揀\n揩\n揉\n揆\n揍\n插\n揣\n提\n握\n揖\n揭\n揮\n捶\n援\n揪\n換\n摒\n揚\n揹\n敞\n敦\n敢\n散\n斑\n斐\n斯\n普\n晰\n晴\n晶\n景\n暑\n智\n晾\n晷\n曾\n替\n期\n朝\n棺\n棕\n棠\n棘\n棗\n椅\n棟\n棵\n森\n棧\n棹\n棒\n棲\n棣\n棋\n棍\n植\n椒\n椎\n棉\n棚\n楮\n棻\n款\n欺\n欽\n殘\n殖\n殼\n毯\n氮\n氯\n氬\n港\n游\n湔\n渡\n渲\n湧\n湊\n渠\n渥\n渣\n減\n湛\n湘\n渤\n湖\n湮\n渭\n渦\n湯\n渴\n湍\n渺\n測\n湃\n渝\n渾\n滋\n溉\n渙\n湎\n湣\n湄\n湲\n湩\n湟\n焙\n焚\n焦\n焰\n無\n然\n煮\n焜\n牌\n犄\n犀\n猶\n猥\n猴\n猩\n琺\n琪\n琳\n琢\n琥\n琵\n琶\n琴\n琯\n琛\n琦\n琨\n甥\n甦\n畫\n番\n痢\n痛\n痣\n痙\n痘\n痞\n痠\n登\n發\n皖\n皓\n皴\n盜\n睏\n短\n硝\n硬\n硯\n稍\n稈\n程\n稅\n稀\n窘\n窗\n窖\n童\n竣\n等\n策\n筆\n筐\n筒\n答\n筍\n筋\n筏\n粟\n粥\n絞\n結\n絨\n絕\n紫\n絮\n絲\n絡\n給\n絢\n絰\n絳\n善\n翔\n翕\n耋\n聒\n肅\n腕\n腔\n腋\n腑\n腎\n脹\n腆\n脾\n腌\n腓\n腴\n舒\n舜\n菩\n萃\n菸\n萍\n菠\n菅\n萋\n華\n菱\n菴\n著\n萊\n菰\n萌\n菌\n菽\n菲\n菊\n萸\n萎\n萄\n菜\n萇\n菔\n菟\n虛\n蛟\n蛙\n蛭\n蛔\n蛛\n蛤\n蛐\n蛞\n街\n裁\n裂\n袱\n覃\n視\n註\n詠\n評\n詞\n証\n詁\n詔\n詛\n詐\n詆\n訴\n診\n訶\n詖\n象\n貂\n貯\n貼\n貳\n貽\n賁\n費\n賀\n貴\n買\n貶\n貿\n貸\n越\n超\n趁\n跎\n距\n跋\n跚\n跑\n跌\n跛\n跆\n軻\n軸\n軼\n辜\n逮\n逵\n週\n逸\n進\n逶\n鄂\n郵\n鄉\n郾\n酣\n酥\n量\n鈔\n鈕\n鈣\n鈉\n鈞\n鈍\n鈐\n鈇\n鈑\n閔\n閏\n開\n閑\n間\n閒\n閎\n隊\n階\n隋\n陽\n隅\n隆\n隍\n陲\n隄\n雁\n雅\n雄\n集\n雇\n雯\n雲\n韌\n項\n順\n須\n飧\n飪\n飯\n飩\n飲\n飭\n馮\n馭\n黃\n黍\n黑\n亂\n傭\n債\n傲\n傳\n僅\n傾\n催\n傷\n傻\n傯\n僇\n剿\n剷\n剽\n募\n勦\n勤\n勢\n勣\n匯\n嗟\n嗨\n嗓\n嗦\n嗎\n嗜\n嗇\n嗑\n嗣\n嗤\n嗯\n嗚\n嗡\n嗅\n嗆\n嗥\n嗉\n園\n圓\n塞\n塑\n塘\n塗\n塚\n塔\n填\n塌\n塭\n塊\n塢\n塒\n塋\n奧\n嫁\n嫉\n嫌\n媾\n媽\n媼\n媳\n嫂\n媲\n嵩\n嵯\n幌\n幹\n廉\n廈\n弒\n彙\n徬\n微\n愚\n意\n慈\n感\n想\n愛\n惹\n愁\n愈\n慎\n慌\n慄\n慍\n愾\n愴\n愧\n愍\n愆\n愷\n戡\n戢\n搓\n搾\n搞\n搪\n搭\n搽\n搬\n搏\n搜\n搔\n損\n搶\n搖\n搗\n搆\n敬\n斟\n新\n暗\n暉\n暇\n暈\n暖\n暄\n暘\n暍\n會\n榔\n業\n楚\n楷\n楠\n楔\n極\n椰\n概\n楊\n楨\n楫\n楞\n楓\n楹\n榆\n楝\n楣\n楛\n歇\n歲\n毀\n殿\n毓\n毽\n溢\n溯\n滓\n溶\n滂\n源\n溝\n滇\n滅\n溥\n溘\n溼\n溺\n溫\n滑\n準\n溜\n滄\n滔\n溪\n溧\n溴\n煎\n煙\n煩\n煤\n煉\n照\n煜\n煬\n煦\n煌\n煥\n煞\n煆\n煨\n煖\n爺\n牒\n猷\n獅\n猿\n猾\n瑯\n瑚\n瑕\n瑟\n瑞\n瑁\n琿\n瑙\n瑛\n瑜\n當\n畸\n瘀\n痰\n瘁\n痲\n痱\n痺\n痿\n痴\n痳\n盞\n盟\n睛\n睫\n睦\n睞\n督\n睹\n睪\n睬\n睜\n睥\n睨\n睢\n矮\n碎\n碰\n碗\n碘\n碌\n碉\n硼\n碑\n碓\n硿\n祺\n祿\n禁\n萬\n禽\n稜\n稚\n稠\n稔\n稟\n稞\n窟\n窠\n筷\n節\n筠\n筮\n筧\n粱\n粳\n粵\n經\n絹\n綑\n綁\n綏\n絛\n置\n罩\n罪\n署\n義\n羨\n群\n聖\n聘\n肆\n肄\n腱\n腰\n腸\n腥\n腮\n腳\n腫\n腹\n腺\n腦\n舅\n艇\n蒂\n葷\n落\n萱\n葵\n葦\n葫\n葉\n葬\n葛\n萼\n萵\n葡\n董\n葩\n葭\n葆\n虞\n虜\n號\n蛹\n蜓\n蜈\n蜇\n蜀\n蛾\n蛻\n蜂\n蜃\n蜆\n蜊\n衙\n裟\n裔\n裙\n補\n裘\n裝\n裡\n裊\n裕\n裒\n覜\n解\n詫\n該\n詳\n試\n詩\n詰\n誇\n詼\n詣\n誠\n話\n誅\n詭\n詢\n詮\n詬\n詹\n詻\n訾\n詨\n豢\n貊\n貉\n賊\n資\n賈\n賄\n貲\n賃\n賂\n賅\n跡\n跟\n跨\n路\n跳\n跺\n跪\n跤\n跦\n躲\n較\n載\n軾\n輊\n辟\n農\n運\n遊\n道\n遂\n達\n逼\n違\n遐\n遇\n遏\n過\n遍\n遑\n逾\n遁\n鄒\n鄗\n酬\n酪\n酩\n釉\n鈷\n鉗\n鈸\n鈽\n鉀\n鈾\n鉛\n鉋\n鉤\n鉑\n鈴\n鉉\n鉍\n鉅\n鈹\n鈿\n鉚\n閘\n隘\n隔\n隕\n雍\n雋\n雉\n雊\n雷\n電\n雹\n零\n靖\n靴\n靶\n預\n頑\n頓\n頊\n頒\n頌\n飼\n飴\n飽\n飾\n馳\n馱\n馴\n髡\n鳩\n麂\n鼎\n鼓\n鼠\n僧\n僮\n僥\n僖\n僚\n僕\n像\n僑\n僱\n僎\n僩\n兢\n凳\n劃\n劂\n匱\n厭\n嗾\n嘀\n嘛\n嘗\n嗽\n嘔\n嘆\n嘉\n嘍\n嘎\n嗷\n嘖\n嘟\n嘈\n嘐\n嗶\n團\n圖\n塵\n塾\n境\n墓\n墊\n塹\n墅\n塽\n壽\n夥\n夢\n夤\n奪\n奩\n嫡\n嫦\n嫩\n嫗\n嫖\n嫘\n嫣\n孵\n寞\n寧\n寡\n寥\n實\n寨\n寢\n寤\n察\n對\n屢\n嶄\n嶇\n幛\n幣\n幕\n幗\n幔\n廓\n廖\n弊\n彆\n彰\n徹\n慇\n愿\n態\n慷\n慢\n慣\n慟\n慚\n慘\n慵\n截\n撇\n摘\n摔\n撤\n摸\n摟\n摺\n摑\n摧\n搴\n摭\n摻\n敲\n斡\n旗\n旖\n暢\n暨\n暝\n榜\n榨\n榕\n槁\n榮\n槓\n構\n榛\n榷\n榻\n榫\n榴\n槐\n槍\n榭\n槌\n榦\n槃\n榣\n歉\n歌\n氳\n漳\n演\n滾\n漓\n滴\n漩\n漾\n漠\n漬\n漏\n漂\n漢\n滿\n滯\n漆\n漱\n漸\n漲\n漣\n漕\n漫\n漯\n澈\n漪\n滬\n漁\n滲\n滌\n滷\n熔\n熙\n煽\n熊\n熄\n熒\n爾\n犒\n犖\n獄\n獐\n瑤\n瑣\n瑪\n瑰\n瑭\n甄\n疑\n瘧\n瘍\n瘋\n瘉\n瘓\n盡\n監\n瞄\n睽\n睿\n睡\n磁\n碟\n碧\n碳\n碩\n碣\n禎\n福\n禍\n種\n稱\n窪\n窩\n竭\n端\n管\n箕\n箋\n筵\n算\n箝\n箔\n箏\n箇\n箄\n粹\n粽\n精\n綻\n綰\n綜\n綽\n綾\n綠\n緊\n綴\n網\n綱\n綺\n綢\n綿\n綵\n綸\n維\n緇\n綬\n罰\n翠\n翡\n翟\n聞\n聚\n肇\n腐\n膀\n膏\n膈\n膊\n腿\n膂\n臧\n臺\n與\n舔\n舞\n艋\n蓉\n蒿\n蓆\n蓄\n蒙\n蒞\n蒲\n蒜\n蓋\n蒸\n蓀\n蓓\n蒐\n蒼\n蓑\n蓊\n蜿\n蜜\n蜻\n蜢\n蜥\n蜴\n蜘\n蝕\n蜷\n蜩\n裳\n褂\n裴\n裹\n裸\n製\n裨\n褚\n裯\n誦\n誌\n語\n誣\n認\n誡\n誓\n誤\n說\n誥\n誨\n誘\n誑\n誚\n誧\n豪\n貍\n貌\n賓\n賑\n賒\n赫\n趙\n趕\n跼\n輔\n輒\n輕\n輓\n辣\n遠\n遘\n遜\n遣\n遙\n遞\n遢\n遝\n遛\n鄙\n鄘\n鄞\n酵\n酸\n酷\n酴\n鉸\n銀\n銅\n銘\n銖\n鉻\n銓\n銜\n銨\n鉼\n銑\n閡\n閨\n閩\n閣\n閥\n閤\n隙\n障\n際\n雌\n雒\n需\n靼\n鞅\n韶\n頗\n領\n颯\n颱\n餃\n餅\n餌\n餉\n駁\n骯\n骰\n髦\n魁\n魂\n鳴\n鳶\n鳳\n麼\n鼻\n齊\n億\n儀\n僻\n僵\n價\n儂\n儈\n儉\n儅\n凜\n劇\n劈\n劉\n劍\n劊\n勰\n厲\n嘮\n嘻\n嘹\n嘲\n嘿\n嘴\n嘩\n噓\n噎\n噗\n噴\n嘶\n嘯\n嘰\n墀\n墟\n增\n墳\n墜\n墮\n墩\n墦\n奭\n嬉\n嫻\n嬋\n嫵\n嬌\n嬈\n寮\n寬\n審\n寫\n層\n履\n嶝\n嶔\n幢\n幟\n幡\n廢\n廚\n廟\n廝\n廣\n廠\n彈\n影\n德\n徵\n慶\n慧\n慮\n慝\n慕\n憂\n慼\n慰\n慫\n慾\n憧\n憐\n憫\n憎\n憬\n憚\n憤\n憔\n憮\n戮\n摩\n摯\n摹\n撞\n撲\n撈\n撐\n撰\n撥\n撓\n撕\n撩\n撒\n撮\n播\n撫\n撚\n撬\n撙\n撢\n撳\n敵\n敷\n數\n暮\n暫\n暴\n暱\n樣\n樟\n槨\n樁\n樞\n標\n槽\n模\n樓\n樊\n槳\n樂\n樅\n槭\n樑\n歐\n歎\n殤\n毅\n毆\n漿\n潼\n澄\n潑\n潦\n潔\n澆\n潭\n潛\n潸\n潮\n澎\n潺\n潰\n潤\n澗\n潘\n滕\n潯\n潠\n潟\n熟\n熬\n熱\n熨\n牖\n犛\n獎\n獗\n瑩\n璋\n璃\n瑾\n璀\n畿\n瘠\n瘩\n瘟\n瘤\n瘦\n瘡\n瘢\n皚\n皺\n盤\n瞎\n瞇\n瞌\n瞑\n瞋\n磋\n磅\n確\n磊\n碾\n磕\n碼\n磐\n稿\n稼\n穀\n稽\n稷\n稻\n窯\n窮\n箭\n箱\n範\n箴\n篆\n篇\n篁\n箠\n篌\n糊\n締\n練\n緯\n緻\n緘\n緬\n緝\n編\n緣\n線\n緞\n緩\n綞\n緙\n緲\n緹\n罵\n罷\n羯\n翩\n耦\n膛\n膜\n膝\n膠\n膚\n膘\n蔗\n蔽\n蔚\n蓮\n蔬\n蔭\n蔓\n蔑\n蔣\n蔡\n蔔\n蓬\n蔥\n蓿\n蔆\n螂\n蝴\n蝶\n蝠\n蝦\n蝸\n蝨\n蝙\n蝗\n蝌\n蝓\n衛\n衝\n褐\n複\n褒\n褓\n褕\n褊\n誼\n諒\n談\n諄\n誕\n請\n諸\n課\n諉\n諂\n調\n誰\n論\n諍\n誶\n誹\n諛\n豌\n豎\n豬\n賠\n賞\n賦\n賤\n賬\n賭\n賢\n賣\n賜\n質\n賡\n赭\n趟\n趣\n踫\n踐\n踝\n踢\n踏\n踩\n踟\n踡\n踞\n躺\n輝\n輛\n輟\n輩\n輦\n輪\n輜\n輞\n輥\n適\n遮\n遨\n遭\n遷\n鄰\n鄭\n鄧\n鄱\n醇\n醉\n醋\n醃\n鋅\n銻\n銷\n鋪\n銬\n鋤\n鋁\n銳\n銼\n鋒\n鋇\n鋰\n銲\n閭\n閱\n霄\n霆\n震\n霉\n靠\n鞍\n鞋\n鞏\n頡\n頫\n頜\n颳\n養\n餓\n餒\n餘\n駝\n駐\n駟\n駛\n駑\n駕\n駒\n駙\n骷\n髮\n髯\n鬧\n魅\n魄\n魷\n魯\n鴆\n鴉\n鴃\n麩\n麾\n黎\n墨\n齒\n儒\n儘\n儔\n儐\n儕\n冀\n冪\n凝\n劑\n劓\n勳\n噙\n噫\n噹\n噩\n噤\n噸\n噪\n器\n噥\n噱\n噯\n噬\n噢\n噶\n壁\n墾\n壇\n壅\n奮\n嬝\n嬴\n學\n寰\n導\n彊\n憲\n憑\n憩\n憊\n懍\n憶\n憾\n懊\n懈\n戰\n擅\n擁\n擋\n撻\n撼\n據\n擄\n擇\n擂\n操\n撿\n擒\n擔\n撾\n整\n曆\n曉\n暹\n曄\n曇\n暸\n樽\n樸\n樺\n橙\n橫\n橘\n樹\n橄\n橢\n橡\n橋\n橇\n樵\n機\n橈\n歙\n歷\n氅\n濂\n澱\n澡\n濃\n澤\n濁\n澧\n澳\n激\n澹\n澦\n澠\n澴\n熾\n燉\n燐\n燒\n燈\n燕\n熹\n燎\n燙\n燜\n燃\n燄\n獨\n璜\n璣\n璘\n璟\n璞\n瓢\n甌\n甍\n瘴\n瘸\n瘺\n盧\n盥\n瞠\n瞞\n瞟\n瞥\n磨\n磚\n磬\n磧\n禦\n積\n穎\n穆\n穌\n穋\n窺\n篙\n簑\n築\n篤\n篛\n篡\n篩\n篦\n糕\n糖\n縊\n縑\n縈\n縛\n縣\n縞\n縉\n縐\n罹\n羲\n翰\n翱\n翮\n膳\n膩\n膨\n臻\n興\n艘\n艙\n蕊\n蕙\n蕈\n蕨\n蕩\n蕃\n蕉\n蕭\n蕪\n蕞\n螃\n螟\n螞\n螢\n融\n衡\n褪\n褲\n褥\n褫\n褡\n親\n諦\n諺\n諫\n諱\n謀\n諜\n諧\n諮\n諾\n謁\n謂\n諷\n諭\n諳\n諶\n諼\n豫\n豭\n貓\n賴\n蹄\n踱\n踴\n蹂\n踹\n踵\n輻\n輯\n輸\n輳\n辨\n辦\n遵\n遴\n選\n遲\n遼\n遺\n鄴\n醒\n錠\n錶\n鋸\n錳\n錯\n錢\n鋼\n錫\n錄\n錚\n錐\n錦\n錡\n錕\n錮\n錙\n閻\n隧\n隨\n險\n雕\n霎\n霑\n霖\n霍\n霓\n霏\n靛\n靦\n鞘\n頰\n頸\n頻\n頷\n頭\n頹\n頤\n餐\n館\n餞\n餛\n餡\n餚\n駭\n駢\n駱\n骸\n骼\n髻\n髭\n鬨\n鮑\n鴕\n鴣\n鴦\n鴨\n鴒\n鴛\n默\n黔\n龍\n龜\n優\n償\n儡\n儲\n勵\n嚎\n嚀\n嚐\n嚅\n嚇\n嚏\n壕\n壓\n壑\n壎\n嬰\n嬪\n嬤\n孺\n尷\n屨\n嶼\n嶺\n嶽\n嶸\n幫\n彌\n徽\n應\n懂\n懇\n懦\n懋\n戲\n戴\n擎\n擊\n擘\n擠\n擰\n擦\n擬\n擱\n擢\n擭\n斂\n斃\n曙\n曖\n檀\n檔\n檄\n檢\n檜\n櫛\n檣\n橾\n檗\n檐\n檠\n歜\n殮\n毚\n氈\n濘\n濱\n濟\n濠\n濛\n濤\n濫\n濯\n澀\n濬\n濡\n濩\n濕\n濮\n濰\n燧\n燮\n燦\n燥\n燭\n燬\n燴\n燠\n爵\n牆\n獰\n獲\n璩\n環\n璦\n璨\n癆\n療\n癌\n盪\n瞳\n瞪\n瞰\n瞬\n瞧\n瞭\n矯\n磷\n磺\n磴\n磯\n礁\n禧\n禪\n穗\n窿\n簇\n簍\n篾\n篷\n簌\n篠\n糠\n糜\n糞\n糢\n糟\n糙\n糝\n縮\n績\n繆\n縷\n縲\n繃\n縫\n總\n縱\n繅\n繁\n縴\n縹\n繈\n縵\n縿\n縯\n罄\n翳\n翼\n聱\n聲\n聰\n聯\n聳\n臆\n臃\n膺\n臂\n臀\n膿\n膽\n臉\n膾\n臨\n舉\n艱\n薪\n薄\n蕾\n薜\n薑\n薔\n薯\n薛\n薇\n薨\n薊\n虧\n蟀\n蟑\n螳\n蟒\n蟆\n螫\n螻\n螺\n蟈\n蟋\n褻\n褶\n襄\n褸\n褽\n覬\n謎\n謗\n謙\n講\n謊\n謠\n謝\n謄\n謐\n豁\n谿\n豳\n賺\n賽\n購\n賸\n賻\n趨\n蹉\n蹋\n蹈\n蹊\n轄\n輾\n轂\n轅\n輿\n避\n遽\n還\n邁\n邂\n邀\n鄹\n醣\n醞\n醜\n鍍\n鎂\n錨\n鍵\n鍊\n鍥\n鍋\n錘\n鍾\n鍬\n鍛\n鍰\n鍚\n鍔\n闊\n闋\n闌\n闈\n闆\n隱\n隸\n雖\n霜\n霞\n鞠\n韓\n顆\n颶\n餵\n騁\n駿\n鮮\n鮫\n鮪\n鮭\n鴻\n鴿\n麋\n黏\n點\n黜\n黝\n黛\n鼾\n齋\n叢\n嚕\n嚮\n壙\n壘\n嬸\n彝\n懣\n戳\n擴\n擲\n擾\n攆\n擺\n擻\n擷\n斷\n曜\n朦\n檳\n檬\n櫃\n檻\n檸\n櫂\n檮\n檯\n歟\n歸\n殯\n瀉\n瀋\n濾\n瀆\n濺\n瀑\n瀏\n燻\n燼\n燾\n燸\n獷\n獵\n璧\n璿\n甕\n癖\n癘\n癒\n瞽\n瞿\n瞻\n瞼\n礎\n禮\n穡\n穢\n穠\n竄\n竅\n簫\n簧\n簪\n簞\n簣\n簡\n糧\n織\n繕\n繞\n繚\n繡\n繒\n繙\n罈\n翹\n翻\n職\n聶\n臍\n臏\n舊\n藏\n薩\n藍\n藐\n藉\n薰\n薺\n薹\n薦\n蟯\n蟬\n蟲\n蟠\n覆\n覲\n觴\n謨\n謹\n謬\n謫\n豐\n贅\n蹙\n蹣\n蹦\n蹤\n蹟\n蹕\n軀\n轉\n轍\n邇\n邃\n邈\n醫\n醬\n釐\n鎔\n鎊\n鎖\n鎢\n鎳\n鎮\n鎬\n鎰\n鎘\n鎚\n鎗\n闔\n闖\n闐\n闕\n離\n雜\n雙\n雛\n雞\n霤\n鞣\n鞦\n鞭\n韹\n額\n顏\n題\n顎\n顓\n颺\n餾\n餿\n餽\n餮\n馥\n騎\n髁\n鬃\n鬆\n魏\n魎\n魍\n鯊\n鯉\n鯽\n鯈\n鯀\n鵑\n鵝\n鵠\n黠\n鼕\n鼬\n儳\n嚥\n壞\n壟\n壢\n寵\n龐\n廬\n懲\n懷\n懶\n懵\n攀\n攏\n曠\n曝\n櫥\n櫝\n櫚\n櫓\n瀛\n瀟\n瀨\n瀚\n瀝\n瀕\n瀘\n爆\n爍\n牘\n犢\n獸\n獺\n璽\n瓊\n瓣\n疇\n疆\n癟\n癡\n矇\n礙\n禱\n穫\n穩\n簾\n簿\n簸\n簽\n簷\n籀\n繫\n繭\n繹\n繩\n繪\n羅\n繳\n羶\n羹\n羸\n臘\n藩\n藝\n藪\n藕\n藤\n藥\n藷\n蟻\n蠅\n蠍\n蟹\n蟾\n襠\n襟\n襖\n襞\n譁\n譜\n識\n證\n譚\n譎\n譏\n譆\n譙\n贈\n贊\n蹼\n蹲\n躇\n蹶\n蹬\n蹺\n蹴\n轔\n轎\n辭\n邊\n邋\n醱\n醮\n鏡\n鏑\n鏟\n鏃\n鏈\n鏜\n鏝\n鏖\n鏢\n鏍\n鏘\n鏤\n鏗\n鏨\n關\n隴\n難\n霪\n霧\n靡\n韜\n韻\n類\n願\n顛\n颼\n饅\n饉\n騖\n騙\n鬍\n鯨\n鯧\n鯖\n鯛\n鶉\n鵡\n鵲\n鵪\n鵬\n麒\n麗\n麓\n麴\n勸\n嚨\n嚷\n嚶\n嚴\n嚼\n壤\n孀\n孃\n孽\n寶\n巉\n懸\n懺\n攘\n攔\n攙\n曦\n朧\n櫬\n瀾\n瀰\n瀲\n爐\n獻\n瓏\n癢\n癥\n礦\n礪\n礬\n礫\n竇\n競\n籌\n籃\n籍\n糯\n糰\n辮\n繽\n繼\n纂\n罌\n耀\n臚\n艦\n藻\n藹\n蘑\n藺\n蘆\n蘋\n蘇\n蘊\n蠔\n蠕\n襤\n覺\n觸\n議\n譬\n警\n譯\n譟\n譫\n贏\n贍\n躉\n躁\n躅\n躂\n醴\n釋\n鐘\n鐃\n鏽\n闡\n霰\n飄\n饒\n饑\n馨\n騫\n騰\n騷\n騵\n鰓\n鰍\n鹹\n麵\n黨\n鼯\n齟\n齣\n齡\n儷\n儸\n囁\n囀\n囂\n夔\n屬\n巍\n懼\n懾\n攝\n攜\n斕\n曩\n櫻\n欄\n櫺\n殲\n灌\n爛\n犧\n瓖\n瓔\n癩\n矓\n籐\n纏\n續\n羼\n蘗\n蘭\n蘚\n蠣\n蠢\n蠡\n蠟\n襪\n襬\n覽\n譴\n護\n譽\n贓\n躊\n躍\n躋\n轟\n辯\n醺\n鐮\n鐳\n鐵\n鐺\n鐸\n鐲\n鐫\n闢\n霸\n霹\n露\n顧\n顥\n饗\n驅\n驃\n驀\n騾\n髏\n魔\n魑\n鰭\n鰥\n鶯\n鶴\n鷂\n鶸\n麝\n黯\n鼙\n齜\n齦\n齧\n儼\n儻\n囈\n囊\n囉\n孿\n巔\n巒\n彎\n懿\n攤\n權\n歡\n灑\n灘\n玀\n瓤\n疊\n癮\n癬\n禳\n籠\n籟\n聾\n聽\n臟\n襲\n襯\n觼\n讀\n贖\n贗\n躑\n躓\n轡\n酈\n鑄\n鑑\n鑒\n霽\n霾\n韃\n韁\n顫\n饕\n驕\n驍\n髒\n鬚\n鱉\n鰱\n鰾\n鰻\n鷓\n鷗\n鼴\n齬\n齪\n龔\n囌\n巖\n戀\n攣\n攫\n攪\n曬\n欐\n瓚\n竊\n籤\n籣\n籥\n纓\n纖\n纔\n臢\n蘸\n蘿\n蠱\n變\n邐\n邏\n鑣\n鑠\n鑤\n靨\n顯\n饜\n驚\n驛\n驗\n髓\n體\n髑\n鱔\n鱗\n鱖\n鷥\n麟\n黴\n囑\n壩\n攬\n灞\n癱\n癲\n罐\n羈\n蠶\n蠹\n衢\n讓\n讒\n讖\n艷\n贛\n釀\n鑪\n靂\n靈\n靄\n韆\n顰\n驟\n鬢\n魘\n鱟\n鷹\n鷺\n鹼\n鹽\n鼇\n齷\n齲\n廳\n欖\n灣\n籬\n籮\n蠻\n觀\n躡\n釁\n鑲\n鑰\n顱\n饞\n髖\n鬣\n黌\n灤\n矚\n讚\n鑷\n韉\n驢\n驥\n纜\n讜\n躪\n釅\n鑽\n鑾\n鑼\n鱷\n鱸\n黷\n豔\n鑿\n鸚\n爨\n驪\n鬱\n鸛\n鸞\n籲\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n⑴\n⑵\n⑶\n⑷\n⑸\n⑹\n⑺\n⑻\n⑼\n⑽\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\n丶\n丿\n亅\n亠\n冂\n冖\n冫\n勹\n匸\n卩\n厶\n夊\n宀\n巛\n⼳\n广\n廴\n彐\n彡\n攴\n无\n疒\n癶\n辵\n¨\nˆ\nヽ\nヾ\nゝ\nゞ\n仝\n々\n〆\n〇\nー\n［\n］\n✽\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n⇧\n↸\n↹\n㇏\n𠃌\n乚\n𠂊\n刂\n䒑\n龰\n冈\n龱\n𧘇\n￢\n￤\n＇\n＂\n㈱\n№\n℡\n゛\n゜\n⺀\n⺄\n⺆\n⺇\n⺈\n⺊\n⺌\n⺍\n⺕\n⺜\n⺝\n⺥\n⺧\n⺪\n⺬\n⺮\n⺶\n⺼\n⺾\n⻆\n⻊\n⻌\n⻍\n⻏\n⻖\n⻗\n⻞\n⻣\nʃ\nɐ\nɛ\nɔ\nɵ\nœ\nø\nŋ\nʊ\nɪ\n乂\n乜\n凵\n匚\n厂\n万\n丌\n乇\n亍\n囗\n兀\n屮\n彳\n丏\n冇\n与\n丮\n亓\n仂\n仉\n仈\n冘\n勼\n卬\n厹\n圠\n夃\n夬\n巿\n旡\n殳\n毌\n气\n爿\n丱\n丼\n仨\n仜\n仩\n仡\n仚\n刌\n匜\n卌\n圢\n圣\n夗\n夯\n宁\n宄\n尒\n尻\n屴\n屳\n帄\n庀\n庂\n忉\n戉\n扐\n氕\n氶\n汃\n氿\n氻\n犮\n犰\n玊\n禸\n肊\n阞\n伎\n优\n伬\n仵\n伔\n仱\n伀\n价\n伈\n伝\n伂\n伅\n伢\n伓\n伄\n仴\n伒\n冱\n刓\n刉\n刐\n劦\n匢\n匟\n卍\n厊\n吇\n囡\n囟\n圮\n圪\n圴\n夼\n妀\n奼\n妅\n奻\n奾\n奷\n奿\n孖\n尕\n尥\n屼\n屺\n屻\n屾\n巟\n幵\n庄\n异\n弚\n彴\n忕\n忔\n忏\n扜\n扞\n扤\n扡\n扦\n扢\n扙\n扠\n扚\n扥\n旯\n旮\n朾\n朹\n朸\n朻\n机\n朿\n朼\n朳\n氘\n汆\n汒\n汜\n汏\n汔\n汋\n汌\n灱\n牞\n犴\n犵\n玎\n甪\n癿\n穵\n网\n艸\n艼\n芀\n艽\n艿\n虍\n襾\n邙\n邘\n邛\n邔\n阢\n阤\n阠\n阣\n佖\n伻\n佢\n佉\n体\n佤\n伾\n佧\n佒\n佟\n佁\n佘\n伭\n伳\n伿\n佡\n冏\n冹\n刜\n刞\n刡\n劭\n劮\n匉\n卣\n卲\n厎\n厏\n吰\n吷\n吪\n呔\n呅\n吙\n吜\n吥\n吘\n吽\n呏\n呁\n吨\n吤\n呇\n囮\n囧\n囥\n坁\n坅\n坌\n坉\n坋\n坒\n夆\n奀\n妦\n妘\n妠\n妗\n妎\n妢\n妐\n妏\n妧\n妡\n宎\n宒\n尨\n尪\n岍\n岏\n岈\n岋\n岉\n岒\n岊\n岆\n岓\n岕\n巠\n帊\n帎\n庋\n庉\n庌\n庈\n庍\n弅\n弝\n彸\n彶\n忒\n忑\n忐\n忭\n忨\n忮\n忳\n忡\n忤\n忣\n忺\n忯\n忷\n忻\n怀\n忴\n戺\n抃\n抌\n抎\n抏\n抔\n抇\n扱\n扻\n扺\n扰\n抁\n抈\n扷\n扽\n扲\n扴\n攷\n旰\n旴\n旳\n旲\n旵\n杅\n杇\n杙\n杕\n杌\n杈\n杝\n杍\n杚\n杋\n毐\n氙\n氚\n汸\n汧\n汫\n沄\n沋\n沏\n汱\n汯\n汩\n沚\n汭\n沇\n沕\n沜\n汦\n汳\n汥\n汻\n沎\n灴\n灺\n牣\n犿\n犽\n狃\n狆\n狁\n犺\n狅\n玕\n玗\n玓\n玔\n玒\n町\n甹\n疔\n疕\n皁\n礽\n耴\n肕\n肙\n肐\n肒\n肜\n芐\n芏\n芅\n芎\n芑\n芓\n芊\n芃\n芄\n豸\n迉\n辿\n邟\n邡\n邥\n邞\n邧\n邠\n阰\n阨\n阯\n阭\n丳\n侘\n佼\n侅\n佽\n侀\n侇\n佶\n佴\n侉\n侄\n佷\n佌\n侗\n佪\n侚\n佹\n侁\n佸\n侐\n侜\n侔\n侞\n侒\n侂\n侕\n佫\n佮\n冞\n冼\n冾\n刵\n刲\n刳\n剆\n刱\n劼\n匊\n匋\n匼\n厒\n厔\n咇\n呿\n咁\n咑\n咂\n咈\n呫\n呺\n呾\n呥\n呬\n呴\n呦\n咍\n呯\n呡\n呠\n咘\n呣\n呧\n呤\n囷\n囹\n坯\n坲\n坭\n坫\n坱\n坰\n坶\n垀\n坵\n坻\n坳\n坴\n坢\n坨\n坽\n夌\n奅\n妵\n妺\n姏\n姎\n妲\n姌\n姁\n妶\n妼\n姃\n姖\n妱\n妽\n姀\n姈\n妴\n姇\n孢\n孥\n宓\n宕\n屄\n屇\n岮\n岤\n岠\n岵\n岯\n岨\n岬\n岟\n岣\n岭\n岢\n岪\n岧\n岝\n岥\n岶\n岰\n岦\n帗\n帔\n帙\n弨\n弢\n弣\n弤\n彔\n徂\n彾\n彽\n忞\n忥\n怭\n怦\n怙\n怲\n怋\n怴\n怊\n怗\n怳\n怚\n怞\n怬\n怢\n怍\n怐\n怮\n怓\n怑\n怌\n怉\n怜\n戔\n戽\n抭\n抴\n拑\n抾\n抪\n抶\n拊\n抮\n抳\n抯\n抻\n抩\n抰\n抸\n攽\n斨\n斻\n昉\n旼\n昄\n昒\n昈\n旻\n昃\n昋\n昍\n昅\n旽\n昑\n昐\n曶\n朊\n枅\n杬\n枎\n枒\n杶\n杻\n枘\n枆\n构\n杴\n枍\n枌\n杺\n枟\n枑\n枙\n枃\n杽\n极\n杸\n杹\n枔\n欥\n殀\n歾\n毞\n氝\n沓\n泬\n泫\n泮\n泙\n沶\n泔\n沭\n泧\n沷\n泐\n泂\n沺\n泃\n泆\n泭\n泲\n泒\n泝\n沴\n沊\n沝\n沀\n泞\n泀\n洰\n泍\n泇\n沰\n泹\n泏\n泩\n泑\n炔\n炘\n炅\n炓\n炆\n炄\n炑\n炖\n炂\n炚\n炃\n牪\n狖\n狋\n狘\n狉\n狜\n狒\n狔\n狚\n狌\n狑\n玤\n玡\n玭\n玦\n玢\n玠\n玬\n玝\n瓝\n瓨\n甿\n畀\n甾\n疌\n疘\n皯\n盳\n盱\n盰\n盵\n矸\n矼\n矹\n矻\n矺\n矷\n祂\n礿\n秅\n穸\n穻\n竻\n籵\n糽\n耵\n肏\n肮\n肣\n肸\n肵\n肭\n舠\n芠\n苀\n芫\n芚\n芘\n芛\n芵\n芧\n芮\n芼\n芞\n芺\n芴\n芨\n芡\n芩\n苂\n芤\n苃\n芶\n芢\n虰\n虯\n虭\n虮\n豖\n迒\n迋\n迓\n迍\n迖\n迕\n迗\n邲\n邴\n邯\n邳\n邰\n阹\n阽\n阼\n阺\n陃\n俍\n俅\n俓\n侲\n俉\n俋\n俁\n俔\n俜\n俙\n侳\n俛\n俇\n俖\n侺\n俀\n侹\n俬\n剄\n剉\n勀\n勂\n匽\n卼\n厗\n厖\n厙\n厘\n咺\n咡\n咭\n咥\n哏\n哃\n茍\n咷\n咮\n哖\n咶\n哅\n哆\n咠\n呰\n咼\n咢\n咾\n呲\n哞\n咰\n垵\n垞\n垟\n垤\n垌\n垗\n垝\n垛\n垔\n垘\n垏\n垙\n垥\n垚\n垕\n壴\n复\n奓\n姡\n姞\n姮\n娀\n姱\n姝\n姺\n姽\n姼\n姶\n姤\n姲\n姷\n姛\n姩\n姳\n姵\n姠\n姾\n姴\n姭\n宨\n屌\n峐\n峘\n峌\n峗\n峋\n峛\n峞\n峚\n峉\n峇\n峊\n峖\n峓\n峔\n峏\n峈\n峆\n峎\n峟\n峸\n巹\n帡\n帢\n帣\n帠\n帤\n庰\n庤\n庢\n庛\n庣\n庥\n弇\n弮\n彖\n徆\n怷\n怹\n恔\n恲\n恞\n恅\n恓\n恇\n恉\n恛\n恌\n恀\n恂\n恟\n怤\n恄\n恘\n恦\n恮\n扂\n扃\n拏\n挍\n挋\n拵\n挎\n挃\n拫\n拹\n挏\n挌\n拸\n拶\n挀\n挓\n挔\n拺\n挕\n拻\n拰\n敁\n敃\n斪\n斿\n昶\n昡\n昲\n昵\n昜\n昦\n昢\n昳\n昫\n昺\n昝\n昴\n昹\n昮\n朏\n朐\n柁\n柲\n柈\n枺\n柜\n枻\n柸\n柘\n柀\n枷\n柅\n柫\n柤\n柟\n枵\n柍\n枳\n柷\n柶\n柮\n柣\n柂\n枹\n柎\n柧\n柰\n枲\n柼\n柆\n柭\n柌\n枮\n柦\n柛\n柺\n柉\n柊\n柃\n柪\n柋\n欨\n殂\n殄\n殶\n毖\n毘\n毠\n氠\n氡\n洨\n洴\n洭\n洟\n洼\n洿\n洒\n洊\n泚\n洳\n洄\n洙\n洺\n洚\n洑\n洀\n洝\n浂\n洁\n洘\n洷\n洃\n洏\n浀\n洇\n洠\n洬\n洈\n洢\n洉\n洐\n炷\n炟\n炾\n炱\n炰\n炡\n炴\n炵\n炩\n牁\n牉\n牊\n牬\n牰\n牳\n牮\n狊\n狤\n狨\n狫\n狟\n狪\n狦\n狣\n玅\n珌\n珂\n珈\n珅\n玹\n玶\n玵\n玴\n珫\n玿\n珇\n玾\n珃\n珆\n玸\n珋\n瓬\n瓮\n甮\n畇\n畈\n疧\n疪\n癹\n盄\n眈\n眃\n眄\n眅\n眊\n盷\n盻\n盺\n矧\n矨\n砆\n砑\n砒\n砅\n砐\n砏\n砎\n砉\n砃\n砓\n祊\n祌\n祋\n祅\n祄\n秕\n种\n秏\n秖\n秎\n窀\n穾\n竑\n笀\n笁\n籺\n籸\n籹\n籿\n粀\n粁\n紃\n紈\n紁\n罘\n羑\n羍\n羾\n耇\n耎\n耏\n耔\n耷\n胘\n胇\n胠\n胑\n胈\n胂\n胐\n胅\n胣\n胙\n胜\n胊\n胕\n胉\n胏\n胗\n胦\n胍\n臿\n舡\n芔\n苙\n苾\n苹\n茇\n苨\n茀\n苕\n茺\n苫\n苖\n苴\n苬\n苡\n苲\n苵\n茌\n苻\n苶\n苰\n苪\n苤\n苠\n苺\n苳\n苭\n虷\n虴\n虼\n虳\n衁\n衎\n衧\n衪\n衩\n觓\n訄\n訇\n赲\n迣\n迡\n迮\n迠\n郱\n邽\n邿\n郕\n郅\n邾\n郇\n郋\n郈\n釓\n陔\n陏\n陑\n陓\n陊\n陎\n倞\n倅\n倇\n倓\n倢\n倰\n倛\n俵\n俴\n倳\n倷\n倬\n俶\n俷\n倗\n倜\n倠\n倧\n倵\n倯\n倱\n倎\n党\n冔\n冓\n凊\n凄\n凅\n凈\n凎\n剡\n剚\n剒\n剞\n剟\n剕\n剢\n勍\n匎\n厞\n唦\n哢\n唗\n唒\n哧\n哳\n哤\n唚\n哿\n唄\n唈\n哫\n唑\n唅\n哱\n唊\n哻\n哷\n哸\n哠\n唎\n唃\n唋\n圁\n圂\n埌\n堲\n埕\n埒\n垺\n埆\n垽\n垼\n垸\n垶\n垿\n埇\n埐\n垹\n埁\n夎\n奊\n娙\n娖\n娭\n娮\n娕\n娏\n娗\n娊\n娞\n娳\n孬\n宧\n宭\n宬\n尃\n屖\n屔\n峬\n峿\n峮\n峱\n峷\n崀\n峹\n帩\n帨\n庨\n庮\n庪\n庬\n弳\n弰\n彧\n恝\n恚\n恧\n恁\n悢\n悈\n悀\n悒\n悁\n悝\n悃\n悕\n悛\n悗\n悇\n悜\n悎\n戙\n扆\n拲\n挐\n捖\n挬\n捄\n捅\n挶\n捃\n揤\n挹\n捋\n捊\n挼\n挩\n捁\n挴\n捘\n捔\n捙\n挭\n捇\n挳\n捚\n捑\n挸\n捗\n捀\n捈\n敊\n敆\n旆\n旃\n旄\n旂\n晊\n晟\n晇\n晑\n朒\n朓\n栟\n栚\n桉\n栲\n栳\n栻\n桋\n桏\n栖\n栱\n栜\n栵\n栫\n栭\n栯\n桎\n桄\n栴\n栝\n栒\n栔\n栦\n栨\n栮\n桍\n栺\n栥\n栠\n欬\n欯\n欭\n欱\n欴\n歭\n肂\n殈\n毦\n毤\n毨\n毣\n毢\n毧\n氥\n浺\n浣\n浤\n浶\n洍\n浡\n涒\n浘\n浢\n浭\n浯\n涑\n涍\n淯\n浿\n涆\n浞\n浠\n涗\n浰\n浼\n浟\n涂\n涘\n洯\n浨\n涋\n浾\n涀\n涄\n洖\n涃\n浻\n浽\n浵\n涐\n烜\n烓\n烑\n烝\n烋\n缹\n烢\n烗\n烒\n烞\n烠\n烔\n烍\n烅\n烆\n烇\n烚\n烎\n烡\n牂\n牸\n牷\n牶\n猀\n狺\n狴\n狾\n狶\n狳\n狻\n猁\n珓\n珙\n珥\n珖\n玼\n珧\n珣\n珩\n珜\n珒\n珛\n珔\n珝\n珚\n珗\n珘\n珨\n瓞\n瓟\n瓴\n瓵\n甡\n畛\n畟\n疰\n痁\n疻\n痄\n痀\n疿\n疶\n疺\n皊\n盉\n眝\n眛\n眐\n眓\n眒\n眣\n眑\n眕\n眙\n眚\n眢\n眧\n砣\n砬\n砢\n砵\n砯\n砨\n砮\n砫\n砡\n砩\n砳\n砪\n砱\n祔\n祛\n祏\n祜\n祓\n祒\n祑\n秫\n秬\n秠\n秮\n秭\n秪\n秜\n秞\n秝\n窆\n窉\n窅\n窋\n窌\n窊\n窇\n竘\n笐\n笄\n笓\n笅\n笏\n笈\n笊\n笎\n笉\n笒\n粄\n粑\n粊\n粌\n粈\n粍\n粅\n紞\n紝\n紑\n紎\n紘\n紖\n紓\n紟\n紒\n紏\n紌\n罜\n罡\n罞\n罠\n罝\n罛\n羖\n羒\n翃\n翂\n翀\n耖\n耾\n耹\n胺\n胲\n胹\n胵\n脁\n胻\n脀\n舁\n舯\n舥\n茳\n茭\n荄\n茙\n荑\n茥\n荖\n茿\n荁\n茦\n茜\n茢\n荂\n荎\n茛\n茪\n茈\n茼\n荍\n茖\n茤\n茠\n茷\n茯\n茩\n荇\n荅\n荌\n荓\n茞\n茬\n荋\n茧\n荈\n虓\n虒\n蚢\n蚨\n蚖\n蚍\n蚑\n蚞\n蚇\n蚗\n蚆\n蚋\n蚚\n蚅\n蚥\n蚙\n蚡\n蚧\n蚕\n蚘\n蚎\n蚝\n蚐\n蚔\n衃\n衄\n衭\n衵\n衶\n衲\n袀\n衱\n衿\n衯\n袃\n衾\n衴\n衼\n訒\n豇\n豗\n豻\n貤\n貣\n赶\n赸\n趵\n趷\n趶\n軑\n軓\n迾\n迵\n适\n迿\n迻\n逄\n迼\n迶\n郖\n郠\n郙\n郚\n郣\n郟\n郥\n郘\n郛\n郗\n郜\n郤\n酐\n酎\n酏\n釕\n釢\n釚\n陜\n陟\n隼\n飣\n髟\n鬯\n乿\n偰\n偪\n偡\n偞\n偠\n偓\n偋\n偝\n偲\n偈\n偍\n偁\n偛\n偊\n偢\n倕\n偅\n偟\n偩\n偫\n偣\n偤\n偆\n偀\n偮\n偳\n偗\n偑\n凐\n剫\n剭\n剬\n剮\n勖\n勓\n匭\n厜\n啵\n啶\n唼\n啍\n啐\n唴\n唪\n啑\n啢\n唶\n唵\n唰\n啒\n啅\n唌\n唲\n啥\n啎\n唹\n啈\n唭\n唻\n啀\n啋\n圊\n圇\n埻\n堔\n埢\n埶\n埜\n埴\n堀\n埭\n埽\n堈\n埸\n堋\n埳\n埏\n堇\n埮\n埣\n埲\n埥\n埬\n埡\n堎\n埼\n堐\n埧\n堁\n堌\n埱\n埩\n埰\n堍\n堄\n奜\n婠\n婘\n婕\n婞\n娸\n娵\n婭\n婐\n婟\n婥\n婬\n婓\n婤\n婗\n婃\n婝\n婒\n婄\n婛\n婈\n媎\n娾\n婍\n娹\n婌\n婰\n婩\n婇\n婑\n婖\n婂\n婜\n孲\n孮\n寁\n寀\n屙\n崞\n崋\n崝\n崚\n崠\n崌\n崨\n崍\n崦\n崥\n崏\n崰\n崒\n崣\n崟\n崮\n帾\n帴\n庱\n庴\n庹\n庲\n庳\n弶\n弸\n徛\n徖\n徟\n悊\n悐\n悆\n悾\n悰\n悺\n惓\n惔\n惏\n惤\n惙\n惝\n惈\n悱\n惛\n悷\n惊\n悿\n惃\n惍\n惀\n挲\n捥\n掊\n掂\n捽\n掽\n掞\n掭\n掝\n掗\n掫\n掎\n捯\n掇\n掐\n据\n掯\n捵\n掜\n捭\n掮\n捼\n掤\n挻\n掟\n捸\n掅\n掁\n掑\n掍\n捰\n敓\n旍\n晥\n晡\n晛\n晙\n晜\n晢\n朘\n桹\n梇\n梐\n梜\n桭\n桮\n梮\n梫\n楖\n桯\n梣\n梬\n梩\n桵\n桴\n梲\n梏\n桷\n梒\n桼\n桫\n桲\n梪\n梀\n桱\n桾\n梛\n梖\n梋\n梠\n梉\n梤\n桸\n桻\n梑\n梌\n梊\n桽\n欶\n欳\n欷\n欸\n殑\n殏\n殍\n殎\n殌\n氪\n淀\n涫\n涴\n涳\n湴\n涬\n淩\n淢\n涷\n淶\n淔\n渀\n淈\n淠\n淟\n淖\n涾\n淥\n淜\n淝\n淛\n淴\n淊\n涽\n淭\n淰\n涺\n淕\n淂\n淏\n淉\n淐\n淲\n淓\n淽\n淗\n淍\n淣\n涻\n烺\n焍\n烷\n焗\n烴\n焌\n烰\n焄\n烳\n焐\n烼\n烿\n焆\n焓\n焀\n烸\n烶\n焋\n焂\n焎\n牾\n牻\n牼\n牿\n猝\n猗\n猇\n猑\n猘\n猊\n猈\n狿\n猏\n猞\n玈\n珶\n珸\n珵\n琄\n琁\n珽\n琇\n琀\n珺\n珼\n珿\n琌\n琋\n珴\n琈\n畤\n畣\n痎\n痒\n痏\n痋\n痌\n痑\n痐\n皏\n皉\n盓\n眹\n眯\n眭\n眱\n眲\n眴\n眳\n眽\n眥\n眻\n眵\n硈\n硒\n硉\n硍\n硊\n硌\n砦\n硅\n硐\n祤\n祧\n祩\n祪\n祣\n祫\n祡\n离\n秺\n秸\n秶\n秷\n窏\n窔\n窐\n笵\n筇\n笴\n笥\n笰\n笢\n笤\n笳\n笘\n笪\n笝\n笱\n笫\n笭\n笯\n笲\n笸\n笚\n笣\n粔\n粘\n粖\n粣\n紵\n紽\n紸\n紶\n紺\n絅\n紬\n紩\n絁\n絇\n紾\n紿\n絊\n紻\n紨\n罣\n羕\n羜\n羝\n羛\n翊\n翋\n翍\n翐\n翑\n翇\n翏\n翉\n耟\n耞\n耛\n聇\n聃\n聈\n脘\n脥\n脙\n脛\n脭\n脟\n脬\n脞\n脡\n脕\n脧\n脝\n脢\n舑\n舸\n舳\n舺\n舴\n舲\n艴\n莐\n莣\n莨\n莍\n荺\n荳\n莤\n荴\n莏\n莁\n莕\n莙\n荵\n莔\n莩\n荽\n莃\n莌\n莝\n莛\n莪\n莋\n荾\n莥\n莯\n莈\n莗\n莰\n荿\n莦\n莇\n莮\n荶\n莚\n虙\n虖\n蚿\n蚷\n蛂\n蛁\n蛅\n蚺\n蚰\n蛈\n蚹\n蚳\n蚸\n蛌\n蚴\n蚻\n蚼\n蛃\n蚽\n蚾\n衒\n袉\n袕\n袨\n袢\n袪\n袚\n袑\n袡\n袟\n袘\n袧\n袙\n袛\n袗\n袤\n袬\n袌\n袓\n袎\n覂\n觖\n觙\n觕\n訰\n訧\n訬\n訞\n谹\n谻\n豜\n豝\n豽\n貥\n赽\n赻\n赹\n趼\n跂\n趹\n趿\n跁\n軘\n軞\n軝\n軜\n軗\n軠\n軡\n逤\n逋\n逑\n逜\n逌\n逡\n郯\n郪\n郰\n郴\n郲\n郳\n郔\n郫\n郬\n郩\n酖\n酘\n酚\n酓\n酕\n釬\n釴\n釱\n釳\n釸\n釤\n釹\n釪\n釫\n釷\n釨\n釮\n镺\n閆\n閈\n陼\n陭\n陫\n陱\n陯\n隿\n靪\n頄\n飥\n馗\n傛\n傕\n傔\n傞\n傋\n傣\n傃\n傌\n傎\n傝\n偨\n傜\n傒\n傂\n傇\n兟\n凔\n匒\n匑\n厤\n厧\n喑\n喨\n喥\n喭\n啷\n噅\n喢\n喓\n喈\n喏\n喵\n喁\n喣\n喒\n喤\n啽\n喌\n喦\n啿\n喕\n喡\n喎\n圌\n堩\n堷\n堙\n堞\n堧\n堣\n堨\n埵\n塈\n堥\n堜\n堛\n堳\n堿\n堶\n堮\n堹\n堸\n堭\n堬\n堻\n奡\n媯\n媔\n媟\n婺\n媢\n媞\n婸\n媦\n婼\n媥\n媬\n媕\n媮\n娷\n媄\n媊\n媗\n媃\n媋\n媩\n婻\n婽\n媌\n媜\n媏\n媓\n媝\n寪\n寍\n寋\n寔\n寑\n寊\n寎\n尌\n尰\n崷\n嵃\n嵫\n嵁\n嵋\n崿\n崵\n嵑\n嵎\n嵕\n崳\n崺\n嵒\n崽\n崱\n嵙\n嵂\n崹\n嵉\n崸\n崼\n崲\n崶\n嵀\n嵅\n幄\n幁\n彘\n徦\n徥\n徫\n惉\n悹\n惌\n惢\n惎\n惄\n愔\n惲\n愊\n愖\n愅\n惵\n愓\n惸\n惼\n惾\n惁\n愃\n愘\n愝\n愐\n惿\n愄\n愋\n扊\n掔\n掱\n掰\n揎\n揥\n揨\n揯\n揃\n撝\n揳\n揊\n揠\n揶\n揕\n揲\n揵\n摡\n揟\n掾\n揝\n揜\n揄\n揘\n揓\n揂\n揇\n揌\n揋\n揈\n揰\n揗\n揙\n攲\n敧\n敪\n敤\n敜\n敨\n敥\n斌\n斝\n斞\n斮\n旐\n旒\n晼\n晬\n晻\n暀\n晱\n晹\n晪\n晲\n朁\n椌\n棓\n椄\n棜\n椪\n棬\n棪\n棱\n椏\n棖\n棷\n棫\n棤\n棶\n椓\n椐\n棳\n棡\n椇\n棌\n椈\n楰\n梴\n椑\n棯\n棆\n椔\n棸\n棐\n棽\n棼\n棨\n椋\n椊\n椗\n棎\n棈\n棝\n棞\n棦\n棴\n棑\n椆\n棔\n棩\n椕\n椥\n棇\n欹\n欻\n欿\n欼\n殔\n殗\n殙\n殕\n殽\n毰\n毲\n毳\n氰\n淼\n湆\n湇\n渟\n湉\n溈\n渼\n渽\n湅\n湢\n渫\n渿\n湁\n湝\n湳\n渜\n渳\n湋\n湀\n湑\n渻\n渃\n渮\n湞\n湨\n湜\n湡\n渱\n渨\n湠\n湱\n湫\n渹\n渢\n渰\n湓\n湥\n渧\n湸\n湤\n湷\n湕\n湹\n湒\n湦\n渵\n渶\n湚\n焠\n焞\n焯\n烻\n焮\n焱\n焣\n焥\n焢\n焲\n焟\n焨\n焺\n焛\n牋\n牚\n犈\n犉\n犆\n犅\n犋\n猒\n猋\n猰\n猢\n猱\n猳\n猧\n猲\n猭\n猦\n猣\n猵\n猌\n琮\n琬\n琰\n琫\n琖\n琚\n琡\n琭\n琱\n琤\n琣\n琝\n琩\n琠\n琲\n瓻\n甯\n畯\n畬\n痧\n痚\n痡\n痦\n痝\n痟\n痤\n痗\n皕\n皒\n盚\n睆\n睇\n睄\n睍\n睅\n睊\n睎\n睋\n睌\n矞\n矬\n硠\n硤\n硥\n硜\n硭\n硱\n硪\n确\n硰\n硩\n硨\n硞\n硢\n祴\n祳\n祲\n祰\n稂\n稊\n稃\n稌\n稄\n窙\n竦\n竤\n筊\n笻\n筄\n筈\n筌\n筎\n筀\n筘\n筅\n粢\n粞\n粨\n粡\n絘\n絯\n絣\n絓\n絖\n絧\n絪\n絏\n絭\n絜\n絫\n絒\n絔\n絩\n絑\n絟\n絎\n缾\n缿\n罥\n罦\n羢\n羠\n羡\n翗\n聑\n聏\n聐\n胾\n胔\n腃\n腊\n腒\n腏\n腇\n脽\n腍\n脺\n臦\n臮\n臷\n臸\n臹\n舄\n舼\n舽\n舿\n艵\n茻\n菹\n萣\n菀\n菨\n萒\n菧\n菤\n菼\n菶\n萐\n菆\n菈\n菫\n菣\n莿\n萁\n菝\n菥\n菘\n菿\n菡\n菋\n菎\n菖\n菵\n菉\n萉\n菞\n萑\n萆\n菂\n菳\n菕\n菺\n菇\n菑\n菪\n萓\n菃\n菬\n菮\n菄\n菻\n菗\n菢\n萛\n菛\n菾\n蛘\n蛢\n蛦\n蛓\n蛣\n蛚\n蛪\n蛝\n蛫\n蛜\n蛬\n蛩\n蛗\n蛨\n蛑\n衈\n衖\n衕\n袺\n裗\n袹\n袸\n裀\n袾\n袶\n袼\n袷\n袽\n袲\n褁\n裉\n覕\n覘\n覗\n觝\n觚\n觛\n詎\n詍\n訹\n詙\n詀\n詗\n詘\n詄\n詅\n詒\n詈\n詑\n詊\n詌\n詏\n豟\n貁\n貀\n貺\n貾\n貰\n貹\n貵\n趄\n趀\n趉\n跘\n跓\n跍\n跇\n跖\n跜\n跏\n跕\n跙\n跈\n跗\n跅\n軯\n軷\n軺\n軹\n軦\n軮\n軥\n軵\n軧\n軨\n軶\n軫\n軱\n軬\n軴\n軩\n逭\n逴\n逯\n鄆\n鄬\n郿\n郼\n鄈\n郹\n郻\n鄁\n鄀\n鄇\n鄅\n鄃\n酡\n酤\n酟\n酢\n酠\n鈁\n鈊\n鈥\n鈃\n鈚\n鈦\n鈏\n鈌\n鈀\n鈒\n釿\n釽\n鈆\n鈄\n鈧\n鈂\n鈜\n鈤\n鈙\n鈗\n鈅\n鈖\n镻\n閍\n閌\n閐\n隇\n陾\n隈\n隉\n隃\n隀\n雂\n雈\n雃\n雱\n雰\n靬\n靰\n靮\n頇\n颩\n飫\n鳦\n黹\n亃\n亄\n亶\n傽\n傿\n僆\n傮\n僄\n僊\n傴\n僈\n僂\n傰\n僁\n傺\n傱\n僋\n僉\n傶\n傸\n凗\n剺\n剸\n剻\n剼\n嗃\n嗛\n嗌\n嗐\n嗋\n嗊\n嗝\n嗀\n嗔\n嗄\n嗩\n喿\n嗒\n喍\n嗏\n嗕\n嗢\n嗖\n嗈\n嗲\n嗍\n嗙\n嗂\n圔\n塓\n塨\n塤\n塏\n塍\n塉\n塯\n塕\n塎\n塝\n塙\n塥\n塛\n堽\n塣\n塱\n壼\n嫇\n嫄\n嫋\n媺\n媸\n媱\n媵\n媰\n媿\n嫈\n媻\n嫆\n媷\n嫀\n嫊\n媴\n媶\n嫍\n媹\n媐\n寖\n寘\n寙\n尟\n尳\n嵱\n嵣\n嵊\n嵥\n嵲\n嵬\n嵞\n嵨\n嵧\n嵢\n巰\n幏\n幎\n幊\n幍\n幋\n廅\n廌\n廆\n廋\n廇\n彀\n徯\n徭\n惷\n慉\n慊\n愫\n慅\n愶\n愲\n愮\n慆\n愯\n慏\n愩\n慀\n戠\n酨\n戣\n戥\n戤\n揅\n揱\n揫\n搐\n搒\n搉\n搠\n搤\n搳\n摃\n搟\n搕\n搘\n搹\n搷\n搢\n搣\n搌\n搦\n搰\n搨\n摁\n搵\n搯\n搊\n搚\n摀\n搥\n搧\n搋\n揧\n搛\n搮\n搡\n搎\n敯\n斒\n旓\n暆\n暌\n暕\n暐\n暋\n暊\n暙\n暔\n晸\n朠\n楦\n楟\n椸\n楎\n楢\n楱\n椿\n楅\n楪\n椹\n楂\n楗\n楙\n楺\n楈\n楉\n椵\n楬\n椳\n椽\n楥\n棰\n楸\n椴\n楩\n楀\n楯\n楄\n楶\n楘\n楁\n楴\n楌\n椻\n楋\n椷\n楜\n楏\n楑\n椲\n楒\n椯\n楻\n椼\n歆\n歅\n歃\n歂\n歈\n歁\n殛\n嗀\n毻\n毼\n毹\n毷\n毸\n溛\n滖\n滈\n溏\n滀\n溟\n溓\n溔\n溠\n溱\n溹\n滆\n滒\n溽\n滁\n溞\n滉\n溷\n溰\n滍\n溦\n滏\n溲\n溾\n滃\n滜\n滘\n溙\n溒\n溎\n溍\n溤\n溡\n溿\n溳\n滐\n滊\n溗\n溮\n溣\n煇\n煔\n煒\n煣\n煠\n煁\n煝\n煲\n煸\n煪\n煡\n煂\n煘\n煃\n煋\n煰\n煟\n煐\n煓\n煄\n煍\n煚\n牏\n犍\n犌\n犑\n犐\n犎\n猼\n獂\n猻\n猺\n獀\n獊\n獉\n瑄\n瑊\n瑋\n瑒\n瑑\n瑗\n瑀\n瑏\n瑐\n瑎\n瑂\n瑆\n瑍\n瑔\n瓡\n瓿\n瓾\n瓽\n甝\n畹\n畷\n榃\n痯\n瘏\n瘃\n痷\n痾\n痼\n痸\n瘐\n痻\n痶\n痭\n痵\n痽\n皙\n皵\n盝\n睕\n睟\n睠\n睒\n睖\n睚\n睩\n睧\n睔\n睙\n睭\n矠\n碇\n碚\n碔\n碏\n碄\n碕\n碅\n碆\n碡\n碃\n硹\n碙\n碀\n碖\n硻\n祼\n禂\n祽\n祹\n稑\n稘\n稙\n稒\n稗\n稕\n稢\n稓\n稛\n稐\n窣\n窢\n窞\n竫\n筦\n筤\n筭\n筴\n筩\n筲\n筥\n筳\n筱\n筰\n筡\n筸\n筶\n筣\n粲\n粴\n粯\n綈\n綆\n綀\n綍\n絿\n綅\n絺\n綎\n絻\n綃\n絼\n綌\n綔\n綄\n絽\n綒\n罭\n罫\n罧\n罨\n罬\n羦\n羥\n羧\n翛\n翜\n耡\n腤\n腠\n腷\n腜\n腩\n腛\n腢\n腲\n朡\n腞\n腶\n腧\n腯\n腄\n腡\n舝\n艉\n艄\n艀\n艂\n艅\n蓱\n萿\n葖\n葶\n葹\n蒏\n蒍\n葥\n葑\n葀\n蒆\n葧\n萰\n葍\n葽\n葚\n葙\n葴\n葳\n葝\n蔇\n葞\n萷\n萺\n萴\n葺\n葃\n葸\n萲\n葅\n萩\n菙\n葋\n萯\n葂\n萭\n葟\n葰\n萹\n葎\n葌\n葒\n葯\n蓅\n蒎\n萻\n葇\n萶\n萳\n葨\n葾\n葄\n萫\n葠\n葔\n葮\n葐\n蜋\n蜄\n蛷\n蜌\n蛺\n蛖\n蛵\n蝍\n蛸\n蜎\n蜉\n蜁\n蛶\n蜍\n蜅\n裖\n裋\n裍\n裎\n裞\n裛\n裚\n裌\n裐\n覅\n覛\n觟\n觥\n觤\n觡\n觠\n觢\n觜\n触\n詶\n誆\n詿\n詡\n訿\n詷\n誂\n誄\n詵\n誃\n誁\n詴\n詺\n谼\n豋\n豊\n豥\n豤\n豦\n貆\n貄\n貅\n賌\n赨\n赩\n趑\n趌\n趎\n趏\n趍\n趓\n趔\n趐\n趒\n跰\n跠\n跬\n跱\n跮\n跐\n跩\n跣\n跢\n跧\n跲\n跫\n跴\n輆\n軿\n輁\n輀\n輅\n輇\n輈\n輂\n遒\n逿\n遄\n遉\n逽\n鄐\n鄍\n鄏\n鄑\n鄖\n鄔\n鄋\n鄎\n酮\n酯\n鉈\n鉒\n鈰\n鈺\n鉦\n鈳\n鉥\n鉞\n銃\n鈮\n鉊\n鉆\n鉭\n鉬\n鉏\n鉠\n鉧\n鉯\n鈶\n鉡\n鉰\n鈱\n鉔\n鉣\n鉐\n鉲\n鉎\n鉓\n鉌\n鉖\n鈲\n閟\n閜\n閞\n閛\n隒\n隓\n隑\n隗\n雎\n雺\n雽\n雸\n雵\n靳\n靷\n靸\n靲\n頏\n頍\n頎\n颬\n飶\n飹\n馯\n馲\n馰\n馵\n骭\n骫\n魛\n鳪\n鳭\n鳧\n麀\n黽\n僦\n僔\n僗\n僨\n僳\n僛\n僪\n僝\n僤\n僓\n僬\n僰\n僯\n僣\n僠\n凘\n劀\n劁\n勩\n勫\n匰\n厬\n嘧\n嘕\n嘌\n嘒\n嗼\n嘏\n嘜\n嘁\n嘓\n嘂\n嗺\n嘝\n嘄\n嗿\n嗹\n墉\n塼\n墐\n墘\n墆\n墁\n塿\n塴\n墋\n塺\n墇\n墑\n墎\n塶\n墂\n墈\n塻\n墔\n墏\n壾\n奫\n嫜\n嫮\n嫥\n嫕\n嫪\n嫚\n嫭\n嫫\n嫳\n嫢\n嫠\n嫛\n嫬\n嫞\n嫝\n嫙\n嫨\n嫟\n孷\n寠\n寣\n屣\n嶂\n嶀\n嵽\n嶆\n嵺\n嶁\n嵷\n嶊\n嶉\n嶈\n嵾\n嵼\n嶍\n嵹\n嵿\n幘\n幙\n幓\n廘\n廑\n廗\n廎\n廜\n廕\n廙\n廒\n廔\n彄\n彃\n彯\n徶\n愬\n愨\n慁\n慞\n慱\n慳\n慒\n慓\n慲\n慬\n憀\n慴\n慔\n慺\n慛\n慥\n愻\n慪\n慡\n慖\n戩\n戧\n戫\n搫\n摍\n摛\n摝\n摴\n摶\n摲\n摳\n摽\n摵\n摦\n撦\n摎\n撂\n摞\n摜\n摋\n摓\n摠\n摐\n摿\n搿\n摬\n摫\n摙\n摥\n摷\n敳\n斠\n暡\n暠\n暟\n朅\n朄\n朢\n榱\n榶\n槉\n榠\n槎\n榖\n榰\n榬\n榼\n榑\n榙\n榎\n榧\n榍\n榩\n榾\n榯\n榿\n槄\n榽\n榤\n槔\n榹\n槊\n榚\n槏\n榳\n榓\n榪\n榡\n榞\n槙\n榗\n榐\n槂\n榵\n榥\n槆\n歊\n歍\n歋\n殞\n殟\n殠\n毃\n毄\n毾\n滎\n滵\n滱\n漃\n漥\n滸\n漷\n滻\n漮\n漉\n潎\n漙\n漚\n漧\n漘\n漻\n漒\n滭\n漊\n漶\n潳\n滹\n滮\n漭\n潀\n漰\n漼\n漵\n滫\n漇\n漎\n潃\n漅\n滽\n滶\n漹\n漜\n滼\n漺\n漟\n漍\n漞\n漈\n漡\n熇\n熐\n熉\n熀\n熅\n熂\n熏\n煻\n熆\n熁\n熗\n牄\n牓\n犗\n犕\n犓\n獃\n獍\n獑\n獌\n瑢\n瑳\n瑱\n瑵\n瑲\n瑧\n瑮\n甀\n甂\n甃\n畽\n疐\n瘖\n瘈\n瘌\n瘕\n瘑\n瘊\n瘔\n皸\n瞁\n睼\n瞅\n瞂\n睮\n瞀\n睯\n睾\n瞃\n碲\n碪\n碴\n碭\n碨\n硾\n碫\n碞\n碥\n碠\n碬\n碢\n碤\n禘\n禊\n禋\n禖\n禕\n禔\n禓\n禗\n禈\n禒\n禐\n稫\n穊\n稰\n稯\n稨\n稦\n窨\n窫\n窬\n竮\n箈\n箜\n箊\n箑\n箐\n箖\n箍\n箌\n箛\n箎\n箅\n箘\n劄\n箙\n箤\n箂\n粻\n粿\n粼\n粺\n綧\n綷\n緂\n綣\n綪\n緁\n緀\n緅\n綝\n緎\n緄\n緆\n緋\n緌\n綯\n綹\n綖\n綼\n綟\n綦\n綮\n綩\n綡\n緉\n罳\n翢\n翣\n翥\n翞\n耤\n聝\n聜\n膉\n膆\n膃\n膇\n膍\n膌\n膋\n舕\n蒗\n蒤\n蒡\n蒟\n蒺\n蓎\n蓂\n蒬\n蒮\n蒫\n蒹\n蒴\n蓁\n蓍\n蒪\n蒚\n蒱\n蓐\n蒝\n蒧\n蒻\n蒢\n蒔\n蓇\n蓌\n蒛\n蒩\n蒯\n蓖\n蒘\n蒶\n蓏\n蒠\n蓗\n蓔\n蓒\n蓛\n蒰\n蒑\n虡\n蜳\n蜣\n蜨\n蝫\n蝀\n蜮\n蜞\n蜡\n蜙\n蜛\n蝃\n蜬\n蝁\n蜾\n蝆\n蜠\n蜲\n蜪\n蜭\n蜼\n蜒\n蜺\n蜱\n蜵\n蝂\n蜦\n蜧\n蜸\n蜤\n蜚\n蜰\n蜑\n裷\n裧\n裱\n裲\n裺\n裾\n裮\n裼\n裶\n裻\n裰\n裬\n裫\n覝\n覡\n覟\n覞\n觩\n觫\n觨\n誫\n誙\n誋\n誒\n誏\n誖\n谽\n豨\n豩\n賕\n賏\n賗\n趖\n踉\n踂\n跿\n踍\n跽\n踊\n踃\n踇\n踆\n踅\n跾\n踀\n踄\n輐\n輑\n輎\n輍\n鄣\n鄜\n鄠\n鄢\n鄟\n鄝\n鄚\n鄤\n鄡\n鄛\n酺\n酲\n酹\n酳\n銥\n銤\n鉶\n銛\n鉺\n銠\n銔\n銪\n銍\n銦\n銚\n銫\n鉹\n銗\n鉿\n銣\n鋮\n銎\n銂\n銕\n銢\n鉽\n銈\n銡\n銊\n銆\n銌\n銙\n銧\n鉾\n銇\n銩\n銝\n銋\n鈭\n隞\n隡\n雿\n靘\n靽\n靺\n靾\n鞃\n鞀\n鞂\n靻\n鞄\n鞁\n靿\n韎\n韍\n頖\n颭\n颮\n餂\n餀\n餇\n馝\n馜\n駃\n馹\n馻\n馺\n駂\n馽\n駇\n骱\n髣\n髧\n鬾\n鬿\n魠\n魡\n魟\n鳱\n鳲\n鳵\n麧\n僿\n儃\n儰\n僸\n儆\n儇\n僶\n僾\n儋\n儌\n僽\n儊\n劋\n劌\n勱\n勯\n噈\n噂\n噌\n嘵\n噁\n噊\n噉\n噆\n噘\n噚\n噀\n嘳\n嘽\n嘬\n嘾\n嘸\n嘪\n嘺\n圚\n墫\n墝\n墱\n墠\n墣\n墯\n墬\n墥\n墡\n壿\n嫿\n嫴\n嫽\n嫷\n嫶\n嬃\n嫸\n嬂\n嫹\n嬁\n嬇\n嬅\n嬏\n屧\n嶙\n嶗\n嶟\n嶒\n嶢\n嶓\n嶕\n嶠\n嶜\n嶡\n嶚\n嶞\n幩\n幝\n幠\n幜\n緳\n廛\n廞\n廡\n彉\n徲\n憋\n憃\n慹\n憱\n憰\n憢\n憉\n憛\n憓\n憯\n憭\n憟\n憒\n憪\n憡\n憍\n慦\n憳\n戭\n摮\n摰\n撖\n撠\n撅\n撗\n撜\n撏\n撋\n撊\n撌\n撣\n撟\n摨\n撱\n撘\n敶\n敺\n敹\n敻\n斲\n斳\n暵\n暰\n暩\n暲\n暷\n暪\n暯\n樀\n樆\n樗\n槥\n槸\n樕\n槱\n槤\n樠\n槿\n槬\n槢\n樛\n樝\n槾\n樧\n槲\n槮\n樔\n槷\n槧\n橀\n樈\n槦\n槻\n樍\n槼\n槫\n樉\n樄\n樘\n樥\n樏\n槶\n樦\n樇\n槴\n樖\n歑\n殥\n殣\n殢\n殦\n氁\n氀\n毿\n氂\n潁\n漦\n潾\n澇\n濆\n澒\n澍\n澉\n澌\n潢\n潏\n澅\n潚\n澖\n潶\n潬\n澂\n潕\n潲\n潒\n潐\n潗\n澔\n澓\n潝\n漀\n潡\n潫\n潽\n潧\n澐\n潓\n澋\n潩\n潿\n澕\n潣\n潷\n潪\n潻\n熲\n熯\n熛\n熰\n熠\n熚\n熩\n熵\n熝\n熥\n熞\n熤\n熡\n熪\n熜\n熧\n熳\n犘\n犚\n獘\n獒\n獞\n獟\n獠\n獝\n獛\n獡\n獚\n獙\n獢\n璇\n璉\n璊\n璆\n璁\n瑽\n璅\n璈\n瑼\n甈\n甇\n畾\n瘥\n瘞\n瘙\n瘝\n瘜\n瘣\n瘚\n瘨\n瘛\n皜\n皝\n皞\n皛\n瞍\n瞏\n瞉\n瞈\n磍\n碻\n磏\n磌\n磑\n磎\n磔\n磈\n磃\n磄\n磉\n禚\n禡\n禠\n禜\n禢\n歶\n稹\n窲\n窴\n窳\n箷\n篋\n箾\n箬\n篎\n箯\n箹\n篊\n箵\n糅\n糈\n糌\n糋\n緷\n緛\n緪\n緧\n緗\n緡\n縃\n緺\n緦\n緶\n緱\n緰\n緮\n緟\n罶\n羬\n羰\n羭\n翭\n翫\n翪\n翬\n翦\n翨\n聤\n聧\n膣\n膟\n膞\n膕\n膢\n膙\n膗\n舖\n艏\n艓\n艒\n艐\n艎\n艑\n蔤\n蔻\n蔏\n蔀\n蔩\n蔎\n蔉\n蔍\n蔟\n蔊\n蔧\n蔜\n蓻\n蔫\n蓺\n蔈\n蔌\n蓴\n蔪\n蓲\n蔕\n蓷\n蓫\n蓳\n蓼\n蔒\n蓪\n蓩\n蔖\n蓾\n蔨\n蔝\n蔮\n蔂\n蓽\n蔞\n蓶\n蔱\n蔦\n蓧\n蓨\n蓰\n蓯\n蓹\n蔘\n蔠\n蔰\n蔋\n蔙\n蔯\n虢\n蝖\n蝣\n蝤\n蝷\n蟡\n蝳\n蝘\n蝔\n蝛\n蝒\n蝡\n蝚\n蝑\n蝞\n蝭\n蝪\n蝐\n蝎\n蝟\n蝝\n蝯\n蝬\n蝺\n蝮\n蝜\n蝥\n蝏\n蝻\n蝵\n蝢\n蝧\n蝩\n衚\n褅\n褌\n褔\n褋\n褗\n褘\n褙\n褆\n褖\n褑\n褎\n褉\n覢\n覤\n覣\n觭\n觰\n觬\n諏\n諆\n誸\n諓\n諑\n諔\n諕\n誻\n諗\n誾\n諀\n諅\n諘\n諃\n誺\n誽\n諙\n谾\n豍\n貏\n賥\n賟\n賙\n賨\n賚\n賝\n賧\n趠\n趜\n趡\n趛\n踠\n踣\n踥\n踤\n踮\n踕\n踛\n踖\n踑\n踙\n踦\n踧\n踔\n踒\n踘\n踓\n踜\n踗\n踚\n輬\n輤\n輘\n輚\n輠\n輣\n輖\n輗\n遳\n遰\n遯\n遧\n遫\n鄯\n鄫\n鄩\n鄪\n鄲\n鄦\n鄮\n醅\n醆\n醊\n醁\n醂\n醄\n醀\n鋐\n鋃\n鋄\n鋀\n鋙\n銶\n鋏\n鋱\n鋟\n鋘\n鋩\n鋗\n鋝\n鋌\n鋯\n鋂\n鋨\n鋊\n鋈\n鋎\n鋦\n鋍\n鋕\n鋉\n鋠\n鋞\n鋧\n鋑\n鋓\n銵\n鋡\n鋆\n銴\n镼\n閬\n閫\n閮\n閰\n隤\n隢\n雓\n霅\n霈\n霂\n靚\n鞊\n鞎\n鞈\n韐\n韏\n頞\n頝\n頦\n頩\n頨\n頠\n頛\n頧\n颲\n餈\n飺\n餑\n餔\n餖\n餗\n餕\n駜\n駍\n駏\n駓\n駔\n駎\n駉\n駘\n駋\n駗\n駌\n骳\n髬\n髫\n髳\n髲\n髱\n魆\n魃\n魧\n魴\n魱\n魦\n魶\n魵\n魰\n魨\n魤\n魬\n鳼\n鳺\n鳽\n鳿\n鳷\n鴇\n鴀\n鳹\n鳻\n鴈\n鴅\n鴄\n麃\n黓\n鼏\n鼐\n儜\n儓\n儗\n儚\n儑\n凞\n匴\n叡\n噰\n噠\n噮\n噳\n噦\n噣\n噭\n噲\n噞\n噷\n圜\n圛\n壈\n墽\n壉\n墿\n墺\n壂\n墼\n壆\n嬗\n嬙\n嬛\n嬡\n嬔\n嬓\n嬐\n嬖\n嬚\n嬠\n嬞\n寯\n嶬\n嶱\n嶩\n嶧\n嶵\n嶰\n嶮\n嶪\n嶨\n嶲\n嶭\n嶯\n嶴\n幧\n幨\n幦\n幯\n廩\n廧\n廦\n廨\n廥\n彋\n徼\n憝\n憨\n憖\n懅\n憴\n懆\n懁\n懌\n憺\n憿\n憸\n憌\n擗\n擖\n擐\n擏\n擉\n撽\n撉\n擃\n擛\n擳\n擙\n攳\n敿\n敼\n斢\n曈\n暾\n曀\n曊\n曋\n曏\n暽\n暻\n暺\n曌\n朣\n樴\n橦\n橉\n橧\n樲\n橨\n樾\n橝\n橭\n橶\n橛\n橑\n樨\n橚\n樻\n樿\n橁\n橪\n橤\n橐\n橏\n橔\n橯\n橩\n橠\n樼\n橞\n橖\n橕\n橍\n橎\n橆\n歕\n歔\n歖\n殧\n殪\n殫\n毈\n毇\n氄\n氃\n氆\n澭\n濋\n澣\n濇\n澼\n濎\n濈\n潞\n濄\n澽\n澞\n濊\n澨\n瀄\n澥\n澮\n澺\n澬\n澪\n濏\n澿\n澸\n澢\n濉\n澫\n濍\n澯\n澲\n澰\n燅\n燂\n熿\n熸\n燖\n燀\n燁\n燋\n燔\n燊\n燇\n燏\n熽\n燘\n熼\n燆\n燚\n燛\n犝\n犞\n獩\n獦\n獧\n獬\n獥\n獫\n獪\n瑿\n璚\n璠\n璔\n璒\n璕\n璡\n甋\n疀\n瘯\n瘭\n瘱\n瘽\n瘳\n瘼\n瘵\n瘲\n瘰\n皻\n盦\n瞚\n瞝\n瞡\n瞜\n瞛\n瞢\n瞣\n瞕\n瞙\n瞗\n磝\n磩\n磥\n磪\n磞\n磣\n磛\n磡\n磢\n磭\n磟\n磠\n禤\n穄\n穈\n穇\n窶\n窸\n窵\n窱\n窷\n篞\n篣\n篧\n篝\n篕\n篥\n篚\n篨\n篹\n篔\n篪\n篢\n篜\n篫\n篘\n篟\n糒\n糔\n糗\n糐\n糑\n縒\n縡\n縗\n縌\n縟\n縠\n縓\n縎\n縜\n縕\n縚\n縢\n縋\n縏\n縖\n縍\n縔\n縥\n縤\n罃\n罻\n罼\n罺\n羱\n翯\n耪\n耩\n聬\n膱\n膦\n膮\n膹\n膵\n膫\n膰\n膬\n膴\n膲\n膷\n膧\n臲\n艕\n艖\n艗\n蕖\n蕅\n蕫\n蕍\n蕓\n蕡\n蕘\n蕀\n蕆\n蕤\n蕁\n蕢\n蕄\n蕑\n蕇\n蕣\n蔾\n蕛\n蕱\n蕎\n蕮\n蕵\n蕕\n蕧\n蕠\n薌\n蕦\n蕝\n蕔\n蕥\n蕬\n虣\n虥\n虤\n螛\n螏\n螗\n螓\n螒\n螈\n螁\n螖\n螘\n蝹\n螇\n螣\n螅\n螐\n螑\n螝\n螄\n螔\n螜\n螚\n螉\n褞\n褦\n褰\n褭\n褮\n褧\n褱\n褢\n褩\n褣\n褯\n褬\n褟\n觱\n諠\n諢\n諲\n諴\n諵\n諝\n謔\n諤\n諟\n諰\n諈\n諞\n諡\n諨\n諿\n諯\n諻\n貑\n貒\n貐\n賵\n賮\n賱\n賰\n賳\n赬\n赮\n趥\n趧\n踳\n踾\n踸\n蹀\n蹅\n踶\n踼\n踽\n蹁\n踰\n踿\n躽\n輮\n輵\n輲\n輹\n輷\n輴\n遶\n遹\n遻\n邆\n郺\n鄳\n鄵\n鄶\n醓\n醐\n醑\n醍\n醏\n錧\n錞\n錈\n錟\n錆\n錏\n鍺\n錸\n錼\n錛\n錣\n錒\n錁\n鍆\n錭\n錎\n錍\n鋋\n錝\n鋺\n錥\n錓\n鋹\n鋷\n錴\n錂\n錤\n鋿\n錩\n錹\n錵\n錪\n錔\n錌\n錋\n鋾\n錉\n錀\n鋻\n錖\n閼\n闍\n閾\n閹\n閺\n閶\n閿\n閵\n閽\n隩\n雔\n霋\n霒\n霐\n鞙\n鞗\n鞔\n韰\n韸\n頵\n頯\n頲\n餤\n餟\n餧\n餩\n馞\n駮\n駬\n駥\n駤\n駰\n駣\n駪\n駩\n駧\n骹\n骿\n骴\n骻\n髶\n髺\n髹\n髷\n鬳\n鮀\n鮅\n鮇\n魼\n魾\n魻\n鮂\n鮓\n鮒\n鮐\n魺\n鮕\n魽\n鮈\n鴥\n鴗\n鴠\n鴞\n鴔\n鴩\n鴝\n鴘\n鴢\n鴐\n鴙\n鴟\n麈\n麆\n麇\n麮\n麭\n黕\n黖\n黺\n鼒\n鼽\n儦\n儥\n儢\n儤\n儠\n儩\n勴\n嚓\n嚌\n嚍\n嚆\n嚄\n嚃\n噾\n嚂\n噿\n嚁\n壖\n壔\n壏\n壒\n嬭\n嬥\n嬲\n嬣\n嬬\n嬧\n嬦\n嬯\n嬮\n孻\n寱\n寲\n嶷\n幬\n幪\n徾\n徻\n懃\n憵\n憼\n懧\n懠\n懥\n懤\n懨\n懞\n擯\n擩\n擣\n擫\n擤\n擨\n斁\n斀\n斶\n旚\n曒\n檍\n檖\n檁\n檥\n檉\n檟\n檛\n檡\n檞\n檇\n檓\n檎\n檕\n檃\n檨\n檤\n檑\n橿\n檦\n檚\n檅\n檌\n檒\n歛\n殭\n氉\n濌\n澩\n濴\n濔\n濣\n濜\n濭\n濧\n濦\n濞\n濲\n濝\n濢\n濨\n燡\n燱\n燨\n燲\n燤\n燰\n燢\n獳\n獮\n獯\n璗\n璲\n璫\n璐\n璪\n璭\n璱\n璥\n璯\n甐\n甑\n甒\n甏\n疄\n癃\n癈\n癉\n癇\n皤\n盩\n瞵\n瞫\n瞲\n瞷\n瞶\n瞴\n瞱\n瞨\n矰\n磳\n磽\n礂\n磻\n磼\n磲\n礅\n磹\n磾\n礄\n禫\n禨\n穜\n穛\n穖\n穘\n穔\n穚\n窾\n竀\n竁\n簅\n簏\n篲\n簀\n篿\n篻\n簎\n篴\n簋\n篳\n簂\n簉\n簃\n簁\n篸\n篽\n篰\n篱\n簐\n簊\n糨\n縭\n縼\n繂\n縳\n顈\n縸\n縪\n繉\n繀\n繇\n縩\n繌\n縰\n縻\n縶\n繄\n縺\n罅\n罿\n罾\n罽\n翴\n翲\n耬\n膻\n臄\n臌\n臊\n臅\n臇\n膼\n臩\n艛\n艚\n艜\n薃\n薀\n薏\n薧\n薕\n薠\n薋\n薣\n蕻\n薤\n薚\n薞\n蕷\n蕼\n薉\n薡\n蕺\n蕸\n蕗\n薎\n薖\n薆\n薍\n薙\n薝\n薁\n薢\n薂\n薈\n薅\n蕹\n蕶\n薘\n薐\n薟\n虨\n螾\n螪\n螭\n蟅\n螰\n螬\n螹\n螵\n螼\n螮\n蟉\n蟃\n蟂\n蟌\n螷\n螯\n蟄\n蟊\n螴\n螶\n螿\n螸\n螽\n蟞\n螲\n褵\n褳\n褼\n褾\n襁\n襒\n褷\n襂\n覭\n覯\n覮\n觲\n觳\n謞\n謘\n謖\n謑\n謅\n謋\n謢\n謏\n謒\n謕\n謇\n謍\n謈\n謆\n謜\n謓\n謚\n豏\n豰\n豲\n豱\n豯\n貕\n貔\n賹\n赯\n蹎\n蹍\n蹓\n蹐\n蹌\n蹇\n轃\n轀\n邅\n遾\n鄸\n醚\n醢\n醛\n醙\n醟\n醡\n醝\n醠\n鎡\n鎃\n鎯\n鍤\n鍖\n鍇\n鍼\n鍘\n鍜\n鍶\n鍉\n鍐\n鍑\n鍠\n鍭\n鎏\n鍌\n鍪\n鍹\n鍗\n鍕\n鍒\n鍏\n鍱\n鍷\n鍻\n鍡\n鍞\n鍣\n鍧\n鎀\n鍎\n鍙\n闇\n闀\n闉\n闃\n闅\n閷\n隮\n隰\n隬\n霠\n霟\n霘\n霝\n霙\n鞚\n鞡\n鞜\n鞞\n鞝\n韕\n韔\n韱\n顁\n顄\n顊\n顉\n顅\n顃\n餥\n餫\n餬\n餪\n餳\n餲\n餯\n餭\n餱\n餰\n馘\n馣\n馡\n騂\n駺\n駴\n駷\n駹\n駸\n駶\n駻\n駽\n駾\n駼\n騃\n骾\n髾\n髽\n鬁\n髼\n魈\n鮚\n鮨\n鮞\n鮛\n鮦\n鮡\n鮥\n鮤\n鮆\n鮢\n鮠\n鮯\n鴳\n鵁\n鵧\n鴶\n鴮\n鴯\n鴱\n鴸\n鴰\n鵅\n鵂\n鵃\n鴾\n鴷\n鵀\n鴽\n翵\n鴭\n麊\n麉\n麍\n麰\n黈\n黚\n黻\n黿\n鼤\n鼣\n鼢\n齔\n龠\n儱\n儭\n儮\n嚘\n嚜\n嚗\n嚚\n嚝\n嚙\n奰\n嬼\n屩\n屪\n巀\n幭\n幮\n懘\n懟\n懭\n懮\n懱\n懪\n懰\n懫\n懖\n懩\n擿\n攄\n擽\n擸\n攁\n攃\n擼\n斔\n旛\n曚\n曛\n曘\n櫅\n檹\n檽\n櫡\n櫆\n檺\n檶\n檷\n櫇\n檴\n檭\n歞\n毉\n氋\n瀇\n瀌\n瀍\n瀁\n瀅\n瀔\n瀎\n濿\n瀀\n濻\n瀦\n濼\n濷\n瀊\n燿\n燹\n爃\n燽\n獶\n璸\n瓀\n璵\n瓁\n璾\n璶\n璻\n瓂\n甔\n甓\n癜\n癤\n癙\n癐\n癓\n癗\n癚\n皦\n皽\n盬\n矂\n瞺\n磿\n礌\n礓\n礔\n礉\n礐\n礒\n礑\n禭\n禬\n穟\n簜\n簩\n簙\n簠\n簟\n簭\n簝\n簦\n簨\n簢\n簥\n簰\n繜\n繐\n繖\n繣\n繘\n繢\n繟\n繑\n繠\n繗\n繓\n羵\n羳\n翷\n翸\n聵\n臑\n臒\n臐\n艟\n艞\n薴\n藆\n藀\n藃\n藂\n薳\n薵\n薽\n藇\n藄\n薿\n藋\n藎\n藈\n藅\n薱\n薶\n藒\n蘤\n薸\n薷\n薾\n虩\n蟧\n蟦\n蟢\n蟛\n蟫\n蟪\n蟥\n蟟\n蟳\n蟤\n蟔\n蟜\n蟓\n蟭\n蟘\n蟣\n螤\n蟗\n蟙\n蠁\n蟴\n蟨\n蟝\n襓\n襋\n襏\n襌\n襆\n襐\n襑\n襉\n謪\n謧\n謣\n謳\n謰\n謵\n譇\n謯\n謼\n謾\n謱\n謥\n謷\n謦\n謶\n謮\n謤\n謻\n謽\n謺\n豂\n豵\n貙\n貘\n貗\n賾\n贄\n贂\n贀\n蹜\n蹢\n蹠\n蹗\n蹖\n蹞\n蹥\n蹧\n蹛\n蹚\n蹡\n蹝\n蹩\n蹔\n轆\n轇\n轈\n轋\n鄨\n鄺\n鄻\n鄾\n醨\n醥\n醧\n醯\n醪\n鎵\n鎌\n鎒\n鎷\n鎛\n鎝\n鎉\n鎧\n鎎\n鎪\n鎞\n鎦\n鎕\n鎈\n鎙\n鎟\n鎍\n鎱\n鎑\n鎲\n鎤\n鎨\n鎴\n鎣\n鎥\n闒\n闓\n闑\n隳\n雗\n雚\n巂\n雟\n雘\n雝\n霣\n霢\n霥\n鞬\n鞮\n鞨\n鞫\n鞤\n鞪\n鞢\n鞥\n韗\n韙\n韖\n韘\n韺\n顐\n顑\n顒\n颸\n饁\n餼\n餺\n騏\n騋\n騉\n騍\n騄\n騑\n騊\n騅\n騇\n騆\n髀\n髜\n鬈\n鬄\n鬅\n鬩\n鬵\n魊\n魌\n魋\n鯇\n鯆\n鯃\n鮿\n鯁\n鮵\n鮸\n鯓\n鮶\n鯄\n鮹\n鮽\n鵜\n鵓\n鵏\n鵊\n鵛\n鵋\n鵙\n鵖\n鵌\n鵗\n鵒\n鵔\n鵟\n鵘\n鵚\n麎\n麌\n黟\n鼁\n鼀\n鼥\n鼫\n鼪\n鼩\n鼨\n齌\n齕\n儴\n儵\n劖\n勷\n厴\n嚫\n嚭\n嚦\n嚧\n嚪\n嚬\n壚\n壝\n壛\n夒\n嬽\n嬾\n嬿\n巃\n幰\n徿\n懻\n攇\n攐\n攍\n攉\n攌\n攎\n斄\n旞\n旝\n曞\n櫧\n櫠\n櫌\n櫑\n櫙\n櫋\n櫟\n櫜\n櫐\n櫫\n櫏\n櫍\n櫞\n歠\n殰\n氌\n瀙\n瀧\n瀠\n瀖\n瀫\n瀡\n瀢\n瀣\n瀩\n瀗\n瀤\n瀜\n瀪\n爌\n爊\n爇\n爂\n爅\n犥\n犦\n犤\n犣\n犡\n瓋\n瓅\n璷\n瓃\n甖\n癠\n矉\n矊\n矄\n矱\n礝\n礛\n礡\n礜\n礗\n礞\n禰\n穧\n穨\n簳\n簼\n簹\n簬\n簻\n糬\n糪\n繶\n繵\n繸\n繰\n繷\n繯\n繺\n繲\n繴\n繨\n罋\n罊\n羃\n羆\n羷\n翽\n翾\n聸\n臗\n臕\n艤\n艡\n艣\n藫\n藱\n藭\n藙\n藡\n藨\n藚\n藗\n藬\n藲\n藸\n藘\n藟\n藣\n藜\n藑\n藰\n藦\n藯\n藞\n藢\n蠀\n蟺\n蠃\n蟶\n蟷\n蠉\n蠌\n蠋\n蠆\n蟼\n蠈\n蟿\n蠊\n蠂\n襢\n襚\n襛\n襗\n襡\n襜\n襘\n襝\n襙\n覈\n覷\n覶\n觶\n譐\n譈\n譊\n譀\n譓\n譖\n譔\n譋\n譕\n譑\n譂\n譒\n譗\n豃\n豷\n豶\n貚\n贆\n贇\n贉\n趬\n趪\n趭\n趫\n蹭\n蹸\n蹳\n蹪\n蹯\n蹻\n軂\n轒\n轑\n轏\n轐\n轓\n辴\n酀\n鄿\n醰\n醭\n鏞\n鏇\n鏏\n鏂\n鏚\n鏐\n鏹\n鏬\n鏌\n鏙\n鎩\n鏦\n鏊\n鏔\n鏮\n鏣\n鏕\n鏄\n鏎\n鏀\n鏒\n鏧\n镽\n闚\n闛\n雡\n霩\n霫\n霬\n霨\n霦\n鞳\n鞷\n鞶\n韝\n韞\n韟\n顜\n顙\n顝\n顗\n颿\n颽\n颻\n颾\n饈\n饇\n饃\n馦\n馧\n騚\n騕\n騥\n騝\n騤\n騛\n騢\n騠\n騧\n騣\n騞\n騜\n騔\n髂\n鬋\n鬊\n鬎\n鬌\n鬷\n鯪\n鯫\n鯠\n鯞\n鯤\n鯦\n鯢\n鯰\n鯔\n鯗\n鯬\n鯜\n鯙\n鯥\n鯕\n鯡\n鯚\n鵷\n鶁\n鶊\n鶄\n鶈\n鵱\n鶀\n鵸\n鶆\n鶋\n鶌\n鵽\n鵫\n鵴\n鵵\n鵰\n鵩\n鶅\n鵳\n鵻\n鶂\n鵯\n鵹\n鵿\n鶇\n鵨\n麔\n麑\n黀\n黼\n鼭\n齀\n齁\n齍\n齖\n齗\n齘\n匷\n嚲\n嚵\n嚳\n壣\n孅\n巆\n巇\n廮\n廯\n忀\n忁\n懹\n攗\n攖\n攕\n攓\n旟\n曨\n曣\n曤\n櫳\n櫰\n櫪\n櫨\n櫹\n櫱\n櫮\n櫯\n瀼\n瀵\n瀯\n瀷\n瀴\n瀱\n灂\n瀸\n瀿\n瀺\n瀹\n灀\n瀻\n瀳\n灁\n爓\n爔\n犨\n獽\n獼\n璺\n皫\n皪\n皾\n盭\n矌\n矎\n矏\n矍\n矲\n礥\n礣\n礧\n礨\n礤\n礩\n禲\n穮\n穬\n穭\n竷\n籉\n籈\n籊\n籇\n籅\n糮\n繻\n繾\n纁\n纀\n羺\n翿\n聹\n臛\n臙\n舋\n艨\n艩\n蘢\n藿\n蘁\n藾\n蘛\n蘀\n藶\n蘄\n蘉\n蘅\n蘌\n藽\n蠙\n蠐\n蠑\n蠗\n蠓\n蠖\n襣\n襦\n覹\n觷\n譠\n譪\n譝\n譨\n譣\n譥\n譧\n譭\n趮\n躆\n躈\n躄\n轙\n轖\n轗\n轕\n轘\n轚\n邍\n酃\n酁\n醷\n醵\n醲\n醳\n鐋\n鐓\n鏻\n鐠\n鐏\n鐔\n鏾\n鐕\n鐐\n鐨\n鐙\n鐍\n鏵\n鐀\n鏷\n鐇\n鐎\n鐖\n鐒\n鏺\n鐉\n鏸\n鐊\n鏿\n鏼\n鐌\n鏶\n鐑\n鐆\n闞\n闠\n闟\n霮\n霯\n鞹\n鞻\n韽\n韾\n顠\n顢\n顣\n顟\n飁\n飂\n饐\n饎\n饙\n饌\n饋\n饓\n騲\n騴\n騱\n騬\n騪\n騶\n騩\n騮\n騸\n騭\n髇\n髊\n髆\n鬐\n鬒\n鬑\n鰋\n鰈\n鯷\n鰅\n鰒\n鯸\n鱀\n鰇\n鰎\n鰆\n鰗\n鰔\n鰉\n鶟\n鶙\n鶤\n鶝\n鶒\n鶘\n鶐\n鶛\n鶠\n鶔\n鶜\n鶪\n鶗\n鶡\n鶚\n鶢\n鶨\n鶞\n鶣\n鶿\n鶩\n鶖\n鶦\n鶧\n麙\n麛\n麚\n黥\n黤\n黧\n黦\n鼰\n鼮\n齛\n齠\n齞\n齝\n齙\n龑\n儺\n儹\n劘\n劗\n囃\n嚽\n嚾\n孈\n孇\n巋\n巏\n廱\n懽\n攛\n欂\n櫼\n欃\n櫸\n欀\n灃\n灄\n灊\n灈\n灉\n灅\n灆\n爝\n爚\n爙\n獾\n甗\n癪\n矐\n礭\n礱\n礯\n籔\n籓\n糲\n纊\n纈\n纋\n纆\n纍\n罍\n羻\n耰\n臝\n蘘\n蘪\n蘦\n蘟\n蘣\n蘜\n蘙\n蘧\n蘮\n蘡\n蘠\n蘩\n蘞\n蘥\n蠩\n蠝\n蠛\n蠠\n蠤\n蠜\n蠫\n衊\n襭\n襩\n襮\n襫\n觺\n譹\n譸\n譅\n譺\n譻\n贐\n贔\n趯\n躎\n躌\n轞\n轛\n轝\n酆\n酄\n酅\n醹\n鐿\n鐻\n鐶\n鐩\n鐽\n鐼\n鐰\n鐹\n鐪\n鐷\n鐬\n鑀\n鐱\n闥\n闤\n闣\n霵\n霺\n鞿\n韡\n顤\n飉\n飆\n飀\n饘\n饖\n騹\n騽\n驆\n驄\n驂\n驁\n騺\n騿\n髍\n鬕\n鬗\n鬘\n鬖\n鬺\n魒\n鰫\n鰝\n鰜\n鰬\n鰣\n鰨\n鰩\n鰤\n鰡\n鶷\n鶶\n鶼\n鷁\n鷇\n鷊\n鷏\n鶾\n鷅\n鷃\n鶻\n鶵\n鷎\n鶹\n鶺\n鶬\n鷈\n鶱\n鶭\n鷌\n鶳\n鷍\n鶲\n鹺\n麜\n黫\n黮\n黭\n鼛\n鼘\n鼚\n鼱\n齎\n齥\n齤\n龒\n亹\n囆\n囅\n囋\n奱\n孋\n孌\n巕\n巑\n廲\n攡\n攠\n攦\n攢\n欋\n欈\n欉\n氍\n灕\n灖\n灗\n灒\n爞\n爟\n犩\n獿\n瓘\n瓕\n瓙\n瓗\n癭\n皭\n礵\n禴\n穰\n穱\n籗\n籜\n籙\n籛\n籚\n糴\n糱\n纑\n罏\n羇\n臞\n艫\n蘴\n蘵\n蘳\n蘬\n蘲\n蘶\n蠬\n蠨\n蠦\n蠪\n蠥\n襱\n覿\n覾\n觻\n譾\n讄\n讂\n讆\n讅\n譿\n贕\n躕\n躔\n躚\n躒\n躐\n躖\n躗\n轠\n轢\n酇\n鑌\n鑐\n鑊\n鑋\n鑏\n鑇\n鑅\n鑈\n鑉\n鑆\n霿\n韣\n顪\n顩\n飋\n饔\n饛\n驎\n驓\n驔\n驌\n驏\n驈\n驊\n驉\n驒\n驐\n髐\n鬙\n鬫\n鬻\n魖\n魕\n鱆\n鱈\n鰿\n鱄\n鰹\n鰳\n鱁\n鰼\n鰷\n鰴\n鰲\n鰽\n鰶\n鷛\n鷒\n鷞\n鷚\n鷋\n鷐\n鷜\n鷑\n鷟\n鷩\n鷙\n鷘\n鷖\n鷵\n鷕\n鷝\n麶\n黰\n鼵\n鼳\n鼲\n齂\n齫\n龕\n龢\n儽\n劙\n壨\n壧\n奲\n孍\n巘\n蠯\n彏\n戁\n戃\n戄\n攩\n攥\n斖\n曫\n欑\n欒\n欏\n毊\n灛\n灚\n爢\n玂\n玁\n玃\n癰\n矔\n籧\n籦\n纕\n艬\n蘺\n虀\n蘹\n蘼\n蘱\n蘻\n蘾\n蠰\n蠲\n蠮\n蠳\n襶\n襴\n襳\n觾\n讌\n讎\n讋\n讈\n豅\n贙\n躘\n轤\n轣\n醼\n鑢\n鑕\n鑝\n鑗\n鑞\n韄\n韅\n頀\n驖\n驙\n鬞\n鬟\n鬠\n鱒\n鱘\n鱐\n鱊\n鱍\n鱋\n鱕\n鱙\n鱌\n鱎\n鷻\n鷷\n鷯\n鷣\n鷫\n鷸\n鷤\n鷶\n鷡\n鷮\n鷦\n鷲\n鷢\n鷬\n鷴\n鷳\n鷨\n鷭\n黂\n黐\n黲\n黳\n鼆\n鼜\n鼸\n鼷\n鼶\n齃\n齏\n齱\n齰\n齮\n齯\n囓\n囍\n孎\n屭\n攭\n曭\n曮\n欓\n灟\n灡\n灝\n灠\n爣\n瓛\n瓥\n矕\n礸\n禷\n禶\n籪\n纗\n羉\n艭\n虃\n蠸\n蠷\n蠵\n衋\n讔\n讕\n躞\n躟\n躠\n躝\n醾\n醽\n釂\n鑫\n鑨\n鑩\n雥\n靆\n靃\n靇\n韇\n韥\n驞\n髕\n魙\n鱣\n鱧\n鱦\n鱢\n鱞\n鱠\n鸂\n鷾\n鸇\n鸃\n鸆\n鸅\n鸀\n鸁\n鸉\n鷿\n鷽\n鸄\n麠\n鼞\n齆\n齴\n齵\n齶\n囔\n攮\n斸\n欘\n欙\n欗\n欚\n灢\n爦\n犪\n矘\n矙\n礹\n籩\n籫\n糶\n纚\n纘\n纛\n纙\n臠\n臡\n虆\n虇\n虈\n襹\n襺\n襼\n襻\n觿\n讘\n讙\n躥\n躤\n躣\n鑮\n鑭\n鑯\n鑱\n鑳\n靉\n顲\n饟\n鱨\n鱮\n鱭\n鸋\n鸍\n鸐\n鸏\n鸒\n鸑\n麡\n黵\n鼉\n齇\n齸\n齻\n齺\n齹\n圞\n灦\n籯\n蠼\n趲\n躦\n釃\n鑴\n鑸\n鑶\n鑵\n驠\n鱴\n鱳\n鱱\n鱵\n鸔\n鸓\n黶\n鼊\n龤\n灨\n灥\n糷\n虪\n蠾\n蠽\n蠿\n讞\n貜\n躩\n軉\n靋\n顳\n顴\n飌\n饡\n馫\n驤\n驦\n驧\n鬤\n鸕\n鸗\n齈\n戇\n欞\n爧\n虌\n躨\n钂\n钀\n钁\n驩\n驨\n鸙\n爩\n虋\n讟\n钃\n鱹\n麷\n癵\n驫\n鱺\n鸝\n灩\n灪\n麤\n齾\n齉\n龘\n碁\n裏\n墻\n恒\n粧\n嫺\n╔\n╦\n╗\n╠\n╬\n╣\n╚\n╩\n╝\n╒\n╤\n╕\n╞\n╪\n╡\n╘\n╧\n╛\n╓\n╥\n╖\n╟\n╫\n╢\n╙\n╨\n╜\n║\n═\n￭\n𠕇\n鋛\n𠗟\n𣿅\n蕌\n䊵\n珯\n况\n㙉\n𤥂\n𨧤\n鍄\n𡧛\n苮\n𣳈\n砼\n杄\n拟\n𤤳\n𨦪\n𠊠\n𦮳\n𡌅\n侫\n𢓭\n倈\n𦴩\n𧪄\n𣘀\n𤪱\n𢔓\n𠍾\n徤\n𠎀\n𠍇\n滛\n𠐟\n儁\n㑺\n儎\n顬\n㝃\n萖\n𤦤\n𠒇\n兠\n𣎴\n兪\n𠯿\n𢃼\n𠋥\n𢔰\n𠖎\n𣈳\n𡦃\n宂\n蝽\n𠖳\n𣲙\n冲\n冸\n鴴\n凉\n减\n凑\n㳜\n凓\n𤪦\n决\n凢\n卂\n凭\n菍\n椾\n𣜭\n彻\n刋\n刦\n刼\n劵\n剗\n劔\n効\n勅\n簕\n蕂\n勠\n蘍\n𦬓\n𨫞\n啉\n滙\n𣾀\n𠥔\n𣿬\n匳\n𠯢\n泋\n𡜦\n栛\n珕\n恊\n㺪\n㣌\n𡛨\n燝\n䒢\n卭\n却\n𨚫\n卾\n𡖖\n𡘓\n矦\n厓\n𨪛\n厠\n厫\n厮\n玧\n𥝲\n㽙\n玜\n叁\n叅\n汉\n义\n埾\n叙\n㪫\n𠮏\n叠\n𣿫\n𢶣\n叶\n𠱷\n吓\n灹\n唫\n晗\n浛\n呭\n𦭓\n𠵴\n啝\n咏\n咤\n䞦\n𡜍\n𠻝\n㶴\n𠵍\n𨦼\n𢚘\n啇\n䳭\n启\n琗\n喆\n喩\n𡣗\n𤀺\n䕒\n𤐵\n暳\n𡂴\n嘷\n曍\n𣊊\n暤\n暭\n噍\n噏\n磱\n囱\n鞇\n叾\n圀\n囯\n园\n𨭦\n㘣\n𡉏\n坆\n𤆥\n汮\n炋\n坂\n㚱\n𦱾\n埦\n𡐖\n堃\n𡑔\n𤍣\n堦\n𤯵\n塜\n墪\n㕡\n壠\n壜\n𡈼\n壻\n寿\n坃\n𪅐\n𤉸\n鏓\n㖡\n够\n梦\n㛃\n湙\n𡘾\n娤\n啓\n𡚒\n蔅\n姉\n𠵎\n𦲁\n𦴪\n𡟜\n姙\n𡟻\n𡞲\n𦶦\n浱\n𡠨\n𡛕\n姹\n𦹅\n媫\n婣\n㛦\n𤦩\n㜈\n媖\n瑥\n嫓\n𦾡\n𢕔\n㶅\n𡤑\n㜲\n𡚸\n広\n勐\n孶\n斈\n孼\n𧨎\n䀄\n䡝\n𠈄\n寕\n慠\n𡨴\n𥧌\n𠖥\n寳\n宝\n䴐\n尅\n𡭄\n尓\n珎\n尔\n𡲥\n𦬨\n屉\n䣝\n岅\n峩\n峯\n嶋\n𡷹\n𡸷\n崐\n崘\n嵆\n𡺤\n岺\n巗\n苼\n㠭\n𤤁\n𢁉\n𢅳\n芇\n㠶\n㯂\n帮\n檊\n幺\n𤒼\n𠳓\n厦\n亷\n厨\n𡝱\n帉\n𨒂\n廹\n廻\n㢠\n廼\n栾\n鐛\n弍\n𠇁\n弢\n㫞\n䢮\n𡌺\n强\n𦢈\n𢏐\n𢑱\n彣\n鞽\n𦹮\n彲\n鍀\n𨨶\n徧\n嶶\n㵟\n𥉐\n𡽪\n𧃸\n𢙨\n釖\n𠊞\n𨨩\n怱\n暅\n𡡷\n㥣\n㷇\n㘹\n垐\n𢞴\n祱\n㹀\n悞\n悳\n𤦂\n𤦏\n𧩓\n璤\n僡\n媠\n慤\n萤\n慂\n慈\n𦻒\n憁\n凴\n𠙖\n憇\n宪\n𣾷\n𢡟\n懓\n𨮝\n𩥝\n懐\n㤲\n𢦀\n𢣁\n怣\n慜\n攞\n掋\n𠄘\n担\n𡝰\n拕\n𢸍\n捬\n𤧟\n㨗\n搸\n揸\n𡎎\n𡟼\n澊\n𢸶\n頔\n𤂌\n𥜝\n擡\n擥\n鑻\n㩦\n携\n㩗\n敍\n漖\n𤨨\n𤨣\n斅\n敭\n敟\n𣁾\n斵\n𤥀\n䬷\n旑\n䃘\n𡠩\n旣\n忟\n𣐀\n昘\n𣇷\n𣇸\n晄\n𣆤\n𣆥\n晋\n𠹵\n晧\n𥇦\n晳\n𡸽\n𣈱\n𨗴\n𣇈\n𥌓\n矅\n𢣷\n馤\n朂\n𤎜\n𤨡\n㬫\n槺\n𣟂\n杧\n杢\n𤇍\n𩃭\n柗\n䓩\n栢\n湐\n鈼\n栁\n𣏦\n𦶠\n桝\n𣑯\n槡\n樋\n𨫟\n楳\n棃\n𣗍\n椁\n椀\n㴲\n㨁\n𣘼\n㮀\n枬\n楡\n𨩊\n䋼\n椶\n榘\n㮡\n𠏉\n荣\n傐\n槹\n𣙙\n𢄪\n橅\n𣜃\n檝\n㯳\n枱\n櫈\n𩆜\n㰍\n欝\n𠤣\n欵\n歴\n𢟍\n溵\n𣫛\n𠎵\n𡥘\n㝀\n吡\n𣭚\n毡\n𣻼\n毜\n氷\n𢒋\n𤣱\n𦭑\n汚\n舦\n汹\n𣶼\n䓅\n𣶽\n𤆤\n𤤌\n𤤀\n𣳉\n㛥\n㳫\n𠴲\n鮃\n𣇹\n𢒑\n羏\n样\n𦴥\n𦶡\n𦷫\n涖\n浜\n湼\n漄\n𤥿\n𤂅\n𦹲\n蔳\n𦽴\n凇\n萮\n𨬡\n𣸯\n瑓\n𣾂\n秌\n湏\n媑\n𣁋\n濸\n㜍\n澝\n𣸰\n滺\n𡒗\n𤀽\n䕕\n鏰\n潄\n潜\n㵎\n潴\n𩅰\n㴻\n澟\n𤅄\n濓\n𤂑\n𤅕\n𤀹\n𣿰\n𣾴\n𤄿\n凟\n𤅖\n𤅗\n𤅀\n𦇝\n灋\n灾\n炧\n炁\n烌\n烕\n烖\n烟\n䄄\n㷨\n熴\n熖\n𤉷\n焫\n煅\n媈\n煊\n岜\n𤍥\n煏\n鍢\n𤋁\n焬\n𤑚\n𤨧\n𤨢\n熺\n𨯨\n炽\n爎\n鑂\n爕\n夑\n鑃\n爤\n鍁\n𥘅\n爮\n牀\n𤥴\n梽\n牕\n牗\n㹕\n𣁄\n栍\n漽\n犂\n猫\n𤠣\n𨠫\n䣭\n𨠄\n猨\n献\n珏\n玪\n𠰺\n𦨮\n珉\n瑉\n𤇢\n𡛧\n𤨤\n昣\n㛅\n𤦷\n𤦍\n𤧻\n珷\n琕\n椃\n𤨦\n琹\n𠗃\n㻗\n𢢭\n瑠\n𨺲\n瑇\n珤\n瑶\n莹\n瑬\n㜰\n瑴\n鏱\n樬\n璂\n䥓\n𤪌\n𤅟\n𤩹\n𨮏\n孆\n𨰃\n𡢞\n瓈\n𡦈\n甎\n甞\n𨻙\n𡩋\n寗\n𨺬\n鎅\n畍\n畊\n畧\n畮\n𤾂\n㼄\n𤴓\n疎\n瑝\n疞\n疴\n瘂\n瘬\n癑\n癏\n癯\n𦏵\n皐\n臯\n㟸\n𦤑\n𦤎\n皡\n皥\n皷\n盌\n𦾟\n葢\n𥂝\n𥅽\n𡸜\n眞\n眦\n着\n撯\n𥈠\n睘\n𣊬\n瞯\n𨥤\n𨥨\n𡛁\n矴\n𡍶\n𤨒\n棊\n碯\n磇\n磓\n隥\n礮\n𥗠\n磗\n礴\n碱\n𧘌\n辸\n袄\n𨬫\n𦂃\n𢘜\n禆\n褀\n椂\n禀\n𥡗\n禝\n𧬹\n礼\n禩\n渪\n𧄦\n㺨\n秆\n𩄍\n秔\n"
  },
  {
    "path": "helix-view/tests/encoding/big5_out_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\n]\n^\n_\n`\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n¡\n¢\n£\n¤\n¥\n¦\n§\n¨\n©\nª\n«\n¬\n­\n®\n¯\n°\n±\n²\n³\n´\nµ\n¶\n·\n¸\n¹\nº\n»\n¼\n½\n¾\n¿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\ná\nâ\nã\nä\nå\næ\nç\nè\né\nê\në\nì\ní\nî\nï\nð\nñ\nò\nó\nô\nõ\nö\n÷\nø\nù\nú\nû\nü\ný\nþ\nÿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nġ\nĢ\nģ\nĤ\nĥ\nĦ\nħ\nĨ\nĩ\nĪ\nī\nĬ\nĭ\nĮ\nį\nİ\nı\nĲ\nĳ\nĴ\nĵ\nĶ\nķ\nĸ\nĹ\nĺ\nĻ\nļ\nĽ\nľ\nĿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nš\nŢ\nţ\nŤ\nť\nŦ\nŧ\nŨ\nũ\nŪ\nū\nŬ\nŭ\nŮ\nů\nŰ\nű\nŲ\nų\nŴ\nŵ\nŶ\nŷ\nŸ\nŹ\nź\nŻ\nż\nŽ\nž\nſ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nơ\nƢ\nƣ\nƤ\nƥ\nƦ\nƧ\nƨ\nƩ\nƪ\nƫ\nƬ\nƭ\nƮ\nƯ\nư\nƱ\nƲ\nƳ\nƴ\nƵ\nƶ\nƷ\nƸ\nƹ\nƺ\nƻ\nƼ\nƽ\nƾ\nƿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nǡ\nǢ\nǣ\nǤ\nǥ\nǦ\nǧ\nǨ\nǩ\nǪ\nǫ\nǬ\nǭ\nǮ\nǯ\nǰ\nǱ\nǲ\nǳ\nǴ\nǵ\nǶ\nǷ\nǸ\nǹ\nǺ\nǻ\nǼ\nǽ\nǾ\nǿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nȡ\nȢ\nȣ\nȤ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nɡ\nɢ\nɣ\nɤ\nɥ\nɦ\nɧ\nɨ\nɩ\nɪ\nɫ\nɬ\nɭ\nɮ\nɯ\nɰ\nɱ\nɲ\nɳ\nɴ\nɵ\nɶ\nɷ\nɸ\nɹ\nɺ\nɻ\nɼ\nɽ\nɾ\nɿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nʡ\nʢ\nʣ\nʤ\nʥ\nʦ\nʧ\nʨ\nʩ\nʪ\nʫ\nʬ\nʭ\nʮ\nʯ\nʰ\nʱ\nʲ\nʳ\nʴ\nʵ\nʶ\nʷ\nʸ\nʹ\nʺ\nʻ\nʼ\nʽ\nʾ\nʿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nˡ\nˢ\nˣ\nˤ\n˥\n˦\n˧\n˨\n˩\n˪\n˫\nˬ\n˭\nˮ\n˯\n˰\n˱\n˲\n˳\n˴\n˵\n˶\n˷\n˸\n˹\n˺\n˻\n˼\n˽\n˾\n˿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n̡\n̢\ṇ\n̤\n̥\n̦\ņ\n̨\n̩\n̪\n̫\n̬\ṋ\n̮\n̯\n̰\ṉ\n̲\n̳\n̴\n̵\n̶\n̷\n̸\n̹\n̺\n̻\n̼\n̽\n̾\n̿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n͡\n͢\nͣ\nͤ\nͥ\nͦ\nͧ\nͨ\nͩ\nͪ\nͫ\nͬ\nͭ\nͮ\nͯ\nͰ\nͱ\nͲ\nͳ\nʹ\n͵\nͶ\nͷ\n͸\n͹\nͺ\nͻ\nͼ\nͽ\n;\nͿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nΡ\n΢\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nΪ\nΫ\nά\nέ\nή\nί\nΰ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nϡ\nϢ\nϣ\nϤ\nϥ\nϦ\nϧ\nϨ\nϩ\nϪ\nϫ\nϬ\nϭ\nϮ\nϯ\nϰ\nϱ\nϲ\nϳ\nϴ\nϵ\n϶\nϷ\nϸ\nϹ\nϺ\nϻ\nϼ\nϽ\nϾ\nϿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nѡ\nѢ\nѣ\nѤ\nѥ\nѦ\nѧ\nѨ\nѩ\nѪ\nѫ\nѬ\nѭ\nѮ\nѯ\nѰ\nѱ\nѲ\nѳ\nѴ\nѵ\nѶ\nѷ\nѸ\nѹ\nѺ\nѻ\nѼ\nѽ\nѾ\nѿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nҡ\nҢ\nң\nҤ\nҥ\nҦ\nҧ\nҨ\nҩ\nҪ\nҫ\nҬ\nҭ\nҮ\nү\nҰ\nұ\nҲ\nҳ\nҴ\nҵ\nҶ\nҷ\nҸ\nҹ\nҺ\nһ\nҼ\nҽ\nҾ\nҿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nӡ\nӢ\nӣ\nӤ\nӥ\nӦ\nӧ\nӨ\nө\nӪ\nӫ\nӬ\nӭ\nӮ\nӯ\nӰ\nӱ\nӲ\nӳ\nӴ\nӵ\nӶ\nӷ\nӸ\nӹ\nӺ\nӻ\nӼ\nӽ\nӾ\nӿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nԡ\nԢ\nԣ\nԤ\nԥ\nԦ\nԧ\nԨ\nԩ\nԪ\nԫ\nԬ\nԭ\nԮ\nԯ\n԰\nԱ\nԲ\nԳ\nԴ\nԵ\nԶ\nԷ\nԸ\nԹ\nԺ\nԻ\nԼ\nԽ\nԾ\nԿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nա\nբ\nգ\nդ\nե\nզ\nէ\nը\nթ\nժ\nի\nլ\nխ\nծ\nկ\nհ\nձ\nղ\nճ\nմ\nյ\nն\nշ\nո\nչ\nպ\nջ\nռ\nս\nվ\nտ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n֡\n֢\n֣\n֤\n֥\n֦\n֧\n֨\n֩\n֪\n֫\n֬\n֭\n֮\n֯\nְ\nֱ\nֲ\nֳ\nִ\nֵ\nֶ\nַ\nָ\nֹ\nֺ\nֻ\nּ\nֽ\n־\nֿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nס\nע\nף\nפ\nץ\nצ\nק\nר\nש\nת\n׫\n׬\n׭\n׮\nׯ\nװ\nױ\nײ\n׳\n״\n׵\n׶\n׷\n׸\n׹\n׺\n׻\n׼\n׽\n׾\n׿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nء\nآ\nأ\nؤ\nإ\nئ\nا\nب\nة\nت\nث\nج\nح\nخ\nد\nذ\nر\nز\nس\nش\nص\nض\nط\nظ\nع\nغ\nػ\nؼ\nؽ\nؾ\nؿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n١\n٢\n٣\n٤\n٥\n٦\n٧\n٨\n٩\n٪\n٫\n٬\n٭\nٮ\nٯ\nٰ\nٱ\nٲ\nٳ\nٴ\nٵ\nٶ\nٷ\nٸ\nٹ\nٺ\nٻ\nټ\nٽ\nپ\nٿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nڡ\nڢ\nڣ\nڤ\nڥ\nڦ\nڧ\nڨ\nک\nڪ\nګ\nڬ\nڭ\nڮ\nگ\nڰ\nڱ\nڲ\nڳ\nڴ\nڵ\nڶ\nڷ\nڸ\nڹ\nں\nڻ\nڼ\nڽ\nھ\nڿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\nz\n{\n|\n}\n~\nۡ\nۢ\nۣ\nۤ\nۥ\nۦ\nۧ\nۨ\n۩\n۪\n۫\n۬\nۭ\nۮ\nۯ\n۰\n۱\n۲\n۳\n۴\n۵\n۶\n۷\n۸\n۹\nۺ\nۻ\nۼ\n۽\n۾\nۿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nܡ\nܢ\nܣ\nܤ\nܥ\nܦ\nܧ\nܨ\nܩ\nܪ\nܫ\nܬ\nܭ\nܮ\nܯ\nܰ\nܱ\nܲ\nܳ\nܴ\nܵ\nܶ\nܷ\nܸ\nܹ\nܺ\nܻ\nܼ\nܽ\nܾ\nܿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nݡ\nݢ\nݣ\nݤ\nݥ\nݦ\nݧ\nݨ\nݩ\nݪ\nݫ\nݬ\nݭ\nݮ\nݯ\nݰ\nݱ\nݲ\nݳ\nݴ\nݵ\nݶ\nݷ\nݸ\nݹ\nݺ\nݻ\nݼ\nݽ\nݾ\nݿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nޡ\nޢ\nޣ\nޤ\nޥ\nަ\nާ\nި\nީ\nު\nޫ\nެ\nޭ\nޮ\nޯ\nް\nޱ\n޲\n޳\n޴\n޵\n޶\n޷\n޸\n޹\n޺\n޻\n޼\n޽\n޾\n޿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nߡ\nߢ\nߣ\nߤ\nߥ\nߦ\nߧ\nߨ\nߩ\nߪ\n߫\n߬\n߭\n߮\n߯\n߰\n߱\n߲\n߳\nߴ\nߵ\n߶\n߷\n߸\n߹\nߺ\n߻\n߼\n߽\n߾\n߿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n`\na\nb\nc\nd\ne\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/euc_kr_in.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n¡\n¢\n£\n¤\n¥\n¦\n§\n¨\n©\nª\n«\n¬\n­\n®\n¯\n°\n±\n²\n³\n´\nµ\n¶\n·\n¸\n¹\nº\n»\n¼\n½\n¾\n¿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nÀ\nÁ\nÂ\nÃ\nÄ\nÅ\nÆ\nÇ\nÈ\nÉ\nÊ\nË\nÌ\nÍ\nÎ\nÏ\nÐ\nÑ\nÒ\nÓ\nÔ\nÕ\nÖ\n×\nØ\nÙ\nÚ\nÛ\nÜ\nÝ\nÞ\nß\nà\ná\nâ\nã\nä\nå\næ\nç\nè\né\nê\në\nì\ní\nî\nï\nð\nñ\nò\nó\nô\nõ\nö\n÷\nø\nù\nú\nû\nü\ný\nþ\nÿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nĀ\nā\nĂ\nă\nĄ\ną\nĆ\nć\nĈ\nĉ\nĊ\nċ\nČ\nč\nĎ\nď\nĐ\nđ\nĒ\nē\nĔ\nĕ\nĖ\nė\nĘ\nę\nĚ\ně\nĜ\nĝ\nĞ\nğ\nĠ\nġ\nĢ\nģ\nĤ\nĥ\nĦ\nħ\nĨ\nĩ\nĪ\nī\nĬ\nĭ\nĮ\nį\nİ\nı\nĲ\nĳ\nĴ\nĵ\nĶ\nķ\nĸ\nĹ\nĺ\nĻ\nļ\nĽ\nľ\nĿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nŀ\nŁ\nł\nŃ\nń\nŅ\nņ\nŇ\nň\nŉ\nŊ\nŋ\nŌ\nō\nŎ\nŏ\nŐ\nő\nŒ\nœ\nŔ\nŕ\nŖ\nŗ\nŘ\nř\nŚ\nś\nŜ\nŝ\nŞ\nş\nŠ\nš\nŢ\nţ\nŤ\nť\nŦ\nŧ\nŨ\nũ\nŪ\nū\nŬ\nŭ\nŮ\nů\nŰ\nű\nŲ\nų\nŴ\nŵ\nŶ\nŷ\nŸ\nŹ\nź\nŻ\nż\nŽ\nž\nſ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nƀ\nƁ\nƂ\nƃ\nƄ\nƅ\nƆ\nƇ\nƈ\nƉ\nƊ\nƋ\nƌ\nƍ\nƎ\nƏ\nƐ\nƑ\nƒ\nƓ\nƔ\nƕ\nƖ\nƗ\nƘ\nƙ\nƚ\nƛ\nƜ\nƝ\nƞ\nƟ\nƠ\nơ\nƢ\nƣ\nƤ\nƥ\nƦ\nƧ\nƨ\nƩ\nƪ\nƫ\nƬ\nƭ\nƮ\nƯ\nư\nƱ\nƲ\nƳ\nƴ\nƵ\nƶ\nƷ\nƸ\nƹ\nƺ\nƻ\nƼ\nƽ\nƾ\nƿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nǀ\nǁ\nǂ\nǃ\nǄ\nǅ\nǆ\nǇ\nǈ\nǉ\nǊ\nǋ\nǌ\nǍ\nǎ\nǏ\nǐ\nǑ\nǒ\nǓ\nǔ\nǕ\nǖ\nǗ\nǘ\nǙ\nǚ\nǛ\nǜ\nǝ\nǞ\nǟ\nǠ\nǡ\nǢ\nǣ\nǤ\nǥ\nǦ\nǧ\nǨ\nǩ\nǪ\nǫ\nǬ\nǭ\nǮ\nǯ\nǰ\nǱ\nǲ\nǳ\nǴ\nǵ\nǶ\nǷ\nǸ\nǹ\nǺ\nǻ\nǼ\nǽ\nǾ\nǿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nȀ\nȁ\nȂ\nȃ\nȄ\nȅ\nȆ\nȇ\nȈ\nȉ\nȊ\nȋ\nȌ\nȍ\nȎ\nȏ\nȐ\nȑ\nȒ\nȓ\nȔ\nȕ\nȖ\nȗ\nȘ\nș\nȚ\nț\nȜ\nȝ\nȞ\nȟ\nȠ\nȡ\nȢ\nȣ\nȤ\nȥ\nȦ\nȧ\nȨ\nȩ\nȪ\nȫ\nȬ\nȭ\nȮ\nȯ\nȰ\nȱ\nȲ\nȳ\nȴ\nȵ\nȶ\nȷ\nȸ\nȹ\nȺ\nȻ\nȼ\nȽ\nȾ\nȿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nɀ\nɁ\nɂ\nɃ\nɄ\nɅ\nɆ\nɇ\nɈ\nɉ\nɊ\nɋ\nɌ\nɍ\nɎ\nɏ\nɐ\nɑ\nɒ\nɓ\nɔ\nɕ\nɖ\nɗ\nɘ\nə\nɚ\nɛ\nɜ\nɝ\nɞ\nɟ\nɠ\nɡ\nɢ\nɣ\nɤ\nɥ\nɦ\nɧ\nɨ\nɩ\nɪ\nɫ\nɬ\nɭ\nɮ\nɯ\nɰ\nɱ\nɲ\nɳ\nɴ\nɵ\nɶ\nɷ\nɸ\nɹ\nɺ\nɻ\nɼ\nɽ\nɾ\nɿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nʀ\nʁ\nʂ\nʃ\nʄ\nʅ\nʆ\nʇ\nʈ\nʉ\nʊ\nʋ\nʌ\nʍ\nʎ\nʏ\nʐ\nʑ\nʒ\nʓ\nʔ\nʕ\nʖ\nʗ\nʘ\nʙ\nʚ\nʛ\nʜ\nʝ\nʞ\nʟ\nʠ\nʡ\nʢ\nʣ\nʤ\nʥ\nʦ\nʧ\nʨ\nʩ\nʪ\nʫ\nʬ\nʭ\nʮ\nʯ\nʰ\nʱ\nʲ\nʳ\nʴ\nʵ\nʶ\nʷ\nʸ\nʹ\nʺ\nʻ\nʼ\nʽ\nʾ\nʿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nˀ\nˁ\n˂\n˃\n˄\n˅\nˆ\nˇ\nˈ\nˉ\nˊ\nˋ\nˌ\nˍ\nˎ\nˏ\nː\nˑ\n˒\n˓\n˔\n˕\n˖\n˗\n˘\n˙\n˚\n˛\n˜\n˝\n˞\n˟\nˠ\nˡ\nˢ\nˣ\nˤ\n˥\n˦\n˧\n˨\n˩\n˪\n˫\nˬ\n˭\nˮ\n˯\n˰\n˱\n˲\n˳\n˴\n˵\n˶\n˷\n˸\n˹\n˺\n˻\n˼\n˽\n˾\n˿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\ǹ\ń\n̂\ñ\n̄\n̅\n̆\ṅ\n̈\n̉\n̊\n̋\ň\n̍\n̎\n̏\n̐\n̑\n̒\n̓\n̔\n̕\n̖\n̗\n̘\n̙\n̚\n̛\n̜\n̝\n̞\n̟\n̠\n̡\n̢\ṇ\n̤\n̥\n̦\ņ\n̨\n̩\n̪\n̫\n̬\ṋ\n̮\n̯\n̰\ṉ\n̲\n̳\n̴\n̵\n̶\n̷\n̸\n̹\n̺\n̻\n̼\n̽\n̾\n̿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\ǹ\ń\n͂\n̓\n̈́\nͅ\n͆\n͇\n͈\n͉\n͊\n͋\n͌\n͍\n͎\n͏\n͐\n͑\n͒\n͓\n͔\n͕\n͖\n͗\n͘\n͙\n͚\n͛\n͜\n͝\n͞\n͟\n͠\n͡\n͢\nͣ\nͤ\nͥ\nͦ\nͧ\nͨ\nͩ\nͪ\nͫ\nͬ\nͭ\nͮ\nͯ\nͰ\nͱ\nͲ\nͳ\nʹ\n͵\nͶ\nͷ\n͸\n͹\nͺ\nͻ\nͼ\nͽ\n;\nͿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n΀\n΁\n΂\n΃\n΄\n΅\nΆ\n·\nΈ\nΉ\nΊ\n΋\nΌ\n΍\nΎ\nΏ\nΐ\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\n΢\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nΪ\nΫ\nά\nέ\nή\nί\nΰ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nπ\nρ\nς\nσ\nτ\nυ\nφ\nχ\nψ\nω\nϊ\nϋ\nό\nύ\nώ\nϏ\nϐ\nϑ\nϒ\nϓ\nϔ\nϕ\nϖ\nϗ\nϘ\nϙ\nϚ\nϛ\nϜ\nϝ\nϞ\nϟ\nϠ\nϡ\nϢ\nϣ\nϤ\nϥ\nϦ\nϧ\nϨ\nϩ\nϪ\nϫ\nϬ\nϭ\nϮ\nϯ\nϰ\nϱ\nϲ\nϳ\nϴ\nϵ\n϶\nϷ\nϸ\nϹ\nϺ\nϻ\nϼ\nϽ\nϾ\nϿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nЀ\nЁ\nЂ\nЃ\nЄ\nЅ\nІ\nЇ\nЈ\nЉ\nЊ\nЋ\nЌ\nЍ\nЎ\nЏ\nА\nБ\nВ\nГ\nД\nЕ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\nѐ\nё\nђ\nѓ\nє\nѕ\nі\nї\nј\nљ\nњ\nћ\nќ\nѝ\nў\nџ\nѠ\nѡ\nѢ\nѣ\nѤ\nѥ\nѦ\nѧ\nѨ\nѩ\nѪ\nѫ\nѬ\nѭ\nѮ\nѯ\nѰ\nѱ\nѲ\nѳ\nѴ\nѵ\nѶ\nѷ\nѸ\nѹ\nѺ\nѻ\nѼ\nѽ\nѾ\nѿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nҀ\nҁ\n҂\n҃\n҄\n҅\n҆\n҇\n҈\n҉\nҊ\nҋ\nҌ\nҍ\nҎ\nҏ\nҐ\nґ\nҒ\nғ\nҔ\nҕ\nҖ\nҗ\nҘ\nҙ\nҚ\nқ\nҜ\nҝ\nҞ\nҟ\nҠ\nҡ\nҢ\nң\nҤ\nҥ\nҦ\nҧ\nҨ\nҩ\nҪ\nҫ\nҬ\nҭ\nҮ\nү\nҰ\nұ\nҲ\nҳ\nҴ\nҵ\nҶ\nҷ\nҸ\nҹ\nҺ\nһ\nҼ\nҽ\nҾ\nҿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nӀ\nӁ\nӂ\nӃ\nӄ\nӅ\nӆ\nӇ\nӈ\nӉ\nӊ\nӋ\nӌ\nӍ\nӎ\nӏ\nӐ\nӑ\nӒ\nӓ\nӔ\nӕ\nӖ\nӗ\nӘ\nә\nӚ\nӛ\nӜ\nӝ\nӞ\nӟ\nӠ\nӡ\nӢ\nӣ\nӤ\nӥ\nӦ\nӧ\nӨ\nө\nӪ\nӫ\nӬ\nӭ\nӮ\nӯ\nӰ\nӱ\nӲ\nӳ\nӴ\nӵ\nӶ\nӷ\nӸ\nӹ\nӺ\nӻ\nӼ\nӽ\nӾ\nӿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nԀ\nԁ\nԂ\nԃ\nԄ\nԅ\nԆ\nԇ\nԈ\nԉ\nԊ\nԋ\nԌ\nԍ\nԎ\nԏ\nԐ\nԑ\nԒ\nԓ\nԔ\nԕ\nԖ\nԗ\nԘ\nԙ\nԚ\nԛ\nԜ\nԝ\nԞ\nԟ\nԠ\nԡ\nԢ\nԣ\nԤ\nԥ\nԦ\nԧ\nԨ\nԩ\nԪ\nԫ\nԬ\nԭ\nԮ\nԯ\n԰\nԱ\nԲ\nԳ\nԴ\nԵ\nԶ\nԷ\nԸ\nԹ\nԺ\nԻ\nԼ\nԽ\nԾ\nԿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nՀ\nՁ\nՂ\nՃ\nՄ\nՅ\nՆ\nՇ\nՈ\nՉ\nՊ\nՋ\nՌ\nՍ\nՎ\nՏ\nՐ\nՑ\nՒ\nՓ\nՔ\nՕ\nՖ\n՗\n՘\nՙ\n՚\n՛\n՜\n՝\n՞\n՟\nՠ\nա\nբ\nգ\nդ\nե\nզ\nէ\nը\nթ\nժ\nի\nլ\nխ\nծ\nկ\nհ\nձ\nղ\nճ\nմ\nյ\nն\nշ\nո\nչ\nպ\nջ\nռ\nս\nվ\nտ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nր\nց\nւ\nփ\nք\nօ\nֆ\nև\nֈ\n։\n֊\n֋\n֌\n֍\n֎\n֏\n֐\n֑\n֒\n֓\n֔\n֕\n֖\n֗\n֘\n֙\n֚\n֛\n֜\n֝\n֞\n֟\n֠\n֡\n֢\n֣\n֤\n֥\n֦\n֧\n֨\n֩\n֪\n֫\n֬\n֭\n֮\n֯\nְ\nֱ\nֲ\nֳ\nִ\nֵ\nֶ\nַ\nָ\nֹ\nֺ\nֻ\nּ\nֽ\n־\nֿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n׀\nׁ\nׂ\n׃\nׄ\nׅ\n׆\nׇ\n׈\n׉\n׊\n׋\n׌\n׍\n׎\n׏\nא\nב\nג\nד\nה\nו\nז\nח\nט\nי\nך\nכ\nל\nם\nמ\nן\nנ\nס\nע\nף\nפ\nץ\nצ\nק\nר\nש\nת\n׫\n׬\n׭\n׮\nׯ\nװ\nױ\nײ\n׳\n״\n׵\n׶\n׷\n׸\n׹\n׺\n׻\n׼\n׽\n׾\n׿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n؀\n؁\n؂\n؃\n؄\n؅\n؆\n؇\n؈\n؉\n؊\n؋\n،\n؍\n؎\n؏\nؐ\nؑ\nؒ\nؓ\nؔ\nؕ\nؖ\nؗ\nؘ\nؙ\nؚ\n؛\n؜\n؝\n؞\n؟\nؠ\nء\nآ\nأ\nؤ\nإ\nئ\nا\nب\nة\nت\nث\nج\nح\nخ\nد\nذ\nر\nز\nس\nش\nص\nض\nط\nظ\nع\nغ\nػ\nؼ\nؽ\nؾ\nؿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nـ\nف\nق\nك\nل\nم\nن\nه\nو\nى\nي\nً\nٌ\nٍ\nَ\nُ\nِ\nّ\nْ\nٓ\nٔ\nٕ\nٖ\nٗ\n٘\nٙ\nٚ\nٛ\nٜ\nٝ\nٞ\nٟ\n٠\n١\n٢\n٣\n٤\n٥\n٦\n٧\n٨\n٩\n٪\n٫\n٬\n٭\nٮ\nٯ\nٰ\nٱ\nٲ\nٳ\nٴ\nٵ\nٶ\nٷ\nٸ\nٹ\nٺ\nٻ\nټ\nٽ\nپ\nٿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nڀ\nځ\nڂ\nڃ\nڄ\nڅ\nچ\nڇ\nڈ\nډ\nڊ\nڋ\nڌ\nڍ\nڎ\nڏ\nڐ\nڑ\nڒ\nړ\nڔ\nڕ\nږ\nڗ\nژ\nڙ\nښ\nڛ\nڜ\nڝ\nڞ\nڟ\nڠ\nڡ\nڢ\nڣ\nڤ\nڥ\nڦ\nڧ\nڨ\nک\nڪ\nګ\nڬ\nڭ\nڮ\nگ\nڰ\nڱ\nڲ\nڳ\nڴ\nڵ\nڶ\nڷ\nڸ\nڹ\nں\nڻ\nڼ\nڽ\nھ\nڿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nۀ\nہ\nۂ\nۃ\nۄ\nۅ\nۆ\nۇ\nۈ\nۉ\nۊ\nۋ\nی\nۍ\nێ\nۏ\nې\nۑ\nے\nۓ\n۔\nە\nۖ\nۗ\nۘ\nۙ\nۚ\nۛ\nۜ\n۝\n۞\n۟\n۠\nۡ\nۢ\nۣ\nۤ\nۥ\nۦ\nۧ\nۨ\n۩\n۪\n۫\n۬\nۭ\nۮ\nۯ\n۰\n۱\n۲\n۳\n۴\n۵\n۶\n۷\n۸\n۹\nۺ\nۻ\nۼ\n۽\n۾\nۿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n܀\n܁\n܂\n܃\n܄\n܅\n܆\n܇\n܈\n܉\n܊\n܋\n܌\n܍\n܎\n܏\nܐ\nܑ\nܒ\nܓ\nܔ\nܕ\nܖ\nܗ\nܘ\nܙ\nܚ\nܛ\nܜ\nܝ\nܞ\nܟ\nܠ\nܡ\nܢ\nܣ\nܤ\nܥ\nܦ\nܧ\nܨ\nܩ\nܪ\nܫ\nܬ\nܭ\nܮ\nܯ\nܰ\nܱ\nܲ\nܳ\nܴ\nܵ\nܶ\nܷ\nܸ\nܹ\nܺ\nܻ\nܼ\nܽ\nܾ\nܿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n݀\n݁\n݂\n݃\n݄\n݅\n݆\n݇\n݈\n݉\n݊\n݋\n݌\nݍ\nݎ\nݏ\nݐ\nݑ\nݒ\nݓ\nݔ\nݕ\nݖ\nݗ\nݘ\nݙ\nݚ\nݛ\nݜ\nݝ\nݞ\nݟ\nݠ\nݡ\nݢ\nݣ\nݤ\nݥ\nݦ\nݧ\nݨ\nݩ\nݪ\nݫ\nݬ\nݭ\nݮ\nݯ\nݰ\nݱ\nݲ\nݳ\nݴ\nݵ\nݶ\nݷ\nݸ\nݹ\nݺ\nݻ\nݼ\nݽ\nݾ\nݿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\nހ\nށ\nނ\nރ\nބ\nޅ\nކ\nއ\nވ\nމ\nފ\nދ\nތ\nލ\nގ\nޏ\nސ\nޑ\nޒ\nޓ\nޔ\nޕ\nޖ\nޗ\nޘ\nޙ\nޚ\nޛ\nޜ\nޝ\nޞ\nޟ\nޠ\nޡ\nޢ\nޣ\nޤ\nޥ\nަ\nާ\nި\nީ\nު\nޫ\nެ\nޭ\nޮ\nޯ\nް\nޱ\n޲\n޳\n޴\n޵\n޶\n޷\n޸\n޹\n޺\n޻\n޼\n޽\n޾\n޿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n߀\n߁\n߂\n߃\n߄\n߅\n߆\n߇\n߈\n߉\nߊ\nߋ\nߌ\nߍ\nߎ\nߏ\nߐ\nߑ\nߒ\nߓ\nߔ\nߕ\nߖ\nߗ\nߘ\nߙ\nߚ\nߛ\nߜ\nߝ\nߞ\nߟ\nߠ\nߡ\nߢ\nߣ\nߤ\nߥ\nߦ\nߧ\nߨ\nߩ\nߪ\n߫\n߬\n߭\n߮\n߯\n߰\n߱\n߲\n߳\nߴ\nߵ\n߶\n߷\n߸\n߹\nߺ\n߻\n߼\n߽\n߾\n߿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/euc_kr_in_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n갂\n갃\n갅\n갆\n갋\n갌\n갍\n갎\n갏\n갘\n갞\n갟\n갡\n갢\n갣\n갥\n갦\n갧\n갨\n갩\n갪\n갫\n갮\n갲\n갳\n갴\n�[\n�\\\n�]\n�^\n�_\n�`\n갵\n갶\n갷\n갺\n갻\n갽\n갾\n갿\n걁\n걂\n걃\n걄\n걅\n걆\n걇\n걈\n걉\n걊\n걌\n걎\n걏\n걐\n걑\n걒\n걓\n걕\n�{\n�|\n�}\n�~\n�\n�\n걖\n걗\n걙\n걚\n걛\n걝\n걞\n걟\n걠\n걡\n걢\n걣\n걤\n걥\n걦\n걧\n걨\n걩\n걪\n걫\n걬\n걭\n걮\n걯\n걲\n걳\n걵\n걶\n걹\n걻\n걼\n걽\n걾\n걿\n겂\n겇\n겈\n겍\n겎\n겏\n겑\n겒\n겓\n겕\n겖\n겗\n겘\n겙\n겚\n겛\n겞\n겢\n겣\n겤\n겥\n겦\n겧\n겫\n겭\n겮\n겱\n겲\n겳\n겴\n겵\n겶\n겷\n겺\n겾\n겿\n곀\n곂\n곃\n곅\n곆\n곇\n곉\n곊\n곋\n곍\n곎\n곏\n곐\n곑\n곒\n곓\n곔\n곖\n곘\n곙\n곚\n곛\n곜\n곝\n곞\n곟\n곢\n곣\n곥\n곦\n곩\n곫\n곭\n곮\n곲\n곴\n곷\n곸\n곹\n곺\n곻\n곾\n곿\n괁\n괂\n괃\n괅\n괇\n괈\n괉\n괊\n괋\n괎\n괐\n괒\n괓\n괔\n괕\n괖\n괗\n괙\n괚\n괛\n괝\n괞\n괟\n괡\n괢\n괣\n괤\n괥\n괦\n괧\n괨\n괪\n괫\n괮\n괯\n괰\n괱\n괲\n괳\n�[\n�\\\n�]\n�^\n�_\n�`\n괶\n괷\n괹\n괺\n괻\n괽\n괾\n괿\n굀\n굁\n굂\n굃\n굆\n굈\n굊\n굋\n굌\n굍\n굎\n굏\n굑\n굒\n굓\n굕\n굖\n굗\n�{\n�|\n�}\n�~\n�\n�\n굙\n굚\n굛\n굜\n굝\n굞\n굟\n굠\n굢\n굤\n굥\n굦\n굧\n굨\n굩\n굪\n굫\n굮\n굯\n굱\n굲\n굷\n굸\n굹\n굺\n굾\n궀\n궃\n궄\n궅\n궆\n궇\n궊\n궋\n궍\n궎\n궏\n궑\n궒\n궓\n궔\n궕\n궖\n궗\n궘\n궙\n궚\n궛\n궞\n궟\n궠\n궡\n궢\n궣\n궥\n궦\n궧\n궨\n궩\n궪\n궫\n궬\n궭\n궮\n궯\n궰\n궱\n궲\n궳\n궴\n궵\n궶\n궸\n궹\n궺\n궻\n궼\n궽\n궾\n궿\n귂\n귃\n귅\n귆\n귇\n귉\n귊\n귋\n귌\n귍\n귎\n귏\n귒\n귔\n귕\n귖\n귗\n귘\n귙\n귚\n귛\n귝\n귞\n귟\n귡\n귢\n귣\n귥\n귦\n귧\n귨\n귩\n귪\n귫\n귬\n귭\n귮\n귯\n귰\n귱\n귲\n귳\n귴\n귵\n귶\n귷\n귺\n귻\n귽\n귾\n긂\n긃\n긄\n긅\n긆\n긇\n긊\n긌\n긎\n긏\n긐\n긑\n긒\n긓\n긕\n긖\n긗\n긘\n긙\n긚\n긛\n긜\n�[\n�\\\n�]\n�^\n�_\n�`\n긝\n긞\n긟\n긠\n긡\n긢\n긣\n긤\n긥\n긦\n긧\n긨\n긩\n긪\n긫\n긬\n긭\n긮\n긯\n긲\n긳\n긵\n긶\n긹\n긻\n긼\n�{\n�|\n�}\n�~\n�\n�\n긽\n긾\n긿\n깂\n깄\n깇\n깈\n깉\n깋\n깏\n깑\n깒\n깓\n깕\n깗\n깘\n깙\n깚\n깛\n깞\n깢\n깣\n깤\n깦\n깧\n깪\n깫\n깭\n깮\n깯\n깱\n깲\n깳\n깴\n깵\n깶\n깷\n깺\n깾\n깿\n꺀\n꺁\n꺂\n꺃\n꺆\n꺇\n꺈\n꺉\n꺊\n꺋\n꺍\n꺎\n꺏\n꺐\n꺑\n꺒\n꺓\n꺔\n꺕\n꺖\n꺗\n꺘\n꺙\n꺚\n꺛\n꺜\n꺝\n꺞\n꺟\n꺠\n꺡\n꺢\n꺣\n꺤\n꺥\n꺦\n꺧\n꺨\n꺩\n꺪\n꺫\n꺬\n꺭\n꺮\n꺯\n꺰\n꺱\n꺲\n꺳\n꺴\n꺵\n꺶\n꺷\n꺸\n꺹\n꺺\n꺻\n꺿\n껁\n껂\n껃\n껅\n껆\n껇\n껈\n껉\n껊\n껋\n껎\n껒\n껓\n껔\n껕\n껖\n껗\n껚\n껛\n껝\n껞\n껟\n껠\n껡\n껢\n껣\n껤\n껥\n껦\n껧\n껩\n껪\n껬\n껮\n껯\n껰\n껱\n껲\n껳\n껵\n껶\n껷\n껹\n껺\n껻\n껽\n껾\n껿\n꼀\n꼁\n꼂\n꼃\n꼄\n꼅\n�[\n�\\\n�]\n�^\n�_\n�`\n꼆\n꼉\n꼊\n꼋\n꼌\n꼎\n꼏\n꼑\n꼒\n꼓\n꼔\n꼕\n꼖\n꼗\n꼘\n꼙\n꼚\n꼛\n꼜\n꼝\n꼞\n꼟\n꼠\n꼡\n꼢\n꼣\n�{\n�|\n�}\n�~\n�\n�\n꼤\n꼥\n꼦\n꼧\n꼨\n꼩\n꼪\n꼫\n꼮\n꼯\n꼱\n꼳\n꼵\n꼶\n꼷\n꼸\n꼹\n꼺\n꼻\n꼾\n꽀\n꽄\n꽅\n꽆\n꽇\n꽊\n꽋\n꽌\n꽍\n꽎\n꽏\n꽑\n꽒\n꽓\n꽔\n꽕\n꽖\n꽗\n꽘\n꽙\n꽚\n꽛\n꽞\n꽟\n꽠\n꽡\n꽢\n꽣\n꽦\n꽧\n꽨\n꽩\n꽪\n꽫\n꽬\n꽭\n꽮\n꽯\n꽰\n꽱\n꽲\n꽳\n꽴\n꽵\n꽶\n꽷\n꽸\n꽺\n꽻\n꽼\n꽽\n꽾\n꽿\n꾁\n꾂\n꾃\n꾅\n꾆\n꾇\n꾉\n꾊\n꾋\n꾌\n꾍\n꾎\n꾏\n꾒\n꾓\n꾔\n꾖\n꾗\n꾘\n꾙\n꾚\n꾛\n꾝\n꾞\n꾟\n꾠\n꾡\n꾢\n꾣\n꾤\n꾥\n꾦\n꾧\n꾨\n꾩\n꾪\n꾫\n꾬\n꾭\n꾮\n꾯\n꾰\n꾱\n꾲\n꾳\n꾴\n꾵\n꾶\n꾷\n꾺\n꾻\n꾽\n꾾\n꾿\n꿁\n꿂\n꿃\n꿄\n꿅\n꿆\n꿊\n꿌\n꿏\n꿐\n꿑\n꿒\n꿓\n꿕\n꿖\n꿗\n꿘\n꿙\n꿚\n꿛\n꿝\n꿞\n꿟\n꿠\n꿡\n�[\n�\\\n�]\n�^\n�_\n�`\n꿢\n꿣\n꿤\n꿥\n꿦\n꿧\n꿪\n꿫\n꿬\n꿭\n꿮\n꿯\n꿲\n꿳\n꿵\n꿶\n꿷\n꿹\n꿺\n꿻\n꿼\n꿽\n꿾\n꿿\n뀂\n뀃\n�{\n�|\n�}\n�~\n�\n�\n뀅\n뀆\n뀇\n뀈\n뀉\n뀊\n뀋\n뀍\n뀎\n뀏\n뀑\n뀒\n뀓\n뀕\n뀖\n뀗\n뀘\n뀙\n뀚\n뀛\n뀞\n뀟\n뀠\n뀡\n뀢\n뀣\n뀤\n뀥\n뀦\n뀧\n뀩\n뀪\n뀫\n뀬\n뀭\n뀮\n뀯\n뀰\n뀱\n뀲\n뀳\n뀴\n뀵\n뀶\n뀷\n뀸\n뀹\n뀺\n뀻\n뀼\n뀽\n뀾\n뀿\n끀\n끁\n끂\n끃\n끆\n끇\n끉\n끋\n끍\n끏\n끐\n끑\n끒\n끖\n끘\n끚\n끛\n끜\n끞\n끟\n끠\n끡\n끢\n끣\n끤\n끥\n끦\n끧\n끨\n끩\n끪\n끫\n끬\n끭\n끮\n끯\n끰\n끱\n끲\n끳\n끴\n끵\n끶\n끷\n끸\n끹\n끺\n끻\n끾\n끿\n낁\n낂\n낃\n낅\n낆\n낇\n낈\n낉\n낊\n낋\n낎\n낐\n낒\n낓\n낔\n낕\n낖\n낗\n낛\n낝\n낞\n낣\n낤\n낥\n낦\n낧\n낪\n낰\n낲\n낶\n낷\n낹\n낺\n낻\n낽\n낾\n낿\n냀\n냁\n냂\n냃\n냆\n냊\n냋\n냌\n냍\n냎\n냏\n냒\n�[\n�\\\n�]\n�^\n�_\n�`\n냓\n냕\n냖\n냗\n냙\n냚\n냛\n냜\n냝\n냞\n냟\n냡\n냢\n냣\n냤\n냦\n냧\n냨\n냩\n냪\n냫\n냬\n냭\n냮\n냯\n냰\n�{\n�|\n�}\n�~\n�\n�\n냱\n냲\n냳\n냴\n냵\n냶\n냷\n냸\n냹\n냺\n냻\n냼\n냽\n냾\n냿\n넀\n넁\n넂\n넃\n넄\n넅\n넆\n넇\n넊\n넍\n넎\n넏\n넑\n넔\n넕\n넖\n넗\n넚\n넞\n넟\n넠\n넡\n넢\n넦\n넧\n넩\n넪\n넫\n넭\n넮\n넯\n넰\n넱\n넲\n넳\n넶\n넺\n넻\n넼\n넽\n넾\n넿\n녂\n녃\n녅\n녆\n녇\n녉\n녊\n녋\n녌\n녍\n녎\n녏\n녒\n녓\n녖\n녗\n녙\n녚\n녛\n녝\n녞\n녟\n녡\n녢\n녣\n녤\n녥\n녦\n녧\n녨\n녩\n녪\n녫\n녬\n녭\n녮\n녯\n녰\n녱\n녲\n녳\n녴\n녵\n녶\n녷\n녺\n녻\n녽\n녾\n녿\n놁\n놃\n놄\n놅\n놆\n놇\n놊\n놌\n놎\n놏\n놐\n놑\n놕\n놖\n놗\n놙\n놚\n놛\n놝\n놞\n놟\n놠\n놡\n놢\n놣\n놤\n놥\n놦\n놧\n놩\n놪\n놫\n놬\n놭\n놮\n놯\n놰\n놱\n놲\n놳\n놴\n놵\n놶\n놷\n놸\n�[\n�\\\n�]\n�^\n�_\n�`\n놹\n놺\n놻\n놼\n놽\n놾\n놿\n뇀\n뇁\n뇂\n뇃\n뇄\n뇅\n뇆\n뇇\n뇈\n뇉\n뇊\n뇋\n뇍\n뇎\n뇏\n뇑\n뇒\n뇓\n뇕\n�{\n�|\n�}\n�~\n�\n�\n뇖\n뇗\n뇘\n뇙\n뇚\n뇛\n뇞\n뇠\n뇡\n뇢\n뇣\n뇤\n뇥\n뇦\n뇧\n뇪\n뇫\n뇭\n뇮\n뇯\n뇱\n뇲\n뇳\n뇴\n뇵\n뇶\n뇷\n뇸\n뇺\n뇼\n뇾\n뇿\n눀\n눁\n눂\n눃\n눆\n눇\n눉\n눊\n눍\n눎\n눏\n눐\n눑\n눒\n눓\n눖\n눘\n눚\n눛\n눜\n눝\n눞\n눟\n눡\n눢\n눣\n눤\n눥\n눦\n눧\n눨\n눩\n눪\n눫\n눬\n눭\n눮\n눯\n눰\n눱\n눲\n눳\n눵\n눶\n눷\n눸\n눹\n눺\n눻\n눽\n눾\n눿\n뉀\n뉁\n뉂\n뉃\n뉄\n뉅\n뉆\n뉇\n뉈\n뉉\n뉊\n뉋\n뉌\n뉍\n뉎\n뉏\n뉐\n뉑\n뉒\n뉓\n뉔\n뉕\n뉖\n뉗\n뉙\n뉚\n뉛\n뉝\n뉞\n뉟\n뉡\n뉢\n뉣\n뉤\n뉥\n뉦\n뉧\n뉪\n뉫\n뉬\n뉭\n뉮\n뉯\n뉰\n뉱\n뉲\n뉳\n뉶\n뉷\n뉸\n뉹\n뉺\n뉻\n뉽\n뉾\n뉿\n늀\n늁\n늂\n늃\n늆\n늇\n늈\n늊\n늋\n늌\n늍\n늎\n�[\n�\\\n�]\n�^\n�_\n�`\n늏\n늒\n늓\n늕\n늖\n늗\n늛\n늜\n늝\n늞\n늟\n늢\n늤\n늧\n늨\n늩\n늫\n늭\n늮\n늯\n늱\n늲\n늳\n늵\n늶\n늷\n�{\n�|\n�}\n�~\n�\n�\n늸\n늹\n늺\n늻\n늼\n늽\n늾\n늿\n닀\n닁\n닂\n닃\n닄\n닅\n닆\n닇\n닊\n닋\n닍\n닎\n닏\n닑\n닓\n닔\n닕\n닖\n닗\n닚\n닜\n닞\n닟\n닠\n닡\n닣\n닧\n닩\n닪\n닰\n닱\n닲\n닶\n닼\n닽\n닾\n댂\n댃\n댅\n댆\n댇\n댉\n댊\n댋\n댌\n댍\n댎\n댏\n댒\n댖\n댗\n댘\n댙\n댚\n댛\n댝\n댞\n댟\n댠\n댡\n댢\n댣\n댤\n댥\n댦\n댧\n댨\n댩\n댪\n댫\n댬\n댭\n댮\n댯\n댰\n댱\n댲\n댳\n댴\n댵\n댶\n댷\n댸\n댹\n댺\n댻\n댼\n댽\n댾\n댿\n덀\n덁\n덂\n덃\n덄\n덅\n덆\n덇\n덈\n덉\n덊\n덋\n덌\n덍\n덎\n덏\n덐\n덑\n덒\n덓\n덗\n덙\n덚\n덝\n덠\n덡\n덢\n덣\n덦\n덨\n덪\n덬\n덭\n덯\n덲\n덳\n덵\n덶\n덷\n덹\n덺\n덻\n덼\n덽\n덾\n덿\n뎂\n뎆\n뎇\n뎈\n뎉\n뎊\n뎋\n뎍\n�[\n�\\\n�]\n�^\n�_\n�`\n뎎\n뎏\n뎑\n뎒\n뎓\n뎕\n뎖\n뎗\n뎘\n뎙\n뎚\n뎛\n뎜\n뎝\n뎞\n뎟\n뎢\n뎣\n뎤\n뎥\n뎦\n뎧\n뎩\n뎪\n뎫\n뎭\n�{\n�|\n�}\n�~\n�\n�\n뎮\n뎯\n뎰\n뎱\n뎲\n뎳\n뎴\n뎵\n뎶\n뎷\n뎸\n뎹\n뎺\n뎻\n뎼\n뎽\n뎾\n뎿\n돀\n돁\n돂\n돃\n돆\n돇\n돉\n돊\n돍\n돏\n돑\n돒\n돓\n돖\n돘\n돚\n돜\n돞\n돟\n돡\n돢\n돣\n돥\n돦\n돧\n돩\n돪\n돫\n돬\n돭\n돮\n돯\n돰\n돱\n돲\n돳\n돴\n돵\n돶\n돷\n돸\n돹\n돺\n돻\n돽\n돾\n돿\n됀\n됁\n됂\n됃\n됄\n됅\n됆\n됇\n됈\n됉\n됊\n됋\n됌\n됍\n됎\n됏\n됑\n됒\n됓\n됔\n됕\n됖\n됗\n됙\n됚\n됛\n됝\n됞\n됟\n됡\n됢\n됣\n됤\n됥\n됦\n됧\n됪\n됬\n됭\n됮\n됯\n됰\n됱\n됲\n됳\n됵\n됶\n됷\n됸\n됹\n됺\n됻\n됼\n됽\n됾\n됿\n둀\n둁\n둂\n둃\n둄\n둅\n둆\n둇\n둈\n둉\n둊\n둋\n둌\n둍\n둎\n둏\n둒\n둓\n둕\n둖\n둗\n둙\n둚\n둛\n둜\n둝\n둞\n둟\n둢\n둤\n둦\n�[\n�\\\n�]\n�^\n�_\n�`\n둧\n둨\n둩\n둪\n둫\n둭\n둮\n둯\n둰\n둱\n둲\n둳\n둴\n둵\n둶\n둷\n둸\n둹\n둺\n둻\n둼\n둽\n둾\n둿\n뒁\n뒂\n�{\n�|\n�}\n�~\n�\n�\n뒃\n뒄\n뒅\n뒆\n뒇\n뒉\n뒊\n뒋\n뒌\n뒍\n뒎\n뒏\n뒐\n뒑\n뒒\n뒓\n뒔\n뒕\n뒖\n뒗\n뒘\n뒙\n뒚\n뒛\n뒜\n뒞\n뒟\n뒠\n뒡\n뒢\n뒣\n뒥\n뒦\n뒧\n뒩\n뒪\n뒫\n뒭\n뒮\n뒯\n뒰\n뒱\n뒲\n뒳\n뒴\n뒶\n뒸\n뒺\n뒻\n뒼\n뒽\n뒾\n뒿\n듁\n듂\n듃\n듅\n듆\n듇\n듉\n듊\n듋\n듌\n듍\n듎\n듏\n듑\n듒\n듓\n듔\n듖\n듗\n듘\n듙\n듚\n듛\n듞\n듟\n듡\n듢\n듥\n듧\n듨\n듩\n듪\n듫\n듮\n듰\n듲\n듳\n듴\n듵\n듶\n듷\n듹\n듺\n듻\n듼\n듽\n듾\n듿\n딀\n딁\n딂\n딃\n딄\n딅\n딆\n딇\n딈\n딉\n딊\n딋\n딌\n딍\n딎\n딏\n딐\n딑\n딒\n딓\n딖\n딗\n딙\n딚\n딝\n딞\n딟\n딠\n딡\n딢\n딣\n딦\n딫\n딬\n딭\n딮\n딯\n딲\n딳\n딵\n딶\n딷\n딹\n딺\n딻\n딼\n딽\n딾\n딿\n땂\n땆\n�[\n�\\\n�]\n�^\n�_\n�`\n땇\n땈\n땉\n땊\n땎\n땏\n땑\n땒\n땓\n땕\n땖\n땗\n땘\n땙\n땚\n땛\n땞\n땢\n땣\n땤\n땥\n땦\n땧\n땨\n땩\n땪\n�{\n�|\n�}\n�~\n�\n�\n땫\n땬\n땭\n땮\n땯\n땰\n땱\n땲\n땳\n땴\n땵\n땶\n땷\n땸\n땹\n땺\n땻\n땼\n땽\n땾\n땿\n떀\n떁\n떂\n떃\n떄\n떅\n떆\n떇\n떈\n떉\n떊\n떋\n떌\n떍\n떎\n떏\n떐\n떑\n떒\n떓\n떔\n떕\n떖\n떗\n떘\n떙\n떚\n떛\n떜\n떝\n떞\n떟\n떢\n떣\n떥\n떦\n떧\n떩\n떬\n떭\n떮\n떯\n떲\n떶\n떷\n떸\n떹\n떺\n떾\n떿\n뗁\n뗂\n뗃\n뗅\n뗆\n뗇\n뗈\n뗉\n뗊\n뗋\n뗎\n뗒\n뗓\n뗔\n뗕\n뗖\n뗗\n뗙\n뗚\n뗛\n뗜\n뗝\n뗞\n뗟\n뗠\n뗡\n뗢\n뗣\n뗤\n뗥\n뗦\n뗧\n뗨\n뗩\n뗪\n뗫\n뗭\n뗮\n뗯\n뗰\n뗱\n뗲\n뗳\n뗴\n뗵\n뗶\n뗷\n뗸\n뗹\n뗺\n뗻\n뗼\n뗽\n뗾\n뗿\n똀\n똁\n똂\n똃\n똄\n똅\n똆\n똇\n똈\n똉\n똊\n똋\n똌\n똍\n똎\n똏\n똒\n똓\n똕\n똖\n똗\n똙\n똚\n똛\n똜\n똝\n�[\n�\\\n�]\n�^\n�_\n�`\n똞\n똟\n똠\n똡\n똢\n똣\n똤\n똦\n똧\n똨\n똩\n똪\n똫\n똭\n똮\n똯\n똰\n똱\n똲\n똳\n똵\n똶\n똷\n똸\n똹\n똺\n�{\n�|\n�}\n�~\n�\n�\n똻\n똼\n똽\n똾\n똿\n뙀\n뙁\n뙂\n뙃\n뙄\n뙅\n뙆\n뙇\n뙉\n뙊\n뙋\n뙌\n뙍\n뙎\n뙏\n뙐\n뙑\n뙒\n뙓\n뙔\n뙕\n뙖\n뙗\n뙘\n뙙\n뙚\n뙛\n뙜\n뙝\n뙞\n뙟\n뙠\n뙡\n뙢\n뙣\n뙥\n뙦\n뙧\n뙩\n뙪\n뙫\n뙬\n뙭\n뙮\n뙯\n뙰\n뙱\n뙲\n뙳\n뙴\n뙵\n뙶\n뙷\n뙸\n뙹\n뙺\n뙻\n뙼\n뙽\n뙾\n뙿\n뚀\n뚁\n뚂\n뚃\n뚄\n뚅\n뚆\n뚇\n뚈\n뚉\n뚊\n뚋\n뚌\n뚍\n뚎\n뚏\n뚐\n뚑\n뚒\n뚓\n뚔\n뚕\n뚖\n뚗\n뚘\n뚙\n뚚\n뚛\n뚞\n뚟\n뚡\n뚢\n뚣\n뚥\n뚦\n뚧\n뚨\n뚩\n뚪\n뚭\n뚮\n뚯\n뚰\n뚲\n뚳\n뚴\n뚵\n뚶\n뚷\n뚸\n뚹\n뚺\n뚻\n뚼\n뚽\n뚾\n뚿\n뛀\n뛁\n뛂\n뛃\n뛄\n뛅\n뛆\n뛇\n뛈\n뛉\n뛊\n뛋\n뛌\n뛍\n뛎\n뛏\n뛐\n뛑\n뛒\n뛓\n뛕\n뛖\n뛗\n뛘\n뛙\n뛚\n뛛\n뛜\n뛝\n�[\n�\\\n�]\n�^\n�_\n�`\n뛞\n뛟\n뛠\n뛡\n뛢\n뛣\n뛤\n뛥\n뛦\n뛧\n뛨\n뛩\n뛪\n뛫\n뛬\n뛭\n뛮\n뛯\n뛱\n뛲\n뛳\n뛵\n뛶\n뛷\n뛹\n뛺\n�{\n�|\n�}\n�~\n�\n�\n뛻\n뛼\n뛽\n뛾\n뛿\n뜂\n뜃\n뜄\n뜆\n뜇\n뜈\n뜉\n뜊\n뜋\n뜌\n뜍\n뜎\n뜏\n뜐\n뜑\n뜒\n뜓\n뜔\n뜕\n뜖\n뜗\n뜘\n뜙\n뜚\n뜛\n뜜\n뜝\n뜞\n뜟\n뜠\n뜡\n뜢\n뜣\n뜤\n뜥\n뜦\n뜧\n뜪\n뜫\n뜭\n뜮\n뜱\n뜲\n뜳\n뜴\n뜵\n뜶\n뜷\n뜺\n뜼\n뜽\n뜾\n뜿\n띀\n띁\n띂\n띃\n띅\n띆\n띇\n띉\n띊\n띋\n띍\n띎\n띏\n띐\n띑\n띒\n띓\n띖\n띗\n띘\n띙\n띚\n띛\n띜\n띝\n띞\n띟\n띡\n띢\n띣\n띥\n띦\n띧\n띩\n띪\n띫\n띬\n띭\n띮\n띯\n띲\n띴\n띶\n띷\n띸\n띹\n띺\n띻\n띾\n띿\n랁\n랂\n랃\n랅\n랆\n랇\n랈\n랉\n랊\n랋\n랎\n랓\n랔\n랕\n랚\n랛\n랝\n랞\n랟\n랡\n랢\n랣\n랤\n랥\n랦\n랧\n랪\n랮\n랯\n랰\n랱\n랲\n랳\n랶\n랷\n랹\n랺\n랻\n랼\n랽\n랾\n랿\n럀\n럁\n�[\n�\\\n�]\n�^\n�_\n�`\n럂\n럃\n럄\n럅\n럆\n럈\n럊\n럋\n럌\n럍\n럎\n럏\n럐\n럑\n럒\n럓\n럔\n럕\n럖\n럗\n럘\n럙\n럚\n럛\n럜\n럝\n�{\n�|\n�}\n�~\n�\n�\n럞\n럟\n럠\n럡\n럢\n럣\n럤\n럥\n럦\n럧\n럨\n럩\n럪\n럫\n럮\n럯\n럱\n럲\n럳\n럵\n럶\n럷\n럸\n럹\n럺\n럻\n럾\n렂\n렃\n렄\n렅\n렆\n렊\n렋\n렍\n렎\n렏\n렑\n렒\n렓\n렔\n렕\n렖\n렗\n렚\n렜\n렞\n렟\n렠\n렡\n렢\n렣\n렦\n렧\n렩\n렪\n렫\n렭\n렮\n렯\n렰\n렱\n렲\n렳\n렶\n렺\n렻\n렼\n렽\n렾\n렿\n롁\n롂\n롃\n롅\n롆\n롇\n롈\n롉\n롊\n롋\n롌\n롍\n롎\n롏\n롐\n롒\n롔\n롕\n롖\n롗\n롘\n롙\n롚\n롛\n롞\n롟\n롡\n롢\n롣\n롥\n롦\n롧\n롨\n롩\n롪\n롫\n롮\n롰\n롲\n롳\n롴\n롵\n롶\n롷\n롹\n롺\n롻\n롽\n롾\n롿\n뢀\n뢁\n뢂\n뢃\n뢄\n뢅\n뢆\n뢇\n뢈\n뢉\n뢊\n뢋\n뢌\n뢎\n뢏\n뢐\n뢑\n뢒\n뢓\n뢔\n뢕\n뢖\n뢗\n뢘\n뢙\n뢚\n뢛\n뢜\n뢝\n뢞\n뢟\n�[\n�\\\n�]\n�^\n�_\n�`\n뢠\n뢡\n뢢\n뢣\n뢤\n뢥\n뢦\n뢧\n뢩\n뢪\n뢫\n뢬\n뢭\n뢮\n뢯\n뢱\n뢲\n뢳\n뢵\n뢶\n뢷\n뢹\n뢺\n뢻\n뢼\n뢽\n�{\n�|\n�}\n�~\n�\n�\n뢾\n뢿\n룂\n룄\n룆\n룇\n룈\n룉\n룊\n룋\n룍\n룎\n룏\n룑\n룒\n룓\n룕\n룖\n룗\n룘\n룙\n룚\n룛\n룜\n룞\n룠\n룢\n룣\n룤\n룥\n룦\n룧\n룪\n룫\n룭\n룮\n룯\n룱\n룲\n룳\n룴\n룵\n룶\n룷\n룺\n룼\n룾\n룿\n뤀\n뤁\n뤂\n뤃\n뤅\n뤆\n뤇\n뤈\n뤉\n뤊\n뤋\n뤌\n뤍\n뤎\n뤏\n뤐\n뤑\n뤒\n뤓\n뤔\n뤕\n뤖\n뤗\n뤙\n뤚\n뤛\n뤜\n뤝\n뤞\n뤟\n뤡\n뤢\n뤣\n뤤\n뤥\n뤦\n뤧\n뤨\n뤩\n뤪\n뤫\n뤬\n뤭\n뤮\n뤯\n뤰\n뤱\n뤲\n뤳\n뤴\n뤵\n뤶\n뤷\n뤸\n뤹\n뤺\n뤻\n뤾\n뤿\n륁\n륂\n륃\n륅\n륆\n륇\n륈\n륉\n륊\n륋\n륍\n륎\n륐\n륒\n륓\n륔\n륕\n륖\n륗\n륚\n륛\n륝\n륞\n륟\n륡\n륢\n륣\n륤\n륥\n륦\n륧\n륪\n륬\n륮\n륯\n륰\n륱\n륲\n륳\n륶\n륷\n륹\n륺\n륻\n륽\n�[\n�\\\n�]\n�^\n�_\n�`\n륾\n륿\n릀\n릁\n릂\n릃\n릆\n릈\n릋\n릌\n릏\n릐\n릑\n릒\n릓\n릔\n릕\n릖\n릗\n릘\n릙\n릚\n릛\n릜\n릝\n릞\n�{\n�|\n�}\n�~\n�\n�\n릟\n릠\n릡\n릢\n릣\n릤\n릥\n릦\n릧\n릨\n릩\n릪\n릫\n릮\n릯\n릱\n릲\n릳\n릵\n릶\n릷\n릸\n릹\n릺\n릻\n릾\n맀\n맂\n맃\n맄\n맅\n맆\n맇\n맊\n맋\n맍\n맓\n맔\n맕\n맖\n맗\n맚\n맜\n맟\n맠\n맢\n맦\n맧\n맩\n맪\n맫\n맭\n맮\n맯\n맰\n맱\n맲\n맳\n맶\n맻\n맼\n맽\n맾\n맿\n먂\n먃\n먄\n먅\n먆\n먇\n먉\n먊\n먋\n먌\n먍\n먎\n먏\n먐\n먑\n먒\n먓\n먔\n먖\n먗\n먘\n먙\n먚\n먛\n먜\n먝\n먞\n먟\n먠\n먡\n먢\n먣\n먤\n먥\n먦\n먧\n먨\n먩\n먪\n먫\n먬\n먭\n먮\n먯\n먰\n먱\n먲\n먳\n먴\n먵\n먶\n먷\n먺\n먻\n먽\n먾\n먿\n멁\n멃\n멄\n멅\n멆\n멇\n멊\n멌\n멏\n멐\n멑\n멒\n멖\n멗\n멙\n멚\n멛\n멝\n멞\n멟\n멠\n멡\n멢\n멣\n멦\n멪\n멫\n멬\n멭\n멮\n멯\n�[\n�\\\n�]\n�^\n�_\n�`\n멲\n멳\n멵\n멶\n멷\n멹\n멺\n멻\n멼\n멽\n멾\n멿\n몀\n몁\n몂\n몆\n몈\n몉\n몊\n몋\n몍\n몎\n몏\n몐\n몑\n몒\n�{\n�|\n�}\n�~\n�\n�\n몓\n몔\n몕\n몖\n몗\n몘\n몙\n몚\n몛\n몜\n몝\n몞\n몟\n몠\n몡\n몢\n몣\n몤\n몥\n몦\n몧\n몪\n몭\n몮\n몯\n몱\n몳\n몴\n몵\n몶\n몷\n몺\n몼\n몾\n몿\n뫀\n뫁\n뫂\n뫃\n뫅\n뫆\n뫇\n뫉\n뫊\n뫋\n뫌\n뫍\n뫎\n뫏\n뫐\n뫑\n뫒\n뫓\n뫔\n뫕\n뫖\n뫗\n뫚\n뫛\n뫜\n뫝\n뫞\n뫟\n뫠\n뫡\n뫢\n뫣\n뫤\n뫥\n뫦\n뫧\n뫨\n뫩\n뫪\n뫫\n뫬\n뫭\n뫮\n뫯\n뫰\n뫱\n뫲\n뫳\n뫴\n뫵\n뫶\n뫷\n뫸\n뫹\n뫺\n뫻\n뫽\n뫾\n뫿\n묁\n묂\n묃\n묅\n묆\n묇\n묈\n묉\n묊\n묋\n묌\n묎\n묐\n묒\n묓\n묔\n묕\n묖\n묗\n묙\n묚\n묛\n묝\n묞\n묟\n묡\n묢\n묣\n묤\n묥\n묦\n묧\n묨\n묪\n묬\n묭\n묮\n묯\n묰\n묱\n묲\n묳\n묷\n묹\n묺\n묿\n뭀\n뭁\n뭂\n뭃\n뭆\n뭈\n뭊\n뭋\n뭌\n뭎\n뭑\n뭒\n�[\n�\\\n�]\n�^\n�_\n�`\n뭓\n뭕\n뭖\n뭗\n뭙\n뭚\n뭛\n뭜\n뭝\n뭞\n뭟\n뭠\n뭢\n뭤\n뭥\n뭦\n뭧\n뭨\n뭩\n뭪\n뭫\n뭭\n뭮\n뭯\n뭰\n뭱\n�{\n�|\n�}\n�~\n�\n�\n뭲\n뭳\n뭴\n뭵\n뭶\n뭷\n뭸\n뭹\n뭺\n뭻\n뭼\n뭽\n뭾\n뭿\n뮀\n뮁\n뮂\n뮃\n뮄\n뮅\n뮆\n뮇\n뮉\n뮊\n뮋\n뮍\n뮎\n뮏\n뮑\n뮒\n뮓\n뮔\n뮕\n뮖\n뮗\n뮘\n뮙\n뮚\n뮛\n뮜\n뮝\n뮞\n뮟\n뮠\n뮡\n뮢\n뮣\n뮥\n뮦\n뮧\n뮩\n뮪\n뮫\n뮭\n뮮\n뮯\n뮰\n뮱\n뮲\n뮳\n뮵\n뮶\n뮸\n뮹\n뮺\n뮻\n뮼\n뮽\n뮾\n뮿\n믁\n믂\n믃\n믅\n믆\n믇\n믉\n믊\n믋\n믌\n믍\n믎\n믏\n믑\n믒\n믔\n믕\n믖\n믗\n믘\n믙\n믚\n믛\n믜\n믝\n믞\n믟\n믠\n믡\n믢\n믣\n믤\n믥\n믦\n믧\n믨\n믩\n믪\n믫\n믬\n믭\n믮\n믯\n믰\n믱\n믲\n믳\n믴\n믵\n믶\n믷\n믺\n믻\n믽\n믾\n밁\n밃\n밄\n밅\n밆\n밇\n밊\n밎\n밐\n밒\n밓\n밙\n밚\n밠\n밡\n밢\n밣\n밦\n밨\n밪\n밫\n밬\n밮\n밯\n밲\n밳\n밵\n�[\n�\\\n�]\n�^\n�_\n�`\n밶\n밷\n밹\n밺\n밻\n밼\n밽\n밾\n밿\n뱂\n뱆\n뱇\n뱈\n뱊\n뱋\n뱎\n뱏\n뱑\n뱒\n뱓\n뱔\n뱕\n뱖\n뱗\n뱘\n뱙\n�{\n�|\n�}\n�~\n�\n�\n뱚\n뱛\n뱜\n뱞\n뱟\n뱠\n뱡\n뱢\n뱣\n뱤\n뱥\n뱦\n뱧\n뱨\n뱩\n뱪\n뱫\n뱬\n뱭\n뱮\n뱯\n뱰\n뱱\n뱲\n뱳\n뱴\n뱵\n뱶\n뱷\n뱸\n뱹\n뱺\n뱻\n뱼\n뱽\n뱾\n뱿\n벀\n벁\n벂\n벃\n벆\n벇\n벉\n벊\n벍\n벏\n벐\n벑\n벒\n벓\n벖\n벘\n벛\n벜\n벝\n벞\n벟\n벢\n벣\n벥\n벦\n벩\n벪\n벫\n벬\n벭\n벮\n벯\n벲\n벶\n벷\n벸\n벹\n벺\n벻\n벾\n벿\n볁\n볂\n볃\n볅\n볆\n볇\n볈\n볉\n볊\n볋\n볌\n볎\n볒\n볓\n볔\n볖\n볗\n볙\n볚\n볛\n볝\n볞\n볟\n볠\n볡\n볢\n볣\n볤\n볥\n볦\n볧\n볨\n볩\n볪\n볫\n볬\n볭\n볮\n볯\n볰\n볱\n볲\n볳\n볷\n볹\n볺\n볻\n볽\n볾\n볿\n봀\n봁\n봂\n봃\n봆\n봈\n봊\n봋\n봌\n봍\n봎\n봏\n봑\n봒\n봓\n봕\n봖\n봗\n봘\n봙\n봚\n봛\n봜\n봝\n�[\n�\\\n�]\n�^\n�_\n�`\n봞\n봟\n봠\n봡\n봢\n봣\n봥\n봦\n봧\n봨\n봩\n봪\n봫\n봭\n봮\n봯\n봰\n봱\n봲\n봳\n봴\n봵\n봶\n봷\n봸\n봹\n�{\n�|\n�}\n�~\n�\n�\n봺\n봻\n봼\n봽\n봾\n봿\n뵁\n뵂\n뵃\n뵄\n뵅\n뵆\n뵇\n뵊\n뵋\n뵍\n뵎\n뵏\n뵑\n뵒\n뵓\n뵔\n뵕\n뵖\n뵗\n뵚\n뵛\n뵜\n뵝\n뵞\n뵟\n뵠\n뵡\n뵢\n뵣\n뵥\n뵦\n뵧\n뵩\n뵪\n뵫\n뵬\n뵭\n뵮\n뵯\n뵰\n뵱\n뵲\n뵳\n뵴\n뵵\n뵶\n뵷\n뵸\n뵹\n뵺\n뵻\n뵼\n뵽\n뵾\n뵿\n붂\n붃\n붅\n붆\n붋\n붌\n붍\n붎\n붏\n붒\n붔\n붖\n붗\n붘\n붛\n붝\n붞\n붟\n붠\n붡\n붢\n붣\n붥\n붦\n붧\n붨\n붩\n붪\n붫\n붬\n붭\n붮\n붯\n붱\n붲\n붳\n붴\n붵\n붶\n붷\n붹\n붺\n붻\n붼\n붽\n붾\n붿\n뷀\n뷁\n뷂\n뷃\n뷄\n뷅\n뷆\n뷇\n뷈\n뷉\n뷊\n뷋\n뷌\n뷍\n뷎\n뷏\n뷐\n뷑\n뷒\n뷓\n뷖\n뷗\n뷙\n뷚\n뷛\n뷝\n뷞\n뷟\n뷠\n뷡\n뷢\n뷣\n뷤\n뷥\n뷦\n뷧\n뷨\n뷪\n뷫\n뷬\n뷭\n뷮\n뷯\n뷱\n�[\n�\\\n�]\n�^\n�_\n�`\n뷲\n뷳\n뷵\n뷶\n뷷\n뷹\n뷺\n뷻\n뷼\n뷽\n뷾\n뷿\n븁\n븂\n븄\n븆\n븇\n븈\n븉\n븊\n븋\n븎\n븏\n븑\n븒\n븓\n�{\n�|\n�}\n�~\n�\n�\n븕\n븖\n븗\n븘\n븙\n븚\n븛\n븞\n븠\n븡\n븢\n븣\n븤\n븥\n븦\n븧\n븨\n븩\n븪\n븫\n븬\n븭\n븮\n븯\n븰\n븱\n븲\n븳\n븴\n븵\n븶\n븷\n븸\n븹\n븺\n븻\n븼\n븽\n븾\n븿\n빀\n빁\n빂\n빃\n빆\n빇\n빉\n빊\n빋\n빍\n빏\n빐\n빑\n빒\n빓\n빖\n빘\n빜\n빝\n빞\n빟\n빢\n빣\n빥\n빦\n빧\n빩\n빫\n빬\n빭\n빮\n빯\n빲\n빶\n빷\n빸\n빹\n빺\n빾\n빿\n뺁\n뺂\n뺃\n뺅\n뺆\n뺇\n뺈\n뺉\n뺊\n뺋\n뺎\n뺒\n뺓\n뺔\n뺕\n뺖\n뺗\n뺚\n뺛\n뺜\n뺝\n뺞\n뺟\n뺠\n뺡\n뺢\n뺣\n뺤\n뺥\n뺦\n뺧\n뺩\n뺪\n뺫\n뺬\n뺭\n뺮\n뺯\n뺰\n뺱\n뺲\n뺳\n뺴\n뺵\n뺶\n뺷\n뺸\n뺹\n뺺\n뺻\n뺼\n뺽\n뺾\n뺿\n뻀\n뻁\n뻂\n뻃\n뻄\n뻅\n뻆\n뻇\n뻈\n뻉\n뻊\n뻋\n뻌\n뻍\n뻎\n뻏\n뻒\n뻓\n�[\n�\\\n�]\n�^\n�_\n�`\n뻕\n뻖\n뻙\n뻚\n뻛\n뻜\n뻝\n뻞\n뻟\n뻡\n뻢\n뻦\n뻧\n뻨\n뻩\n뻪\n뻫\n뻭\n뻮\n뻯\n뻰\n뻱\n뻲\n뻳\n뻴\n뻵\n�{\n�|\n�}\n�~\n�\n�\n뻶\n뻷\n뻸\n뻹\n뻺\n뻻\n뻼\n뻽\n뻾\n뻿\n뼀\n뼂\n뼃\n뼄\n뼅\n뼆\n뼇\n뼊\n뼋\n뼌\n뼍\n뼎\n뼏\n뼐\n뼑\n뼒\n뼓\n뼔\n뼕\n뼖\n뼗\n뼚\n뼞\n뼟\n뼠\n뼡\n뼢\n뼣\n뼤\n뼥\n뼦\n뼧\n뼨\n뼩\n뼪\n뼫\n뼬\n뼭\n뼮\n뼯\n뼰\n뼱\n뼲\n뼳\n뼴\n뼵\n뼶\n뼷\n뼸\n뼹\n뼺\n뼻\n뼼\n뼽\n뼾\n뼿\n뽂\n뽃\n뽅\n뽆\n뽇\n뽉\n뽊\n뽋\n뽌\n뽍\n뽎\n뽏\n뽒\n뽓\n뽔\n뽖\n뽗\n뽘\n뽙\n뽚\n뽛\n뽜\n뽝\n뽞\n뽟\n뽠\n뽡\n뽢\n뽣\n뽤\n뽥\n뽦\n뽧\n뽨\n뽩\n뽪\n뽫\n뽬\n뽭\n뽮\n뽯\n뽰\n뽱\n뽲\n뽳\n뽴\n뽵\n뽶\n뽷\n뽸\n뽹\n뽺\n뽻\n뽼\n뽽\n뽾\n뽿\n뾀\n뾁\n뾂\n뾃\n뾄\n뾅\n뾆\n뾇\n뾈\n뾉\n뾊\n뾋\n뾌\n뾍\n뾎\n뾏\n뾐\n뾑\n뾒\n뾓\n뾕\n뾖\n뾗\n뾘\n뾙\n뾚\n뾛\n뾜\n뾝\n�[\n�\\\n�]\n�^\n�_\n�`\n뾞\n뾟\n뾠\n뾡\n뾢\n뾣\n뾤\n뾥\n뾦\n뾧\n뾨\n뾩\n뾪\n뾫\n뾬\n뾭\n뾮\n뾯\n뾱\n뾲\n뾳\n뾴\n뾵\n뾶\n뾷\n뾸\n�{\n�|\n�}\n�~\n�\n�\n뾹\n뾺\n뾻\n뾼\n뾽\n뾾\n뾿\n뿀\n뿁\n뿂\n뿃\n뿄\n뿆\n뿇\n뿈\n뿉\n뿊\n뿋\n뿎\n뿏\n뿑\n뿒\n뿓\n뿕\n뿖\n뿗\n뿘\n뿙\n뿚\n뿛\n뿝\n뿞\n뿠\n뿢\n뿣\n뿤\n뿥\n뿦\n뿧\n뿨\n뿩\n뿪\n뿫\n뿬\n뿭\n뿮\n뿯\n뿰\n뿱\n뿲\n뿳\n뿴\n뿵\n뿶\n뿷\n뿸\n뿹\n뿺\n뿻\n뿼\n뿽\n뿾\n뿿\n쀀\n쀁\n쀂\n쀃\n쀄\n쀅\n쀆\n쀇\n쀈\n쀉\n쀊\n쀋\n쀌\n쀍\n쀎\n쀏\n쀐\n쀑\n쀒\n쀓\n쀔\n쀕\n쀖\n쀗\n쀘\n쀙\n쀚\n쀛\n쀜\n쀝\n쀞\n쀟\n쀠\n쀡\n쀢\n쀣\n쀤\n쀥\n쀦\n쀧\n쀨\n쀩\n쀪\n쀫\n쀬\n쀭\n쀮\n쀯\n쀰\n쀱\n쀲\n쀳\n쀴\n쀵\n쀶\n쀷\n쀸\n쀹\n쀺\n쀻\n쀽\n쀾\n쀿\n쁀\n쁁\n쁂\n쁃\n쁄\n쁅\n쁆\n쁇\n쁈\n쁉\n쁊\n쁋\n쁌\n쁍\n쁎\n쁏\n쁐\n쁒\n쁓\n쁔\n쁕\n쁖\n쁗\n쁙\n쁚\n쁛\n�[\n�\\\n�]\n�^\n�_\n�`\n쁝\n쁞\n쁟\n쁡\n쁢\n쁣\n쁤\n쁥\n쁦\n쁧\n쁪\n쁫\n쁬\n쁭\n쁮\n쁯\n쁰\n쁱\n쁲\n쁳\n쁴\n쁵\n쁶\n쁷\n쁸\n쁹\n�{\n�|\n�}\n�~\n�\n�\n쁺\n쁻\n쁼\n쁽\n쁾\n쁿\n삀\n삁\n삂\n삃\n삄\n삅\n삆\n삇\n삈\n삉\n삊\n삋\n삌\n삍\n삎\n삏\n삒\n삓\n삕\n삖\n삗\n삙\n삚\n삛\n삜\n삝\n삞\n삟\n삢\n삤\n삦\n삧\n삨\n삩\n삪\n삫\n삮\n삱\n삲\n삷\n삸\n삹\n삺\n삻\n삾\n샂\n샃\n샄\n샆\n샇\n샊\n샋\n샍\n샎\n샏\n샑\n샒\n샓\n샔\n샕\n샖\n샗\n샚\n샞\n샟\n샠\n샡\n샢\n샣\n샦\n샧\n샩\n샪\n샫\n샭\n샮\n샯\n샰\n샱\n샲\n샳\n샶\n샸\n샺\n샻\n샼\n샽\n샾\n샿\n섁\n섂\n섃\n섅\n섆\n섇\n섉\n섊\n섋\n섌\n섍\n섎\n섏\n섑\n섒\n섓\n섔\n섖\n섗\n섘\n섙\n섚\n섛\n섡\n섢\n섥\n섨\n섩\n섪\n섫\n섮\n섲\n섳\n섴\n섵\n섷\n섺\n섻\n섽\n섾\n섿\n셁\n셂\n셃\n셄\n셅\n셆\n셇\n셊\n셎\n셏\n셐\n셑\n셒\n셓\n셖\n셗\n�[\n�\\\n�]\n�^\n�_\n�`\n셙\n셚\n셛\n셝\n셞\n셟\n셠\n셡\n셢\n셣\n셦\n셪\n셫\n셬\n셭\n셮\n셯\n셱\n셲\n셳\n셵\n셶\n셷\n셹\n셺\n셻\n�{\n�|\n�}\n�~\n�\n�\n셼\n셽\n셾\n셿\n솀\n솁\n솂\n솃\n솄\n솆\n솇\n솈\n솉\n솊\n솋\n솏\n솑\n솒\n솓\n솕\n솗\n솘\n솙\n솚\n솛\n솞\n솠\n솢\n솣\n솤\n솦\n솧\n솪\n솫\n솭\n솮\n솯\n솱\n솲\n솳\n솴\n솵\n솶\n솷\n솸\n솹\n솺\n솻\n솼\n솾\n솿\n쇀\n쇁\n쇂\n쇃\n쇅\n쇆\n쇇\n쇉\n쇊\n쇋\n쇍\n쇎\n쇏\n쇐\n쇑\n쇒\n쇓\n쇕\n쇖\n쇙\n쇚\n쇛\n쇜\n쇝\n쇞\n쇟\n쇡\n쇢\n쇣\n쇥\n쇦\n쇧\n쇩\n쇪\n쇫\n쇬\n쇭\n쇮\n쇯\n쇲\n쇴\n쇵\n쇶\n쇷\n쇸\n쇹\n쇺\n쇻\n쇾\n쇿\n숁\n숂\n숃\n숅\n숆\n숇\n숈\n숉\n숊\n숋\n숎\n숐\n숒\n숓\n숔\n숕\n숖\n숗\n숚\n숛\n숝\n숞\n숡\n숢\n숣\n숤\n숥\n숦\n숧\n숪\n숬\n숮\n숰\n숳\n숵\n숶\n숷\n숸\n숹\n숺\n숻\n숼\n숽\n숾\n숿\n쉀\n쉁\n쉂\n쉃\n쉄\n쉅\n�[\n�\\\n�]\n�^\n�_\n�`\n쉆\n쉇\n쉉\n쉊\n쉋\n쉌\n쉍\n쉎\n쉏\n쉒\n쉓\n쉕\n쉖\n쉗\n쉙\n쉚\n쉛\n쉜\n쉝\n쉞\n쉟\n쉡\n쉢\n쉣\n쉤\n쉦\n�{\n�|\n�}\n�~\n�\n�\n쉧\n쉨\n쉩\n쉪\n쉫\n쉮\n쉯\n쉱\n쉲\n쉳\n쉵\n쉶\n쉷\n쉸\n쉹\n쉺\n쉻\n쉾\n슀\n슂\n슃\n슄\n슅\n슆\n슇\n슊\n슋\n슌\n슍\n슎\n슏\n슑\n슒\n슓\n슔\n슕\n슖\n슗\n슙\n슚\n슜\n슞\n슟\n슠\n슡\n슢\n슣\n슦\n슧\n슩\n슪\n슫\n슮\n슯\n슰\n슱\n슲\n슳\n슶\n슸\n슺\n슻\n슼\n슽\n슾\n슿\n싀\n싁\n싂\n싃\n싄\n싅\n싆\n싇\n싈\n싉\n싊\n싋\n싌\n싍\n싎\n싏\n싐\n싑\n싒\n싓\n싔\n싕\n싖\n싗\n싘\n싙\n싚\n싛\n싞\n싟\n싡\n싢\n싥\n싦\n싧\n싨\n싩\n싪\n싮\n싰\n싲\n싳\n싴\n싵\n싷\n싺\n싽\n싾\n싿\n쌁\n쌂\n쌃\n쌄\n쌅\n쌆\n쌇\n쌊\n쌋\n쌎\n쌏\n쌐\n쌑\n쌒\n쌖\n쌗\n쌙\n쌚\n쌛\n쌝\n쌞\n쌟\n쌠\n쌡\n쌢\n쌣\n쌦\n쌧\n쌪\n쌫\n쌬\n쌭\n쌮\n쌯\n쌰\n쌱\n쌲\n�[\n�\\\n�]\n�^\n�_\n�`\n쌳\n쌴\n쌵\n쌶\n쌷\n쌸\n쌹\n쌺\n쌻\n쌼\n쌽\n쌾\n쌿\n썀\n썁\n썂\n썃\n썄\n썆\n썇\n썈\n썉\n썊\n썋\n썌\n썍\n�{\n�|\n�}\n�~\n�\n�\n썎\n썏\n썐\n썑\n썒\n썓\n썔\n썕\n썖\n썗\n썘\n썙\n썚\n썛\n썜\n썝\n썞\n썟\n썠\n썡\n썢\n썣\n썤\n썥\n썦\n썧\n썪\n썫\n썭\n썮\n썯\n썱\n썳\n썴\n썵\n썶\n썷\n썺\n썻\n썾\n썿\n쎀\n쎁\n쎂\n쎃\n쎅\n쎆\n쎇\n쎉\n쎊\n쎋\n쎍\n쎎\n쎏\n쎐\n쎑\n쎒\n쎓\n쎔\n쎕\n쎖\n쎗\n쎘\n쎙\n쎚\n쎛\n쎜\n쎝\n쎞\n쎟\n쎠\n쎡\n쎢\n쎣\n쎤\n쎥\n쎦\n쎧\n쎨\n쎩\n쎪\n쎫\n쎬\n쎭\n쎮\n쎯\n쎰\n쎱\n쎲\n쎳\n쎴\n쎵\n쎶\n쎷\n쎸\n쎹\n쎺\n쎻\n쎼\n쎽\n쎾\n쎿\n쏁\n쏂\n쏃\n쏄\n쏅\n쏆\n쏇\n쏈\n쏉\n쏊\n쏋\n쏌\n쏍\n쏎\n쏏\n쏐\n쏑\n쏒\n쏓\n쏔\n쏕\n쏖\n쏗\n쏚\n쏛\n쏝\n쏞\n쏡\n쏣\n쏤\n쏥\n쏦\n쏧\n쏪\n쏫\n쏬\n쏮\n쏯\n쏰\n쏱\n쏲\n쏳\n쏶\n쏷\n쏹\n쏺\n쏻\n쏼\n쏽\n쏾\n�[\n�\\\n�]\n�^\n�_\n�`\n쏿\n쐀\n쐁\n쐂\n쐃\n쐄\n쐅\n쐆\n쐇\n쐉\n쐊\n쐋\n쐌\n쐍\n쐎\n쐏\n쐑\n쐒\n쐓\n쐔\n쐕\n쐖\n쐗\n쐘\n쐙\n쐚\n�{\n�|\n�}\n�~\n�\n�\n쐛\n쐜\n쐝\n쐞\n쐟\n쐠\n쐡\n쐢\n쐣\n쐥\n쐦\n쐧\n쐨\n쐩\n쐪\n쐫\n쐭\n쐮\n쐯\n쐱\n쐲\n쐳\n쐵\n쐶\n쐷\n쐸\n쐹\n쐺\n쐻\n쐾\n쐿\n쑀\n쑁\n쑂\n쑃\n쑄\n쑅\n쑆\n쑇\n쑉\n쑊\n쑋\n쑌\n쑍\n쑎\n쑏\n쑐\n쑑\n쑒\n쑓\n쑔\n쑕\n쑖\n쑗\n쑘\n쑙\n쑚\n쑛\n쑜\n쑝\n쑞\n쑟\n쑠\n쑡\n쑢\n쑣\n쑦\n쑧\n쑩\n쑪\n쑫\n쑭\n쑮\n쑯\n쑰\n쑱\n쑲\n쑳\n쑶\n쑷\n쑸\n쑺\n쑻\n쑼\n쑽\n쑾\n쑿\n쒁\n쒂\n쒃\n쒄\n쒅\n쒆\n쒇\n쒈\n쒉\n쒊\n쒋\n쒌\n쒍\n쒎\n쒏\n쒐\n쒑\n쒒\n쒓\n쒕\n쒖\n쒗\n쒘\n쒙\n쒚\n쒛\n쒝\n쒞\n쒟\n쒠\n쒡\n쒢\n쒣\n쒤\n쒥\n쒦\n쒧\n쒨\n쒩\n쒪\n쒫\n쒬\n쒭\n쒮\n쒯\n쒰\n쒱\n쒲\n쒳\n쒴\n쒵\n쒶\n쒷\n쒹\n쒺\n쒻\n쒽\n쒾\n쒿\n쓀\n쓁\n쓂\n쓃\n쓄\n쓅\n�[\n�\\\n�]\n�^\n�_\n�`\n쓆\n쓇\n쓈\n쓉\n쓊\n쓋\n쓌\n쓍\n쓎\n쓏\n쓐\n쓑\n쓒\n쓓\n쓔\n쓕\n쓖\n쓗\n쓘\n쓙\n쓚\n쓛\n쓜\n쓝\n쓞\n쓟\n�{\n�|\n�}\n�~\n�\n�\n쓠\n쓡\n쓢\n쓣\n쓤\n쓥\n쓦\n쓧\n쓨\n쓪\n쓫\n쓬\n쓭\n쓮\n쓯\n쓲\n쓳\n쓵\n쓶\n쓷\n쓹\n쓻\n쓼\n쓽\n쓾\n씂\n씃\n씄\n씅\n씆\n씇\n씈\n씉\n씊\n씋\n씍\n씎\n씏\n씑\n씒\n씓\n씕\n씖\n씗\n씘\n씙\n씚\n씛\n씝\n씞\n씟\n씠\n씡\n씢\n씣\n씤\n씥\n씦\n씧\n씪\n씫\n씭\n씮\n씯\n씱\n씲\n씳\n씴\n씵\n씶\n씷\n씺\n씼\n씾\n씿\n앀\n앁\n앂\n앃\n앆\n앇\n앋\n앏\n앐\n앑\n앒\n앖\n앚\n앛\n앜\n앟\n앢\n앣\n앥\n앦\n앧\n앩\n앪\n앫\n앬\n앭\n앮\n앯\n앲\n앶\n앷\n앸\n앹\n앺\n앻\n앾\n앿\n얁\n얂\n얃\n얅\n얆\n얈\n얉\n얊\n얋\n얎\n얐\n얒\n얓\n얔\n얖\n얙\n얚\n얛\n얝\n얞\n얟\n얡\n얢\n얣\n얤\n얥\n얦\n얧\n얨\n얪\n얫\n얬\n얭\n얮\n얯\n얰\n얱\n얲\n얳\n얶\n�[\n�\\\n�]\n�^\n�_\n�`\n얷\n얺\n얿\n엀\n엁\n엂\n엃\n엋\n엍\n엏\n엒\n엓\n엕\n엖\n엗\n엙\n엚\n엛\n엜\n엝\n엞\n엟\n엢\n엤\n엦\n엧\n�{\n�|\n�}\n�~\n�\n�\n엨\n엩\n엪\n엫\n엯\n엱\n엲\n엳\n엵\n엸\n엹\n엺\n엻\n옂\n옃\n옄\n옉\n옊\n옋\n옍\n옎\n옏\n옑\n옒\n옓\n옔\n옕\n옖\n옗\n옚\n옝\n옞\n옟\n옠\n옡\n옢\n옣\n옦\n옧\n옩\n옪\n옫\n옯\n옱\n옲\n옶\n옸\n옺\n옼\n옽\n옾\n옿\n왂\n왃\n왅\n왆\n왇\n왉\n왊\n왋\n왌\n왍\n왎\n왏\n왒\n왖\n왗\n왘\n왙\n왚\n왛\n왞\n왟\n왡\n왢\n왣\n왤\n왥\n왦\n왧\n왨\n왩\n왪\n왫\n왭\n왮\n왰\n왲\n왳\n왴\n왵\n왶\n왷\n왺\n왻\n왽\n왾\n왿\n욁\n욂\n욃\n욄\n욅\n욆\n욇\n욊\n욌\n욎\n욏\n욐\n욑\n욒\n욓\n욖\n욗\n욙\n욚\n욛\n욝\n욞\n욟\n욠\n욡\n욢\n욣\n욦\n욨\n욪\n욫\n욬\n욭\n욮\n욯\n욲\n욳\n욵\n욶\n욷\n욻\n욼\n욽\n욾\n욿\n웂\n웄\n웆\n웇\n웈\n웉\n웊\n웋\n웎\n�[\n�\\\n�]\n�^\n�_\n�`\n웏\n웑\n웒\n웓\n웕\n웖\n웗\n웘\n웙\n웚\n웛\n웞\n웟\n웢\n웣\n웤\n웥\n웦\n웧\n웪\n웫\n웭\n웮\n웯\n웱\n웲\n�{\n�|\n�}\n�~\n�\n�\n웳\n웴\n웵\n웶\n웷\n웺\n웻\n웼\n웾\n웿\n윀\n윁\n윂\n윃\n윆\n윇\n윉\n윊\n윋\n윍\n윎\n윏\n윐\n윑\n윒\n윓\n윖\n윘\n윚\n윛\n윜\n윝\n윞\n윟\n윢\n윣\n윥\n윦\n윧\n윩\n윪\n윫\n윬\n윭\n윮\n윯\n윲\n윴\n윶\n윸\n윹\n윺\n윻\n윾\n윿\n읁\n읂\n읃\n읅\n읆\n읇\n읈\n읉\n읋\n읎\n읐\n읙\n읚\n읛\n읝\n읞\n읟\n읡\n읢\n읣\n읤\n읥\n읦\n읧\n읩\n읪\n읬\n읭\n읮\n읯\n읰\n읱\n읲\n읳\n읶\n읷\n읹\n읺\n읻\n읿\n잀\n잁\n잂\n잆\n잋\n잌\n잍\n잏\n잒\n잓\n잕\n잙\n잛\n잜\n잝\n잞\n잟\n잢\n잧\n잨\n잩\n잪\n잫\n잮\n잯\n잱\n잲\n잳\n잵\n잶\n잷\n잸\n잹\n잺\n잻\n잾\n쟂\n쟃\n쟄\n쟅\n쟆\n쟇\n쟊\n쟋\n쟍\n쟏\n쟑\n쟒\n쟓\n쟔\n쟕\n쟖\n쟗\n쟙\n쟚\n쟛\n쟜\n�[\n�\\\n�]\n�^\n�_\n�`\n쟞\n쟟\n쟠\n쟡\n쟢\n쟣\n쟥\n쟦\n쟧\n쟩\n쟪\n쟫\n쟭\n쟮\n쟯\n쟰\n쟱\n쟲\n쟳\n쟴\n쟵\n쟶\n쟷\n쟸\n쟹\n쟺\n�{\n�|\n�}\n�~\n�\n�\n쟻\n쟼\n쟽\n쟾\n쟿\n젂\n젃\n젅\n젆\n젇\n젉\n젋\n젌\n젍\n젎\n젏\n젒\n젔\n젗\n젘\n젙\n젚\n젛\n젞\n젟\n젡\n젢\n젣\n젥\n젦\n젧\n젨\n젩\n젪\n젫\n젮\n젰\n젲\n젳\n젴\n젵\n젶\n젷\n젹\n젺\n젻\n젽\n젾\n젿\n졁\n졂\n졃\n졄\n졅\n졆\n졇\n졊\n졋\n졎\n졏\n졐\n졑\n졒\n졓\n졕\n졖\n졗\n졘\n졙\n졚\n졛\n졜\n졝\n졞\n졟\n졠\n졡\n졢\n졣\n졤\n졥\n졦\n졧\n졨\n졩\n졪\n졫\n졬\n졭\n졮\n졯\n졲\n졳\n졵\n졶\n졷\n졹\n졻\n졼\n졽\n졾\n졿\n좂\n좄\n좈\n좉\n좊\n좎\n좏\n좐\n좑\n좒\n좓\n좕\n좖\n좗\n좘\n좙\n좚\n좛\n좜\n좞\n좠\n좢\n좣\n좤\n좥\n좦\n좧\n좩\n좪\n좫\n좬\n좭\n좮\n좯\n좰\n좱\n좲\n좳\n좴\n좵\n좶\n좷\n좸\n좹\n좺\n좻\n좾\n좿\n죀\n죁\n�[\n�\\\n�]\n�^\n�_\n�`\n죂\n죃\n죅\n죆\n죇\n죉\n죊\n죋\n죍\n죎\n죏\n죐\n죑\n죒\n죓\n죖\n죘\n죚\n죛\n죜\n죝\n죞\n죟\n죢\n죣\n죥\n�{\n�|\n�}\n�~\n�\n�\n죦\n죧\n죨\n죩\n죪\n죫\n죬\n죭\n죮\n죯\n죰\n죱\n죲\n죳\n죴\n죶\n죷\n죸\n죹\n죺\n죻\n죾\n죿\n줁\n줂\n줃\n줇\n줈\n줉\n줊\n줋\n줎\n　\n、\n。\n·\n‥\n…\n¨\n〃\n­\n―\n∥\n＼\n∼\n‘\n’\n“\n”\n〔\n〕\n〈\n〉\n《\n》\n「\n」\n『\n』\n【\n】\n±\n×\n÷\n≠\n≤\n≥\n∞\n∴\n°\n′\n″\n℃\nÅ\n￠\n￡\n￥\n♂\n♀\n∠\n⊥\n⌒\n∂\n∇\n≡\n≒\n§\n※\n☆\n★\n○\n●\n◎\n◇\n◆\n□\n■\n△\n▲\n▽\n▼\n→\n←\n↑\n↓\n↔\n〓\n≪\n≫\n√\n∽\n∝\n∵\n∫\n∬\n∈\n∋\n⊆\n⊇\n⊂\n⊃\n∪\n∩\n∧\n∨\n￢\n줐\n줒\n줓\n줔\n줕\n줖\n줗\n줙\n줚\n줛\n줜\n줝\n줞\n줟\n줠\n줡\n줢\n줣\n줤\n줥\n줦\n줧\n줨\n줩\n줪\n줫\n�[\n�\\\n�]\n�^\n�_\n�`\n줭\n줮\n줯\n줰\n줱\n줲\n줳\n줵\n줶\n줷\n줸\n줹\n줺\n줻\n줼\n줽\n줾\n줿\n쥀\n쥁\n쥂\n쥃\n쥄\n쥅\n쥆\n쥇\n�{\n�|\n�}\n�~\n�\n�\n쥈\n쥉\n쥊\n쥋\n쥌\n쥍\n쥎\n쥏\n쥒\n쥓\n쥕\n쥖\n쥗\n쥙\n쥚\n쥛\n쥜\n쥝\n쥞\n쥟\n쥢\n쥤\n쥥\n쥦\n쥧\n쥨\n쥩\n쥪\n쥫\n쥭\n쥮\n쥯\n⇒\n⇔\n∀\n∃\n´\n～\nˇ\n˘\n˝\n˚\n˙\n¸\n˛\n¡\n¿\nː\n∮\n∑\n∏\n¤\n℉\n‰\n◁\n◀\n▷\n▶\n♤\n♠\n♡\n♥\n♧\n♣\n⊙\n◈\n▣\n◐\n◑\n▒\n▤\n▥\n▨\n▧\n▦\n▩\n♨\n☏\n☎\n☜\n☞\n¶\n†\n‡\n↕\n↗\n↙\n↖\n↘\n♭\n♩\n♪\n♬\n㉿\n㈜\n№\n㏇\n™\n㏂\n㏘\n℡\n€\n®\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n쥱\n쥲\n쥳\n쥵\n쥶\n쥷\n쥸\n쥹\n쥺\n쥻\n쥽\n쥾\n쥿\n즀\n즁\n즂\n즃\n즄\n즅\n즆\n즇\n즊\n즋\n즍\n즎\n즏\n�[\n�\\\n�]\n�^\n�_\n�`\n즑\n즒\n즓\n즔\n즕\n즖\n즗\n즚\n즜\n즞\n즟\n즠\n즡\n즢\n즣\n즤\n즥\n즦\n즧\n즨\n즩\n즪\n즫\n즬\n즭\n즮\n�{\n�|\n�}\n�~\n�\n�\n즯\n즰\n즱\n즲\n즳\n즴\n즵\n즶\n즷\n즸\n즹\n즺\n즻\n즼\n즽\n즾\n즿\n짂\n짃\n짅\n짆\n짉\n짋\n짌\n짍\n짎\n짏\n짒\n짔\n짗\n짘\n짛\n！\n＂\n＃\n＄\n％\n＆\n＇\n（\n）\n＊\n＋\n，\n－\n．\n／\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\n：\n；\n＜\n＝\n＞\n？\n＠\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\n［\n￦\n］\n＾\n＿\n｀\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\n｛\n｜\n｝\n￣\n짞\n짟\n짡\n짣\n짥\n짦\n짨\n짩\n짪\n짫\n짮\n짲\n짳\n짴\n짵\n짶\n짷\n짺\n짻\n짽\n짾\n짿\n쨁\n쨂\n쨃\n쨄\n�[\n�\\\n�]\n�^\n�_\n�`\n쨅\n쨆\n쨇\n쨊\n쨎\n쨏\n쨐\n쨑\n쨒\n쨓\n쨕\n쨖\n쨗\n쨙\n쨚\n쨛\n쨜\n쨝\n쨞\n쨟\n쨠\n쨡\n쨢\n쨣\n쨤\n쨥\n�{\n�|\n�}\n�~\n�\n�\n쨦\n쨧\n쨨\n쨪\n쨫\n쨬\n쨭\n쨮\n쨯\n쨰\n쨱\n쨲\n쨳\n쨴\n쨵\n쨶\n쨷\n쨸\n쨹\n쨺\n쨻\n쨼\n쨽\n쨾\n쨿\n쩀\n쩁\n쩂\n쩃\n쩄\n쩅\n쩆\nㄱ\nㄲ\nㄳ\nㄴ\nㄵ\nㄶ\nㄷ\nㄸ\nㄹ\nㄺ\nㄻ\nㄼ\nㄽ\nㄾ\nㄿ\nㅀ\nㅁ\nㅂ\nㅃ\nㅄ\nㅅ\nㅆ\nㅇ\nㅈ\nㅉ\nㅊ\nㅋ\nㅌ\nㅍ\nㅎ\nㅏ\nㅐ\nㅑ\nㅒ\nㅓ\nㅔ\nㅕ\nㅖ\nㅗ\nㅘ\nㅙ\nㅚ\nㅛ\nㅜ\nㅝ\nㅞ\nㅟ\nㅠ\nㅡ\nㅢ\nㅣ\nㅤ\nㅥ\nㅦ\nㅧ\nㅨ\nㅩ\nㅪ\nㅫ\nㅬ\nㅭ\nㅮ\nㅯ\nㅰ\nㅱ\nㅲ\nㅳ\nㅴ\nㅵ\nㅶ\nㅷ\nㅸ\nㅹ\nㅺ\nㅻ\nㅼ\nㅽ\nㅾ\nㅿ\nㆀ\nㆁ\nㆂ\nㆃ\nㆄ\nㆅ\nㆆ\nㆇ\nㆈ\nㆉ\nㆊ\nㆋ\nㆌ\nㆍ\nㆎ\n쩇\n쩈\n쩉\n쩊\n쩋\n쩎\n쩏\n쩑\n쩒\n쩓\n쩕\n쩖\n쩗\n쩘\n쩙\n쩚\n쩛\n쩞\n쩢\n쩣\n쩤\n쩥\n쩦\n쩧\n쩩\n쩪\n�[\n�\\\n�]\n�^\n�_\n�`\n쩫\n쩬\n쩭\n쩮\n쩯\n쩰\n쩱\n쩲\n쩳\n쩴\n쩵\n쩶\n쩷\n쩸\n쩹\n쩺\n쩻\n쩼\n쩾\n쩿\n쪀\n쪁\n쪂\n쪃\n쪅\n쪆\n�{\n�|\n�}\n�~\n�\n�\n쪇\n쪈\n쪉\n쪊\n쪋\n쪌\n쪍\n쪎\n쪏\n쪐\n쪑\n쪒\n쪓\n쪔\n쪕\n쪖\n쪗\n쪙\n쪚\n쪛\n쪜\n쪝\n쪞\n쪟\n쪠\n쪡\n쪢\n쪣\n쪤\n쪥\n쪦\n쪧\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\n�\n�\n�\n�\n�\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n�\n�\n�\n�\n�\n�\n�\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\n�\n�\n�\n�\n�\n�\n�\n�\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\n�\n�\n�\n�\n�\n�\n쪨\n쪩\n쪪\n쪫\n쪬\n쪭\n쪮\n쪯\n쪰\n쪱\n쪲\n쪳\n쪴\n쪵\n쪶\n쪷\n쪸\n쪹\n쪺\n쪻\n쪾\n쪿\n쫁\n쫂\n쫃\n쫅\n�[\n�\\\n�]\n�^\n�_\n�`\n쫆\n쫇\n쫈\n쫉\n쫊\n쫋\n쫎\n쫐\n쫒\n쫔\n쫕\n쫖\n쫗\n쫚\n쫛\n쫜\n쫝\n쫞\n쫟\n쫡\n쫢\n쫣\n쫤\n쫥\n쫦\n쫧\n�{\n�|\n�}\n�~\n�\n�\n쫨\n쫩\n쫪\n쫫\n쫭\n쫮\n쫯\n쫰\n쫱\n쫲\n쫳\n쫵\n쫶\n쫷\n쫸\n쫹\n쫺\n쫻\n쫼\n쫽\n쫾\n쫿\n쬀\n쬁\n쬂\n쬃\n쬄\n쬅\n쬆\n쬇\n쬉\n쬊\n─\n│\n┌\n┐\n┘\n└\n├\n┬\n┤\n┴\n┼\n━\n┃\n┏\n┓\n┛\n┗\n┣\n┳\n┫\n┻\n╋\n┠\n┯\n┨\n┷\n┿\n┝\n┰\n┥\n┸\n╂\n┒\n┑\n┚\n┙\n┖\n┕\n┎\n┍\n┞\n┟\n┡\n┢\n┦\n┧\n┩\n┪\n┭\n┮\n┱\n┲\n┵\n┶\n┹\n┺\n┽\n┾\n╀\n╁\n╃\n╄\n╅\n╆\n╇\n╈\n╉\n╊\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n쬋\n쬌\n쬍\n쬎\n쬏\n쬑\n쬒\n쬓\n쬕\n쬖\n쬗\n쬙\n쬚\n쬛\n쬜\n쬝\n쬞\n쬟\n쬢\n쬣\n쬤\n쬥\n쬦\n쬧\n쬨\n쬩\n�[\n�\\\n�]\n�^\n�_\n�`\n쬪\n쬫\n쬬\n쬭\n쬮\n쬯\n쬰\n쬱\n쬲\n쬳\n쬴\n쬵\n쬶\n쬷\n쬸\n쬹\n쬺\n쬻\n쬼\n쬽\n쬾\n쬿\n쭀\n쭂\n쭃\n쭄\n�{\n�|\n�}\n�~\n�\n�\n쭅\n쭆\n쭇\n쭊\n쭋\n쭍\n쭎\n쭏\n쭑\n쭒\n쭓\n쭔\n쭕\n쭖\n쭗\n쭚\n쭛\n쭜\n쭞\n쭟\n쭠\n쭡\n쭢\n쭣\n쭥\n쭦\n쭧\n쭨\n쭩\n쭪\n쭫\n쭬\n㎕\n㎖\n㎗\nℓ\n㎘\n㏄\n㎣\n㎤\n㎥\n㎦\n㎙\n㎚\n㎛\n㎜\n㎝\n㎞\n㎟\n㎠\n㎡\n㎢\n㏊\n㎍\n㎎\n㎏\n㏏\n㎈\n㎉\n㏈\n㎧\n㎨\n㎰\n㎱\n㎲\n㎳\n㎴\n㎵\n㎶\n㎷\n㎸\n㎹\n㎀\n㎁\n㎂\n㎃\n㎄\n㎺\n㎻\n㎼\n㎽\n㎾\n㎿\n㎐\n㎑\n㎒\n㎓\n㎔\nΩ\n㏀\n㏁\n㎊\n㎋\n㎌\n㏖\n㏅\n㎭\n㎮\n㎯\n㏛\n㎩\n㎪\n㎫\n㎬\n㏝\n㏐\n㏓\n㏃\n㏉\n㏜\n㏆\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n쭭\n쭮\n쭯\n쭰\n쭱\n쭲\n쭳\n쭴\n쭵\n쭶\n쭷\n쭺\n쭻\n쭼\n쭽\n쭾\n쭿\n쮀\n쮁\n쮂\n쮃\n쮄\n쮅\n쮆\n쮇\n쮈\n�[\n�\\\n�]\n�^\n�_\n�`\n쮉\n쮊\n쮋\n쮌\n쮍\n쮎\n쮏\n쮐\n쮑\n쮒\n쮓\n쮔\n쮕\n쮖\n쮗\n쮘\n쮙\n쮚\n쮛\n쮝\n쮞\n쮟\n쮠\n쮡\n쮢\n쮣\n�{\n�|\n�}\n�~\n�\n�\n쮤\n쮥\n쮦\n쮧\n쮨\n쮩\n쮪\n쮫\n쮬\n쮭\n쮮\n쮯\n쮰\n쮱\n쮲\n쮳\n쮴\n쮵\n쮶\n쮷\n쮹\n쮺\n쮻\n쮼\n쮽\n쮾\n쮿\n쯀\n쯁\n쯂\n쯃\n쯄\nÆ\nÐ\nª\nĦ\n�\nĲ\n�\nĿ\nŁ\nØ\nŒ\nº\nÞ\nŦ\nŊ\n�\n㉠\n㉡\n㉢\n㉣\n㉤\n㉥\n㉦\n㉧\n㉨\n㉩\n㉪\n㉫\n㉬\n㉭\n㉮\n㉯\n㉰\n㉱\n㉲\n㉳\n㉴\n㉵\n㉶\n㉷\n㉸\n㉹\n㉺\n㉻\nⓐ\nⓑ\nⓒ\nⓓ\nⓔ\nⓕ\nⓖ\nⓗ\nⓘ\nⓙ\nⓚ\nⓛ\nⓜ\nⓝ\nⓞ\nⓟ\nⓠ\nⓡ\nⓢ\nⓣ\nⓤ\nⓥ\nⓦ\nⓧ\nⓨ\nⓩ\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n⑪\n⑫\n⑬\n⑭\n⑮\n½\n⅓\n⅔\n¼\n¾\n⅛\n⅜\n⅝\n⅞\n쯅\n쯆\n쯇\n쯈\n쯉\n쯊\n쯋\n쯌\n쯍\n쯎\n쯏\n쯐\n쯑\n쯒\n쯓\n쯕\n쯖\n쯗\n쯘\n쯙\n쯚\n쯛\n쯜\n쯝\n쯞\n쯟\n�[\n�\\\n�]\n�^\n�_\n�`\n쯠\n쯡\n쯢\n쯣\n쯥\n쯦\n쯨\n쯪\n쯫\n쯬\n쯭\n쯮\n쯯\n쯰\n쯱\n쯲\n쯳\n쯴\n쯵\n쯶\n쯷\n쯸\n쯹\n쯺\n쯻\n쯼\n�{\n�|\n�}\n�~\n�\n�\n쯽\n쯾\n쯿\n찀\n찁\n찂\n찃\n찄\n찅\n찆\n찇\n찈\n찉\n찊\n찋\n찎\n찏\n찑\n찒\n찓\n찕\n찖\n찗\n찘\n찙\n찚\n찛\n찞\n찟\n찠\n찣\n찤\næ\nđ\nð\nħ\nı\nĳ\nĸ\nŀ\nł\nø\nœ\nß\nþ\nŧ\nŋ\nŉ\n㈀\n㈁\n㈂\n㈃\n㈄\n㈅\n㈆\n㈇\n㈈\n㈉\n㈊\n㈋\n㈌\n㈍\n㈎\n㈏\n㈐\n㈑\n㈒\n㈓\n㈔\n㈕\n㈖\n㈗\n㈘\n㈙\n㈚\n㈛\n⒜\n⒝\n⒞\n⒟\n⒠\n⒡\n⒢\n⒣\n⒤\n⒥\n⒦\n⒧\n⒨\n⒩\n⒪\n⒫\n⒬\n⒭\n⒮\n⒯\n⒰\n⒱\n⒲\n⒳\n⒴\n⒵\n⑴\n⑵\n⑶\n⑷\n⑸\n⑹\n⑺\n⑻\n⑼\n⑽\n⑾\n⑿\n⒀\n⒁\n⒂\n¹\n²\n³\n⁴\nⁿ\n₁\n₂\n₃\n₄\n찥\n찦\n찪\n찫\n찭\n찯\n찱\n찲\n찳\n찴\n찵\n찶\n찷\n찺\n찿\n챀\n챁\n챂\n챃\n챆\n챇\n챉\n챊\n챋\n챍\n챎\n�[\n�\\\n�]\n�^\n�_\n�`\n챏\n챐\n챑\n챒\n챓\n챖\n챚\n챛\n챜\n챝\n챞\n챟\n챡\n챢\n챣\n챥\n챧\n챩\n챪\n챫\n챬\n챭\n챮\n챯\n챱\n챲\n�{\n�|\n�}\n�~\n�\n�\n챳\n챴\n챶\n챷\n챸\n챹\n챺\n챻\n챼\n챽\n챾\n챿\n첀\n첁\n첂\n첃\n첄\n첅\n첆\n첇\n첈\n첉\n첊\n첋\n첌\n첍\n첎\n첏\n첐\n첑\n첒\n첓\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n첔\n첕\n첖\n첗\n첚\n첛\n첝\n첞\n첟\n첡\n첢\n첣\n첤\n첥\n첦\n첧\n첪\n첮\n첯\n첰\n첱\n첲\n첳\n첶\n첷\n첹\n�[\n�\\\n�]\n�^\n�_\n�`\n첺\n첻\n첽\n첾\n첿\n쳀\n쳁\n쳂\n쳃\n쳆\n쳈\n쳊\n쳋\n쳌\n쳍\n쳎\n쳏\n쳑\n쳒\n쳓\n쳕\n쳖\n쳗\n쳘\n쳙\n쳚\n�{\n�|\n�}\n�~\n�\n�\n쳛\n쳜\n쳝\n쳞\n쳟\n쳠\n쳡\n쳢\n쳣\n쳥\n쳦\n쳧\n쳨\n쳩\n쳪\n쳫\n쳭\n쳮\n쳯\n쳱\n쳲\n쳳\n쳴\n쳵\n쳶\n쳷\n쳸\n쳹\n쳺\n쳻\n쳼\n쳽\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\n�\n�\n�\n�\n�\n�\n�\n�\n쳾\n쳿\n촀\n촂\n촃\n촄\n촅\n촆\n촇\n촊\n촋\n촍\n촎\n촏\n촑\n촒\n촓\n촔\n촕\n촖\n촗\n촚\n촜\n촞\n촟\n촠\n�[\n�\\\n�]\n�^\n�_\n�`\n촡\n촢\n촣\n촥\n촦\n촧\n촩\n촪\n촫\n촭\n촮\n촯\n촰\n촱\n촲\n촳\n촴\n촵\n촶\n촷\n촸\n촺\n촻\n촼\n촽\n촾\n�{\n�|\n�}\n�~\n�\n�\n촿\n쵀\n쵁\n쵂\n쵃\n쵄\n쵅\n쵆\n쵇\n쵈\n쵉\n쵊\n쵋\n쵌\n쵍\n쵎\n쵏\n쵐\n쵑\n쵒\n쵓\n쵔\n쵕\n쵖\n쵗\n쵘\n쵙\n쵚\n쵛\n쵝\n쵞\n쵟\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n쵡\n쵢\n쵣\n쵥\n쵦\n쵧\n쵨\n쵩\n쵪\n쵫\n쵮\n쵰\n쵲\n쵳\n쵴\n쵵\n쵶\n쵷\n쵹\n쵺\n쵻\n쵼\n쵽\n쵾\n쵿\n춀\n�[\n�\\\n�]\n�^\n�_\n�`\n춁\n춂\n춃\n춄\n춅\n춆\n춇\n춉\n춊\n춋\n춌\n춍\n춎\n춏\n춐\n춑\n춒\n춓\n춖\n춗\n춙\n춚\n춛\n춝\n춞\n춟\n�{\n�|\n�}\n�~\n�\n�\n춠\n춡\n춢\n춣\n춦\n춨\n춪\n춫\n춬\n춭\n춮\n춯\n춱\n춲\n춳\n춴\n춵\n춶\n춷\n춸\n춹\n춺\n춻\n춼\n춽\n춾\n춿\n췀\n췁\n췂\n췃\n췅\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n췆\n췇\n췈\n췉\n췊\n췋\n췍\n췎\n췏\n췑\n췒\n췓\n췔\n췕\n췖\n췗\n췘\n췙\n췚\n췛\n췜\n췝\n췞\n췟\n췠\n췡\n�[\n�\\\n�]\n�^\n�_\n�`\n췢\n췣\n췤\n췥\n췦\n췧\n췩\n췪\n췫\n췭\n췮\n췯\n췱\n췲\n췳\n췴\n췵\n췶\n췷\n췺\n췼\n췾\n췿\n츀\n츁\n츂\n�{\n�|\n�}\n�~\n�\n�\n츃\n츅\n츆\n츇\n츉\n츊\n츋\n츍\n츎\n츏\n츐\n츑\n츒\n츓\n츕\n츖\n츗\n츘\n츚\n츛\n츜\n츝\n츞\n츟\n츢\n츣\n츥\n츦\n츧\n츩\n츪\n츫\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n츬\n츭\n츮\n츯\n츲\n츴\n츶\n츷\n츸\n츹\n츺\n츻\n츼\n츽\n츾\n츿\n칀\n칁\n칂\n칃\n칄\n칅\n칆\n칇\n칈\n칉\n�[\n�\\\n�]\n�^\n�_\n�`\n칊\n칋\n칌\n칍\n칎\n칏\n칐\n칑\n칒\n칓\n칔\n칕\n칖\n칗\n칚\n칛\n칝\n칞\n칢\n칣\n칤\n칥\n칦\n칧\n칪\n칬\n�{\n�|\n�}\n�~\n�\n�\n칮\n칯\n칰\n칱\n칲\n칳\n칶\n칷\n칹\n칺\n칻\n칽\n칾\n칿\n캀\n캁\n캂\n캃\n캆\n캈\n캊\n캋\n캌\n캍\n캎\n캏\n캒\n캓\n캕\n캖\n캗\n캙\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n캚\n캛\n캜\n캝\n캞\n캟\n캢\n캦\n캧\n캨\n캩\n캪\n캫\n캮\n캯\n캰\n캱\n캲\n캳\n캴\n캵\n캶\n캷\n캸\n캹\n캺\n�[\n�\\\n�]\n�^\n�_\n�`\n캻\n캼\n캽\n캾\n캿\n컀\n컂\n컃\n컄\n컅\n컆\n컇\n컈\n컉\n컊\n컋\n컌\n컍\n컎\n컏\n컐\n컑\n컒\n컓\n컔\n컕\n�{\n�|\n�}\n�~\n�\n�\n컖\n컗\n컘\n컙\n컚\n컛\n컜\n컝\n컞\n컟\n컠\n컡\n컢\n컣\n컦\n컧\n컩\n컪\n컭\n컮\n컯\n컰\n컱\n컲\n컳\n컶\n컺\n컻\n컼\n컽\n컾\n컿\n가\n각\n간\n갇\n갈\n갉\n갊\n감\n갑\n값\n갓\n갔\n강\n갖\n갗\n같\n갚\n갛\n개\n객\n갠\n갤\n갬\n갭\n갯\n갰\n갱\n갸\n갹\n갼\n걀\n걋\n걍\n걔\n걘\n걜\n거\n걱\n건\n걷\n걸\n걺\n검\n겁\n것\n겄\n겅\n겆\n겉\n겊\n겋\n게\n겐\n겔\n겜\n겝\n겟\n겠\n겡\n겨\n격\n겪\n견\n겯\n결\n겸\n겹\n겻\n겼\n경\n곁\n계\n곈\n곌\n곕\n곗\n고\n곡\n곤\n곧\n골\n곪\n곬\n곯\n곰\n곱\n곳\n공\n곶\n과\n곽\n관\n괄\n괆\n켂\n켃\n켅\n켆\n켇\n켉\n켊\n켋\n켌\n켍\n켎\n켏\n켒\n켔\n켖\n켗\n켘\n켙\n켚\n켛\n켝\n켞\n켟\n켡\n켢\n켣\n�[\n�\\\n�]\n�^\n�_\n�`\n켥\n켦\n켧\n켨\n켩\n켪\n켫\n켮\n켲\n켳\n켴\n켵\n켶\n켷\n켹\n켺\n켻\n켼\n켽\n켾\n켿\n콀\n콁\n콂\n콃\n콄\n�{\n�|\n�}\n�~\n�\n�\n콅\n콆\n콇\n콈\n콉\n콊\n콋\n콌\n콍\n콎\n콏\n콐\n콑\n콒\n콓\n콖\n콗\n콙\n콚\n콛\n콝\n콞\n콟\n콠\n콡\n콢\n콣\n콦\n콨\n콪\n콫\n콬\n괌\n괍\n괏\n광\n괘\n괜\n괠\n괩\n괬\n괭\n괴\n괵\n괸\n괼\n굄\n굅\n굇\n굉\n교\n굔\n굘\n굡\n굣\n구\n국\n군\n굳\n굴\n굵\n굶\n굻\n굼\n굽\n굿\n궁\n궂\n궈\n궉\n권\n궐\n궜\n궝\n궤\n궷\n귀\n귁\n귄\n귈\n귐\n귑\n귓\n규\n균\n귤\n그\n극\n근\n귿\n글\n긁\n금\n급\n긋\n긍\n긔\n기\n긱\n긴\n긷\n길\n긺\n김\n깁\n깃\n깅\n깆\n깊\n까\n깍\n깎\n깐\n깔\n깖\n깜\n깝\n깟\n깠\n깡\n깥\n깨\n깩\n깬\n깰\n깸\n콭\n콮\n콯\n콲\n콳\n콵\n콶\n콷\n콹\n콺\n콻\n콼\n콽\n콾\n콿\n쾁\n쾂\n쾃\n쾄\n쾆\n쾇\n쾈\n쾉\n쾊\n쾋\n쾍\n�[\n�\\\n�]\n�^\n�_\n�`\n쾎\n쾏\n쾐\n쾑\n쾒\n쾓\n쾔\n쾕\n쾖\n쾗\n쾘\n쾙\n쾚\n쾛\n쾜\n쾝\n쾞\n쾟\n쾠\n쾢\n쾣\n쾤\n쾥\n쾦\n쾧\n쾩\n�{\n�|\n�}\n�~\n�\n�\n쾪\n쾫\n쾬\n쾭\n쾮\n쾯\n쾱\n쾲\n쾳\n쾴\n쾵\n쾶\n쾷\n쾸\n쾹\n쾺\n쾻\n쾼\n쾽\n쾾\n쾿\n쿀\n쿁\n쿂\n쿃\n쿅\n쿆\n쿇\n쿈\n쿉\n쿊\n쿋\n깹\n깻\n깼\n깽\n꺄\n꺅\n꺌\n꺼\n꺽\n꺾\n껀\n껄\n껌\n껍\n껏\n껐\n껑\n께\n껙\n껜\n껨\n껫\n껭\n껴\n껸\n껼\n꼇\n꼈\n꼍\n꼐\n꼬\n꼭\n꼰\n꼲\n꼴\n꼼\n꼽\n꼿\n꽁\n꽂\n꽃\n꽈\n꽉\n꽐\n꽜\n꽝\n꽤\n꽥\n꽹\n꾀\n꾄\n꾈\n꾐\n꾑\n꾕\n꾜\n꾸\n꾹\n꾼\n꿀\n꿇\n꿈\n꿉\n꿋\n꿍\n꿎\n꿔\n꿜\n꿨\n꿩\n꿰\n꿱\n꿴\n꿸\n뀀\n뀁\n뀄\n뀌\n뀐\n뀔\n뀜\n뀝\n뀨\n끄\n끅\n끈\n끊\n끌\n끎\n끓\n끔\n끕\n끗\n끙\n쿌\n쿍\n쿎\n쿏\n쿐\n쿑\n쿒\n쿓\n쿔\n쿕\n쿖\n쿗\n쿘\n쿙\n쿚\n쿛\n쿜\n쿝\n쿞\n쿟\n쿢\n쿣\n쿥\n쿦\n쿧\n쿩\n�[\n�\\\n�]\n�^\n�_\n�`\n쿪\n쿫\n쿬\n쿭\n쿮\n쿯\n쿲\n쿴\n쿶\n쿷\n쿸\n쿹\n쿺\n쿻\n쿽\n쿾\n쿿\n퀁\n퀂\n퀃\n퀅\n퀆\n퀇\n퀈\n퀉\n퀊\n�{\n�|\n�}\n�~\n�\n�\n퀋\n퀌\n퀍\n퀎\n퀏\n퀐\n퀒\n퀓\n퀔\n퀕\n퀖\n퀗\n퀙\n퀚\n퀛\n퀜\n퀝\n퀞\n퀟\n퀠\n퀡\n퀢\n퀣\n퀤\n퀥\n퀦\n퀧\n퀨\n퀩\n퀪\n퀫\n퀬\n끝\n끼\n끽\n낀\n낄\n낌\n낍\n낏\n낑\n나\n낙\n낚\n난\n낟\n날\n낡\n낢\n남\n납\n낫\n났\n낭\n낮\n낯\n낱\n낳\n내\n낵\n낸\n낼\n냄\n냅\n냇\n냈\n냉\n냐\n냑\n냔\n냘\n냠\n냥\n너\n넉\n넋\n넌\n널\n넒\n넓\n넘\n넙\n넛\n넜\n넝\n넣\n네\n넥\n넨\n넬\n넴\n넵\n넷\n넸\n넹\n녀\n녁\n년\n녈\n념\n녑\n녔\n녕\n녘\n녜\n녠\n노\n녹\n논\n놀\n놂\n놈\n놉\n놋\n농\n높\n놓\n놔\n놘\n놜\n놨\n뇌\n뇐\n뇔\n뇜\n뇝\n퀮\n퀯\n퀰\n퀱\n퀲\n퀳\n퀶\n퀷\n퀹\n퀺\n퀻\n퀽\n퀾\n퀿\n큀\n큁\n큂\n큃\n큆\n큈\n큊\n큋\n큌\n큍\n큎\n큏\n�[\n�\\\n�]\n�^\n�_\n�`\n큑\n큒\n큓\n큕\n큖\n큗\n큙\n큚\n큛\n큜\n큝\n큞\n큟\n큡\n큢\n큣\n큤\n큥\n큦\n큧\n큨\n큩\n큪\n큫\n큮\n큯\n�{\n�|\n�}\n�~\n�\n�\n큱\n큲\n큳\n큵\n큶\n큷\n큸\n큹\n큺\n큻\n큾\n큿\n킀\n킂\n킃\n킄\n킅\n킆\n킇\n킈\n킉\n킊\n킋\n킌\n킍\n킎\n킏\n킐\n킑\n킒\n킓\n킔\n뇟\n뇨\n뇩\n뇬\n뇰\n뇹\n뇻\n뇽\n누\n눅\n눈\n눋\n눌\n눔\n눕\n눗\n눙\n눠\n눴\n눼\n뉘\n뉜\n뉠\n뉨\n뉩\n뉴\n뉵\n뉼\n늄\n늅\n늉\n느\n늑\n는\n늘\n늙\n늚\n늠\n늡\n늣\n능\n늦\n늪\n늬\n늰\n늴\n니\n닉\n닌\n닐\n닒\n님\n닙\n닛\n닝\n닢\n다\n닥\n닦\n단\n닫\n달\n닭\n닮\n닯\n닳\n담\n답\n닷\n닸\n당\n닺\n닻\n닿\n대\n댁\n댄\n댈\n댐\n댑\n댓\n댔\n댕\n댜\n더\n덕\n덖\n던\n덛\n덜\n덞\n덟\n덤\n덥\n킕\n킖\n킗\n킘\n킙\n킚\n킛\n킜\n킝\n킞\n킟\n킠\n킡\n킢\n킣\n킦\n킧\n킩\n킪\n킫\n킭\n킮\n킯\n킰\n킱\n킲\n�[\n�\\\n�]\n�^\n�_\n�`\n킳\n킶\n킸\n킺\n킻\n킼\n킽\n킾\n킿\n탂\n탃\n탅\n탆\n탇\n탊\n탋\n탌\n탍\n탎\n탏\n탒\n탖\n탗\n탘\n탙\n탚\n�{\n�|\n�}\n�~\n�\n�\n탛\n탞\n탟\n탡\n탢\n탣\n탥\n탦\n탧\n탨\n탩\n탪\n탫\n탮\n탲\n탳\n탴\n탵\n탶\n탷\n탹\n탺\n탻\n탼\n탽\n탾\n탿\n턀\n턁\n턂\n턃\n턄\n덧\n덩\n덫\n덮\n데\n덱\n덴\n델\n뎀\n뎁\n뎃\n뎄\n뎅\n뎌\n뎐\n뎔\n뎠\n뎡\n뎨\n뎬\n도\n독\n돈\n돋\n돌\n돎\n돐\n돔\n돕\n돗\n동\n돛\n돝\n돠\n돤\n돨\n돼\n됐\n되\n된\n될\n됨\n됩\n됫\n됴\n두\n둑\n둔\n둘\n둠\n둡\n둣\n둥\n둬\n뒀\n뒈\n뒝\n뒤\n뒨\n뒬\n뒵\n뒷\n뒹\n듀\n듄\n듈\n듐\n듕\n드\n득\n든\n듣\n들\n듦\n듬\n듭\n듯\n등\n듸\n디\n딕\n딘\n딛\n딜\n딤\n딥\n딧\n딨\n딩\n딪\n따\n딱\n딴\n딸\n턅\n턆\n턇\n턈\n턉\n턊\n턋\n턌\n턎\n턏\n턐\n턑\n턒\n턓\n턔\n턕\n턖\n턗\n턘\n턙\n턚\n턛\n턜\n턝\n턞\n턟\n�[\n�\\\n�]\n�^\n�_\n�`\n턠\n턡\n턢\n턣\n턤\n턥\n턦\n턧\n턨\n턩\n턪\n턫\n턬\n턭\n턮\n턯\n턲\n턳\n턵\n턶\n턷\n턹\n턻\n턼\n턽\n턾\n�{\n�|\n�}\n�~\n�\n�\n턿\n텂\n텆\n텇\n텈\n텉\n텊\n텋\n텎\n텏\n텑\n텒\n텓\n텕\n텖\n텗\n텘\n텙\n텚\n텛\n텞\n텠\n텢\n텣\n텤\n텥\n텦\n텧\n텩\n텪\n텫\n텭\n땀\n땁\n땃\n땄\n땅\n땋\n때\n땍\n땐\n땔\n땜\n땝\n땟\n땠\n땡\n떠\n떡\n떤\n떨\n떪\n떫\n떰\n떱\n떳\n떴\n떵\n떻\n떼\n떽\n뗀\n뗄\n뗌\n뗍\n뗏\n뗐\n뗑\n뗘\n뗬\n또\n똑\n똔\n똘\n똥\n똬\n똴\n뙈\n뙤\n뙨\n뚜\n뚝\n뚠\n뚤\n뚫\n뚬\n뚱\n뛔\n뛰\n뛴\n뛸\n뜀\n뜁\n뜅\n뜨\n뜩\n뜬\n뜯\n뜰\n뜸\n뜹\n뜻\n띄\n띈\n띌\n띔\n띕\n띠\n띤\n띨\n띰\n띱\n띳\n띵\n라\n락\n란\n랄\n람\n랍\n랏\n랐\n랑\n랒\n랖\n랗\n텮\n텯\n텰\n텱\n텲\n텳\n텴\n텵\n텶\n텷\n텸\n텹\n텺\n텻\n텽\n텾\n텿\n톀\n톁\n톂\n톃\n톅\n톆\n톇\n톉\n톊\n�[\n�\\\n�]\n�^\n�_\n�`\n톋\n톌\n톍\n톎\n톏\n톐\n톑\n톒\n톓\n톔\n톕\n톖\n톗\n톘\n톙\n톚\n톛\n톜\n톝\n톞\n톟\n톢\n톣\n톥\n톦\n톧\n�{\n�|\n�}\n�~\n�\n�\n톩\n톪\n톫\n톬\n톭\n톮\n톯\n톲\n톴\n톶\n톷\n톸\n톹\n톻\n톽\n톾\n톿\n퇁\n퇂\n퇃\n퇄\n퇅\n퇆\n퇇\n퇈\n퇉\n퇊\n퇋\n퇌\n퇍\n퇎\n퇏\n래\n랙\n랜\n랠\n램\n랩\n랫\n랬\n랭\n랴\n략\n랸\n럇\n량\n러\n럭\n런\n럴\n럼\n럽\n럿\n렀\n렁\n렇\n레\n렉\n렌\n렐\n렘\n렙\n렛\n렝\n려\n력\n련\n렬\n렴\n렵\n렷\n렸\n령\n례\n롄\n롑\n롓\n로\n록\n론\n롤\n롬\n롭\n롯\n롱\n롸\n롼\n뢍\n뢨\n뢰\n뢴\n뢸\n룀\n룁\n룃\n룅\n료\n룐\n룔\n룝\n룟\n룡\n루\n룩\n룬\n룰\n룸\n룹\n룻\n룽\n뤄\n뤘\n뤠\n뤼\n뤽\n륀\n륄\n륌\n륏\n륑\n류\n륙\n륜\n률\n륨\n륩\n퇐\n퇑\n퇒\n퇓\n퇔\n퇕\n퇖\n퇗\n퇙\n퇚\n퇛\n퇜\n퇝\n퇞\n퇟\n퇠\n퇡\n퇢\n퇣\n퇤\n퇥\n퇦\n퇧\n퇨\n퇩\n퇪\n�[\n�\\\n�]\n�^\n�_\n�`\n퇫\n퇬\n퇭\n퇮\n퇯\n퇰\n퇱\n퇲\n퇳\n퇵\n퇶\n퇷\n퇹\n퇺\n퇻\n퇼\n퇽\n퇾\n퇿\n툀\n툁\n툂\n툃\n툄\n툅\n툆\n�{\n�|\n�}\n�~\n�\n�\n툈\n툊\n툋\n툌\n툍\n툎\n툏\n툑\n툒\n툓\n툔\n툕\n툖\n툗\n툘\n툙\n툚\n툛\n툜\n툝\n툞\n툟\n툠\n툡\n툢\n툣\n툤\n툥\n툦\n툧\n툨\n툩\n륫\n륭\n르\n륵\n른\n를\n름\n릅\n릇\n릉\n릊\n릍\n릎\n리\n릭\n린\n릴\n림\n립\n릿\n링\n마\n막\n만\n많\n맏\n말\n맑\n맒\n맘\n맙\n맛\n망\n맞\n맡\n맣\n매\n맥\n맨\n맬\n맴\n맵\n맷\n맸\n맹\n맺\n먀\n먁\n먈\n먕\n머\n먹\n먼\n멀\n멂\n멈\n멉\n멋\n멍\n멎\n멓\n메\n멕\n멘\n멜\n멤\n멥\n멧\n멨\n멩\n며\n멱\n면\n멸\n몃\n몄\n명\n몇\n몌\n모\n목\n몫\n몬\n몰\n몲\n몸\n몹\n못\n몽\n뫄\n뫈\n뫘\n뫙\n뫼\n툪\n툫\n툮\n툯\n툱\n툲\n툳\n툵\n툶\n툷\n툸\n툹\n툺\n툻\n툾\n퉀\n퉂\n퉃\n퉄\n퉅\n퉆\n퉇\n퉉\n퉊\n퉋\n퉌\n�[\n�\\\n�]\n�^\n�_\n�`\n퉍\n퉎\n퉏\n퉐\n퉑\n퉒\n퉓\n퉔\n퉕\n퉖\n퉗\n퉘\n퉙\n퉚\n퉛\n퉝\n퉞\n퉟\n퉠\n퉡\n퉢\n퉣\n퉥\n퉦\n퉧\n퉨\n�{\n�|\n�}\n�~\n�\n�\n퉩\n퉪\n퉫\n퉬\n퉭\n퉮\n퉯\n퉰\n퉱\n퉲\n퉳\n퉴\n퉵\n퉶\n퉷\n퉸\n퉹\n퉺\n퉻\n퉼\n퉽\n퉾\n퉿\n튂\n튃\n튅\n튆\n튇\n튉\n튊\n튋\n튌\n묀\n묄\n묍\n묏\n묑\n묘\n묜\n묠\n묩\n묫\n무\n묵\n묶\n문\n묻\n물\n묽\n묾\n뭄\n뭅\n뭇\n뭉\n뭍\n뭏\n뭐\n뭔\n뭘\n뭡\n뭣\n뭬\n뮈\n뮌\n뮐\n뮤\n뮨\n뮬\n뮴\n뮷\n므\n믄\n믈\n믐\n믓\n미\n믹\n민\n믿\n밀\n밂\n밈\n밉\n밋\n밌\n밍\n및\n밑\n바\n박\n밖\n밗\n반\n받\n발\n밝\n밞\n밟\n밤\n밥\n밧\n방\n밭\n배\n백\n밴\n밸\n뱀\n뱁\n뱃\n뱄\n뱅\n뱉\n뱌\n뱍\n뱐\n뱝\n버\n벅\n번\n벋\n벌\n벎\n범\n법\n벗\n튍\n튎\n튏\n튒\n튓\n튔\n튖\n튗\n튘\n튙\n튚\n튛\n튝\n튞\n튟\n튡\n튢\n튣\n튥\n튦\n튧\n튨\n튩\n튪\n튫\n튭\n�[\n�\\\n�]\n�^\n�_\n�`\n튮\n튯\n튰\n튲\n튳\n튴\n튵\n튶\n튷\n튺\n튻\n튽\n튾\n틁\n틃\n틄\n틅\n틆\n틇\n틊\n틌\n틍\n틎\n틏\n틐\n틑\n�{\n�|\n�}\n�~\n�\n�\n틒\n틓\n틕\n틖\n틗\n틙\n틚\n틛\n틝\n틞\n틟\n틠\n틡\n틢\n틣\n틦\n틧\n틨\n틩\n틪\n틫\n틬\n틭\n틮\n틯\n틲\n틳\n틵\n틶\n틷\n틹\n틺\n벙\n벚\n베\n벡\n벤\n벧\n벨\n벰\n벱\n벳\n벴\n벵\n벼\n벽\n변\n별\n볍\n볏\n볐\n병\n볕\n볘\n볜\n보\n복\n볶\n본\n볼\n봄\n봅\n봇\n봉\n봐\n봔\n봤\n봬\n뵀\n뵈\n뵉\n뵌\n뵐\n뵘\n뵙\n뵤\n뵨\n부\n북\n분\n붇\n불\n붉\n붊\n붐\n붑\n붓\n붕\n붙\n붚\n붜\n붤\n붰\n붸\n뷔\n뷕\n뷘\n뷜\n뷩\n뷰\n뷴\n뷸\n븀\n븃\n븅\n브\n븍\n븐\n블\n븜\n븝\n븟\n비\n빅\n빈\n빌\n빎\n빔\n빕\n빗\n빙\n빚\n빛\n빠\n빡\n빤\n틻\n틼\n틽\n틾\n틿\n팂\n팄\n팆\n팇\n팈\n팉\n팊\n팋\n팏\n팑\n팒\n팓\n팕\n팗\n팘\n팙\n팚\n팛\n팞\n팢\n팣\n�[\n�\\\n�]\n�^\n�_\n�`\n팤\n팦\n팧\n팪\n팫\n팭\n팮\n팯\n팱\n팲\n팳\n팴\n팵\n팶\n팷\n팺\n팾\n팿\n퍀\n퍁\n퍂\n퍃\n퍆\n퍇\n퍈\n퍉\n�{\n�|\n�}\n�~\n�\n�\n퍊\n퍋\n퍌\n퍍\n퍎\n퍏\n퍐\n퍑\n퍒\n퍓\n퍔\n퍕\n퍖\n퍗\n퍘\n퍙\n퍚\n퍛\n퍜\n퍝\n퍞\n퍟\n퍠\n퍡\n퍢\n퍣\n퍤\n퍥\n퍦\n퍧\n퍨\n퍩\n빨\n빪\n빰\n빱\n빳\n빴\n빵\n빻\n빼\n빽\n뺀\n뺄\n뺌\n뺍\n뺏\n뺐\n뺑\n뺘\n뺙\n뺨\n뻐\n뻑\n뻔\n뻗\n뻘\n뻠\n뻣\n뻤\n뻥\n뻬\n뼁\n뼈\n뼉\n뼘\n뼙\n뼛\n뼜\n뼝\n뽀\n뽁\n뽄\n뽈\n뽐\n뽑\n뽕\n뾔\n뾰\n뿅\n뿌\n뿍\n뿐\n뿔\n뿜\n뿟\n뿡\n쀼\n쁑\n쁘\n쁜\n쁠\n쁨\n쁩\n삐\n삑\n삔\n삘\n삠\n삡\n삣\n삥\n사\n삭\n삯\n산\n삳\n살\n삵\n삶\n삼\n삽\n삿\n샀\n상\n샅\n새\n색\n샌\n샐\n샘\n샙\n샛\n샜\n생\n샤\n퍪\n퍫\n퍬\n퍭\n퍮\n퍯\n퍰\n퍱\n퍲\n퍳\n퍴\n퍵\n퍶\n퍷\n퍸\n퍹\n퍺\n퍻\n퍾\n퍿\n펁\n펂\n펃\n펅\n펆\n펇\n�[\n�\\\n�]\n�^\n�_\n�`\n펈\n펉\n펊\n펋\n펎\n펒\n펓\n펔\n펕\n펖\n펗\n펚\n펛\n펝\n펞\n펟\n펡\n펢\n펣\n펤\n펥\n펦\n펧\n펪\n펬\n펮\n�{\n�|\n�}\n�~\n�\n�\n펯\n펰\n펱\n펲\n펳\n펵\n펶\n펷\n펹\n펺\n펻\n펽\n펾\n펿\n폀\n폁\n폂\n폃\n폆\n폇\n폊\n폋\n폌\n폍\n폎\n폏\n폑\n폒\n폓\n폔\n폕\n폖\n샥\n샨\n샬\n샴\n샵\n샷\n샹\n섀\n섄\n섈\n섐\n섕\n서\n석\n섞\n섟\n선\n섣\n설\n섦\n섧\n섬\n섭\n섯\n섰\n성\n섶\n세\n섹\n센\n셀\n셈\n셉\n셋\n셌\n셍\n셔\n셕\n션\n셜\n셤\n셥\n셧\n셨\n셩\n셰\n셴\n셸\n솅\n소\n속\n솎\n손\n솔\n솖\n솜\n솝\n솟\n송\n솥\n솨\n솩\n솬\n솰\n솽\n쇄\n쇈\n쇌\n쇔\n쇗\n쇘\n쇠\n쇤\n쇨\n쇰\n쇱\n쇳\n쇼\n쇽\n숀\n숄\n숌\n숍\n숏\n숑\n수\n숙\n순\n숟\n술\n숨\n숩\n숫\n숭\n폗\n폙\n폚\n폛\n폜\n폝\n폞\n폟\n폠\n폢\n폤\n폥\n폦\n폧\n폨\n폩\n폪\n폫\n폮\n폯\n폱\n폲\n폳\n폵\n폶\n폷\n�[\n�\\\n�]\n�^\n�_\n�`\n폸\n폹\n폺\n폻\n폾\n퐀\n퐂\n퐃\n퐄\n퐅\n퐆\n퐇\n퐉\n퐊\n퐋\n퐌\n퐍\n퐎\n퐏\n퐐\n퐑\n퐒\n퐓\n퐔\n퐕\n퐖\n�{\n�|\n�}\n�~\n�\n�\n퐗\n퐘\n퐙\n퐚\n퐛\n퐜\n퐞\n퐟\n퐠\n퐡\n퐢\n퐣\n퐤\n퐥\n퐦\n퐧\n퐨\n퐩\n퐪\n퐫\n퐬\n퐭\n퐮\n퐯\n퐰\n퐱\n퐲\n퐳\n퐴\n퐵\n퐶\n퐷\n숯\n숱\n숲\n숴\n쉈\n쉐\n쉑\n쉔\n쉘\n쉠\n쉥\n쉬\n쉭\n쉰\n쉴\n쉼\n쉽\n쉿\n슁\n슈\n슉\n슐\n슘\n슛\n슝\n스\n슥\n슨\n슬\n슭\n슴\n습\n슷\n승\n시\n식\n신\n싣\n실\n싫\n심\n십\n싯\n싱\n싶\n싸\n싹\n싻\n싼\n쌀\n쌈\n쌉\n쌌\n쌍\n쌓\n쌔\n쌕\n쌘\n쌜\n쌤\n쌥\n쌨\n쌩\n썅\n써\n썩\n썬\n썰\n썲\n썸\n썹\n썼\n썽\n쎄\n쎈\n쎌\n쏀\n쏘\n쏙\n쏜\n쏟\n쏠\n쏢\n쏨\n쏩\n쏭\n쏴\n쏵\n쏸\n쐈\n쐐\n쐤\n쐬\n쐰\n퐸\n퐹\n퐺\n퐻\n퐼\n퐽\n퐾\n퐿\n푁\n푂\n푃\n푅\n푆\n푇\n푈\n푉\n푊\n푋\n푌\n푍\n푎\n푏\n푐\n푑\n푒\n푓\n�[\n�\\\n�]\n�^\n�_\n�`\n푔\n푕\n푖\n푗\n푘\n푙\n푚\n푛\n푝\n푞\n푟\n푡\n푢\n푣\n푥\n푦\n푧\n푨\n푩\n푪\n푫\n푬\n푮\n푰\n푱\n푲\n�{\n�|\n�}\n�~\n�\n�\n푳\n푴\n푵\n푶\n푷\n푺\n푻\n푽\n푾\n풁\n풃\n풄\n풅\n풆\n풇\n풊\n풌\n풎\n풏\n풐\n풑\n풒\n풓\n풕\n풖\n풗\n풘\n풙\n풚\n풛\n풜\n풝\n쐴\n쐼\n쐽\n쑈\n쑤\n쑥\n쑨\n쑬\n쑴\n쑵\n쑹\n쒀\n쒔\n쒜\n쒸\n쒼\n쓩\n쓰\n쓱\n쓴\n쓸\n쓺\n쓿\n씀\n씁\n씌\n씐\n씔\n씜\n씨\n씩\n씬\n씰\n씸\n씹\n씻\n씽\n아\n악\n안\n앉\n않\n알\n앍\n앎\n앓\n암\n압\n앗\n았\n앙\n앝\n앞\n애\n액\n앤\n앨\n앰\n앱\n앳\n앴\n앵\n야\n약\n얀\n얄\n얇\n얌\n얍\n얏\n양\n얕\n얗\n얘\n얜\n얠\n얩\n어\n억\n언\n얹\n얻\n얼\n얽\n얾\n엄\n업\n없\n엇\n었\n엉\n엊\n엌\n엎\n풞\n풟\n풠\n풡\n풢\n풣\n풤\n풥\n풦\n풧\n풨\n풪\n풫\n풬\n풭\n풮\n풯\n풰\n풱\n풲\n풳\n풴\n풵\n풶\n풷\n풸\n�[\n�\\\n�]\n�^\n�_\n�`\n풹\n풺\n풻\n풼\n풽\n풾\n풿\n퓀\n퓁\n퓂\n퓃\n퓄\n퓅\n퓆\n퓇\n퓈\n퓉\n퓊\n퓋\n퓍\n퓎\n퓏\n퓑\n퓒\n퓓\n퓕\n�{\n�|\n�}\n�~\n�\n�\n퓖\n퓗\n퓘\n퓙\n퓚\n퓛\n퓝\n퓞\n퓠\n퓡\n퓢\n퓣\n퓤\n퓥\n퓦\n퓧\n퓩\n퓪\n퓫\n퓭\n퓮\n퓯\n퓱\n퓲\n퓳\n퓴\n퓵\n퓶\n퓷\n퓹\n퓺\n퓼\n에\n엑\n엔\n엘\n엠\n엡\n엣\n엥\n여\n역\n엮\n연\n열\n엶\n엷\n염\n엽\n엾\n엿\n였\n영\n옅\n옆\n옇\n예\n옌\n옐\n옘\n옙\n옛\n옜\n오\n옥\n온\n올\n옭\n옮\n옰\n옳\n옴\n옵\n옷\n옹\n옻\n와\n왁\n완\n왈\n왐\n왑\n왓\n왔\n왕\n왜\n왝\n왠\n왬\n왯\n왱\n외\n왹\n왼\n욀\n욈\n욉\n욋\n욍\n요\n욕\n욘\n욜\n욤\n욥\n욧\n용\n우\n욱\n운\n울\n욹\n욺\n움\n웁\n웃\n웅\n워\n웍\n원\n월\n웜\n웝\n웠\n웡\n웨\n퓾\n퓿\n픀\n픁\n픂\n픃\n픅\n픆\n픇\n픉\n픊\n픋\n픍\n픎\n픏\n픐\n픑\n픒\n픓\n픖\n픘\n픙\n픚\n픛\n픜\n픝\n�[\n�\\\n�]\n�^\n�_\n�`\n픞\n픟\n픠\n픡\n픢\n픣\n픤\n픥\n픦\n픧\n픨\n픩\n픪\n픫\n픬\n픭\n픮\n픯\n픰\n픱\n픲\n픳\n픴\n픵\n픶\n픷\n�{\n�|\n�}\n�~\n�\n�\n픸\n픹\n픺\n픻\n픾\n픿\n핁\n핂\n핃\n핅\n핆\n핇\n핈\n핉\n핊\n핋\n핎\n핐\n핒\n핓\n핔\n핕\n핖\n핗\n핚\n핛\n핝\n핞\n핟\n핡\n핢\n핣\n웩\n웬\n웰\n웸\n웹\n웽\n위\n윅\n윈\n윌\n윔\n윕\n윗\n윙\n유\n육\n윤\n율\n윰\n윱\n윳\n융\n윷\n으\n윽\n은\n을\n읊\n음\n읍\n읏\n응\n읒\n읓\n읔\n읕\n읖\n읗\n의\n읜\n읠\n읨\n읫\n이\n익\n인\n일\n읽\n읾\n잃\n임\n입\n잇\n있\n잉\n잊\n잎\n자\n작\n잔\n잖\n잗\n잘\n잚\n잠\n잡\n잣\n잤\n장\n잦\n재\n잭\n잰\n잴\n잼\n잽\n잿\n쟀\n쟁\n쟈\n쟉\n쟌\n쟎\n쟐\n쟘\n쟝\n쟤\n쟨\n쟬\n저\n적\n전\n절\n젊\n핤\n핦\n핧\n핪\n핬\n핮\n핯\n핰\n핱\n핲\n핳\n핶\n핷\n핹\n핺\n핻\n핽\n핾\n핿\n햀\n햁\n햂\n햃\n햆\n햊\n햋\n�[\n�\\\n�]\n�^\n�_\n�`\n햌\n햍\n햎\n햏\n햑\n햒\n햓\n햔\n햕\n햖\n햗\n햘\n햙\n햚\n햛\n햜\n햝\n햞\n햟\n햠\n햡\n햢\n햣\n햤\n햦\n햧\n�{\n�|\n�}\n�~\n�\n�\n햨\n햩\n햪\n햫\n햬\n햭\n햮\n햯\n햰\n햱\n햲\n햳\n햴\n햵\n햶\n햷\n햸\n햹\n햺\n햻\n햼\n햽\n햾\n햿\n헀\n헁\n헂\n헃\n헄\n헅\n헆\n헇\n점\n접\n젓\n정\n젖\n제\n젝\n젠\n젤\n젬\n젭\n젯\n젱\n져\n젼\n졀\n졈\n졉\n졌\n졍\n졔\n조\n족\n존\n졸\n졺\n좀\n좁\n좃\n종\n좆\n좇\n좋\n좌\n좍\n좔\n좝\n좟\n좡\n좨\n좼\n좽\n죄\n죈\n죌\n죔\n죕\n죗\n죙\n죠\n죡\n죤\n죵\n주\n죽\n준\n줄\n줅\n줆\n줌\n줍\n줏\n중\n줘\n줬\n줴\n쥐\n쥑\n쥔\n쥘\n쥠\n쥡\n쥣\n쥬\n쥰\n쥴\n쥼\n즈\n즉\n즌\n즐\n즘\n즙\n즛\n증\n지\n직\n진\n짇\n질\n짊\n짐\n집\n짓\n헊\n헋\n헍\n헎\n헏\n헑\n헓\n헔\n헕\n헖\n헗\n헚\n헜\n헞\n헟\n헠\n헡\n헢\n헣\n헦\n헧\n헩\n헪\n헫\n헭\n헮\n�[\n�\\\n�]\n�^\n�_\n�`\n헯\n헰\n헱\n헲\n헳\n헶\n헸\n헺\n헻\n헼\n헽\n헾\n헿\n혂\n혃\n혅\n혆\n혇\n혉\n혊\n혋\n혌\n혍\n혎\n혏\n혒\n�{\n�|\n�}\n�~\n�\n�\n혖\n혗\n혘\n혙\n혚\n혛\n혝\n혞\n혟\n혡\n혢\n혣\n혥\n혦\n혧\n혨\n혩\n혪\n혫\n혬\n혮\n혯\n혰\n혱\n혲\n혳\n혴\n혵\n혶\n혷\n혺\n혻\n징\n짖\n짙\n짚\n짜\n짝\n짠\n짢\n짤\n짧\n짬\n짭\n짯\n짰\n짱\n째\n짹\n짼\n쨀\n쨈\n쨉\n쨋\n쨌\n쨍\n쨔\n쨘\n쨩\n쩌\n쩍\n쩐\n쩔\n쩜\n쩝\n쩟\n쩠\n쩡\n쩨\n쩽\n쪄\n쪘\n쪼\n쪽\n쫀\n쫄\n쫌\n쫍\n쫏\n쫑\n쫓\n쫘\n쫙\n쫠\n쫬\n쫴\n쬈\n쬐\n쬔\n쬘\n쬠\n쬡\n쭁\n쭈\n쭉\n쭌\n쭐\n쭘\n쭙\n쭝\n쭤\n쭸\n쭹\n쮜\n쮸\n쯔\n쯤\n쯧\n쯩\n찌\n찍\n찐\n찔\n찜\n찝\n찡\n찢\n찧\n차\n착\n찬\n찮\n찰\n참\n찹\n찻\n혽\n혾\n혿\n홁\n홂\n홃\n홄\n홆\n홇\n홊\n홌\n홎\n홏\n홐\n홒\n홓\n홖\n홗\n홙\n홚\n홛\n홝\n홞\n홟\n홠\n홡\n�[\n�\\\n�]\n�^\n�_\n�`\n홢\n홣\n홤\n홥\n홦\n홨\n홪\n홫\n홬\n홭\n홮\n홯\n홲\n홳\n홵\n홶\n홷\n홸\n홹\n홺\n홻\n홼\n홽\n홾\n홿\n횀\n�{\n�|\n�}\n�~\n�\n�\n횁\n횂\n횄\n횆\n횇\n횈\n횉\n횊\n횋\n횎\n횏\n횑\n횒\n횓\n횕\n횖\n횗\n횘\n횙\n횚\n횛\n횜\n횞\n횠\n횢\n횣\n횤\n횥\n횦\n횧\n횩\n횪\n찼\n창\n찾\n채\n책\n챈\n챌\n챔\n챕\n챗\n챘\n챙\n챠\n챤\n챦\n챨\n챰\n챵\n처\n척\n천\n철\n첨\n첩\n첫\n첬\n청\n체\n첵\n첸\n첼\n쳄\n쳅\n쳇\n쳉\n쳐\n쳔\n쳤\n쳬\n쳰\n촁\n초\n촉\n촌\n촐\n촘\n촙\n촛\n총\n촤\n촨\n촬\n촹\n최\n쵠\n쵤\n쵬\n쵭\n쵯\n쵱\n쵸\n춈\n추\n축\n춘\n출\n춤\n춥\n춧\n충\n춰\n췄\n췌\n췐\n취\n췬\n췰\n췸\n췹\n췻\n췽\n츄\n츈\n츌\n츔\n츙\n츠\n측\n츤\n츨\n츰\n츱\n츳\n층\n횫\n횭\n횮\n횯\n횱\n횲\n횳\n횴\n횵\n횶\n횷\n횸\n횺\n횼\n횽\n횾\n횿\n훀\n훁\n훂\n훃\n훆\n훇\n훉\n훊\n훋\n�[\n�\\\n�]\n�^\n�_\n�`\n훍\n훎\n훏\n훐\n훒\n훓\n훕\n훖\n훘\n훚\n훛\n훜\n훝\n훞\n훟\n훡\n훢\n훣\n훥\n훦\n훧\n훩\n훪\n훫\n훬\n훭\n�{\n�|\n�}\n�~\n�\n�\n훮\n훯\n훱\n훲\n훳\n훴\n훶\n훷\n훸\n훹\n훺\n훻\n훾\n훿\n휁\n휂\n휃\n휅\n휆\n휇\n휈\n휉\n휊\n휋\n휌\n휍\n휎\n휏\n휐\n휒\n휓\n휔\n치\n칙\n친\n칟\n칠\n칡\n침\n칩\n칫\n칭\n카\n칵\n칸\n칼\n캄\n캅\n캇\n캉\n캐\n캑\n캔\n캘\n캠\n캡\n캣\n캤\n캥\n캬\n캭\n컁\n커\n컥\n컨\n컫\n컬\n컴\n컵\n컷\n컸\n컹\n케\n켁\n켄\n켈\n켐\n켑\n켓\n켕\n켜\n켠\n켤\n켬\n켭\n켯\n켰\n켱\n켸\n코\n콕\n콘\n콜\n콤\n콥\n콧\n콩\n콰\n콱\n콴\n콸\n쾀\n쾅\n쾌\n쾡\n쾨\n쾰\n쿄\n쿠\n쿡\n쿤\n쿨\n쿰\n쿱\n쿳\n쿵\n쿼\n퀀\n퀄\n퀑\n퀘\n퀭\n퀴\n퀵\n퀸\n퀼\n휕\n휖\n휗\n휚\n휛\n휝\n휞\n휟\n휡\n휢\n휣\n휤\n휥\n휦\n휧\n휪\n휬\n휮\n휯\n휰\n휱\n휲\n휳\n휶\n휷\n휹\n�[\n�\\\n�]\n�^\n�_\n�`\n휺\n휻\n휽\n휾\n휿\n흀\n흁\n흂\n흃\n흅\n흆\n흈\n흊\n흋\n흌\n흍\n흎\n흏\n흒\n흓\n흕\n흚\n흛\n흜\n흝\n흞\n�{\n�|\n�}\n�~\n�\n�\n흟\n흢\n흤\n흦\n흧\n흨\n흪\n흫\n흭\n흮\n흯\n흱\n흲\n흳\n흵\n흶\n흷\n흸\n흹\n흺\n흻\n흾\n흿\n힀\n힂\n힃\n힄\n힅\n힆\n힇\n힊\n힋\n큄\n큅\n큇\n큉\n큐\n큔\n큘\n큠\n크\n큭\n큰\n클\n큼\n큽\n킁\n키\n킥\n킨\n킬\n킴\n킵\n킷\n킹\n타\n탁\n탄\n탈\n탉\n탐\n탑\n탓\n탔\n탕\n태\n택\n탠\n탤\n탬\n탭\n탯\n탰\n탱\n탸\n턍\n터\n턱\n턴\n털\n턺\n텀\n텁\n텃\n텄\n텅\n테\n텍\n텐\n텔\n템\n텝\n텟\n텡\n텨\n텬\n텼\n톄\n톈\n토\n톡\n톤\n톨\n톰\n톱\n톳\n통\n톺\n톼\n퇀\n퇘\n퇴\n퇸\n툇\n툉\n툐\n투\n툭\n툰\n툴\n툼\n툽\n툿\n퉁\n퉈\n퉜\n힍\n힎\n힏\n힑\n힒\n힓\n힔\n힕\n힖\n힗\n힚\n힜\n힞\n힟\n힠\n힡\n힢\n힣\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n퉤\n튀\n튁\n튄\n튈\n튐\n튑\n튕\n튜\n튠\n튤\n튬\n튱\n트\n특\n튼\n튿\n틀\n틂\n틈\n틉\n틋\n틔\n틘\n틜\n틤\n틥\n티\n틱\n틴\n틸\n팀\n팁\n팃\n팅\n파\n팍\n팎\n판\n팔\n팖\n팜\n팝\n팟\n팠\n팡\n팥\n패\n팩\n팬\n팰\n팸\n팹\n팻\n팼\n팽\n퍄\n퍅\n퍼\n퍽\n펀\n펄\n펌\n펍\n펏\n펐\n펑\n페\n펙\n펜\n펠\n펨\n펩\n펫\n펭\n펴\n편\n펼\n폄\n폅\n폈\n평\n폐\n폘\n폡\n폣\n포\n폭\n폰\n폴\n폼\n폽\n폿\n퐁\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n퐈\n퐝\n푀\n푄\n표\n푠\n푤\n푭\n푯\n푸\n푹\n푼\n푿\n풀\n풂\n품\n풉\n풋\n풍\n풔\n풩\n퓌\n퓐\n퓔\n퓜\n퓟\n퓨\n퓬\n퓰\n퓸\n퓻\n퓽\n프\n픈\n플\n픔\n픕\n픗\n피\n픽\n핀\n필\n핌\n핍\n핏\n핑\n하\n학\n한\n할\n핥\n함\n합\n핫\n항\n해\n핵\n핸\n핼\n햄\n햅\n햇\n했\n행\n햐\n향\n허\n헉\n헌\n헐\n헒\n험\n헙\n헛\n헝\n헤\n헥\n헨\n헬\n헴\n헵\n헷\n헹\n혀\n혁\n현\n혈\n혐\n협\n혓\n혔\n형\n혜\n혠\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n혤\n혭\n호\n혹\n혼\n홀\n홅\n홈\n홉\n홋\n홍\n홑\n화\n확\n환\n활\n홧\n황\n홰\n홱\n홴\n횃\n횅\n회\n획\n횐\n횔\n횝\n횟\n횡\n효\n횬\n횰\n횹\n횻\n후\n훅\n훈\n훌\n훑\n훔\n훗\n훙\n훠\n훤\n훨\n훰\n훵\n훼\n훽\n휀\n휄\n휑\n휘\n휙\n휜\n휠\n휨\n휩\n휫\n휭\n휴\n휵\n휸\n휼\n흄\n흇\n흉\n흐\n흑\n흔\n흖\n흗\n흘\n흙\n흠\n흡\n흣\n흥\n흩\n희\n흰\n흴\n흼\n흽\n힁\n히\n힉\n힌\n힐\n힘\n힙\n힛\n힝\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n伽\n佳\n假\n價\n加\n可\n呵\n哥\n嘉\n嫁\n家\n暇\n架\n枷\n柯\n歌\n珂\n痂\n稼\n苛\n茄\n街\n袈\n訶\n賈\n跏\n軻\n迦\n駕\n刻\n却\n各\n恪\n慤\n殼\n珏\n脚\n覺\n角\n閣\n侃\n刊\n墾\n奸\n姦\n干\n幹\n懇\n揀\n杆\n柬\n桿\n澗\n癎\n看\n磵\n稈\n竿\n簡\n肝\n艮\n艱\n諫\n間\n乫\n喝\n曷\n渴\n碣\n竭\n葛\n褐\n蝎\n鞨\n勘\n坎\n堪\n嵌\n感\n憾\n戡\n敢\n柑\n橄\n減\n甘\n疳\n監\n瞰\n紺\n邯\n鑑\n鑒\n龕\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n匣\n岬\n甲\n胛\n鉀\n閘\n剛\n堈\n姜\n岡\n崗\n康\n强\n彊\n慷\n江\n畺\n疆\n糠\n絳\n綱\n羌\n腔\n舡\n薑\n襁\n講\n鋼\n降\n鱇\n介\n价\n個\n凱\n塏\n愷\n愾\n慨\n改\n槪\n漑\n疥\n皆\n盖\n箇\n芥\n蓋\n豈\n鎧\n開\n喀\n客\n坑\n更\n粳\n羹\n醵\n倨\n去\n居\n巨\n拒\n据\n據\n擧\n渠\n炬\n祛\n距\n踞\n車\n遽\n鉅\n鋸\n乾\n件\n健\n巾\n建\n愆\n楗\n腱\n虔\n蹇\n鍵\n騫\n乞\n傑\n杰\n桀\n儉\n劍\n劒\n檢\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n瞼\n鈐\n黔\n劫\n怯\n迲\n偈\n憩\n揭\n擊\n格\n檄\n激\n膈\n覡\n隔\n堅\n牽\n犬\n甄\n絹\n繭\n肩\n見\n譴\n遣\n鵑\n抉\n決\n潔\n結\n缺\n訣\n兼\n慊\n箝\n謙\n鉗\n鎌\n京\n俓\n倞\n傾\n儆\n勁\n勍\n卿\n坰\n境\n庚\n徑\n慶\n憬\n擎\n敬\n景\n暻\n更\n梗\n涇\n炅\n烱\n璟\n璥\n瓊\n痙\n硬\n磬\n竟\n競\n絅\n經\n耕\n耿\n脛\n莖\n警\n輕\n逕\n鏡\n頃\n頸\n驚\n鯨\n係\n啓\n堺\n契\n季\n屆\n悸\n戒\n桂\n械\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n棨\n溪\n界\n癸\n磎\n稽\n系\n繫\n繼\n計\n誡\n谿\n階\n鷄\n古\n叩\n告\n呱\n固\n姑\n孤\n尻\n庫\n拷\n攷\n故\n敲\n暠\n枯\n槁\n沽\n痼\n皐\n睾\n稿\n羔\n考\n股\n膏\n苦\n苽\n菰\n藁\n蠱\n袴\n誥\n賈\n辜\n錮\n雇\n顧\n高\n鼓\n哭\n斛\n曲\n梏\n穀\n谷\n鵠\n困\n坤\n崑\n昆\n梱\n棍\n滾\n琨\n袞\n鯤\n汨\n滑\n骨\n供\n公\n共\n功\n孔\n工\n恐\n恭\n拱\n控\n攻\n珙\n空\n蚣\n貢\n鞏\n串\n寡\n戈\n果\n瓜\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n科\n菓\n誇\n課\n跨\n過\n鍋\n顆\n廓\n槨\n藿\n郭\n串\n冠\n官\n寬\n慣\n棺\n款\n灌\n琯\n瓘\n管\n罐\n菅\n觀\n貫\n關\n館\n刮\n恝\n括\n适\n侊\n光\n匡\n壙\n廣\n曠\n洸\n炚\n狂\n珖\n筐\n胱\n鑛\n卦\n掛\n罫\n乖\n傀\n塊\n壞\n怪\n愧\n拐\n槐\n魁\n宏\n紘\n肱\n轟\n交\n僑\n咬\n喬\n嬌\n嶠\n巧\n攪\n敎\n校\n橋\n狡\n皎\n矯\n絞\n翹\n膠\n蕎\n蛟\n較\n轎\n郊\n餃\n驕\n鮫\n丘\n久\n九\n仇\n俱\n具\n勾\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n區\n口\n句\n咎\n嘔\n坵\n垢\n寇\n嶇\n廐\n懼\n拘\n救\n枸\n柩\n構\n歐\n毆\n毬\n求\n溝\n灸\n狗\n玖\n球\n瞿\n矩\n究\n絿\n耉\n臼\n舅\n舊\n苟\n衢\n謳\n購\n軀\n逑\n邱\n鉤\n銶\n駒\n驅\n鳩\n鷗\n龜\n國\n局\n菊\n鞠\n鞫\n麴\n君\n窘\n群\n裙\n軍\n郡\n堀\n屈\n掘\n窟\n宮\n弓\n穹\n窮\n芎\n躬\n倦\n券\n勸\n卷\n圈\n拳\n捲\n權\n淃\n眷\n厥\n獗\n蕨\n蹶\n闕\n机\n櫃\n潰\n詭\n軌\n饋\n句\n晷\n歸\n貴\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n鬼\n龜\n叫\n圭\n奎\n揆\n槻\n珪\n硅\n窺\n竅\n糾\n葵\n規\n赳\n逵\n閨\n勻\n均\n畇\n筠\n菌\n鈞\n龜\n橘\n克\n剋\n劇\n戟\n棘\n極\n隙\n僅\n劤\n勤\n懃\n斤\n根\n槿\n瑾\n筋\n芹\n菫\n覲\n謹\n近\n饉\n契\n今\n妗\n擒\n昑\n檎\n琴\n禁\n禽\n芩\n衾\n衿\n襟\n金\n錦\n伋\n及\n急\n扱\n汲\n級\n給\n亘\n兢\n矜\n肯\n企\n伎\n其\n冀\n嗜\n器\n圻\n基\n埼\n夔\n奇\n妓\n寄\n岐\n崎\n己\n幾\n忌\n技\n旗\n旣\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n朞\n期\n杞\n棋\n棄\n機\n欺\n氣\n汽\n沂\n淇\n玘\n琦\n琪\n璂\n璣\n畸\n畿\n碁\n磯\n祁\n祇\n祈\n祺\n箕\n紀\n綺\n羈\n耆\n耭\n肌\n記\n譏\n豈\n起\n錡\n錤\n飢\n饑\n騎\n騏\n驥\n麒\n緊\n佶\n吉\n拮\n桔\n金\n喫\n儺\n喇\n奈\n娜\n懦\n懶\n拏\n拿\n癩\n羅\n蘿\n螺\n裸\n邏\n那\n樂\n洛\n烙\n珞\n落\n諾\n酪\n駱\n亂\n卵\n暖\n欄\n煖\n爛\n蘭\n難\n鸞\n捏\n捺\n南\n嵐\n枏\n楠\n湳\n濫\n男\n藍\n襤\n拉\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n納\n臘\n蠟\n衲\n囊\n娘\n廊\n朗\n浪\n狼\n郎\n乃\n來\n內\n奈\n柰\n耐\n冷\n女\n年\n撚\n秊\n念\n恬\n拈\n捻\n寧\n寗\n努\n勞\n奴\n弩\n怒\n擄\n櫓\n爐\n瑙\n盧\n老\n蘆\n虜\n路\n露\n駑\n魯\n鷺\n碌\n祿\n綠\n菉\n錄\n鹿\n論\n壟\n弄\n濃\n籠\n聾\n膿\n農\n惱\n牢\n磊\n腦\n賂\n雷\n尿\n壘\n屢\n樓\n淚\n漏\n累\n縷\n陋\n嫩\n訥\n杻\n紐\n勒\n肋\n凜\n凌\n稜\n綾\n能\n菱\n陵\n尼\n泥\n匿\n溺\n多\n茶\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n丹\n亶\n但\n單\n團\n壇\n彖\n斷\n旦\n檀\n段\n湍\n短\n端\n簞\n緞\n蛋\n袒\n鄲\n鍛\n撻\n澾\n獺\n疸\n達\n啖\n坍\n憺\n擔\n曇\n淡\n湛\n潭\n澹\n痰\n聃\n膽\n蕁\n覃\n談\n譚\n錟\n沓\n畓\n答\n踏\n遝\n唐\n堂\n塘\n幢\n戇\n撞\n棠\n當\n糖\n螳\n黨\n代\n垈\n坮\n大\n對\n岱\n帶\n待\n戴\n擡\n玳\n臺\n袋\n貸\n隊\n黛\n宅\n德\n悳\n倒\n刀\n到\n圖\n堵\n塗\n導\n屠\n島\n嶋\n度\n徒\n悼\n挑\n掉\n搗\n桃\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n棹\n櫂\n淘\n渡\n滔\n濤\n燾\n盜\n睹\n禱\n稻\n萄\n覩\n賭\n跳\n蹈\n逃\n途\n道\n都\n鍍\n陶\n韜\n毒\n瀆\n牘\n犢\n獨\n督\n禿\n篤\n纛\n讀\n墩\n惇\n敦\n旽\n暾\n沌\n焞\n燉\n豚\n頓\n乭\n突\n仝\n冬\n凍\n動\n同\n憧\n東\n桐\n棟\n洞\n潼\n疼\n瞳\n童\n胴\n董\n銅\n兜\n斗\n杜\n枓\n痘\n竇\n荳\n讀\n豆\n逗\n頭\n屯\n臀\n芚\n遁\n遯\n鈍\n得\n嶝\n橙\n燈\n登\n等\n藤\n謄\n鄧\n騰\n喇\n懶\n拏\n癩\n羅\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n蘿\n螺\n裸\n邏\n樂\n洛\n烙\n珞\n絡\n落\n諾\n酪\n駱\n丹\n亂\n卵\n欄\n欒\n瀾\n爛\n蘭\n鸞\n剌\n辣\n嵐\n擥\n攬\n欖\n濫\n籃\n纜\n藍\n襤\n覽\n拉\n臘\n蠟\n廊\n朗\n浪\n狼\n琅\n瑯\n螂\n郞\n來\n崍\n徠\n萊\n冷\n掠\n略\n亮\n倆\n兩\n凉\n梁\n樑\n粮\n粱\n糧\n良\n諒\n輛\n量\n侶\n儷\n勵\n呂\n廬\n慮\n戾\n旅\n櫚\n濾\n礪\n藜\n蠣\n閭\n驢\n驪\n麗\n黎\n力\n曆\n歷\n瀝\n礫\n轢\n靂\n憐\n戀\n攣\n漣\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n煉\n璉\n練\n聯\n蓮\n輦\n連\n鍊\n冽\n列\n劣\n洌\n烈\n裂\n廉\n斂\n殮\n濂\n簾\n獵\n令\n伶\n囹\n寧\n岺\n嶺\n怜\n玲\n笭\n羚\n翎\n聆\n逞\n鈴\n零\n靈\n領\n齡\n例\n澧\n禮\n醴\n隷\n勞\n怒\n撈\n擄\n櫓\n潞\n瀘\n爐\n盧\n老\n蘆\n虜\n路\n輅\n露\n魯\n鷺\n鹵\n碌\n祿\n綠\n菉\n錄\n鹿\n麓\n論\n壟\n弄\n朧\n瀧\n瓏\n籠\n聾\n儡\n瀨\n牢\n磊\n賂\n賚\n賴\n雷\n了\n僚\n寮\n廖\n料\n燎\n療\n瞭\n聊\n蓼\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n遼\n鬧\n龍\n壘\n婁\n屢\n樓\n淚\n漏\n瘻\n累\n縷\n蔞\n褸\n鏤\n陋\n劉\n旒\n柳\n榴\n流\n溜\n瀏\n琉\n瑠\n留\n瘤\n硫\n謬\n類\n六\n戮\n陸\n侖\n倫\n崙\n淪\n綸\n輪\n律\n慄\n栗\n率\n隆\n勒\n肋\n凜\n凌\n楞\n稜\n綾\n菱\n陵\n俚\n利\n厘\n吏\n唎\n履\n悧\n李\n梨\n浬\n犁\n狸\n理\n璃\n異\n痢\n籬\n罹\n羸\n莉\n裏\n裡\n里\n釐\n離\n鯉\n吝\n潾\n燐\n璘\n藺\n躪\n隣\n鱗\n麟\n林\n淋\n琳\n臨\n霖\n砬\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n立\n笠\n粒\n摩\n瑪\n痲\n碼\n磨\n馬\n魔\n麻\n寞\n幕\n漠\n膜\n莫\n邈\n万\n卍\n娩\n巒\n彎\n慢\n挽\n晩\n曼\n滿\n漫\n灣\n瞞\n萬\n蔓\n蠻\n輓\n饅\n鰻\n唜\n抹\n末\n沫\n茉\n襪\n靺\n亡\n妄\n忘\n忙\n望\n網\n罔\n芒\n茫\n莽\n輞\n邙\n埋\n妹\n媒\n寐\n昧\n枚\n梅\n每\n煤\n罵\n買\n賣\n邁\n魅\n脈\n貊\n陌\n驀\n麥\n孟\n氓\n猛\n盲\n盟\n萌\n冪\n覓\n免\n冕\n勉\n棉\n沔\n眄\n眠\n綿\n緬\n面\n麵\n滅\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n蔑\n冥\n名\n命\n明\n暝\n椧\n溟\n皿\n瞑\n茗\n蓂\n螟\n酩\n銘\n鳴\n袂\n侮\n冒\n募\n姆\n帽\n慕\n摸\n摹\n暮\n某\n模\n母\n毛\n牟\n牡\n瑁\n眸\n矛\n耗\n芼\n茅\n謀\n謨\n貌\n木\n沐\n牧\n目\n睦\n穆\n鶩\n歿\n沒\n夢\n朦\n蒙\n卯\n墓\n妙\n廟\n描\n昴\n杳\n渺\n猫\n竗\n苗\n錨\n務\n巫\n憮\n懋\n戊\n拇\n撫\n无\n楙\n武\n毋\n無\n珷\n畝\n繆\n舞\n茂\n蕪\n誣\n貿\n霧\n鵡\n墨\n默\n們\n刎\n吻\n問\n文\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n汶\n紊\n紋\n聞\n蚊\n門\n雯\n勿\n沕\n物\n味\n媚\n尾\n嵋\n彌\n微\n未\n梶\n楣\n渼\n湄\n眉\n米\n美\n薇\n謎\n迷\n靡\n黴\n岷\n悶\n愍\n憫\n敏\n旻\n旼\n民\n泯\n玟\n珉\n緡\n閔\n密\n蜜\n謐\n剝\n博\n拍\n搏\n撲\n朴\n樸\n泊\n珀\n璞\n箔\n粕\n縛\n膊\n舶\n薄\n迫\n雹\n駁\n伴\n半\n反\n叛\n拌\n搬\n攀\n斑\n槃\n泮\n潘\n班\n畔\n瘢\n盤\n盼\n磐\n磻\n礬\n絆\n般\n蟠\n返\n頒\n飯\n勃\n拔\n撥\n渤\n潑\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n發\n跋\n醱\n鉢\n髮\n魃\n倣\n傍\n坊\n妨\n尨\n幇\n彷\n房\n放\n方\n旁\n昉\n枋\n榜\n滂\n磅\n紡\n肪\n膀\n舫\n芳\n蒡\n蚌\n訪\n謗\n邦\n防\n龐\n倍\n俳\n北\n培\n徘\n拜\n排\n杯\n湃\n焙\n盃\n背\n胚\n裴\n裵\n褙\n賠\n輩\n配\n陪\n伯\n佰\n帛\n柏\n栢\n白\n百\n魄\n幡\n樊\n煩\n燔\n番\n磻\n繁\n蕃\n藩\n飜\n伐\n筏\n罰\n閥\n凡\n帆\n梵\n氾\n汎\n泛\n犯\n範\n范\n法\n琺\n僻\n劈\n壁\n擘\n檗\n璧\n癖\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n碧\n蘗\n闢\n霹\n便\n卞\n弁\n變\n辨\n辯\n邊\n別\n瞥\n鱉\n鼈\n丙\n倂\n兵\n屛\n幷\n昞\n昺\n柄\n棅\n炳\n甁\n病\n秉\n竝\n輧\n餠\n騈\n保\n堡\n報\n寶\n普\n步\n洑\n湺\n潽\n珤\n甫\n菩\n補\n褓\n譜\n輔\n伏\n僕\n匐\n卜\n宓\n復\n服\n福\n腹\n茯\n蔔\n複\n覆\n輹\n輻\n馥\n鰒\n本\n乶\n俸\n奉\n封\n峯\n峰\n捧\n棒\n烽\n熢\n琫\n縫\n蓬\n蜂\n逢\n鋒\n鳳\n不\n付\n俯\n傅\n剖\n副\n否\n咐\n埠\n夫\n婦\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n孚\n孵\n富\n府\n復\n扶\n敷\n斧\n浮\n溥\n父\n符\n簿\n缶\n腐\n腑\n膚\n艀\n芙\n莩\n訃\n負\n賦\n賻\n赴\n趺\n部\n釜\n阜\n附\n駙\n鳧\n北\n分\n吩\n噴\n墳\n奔\n奮\n忿\n憤\n扮\n昐\n汾\n焚\n盆\n粉\n糞\n紛\n芬\n賁\n雰\n不\n佛\n弗\n彿\n拂\n崩\n朋\n棚\n硼\n繃\n鵬\n丕\n備\n匕\n匪\n卑\n妃\n婢\n庇\n悲\n憊\n扉\n批\n斐\n枇\n榧\n比\n毖\n毗\n毘\n沸\n泌\n琵\n痺\n砒\n碑\n秕\n秘\n粃\n緋\n翡\n肥\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n脾\n臂\n菲\n蜚\n裨\n誹\n譬\n費\n鄙\n非\n飛\n鼻\n嚬\n嬪\n彬\n斌\n檳\n殯\n浜\n濱\n瀕\n牝\n玭\n貧\n賓\n頻\n憑\n氷\n聘\n騁\n乍\n事\n些\n仕\n伺\n似\n使\n俟\n僿\n史\n司\n唆\n嗣\n四\n士\n奢\n娑\n寫\n寺\n射\n巳\n師\n徙\n思\n捨\n斜\n斯\n柶\n査\n梭\n死\n沙\n泗\n渣\n瀉\n獅\n砂\n社\n祀\n祠\n私\n篩\n紗\n絲\n肆\n舍\n莎\n蓑\n蛇\n裟\n詐\n詞\n謝\n賜\n赦\n辭\n邪\n飼\n駟\n麝\n削\n數\n朔\n索\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n傘\n刪\n山\n散\n汕\n珊\n産\n疝\n算\n蒜\n酸\n霰\n乷\n撒\n殺\n煞\n薩\n三\n參\n杉\n森\n渗\n芟\n蔘\n衫\n揷\n澁\n鈒\n颯\n上\n傷\n像\n償\n商\n喪\n嘗\n孀\n尙\n峠\n常\n床\n庠\n廂\n想\n桑\n橡\n湘\n爽\n牀\n狀\n相\n祥\n箱\n翔\n裳\n觴\n詳\n象\n賞\n霜\n塞\n璽\n賽\n嗇\n塞\n穡\n索\n色\n牲\n生\n甥\n省\n笙\n墅\n壻\n嶼\n序\n庶\n徐\n恕\n抒\n捿\n敍\n暑\n曙\n書\n栖\n棲\n犀\n瑞\n筮\n絮\n緖\n署\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n胥\n舒\n薯\n西\n誓\n逝\n鋤\n黍\n鼠\n夕\n奭\n席\n惜\n昔\n晳\n析\n汐\n淅\n潟\n石\n碩\n蓆\n釋\n錫\n仙\n僊\n先\n善\n嬋\n宣\n扇\n敾\n旋\n渲\n煽\n琁\n瑄\n璇\n璿\n癬\n禪\n線\n繕\n羨\n腺\n膳\n船\n蘚\n蟬\n詵\n跣\n選\n銑\n鐥\n饍\n鮮\n卨\n屑\n楔\n泄\n洩\n渫\n舌\n薛\n褻\n設\n說\n雪\n齧\n剡\n暹\n殲\n纖\n蟾\n贍\n閃\n陝\n攝\n涉\n燮\n葉\n城\n姓\n宬\n性\n惺\n成\n星\n晟\n猩\n珹\n盛\n省\n筬\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n聖\n聲\n腥\n誠\n醒\n世\n勢\n歲\n洗\n稅\n笹\n細\n說\n貰\n召\n嘯\n塑\n宵\n小\n少\n巢\n所\n掃\n搔\n昭\n梳\n沼\n消\n溯\n瀟\n炤\n燒\n甦\n疏\n疎\n瘙\n笑\n篠\n簫\n素\n紹\n蔬\n蕭\n蘇\n訴\n逍\n遡\n邵\n銷\n韶\n騷\n俗\n屬\n束\n涑\n粟\n續\n謖\n贖\n速\n孫\n巽\n損\n蓀\n遜\n飡\n率\n宋\n悚\n松\n淞\n訟\n誦\n送\n頌\n刷\n殺\n灑\n碎\n鎖\n衰\n釗\n修\n受\n嗽\n囚\n垂\n壽\n嫂\n守\n岫\n峀\n帥\n愁\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n戍\n手\n授\n搜\n收\n數\n樹\n殊\n水\n洙\n漱\n燧\n狩\n獸\n琇\n璲\n瘦\n睡\n秀\n穗\n竪\n粹\n綏\n綬\n繡\n羞\n脩\n茱\n蒐\n蓚\n藪\n袖\n誰\n讐\n輸\n遂\n邃\n酬\n銖\n銹\n隋\n隧\n隨\n雖\n需\n須\n首\n髓\n鬚\n叔\n塾\n夙\n孰\n宿\n淑\n潚\n熟\n琡\n璹\n肅\n菽\n巡\n徇\n循\n恂\n旬\n栒\n楯\n橓\n殉\n洵\n淳\n珣\n盾\n瞬\n筍\n純\n脣\n舜\n荀\n蓴\n蕣\n詢\n諄\n醇\n錞\n順\n馴\n戌\n術\n述\n鉥\n崇\n崧\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n嵩\n瑟\n膝\n蝨\n濕\n拾\n習\n褶\n襲\n丞\n乘\n僧\n勝\n升\n承\n昇\n繩\n蠅\n陞\n侍\n匙\n嘶\n始\n媤\n尸\n屎\n屍\n市\n弑\n恃\n施\n是\n時\n枾\n柴\n猜\n矢\n示\n翅\n蒔\n蓍\n視\n試\n詩\n諡\n豕\n豺\n埴\n寔\n式\n息\n拭\n植\n殖\n湜\n熄\n篒\n蝕\n識\n軾\n食\n飾\n伸\n侁\n信\n呻\n娠\n宸\n愼\n新\n晨\n燼\n申\n神\n紳\n腎\n臣\n莘\n薪\n藎\n蜃\n訊\n身\n辛\n辰\n迅\n失\n室\n實\n悉\n審\n尋\n心\n沁\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n沈\n深\n瀋\n甚\n芯\n諶\n什\n十\n拾\n雙\n氏\n亞\n俄\n兒\n啞\n娥\n峨\n我\n牙\n芽\n莪\n蛾\n衙\n訝\n阿\n雅\n餓\n鴉\n鵝\n堊\n岳\n嶽\n幄\n惡\n愕\n握\n樂\n渥\n鄂\n鍔\n顎\n鰐\n齷\n安\n岸\n按\n晏\n案\n眼\n雁\n鞍\n顔\n鮟\n斡\n謁\n軋\n閼\n唵\n岩\n巖\n庵\n暗\n癌\n菴\n闇\n壓\n押\n狎\n鴨\n仰\n央\n怏\n昻\n殃\n秧\n鴦\n厓\n哀\n埃\n崖\n愛\n曖\n涯\n碍\n艾\n隘\n靄\n厄\n扼\n掖\n液\n縊\n腋\n額\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n櫻\n罌\n鶯\n鸚\n也\n倻\n冶\n夜\n惹\n揶\n椰\n爺\n耶\n若\n野\n弱\n掠\n略\n約\n若\n葯\n蒻\n藥\n躍\n亮\n佯\n兩\n凉\n壤\n孃\n恙\n揚\n攘\n敭\n暘\n梁\n楊\n樣\n洋\n瀁\n煬\n痒\n瘍\n禳\n穰\n糧\n羊\n良\n襄\n諒\n讓\n釀\n陽\n量\n養\n圄\n御\n於\n漁\n瘀\n禦\n語\n馭\n魚\n齬\n億\n憶\n抑\n檍\n臆\n偃\n堰\n彦\n焉\n言\n諺\n孼\n蘖\n俺\n儼\n嚴\n奄\n掩\n淹\n嶪\n業\n円\n予\n余\n勵\n呂\n女\n如\n廬\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n旅\n歟\n汝\n濾\n璵\n礖\n礪\n與\n艅\n茹\n輿\n轝\n閭\n餘\n驪\n麗\n黎\n亦\n力\n域\n役\n易\n曆\n歷\n疫\n繹\n譯\n轢\n逆\n驛\n嚥\n堧\n姸\n娟\n宴\n年\n延\n憐\n戀\n捐\n挻\n撚\n椽\n沇\n沿\n涎\n涓\n淵\n演\n漣\n烟\n然\n煙\n煉\n燃\n燕\n璉\n硏\n硯\n秊\n筵\n緣\n練\n縯\n聯\n衍\n軟\n輦\n蓮\n連\n鉛\n鍊\n鳶\n列\n劣\n咽\n悅\n涅\n烈\n熱\n裂\n說\n閱\n厭\n廉\n念\n捻\n染\n殮\n炎\n焰\n琰\n艶\n苒\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n簾\n閻\n髥\n鹽\n曄\n獵\n燁\n葉\n令\n囹\n塋\n寧\n嶺\n嶸\n影\n怜\n映\n暎\n楹\n榮\n永\n泳\n渶\n潁\n濚\n瀛\n瀯\n煐\n營\n獰\n玲\n瑛\n瑩\n瓔\n盈\n穎\n纓\n羚\n聆\n英\n詠\n迎\n鈴\n鍈\n零\n霙\n靈\n領\n乂\n倪\n例\n刈\n叡\n曳\n汭\n濊\n猊\n睿\n穢\n芮\n藝\n蘂\n禮\n裔\n詣\n譽\n豫\n醴\n銳\n隸\n霓\n預\n五\n伍\n俉\n傲\n午\n吾\n吳\n嗚\n塢\n墺\n奧\n娛\n寤\n悟\n惡\n懊\n敖\n旿\n晤\n梧\n汚\n澳\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n烏\n熬\n獒\n筽\n蜈\n誤\n鰲\n鼇\n屋\n沃\n獄\n玉\n鈺\n溫\n瑥\n瘟\n穩\n縕\n蘊\n兀\n壅\n擁\n瓮\n甕\n癰\n翁\n邕\n雍\n饔\n渦\n瓦\n窩\n窪\n臥\n蛙\n蝸\n訛\n婉\n完\n宛\n梡\n椀\n浣\n玩\n琓\n琬\n碗\n緩\n翫\n脘\n腕\n莞\n豌\n阮\n頑\n曰\n往\n旺\n枉\n汪\n王\n倭\n娃\n歪\n矮\n外\n嵬\n巍\n猥\n畏\n了\n僚\n僥\n凹\n堯\n夭\n妖\n姚\n寥\n寮\n尿\n嶢\n拗\n搖\n撓\n擾\n料\n曜\n樂\n橈\n燎\n燿\n瑤\n療\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n窈\n窯\n繇\n繞\n耀\n腰\n蓼\n蟯\n要\n謠\n遙\n遼\n邀\n饒\n慾\n欲\n浴\n縟\n褥\n辱\n俑\n傭\n冗\n勇\n埇\n墉\n容\n庸\n慂\n榕\n涌\n湧\n溶\n熔\n瑢\n用\n甬\n聳\n茸\n蓉\n踊\n鎔\n鏞\n龍\n于\n佑\n偶\n優\n又\n友\n右\n宇\n寓\n尤\n愚\n憂\n旴\n牛\n玗\n瑀\n盂\n祐\n禑\n禹\n紆\n羽\n芋\n藕\n虞\n迂\n遇\n郵\n釪\n隅\n雨\n雩\n勖\n彧\n旭\n昱\n栯\n煜\n稶\n郁\n頊\n云\n暈\n橒\n殞\n澐\n熉\n耘\n芸\n蕓\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n運\n隕\n雲\n韻\n蔚\n鬱\n亐\n熊\n雄\n元\n原\n員\n圓\n園\n垣\n媛\n嫄\n寃\n怨\n愿\n援\n沅\n洹\n湲\n源\n爰\n猿\n瑗\n苑\n袁\n轅\n遠\n阮\n院\n願\n鴛\n月\n越\n鉞\n位\n偉\n僞\n危\n圍\n委\n威\n尉\n慰\n暐\n渭\n爲\n瑋\n緯\n胃\n萎\n葦\n蔿\n蝟\n衛\n褘\n謂\n違\n韋\n魏\n乳\n侑\n儒\n兪\n劉\n唯\n喩\n孺\n宥\n幼\n幽\n庾\n悠\n惟\n愈\n愉\n揄\n攸\n有\n杻\n柔\n柚\n柳\n楡\n楢\n油\n洧\n流\n游\n溜\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n濡\n猶\n猷\n琉\n瑜\n由\n留\n癒\n硫\n紐\n維\n臾\n萸\n裕\n誘\n諛\n諭\n踰\n蹂\n遊\n逾\n遺\n酉\n釉\n鍮\n類\n六\n堉\n戮\n毓\n肉\n育\n陸\n倫\n允\n奫\n尹\n崙\n淪\n潤\n玧\n胤\n贇\n輪\n鈗\n閏\n律\n慄\n栗\n率\n聿\n戎\n瀜\n絨\n融\n隆\n垠\n恩\n慇\n殷\n誾\n銀\n隱\n乙\n吟\n淫\n蔭\n陰\n音\n飮\n揖\n泣\n邑\n凝\n應\n膺\n鷹\n依\n倚\n儀\n宜\n意\n懿\n擬\n椅\n毅\n疑\n矣\n義\n艤\n薏\n蟻\n衣\n誼\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n議\n醫\n二\n以\n伊\n利\n吏\n夷\n姨\n履\n已\n弛\n彛\n怡\n易\n李\n梨\n泥\n爾\n珥\n理\n異\n痍\n痢\n移\n罹\n而\n耳\n肄\n苡\n荑\n裏\n裡\n貽\n貳\n邇\n里\n離\n飴\n餌\n匿\n溺\n瀷\n益\n翊\n翌\n翼\n謚\n人\n仁\n刃\n印\n吝\n咽\n因\n姻\n寅\n引\n忍\n湮\n燐\n璘\n絪\n茵\n藺\n蚓\n認\n隣\n靭\n靷\n鱗\n麟\n一\n佚\n佾\n壹\n日\n溢\n逸\n鎰\n馹\n任\n壬\n妊\n姙\n恁\n林\n淋\n稔\n臨\n荏\n賃\n入\n卄\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n立\n笠\n粒\n仍\n剩\n孕\n芿\n仔\n刺\n咨\n姉\n姿\n子\n字\n孜\n恣\n慈\n滋\n炙\n煮\n玆\n瓷\n疵\n磁\n紫\n者\n自\n茨\n蔗\n藉\n諮\n資\n雌\n作\n勺\n嚼\n斫\n昨\n灼\n炸\n爵\n綽\n芍\n酌\n雀\n鵲\n孱\n棧\n殘\n潺\n盞\n岑\n暫\n潛\n箴\n簪\n蠶\n雜\n丈\n仗\n匠\n場\n墻\n壯\n奬\n將\n帳\n庄\n張\n掌\n暲\n杖\n樟\n檣\n欌\n漿\n牆\n狀\n獐\n璋\n章\n粧\n腸\n臟\n臧\n莊\n葬\n蔣\n薔\n藏\n裝\n贓\n醬\n長\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n障\n再\n哉\n在\n宰\n才\n材\n栽\n梓\n渽\n滓\n災\n縡\n裁\n財\n載\n齋\n齎\n爭\n箏\n諍\n錚\n佇\n低\n儲\n咀\n姐\n底\n抵\n杵\n楮\n樗\n沮\n渚\n狙\n猪\n疽\n箸\n紵\n苧\n菹\n著\n藷\n詛\n貯\n躇\n這\n邸\n雎\n齟\n勣\n吊\n嫡\n寂\n摘\n敵\n滴\n狄\n炙\n的\n積\n笛\n籍\n績\n翟\n荻\n謫\n賊\n赤\n跡\n蹟\n迪\n迹\n適\n鏑\n佃\n佺\n傳\n全\n典\n前\n剪\n塡\n塼\n奠\n專\n展\n廛\n悛\n戰\n栓\n殿\n氈\n澱\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n煎\n琠\n田\n甸\n畑\n癲\n筌\n箋\n箭\n篆\n纏\n詮\n輾\n轉\n鈿\n銓\n錢\n鐫\n電\n顚\n顫\n餞\n切\n截\n折\n浙\n癤\n竊\n節\n絶\n占\n岾\n店\n漸\n点\n粘\n霑\n鮎\n點\n接\n摺\n蝶\n丁\n井\n亭\n停\n偵\n呈\n姃\n定\n幀\n庭\n廷\n征\n情\n挺\n政\n整\n旌\n晶\n晸\n柾\n楨\n檉\n正\n汀\n淀\n淨\n渟\n湞\n瀞\n炡\n玎\n珽\n町\n睛\n碇\n禎\n程\n穽\n精\n綎\n艇\n訂\n諪\n貞\n鄭\n酊\n釘\n鉦\n鋌\n錠\n霆\n靖\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n靜\n頂\n鼎\n制\n劑\n啼\n堤\n帝\n弟\n悌\n提\n梯\n濟\n祭\n第\n臍\n薺\n製\n諸\n蹄\n醍\n除\n際\n霽\n題\n齊\n俎\n兆\n凋\n助\n嘲\n弔\n彫\n措\n操\n早\n晁\n曺\n曹\n朝\n條\n棗\n槽\n漕\n潮\n照\n燥\n爪\n璪\n眺\n祖\n祚\n租\n稠\n窕\n粗\n糟\n組\n繰\n肇\n藻\n蚤\n詔\n調\n趙\n躁\n造\n遭\n釣\n阻\n雕\n鳥\n族\n簇\n足\n鏃\n存\n尊\n卒\n拙\n猝\n倧\n宗\n從\n悰\n慫\n棕\n淙\n琮\n種\n終\n綜\n縱\n腫\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n踪\n踵\n鍾\n鐘\n佐\n坐\n左\n座\n挫\n罪\n主\n住\n侏\n做\n姝\n胄\n呪\n周\n嗾\n奏\n宙\n州\n廚\n晝\n朱\n柱\n株\n注\n洲\n湊\n澍\n炷\n珠\n疇\n籌\n紂\n紬\n綢\n舟\n蛛\n註\n誅\n走\n躊\n輳\n週\n酎\n酒\n鑄\n駐\n竹\n粥\n俊\n儁\n准\n埈\n寯\n峻\n晙\n樽\n浚\n準\n濬\n焌\n畯\n竣\n蠢\n逡\n遵\n雋\n駿\n茁\n中\n仲\n衆\n重\n卽\n櫛\n楫\n汁\n葺\n增\n憎\n曾\n拯\n烝\n甑\n症\n繒\n蒸\n證\n贈\n之\n只\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n咫\n地\n址\n志\n持\n指\n摯\n支\n旨\n智\n枝\n枳\n止\n池\n沚\n漬\n知\n砥\n祉\n祗\n紙\n肢\n脂\n至\n芝\n芷\n蜘\n誌\n識\n贄\n趾\n遲\n直\n稙\n稷\n織\n職\n唇\n嗔\n塵\n振\n搢\n晉\n晋\n桭\n榛\n殄\n津\n溱\n珍\n瑨\n璡\n畛\n疹\n盡\n眞\n瞋\n秦\n縉\n縝\n臻\n蔯\n袗\n診\n賑\n軫\n辰\n進\n鎭\n陣\n陳\n震\n侄\n叱\n姪\n嫉\n帙\n桎\n瓆\n疾\n秩\n窒\n膣\n蛭\n質\n跌\n迭\n斟\n朕\n什\n執\n潗\n緝\n輯\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n鏶\n集\n徵\n懲\n澄\n且\n侘\n借\n叉\n嗟\n嵯\n差\n次\n此\n磋\n箚\n茶\n蹉\n車\n遮\n捉\n搾\n着\n窄\n錯\n鑿\n齪\n撰\n澯\n燦\n璨\n瓚\n竄\n簒\n纂\n粲\n纘\n讚\n贊\n鑽\n餐\n饌\n刹\n察\n擦\n札\n紮\n僭\n參\n塹\n慘\n慙\n懺\n斬\n站\n讒\n讖\n倉\n倡\n創\n唱\n娼\n廠\n彰\n愴\n敞\n昌\n昶\n暢\n槍\n滄\n漲\n猖\n瘡\n窓\n脹\n艙\n菖\n蒼\n債\n埰\n寀\n寨\n彩\n採\n砦\n綵\n菜\n蔡\n采\n釵\n冊\n柵\n策\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n責\n凄\n妻\n悽\n處\n倜\n刺\n剔\n尺\n慽\n戚\n拓\n擲\n斥\n滌\n瘠\n脊\n蹠\n陟\n隻\n仟\n千\n喘\n天\n川\n擅\n泉\n淺\n玔\n穿\n舛\n薦\n賤\n踐\n遷\n釧\n闡\n阡\n韆\n凸\n哲\n喆\n徹\n撤\n澈\n綴\n輟\n轍\n鐵\n僉\n尖\n沾\n添\n甛\n瞻\n簽\n籤\n詹\n諂\n堞\n妾\n帖\n捷\n牒\n疊\n睫\n諜\n貼\n輒\n廳\n晴\n淸\n聽\n菁\n請\n靑\n鯖\n切\n剃\n替\n涕\n滯\n締\n諦\n逮\n遞\n體\n初\n剿\n哨\n憔\n抄\n招\n梢\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n椒\n楚\n樵\n炒\n焦\n硝\n礁\n礎\n秒\n稍\n肖\n艸\n苕\n草\n蕉\n貂\n超\n酢\n醋\n醮\n促\n囑\n燭\n矗\n蜀\n觸\n寸\n忖\n村\n邨\n叢\n塚\n寵\n悤\n憁\n摠\n總\n聰\n蔥\n銃\n撮\n催\n崔\n最\n墜\n抽\n推\n椎\n楸\n樞\n湫\n皺\n秋\n芻\n萩\n諏\n趨\n追\n鄒\n酋\n醜\n錐\n錘\n鎚\n雛\n騶\n鰍\n丑\n畜\n祝\n竺\n筑\n築\n縮\n蓄\n蹙\n蹴\n軸\n逐\n春\n椿\n瑃\n出\n朮\n黜\n充\n忠\n沖\n蟲\n衝\n衷\n悴\n膵\n萃\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n贅\n取\n吹\n嘴\n娶\n就\n炊\n翠\n聚\n脆\n臭\n趣\n醉\n驟\n鷲\n側\n仄\n厠\n惻\n測\n層\n侈\n値\n嗤\n峙\n幟\n恥\n梔\n治\n淄\n熾\n痔\n痴\n癡\n稚\n穉\n緇\n緻\n置\n致\n蚩\n輜\n雉\n馳\n齒\n則\n勅\n飭\n親\n七\n柒\n漆\n侵\n寢\n枕\n沈\n浸\n琛\n砧\n針\n鍼\n蟄\n秤\n稱\n快\n他\n咤\n唾\n墮\n妥\n惰\n打\n拖\n朶\n楕\n舵\n陀\n馱\n駝\n倬\n卓\n啄\n坼\n度\n托\n拓\n擢\n晫\n柝\n濁\n濯\n琢\n琸\n託\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n鐸\n呑\n嘆\n坦\n彈\n憚\n歎\n灘\n炭\n綻\n誕\n奪\n脫\n探\n眈\n耽\n貪\n塔\n搭\n榻\n宕\n帑\n湯\n糖\n蕩\n兌\n台\n太\n怠\n態\n殆\n汰\n泰\n笞\n胎\n苔\n跆\n邰\n颱\n宅\n擇\n澤\n撑\n攄\n兎\n吐\n土\n討\n慟\n桶\n洞\n痛\n筒\n統\n通\n堆\n槌\n腿\n褪\n退\n頹\n偸\n套\n妬\n投\n透\n鬪\n慝\n特\n闖\n坡\n婆\n巴\n把\n播\n擺\n杷\n波\n派\n爬\n琶\n破\n罷\n芭\n跛\n頗\n判\n坂\n板\n版\n瓣\n販\n辦\n鈑\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n阪\n八\n叭\n捌\n佩\n唄\n悖\n敗\n沛\n浿\n牌\n狽\n稗\n覇\n貝\n彭\n澎\n烹\n膨\n愎\n便\n偏\n扁\n片\n篇\n編\n翩\n遍\n鞭\n騙\n貶\n坪\n平\n枰\n萍\n評\n吠\n嬖\n幣\n廢\n弊\n斃\n肺\n蔽\n閉\n陛\n佈\n包\n匍\n匏\n咆\n哺\n圃\n布\n怖\n抛\n抱\n捕\n暴\n泡\n浦\n疱\n砲\n胞\n脯\n苞\n葡\n蒲\n袍\n褒\n逋\n鋪\n飽\n鮑\n幅\n暴\n曝\n瀑\n爆\n輻\n俵\n剽\n彪\n慓\n杓\n標\n漂\n瓢\n票\n表\n豹\n飇\n飄\n驃\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n品\n稟\n楓\n諷\n豊\n風\n馮\n彼\n披\n疲\n皮\n被\n避\n陂\n匹\n弼\n必\n泌\n珌\n畢\n疋\n筆\n苾\n馝\n乏\n逼\n下\n何\n厦\n夏\n廈\n昰\n河\n瑕\n荷\n蝦\n賀\n遐\n霞\n鰕\n壑\n學\n虐\n謔\n鶴\n寒\n恨\n悍\n旱\n汗\n漢\n澣\n瀚\n罕\n翰\n閑\n閒\n限\n韓\n割\n轄\n函\n含\n咸\n啣\n喊\n檻\n涵\n緘\n艦\n銜\n陷\n鹹\n合\n哈\n盒\n蛤\n閤\n闔\n陜\n亢\n伉\n姮\n嫦\n巷\n恒\n抗\n杭\n桁\n沆\n港\n缸\n肛\n航\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n行\n降\n項\n亥\n偕\n咳\n垓\n奚\n孩\n害\n懈\n楷\n海\n瀣\n蟹\n解\n該\n諧\n邂\n駭\n骸\n劾\n核\n倖\n幸\n杏\n荇\n行\n享\n向\n嚮\n珦\n鄕\n響\n餉\n饗\n香\n噓\n墟\n虛\n許\n憲\n櫶\n獻\n軒\n歇\n險\n驗\n奕\n爀\n赫\n革\n俔\n峴\n弦\n懸\n晛\n泫\n炫\n玄\n玹\n現\n眩\n睍\n絃\n絢\n縣\n舷\n衒\n見\n賢\n鉉\n顯\n孑\n穴\n血\n頁\n嫌\n俠\n協\n夾\n峽\n挾\n浹\n狹\n脅\n脇\n莢\n鋏\n頰\n亨\n兄\n刑\n型\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n形\n泂\n滎\n瀅\n灐\n炯\n熒\n珩\n瑩\n荊\n螢\n衡\n逈\n邢\n鎣\n馨\n兮\n彗\n惠\n慧\n暳\n蕙\n蹊\n醯\n鞋\n乎\n互\n呼\n壕\n壺\n好\n岵\n弧\n戶\n扈\n昊\n晧\n毫\n浩\n淏\n湖\n滸\n澔\n濠\n濩\n灝\n狐\n琥\n瑚\n瓠\n皓\n祜\n糊\n縞\n胡\n芦\n葫\n蒿\n虎\n號\n蝴\n護\n豪\n鎬\n頀\n顥\n惑\n或\n酷\n婚\n昏\n混\n渾\n琿\n魂\n忽\n惚\n笏\n哄\n弘\n汞\n泓\n洪\n烘\n紅\n虹\n訌\n鴻\n化\n和\n嬅\n樺\n火\n畵\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n禍\n禾\n花\n華\n話\n譁\n貨\n靴\n廓\n擴\n攫\n確\n碻\n穫\n丸\n喚\n奐\n宦\n幻\n患\n換\n歡\n晥\n桓\n渙\n煥\n環\n紈\n還\n驩\n鰥\n活\n滑\n猾\n豁\n闊\n凰\n幌\n徨\n恍\n惶\n愰\n慌\n晃\n晄\n榥\n況\n湟\n滉\n潢\n煌\n璜\n皇\n篁\n簧\n荒\n蝗\n遑\n隍\n黃\n匯\n回\n廻\n徊\n恢\n悔\n懷\n晦\n會\n檜\n淮\n澮\n灰\n獪\n繪\n膾\n茴\n蛔\n誨\n賄\n劃\n獲\n宖\n橫\n鐄\n哮\n嚆\n孝\n效\n斅\n曉\n梟\n涍\n淆\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n爻\n肴\n酵\n驍\n侯\n候\n厚\n后\n吼\n喉\n嗅\n帿\n後\n朽\n煦\n珝\n逅\n勛\n勳\n塤\n壎\n焄\n熏\n燻\n薰\n訓\n暈\n薨\n喧\n暄\n煊\n萱\n卉\n喙\n毁\n彙\n徽\n揮\n暉\n煇\n諱\n輝\n麾\n休\n携\n烋\n畦\n虧\n恤\n譎\n鷸\n兇\n凶\n匈\n洶\n胸\n黑\n昕\n欣\n炘\n痕\n吃\n屹\n紇\n訖\n欠\n欽\n歆\n吸\n恰\n洽\n翕\n興\n僖\n凞\n喜\n噫\n囍\n姬\n嬉\n希\n憙\n憘\n戱\n晞\n曦\n熙\n熹\n熺\n犧\n禧\n稀\n羲\n詰\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n"
  },
  {
    "path": "helix-view/tests/encoding/euc_kr_out.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n갂\n갃\n갅\n갆\n갋\n갌\n갍\n갎\n갏\n갘\n갞\n갟\n갡\n갢\n갣\n갥\n갦\n갧\n갨\n갩\n갪\n갫\n갮\n갲\n갳\n갴\n갵\n갶\n갷\n갺\n갻\n갽\n갾\n갿\n걁\n걂\n걃\n걄\n걅\n걆\n걇\n걈\n걉\n걊\n걌\n걎\n걏\n걐\n걑\n걒\n걓\n걕\n걖\n걗\n걙\n걚\n걛\n걝\n걞\n걟\n걠\n걡\n걢\n걣\n걤\n걥\n걦\n걧\n걨\n걩\n걪\n걫\n걬\n걭\n걮\n걯\n걲\n걳\n걵\n걶\n걹\n걻\n걼\n걽\n걾\n걿\n겂\n겇\n겈\n겍\n겎\n겏\n겑\n겒\n겓\n겕\n겖\n겗\n겘\n겙\n겚\n겛\n겞\n겢\n겣\n겤\n겥\n겦\n겧\n겫\n겭\n겮\n겱\n겲\n겳\n겴\n겵\n겶\n겷\n겺\n겾\n겿\n곀\n곂\n곃\n곅\n곆\n곇\n곉\n곊\n곋\n곍\n곎\n곏\n곐\n곑\n곒\n곓\n곔\n곖\n곘\n곙\n곚\n곛\n곜\n곝\n곞\n곟\n곢\n곣\n곥\n곦\n곩\n곫\n곭\n곮\n곲\n곴\n곷\n곸\n곹\n곺\n곻\n곾\n곿\n괁\n괂\n괃\n괅\n괇\n괈\n괉\n괊\n괋\n괎\n괐\n괒\n괓\n괔\n괕\n괖\n괗\n괙\n괚\n괛\n괝\n괞\n괟\n괡\n괢\n괣\n괤\n괥\n괦\n괧\n괨\n괪\n괫\n괮\n괯\n괰\n괱\n괲\n괳\n괶\n괷\n괹\n괺\n괻\n괽\n괾\n괿\n굀\n굁\n굂\n굃\n굆\n굈\n굊\n굋\n굌\n굍\n굎\n굏\n굑\n굒\n굓\n굕\n굖\n굗\n굙\n굚\n굛\n굜\n굝\n굞\n굟\n굠\n굢\n굤\n굥\n굦\n굧\n굨\n굩\n굪\n굫\n굮\n굯\n굱\n굲\n굷\n굸\n굹\n굺\n굾\n궀\n궃\n궄\n궅\n궆\n궇\n궊\n궋\n궍\n궎\n궏\n궑\n궒\n궓\n궔\n궕\n궖\n궗\n궘\n궙\n궚\n궛\n궞\n궟\n궠\n궡\n궢\n궣\n궥\n궦\n궧\n궨\n궩\n궪\n궫\n궬\n궭\n궮\n궯\n궰\n궱\n궲\n궳\n궴\n궵\n궶\n궸\n궹\n궺\n궻\n궼\n궽\n궾\n궿\n귂\n귃\n귅\n귆\n귇\n귉\n귊\n귋\n귌\n귍\n귎\n귏\n귒\n귔\n귕\n귖\n귗\n귘\n귙\n귚\n귛\n귝\n귞\n귟\n귡\n귢\n귣\n귥\n귦\n귧\n귨\n귩\n귪\n귫\n귬\n귭\n귮\n귯\n귰\n귱\n귲\n귳\n귴\n귵\n귶\n귷\n귺\n귻\n귽\n귾\n긂\n긃\n긄\n긅\n긆\n긇\n긊\n긌\n긎\n긏\n긐\n긑\n긒\n긓\n긕\n긖\n긗\n긘\n긙\n긚\n긛\n긜\n긝\n긞\n긟\n긠\n긡\n긢\n긣\n긤\n긥\n긦\n긧\n긨\n긩\n긪\n긫\n긬\n긭\n긮\n긯\n긲\n긳\n긵\n긶\n긹\n긻\n긼\n긽\n긾\n긿\n깂\n깄\n깇\n깈\n깉\n깋\n깏\n깑\n깒\n깓\n깕\n깗\n깘\n깙\n깚\n깛\n깞\n깢\n깣\n깤\n깦\n깧\n깪\n깫\n깭\n깮\n깯\n깱\n깲\n깳\n깴\n깵\n깶\n깷\n깺\n깾\n깿\n꺀\n꺁\n꺂\n꺃\n꺆\n꺇\n꺈\n꺉\n꺊\n꺋\n꺍\n꺎\n꺏\n꺐\n꺑\n꺒\n꺓\n꺔\n꺕\n꺖\n꺗\n꺘\n꺙\n꺚\n꺛\n꺜\n꺝\n꺞\n꺟\n꺠\n꺡\n꺢\n꺣\n꺤\n꺥\n꺦\n꺧\n꺨\n꺩\n꺪\n꺫\n꺬\n꺭\n꺮\n꺯\n꺰\n꺱\n꺲\n꺳\n꺴\n꺵\n꺶\n꺷\n꺸\n꺹\n꺺\n꺻\n꺿\n껁\n껂\n껃\n껅\n껆\n껇\n껈\n껉\n껊\n껋\n껎\n껒\n껓\n껔\n껕\n껖\n껗\n껚\n껛\n껝\n껞\n껟\n껠\n껡\n껢\n껣\n껤\n껥\n껦\n껧\n껩\n껪\n껬\n껮\n껯\n껰\n껱\n껲\n껳\n껵\n껶\n껷\n껹\n껺\n껻\n껽\n껾\n껿\n꼀\n꼁\n꼂\n꼃\n꼄\n꼅\n꼆\n꼉\n꼊\n꼋\n꼌\n꼎\n꼏\n꼑\n꼒\n꼓\n꼔\n꼕\n꼖\n꼗\n꼘\n꼙\n꼚\n꼛\n꼜\n꼝\n꼞\n꼟\n꼠\n꼡\n꼢\n꼣\n꼤\n꼥\n꼦\n꼧\n꼨\n꼩\n꼪\n꼫\n꼮\n꼯\n꼱\n꼳\n꼵\n꼶\n꼷\n꼸\n꼹\n꼺\n꼻\n꼾\n꽀\n꽄\n꽅\n꽆\n꽇\n꽊\n꽋\n꽌\n꽍\n꽎\n꽏\n꽑\n꽒\n꽓\n꽔\n꽕\n꽖\n꽗\n꽘\n꽙\n꽚\n꽛\n꽞\n꽟\n꽠\n꽡\n꽢\n꽣\n꽦\n꽧\n꽨\n꽩\n꽪\n꽫\n꽬\n꽭\n꽮\n꽯\n꽰\n꽱\n꽲\n꽳\n꽴\n꽵\n꽶\n꽷\n꽸\n꽺\n꽻\n꽼\n꽽\n꽾\n꽿\n꾁\n꾂\n꾃\n꾅\n꾆\n꾇\n꾉\n꾊\n꾋\n꾌\n꾍\n꾎\n꾏\n꾒\n꾓\n꾔\n꾖\n꾗\n꾘\n꾙\n꾚\n꾛\n꾝\n꾞\n꾟\n꾠\n꾡\n꾢\n꾣\n꾤\n꾥\n꾦\n꾧\n꾨\n꾩\n꾪\n꾫\n꾬\n꾭\n꾮\n꾯\n꾰\n꾱\n꾲\n꾳\n꾴\n꾵\n꾶\n꾷\n꾺\n꾻\n꾽\n꾾\n꾿\n꿁\n꿂\n꿃\n꿄\n꿅\n꿆\n꿊\n꿌\n꿏\n꿐\n꿑\n꿒\n꿓\n꿕\n꿖\n꿗\n꿘\n꿙\n꿚\n꿛\n꿝\n꿞\n꿟\n꿠\n꿡\n꿢\n꿣\n꿤\n꿥\n꿦\n꿧\n꿪\n꿫\n꿬\n꿭\n꿮\n꿯\n꿲\n꿳\n꿵\n꿶\n꿷\n꿹\n꿺\n꿻\n꿼\n꿽\n꿾\n꿿\n뀂\n뀃\n뀅\n뀆\n뀇\n뀈\n뀉\n뀊\n뀋\n뀍\n뀎\n뀏\n뀑\n뀒\n뀓\n뀕\n뀖\n뀗\n뀘\n뀙\n뀚\n뀛\n뀞\n뀟\n뀠\n뀡\n뀢\n뀣\n뀤\n뀥\n뀦\n뀧\n뀩\n뀪\n뀫\n뀬\n뀭\n뀮\n뀯\n뀰\n뀱\n뀲\n뀳\n뀴\n뀵\n뀶\n뀷\n뀸\n뀹\n뀺\n뀻\n뀼\n뀽\n뀾\n뀿\n끀\n끁\n끂\n끃\n끆\n끇\n끉\n끋\n끍\n끏\n끐\n끑\n끒\n끖\n끘\n끚\n끛\n끜\n끞\n끟\n끠\n끡\n끢\n끣\n끤\n끥\n끦\n끧\n끨\n끩\n끪\n끫\n끬\n끭\n끮\n끯\n끰\n끱\n끲\n끳\n끴\n끵\n끶\n끷\n끸\n끹\n끺\n끻\n끾\n끿\n낁\n낂\n낃\n낅\n낆\n낇\n낈\n낉\n낊\n낋\n낎\n낐\n낒\n낓\n낔\n낕\n낖\n낗\n낛\n낝\n낞\n낣\n낤\n낥\n낦\n낧\n낪\n낰\n낲\n낶\n낷\n낹\n낺\n낻\n낽\n낾\n낿\n냀\n냁\n냂\n냃\n냆\n냊\n냋\n냌\n냍\n냎\n냏\n냒\n냓\n냕\n냖\n냗\n냙\n냚\n냛\n냜\n냝\n냞\n냟\n냡\n냢\n냣\n냤\n냦\n냧\n냨\n냩\n냪\n냫\n냬\n냭\n냮\n냯\n냰\n냱\n냲\n냳\n냴\n냵\n냶\n냷\n냸\n냹\n냺\n냻\n냼\n냽\n냾\n냿\n넀\n넁\n넂\n넃\n넄\n넅\n넆\n넇\n넊\n넍\n넎\n넏\n넑\n넔\n넕\n넖\n넗\n넚\n넞\n넟\n넠\n넡\n넢\n넦\n넧\n넩\n넪\n넫\n넭\n넮\n넯\n넰\n넱\n넲\n넳\n넶\n넺\n넻\n넼\n넽\n넾\n넿\n녂\n녃\n녅\n녆\n녇\n녉\n녊\n녋\n녌\n녍\n녎\n녏\n녒\n녓\n녖\n녗\n녙\n녚\n녛\n녝\n녞\n녟\n녡\n녢\n녣\n녤\n녥\n녦\n녧\n녨\n녩\n녪\n녫\n녬\n녭\n녮\n녯\n녰\n녱\n녲\n녳\n녴\n녵\n녶\n녷\n녺\n녻\n녽\n녾\n녿\n놁\n놃\n놄\n놅\n놆\n놇\n놊\n놌\n놎\n놏\n놐\n놑\n놕\n놖\n놗\n놙\n놚\n놛\n놝\n놞\n놟\n놠\n놡\n놢\n놣\n놤\n놥\n놦\n놧\n놩\n놪\n놫\n놬\n놭\n놮\n놯\n놰\n놱\n놲\n놳\n놴\n놵\n놶\n놷\n놸\n놹\n놺\n놻\n놼\n놽\n놾\n놿\n뇀\n뇁\n뇂\n뇃\n뇄\n뇅\n뇆\n뇇\n뇈\n뇉\n뇊\n뇋\n뇍\n뇎\n뇏\n뇑\n뇒\n뇓\n뇕\n뇖\n뇗\n뇘\n뇙\n뇚\n뇛\n뇞\n뇠\n뇡\n뇢\n뇣\n뇤\n뇥\n뇦\n뇧\n뇪\n뇫\n뇭\n뇮\n뇯\n뇱\n뇲\n뇳\n뇴\n뇵\n뇶\n뇷\n뇸\n뇺\n뇼\n뇾\n뇿\n눀\n눁\n눂\n눃\n눆\n눇\n눉\n눊\n눍\n눎\n눏\n눐\n눑\n눒\n눓\n눖\n눘\n눚\n눛\n눜\n눝\n눞\n눟\n눡\n눢\n눣\n눤\n눥\n눦\n눧\n눨\n눩\n눪\n눫\n눬\n눭\n눮\n눯\n눰\n눱\n눲\n눳\n눵\n눶\n눷\n눸\n눹\n눺\n눻\n눽\n눾\n눿\n뉀\n뉁\n뉂\n뉃\n뉄\n뉅\n뉆\n뉇\n뉈\n뉉\n뉊\n뉋\n뉌\n뉍\n뉎\n뉏\n뉐\n뉑\n뉒\n뉓\n뉔\n뉕\n뉖\n뉗\n뉙\n뉚\n뉛\n뉝\n뉞\n뉟\n뉡\n뉢\n뉣\n뉤\n뉥\n뉦\n뉧\n뉪\n뉫\n뉬\n뉭\n뉮\n뉯\n뉰\n뉱\n뉲\n뉳\n뉶\n뉷\n뉸\n뉹\n뉺\n뉻\n뉽\n뉾\n뉿\n늀\n늁\n늂\n늃\n늆\n늇\n늈\n늊\n늋\n늌\n늍\n늎\n늏\n늒\n늓\n늕\n늖\n늗\n늛\n늜\n늝\n늞\n늟\n늢\n늤\n늧\n늨\n늩\n늫\n늭\n늮\n늯\n늱\n늲\n늳\n늵\n늶\n늷\n늸\n늹\n늺\n늻\n늼\n늽\n늾\n늿\n닀\n닁\n닂\n닃\n닄\n닅\n닆\n닇\n닊\n닋\n닍\n닎\n닏\n닑\n닓\n닔\n닕\n닖\n닗\n닚\n닜\n닞\n닟\n닠\n닡\n닣\n닧\n닩\n닪\n닰\n닱\n닲\n닶\n닼\n닽\n닾\n댂\n댃\n댅\n댆\n댇\n댉\n댊\n댋\n댌\n댍\n댎\n댏\n댒\n댖\n댗\n댘\n댙\n댚\n댛\n댝\n댞\n댟\n댠\n댡\n댢\n댣\n댤\n댥\n댦\n댧\n댨\n댩\n댪\n댫\n댬\n댭\n댮\n댯\n댰\n댱\n댲\n댳\n댴\n댵\n댶\n댷\n댸\n댹\n댺\n댻\n댼\n댽\n댾\n댿\n덀\n덁\n덂\n덃\n덄\n덅\n덆\n덇\n덈\n덉\n덊\n덋\n덌\n덍\n덎\n덏\n덐\n덑\n덒\n덓\n덗\n덙\n덚\n덝\n덠\n덡\n덢\n덣\n덦\n덨\n덪\n덬\n덭\n덯\n덲\n덳\n덵\n덶\n덷\n덹\n덺\n덻\n덼\n덽\n덾\n덿\n뎂\n뎆\n뎇\n뎈\n뎉\n뎊\n뎋\n뎍\n뎎\n뎏\n뎑\n뎒\n뎓\n뎕\n뎖\n뎗\n뎘\n뎙\n뎚\n뎛\n뎜\n뎝\n뎞\n뎟\n뎢\n뎣\n뎤\n뎥\n뎦\n뎧\n뎩\n뎪\n뎫\n뎭\n뎮\n뎯\n뎰\n뎱\n뎲\n뎳\n뎴\n뎵\n뎶\n뎷\n뎸\n뎹\n뎺\n뎻\n뎼\n뎽\n뎾\n뎿\n돀\n돁\n돂\n돃\n돆\n돇\n돉\n돊\n돍\n돏\n돑\n돒\n돓\n돖\n돘\n돚\n돜\n돞\n돟\n돡\n돢\n돣\n돥\n돦\n돧\n돩\n돪\n돫\n돬\n돭\n돮\n돯\n돰\n돱\n돲\n돳\n돴\n돵\n돶\n돷\n돸\n돹\n돺\n돻\n돽\n돾\n돿\n됀\n됁\n됂\n됃\n됄\n됅\n됆\n됇\n됈\n됉\n됊\n됋\n됌\n됍\n됎\n됏\n됑\n됒\n됓\n됔\n됕\n됖\n됗\n됙\n됚\n됛\n됝\n됞\n됟\n됡\n됢\n됣\n됤\n됥\n됦\n됧\n됪\n됬\n됭\n됮\n됯\n됰\n됱\n됲\n됳\n됵\n됶\n됷\n됸\n됹\n됺\n됻\n됼\n됽\n됾\n됿\n둀\n둁\n둂\n둃\n둄\n둅\n둆\n둇\n둈\n둉\n둊\n둋\n둌\n둍\n둎\n둏\n둒\n둓\n둕\n둖\n둗\n둙\n둚\n둛\n둜\n둝\n둞\n둟\n둢\n둤\n둦\n둧\n둨\n둩\n둪\n둫\n둭\n둮\n둯\n둰\n둱\n둲\n둳\n둴\n둵\n둶\n둷\n둸\n둹\n둺\n둻\n둼\n둽\n둾\n둿\n뒁\n뒂\n뒃\n뒄\n뒅\n뒆\n뒇\n뒉\n뒊\n뒋\n뒌\n뒍\n뒎\n뒏\n뒐\n뒑\n뒒\n뒓\n뒔\n뒕\n뒖\n뒗\n뒘\n뒙\n뒚\n뒛\n뒜\n뒞\n뒟\n뒠\n뒡\n뒢\n뒣\n뒥\n뒦\n뒧\n뒩\n뒪\n뒫\n뒭\n뒮\n뒯\n뒰\n뒱\n뒲\n뒳\n뒴\n뒶\n뒸\n뒺\n뒻\n뒼\n뒽\n뒾\n뒿\n듁\n듂\n듃\n듅\n듆\n듇\n듉\n듊\n듋\n듌\n듍\n듎\n듏\n듑\n듒\n듓\n듔\n듖\n듗\n듘\n듙\n듚\n듛\n듞\n듟\n듡\n듢\n듥\n듧\n듨\n듩\n듪\n듫\n듮\n듰\n듲\n듳\n듴\n듵\n듶\n듷\n듹\n듺\n듻\n듼\n듽\n듾\n듿\n딀\n딁\n딂\n딃\n딄\n딅\n딆\n딇\n딈\n딉\n딊\n딋\n딌\n딍\n딎\n딏\n딐\n딑\n딒\n딓\n딖\n딗\n딙\n딚\n딝\n딞\n딟\n딠\n딡\n딢\n딣\n딦\n딫\n딬\n딭\n딮\n딯\n딲\n딳\n딵\n딶\n딷\n딹\n딺\n딻\n딼\n딽\n딾\n딿\n땂\n땆\n땇\n땈\n땉\n땊\n땎\n땏\n땑\n땒\n땓\n땕\n땖\n땗\n땘\n땙\n땚\n땛\n땞\n땢\n땣\n땤\n땥\n땦\n땧\n땨\n땩\n땪\n땫\n땬\n땭\n땮\n땯\n땰\n땱\n땲\n땳\n땴\n땵\n땶\n땷\n땸\n땹\n땺\n땻\n땼\n땽\n땾\n땿\n떀\n떁\n떂\n떃\n떄\n떅\n떆\n떇\n떈\n떉\n떊\n떋\n떌\n떍\n떎\n떏\n떐\n떑\n떒\n떓\n떔\n떕\n떖\n떗\n떘\n떙\n떚\n떛\n떜\n떝\n떞\n떟\n떢\n떣\n떥\n떦\n떧\n떩\n떬\n떭\n떮\n떯\n떲\n떶\n떷\n떸\n떹\n떺\n떾\n떿\n뗁\n뗂\n뗃\n뗅\n뗆\n뗇\n뗈\n뗉\n뗊\n뗋\n뗎\n뗒\n뗓\n뗔\n뗕\n뗖\n뗗\n뗙\n뗚\n뗛\n뗜\n뗝\n뗞\n뗟\n뗠\n뗡\n뗢\n뗣\n뗤\n뗥\n뗦\n뗧\n뗨\n뗩\n뗪\n뗫\n뗭\n뗮\n뗯\n뗰\n뗱\n뗲\n뗳\n뗴\n뗵\n뗶\n뗷\n뗸\n뗹\n뗺\n뗻\n뗼\n뗽\n뗾\n뗿\n똀\n똁\n똂\n똃\n똄\n똅\n똆\n똇\n똈\n똉\n똊\n똋\n똌\n똍\n똎\n똏\n똒\n똓\n똕\n똖\n똗\n똙\n똚\n똛\n똜\n똝\n똞\n똟\n똠\n똡\n똢\n똣\n똤\n똦\n똧\n똨\n똩\n똪\n똫\n똭\n똮\n똯\n똰\n똱\n똲\n똳\n똵\n똶\n똷\n똸\n똹\n똺\n똻\n똼\n똽\n똾\n똿\n뙀\n뙁\n뙂\n뙃\n뙄\n뙅\n뙆\n뙇\n뙉\n뙊\n뙋\n뙌\n뙍\n뙎\n뙏\n뙐\n뙑\n뙒\n뙓\n뙔\n뙕\n뙖\n뙗\n뙘\n뙙\n뙚\n뙛\n뙜\n뙝\n뙞\n뙟\n뙠\n뙡\n뙢\n뙣\n뙥\n뙦\n뙧\n뙩\n뙪\n뙫\n뙬\n뙭\n뙮\n뙯\n뙰\n뙱\n뙲\n뙳\n뙴\n뙵\n뙶\n뙷\n뙸\n뙹\n뙺\n뙻\n뙼\n뙽\n뙾\n뙿\n뚀\n뚁\n뚂\n뚃\n뚄\n뚅\n뚆\n뚇\n뚈\n뚉\n뚊\n뚋\n뚌\n뚍\n뚎\n뚏\n뚐\n뚑\n뚒\n뚓\n뚔\n뚕\n뚖\n뚗\n뚘\n뚙\n뚚\n뚛\n뚞\n뚟\n뚡\n뚢\n뚣\n뚥\n뚦\n뚧\n뚨\n뚩\n뚪\n뚭\n뚮\n뚯\n뚰\n뚲\n뚳\n뚴\n뚵\n뚶\n뚷\n뚸\n뚹\n뚺\n뚻\n뚼\n뚽\n뚾\n뚿\n뛀\n뛁\n뛂\n뛃\n뛄\n뛅\n뛆\n뛇\n뛈\n뛉\n뛊\n뛋\n뛌\n뛍\n뛎\n뛏\n뛐\n뛑\n뛒\n뛓\n뛕\n뛖\n뛗\n뛘\n뛙\n뛚\n뛛\n뛜\n뛝\n뛞\n뛟\n뛠\n뛡\n뛢\n뛣\n뛤\n뛥\n뛦\n뛧\n뛨\n뛩\n뛪\n뛫\n뛬\n뛭\n뛮\n뛯\n뛱\n뛲\n뛳\n뛵\n뛶\n뛷\n뛹\n뛺\n뛻\n뛼\n뛽\n뛾\n뛿\n뜂\n뜃\n뜄\n뜆\n뜇\n뜈\n뜉\n뜊\n뜋\n뜌\n뜍\n뜎\n뜏\n뜐\n뜑\n뜒\n뜓\n뜔\n뜕\n뜖\n뜗\n뜘\n뜙\n뜚\n뜛\n뜜\n뜝\n뜞\n뜟\n뜠\n뜡\n뜢\n뜣\n뜤\n뜥\n뜦\n뜧\n뜪\n뜫\n뜭\n뜮\n뜱\n뜲\n뜳\n뜴\n뜵\n뜶\n뜷\n뜺\n뜼\n뜽\n뜾\n뜿\n띀\n띁\n띂\n띃\n띅\n띆\n띇\n띉\n띊\n띋\n띍\n띎\n띏\n띐\n띑\n띒\n띓\n띖\n띗\n띘\n띙\n띚\n띛\n띜\n띝\n띞\n띟\n띡\n띢\n띣\n띥\n띦\n띧\n띩\n띪\n띫\n띬\n띭\n띮\n띯\n띲\n띴\n띶\n띷\n띸\n띹\n띺\n띻\n띾\n띿\n랁\n랂\n랃\n랅\n랆\n랇\n랈\n랉\n랊\n랋\n랎\n랓\n랔\n랕\n랚\n랛\n랝\n랞\n랟\n랡\n랢\n랣\n랤\n랥\n랦\n랧\n랪\n랮\n랯\n랰\n랱\n랲\n랳\n랶\n랷\n랹\n랺\n랻\n랼\n랽\n랾\n랿\n럀\n럁\n럂\n럃\n럄\n럅\n럆\n럈\n럊\n럋\n럌\n럍\n럎\n럏\n럐\n럑\n럒\n럓\n럔\n럕\n럖\n럗\n럘\n럙\n럚\n럛\n럜\n럝\n럞\n럟\n럠\n럡\n럢\n럣\n럤\n럥\n럦\n럧\n럨\n럩\n럪\n럫\n럮\n럯\n럱\n럲\n럳\n럵\n럶\n럷\n럸\n럹\n럺\n럻\n럾\n렂\n렃\n렄\n렅\n렆\n렊\n렋\n렍\n렎\n렏\n렑\n렒\n렓\n렔\n렕\n렖\n렗\n렚\n렜\n렞\n렟\n렠\n렡\n렢\n렣\n렦\n렧\n렩\n렪\n렫\n렭\n렮\n렯\n렰\n렱\n렲\n렳\n렶\n렺\n렻\n렼\n렽\n렾\n렿\n롁\n롂\n롃\n롅\n롆\n롇\n롈\n롉\n롊\n롋\n롌\n롍\n롎\n롏\n롐\n롒\n롔\n롕\n롖\n롗\n롘\n롙\n롚\n롛\n롞\n롟\n롡\n롢\n롣\n롥\n롦\n롧\n롨\n롩\n롪\n롫\n롮\n롰\n롲\n롳\n롴\n롵\n롶\n롷\n롹\n롺\n롻\n롽\n롾\n롿\n뢀\n뢁\n뢂\n뢃\n뢄\n뢅\n뢆\n뢇\n뢈\n뢉\n뢊\n뢋\n뢌\n뢎\n뢏\n뢐\n뢑\n뢒\n뢓\n뢔\n뢕\n뢖\n뢗\n뢘\n뢙\n뢚\n뢛\n뢜\n뢝\n뢞\n뢟\n뢠\n뢡\n뢢\n뢣\n뢤\n뢥\n뢦\n뢧\n뢩\n뢪\n뢫\n뢬\n뢭\n뢮\n뢯\n뢱\n뢲\n뢳\n뢵\n뢶\n뢷\n뢹\n뢺\n뢻\n뢼\n뢽\n뢾\n뢿\n룂\n룄\n룆\n룇\n룈\n룉\n룊\n룋\n룍\n룎\n룏\n룑\n룒\n룓\n룕\n룖\n룗\n룘\n룙\n룚\n룛\n룜\n룞\n룠\n룢\n룣\n룤\n룥\n룦\n룧\n룪\n룫\n룭\n룮\n룯\n룱\n룲\n룳\n룴\n룵\n룶\n룷\n룺\n룼\n룾\n룿\n뤀\n뤁\n뤂\n뤃\n뤅\n뤆\n뤇\n뤈\n뤉\n뤊\n뤋\n뤌\n뤍\n뤎\n뤏\n뤐\n뤑\n뤒\n뤓\n뤔\n뤕\n뤖\n뤗\n뤙\n뤚\n뤛\n뤜\n뤝\n뤞\n뤟\n뤡\n뤢\n뤣\n뤤\n뤥\n뤦\n뤧\n뤨\n뤩\n뤪\n뤫\n뤬\n뤭\n뤮\n뤯\n뤰\n뤱\n뤲\n뤳\n뤴\n뤵\n뤶\n뤷\n뤸\n뤹\n뤺\n뤻\n뤾\n뤿\n륁\n륂\n륃\n륅\n륆\n륇\n륈\n륉\n륊\n륋\n륍\n륎\n륐\n륒\n륓\n륔\n륕\n륖\n륗\n륚\n륛\n륝\n륞\n륟\n륡\n륢\n륣\n륤\n륥\n륦\n륧\n륪\n륬\n륮\n륯\n륰\n륱\n륲\n륳\n륶\n륷\n륹\n륺\n륻\n륽\n륾\n륿\n릀\n릁\n릂\n릃\n릆\n릈\n릋\n릌\n릏\n릐\n릑\n릒\n릓\n릔\n릕\n릖\n릗\n릘\n릙\n릚\n릛\n릜\n릝\n릞\n릟\n릠\n릡\n릢\n릣\n릤\n릥\n릦\n릧\n릨\n릩\n릪\n릫\n릮\n릯\n릱\n릲\n릳\n릵\n릶\n릷\n릸\n릹\n릺\n릻\n릾\n맀\n맂\n맃\n맄\n맅\n맆\n맇\n맊\n맋\n맍\n맓\n맔\n맕\n맖\n맗\n맚\n맜\n맟\n맠\n맢\n맦\n맧\n맩\n맪\n맫\n맭\n맮\n맯\n맰\n맱\n맲\n맳\n맶\n맻\n맼\n맽\n맾\n맿\n먂\n먃\n먄\n먅\n먆\n먇\n먉\n먊\n먋\n먌\n먍\n먎\n먏\n먐\n먑\n먒\n먓\n먔\n먖\n먗\n먘\n먙\n먚\n먛\n먜\n먝\n먞\n먟\n먠\n먡\n먢\n먣\n먤\n먥\n먦\n먧\n먨\n먩\n먪\n먫\n먬\n먭\n먮\n먯\n먰\n먱\n먲\n먳\n먴\n먵\n먶\n먷\n먺\n먻\n먽\n먾\n먿\n멁\n멃\n멄\n멅\n멆\n멇\n멊\n멌\n멏\n멐\n멑\n멒\n멖\n멗\n멙\n멚\n멛\n멝\n멞\n멟\n멠\n멡\n멢\n멣\n멦\n멪\n멫\n멬\n멭\n멮\n멯\n멲\n멳\n멵\n멶\n멷\n멹\n멺\n멻\n멼\n멽\n멾\n멿\n몀\n몁\n몂\n몆\n몈\n몉\n몊\n몋\n몍\n몎\n몏\n몐\n몑\n몒\n몓\n몔\n몕\n몖\n몗\n몘\n몙\n몚\n몛\n몜\n몝\n몞\n몟\n몠\n몡\n몢\n몣\n몤\n몥\n몦\n몧\n몪\n몭\n몮\n몯\n몱\n몳\n몴\n몵\n몶\n몷\n몺\n몼\n몾\n몿\n뫀\n뫁\n뫂\n뫃\n뫅\n뫆\n뫇\n뫉\n뫊\n뫋\n뫌\n뫍\n뫎\n뫏\n뫐\n뫑\n뫒\n뫓\n뫔\n뫕\n뫖\n뫗\n뫚\n뫛\n뫜\n뫝\n뫞\n뫟\n뫠\n뫡\n뫢\n뫣\n뫤\n뫥\n뫦\n뫧\n뫨\n뫩\n뫪\n뫫\n뫬\n뫭\n뫮\n뫯\n뫰\n뫱\n뫲\n뫳\n뫴\n뫵\n뫶\n뫷\n뫸\n뫹\n뫺\n뫻\n뫽\n뫾\n뫿\n묁\n묂\n묃\n묅\n묆\n묇\n묈\n묉\n묊\n묋\n묌\n묎\n묐\n묒\n묓\n묔\n묕\n묖\n묗\n묙\n묚\n묛\n묝\n묞\n묟\n묡\n묢\n묣\n묤\n묥\n묦\n묧\n묨\n묪\n묬\n묭\n묮\n묯\n묰\n묱\n묲\n묳\n묷\n묹\n묺\n묿\n뭀\n뭁\n뭂\n뭃\n뭆\n뭈\n뭊\n뭋\n뭌\n뭎\n뭑\n뭒\n뭓\n뭕\n뭖\n뭗\n뭙\n뭚\n뭛\n뭜\n뭝\n뭞\n뭟\n뭠\n뭢\n뭤\n뭥\n뭦\n뭧\n뭨\n뭩\n뭪\n뭫\n뭭\n뭮\n뭯\n뭰\n뭱\n뭲\n뭳\n뭴\n뭵\n뭶\n뭷\n뭸\n뭹\n뭺\n뭻\n뭼\n뭽\n뭾\n뭿\n뮀\n뮁\n뮂\n뮃\n뮄\n뮅\n뮆\n뮇\n뮉\n뮊\n뮋\n뮍\n뮎\n뮏\n뮑\n뮒\n뮓\n뮔\n뮕\n뮖\n뮗\n뮘\n뮙\n뮚\n뮛\n뮜\n뮝\n뮞\n뮟\n뮠\n뮡\n뮢\n뮣\n뮥\n뮦\n뮧\n뮩\n뮪\n뮫\n뮭\n뮮\n뮯\n뮰\n뮱\n뮲\n뮳\n뮵\n뮶\n뮸\n뮹\n뮺\n뮻\n뮼\n뮽\n뮾\n뮿\n믁\n믂\n믃\n믅\n믆\n믇\n믉\n믊\n믋\n믌\n믍\n믎\n믏\n믑\n믒\n믔\n믕\n믖\n믗\n믘\n믙\n믚\n믛\n믜\n믝\n믞\n믟\n믠\n믡\n믢\n믣\n믤\n믥\n믦\n믧\n믨\n믩\n믪\n믫\n믬\n믭\n믮\n믯\n믰\n믱\n믲\n믳\n믴\n믵\n믶\n믷\n믺\n믻\n믽\n믾\n밁\n밃\n밄\n밅\n밆\n밇\n밊\n밎\n밐\n밒\n밓\n밙\n밚\n밠\n밡\n밢\n밣\n밦\n밨\n밪\n밫\n밬\n밮\n밯\n밲\n밳\n밵\n밶\n밷\n밹\n밺\n밻\n밼\n밽\n밾\n밿\n뱂\n뱆\n뱇\n뱈\n뱊\n뱋\n뱎\n뱏\n뱑\n뱒\n뱓\n뱔\n뱕\n뱖\n뱗\n뱘\n뱙\n뱚\n뱛\n뱜\n뱞\n뱟\n뱠\n뱡\n뱢\n뱣\n뱤\n뱥\n뱦\n뱧\n뱨\n뱩\n뱪\n뱫\n뱬\n뱭\n뱮\n뱯\n뱰\n뱱\n뱲\n뱳\n뱴\n뱵\n뱶\n뱷\n뱸\n뱹\n뱺\n뱻\n뱼\n뱽\n뱾\n뱿\n벀\n벁\n벂\n벃\n벆\n벇\n벉\n벊\n벍\n벏\n벐\n벑\n벒\n벓\n벖\n벘\n벛\n벜\n벝\n벞\n벟\n벢\n벣\n벥\n벦\n벩\n벪\n벫\n벬\n벭\n벮\n벯\n벲\n벶\n벷\n벸\n벹\n벺\n벻\n벾\n벿\n볁\n볂\n볃\n볅\n볆\n볇\n볈\n볉\n볊\n볋\n볌\n볎\n볒\n볓\n볔\n볖\n볗\n볙\n볚\n볛\n볝\n볞\n볟\n볠\n볡\n볢\n볣\n볤\n볥\n볦\n볧\n볨\n볩\n볪\n볫\n볬\n볭\n볮\n볯\n볰\n볱\n볲\n볳\n볷\n볹\n볺\n볻\n볽\n볾\n볿\n봀\n봁\n봂\n봃\n봆\n봈\n봊\n봋\n봌\n봍\n봎\n봏\n봑\n봒\n봓\n봕\n봖\n봗\n봘\n봙\n봚\n봛\n봜\n봝\n봞\n봟\n봠\n봡\n봢\n봣\n봥\n봦\n봧\n봨\n봩\n봪\n봫\n봭\n봮\n봯\n봰\n봱\n봲\n봳\n봴\n봵\n봶\n봷\n봸\n봹\n봺\n봻\n봼\n봽\n봾\n봿\n뵁\n뵂\n뵃\n뵄\n뵅\n뵆\n뵇\n뵊\n뵋\n뵍\n뵎\n뵏\n뵑\n뵒\n뵓\n뵔\n뵕\n뵖\n뵗\n뵚\n뵛\n뵜\n뵝\n뵞\n뵟\n뵠\n뵡\n뵢\n뵣\n뵥\n뵦\n뵧\n뵩\n뵪\n뵫\n뵬\n뵭\n뵮\n뵯\n뵰\n뵱\n뵲\n뵳\n뵴\n뵵\n뵶\n뵷\n뵸\n뵹\n뵺\n뵻\n뵼\n뵽\n뵾\n뵿\n붂\n붃\n붅\n붆\n붋\n붌\n붍\n붎\n붏\n붒\n붔\n붖\n붗\n붘\n붛\n붝\n붞\n붟\n붠\n붡\n붢\n붣\n붥\n붦\n붧\n붨\n붩\n붪\n붫\n붬\n붭\n붮\n붯\n붱\n붲\n붳\n붴\n붵\n붶\n붷\n붹\n붺\n붻\n붼\n붽\n붾\n붿\n뷀\n뷁\n뷂\n뷃\n뷄\n뷅\n뷆\n뷇\n뷈\n뷉\n뷊\n뷋\n뷌\n뷍\n뷎\n뷏\n뷐\n뷑\n뷒\n뷓\n뷖\n뷗\n뷙\n뷚\n뷛\n뷝\n뷞\n뷟\n뷠\n뷡\n뷢\n뷣\n뷤\n뷥\n뷦\n뷧\n뷨\n뷪\n뷫\n뷬\n뷭\n뷮\n뷯\n뷱\n뷲\n뷳\n뷵\n뷶\n뷷\n뷹\n뷺\n뷻\n뷼\n뷽\n뷾\n뷿\n븁\n븂\n븄\n븆\n븇\n븈\n븉\n븊\n븋\n븎\n븏\n븑\n븒\n븓\n븕\n븖\n븗\n븘\n븙\n븚\n븛\n븞\n븠\n븡\n븢\n븣\n븤\n븥\n븦\n븧\n븨\n븩\n븪\n븫\n븬\n븭\n븮\n븯\n븰\n븱\n븲\n븳\n븴\n븵\n븶\n븷\n븸\n븹\n븺\n븻\n븼\n븽\n븾\n븿\n빀\n빁\n빂\n빃\n빆\n빇\n빉\n빊\n빋\n빍\n빏\n빐\n빑\n빒\n빓\n빖\n빘\n빜\n빝\n빞\n빟\n빢\n빣\n빥\n빦\n빧\n빩\n빫\n빬\n빭\n빮\n빯\n빲\n빶\n빷\n빸\n빹\n빺\n빾\n빿\n뺁\n뺂\n뺃\n뺅\n뺆\n뺇\n뺈\n뺉\n뺊\n뺋\n뺎\n뺒\n뺓\n뺔\n뺕\n뺖\n뺗\n뺚\n뺛\n뺜\n뺝\n뺞\n뺟\n뺠\n뺡\n뺢\n뺣\n뺤\n뺥\n뺦\n뺧\n뺩\n뺪\n뺫\n뺬\n뺭\n뺮\n뺯\n뺰\n뺱\n뺲\n뺳\n뺴\n뺵\n뺶\n뺷\n뺸\n뺹\n뺺\n뺻\n뺼\n뺽\n뺾\n뺿\n뻀\n뻁\n뻂\n뻃\n뻄\n뻅\n뻆\n뻇\n뻈\n뻉\n뻊\n뻋\n뻌\n뻍\n뻎\n뻏\n뻒\n뻓\n뻕\n뻖\n뻙\n뻚\n뻛\n뻜\n뻝\n뻞\n뻟\n뻡\n뻢\n뻦\n뻧\n뻨\n뻩\n뻪\n뻫\n뻭\n뻮\n뻯\n뻰\n뻱\n뻲\n뻳\n뻴\n뻵\n뻶\n뻷\n뻸\n뻹\n뻺\n뻻\n뻼\n뻽\n뻾\n뻿\n뼀\n뼂\n뼃\n뼄\n뼅\n뼆\n뼇\n뼊\n뼋\n뼌\n뼍\n뼎\n뼏\n뼐\n뼑\n뼒\n뼓\n뼔\n뼕\n뼖\n뼗\n뼚\n뼞\n뼟\n뼠\n뼡\n뼢\n뼣\n뼤\n뼥\n뼦\n뼧\n뼨\n뼩\n뼪\n뼫\n뼬\n뼭\n뼮\n뼯\n뼰\n뼱\n뼲\n뼳\n뼴\n뼵\n뼶\n뼷\n뼸\n뼹\n뼺\n뼻\n뼼\n뼽\n뼾\n뼿\n뽂\n뽃\n뽅\n뽆\n뽇\n뽉\n뽊\n뽋\n뽌\n뽍\n뽎\n뽏\n뽒\n뽓\n뽔\n뽖\n뽗\n뽘\n뽙\n뽚\n뽛\n뽜\n뽝\n뽞\n뽟\n뽠\n뽡\n뽢\n뽣\n뽤\n뽥\n뽦\n뽧\n뽨\n뽩\n뽪\n뽫\n뽬\n뽭\n뽮\n뽯\n뽰\n뽱\n뽲\n뽳\n뽴\n뽵\n뽶\n뽷\n뽸\n뽹\n뽺\n뽻\n뽼\n뽽\n뽾\n뽿\n뾀\n뾁\n뾂\n뾃\n뾄\n뾅\n뾆\n뾇\n뾈\n뾉\n뾊\n뾋\n뾌\n뾍\n뾎\n뾏\n뾐\n뾑\n뾒\n뾓\n뾕\n뾖\n뾗\n뾘\n뾙\n뾚\n뾛\n뾜\n뾝\n뾞\n뾟\n뾠\n뾡\n뾢\n뾣\n뾤\n뾥\n뾦\n뾧\n뾨\n뾩\n뾪\n뾫\n뾬\n뾭\n뾮\n뾯\n뾱\n뾲\n뾳\n뾴\n뾵\n뾶\n뾷\n뾸\n뾹\n뾺\n뾻\n뾼\n뾽\n뾾\n뾿\n뿀\n뿁\n뿂\n뿃\n뿄\n뿆\n뿇\n뿈\n뿉\n뿊\n뿋\n뿎\n뿏\n뿑\n뿒\n뿓\n뿕\n뿖\n뿗\n뿘\n뿙\n뿚\n뿛\n뿝\n뿞\n뿠\n뿢\n뿣\n뿤\n뿥\n뿦\n뿧\n뿨\n뿩\n뿪\n뿫\n뿬\n뿭\n뿮\n뿯\n뿰\n뿱\n뿲\n뿳\n뿴\n뿵\n뿶\n뿷\n뿸\n뿹\n뿺\n뿻\n뿼\n뿽\n뿾\n뿿\n쀀\n쀁\n쀂\n쀃\n쀄\n쀅\n쀆\n쀇\n쀈\n쀉\n쀊\n쀋\n쀌\n쀍\n쀎\n쀏\n쀐\n쀑\n쀒\n쀓\n쀔\n쀕\n쀖\n쀗\n쀘\n쀙\n쀚\n쀛\n쀜\n쀝\n쀞\n쀟\n쀠\n쀡\n쀢\n쀣\n쀤\n쀥\n쀦\n쀧\n쀨\n쀩\n쀪\n쀫\n쀬\n쀭\n쀮\n쀯\n쀰\n쀱\n쀲\n쀳\n쀴\n쀵\n쀶\n쀷\n쀸\n쀹\n쀺\n쀻\n쀽\n쀾\n쀿\n쁀\n쁁\n쁂\n쁃\n쁄\n쁅\n쁆\n쁇\n쁈\n쁉\n쁊\n쁋\n쁌\n쁍\n쁎\n쁏\n쁐\n쁒\n쁓\n쁔\n쁕\n쁖\n쁗\n쁙\n쁚\n쁛\n쁝\n쁞\n쁟\n쁡\n쁢\n쁣\n쁤\n쁥\n쁦\n쁧\n쁪\n쁫\n쁬\n쁭\n쁮\n쁯\n쁰\n쁱\n쁲\n쁳\n쁴\n쁵\n쁶\n쁷\n쁸\n쁹\n쁺\n쁻\n쁼\n쁽\n쁾\n쁿\n삀\n삁\n삂\n삃\n삄\n삅\n삆\n삇\n삈\n삉\n삊\n삋\n삌\n삍\n삎\n삏\n삒\n삓\n삕\n삖\n삗\n삙\n삚\n삛\n삜\n삝\n삞\n삟\n삢\n삤\n삦\n삧\n삨\n삩\n삪\n삫\n삮\n삱\n삲\n삷\n삸\n삹\n삺\n삻\n삾\n샂\n샃\n샄\n샆\n샇\n샊\n샋\n샍\n샎\n샏\n샑\n샒\n샓\n샔\n샕\n샖\n샗\n샚\n샞\n샟\n샠\n샡\n샢\n샣\n샦\n샧\n샩\n샪\n샫\n샭\n샮\n샯\n샰\n샱\n샲\n샳\n샶\n샸\n샺\n샻\n샼\n샽\n샾\n샿\n섁\n섂\n섃\n섅\n섆\n섇\n섉\n섊\n섋\n섌\n섍\n섎\n섏\n섑\n섒\n섓\n섔\n섖\n섗\n섘\n섙\n섚\n섛\n섡\n섢\n섥\n섨\n섩\n섪\n섫\n섮\n섲\n섳\n섴\n섵\n섷\n섺\n섻\n섽\n섾\n섿\n셁\n셂\n셃\n셄\n셅\n셆\n셇\n셊\n셎\n셏\n셐\n셑\n셒\n셓\n셖\n셗\n셙\n셚\n셛\n셝\n셞\n셟\n셠\n셡\n셢\n셣\n셦\n셪\n셫\n셬\n셭\n셮\n셯\n셱\n셲\n셳\n셵\n셶\n셷\n셹\n셺\n셻\n셼\n셽\n셾\n셿\n솀\n솁\n솂\n솃\n솄\n솆\n솇\n솈\n솉\n솊\n솋\n솏\n솑\n솒\n솓\n솕\n솗\n솘\n솙\n솚\n솛\n솞\n솠\n솢\n솣\n솤\n솦\n솧\n솪\n솫\n솭\n솮\n솯\n솱\n솲\n솳\n솴\n솵\n솶\n솷\n솸\n솹\n솺\n솻\n솼\n솾\n솿\n쇀\n쇁\n쇂\n쇃\n쇅\n쇆\n쇇\n쇉\n쇊\n쇋\n쇍\n쇎\n쇏\n쇐\n쇑\n쇒\n쇓\n쇕\n쇖\n쇙\n쇚\n쇛\n쇜\n쇝\n쇞\n쇟\n쇡\n쇢\n쇣\n쇥\n쇦\n쇧\n쇩\n쇪\n쇫\n쇬\n쇭\n쇮\n쇯\n쇲\n쇴\n쇵\n쇶\n쇷\n쇸\n쇹\n쇺\n쇻\n쇾\n쇿\n숁\n숂\n숃\n숅\n숆\n숇\n숈\n숉\n숊\n숋\n숎\n숐\n숒\n숓\n숔\n숕\n숖\n숗\n숚\n숛\n숝\n숞\n숡\n숢\n숣\n숤\n숥\n숦\n숧\n숪\n숬\n숮\n숰\n숳\n숵\n숶\n숷\n숸\n숹\n숺\n숻\n숼\n숽\n숾\n숿\n쉀\n쉁\n쉂\n쉃\n쉄\n쉅\n쉆\n쉇\n쉉\n쉊\n쉋\n쉌\n쉍\n쉎\n쉏\n쉒\n쉓\n쉕\n쉖\n쉗\n쉙\n쉚\n쉛\n쉜\n쉝\n쉞\n쉟\n쉡\n쉢\n쉣\n쉤\n쉦\n쉧\n쉨\n쉩\n쉪\n쉫\n쉮\n쉯\n쉱\n쉲\n쉳\n쉵\n쉶\n쉷\n쉸\n쉹\n쉺\n쉻\n쉾\n슀\n슂\n슃\n슄\n슅\n슆\n슇\n슊\n슋\n슌\n슍\n슎\n슏\n슑\n슒\n슓\n슔\n슕\n슖\n슗\n슙\n슚\n슜\n슞\n슟\n슠\n슡\n슢\n슣\n슦\n슧\n슩\n슪\n슫\n슮\n슯\n슰\n슱\n슲\n슳\n슶\n슸\n슺\n슻\n슼\n슽\n슾\n슿\n싀\n싁\n싂\n싃\n싄\n싅\n싆\n싇\n싈\n싉\n싊\n싋\n싌\n싍\n싎\n싏\n싐\n싑\n싒\n싓\n싔\n싕\n싖\n싗\n싘\n싙\n싚\n싛\n싞\n싟\n싡\n싢\n싥\n싦\n싧\n싨\n싩\n싪\n싮\n싰\n싲\n싳\n싴\n싵\n싷\n싺\n싽\n싾\n싿\n쌁\n쌂\n쌃\n쌄\n쌅\n쌆\n쌇\n쌊\n쌋\n쌎\n쌏\n쌐\n쌑\n쌒\n쌖\n쌗\n쌙\n쌚\n쌛\n쌝\n쌞\n쌟\n쌠\n쌡\n쌢\n쌣\n쌦\n쌧\n쌪\n쌫\n쌬\n쌭\n쌮\n쌯\n쌰\n쌱\n쌲\n쌳\n쌴\n쌵\n쌶\n쌷\n쌸\n쌹\n쌺\n쌻\n쌼\n쌽\n쌾\n쌿\n썀\n썁\n썂\n썃\n썄\n썆\n썇\n썈\n썉\n썊\n썋\n썌\n썍\n썎\n썏\n썐\n썑\n썒\n썓\n썔\n썕\n썖\n썗\n썘\n썙\n썚\n썛\n썜\n썝\n썞\n썟\n썠\n썡\n썢\n썣\n썤\n썥\n썦\n썧\n썪\n썫\n썭\n썮\n썯\n썱\n썳\n썴\n썵\n썶\n썷\n썺\n썻\n썾\n썿\n쎀\n쎁\n쎂\n쎃\n쎅\n쎆\n쎇\n쎉\n쎊\n쎋\n쎍\n쎎\n쎏\n쎐\n쎑\n쎒\n쎓\n쎔\n쎕\n쎖\n쎗\n쎘\n쎙\n쎚\n쎛\n쎜\n쎝\n쎞\n쎟\n쎠\n쎡\n쎢\n쎣\n쎤\n쎥\n쎦\n쎧\n쎨\n쎩\n쎪\n쎫\n쎬\n쎭\n쎮\n쎯\n쎰\n쎱\n쎲\n쎳\n쎴\n쎵\n쎶\n쎷\n쎸\n쎹\n쎺\n쎻\n쎼\n쎽\n쎾\n쎿\n쏁\n쏂\n쏃\n쏄\n쏅\n쏆\n쏇\n쏈\n쏉\n쏊\n쏋\n쏌\n쏍\n쏎\n쏏\n쏐\n쏑\n쏒\n쏓\n쏔\n쏕\n쏖\n쏗\n쏚\n쏛\n쏝\n쏞\n쏡\n쏣\n쏤\n쏥\n쏦\n쏧\n쏪\n쏫\n쏬\n쏮\n쏯\n쏰\n쏱\n쏲\n쏳\n쏶\n쏷\n쏹\n쏺\n쏻\n쏼\n쏽\n쏾\n쏿\n쐀\n쐁\n쐂\n쐃\n쐄\n쐅\n쐆\n쐇\n쐉\n쐊\n쐋\n쐌\n쐍\n쐎\n쐏\n쐑\n쐒\n쐓\n쐔\n쐕\n쐖\n쐗\n쐘\n쐙\n쐚\n쐛\n쐜\n쐝\n쐞\n쐟\n쐠\n쐡\n쐢\n쐣\n쐥\n쐦\n쐧\n쐨\n쐩\n쐪\n쐫\n쐭\n쐮\n쐯\n쐱\n쐲\n쐳\n쐵\n쐶\n쐷\n쐸\n쐹\n쐺\n쐻\n쐾\n쐿\n쑀\n쑁\n쑂\n쑃\n쑄\n쑅\n쑆\n쑇\n쑉\n쑊\n쑋\n쑌\n쑍\n쑎\n쑏\n쑐\n쑑\n쑒\n쑓\n쑔\n쑕\n쑖\n쑗\n쑘\n쑙\n쑚\n쑛\n쑜\n쑝\n쑞\n쑟\n쑠\n쑡\n쑢\n쑣\n쑦\n쑧\n쑩\n쑪\n쑫\n쑭\n쑮\n쑯\n쑰\n쑱\n쑲\n쑳\n쑶\n쑷\n쑸\n쑺\n쑻\n쑼\n쑽\n쑾\n쑿\n쒁\n쒂\n쒃\n쒄\n쒅\n쒆\n쒇\n쒈\n쒉\n쒊\n쒋\n쒌\n쒍\n쒎\n쒏\n쒐\n쒑\n쒒\n쒓\n쒕\n쒖\n쒗\n쒘\n쒙\n쒚\n쒛\n쒝\n쒞\n쒟\n쒠\n쒡\n쒢\n쒣\n쒤\n쒥\n쒦\n쒧\n쒨\n쒩\n쒪\n쒫\n쒬\n쒭\n쒮\n쒯\n쒰\n쒱\n쒲\n쒳\n쒴\n쒵\n쒶\n쒷\n쒹\n쒺\n쒻\n쒽\n쒾\n쒿\n쓀\n쓁\n쓂\n쓃\n쓄\n쓅\n쓆\n쓇\n쓈\n쓉\n쓊\n쓋\n쓌\n쓍\n쓎\n쓏\n쓐\n쓑\n쓒\n쓓\n쓔\n쓕\n쓖\n쓗\n쓘\n쓙\n쓚\n쓛\n쓜\n쓝\n쓞\n쓟\n쓠\n쓡\n쓢\n쓣\n쓤\n쓥\n쓦\n쓧\n쓨\n쓪\n쓫\n쓬\n쓭\n쓮\n쓯\n쓲\n쓳\n쓵\n쓶\n쓷\n쓹\n쓻\n쓼\n쓽\n쓾\n씂\n씃\n씄\n씅\n씆\n씇\n씈\n씉\n씊\n씋\n씍\n씎\n씏\n씑\n씒\n씓\n씕\n씖\n씗\n씘\n씙\n씚\n씛\n씝\n씞\n씟\n씠\n씡\n씢\n씣\n씤\n씥\n씦\n씧\n씪\n씫\n씭\n씮\n씯\n씱\n씲\n씳\n씴\n씵\n씶\n씷\n씺\n씼\n씾\n씿\n앀\n앁\n앂\n앃\n앆\n앇\n앋\n앏\n앐\n앑\n앒\n앖\n앚\n앛\n앜\n앟\n앢\n앣\n앥\n앦\n앧\n앩\n앪\n앫\n앬\n앭\n앮\n앯\n앲\n앶\n앷\n앸\n앹\n앺\n앻\n앾\n앿\n얁\n얂\n얃\n얅\n얆\n얈\n얉\n얊\n얋\n얎\n얐\n얒\n얓\n얔\n얖\n얙\n얚\n얛\n얝\n얞\n얟\n얡\n얢\n얣\n얤\n얥\n얦\n얧\n얨\n얪\n얫\n얬\n얭\n얮\n얯\n얰\n얱\n얲\n얳\n얶\n얷\n얺\n얿\n엀\n엁\n엂\n엃\n엋\n엍\n엏\n엒\n엓\n엕\n엖\n엗\n엙\n엚\n엛\n엜\n엝\n엞\n엟\n엢\n엤\n엦\n엧\n엨\n엩\n엪\n엫\n엯\n엱\n엲\n엳\n엵\n엸\n엹\n엺\n엻\n옂\n옃\n옄\n옉\n옊\n옋\n옍\n옎\n옏\n옑\n옒\n옓\n옔\n옕\n옖\n옗\n옚\n옝\n옞\n옟\n옠\n옡\n옢\n옣\n옦\n옧\n옩\n옪\n옫\n옯\n옱\n옲\n옶\n옸\n옺\n옼\n옽\n옾\n옿\n왂\n왃\n왅\n왆\n왇\n왉\n왊\n왋\n왌\n왍\n왎\n왏\n왒\n왖\n왗\n왘\n왙\n왚\n왛\n왞\n왟\n왡\n왢\n왣\n왤\n왥\n왦\n왧\n왨\n왩\n왪\n왫\n왭\n왮\n왰\n왲\n왳\n왴\n왵\n왶\n왷\n왺\n왻\n왽\n왾\n왿\n욁\n욂\n욃\n욄\n욅\n욆\n욇\n욊\n욌\n욎\n욏\n욐\n욑\n욒\n욓\n욖\n욗\n욙\n욚\n욛\n욝\n욞\n욟\n욠\n욡\n욢\n욣\n욦\n욨\n욪\n욫\n욬\n욭\n욮\n욯\n욲\n욳\n욵\n욶\n욷\n욻\n욼\n욽\n욾\n욿\n웂\n웄\n웆\n웇\n웈\n웉\n웊\n웋\n웎\n웏\n웑\n웒\n웓\n웕\n웖\n웗\n웘\n웙\n웚\n웛\n웞\n웟\n웢\n웣\n웤\n웥\n웦\n웧\n웪\n웫\n웭\n웮\n웯\n웱\n웲\n웳\n웴\n웵\n웶\n웷\n웺\n웻\n웼\n웾\n웿\n윀\n윁\n윂\n윃\n윆\n윇\n윉\n윊\n윋\n윍\n윎\n윏\n윐\n윑\n윒\n윓\n윖\n윘\n윚\n윛\n윜\n윝\n윞\n윟\n윢\n윣\n윥\n윦\n윧\n윩\n윪\n윫\n윬\n윭\n윮\n윯\n윲\n윴\n윶\n윸\n윹\n윺\n윻\n윾\n윿\n읁\n읂\n읃\n읅\n읆\n읇\n읈\n읉\n읋\n읎\n읐\n읙\n읚\n읛\n읝\n읞\n읟\n읡\n읢\n읣\n읤\n읥\n읦\n읧\n읩\n읪\n읬\n읭\n읮\n읯\n읰\n읱\n읲\n읳\n읶\n읷\n읹\n읺\n읻\n읿\n잀\n잁\n잂\n잆\n잋\n잌\n잍\n잏\n잒\n잓\n잕\n잙\n잛\n잜\n잝\n잞\n잟\n잢\n잧\n잨\n잩\n잪\n잫\n잮\n잯\n잱\n잲\n잳\n잵\n잶\n잷\n잸\n잹\n잺\n잻\n잾\n쟂\n쟃\n쟄\n쟅\n쟆\n쟇\n쟊\n쟋\n쟍\n쟏\n쟑\n쟒\n쟓\n쟔\n쟕\n쟖\n쟗\n쟙\n쟚\n쟛\n쟜\n쟞\n쟟\n쟠\n쟡\n쟢\n쟣\n쟥\n쟦\n쟧\n쟩\n쟪\n쟫\n쟭\n쟮\n쟯\n쟰\n쟱\n쟲\n쟳\n쟴\n쟵\n쟶\n쟷\n쟸\n쟹\n쟺\n쟻\n쟼\n쟽\n쟾\n쟿\n젂\n젃\n젅\n젆\n젇\n젉\n젋\n젌\n젍\n젎\n젏\n젒\n젔\n젗\n젘\n젙\n젚\n젛\n젞\n젟\n젡\n젢\n젣\n젥\n젦\n젧\n젨\n젩\n젪\n젫\n젮\n젰\n젲\n젳\n젴\n젵\n젶\n젷\n젹\n젺\n젻\n젽\n젾\n젿\n졁\n졂\n졃\n졄\n졅\n졆\n졇\n졊\n졋\n졎\n졏\n졐\n졑\n졒\n졓\n졕\n졖\n졗\n졘\n졙\n졚\n졛\n졜\n졝\n졞\n졟\n졠\n졡\n졢\n졣\n졤\n졥\n졦\n졧\n졨\n졩\n졪\n졫\n졬\n졭\n졮\n졯\n졲\n졳\n졵\n졶\n졷\n졹\n졻\n졼\n졽\n졾\n졿\n좂\n좄\n좈\n좉\n좊\n좎\n좏\n좐\n좑\n좒\n좓\n좕\n좖\n좗\n좘\n좙\n좚\n좛\n좜\n좞\n좠\n좢\n좣\n좤\n좥\n좦\n좧\n좩\n좪\n좫\n좬\n좭\n좮\n좯\n좰\n좱\n좲\n좳\n좴\n좵\n좶\n좷\n좸\n좹\n좺\n좻\n좾\n좿\n죀\n죁\n죂\n죃\n죅\n죆\n죇\n죉\n죊\n죋\n죍\n죎\n죏\n죐\n죑\n죒\n죓\n죖\n죘\n죚\n죛\n죜\n죝\n죞\n죟\n죢\n죣\n죥\n죦\n죧\n죨\n죩\n죪\n죫\n죬\n죭\n죮\n죯\n죰\n죱\n죲\n죳\n죴\n죶\n죷\n죸\n죹\n죺\n죻\n죾\n죿\n줁\n줂\n줃\n줇\n줈\n줉\n줊\n줋\n줎\n　\n、\n。\n·\n‥\n…\n¨\n〃\n­\n―\n∥\n＼\n∼\n‘\n’\n“\n”\n〔\n〕\n〈\n〉\n《\n》\n「\n」\n『\n』\n【\n】\n±\n×\n÷\n≠\n≤\n≥\n∞\n∴\n°\n′\n″\n℃\nÅ\n￠\n￡\n￥\n♂\n♀\n∠\n⊥\n⌒\n∂\n∇\n≡\n≒\n§\n※\n☆\n★\n○\n●\n◎\n◇\n◆\n□\n■\n△\n▲\n▽\n▼\n→\n←\n↑\n↓\n↔\n〓\n≪\n≫\n√\n∽\n∝\n∵\n∫\n∬\n∈\n∋\n⊆\n⊇\n⊂\n⊃\n∪\n∩\n∧\n∨\n￢\n줐\n줒\n줓\n줔\n줕\n줖\n줗\n줙\n줚\n줛\n줜\n줝\n줞\n줟\n줠\n줡\n줢\n줣\n줤\n줥\n줦\n줧\n줨\n줩\n줪\n줫\n줭\n줮\n줯\n줰\n줱\n줲\n줳\n줵\n줶\n줷\n줸\n줹\n줺\n줻\n줼\n줽\n줾\n줿\n쥀\n쥁\n쥂\n쥃\n쥄\n쥅\n쥆\n쥇\n쥈\n쥉\n쥊\n쥋\n쥌\n쥍\n쥎\n쥏\n쥒\n쥓\n쥕\n쥖\n쥗\n쥙\n쥚\n쥛\n쥜\n쥝\n쥞\n쥟\n쥢\n쥤\n쥥\n쥦\n쥧\n쥨\n쥩\n쥪\n쥫\n쥭\n쥮\n쥯\n⇒\n⇔\n∀\n∃\n´\n～\nˇ\n˘\n˝\n˚\n˙\n¸\n˛\n¡\n¿\nː\n∮\n∑\n∏\n¤\n℉\n‰\n◁\n◀\n▷\n▶\n♤\n♠\n♡\n♥\n♧\n♣\n⊙\n◈\n▣\n◐\n◑\n▒\n▤\n▥\n▨\n▧\n▦\n▩\n♨\n☏\n☎\n☜\n☞\n¶\n†\n‡\n↕\n↗\n↙\n↖\n↘\n♭\n♩\n♪\n♬\n㉿\n㈜\n№\n㏇\n™\n㏂\n㏘\n℡\n€\n®\n쥱\n쥲\n쥳\n쥵\n쥶\n쥷\n쥸\n쥹\n쥺\n쥻\n쥽\n쥾\n쥿\n즀\n즁\n즂\n즃\n즄\n즅\n즆\n즇\n즊\n즋\n즍\n즎\n즏\n즑\n즒\n즓\n즔\n즕\n즖\n즗\n즚\n즜\n즞\n즟\n즠\n즡\n즢\n즣\n즤\n즥\n즦\n즧\n즨\n즩\n즪\n즫\n즬\n즭\n즮\n즯\n즰\n즱\n즲\n즳\n즴\n즵\n즶\n즷\n즸\n즹\n즺\n즻\n즼\n즽\n즾\n즿\n짂\n짃\n짅\n짆\n짉\n짋\n짌\n짍\n짎\n짏\n짒\n짔\n짗\n짘\n짛\n！\n＂\n＃\n＄\n％\n＆\n＇\n（\n）\n＊\n＋\n，\n－\n．\n／\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\n：\n；\n＜\n＝\n＞\n？\n＠\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\n［\n￦\n］\n＾\n＿\n｀\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\n｛\n｜\n｝\n￣\n짞\n짟\n짡\n짣\n짥\n짦\n짨\n짩\n짪\n짫\n짮\n짲\n짳\n짴\n짵\n짶\n짷\n짺\n짻\n짽\n짾\n짿\n쨁\n쨂\n쨃\n쨄\n쨅\n쨆\n쨇\n쨊\n쨎\n쨏\n쨐\n쨑\n쨒\n쨓\n쨕\n쨖\n쨗\n쨙\n쨚\n쨛\n쨜\n쨝\n쨞\n쨟\n쨠\n쨡\n쨢\n쨣\n쨤\n쨥\n쨦\n쨧\n쨨\n쨪\n쨫\n쨬\n쨭\n쨮\n쨯\n쨰\n쨱\n쨲\n쨳\n쨴\n쨵\n쨶\n쨷\n쨸\n쨹\n쨺\n쨻\n쨼\n쨽\n쨾\n쨿\n쩀\n쩁\n쩂\n쩃\n쩄\n쩅\n쩆\nㄱ\nㄲ\nㄳ\nㄴ\nㄵ\nㄶ\nㄷ\nㄸ\nㄹ\nㄺ\nㄻ\nㄼ\nㄽ\nㄾ\nㄿ\nㅀ\nㅁ\nㅂ\nㅃ\nㅄ\nㅅ\nㅆ\nㅇ\nㅈ\nㅉ\nㅊ\nㅋ\nㅌ\nㅍ\nㅎ\nㅏ\nㅐ\nㅑ\nㅒ\nㅓ\nㅔ\nㅕ\nㅖ\nㅗ\nㅘ\nㅙ\nㅚ\nㅛ\nㅜ\nㅝ\nㅞ\nㅟ\nㅠ\nㅡ\nㅢ\nㅣ\nㅤ\nㅥ\nㅦ\nㅧ\nㅨ\nㅩ\nㅪ\nㅫ\nㅬ\nㅭ\nㅮ\nㅯ\nㅰ\nㅱ\nㅲ\nㅳ\nㅴ\nㅵ\nㅶ\nㅷ\nㅸ\nㅹ\nㅺ\nㅻ\nㅼ\nㅽ\nㅾ\nㅿ\nㆀ\nㆁ\nㆂ\nㆃ\nㆄ\nㆅ\nㆆ\nㆇ\nㆈ\nㆉ\nㆊ\nㆋ\nㆌ\nㆍ\nㆎ\n쩇\n쩈\n쩉\n쩊\n쩋\n쩎\n쩏\n쩑\n쩒\n쩓\n쩕\n쩖\n쩗\n쩘\n쩙\n쩚\n쩛\n쩞\n쩢\n쩣\n쩤\n쩥\n쩦\n쩧\n쩩\n쩪\n쩫\n쩬\n쩭\n쩮\n쩯\n쩰\n쩱\n쩲\n쩳\n쩴\n쩵\n쩶\n쩷\n쩸\n쩹\n쩺\n쩻\n쩼\n쩾\n쩿\n쪀\n쪁\n쪂\n쪃\n쪅\n쪆\n쪇\n쪈\n쪉\n쪊\n쪋\n쪌\n쪍\n쪎\n쪏\n쪐\n쪑\n쪒\n쪓\n쪔\n쪕\n쪖\n쪗\n쪙\n쪚\n쪛\n쪜\n쪝\n쪞\n쪟\n쪠\n쪡\n쪢\n쪣\n쪤\n쪥\n쪦\n쪧\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\n쪨\n쪩\n쪪\n쪫\n쪬\n쪭\n쪮\n쪯\n쪰\n쪱\n쪲\n쪳\n쪴\n쪵\n쪶\n쪷\n쪸\n쪹\n쪺\n쪻\n쪾\n쪿\n쫁\n쫂\n쫃\n쫅\n쫆\n쫇\n쫈\n쫉\n쫊\n쫋\n쫎\n쫐\n쫒\n쫔\n쫕\n쫖\n쫗\n쫚\n쫛\n쫜\n쫝\n쫞\n쫟\n쫡\n쫢\n쫣\n쫤\n쫥\n쫦\n쫧\n쫨\n쫩\n쫪\n쫫\n쫭\n쫮\n쫯\n쫰\n쫱\n쫲\n쫳\n쫵\n쫶\n쫷\n쫸\n쫹\n쫺\n쫻\n쫼\n쫽\n쫾\n쫿\n쬀\n쬁\n쬂\n쬃\n쬄\n쬅\n쬆\n쬇\n쬉\n쬊\n─\n│\n┌\n┐\n┘\n└\n├\n┬\n┤\n┴\n┼\n━\n┃\n┏\n┓\n┛\n┗\n┣\n┳\n┫\n┻\n╋\n┠\n┯\n┨\n┷\n┿\n┝\n┰\n┥\n┸\n╂\n┒\n┑\n┚\n┙\n┖\n┕\n┎\n┍\n┞\n┟\n┡\n┢\n┦\n┧\n┩\n┪\n┭\n┮\n┱\n┲\n┵\n┶\n┹\n┺\n┽\n┾\n╀\n╁\n╃\n╄\n╅\n╆\n╇\n╈\n╉\n╊\n쬋\n쬌\n쬍\n쬎\n쬏\n쬑\n쬒\n쬓\n쬕\n쬖\n쬗\n쬙\n쬚\n쬛\n쬜\n쬝\n쬞\n쬟\n쬢\n쬣\n쬤\n쬥\n쬦\n쬧\n쬨\n쬩\n쬪\n쬫\n쬬\n쬭\n쬮\n쬯\n쬰\n쬱\n쬲\n쬳\n쬴\n쬵\n쬶\n쬷\n쬸\n쬹\n쬺\n쬻\n쬼\n쬽\n쬾\n쬿\n쭀\n쭂\n쭃\n쭄\n쭅\n쭆\n쭇\n쭊\n쭋\n쭍\n쭎\n쭏\n쭑\n쭒\n쭓\n쭔\n쭕\n쭖\n쭗\n쭚\n쭛\n쭜\n쭞\n쭟\n쭠\n쭡\n쭢\n쭣\n쭥\n쭦\n쭧\n쭨\n쭩\n쭪\n쭫\n쭬\n㎕\n㎖\n㎗\nℓ\n㎘\n㏄\n㎣\n㎤\n㎥\n㎦\n㎙\n㎚\n㎛\n㎜\n㎝\n㎞\n㎟\n㎠\n㎡\n㎢\n㏊\n㎍\n㎎\n㎏\n㏏\n㎈\n㎉\n㏈\n㎧\n㎨\n㎰\n㎱\n㎲\n㎳\n㎴\n㎵\n㎶\n㎷\n㎸\n㎹\n㎀\n㎁\n㎂\n㎃\n㎄\n㎺\n㎻\n㎼\n㎽\n㎾\n㎿\n㎐\n㎑\n㎒\n㎓\n㎔\nΩ\n㏀\n㏁\n㎊\n㎋\n㎌\n㏖\n㏅\n㎭\n㎮\n㎯\n㏛\n㎩\n㎪\n㎫\n㎬\n㏝\n㏐\n㏓\n㏃\n㏉\n㏜\n㏆\n쭭\n쭮\n쭯\n쭰\n쭱\n쭲\n쭳\n쭴\n쭵\n쭶\n쭷\n쭺\n쭻\n쭼\n쭽\n쭾\n쭿\n쮀\n쮁\n쮂\n쮃\n쮄\n쮅\n쮆\n쮇\n쮈\n쮉\n쮊\n쮋\n쮌\n쮍\n쮎\n쮏\n쮐\n쮑\n쮒\n쮓\n쮔\n쮕\n쮖\n쮗\n쮘\n쮙\n쮚\n쮛\n쮝\n쮞\n쮟\n쮠\n쮡\n쮢\n쮣\n쮤\n쮥\n쮦\n쮧\n쮨\n쮩\n쮪\n쮫\n쮬\n쮭\n쮮\n쮯\n쮰\n쮱\n쮲\n쮳\n쮴\n쮵\n쮶\n쮷\n쮹\n쮺\n쮻\n쮼\n쮽\n쮾\n쮿\n쯀\n쯁\n쯂\n쯃\n쯄\nÆ\nÐ\nª\nĦ\nĲ\nĿ\nŁ\nØ\nŒ\nº\nÞ\nŦ\nŊ\n㉠\n㉡\n㉢\n㉣\n㉤\n㉥\n㉦\n㉧\n㉨\n㉩\n㉪\n㉫\n㉬\n㉭\n㉮\n㉯\n㉰\n㉱\n㉲\n㉳\n㉴\n㉵\n㉶\n㉷\n㉸\n㉹\n㉺\n㉻\nⓐ\nⓑ\nⓒ\nⓓ\nⓔ\nⓕ\nⓖ\nⓗ\nⓘ\nⓙ\nⓚ\nⓛ\nⓜ\nⓝ\nⓞ\nⓟ\nⓠ\nⓡ\nⓢ\nⓣ\nⓤ\nⓥ\nⓦ\nⓧ\nⓨ\nⓩ\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n⑪\n⑫\n⑬\n⑭\n⑮\n½\n⅓\n⅔\n¼\n¾\n⅛\n⅜\n⅝\n⅞\n쯅\n쯆\n쯇\n쯈\n쯉\n쯊\n쯋\n쯌\n쯍\n쯎\n쯏\n쯐\n쯑\n쯒\n쯓\n쯕\n쯖\n쯗\n쯘\n쯙\n쯚\n쯛\n쯜\n쯝\n쯞\n쯟\n쯠\n쯡\n쯢\n쯣\n쯥\n쯦\n쯨\n쯪\n쯫\n쯬\n쯭\n쯮\n쯯\n쯰\n쯱\n쯲\n쯳\n쯴\n쯵\n쯶\n쯷\n쯸\n쯹\n쯺\n쯻\n쯼\n쯽\n쯾\n쯿\n찀\n찁\n찂\n찃\n찄\n찅\n찆\n찇\n찈\n찉\n찊\n찋\n찎\n찏\n찑\n찒\n찓\n찕\n찖\n찗\n찘\n찙\n찚\n찛\n찞\n찟\n찠\n찣\n찤\næ\nđ\nð\nħ\nı\nĳ\nĸ\nŀ\nł\nø\nœ\nß\nþ\nŧ\nŋ\nŉ\n㈀\n㈁\n㈂\n㈃\n㈄\n㈅\n㈆\n㈇\n㈈\n㈉\n㈊\n㈋\n㈌\n㈍\n㈎\n㈏\n㈐\n㈑\n㈒\n㈓\n㈔\n㈕\n㈖\n㈗\n㈘\n㈙\n㈚\n㈛\n⒜\n⒝\n⒞\n⒟\n⒠\n⒡\n⒢\n⒣\n⒤\n⒥\n⒦\n⒧\n⒨\n⒩\n⒪\n⒫\n⒬\n⒭\n⒮\n⒯\n⒰\n⒱\n⒲\n⒳\n⒴\n⒵\n⑴\n⑵\n⑶\n⑷\n⑸\n⑹\n⑺\n⑻\n⑼\n⑽\n⑾\n⑿\n⒀\n⒁\n⒂\n¹\n²\n³\n⁴\nⁿ\n₁\n₂\n₃\n₄\n찥\n찦\n찪\n찫\n찭\n찯\n찱\n찲\n찳\n찴\n찵\n찶\n찷\n찺\n찿\n챀\n챁\n챂\n챃\n챆\n챇\n챉\n챊\n챋\n챍\n챎\n챏\n챐\n챑\n챒\n챓\n챖\n챚\n챛\n챜\n챝\n챞\n챟\n챡\n챢\n챣\n챥\n챧\n챩\n챪\n챫\n챬\n챭\n챮\n챯\n챱\n챲\n챳\n챴\n챶\n챷\n챸\n챹\n챺\n챻\n챼\n챽\n챾\n챿\n첀\n첁\n첂\n첃\n첄\n첅\n첆\n첇\n첈\n첉\n첊\n첋\n첌\n첍\n첎\n첏\n첐\n첑\n첒\n첓\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\n첔\n첕\n첖\n첗\n첚\n첛\n첝\n첞\n첟\n첡\n첢\n첣\n첤\n첥\n첦\n첧\n첪\n첮\n첯\n첰\n첱\n첲\n첳\n첶\n첷\n첹\n첺\n첻\n첽\n첾\n첿\n쳀\n쳁\n쳂\n쳃\n쳆\n쳈\n쳊\n쳋\n쳌\n쳍\n쳎\n쳏\n쳑\n쳒\n쳓\n쳕\n쳖\n쳗\n쳘\n쳙\n쳚\n쳛\n쳜\n쳝\n쳞\n쳟\n쳠\n쳡\n쳢\n쳣\n쳥\n쳦\n쳧\n쳨\n쳩\n쳪\n쳫\n쳭\n쳮\n쳯\n쳱\n쳲\n쳳\n쳴\n쳵\n쳶\n쳷\n쳸\n쳹\n쳺\n쳻\n쳼\n쳽\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\n쳾\n쳿\n촀\n촂\n촃\n촄\n촅\n촆\n촇\n촊\n촋\n촍\n촎\n촏\n촑\n촒\n촓\n촔\n촕\n촖\n촗\n촚\n촜\n촞\n촟\n촠\n촡\n촢\n촣\n촥\n촦\n촧\n촩\n촪\n촫\n촭\n촮\n촯\n촰\n촱\n촲\n촳\n촴\n촵\n촶\n촷\n촸\n촺\n촻\n촼\n촽\n촾\n촿\n쵀\n쵁\n쵂\n쵃\n쵄\n쵅\n쵆\n쵇\n쵈\n쵉\n쵊\n쵋\n쵌\n쵍\n쵎\n쵏\n쵐\n쵑\n쵒\n쵓\n쵔\n쵕\n쵖\n쵗\n쵘\n쵙\n쵚\n쵛\n쵝\n쵞\n쵟\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n쵡\n쵢\n쵣\n쵥\n쵦\n쵧\n쵨\n쵩\n쵪\n쵫\n쵮\n쵰\n쵲\n쵳\n쵴\n쵵\n쵶\n쵷\n쵹\n쵺\n쵻\n쵼\n쵽\n쵾\n쵿\n춀\n춁\n춂\n춃\n춄\n춅\n춆\n춇\n춉\n춊\n춋\n춌\n춍\n춎\n춏\n춐\n춑\n춒\n춓\n춖\n춗\n춙\n춚\n춛\n춝\n춞\n춟\n춠\n춡\n춢\n춣\n춦\n춨\n춪\n춫\n춬\n춭\n춮\n춯\n춱\n춲\n춳\n춴\n춵\n춶\n춷\n춸\n춹\n춺\n춻\n춼\n춽\n춾\n춿\n췀\n췁\n췂\n췃\n췅\n췆\n췇\n췈\n췉\n췊\n췋\n췍\n췎\n췏\n췑\n췒\n췓\n췔\n췕\n췖\n췗\n췘\n췙\n췚\n췛\n췜\n췝\n췞\n췟\n췠\n췡\n췢\n췣\n췤\n췥\n췦\n췧\n췩\n췪\n췫\n췭\n췮\n췯\n췱\n췲\n췳\n췴\n췵\n췶\n췷\n췺\n췼\n췾\n췿\n츀\n츁\n츂\n츃\n츅\n츆\n츇\n츉\n츊\n츋\n츍\n츎\n츏\n츐\n츑\n츒\n츓\n츕\n츖\n츗\n츘\n츚\n츛\n츜\n츝\n츞\n츟\n츢\n츣\n츥\n츦\n츧\n츩\n츪\n츫\n츬\n츭\n츮\n츯\n츲\n츴\n츶\n츷\n츸\n츹\n츺\n츻\n츼\n츽\n츾\n츿\n칀\n칁\n칂\n칃\n칄\n칅\n칆\n칇\n칈\n칉\n칊\n칋\n칌\n칍\n칎\n칏\n칐\n칑\n칒\n칓\n칔\n칕\n칖\n칗\n칚\n칛\n칝\n칞\n칢\n칣\n칤\n칥\n칦\n칧\n칪\n칬\n칮\n칯\n칰\n칱\n칲\n칳\n칶\n칷\n칹\n칺\n칻\n칽\n칾\n칿\n캀\n캁\n캂\n캃\n캆\n캈\n캊\n캋\n캌\n캍\n캎\n캏\n캒\n캓\n캕\n캖\n캗\n캙\n캚\n캛\n캜\n캝\n캞\n캟\n캢\n캦\n캧\n캨\n캩\n캪\n캫\n캮\n캯\n캰\n캱\n캲\n캳\n캴\n캵\n캶\n캷\n캸\n캹\n캺\n캻\n캼\n캽\n캾\n캿\n컀\n컂\n컃\n컄\n컅\n컆\n컇\n컈\n컉\n컊\n컋\n컌\n컍\n컎\n컏\n컐\n컑\n컒\n컓\n컔\n컕\n컖\n컗\n컘\n컙\n컚\n컛\n컜\n컝\n컞\n컟\n컠\n컡\n컢\n컣\n컦\n컧\n컩\n컪\n컭\n컮\n컯\n컰\n컱\n컲\n컳\n컶\n컺\n컻\n컼\n컽\n컾\n컿\n가\n각\n간\n갇\n갈\n갉\n갊\n감\n갑\n값\n갓\n갔\n강\n갖\n갗\n같\n갚\n갛\n개\n객\n갠\n갤\n갬\n갭\n갯\n갰\n갱\n갸\n갹\n갼\n걀\n걋\n걍\n걔\n걘\n걜\n거\n걱\n건\n걷\n걸\n걺\n검\n겁\n것\n겄\n겅\n겆\n겉\n겊\n겋\n게\n겐\n겔\n겜\n겝\n겟\n겠\n겡\n겨\n격\n겪\n견\n겯\n결\n겸\n겹\n겻\n겼\n경\n곁\n계\n곈\n곌\n곕\n곗\n고\n곡\n곤\n곧\n골\n곪\n곬\n곯\n곰\n곱\n곳\n공\n곶\n과\n곽\n관\n괄\n괆\n켂\n켃\n켅\n켆\n켇\n켉\n켊\n켋\n켌\n켍\n켎\n켏\n켒\n켔\n켖\n켗\n켘\n켙\n켚\n켛\n켝\n켞\n켟\n켡\n켢\n켣\n켥\n켦\n켧\n켨\n켩\n켪\n켫\n켮\n켲\n켳\n켴\n켵\n켶\n켷\n켹\n켺\n켻\n켼\n켽\n켾\n켿\n콀\n콁\n콂\n콃\n콄\n콅\n콆\n콇\n콈\n콉\n콊\n콋\n콌\n콍\n콎\n콏\n콐\n콑\n콒\n콓\n콖\n콗\n콙\n콚\n콛\n콝\n콞\n콟\n콠\n콡\n콢\n콣\n콦\n콨\n콪\n콫\n콬\n괌\n괍\n괏\n광\n괘\n괜\n괠\n괩\n괬\n괭\n괴\n괵\n괸\n괼\n굄\n굅\n굇\n굉\n교\n굔\n굘\n굡\n굣\n구\n국\n군\n굳\n굴\n굵\n굶\n굻\n굼\n굽\n굿\n궁\n궂\n궈\n궉\n권\n궐\n궜\n궝\n궤\n궷\n귀\n귁\n귄\n귈\n귐\n귑\n귓\n규\n균\n귤\n그\n극\n근\n귿\n글\n긁\n금\n급\n긋\n긍\n긔\n기\n긱\n긴\n긷\n길\n긺\n김\n깁\n깃\n깅\n깆\n깊\n까\n깍\n깎\n깐\n깔\n깖\n깜\n깝\n깟\n깠\n깡\n깥\n깨\n깩\n깬\n깰\n깸\n콭\n콮\n콯\n콲\n콳\n콵\n콶\n콷\n콹\n콺\n콻\n콼\n콽\n콾\n콿\n쾁\n쾂\n쾃\n쾄\n쾆\n쾇\n쾈\n쾉\n쾊\n쾋\n쾍\n쾎\n쾏\n쾐\n쾑\n쾒\n쾓\n쾔\n쾕\n쾖\n쾗\n쾘\n쾙\n쾚\n쾛\n쾜\n쾝\n쾞\n쾟\n쾠\n쾢\n쾣\n쾤\n쾥\n쾦\n쾧\n쾩\n쾪\n쾫\n쾬\n쾭\n쾮\n쾯\n쾱\n쾲\n쾳\n쾴\n쾵\n쾶\n쾷\n쾸\n쾹\n쾺\n쾻\n쾼\n쾽\n쾾\n쾿\n쿀\n쿁\n쿂\n쿃\n쿅\n쿆\n쿇\n쿈\n쿉\n쿊\n쿋\n깹\n깻\n깼\n깽\n꺄\n꺅\n꺌\n꺼\n꺽\n꺾\n껀\n껄\n껌\n껍\n껏\n껐\n껑\n께\n껙\n껜\n껨\n껫\n껭\n껴\n껸\n껼\n꼇\n꼈\n꼍\n꼐\n꼬\n꼭\n꼰\n꼲\n꼴\n꼼\n꼽\n꼿\n꽁\n꽂\n꽃\n꽈\n꽉\n꽐\n꽜\n꽝\n꽤\n꽥\n꽹\n꾀\n꾄\n꾈\n꾐\n꾑\n꾕\n꾜\n꾸\n꾹\n꾼\n꿀\n꿇\n꿈\n꿉\n꿋\n꿍\n꿎\n꿔\n꿜\n꿨\n꿩\n꿰\n꿱\n꿴\n꿸\n뀀\n뀁\n뀄\n뀌\n뀐\n뀔\n뀜\n뀝\n뀨\n끄\n끅\n끈\n끊\n끌\n끎\n끓\n끔\n끕\n끗\n끙\n쿌\n쿍\n쿎\n쿏\n쿐\n쿑\n쿒\n쿓\n쿔\n쿕\n쿖\n쿗\n쿘\n쿙\n쿚\n쿛\n쿜\n쿝\n쿞\n쿟\n쿢\n쿣\n쿥\n쿦\n쿧\n쿩\n쿪\n쿫\n쿬\n쿭\n쿮\n쿯\n쿲\n쿴\n쿶\n쿷\n쿸\n쿹\n쿺\n쿻\n쿽\n쿾\n쿿\n퀁\n퀂\n퀃\n퀅\n퀆\n퀇\n퀈\n퀉\n퀊\n퀋\n퀌\n퀍\n퀎\n퀏\n퀐\n퀒\n퀓\n퀔\n퀕\n퀖\n퀗\n퀙\n퀚\n퀛\n퀜\n퀝\n퀞\n퀟\n퀠\n퀡\n퀢\n퀣\n퀤\n퀥\n퀦\n퀧\n퀨\n퀩\n퀪\n퀫\n퀬\n끝\n끼\n끽\n낀\n낄\n낌\n낍\n낏\n낑\n나\n낙\n낚\n난\n낟\n날\n낡\n낢\n남\n납\n낫\n났\n낭\n낮\n낯\n낱\n낳\n내\n낵\n낸\n낼\n냄\n냅\n냇\n냈\n냉\n냐\n냑\n냔\n냘\n냠\n냥\n너\n넉\n넋\n넌\n널\n넒\n넓\n넘\n넙\n넛\n넜\n넝\n넣\n네\n넥\n넨\n넬\n넴\n넵\n넷\n넸\n넹\n녀\n녁\n년\n녈\n념\n녑\n녔\n녕\n녘\n녜\n녠\n노\n녹\n논\n놀\n놂\n놈\n놉\n놋\n농\n높\n놓\n놔\n놘\n놜\n놨\n뇌\n뇐\n뇔\n뇜\n뇝\n퀮\n퀯\n퀰\n퀱\n퀲\n퀳\n퀶\n퀷\n퀹\n퀺\n퀻\n퀽\n퀾\n퀿\n큀\n큁\n큂\n큃\n큆\n큈\n큊\n큋\n큌\n큍\n큎\n큏\n큑\n큒\n큓\n큕\n큖\n큗\n큙\n큚\n큛\n큜\n큝\n큞\n큟\n큡\n큢\n큣\n큤\n큥\n큦\n큧\n큨\n큩\n큪\n큫\n큮\n큯\n큱\n큲\n큳\n큵\n큶\n큷\n큸\n큹\n큺\n큻\n큾\n큿\n킀\n킂\n킃\n킄\n킅\n킆\n킇\n킈\n킉\n킊\n킋\n킌\n킍\n킎\n킏\n킐\n킑\n킒\n킓\n킔\n뇟\n뇨\n뇩\n뇬\n뇰\n뇹\n뇻\n뇽\n누\n눅\n눈\n눋\n눌\n눔\n눕\n눗\n눙\n눠\n눴\n눼\n뉘\n뉜\n뉠\n뉨\n뉩\n뉴\n뉵\n뉼\n늄\n늅\n늉\n느\n늑\n는\n늘\n늙\n늚\n늠\n늡\n늣\n능\n늦\n늪\n늬\n늰\n늴\n니\n닉\n닌\n닐\n닒\n님\n닙\n닛\n닝\n닢\n다\n닥\n닦\n단\n닫\n달\n닭\n닮\n닯\n닳\n담\n답\n닷\n닸\n당\n닺\n닻\n닿\n대\n댁\n댄\n댈\n댐\n댑\n댓\n댔\n댕\n댜\n더\n덕\n덖\n던\n덛\n덜\n덞\n덟\n덤\n덥\n킕\n킖\n킗\n킘\n킙\n킚\n킛\n킜\n킝\n킞\n킟\n킠\n킡\n킢\n킣\n킦\n킧\n킩\n킪\n킫\n킭\n킮\n킯\n킰\n킱\n킲\n킳\n킶\n킸\n킺\n킻\n킼\n킽\n킾\n킿\n탂\n탃\n탅\n탆\n탇\n탊\n탋\n탌\n탍\n탎\n탏\n탒\n탖\n탗\n탘\n탙\n탚\n탛\n탞\n탟\n탡\n탢\n탣\n탥\n탦\n탧\n탨\n탩\n탪\n탫\n탮\n탲\n탳\n탴\n탵\n탶\n탷\n탹\n탺\n탻\n탼\n탽\n탾\n탿\n턀\n턁\n턂\n턃\n턄\n덧\n덩\n덫\n덮\n데\n덱\n덴\n델\n뎀\n뎁\n뎃\n뎄\n뎅\n뎌\n뎐\n뎔\n뎠\n뎡\n뎨\n뎬\n도\n독\n돈\n돋\n돌\n돎\n돐\n돔\n돕\n돗\n동\n돛\n돝\n돠\n돤\n돨\n돼\n됐\n되\n된\n될\n됨\n됩\n됫\n됴\n두\n둑\n둔\n둘\n둠\n둡\n둣\n둥\n둬\n뒀\n뒈\n뒝\n뒤\n뒨\n뒬\n뒵\n뒷\n뒹\n듀\n듄\n듈\n듐\n듕\n드\n득\n든\n듣\n들\n듦\n듬\n듭\n듯\n등\n듸\n디\n딕\n딘\n딛\n딜\n딤\n딥\n딧\n딨\n딩\n딪\n따\n딱\n딴\n딸\n턅\n턆\n턇\n턈\n턉\n턊\n턋\n턌\n턎\n턏\n턐\n턑\n턒\n턓\n턔\n턕\n턖\n턗\n턘\n턙\n턚\n턛\n턜\n턝\n턞\n턟\n턠\n턡\n턢\n턣\n턤\n턥\n턦\n턧\n턨\n턩\n턪\n턫\n턬\n턭\n턮\n턯\n턲\n턳\n턵\n턶\n턷\n턹\n턻\n턼\n턽\n턾\n턿\n텂\n텆\n텇\n텈\n텉\n텊\n텋\n텎\n텏\n텑\n텒\n텓\n텕\n텖\n텗\n텘\n텙\n텚\n텛\n텞\n텠\n텢\n텣\n텤\n텥\n텦\n텧\n텩\n텪\n텫\n텭\n땀\n땁\n땃\n땄\n땅\n땋\n때\n땍\n땐\n땔\n땜\n땝\n땟\n땠\n땡\n떠\n떡\n떤\n떨\n떪\n떫\n떰\n떱\n떳\n떴\n떵\n떻\n떼\n떽\n뗀\n뗄\n뗌\n뗍\n뗏\n뗐\n뗑\n뗘\n뗬\n또\n똑\n똔\n똘\n똥\n똬\n똴\n뙈\n뙤\n뙨\n뚜\n뚝\n뚠\n뚤\n뚫\n뚬\n뚱\n뛔\n뛰\n뛴\n뛸\n뜀\n뜁\n뜅\n뜨\n뜩\n뜬\n뜯\n뜰\n뜸\n뜹\n뜻\n띄\n띈\n띌\n띔\n띕\n띠\n띤\n띨\n띰\n띱\n띳\n띵\n라\n락\n란\n랄\n람\n랍\n랏\n랐\n랑\n랒\n랖\n랗\n텮\n텯\n텰\n텱\n텲\n텳\n텴\n텵\n텶\n텷\n텸\n텹\n텺\n텻\n텽\n텾\n텿\n톀\n톁\n톂\n톃\n톅\n톆\n톇\n톉\n톊\n톋\n톌\n톍\n톎\n톏\n톐\n톑\n톒\n톓\n톔\n톕\n톖\n톗\n톘\n톙\n톚\n톛\n톜\n톝\n톞\n톟\n톢\n톣\n톥\n톦\n톧\n톩\n톪\n톫\n톬\n톭\n톮\n톯\n톲\n톴\n톶\n톷\n톸\n톹\n톻\n톽\n톾\n톿\n퇁\n퇂\n퇃\n퇄\n퇅\n퇆\n퇇\n퇈\n퇉\n퇊\n퇋\n퇌\n퇍\n퇎\n퇏\n래\n랙\n랜\n랠\n램\n랩\n랫\n랬\n랭\n랴\n략\n랸\n럇\n량\n러\n럭\n런\n럴\n럼\n럽\n럿\n렀\n렁\n렇\n레\n렉\n렌\n렐\n렘\n렙\n렛\n렝\n려\n력\n련\n렬\n렴\n렵\n렷\n렸\n령\n례\n롄\n롑\n롓\n로\n록\n론\n롤\n롬\n롭\n롯\n롱\n롸\n롼\n뢍\n뢨\n뢰\n뢴\n뢸\n룀\n룁\n룃\n룅\n료\n룐\n룔\n룝\n룟\n룡\n루\n룩\n룬\n룰\n룸\n룹\n룻\n룽\n뤄\n뤘\n뤠\n뤼\n뤽\n륀\n륄\n륌\n륏\n륑\n류\n륙\n륜\n률\n륨\n륩\n퇐\n퇑\n퇒\n퇓\n퇔\n퇕\n퇖\n퇗\n퇙\n퇚\n퇛\n퇜\n퇝\n퇞\n퇟\n퇠\n퇡\n퇢\n퇣\n퇤\n퇥\n퇦\n퇧\n퇨\n퇩\n퇪\n퇫\n퇬\n퇭\n퇮\n퇯\n퇰\n퇱\n퇲\n퇳\n퇵\n퇶\n퇷\n퇹\n퇺\n퇻\n퇼\n퇽\n퇾\n퇿\n툀\n툁\n툂\n툃\n툄\n툅\n툆\n툈\n툊\n툋\n툌\n툍\n툎\n툏\n툑\n툒\n툓\n툔\n툕\n툖\n툗\n툘\n툙\n툚\n툛\n툜\n툝\n툞\n툟\n툠\n툡\n툢\n툣\n툤\n툥\n툦\n툧\n툨\n툩\n륫\n륭\n르\n륵\n른\n를\n름\n릅\n릇\n릉\n릊\n릍\n릎\n리\n릭\n린\n릴\n림\n립\n릿\n링\n마\n막\n만\n많\n맏\n말\n맑\n맒\n맘\n맙\n맛\n망\n맞\n맡\n맣\n매\n맥\n맨\n맬\n맴\n맵\n맷\n맸\n맹\n맺\n먀\n먁\n먈\n먕\n머\n먹\n먼\n멀\n멂\n멈\n멉\n멋\n멍\n멎\n멓\n메\n멕\n멘\n멜\n멤\n멥\n멧\n멨\n멩\n며\n멱\n면\n멸\n몃\n몄\n명\n몇\n몌\n모\n목\n몫\n몬\n몰\n몲\n몸\n몹\n못\n몽\n뫄\n뫈\n뫘\n뫙\n뫼\n툪\n툫\n툮\n툯\n툱\n툲\n툳\n툵\n툶\n툷\n툸\n툹\n툺\n툻\n툾\n퉀\n퉂\n퉃\n퉄\n퉅\n퉆\n퉇\n퉉\n퉊\n퉋\n퉌\n퉍\n퉎\n퉏\n퉐\n퉑\n퉒\n퉓\n퉔\n퉕\n퉖\n퉗\n퉘\n퉙\n퉚\n퉛\n퉝\n퉞\n퉟\n퉠\n퉡\n퉢\n퉣\n퉥\n퉦\n퉧\n퉨\n퉩\n퉪\n퉫\n퉬\n퉭\n퉮\n퉯\n퉰\n퉱\n퉲\n퉳\n퉴\n퉵\n퉶\n퉷\n퉸\n퉹\n퉺\n퉻\n퉼\n퉽\n퉾\n퉿\n튂\n튃\n튅\n튆\n튇\n튉\n튊\n튋\n튌\n묀\n묄\n묍\n묏\n묑\n묘\n묜\n묠\n묩\n묫\n무\n묵\n묶\n문\n묻\n물\n묽\n묾\n뭄\n뭅\n뭇\n뭉\n뭍\n뭏\n뭐\n뭔\n뭘\n뭡\n뭣\n뭬\n뮈\n뮌\n뮐\n뮤\n뮨\n뮬\n뮴\n뮷\n므\n믄\n믈\n믐\n믓\n미\n믹\n민\n믿\n밀\n밂\n밈\n밉\n밋\n밌\n밍\n및\n밑\n바\n박\n밖\n밗\n반\n받\n발\n밝\n밞\n밟\n밤\n밥\n밧\n방\n밭\n배\n백\n밴\n밸\n뱀\n뱁\n뱃\n뱄\n뱅\n뱉\n뱌\n뱍\n뱐\n뱝\n버\n벅\n번\n벋\n벌\n벎\n범\n법\n벗\n튍\n튎\n튏\n튒\n튓\n튔\n튖\n튗\n튘\n튙\n튚\n튛\n튝\n튞\n튟\n튡\n튢\n튣\n튥\n튦\n튧\n튨\n튩\n튪\n튫\n튭\n튮\n튯\n튰\n튲\n튳\n튴\n튵\n튶\n튷\n튺\n튻\n튽\n튾\n틁\n틃\n틄\n틅\n틆\n틇\n틊\n틌\n틍\n틎\n틏\n틐\n틑\n틒\n틓\n틕\n틖\n틗\n틙\n틚\n틛\n틝\n틞\n틟\n틠\n틡\n틢\n틣\n틦\n틧\n틨\n틩\n틪\n틫\n틬\n틭\n틮\n틯\n틲\n틳\n틵\n틶\n틷\n틹\n틺\n벙\n벚\n베\n벡\n벤\n벧\n벨\n벰\n벱\n벳\n벴\n벵\n벼\n벽\n변\n별\n볍\n볏\n볐\n병\n볕\n볘\n볜\n보\n복\n볶\n본\n볼\n봄\n봅\n봇\n봉\n봐\n봔\n봤\n봬\n뵀\n뵈\n뵉\n뵌\n뵐\n뵘\n뵙\n뵤\n뵨\n부\n북\n분\n붇\n불\n붉\n붊\n붐\n붑\n붓\n붕\n붙\n붚\n붜\n붤\n붰\n붸\n뷔\n뷕\n뷘\n뷜\n뷩\n뷰\n뷴\n뷸\n븀\n븃\n븅\n브\n븍\n븐\n블\n븜\n븝\n븟\n비\n빅\n빈\n빌\n빎\n빔\n빕\n빗\n빙\n빚\n빛\n빠\n빡\n빤\n틻\n틼\n틽\n틾\n틿\n팂\n팄\n팆\n팇\n팈\n팉\n팊\n팋\n팏\n팑\n팒\n팓\n팕\n팗\n팘\n팙\n팚\n팛\n팞\n팢\n팣\n팤\n팦\n팧\n팪\n팫\n팭\n팮\n팯\n팱\n팲\n팳\n팴\n팵\n팶\n팷\n팺\n팾\n팿\n퍀\n퍁\n퍂\n퍃\n퍆\n퍇\n퍈\n퍉\n퍊\n퍋\n퍌\n퍍\n퍎\n퍏\n퍐\n퍑\n퍒\n퍓\n퍔\n퍕\n퍖\n퍗\n퍘\n퍙\n퍚\n퍛\n퍜\n퍝\n퍞\n퍟\n퍠\n퍡\n퍢\n퍣\n퍤\n퍥\n퍦\n퍧\n퍨\n퍩\n빨\n빪\n빰\n빱\n빳\n빴\n빵\n빻\n빼\n빽\n뺀\n뺄\n뺌\n뺍\n뺏\n뺐\n뺑\n뺘\n뺙\n뺨\n뻐\n뻑\n뻔\n뻗\n뻘\n뻠\n뻣\n뻤\n뻥\n뻬\n뼁\n뼈\n뼉\n뼘\n뼙\n뼛\n뼜\n뼝\n뽀\n뽁\n뽄\n뽈\n뽐\n뽑\n뽕\n뾔\n뾰\n뿅\n뿌\n뿍\n뿐\n뿔\n뿜\n뿟\n뿡\n쀼\n쁑\n쁘\n쁜\n쁠\n쁨\n쁩\n삐\n삑\n삔\n삘\n삠\n삡\n삣\n삥\n사\n삭\n삯\n산\n삳\n살\n삵\n삶\n삼\n삽\n삿\n샀\n상\n샅\n새\n색\n샌\n샐\n샘\n샙\n샛\n샜\n생\n샤\n퍪\n퍫\n퍬\n퍭\n퍮\n퍯\n퍰\n퍱\n퍲\n퍳\n퍴\n퍵\n퍶\n퍷\n퍸\n퍹\n퍺\n퍻\n퍾\n퍿\n펁\n펂\n펃\n펅\n펆\n펇\n펈\n펉\n펊\n펋\n펎\n펒\n펓\n펔\n펕\n펖\n펗\n펚\n펛\n펝\n펞\n펟\n펡\n펢\n펣\n펤\n펥\n펦\n펧\n펪\n펬\n펮\n펯\n펰\n펱\n펲\n펳\n펵\n펶\n펷\n펹\n펺\n펻\n펽\n펾\n펿\n폀\n폁\n폂\n폃\n폆\n폇\n폊\n폋\n폌\n폍\n폎\n폏\n폑\n폒\n폓\n폔\n폕\n폖\n샥\n샨\n샬\n샴\n샵\n샷\n샹\n섀\n섄\n섈\n섐\n섕\n서\n석\n섞\n섟\n선\n섣\n설\n섦\n섧\n섬\n섭\n섯\n섰\n성\n섶\n세\n섹\n센\n셀\n셈\n셉\n셋\n셌\n셍\n셔\n셕\n션\n셜\n셤\n셥\n셧\n셨\n셩\n셰\n셴\n셸\n솅\n소\n속\n솎\n손\n솔\n솖\n솜\n솝\n솟\n송\n솥\n솨\n솩\n솬\n솰\n솽\n쇄\n쇈\n쇌\n쇔\n쇗\n쇘\n쇠\n쇤\n쇨\n쇰\n쇱\n쇳\n쇼\n쇽\n숀\n숄\n숌\n숍\n숏\n숑\n수\n숙\n순\n숟\n술\n숨\n숩\n숫\n숭\n폗\n폙\n폚\n폛\n폜\n폝\n폞\n폟\n폠\n폢\n폤\n폥\n폦\n폧\n폨\n폩\n폪\n폫\n폮\n폯\n폱\n폲\n폳\n폵\n폶\n폷\n폸\n폹\n폺\n폻\n폾\n퐀\n퐂\n퐃\n퐄\n퐅\n퐆\n퐇\n퐉\n퐊\n퐋\n퐌\n퐍\n퐎\n퐏\n퐐\n퐑\n퐒\n퐓\n퐔\n퐕\n퐖\n퐗\n퐘\n퐙\n퐚\n퐛\n퐜\n퐞\n퐟\n퐠\n퐡\n퐢\n퐣\n퐤\n퐥\n퐦\n퐧\n퐨\n퐩\n퐪\n퐫\n퐬\n퐭\n퐮\n퐯\n퐰\n퐱\n퐲\n퐳\n퐴\n퐵\n퐶\n퐷\n숯\n숱\n숲\n숴\n쉈\n쉐\n쉑\n쉔\n쉘\n쉠\n쉥\n쉬\n쉭\n쉰\n쉴\n쉼\n쉽\n쉿\n슁\n슈\n슉\n슐\n슘\n슛\n슝\n스\n슥\n슨\n슬\n슭\n슴\n습\n슷\n승\n시\n식\n신\n싣\n실\n싫\n심\n십\n싯\n싱\n싶\n싸\n싹\n싻\n싼\n쌀\n쌈\n쌉\n쌌\n쌍\n쌓\n쌔\n쌕\n쌘\n쌜\n쌤\n쌥\n쌨\n쌩\n썅\n써\n썩\n썬\n썰\n썲\n썸\n썹\n썼\n썽\n쎄\n쎈\n쎌\n쏀\n쏘\n쏙\n쏜\n쏟\n쏠\n쏢\n쏨\n쏩\n쏭\n쏴\n쏵\n쏸\n쐈\n쐐\n쐤\n쐬\n쐰\n퐸\n퐹\n퐺\n퐻\n퐼\n퐽\n퐾\n퐿\n푁\n푂\n푃\n푅\n푆\n푇\n푈\n푉\n푊\n푋\n푌\n푍\n푎\n푏\n푐\n푑\n푒\n푓\n푔\n푕\n푖\n푗\n푘\n푙\n푚\n푛\n푝\n푞\n푟\n푡\n푢\n푣\n푥\n푦\n푧\n푨\n푩\n푪\n푫\n푬\n푮\n푰\n푱\n푲\n푳\n푴\n푵\n푶\n푷\n푺\n푻\n푽\n푾\n풁\n풃\n풄\n풅\n풆\n풇\n풊\n풌\n풎\n풏\n풐\n풑\n풒\n풓\n풕\n풖\n풗\n풘\n풙\n풚\n풛\n풜\n풝\n쐴\n쐼\n쐽\n쑈\n쑤\n쑥\n쑨\n쑬\n쑴\n쑵\n쑹\n쒀\n쒔\n쒜\n쒸\n쒼\n쓩\n쓰\n쓱\n쓴\n쓸\n쓺\n쓿\n씀\n씁\n씌\n씐\n씔\n씜\n씨\n씩\n씬\n씰\n씸\n씹\n씻\n씽\n아\n악\n안\n앉\n않\n알\n앍\n앎\n앓\n암\n압\n앗\n았\n앙\n앝\n앞\n애\n액\n앤\n앨\n앰\n앱\n앳\n앴\n앵\n야\n약\n얀\n얄\n얇\n얌\n얍\n얏\n양\n얕\n얗\n얘\n얜\n얠\n얩\n어\n억\n언\n얹\n얻\n얼\n얽\n얾\n엄\n업\n없\n엇\n었\n엉\n엊\n엌\n엎\n풞\n풟\n풠\n풡\n풢\n풣\n풤\n풥\n풦\n풧\n풨\n풪\n풫\n풬\n풭\n풮\n풯\n풰\n풱\n풲\n풳\n풴\n풵\n풶\n풷\n풸\n풹\n풺\n풻\n풼\n풽\n풾\n풿\n퓀\n퓁\n퓂\n퓃\n퓄\n퓅\n퓆\n퓇\n퓈\n퓉\n퓊\n퓋\n퓍\n퓎\n퓏\n퓑\n퓒\n퓓\n퓕\n퓖\n퓗\n퓘\n퓙\n퓚\n퓛\n퓝\n퓞\n퓠\n퓡\n퓢\n퓣\n퓤\n퓥\n퓦\n퓧\n퓩\n퓪\n퓫\n퓭\n퓮\n퓯\n퓱\n퓲\n퓳\n퓴\n퓵\n퓶\n퓷\n퓹\n퓺\n퓼\n에\n엑\n엔\n엘\n엠\n엡\n엣\n엥\n여\n역\n엮\n연\n열\n엶\n엷\n염\n엽\n엾\n엿\n였\n영\n옅\n옆\n옇\n예\n옌\n옐\n옘\n옙\n옛\n옜\n오\n옥\n온\n올\n옭\n옮\n옰\n옳\n옴\n옵\n옷\n옹\n옻\n와\n왁\n완\n왈\n왐\n왑\n왓\n왔\n왕\n왜\n왝\n왠\n왬\n왯\n왱\n외\n왹\n왼\n욀\n욈\n욉\n욋\n욍\n요\n욕\n욘\n욜\n욤\n욥\n욧\n용\n우\n욱\n운\n울\n욹\n욺\n움\n웁\n웃\n웅\n워\n웍\n원\n월\n웜\n웝\n웠\n웡\n웨\n퓾\n퓿\n픀\n픁\n픂\n픃\n픅\n픆\n픇\n픉\n픊\n픋\n픍\n픎\n픏\n픐\n픑\n픒\n픓\n픖\n픘\n픙\n픚\n픛\n픜\n픝\n픞\n픟\n픠\n픡\n픢\n픣\n픤\n픥\n픦\n픧\n픨\n픩\n픪\n픫\n픬\n픭\n픮\n픯\n픰\n픱\n픲\n픳\n픴\n픵\n픶\n픷\n픸\n픹\n픺\n픻\n픾\n픿\n핁\n핂\n핃\n핅\n핆\n핇\n핈\n핉\n핊\n핋\n핎\n핐\n핒\n핓\n핔\n핕\n핖\n핗\n핚\n핛\n핝\n핞\n핟\n핡\n핢\n핣\n웩\n웬\n웰\n웸\n웹\n웽\n위\n윅\n윈\n윌\n윔\n윕\n윗\n윙\n유\n육\n윤\n율\n윰\n윱\n윳\n융\n윷\n으\n윽\n은\n을\n읊\n음\n읍\n읏\n응\n읒\n읓\n읔\n읕\n읖\n읗\n의\n읜\n읠\n읨\n읫\n이\n익\n인\n일\n읽\n읾\n잃\n임\n입\n잇\n있\n잉\n잊\n잎\n자\n작\n잔\n잖\n잗\n잘\n잚\n잠\n잡\n잣\n잤\n장\n잦\n재\n잭\n잰\n잴\n잼\n잽\n잿\n쟀\n쟁\n쟈\n쟉\n쟌\n쟎\n쟐\n쟘\n쟝\n쟤\n쟨\n쟬\n저\n적\n전\n절\n젊\n핤\n핦\n핧\n핪\n핬\n핮\n핯\n핰\n핱\n핲\n핳\n핶\n핷\n핹\n핺\n핻\n핽\n핾\n핿\n햀\n햁\n햂\n햃\n햆\n햊\n햋\n햌\n햍\n햎\n햏\n햑\n햒\n햓\n햔\n햕\n햖\n햗\n햘\n햙\n햚\n햛\n햜\n햝\n햞\n햟\n햠\n햡\n햢\n햣\n햤\n햦\n햧\n햨\n햩\n햪\n햫\n햬\n햭\n햮\n햯\n햰\n햱\n햲\n햳\n햴\n햵\n햶\n햷\n햸\n햹\n햺\n햻\n햼\n햽\n햾\n햿\n헀\n헁\n헂\n헃\n헄\n헅\n헆\n헇\n점\n접\n젓\n정\n젖\n제\n젝\n젠\n젤\n젬\n젭\n젯\n젱\n져\n젼\n졀\n졈\n졉\n졌\n졍\n졔\n조\n족\n존\n졸\n졺\n좀\n좁\n좃\n종\n좆\n좇\n좋\n좌\n좍\n좔\n좝\n좟\n좡\n좨\n좼\n좽\n죄\n죈\n죌\n죔\n죕\n죗\n죙\n죠\n죡\n죤\n죵\n주\n죽\n준\n줄\n줅\n줆\n줌\n줍\n줏\n중\n줘\n줬\n줴\n쥐\n쥑\n쥔\n쥘\n쥠\n쥡\n쥣\n쥬\n쥰\n쥴\n쥼\n즈\n즉\n즌\n즐\n즘\n즙\n즛\n증\n지\n직\n진\n짇\n질\n짊\n짐\n집\n짓\n헊\n헋\n헍\n헎\n헏\n헑\n헓\n헔\n헕\n헖\n헗\n헚\n헜\n헞\n헟\n헠\n헡\n헢\n헣\n헦\n헧\n헩\n헪\n헫\n헭\n헮\n헯\n헰\n헱\n헲\n헳\n헶\n헸\n헺\n헻\n헼\n헽\n헾\n헿\n혂\n혃\n혅\n혆\n혇\n혉\n혊\n혋\n혌\n혍\n혎\n혏\n혒\n혖\n혗\n혘\n혙\n혚\n혛\n혝\n혞\n혟\n혡\n혢\n혣\n혥\n혦\n혧\n혨\n혩\n혪\n혫\n혬\n혮\n혯\n혰\n혱\n혲\n혳\n혴\n혵\n혶\n혷\n혺\n혻\n징\n짖\n짙\n짚\n짜\n짝\n짠\n짢\n짤\n짧\n짬\n짭\n짯\n짰\n짱\n째\n짹\n짼\n쨀\n쨈\n쨉\n쨋\n쨌\n쨍\n쨔\n쨘\n쨩\n쩌\n쩍\n쩐\n쩔\n쩜\n쩝\n쩟\n쩠\n쩡\n쩨\n쩽\n쪄\n쪘\n쪼\n쪽\n쫀\n쫄\n쫌\n쫍\n쫏\n쫑\n쫓\n쫘\n쫙\n쫠\n쫬\n쫴\n쬈\n쬐\n쬔\n쬘\n쬠\n쬡\n쭁\n쭈\n쭉\n쭌\n쭐\n쭘\n쭙\n쭝\n쭤\n쭸\n쭹\n쮜\n쮸\n쯔\n쯤\n쯧\n쯩\n찌\n찍\n찐\n찔\n찜\n찝\n찡\n찢\n찧\n차\n착\n찬\n찮\n찰\n참\n찹\n찻\n혽\n혾\n혿\n홁\n홂\n홃\n홄\n홆\n홇\n홊\n홌\n홎\n홏\n홐\n홒\n홓\n홖\n홗\n홙\n홚\n홛\n홝\n홞\n홟\n홠\n홡\n홢\n홣\n홤\n홥\n홦\n홨\n홪\n홫\n홬\n홭\n홮\n홯\n홲\n홳\n홵\n홶\n홷\n홸\n홹\n홺\n홻\n홼\n홽\n홾\n홿\n횀\n횁\n횂\n횄\n횆\n횇\n횈\n횉\n횊\n횋\n횎\n횏\n횑\n횒\n횓\n횕\n횖\n횗\n횘\n횙\n횚\n횛\n횜\n횞\n횠\n횢\n횣\n횤\n횥\n횦\n횧\n횩\n횪\n찼\n창\n찾\n채\n책\n챈\n챌\n챔\n챕\n챗\n챘\n챙\n챠\n챤\n챦\n챨\n챰\n챵\n처\n척\n천\n철\n첨\n첩\n첫\n첬\n청\n체\n첵\n첸\n첼\n쳄\n쳅\n쳇\n쳉\n쳐\n쳔\n쳤\n쳬\n쳰\n촁\n초\n촉\n촌\n촐\n촘\n촙\n촛\n총\n촤\n촨\n촬\n촹\n최\n쵠\n쵤\n쵬\n쵭\n쵯\n쵱\n쵸\n춈\n추\n축\n춘\n출\n춤\n춥\n춧\n충\n춰\n췄\n췌\n췐\n취\n췬\n췰\n췸\n췹\n췻\n췽\n츄\n츈\n츌\n츔\n츙\n츠\n측\n츤\n츨\n츰\n츱\n츳\n층\n횫\n횭\n횮\n횯\n횱\n횲\n횳\n횴\n횵\n횶\n횷\n횸\n횺\n횼\n횽\n횾\n횿\n훀\n훁\n훂\n훃\n훆\n훇\n훉\n훊\n훋\n훍\n훎\n훏\n훐\n훒\n훓\n훕\n훖\n훘\n훚\n훛\n훜\n훝\n훞\n훟\n훡\n훢\n훣\n훥\n훦\n훧\n훩\n훪\n훫\n훬\n훭\n훮\n훯\n훱\n훲\n훳\n훴\n훶\n훷\n훸\n훹\n훺\n훻\n훾\n훿\n휁\n휂\n휃\n휅\n휆\n휇\n휈\n휉\n휊\n휋\n휌\n휍\n휎\n휏\n휐\n휒\n휓\n휔\n치\n칙\n친\n칟\n칠\n칡\n침\n칩\n칫\n칭\n카\n칵\n칸\n칼\n캄\n캅\n캇\n캉\n캐\n캑\n캔\n캘\n캠\n캡\n캣\n캤\n캥\n캬\n캭\n컁\n커\n컥\n컨\n컫\n컬\n컴\n컵\n컷\n컸\n컹\n케\n켁\n켄\n켈\n켐\n켑\n켓\n켕\n켜\n켠\n켤\n켬\n켭\n켯\n켰\n켱\n켸\n코\n콕\n콘\n콜\n콤\n콥\n콧\n콩\n콰\n콱\n콴\n콸\n쾀\n쾅\n쾌\n쾡\n쾨\n쾰\n쿄\n쿠\n쿡\n쿤\n쿨\n쿰\n쿱\n쿳\n쿵\n쿼\n퀀\n퀄\n퀑\n퀘\n퀭\n퀴\n퀵\n퀸\n퀼\n휕\n휖\n휗\n휚\n휛\n휝\n휞\n휟\n휡\n휢\n휣\n휤\n휥\n휦\n휧\n휪\n휬\n휮\n휯\n휰\n휱\n휲\n휳\n휶\n휷\n휹\n휺\n휻\n휽\n휾\n휿\n흀\n흁\n흂\n흃\n흅\n흆\n흈\n흊\n흋\n흌\n흍\n흎\n흏\n흒\n흓\n흕\n흚\n흛\n흜\n흝\n흞\n흟\n흢\n흤\n흦\n흧\n흨\n흪\n흫\n흭\n흮\n흯\n흱\n흲\n흳\n흵\n흶\n흷\n흸\n흹\n흺\n흻\n흾\n흿\n힀\n힂\n힃\n힄\n힅\n힆\n힇\n힊\n힋\n큄\n큅\n큇\n큉\n큐\n큔\n큘\n큠\n크\n큭\n큰\n클\n큼\n큽\n킁\n키\n킥\n킨\n킬\n킴\n킵\n킷\n킹\n타\n탁\n탄\n탈\n탉\n탐\n탑\n탓\n탔\n탕\n태\n택\n탠\n탤\n탬\n탭\n탯\n탰\n탱\n탸\n턍\n터\n턱\n턴\n털\n턺\n텀\n텁\n텃\n텄\n텅\n테\n텍\n텐\n텔\n템\n텝\n텟\n텡\n텨\n텬\n텼\n톄\n톈\n토\n톡\n톤\n톨\n톰\n톱\n톳\n통\n톺\n톼\n퇀\n퇘\n퇴\n퇸\n툇\n툉\n툐\n투\n툭\n툰\n툴\n툼\n툽\n툿\n퉁\n퉈\n퉜\n힍\n힎\n힏\n힑\n힒\n힓\n힔\n힕\n힖\n힗\n힚\n힜\n힞\n힟\n힠\n힡\n힢\n힣\n퉤\n튀\n튁\n튄\n튈\n튐\n튑\n튕\n튜\n튠\n튤\n튬\n튱\n트\n특\n튼\n튿\n틀\n틂\n틈\n틉\n틋\n틔\n틘\n틜\n틤\n틥\n티\n틱\n틴\n틸\n팀\n팁\n팃\n팅\n파\n팍\n팎\n판\n팔\n팖\n팜\n팝\n팟\n팠\n팡\n팥\n패\n팩\n팬\n팰\n팸\n팹\n팻\n팼\n팽\n퍄\n퍅\n퍼\n퍽\n펀\n펄\n펌\n펍\n펏\n펐\n펑\n페\n펙\n펜\n펠\n펨\n펩\n펫\n펭\n펴\n편\n펼\n폄\n폅\n폈\n평\n폐\n폘\n폡\n폣\n포\n폭\n폰\n폴\n폼\n폽\n폿\n퐁\n퐈\n퐝\n푀\n푄\n표\n푠\n푤\n푭\n푯\n푸\n푹\n푼\n푿\n풀\n풂\n품\n풉\n풋\n풍\n풔\n풩\n퓌\n퓐\n퓔\n퓜\n퓟\n퓨\n퓬\n퓰\n퓸\n퓻\n퓽\n프\n픈\n플\n픔\n픕\n픗\n피\n픽\n핀\n필\n핌\n핍\n핏\n핑\n하\n학\n한\n할\n핥\n함\n합\n핫\n항\n해\n핵\n핸\n핼\n햄\n햅\n햇\n했\n행\n햐\n향\n허\n헉\n헌\n헐\n헒\n험\n헙\n헛\n헝\n헤\n헥\n헨\n헬\n헴\n헵\n헷\n헹\n혀\n혁\n현\n혈\n혐\n협\n혓\n혔\n형\n혜\n혠\n혤\n혭\n호\n혹\n혼\n홀\n홅\n홈\n홉\n홋\n홍\n홑\n화\n확\n환\n활\n홧\n황\n홰\n홱\n홴\n횃\n횅\n회\n획\n횐\n횔\n횝\n횟\n횡\n효\n횬\n횰\n횹\n횻\n후\n훅\n훈\n훌\n훑\n훔\n훗\n훙\n훠\n훤\n훨\n훰\n훵\n훼\n훽\n휀\n휄\n휑\n휘\n휙\n휜\n휠\n휨\n휩\n휫\n휭\n휴\n휵\n휸\n휼\n흄\n흇\n흉\n흐\n흑\n흔\n흖\n흗\n흘\n흙\n흠\n흡\n흣\n흥\n흩\n희\n흰\n흴\n흼\n흽\n힁\n히\n힉\n힌\n힐\n힘\n힙\n힛\n힝\n伽\n佳\n假\n價\n加\n可\n呵\n哥\n嘉\n嫁\n家\n暇\n架\n枷\n柯\n歌\n珂\n痂\n稼\n苛\n茄\n街\n袈\n訶\n賈\n跏\n軻\n迦\n駕\n刻\n却\n各\n恪\n慤\n殼\n珏\n脚\n覺\n角\n閣\n侃\n刊\n墾\n奸\n姦\n干\n幹\n懇\n揀\n杆\n柬\n桿\n澗\n癎\n看\n磵\n稈\n竿\n簡\n肝\n艮\n艱\n諫\n間\n乫\n喝\n曷\n渴\n碣\n竭\n葛\n褐\n蝎\n鞨\n勘\n坎\n堪\n嵌\n感\n憾\n戡\n敢\n柑\n橄\n減\n甘\n疳\n監\n瞰\n紺\n邯\n鑑\n鑒\n龕\n匣\n岬\n甲\n胛\n鉀\n閘\n剛\n堈\n姜\n岡\n崗\n康\n强\n彊\n慷\n江\n畺\n疆\n糠\n絳\n綱\n羌\n腔\n舡\n薑\n襁\n講\n鋼\n降\n鱇\n介\n价\n個\n凱\n塏\n愷\n愾\n慨\n改\n槪\n漑\n疥\n皆\n盖\n箇\n芥\n蓋\n豈\n鎧\n開\n喀\n客\n坑\n更\n粳\n羹\n醵\n倨\n去\n居\n巨\n拒\n据\n據\n擧\n渠\n炬\n祛\n距\n踞\n車\n遽\n鉅\n鋸\n乾\n件\n健\n巾\n建\n愆\n楗\n腱\n虔\n蹇\n鍵\n騫\n乞\n傑\n杰\n桀\n儉\n劍\n劒\n檢\n瞼\n鈐\n黔\n劫\n怯\n迲\n偈\n憩\n揭\n擊\n格\n檄\n激\n膈\n覡\n隔\n堅\n牽\n犬\n甄\n絹\n繭\n肩\n見\n譴\n遣\n鵑\n抉\n決\n潔\n結\n缺\n訣\n兼\n慊\n箝\n謙\n鉗\n鎌\n京\n俓\n倞\n傾\n儆\n勁\n勍\n卿\n坰\n境\n庚\n徑\n慶\n憬\n擎\n敬\n景\n暻\n更\n梗\n涇\n炅\n烱\n璟\n璥\n瓊\n痙\n硬\n磬\n竟\n競\n絅\n經\n耕\n耿\n脛\n莖\n警\n輕\n逕\n鏡\n頃\n頸\n驚\n鯨\n係\n啓\n堺\n契\n季\n屆\n悸\n戒\n桂\n械\n棨\n溪\n界\n癸\n磎\n稽\n系\n繫\n繼\n計\n誡\n谿\n階\n鷄\n古\n叩\n告\n呱\n固\n姑\n孤\n尻\n庫\n拷\n攷\n故\n敲\n暠\n枯\n槁\n沽\n痼\n皐\n睾\n稿\n羔\n考\n股\n膏\n苦\n苽\n菰\n藁\n蠱\n袴\n誥\n賈\n辜\n錮\n雇\n顧\n高\n鼓\n哭\n斛\n曲\n梏\n穀\n谷\n鵠\n困\n坤\n崑\n昆\n梱\n棍\n滾\n琨\n袞\n鯤\n汨\n滑\n骨\n供\n公\n共\n功\n孔\n工\n恐\n恭\n拱\n控\n攻\n珙\n空\n蚣\n貢\n鞏\n串\n寡\n戈\n果\n瓜\n科\n菓\n誇\n課\n跨\n過\n鍋\n顆\n廓\n槨\n藿\n郭\n串\n冠\n官\n寬\n慣\n棺\n款\n灌\n琯\n瓘\n管\n罐\n菅\n觀\n貫\n關\n館\n刮\n恝\n括\n适\n侊\n光\n匡\n壙\n廣\n曠\n洸\n炚\n狂\n珖\n筐\n胱\n鑛\n卦\n掛\n罫\n乖\n傀\n塊\n壞\n怪\n愧\n拐\n槐\n魁\n宏\n紘\n肱\n轟\n交\n僑\n咬\n喬\n嬌\n嶠\n巧\n攪\n敎\n校\n橋\n狡\n皎\n矯\n絞\n翹\n膠\n蕎\n蛟\n較\n轎\n郊\n餃\n驕\n鮫\n丘\n久\n九\n仇\n俱\n具\n勾\n區\n口\n句\n咎\n嘔\n坵\n垢\n寇\n嶇\n廐\n懼\n拘\n救\n枸\n柩\n構\n歐\n毆\n毬\n求\n溝\n灸\n狗\n玖\n球\n瞿\n矩\n究\n絿\n耉\n臼\n舅\n舊\n苟\n衢\n謳\n購\n軀\n逑\n邱\n鉤\n銶\n駒\n驅\n鳩\n鷗\n龜\n國\n局\n菊\n鞠\n鞫\n麴\n君\n窘\n群\n裙\n軍\n郡\n堀\n屈\n掘\n窟\n宮\n弓\n穹\n窮\n芎\n躬\n倦\n券\n勸\n卷\n圈\n拳\n捲\n權\n淃\n眷\n厥\n獗\n蕨\n蹶\n闕\n机\n櫃\n潰\n詭\n軌\n饋\n句\n晷\n歸\n貴\n鬼\n龜\n叫\n圭\n奎\n揆\n槻\n珪\n硅\n窺\n竅\n糾\n葵\n規\n赳\n逵\n閨\n勻\n均\n畇\n筠\n菌\n鈞\n龜\n橘\n克\n剋\n劇\n戟\n棘\n極\n隙\n僅\n劤\n勤\n懃\n斤\n根\n槿\n瑾\n筋\n芹\n菫\n覲\n謹\n近\n饉\n契\n今\n妗\n擒\n昑\n檎\n琴\n禁\n禽\n芩\n衾\n衿\n襟\n金\n錦\n伋\n及\n急\n扱\n汲\n級\n給\n亘\n兢\n矜\n肯\n企\n伎\n其\n冀\n嗜\n器\n圻\n基\n埼\n夔\n奇\n妓\n寄\n岐\n崎\n己\n幾\n忌\n技\n旗\n旣\n朞\n期\n杞\n棋\n棄\n機\n欺\n氣\n汽\n沂\n淇\n玘\n琦\n琪\n璂\n璣\n畸\n畿\n碁\n磯\n祁\n祇\n祈\n祺\n箕\n紀\n綺\n羈\n耆\n耭\n肌\n記\n譏\n豈\n起\n錡\n錤\n飢\n饑\n騎\n騏\n驥\n麒\n緊\n佶\n吉\n拮\n桔\n金\n喫\n儺\n喇\n奈\n娜\n懦\n懶\n拏\n拿\n癩\n羅\n蘿\n螺\n裸\n邏\n那\n樂\n洛\n烙\n珞\n落\n諾\n酪\n駱\n亂\n卵\n暖\n欄\n煖\n爛\n蘭\n難\n鸞\n捏\n捺\n南\n嵐\n枏\n楠\n湳\n濫\n男\n藍\n襤\n拉\n納\n臘\n蠟\n衲\n囊\n娘\n廊\n朗\n浪\n狼\n郎\n乃\n來\n內\n奈\n柰\n耐\n冷\n女\n年\n撚\n秊\n念\n恬\n拈\n捻\n寧\n寗\n努\n勞\n奴\n弩\n怒\n擄\n櫓\n爐\n瑙\n盧\n老\n蘆\n虜\n路\n露\n駑\n魯\n鷺\n碌\n祿\n綠\n菉\n錄\n鹿\n論\n壟\n弄\n濃\n籠\n聾\n膿\n農\n惱\n牢\n磊\n腦\n賂\n雷\n尿\n壘\n屢\n樓\n淚\n漏\n累\n縷\n陋\n嫩\n訥\n杻\n紐\n勒\n肋\n凜\n凌\n稜\n綾\n能\n菱\n陵\n尼\n泥\n匿\n溺\n多\n茶\n丹\n亶\n但\n單\n團\n壇\n彖\n斷\n旦\n檀\n段\n湍\n短\n端\n簞\n緞\n蛋\n袒\n鄲\n鍛\n撻\n澾\n獺\n疸\n達\n啖\n坍\n憺\n擔\n曇\n淡\n湛\n潭\n澹\n痰\n聃\n膽\n蕁\n覃\n談\n譚\n錟\n沓\n畓\n答\n踏\n遝\n唐\n堂\n塘\n幢\n戇\n撞\n棠\n當\n糖\n螳\n黨\n代\n垈\n坮\n大\n對\n岱\n帶\n待\n戴\n擡\n玳\n臺\n袋\n貸\n隊\n黛\n宅\n德\n悳\n倒\n刀\n到\n圖\n堵\n塗\n導\n屠\n島\n嶋\n度\n徒\n悼\n挑\n掉\n搗\n桃\n棹\n櫂\n淘\n渡\n滔\n濤\n燾\n盜\n睹\n禱\n稻\n萄\n覩\n賭\n跳\n蹈\n逃\n途\n道\n都\n鍍\n陶\n韜\n毒\n瀆\n牘\n犢\n獨\n督\n禿\n篤\n纛\n讀\n墩\n惇\n敦\n旽\n暾\n沌\n焞\n燉\n豚\n頓\n乭\n突\n仝\n冬\n凍\n動\n同\n憧\n東\n桐\n棟\n洞\n潼\n疼\n瞳\n童\n胴\n董\n銅\n兜\n斗\n杜\n枓\n痘\n竇\n荳\n讀\n豆\n逗\n頭\n屯\n臀\n芚\n遁\n遯\n鈍\n得\n嶝\n橙\n燈\n登\n等\n藤\n謄\n鄧\n騰\n喇\n懶\n拏\n癩\n羅\n蘿\n螺\n裸\n邏\n樂\n洛\n烙\n珞\n絡\n落\n諾\n酪\n駱\n丹\n亂\n卵\n欄\n欒\n瀾\n爛\n蘭\n鸞\n剌\n辣\n嵐\n擥\n攬\n欖\n濫\n籃\n纜\n藍\n襤\n覽\n拉\n臘\n蠟\n廊\n朗\n浪\n狼\n琅\n瑯\n螂\n郞\n來\n崍\n徠\n萊\n冷\n掠\n略\n亮\n倆\n兩\n凉\n梁\n樑\n粮\n粱\n糧\n良\n諒\n輛\n量\n侶\n儷\n勵\n呂\n廬\n慮\n戾\n旅\n櫚\n濾\n礪\n藜\n蠣\n閭\n驢\n驪\n麗\n黎\n力\n曆\n歷\n瀝\n礫\n轢\n靂\n憐\n戀\n攣\n漣\n煉\n璉\n練\n聯\n蓮\n輦\n連\n鍊\n冽\n列\n劣\n洌\n烈\n裂\n廉\n斂\n殮\n濂\n簾\n獵\n令\n伶\n囹\n寧\n岺\n嶺\n怜\n玲\n笭\n羚\n翎\n聆\n逞\n鈴\n零\n靈\n領\n齡\n例\n澧\n禮\n醴\n隷\n勞\n怒\n撈\n擄\n櫓\n潞\n瀘\n爐\n盧\n老\n蘆\n虜\n路\n輅\n露\n魯\n鷺\n鹵\n碌\n祿\n綠\n菉\n錄\n鹿\n麓\n論\n壟\n弄\n朧\n瀧\n瓏\n籠\n聾\n儡\n瀨\n牢\n磊\n賂\n賚\n賴\n雷\n了\n僚\n寮\n廖\n料\n燎\n療\n瞭\n聊\n蓼\n遼\n鬧\n龍\n壘\n婁\n屢\n樓\n淚\n漏\n瘻\n累\n縷\n蔞\n褸\n鏤\n陋\n劉\n旒\n柳\n榴\n流\n溜\n瀏\n琉\n瑠\n留\n瘤\n硫\n謬\n類\n六\n戮\n陸\n侖\n倫\n崙\n淪\n綸\n輪\n律\n慄\n栗\n率\n隆\n勒\n肋\n凜\n凌\n楞\n稜\n綾\n菱\n陵\n俚\n利\n厘\n吏\n唎\n履\n悧\n李\n梨\n浬\n犁\n狸\n理\n璃\n異\n痢\n籬\n罹\n羸\n莉\n裏\n裡\n里\n釐\n離\n鯉\n吝\n潾\n燐\n璘\n藺\n躪\n隣\n鱗\n麟\n林\n淋\n琳\n臨\n霖\n砬\n立\n笠\n粒\n摩\n瑪\n痲\n碼\n磨\n馬\n魔\n麻\n寞\n幕\n漠\n膜\n莫\n邈\n万\n卍\n娩\n巒\n彎\n慢\n挽\n晩\n曼\n滿\n漫\n灣\n瞞\n萬\n蔓\n蠻\n輓\n饅\n鰻\n唜\n抹\n末\n沫\n茉\n襪\n靺\n亡\n妄\n忘\n忙\n望\n網\n罔\n芒\n茫\n莽\n輞\n邙\n埋\n妹\n媒\n寐\n昧\n枚\n梅\n每\n煤\n罵\n買\n賣\n邁\n魅\n脈\n貊\n陌\n驀\n麥\n孟\n氓\n猛\n盲\n盟\n萌\n冪\n覓\n免\n冕\n勉\n棉\n沔\n眄\n眠\n綿\n緬\n面\n麵\n滅\n蔑\n冥\n名\n命\n明\n暝\n椧\n溟\n皿\n瞑\n茗\n蓂\n螟\n酩\n銘\n鳴\n袂\n侮\n冒\n募\n姆\n帽\n慕\n摸\n摹\n暮\n某\n模\n母\n毛\n牟\n牡\n瑁\n眸\n矛\n耗\n芼\n茅\n謀\n謨\n貌\n木\n沐\n牧\n目\n睦\n穆\n鶩\n歿\n沒\n夢\n朦\n蒙\n卯\n墓\n妙\n廟\n描\n昴\n杳\n渺\n猫\n竗\n苗\n錨\n務\n巫\n憮\n懋\n戊\n拇\n撫\n无\n楙\n武\n毋\n無\n珷\n畝\n繆\n舞\n茂\n蕪\n誣\n貿\n霧\n鵡\n墨\n默\n們\n刎\n吻\n問\n文\n汶\n紊\n紋\n聞\n蚊\n門\n雯\n勿\n沕\n物\n味\n媚\n尾\n嵋\n彌\n微\n未\n梶\n楣\n渼\n湄\n眉\n米\n美\n薇\n謎\n迷\n靡\n黴\n岷\n悶\n愍\n憫\n敏\n旻\n旼\n民\n泯\n玟\n珉\n緡\n閔\n密\n蜜\n謐\n剝\n博\n拍\n搏\n撲\n朴\n樸\n泊\n珀\n璞\n箔\n粕\n縛\n膊\n舶\n薄\n迫\n雹\n駁\n伴\n半\n反\n叛\n拌\n搬\n攀\n斑\n槃\n泮\n潘\n班\n畔\n瘢\n盤\n盼\n磐\n磻\n礬\n絆\n般\n蟠\n返\n頒\n飯\n勃\n拔\n撥\n渤\n潑\n發\n跋\n醱\n鉢\n髮\n魃\n倣\n傍\n坊\n妨\n尨\n幇\n彷\n房\n放\n方\n旁\n昉\n枋\n榜\n滂\n磅\n紡\n肪\n膀\n舫\n芳\n蒡\n蚌\n訪\n謗\n邦\n防\n龐\n倍\n俳\n北\n培\n徘\n拜\n排\n杯\n湃\n焙\n盃\n背\n胚\n裴\n裵\n褙\n賠\n輩\n配\n陪\n伯\n佰\n帛\n柏\n栢\n白\n百\n魄\n幡\n樊\n煩\n燔\n番\n磻\n繁\n蕃\n藩\n飜\n伐\n筏\n罰\n閥\n凡\n帆\n梵\n氾\n汎\n泛\n犯\n範\n范\n法\n琺\n僻\n劈\n壁\n擘\n檗\n璧\n癖\n碧\n蘗\n闢\n霹\n便\n卞\n弁\n變\n辨\n辯\n邊\n別\n瞥\n鱉\n鼈\n丙\n倂\n兵\n屛\n幷\n昞\n昺\n柄\n棅\n炳\n甁\n病\n秉\n竝\n輧\n餠\n騈\n保\n堡\n報\n寶\n普\n步\n洑\n湺\n潽\n珤\n甫\n菩\n補\n褓\n譜\n輔\n伏\n僕\n匐\n卜\n宓\n復\n服\n福\n腹\n茯\n蔔\n複\n覆\n輹\n輻\n馥\n鰒\n本\n乶\n俸\n奉\n封\n峯\n峰\n捧\n棒\n烽\n熢\n琫\n縫\n蓬\n蜂\n逢\n鋒\n鳳\n不\n付\n俯\n傅\n剖\n副\n否\n咐\n埠\n夫\n婦\n孚\n孵\n富\n府\n復\n扶\n敷\n斧\n浮\n溥\n父\n符\n簿\n缶\n腐\n腑\n膚\n艀\n芙\n莩\n訃\n負\n賦\n賻\n赴\n趺\n部\n釜\n阜\n附\n駙\n鳧\n北\n分\n吩\n噴\n墳\n奔\n奮\n忿\n憤\n扮\n昐\n汾\n焚\n盆\n粉\n糞\n紛\n芬\n賁\n雰\n不\n佛\n弗\n彿\n拂\n崩\n朋\n棚\n硼\n繃\n鵬\n丕\n備\n匕\n匪\n卑\n妃\n婢\n庇\n悲\n憊\n扉\n批\n斐\n枇\n榧\n比\n毖\n毗\n毘\n沸\n泌\n琵\n痺\n砒\n碑\n秕\n秘\n粃\n緋\n翡\n肥\n脾\n臂\n菲\n蜚\n裨\n誹\n譬\n費\n鄙\n非\n飛\n鼻\n嚬\n嬪\n彬\n斌\n檳\n殯\n浜\n濱\n瀕\n牝\n玭\n貧\n賓\n頻\n憑\n氷\n聘\n騁\n乍\n事\n些\n仕\n伺\n似\n使\n俟\n僿\n史\n司\n唆\n嗣\n四\n士\n奢\n娑\n寫\n寺\n射\n巳\n師\n徙\n思\n捨\n斜\n斯\n柶\n査\n梭\n死\n沙\n泗\n渣\n瀉\n獅\n砂\n社\n祀\n祠\n私\n篩\n紗\n絲\n肆\n舍\n莎\n蓑\n蛇\n裟\n詐\n詞\n謝\n賜\n赦\n辭\n邪\n飼\n駟\n麝\n削\n數\n朔\n索\n傘\n刪\n山\n散\n汕\n珊\n産\n疝\n算\n蒜\n酸\n霰\n乷\n撒\n殺\n煞\n薩\n三\n參\n杉\n森\n渗\n芟\n蔘\n衫\n揷\n澁\n鈒\n颯\n上\n傷\n像\n償\n商\n喪\n嘗\n孀\n尙\n峠\n常\n床\n庠\n廂\n想\n桑\n橡\n湘\n爽\n牀\n狀\n相\n祥\n箱\n翔\n裳\n觴\n詳\n象\n賞\n霜\n塞\n璽\n賽\n嗇\n塞\n穡\n索\n色\n牲\n生\n甥\n省\n笙\n墅\n壻\n嶼\n序\n庶\n徐\n恕\n抒\n捿\n敍\n暑\n曙\n書\n栖\n棲\n犀\n瑞\n筮\n絮\n緖\n署\n胥\n舒\n薯\n西\n誓\n逝\n鋤\n黍\n鼠\n夕\n奭\n席\n惜\n昔\n晳\n析\n汐\n淅\n潟\n石\n碩\n蓆\n釋\n錫\n仙\n僊\n先\n善\n嬋\n宣\n扇\n敾\n旋\n渲\n煽\n琁\n瑄\n璇\n璿\n癬\n禪\n線\n繕\n羨\n腺\n膳\n船\n蘚\n蟬\n詵\n跣\n選\n銑\n鐥\n饍\n鮮\n卨\n屑\n楔\n泄\n洩\n渫\n舌\n薛\n褻\n設\n說\n雪\n齧\n剡\n暹\n殲\n纖\n蟾\n贍\n閃\n陝\n攝\n涉\n燮\n葉\n城\n姓\n宬\n性\n惺\n成\n星\n晟\n猩\n珹\n盛\n省\n筬\n聖\n聲\n腥\n誠\n醒\n世\n勢\n歲\n洗\n稅\n笹\n細\n說\n貰\n召\n嘯\n塑\n宵\n小\n少\n巢\n所\n掃\n搔\n昭\n梳\n沼\n消\n溯\n瀟\n炤\n燒\n甦\n疏\n疎\n瘙\n笑\n篠\n簫\n素\n紹\n蔬\n蕭\n蘇\n訴\n逍\n遡\n邵\n銷\n韶\n騷\n俗\n屬\n束\n涑\n粟\n續\n謖\n贖\n速\n孫\n巽\n損\n蓀\n遜\n飡\n率\n宋\n悚\n松\n淞\n訟\n誦\n送\n頌\n刷\n殺\n灑\n碎\n鎖\n衰\n釗\n修\n受\n嗽\n囚\n垂\n壽\n嫂\n守\n岫\n峀\n帥\n愁\n戍\n手\n授\n搜\n收\n數\n樹\n殊\n水\n洙\n漱\n燧\n狩\n獸\n琇\n璲\n瘦\n睡\n秀\n穗\n竪\n粹\n綏\n綬\n繡\n羞\n脩\n茱\n蒐\n蓚\n藪\n袖\n誰\n讐\n輸\n遂\n邃\n酬\n銖\n銹\n隋\n隧\n隨\n雖\n需\n須\n首\n髓\n鬚\n叔\n塾\n夙\n孰\n宿\n淑\n潚\n熟\n琡\n璹\n肅\n菽\n巡\n徇\n循\n恂\n旬\n栒\n楯\n橓\n殉\n洵\n淳\n珣\n盾\n瞬\n筍\n純\n脣\n舜\n荀\n蓴\n蕣\n詢\n諄\n醇\n錞\n順\n馴\n戌\n術\n述\n鉥\n崇\n崧\n嵩\n瑟\n膝\n蝨\n濕\n拾\n習\n褶\n襲\n丞\n乘\n僧\n勝\n升\n承\n昇\n繩\n蠅\n陞\n侍\n匙\n嘶\n始\n媤\n尸\n屎\n屍\n市\n弑\n恃\n施\n是\n時\n枾\n柴\n猜\n矢\n示\n翅\n蒔\n蓍\n視\n試\n詩\n諡\n豕\n豺\n埴\n寔\n式\n息\n拭\n植\n殖\n湜\n熄\n篒\n蝕\n識\n軾\n食\n飾\n伸\n侁\n信\n呻\n娠\n宸\n愼\n新\n晨\n燼\n申\n神\n紳\n腎\n臣\n莘\n薪\n藎\n蜃\n訊\n身\n辛\n辰\n迅\n失\n室\n實\n悉\n審\n尋\n心\n沁\n沈\n深\n瀋\n甚\n芯\n諶\n什\n十\n拾\n雙\n氏\n亞\n俄\n兒\n啞\n娥\n峨\n我\n牙\n芽\n莪\n蛾\n衙\n訝\n阿\n雅\n餓\n鴉\n鵝\n堊\n岳\n嶽\n幄\n惡\n愕\n握\n樂\n渥\n鄂\n鍔\n顎\n鰐\n齷\n安\n岸\n按\n晏\n案\n眼\n雁\n鞍\n顔\n鮟\n斡\n謁\n軋\n閼\n唵\n岩\n巖\n庵\n暗\n癌\n菴\n闇\n壓\n押\n狎\n鴨\n仰\n央\n怏\n昻\n殃\n秧\n鴦\n厓\n哀\n埃\n崖\n愛\n曖\n涯\n碍\n艾\n隘\n靄\n厄\n扼\n掖\n液\n縊\n腋\n額\n櫻\n罌\n鶯\n鸚\n也\n倻\n冶\n夜\n惹\n揶\n椰\n爺\n耶\n若\n野\n弱\n掠\n略\n約\n若\n葯\n蒻\n藥\n躍\n亮\n佯\n兩\n凉\n壤\n孃\n恙\n揚\n攘\n敭\n暘\n梁\n楊\n樣\n洋\n瀁\n煬\n痒\n瘍\n禳\n穰\n糧\n羊\n良\n襄\n諒\n讓\n釀\n陽\n量\n養\n圄\n御\n於\n漁\n瘀\n禦\n語\n馭\n魚\n齬\n億\n憶\n抑\n檍\n臆\n偃\n堰\n彦\n焉\n言\n諺\n孼\n蘖\n俺\n儼\n嚴\n奄\n掩\n淹\n嶪\n業\n円\n予\n余\n勵\n呂\n女\n如\n廬\n旅\n歟\n汝\n濾\n璵\n礖\n礪\n與\n艅\n茹\n輿\n轝\n閭\n餘\n驪\n麗\n黎\n亦\n力\n域\n役\n易\n曆\n歷\n疫\n繹\n譯\n轢\n逆\n驛\n嚥\n堧\n姸\n娟\n宴\n年\n延\n憐\n戀\n捐\n挻\n撚\n椽\n沇\n沿\n涎\n涓\n淵\n演\n漣\n烟\n然\n煙\n煉\n燃\n燕\n璉\n硏\n硯\n秊\n筵\n緣\n練\n縯\n聯\n衍\n軟\n輦\n蓮\n連\n鉛\n鍊\n鳶\n列\n劣\n咽\n悅\n涅\n烈\n熱\n裂\n說\n閱\n厭\n廉\n念\n捻\n染\n殮\n炎\n焰\n琰\n艶\n苒\n簾\n閻\n髥\n鹽\n曄\n獵\n燁\n葉\n令\n囹\n塋\n寧\n嶺\n嶸\n影\n怜\n映\n暎\n楹\n榮\n永\n泳\n渶\n潁\n濚\n瀛\n瀯\n煐\n營\n獰\n玲\n瑛\n瑩\n瓔\n盈\n穎\n纓\n羚\n聆\n英\n詠\n迎\n鈴\n鍈\n零\n霙\n靈\n領\n乂\n倪\n例\n刈\n叡\n曳\n汭\n濊\n猊\n睿\n穢\n芮\n藝\n蘂\n禮\n裔\n詣\n譽\n豫\n醴\n銳\n隸\n霓\n預\n五\n伍\n俉\n傲\n午\n吾\n吳\n嗚\n塢\n墺\n奧\n娛\n寤\n悟\n惡\n懊\n敖\n旿\n晤\n梧\n汚\n澳\n烏\n熬\n獒\n筽\n蜈\n誤\n鰲\n鼇\n屋\n沃\n獄\n玉\n鈺\n溫\n瑥\n瘟\n穩\n縕\n蘊\n兀\n壅\n擁\n瓮\n甕\n癰\n翁\n邕\n雍\n饔\n渦\n瓦\n窩\n窪\n臥\n蛙\n蝸\n訛\n婉\n完\n宛\n梡\n椀\n浣\n玩\n琓\n琬\n碗\n緩\n翫\n脘\n腕\n莞\n豌\n阮\n頑\n曰\n往\n旺\n枉\n汪\n王\n倭\n娃\n歪\n矮\n外\n嵬\n巍\n猥\n畏\n了\n僚\n僥\n凹\n堯\n夭\n妖\n姚\n寥\n寮\n尿\n嶢\n拗\n搖\n撓\n擾\n料\n曜\n樂\n橈\n燎\n燿\n瑤\n療\n窈\n窯\n繇\n繞\n耀\n腰\n蓼\n蟯\n要\n謠\n遙\n遼\n邀\n饒\n慾\n欲\n浴\n縟\n褥\n辱\n俑\n傭\n冗\n勇\n埇\n墉\n容\n庸\n慂\n榕\n涌\n湧\n溶\n熔\n瑢\n用\n甬\n聳\n茸\n蓉\n踊\n鎔\n鏞\n龍\n于\n佑\n偶\n優\n又\n友\n右\n宇\n寓\n尤\n愚\n憂\n旴\n牛\n玗\n瑀\n盂\n祐\n禑\n禹\n紆\n羽\n芋\n藕\n虞\n迂\n遇\n郵\n釪\n隅\n雨\n雩\n勖\n彧\n旭\n昱\n栯\n煜\n稶\n郁\n頊\n云\n暈\n橒\n殞\n澐\n熉\n耘\n芸\n蕓\n運\n隕\n雲\n韻\n蔚\n鬱\n亐\n熊\n雄\n元\n原\n員\n圓\n園\n垣\n媛\n嫄\n寃\n怨\n愿\n援\n沅\n洹\n湲\n源\n爰\n猿\n瑗\n苑\n袁\n轅\n遠\n阮\n院\n願\n鴛\n月\n越\n鉞\n位\n偉\n僞\n危\n圍\n委\n威\n尉\n慰\n暐\n渭\n爲\n瑋\n緯\n胃\n萎\n葦\n蔿\n蝟\n衛\n褘\n謂\n違\n韋\n魏\n乳\n侑\n儒\n兪\n劉\n唯\n喩\n孺\n宥\n幼\n幽\n庾\n悠\n惟\n愈\n愉\n揄\n攸\n有\n杻\n柔\n柚\n柳\n楡\n楢\n油\n洧\n流\n游\n溜\n濡\n猶\n猷\n琉\n瑜\n由\n留\n癒\n硫\n紐\n維\n臾\n萸\n裕\n誘\n諛\n諭\n踰\n蹂\n遊\n逾\n遺\n酉\n釉\n鍮\n類\n六\n堉\n戮\n毓\n肉\n育\n陸\n倫\n允\n奫\n尹\n崙\n淪\n潤\n玧\n胤\n贇\n輪\n鈗\n閏\n律\n慄\n栗\n率\n聿\n戎\n瀜\n絨\n融\n隆\n垠\n恩\n慇\n殷\n誾\n銀\n隱\n乙\n吟\n淫\n蔭\n陰\n音\n飮\n揖\n泣\n邑\n凝\n應\n膺\n鷹\n依\n倚\n儀\n宜\n意\n懿\n擬\n椅\n毅\n疑\n矣\n義\n艤\n薏\n蟻\n衣\n誼\n議\n醫\n二\n以\n伊\n利\n吏\n夷\n姨\n履\n已\n弛\n彛\n怡\n易\n李\n梨\n泥\n爾\n珥\n理\n異\n痍\n痢\n移\n罹\n而\n耳\n肄\n苡\n荑\n裏\n裡\n貽\n貳\n邇\n里\n離\n飴\n餌\n匿\n溺\n瀷\n益\n翊\n翌\n翼\n謚\n人\n仁\n刃\n印\n吝\n咽\n因\n姻\n寅\n引\n忍\n湮\n燐\n璘\n絪\n茵\n藺\n蚓\n認\n隣\n靭\n靷\n鱗\n麟\n一\n佚\n佾\n壹\n日\n溢\n逸\n鎰\n馹\n任\n壬\n妊\n姙\n恁\n林\n淋\n稔\n臨\n荏\n賃\n入\n卄\n立\n笠\n粒\n仍\n剩\n孕\n芿\n仔\n刺\n咨\n姉\n姿\n子\n字\n孜\n恣\n慈\n滋\n炙\n煮\n玆\n瓷\n疵\n磁\n紫\n者\n自\n茨\n蔗\n藉\n諮\n資\n雌\n作\n勺\n嚼\n斫\n昨\n灼\n炸\n爵\n綽\n芍\n酌\n雀\n鵲\n孱\n棧\n殘\n潺\n盞\n岑\n暫\n潛\n箴\n簪\n蠶\n雜\n丈\n仗\n匠\n場\n墻\n壯\n奬\n將\n帳\n庄\n張\n掌\n暲\n杖\n樟\n檣\n欌\n漿\n牆\n狀\n獐\n璋\n章\n粧\n腸\n臟\n臧\n莊\n葬\n蔣\n薔\n藏\n裝\n贓\n醬\n長\n障\n再\n哉\n在\n宰\n才\n材\n栽\n梓\n渽\n滓\n災\n縡\n裁\n財\n載\n齋\n齎\n爭\n箏\n諍\n錚\n佇\n低\n儲\n咀\n姐\n底\n抵\n杵\n楮\n樗\n沮\n渚\n狙\n猪\n疽\n箸\n紵\n苧\n菹\n著\n藷\n詛\n貯\n躇\n這\n邸\n雎\n齟\n勣\n吊\n嫡\n寂\n摘\n敵\n滴\n狄\n炙\n的\n積\n笛\n籍\n績\n翟\n荻\n謫\n賊\n赤\n跡\n蹟\n迪\n迹\n適\n鏑\n佃\n佺\n傳\n全\n典\n前\n剪\n塡\n塼\n奠\n專\n展\n廛\n悛\n戰\n栓\n殿\n氈\n澱\n煎\n琠\n田\n甸\n畑\n癲\n筌\n箋\n箭\n篆\n纏\n詮\n輾\n轉\n鈿\n銓\n錢\n鐫\n電\n顚\n顫\n餞\n切\n截\n折\n浙\n癤\n竊\n節\n絶\n占\n岾\n店\n漸\n点\n粘\n霑\n鮎\n點\n接\n摺\n蝶\n丁\n井\n亭\n停\n偵\n呈\n姃\n定\n幀\n庭\n廷\n征\n情\n挺\n政\n整\n旌\n晶\n晸\n柾\n楨\n檉\n正\n汀\n淀\n淨\n渟\n湞\n瀞\n炡\n玎\n珽\n町\n睛\n碇\n禎\n程\n穽\n精\n綎\n艇\n訂\n諪\n貞\n鄭\n酊\n釘\n鉦\n鋌\n錠\n霆\n靖\n靜\n頂\n鼎\n制\n劑\n啼\n堤\n帝\n弟\n悌\n提\n梯\n濟\n祭\n第\n臍\n薺\n製\n諸\n蹄\n醍\n除\n際\n霽\n題\n齊\n俎\n兆\n凋\n助\n嘲\n弔\n彫\n措\n操\n早\n晁\n曺\n曹\n朝\n條\n棗\n槽\n漕\n潮\n照\n燥\n爪\n璪\n眺\n祖\n祚\n租\n稠\n窕\n粗\n糟\n組\n繰\n肇\n藻\n蚤\n詔\n調\n趙\n躁\n造\n遭\n釣\n阻\n雕\n鳥\n族\n簇\n足\n鏃\n存\n尊\n卒\n拙\n猝\n倧\n宗\n從\n悰\n慫\n棕\n淙\n琮\n種\n終\n綜\n縱\n腫\n踪\n踵\n鍾\n鐘\n佐\n坐\n左\n座\n挫\n罪\n主\n住\n侏\n做\n姝\n胄\n呪\n周\n嗾\n奏\n宙\n州\n廚\n晝\n朱\n柱\n株\n注\n洲\n湊\n澍\n炷\n珠\n疇\n籌\n紂\n紬\n綢\n舟\n蛛\n註\n誅\n走\n躊\n輳\n週\n酎\n酒\n鑄\n駐\n竹\n粥\n俊\n儁\n准\n埈\n寯\n峻\n晙\n樽\n浚\n準\n濬\n焌\n畯\n竣\n蠢\n逡\n遵\n雋\n駿\n茁\n中\n仲\n衆\n重\n卽\n櫛\n楫\n汁\n葺\n增\n憎\n曾\n拯\n烝\n甑\n症\n繒\n蒸\n證\n贈\n之\n只\n咫\n地\n址\n志\n持\n指\n摯\n支\n旨\n智\n枝\n枳\n止\n池\n沚\n漬\n知\n砥\n祉\n祗\n紙\n肢\n脂\n至\n芝\n芷\n蜘\n誌\n識\n贄\n趾\n遲\n直\n稙\n稷\n織\n職\n唇\n嗔\n塵\n振\n搢\n晉\n晋\n桭\n榛\n殄\n津\n溱\n珍\n瑨\n璡\n畛\n疹\n盡\n眞\n瞋\n秦\n縉\n縝\n臻\n蔯\n袗\n診\n賑\n軫\n辰\n進\n鎭\n陣\n陳\n震\n侄\n叱\n姪\n嫉\n帙\n桎\n瓆\n疾\n秩\n窒\n膣\n蛭\n質\n跌\n迭\n斟\n朕\n什\n執\n潗\n緝\n輯\n鏶\n集\n徵\n懲\n澄\n且\n侘\n借\n叉\n嗟\n嵯\n差\n次\n此\n磋\n箚\n茶\n蹉\n車\n遮\n捉\n搾\n着\n窄\n錯\n鑿\n齪\n撰\n澯\n燦\n璨\n瓚\n竄\n簒\n纂\n粲\n纘\n讚\n贊\n鑽\n餐\n饌\n刹\n察\n擦\n札\n紮\n僭\n參\n塹\n慘\n慙\n懺\n斬\n站\n讒\n讖\n倉\n倡\n創\n唱\n娼\n廠\n彰\n愴\n敞\n昌\n昶\n暢\n槍\n滄\n漲\n猖\n瘡\n窓\n脹\n艙\n菖\n蒼\n債\n埰\n寀\n寨\n彩\n採\n砦\n綵\n菜\n蔡\n采\n釵\n冊\n柵\n策\n責\n凄\n妻\n悽\n處\n倜\n刺\n剔\n尺\n慽\n戚\n拓\n擲\n斥\n滌\n瘠\n脊\n蹠\n陟\n隻\n仟\n千\n喘\n天\n川\n擅\n泉\n淺\n玔\n穿\n舛\n薦\n賤\n踐\n遷\n釧\n闡\n阡\n韆\n凸\n哲\n喆\n徹\n撤\n澈\n綴\n輟\n轍\n鐵\n僉\n尖\n沾\n添\n甛\n瞻\n簽\n籤\n詹\n諂\n堞\n妾\n帖\n捷\n牒\n疊\n睫\n諜\n貼\n輒\n廳\n晴\n淸\n聽\n菁\n請\n靑\n鯖\n切\n剃\n替\n涕\n滯\n締\n諦\n逮\n遞\n體\n初\n剿\n哨\n憔\n抄\n招\n梢\n椒\n楚\n樵\n炒\n焦\n硝\n礁\n礎\n秒\n稍\n肖\n艸\n苕\n草\n蕉\n貂\n超\n酢\n醋\n醮\n促\n囑\n燭\n矗\n蜀\n觸\n寸\n忖\n村\n邨\n叢\n塚\n寵\n悤\n憁\n摠\n總\n聰\n蔥\n銃\n撮\n催\n崔\n最\n墜\n抽\n推\n椎\n楸\n樞\n湫\n皺\n秋\n芻\n萩\n諏\n趨\n追\n鄒\n酋\n醜\n錐\n錘\n鎚\n雛\n騶\n鰍\n丑\n畜\n祝\n竺\n筑\n築\n縮\n蓄\n蹙\n蹴\n軸\n逐\n春\n椿\n瑃\n出\n朮\n黜\n充\n忠\n沖\n蟲\n衝\n衷\n悴\n膵\n萃\n贅\n取\n吹\n嘴\n娶\n就\n炊\n翠\n聚\n脆\n臭\n趣\n醉\n驟\n鷲\n側\n仄\n厠\n惻\n測\n層\n侈\n値\n嗤\n峙\n幟\n恥\n梔\n治\n淄\n熾\n痔\n痴\n癡\n稚\n穉\n緇\n緻\n置\n致\n蚩\n輜\n雉\n馳\n齒\n則\n勅\n飭\n親\n七\n柒\n漆\n侵\n寢\n枕\n沈\n浸\n琛\n砧\n針\n鍼\n蟄\n秤\n稱\n快\n他\n咤\n唾\n墮\n妥\n惰\n打\n拖\n朶\n楕\n舵\n陀\n馱\n駝\n倬\n卓\n啄\n坼\n度\n托\n拓\n擢\n晫\n柝\n濁\n濯\n琢\n琸\n託\n鐸\n呑\n嘆\n坦\n彈\n憚\n歎\n灘\n炭\n綻\n誕\n奪\n脫\n探\n眈\n耽\n貪\n塔\n搭\n榻\n宕\n帑\n湯\n糖\n蕩\n兌\n台\n太\n怠\n態\n殆\n汰\n泰\n笞\n胎\n苔\n跆\n邰\n颱\n宅\n擇\n澤\n撑\n攄\n兎\n吐\n土\n討\n慟\n桶\n洞\n痛\n筒\n統\n通\n堆\n槌\n腿\n褪\n退\n頹\n偸\n套\n妬\n投\n透\n鬪\n慝\n特\n闖\n坡\n婆\n巴\n把\n播\n擺\n杷\n波\n派\n爬\n琶\n破\n罷\n芭\n跛\n頗\n判\n坂\n板\n版\n瓣\n販\n辦\n鈑\n阪\n八\n叭\n捌\n佩\n唄\n悖\n敗\n沛\n浿\n牌\n狽\n稗\n覇\n貝\n彭\n澎\n烹\n膨\n愎\n便\n偏\n扁\n片\n篇\n編\n翩\n遍\n鞭\n騙\n貶\n坪\n平\n枰\n萍\n評\n吠\n嬖\n幣\n廢\n弊\n斃\n肺\n蔽\n閉\n陛\n佈\n包\n匍\n匏\n咆\n哺\n圃\n布\n怖\n抛\n抱\n捕\n暴\n泡\n浦\n疱\n砲\n胞\n脯\n苞\n葡\n蒲\n袍\n褒\n逋\n鋪\n飽\n鮑\n幅\n暴\n曝\n瀑\n爆\n輻\n俵\n剽\n彪\n慓\n杓\n標\n漂\n瓢\n票\n表\n豹\n飇\n飄\n驃\n品\n稟\n楓\n諷\n豊\n風\n馮\n彼\n披\n疲\n皮\n被\n避\n陂\n匹\n弼\n必\n泌\n珌\n畢\n疋\n筆\n苾\n馝\n乏\n逼\n下\n何\n厦\n夏\n廈\n昰\n河\n瑕\n荷\n蝦\n賀\n遐\n霞\n鰕\n壑\n學\n虐\n謔\n鶴\n寒\n恨\n悍\n旱\n汗\n漢\n澣\n瀚\n罕\n翰\n閑\n閒\n限\n韓\n割\n轄\n函\n含\n咸\n啣\n喊\n檻\n涵\n緘\n艦\n銜\n陷\n鹹\n合\n哈\n盒\n蛤\n閤\n闔\n陜\n亢\n伉\n姮\n嫦\n巷\n恒\n抗\n杭\n桁\n沆\n港\n缸\n肛\n航\n行\n降\n項\n亥\n偕\n咳\n垓\n奚\n孩\n害\n懈\n楷\n海\n瀣\n蟹\n解\n該\n諧\n邂\n駭\n骸\n劾\n核\n倖\n幸\n杏\n荇\n行\n享\n向\n嚮\n珦\n鄕\n響\n餉\n饗\n香\n噓\n墟\n虛\n許\n憲\n櫶\n獻\n軒\n歇\n險\n驗\n奕\n爀\n赫\n革\n俔\n峴\n弦\n懸\n晛\n泫\n炫\n玄\n玹\n現\n眩\n睍\n絃\n絢\n縣\n舷\n衒\n見\n賢\n鉉\n顯\n孑\n穴\n血\n頁\n嫌\n俠\n協\n夾\n峽\n挾\n浹\n狹\n脅\n脇\n莢\n鋏\n頰\n亨\n兄\n刑\n型\n形\n泂\n滎\n瀅\n灐\n炯\n熒\n珩\n瑩\n荊\n螢\n衡\n逈\n邢\n鎣\n馨\n兮\n彗\n惠\n慧\n暳\n蕙\n蹊\n醯\n鞋\n乎\n互\n呼\n壕\n壺\n好\n岵\n弧\n戶\n扈\n昊\n晧\n毫\n浩\n淏\n湖\n滸\n澔\n濠\n濩\n灝\n狐\n琥\n瑚\n瓠\n皓\n祜\n糊\n縞\n胡\n芦\n葫\n蒿\n虎\n號\n蝴\n護\n豪\n鎬\n頀\n顥\n惑\n或\n酷\n婚\n昏\n混\n渾\n琿\n魂\n忽\n惚\n笏\n哄\n弘\n汞\n泓\n洪\n烘\n紅\n虹\n訌\n鴻\n化\n和\n嬅\n樺\n火\n畵\n禍\n禾\n花\n華\n話\n譁\n貨\n靴\n廓\n擴\n攫\n確\n碻\n穫\n丸\n喚\n奐\n宦\n幻\n患\n換\n歡\n晥\n桓\n渙\n煥\n環\n紈\n還\n驩\n鰥\n活\n滑\n猾\n豁\n闊\n凰\n幌\n徨\n恍\n惶\n愰\n慌\n晃\n晄\n榥\n況\n湟\n滉\n潢\n煌\n璜\n皇\n篁\n簧\n荒\n蝗\n遑\n隍\n黃\n匯\n回\n廻\n徊\n恢\n悔\n懷\n晦\n會\n檜\n淮\n澮\n灰\n獪\n繪\n膾\n茴\n蛔\n誨\n賄\n劃\n獲\n宖\n橫\n鐄\n哮\n嚆\n孝\n效\n斅\n曉\n梟\n涍\n淆\n爻\n肴\n酵\n驍\n侯\n候\n厚\n后\n吼\n喉\n嗅\n帿\n後\n朽\n煦\n珝\n逅\n勛\n勳\n塤\n壎\n焄\n熏\n燻\n薰\n訓\n暈\n薨\n喧\n暄\n煊\n萱\n卉\n喙\n毁\n彙\n徽\n揮\n暉\n煇\n諱\n輝\n麾\n休\n携\n烋\n畦\n虧\n恤\n譎\n鷸\n兇\n凶\n匈\n洶\n胸\n黑\n昕\n欣\n炘\n痕\n吃\n屹\n紇\n訖\n欠\n欽\n歆\n吸\n恰\n洽\n翕\n興\n僖\n凞\n喜\n噫\n囍\n姬\n嬉\n希\n憙\n憘\n戱\n晞\n曦\n熙\n熹\n熺\n犧\n禧\n稀\n羲\n詰\n"
  },
  {
    "path": "helix-view/tests/encoding/euc_kr_out_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n¡\n¢\n£\n¤\n¥\n¦\n§\n¨\n©\nª\n«\n¬\n­\n®\n¯\n°\n±\n²\n³\n´\nµ\n¶\n·\n¸\n¹\nº\n»\n¼\n½\n¾\n¿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\nÁ\nÂ\nÃ\nÄ\nÅ\nÆ\nÇ\nÈ\nÉ\nÊ\nË\nÌ\nÍ\nÎ\nÏ\nÐ\nÑ\nÒ\nÓ\nÔ\nÕ\nÖ\n×\nØ\nÙ\nÚ\nÛ\nÜ\nÝ\nÞ\nß\nà\ná\nâ\nã\nä\nå\næ\nç\nè\né\nê\në\nì\ní\nî\nï\nð\nñ\nò\nó\nô\nõ\nö\n÷\nø\nù\nú\nû\nü\ný\nþ\nÿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\nā\nĂ\nă\nĄ\ną\nĆ\nć\nĈ\nĉ\nĊ\nċ\nČ\nč\nĎ\nď\nĐ\nđ\nĒ\nē\nĔ\nĕ\nĖ\nė\nĘ\nę\nĚ\ně\nĜ\nĝ\nĞ\nğ\nĠ\nġ\nĢ\nģ\nĤ\nĥ\nĦ\nħ\nĨ\nĩ\nĪ\nī\nĬ\nĭ\nĮ\nį\nİ\nı\nĲ\nĳ\nĴ\nĵ\nĶ\nķ\nĸ\nĹ\nĺ\nĻ\nļ\nĽ\nľ\nĿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\nŁ\nł\nŃ\nń\nŅ\nņ\nŇ\nň\nŉ\nŊ\nŋ\nŌ\nō\nŎ\nŏ\nŐ\nő\nŒ\nœ\nŔ\nŕ\nŖ\nŗ\nŘ\nř\nŚ\nś\nŜ\nŝ\nŞ\nş\nŠ\nš\nŢ\nţ\nŤ\nť\nŦ\nŧ\nŨ\nũ\nŪ\nū\nŬ\nŭ\nŮ\nů\nŰ\nű\nŲ\nų\nŴ\nŵ\nŶ\nŷ\nŸ\nŹ\nź\nŻ\nż\nŽ\nž\nſ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nơ\nƢ\nƣ\nƤ\nƥ\nƦ\nƧ\nƨ\nƩ\nƪ\nƫ\nƬ\nƭ\nƮ\nƯ\nư\nƱ\nƲ\nƳ\nƴ\nƵ\nƶ\nƷ\nƸ\nƹ\nƺ\nƻ\nƼ\nƽ\nƾ\nƿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nǡ\nǢ\nǣ\nǤ\nǥ\nǦ\nǧ\nǨ\nǩ\nǪ\nǫ\nǬ\nǭ\nǮ\nǯ\nǰ\nǱ\nǲ\nǳ\nǴ\nǵ\nǶ\nǷ\nǸ\nǹ\nǺ\nǻ\nǼ\nǽ\nǾ\nǿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nȡ\nȢ\nȣ\nȤ\nȥ\nȦ\nȧ\nȨ\nȩ\nȪ\nȫ\nȬ\nȭ\nȮ\nȯ\nȰ\nȱ\nȲ\nȳ\nȴ\nȵ\nȶ\nȷ\nȸ\nȹ\nȺ\nȻ\nȼ\nȽ\nȾ\nȿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nʡ\nʢ\nʣ\nʤ\nʥ\nʦ\nʧ\nʨ\nʩ\nʪ\nʫ\nʬ\nʭ\nʮ\nʯ\nʰ\nʱ\nʲ\nʳ\nʴ\nʵ\nʶ\nʷ\nʸ\nʹ\nʺ\nʻ\nʼ\nʽ\nʾ\nʿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nˡ\nˢ\nˣ\nˤ\n˥\n˦\n˧\n˨\n˩\n˪\n˫\nˬ\n˭\nˮ\n˯\n˰\n˱\n˲\n˳\n˴\n˵\n˶\n˷\n˸\n˹\n˺\n˻\n˼\n˽\n˾\n˿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n̡\n̢\ṇ\n̤\n̥\n̦\ņ\n̨\n̩\n̪\n̫\n̬\ṋ\n̮\n̯\n̰\ṉ\n̲\n̳\n̴\n̵\n̶\n̷\n̸\n̹\n̺\n̻\n̼\n̽\n̾\n̿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n͡\n͢\nͣ\nͤ\nͥ\nͦ\nͧ\nͨ\nͩ\nͪ\nͫ\nͬ\nͭ\nͮ\nͯ\nͰ\nͱ\nͲ\nͳ\nʹ\n͵\nͶ\nͷ\n͸\n͹\nͺ\nͻ\nͼ\nͽ\n;\nͿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nΡ\n΢\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nΪ\nΫ\nά\nέ\nή\nί\nΰ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nϡ\nϢ\nϣ\nϤ\nϥ\nϦ\nϧ\nϨ\nϩ\nϪ\nϫ\nϬ\nϭ\nϮ\nϯ\nϰ\nϱ\nϲ\nϳ\nϴ\nϵ\n϶\nϷ\nϸ\nϹ\nϺ\nϻ\nϼ\nϽ\nϾ\nϿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nѡ\nѢ\nѣ\nѤ\nѥ\nѦ\nѧ\nѨ\nѩ\nѪ\nѫ\nѬ\nѭ\nѮ\nѯ\nѰ\nѱ\nѲ\nѳ\nѴ\nѵ\nѶ\nѷ\nѸ\nѹ\nѺ\nѻ\nѼ\nѽ\nѾ\nѿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nҡ\nҢ\nң\nҤ\nҥ\nҦ\nҧ\nҨ\nҩ\nҪ\nҫ\nҬ\nҭ\nҮ\nү\nҰ\nұ\nҲ\nҳ\nҴ\nҵ\nҶ\nҷ\nҸ\nҹ\nҺ\nһ\nҼ\nҽ\nҾ\nҿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nӡ\nӢ\nӣ\nӤ\nӥ\nӦ\nӧ\nӨ\nө\nӪ\nӫ\nӬ\nӭ\nӮ\nӯ\nӰ\nӱ\nӲ\nӳ\nӴ\nӵ\nӶ\nӷ\nӸ\nӹ\nӺ\nӻ\nӼ\nӽ\nӾ\nӿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nԡ\nԢ\nԣ\nԤ\nԥ\nԦ\nԧ\nԨ\nԩ\nԪ\nԫ\nԬ\nԭ\nԮ\nԯ\n԰\nԱ\nԲ\nԳ\nԴ\nԵ\nԶ\nԷ\nԸ\nԹ\nԺ\nԻ\nԼ\nԽ\nԾ\nԿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nա\nբ\nգ\nդ\nե\nզ\nէ\nը\nթ\nժ\nի\nլ\nխ\nծ\nկ\nհ\nձ\nղ\nճ\nմ\nյ\nն\nշ\nո\nչ\nպ\nջ\nռ\nս\nվ\nտ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n֡\n֢\n֣\n֤\n֥\n֦\n֧\n֨\n֩\n֪\n֫\n֬\n֭\n֮\n֯\nְ\nֱ\nֲ\nֳ\nִ\nֵ\nֶ\nַ\nָ\nֹ\nֺ\nֻ\nּ\nֽ\n־\nֿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nס\nע\nף\nפ\nץ\nצ\nק\nר\nש\nת\n׫\n׬\n׭\n׮\nׯ\nװ\nױ\nײ\n׳\n״\n׵\n׶\n׷\n׸\n׹\n׺\n׻\n׼\n׽\n׾\n׿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nء\nآ\nأ\nؤ\nإ\nئ\nا\nب\nة\nت\nث\nج\nح\nخ\nد\nذ\nر\nز\nس\nش\nص\nض\nط\nظ\nع\nغ\nػ\nؼ\nؽ\nؾ\nؿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n١\n٢\n٣\n٤\n٥\n٦\n٧\n٨\n٩\n٪\n٫\n٬\n٭\nٮ\nٯ\nٰ\nٱ\nٲ\nٳ\nٴ\nٵ\nٶ\nٷ\nٸ\nٹ\nٺ\nٻ\nټ\nٽ\nپ\nٿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nڡ\nڢ\nڣ\nڤ\nڥ\nڦ\nڧ\nڨ\nک\nڪ\nګ\nڬ\nڭ\nڮ\nگ\nڰ\nڱ\nڲ\nڳ\nڴ\nڵ\nڶ\nڷ\nڸ\nڹ\nں\nڻ\nڼ\nڽ\nھ\nڿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nۡ\nۢ\nۣ\nۤ\nۥ\nۦ\nۧ\nۨ\n۩\n۪\n۫\n۬\nۭ\nۮ\nۯ\n۰\n۱\n۲\n۳\n۴\n۵\n۶\n۷\n۸\n۹\nۺ\nۻ\nۼ\n۽\n۾\nۿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nܡ\nܢ\nܣ\nܤ\nܥ\nܦ\nܧ\nܨ\nܩ\nܪ\nܫ\nܬ\nܭ\nܮ\nܯ\nܰ\nܱ\nܲ\nܳ\nܴ\nܵ\nܶ\nܷ\nܸ\nܹ\nܺ\nܻ\nܼ\nܽ\nܾ\nܿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nݡ\nݢ\nݣ\nݤ\nݥ\nݦ\nݧ\nݨ\nݩ\nݪ\nݫ\nݬ\nݭ\nݮ\nݯ\nݰ\nݱ\nݲ\nݳ\nݴ\nݵ\nݶ\nݷ\nݸ\nݹ\nݺ\nݻ\nݼ\nݽ\nݾ\nݿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nޡ\nޢ\nޣ\nޤ\nޥ\nަ\nާ\nި\nީ\nު\nޫ\nެ\nޭ\nޮ\nޯ\nް\nޱ\n޲\n޳\n޴\n޵\n޶\n޷\n޸\n޹\n޺\n޻\n޼\n޽\n޾\n޿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nߡ\nߢ\nߣ\nߤ\nߥ\nߦ\nߧ\nߨ\nߩ\nߪ\n߫\n߬\n߭\n߮\n߯\n߰\n߱\n߲\n߳\nߴ\nߵ\n߶\n߷\n߸\n߹\nߺ\n߻\n߼\n߽\n߾\n߿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/gb18030_in.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n¡\n¢\n£\n¤\n¥\n¦\n§\n¨\n©\nª\n«\n¬\n­\n®\n¯\n°\n±\n²\n³\n´\nµ\n¶\n·\n¸\n¹\nº\n»\n¼\n½\n¾\n¿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nÀ\nÁ\nÂ\nÃ\nÄ\nÅ\nÆ\nÇ\nÈ\nÉ\nÊ\nË\nÌ\nÍ\nÎ\nÏ\nÐ\nÑ\nÒ\nÓ\nÔ\nÕ\nÖ\n×\nØ\nÙ\nÚ\nÛ\nÜ\nÝ\nÞ\nß\nà\ná\nâ\nã\nä\nå\næ\nç\nè\né\nê\në\nì\ní\nî\nï\nð\nñ\nò\nó\nô\nõ\nö\n÷\nø\nù\nú\nû\nü\ný\nþ\nÿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nĀ\nā\nĂ\nă\nĄ\ną\nĆ\nć\nĈ\nĉ\nĊ\nċ\nČ\nč\nĎ\nď\nĐ\nđ\nĒ\nē\nĔ\nĕ\nĖ\nė\nĘ\nę\nĚ\ně\nĜ\nĝ\nĞ\nğ\nĠ\nġ\nĢ\nģ\nĤ\nĥ\nĦ\nħ\nĨ\nĩ\nĪ\nī\nĬ\nĭ\nĮ\nį\nİ\nı\nĲ\nĳ\nĴ\nĵ\nĶ\nķ\nĸ\nĹ\nĺ\nĻ\nļ\nĽ\nľ\nĿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nŀ\nŁ\nł\nŃ\nń\nŅ\nņ\nŇ\nň\nŉ\nŊ\nŋ\nŌ\nō\nŎ\nŏ\nŐ\nő\nŒ\nœ\nŔ\nŕ\nŖ\nŗ\nŘ\nř\nŚ\nś\nŜ\nŝ\nŞ\nş\nŠ\nš\nŢ\nţ\nŤ\nť\nŦ\nŧ\nŨ\nũ\nŪ\nū\nŬ\nŭ\nŮ\nů\nŰ\nű\nŲ\nų\nŴ\nŵ\nŶ\nŷ\nŸ\nŹ\nź\nŻ\nż\nŽ\nž\nſ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nƀ\nƁ\nƂ\nƃ\nƄ\nƅ\nƆ\nƇ\nƈ\nƉ\nƊ\nƋ\nƌ\nƍ\nƎ\nƏ\nƐ\nƑ\nƒ\nƓ\nƔ\nƕ\nƖ\nƗ\nƘ\nƙ\nƚ\nƛ\nƜ\nƝ\nƞ\nƟ\nƠ\nơ\nƢ\nƣ\nƤ\nƥ\nƦ\nƧ\nƨ\nƩ\nƪ\nƫ\nƬ\nƭ\nƮ\nƯ\nư\nƱ\nƲ\nƳ\nƴ\nƵ\nƶ\nƷ\nƸ\nƹ\nƺ\nƻ\nƼ\nƽ\nƾ\nƿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nǀ\nǁ\nǂ\nǃ\nǄ\nǅ\nǆ\nǇ\nǈ\nǉ\nǊ\nǋ\nǌ\nǍ\nǎ\nǏ\nǐ\nǑ\nǒ\nǓ\nǔ\nǕ\nǖ\nǗ\nǘ\nǙ\nǚ\nǛ\nǜ\nǝ\nǞ\nǟ\nǠ\nǡ\nǢ\nǣ\nǤ\nǥ\nǦ\nǧ\nǨ\nǩ\nǪ\nǫ\nǬ\nǭ\nǮ\nǯ\nǰ\nǱ\nǲ\nǳ\nǴ\nǵ\nǶ\nǷ\nǸ\nǹ\nǺ\nǻ\nǼ\nǽ\nǾ\nǿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nȀ\nȁ\nȂ\nȃ\nȄ\nȅ\nȆ\nȇ\nȈ\nȉ\nȊ\nȋ\nȌ\nȍ\nȎ\nȏ\nȐ\nȑ\nȒ\nȓ\nȔ\nȕ\nȖ\nȗ\nȘ\nș\nȚ\nț\nȜ\nȝ\nȞ\nȟ\nȠ\nȡ\nȢ\nȣ\nȤ\nȥ\nȦ\nȧ\nȨ\nȩ\nȪ\nȫ\nȬ\nȭ\nȮ\nȯ\nȰ\nȱ\nȲ\nȳ\nȴ\nȵ\nȶ\nȷ\nȸ\nȹ\nȺ\nȻ\nȼ\nȽ\nȾ\nȿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nɀ\nɁ\nɂ\nɃ\nɄ\nɅ\nɆ\nɇ\nɈ\nɉ\nɊ\nɋ\nɌ\nɍ\nɎ\nɏ\nɐ\nɑ\nɒ\nɓ\nɔ\nɕ\nɖ\nɗ\nɘ\nə\nɚ\nɛ\nɜ\nɝ\nɞ\nɟ\nɠ\nɡ\nɢ\nɣ\nɤ\nɥ\nɦ\nɧ\nɨ\nɩ\nɪ\nɫ\nɬ\nɭ\nɮ\nɯ\nɰ\nɱ\nɲ\nɳ\nɴ\nɵ\nɶ\nɷ\nɸ\nɹ\nɺ\nɻ\nɼ\nɽ\nɾ\nɿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nʀ\nʁ\nʂ\nʃ\nʄ\nʅ\nʆ\nʇ\nʈ\nʉ\nʊ\nʋ\nʌ\nʍ\nʎ\nʏ\nʐ\nʑ\nʒ\nʓ\nʔ\nʕ\nʖ\nʗ\nʘ\nʙ\nʚ\nʛ\nʜ\nʝ\nʞ\nʟ\nʠ\nʡ\nʢ\nʣ\nʤ\nʥ\nʦ\nʧ\nʨ\nʩ\nʪ\nʫ\nʬ\nʭ\nʮ\nʯ\nʰ\nʱ\nʲ\nʳ\nʴ\nʵ\nʶ\nʷ\nʸ\nʹ\nʺ\nʻ\nʼ\nʽ\nʾ\nʿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nˀ\nˁ\n˂\n˃\n˄\n˅\nˆ\nˇ\nˈ\nˉ\nˊ\nˋ\nˌ\nˍ\nˎ\nˏ\nː\nˑ\n˒\n˓\n˔\n˕\n˖\n˗\n˘\n˙\n˚\n˛\n˜\n˝\n˞\n˟\nˠ\nˡ\nˢ\nˣ\nˤ\n˥\n˦\n˧\n˨\n˩\n˪\n˫\nˬ\n˭\nˮ\n˯\n˰\n˱\n˲\n˳\n˴\n˵\n˶\n˷\n˸\n˹\n˺\n˻\n˼\n˽\n˾\n˿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\ǹ\ń\n̂\ñ\n̄\n̅\n̆\ṅ\n̈\n̉\n̊\n̋\ň\n̍\n̎\n̏\n̐\n̑\n̒\n̓\n̔\n̕\n̖\n̗\n̘\n̙\n̚\n̛\n̜\n̝\n̞\n̟\n̠\n̡\n̢\ṇ\n̤\n̥\n̦\ņ\n̨\n̩\n̪\n̫\n̬\ṋ\n̮\n̯\n̰\ṉ\n̲\n̳\n̴\n̵\n̶\n̷\n̸\n̹\n̺\n̻\n̼\n̽\n̾\n̿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\ǹ\ń\n͂\n̓\n̈́\nͅ\n͆\n͇\n͈\n͉\n͊\n͋\n͌\n͍\n͎\n͏\n͐\n͑\n͒\n͓\n͔\n͕\n͖\n͗\n͘\n͙\n͚\n͛\n͜\n͝\n͞\n͟\n͠\n͡\n͢\nͣ\nͤ\nͥ\nͦ\nͧ\nͨ\nͩ\nͪ\nͫ\nͬ\nͭ\nͮ\nͯ\nͰ\nͱ\nͲ\nͳ\nʹ\n͵\nͶ\nͷ\n͸\n͹\nͺ\nͻ\nͼ\nͽ\n;\nͿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n΀\n΁\n΂\n΃\n΄\n΅\nΆ\n·\nΈ\nΉ\nΊ\n΋\nΌ\n΍\nΎ\nΏ\nΐ\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\n΢\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nΪ\nΫ\nά\nέ\nή\nί\nΰ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nπ\nρ\nς\nσ\nτ\nυ\nφ\nχ\nψ\nω\nϊ\nϋ\nό\nύ\nώ\nϏ\nϐ\nϑ\nϒ\nϓ\nϔ\nϕ\nϖ\nϗ\nϘ\nϙ\nϚ\nϛ\nϜ\nϝ\nϞ\nϟ\nϠ\nϡ\nϢ\nϣ\nϤ\nϥ\nϦ\nϧ\nϨ\nϩ\nϪ\nϫ\nϬ\nϭ\nϮ\nϯ\nϰ\nϱ\nϲ\nϳ\nϴ\nϵ\n϶\nϷ\nϸ\nϹ\nϺ\nϻ\nϼ\nϽ\nϾ\nϿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nЀ\nЁ\nЂ\nЃ\nЄ\nЅ\nІ\nЇ\nЈ\nЉ\nЊ\nЋ\nЌ\nЍ\nЎ\nЏ\nА\nБ\nВ\nГ\nД\nЕ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\nѐ\nё\nђ\nѓ\nє\nѕ\nі\nї\nј\nљ\nњ\nћ\nќ\nѝ\nў\nџ\nѠ\nѡ\nѢ\nѣ\nѤ\nѥ\nѦ\nѧ\nѨ\nѩ\nѪ\nѫ\nѬ\nѭ\nѮ\nѯ\nѰ\nѱ\nѲ\nѳ\nѴ\nѵ\nѶ\nѷ\nѸ\nѹ\nѺ\nѻ\nѼ\nѽ\nѾ\nѿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nҀ\nҁ\n҂\n҃\n҄\n҅\n҆\n҇\n҈\n҉\nҊ\nҋ\nҌ\nҍ\nҎ\nҏ\nҐ\nґ\nҒ\nғ\nҔ\nҕ\nҖ\nҗ\nҘ\nҙ\nҚ\nқ\nҜ\nҝ\nҞ\nҟ\nҠ\nҡ\nҢ\nң\nҤ\nҥ\nҦ\nҧ\nҨ\nҩ\nҪ\nҫ\nҬ\nҭ\nҮ\nү\nҰ\nұ\nҲ\nҳ\nҴ\nҵ\nҶ\nҷ\nҸ\nҹ\nҺ\nһ\nҼ\nҽ\nҾ\nҿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nӀ\nӁ\nӂ\nӃ\nӄ\nӅ\nӆ\nӇ\nӈ\nӉ\nӊ\nӋ\nӌ\nӍ\nӎ\nӏ\nӐ\nӑ\nӒ\nӓ\nӔ\nӕ\nӖ\nӗ\nӘ\nә\nӚ\nӛ\nӜ\nӝ\nӞ\nӟ\nӠ\nӡ\nӢ\nӣ\nӤ\nӥ\nӦ\nӧ\nӨ\nө\nӪ\nӫ\nӬ\nӭ\nӮ\nӯ\nӰ\nӱ\nӲ\nӳ\nӴ\nӵ\nӶ\nӷ\nӸ\nӹ\nӺ\nӻ\nӼ\nӽ\nӾ\nӿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nԀ\nԁ\nԂ\nԃ\nԄ\nԅ\nԆ\nԇ\nԈ\nԉ\nԊ\nԋ\nԌ\nԍ\nԎ\nԏ\nԐ\nԑ\nԒ\nԓ\nԔ\nԕ\nԖ\nԗ\nԘ\nԙ\nԚ\nԛ\nԜ\nԝ\nԞ\nԟ\nԠ\nԡ\nԢ\nԣ\nԤ\nԥ\nԦ\nԧ\nԨ\nԩ\nԪ\nԫ\nԬ\nԭ\nԮ\nԯ\n԰\nԱ\nԲ\nԳ\nԴ\nԵ\nԶ\nԷ\nԸ\nԹ\nԺ\nԻ\nԼ\nԽ\nԾ\nԿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nՀ\nՁ\nՂ\nՃ\nՄ\nՅ\nՆ\nՇ\nՈ\nՉ\nՊ\nՋ\nՌ\nՍ\nՎ\nՏ\nՐ\nՑ\nՒ\nՓ\nՔ\nՕ\nՖ\n՗\n՘\nՙ\n՚\n՛\n՜\n՝\n՞\n՟\nՠ\nա\nբ\nգ\nդ\nե\nզ\nէ\nը\nթ\nժ\nի\nլ\nխ\nծ\nկ\nհ\nձ\nղ\nճ\nմ\nյ\nն\nշ\nո\nչ\nպ\nջ\nռ\nս\nվ\nտ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nր\nց\nւ\nփ\nք\nօ\nֆ\nև\nֈ\n։\n֊\n֋\n֌\n֍\n֎\n֏\n֐\n֑\n֒\n֓\n֔\n֕\n֖\n֗\n֘\n֙\n֚\n֛\n֜\n֝\n֞\n֟\n֠\n֡\n֢\n֣\n֤\n֥\n֦\n֧\n֨\n֩\n֪\n֫\n֬\n֭\n֮\n֯\nְ\nֱ\nֲ\nֳ\nִ\nֵ\nֶ\nַ\nָ\nֹ\nֺ\nֻ\nּ\nֽ\n־\nֿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n׀\nׁ\nׂ\n׃\nׄ\nׅ\n׆\nׇ\n׈\n׉\n׊\n׋\n׌\n׍\n׎\n׏\nא\nב\nג\nד\nה\nו\nז\nח\nט\nי\nך\nכ\nל\nם\nמ\nן\nנ\nס\nע\nף\nפ\nץ\nצ\nק\nר\nש\nת\n׫\n׬\n׭\n׮\nׯ\nװ\nױ\nײ\n׳\n״\n׵\n׶\n׷\n׸\n׹\n׺\n׻\n׼\n׽\n׾\n׿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n؀\n؁\n؂\n؃\n؄\n؅\n؆\n؇\n؈\n؉\n؊\n؋\n،\n؍\n؎\n؏\nؐ\nؑ\nؒ\nؓ\nؔ\nؕ\nؖ\nؗ\nؘ\nؙ\nؚ\n؛\n؜\n؝\n؞\n؟\nؠ\nء\nآ\nأ\nؤ\nإ\nئ\nا\nب\nة\nت\nث\nج\nح\nخ\nد\nذ\nر\nز\nس\nش\nص\nض\nط\nظ\nع\nغ\nػ\nؼ\nؽ\nؾ\nؿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nـ\nف\nق\nك\nل\nم\nن\nه\nو\nى\nي\nً\nٌ\nٍ\nَ\nُ\nِ\nّ\nْ\nٓ\nٔ\nٕ\nٖ\nٗ\n٘\nٙ\nٚ\nٛ\nٜ\nٝ\nٞ\nٟ\n٠\n١\n٢\n٣\n٤\n٥\n٦\n٧\n٨\n٩\n٪\n٫\n٬\n٭\nٮ\nٯ\nٰ\nٱ\nٲ\nٳ\nٴ\nٵ\nٶ\nٷ\nٸ\nٹ\nٺ\nٻ\nټ\nٽ\nپ\nٿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nڀ\nځ\nڂ\nڃ\nڄ\nڅ\nچ\nڇ\nڈ\nډ\nڊ\nڋ\nڌ\nڍ\nڎ\nڏ\nڐ\nڑ\nڒ\nړ\nڔ\nڕ\nږ\nڗ\nژ\nڙ\nښ\nڛ\nڜ\nڝ\nڞ\nڟ\nڠ\nڡ\nڢ\nڣ\nڤ\nڥ\nڦ\nڧ\nڨ\nک\nڪ\nګ\nڬ\nڭ\nڮ\nگ\nڰ\nڱ\nڲ\nڳ\nڴ\nڵ\nڶ\nڷ\nڸ\nڹ\nں\nڻ\nڼ\nڽ\nھ\nڿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nۀ\nہ\nۂ\nۃ\nۄ\nۅ\nۆ\nۇ\nۈ\nۉ\nۊ\nۋ\nی\nۍ\nێ\nۏ\nې\nۑ\nے\nۓ\n۔\nە\nۖ\nۗ\nۘ\nۙ\nۚ\nۛ\nۜ\n۝\n۞\n۟\n۠\nۡ\nۢ\nۣ\nۤ\nۥ\nۦ\nۧ\nۨ\n۩\n۪\n۫\n۬\nۭ\nۮ\nۯ\n۰\n۱\n۲\n۳\n۴\n۵\n۶\n۷\n۸\n۹\nۺ\nۻ\nۼ\n۽\n۾\nۿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n܀\n܁\n܂\n܃\n܄\n܅\n܆\n܇\n܈\n܉\n܊\n܋\n܌\n܍\n܎\n܏\nܐ\nܑ\nܒ\nܓ\nܔ\nܕ\nܖ\nܗ\nܘ\nܙ\nܚ\nܛ\nܜ\nܝ\nܞ\nܟ\nܠ\nܡ\nܢ\nܣ\nܤ\nܥ\nܦ\nܧ\nܨ\nܩ\nܪ\nܫ\nܬ\nܭ\nܮ\nܯ\nܰ\nܱ\nܲ\nܳ\nܴ\nܵ\nܶ\nܷ\nܸ\nܹ\nܺ\nܻ\nܼ\nܽ\nܾ\nܿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n݀\n݁\n݂\n݃\n݄\n݅\n݆\n݇\n݈\n݉\n݊\n݋\n݌\nݍ\nݎ\nݏ\nݐ\nݑ\nݒ\nݓ\nݔ\nݕ\nݖ\nݗ\nݘ\nݙ\nݚ\nݛ\nݜ\nݝ\nݞ\nݟ\nݠ\nݡ\nݢ\nݣ\nݤ\nݥ\nݦ\nݧ\nݨ\nݩ\nݪ\nݫ\nݬ\nݭ\nݮ\nݯ\nݰ\nݱ\nݲ\nݳ\nݴ\nݵ\nݶ\nݷ\nݸ\nݹ\nݺ\nݻ\nݼ\nݽ\nݾ\nݿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nހ\nށ\nނ\nރ\nބ\nޅ\nކ\nއ\nވ\nމ\nފ\nދ\nތ\nލ\nގ\nޏ\nސ\nޑ\nޒ\nޓ\nޔ\nޕ\nޖ\nޗ\nޘ\nޙ\nޚ\nޛ\nޜ\nޝ\nޞ\nޟ\nޠ\nޡ\nޢ\nޣ\nޤ\nޥ\nަ\nާ\nި\nީ\nު\nޫ\nެ\nޭ\nޮ\nޯ\nް\nޱ\n޲\n޳\n޴\n޵\n޶\n޷\n޸\n޹\n޺\n޻\n޼\n޽\n޾\n޿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n߀\n߁\n߂\n߃\n߄\n߅\n߆\n߇\n߈\n߉\nߊ\nߋ\nߌ\nߍ\nߎ\nߏ\nߐ\nߑ\nߒ\nߓ\nߔ\nߕ\nߖ\nߗ\nߘ\nߙ\nߚ\nߛ\nߜ\nߝ\nߞ\nߟ\nߠ\nߡ\nߢ\nߣ\nߤ\nߥ\nߦ\nߧ\nߨ\nߩ\nߪ\n߫\n߬\n߭\n߮\n߯\n߰\n߱\n߲\n߳\nߴ\nߵ\n߶\n߷\n߸\n߹\nߺ\n߻\n߼\n߽\n߾\n߿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/gb18030_in_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n丂\n丄\n丅\n丆\n丏\n丒\n丗\n丟\n丠\n両\n丣\n並\n丩\n丮\n丯\n丱\n丳\n丵\n丷\n丼\n乀\n乁\n乂\n乄\n乆\n乊\n乑\n乕\n乗\n乚\n乛\n乢\n乣\n乤\n乥\n乧\n乨\n乪\n乫\n乬\n乭\n乮\n乯\n乲\n乴\n乵\n乶\n乷\n乸\n乹\n乺\n乻\n乼\n乽\n乿\n亀\n亁\n亂\n亃\n亄\n亅\n亇\n亊\n亐\n亖\n亗\n亙\n亜\n亝\n亞\n亣\n亪\n亯\n亰\n亱\n亴\n亶\n亷\n亸\n亹\n亼\n亽\n亾\n仈\n仌\n仏\n仐\n仒\n仚\n仛\n仜\n仠\n仢\n仦\n仧\n仩\n仭\n仮\n仯\n仱\n仴\n仸\n仹\n仺\n仼\n仾\n伀\n伂\n伃\n伄\n伅\n伆\n伇\n伈\n伋\n伌\n伒\n伓\n伔\n伕\n伖\n伜\n伝\n伡\n伣\n伨\n伩\n伬\n伭\n伮\n伱\n伳\n伵\n伷\n伹\n伻\n伾\n伿\n佀\n佁\n佂\n佄\n佅\n佇\n佈\n佉\n佊\n佋\n佌\n佒\n佔\n佖\n佡\n佢\n佦\n佨\n佪\n佫\n佭\n佮\n佱\n佲\n併\n佷\n佸\n佹\n佺\n佽\n侀\n侁\n侂\n侅\n來\n侇\n侊\n侌\n侎\n侐\n侒\n侓\n侕\n侖\n侘\n侙\n侚\n侜\n侞\n侟\n価\n侢\n侤\n侫\n侭\n侰\n侱\n侲\n侳\n侴\n侶\n侷\n侸\n侹\n侺\n侻\n侼\n侽\n侾\n俀\n俁\n係\n俆\n俇\n俈\n俉\n俋\n俌\n俍\n俒\n俓\n俔\n俕\n俖\n俙\n俛\n俠\n俢\n俤\n俥\n俧\n俫\n俬\n俰\n俲\n俴\n俵\n俶\n俷\n俹\n俻\n俼\n俽\n俿\n倀\n倁\n倂\n倃\n倄\n倅\n倆\n倇\n倈\n倉\n倊\n個\n倎\n倐\n們\n倓\n倕\n倖\n倗\n倛\n倝\n倞\n倠\n倢\n倣\n値\n倧\n倫\n倯\n倰\n倱\n倲\n倳\n倴\n倵\n倶\n倷\n倸\n倹\n倻\n倽\n倿\n偀\n偁\n偂\n偄\n偅\n偆\n偉\n偊\n偋\n偍\n偐\n偑\n偒\n偓\n偔\n偖\n偗\n偘\n偙\n偛\n偝\n偞\n偟\n偠\n偡\n偢\n偣\n偤\n偦\n偧\n偨\n偩\n偪\n偫\n偭\n偮\n偯\n偰\n偱\n偲\n偳\n側\n偵\n偸\n偹\n偺\n偼\n偽\n傁\n傂\n傃\n傄\n傆\n傇\n傉\n傊\n傋\n傌\n傎\n傏\n傐\n傑\n傒\n傓\n傔\n傕\n傖\n傗\n傘\n備\n傚\n傛\n傜\n傝\n傞\n傟\n傠\n傡\n傢\n傤\n傦\n傪\n傫\n傭\n傮\n傯\n傰\n傱\n傳\n傴\n債\n傶\n傷\n傸\n傹\n傼\n傽\n傾\n傿\n僀\n僁\n僂\n僃\n僄\n僅\n僆\n僇\n僈\n僉\n僊\n僋\n僌\n働\n僎\n僐\n僑\n僒\n僓\n僔\n僕\n僗\n僘\n僙\n僛\n僜\n僝\n僞\n僟\n僠\n僡\n僢\n僣\n僤\n僥\n僨\n僩\n僪\n僫\n僯\n僰\n僱\n僲\n僴\n僶\n僷\n僸\n價\n僺\n僼\n僽\n僾\n僿\n儀\n儁\n儂\n儃\n億\n儅\n儈\n儉\n儊\n儌\n儍\n儎\n儏\n儐\n儑\n儓\n儔\n儕\n儖\n儗\n儘\n儙\n儚\n儛\n儜\n儝\n儞\n償\n儠\n儢\n儣\n儤\n儥\n儦\n儧\n儨\n儩\n優\n儫\n儬\n儭\n儮\n儯\n儰\n儱\n儲\n儳\n儴\n儵\n儶\n儷\n儸\n儹\n儺\n儻\n儼\n儽\n儾\n兂\n兇\n兊\n兌\n兎\n兏\n児\n兒\n兓\n兗\n兘\n兙\n兛\n兝\n兞\n兟\n兠\n兡\n兣\n兤\n兦\n內\n兩\n兪\n兯\n兲\n兺\n兾\n兿\n冃\n冄\n円\n冇\n冊\n冋\n冎\n冏\n冐\n冑\n冓\n冔\n冘\n冚\n冝\n冞\n冟\n冡\n冣\n冦\n冧\n冨\n冩\n冪\n冭\n冮\n冴\n冸\n冹\n冺\n冾\n冿\n凁\n凂\n凃\n凅\n凈\n凊\n凍\n凎\n凐\n凒\n凓\n凔\n凕\n凖\n凗\n凘\n凙\n凚\n凜\n凞\n凟\n凢\n凣\n凥\n処\n凧\n凨\n凩\n凪\n凬\n凮\n凱\n凲\n凴\n凷\n凾\n刄\n刅\n刉\n刋\n刌\n刏\n刐\n刓\n刔\n刕\n刜\n刞\n刟\n刡\n刢\n刣\n別\n刦\n刧\n刪\n刬\n刯\n刱\n刲\n刴\n刵\n刼\n刾\n剄\n剅\n剆\n則\n剈\n剉\n剋\n剎\n剏\n剒\n剓\n剕\n剗\n剘\n剙\n剚\n剛\n剝\n剟\n剠\n剢\n剣\n剤\n剦\n剨\n剫\n剬\n剭\n剮\n剰\n剱\n剳\n剴\n創\n剶\n剷\n剸\n剹\n剺\n剻\n剼\n剾\n劀\n劃\n劄\n劅\n劆\n劇\n劉\n劊\n劋\n劌\n劍\n劎\n劏\n劑\n劒\n劔\n劕\n劖\n劗\n劘\n劙\n劚\n劜\n劤\n劥\n劦\n劧\n劮\n劯\n劰\n労\n劵\n劶\n劷\n劸\n効\n劺\n劻\n劼\n劽\n勀\n勁\n勂\n勄\n勅\n勆\n勈\n勊\n勌\n勍\n勎\n勏\n勑\n勓\n勔\n動\n勗\n務\n勚\n勛\n勜\n勝\n勞\n勠\n勡\n勢\n勣\n勥\n勦\n勧\n勨\n勩\n勪\n勫\n勬\n勭\n勮\n勯\n勱\n勲\n勳\n勴\n勵\n勶\n勷\n勸\n勻\n勼\n勽\n匁\n匂\n匃\n匄\n匇\n匉\n匊\n匋\n匌\n匎\n匑\n匒\n匓\n匔\n匘\n匛\n匜\n匞\n匟\n匢\n匤\n匥\n匧\n匨\n匩\n匫\n匬\n匭\n匯\n匰\n匱\n匲\n匳\n匴\n匵\n匶\n匷\n匸\n匼\n匽\n區\n卂\n卄\n卆\n卋\n卌\n卍\n卐\n協\n単\n卙\n卛\n卝\n卥\n卨\n卪\n卬\n卭\n卲\n卶\n卹\n卻\n卼\n卽\n卾\n厀\n厁\n厃\n厇\n厈\n厊\n厎\n厏\n厐\n厑\n厒\n厓\n厔\n厖\n厗\n厙\n厛\n厜\n厞\n厠\n厡\n厤\n厧\n厪\n厫\n厬\n厭\n厯\n厰\n厱\n厲\n厳\n厴\n厵\n厷\n厸\n厹\n厺\n厼\n厽\n厾\n叀\n參\n叄\n叅\n叆\n叇\n収\n叏\n叐\n叒\n叓\n叕\n叚\n叜\n叝\n叞\n叡\n叢\n叧\n叴\n叺\n叾\n叿\n吀\n吂\n吅\n吇\n吋\n吔\n吘\n吙\n吚\n吜\n吢\n吤\n吥\n吪\n吰\n吳\n吶\n吷\n吺\n吽\n吿\n呁\n呂\n呄\n呅\n呇\n呉\n呌\n呍\n呎\n呏\n呑\n呚\n呝\n呞\n呟\n呠\n呡\n呣\n呥\n呧\n呩\n呪\n呫\n呬\n呭\n呮\n呯\n呰\n呴\n呹\n呺\n呾\n呿\n咁\n咃\n咅\n咇\n咈\n咉\n咊\n咍\n咑\n咓\n咗\n咘\n咜\n咞\n咟\n咠\n咡\n咢\n咥\n咮\n咰\n咲\n咵\n咶\n咷\n咹\n咺\n咼\n咾\n哃\n哅\n哊\n哋\n哖\n哘\n哛\n哠\n員\n哢\n哣\n哤\n哫\n哬\n哯\n哰\n哱\n哴\n哵\n哶\n哷\n哸\n哹\n哻\n哾\n唀\n唂\n唃\n唄\n唅\n唈\n唊\n唋\n唌\n唍\n唎\n唒\n唓\n唕\n唖\n唗\n唘\n唙\n唚\n唜\n唝\n唞\n唟\n唡\n唥\n唦\n唨\n唩\n唫\n唭\n唲\n唴\n唵\n唶\n唸\n唹\n唺\n唻\n唽\n啀\n啂\n啅\n啇\n啈\n啋\n啌\n啍\n啎\n問\n啑\n啒\n啓\n啔\n啗\n啘\n啙\n啚\n啛\n啝\n啞\n啟\n啠\n啢\n啣\n啨\n啩\n啫\n啯\n啰\n啱\n啲\n啳\n啴\n啹\n啺\n啽\n啿\n喅\n喆\n喌\n喍\n喎\n喐\n喒\n喓\n喕\n喖\n喗\n喚\n喛\n喞\n喠\n喡\n喢\n喣\n喤\n喥\n喦\n喨\n喩\n喪\n喫\n喬\n喭\n單\n喯\n喰\n喲\n喴\n営\n喸\n喺\n喼\n喿\n嗀\n嗁\n嗂\n嗃\n嗆\n嗇\n嗈\n嗊\n嗋\n嗎\n嗏\n嗐\n嗕\n嗗\n嗘\n嗙\n嗚\n嗛\n嗞\n嗠\n嗢\n嗧\n嗩\n嗭\n嗮\n嗰\n嗱\n嗴\n嗶\n嗸\n嗹\n嗺\n嗻\n嗼\n嗿\n嘂\n嘃\n嘄\n嘅\n嘆\n嘇\n嘊\n嘋\n嘍\n嘐\n嘑\n嘒\n嘓\n嘔\n嘕\n嘖\n嘗\n嘙\n嘚\n嘜\n嘝\n嘠\n嘡\n嘢\n嘥\n嘦\n嘨\n嘩\n嘪\n嘫\n嘮\n嘯\n嘰\n嘳\n嘵\n嘷\n嘸\n嘺\n嘼\n嘽\n嘾\n噀\n噁\n噂\n噃\n噄\n噅\n噆\n噇\n噈\n噉\n噊\n噋\n噏\n噐\n噑\n噒\n噓\n噕\n噖\n噚\n噛\n噝\n噞\n噟\n噠\n噡\n噣\n噥\n噦\n噧\n噭\n噮\n噯\n噰\n噲\n噳\n噴\n噵\n噷\n噸\n噹\n噺\n噽\n噾\n噿\n嚀\n嚁\n嚂\n嚃\n嚄\n嚇\n嚈\n嚉\n嚊\n嚋\n嚌\n嚍\n嚐\n嚑\n嚒\n嚔\n嚕\n嚖\n嚗\n嚘\n嚙\n嚚\n嚛\n嚜\n嚝\n嚞\n嚟\n嚠\n嚡\n嚢\n嚤\n嚥\n嚦\n嚧\n嚨\n嚩\n嚪\n嚫\n嚬\n嚭\n嚮\n嚰\n嚱\n嚲\n嚳\n嚴\n嚵\n嚶\n嚸\n嚹\n嚺\n嚻\n嚽\n嚾\n嚿\n囀\n囁\n囂\n囃\n囄\n囅\n囆\n囇\n囈\n囉\n囋\n囌\n囍\n囎\n囏\n囐\n囑\n囒\n囓\n囕\n囖\n囘\n囙\n囜\n団\n囥\n囦\n囧\n囨\n囩\n囪\n囬\n囮\n囯\n囲\n図\n囶\n囷\n囸\n囻\n囼\n圀\n圁\n圂\n圅\n圇\n國\n圌\n圍\n圎\n圏\n圐\n圑\n園\n圓\n圔\n圕\n圖\n圗\n團\n圙\n圚\n圛\n圝\n圞\n圠\n圡\n圢\n圤\n圥\n圦\n圧\n圫\n圱\n圲\n圴\n圵\n圶\n圷\n圸\n圼\n圽\n圿\n坁\n坃\n坄\n坅\n坆\n坈\n坉\n坋\n坒\n坓\n坔\n坕\n坖\n坘\n坙\n坢\n坣\n坥\n坧\n坬\n坮\n坰\n坱\n坲\n坴\n坵\n坸\n坹\n坺\n坽\n坾\n坿\n垀\n垁\n垇\n垈\n垉\n垊\n垍\n垎\n垏\n垐\n垑\n垔\n垕\n垖\n垗\n垘\n垙\n垚\n垜\n垝\n垞\n垟\n垥\n垨\n垪\n垬\n垯\n垰\n垱\n垳\n垵\n垶\n垷\n垹\n垺\n垻\n垼\n垽\n垾\n垿\n埀\n埁\n埄\n埅\n埆\n埇\n埈\n埉\n埊\n埌\n埍\n埐\n埑\n埓\n埖\n埗\n埛\n埜\n埞\n埡\n埢\n埣\n埥\n埦\n埧\n埨\n埩\n埪\n埫\n埬\n埮\n埰\n埱\n埲\n埳\n埵\n埶\n執\n埻\n埼\n埾\n埿\n堁\n堃\n堄\n堅\n堈\n堉\n堊\n堌\n堎\n堏\n堐\n堒\n堓\n堔\n堖\n堗\n堘\n堚\n堛\n堜\n堝\n堟\n堢\n堣\n堥\n堦\n堧\n堨\n堩\n堫\n堬\n堭\n堮\n堯\n報\n堲\n堳\n場\n堶\n堷\n堸\n堹\n堺\n堻\n堼\n堽\n堾\n堿\n塀\n塁\n塂\n塃\n塅\n塆\n塇\n塈\n塉\n塊\n塋\n塎\n塏\n塐\n塒\n塓\n塕\n塖\n塗\n塙\n塚\n塛\n塜\n塝\n塟\n塠\n塡\n塢\n塣\n塤\n塦\n塧\n塨\n塩\n塪\n塭\n塮\n塯\n塰\n塱\n塲\n塳\n塴\n塵\n塶\n塷\n塸\n塹\n塺\n塻\n塼\n塽\n塿\n墂\n墄\n墆\n墇\n墈\n墊\n墋\n墌\n墍\n墎\n墏\n墐\n墑\n墔\n墕\n墖\n増\n墘\n墛\n墜\n墝\n墠\n墡\n墢\n墣\n墤\n墥\n墦\n墧\n墪\n墫\n墬\n墭\n墮\n墯\n墰\n墱\n墲\n墳\n墴\n墵\n墶\n墷\n墸\n墹\n墺\n墻\n墽\n墾\n墿\n壀\n壂\n壃\n壄\n壆\n壇\n壈\n壉\n壊\n壋\n壌\n壍\n壎\n壏\n壐\n壒\n壓\n壔\n壖\n壗\n壘\n壙\n壚\n壛\n壜\n壝\n壞\n壟\n壠\n壡\n壢\n壣\n壥\n壦\n壧\n壨\n壩\n壪\n壭\n壯\n壱\n売\n壴\n壵\n壷\n壸\n壺\n壻\n壼\n壽\n壾\n壿\n夀\n夁\n夃\n夅\n夆\n夈\n変\n夊\n夋\n夌\n夎\n夐\n夑\n夒\n夓\n夗\n夘\n夛\n夝\n夞\n夠\n夡\n夢\n夣\n夦\n夨\n夬\n夰\n夲\n夳\n夵\n夶\n夻\n夽\n夾\n夿\n奀\n奃\n奅\n奆\n奊\n奌\n奍\n奐\n奒\n奓\n奙\n奛\n奜\n奝\n奞\n奟\n奡\n奣\n奤\n奦\n奧\n奨\n奩\n奪\n奫\n奬\n奭\n奮\n奯\n奰\n奱\n奲\n奵\n奷\n奺\n奻\n奼\n奾\n奿\n妀\n妅\n妉\n妋\n妌\n妎\n妏\n妐\n妑\n妔\n妕\n妘\n妚\n妛\n妜\n妝\n妟\n妠\n妡\n妢\n妦\n妧\n妬\n妭\n妰\n妱\n妳\n妴\n妵\n妶\n妷\n妸\n妺\n妼\n妽\n妿\n姀\n姁\n姂\n姃\n姄\n姅\n姇\n姈\n姉\n姌\n姍\n姎\n姏\n姕\n姖\n姙\n姛\n姞\n姟\n姠\n姡\n姢\n姤\n姦\n姧\n姩\n姪\n姫\n姭\n姮\n姯\n姰\n姱\n姲\n姳\n姴\n姵\n姶\n姷\n姸\n姺\n姼\n姽\n姾\n娀\n娂\n娊\n娋\n娍\n娎\n娏\n娐\n娒\n娔\n娕\n娖\n娗\n娙\n娚\n娛\n娝\n娞\n娡\n娢\n娤\n娦\n娧\n娨\n娪\n娫\n娬\n娭\n娮\n娯\n娰\n娳\n娵\n娷\n娸\n娹\n娺\n娻\n娽\n娾\n娿\n婁\n婂\n婃\n婄\n婅\n婇\n婈\n婋\n婌\n婍\n婎\n婏\n婐\n婑\n婒\n婓\n婔\n婖\n婗\n婘\n婙\n婛\n婜\n婝\n婞\n婟\n婠\n婡\n婣\n婤\n婥\n婦\n婨\n婩\n婫\n婬\n婭\n婮\n婯\n婰\n婱\n婲\n婳\n婸\n婹\n婻\n婼\n婽\n婾\n媀\n媁\n媂\n媃\n媄\n媅\n媆\n媇\n媈\n媉\n媊\n媋\n媌\n媍\n媎\n媏\n媐\n媑\n媓\n媔\n媕\n媖\n媗\n媘\n媙\n媜\n媝\n媞\n媟\n媠\n媡\n媢\n媣\n媤\n媥\n媦\n媧\n媨\n媩\n媫\n媬\n媭\n媮\n媯\n媰\n媱\n媴\n媶\n媷\n媹\n媺\n媻\n媼\n媽\n媿\n嫀\n嫃\n嫄\n嫅\n嫆\n嫇\n嫈\n嫊\n嫋\n嫍\n嫎\n嫏\n嫐\n嫑\n嫓\n嫕\n嫗\n嫙\n嫚\n嫛\n嫝\n嫞\n嫟\n嫢\n嫤\n嫥\n嫧\n嫨\n嫪\n嫬\n嫭\n嫮\n嫯\n嫰\n嫲\n嫳\n嫴\n嫵\n嫶\n嫷\n嫸\n嫹\n嫺\n嫻\n嫼\n嫽\n嫾\n嫿\n嬀\n嬁\n嬂\n嬃\n嬄\n嬅\n嬆\n嬇\n嬈\n嬊\n嬋\n嬌\n嬍\n嬎\n嬏\n嬐\n嬑\n嬒\n嬓\n嬔\n嬕\n嬘\n嬙\n嬚\n嬛\n嬜\n嬝\n嬞\n嬟\n嬠\n嬡\n嬢\n嬣\n嬤\n嬥\n嬦\n嬧\n嬨\n嬩\n嬪\n嬫\n嬬\n嬭\n嬮\n嬯\n嬰\n嬱\n嬳\n嬵\n嬶\n嬸\n嬹\n嬺\n嬻\n嬼\n嬽\n嬾\n嬿\n孁\n孂\n孃\n孄\n孅\n孆\n孇\n孈\n孉\n孊\n孋\n孌\n孍\n孎\n孏\n孒\n孖\n孞\n孠\n孡\n孧\n孨\n孫\n孭\n孮\n孯\n孲\n孴\n孶\n孷\n學\n孹\n孻\n孼\n孾\n孿\n宂\n宆\n宊\n宍\n宎\n宐\n宑\n宒\n宔\n宖\n実\n宧\n宨\n宩\n宬\n宭\n宮\n宯\n宱\n宲\n宷\n宺\n宻\n宼\n寀\n寁\n寃\n寈\n寉\n寊\n寋\n寍\n寎\n寏\n寑\n寔\n寕\n寖\n寗\n寘\n寙\n寚\n寛\n寜\n寠\n寢\n寣\n實\n寧\n審\n寪\n寫\n寬\n寭\n寯\n寱\n寲\n寳\n寴\n寵\n寶\n寷\n寽\n対\n尀\n専\n尃\n尅\n將\n專\n尋\n尌\n對\n導\n尐\n尒\n尓\n尗\n尙\n尛\n尞\n尟\n尠\n尡\n尣\n尦\n尨\n尩\n尪\n尫\n尭\n尮\n尯\n尰\n尲\n尳\n尵\n尶\n尷\n屃\n屄\n屆\n屇\n屌\n屍\n屒\n屓\n屔\n屖\n屗\n屘\n屚\n屛\n屜\n屝\n屟\n屢\n層\n屧\n屨\n屩\n屪\n屫\n屬\n屭\n屰\n屲\n屳\n屴\n屵\n屶\n屷\n屸\n屻\n屼\n屽\n屾\n岀\n岃\n岄\n岅\n岆\n岇\n岉\n岊\n岋\n岎\n岏\n岒\n岓\n岕\n岝\n岞\n岟\n岠\n岡\n岤\n岥\n岦\n岧\n岨\n岪\n岮\n岯\n岰\n岲\n岴\n岶\n岹\n岺\n岻\n岼\n岾\n峀\n峂\n峃\n峅\n峆\n峇\n峈\n峉\n峊\n峌\n峍\n峎\n峏\n峐\n峑\n峓\n峔\n峕\n峖\n峗\n峘\n峚\n峛\n峜\n峝\n峞\n峟\n峠\n峢\n峣\n峧\n峩\n峫\n峬\n峮\n峯\n峱\n峲\n峳\n峴\n峵\n島\n峷\n峸\n峹\n峺\n峼\n峽\n峾\n峿\n崀\n崁\n崄\n崅\n崈\n崉\n崊\n崋\n崌\n崍\n崏\n崐\n崑\n崒\n崓\n崕\n崗\n崘\n崙\n崚\n崜\n崝\n崟\n崠\n崡\n崢\n崣\n崥\n崨\n崪\n崫\n崬\n崯\n崰\n崱\n崲\n崳\n崵\n崶\n崷\n崸\n崹\n崺\n崻\n崼\n崿\n嵀\n嵁\n嵂\n嵃\n嵄\n嵅\n嵆\n嵈\n嵉\n嵍\n嵎\n嵏\n嵐\n嵑\n嵒\n嵓\n嵔\n嵕\n嵖\n嵗\n嵙\n嵚\n嵜\n嵞\n嵟\n嵠\n嵡\n嵢\n嵣\n嵤\n嵥\n嵦\n嵧\n嵨\n嵪\n嵭\n嵮\n嵰\n嵱\n嵲\n嵳\n嵵\n嵶\n嵷\n嵸\n嵹\n嵺\n嵻\n嵼\n嵽\n嵾\n嵿\n嶀\n嶁\n嶃\n嶄\n嶅\n嶆\n嶇\n嶈\n嶉\n嶊\n嶋\n嶌\n嶍\n嶎\n嶏\n嶐\n嶑\n嶒\n嶓\n嶔\n嶕\n嶖\n嶗\n嶘\n嶚\n嶛\n嶜\n嶞\n嶟\n嶠\n嶡\n嶢\n嶣\n嶤\n嶥\n嶦\n嶧\n嶨\n嶩\n嶪\n嶫\n嶬\n嶭\n嶮\n嶯\n嶰\n嶱\n嶲\n嶳\n嶴\n嶵\n嶶\n嶸\n嶹\n嶺\n嶻\n嶼\n嶽\n嶾\n嶿\n巀\n巁\n巂\n巃\n巄\n巆\n巇\n巈\n巉\n巊\n巋\n巌\n巎\n巏\n巐\n巑\n巒\n巓\n巔\n巕\n巖\n巗\n巘\n巙\n巚\n巜\n巟\n巠\n巣\n巤\n巪\n巬\n巭\n巰\n巵\n巶\n巸\n巹\n巺\n巻\n巼\n巿\n帀\n帄\n帇\n帉\n帊\n帋\n帍\n帎\n帒\n帓\n帗\n帞\n帟\n帠\n帡\n帢\n帣\n帤\n帥\n帨\n帩\n帪\n師\n帬\n帯\n帰\n帲\n帳\n帴\n帵\n帶\n帹\n帺\n帾\n帿\n幀\n幁\n幃\n幆\n幇\n幈\n幉\n幊\n幋\n幍\n幎\n幏\n幐\n幑\n幒\n幓\n幖\n幗\n幘\n幙\n幚\n幜\n幝\n幟\n幠\n幣\n幤\n幥\n幦\n幧\n幨\n幩\n幪\n幫\n幬\n幭\n幮\n幯\n幰\n幱\n幵\n幷\n幹\n幾\n庁\n庂\n広\n庅\n庈\n庉\n庌\n庍\n庎\n庒\n庘\n庛\n庝\n庡\n庢\n庣\n庤\n庨\n庩\n庪\n庫\n庬\n庮\n庯\n庰\n庱\n庲\n庴\n庺\n庻\n庼\n庽\n庿\n廀\n廁\n廂\n廃\n廄\n廅\n廆\n廇\n廈\n廋\n廌\n廍\n廎\n廏\n廐\n廔\n廕\n廗\n廘\n廙\n廚\n廜\n廝\n廞\n廟\n廠\n廡\n廢\n廣\n廤\n廥\n廦\n廧\n廩\n廫\n廬\n廭\n廮\n廯\n廰\n廱\n廲\n廳\n廵\n廸\n廹\n廻\n廼\n廽\n弅\n弆\n弇\n弉\n弌\n弍\n弎\n弐\n弒\n弔\n弖\n弙\n弚\n弜\n弝\n弞\n弡\n弢\n弣\n弤\n弨\n弫\n弬\n弮\n弰\n弲\n弳\n弴\n張\n弶\n強\n弸\n弻\n弽\n弾\n弿\n彁\n彂\n彃\n彄\n彅\n彆\n彇\n彈\n彉\n彊\n彋\n彌\n彍\n彎\n彏\n彑\n彔\n彙\n彚\n彛\n彜\n彞\n彟\n彠\n彣\n彥\n彧\n彨\n彫\n彮\n彯\n彲\n彴\n彵\n彶\n彸\n彺\n彽\n彾\n彿\n徃\n徆\n徍\n徎\n徏\n徑\n従\n徔\n徖\n徚\n徛\n徝\n從\n徟\n徠\n徢\n徣\n徤\n徥\n徦\n徧\n復\n徫\n徬\n徯\n徰\n徱\n徲\n徳\n徴\n徶\n徸\n徹\n徺\n徻\n徾\n徿\n忀\n忁\n忂\n忇\n忈\n忊\n忋\n忎\n忓\n忔\n忕\n忚\n忛\n応\n忞\n忟\n忢\n忣\n忥\n忦\n忨\n忩\n忬\n忯\n忰\n忲\n忳\n忴\n忶\n忷\n忹\n忺\n忼\n怇\n怈\n怉\n怋\n怌\n怐\n怑\n怓\n怗\n怘\n怚\n怞\n怟\n怢\n怣\n怤\n怬\n怭\n怮\n怰\n怱\n怲\n怳\n怴\n怶\n怷\n怸\n怹\n怺\n怽\n怾\n恀\n恄\n恅\n恆\n恇\n恈\n恉\n恊\n恌\n恎\n恏\n恑\n恓\n恔\n恖\n恗\n恘\n恛\n恜\n恞\n恟\n恠\n恡\n恥\n恦\n恮\n恱\n恲\n恴\n恵\n恷\n恾\n悀\n悁\n悂\n悅\n悆\n悇\n悈\n悊\n悋\n悎\n悏\n悐\n悑\n悓\n悕\n悗\n悘\n悙\n悜\n悞\n悡\n悢\n悤\n悥\n悧\n悩\n悪\n悮\n悰\n悳\n悵\n悶\n悷\n悹\n悺\n悽\n悾\n悿\n惀\n惁\n惂\n惃\n惄\n惇\n惈\n惉\n惌\n惍\n惎\n惏\n惐\n惒\n惓\n惔\n惖\n惗\n惙\n惛\n惞\n惡\n惢\n惣\n惤\n惥\n惪\n惱\n惲\n惵\n惷\n惸\n惻\n惼\n惽\n惾\n惿\n愂\n愃\n愄\n愅\n愇\n愊\n愋\n愌\n愐\n愑\n愒\n愓\n愔\n愖\n愗\n愘\n愙\n愛\n愜\n愝\n愞\n愡\n愢\n愥\n愨\n愩\n愪\n愬\n愭\n愮\n愯\n愰\n愱\n愲\n愳\n愴\n愵\n愶\n愷\n愸\n愹\n愺\n愻\n愼\n愽\n愾\n慀\n慁\n慂\n慃\n慄\n慅\n慆\n慇\n慉\n態\n慍\n慏\n慐\n慒\n慓\n慔\n慖\n慗\n慘\n慙\n慚\n慛\n慜\n慞\n慟\n慠\n慡\n慣\n慤\n慥\n慦\n慩\n慪\n慫\n慬\n慭\n慮\n慯\n慱\n慲\n慳\n慴\n慶\n慸\n慹\n慺\n慻\n慼\n慽\n慾\n慿\n憀\n憁\n憂\n憃\n憄\n憅\n憆\n憇\n憈\n憉\n憊\n憌\n憍\n憏\n憐\n憑\n憒\n憓\n憕\n憖\n憗\n憘\n憙\n憚\n憛\n憜\n憞\n憟\n憠\n憡\n憢\n憣\n憤\n憥\n憦\n憪\n憫\n憭\n憮\n憯\n憰\n憱\n憲\n憳\n憴\n憵\n憶\n憸\n憹\n憺\n憻\n憼\n憽\n憿\n懀\n懁\n懃\n懄\n懅\n懆\n懇\n應\n懌\n懍\n懎\n懏\n懐\n懓\n懕\n懖\n懗\n懘\n懙\n懚\n懛\n懜\n懝\n懞\n懟\n懠\n懡\n懢\n懣\n懤\n懥\n懧\n懨\n懩\n懪\n懫\n懬\n懭\n懮\n懯\n懰\n懱\n懲\n懳\n懴\n懶\n懷\n懸\n懹\n懺\n懻\n懼\n懽\n懾\n戀\n戁\n戂\n戃\n戄\n戅\n戇\n戉\n戓\n戔\n戙\n戜\n戝\n戞\n戠\n戣\n戦\n戧\n戨\n戩\n戫\n戭\n戯\n戰\n戱\n戲\n戵\n戶\n戸\n戹\n戺\n戻\n戼\n扂\n扄\n扅\n扆\n扊\n扏\n扐\n払\n扖\n扗\n扙\n扚\n扜\n扝\n扞\n扟\n扠\n扡\n扢\n扤\n扥\n扨\n扱\n扲\n扴\n扵\n扷\n扸\n扺\n扻\n扽\n抁\n抂\n抃\n抅\n抆\n抇\n抈\n抋\n抌\n抍\n抎\n抏\n抐\n抔\n抙\n抜\n抝\n択\n抣\n抦\n抧\n抩\n抪\n抭\n抮\n抯\n抰\n抲\n抳\n抴\n抶\n抷\n抸\n抺\n抾\n拀\n拁\n拃\n拋\n拏\n拑\n拕\n拝\n拞\n拠\n拡\n拤\n拪\n拫\n拰\n拲\n拵\n拸\n拹\n拺\n拻\n挀\n挃\n挄\n挅\n挆\n挊\n挋\n挌\n挍\n挏\n挐\n挒\n挓\n挔\n挕\n挗\n挘\n挙\n挜\n挦\n挧\n挩\n挬\n挭\n挮\n挰\n挱\n挳\n挴\n挵\n挶\n挷\n挸\n挻\n挼\n挾\n挿\n捀\n捁\n捄\n捇\n捈\n捊\n捑\n捒\n捓\n捔\n捖\n捗\n捘\n捙\n捚\n捛\n捜\n捝\n捠\n捤\n捥\n捦\n捨\n捪\n捫\n捬\n捯\n捰\n捲\n捳\n捴\n捵\n捸\n捹\n捼\n捽\n捾\n捿\n掁\n掃\n掄\n掅\n掆\n掋\n掍\n掑\n掓\n掔\n掕\n掗\n掙\n掚\n掛\n掜\n掝\n掞\n掟\n採\n掤\n掦\n掫\n掯\n掱\n掲\n掵\n掶\n掹\n掻\n掽\n掿\n揀\n揁\n揂\n揃\n揅\n揇\n揈\n揊\n揋\n揌\n揑\n揓\n揔\n揕\n揗\n揘\n揙\n揚\n換\n揜\n揝\n揟\n揢\n揤\n揥\n揦\n揧\n揨\n揫\n揬\n揮\n揯\n揰\n揱\n揳\n揵\n揷\n揹\n揺\n揻\n揼\n揾\n搃\n搄\n搆\n搇\n搈\n搉\n搊\n損\n搎\n搑\n搒\n搕\n搖\n搗\n搘\n搙\n搚\n搝\n搟\n搢\n搣\n搤\n搥\n搧\n搨\n搩\n搫\n搮\n搯\n搰\n搱\n搲\n搳\n搵\n搶\n搷\n搸\n搹\n搻\n搼\n搾\n摀\n摂\n摃\n摉\n摋\n摌\n摍\n摎\n摏\n摐\n摑\n摓\n摕\n摖\n摗\n摙\n摚\n摛\n摜\n摝\n摟\n摠\n摡\n摢\n摣\n摤\n摥\n摦\n摨\n摪\n摫\n摬\n摮\n摯\n摰\n摱\n摲\n摳\n摴\n摵\n摶\n摷\n摻\n摼\n摽\n摾\n摿\n撀\n撁\n撃\n撆\n撈\n撉\n撊\n撋\n撌\n撍\n撎\n撏\n撐\n撓\n撔\n撗\n撘\n撚\n撛\n撜\n撝\n撟\n撠\n撡\n撢\n撣\n撥\n撦\n撧\n撨\n撪\n撫\n撯\n撱\n撲\n撳\n撴\n撶\n撹\n撻\n撽\n撾\n撿\n擁\n擃\n擄\n擆\n擇\n擈\n擉\n擊\n擋\n擌\n擏\n擑\n擓\n擔\n擕\n擖\n擙\n據\n擛\n擜\n擝\n擟\n擠\n擡\n擣\n擥\n擧\n擨\n擩\n擪\n擫\n擬\n擭\n擮\n擯\n擰\n擱\n擲\n擳\n擴\n擵\n擶\n擷\n擸\n擹\n擺\n擻\n擼\n擽\n擾\n擿\n攁\n攂\n攃\n攄\n攅\n攆\n攇\n攈\n攊\n攋\n攌\n攍\n攎\n攏\n攐\n攑\n攓\n攔\n攕\n攖\n攗\n攙\n攚\n攛\n攜\n攝\n攞\n攟\n攠\n攡\n攢\n攣\n攤\n攦\n攧\n攨\n攩\n攪\n攬\n攭\n攰\n攱\n攲\n攳\n攷\n攺\n攼\n攽\n敀\n敁\n敂\n敃\n敄\n敆\n敇\n敊\n敋\n敍\n敎\n敐\n敒\n敓\n敔\n敗\n敘\n敚\n敜\n敟\n敠\n敡\n敤\n敥\n敧\n敨\n敩\n敪\n敭\n敮\n敯\n敱\n敳\n敵\n敶\n數\n敹\n敺\n敻\n敼\n敽\n敾\n敿\n斀\n斁\n斂\n斃\n斄\n斅\n斆\n斈\n斉\n斊\n斍\n斎\n斏\n斒\n斔\n斕\n斖\n斘\n斚\n斝\n斞\n斠\n斢\n斣\n斦\n斨\n斪\n斬\n斮\n斱\n斲\n斳\n斴\n斵\n斶\n斷\n斸\n斺\n斻\n斾\n斿\n旀\n旂\n旇\n旈\n旉\n旊\n旍\n旐\n旑\n旓\n旔\n旕\n旘\n旙\n旚\n旛\n旜\n旝\n旞\n旟\n旡\n旣\n旤\n旪\n旫\n旲\n旳\n旴\n旵\n旸\n旹\n旻\n旼\n旽\n旾\n旿\n昁\n昄\n昅\n昇\n昈\n昉\n昋\n昍\n昐\n昑\n昒\n昖\n昗\n昘\n昚\n昛\n昜\n昞\n昡\n昢\n昣\n昤\n昦\n昩\n昪\n昫\n昬\n昮\n昰\n昲\n昳\n昷\n昸\n昹\n昺\n昻\n昽\n昿\n晀\n時\n晄\n晅\n晆\n晇\n晈\n晉\n晊\n晍\n晎\n晐\n晑\n晘\n晙\n晛\n晜\n晝\n晞\n晠\n晢\n晣\n晥\n晧\n晩\n晪\n晫\n晬\n晭\n晱\n晲\n晳\n晵\n晸\n晹\n晻\n晼\n晽\n晿\n暀\n暁\n暃\n暅\n暆\n暈\n暉\n暊\n暋\n暍\n暎\n暏\n暐\n暒\n暓\n暔\n暕\n暘\n暙\n暚\n暛\n暜\n暞\n暟\n暠\n暡\n暢\n暣\n暤\n暥\n暦\n暩\n暪\n暫\n暬\n暭\n暯\n暰\n暱\n暲\n暳\n暵\n暶\n暷\n暸\n暺\n暻\n暼\n暽\n暿\n曀\n曁\n曂\n曃\n曄\n曅\n曆\n曇\n曈\n曉\n曊\n曋\n曌\n曍\n曎\n曏\n曐\n曑\n曒\n曓\n曔\n曕\n曖\n曗\n曘\n曚\n曞\n曟\n曠\n曡\n曢\n曣\n曤\n曥\n曧\n曨\n曪\n曫\n曬\n曭\n曮\n曯\n曱\n曵\n曶\n書\n曺\n曻\n曽\n朁\n朂\n會\n朄\n朅\n朆\n朇\n朌\n朎\n朏\n朑\n朒\n朓\n朖\n朘\n朙\n朚\n朜\n朞\n朠\n朡\n朢\n朣\n朤\n朥\n朧\n朩\n朮\n朰\n朲\n朳\n朶\n朷\n朸\n朹\n朻\n朼\n朾\n朿\n杁\n杄\n杅\n杇\n杊\n杋\n杍\n杒\n杔\n杕\n杗\n杘\n杙\n杚\n杛\n杝\n杢\n杣\n杤\n杦\n杧\n杫\n杬\n杮\n東\n杴\n杶\n杸\n杹\n杺\n杻\n杽\n枀\n枂\n枃\n枅\n枆\n枈\n枊\n枌\n枍\n枎\n枏\n枑\n枒\n枓\n枔\n枖\n枙\n枛\n枟\n枠\n枡\n枤\n枦\n枩\n枬\n枮\n枱\n枲\n枴\n枹\n枺\n枻\n枼\n枽\n枾\n枿\n柀\n柂\n柅\n柆\n柇\n柈\n柉\n柊\n柋\n柌\n柍\n柎\n柕\n柖\n柗\n柛\n柟\n柡\n柣\n柤\n柦\n柧\n柨\n柪\n柫\n柭\n柮\n柲\n柵\n柶\n柷\n柸\n柹\n柺\n査\n柼\n柾\n栁\n栂\n栃\n栄\n栆\n栍\n栐\n栒\n栔\n栕\n栘\n栙\n栚\n栛\n栜\n栞\n栟\n栠\n栢\n栣\n栤\n栥\n栦\n栧\n栨\n栫\n栬\n栭\n栮\n栯\n栰\n栱\n栴\n栵\n栶\n栺\n栻\n栿\n桇\n桋\n桍\n桏\n桒\n桖\n桗\n桘\n桙\n桚\n桛\n桜\n桝\n桞\n桟\n桪\n桬\n桭\n桮\n桯\n桰\n桱\n桲\n桳\n桵\n桸\n桹\n桺\n桻\n桼\n桽\n桾\n桿\n梀\n梂\n梄\n梇\n梈\n梉\n梊\n梋\n梌\n梍\n梎\n梐\n梑\n梒\n梔\n梕\n梖\n梘\n梙\n梚\n梛\n梜\n條\n梞\n梟\n梠\n梡\n梣\n梤\n梥\n梩\n梪\n梫\n梬\n梮\n梱\n梲\n梴\n梶\n梷\n梸\n梹\n梺\n梻\n梼\n梽\n梾\n梿\n棁\n棃\n棄\n棅\n棆\n棇\n棈\n棊\n棌\n棎\n棏\n棐\n棑\n棓\n棔\n棖\n棗\n棙\n棛\n棜\n棝\n棞\n棟\n棡\n棢\n棤\n棥\n棦\n棧\n棨\n棩\n棪\n棫\n棬\n棭\n棯\n棲\n棳\n棴\n棶\n棷\n棸\n棻\n棽\n棾\n棿\n椀\n椂\n椃\n椄\n椆\n椇\n椈\n椉\n椊\n椌\n椏\n椑\n椓\n椔\n椕\n椖\n椗\n椘\n椙\n椚\n椛\n検\n椝\n椞\n椡\n椢\n椣\n椥\n椦\n椧\n椨\n椩\n椪\n椫\n椬\n椮\n椯\n椱\n椲\n椳\n椵\n椶\n椷\n椸\n椺\n椻\n椼\n椾\n楀\n楁\n楃\n楄\n楅\n楆\n楇\n楈\n楉\n楊\n楋\n楌\n楍\n楎\n楏\n楐\n楑\n楒\n楓\n楕\n楖\n楘\n楙\n楛\n楜\n楟\n楡\n楢\n楤\n楥\n楧\n楨\n楩\n楪\n楬\n業\n楯\n楰\n楲\n楳\n楴\n極\n楶\n楺\n楻\n楽\n楾\n楿\n榁\n榃\n榅\n榊\n榋\n榌\n榎\n榏\n榐\n榑\n榒\n榓\n榖\n榗\n榙\n榚\n榝\n榞\n榟\n榠\n榡\n榢\n榣\n榤\n榥\n榦\n榩\n榪\n榬\n榮\n榯\n榰\n榲\n榳\n榵\n榶\n榸\n榹\n榺\n榼\n榽\n榾\n榿\n槀\n槂\n槃\n槄\n槅\n槆\n槇\n槈\n槉\n構\n槍\n槏\n槑\n槒\n槓\n槕\n槖\n槗\n様\n槙\n槚\n槜\n槝\n槞\n槡\n槢\n槣\n槤\n槥\n槦\n槧\n槨\n槩\n槪\n槫\n槬\n槮\n槯\n槰\n槱\n槳\n槴\n槵\n槶\n槷\n槸\n槹\n槺\n槻\n槼\n槾\n樀\n樁\n樂\n樃\n樄\n樅\n樆\n樇\n樈\n樉\n樋\n樌\n樍\n樎\n樏\n樐\n樑\n樒\n樓\n樔\n樕\n樖\n標\n樚\n樛\n樜\n樝\n樞\n樠\n樢\n樣\n樤\n樥\n樦\n樧\n権\n樫\n樬\n樭\n樮\n樰\n樲\n樳\n樴\n樶\n樷\n樸\n樹\n樺\n樻\n樼\n樿\n橀\n橁\n橂\n橃\n橅\n橆\n橈\n橉\n橊\n橋\n橌\n橍\n橎\n橏\n橑\n橒\n橓\n橔\n橕\n橖\n橗\n橚\n橜\n橝\n橞\n機\n橠\n橢\n橣\n橤\n橦\n橧\n橨\n橩\n橪\n橫\n橬\n橭\n橮\n橯\n橰\n橲\n橳\n橴\n橵\n橶\n橷\n橸\n橺\n橻\n橽\n橾\n橿\n檁\n檂\n檃\n檅\n檆\n檇\n檈\n檉\n檊\n檋\n檌\n檍\n檏\n檒\n檓\n檔\n檕\n檖\n檘\n檙\n檚\n檛\n檜\n檝\n檞\n檟\n檡\n檢\n檣\n檤\n檥\n檦\n檧\n檨\n檪\n檭\n檮\n檯\n檰\n檱\n檲\n檳\n檴\n檵\n檶\n檷\n檸\n檹\n檺\n檻\n檼\n檽\n檾\n檿\n櫀\n櫁\n櫂\n櫃\n櫄\n櫅\n櫆\n櫇\n櫈\n櫉\n櫊\n櫋\n櫌\n櫍\n櫎\n櫏\n櫐\n櫑\n櫒\n櫓\n櫔\n櫕\n櫖\n櫗\n櫘\n櫙\n櫚\n櫛\n櫜\n櫝\n櫞\n櫟\n櫠\n櫡\n櫢\n櫣\n櫤\n櫥\n櫦\n櫧\n櫨\n櫩\n櫪\n櫫\n櫬\n櫭\n櫮\n櫯\n櫰\n櫱\n櫲\n櫳\n櫴\n櫵\n櫶\n櫷\n櫸\n櫹\n櫺\n櫻\n櫼\n櫽\n櫾\n櫿\n欀\n欁\n欂\n欃\n欄\n欅\n欆\n欇\n欈\n欉\n權\n欋\n欌\n欍\n欎\n欏\n欐\n欑\n欒\n欓\n欔\n欕\n欖\n欗\n欘\n欙\n欚\n欛\n欜\n欝\n欞\n欟\n欥\n欦\n欨\n欩\n欪\n欫\n欬\n欭\n欮\n欯\n欰\n欱\n欳\n欴\n欵\n欶\n欸\n欻\n欼\n欽\n欿\n歀\n歁\n歂\n歄\n歅\n歈\n歊\n歋\n歍\n歎\n歏\n歐\n歑\n歒\n歓\n歔\n歕\n歖\n歗\n歘\n歚\n歛\n歜\n歝\n歞\n歟\n歠\n歡\n歨\n歩\n歫\n歬\n歭\n歮\n歯\n歰\n歱\n歲\n歳\n歴\n歵\n歶\n歷\n歸\n歺\n歽\n歾\n歿\n殀\n殅\n殈\n殌\n殎\n殏\n殐\n殑\n殔\n殕\n殗\n殘\n殙\n殜\n殝\n殞\n殟\n殠\n殢\n殣\n殤\n殥\n殦\n殧\n殨\n殩\n殫\n殬\n殭\n殮\n殯\n殰\n殱\n殲\n殶\n殸\n殹\n殺\n殻\n殼\n殽\n殾\n毀\n毃\n毄\n毆\n毇\n毈\n毉\n毊\n毌\n毎\n毐\n毑\n毘\n毚\n毜\n毝\n毞\n毟\n毠\n毢\n毣\n毤\n毥\n毦\n毧\n毨\n毩\n毬\n毭\n毮\n毰\n毱\n毲\n毴\n毶\n毷\n毸\n毺\n毻\n毼\n毾\n毿\n氀\n氁\n氂\n氃\n氄\n氈\n氉\n氊\n氋\n氌\n氎\n氒\n気\n氜\n氝\n氞\n氠\n氣\n氥\n氫\n氬\n氭\n氱\n氳\n氶\n氷\n氹\n氺\n氻\n氼\n氾\n氿\n汃\n汄\n汅\n汈\n汋\n汌\n汍\n汎\n汏\n汑\n汒\n汓\n汖\n汘\n汙\n汚\n汢\n汣\n汥\n汦\n汧\n汫\n汬\n汭\n汮\n汯\n汱\n汳\n汵\n汷\n汸\n決\n汻\n汼\n汿\n沀\n沄\n沇\n沊\n沋\n沍\n沎\n沑\n沒\n沕\n沖\n沗\n沘\n沚\n沜\n沝\n沞\n沠\n沢\n沨\n沬\n沯\n沰\n沴\n沵\n沶\n沷\n沺\n泀\n況\n泂\n泃\n泆\n泇\n泈\n泋\n泍\n泎\n泏\n泑\n泒\n泘\n泙\n泚\n泜\n泝\n泟\n泤\n泦\n泧\n泩\n泬\n泭\n泲\n泴\n泹\n泿\n洀\n洂\n洃\n洅\n洆\n洈\n洉\n洊\n洍\n洏\n洐\n洑\n洓\n洔\n洕\n洖\n洘\n洜\n洝\n洟\n洠\n洡\n洢\n洣\n洤\n洦\n洨\n洩\n洬\n洭\n洯\n洰\n洴\n洶\n洷\n洸\n洺\n洿\n浀\n浂\n浄\n浉\n浌\n浐\n浕\n浖\n浗\n浘\n浛\n浝\n浟\n浡\n浢\n浤\n浥\n浧\n浨\n浫\n浬\n浭\n浰\n浱\n浲\n浳\n浵\n浶\n浹\n浺\n浻\n浽\n浾\n浿\n涀\n涁\n涃\n涄\n涆\n涇\n涊\n涋\n涍\n涏\n涐\n涒\n涖\n涗\n涘\n涙\n涚\n涜\n涢\n涥\n涬\n涭\n涰\n涱\n涳\n涴\n涶\n涷\n涹\n涺\n涻\n涼\n涽\n涾\n淁\n淂\n淃\n淈\n淉\n淊\n淍\n淎\n淏\n淐\n淒\n淓\n淔\n淕\n淗\n淚\n淛\n淜\n淟\n淢\n淣\n淥\n淧\n淨\n淩\n淪\n淭\n淯\n淰\n淲\n淴\n淵\n淶\n淸\n淺\n淽\n淾\n淿\n渀\n渁\n渂\n渃\n渄\n渆\n渇\n済\n渉\n渋\n渏\n渒\n渓\n渕\n渘\n渙\n減\n渜\n渞\n渟\n渢\n渦\n渧\n渨\n渪\n測\n渮\n渰\n渱\n渳\n渵\n渶\n渷\n渹\n渻\n渼\n渽\n渾\n渿\n湀\n湁\n湂\n湅\n湆\n湇\n湈\n湉\n湊\n湋\n湌\n湏\n湐\n湑\n湒\n湕\n湗\n湙\n湚\n湜\n湝\n湞\n湠\n湡\n湢\n湣\n湤\n湥\n湦\n湧\n湨\n湩\n湪\n湬\n湭\n湯\n湰\n湱\n湲\n湳\n湴\n湵\n湶\n湷\n湸\n湹\n湺\n湻\n湼\n湽\n満\n溁\n溂\n溄\n溇\n溈\n溊\n溋\n溌\n溍\n溎\n溑\n溒\n溓\n溔\n溕\n準\n溗\n溙\n溚\n溛\n溝\n溞\n溠\n溡\n溣\n溤\n溦\n溨\n溩\n溫\n溬\n溭\n溮\n溰\n溳\n溵\n溸\n溹\n溼\n溾\n溿\n滀\n滃\n滄\n滅\n滆\n滈\n滉\n滊\n滌\n滍\n滎\n滐\n滒\n滖\n滘\n滙\n滛\n滜\n滝\n滣\n滧\n滪\n滫\n滬\n滭\n滮\n滯\n滰\n滱\n滲\n滳\n滵\n滶\n滷\n滸\n滺\n滻\n滼\n滽\n滾\n滿\n漀\n漁\n漃\n漄\n漅\n漇\n漈\n漊\n漋\n漌\n漍\n漎\n漐\n漑\n漒\n漖\n漗\n漘\n漙\n漚\n漛\n漜\n漝\n漞\n漟\n漡\n漢\n漣\n漥\n漦\n漧\n漨\n漬\n漮\n漰\n漲\n漴\n漵\n漷\n漸\n漹\n漺\n漻\n漼\n漽\n漿\n潀\n潁\n潂\n潃\n潄\n潅\n潈\n潉\n潊\n潌\n潎\n潏\n潐\n潑\n潒\n潓\n潔\n潕\n潖\n潗\n潙\n潚\n潛\n潝\n潟\n潠\n潡\n潣\n潤\n潥\n潧\n潨\n潩\n潪\n潫\n潬\n潯\n潰\n潱\n潳\n潵\n潶\n潷\n潹\n潻\n潽\n潾\n潿\n澀\n澁\n澂\n澃\n澅\n澆\n澇\n澊\n澋\n澏\n澐\n澑\n澒\n澓\n澔\n澕\n澖\n澗\n澘\n澙\n澚\n澛\n澝\n澞\n澟\n澠\n澢\n澣\n澤\n澥\n澦\n澨\n澩\n澪\n澫\n澬\n澭\n澮\n澯\n澰\n澱\n澲\n澴\n澵\n澷\n澸\n澺\n澻\n澼\n澽\n澾\n澿\n濁\n濃\n濄\n濅\n濆\n濇\n濈\n濊\n濋\n濌\n濍\n濎\n濏\n濐\n濓\n濔\n濕\n濖\n濗\n濘\n濙\n濚\n濛\n濜\n濝\n濟\n濢\n濣\n濤\n濥\n濦\n濧\n濨\n濩\n濪\n濫\n濬\n濭\n濰\n濱\n濲\n濳\n濴\n濵\n濶\n濷\n濸\n濹\n濺\n濻\n濼\n濽\n濾\n濿\n瀀\n瀁\n瀂\n瀃\n瀄\n瀅\n瀆\n瀇\n瀈\n瀉\n瀊\n瀋\n瀌\n瀍\n瀎\n瀏\n瀐\n瀒\n瀓\n瀔\n瀕\n瀖\n瀗\n瀘\n瀙\n瀜\n瀝\n瀞\n瀟\n瀠\n瀡\n瀢\n瀤\n瀥\n瀦\n瀧\n瀨\n瀩\n瀪\n瀫\n瀬\n瀭\n瀮\n瀯\n瀰\n瀱\n瀲\n瀳\n瀴\n瀶\n瀷\n瀸\n瀺\n瀻\n瀼\n瀽\n瀾\n瀿\n灀\n灁\n灂\n灃\n灄\n灅\n灆\n灇\n灈\n灉\n灊\n灋\n灍\n灎\n灐\n灑\n灒\n灓\n灔\n灕\n灖\n灗\n灘\n灙\n灚\n灛\n灜\n灝\n灟\n灠\n灡\n灢\n灣\n灤\n灥\n灦\n灧\n灨\n灩\n灪\n灮\n灱\n灲\n灳\n灴\n灷\n灹\n灺\n灻\n災\n炁\n炂\n炃\n炄\n炆\n炇\n炈\n炋\n炌\n炍\n炏\n炐\n炑\n炓\n炗\n炘\n炚\n炛\n炞\n炟\n炠\n炡\n炢\n炣\n炤\n炥\n炦\n炧\n炨\n炩\n炪\n炰\n炲\n炴\n炵\n炶\n為\n炾\n炿\n烄\n烅\n烆\n烇\n烉\n烋\n烌\n烍\n烎\n烏\n烐\n烑\n烒\n烓\n烔\n烕\n烖\n烗\n烚\n烜\n烝\n烞\n烠\n烡\n烢\n烣\n烥\n烪\n烮\n烰\n烱\n烲\n烳\n烴\n烵\n烶\n烸\n烺\n烻\n烼\n烾\n烿\n焀\n焁\n焂\n焃\n焄\n焅\n焆\n焇\n焈\n焋\n焌\n焍\n焎\n焏\n焑\n焒\n焔\n焗\n焛\n焜\n焝\n焞\n焟\n焠\n無\n焢\n焣\n焤\n焥\n焧\n焨\n焩\n焪\n焫\n焬\n焭\n焮\n焲\n焳\n焴\n焵\n焷\n焸\n焹\n焺\n焻\n焼\n焽\n焾\n焿\n煀\n煁\n煂\n煃\n煄\n煆\n煇\n煈\n煉\n煋\n煍\n煏\n煐\n煑\n煒\n煓\n煔\n煕\n煖\n煗\n煘\n煙\n煚\n煛\n煝\n煟\n煠\n煡\n煢\n煣\n煥\n煩\n煪\n煫\n煬\n煭\n煯\n煰\n煱\n煴\n煵\n煶\n煷\n煹\n煻\n煼\n煾\n煿\n熀\n熁\n熂\n熃\n熅\n熆\n熇\n熈\n熉\n熋\n熌\n熍\n熎\n熐\n熑\n熒\n熓\n熕\n熖\n熗\n熚\n熛\n熜\n熝\n熞\n熡\n熢\n熣\n熤\n熥\n熦\n熧\n熩\n熪\n熫\n熭\n熮\n熯\n熰\n熱\n熲\n熴\n熶\n熷\n熸\n熺\n熻\n熼\n熽\n熾\n熿\n燀\n燁\n燂\n燄\n燅\n燆\n燇\n燈\n燉\n燊\n燋\n燌\n燍\n燏\n燐\n燑\n燒\n燓\n燖\n燗\n燘\n燙\n燚\n燛\n燜\n燝\n燞\n營\n燡\n燢\n燣\n燤\n燦\n燨\n燩\n燪\n燫\n燬\n燭\n燯\n燰\n燱\n燲\n燳\n燴\n燵\n燶\n燷\n燸\n燺\n燻\n燼\n燽\n燾\n燿\n爀\n爁\n爂\n爃\n爄\n爅\n爇\n爈\n爉\n爊\n爋\n爌\n爍\n爎\n爏\n爐\n爑\n爒\n爓\n爔\n爕\n爖\n爗\n爘\n爙\n爚\n爛\n爜\n爞\n爟\n爠\n爡\n爢\n爣\n爤\n爥\n爦\n爧\n爩\n爫\n爭\n爮\n爯\n爲\n爳\n爴\n爺\n爼\n爾\n牀\n牁\n牂\n牃\n牄\n牅\n牆\n牉\n牊\n牋\n牎\n牏\n牐\n牑\n牓\n牔\n牕\n牗\n牘\n牚\n牜\n牞\n牠\n牣\n牤\n牥\n牨\n牪\n牫\n牬\n牭\n牰\n牱\n牳\n牴\n牶\n牷\n牸\n牻\n牼\n牽\n犂\n犃\n犅\n犆\n犇\n犈\n犉\n犌\n犎\n犐\n犑\n犓\n犔\n犕\n犖\n犗\n犘\n犙\n犚\n犛\n犜\n犝\n犞\n犠\n犡\n犢\n犣\n犤\n犥\n犦\n犧\n犨\n犩\n犪\n犫\n犮\n犱\n犲\n犳\n犵\n犺\n犻\n犼\n犽\n犾\n犿\n狀\n狅\n狆\n狇\n狉\n狊\n狋\n狌\n狏\n狑\n狓\n狔\n狕\n狖\n狘\n狚\n狛\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n　\n、\n。\n·\nˉ\nˇ\n¨\n〃\n々\n—\n～\n‖\n…\n‘\n’\n“\n”\n〔\n〕\n〈\n〉\n《\n》\n「\n」\n『\n』\n〖\n〗\n【\n】\n±\n×\n÷\n∶\n∧\n∨\n∑\n∏\n∪\n∩\n∈\n∷\n√\n⊥\n∥\n∠\n⌒\n⊙\n∫\n∮\n≡\n≌\n≈\n∽\n∝\n≠\n≮\n≯\n≤\n≥\n∞\n∵\n∴\n♂\n♀\n°\n′\n″\n℃\n＄\n¤\n￠\n￡\n‰\n§\n№\n☆\n★\n○\n●\n◎\n◇\n◆\n□\n■\n△\n▲\n※\n→\n←\n↑\n↓\n〓\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\n\n\n\n\n\n\n⒈\n⒉\n⒊\n⒋\n⒌\n⒍\n⒎\n⒏\n⒐\n⒑\n⒒\n⒓\n⒔\n⒕\n⒖\n⒗\n⒘\n⒙\n⒚\n⒛\n⑴\n⑵\n⑶\n⑷\n⑸\n⑹\n⑺\n⑻\n⑼\n⑽\n⑾\n⑿\n⒀\n⒁\n⒂\n⒃\n⒄\n⒅\n⒆\n⒇\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n€\n\n㈠\n㈡\n㈢\n㈣\n㈤\n㈥\n㈦\n㈧\n㈨\n㈩\n\n\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\nⅪ\nⅫ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n　\n！\n＂\n＃\n￥\n％\n＆\n＇\n（\n）\n＊\n＋\n，\n－\n．\n／\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\n：\n；\n＜\n＝\n＞\n？\n＠\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\n［\n＼\n］\n＾\n＿\n｀\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\n｛\n｜\n｝\n￣\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\n\n\n\n\n\n\n\n\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\n︐\n︒\n︑\n︓\n︔\n︕\n︖\n︵\n︶\n︹\n︺\n︿\n﹀\n︽\n︾\n﹁\n﹂\n﹃\n﹄\n︗\n︘\n︻\n︼\n︷\n︸\n︱\n︙\n︳\n︴\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n\n\n\n\n\n\n\n\n\n\n\n\n\nˊ\nˋ\n˙\n–\n―\n‥\n‵\n℅\n℉\n↖\n↗\n↘\n↙\n∕\n∟\n∣\n≒\n≦\n≧\n⊿\n═\n║\n╒\n╓\n╔\n╕\n╖\n╗\n╘\n╙\n╚\n╛\n╜\n╝\n╞\n╟\n╠\n╡\n╢\n╣\n╤\n╥\n╦\n╧\n╨\n╩\n╪\n╫\n╬\n╭\n╮\n╯\n╰\n╱\n╲\n╳\n▁\n▂\n▃\n▄\n▅\n▆\n▇\n█\n▉\n▊\n▋\n▌\n▍\n▎\n▏\n▓\n▔\n▕\n▼\n▽\n◢\n◣\n◤\n◥\n☉\n⊕\n〒\n〝\n〞\n\n\n\n\n\n\n\n\n\n\n\nā\ná\nǎ\nà\nē\né\ně\nè\nī\ní\nǐ\nì\nō\nó\nǒ\nò\nū\nú\nǔ\nù\nǖ\nǘ\nǚ\nǜ\nü\nê\nɑ\nḿ\nń\nň\nǹ\nɡ\n\n\n\n\nㄅ\nㄆ\nㄇ\nㄈ\nㄉ\nㄊ\nㄋ\nㄌ\nㄍ\nㄎ\nㄏ\nㄐ\nㄑ\nㄒ\nㄓ\nㄔ\nㄕ\nㄖ\nㄗ\nㄘ\nㄙ\nㄚ\nㄛ\nㄜ\nㄝ\nㄞ\nㄟ\nㄠ\nㄡ\nㄢ\nㄣ\nㄤ\nㄥ\nㄦ\nㄧ\nㄨ\nㄩ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n〡\n〢\n〣\n〤\n〥\n〦\n〧\n〨\n〩\n㊣\n㎎\n㎏\n㎜\n㎝\n㎞\n㎡\n㏄\n㏎\n㏑\n㏒\n㏕\n︰\n￢\n￤\n\n℡\n㈱\n\n‐\n\n\n\nー\n゛\n゜\nヽ\nヾ\n〆\nゝ\nゞ\n﹉\n﹊\n﹋\n﹌\n﹍\n﹎\n﹏\n﹐\n﹑\n﹒\n﹔\n﹕\n﹖\n﹗\n﹙\n﹚\n﹛\n﹜\n﹝\n﹞\n﹟\n﹠\n﹡\n﹢\n﹣\n﹤\n﹥\n﹦\n﹨\n﹩\n﹪\n﹫\n〾\n⿰\n⿱\n⿲\n⿳\n⿴\n⿵\n⿶\n⿷\n⿸\n⿹\n⿺\n⿻\n〇\n\n\n\n\n\n\n\n\n\n\n\n\n\n─\n━\n│\n┃\n┄\n┅\n┆\n┇\n┈\n┉\n┊\n┋\n┌\n┍\n┎\n┏\n┐\n┑\n┒\n┓\n└\n┕\n┖\n┗\n┘\n┙\n┚\n┛\n├\n┝\n┞\n┟\n┠\n┡\n┢\n┣\n┤\n┥\n┦\n┧\n┨\n┩\n┪\n┫\n┬\n┭\n┮\n┯\n┰\n┱\n┲\n┳\n┴\n┵\n┶\n┷\n┸\n┹\n┺\n┻\n┼\n┽\n┾\n┿\n╀\n╁\n╂\n╃\n╄\n╅\n╆\n╇\n╈\n╉\n╊\n╋\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n狜\n狝\n狟\n狢\n狣\n狤\n狥\n狦\n狧\n狪\n狫\n狵\n狶\n狹\n狽\n狾\n狿\n猀\n猂\n猄\n猅\n猆\n猇\n猈\n猉\n猋\n猌\n猍\n猏\n猐\n猑\n猒\n猔\n猘\n猙\n猚\n猟\n猠\n猣\n猤\n猦\n猧\n猨\n猭\n猯\n猰\n猲\n猳\n猵\n猶\n猺\n猻\n猼\n猽\n獀\n獁\n獂\n獃\n獄\n獅\n獆\n獇\n獈\n獉\n獊\n獋\n獌\n獎\n獏\n獑\n獓\n獔\n獕\n獖\n獘\n獙\n獚\n獛\n獜\n獝\n獞\n獟\n獡\n獢\n獣\n獤\n獥\n獦\n獧\n獨\n獩\n獪\n獫\n獮\n獰\n獱\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n獲\n獳\n獴\n獵\n獶\n獷\n獸\n獹\n獺\n獻\n獼\n獽\n獿\n玀\n玁\n玂\n玃\n玅\n玆\n玈\n玊\n玌\n玍\n玏\n玐\n玒\n玓\n玔\n玕\n玗\n玘\n玙\n玚\n玜\n玝\n玞\n玠\n玡\n玣\n玤\n玥\n玦\n玧\n玨\n玪\n玬\n玭\n玱\n玴\n玵\n玶\n玸\n玹\n玼\n玽\n玾\n玿\n珁\n珃\n珄\n珅\n珆\n珇\n珋\n珌\n珎\n珒\n珓\n珔\n珕\n珖\n珗\n珘\n珚\n珛\n珜\n珝\n珟\n珡\n珢\n珣\n珤\n珦\n珨\n珪\n珫\n珬\n珮\n珯\n珰\n珱\n珳\n珴\n珵\n珶\n珷\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n珸\n珹\n珺\n珻\n珼\n珽\n現\n珿\n琀\n琁\n琂\n琄\n琇\n琈\n琋\n琌\n琍\n琎\n琑\n琒\n琓\n琔\n琕\n琖\n琗\n琘\n琙\n琜\n琝\n琞\n琟\n琠\n琡\n琣\n琤\n琧\n琩\n琫\n琭\n琯\n琱\n琲\n琷\n琸\n琹\n琺\n琻\n琽\n琾\n琿\n瑀\n瑂\n瑃\n瑄\n瑅\n瑆\n瑇\n瑈\n瑉\n瑊\n瑋\n瑌\n瑍\n瑎\n瑏\n瑐\n瑑\n瑒\n瑓\n瑔\n瑖\n瑘\n瑝\n瑠\n瑡\n瑢\n瑣\n瑤\n瑥\n瑦\n瑧\n瑨\n瑩\n瑪\n瑫\n瑬\n瑮\n瑯\n瑱\n瑲\n瑳\n瑴\n瑵\n瑸\n瑹\n瑺\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n瑻\n瑼\n瑽\n瑿\n璂\n璄\n璅\n璆\n璈\n璉\n璊\n璌\n璍\n璏\n璑\n璒\n璓\n璔\n璕\n璖\n璗\n璘\n璙\n璚\n璛\n璝\n璟\n璠\n璡\n璢\n璣\n璤\n璥\n璦\n璪\n璫\n璬\n璭\n璮\n璯\n環\n璱\n璲\n璳\n璴\n璵\n璶\n璷\n璸\n璹\n璻\n璼\n璽\n璾\n璿\n瓀\n瓁\n瓂\n瓃\n瓄\n瓅\n瓆\n瓇\n瓈\n瓉\n瓊\n瓋\n瓌\n瓍\n瓎\n瓏\n瓐\n瓑\n瓓\n瓔\n瓕\n瓖\n瓗\n瓘\n瓙\n瓚\n瓛\n瓝\n瓟\n瓡\n瓥\n瓧\n瓨\n瓩\n瓪\n瓫\n瓬\n瓭\n瓰\n瓱\n瓲\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n瓳\n瓵\n瓸\n瓹\n瓺\n瓻\n瓼\n瓽\n瓾\n甀\n甁\n甂\n甃\n甅\n甆\n甇\n甈\n甉\n甊\n甋\n甌\n甎\n甐\n甒\n甔\n甕\n甖\n甗\n甛\n甝\n甞\n甠\n甡\n產\n産\n甤\n甦\n甧\n甪\n甮\n甴\n甶\n甹\n甼\n甽\n甿\n畁\n畂\n畃\n畄\n畆\n畇\n畉\n畊\n畍\n畐\n畑\n畒\n畓\n畕\n畖\n畗\n畘\n畝\n畞\n畟\n畠\n畡\n畢\n畣\n畤\n畧\n畨\n畩\n畫\n畬\n畭\n畮\n畯\n異\n畱\n畳\n畵\n當\n畷\n畺\n畻\n畼\n畽\n畾\n疀\n疁\n疂\n疄\n疅\n疇\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n疈\n疉\n疊\n疌\n疍\n疎\n疐\n疓\n疕\n疘\n疛\n疜\n疞\n疢\n疦\n疧\n疨\n疩\n疪\n疭\n疶\n疷\n疺\n疻\n疿\n痀\n痁\n痆\n痋\n痌\n痎\n痏\n痐\n痑\n痓\n痗\n痙\n痚\n痜\n痝\n痟\n痠\n痡\n痥\n痩\n痬\n痭\n痮\n痯\n痲\n痳\n痵\n痶\n痷\n痸\n痺\n痻\n痽\n痾\n瘂\n瘄\n瘆\n瘇\n瘈\n瘉\n瘋\n瘍\n瘎\n瘏\n瘑\n瘒\n瘓\n瘔\n瘖\n瘚\n瘜\n瘝\n瘞\n瘡\n瘣\n瘧\n瘨\n瘬\n瘮\n瘯\n瘱\n瘲\n瘶\n瘷\n瘹\n瘺\n瘻\n瘽\n癁\n療\n癄\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n癅\n癆\n癇\n癈\n癉\n癊\n癋\n癎\n癏\n癐\n癑\n癒\n癓\n癕\n癗\n癘\n癙\n癚\n癛\n癝\n癟\n癠\n癡\n癢\n癤\n癥\n癦\n癧\n癨\n癩\n癪\n癬\n癭\n癮\n癰\n癱\n癲\n癳\n癴\n癵\n癶\n癷\n癹\n発\n發\n癿\n皀\n皁\n皃\n皅\n皉\n皊\n皌\n皍\n皏\n皐\n皒\n皔\n皕\n皗\n皘\n皚\n皛\n皜\n皝\n皞\n皟\n皠\n皡\n皢\n皣\n皥\n皦\n皧\n皨\n皩\n皪\n皫\n皬\n皭\n皯\n皰\n皳\n皵\n皶\n皷\n皸\n皹\n皺\n皻\n皼\n皽\n皾\n盀\n盁\n盃\n啊\n阿\n埃\n挨\n哎\n唉\n哀\n皑\n癌\n蔼\n矮\n艾\n碍\n爱\n隘\n鞍\n氨\n安\n俺\n按\n暗\n岸\n胺\n案\n肮\n昂\n盎\n凹\n敖\n熬\n翱\n袄\n傲\n奥\n懊\n澳\n芭\n捌\n扒\n叭\n吧\n笆\n八\n疤\n巴\n拔\n跋\n靶\n把\n耙\n坝\n霸\n罢\n爸\n白\n柏\n百\n摆\n佰\n败\n拜\n稗\n斑\n班\n搬\n扳\n般\n颁\n板\n版\n扮\n拌\n伴\n瓣\n半\n办\n绊\n邦\n帮\n梆\n榜\n膀\n绑\n棒\n磅\n蚌\n镑\n傍\n谤\n苞\n胞\n包\n褒\n剥\n盄\n盇\n盉\n盋\n盌\n盓\n盕\n盙\n盚\n盜\n盝\n盞\n盠\n盡\n盢\n監\n盤\n盦\n盧\n盨\n盩\n盪\n盫\n盬\n盭\n盰\n盳\n盵\n盶\n盷\n盺\n盻\n盽\n盿\n眀\n眂\n眃\n眅\n眆\n眊\n県\n眎\n眏\n眐\n眑\n眒\n眓\n眔\n眕\n眖\n眗\n眘\n眛\n眜\n眝\n眞\n眡\n眣\n眤\n眥\n眧\n眪\n眫\n眬\n眮\n眰\n眱\n眲\n眳\n眴\n眹\n眻\n眽\n眾\n眿\n睂\n睄\n睅\n睆\n睈\n睉\n睊\n睋\n睌\n睍\n睎\n睏\n睒\n睓\n睔\n睕\n睖\n睗\n睘\n睙\n睜\n薄\n雹\n保\n堡\n饱\n宝\n抱\n报\n暴\n豹\n鲍\n爆\n杯\n碑\n悲\n卑\n北\n辈\n背\n贝\n钡\n倍\n狈\n备\n惫\n焙\n被\n奔\n苯\n本\n笨\n崩\n绷\n甭\n泵\n蹦\n迸\n逼\n鼻\n比\n鄙\n笔\n彼\n碧\n蓖\n蔽\n毕\n毙\n毖\n币\n庇\n痹\n闭\n敝\n弊\n必\n辟\n壁\n臂\n避\n陛\n鞭\n边\n编\n贬\n扁\n便\n变\n卞\n辨\n辩\n辫\n遍\n标\n彪\n膘\n表\n鳖\n憋\n别\n瘪\n彬\n斌\n濒\n滨\n宾\n摈\n兵\n冰\n柄\n丙\n秉\n饼\n炳\n睝\n睞\n睟\n睠\n睤\n睧\n睩\n睪\n睭\n睮\n睯\n睰\n睱\n睲\n睳\n睴\n睵\n睶\n睷\n睸\n睺\n睻\n睼\n瞁\n瞂\n瞃\n瞆\n瞇\n瞈\n瞉\n瞊\n瞋\n瞏\n瞐\n瞓\n瞔\n瞕\n瞖\n瞗\n瞘\n瞙\n瞚\n瞛\n瞜\n瞝\n瞞\n瞡\n瞣\n瞤\n瞦\n瞨\n瞫\n瞭\n瞮\n瞯\n瞱\n瞲\n瞴\n瞶\n瞷\n瞸\n瞹\n瞺\n瞼\n瞾\n矀\n矁\n矂\n矃\n矄\n矅\n矆\n矇\n矈\n矉\n矊\n矋\n矌\n矎\n矏\n矐\n矑\n矒\n矓\n矔\n矕\n矖\n矘\n矙\n矚\n矝\n矞\n矟\n矠\n矡\n矤\n病\n并\n玻\n菠\n播\n拨\n钵\n波\n博\n勃\n搏\n铂\n箔\n伯\n帛\n舶\n脖\n膊\n渤\n泊\n驳\n捕\n卜\n哺\n补\n埠\n不\n布\n步\n簿\n部\n怖\n擦\n猜\n裁\n材\n才\n财\n睬\n踩\n采\n彩\n菜\n蔡\n餐\n参\n蚕\n残\n惭\n惨\n灿\n苍\n舱\n仓\n沧\n藏\n操\n糙\n槽\n曹\n草\n厕\n策\n侧\n册\n测\n层\n蹭\n插\n叉\n茬\n茶\n查\n碴\n搽\n察\n岔\n差\n诧\n拆\n柴\n豺\n搀\n掺\n蝉\n馋\n谗\n缠\n铲\n产\n阐\n颤\n昌\n猖\n矦\n矨\n矪\n矯\n矰\n矱\n矲\n矴\n矵\n矷\n矹\n矺\n矻\n矼\n砃\n砄\n砅\n砆\n砇\n砈\n砊\n砋\n砎\n砏\n砐\n砓\n砕\n砙\n砛\n砞\n砠\n砡\n砢\n砤\n砨\n砪\n砫\n砮\n砯\n砱\n砲\n砳\n砵\n砶\n砽\n砿\n硁\n硂\n硃\n硄\n硆\n硈\n硉\n硊\n硋\n硍\n硏\n硑\n硓\n硔\n硘\n硙\n硚\n硛\n硜\n硞\n硟\n硠\n硡\n硢\n硣\n硤\n硥\n硦\n硧\n硨\n硩\n硯\n硰\n硱\n硲\n硳\n硴\n硵\n硶\n硸\n硹\n硺\n硻\n硽\n硾\n硿\n碀\n碁\n碂\n碃\n场\n尝\n常\n长\n偿\n肠\n厂\n敞\n畅\n唱\n倡\n超\n抄\n钞\n朝\n嘲\n潮\n巢\n吵\n炒\n车\n扯\n撤\n掣\n彻\n澈\n郴\n臣\n辰\n尘\n晨\n忱\n沉\n陈\n趁\n衬\n撑\n称\n城\n橙\n成\n呈\n乘\n程\n惩\n澄\n诚\n承\n逞\n骋\n秤\n吃\n痴\n持\n匙\n池\n迟\n弛\n驰\n耻\n齿\n侈\n尺\n赤\n翅\n斥\n炽\n充\n冲\n虫\n崇\n宠\n抽\n酬\n畴\n踌\n稠\n愁\n筹\n仇\n绸\n瞅\n丑\n臭\n初\n出\n橱\n厨\n躇\n锄\n雏\n滁\n除\n楚\n碄\n碅\n碆\n碈\n碊\n碋\n碏\n碐\n碒\n碔\n碕\n碖\n碙\n碝\n碞\n碠\n碢\n碤\n碦\n碨\n碩\n碪\n碫\n碬\n碭\n碮\n碯\n碵\n碶\n碷\n碸\n確\n碻\n碼\n碽\n碿\n磀\n磂\n磃\n磄\n磆\n磇\n磈\n磌\n磍\n磎\n磏\n磑\n磒\n磓\n磖\n磗\n磘\n磚\n磛\n磜\n磝\n磞\n磟\n磠\n磡\n磢\n磣\n磤\n磥\n磦\n磧\n磩\n磪\n磫\n磭\n磮\n磯\n磰\n磱\n磳\n磵\n磶\n磸\n磹\n磻\n磼\n磽\n磾\n磿\n礀\n礂\n礃\n礄\n礆\n礇\n礈\n礉\n礊\n礋\n礌\n础\n储\n矗\n搐\n触\n处\n揣\n川\n穿\n椽\n传\n船\n喘\n串\n疮\n窗\n幢\n床\n闯\n创\n吹\n炊\n捶\n锤\n垂\n春\n椿\n醇\n唇\n淳\n纯\n蠢\n戳\n绰\n疵\n茨\n磁\n雌\n辞\n慈\n瓷\n词\n此\n刺\n赐\n次\n聪\n葱\n囱\n匆\n从\n丛\n凑\n粗\n醋\n簇\n促\n蹿\n篡\n窜\n摧\n崔\n催\n脆\n瘁\n粹\n淬\n翠\n村\n存\n寸\n磋\n撮\n搓\n措\n挫\n错\n搭\n达\n答\n瘩\n打\n大\n呆\n歹\n傣\n戴\n带\n殆\n代\n贷\n袋\n待\n逮\n礍\n礎\n礏\n礐\n礑\n礒\n礔\n礕\n礖\n礗\n礘\n礙\n礚\n礛\n礜\n礝\n礟\n礠\n礡\n礢\n礣\n礥\n礦\n礧\n礨\n礩\n礪\n礫\n礬\n礭\n礮\n礯\n礰\n礱\n礲\n礳\n礵\n礶\n礷\n礸\n礹\n礽\n礿\n祂\n祃\n祄\n祅\n祇\n祊\n祋\n祌\n祍\n祎\n祏\n祐\n祑\n祒\n祔\n祕\n祘\n祙\n祡\n祣\n祤\n祦\n祩\n祪\n祫\n祬\n祮\n祰\n祱\n祲\n祳\n祴\n祵\n祶\n祹\n祻\n祼\n祽\n祾\n祿\n禂\n禃\n禆\n禇\n禈\n禉\n禋\n禌\n禍\n禎\n禐\n禑\n禒\n怠\n耽\n担\n丹\n单\n郸\n掸\n胆\n旦\n氮\n但\n惮\n淡\n诞\n弹\n蛋\n当\n挡\n党\n荡\n档\n刀\n捣\n蹈\n倒\n岛\n祷\n导\n到\n稻\n悼\n道\n盗\n德\n得\n的\n蹬\n灯\n登\n等\n瞪\n凳\n邓\n堤\n低\n滴\n迪\n敌\n笛\n狄\n涤\n翟\n嫡\n抵\n底\n地\n蒂\n第\n帝\n弟\n递\n缔\n颠\n掂\n滇\n碘\n点\n典\n靛\n垫\n电\n佃\n甸\n店\n惦\n奠\n淀\n殿\n碉\n叼\n雕\n凋\n刁\n掉\n吊\n钓\n调\n跌\n爹\n碟\n蝶\n迭\n谍\n叠\n禓\n禔\n禕\n禖\n禗\n禘\n禙\n禛\n禜\n禝\n禞\n禟\n禠\n禡\n禢\n禣\n禤\n禥\n禦\n禨\n禩\n禪\n禫\n禬\n禭\n禮\n禯\n禰\n禱\n禲\n禴\n禵\n禶\n禷\n禸\n禼\n禿\n秂\n秄\n秅\n秇\n秈\n秊\n秌\n秎\n秏\n秐\n秓\n秔\n秖\n秗\n秙\n秚\n秛\n秜\n秝\n秞\n秠\n秡\n秢\n秥\n秨\n秪\n秬\n秮\n秱\n秲\n秳\n秴\n秵\n秶\n秷\n秹\n秺\n秼\n秾\n秿\n稁\n稄\n稅\n稇\n稈\n稉\n稊\n稌\n稏\n稐\n稑\n稒\n稓\n稕\n稖\n稘\n稙\n稛\n稜\n丁\n盯\n叮\n钉\n顶\n鼎\n锭\n定\n订\n丢\n东\n冬\n董\n懂\n动\n栋\n侗\n恫\n冻\n洞\n兜\n抖\n斗\n陡\n豆\n逗\n痘\n都\n督\n毒\n犊\n独\n读\n堵\n睹\n赌\n杜\n镀\n肚\n度\n渡\n妒\n端\n短\n锻\n段\n断\n缎\n堆\n兑\n队\n对\n墩\n吨\n蹲\n敦\n顿\n囤\n钝\n盾\n遁\n掇\n哆\n多\n夺\n垛\n躲\n朵\n跺\n舵\n剁\n惰\n堕\n蛾\n峨\n鹅\n俄\n额\n讹\n娥\n恶\n厄\n扼\n遏\n鄂\n饿\n恩\n而\n儿\n耳\n尔\n饵\n洱\n二\n稝\n稟\n稡\n稢\n稤\n稥\n稦\n稧\n稨\n稩\n稪\n稫\n稬\n稭\n種\n稯\n稰\n稱\n稲\n稴\n稵\n稶\n稸\n稺\n稾\n穀\n穁\n穂\n穃\n穄\n穅\n穇\n穈\n穉\n穊\n穋\n穌\n積\n穎\n穏\n穐\n穒\n穓\n穔\n穕\n穖\n穘\n穙\n穚\n穛\n穜\n穝\n穞\n穟\n穠\n穡\n穢\n穣\n穤\n穥\n穦\n穧\n穨\n穩\n穪\n穫\n穬\n穭\n穮\n穯\n穱\n穲\n穳\n穵\n穻\n穼\n穽\n穾\n窂\n窅\n窇\n窉\n窊\n窋\n窌\n窎\n窏\n窐\n窓\n窔\n窙\n窚\n窛\n窞\n窡\n窢\n贰\n发\n罚\n筏\n伐\n乏\n阀\n法\n珐\n藩\n帆\n番\n翻\n樊\n矾\n钒\n繁\n凡\n烦\n反\n返\n范\n贩\n犯\n饭\n泛\n坊\n芳\n方\n肪\n房\n防\n妨\n仿\n访\n纺\n放\n菲\n非\n啡\n飞\n肥\n匪\n诽\n吠\n肺\n废\n沸\n费\n芬\n酚\n吩\n氛\n分\n纷\n坟\n焚\n汾\n粉\n奋\n份\n忿\n愤\n粪\n丰\n封\n枫\n蜂\n峰\n锋\n风\n疯\n烽\n逢\n冯\n缝\n讽\n奉\n凤\n佛\n否\n夫\n敷\n肤\n孵\n扶\n拂\n辐\n幅\n氟\n符\n伏\n俘\n服\n窣\n窤\n窧\n窩\n窪\n窫\n窮\n窯\n窰\n窱\n窲\n窴\n窵\n窶\n窷\n窸\n窹\n窺\n窻\n窼\n窽\n窾\n竀\n竁\n竂\n竃\n竄\n竅\n竆\n竇\n竈\n竉\n竊\n竌\n竍\n竎\n竏\n竐\n竑\n竒\n竓\n竔\n竕\n竗\n竘\n竚\n竛\n竜\n竝\n竡\n竢\n竤\n竧\n竨\n竩\n竪\n竫\n竬\n竮\n竰\n竱\n竲\n竳\n竴\n竵\n競\n竷\n竸\n竻\n竼\n竾\n笀\n笁\n笂\n笅\n笇\n笉\n笌\n笍\n笎\n笐\n笒\n笓\n笖\n笗\n笘\n笚\n笜\n笝\n笟\n笡\n笢\n笣\n笧\n笩\n笭\n浮\n涪\n福\n袱\n弗\n甫\n抚\n辅\n俯\n釜\n斧\n脯\n腑\n府\n腐\n赴\n副\n覆\n赋\n复\n傅\n付\n阜\n父\n腹\n负\n富\n讣\n附\n妇\n缚\n咐\n噶\n嘎\n该\n改\n概\n钙\n盖\n溉\n干\n甘\n杆\n柑\n竿\n肝\n赶\n感\n秆\n敢\n赣\n冈\n刚\n钢\n缸\n肛\n纲\n岗\n港\n杠\n篙\n皋\n高\n膏\n羔\n糕\n搞\n镐\n稿\n告\n哥\n歌\n搁\n戈\n鸽\n胳\n疙\n割\n革\n葛\n格\n蛤\n阁\n隔\n铬\n个\n各\n给\n根\n跟\n耕\n更\n庚\n羹\n笯\n笰\n笲\n笴\n笵\n笶\n笷\n笹\n笻\n笽\n笿\n筀\n筁\n筂\n筃\n筄\n筆\n筈\n筊\n筍\n筎\n筓\n筕\n筗\n筙\n筜\n筞\n筟\n筡\n筣\n筤\n筥\n筦\n筧\n筨\n筩\n筪\n筫\n筬\n筭\n筯\n筰\n筳\n筴\n筶\n筸\n筺\n筼\n筽\n筿\n箁\n箂\n箃\n箄\n箆\n箇\n箈\n箉\n箊\n箋\n箌\n箎\n箏\n箑\n箒\n箓\n箖\n箘\n箙\n箚\n箛\n箞\n箟\n箠\n箣\n箤\n箥\n箮\n箯\n箰\n箲\n箳\n箵\n箶\n箷\n箹\n箺\n箻\n箼\n箽\n箾\n箿\n節\n篂\n篃\n範\n埂\n耿\n梗\n工\n攻\n功\n恭\n龚\n供\n躬\n公\n宫\n弓\n巩\n汞\n拱\n贡\n共\n钩\n勾\n沟\n苟\n狗\n垢\n构\n购\n够\n辜\n菇\n咕\n箍\n估\n沽\n孤\n姑\n鼓\n古\n蛊\n骨\n谷\n股\n故\n顾\n固\n雇\n刮\n瓜\n剐\n寡\n挂\n褂\n乖\n拐\n怪\n棺\n关\n官\n冠\n观\n管\n馆\n罐\n惯\n灌\n贯\n光\n广\n逛\n瑰\n规\n圭\n硅\n归\n龟\n闺\n轨\n鬼\n诡\n癸\n桂\n柜\n跪\n贵\n刽\n辊\n滚\n棍\n锅\n郭\n国\n果\n裹\n过\n哈\n篅\n篈\n築\n篊\n篋\n篍\n篎\n篏\n篐\n篒\n篔\n篕\n篖\n篗\n篘\n篛\n篜\n篞\n篟\n篠\n篢\n篣\n篤\n篧\n篨\n篩\n篫\n篬\n篭\n篯\n篰\n篲\n篳\n篴\n篵\n篶\n篸\n篹\n篺\n篻\n篽\n篿\n簀\n簁\n簂\n簃\n簄\n簅\n簆\n簈\n簉\n簊\n簍\n簎\n簐\n簑\n簒\n簓\n簔\n簕\n簗\n簘\n簙\n簚\n簛\n簜\n簝\n簞\n簠\n簡\n簢\n簣\n簤\n簥\n簨\n簩\n簫\n簬\n簭\n簮\n簯\n簰\n簱\n簲\n簳\n簴\n簵\n簶\n簷\n簹\n簺\n簻\n簼\n簽\n簾\n籂\n骸\n孩\n海\n氦\n亥\n害\n骇\n酣\n憨\n邯\n韩\n含\n涵\n寒\n函\n喊\n罕\n翰\n撼\n捍\n旱\n憾\n悍\n焊\n汗\n汉\n夯\n杭\n航\n壕\n嚎\n豪\n毫\n郝\n好\n耗\n号\n浩\n呵\n喝\n荷\n菏\n核\n禾\n和\n何\n合\n盒\n貉\n阂\n河\n涸\n赫\n褐\n鹤\n贺\n嘿\n黑\n痕\n很\n狠\n恨\n哼\n亨\n横\n衡\n恒\n轰\n哄\n烘\n虹\n鸿\n洪\n宏\n弘\n红\n喉\n侯\n猴\n吼\n厚\n候\n后\n呼\n乎\n忽\n瑚\n壶\n葫\n胡\n蝴\n狐\n糊\n湖\n籃\n籄\n籅\n籆\n籇\n籈\n籉\n籊\n籋\n籌\n籎\n籏\n籐\n籑\n籒\n籓\n籔\n籕\n籖\n籗\n籘\n籙\n籚\n籛\n籜\n籝\n籞\n籟\n籠\n籡\n籢\n籣\n籤\n籥\n籦\n籧\n籨\n籩\n籪\n籫\n籬\n籭\n籮\n籯\n籰\n籱\n籲\n籵\n籶\n籷\n籸\n籹\n籺\n籾\n籿\n粀\n粁\n粂\n粃\n粄\n粅\n粆\n粇\n粈\n粊\n粋\n粌\n粍\n粎\n粏\n粐\n粓\n粔\n粖\n粙\n粚\n粛\n粠\n粡\n粣\n粦\n粧\n粨\n粩\n粫\n粬\n粭\n粯\n粰\n粴\n粵\n粶\n粷\n粸\n粺\n粻\n弧\n虎\n唬\n护\n互\n沪\n户\n花\n哗\n华\n猾\n滑\n画\n划\n化\n话\n槐\n徊\n怀\n淮\n坏\n欢\n环\n桓\n还\n缓\n换\n患\n唤\n痪\n豢\n焕\n涣\n宦\n幻\n荒\n慌\n黄\n磺\n蝗\n簧\n皇\n凰\n惶\n煌\n晃\n幌\n恍\n谎\n灰\n挥\n辉\n徽\n恢\n蛔\n回\n毁\n悔\n慧\n卉\n惠\n晦\n贿\n秽\n会\n烩\n汇\n讳\n诲\n绘\n荤\n昏\n婚\n魂\n浑\n混\n豁\n活\n伙\n火\n获\n或\n惑\n霍\n货\n祸\n击\n圾\n基\n机\n畸\n稽\n积\n箕\n粿\n糀\n糂\n糃\n糄\n糆\n糉\n糋\n糎\n糏\n糐\n糑\n糒\n糓\n糔\n糘\n糚\n糛\n糝\n糞\n糡\n糢\n糣\n糤\n糥\n糦\n糧\n糩\n糪\n糫\n糬\n糭\n糮\n糰\n糱\n糲\n糳\n糴\n糵\n糶\n糷\n糹\n糺\n糼\n糽\n糾\n糿\n紀\n紁\n紂\n紃\n約\n紅\n紆\n紇\n紈\n紉\n紋\n紌\n納\n紎\n紏\n紐\n紑\n紒\n紓\n純\n紕\n紖\n紗\n紘\n紙\n級\n紛\n紜\n紝\n紞\n紟\n紡\n紣\n紤\n紥\n紦\n紨\n紩\n紪\n紬\n紭\n紮\n細\n紱\n紲\n紳\n紴\n紵\n紶\n肌\n饥\n迹\n激\n讥\n鸡\n姬\n绩\n缉\n吉\n极\n棘\n辑\n籍\n集\n及\n急\n疾\n汲\n即\n嫉\n级\n挤\n几\n脊\n己\n蓟\n技\n冀\n季\n伎\n祭\n剂\n悸\n济\n寄\n寂\n计\n记\n既\n忌\n际\n妓\n继\n纪\n嘉\n枷\n夹\n佳\n家\n加\n荚\n颊\n贾\n甲\n钾\n假\n稼\n价\n架\n驾\n嫁\n歼\n监\n坚\n尖\n笺\n间\n煎\n兼\n肩\n艰\n奸\n缄\n茧\n检\n柬\n碱\n硷\n拣\n捡\n简\n俭\n剪\n减\n荐\n槛\n鉴\n践\n贱\n见\n键\n箭\n件\n紷\n紸\n紹\n紺\n紻\n紼\n紽\n紾\n紿\n絀\n絁\n終\n絃\n組\n絅\n絆\n絇\n絈\n絉\n絊\n絋\n経\n絍\n絎\n絏\n結\n絑\n絒\n絓\n絔\n絕\n絖\n絗\n絘\n絙\n絚\n絛\n絜\n絝\n絞\n絟\n絠\n絡\n絢\n絣\n絤\n絥\n給\n絧\n絨\n絩\n絪\n絫\n絬\n絭\n絯\n絰\n統\n絲\n絳\n絴\n絵\n絶\n絸\n絹\n絺\n絻\n絼\n絽\n絾\n絿\n綀\n綁\n綂\n綃\n綄\n綅\n綆\n綇\n綈\n綉\n綊\n綋\n綌\n綍\n綎\n綏\n綐\n綑\n綒\n經\n綔\n綕\n綖\n綗\n綘\n健\n舰\n剑\n饯\n渐\n溅\n涧\n建\n僵\n姜\n将\n浆\n江\n疆\n蒋\n桨\n奖\n讲\n匠\n酱\n降\n蕉\n椒\n礁\n焦\n胶\n交\n郊\n浇\n骄\n娇\n嚼\n搅\n铰\n矫\n侥\n脚\n狡\n角\n饺\n缴\n绞\n剿\n教\n酵\n轿\n较\n叫\n窖\n揭\n接\n皆\n秸\n街\n阶\n截\n劫\n节\n桔\n杰\n捷\n睫\n竭\n洁\n结\n解\n姐\n戒\n藉\n芥\n界\n借\n介\n疥\n诫\n届\n巾\n筋\n斤\n金\n今\n津\n襟\n紧\n锦\n仅\n谨\n进\n靳\n晋\n禁\n近\n烬\n浸\n継\n続\n綛\n綜\n綝\n綞\n綟\n綠\n綡\n綢\n綣\n綤\n綥\n綧\n綨\n綩\n綪\n綫\n綬\n維\n綯\n綰\n綱\n網\n綳\n綴\n綵\n綶\n綷\n綸\n綹\n綺\n綻\n綼\n綽\n綾\n綿\n緀\n緁\n緂\n緃\n緄\n緅\n緆\n緇\n緈\n緉\n緊\n緋\n緌\n緍\n緎\n総\n緐\n緑\n緒\n緓\n緔\n緕\n緖\n緗\n緘\n緙\n線\n緛\n緜\n緝\n緞\n緟\n締\n緡\n緢\n緣\n緤\n緥\n緦\n緧\n編\n緩\n緪\n緫\n緬\n緭\n緮\n緯\n緰\n緱\n緲\n緳\n練\n緵\n緶\n緷\n緸\n緹\n緺\n尽\n劲\n荆\n兢\n茎\n睛\n晶\n鲸\n京\n惊\n精\n粳\n经\n井\n警\n景\n颈\n静\n境\n敬\n镜\n径\n痉\n靖\n竟\n竞\n净\n炯\n窘\n揪\n究\n纠\n玖\n韭\n久\n灸\n九\n酒\n厩\n救\n旧\n臼\n舅\n咎\n就\n疚\n鞠\n拘\n狙\n疽\n居\n驹\n菊\n局\n咀\n矩\n举\n沮\n聚\n拒\n据\n巨\n具\n距\n踞\n锯\n俱\n句\n惧\n炬\n剧\n捐\n鹃\n娟\n倦\n眷\n卷\n绢\n撅\n攫\n抉\n掘\n倔\n爵\n觉\n决\n诀\n绝\n均\n菌\n钧\n军\n君\n峻\n緻\n緼\n緽\n緾\n緿\n縀\n縁\n縂\n縃\n縄\n縅\n縆\n縇\n縈\n縉\n縊\n縋\n縌\n縍\n縎\n縏\n縐\n縑\n縒\n縓\n縔\n縕\n縖\n縗\n縘\n縙\n縚\n縛\n縜\n縝\n縞\n縟\n縠\n縡\n縢\n縣\n縤\n縥\n縦\n縧\n縨\n縩\n縪\n縫\n縬\n縭\n縮\n縯\n縰\n縱\n縲\n縳\n縴\n縵\n縶\n縷\n縸\n縹\n縺\n縼\n總\n績\n縿\n繀\n繂\n繃\n繄\n繅\n繆\n繈\n繉\n繊\n繋\n繌\n繍\n繎\n繏\n繐\n繑\n繒\n繓\n織\n繕\n繖\n繗\n繘\n繙\n繚\n繛\n繜\n繝\n俊\n竣\n浚\n郡\n骏\n喀\n咖\n卡\n咯\n开\n揩\n楷\n凯\n慨\n刊\n堪\n勘\n坎\n砍\n看\n康\n慷\n糠\n扛\n抗\n亢\n炕\n考\n拷\n烤\n靠\n坷\n苛\n柯\n棵\n磕\n颗\n科\n壳\n咳\n可\n渴\n克\n刻\n客\n课\n肯\n啃\n垦\n恳\n坑\n吭\n空\n恐\n孔\n控\n抠\n口\n扣\n寇\n枯\n哭\n窟\n苦\n酷\n库\n裤\n夸\n垮\n挎\n跨\n胯\n块\n筷\n侩\n快\n宽\n款\n匡\n筐\n狂\n框\n矿\n眶\n旷\n况\n亏\n盔\n岿\n窥\n葵\n奎\n魁\n傀\n繞\n繟\n繠\n繡\n繢\n繣\n繤\n繥\n繦\n繧\n繨\n繩\n繪\n繫\n繬\n繭\n繮\n繯\n繰\n繱\n繲\n繳\n繴\n繵\n繶\n繷\n繸\n繹\n繺\n繻\n繼\n繽\n繾\n繿\n纀\n纁\n纃\n纄\n纅\n纆\n纇\n纈\n纉\n纊\n纋\n續\n纍\n纎\n纏\n纐\n纑\n纒\n纓\n纔\n纕\n纖\n纗\n纘\n纙\n纚\n纜\n纝\n纞\n纮\n纴\n纻\n纼\n绖\n绤\n绬\n绹\n缊\n缐\n缞\n缷\n缹\n缻\n缼\n缽\n缾\n缿\n罀\n罁\n罃\n罆\n罇\n罈\n罉\n罊\n罋\n罌\n罍\n罎\n罏\n罒\n罓\n馈\n愧\n溃\n坤\n昆\n捆\n困\n括\n扩\n廓\n阔\n垃\n拉\n喇\n蜡\n腊\n辣\n啦\n莱\n来\n赖\n蓝\n婪\n栏\n拦\n篮\n阑\n兰\n澜\n谰\n揽\n览\n懒\n缆\n烂\n滥\n琅\n榔\n狼\n廊\n郎\n朗\n浪\n捞\n劳\n牢\n老\n佬\n姥\n酪\n烙\n涝\n勒\n乐\n雷\n镭\n蕾\n磊\n累\n儡\n垒\n擂\n肋\n类\n泪\n棱\n楞\n冷\n厘\n梨\n犁\n黎\n篱\n狸\n离\n漓\n理\n李\n里\n鲤\n礼\n莉\n荔\n吏\n栗\n丽\n厉\n励\n砾\n历\n利\n傈\n例\n俐\n罖\n罙\n罛\n罜\n罝\n罞\n罠\n罣\n罤\n罥\n罦\n罧\n罫\n罬\n罭\n罯\n罰\n罳\n罵\n罶\n罷\n罸\n罺\n罻\n罼\n罽\n罿\n羀\n羂\n羃\n羄\n羅\n羆\n羇\n羈\n羉\n羋\n羍\n羏\n羐\n羑\n羒\n羓\n羕\n羖\n羗\n羘\n羙\n羛\n羜\n羠\n羢\n羣\n羥\n羦\n羨\n義\n羪\n羫\n羬\n羭\n羮\n羱\n羳\n羴\n羵\n羶\n羷\n羺\n羻\n羾\n翀\n翂\n翃\n翄\n翆\n翇\n翈\n翉\n翋\n翍\n翏\n翐\n翑\n習\n翓\n翖\n翗\n翙\n翚\n翛\n翜\n翝\n翞\n翢\n翣\n痢\n立\n粒\n沥\n隶\n力\n璃\n哩\n俩\n联\n莲\n连\n镰\n廉\n怜\n涟\n帘\n敛\n脸\n链\n恋\n炼\n练\n粮\n凉\n梁\n粱\n良\n两\n辆\n量\n晾\n亮\n谅\n撩\n聊\n僚\n疗\n燎\n寥\n辽\n潦\n了\n撂\n镣\n廖\n料\n列\n裂\n烈\n劣\n猎\n琳\n林\n磷\n霖\n临\n邻\n鳞\n淋\n凛\n赁\n吝\n拎\n玲\n菱\n零\n龄\n铃\n伶\n羚\n凌\n灵\n陵\n岭\n领\n另\n令\n溜\n琉\n榴\n硫\n馏\n留\n刘\n瘤\n流\n柳\n六\n龙\n聋\n咙\n笼\n窿\n翤\n翧\n翨\n翪\n翫\n翬\n翭\n翯\n翲\n翴\n翵\n翶\n翷\n翸\n翹\n翺\n翽\n翾\n翿\n耂\n耇\n耈\n耉\n耊\n耎\n耏\n耑\n耓\n耚\n耛\n耝\n耞\n耟\n耡\n耣\n耤\n耫\n耬\n耭\n耮\n耯\n耰\n耲\n耴\n耹\n耺\n耼\n耾\n聀\n聁\n聄\n聅\n聇\n聈\n聉\n聎\n聏\n聐\n聑\n聓\n聕\n聖\n聗\n聙\n聛\n聜\n聝\n聞\n聟\n聠\n聡\n聢\n聣\n聤\n聥\n聦\n聧\n聨\n聫\n聬\n聭\n聮\n聯\n聰\n聲\n聳\n聴\n聵\n聶\n職\n聸\n聹\n聺\n聻\n聼\n聽\n隆\n垄\n拢\n陇\n楼\n娄\n搂\n篓\n漏\n陋\n芦\n卢\n颅\n庐\n炉\n掳\n卤\n虏\n鲁\n麓\n碌\n露\n路\n赂\n鹿\n潞\n禄\n录\n陆\n戮\n驴\n吕\n铝\n侣\n旅\n履\n屡\n缕\n虑\n氯\n律\n率\n滤\n绿\n峦\n挛\n孪\n滦\n卵\n乱\n掠\n略\n抡\n轮\n伦\n仑\n沦\n纶\n论\n萝\n螺\n罗\n逻\n锣\n箩\n骡\n裸\n落\n洛\n骆\n络\n妈\n麻\n玛\n码\n蚂\n马\n骂\n嘛\n吗\n埋\n买\n麦\n卖\n迈\n脉\n瞒\n馒\n蛮\n满\n蔓\n曼\n慢\n漫\n聾\n肁\n肂\n肅\n肈\n肊\n肍\n肎\n肏\n肐\n肑\n肒\n肔\n肕\n肗\n肙\n肞\n肣\n肦\n肧\n肨\n肬\n肰\n肳\n肵\n肶\n肸\n肹\n肻\n胅\n胇\n胈\n胉\n胊\n胋\n胏\n胐\n胑\n胒\n胓\n胔\n胕\n胘\n胟\n胠\n胢\n胣\n胦\n胮\n胵\n胷\n胹\n胻\n胾\n胿\n脀\n脁\n脃\n脄\n脅\n脇\n脈\n脋\n脌\n脕\n脗\n脙\n脛\n脜\n脝\n脟\n脠\n脡\n脢\n脣\n脤\n脥\n脦\n脧\n脨\n脩\n脪\n脫\n脭\n脮\n脰\n脳\n脴\n脵\n脷\n脹\n脺\n脻\n脼\n脽\n脿\n谩\n芒\n茫\n盲\n氓\n忙\n莽\n猫\n茅\n锚\n毛\n矛\n铆\n卯\n茂\n冒\n帽\n貌\n贸\n么\n玫\n枚\n梅\n酶\n霉\n煤\n没\n眉\n媒\n镁\n每\n美\n昧\n寐\n妹\n媚\n门\n闷\n们\n萌\n蒙\n檬\n盟\n锰\n猛\n梦\n孟\n眯\n醚\n靡\n糜\n迷\n谜\n弥\n米\n秘\n觅\n泌\n蜜\n密\n幂\n棉\n眠\n绵\n冕\n免\n勉\n娩\n缅\n面\n苗\n描\n瞄\n藐\n秒\n渺\n庙\n妙\n蔑\n灭\n民\n抿\n皿\n敏\n悯\n闽\n明\n螟\n鸣\n铭\n名\n命\n谬\n摸\n腀\n腁\n腂\n腃\n腄\n腅\n腇\n腉\n腍\n腎\n腏\n腒\n腖\n腗\n腘\n腛\n腜\n腝\n腞\n腟\n腡\n腢\n腣\n腤\n腦\n腨\n腪\n腫\n腬\n腯\n腲\n腳\n腵\n腶\n腷\n腸\n膁\n膃\n膄\n膅\n膆\n膇\n膉\n膋\n膌\n膍\n膎\n膐\n膒\n膓\n膔\n膕\n膖\n膗\n膙\n膚\n膞\n膟\n膠\n膡\n膢\n膤\n膥\n膧\n膩\n膫\n膬\n膭\n膮\n膯\n膰\n膱\n膲\n膴\n膵\n膶\n膷\n膸\n膹\n膼\n膽\n膾\n膿\n臄\n臅\n臇\n臈\n臉\n臋\n臍\n臎\n臏\n臐\n臑\n臒\n臓\n摹\n蘑\n模\n膜\n磨\n摩\n魔\n抹\n末\n莫\n墨\n默\n沫\n漠\n寞\n陌\n谋\n牟\n某\n拇\n牡\n亩\n姆\n母\n墓\n暮\n幕\n募\n慕\n木\n目\n睦\n牧\n穆\n拿\n哪\n呐\n钠\n那\n娜\n纳\n氖\n乃\n奶\n耐\n奈\n南\n男\n难\n囊\n挠\n脑\n恼\n闹\n淖\n呢\n馁\n内\n嫩\n能\n妮\n霓\n倪\n泥\n尼\n拟\n你\n匿\n腻\n逆\n溺\n蔫\n拈\n年\n碾\n撵\n捻\n念\n娘\n酿\n鸟\n尿\n捏\n聂\n孽\n啮\n镊\n镍\n涅\n您\n柠\n狞\n凝\n宁\n臔\n臕\n臖\n臗\n臘\n臙\n臚\n臛\n臜\n臝\n臞\n臟\n臠\n臡\n臢\n臤\n臥\n臦\n臨\n臩\n臫\n臮\n臯\n臰\n臱\n臲\n臵\n臶\n臷\n臸\n臹\n臺\n臽\n臿\n舃\n與\n興\n舉\n舊\n舋\n舎\n舏\n舑\n舓\n舕\n舖\n舗\n舘\n舙\n舚\n舝\n舠\n舤\n舥\n舦\n舧\n舩\n舮\n舲\n舺\n舼\n舽\n舿\n艀\n艁\n艂\n艃\n艅\n艆\n艈\n艊\n艌\n艍\n艎\n艐\n艑\n艒\n艓\n艔\n艕\n艖\n艗\n艙\n艛\n艜\n艝\n艞\n艠\n艡\n艢\n艣\n艤\n艥\n艦\n艧\n艩\n拧\n泞\n牛\n扭\n钮\n纽\n脓\n浓\n农\n弄\n奴\n努\n怒\n女\n暖\n虐\n疟\n挪\n懦\n糯\n诺\n哦\n欧\n鸥\n殴\n藕\n呕\n偶\n沤\n啪\n趴\n爬\n帕\n怕\n琶\n拍\n排\n牌\n徘\n湃\n派\n攀\n潘\n盘\n磐\n盼\n畔\n判\n叛\n乓\n庞\n旁\n耪\n胖\n抛\n咆\n刨\n炮\n袍\n跑\n泡\n呸\n胚\n培\n裴\n赔\n陪\n配\n佩\n沛\n喷\n盆\n砰\n抨\n烹\n澎\n彭\n蓬\n棚\n硼\n篷\n膨\n朋\n鹏\n捧\n碰\n坯\n砒\n霹\n批\n披\n劈\n琵\n毗\n艪\n艫\n艬\n艭\n艱\n艵\n艶\n艷\n艸\n艻\n艼\n芀\n芁\n芃\n芅\n芆\n芇\n芉\n芌\n芐\n芓\n芔\n芕\n芖\n芚\n芛\n芞\n芠\n芢\n芣\n芧\n芲\n芵\n芶\n芺\n芻\n芼\n芿\n苀\n苂\n苃\n苅\n苆\n苉\n苐\n苖\n苙\n苚\n苝\n苢\n苧\n苨\n苩\n苪\n苬\n苭\n苮\n苰\n苲\n苳\n苵\n苶\n苸\n苺\n苼\n苽\n苾\n苿\n茀\n茊\n茋\n茍\n茐\n茒\n茓\n茖\n茘\n茙\n茝\n茞\n茟\n茠\n茡\n茢\n茣\n茤\n茥\n茦\n茩\n茪\n茮\n茰\n茲\n茷\n茻\n茽\n啤\n脾\n疲\n皮\n匹\n痞\n僻\n屁\n譬\n篇\n偏\n片\n骗\n飘\n漂\n瓢\n票\n撇\n瞥\n拼\n频\n贫\n品\n聘\n乒\n坪\n苹\n萍\n平\n凭\n瓶\n评\n屏\n坡\n泼\n颇\n婆\n破\n魄\n迫\n粕\n剖\n扑\n铺\n仆\n莆\n葡\n菩\n蒲\n埔\n朴\n圃\n普\n浦\n谱\n曝\n瀑\n期\n欺\n栖\n戚\n妻\n七\n凄\n漆\n柒\n沏\n其\n棋\n奇\n歧\n畦\n崎\n脐\n齐\n旗\n祈\n祁\n骑\n起\n岂\n乞\n企\n启\n契\n砌\n器\n气\n迄\n弃\n汽\n泣\n讫\n掐\n茾\n茿\n荁\n荂\n荄\n荅\n荈\n荊\n荋\n荌\n荍\n荎\n荓\n荕\n荖\n荗\n荘\n荙\n荝\n荢\n荰\n荱\n荲\n荳\n荴\n荵\n荶\n荹\n荺\n荾\n荿\n莀\n莁\n莂\n莃\n莄\n莇\n莈\n莊\n莋\n莌\n莍\n莏\n莐\n莑\n莔\n莕\n莖\n莗\n莙\n莚\n莝\n莟\n莡\n莢\n莣\n莤\n莥\n莦\n莧\n莬\n莭\n莮\n莯\n莵\n莻\n莾\n莿\n菂\n菃\n菄\n菆\n菈\n菉\n菋\n菍\n菎\n菐\n菑\n菒\n菓\n菕\n菗\n菙\n菚\n菛\n菞\n菢\n菣\n菤\n菦\n菧\n菨\n菫\n菬\n菭\n恰\n洽\n牵\n扦\n钎\n铅\n千\n迁\n签\n仟\n谦\n乾\n黔\n钱\n钳\n前\n潜\n遣\n浅\n谴\n堑\n嵌\n欠\n歉\n枪\n呛\n腔\n羌\n墙\n蔷\n强\n抢\n橇\n锹\n敲\n悄\n桥\n瞧\n乔\n侨\n巧\n鞘\n撬\n翘\n峭\n俏\n窍\n切\n茄\n且\n怯\n窃\n钦\n侵\n亲\n秦\n琴\n勤\n芹\n擒\n禽\n寝\n沁\n青\n轻\n氢\n倾\n卿\n清\n擎\n晴\n氰\n情\n顷\n请\n庆\n琼\n穷\n秋\n丘\n邱\n球\n求\n囚\n酋\n泅\n趋\n区\n蛆\n曲\n躯\n屈\n驱\n渠\n菮\n華\n菳\n菴\n菵\n菶\n菷\n菺\n菻\n菼\n菾\n菿\n萀\n萂\n萅\n萇\n萈\n萉\n萊\n萐\n萒\n萓\n萔\n萕\n萖\n萗\n萙\n萚\n萛\n萞\n萟\n萠\n萡\n萢\n萣\n萩\n萪\n萫\n萬\n萭\n萮\n萯\n萰\n萲\n萳\n萴\n萵\n萶\n萷\n萹\n萺\n萻\n萾\n萿\n葀\n葁\n葂\n葃\n葄\n葅\n葇\n葈\n葉\n葊\n葋\n葌\n葍\n葎\n葏\n葐\n葒\n葓\n葔\n葕\n葖\n葘\n葝\n葞\n葟\n葠\n葢\n葤\n葥\n葦\n葧\n葨\n葪\n葮\n葯\n葰\n葲\n葴\n葷\n葹\n葻\n葼\n取\n娶\n龋\n趣\n去\n圈\n颧\n权\n醛\n泉\n全\n痊\n拳\n犬\n券\n劝\n缺\n炔\n瘸\n却\n鹊\n榷\n确\n雀\n裙\n群\n然\n燃\n冉\n染\n瓤\n壤\n攘\n嚷\n让\n饶\n扰\n绕\n惹\n热\n壬\n仁\n人\n忍\n韧\n任\n认\n刃\n妊\n纫\n扔\n仍\n日\n戎\n茸\n蓉\n荣\n融\n熔\n溶\n容\n绒\n冗\n揉\n柔\n肉\n茹\n蠕\n儒\n孺\n如\n辱\n乳\n汝\n入\n褥\n软\n阮\n蕊\n瑞\n锐\n闰\n润\n若\n弱\n撒\n洒\n萨\n腮\n鳃\n塞\n赛\n三\n叁\n葽\n葾\n葿\n蒀\n蒁\n蒃\n蒄\n蒅\n蒆\n蒊\n蒍\n蒏\n蒐\n蒑\n蒒\n蒓\n蒔\n蒕\n蒖\n蒘\n蒚\n蒛\n蒝\n蒞\n蒟\n蒠\n蒢\n蒣\n蒤\n蒥\n蒦\n蒧\n蒨\n蒩\n蒪\n蒫\n蒬\n蒭\n蒮\n蒰\n蒱\n蒳\n蒵\n蒶\n蒷\n蒻\n蒼\n蒾\n蓀\n蓂\n蓃\n蓅\n蓆\n蓇\n蓈\n蓋\n蓌\n蓎\n蓏\n蓒\n蓔\n蓕\n蓗\n蓘\n蓙\n蓚\n蓛\n蓜\n蓞\n蓡\n蓢\n蓤\n蓧\n蓨\n蓩\n蓪\n蓫\n蓭\n蓮\n蓯\n蓱\n蓲\n蓳\n蓴\n蓵\n蓶\n蓷\n蓸\n蓹\n蓺\n蓻\n蓽\n蓾\n蔀\n蔁\n蔂\n伞\n散\n桑\n嗓\n丧\n搔\n骚\n扫\n嫂\n瑟\n色\n涩\n森\n僧\n莎\n砂\n杀\n刹\n沙\n纱\n傻\n啥\n煞\n筛\n晒\n珊\n苫\n杉\n山\n删\n煽\n衫\n闪\n陕\n擅\n赡\n膳\n善\n汕\n扇\n缮\n墒\n伤\n商\n赏\n晌\n上\n尚\n裳\n梢\n捎\n稍\n烧\n芍\n勺\n韶\n少\n哨\n邵\n绍\n奢\n赊\n蛇\n舌\n舍\n赦\n摄\n射\n慑\n涉\n社\n设\n砷\n申\n呻\n伸\n身\n深\n娠\n绅\n神\n沈\n审\n婶\n甚\n肾\n慎\n渗\n声\n生\n甥\n牲\n升\n绳\n蔃\n蔄\n蔅\n蔆\n蔇\n蔈\n蔉\n蔊\n蔋\n蔍\n蔎\n蔏\n蔐\n蔒\n蔔\n蔕\n蔖\n蔘\n蔙\n蔛\n蔜\n蔝\n蔞\n蔠\n蔢\n蔣\n蔤\n蔥\n蔦\n蔧\n蔨\n蔩\n蔪\n蔭\n蔮\n蔯\n蔰\n蔱\n蔲\n蔳\n蔴\n蔵\n蔶\n蔾\n蔿\n蕀\n蕁\n蕂\n蕄\n蕅\n蕆\n蕇\n蕋\n蕌\n蕍\n蕎\n蕏\n蕐\n蕑\n蕒\n蕓\n蕔\n蕕\n蕗\n蕘\n蕚\n蕛\n蕜\n蕝\n蕟\n蕠\n蕡\n蕢\n蕣\n蕥\n蕦\n蕧\n蕩\n蕪\n蕫\n蕬\n蕭\n蕮\n蕯\n蕰\n蕱\n蕳\n蕵\n蕶\n蕷\n蕸\n蕼\n蕽\n蕿\n薀\n薁\n省\n盛\n剩\n胜\n圣\n师\n失\n狮\n施\n湿\n诗\n尸\n虱\n十\n石\n拾\n时\n什\n食\n蚀\n实\n识\n史\n矢\n使\n屎\n驶\n始\n式\n示\n士\n世\n柿\n事\n拭\n誓\n逝\n势\n是\n嗜\n噬\n适\n仕\n侍\n释\n饰\n氏\n市\n恃\n室\n视\n试\n收\n手\n首\n守\n寿\n授\n售\n受\n瘦\n兽\n蔬\n枢\n梳\n殊\n抒\n输\n叔\n舒\n淑\n疏\n书\n赎\n孰\n熟\n薯\n暑\n曙\n署\n蜀\n黍\n鼠\n属\n术\n述\n树\n束\n戍\n竖\n墅\n庶\n数\n漱\n薂\n薃\n薆\n薈\n薉\n薊\n薋\n薌\n薍\n薎\n薐\n薑\n薒\n薓\n薔\n薕\n薖\n薗\n薘\n薙\n薚\n薝\n薞\n薟\n薠\n薡\n薢\n薣\n薥\n薦\n薧\n薩\n薫\n薬\n薭\n薱\n薲\n薳\n薴\n薵\n薶\n薸\n薺\n薻\n薼\n薽\n薾\n薿\n藀\n藂\n藃\n藄\n藅\n藆\n藇\n藈\n藊\n藋\n藌\n藍\n藎\n藑\n藒\n藔\n藖\n藗\n藘\n藙\n藚\n藛\n藝\n藞\n藟\n藠\n藡\n藢\n藣\n藥\n藦\n藧\n藨\n藪\n藫\n藬\n藭\n藮\n藯\n藰\n藱\n藲\n藳\n藴\n藵\n藶\n藷\n藸\n恕\n刷\n耍\n摔\n衰\n甩\n帅\n栓\n拴\n霜\n双\n爽\n谁\n水\n睡\n税\n吮\n瞬\n顺\n舜\n说\n硕\n朔\n烁\n斯\n撕\n嘶\n思\n私\n司\n丝\n死\n肆\n寺\n嗣\n四\n伺\n似\n饲\n巳\n松\n耸\n怂\n颂\n送\n宋\n讼\n诵\n搜\n艘\n擞\n嗽\n苏\n酥\n俗\n素\n速\n粟\n僳\n塑\n溯\n宿\n诉\n肃\n酸\n蒜\n算\n虽\n隋\n随\n绥\n髓\n碎\n岁\n穗\n遂\n隧\n祟\n孙\n损\n笋\n蓑\n梭\n唆\n缩\n琐\n索\n锁\n所\n塌\n他\n它\n她\n塔\n藹\n藺\n藼\n藽\n藾\n蘀\n蘁\n蘂\n蘃\n蘄\n蘆\n蘇\n蘈\n蘉\n蘊\n蘋\n蘌\n蘍\n蘎\n蘏\n蘐\n蘒\n蘓\n蘔\n蘕\n蘗\n蘘\n蘙\n蘚\n蘛\n蘜\n蘝\n蘞\n蘟\n蘠\n蘡\n蘢\n蘣\n蘤\n蘥\n蘦\n蘨\n蘪\n蘫\n蘬\n蘭\n蘮\n蘯\n蘰\n蘱\n蘲\n蘳\n蘴\n蘵\n蘶\n蘷\n蘹\n蘺\n蘻\n蘽\n蘾\n蘿\n虀\n虁\n虂\n虃\n虄\n虅\n虆\n虇\n虈\n虉\n虊\n虋\n虌\n虒\n虓\n處\n虖\n虗\n虘\n虙\n虛\n虜\n虝\n號\n虠\n虡\n虣\n虤\n虥\n虦\n虧\n虨\n虩\n虪\n獭\n挞\n蹋\n踏\n胎\n苔\n抬\n台\n泰\n酞\n太\n态\n汰\n坍\n摊\n贪\n瘫\n滩\n坛\n檀\n痰\n潭\n谭\n谈\n坦\n毯\n袒\n碳\n探\n叹\n炭\n汤\n塘\n搪\n堂\n棠\n膛\n唐\n糖\n倘\n躺\n淌\n趟\n烫\n掏\n涛\n滔\n绦\n萄\n桃\n逃\n淘\n陶\n讨\n套\n特\n藤\n腾\n疼\n誊\n梯\n剔\n踢\n锑\n提\n题\n蹄\n啼\n体\n替\n嚏\n惕\n涕\n剃\n屉\n天\n添\n填\n田\n甜\n恬\n舔\n腆\n挑\n条\n迢\n眺\n跳\n贴\n铁\n帖\n厅\n听\n烃\n虭\n虯\n虰\n虲\n虳\n虴\n虵\n虶\n虷\n虸\n蚃\n蚄\n蚅\n蚆\n蚇\n蚈\n蚉\n蚎\n蚏\n蚐\n蚑\n蚒\n蚔\n蚖\n蚗\n蚘\n蚙\n蚚\n蚛\n蚞\n蚟\n蚠\n蚡\n蚢\n蚥\n蚦\n蚫\n蚭\n蚮\n蚲\n蚳\n蚷\n蚸\n蚹\n蚻\n蚼\n蚽\n蚾\n蚿\n蛁\n蛂\n蛃\n蛅\n蛈\n蛌\n蛍\n蛒\n蛓\n蛕\n蛖\n蛗\n蛚\n蛜\n蛝\n蛠\n蛡\n蛢\n蛣\n蛥\n蛦\n蛧\n蛨\n蛪\n蛫\n蛬\n蛯\n蛵\n蛶\n蛷\n蛺\n蛻\n蛼\n蛽\n蛿\n蜁\n蜄\n蜅\n蜆\n蜋\n蜌\n蜎\n蜏\n蜐\n蜑\n蜔\n蜖\n汀\n廷\n停\n亭\n庭\n挺\n艇\n通\n桐\n酮\n瞳\n同\n铜\n彤\n童\n桶\n捅\n筒\n统\n痛\n偷\n投\n头\n透\n凸\n秃\n突\n图\n徒\n途\n涂\n屠\n土\n吐\n兔\n湍\n团\n推\n颓\n腿\n蜕\n褪\n退\n吞\n屯\n臀\n拖\n托\n脱\n鸵\n陀\n驮\n驼\n椭\n妥\n拓\n唾\n挖\n哇\n蛙\n洼\n娃\n瓦\n袜\n歪\n外\n豌\n弯\n湾\n玩\n顽\n丸\n烷\n完\n碗\n挽\n晚\n皖\n惋\n宛\n婉\n万\n腕\n汪\n王\n亡\n枉\n网\n往\n旺\n望\n忘\n妄\n威\n蜙\n蜛\n蜝\n蜟\n蜠\n蜤\n蜦\n蜧\n蜨\n蜪\n蜫\n蜬\n蜭\n蜯\n蜰\n蜲\n蜳\n蜵\n蜶\n蜸\n蜹\n蜺\n蜼\n蜽\n蝀\n蝁\n蝂\n蝃\n蝄\n蝅\n蝆\n蝊\n蝋\n蝍\n蝏\n蝐\n蝑\n蝒\n蝔\n蝕\n蝖\n蝘\n蝚\n蝛\n蝜\n蝝\n蝞\n蝟\n蝡\n蝢\n蝦\n蝧\n蝨\n蝩\n蝪\n蝫\n蝬\n蝭\n蝯\n蝱\n蝲\n蝳\n蝵\n蝷\n蝸\n蝹\n蝺\n蝿\n螀\n螁\n螄\n螆\n螇\n螉\n螊\n螌\n螎\n螏\n螐\n螑\n螒\n螔\n螕\n螖\n螘\n螙\n螚\n螛\n螜\n螝\n螞\n螠\n螡\n螢\n螣\n螤\n巍\n微\n危\n韦\n违\n桅\n围\n唯\n惟\n为\n潍\n维\n苇\n萎\n委\n伟\n伪\n尾\n纬\n未\n蔚\n味\n畏\n胃\n喂\n魏\n位\n渭\n谓\n尉\n慰\n卫\n瘟\n温\n蚊\n文\n闻\n纹\n吻\n稳\n紊\n问\n嗡\n翁\n瓮\n挝\n蜗\n涡\n窝\n我\n斡\n卧\n握\n沃\n巫\n呜\n钨\n乌\n污\n诬\n屋\n无\n芜\n梧\n吾\n吴\n毋\n武\n五\n捂\n午\n舞\n伍\n侮\n坞\n戊\n雾\n晤\n物\n勿\n务\n悟\n误\n昔\n熙\n析\n西\n硒\n矽\n晰\n嘻\n吸\n锡\n牺\n螥\n螦\n螧\n螩\n螪\n螮\n螰\n螱\n螲\n螴\n螶\n螷\n螸\n螹\n螻\n螼\n螾\n螿\n蟁\n蟂\n蟃\n蟄\n蟅\n蟇\n蟈\n蟉\n蟌\n蟍\n蟎\n蟏\n蟐\n蟔\n蟕\n蟖\n蟗\n蟘\n蟙\n蟚\n蟜\n蟝\n蟞\n蟟\n蟡\n蟢\n蟣\n蟤\n蟦\n蟧\n蟨\n蟩\n蟫\n蟬\n蟭\n蟯\n蟰\n蟱\n蟲\n蟳\n蟴\n蟵\n蟶\n蟷\n蟸\n蟺\n蟻\n蟼\n蟽\n蟿\n蠀\n蠁\n蠂\n蠄\n蠅\n蠆\n蠇\n蠈\n蠉\n蠋\n蠌\n蠍\n蠎\n蠏\n蠐\n蠑\n蠒\n蠔\n蠗\n蠘\n蠙\n蠚\n蠜\n蠝\n蠞\n蠟\n蠠\n蠣\n稀\n息\n希\n悉\n膝\n夕\n惜\n熄\n烯\n溪\n汐\n犀\n檄\n袭\n席\n习\n媳\n喜\n铣\n洗\n系\n隙\n戏\n细\n瞎\n虾\n匣\n霞\n辖\n暇\n峡\n侠\n狭\n下\n厦\n夏\n吓\n掀\n锨\n先\n仙\n鲜\n纤\n咸\n贤\n衔\n舷\n闲\n涎\n弦\n嫌\n显\n险\n现\n献\n县\n腺\n馅\n羡\n宪\n陷\n限\n线\n相\n厢\n镶\n香\n箱\n襄\n湘\n乡\n翔\n祥\n详\n想\n响\n享\n项\n巷\n橡\n像\n向\n象\n萧\n硝\n霄\n削\n哮\n嚣\n销\n消\n宵\n淆\n晓\n蠤\n蠥\n蠦\n蠧\n蠨\n蠩\n蠪\n蠫\n蠬\n蠭\n蠮\n蠯\n蠰\n蠱\n蠳\n蠴\n蠵\n蠶\n蠷\n蠸\n蠺\n蠻\n蠽\n蠾\n蠿\n衁\n衂\n衃\n衆\n衇\n衈\n衉\n衊\n衋\n衎\n衏\n衐\n衑\n衒\n術\n衕\n衖\n衘\n衚\n衛\n衜\n衝\n衞\n衟\n衠\n衦\n衧\n衪\n衭\n衯\n衱\n衳\n衴\n衵\n衶\n衸\n衹\n衺\n衻\n衼\n袀\n袃\n袆\n袇\n袉\n袊\n袌\n袎\n袏\n袐\n袑\n袓\n袔\n袕\n袗\n袘\n袙\n袚\n袛\n袝\n袞\n袟\n袠\n袡\n袣\n袥\n袦\n袧\n袨\n袩\n袪\n小\n孝\n校\n肖\n啸\n笑\n效\n楔\n些\n歇\n蝎\n鞋\n协\n挟\n携\n邪\n斜\n胁\n谐\n写\n械\n卸\n蟹\n懈\n泄\n泻\n谢\n屑\n薪\n芯\n锌\n欣\n辛\n新\n忻\n心\n信\n衅\n星\n腥\n猩\n惺\n兴\n刑\n型\n形\n邢\n行\n醒\n幸\n杏\n性\n姓\n兄\n凶\n胸\n匈\n汹\n雄\n熊\n休\n修\n羞\n朽\n嗅\n锈\n秀\n袖\n绣\n墟\n戌\n需\n虚\n嘘\n须\n徐\n许\n蓄\n酗\n叙\n旭\n序\n畜\n恤\n絮\n婿\n绪\n续\n轩\n喧\n宣\n悬\n旋\n玄\n袬\n袮\n袯\n袰\n袲\n袳\n袴\n袵\n袶\n袸\n袹\n袺\n袻\n袽\n袾\n袿\n裀\n裃\n裄\n裇\n裈\n裊\n裋\n裌\n裍\n裏\n裐\n裑\n裓\n裖\n裗\n裚\n裛\n補\n裝\n裞\n裠\n裡\n裦\n裧\n裩\n裪\n裫\n裬\n裭\n裮\n裯\n裲\n裵\n裶\n裷\n裺\n裻\n製\n裿\n褀\n褁\n褃\n褄\n褅\n褆\n複\n褈\n褉\n褋\n褌\n褍\n褎\n褏\n褑\n褔\n褕\n褖\n褗\n褘\n褜\n褝\n褞\n褟\n褠\n褢\n褣\n褤\n褦\n褧\n褨\n褩\n褬\n褭\n褮\n褯\n褱\n褲\n褳\n褵\n褷\n选\n癣\n眩\n绚\n靴\n薛\n学\n穴\n雪\n血\n勋\n熏\n循\n旬\n询\n寻\n驯\n巡\n殉\n汛\n训\n讯\n逊\n迅\n压\n押\n鸦\n鸭\n呀\n丫\n芽\n牙\n蚜\n崖\n衙\n涯\n雅\n哑\n亚\n讶\n焉\n咽\n阉\n烟\n淹\n盐\n严\n研\n蜒\n岩\n延\n言\n颜\n阎\n炎\n沿\n奄\n掩\n眼\n衍\n演\n艳\n堰\n燕\n厌\n砚\n雁\n唁\n彦\n焰\n宴\n谚\n验\n殃\n央\n鸯\n秧\n杨\n扬\n佯\n疡\n羊\n洋\n阳\n氧\n仰\n痒\n养\n样\n漾\n邀\n腰\n妖\n瑶\n褸\n褹\n褺\n褻\n褼\n褽\n褾\n褿\n襀\n襂\n襃\n襅\n襆\n襇\n襈\n襉\n襊\n襋\n襌\n襍\n襎\n襏\n襐\n襑\n襒\n襓\n襔\n襕\n襖\n襗\n襘\n襙\n襚\n襛\n襜\n襝\n襠\n襡\n襢\n襣\n襤\n襥\n襧\n襨\n襩\n襪\n襫\n襬\n襭\n襮\n襯\n襰\n襱\n襲\n襳\n襴\n襵\n襶\n襷\n襸\n襹\n襺\n襼\n襽\n襾\n覀\n覂\n覄\n覅\n覇\n覈\n覉\n覊\n見\n覌\n覍\n覎\n規\n覐\n覑\n覒\n覓\n覔\n覕\n視\n覗\n覘\n覙\n覚\n覛\n覜\n覝\n覞\n覟\n覠\n覡\n摇\n尧\n遥\n窑\n谣\n姚\n咬\n舀\n药\n要\n耀\n椰\n噎\n耶\n爷\n野\n冶\n也\n页\n掖\n业\n叶\n曳\n腋\n夜\n液\n一\n壹\n医\n揖\n铱\n依\n伊\n衣\n颐\n夷\n遗\n移\n仪\n胰\n疑\n沂\n宜\n姨\n彝\n椅\n蚁\n倚\n已\n乙\n矣\n以\n艺\n抑\n易\n邑\n屹\n亿\n役\n臆\n逸\n肄\n疫\n亦\n裔\n意\n毅\n忆\n义\n益\n溢\n诣\n议\n谊\n译\n异\n翼\n翌\n绎\n茵\n荫\n因\n殷\n音\n阴\n姻\n吟\n银\n淫\n寅\n饮\n尹\n引\n隐\n覢\n覣\n覤\n覥\n覦\n覧\n覨\n覩\n親\n覫\n覬\n覭\n覮\n覯\n覰\n覱\n覲\n観\n覴\n覵\n覶\n覷\n覸\n覹\n覺\n覻\n覼\n覽\n覾\n覿\n觀\n觃\n觍\n觓\n觔\n觕\n觗\n觘\n觙\n觛\n觝\n觟\n觠\n觡\n觢\n觤\n觧\n觨\n觩\n觪\n觬\n觭\n觮\n觰\n觱\n觲\n觴\n觵\n觶\n觷\n觸\n觹\n觺\n觻\n觼\n觽\n觾\n觿\n訁\n訂\n訃\n訄\n訅\n訆\n計\n訉\n訊\n訋\n訌\n訍\n討\n訏\n訐\n訑\n訒\n訓\n訔\n訕\n訖\n託\n記\n訙\n訚\n訛\n訜\n訝\n印\n英\n樱\n婴\n鹰\n应\n缨\n莹\n萤\n营\n荧\n蝇\n迎\n赢\n盈\n影\n颖\n硬\n映\n哟\n拥\n佣\n臃\n痈\n庸\n雍\n踊\n蛹\n咏\n泳\n涌\n永\n恿\n勇\n用\n幽\n优\n悠\n忧\n尤\n由\n邮\n铀\n犹\n油\n游\n酉\n有\n友\n右\n佑\n釉\n诱\n又\n幼\n迂\n淤\n于\n盂\n榆\n虞\n愚\n舆\n余\n俞\n逾\n鱼\n愉\n渝\n渔\n隅\n予\n娱\n雨\n与\n屿\n禹\n宇\n语\n羽\n玉\n域\n芋\n郁\n吁\n遇\n喻\n峪\n御\n愈\n欲\n狱\n育\n誉\n訞\n訟\n訠\n訡\n訢\n訣\n訤\n訥\n訦\n訧\n訨\n訩\n訪\n訫\n訬\n設\n訮\n訯\n訰\n許\n訲\n訳\n訴\n訵\n訶\n訷\n訸\n訹\n診\n註\n証\n訽\n訿\n詀\n詁\n詂\n詃\n詄\n詅\n詆\n詇\n詉\n詊\n詋\n詌\n詍\n詎\n詏\n詐\n詑\n詒\n詓\n詔\n評\n詖\n詗\n詘\n詙\n詚\n詛\n詜\n詝\n詞\n詟\n詠\n詡\n詢\n詣\n詤\n詥\n試\n詧\n詨\n詩\n詪\n詫\n詬\n詭\n詮\n詯\n詰\n話\n該\n詳\n詴\n詵\n詶\n詷\n詸\n詺\n詻\n詼\n詽\n詾\n詿\n誀\n浴\n寓\n裕\n预\n豫\n驭\n鸳\n渊\n冤\n元\n垣\n袁\n原\n援\n辕\n园\n员\n圆\n猿\n源\n缘\n远\n苑\n愿\n怨\n院\n曰\n约\n越\n跃\n钥\n岳\n粤\n月\n悦\n阅\n耘\n云\n郧\n匀\n陨\n允\n运\n蕴\n酝\n晕\n韵\n孕\n匝\n砸\n杂\n栽\n哉\n灾\n宰\n载\n再\n在\n咱\n攒\n暂\n赞\n赃\n脏\n葬\n遭\n糟\n凿\n藻\n枣\n早\n澡\n蚤\n躁\n噪\n造\n皂\n灶\n燥\n责\n择\n则\n泽\n贼\n怎\n增\n憎\n曾\n赠\n扎\n喳\n渣\n札\n轧\n誁\n誂\n誃\n誄\n誅\n誆\n誇\n誈\n誋\n誌\n認\n誎\n誏\n誐\n誑\n誒\n誔\n誕\n誖\n誗\n誘\n誙\n誚\n誛\n誜\n誝\n語\n誟\n誠\n誡\n誢\n誣\n誤\n誥\n誦\n誧\n誨\n誩\n說\n誫\n説\n読\n誮\n誯\n誰\n誱\n課\n誳\n誴\n誵\n誶\n誷\n誸\n誹\n誺\n誻\n誼\n誽\n誾\n調\n諀\n諁\n諂\n諃\n諄\n諅\n諆\n談\n諈\n諉\n諊\n請\n諌\n諍\n諎\n諏\n諐\n諑\n諒\n諓\n諔\n諕\n論\n諗\n諘\n諙\n諚\n諛\n諜\n諝\n諞\n諟\n諠\n諡\n諢\n諣\n铡\n闸\n眨\n栅\n榨\n咋\n乍\n炸\n诈\n摘\n斋\n宅\n窄\n债\n寨\n瞻\n毡\n詹\n粘\n沾\n盏\n斩\n辗\n崭\n展\n蘸\n栈\n占\n战\n站\n湛\n绽\n樟\n章\n彰\n漳\n张\n掌\n涨\n杖\n丈\n帐\n账\n仗\n胀\n瘴\n障\n招\n昭\n找\n沼\n赵\n照\n罩\n兆\n肇\n召\n遮\n折\n哲\n蛰\n辙\n者\n锗\n蔗\n这\n浙\n珍\n斟\n真\n甄\n砧\n臻\n贞\n针\n侦\n枕\n疹\n诊\n震\n振\n镇\n阵\n蒸\n挣\n睁\n征\n狰\n争\n怔\n整\n拯\n正\n政\n諤\n諥\n諦\n諧\n諨\n諩\n諪\n諫\n諬\n諭\n諮\n諯\n諰\n諱\n諲\n諳\n諴\n諵\n諶\n諷\n諸\n諹\n諺\n諻\n諼\n諽\n諾\n諿\n謀\n謁\n謂\n謃\n謄\n謅\n謆\n謈\n謉\n謊\n謋\n謌\n謍\n謎\n謏\n謐\n謑\n謒\n謓\n謔\n謕\n謖\n謗\n謘\n謙\n謚\n講\n謜\n謝\n謞\n謟\n謠\n謡\n謢\n謣\n謤\n謥\n謧\n謨\n謩\n謪\n謫\n謬\n謭\n謮\n謯\n謰\n謱\n謲\n謳\n謴\n謵\n謶\n謷\n謸\n謹\n謺\n謻\n謼\n謽\n謾\n謿\n譀\n譁\n譂\n譃\n譄\n譅\n帧\n症\n郑\n证\n芝\n枝\n支\n吱\n蜘\n知\n肢\n脂\n汁\n之\n织\n职\n直\n植\n殖\n执\n值\n侄\n址\n指\n止\n趾\n只\n旨\n纸\n志\n挚\n掷\n至\n致\n置\n帜\n峙\n制\n智\n秩\n稚\n质\n炙\n痔\n滞\n治\n窒\n中\n盅\n忠\n钟\n衷\n终\n种\n肿\n重\n仲\n众\n舟\n周\n州\n洲\n诌\n粥\n轴\n肘\n帚\n咒\n皱\n宙\n昼\n骤\n珠\n株\n蛛\n朱\n猪\n诸\n诛\n逐\n竹\n烛\n煮\n拄\n瞩\n嘱\n主\n著\n柱\n助\n蛀\n贮\n铸\n筑\n譆\n譇\n譈\n證\n譊\n譋\n譌\n譍\n譎\n譏\n譐\n譑\n譒\n譓\n譔\n譕\n譖\n譗\n識\n譙\n譚\n譛\n譜\n譝\n譞\n譟\n譠\n譡\n譢\n譣\n譤\n譥\n譧\n譨\n譩\n譪\n譫\n譭\n譮\n譯\n議\n譱\n譲\n譳\n譴\n譵\n譶\n護\n譸\n譹\n譺\n譻\n譼\n譽\n譾\n譿\n讀\n讁\n讂\n讃\n讄\n讅\n讆\n讇\n讈\n讉\n變\n讋\n讌\n讍\n讎\n讏\n讐\n讑\n讒\n讓\n讔\n讕\n讖\n讗\n讘\n讙\n讚\n讛\n讜\n讝\n讞\n讟\n讬\n讱\n讻\n诇\n诐\n诪\n谉\n谞\n住\n注\n祝\n驻\n抓\n爪\n拽\n专\n砖\n转\n撰\n赚\n篆\n桩\n庄\n装\n妆\n撞\n壮\n状\n椎\n锥\n追\n赘\n坠\n缀\n谆\n准\n捉\n拙\n卓\n桌\n琢\n茁\n酌\n啄\n着\n灼\n浊\n兹\n咨\n资\n姿\n滋\n淄\n孜\n紫\n仔\n籽\n滓\n子\n自\n渍\n字\n鬃\n棕\n踪\n宗\n综\n总\n纵\n邹\n走\n奏\n揍\n租\n足\n卒\n族\n祖\n诅\n阻\n组\n钻\n纂\n嘴\n醉\n最\n罪\n尊\n遵\n昨\n左\n佐\n柞\n做\n作\n坐\n座\n\n\n\n\n\n谸\n谹\n谺\n谻\n谼\n谽\n谾\n谿\n豀\n豂\n豃\n豄\n豅\n豈\n豊\n豋\n豍\n豎\n豏\n豐\n豑\n豒\n豓\n豔\n豖\n豗\n豘\n豙\n豛\n豜\n豝\n豞\n豟\n豠\n豣\n豤\n豥\n豦\n豧\n豨\n豩\n豬\n豭\n豮\n豯\n豰\n豱\n豲\n豴\n豵\n豶\n豷\n豻\n豼\n豽\n豾\n豿\n貀\n貁\n貃\n貄\n貆\n貇\n貈\n貋\n貍\n貎\n貏\n貐\n貑\n貒\n貓\n貕\n貖\n貗\n貙\n貚\n貛\n貜\n貝\n貞\n貟\n負\n財\n貢\n貣\n貤\n貥\n貦\n貧\n貨\n販\n貪\n貫\n責\n貭\n亍\n丌\n兀\n丐\n廿\n卅\n丕\n亘\n丞\n鬲\n孬\n噩\n丨\n禺\n丿\n匕\n乇\n夭\n爻\n卮\n氐\n囟\n胤\n馗\n毓\n睾\n鼗\n丶\n亟\n鼐\n乜\n乩\n亓\n芈\n孛\n啬\n嘏\n仄\n厍\n厝\n厣\n厥\n厮\n靥\n赝\n匚\n叵\n匦\n匮\n匾\n赜\n卦\n卣\n刂\n刈\n刎\n刭\n刳\n刿\n剀\n剌\n剞\n剡\n剜\n蒯\n剽\n劂\n劁\n劐\n劓\n冂\n罔\n亻\n仃\n仉\n仂\n仨\n仡\n仫\n仞\n伛\n仳\n伢\n佤\n仵\n伥\n伧\n伉\n伫\n佞\n佧\n攸\n佚\n佝\n貮\n貯\n貰\n貱\n貲\n貳\n貴\n貵\n貶\n買\n貸\n貹\n貺\n費\n貼\n貽\n貾\n貿\n賀\n賁\n賂\n賃\n賄\n賅\n賆\n資\n賈\n賉\n賊\n賋\n賌\n賍\n賎\n賏\n賐\n賑\n賒\n賓\n賔\n賕\n賖\n賗\n賘\n賙\n賚\n賛\n賜\n賝\n賞\n賟\n賠\n賡\n賢\n賣\n賤\n賥\n賦\n賧\n賨\n賩\n質\n賫\n賬\n賭\n賮\n賯\n賰\n賱\n賲\n賳\n賴\n賵\n賶\n賷\n賸\n賹\n賺\n賻\n購\n賽\n賾\n賿\n贀\n贁\n贂\n贃\n贄\n贅\n贆\n贇\n贈\n贉\n贊\n贋\n贌\n贍\n佟\n佗\n伲\n伽\n佶\n佴\n侑\n侉\n侃\n侏\n佾\n佻\n侪\n佼\n侬\n侔\n俦\n俨\n俪\n俅\n俚\n俣\n俜\n俑\n俟\n俸\n倩\n偌\n俳\n倬\n倏\n倮\n倭\n俾\n倜\n倌\n倥\n倨\n偾\n偃\n偕\n偈\n偎\n偬\n偻\n傥\n傧\n傩\n傺\n僖\n儆\n僭\n僬\n僦\n僮\n儇\n儋\n仝\n氽\n佘\n佥\n俎\n龠\n汆\n籴\n兮\n巽\n黉\n馘\n冁\n夔\n勹\n匍\n訇\n匐\n凫\n夙\n兕\n亠\n兖\n亳\n衮\n袤\n亵\n脔\n裒\n禀\n嬴\n蠃\n羸\n冫\n冱\n冽\n冼\n贎\n贏\n贐\n贑\n贒\n贓\n贔\n贕\n贖\n贗\n贘\n贙\n贚\n贛\n贜\n贠\n赑\n赒\n赗\n赟\n赥\n赨\n赩\n赪\n赬\n赮\n赯\n赱\n赲\n赸\n赹\n赺\n赻\n赼\n赽\n赾\n赿\n趀\n趂\n趃\n趆\n趇\n趈\n趉\n趌\n趍\n趎\n趏\n趐\n趒\n趓\n趕\n趖\n趗\n趘\n趙\n趚\n趛\n趜\n趝\n趞\n趠\n趡\n趢\n趤\n趥\n趦\n趧\n趨\n趩\n趪\n趫\n趬\n趭\n趮\n趯\n趰\n趲\n趶\n趷\n趹\n趻\n趽\n跀\n跁\n跂\n跅\n跇\n跈\n跉\n跊\n跍\n跐\n跒\n跓\n跔\n凇\n冖\n冢\n冥\n讠\n讦\n讧\n讪\n讴\n讵\n讷\n诂\n诃\n诋\n诏\n诎\n诒\n诓\n诔\n诖\n诘\n诙\n诜\n诟\n诠\n诤\n诨\n诩\n诮\n诰\n诳\n诶\n诹\n诼\n诿\n谀\n谂\n谄\n谇\n谌\n谏\n谑\n谒\n谔\n谕\n谖\n谙\n谛\n谘\n谝\n谟\n谠\n谡\n谥\n谧\n谪\n谫\n谮\n谯\n谲\n谳\n谵\n谶\n卩\n卺\n阝\n阢\n阡\n阱\n阪\n阽\n阼\n陂\n陉\n陔\n陟\n陧\n陬\n陲\n陴\n隈\n隍\n隗\n隰\n邗\n邛\n邝\n邙\n邬\n邡\n邴\n邳\n邶\n邺\n跕\n跘\n跙\n跜\n跠\n跡\n跢\n跥\n跦\n跧\n跩\n跭\n跮\n跰\n跱\n跲\n跴\n跶\n跼\n跾\n跿\n踀\n踁\n踂\n踃\n踄\n踆\n踇\n踈\n踋\n踍\n踎\n踐\n踑\n踒\n踓\n踕\n踖\n踗\n踘\n踙\n踚\n踛\n踜\n踠\n踡\n踤\n踥\n踦\n踧\n踨\n踫\n踭\n踰\n踲\n踳\n踴\n踶\n踷\n踸\n踻\n踼\n踾\n踿\n蹃\n蹅\n蹆\n蹌\n蹍\n蹎\n蹏\n蹐\n蹓\n蹔\n蹕\n蹖\n蹗\n蹘\n蹚\n蹛\n蹜\n蹝\n蹞\n蹟\n蹠\n蹡\n蹢\n蹣\n蹤\n蹥\n蹧\n蹨\n蹪\n蹫\n蹮\n蹱\n邸\n邰\n郏\n郅\n邾\n郐\n郄\n郇\n郓\n郦\n郢\n郜\n郗\n郛\n郫\n郯\n郾\n鄄\n鄢\n鄞\n鄣\n鄱\n鄯\n鄹\n酃\n酆\n刍\n奂\n劢\n劬\n劭\n劾\n哿\n勐\n勖\n勰\n叟\n燮\n矍\n廴\n凵\n凼\n鬯\n厶\n弁\n畚\n巯\n坌\n垩\n垡\n塾\n墼\n壅\n壑\n圩\n圬\n圪\n圳\n圹\n圮\n圯\n坜\n圻\n坂\n坩\n垅\n坫\n垆\n坼\n坻\n坨\n坭\n坶\n坳\n垭\n垤\n垌\n垲\n埏\n垧\n垴\n垓\n垠\n埕\n埘\n埚\n埙\n埒\n垸\n埴\n埯\n埸\n埤\n埝\n蹳\n蹵\n蹷\n蹸\n蹹\n蹺\n蹻\n蹽\n蹾\n躀\n躂\n躃\n躄\n躆\n躈\n躉\n躊\n躋\n躌\n躍\n躎\n躑\n躒\n躓\n躕\n躖\n躗\n躘\n躙\n躚\n躛\n躝\n躟\n躠\n躡\n躢\n躣\n躤\n躥\n躦\n躧\n躨\n躩\n躪\n躭\n躮\n躰\n躱\n躳\n躴\n躵\n躶\n躷\n躸\n躹\n躻\n躼\n躽\n躾\n躿\n軀\n軁\n軂\n軃\n軄\n軅\n軆\n軇\n軈\n軉\n車\n軋\n軌\n軍\n軏\n軐\n軑\n軒\n軓\n軔\n軕\n軖\n軗\n軘\n軙\n軚\n軛\n軜\n軝\n軞\n軟\n軠\n軡\n転\n軣\n軤\n堋\n堍\n埽\n埭\n堀\n堞\n堙\n塄\n堠\n塥\n塬\n墁\n墉\n墚\n墀\n馨\n鼙\n懿\n艹\n艽\n艿\n芏\n芊\n芨\n芄\n芎\n芑\n芗\n芙\n芫\n芸\n芾\n芰\n苈\n苊\n苣\n芘\n芷\n芮\n苋\n苌\n苁\n芩\n芴\n芡\n芪\n芟\n苄\n苎\n芤\n苡\n茉\n苷\n苤\n茏\n茇\n苜\n苴\n苒\n苘\n茌\n苻\n苓\n茑\n茚\n茆\n茔\n茕\n苠\n苕\n茜\n荑\n荛\n荜\n茈\n莒\n茼\n茴\n茱\n莛\n荞\n茯\n荏\n荇\n荃\n荟\n荀\n茗\n荠\n茭\n茺\n茳\n荦\n荥\n軥\n軦\n軧\n軨\n軩\n軪\n軫\n軬\n軭\n軮\n軯\n軰\n軱\n軲\n軳\n軴\n軵\n軶\n軷\n軸\n軹\n軺\n軻\n軼\n軽\n軾\n軿\n輀\n輁\n輂\n較\n輄\n輅\n輆\n輇\n輈\n載\n輊\n輋\n輌\n輍\n輎\n輏\n輐\n輑\n輒\n輓\n輔\n輕\n輖\n輗\n輘\n輙\n輚\n輛\n輜\n輝\n輞\n輟\n輠\n輡\n輢\n輣\n輤\n輥\n輦\n輧\n輨\n輩\n輪\n輫\n輬\n輭\n輮\n輯\n輰\n輱\n輲\n輳\n輴\n輵\n輶\n輷\n輸\n輹\n輺\n輻\n輼\n輽\n輾\n輿\n轀\n轁\n轂\n轃\n轄\n荨\n茛\n荩\n荬\n荪\n荭\n荮\n莰\n荸\n莳\n莴\n莠\n莪\n莓\n莜\n莅\n荼\n莶\n莩\n荽\n莸\n荻\n莘\n莞\n莨\n莺\n莼\n菁\n萁\n菥\n菘\n堇\n萘\n萋\n菝\n菽\n菖\n萜\n萸\n萑\n萆\n菔\n菟\n萏\n萃\n菸\n菹\n菪\n菅\n菀\n萦\n菰\n菡\n葜\n葑\n葚\n葙\n葳\n蒇\n蒈\n葺\n蒉\n葸\n萼\n葆\n葩\n葶\n蒌\n蒎\n萱\n葭\n蓁\n蓍\n蓐\n蓦\n蒽\n蓓\n蓊\n蒿\n蒺\n蓠\n蒡\n蒹\n蒴\n蒗\n蓥\n蓣\n蔌\n甍\n蔸\n蓰\n蔹\n蔟\n蔺\n轅\n轆\n轇\n轈\n轉\n轊\n轋\n轌\n轍\n轎\n轏\n轐\n轑\n轒\n轓\n轔\n轕\n轖\n轗\n轘\n轙\n轚\n轛\n轜\n轝\n轞\n轟\n轠\n轡\n轢\n轣\n轤\n轥\n轪\n辀\n辌\n辒\n辝\n辠\n辡\n辢\n辤\n辥\n辦\n辧\n辪\n辬\n辭\n辮\n辯\n農\n辳\n辴\n辵\n辷\n辸\n辺\n辻\n込\n辿\n迀\n迃\n迆\n迉\n迊\n迋\n迌\n迍\n迏\n迒\n迖\n迗\n迚\n迠\n迡\n迣\n迧\n迬\n迯\n迱\n迲\n迴\n迵\n迶\n迺\n迻\n迼\n迾\n迿\n逇\n逈\n逌\n逎\n逓\n逕\n逘\n蕖\n蔻\n蓿\n蓼\n蕙\n蕈\n蕨\n蕤\n蕞\n蕺\n瞢\n蕃\n蕲\n蕻\n薤\n薨\n薇\n薏\n蕹\n薮\n薜\n薅\n薹\n薷\n薰\n藓\n藁\n藜\n藿\n蘧\n蘅\n蘩\n蘖\n蘼\n廾\n弈\n夼\n奁\n耷\n奕\n奚\n奘\n匏\n尢\n尥\n尬\n尴\n扌\n扪\n抟\n抻\n拊\n拚\n拗\n拮\n挢\n拶\n挹\n捋\n捃\n掭\n揶\n捱\n捺\n掎\n掴\n捭\n掬\n掊\n捩\n掮\n掼\n揲\n揸\n揠\n揿\n揄\n揞\n揎\n摒\n揆\n掾\n摅\n摁\n搋\n搛\n搠\n搌\n搦\n搡\n摞\n撄\n摭\n撖\n這\n逜\n連\n逤\n逥\n逧\n逨\n逩\n逪\n逫\n逬\n逰\n週\n進\n逳\n逴\n逷\n逹\n逺\n逽\n逿\n遀\n遃\n遅\n遆\n遈\n遉\n遊\n運\n遌\n過\n達\n違\n遖\n遙\n遚\n遜\n遝\n遞\n遟\n遠\n遡\n遤\n遦\n遧\n適\n遪\n遫\n遬\n遯\n遰\n遱\n遲\n遳\n遶\n遷\n選\n遹\n遺\n遻\n遼\n遾\n邁\n還\n邅\n邆\n邇\n邉\n邊\n邌\n邍\n邎\n邏\n邐\n邒\n邔\n邖\n邘\n邚\n邜\n邞\n邟\n邠\n邤\n邥\n邧\n邨\n邩\n邫\n邭\n邲\n邷\n邼\n邽\n邿\n郀\n摺\n撷\n撸\n撙\n撺\n擀\n擐\n擗\n擤\n擢\n攉\n攥\n攮\n弋\n忒\n甙\n弑\n卟\n叱\n叽\n叩\n叨\n叻\n吒\n吖\n吆\n呋\n呒\n呓\n呔\n呖\n呃\n吡\n呗\n呙\n吣\n吲\n咂\n咔\n呷\n呱\n呤\n咚\n咛\n咄\n呶\n呦\n咝\n哐\n咭\n哂\n咴\n哒\n咧\n咦\n哓\n哔\n呲\n咣\n哕\n咻\n咿\n哌\n哙\n哚\n哜\n咩\n咪\n咤\n哝\n哏\n哞\n唛\n哧\n唠\n哽\n唔\n哳\n唢\n唣\n唏\n唑\n唧\n唪\n啧\n喏\n喵\n啉\n啭\n啁\n啕\n唿\n啐\n唼\n郂\n郃\n郆\n郈\n郉\n郋\n郌\n郍\n郒\n郔\n郕\n郖\n郘\n郙\n郚\n郞\n郟\n郠\n郣\n郤\n郥\n郩\n郪\n郬\n郮\n郰\n郱\n郲\n郳\n郵\n郶\n郷\n郹\n郺\n郻\n郼\n郿\n鄀\n鄁\n鄃\n鄅\n鄆\n鄇\n鄈\n鄉\n鄊\n鄋\n鄌\n鄍\n鄎\n鄏\n鄐\n鄑\n鄒\n鄓\n鄔\n鄕\n鄖\n鄗\n鄘\n鄚\n鄛\n鄜\n鄝\n鄟\n鄠\n鄡\n鄤\n鄥\n鄦\n鄧\n鄨\n鄩\n鄪\n鄫\n鄬\n鄭\n鄮\n鄰\n鄲\n鄳\n鄴\n鄵\n鄶\n鄷\n鄸\n鄺\n鄻\n鄼\n鄽\n鄾\n鄿\n酀\n酁\n酂\n酄\n唷\n啖\n啵\n啶\n啷\n唳\n唰\n啜\n喋\n嗒\n喃\n喱\n喹\n喈\n喁\n喟\n啾\n嗖\n喑\n啻\n嗟\n喽\n喾\n喔\n喙\n嗪\n嗷\n嗉\n嘟\n嗑\n嗫\n嗬\n嗔\n嗦\n嗝\n嗄\n嗯\n嗥\n嗲\n嗳\n嗌\n嗍\n嗨\n嗵\n嗤\n辔\n嘞\n嘈\n嘌\n嘁\n嘤\n嘣\n嗾\n嘀\n嘧\n嘭\n噘\n嘹\n噗\n嘬\n噍\n噢\n噙\n噜\n噌\n噔\n嚆\n噤\n噱\n噫\n噻\n噼\n嚅\n嚓\n嚯\n囔\n囗\n囝\n囡\n囵\n囫\n囹\n囿\n圄\n圊\n圉\n圜\n帏\n帙\n帔\n帑\n帱\n帻\n帼\n酅\n酇\n酈\n酑\n酓\n酔\n酕\n酖\n酘\n酙\n酛\n酜\n酟\n酠\n酦\n酧\n酨\n酫\n酭\n酳\n酺\n酻\n酼\n醀\n醁\n醂\n醃\n醄\n醆\n醈\n醊\n醎\n醏\n醓\n醔\n醕\n醖\n醗\n醘\n醙\n醜\n醝\n醞\n醟\n醠\n醡\n醤\n醥\n醦\n醧\n醨\n醩\n醫\n醬\n醰\n醱\n醲\n醳\n醶\n醷\n醸\n醹\n醻\n醼\n醽\n醾\n醿\n釀\n釁\n釂\n釃\n釄\n釅\n釆\n釈\n釋\n釐\n釒\n釓\n釔\n釕\n釖\n釗\n釘\n釙\n釚\n釛\n針\n釞\n釟\n釠\n釡\n釢\n釣\n釤\n釥\n帷\n幄\n幔\n幛\n幞\n幡\n岌\n屺\n岍\n岐\n岖\n岈\n岘\n岙\n岑\n岚\n岜\n岵\n岢\n岽\n岬\n岫\n岱\n岣\n峁\n岷\n峄\n峒\n峤\n峋\n峥\n崂\n崃\n崧\n崦\n崮\n崤\n崞\n崆\n崛\n嵘\n崾\n崴\n崽\n嵬\n嵛\n嵯\n嵝\n嵫\n嵋\n嵊\n嵩\n嵴\n嶂\n嶙\n嶝\n豳\n嶷\n巅\n彳\n彷\n徂\n徇\n徉\n後\n徕\n徙\n徜\n徨\n徭\n徵\n徼\n衢\n彡\n犭\n犰\n犴\n犷\n犸\n狃\n狁\n狎\n狍\n狒\n狨\n狯\n狩\n狲\n狴\n狷\n猁\n狳\n猃\n狺\n釦\n釧\n釨\n釩\n釪\n釫\n釬\n釭\n釮\n釯\n釰\n釱\n釲\n釳\n釴\n釵\n釶\n釷\n釸\n釹\n釺\n釻\n釼\n釽\n釾\n釿\n鈀\n鈁\n鈂\n鈃\n鈄\n鈅\n鈆\n鈇\n鈈\n鈉\n鈊\n鈋\n鈌\n鈍\n鈎\n鈏\n鈐\n鈑\n鈒\n鈓\n鈔\n鈕\n鈖\n鈗\n鈘\n鈙\n鈚\n鈛\n鈜\n鈝\n鈞\n鈟\n鈠\n鈡\n鈢\n鈣\n鈤\n鈥\n鈦\n鈧\n鈨\n鈩\n鈪\n鈫\n鈬\n鈭\n鈮\n鈯\n鈰\n鈱\n鈲\n鈳\n鈴\n鈵\n鈶\n鈷\n鈸\n鈹\n鈺\n鈻\n鈼\n鈽\n鈾\n鈿\n鉀\n鉁\n鉂\n鉃\n鉄\n鉅\n狻\n猗\n猓\n猡\n猊\n猞\n猝\n猕\n猢\n猹\n猥\n猬\n猸\n猱\n獐\n獍\n獗\n獠\n獬\n獯\n獾\n舛\n夥\n飧\n夤\n夂\n饣\n饧\n饨\n饩\n饪\n饫\n饬\n饴\n饷\n饽\n馀\n馄\n馇\n馊\n馍\n馐\n馑\n馓\n馔\n馕\n庀\n庑\n庋\n庖\n庥\n庠\n庹\n庵\n庾\n庳\n赓\n廒\n廑\n廛\n廨\n廪\n膺\n忄\n忉\n忖\n忏\n怃\n忮\n怄\n忡\n忤\n忾\n怅\n怆\n忪\n忭\n忸\n怙\n怵\n怦\n怛\n怏\n怍\n怩\n怫\n怊\n怿\n怡\n恸\n恹\n恻\n恺\n恂\n鉆\n鉇\n鉈\n鉉\n鉊\n鉋\n鉌\n鉍\n鉎\n鉏\n鉐\n鉑\n鉒\n鉓\n鉔\n鉕\n鉖\n鉗\n鉘\n鉙\n鉚\n鉛\n鉜\n鉝\n鉞\n鉟\n鉠\n鉡\n鉢\n鉣\n鉤\n鉥\n鉦\n鉧\n鉨\n鉩\n鉪\n鉫\n鉬\n鉭\n鉮\n鉯\n鉰\n鉱\n鉲\n鉳\n鉵\n鉶\n鉷\n鉸\n鉹\n鉺\n鉻\n鉼\n鉽\n鉾\n鉿\n銀\n銁\n銂\n銃\n銄\n銅\n銆\n銇\n銈\n銉\n銊\n銋\n銌\n銍\n銏\n銐\n銑\n銒\n銓\n銔\n銕\n銖\n銗\n銘\n銙\n銚\n銛\n銜\n銝\n銞\n銟\n銠\n銡\n銢\n銣\n銤\n銥\n銦\n銧\n恪\n恽\n悖\n悚\n悭\n悝\n悃\n悒\n悌\n悛\n惬\n悻\n悱\n惝\n惘\n惆\n惚\n悴\n愠\n愦\n愕\n愣\n惴\n愀\n愎\n愫\n慊\n慵\n憬\n憔\n憧\n憷\n懔\n懵\n忝\n隳\n闩\n闫\n闱\n闳\n闵\n闶\n闼\n闾\n阃\n阄\n阆\n阈\n阊\n阋\n阌\n阍\n阏\n阒\n阕\n阖\n阗\n阙\n阚\n丬\n爿\n戕\n氵\n汔\n汜\n汊\n沣\n沅\n沐\n沔\n沌\n汨\n汩\n汴\n汶\n沆\n沩\n泐\n泔\n沭\n泷\n泸\n泱\n泗\n沲\n泠\n泖\n泺\n泫\n泮\n沱\n泓\n泯\n泾\n銨\n銩\n銪\n銫\n銬\n銭\n銯\n銰\n銱\n銲\n銳\n銴\n銵\n銶\n銷\n銸\n銹\n銺\n銻\n銼\n銽\n銾\n銿\n鋀\n鋁\n鋂\n鋃\n鋄\n鋅\n鋆\n鋇\n鋉\n鋊\n鋋\n鋌\n鋍\n鋎\n鋏\n鋐\n鋑\n鋒\n鋓\n鋔\n鋕\n鋖\n鋗\n鋘\n鋙\n鋚\n鋛\n鋜\n鋝\n鋞\n鋟\n鋠\n鋡\n鋢\n鋣\n鋤\n鋥\n鋦\n鋧\n鋨\n鋩\n鋪\n鋫\n鋬\n鋭\n鋮\n鋯\n鋰\n鋱\n鋲\n鋳\n鋴\n鋵\n鋶\n鋷\n鋸\n鋹\n鋺\n鋻\n鋼\n鋽\n鋾\n鋿\n錀\n錁\n錂\n錃\n錄\n錅\n錆\n錇\n錈\n錉\n洹\n洧\n洌\n浃\n浈\n洇\n洄\n洙\n洎\n洫\n浍\n洮\n洵\n洚\n浏\n浒\n浔\n洳\n涑\n浯\n涞\n涠\n浞\n涓\n涔\n浜\n浠\n浼\n浣\n渚\n淇\n淅\n淞\n渎\n涿\n淠\n渑\n淦\n淝\n淙\n渖\n涫\n渌\n涮\n渫\n湮\n湎\n湫\n溲\n湟\n溆\n湓\n湔\n渲\n渥\n湄\n滟\n溱\n溘\n滠\n漭\n滢\n溥\n溧\n溽\n溻\n溷\n滗\n溴\n滏\n溏\n滂\n溟\n潢\n潆\n潇\n漤\n漕\n滹\n漯\n漶\n潋\n潴\n漪\n漉\n漩\n澉\n澍\n澌\n潸\n潲\n潼\n潺\n濑\n錊\n錋\n錌\n錍\n錎\n錏\n錐\n錑\n錒\n錓\n錔\n錕\n錖\n錗\n錘\n錙\n錚\n錛\n錜\n錝\n錞\n錟\n錠\n錡\n錢\n錣\n錤\n錥\n錦\n錧\n錨\n錩\n錪\n錫\n錬\n錭\n錮\n錯\n錰\n錱\n録\n錳\n錴\n錵\n錶\n錷\n錸\n錹\n錺\n錻\n錼\n錽\n錿\n鍀\n鍁\n鍂\n鍃\n鍄\n鍅\n鍆\n鍇\n鍈\n鍉\n鍊\n鍋\n鍌\n鍍\n鍎\n鍏\n鍐\n鍑\n鍒\n鍓\n鍔\n鍕\n鍖\n鍗\n鍘\n鍙\n鍚\n鍛\n鍜\n鍝\n鍞\n鍟\n鍠\n鍡\n鍢\n鍣\n鍤\n鍥\n鍦\n鍧\n鍨\n鍩\n鍫\n濉\n澧\n澹\n澶\n濂\n濡\n濮\n濞\n濠\n濯\n瀚\n瀣\n瀛\n瀹\n瀵\n灏\n灞\n宀\n宄\n宕\n宓\n宥\n宸\n甯\n骞\n搴\n寤\n寮\n褰\n寰\n蹇\n謇\n辶\n迓\n迕\n迥\n迮\n迤\n迩\n迦\n迳\n迨\n逅\n逄\n逋\n逦\n逑\n逍\n逖\n逡\n逵\n逶\n逭\n逯\n遄\n遑\n遒\n遐\n遨\n遘\n遢\n遛\n暹\n遴\n遽\n邂\n邈\n邃\n邋\n彐\n彗\n彖\n彘\n尻\n咫\n屐\n屙\n孱\n屣\n屦\n羼\n弪\n弩\n弭\n艴\n弼\n鬻\n屮\n妁\n妃\n妍\n妩\n妪\n妣\n鍬\n鍭\n鍮\n鍯\n鍰\n鍱\n鍲\n鍳\n鍴\n鍵\n鍶\n鍷\n鍸\n鍹\n鍺\n鍻\n鍼\n鍽\n鍾\n鍿\n鎀\n鎁\n鎂\n鎃\n鎄\n鎅\n鎆\n鎇\n鎈\n鎉\n鎊\n鎋\n鎌\n鎍\n鎎\n鎐\n鎑\n鎒\n鎓\n鎔\n鎕\n鎖\n鎗\n鎘\n鎙\n鎚\n鎛\n鎜\n鎝\n鎞\n鎟\n鎠\n鎡\n鎢\n鎣\n鎤\n鎥\n鎦\n鎧\n鎨\n鎩\n鎪\n鎫\n鎬\n鎭\n鎮\n鎯\n鎰\n鎱\n鎲\n鎳\n鎴\n鎵\n鎶\n鎷\n鎸\n鎹\n鎺\n鎻\n鎼\n鎽\n鎾\n鎿\n鏀\n鏁\n鏂\n鏃\n鏄\n鏅\n鏆\n鏇\n鏈\n鏉\n鏋\n鏌\n鏍\n妗\n姊\n妫\n妞\n妤\n姒\n妲\n妯\n姗\n妾\n娅\n娆\n姝\n娈\n姣\n姘\n姹\n娌\n娉\n娲\n娴\n娑\n娣\n娓\n婀\n婧\n婊\n婕\n娼\n婢\n婵\n胬\n媪\n媛\n婷\n婺\n媾\n嫫\n媲\n嫒\n嫔\n媸\n嫠\n嫣\n嫱\n嫖\n嫦\n嫘\n嫜\n嬉\n嬗\n嬖\n嬲\n嬷\n孀\n尕\n尜\n孚\n孥\n孳\n孑\n孓\n孢\n驵\n驷\n驸\n驺\n驿\n驽\n骀\n骁\n骅\n骈\n骊\n骐\n骒\n骓\n骖\n骘\n骛\n骜\n骝\n骟\n骠\n骢\n骣\n骥\n骧\n纟\n纡\n纣\n纥\n纨\n纩\n鏎\n鏏\n鏐\n鏑\n鏒\n鏓\n鏔\n鏕\n鏗\n鏘\n鏙\n鏚\n鏛\n鏜\n鏝\n鏞\n鏟\n鏠\n鏡\n鏢\n鏣\n鏤\n鏥\n鏦\n鏧\n鏨\n鏩\n鏪\n鏫\n鏬\n鏭\n鏮\n鏯\n鏰\n鏱\n鏲\n鏳\n鏴\n鏵\n鏶\n鏷\n鏸\n鏹\n鏺\n鏻\n鏼\n鏽\n鏾\n鏿\n鐀\n鐁\n鐂\n鐃\n鐄\n鐅\n鐆\n鐇\n鐈\n鐉\n鐊\n鐋\n鐌\n鐍\n鐎\n鐏\n鐐\n鐑\n鐒\n鐓\n鐔\n鐕\n鐖\n鐗\n鐘\n鐙\n鐚\n鐛\n鐜\n鐝\n鐞\n鐟\n鐠\n鐡\n鐢\n鐣\n鐤\n鐥\n鐦\n鐧\n鐨\n鐩\n鐪\n鐫\n鐬\n鐭\n鐮\n纭\n纰\n纾\n绀\n绁\n绂\n绉\n绋\n绌\n绐\n绔\n绗\n绛\n绠\n绡\n绨\n绫\n绮\n绯\n绱\n绲\n缍\n绶\n绺\n绻\n绾\n缁\n缂\n缃\n缇\n缈\n缋\n缌\n缏\n缑\n缒\n缗\n缙\n缜\n缛\n缟\n缡\n缢\n缣\n缤\n缥\n缦\n缧\n缪\n缫\n缬\n缭\n缯\n缰\n缱\n缲\n缳\n缵\n幺\n畿\n巛\n甾\n邕\n玎\n玑\n玮\n玢\n玟\n珏\n珂\n珑\n玷\n玳\n珀\n珉\n珈\n珥\n珙\n顼\n琊\n珩\n珧\n珞\n玺\n珲\n琏\n琪\n瑛\n琦\n琥\n琨\n琰\n琮\n琬\n鐯\n鐰\n鐱\n鐲\n鐳\n鐴\n鐵\n鐶\n鐷\n鐸\n鐹\n鐺\n鐻\n鐼\n鐽\n鐿\n鑀\n鑁\n鑂\n鑃\n鑄\n鑅\n鑆\n鑇\n鑈\n鑉\n鑊\n鑋\n鑌\n鑍\n鑎\n鑏\n鑐\n鑑\n鑒\n鑓\n鑔\n鑕\n鑖\n鑗\n鑘\n鑙\n鑚\n鑛\n鑜\n鑝\n鑞\n鑟\n鑠\n鑡\n鑢\n鑣\n鑤\n鑥\n鑦\n鑧\n鑨\n鑩\n鑪\n鑬\n鑭\n鑮\n鑯\n鑰\n鑱\n鑲\n鑳\n鑴\n鑵\n鑶\n鑷\n鑸\n鑹\n鑺\n鑻\n鑼\n鑽\n鑾\n鑿\n钀\n钁\n钂\n钃\n钄\n钑\n钖\n钘\n铇\n铏\n铓\n铔\n铚\n铦\n铻\n锜\n锠\n琛\n琚\n瑁\n瑜\n瑗\n瑕\n瑙\n瑷\n瑭\n瑾\n璜\n璎\n璀\n璁\n璇\n璋\n璞\n璨\n璩\n璐\n璧\n瓒\n璺\n韪\n韫\n韬\n杌\n杓\n杞\n杈\n杩\n枥\n枇\n杪\n杳\n枘\n枧\n杵\n枨\n枞\n枭\n枋\n杷\n杼\n柰\n栉\n柘\n栊\n柩\n枰\n栌\n柙\n枵\n柚\n枳\n柝\n栀\n柃\n枸\n柢\n栎\n柁\n柽\n栲\n栳\n桠\n桡\n桎\n桢\n桄\n桤\n梃\n栝\n桕\n桦\n桁\n桧\n桀\n栾\n桊\n桉\n栩\n梵\n梏\n桴\n桷\n梓\n桫\n棂\n楮\n棼\n椟\n椠\n棹\n锧\n锳\n锽\n镃\n镈\n镋\n镕\n镚\n镠\n镮\n镴\n镵\n長\n镸\n镹\n镺\n镻\n镼\n镽\n镾\n門\n閁\n閂\n閃\n閄\n閅\n閆\n閇\n閈\n閉\n閊\n開\n閌\n閍\n閎\n閏\n閐\n閑\n閒\n間\n閔\n閕\n閖\n閗\n閘\n閙\n閚\n閛\n閜\n閝\n閞\n閟\n閠\n閡\n関\n閣\n閤\n閥\n閦\n閧\n閨\n閩\n閪\n閫\n閬\n閭\n閮\n閯\n閰\n閱\n閲\n閳\n閴\n閵\n閶\n閷\n閸\n閹\n閺\n閻\n閼\n閽\n閾\n閿\n闀\n闁\n闂\n闃\n闄\n闅\n闆\n闇\n闈\n闉\n闊\n闋\n椤\n棰\n椋\n椁\n楗\n棣\n椐\n楱\n椹\n楠\n楂\n楝\n榄\n楫\n榀\n榘\n楸\n椴\n槌\n榇\n榈\n槎\n榉\n楦\n楣\n楹\n榛\n榧\n榻\n榫\n榭\n槔\n榱\n槁\n槊\n槟\n榕\n槠\n榍\n槿\n樯\n槭\n樗\n樘\n橥\n槲\n橄\n樾\n檠\n橐\n橛\n樵\n檎\n橹\n樽\n樨\n橘\n橼\n檑\n檐\n檩\n檗\n檫\n猷\n獒\n殁\n殂\n殇\n殄\n殒\n殓\n殍\n殚\n殛\n殡\n殪\n轫\n轭\n轱\n轲\n轳\n轵\n轶\n轸\n轷\n轹\n轺\n轼\n轾\n辁\n辂\n辄\n辇\n辋\n闌\n闍\n闎\n闏\n闐\n闑\n闒\n闓\n闔\n闕\n闖\n闗\n闘\n闙\n闚\n闛\n關\n闝\n闞\n闟\n闠\n闡\n闢\n闣\n闤\n闥\n闦\n闧\n闬\n闿\n阇\n阓\n阘\n阛\n阞\n阠\n阣\n阤\n阥\n阦\n阧\n阨\n阩\n阫\n阬\n阭\n阯\n阰\n阷\n阸\n阹\n阺\n阾\n陁\n陃\n陊\n陎\n陏\n陑\n陒\n陓\n陖\n陗\n陘\n陙\n陚\n陜\n陝\n陞\n陠\n陣\n陥\n陦\n陫\n陭\n陮\n陯\n陰\n陱\n陳\n陸\n陹\n険\n陻\n陼\n陽\n陾\n陿\n隀\n隁\n隂\n隃\n隄\n隇\n隉\n隊\n辍\n辎\n辏\n辘\n辚\n軎\n戋\n戗\n戛\n戟\n戢\n戡\n戥\n戤\n戬\n臧\n瓯\n瓴\n瓿\n甏\n甑\n甓\n攴\n旮\n旯\n旰\n昊\n昙\n杲\n昃\n昕\n昀\n炅\n曷\n昝\n昴\n昱\n昶\n昵\n耆\n晟\n晔\n晁\n晏\n晖\n晡\n晗\n晷\n暄\n暌\n暧\n暝\n暾\n曛\n曜\n曦\n曩\n贲\n贳\n贶\n贻\n贽\n赀\n赅\n赆\n赈\n赉\n赇\n赍\n赕\n赙\n觇\n觊\n觋\n觌\n觎\n觏\n觐\n觑\n牮\n犟\n牝\n牦\n牯\n牾\n牿\n犄\n犋\n犍\n犏\n犒\n挈\n挲\n掰\n隌\n階\n隑\n隒\n隓\n隕\n隖\n隚\n際\n隝\n隞\n隟\n隠\n隡\n隢\n隣\n隤\n隥\n隦\n隨\n隩\n險\n隫\n隬\n隭\n隮\n隯\n隱\n隲\n隴\n隵\n隷\n隸\n隺\n隻\n隿\n雂\n雃\n雈\n雊\n雋\n雐\n雑\n雓\n雔\n雖\n雗\n雘\n雙\n雚\n雛\n雜\n雝\n雞\n雟\n雡\n離\n難\n雤\n雥\n雦\n雧\n雫\n雬\n雭\n雮\n雰\n雱\n雲\n雴\n雵\n雸\n雺\n電\n雼\n雽\n雿\n霂\n霃\n霅\n霊\n霋\n霌\n霐\n霑\n霒\n霔\n霕\n霗\n霘\n霙\n霚\n霛\n霝\n霟\n霠\n搿\n擘\n耄\n毪\n毳\n毽\n毵\n毹\n氅\n氇\n氆\n氍\n氕\n氘\n氙\n氚\n氡\n氩\n氤\n氪\n氲\n攵\n敕\n敫\n牍\n牒\n牖\n爰\n虢\n刖\n肟\n肜\n肓\n肼\n朊\n肽\n肱\n肫\n肭\n肴\n肷\n胧\n胨\n胩\n胪\n胛\n胂\n胄\n胙\n胍\n胗\n朐\n胝\n胫\n胱\n胴\n胭\n脍\n脎\n胲\n胼\n朕\n脒\n豚\n脶\n脞\n脬\n脘\n脲\n腈\n腌\n腓\n腴\n腙\n腚\n腱\n腠\n腩\n腼\n腽\n腭\n腧\n塍\n媵\n膈\n膂\n膑\n滕\n膣\n膪\n臌\n朦\n臊\n膻\n霡\n霢\n霣\n霤\n霥\n霦\n霧\n霨\n霩\n霫\n霬\n霮\n霯\n霱\n霳\n霴\n霵\n霶\n霷\n霺\n霻\n霼\n霽\n霿\n靀\n靁\n靂\n靃\n靄\n靅\n靆\n靇\n靈\n靉\n靊\n靋\n靌\n靍\n靎\n靏\n靐\n靑\n靔\n靕\n靗\n靘\n靚\n靜\n靝\n靟\n靣\n靤\n靦\n靧\n靨\n靪\n靫\n靬\n靭\n靮\n靯\n靰\n靱\n靲\n靵\n靷\n靸\n靹\n靺\n靻\n靽\n靾\n靿\n鞀\n鞁\n鞂\n鞃\n鞄\n鞆\n鞇\n鞈\n鞉\n鞊\n鞌\n鞎\n鞏\n鞐\n鞓\n鞕\n鞖\n鞗\n鞙\n鞚\n鞛\n鞜\n鞝\n臁\n膦\n欤\n欷\n欹\n歃\n歆\n歙\n飑\n飒\n飓\n飕\n飙\n飚\n殳\n彀\n毂\n觳\n斐\n齑\n斓\n於\n旆\n旄\n旃\n旌\n旎\n旒\n旖\n炀\n炜\n炖\n炝\n炻\n烀\n炷\n炫\n炱\n烨\n烊\n焐\n焓\n焖\n焯\n焱\n煳\n煜\n煨\n煅\n煲\n煊\n煸\n煺\n熘\n熳\n熵\n熨\n熠\n燠\n燔\n燧\n燹\n爝\n爨\n灬\n焘\n煦\n熹\n戾\n戽\n扃\n扈\n扉\n礻\n祀\n祆\n祉\n祛\n祜\n祓\n祚\n祢\n祗\n祠\n祯\n祧\n祺\n禅\n禊\n禚\n禧\n禳\n忑\n忐\n鞞\n鞟\n鞡\n鞢\n鞤\n鞥\n鞦\n鞧\n鞨\n鞩\n鞪\n鞬\n鞮\n鞰\n鞱\n鞳\n鞵\n鞶\n鞷\n鞸\n鞹\n鞺\n鞻\n鞼\n鞽\n鞾\n鞿\n韀\n韁\n韂\n韃\n韄\n韅\n韆\n韇\n韈\n韉\n韊\n韋\n韌\n韍\n韎\n韏\n韐\n韑\n韒\n韓\n韔\n韕\n韖\n韗\n韘\n韙\n韚\n韛\n韜\n韝\n韞\n韟\n韠\n韡\n韢\n韣\n韤\n韥\n韨\n韮\n韯\n韰\n韱\n韲\n韴\n韷\n韸\n韹\n韺\n韻\n韼\n韽\n韾\n響\n頀\n頁\n頂\n頃\n頄\n項\n順\n頇\n須\n頉\n頊\n頋\n頌\n頍\n頎\n怼\n恝\n恚\n恧\n恁\n恙\n恣\n悫\n愆\n愍\n慝\n憩\n憝\n懋\n懑\n戆\n肀\n聿\n沓\n泶\n淼\n矶\n矸\n砀\n砉\n砗\n砘\n砑\n斫\n砭\n砜\n砝\n砹\n砺\n砻\n砟\n砼\n砥\n砬\n砣\n砩\n硎\n硭\n硖\n硗\n砦\n硐\n硇\n硌\n硪\n碛\n碓\n碚\n碇\n碜\n碡\n碣\n碲\n碹\n碥\n磔\n磙\n磉\n磬\n磲\n礅\n磴\n礓\n礤\n礞\n礴\n龛\n黹\n黻\n黼\n盱\n眄\n眍\n盹\n眇\n眈\n眚\n眢\n眙\n眭\n眦\n眵\n眸\n睐\n睑\n睇\n睃\n睚\n睨\n頏\n預\n頑\n頒\n頓\n頔\n頕\n頖\n頗\n領\n頙\n頚\n頛\n頜\n頝\n頞\n頟\n頠\n頡\n頢\n頣\n頤\n頥\n頦\n頧\n頨\n頩\n頪\n頫\n頬\n頭\n頮\n頯\n頰\n頱\n頲\n頳\n頴\n頵\n頶\n頷\n頸\n頹\n頺\n頻\n頼\n頽\n頾\n頿\n顀\n顁\n顂\n顃\n顄\n顅\n顆\n顇\n顈\n顉\n顊\n顋\n題\n額\n顎\n顏\n顐\n顑\n顒\n顓\n顔\n顕\n顖\n顗\n願\n顙\n顚\n顛\n顜\n顝\n類\n顟\n顠\n顡\n顢\n顣\n顤\n顥\n顦\n顧\n顨\n顩\n顪\n顫\n顬\n顭\n顮\n睢\n睥\n睿\n瞍\n睽\n瞀\n瞌\n瞑\n瞟\n瞠\n瞰\n瞵\n瞽\n町\n畀\n畎\n畋\n畈\n畛\n畲\n畹\n疃\n罘\n罡\n罟\n詈\n罨\n罴\n罱\n罹\n羁\n罾\n盍\n盥\n蠲\n钅\n钆\n钇\n钋\n钊\n钌\n钍\n钏\n钐\n钔\n钗\n钕\n钚\n钛\n钜\n钣\n钤\n钫\n钪\n钭\n钬\n钯\n钰\n钲\n钴\n钶\n钷\n钸\n钹\n钺\n钼\n钽\n钿\n铄\n铈\n铉\n铊\n铋\n铌\n铍\n铎\n铐\n铑\n铒\n铕\n铖\n铗\n铙\n铘\n铛\n铞\n铟\n铠\n铢\n铤\n铥\n铧\n铨\n铪\n顯\n顰\n顱\n顲\n顳\n顴\n颋\n颎\n颒\n颕\n颙\n颣\n風\n颩\n颪\n颫\n颬\n颭\n颮\n颯\n颰\n颱\n颲\n颳\n颴\n颵\n颶\n颷\n颸\n颹\n颺\n颻\n颼\n颽\n颾\n颿\n飀\n飁\n飂\n飃\n飄\n飅\n飆\n飇\n飈\n飉\n飊\n飋\n飌\n飍\n飏\n飐\n飔\n飖\n飗\n飛\n飜\n飝\n飠\n飡\n飢\n飣\n飤\n飥\n飦\n飩\n飪\n飫\n飬\n飭\n飮\n飯\n飰\n飱\n飲\n飳\n飴\n飵\n飶\n飷\n飸\n飹\n飺\n飻\n飼\n飽\n飾\n飿\n餀\n餁\n餂\n餃\n餄\n餅\n餆\n餇\n铩\n铫\n铮\n铯\n铳\n铴\n铵\n铷\n铹\n铼\n铽\n铿\n锃\n锂\n锆\n锇\n锉\n锊\n锍\n锎\n锏\n锒\n锓\n锔\n锕\n锖\n锘\n锛\n锝\n锞\n锟\n锢\n锪\n锫\n锩\n锬\n锱\n锲\n锴\n锶\n锷\n锸\n锼\n锾\n锿\n镂\n锵\n镄\n镅\n镆\n镉\n镌\n镎\n镏\n镒\n镓\n镔\n镖\n镗\n镘\n镙\n镛\n镞\n镟\n镝\n镡\n镢\n镤\n镥\n镦\n镧\n镨\n镩\n镪\n镫\n镬\n镯\n镱\n镲\n镳\n锺\n矧\n矬\n雉\n秕\n秭\n秣\n秫\n稆\n嵇\n稃\n稂\n稞\n稔\n餈\n餉\n養\n餋\n餌\n餎\n餏\n餑\n餒\n餓\n餔\n餕\n餖\n餗\n餘\n餙\n餚\n餛\n餜\n餝\n餞\n餟\n餠\n餡\n餢\n餣\n餤\n餥\n餦\n餧\n館\n餩\n餪\n餫\n餬\n餭\n餯\n餰\n餱\n餲\n餳\n餴\n餵\n餶\n餷\n餸\n餹\n餺\n餻\n餼\n餽\n餾\n餿\n饀\n饁\n饂\n饃\n饄\n饅\n饆\n饇\n饈\n饉\n饊\n饋\n饌\n饍\n饎\n饏\n饐\n饑\n饒\n饓\n饖\n饗\n饘\n饙\n饚\n饛\n饜\n饝\n饞\n饟\n饠\n饡\n饢\n饤\n饦\n饳\n饸\n饹\n饻\n饾\n馂\n馃\n馉\n稹\n稷\n穑\n黏\n馥\n穰\n皈\n皎\n皓\n皙\n皤\n瓞\n瓠\n甬\n鸠\n鸢\n鸨\n鸩\n鸪\n鸫\n鸬\n鸲\n鸱\n鸶\n鸸\n鸷\n鸹\n鸺\n鸾\n鹁\n鹂\n鹄\n鹆\n鹇\n鹈\n鹉\n鹋\n鹌\n鹎\n鹑\n鹕\n鹗\n鹚\n鹛\n鹜\n鹞\n鹣\n鹦\n鹧\n鹨\n鹩\n鹪\n鹫\n鹬\n鹱\n鹭\n鹳\n疒\n疔\n疖\n疠\n疝\n疬\n疣\n疳\n疴\n疸\n痄\n疱\n疰\n痃\n痂\n痖\n痍\n痣\n痨\n痦\n痤\n痫\n痧\n瘃\n痱\n痼\n痿\n瘐\n瘀\n瘅\n瘌\n瘗\n瘊\n瘥\n瘘\n瘕\n瘙\n馌\n馎\n馚\n馛\n馜\n馝\n馞\n馟\n馠\n馡\n馢\n馣\n馤\n馦\n馧\n馩\n馪\n馫\n馬\n馭\n馮\n馯\n馰\n馱\n馲\n馳\n馴\n馵\n馶\n馷\n馸\n馹\n馺\n馻\n馼\n馽\n馾\n馿\n駀\n駁\n駂\n駃\n駄\n駅\n駆\n駇\n駈\n駉\n駊\n駋\n駌\n駍\n駎\n駏\n駐\n駑\n駒\n駓\n駔\n駕\n駖\n駗\n駘\n駙\n駚\n駛\n駜\n駝\n駞\n駟\n駠\n駡\n駢\n駣\n駤\n駥\n駦\n駧\n駨\n駩\n駪\n駫\n駬\n駭\n駮\n駯\n駰\n駱\n駲\n駳\n駴\n駵\n駶\n駷\n駸\n駹\n瘛\n瘼\n瘢\n瘠\n癀\n瘭\n瘰\n瘿\n瘵\n癃\n瘾\n瘳\n癍\n癞\n癔\n癜\n癖\n癫\n癯\n翊\n竦\n穸\n穹\n窀\n窆\n窈\n窕\n窦\n窠\n窬\n窨\n窭\n窳\n衤\n衩\n衲\n衽\n衿\n袂\n袢\n裆\n袷\n袼\n裉\n裢\n裎\n裣\n裥\n裱\n褚\n裼\n裨\n裾\n裰\n褡\n褙\n褓\n褛\n褊\n褴\n褫\n褶\n襁\n襦\n襻\n疋\n胥\n皲\n皴\n矜\n耒\n耔\n耖\n耜\n耠\n耢\n耥\n耦\n耧\n耩\n耨\n耱\n耋\n耵\n聃\n聆\n聍\n聒\n聩\n聱\n覃\n顸\n颀\n颃\n駺\n駻\n駼\n駽\n駾\n駿\n騀\n騁\n騂\n騃\n騄\n騅\n騆\n騇\n騈\n騉\n騊\n騋\n騌\n騍\n騎\n騏\n騐\n騑\n騒\n験\n騔\n騕\n騖\n騗\n騘\n騙\n騚\n騛\n騜\n騝\n騞\n騟\n騠\n騡\n騢\n騣\n騤\n騥\n騦\n騧\n騨\n騩\n騪\n騫\n騬\n騭\n騮\n騯\n騰\n騱\n騲\n騳\n騴\n騵\n騶\n騷\n騸\n騹\n騺\n騻\n騼\n騽\n騾\n騿\n驀\n驁\n驂\n驃\n驄\n驅\n驆\n驇\n驈\n驉\n驊\n驋\n驌\n驍\n驎\n驏\n驐\n驑\n驒\n驓\n驔\n驕\n驖\n驗\n驘\n驙\n颉\n颌\n颍\n颏\n颔\n颚\n颛\n颞\n颟\n颡\n颢\n颥\n颦\n虍\n虔\n虬\n虮\n虿\n虺\n虼\n虻\n蚨\n蚍\n蚋\n蚬\n蚝\n蚧\n蚣\n蚪\n蚓\n蚩\n蚶\n蛄\n蚵\n蛎\n蚰\n蚺\n蚱\n蚯\n蛉\n蛏\n蚴\n蛩\n蛱\n蛲\n蛭\n蛳\n蛐\n蜓\n蛞\n蛴\n蛟\n蛘\n蛑\n蜃\n蜇\n蛸\n蜈\n蜊\n蜍\n蜉\n蜣\n蜻\n蜞\n蜥\n蜮\n蜚\n蜾\n蝈\n蜴\n蜱\n蜩\n蜷\n蜿\n螂\n蜢\n蝽\n蝾\n蝻\n蝠\n蝰\n蝌\n蝮\n螋\n蝓\n蝣\n蝼\n蝤\n蝙\n蝥\n螓\n螯\n螨\n蟒\n驚\n驛\n驜\n驝\n驞\n驟\n驠\n驡\n驢\n驣\n驤\n驥\n驦\n驧\n驨\n驩\n驪\n驫\n驲\n骃\n骉\n骍\n骎\n骔\n骕\n骙\n骦\n骩\n骪\n骫\n骬\n骭\n骮\n骯\n骲\n骳\n骴\n骵\n骹\n骻\n骽\n骾\n骿\n髃\n髄\n髆\n髇\n髈\n髉\n髊\n髍\n髎\n髏\n髐\n髒\n體\n髕\n髖\n髗\n髙\n髚\n髛\n髜\n髝\n髞\n髠\n髢\n髣\n髤\n髥\n髧\n髨\n髩\n髪\n髬\n髮\n髰\n髱\n髲\n髳\n髴\n髵\n髶\n髷\n髸\n髺\n髼\n髽\n髾\n髿\n鬀\n鬁\n鬂\n鬄\n鬅\n鬆\n蟆\n螈\n螅\n螭\n螗\n螃\n螫\n蟥\n螬\n螵\n螳\n蟋\n蟓\n螽\n蟑\n蟀\n蟊\n蟛\n蟪\n蟠\n蟮\n蠖\n蠓\n蟾\n蠊\n蠛\n蠡\n蠹\n蠼\n缶\n罂\n罄\n罅\n舐\n竺\n竽\n笈\n笃\n笄\n笕\n笊\n笫\n笏\n筇\n笸\n笪\n笙\n笮\n笱\n笠\n笥\n笤\n笳\n笾\n笞\n筘\n筚\n筅\n筵\n筌\n筝\n筠\n筮\n筻\n筢\n筲\n筱\n箐\n箦\n箧\n箸\n箬\n箝\n箨\n箅\n箪\n箜\n箢\n箫\n箴\n篑\n篁\n篌\n篝\n篚\n篥\n篦\n篪\n簌\n篾\n篼\n簏\n簖\n簋\n鬇\n鬉\n鬊\n鬋\n鬌\n鬍\n鬎\n鬐\n鬑\n鬒\n鬔\n鬕\n鬖\n鬗\n鬘\n鬙\n鬚\n鬛\n鬜\n鬝\n鬞\n鬠\n鬡\n鬢\n鬤\n鬥\n鬦\n鬧\n鬨\n鬩\n鬪\n鬫\n鬬\n鬭\n鬮\n鬰\n鬱\n鬳\n鬴\n鬵\n鬶\n鬷\n鬸\n鬹\n鬺\n鬽\n鬾\n鬿\n魀\n魆\n魊\n魋\n魌\n魎\n魐\n魒\n魓\n魕\n魖\n魗\n魘\n魙\n魚\n魛\n魜\n魝\n魞\n魟\n魠\n魡\n魢\n魣\n魤\n魥\n魦\n魧\n魨\n魩\n魪\n魫\n魬\n魭\n魮\n魯\n魰\n魱\n魲\n魳\n魴\n魵\n魶\n魷\n魸\n魹\n魺\n魻\n簟\n簪\n簦\n簸\n籁\n籀\n臾\n舁\n舂\n舄\n臬\n衄\n舡\n舢\n舣\n舭\n舯\n舨\n舫\n舸\n舻\n舳\n舴\n舾\n艄\n艉\n艋\n艏\n艚\n艟\n艨\n衾\n袅\n袈\n裘\n裟\n襞\n羝\n羟\n羧\n羯\n羰\n羲\n籼\n敉\n粑\n粝\n粜\n粞\n粢\n粲\n粼\n粽\n糁\n糇\n糌\n糍\n糈\n糅\n糗\n糨\n艮\n暨\n羿\n翎\n翕\n翥\n翡\n翦\n翩\n翮\n翳\n糸\n絷\n綦\n綮\n繇\n纛\n麸\n麴\n赳\n趄\n趔\n趑\n趱\n赧\n赭\n豇\n豉\n酊\n酐\n酎\n酏\n酤\n魼\n魽\n魾\n魿\n鮀\n鮁\n鮂\n鮃\n鮄\n鮅\n鮆\n鮇\n鮈\n鮉\n鮊\n鮋\n鮌\n鮍\n鮎\n鮏\n鮐\n鮑\n鮒\n鮓\n鮔\n鮕\n鮖\n鮗\n鮘\n鮙\n鮚\n鮛\n鮜\n鮝\n鮞\n鮟\n鮠\n鮡\n鮢\n鮣\n鮤\n鮥\n鮦\n鮧\n鮨\n鮩\n鮪\n鮫\n鮬\n鮭\n鮮\n鮯\n鮰\n鮱\n鮲\n鮳\n鮴\n鮵\n鮶\n鮷\n鮸\n鮹\n鮺\n鮻\n鮼\n鮽\n鮾\n鮿\n鯀\n鯁\n鯂\n鯃\n鯄\n鯅\n鯆\n鯇\n鯈\n鯉\n鯊\n鯋\n鯌\n鯍\n鯎\n鯏\n鯐\n鯑\n鯒\n鯓\n鯔\n鯕\n鯖\n鯗\n鯘\n鯙\n鯚\n鯛\n酢\n酡\n酰\n酩\n酯\n酽\n酾\n酲\n酴\n酹\n醌\n醅\n醐\n醍\n醑\n醢\n醣\n醪\n醭\n醮\n醯\n醵\n醴\n醺\n豕\n鹾\n趸\n跫\n踅\n蹙\n蹩\n趵\n趿\n趼\n趺\n跄\n跖\n跗\n跚\n跞\n跎\n跏\n跛\n跆\n跬\n跷\n跸\n跣\n跹\n跻\n跤\n踉\n跽\n踔\n踝\n踟\n踬\n踮\n踣\n踯\n踺\n蹀\n踹\n踵\n踽\n踱\n蹉\n蹁\n蹂\n蹑\n蹒\n蹊\n蹰\n蹶\n蹼\n蹯\n蹴\n躅\n躏\n躔\n躐\n躜\n躞\n豸\n貂\n貊\n貅\n貘\n貔\n斛\n觖\n觞\n觚\n觜\n鯜\n鯝\n鯞\n鯟\n鯠\n鯡\n鯢\n鯣\n鯤\n鯥\n鯦\n鯧\n鯨\n鯩\n鯪\n鯫\n鯬\n鯭\n鯮\n鯯\n鯰\n鯱\n鯲\n鯳\n鯴\n鯵\n鯶\n鯷\n鯸\n鯹\n鯺\n鯻\n鯼\n鯽\n鯾\n鯿\n鰀\n鰁\n鰂\n鰃\n鰄\n鰅\n鰆\n鰇\n鰈\n鰉\n鰊\n鰋\n鰌\n鰍\n鰎\n鰏\n鰐\n鰑\n鰒\n鰓\n鰔\n鰕\n鰖\n鰗\n鰘\n鰙\n鰚\n鰛\n鰜\n鰝\n鰞\n鰟\n鰠\n鰡\n鰢\n鰣\n鰤\n鰥\n鰦\n鰧\n鰨\n鰩\n鰪\n鰫\n鰬\n鰭\n鰮\n鰯\n鰰\n鰱\n鰲\n鰳\n鰴\n鰵\n鰶\n鰷\n鰸\n鰹\n鰺\n鰻\n觥\n觫\n觯\n訾\n謦\n靓\n雩\n雳\n雯\n霆\n霁\n霈\n霏\n霎\n霪\n霭\n霰\n霾\n龀\n龃\n龅\n龆\n龇\n龈\n龉\n龊\n龌\n黾\n鼋\n鼍\n隹\n隼\n隽\n雎\n雒\n瞿\n雠\n銎\n銮\n鋈\n錾\n鍪\n鏊\n鎏\n鐾\n鑫\n鱿\n鲂\n鲅\n鲆\n鲇\n鲈\n稣\n鲋\n鲎\n鲐\n鲑\n鲒\n鲔\n鲕\n鲚\n鲛\n鲞\n鲟\n鲠\n鲡\n鲢\n鲣\n鲥\n鲦\n鲧\n鲨\n鲩\n鲫\n鲭\n鲮\n鲰\n鲱\n鲲\n鲳\n鲴\n鲵\n鲶\n鲷\n鲺\n鲻\n鲼\n鲽\n鳄\n鳅\n鳆\n鳇\n鳊\n鳋\n鰼\n鰽\n鰾\n鰿\n鱀\n鱁\n鱂\n鱃\n鱄\n鱅\n鱆\n鱇\n鱈\n鱉\n鱊\n鱋\n鱌\n鱍\n鱎\n鱏\n鱐\n鱑\n鱒\n鱓\n鱔\n鱕\n鱖\n鱗\n鱘\n鱙\n鱚\n鱛\n鱜\n鱝\n鱞\n鱟\n鱠\n鱡\n鱢\n鱣\n鱤\n鱥\n鱦\n鱧\n鱨\n鱩\n鱪\n鱫\n鱬\n鱭\n鱮\n鱯\n鱰\n鱱\n鱲\n鱳\n鱴\n鱵\n鱶\n鱷\n鱸\n鱹\n鱺\n鱻\n鱽\n鱾\n鲀\n鲃\n鲄\n鲉\n鲊\n鲌\n鲏\n鲓\n鲖\n鲗\n鲘\n鲙\n鲝\n鲪\n鲬\n鲯\n鲹\n鲾\n鲿\n鳀\n鳁\n鳂\n鳈\n鳉\n鳑\n鳒\n鳚\n鳛\n鳠\n鳡\n鳌\n鳍\n鳎\n鳏\n鳐\n鳓\n鳔\n鳕\n鳗\n鳘\n鳙\n鳜\n鳝\n鳟\n鳢\n靼\n鞅\n鞑\n鞒\n鞔\n鞯\n鞫\n鞣\n鞲\n鞴\n骱\n骰\n骷\n鹘\n骶\n骺\n骼\n髁\n髀\n髅\n髂\n髋\n髌\n髑\n魅\n魃\n魇\n魉\n魈\n魍\n魑\n飨\n餍\n餮\n饕\n饔\n髟\n髡\n髦\n髯\n髫\n髻\n髭\n髹\n鬈\n鬏\n鬓\n鬟\n鬣\n麽\n麾\n縻\n麂\n麇\n麈\n麋\n麒\n鏖\n麝\n麟\n黛\n黜\n黝\n黠\n黟\n黢\n黩\n黧\n黥\n黪\n黯\n鼢\n鼬\n鼯\n鼹\n鼷\n鼽\n鼾\n齄\n鳣\n鳤\n鳥\n鳦\n鳧\n鳨\n鳩\n鳪\n鳫\n鳬\n鳭\n鳮\n鳯\n鳰\n鳱\n鳲\n鳳\n鳴\n鳵\n鳶\n鳷\n鳸\n鳹\n鳺\n鳻\n鳼\n鳽\n鳾\n鳿\n鴀\n鴁\n鴂\n鴃\n鴄\n鴅\n鴆\n鴇\n鴈\n鴉\n鴊\n鴋\n鴌\n鴍\n鴎\n鴏\n鴐\n鴑\n鴒\n鴓\n鴔\n鴕\n鴖\n鴗\n鴘\n鴙\n鴚\n鴛\n鴜\n鴝\n鴞\n鴟\n鴠\n鴡\n鴢\n鴣\n鴤\n鴥\n鴦\n鴧\n鴨\n鴩\n鴪\n鴫\n鴬\n鴭\n鴮\n鴯\n鴰\n鴱\n鴲\n鴳\n鴴\n鴵\n鴶\n鴷\n鴸\n鴹\n鴺\n鴻\n鴼\n鴽\n鴾\n鴿\n鵀\n鵁\n鵂\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n鵃\n鵄\n鵅\n鵆\n鵇\n鵈\n鵉\n鵊\n鵋\n鵌\n鵍\n鵎\n鵏\n鵐\n鵑\n鵒\n鵓\n鵔\n鵕\n鵖\n鵗\n鵘\n鵙\n鵚\n鵛\n鵜\n鵝\n鵞\n鵟\n鵠\n鵡\n鵢\n鵣\n鵤\n鵥\n鵦\n鵧\n鵨\n鵩\n鵪\n鵫\n鵬\n鵭\n鵮\n鵯\n鵰\n鵱\n鵲\n鵳\n鵴\n鵵\n鵶\n鵷\n鵸\n鵹\n鵺\n鵻\n鵼\n鵽\n鵾\n鵿\n鶀\n鶁\n鶂\n鶃\n鶄\n鶅\n鶆\n鶇\n鶈\n鶉\n鶊\n鶋\n鶌\n鶍\n鶎\n鶏\n鶐\n鶑\n鶒\n鶓\n鶔\n鶕\n鶖\n鶗\n鶘\n鶙\n鶚\n鶛\n鶜\n鶝\n鶞\n鶟\n鶠\n鶡\n鶢\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n鶣\n鶤\n鶥\n鶦\n鶧\n鶨\n鶩\n鶪\n鶫\n鶬\n鶭\n鶮\n鶯\n鶰\n鶱\n鶲\n鶳\n鶴\n鶵\n鶶\n鶷\n鶸\n鶹\n鶺\n鶻\n鶼\n鶽\n鶾\n鶿\n鷀\n鷁\n鷂\n鷃\n鷄\n鷅\n鷆\n鷇\n鷈\n鷉\n鷊\n鷋\n鷌\n鷍\n鷎\n鷏\n鷐\n鷑\n鷒\n鷓\n鷔\n鷕\n鷖\n鷗\n鷘\n鷙\n鷚\n鷛\n鷜\n鷝\n鷞\n鷟\n鷠\n鷡\n鷢\n鷣\n鷤\n鷥\n鷦\n鷧\n鷨\n鷩\n鷪\n鷫\n鷬\n鷭\n鷮\n鷯\n鷰\n鷱\n鷲\n鷳\n鷴\n鷵\n鷶\n鷷\n鷸\n鷹\n鷺\n鷻\n鷼\n鷽\n鷾\n鷿\n鸀\n鸁\n鸂\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n鸃\n鸄\n鸅\n鸆\n鸇\n鸈\n鸉\n鸊\n鸋\n鸌\n鸍\n鸎\n鸏\n鸐\n鸑\n鸒\n鸓\n鸔\n鸕\n鸖\n鸗\n鸘\n鸙\n鸚\n鸛\n鸜\n鸝\n鸞\n鸤\n鸧\n鸮\n鸰\n鸴\n鸻\n鸼\n鹀\n鹍\n鹐\n鹒\n鹓\n鹔\n鹖\n鹙\n鹝\n鹟\n鹠\n鹡\n鹢\n鹥\n鹮\n鹯\n鹲\n鹴\n鹵\n鹶\n鹷\n鹸\n鹹\n鹺\n鹻\n鹼\n鹽\n麀\n麁\n麃\n麄\n麅\n麆\n麉\n麊\n麌\n麍\n麎\n麏\n麐\n麑\n麔\n麕\n麖\n麗\n麘\n麙\n麚\n麛\n麜\n麞\n麠\n麡\n麢\n麣\n麤\n麥\n麧\n麨\n麩\n麪\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n麫\n麬\n麭\n麮\n麯\n麰\n麱\n麲\n麳\n麵\n麶\n麷\n麹\n麺\n麼\n麿\n黀\n黁\n黂\n黃\n黅\n黆\n黇\n黈\n黊\n黋\n黌\n黐\n黒\n黓\n黕\n黖\n黗\n黙\n黚\n點\n黡\n黣\n黤\n黦\n黨\n黫\n黬\n黭\n黮\n黰\n黱\n黲\n黳\n黴\n黵\n黶\n黷\n黸\n黺\n黽\n黿\n鼀\n鼁\n鼂\n鼃\n鼄\n鼅\n鼆\n鼇\n鼈\n鼉\n鼊\n鼌\n鼏\n鼑\n鼒\n鼔\n鼕\n鼖\n鼘\n鼚\n鼛\n鼜\n鼝\n鼞\n鼟\n鼡\n鼣\n鼤\n鼥\n鼦\n鼧\n鼨\n鼩\n鼪\n鼫\n鼭\n鼮\n鼰\n鼱\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n鼲\n鼳\n鼴\n鼵\n鼶\n鼸\n鼺\n鼼\n鼿\n齀\n齁\n齂\n齃\n齅\n齆\n齇\n齈\n齉\n齊\n齋\n齌\n齍\n齎\n齏\n齒\n齓\n齔\n齕\n齖\n齗\n齘\n齙\n齚\n齛\n齜\n齝\n齞\n齟\n齠\n齡\n齢\n齣\n齤\n齥\n齦\n齧\n齨\n齩\n齪\n齫\n齬\n齭\n齮\n齯\n齰\n齱\n齲\n齳\n齴\n齵\n齶\n齷\n齸\n齹\n齺\n齻\n齼\n齽\n齾\n龁\n龂\n龍\n龎\n龏\n龐\n龑\n龒\n龓\n龔\n龕\n龖\n龗\n龘\n龜\n龝\n龞\n龡\n龢\n龣\n龤\n龥\n郎\n凉\n秊\n裏\n隣\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n兀\n嗀\n﨎\n﨏\n﨑\n﨓\n﨔\n礼\n﨟\n蘒\n﨡\n﨣\n﨤\n﨧\n﨨\n﨩\n⺁\n\n\n\n⺄\n㑳\n㑇\n⺈\n⺋\n龴\n㖞\n㘚\n㘎\n⺌\n⺗\n㥮\n㤘\n龵\n㧏\n㧟\n㩳\n㧐\n龶\n龷\n㭎\n㱮\n㳠\n⺧\n\n龸\n⺪\n䁖\n䅟\n⺮\n䌷\n⺳\n⺶\n⺷\n\n䎱\n䎬\n⺻\n䏝\n䓖\n䙡\n䙌\n龹\n䜣\n䜩\n䝼\n䞍\n⻊\n䥇\n䥺\n䥽\n䦂\n䦃\n䦅\n䦆\n䦟\n䦛\n䦷\n䦶\n龺\n\n䲣\n䲟\n䲠\n䲡\n䱷\n䲢\n䴓\n䴔\n䴕\n䴖\n䴗\n䴘\n䴙\n䶮\n龻\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/gb18030_out.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n丂\n丄\n丅\n丆\n丏\n丒\n丗\n丟\n丠\n両\n丣\n並\n丩\n丮\n丯\n丱\n丳\n丵\n丷\n丼\n乀\n乁\n乂\n乄\n乆\n乊\n乑\n乕\n乗\n乚\n乛\n乢\n乣\n乤\n乥\n乧\n乨\n乪\n乫\n乬\n乭\n乮\n乯\n乲\n乴\n乵\n乶\n乷\n乸\n乹\n乺\n乻\n乼\n乽\n乿\n亀\n亁\n亂\n亃\n亄\n亅\n亇\n亊\n亐\n亖\n亗\n亙\n亜\n亝\n亞\n亣\n亪\n亯\n亰\n亱\n亴\n亶\n亷\n亸\n亹\n亼\n亽\n亾\n仈\n仌\n仏\n仐\n仒\n仚\n仛\n仜\n仠\n仢\n仦\n仧\n仩\n仭\n仮\n仯\n仱\n仴\n仸\n仹\n仺\n仼\n仾\n伀\n伂\n伃\n伄\n伅\n伆\n伇\n伈\n伋\n伌\n伒\n伓\n伔\n伕\n伖\n伜\n伝\n伡\n伣\n伨\n伩\n伬\n伭\n伮\n伱\n伳\n伵\n伷\n伹\n伻\n伾\n伿\n佀\n佁\n佂\n佄\n佅\n佇\n佈\n佉\n佊\n佋\n佌\n佒\n佔\n佖\n佡\n佢\n佦\n佨\n佪\n佫\n佭\n佮\n佱\n佲\n併\n佷\n佸\n佹\n佺\n佽\n侀\n侁\n侂\n侅\n來\n侇\n侊\n侌\n侎\n侐\n侒\n侓\n侕\n侖\n侘\n侙\n侚\n侜\n侞\n侟\n価\n侢\n侤\n侫\n侭\n侰\n侱\n侲\n侳\n侴\n侶\n侷\n侸\n侹\n侺\n侻\n侼\n侽\n侾\n俀\n俁\n係\n俆\n俇\n俈\n俉\n俋\n俌\n俍\n俒\n俓\n俔\n俕\n俖\n俙\n俛\n俠\n俢\n俤\n俥\n俧\n俫\n俬\n俰\n俲\n俴\n俵\n俶\n俷\n俹\n俻\n俼\n俽\n俿\n倀\n倁\n倂\n倃\n倄\n倅\n倆\n倇\n倈\n倉\n倊\n個\n倎\n倐\n們\n倓\n倕\n倖\n倗\n倛\n倝\n倞\n倠\n倢\n倣\n値\n倧\n倫\n倯\n倰\n倱\n倲\n倳\n倴\n倵\n倶\n倷\n倸\n倹\n倻\n倽\n倿\n偀\n偁\n偂\n偄\n偅\n偆\n偉\n偊\n偋\n偍\n偐\n偑\n偒\n偓\n偔\n偖\n偗\n偘\n偙\n偛\n偝\n偞\n偟\n偠\n偡\n偢\n偣\n偤\n偦\n偧\n偨\n偩\n偪\n偫\n偭\n偮\n偯\n偰\n偱\n偲\n偳\n側\n偵\n偸\n偹\n偺\n偼\n偽\n傁\n傂\n傃\n傄\n傆\n傇\n傉\n傊\n傋\n傌\n傎\n傏\n傐\n傑\n傒\n傓\n傔\n傕\n傖\n傗\n傘\n備\n傚\n傛\n傜\n傝\n傞\n傟\n傠\n傡\n傢\n傤\n傦\n傪\n傫\n傭\n傮\n傯\n傰\n傱\n傳\n傴\n債\n傶\n傷\n傸\n傹\n傼\n傽\n傾\n傿\n僀\n僁\n僂\n僃\n僄\n僅\n僆\n僇\n僈\n僉\n僊\n僋\n僌\n働\n僎\n僐\n僑\n僒\n僓\n僔\n僕\n僗\n僘\n僙\n僛\n僜\n僝\n僞\n僟\n僠\n僡\n僢\n僣\n僤\n僥\n僨\n僩\n僪\n僫\n僯\n僰\n僱\n僲\n僴\n僶\n僷\n僸\n價\n僺\n僼\n僽\n僾\n僿\n儀\n儁\n儂\n儃\n億\n儅\n儈\n儉\n儊\n儌\n儍\n儎\n儏\n儐\n儑\n儓\n儔\n儕\n儖\n儗\n儘\n儙\n儚\n儛\n儜\n儝\n儞\n償\n儠\n儢\n儣\n儤\n儥\n儦\n儧\n儨\n儩\n優\n儫\n儬\n儭\n儮\n儯\n儰\n儱\n儲\n儳\n儴\n儵\n儶\n儷\n儸\n儹\n儺\n儻\n儼\n儽\n儾\n兂\n兇\n兊\n兌\n兎\n兏\n児\n兒\n兓\n兗\n兘\n兙\n兛\n兝\n兞\n兟\n兠\n兡\n兣\n兤\n兦\n內\n兩\n兪\n兯\n兲\n兺\n兾\n兿\n冃\n冄\n円\n冇\n冊\n冋\n冎\n冏\n冐\n冑\n冓\n冔\n冘\n冚\n冝\n冞\n冟\n冡\n冣\n冦\n冧\n冨\n冩\n冪\n冭\n冮\n冴\n冸\n冹\n冺\n冾\n冿\n凁\n凂\n凃\n凅\n凈\n凊\n凍\n凎\n凐\n凒\n凓\n凔\n凕\n凖\n凗\n凘\n凙\n凚\n凜\n凞\n凟\n凢\n凣\n凥\n処\n凧\n凨\n凩\n凪\n凬\n凮\n凱\n凲\n凴\n凷\n凾\n刄\n刅\n刉\n刋\n刌\n刏\n刐\n刓\n刔\n刕\n刜\n刞\n刟\n刡\n刢\n刣\n別\n刦\n刧\n刪\n刬\n刯\n刱\n刲\n刴\n刵\n刼\n刾\n剄\n剅\n剆\n則\n剈\n剉\n剋\n剎\n剏\n剒\n剓\n剕\n剗\n剘\n剙\n剚\n剛\n剝\n剟\n剠\n剢\n剣\n剤\n剦\n剨\n剫\n剬\n剭\n剮\n剰\n剱\n剳\n剴\n創\n剶\n剷\n剸\n剹\n剺\n剻\n剼\n剾\n劀\n劃\n劄\n劅\n劆\n劇\n劉\n劊\n劋\n劌\n劍\n劎\n劏\n劑\n劒\n劔\n劕\n劖\n劗\n劘\n劙\n劚\n劜\n劤\n劥\n劦\n劧\n劮\n劯\n劰\n労\n劵\n劶\n劷\n劸\n効\n劺\n劻\n劼\n劽\n勀\n勁\n勂\n勄\n勅\n勆\n勈\n勊\n勌\n勍\n勎\n勏\n勑\n勓\n勔\n動\n勗\n務\n勚\n勛\n勜\n勝\n勞\n勠\n勡\n勢\n勣\n勥\n勦\n勧\n勨\n勩\n勪\n勫\n勬\n勭\n勮\n勯\n勱\n勲\n勳\n勴\n勵\n勶\n勷\n勸\n勻\n勼\n勽\n匁\n匂\n匃\n匄\n匇\n匉\n匊\n匋\n匌\n匎\n匑\n匒\n匓\n匔\n匘\n匛\n匜\n匞\n匟\n匢\n匤\n匥\n匧\n匨\n匩\n匫\n匬\n匭\n匯\n匰\n匱\n匲\n匳\n匴\n匵\n匶\n匷\n匸\n匼\n匽\n區\n卂\n卄\n卆\n卋\n卌\n卍\n卐\n協\n単\n卙\n卛\n卝\n卥\n卨\n卪\n卬\n卭\n卲\n卶\n卹\n卻\n卼\n卽\n卾\n厀\n厁\n厃\n厇\n厈\n厊\n厎\n厏\n厐\n厑\n厒\n厓\n厔\n厖\n厗\n厙\n厛\n厜\n厞\n厠\n厡\n厤\n厧\n厪\n厫\n厬\n厭\n厯\n厰\n厱\n厲\n厳\n厴\n厵\n厷\n厸\n厹\n厺\n厼\n厽\n厾\n叀\n參\n叄\n叅\n叆\n叇\n収\n叏\n叐\n叒\n叓\n叕\n叚\n叜\n叝\n叞\n叡\n叢\n叧\n叴\n叺\n叾\n叿\n吀\n吂\n吅\n吇\n吋\n吔\n吘\n吙\n吚\n吜\n吢\n吤\n吥\n吪\n吰\n吳\n吶\n吷\n吺\n吽\n吿\n呁\n呂\n呄\n呅\n呇\n呉\n呌\n呍\n呎\n呏\n呑\n呚\n呝\n呞\n呟\n呠\n呡\n呣\n呥\n呧\n呩\n呪\n呫\n呬\n呭\n呮\n呯\n呰\n呴\n呹\n呺\n呾\n呿\n咁\n咃\n咅\n咇\n咈\n咉\n咊\n咍\n咑\n咓\n咗\n咘\n咜\n咞\n咟\n咠\n咡\n咢\n咥\n咮\n咰\n咲\n咵\n咶\n咷\n咹\n咺\n咼\n咾\n哃\n哅\n哊\n哋\n哖\n哘\n哛\n哠\n員\n哢\n哣\n哤\n哫\n哬\n哯\n哰\n哱\n哴\n哵\n哶\n哷\n哸\n哹\n哻\n哾\n唀\n唂\n唃\n唄\n唅\n唈\n唊\n唋\n唌\n唍\n唎\n唒\n唓\n唕\n唖\n唗\n唘\n唙\n唚\n唜\n唝\n唞\n唟\n唡\n唥\n唦\n唨\n唩\n唫\n唭\n唲\n唴\n唵\n唶\n唸\n唹\n唺\n唻\n唽\n啀\n啂\n啅\n啇\n啈\n啋\n啌\n啍\n啎\n問\n啑\n啒\n啓\n啔\n啗\n啘\n啙\n啚\n啛\n啝\n啞\n啟\n啠\n啢\n啣\n啨\n啩\n啫\n啯\n啰\n啱\n啲\n啳\n啴\n啹\n啺\n啽\n啿\n喅\n喆\n喌\n喍\n喎\n喐\n喒\n喓\n喕\n喖\n喗\n喚\n喛\n喞\n喠\n喡\n喢\n喣\n喤\n喥\n喦\n喨\n喩\n喪\n喫\n喬\n喭\n單\n喯\n喰\n喲\n喴\n営\n喸\n喺\n喼\n喿\n嗀\n嗁\n嗂\n嗃\n嗆\n嗇\n嗈\n嗊\n嗋\n嗎\n嗏\n嗐\n嗕\n嗗\n嗘\n嗙\n嗚\n嗛\n嗞\n嗠\n嗢\n嗧\n嗩\n嗭\n嗮\n嗰\n嗱\n嗴\n嗶\n嗸\n嗹\n嗺\n嗻\n嗼\n嗿\n嘂\n嘃\n嘄\n嘅\n嘆\n嘇\n嘊\n嘋\n嘍\n嘐\n嘑\n嘒\n嘓\n嘔\n嘕\n嘖\n嘗\n嘙\n嘚\n嘜\n嘝\n嘠\n嘡\n嘢\n嘥\n嘦\n嘨\n嘩\n嘪\n嘫\n嘮\n嘯\n嘰\n嘳\n嘵\n嘷\n嘸\n嘺\n嘼\n嘽\n嘾\n噀\n噁\n噂\n噃\n噄\n噅\n噆\n噇\n噈\n噉\n噊\n噋\n噏\n噐\n噑\n噒\n噓\n噕\n噖\n噚\n噛\n噝\n噞\n噟\n噠\n噡\n噣\n噥\n噦\n噧\n噭\n噮\n噯\n噰\n噲\n噳\n噴\n噵\n噷\n噸\n噹\n噺\n噽\n噾\n噿\n嚀\n嚁\n嚂\n嚃\n嚄\n嚇\n嚈\n嚉\n嚊\n嚋\n嚌\n嚍\n嚐\n嚑\n嚒\n嚔\n嚕\n嚖\n嚗\n嚘\n嚙\n嚚\n嚛\n嚜\n嚝\n嚞\n嚟\n嚠\n嚡\n嚢\n嚤\n嚥\n嚦\n嚧\n嚨\n嚩\n嚪\n嚫\n嚬\n嚭\n嚮\n嚰\n嚱\n嚲\n嚳\n嚴\n嚵\n嚶\n嚸\n嚹\n嚺\n嚻\n嚽\n嚾\n嚿\n囀\n囁\n囂\n囃\n囄\n囅\n囆\n囇\n囈\n囉\n囋\n囌\n囍\n囎\n囏\n囐\n囑\n囒\n囓\n囕\n囖\n囘\n囙\n囜\n団\n囥\n囦\n囧\n囨\n囩\n囪\n囬\n囮\n囯\n囲\n図\n囶\n囷\n囸\n囻\n囼\n圀\n圁\n圂\n圅\n圇\n國\n圌\n圍\n圎\n圏\n圐\n圑\n園\n圓\n圔\n圕\n圖\n圗\n團\n圙\n圚\n圛\n圝\n圞\n圠\n圡\n圢\n圤\n圥\n圦\n圧\n圫\n圱\n圲\n圴\n圵\n圶\n圷\n圸\n圼\n圽\n圿\n坁\n坃\n坄\n坅\n坆\n坈\n坉\n坋\n坒\n坓\n坔\n坕\n坖\n坘\n坙\n坢\n坣\n坥\n坧\n坬\n坮\n坰\n坱\n坲\n坴\n坵\n坸\n坹\n坺\n坽\n坾\n坿\n垀\n垁\n垇\n垈\n垉\n垊\n垍\n垎\n垏\n垐\n垑\n垔\n垕\n垖\n垗\n垘\n垙\n垚\n垜\n垝\n垞\n垟\n垥\n垨\n垪\n垬\n垯\n垰\n垱\n垳\n垵\n垶\n垷\n垹\n垺\n垻\n垼\n垽\n垾\n垿\n埀\n埁\n埄\n埅\n埆\n埇\n埈\n埉\n埊\n埌\n埍\n埐\n埑\n埓\n埖\n埗\n埛\n埜\n埞\n埡\n埢\n埣\n埥\n埦\n埧\n埨\n埩\n埪\n埫\n埬\n埮\n埰\n埱\n埲\n埳\n埵\n埶\n執\n埻\n埼\n埾\n埿\n堁\n堃\n堄\n堅\n堈\n堉\n堊\n堌\n堎\n堏\n堐\n堒\n堓\n堔\n堖\n堗\n堘\n堚\n堛\n堜\n堝\n堟\n堢\n堣\n堥\n堦\n堧\n堨\n堩\n堫\n堬\n堭\n堮\n堯\n報\n堲\n堳\n場\n堶\n堷\n堸\n堹\n堺\n堻\n堼\n堽\n堾\n堿\n塀\n塁\n塂\n塃\n塅\n塆\n塇\n塈\n塉\n塊\n塋\n塎\n塏\n塐\n塒\n塓\n塕\n塖\n塗\n塙\n塚\n塛\n塜\n塝\n塟\n塠\n塡\n塢\n塣\n塤\n塦\n塧\n塨\n塩\n塪\n塭\n塮\n塯\n塰\n塱\n塲\n塳\n塴\n塵\n塶\n塷\n塸\n塹\n塺\n塻\n塼\n塽\n塿\n墂\n墄\n墆\n墇\n墈\n墊\n墋\n墌\n墍\n墎\n墏\n墐\n墑\n墔\n墕\n墖\n増\n墘\n墛\n墜\n墝\n墠\n墡\n墢\n墣\n墤\n墥\n墦\n墧\n墪\n墫\n墬\n墭\n墮\n墯\n墰\n墱\n墲\n墳\n墴\n墵\n墶\n墷\n墸\n墹\n墺\n墻\n墽\n墾\n墿\n壀\n壂\n壃\n壄\n壆\n壇\n壈\n壉\n壊\n壋\n壌\n壍\n壎\n壏\n壐\n壒\n壓\n壔\n壖\n壗\n壘\n壙\n壚\n壛\n壜\n壝\n壞\n壟\n壠\n壡\n壢\n壣\n壥\n壦\n壧\n壨\n壩\n壪\n壭\n壯\n壱\n売\n壴\n壵\n壷\n壸\n壺\n壻\n壼\n壽\n壾\n壿\n夀\n夁\n夃\n夅\n夆\n夈\n変\n夊\n夋\n夌\n夎\n夐\n夑\n夒\n夓\n夗\n夘\n夛\n夝\n夞\n夠\n夡\n夢\n夣\n夦\n夨\n夬\n夰\n夲\n夳\n夵\n夶\n夻\n夽\n夾\n夿\n奀\n奃\n奅\n奆\n奊\n奌\n奍\n奐\n奒\n奓\n奙\n奛\n奜\n奝\n奞\n奟\n奡\n奣\n奤\n奦\n奧\n奨\n奩\n奪\n奫\n奬\n奭\n奮\n奯\n奰\n奱\n奲\n奵\n奷\n奺\n奻\n奼\n奾\n奿\n妀\n妅\n妉\n妋\n妌\n妎\n妏\n妐\n妑\n妔\n妕\n妘\n妚\n妛\n妜\n妝\n妟\n妠\n妡\n妢\n妦\n妧\n妬\n妭\n妰\n妱\n妳\n妴\n妵\n妶\n妷\n妸\n妺\n妼\n妽\n妿\n姀\n姁\n姂\n姃\n姄\n姅\n姇\n姈\n姉\n姌\n姍\n姎\n姏\n姕\n姖\n姙\n姛\n姞\n姟\n姠\n姡\n姢\n姤\n姦\n姧\n姩\n姪\n姫\n姭\n姮\n姯\n姰\n姱\n姲\n姳\n姴\n姵\n姶\n姷\n姸\n姺\n姼\n姽\n姾\n娀\n娂\n娊\n娋\n娍\n娎\n娏\n娐\n娒\n娔\n娕\n娖\n娗\n娙\n娚\n娛\n娝\n娞\n娡\n娢\n娤\n娦\n娧\n娨\n娪\n娫\n娬\n娭\n娮\n娯\n娰\n娳\n娵\n娷\n娸\n娹\n娺\n娻\n娽\n娾\n娿\n婁\n婂\n婃\n婄\n婅\n婇\n婈\n婋\n婌\n婍\n婎\n婏\n婐\n婑\n婒\n婓\n婔\n婖\n婗\n婘\n婙\n婛\n婜\n婝\n婞\n婟\n婠\n婡\n婣\n婤\n婥\n婦\n婨\n婩\n婫\n婬\n婭\n婮\n婯\n婰\n婱\n婲\n婳\n婸\n婹\n婻\n婼\n婽\n婾\n媀\n媁\n媂\n媃\n媄\n媅\n媆\n媇\n媈\n媉\n媊\n媋\n媌\n媍\n媎\n媏\n媐\n媑\n媓\n媔\n媕\n媖\n媗\n媘\n媙\n媜\n媝\n媞\n媟\n媠\n媡\n媢\n媣\n媤\n媥\n媦\n媧\n媨\n媩\n媫\n媬\n媭\n媮\n媯\n媰\n媱\n媴\n媶\n媷\n媹\n媺\n媻\n媼\n媽\n媿\n嫀\n嫃\n嫄\n嫅\n嫆\n嫇\n嫈\n嫊\n嫋\n嫍\n嫎\n嫏\n嫐\n嫑\n嫓\n嫕\n嫗\n嫙\n嫚\n嫛\n嫝\n嫞\n嫟\n嫢\n嫤\n嫥\n嫧\n嫨\n嫪\n嫬\n嫭\n嫮\n嫯\n嫰\n嫲\n嫳\n嫴\n嫵\n嫶\n嫷\n嫸\n嫹\n嫺\n嫻\n嫼\n嫽\n嫾\n嫿\n嬀\n嬁\n嬂\n嬃\n嬄\n嬅\n嬆\n嬇\n嬈\n嬊\n嬋\n嬌\n嬍\n嬎\n嬏\n嬐\n嬑\n嬒\n嬓\n嬔\n嬕\n嬘\n嬙\n嬚\n嬛\n嬜\n嬝\n嬞\n嬟\n嬠\n嬡\n嬢\n嬣\n嬤\n嬥\n嬦\n嬧\n嬨\n嬩\n嬪\n嬫\n嬬\n嬭\n嬮\n嬯\n嬰\n嬱\n嬳\n嬵\n嬶\n嬸\n嬹\n嬺\n嬻\n嬼\n嬽\n嬾\n嬿\n孁\n孂\n孃\n孄\n孅\n孆\n孇\n孈\n孉\n孊\n孋\n孌\n孍\n孎\n孏\n孒\n孖\n孞\n孠\n孡\n孧\n孨\n孫\n孭\n孮\n孯\n孲\n孴\n孶\n孷\n學\n孹\n孻\n孼\n孾\n孿\n宂\n宆\n宊\n宍\n宎\n宐\n宑\n宒\n宔\n宖\n実\n宧\n宨\n宩\n宬\n宭\n宮\n宯\n宱\n宲\n宷\n宺\n宻\n宼\n寀\n寁\n寃\n寈\n寉\n寊\n寋\n寍\n寎\n寏\n寑\n寔\n寕\n寖\n寗\n寘\n寙\n寚\n寛\n寜\n寠\n寢\n寣\n實\n寧\n審\n寪\n寫\n寬\n寭\n寯\n寱\n寲\n寳\n寴\n寵\n寶\n寷\n寽\n対\n尀\n専\n尃\n尅\n將\n專\n尋\n尌\n對\n導\n尐\n尒\n尓\n尗\n尙\n尛\n尞\n尟\n尠\n尡\n尣\n尦\n尨\n尩\n尪\n尫\n尭\n尮\n尯\n尰\n尲\n尳\n尵\n尶\n尷\n屃\n屄\n屆\n屇\n屌\n屍\n屒\n屓\n屔\n屖\n屗\n屘\n屚\n屛\n屜\n屝\n屟\n屢\n層\n屧\n屨\n屩\n屪\n屫\n屬\n屭\n屰\n屲\n屳\n屴\n屵\n屶\n屷\n屸\n屻\n屼\n屽\n屾\n岀\n岃\n岄\n岅\n岆\n岇\n岉\n岊\n岋\n岎\n岏\n岒\n岓\n岕\n岝\n岞\n岟\n岠\n岡\n岤\n岥\n岦\n岧\n岨\n岪\n岮\n岯\n岰\n岲\n岴\n岶\n岹\n岺\n岻\n岼\n岾\n峀\n峂\n峃\n峅\n峆\n峇\n峈\n峉\n峊\n峌\n峍\n峎\n峏\n峐\n峑\n峓\n峔\n峕\n峖\n峗\n峘\n峚\n峛\n峜\n峝\n峞\n峟\n峠\n峢\n峣\n峧\n峩\n峫\n峬\n峮\n峯\n峱\n峲\n峳\n峴\n峵\n島\n峷\n峸\n峹\n峺\n峼\n峽\n峾\n峿\n崀\n崁\n崄\n崅\n崈\n崉\n崊\n崋\n崌\n崍\n崏\n崐\n崑\n崒\n崓\n崕\n崗\n崘\n崙\n崚\n崜\n崝\n崟\n崠\n崡\n崢\n崣\n崥\n崨\n崪\n崫\n崬\n崯\n崰\n崱\n崲\n崳\n崵\n崶\n崷\n崸\n崹\n崺\n崻\n崼\n崿\n嵀\n嵁\n嵂\n嵃\n嵄\n嵅\n嵆\n嵈\n嵉\n嵍\n嵎\n嵏\n嵐\n嵑\n嵒\n嵓\n嵔\n嵕\n嵖\n嵗\n嵙\n嵚\n嵜\n嵞\n嵟\n嵠\n嵡\n嵢\n嵣\n嵤\n嵥\n嵦\n嵧\n嵨\n嵪\n嵭\n嵮\n嵰\n嵱\n嵲\n嵳\n嵵\n嵶\n嵷\n嵸\n嵹\n嵺\n嵻\n嵼\n嵽\n嵾\n嵿\n嶀\n嶁\n嶃\n嶄\n嶅\n嶆\n嶇\n嶈\n嶉\n嶊\n嶋\n嶌\n嶍\n嶎\n嶏\n嶐\n嶑\n嶒\n嶓\n嶔\n嶕\n嶖\n嶗\n嶘\n嶚\n嶛\n嶜\n嶞\n嶟\n嶠\n嶡\n嶢\n嶣\n嶤\n嶥\n嶦\n嶧\n嶨\n嶩\n嶪\n嶫\n嶬\n嶭\n嶮\n嶯\n嶰\n嶱\n嶲\n嶳\n嶴\n嶵\n嶶\n嶸\n嶹\n嶺\n嶻\n嶼\n嶽\n嶾\n嶿\n巀\n巁\n巂\n巃\n巄\n巆\n巇\n巈\n巉\n巊\n巋\n巌\n巎\n巏\n巐\n巑\n巒\n巓\n巔\n巕\n巖\n巗\n巘\n巙\n巚\n巜\n巟\n巠\n巣\n巤\n巪\n巬\n巭\n巰\n巵\n巶\n巸\n巹\n巺\n巻\n巼\n巿\n帀\n帄\n帇\n帉\n帊\n帋\n帍\n帎\n帒\n帓\n帗\n帞\n帟\n帠\n帡\n帢\n帣\n帤\n帥\n帨\n帩\n帪\n師\n帬\n帯\n帰\n帲\n帳\n帴\n帵\n帶\n帹\n帺\n帾\n帿\n幀\n幁\n幃\n幆\n幇\n幈\n幉\n幊\n幋\n幍\n幎\n幏\n幐\n幑\n幒\n幓\n幖\n幗\n幘\n幙\n幚\n幜\n幝\n幟\n幠\n幣\n幤\n幥\n幦\n幧\n幨\n幩\n幪\n幫\n幬\n幭\n幮\n幯\n幰\n幱\n幵\n幷\n幹\n幾\n庁\n庂\n広\n庅\n庈\n庉\n庌\n庍\n庎\n庒\n庘\n庛\n庝\n庡\n庢\n庣\n庤\n庨\n庩\n庪\n庫\n庬\n庮\n庯\n庰\n庱\n庲\n庴\n庺\n庻\n庼\n庽\n庿\n廀\n廁\n廂\n廃\n廄\n廅\n廆\n廇\n廈\n廋\n廌\n廍\n廎\n廏\n廐\n廔\n廕\n廗\n廘\n廙\n廚\n廜\n廝\n廞\n廟\n廠\n廡\n廢\n廣\n廤\n廥\n廦\n廧\n廩\n廫\n廬\n廭\n廮\n廯\n廰\n廱\n廲\n廳\n廵\n廸\n廹\n廻\n廼\n廽\n弅\n弆\n弇\n弉\n弌\n弍\n弎\n弐\n弒\n弔\n弖\n弙\n弚\n弜\n弝\n弞\n弡\n弢\n弣\n弤\n弨\n弫\n弬\n弮\n弰\n弲\n弳\n弴\n張\n弶\n強\n弸\n弻\n弽\n弾\n弿\n彁\n彂\n彃\n彄\n彅\n彆\n彇\n彈\n彉\n彊\n彋\n彌\n彍\n彎\n彏\n彑\n彔\n彙\n彚\n彛\n彜\n彞\n彟\n彠\n彣\n彥\n彧\n彨\n彫\n彮\n彯\n彲\n彴\n彵\n彶\n彸\n彺\n彽\n彾\n彿\n徃\n徆\n徍\n徎\n徏\n徑\n従\n徔\n徖\n徚\n徛\n徝\n從\n徟\n徠\n徢\n徣\n徤\n徥\n徦\n徧\n復\n徫\n徬\n徯\n徰\n徱\n徲\n徳\n徴\n徶\n徸\n徹\n徺\n徻\n徾\n徿\n忀\n忁\n忂\n忇\n忈\n忊\n忋\n忎\n忓\n忔\n忕\n忚\n忛\n応\n忞\n忟\n忢\n忣\n忥\n忦\n忨\n忩\n忬\n忯\n忰\n忲\n忳\n忴\n忶\n忷\n忹\n忺\n忼\n怇\n怈\n怉\n怋\n怌\n怐\n怑\n怓\n怗\n怘\n怚\n怞\n怟\n怢\n怣\n怤\n怬\n怭\n怮\n怰\n怱\n怲\n怳\n怴\n怶\n怷\n怸\n怹\n怺\n怽\n怾\n恀\n恄\n恅\n恆\n恇\n恈\n恉\n恊\n恌\n恎\n恏\n恑\n恓\n恔\n恖\n恗\n恘\n恛\n恜\n恞\n恟\n恠\n恡\n恥\n恦\n恮\n恱\n恲\n恴\n恵\n恷\n恾\n悀\n悁\n悂\n悅\n悆\n悇\n悈\n悊\n悋\n悎\n悏\n悐\n悑\n悓\n悕\n悗\n悘\n悙\n悜\n悞\n悡\n悢\n悤\n悥\n悧\n悩\n悪\n悮\n悰\n悳\n悵\n悶\n悷\n悹\n悺\n悽\n悾\n悿\n惀\n惁\n惂\n惃\n惄\n惇\n惈\n惉\n惌\n惍\n惎\n惏\n惐\n惒\n惓\n惔\n惖\n惗\n惙\n惛\n惞\n惡\n惢\n惣\n惤\n惥\n惪\n惱\n惲\n惵\n惷\n惸\n惻\n惼\n惽\n惾\n惿\n愂\n愃\n愄\n愅\n愇\n愊\n愋\n愌\n愐\n愑\n愒\n愓\n愔\n愖\n愗\n愘\n愙\n愛\n愜\n愝\n愞\n愡\n愢\n愥\n愨\n愩\n愪\n愬\n愭\n愮\n愯\n愰\n愱\n愲\n愳\n愴\n愵\n愶\n愷\n愸\n愹\n愺\n愻\n愼\n愽\n愾\n慀\n慁\n慂\n慃\n慄\n慅\n慆\n慇\n慉\n態\n慍\n慏\n慐\n慒\n慓\n慔\n慖\n慗\n慘\n慙\n慚\n慛\n慜\n慞\n慟\n慠\n慡\n慣\n慤\n慥\n慦\n慩\n慪\n慫\n慬\n慭\n慮\n慯\n慱\n慲\n慳\n慴\n慶\n慸\n慹\n慺\n慻\n慼\n慽\n慾\n慿\n憀\n憁\n憂\n憃\n憄\n憅\n憆\n憇\n憈\n憉\n憊\n憌\n憍\n憏\n憐\n憑\n憒\n憓\n憕\n憖\n憗\n憘\n憙\n憚\n憛\n憜\n憞\n憟\n憠\n憡\n憢\n憣\n憤\n憥\n憦\n憪\n憫\n憭\n憮\n憯\n憰\n憱\n憲\n憳\n憴\n憵\n憶\n憸\n憹\n憺\n憻\n憼\n憽\n憿\n懀\n懁\n懃\n懄\n懅\n懆\n懇\n應\n懌\n懍\n懎\n懏\n懐\n懓\n懕\n懖\n懗\n懘\n懙\n懚\n懛\n懜\n懝\n懞\n懟\n懠\n懡\n懢\n懣\n懤\n懥\n懧\n懨\n懩\n懪\n懫\n懬\n懭\n懮\n懯\n懰\n懱\n懲\n懳\n懴\n懶\n懷\n懸\n懹\n懺\n懻\n懼\n懽\n懾\n戀\n戁\n戂\n戃\n戄\n戅\n戇\n戉\n戓\n戔\n戙\n戜\n戝\n戞\n戠\n戣\n戦\n戧\n戨\n戩\n戫\n戭\n戯\n戰\n戱\n戲\n戵\n戶\n戸\n戹\n戺\n戻\n戼\n扂\n扄\n扅\n扆\n扊\n扏\n扐\n払\n扖\n扗\n扙\n扚\n扜\n扝\n扞\n扟\n扠\n扡\n扢\n扤\n扥\n扨\n扱\n扲\n扴\n扵\n扷\n扸\n扺\n扻\n扽\n抁\n抂\n抃\n抅\n抆\n抇\n抈\n抋\n抌\n抍\n抎\n抏\n抐\n抔\n抙\n抜\n抝\n択\n抣\n抦\n抧\n抩\n抪\n抭\n抮\n抯\n抰\n抲\n抳\n抴\n抶\n抷\n抸\n抺\n抾\n拀\n拁\n拃\n拋\n拏\n拑\n拕\n拝\n拞\n拠\n拡\n拤\n拪\n拫\n拰\n拲\n拵\n拸\n拹\n拺\n拻\n挀\n挃\n挄\n挅\n挆\n挊\n挋\n挌\n挍\n挏\n挐\n挒\n挓\n挔\n挕\n挗\n挘\n挙\n挜\n挦\n挧\n挩\n挬\n挭\n挮\n挰\n挱\n挳\n挴\n挵\n挶\n挷\n挸\n挻\n挼\n挾\n挿\n捀\n捁\n捄\n捇\n捈\n捊\n捑\n捒\n捓\n捔\n捖\n捗\n捘\n捙\n捚\n捛\n捜\n捝\n捠\n捤\n捥\n捦\n捨\n捪\n捫\n捬\n捯\n捰\n捲\n捳\n捴\n捵\n捸\n捹\n捼\n捽\n捾\n捿\n掁\n掃\n掄\n掅\n掆\n掋\n掍\n掑\n掓\n掔\n掕\n掗\n掙\n掚\n掛\n掜\n掝\n掞\n掟\n採\n掤\n掦\n掫\n掯\n掱\n掲\n掵\n掶\n掹\n掻\n掽\n掿\n揀\n揁\n揂\n揃\n揅\n揇\n揈\n揊\n揋\n揌\n揑\n揓\n揔\n揕\n揗\n揘\n揙\n揚\n換\n揜\n揝\n揟\n揢\n揤\n揥\n揦\n揧\n揨\n揫\n揬\n揮\n揯\n揰\n揱\n揳\n揵\n揷\n揹\n揺\n揻\n揼\n揾\n搃\n搄\n搆\n搇\n搈\n搉\n搊\n損\n搎\n搑\n搒\n搕\n搖\n搗\n搘\n搙\n搚\n搝\n搟\n搢\n搣\n搤\n搥\n搧\n搨\n搩\n搫\n搮\n搯\n搰\n搱\n搲\n搳\n搵\n搶\n搷\n搸\n搹\n搻\n搼\n搾\n摀\n摂\n摃\n摉\n摋\n摌\n摍\n摎\n摏\n摐\n摑\n摓\n摕\n摖\n摗\n摙\n摚\n摛\n摜\n摝\n摟\n摠\n摡\n摢\n摣\n摤\n摥\n摦\n摨\n摪\n摫\n摬\n摮\n摯\n摰\n摱\n摲\n摳\n摴\n摵\n摶\n摷\n摻\n摼\n摽\n摾\n摿\n撀\n撁\n撃\n撆\n撈\n撉\n撊\n撋\n撌\n撍\n撎\n撏\n撐\n撓\n撔\n撗\n撘\n撚\n撛\n撜\n撝\n撟\n撠\n撡\n撢\n撣\n撥\n撦\n撧\n撨\n撪\n撫\n撯\n撱\n撲\n撳\n撴\n撶\n撹\n撻\n撽\n撾\n撿\n擁\n擃\n擄\n擆\n擇\n擈\n擉\n擊\n擋\n擌\n擏\n擑\n擓\n擔\n擕\n擖\n擙\n據\n擛\n擜\n擝\n擟\n擠\n擡\n擣\n擥\n擧\n擨\n擩\n擪\n擫\n擬\n擭\n擮\n擯\n擰\n擱\n擲\n擳\n擴\n擵\n擶\n擷\n擸\n擹\n擺\n擻\n擼\n擽\n擾\n擿\n攁\n攂\n攃\n攄\n攅\n攆\n攇\n攈\n攊\n攋\n攌\n攍\n攎\n攏\n攐\n攑\n攓\n攔\n攕\n攖\n攗\n攙\n攚\n攛\n攜\n攝\n攞\n攟\n攠\n攡\n攢\n攣\n攤\n攦\n攧\n攨\n攩\n攪\n攬\n攭\n攰\n攱\n攲\n攳\n攷\n攺\n攼\n攽\n敀\n敁\n敂\n敃\n敄\n敆\n敇\n敊\n敋\n敍\n敎\n敐\n敒\n敓\n敔\n敗\n敘\n敚\n敜\n敟\n敠\n敡\n敤\n敥\n敧\n敨\n敩\n敪\n敭\n敮\n敯\n敱\n敳\n敵\n敶\n數\n敹\n敺\n敻\n敼\n敽\n敾\n敿\n斀\n斁\n斂\n斃\n斄\n斅\n斆\n斈\n斉\n斊\n斍\n斎\n斏\n斒\n斔\n斕\n斖\n斘\n斚\n斝\n斞\n斠\n斢\n斣\n斦\n斨\n斪\n斬\n斮\n斱\n斲\n斳\n斴\n斵\n斶\n斷\n斸\n斺\n斻\n斾\n斿\n旀\n旂\n旇\n旈\n旉\n旊\n旍\n旐\n旑\n旓\n旔\n旕\n旘\n旙\n旚\n旛\n旜\n旝\n旞\n旟\n旡\n旣\n旤\n旪\n旫\n旲\n旳\n旴\n旵\n旸\n旹\n旻\n旼\n旽\n旾\n旿\n昁\n昄\n昅\n昇\n昈\n昉\n昋\n昍\n昐\n昑\n昒\n昖\n昗\n昘\n昚\n昛\n昜\n昞\n昡\n昢\n昣\n昤\n昦\n昩\n昪\n昫\n昬\n昮\n昰\n昲\n昳\n昷\n昸\n昹\n昺\n昻\n昽\n昿\n晀\n時\n晄\n晅\n晆\n晇\n晈\n晉\n晊\n晍\n晎\n晐\n晑\n晘\n晙\n晛\n晜\n晝\n晞\n晠\n晢\n晣\n晥\n晧\n晩\n晪\n晫\n晬\n晭\n晱\n晲\n晳\n晵\n晸\n晹\n晻\n晼\n晽\n晿\n暀\n暁\n暃\n暅\n暆\n暈\n暉\n暊\n暋\n暍\n暎\n暏\n暐\n暒\n暓\n暔\n暕\n暘\n暙\n暚\n暛\n暜\n暞\n暟\n暠\n暡\n暢\n暣\n暤\n暥\n暦\n暩\n暪\n暫\n暬\n暭\n暯\n暰\n暱\n暲\n暳\n暵\n暶\n暷\n暸\n暺\n暻\n暼\n暽\n暿\n曀\n曁\n曂\n曃\n曄\n曅\n曆\n曇\n曈\n曉\n曊\n曋\n曌\n曍\n曎\n曏\n曐\n曑\n曒\n曓\n曔\n曕\n曖\n曗\n曘\n曚\n曞\n曟\n曠\n曡\n曢\n曣\n曤\n曥\n曧\n曨\n曪\n曫\n曬\n曭\n曮\n曯\n曱\n曵\n曶\n書\n曺\n曻\n曽\n朁\n朂\n會\n朄\n朅\n朆\n朇\n朌\n朎\n朏\n朑\n朒\n朓\n朖\n朘\n朙\n朚\n朜\n朞\n朠\n朡\n朢\n朣\n朤\n朥\n朧\n朩\n朮\n朰\n朲\n朳\n朶\n朷\n朸\n朹\n朻\n朼\n朾\n朿\n杁\n杄\n杅\n杇\n杊\n杋\n杍\n杒\n杔\n杕\n杗\n杘\n杙\n杚\n杛\n杝\n杢\n杣\n杤\n杦\n杧\n杫\n杬\n杮\n東\n杴\n杶\n杸\n杹\n杺\n杻\n杽\n枀\n枂\n枃\n枅\n枆\n枈\n枊\n枌\n枍\n枎\n枏\n枑\n枒\n枓\n枔\n枖\n枙\n枛\n枟\n枠\n枡\n枤\n枦\n枩\n枬\n枮\n枱\n枲\n枴\n枹\n枺\n枻\n枼\n枽\n枾\n枿\n柀\n柂\n柅\n柆\n柇\n柈\n柉\n柊\n柋\n柌\n柍\n柎\n柕\n柖\n柗\n柛\n柟\n柡\n柣\n柤\n柦\n柧\n柨\n柪\n柫\n柭\n柮\n柲\n柵\n柶\n柷\n柸\n柹\n柺\n査\n柼\n柾\n栁\n栂\n栃\n栄\n栆\n栍\n栐\n栒\n栔\n栕\n栘\n栙\n栚\n栛\n栜\n栞\n栟\n栠\n栢\n栣\n栤\n栥\n栦\n栧\n栨\n栫\n栬\n栭\n栮\n栯\n栰\n栱\n栴\n栵\n栶\n栺\n栻\n栿\n桇\n桋\n桍\n桏\n桒\n桖\n桗\n桘\n桙\n桚\n桛\n桜\n桝\n桞\n桟\n桪\n桬\n桭\n桮\n桯\n桰\n桱\n桲\n桳\n桵\n桸\n桹\n桺\n桻\n桼\n桽\n桾\n桿\n梀\n梂\n梄\n梇\n梈\n梉\n梊\n梋\n梌\n梍\n梎\n梐\n梑\n梒\n梔\n梕\n梖\n梘\n梙\n梚\n梛\n梜\n條\n梞\n梟\n梠\n梡\n梣\n梤\n梥\n梩\n梪\n梫\n梬\n梮\n梱\n梲\n梴\n梶\n梷\n梸\n梹\n梺\n梻\n梼\n梽\n梾\n梿\n棁\n棃\n棄\n棅\n棆\n棇\n棈\n棊\n棌\n棎\n棏\n棐\n棑\n棓\n棔\n棖\n棗\n棙\n棛\n棜\n棝\n棞\n棟\n棡\n棢\n棤\n棥\n棦\n棧\n棨\n棩\n棪\n棫\n棬\n棭\n棯\n棲\n棳\n棴\n棶\n棷\n棸\n棻\n棽\n棾\n棿\n椀\n椂\n椃\n椄\n椆\n椇\n椈\n椉\n椊\n椌\n椏\n椑\n椓\n椔\n椕\n椖\n椗\n椘\n椙\n椚\n椛\n検\n椝\n椞\n椡\n椢\n椣\n椥\n椦\n椧\n椨\n椩\n椪\n椫\n椬\n椮\n椯\n椱\n椲\n椳\n椵\n椶\n椷\n椸\n椺\n椻\n椼\n椾\n楀\n楁\n楃\n楄\n楅\n楆\n楇\n楈\n楉\n楊\n楋\n楌\n楍\n楎\n楏\n楐\n楑\n楒\n楓\n楕\n楖\n楘\n楙\n楛\n楜\n楟\n楡\n楢\n楤\n楥\n楧\n楨\n楩\n楪\n楬\n業\n楯\n楰\n楲\n楳\n楴\n極\n楶\n楺\n楻\n楽\n楾\n楿\n榁\n榃\n榅\n榊\n榋\n榌\n榎\n榏\n榐\n榑\n榒\n榓\n榖\n榗\n榙\n榚\n榝\n榞\n榟\n榠\n榡\n榢\n榣\n榤\n榥\n榦\n榩\n榪\n榬\n榮\n榯\n榰\n榲\n榳\n榵\n榶\n榸\n榹\n榺\n榼\n榽\n榾\n榿\n槀\n槂\n槃\n槄\n槅\n槆\n槇\n槈\n槉\n構\n槍\n槏\n槑\n槒\n槓\n槕\n槖\n槗\n様\n槙\n槚\n槜\n槝\n槞\n槡\n槢\n槣\n槤\n槥\n槦\n槧\n槨\n槩\n槪\n槫\n槬\n槮\n槯\n槰\n槱\n槳\n槴\n槵\n槶\n槷\n槸\n槹\n槺\n槻\n槼\n槾\n樀\n樁\n樂\n樃\n樄\n樅\n樆\n樇\n樈\n樉\n樋\n樌\n樍\n樎\n樏\n樐\n樑\n樒\n樓\n樔\n樕\n樖\n標\n樚\n樛\n樜\n樝\n樞\n樠\n樢\n樣\n樤\n樥\n樦\n樧\n権\n樫\n樬\n樭\n樮\n樰\n樲\n樳\n樴\n樶\n樷\n樸\n樹\n樺\n樻\n樼\n樿\n橀\n橁\n橂\n橃\n橅\n橆\n橈\n橉\n橊\n橋\n橌\n橍\n橎\n橏\n橑\n橒\n橓\n橔\n橕\n橖\n橗\n橚\n橜\n橝\n橞\n機\n橠\n橢\n橣\n橤\n橦\n橧\n橨\n橩\n橪\n橫\n橬\n橭\n橮\n橯\n橰\n橲\n橳\n橴\n橵\n橶\n橷\n橸\n橺\n橻\n橽\n橾\n橿\n檁\n檂\n檃\n檅\n檆\n檇\n檈\n檉\n檊\n檋\n檌\n檍\n檏\n檒\n檓\n檔\n檕\n檖\n檘\n檙\n檚\n檛\n檜\n檝\n檞\n檟\n檡\n檢\n檣\n檤\n檥\n檦\n檧\n檨\n檪\n檭\n檮\n檯\n檰\n檱\n檲\n檳\n檴\n檵\n檶\n檷\n檸\n檹\n檺\n檻\n檼\n檽\n檾\n檿\n櫀\n櫁\n櫂\n櫃\n櫄\n櫅\n櫆\n櫇\n櫈\n櫉\n櫊\n櫋\n櫌\n櫍\n櫎\n櫏\n櫐\n櫑\n櫒\n櫓\n櫔\n櫕\n櫖\n櫗\n櫘\n櫙\n櫚\n櫛\n櫜\n櫝\n櫞\n櫟\n櫠\n櫡\n櫢\n櫣\n櫤\n櫥\n櫦\n櫧\n櫨\n櫩\n櫪\n櫫\n櫬\n櫭\n櫮\n櫯\n櫰\n櫱\n櫲\n櫳\n櫴\n櫵\n櫶\n櫷\n櫸\n櫹\n櫺\n櫻\n櫼\n櫽\n櫾\n櫿\n欀\n欁\n欂\n欃\n欄\n欅\n欆\n欇\n欈\n欉\n權\n欋\n欌\n欍\n欎\n欏\n欐\n欑\n欒\n欓\n欔\n欕\n欖\n欗\n欘\n欙\n欚\n欛\n欜\n欝\n欞\n欟\n欥\n欦\n欨\n欩\n欪\n欫\n欬\n欭\n欮\n欯\n欰\n欱\n欳\n欴\n欵\n欶\n欸\n欻\n欼\n欽\n欿\n歀\n歁\n歂\n歄\n歅\n歈\n歊\n歋\n歍\n歎\n歏\n歐\n歑\n歒\n歓\n歔\n歕\n歖\n歗\n歘\n歚\n歛\n歜\n歝\n歞\n歟\n歠\n歡\n歨\n歩\n歫\n歬\n歭\n歮\n歯\n歰\n歱\n歲\n歳\n歴\n歵\n歶\n歷\n歸\n歺\n歽\n歾\n歿\n殀\n殅\n殈\n殌\n殎\n殏\n殐\n殑\n殔\n殕\n殗\n殘\n殙\n殜\n殝\n殞\n殟\n殠\n殢\n殣\n殤\n殥\n殦\n殧\n殨\n殩\n殫\n殬\n殭\n殮\n殯\n殰\n殱\n殲\n殶\n殸\n殹\n殺\n殻\n殼\n殽\n殾\n毀\n毃\n毄\n毆\n毇\n毈\n毉\n毊\n毌\n毎\n毐\n毑\n毘\n毚\n毜\n毝\n毞\n毟\n毠\n毢\n毣\n毤\n毥\n毦\n毧\n毨\n毩\n毬\n毭\n毮\n毰\n毱\n毲\n毴\n毶\n毷\n毸\n毺\n毻\n毼\n毾\n毿\n氀\n氁\n氂\n氃\n氄\n氈\n氉\n氊\n氋\n氌\n氎\n氒\n気\n氜\n氝\n氞\n氠\n氣\n氥\n氫\n氬\n氭\n氱\n氳\n氶\n氷\n氹\n氺\n氻\n氼\n氾\n氿\n汃\n汄\n汅\n汈\n汋\n汌\n汍\n汎\n汏\n汑\n汒\n汓\n汖\n汘\n汙\n汚\n汢\n汣\n汥\n汦\n汧\n汫\n汬\n汭\n汮\n汯\n汱\n汳\n汵\n汷\n汸\n決\n汻\n汼\n汿\n沀\n沄\n沇\n沊\n沋\n沍\n沎\n沑\n沒\n沕\n沖\n沗\n沘\n沚\n沜\n沝\n沞\n沠\n沢\n沨\n沬\n沯\n沰\n沴\n沵\n沶\n沷\n沺\n泀\n況\n泂\n泃\n泆\n泇\n泈\n泋\n泍\n泎\n泏\n泑\n泒\n泘\n泙\n泚\n泜\n泝\n泟\n泤\n泦\n泧\n泩\n泬\n泭\n泲\n泴\n泹\n泿\n洀\n洂\n洃\n洅\n洆\n洈\n洉\n洊\n洍\n洏\n洐\n洑\n洓\n洔\n洕\n洖\n洘\n洜\n洝\n洟\n洠\n洡\n洢\n洣\n洤\n洦\n洨\n洩\n洬\n洭\n洯\n洰\n洴\n洶\n洷\n洸\n洺\n洿\n浀\n浂\n浄\n浉\n浌\n浐\n浕\n浖\n浗\n浘\n浛\n浝\n浟\n浡\n浢\n浤\n浥\n浧\n浨\n浫\n浬\n浭\n浰\n浱\n浲\n浳\n浵\n浶\n浹\n浺\n浻\n浽\n浾\n浿\n涀\n涁\n涃\n涄\n涆\n涇\n涊\n涋\n涍\n涏\n涐\n涒\n涖\n涗\n涘\n涙\n涚\n涜\n涢\n涥\n涬\n涭\n涰\n涱\n涳\n涴\n涶\n涷\n涹\n涺\n涻\n涼\n涽\n涾\n淁\n淂\n淃\n淈\n淉\n淊\n淍\n淎\n淏\n淐\n淒\n淓\n淔\n淕\n淗\n淚\n淛\n淜\n淟\n淢\n淣\n淥\n淧\n淨\n淩\n淪\n淭\n淯\n淰\n淲\n淴\n淵\n淶\n淸\n淺\n淽\n淾\n淿\n渀\n渁\n渂\n渃\n渄\n渆\n渇\n済\n渉\n渋\n渏\n渒\n渓\n渕\n渘\n渙\n減\n渜\n渞\n渟\n渢\n渦\n渧\n渨\n渪\n測\n渮\n渰\n渱\n渳\n渵\n渶\n渷\n渹\n渻\n渼\n渽\n渾\n渿\n湀\n湁\n湂\n湅\n湆\n湇\n湈\n湉\n湊\n湋\n湌\n湏\n湐\n湑\n湒\n湕\n湗\n湙\n湚\n湜\n湝\n湞\n湠\n湡\n湢\n湣\n湤\n湥\n湦\n湧\n湨\n湩\n湪\n湬\n湭\n湯\n湰\n湱\n湲\n湳\n湴\n湵\n湶\n湷\n湸\n湹\n湺\n湻\n湼\n湽\n満\n溁\n溂\n溄\n溇\n溈\n溊\n溋\n溌\n溍\n溎\n溑\n溒\n溓\n溔\n溕\n準\n溗\n溙\n溚\n溛\n溝\n溞\n溠\n溡\n溣\n溤\n溦\n溨\n溩\n溫\n溬\n溭\n溮\n溰\n溳\n溵\n溸\n溹\n溼\n溾\n溿\n滀\n滃\n滄\n滅\n滆\n滈\n滉\n滊\n滌\n滍\n滎\n滐\n滒\n滖\n滘\n滙\n滛\n滜\n滝\n滣\n滧\n滪\n滫\n滬\n滭\n滮\n滯\n滰\n滱\n滲\n滳\n滵\n滶\n滷\n滸\n滺\n滻\n滼\n滽\n滾\n滿\n漀\n漁\n漃\n漄\n漅\n漇\n漈\n漊\n漋\n漌\n漍\n漎\n漐\n漑\n漒\n漖\n漗\n漘\n漙\n漚\n漛\n漜\n漝\n漞\n漟\n漡\n漢\n漣\n漥\n漦\n漧\n漨\n漬\n漮\n漰\n漲\n漴\n漵\n漷\n漸\n漹\n漺\n漻\n漼\n漽\n漿\n潀\n潁\n潂\n潃\n潄\n潅\n潈\n潉\n潊\n潌\n潎\n潏\n潐\n潑\n潒\n潓\n潔\n潕\n潖\n潗\n潙\n潚\n潛\n潝\n潟\n潠\n潡\n潣\n潤\n潥\n潧\n潨\n潩\n潪\n潫\n潬\n潯\n潰\n潱\n潳\n潵\n潶\n潷\n潹\n潻\n潽\n潾\n潿\n澀\n澁\n澂\n澃\n澅\n澆\n澇\n澊\n澋\n澏\n澐\n澑\n澒\n澓\n澔\n澕\n澖\n澗\n澘\n澙\n澚\n澛\n澝\n澞\n澟\n澠\n澢\n澣\n澤\n澥\n澦\n澨\n澩\n澪\n澫\n澬\n澭\n澮\n澯\n澰\n澱\n澲\n澴\n澵\n澷\n澸\n澺\n澻\n澼\n澽\n澾\n澿\n濁\n濃\n濄\n濅\n濆\n濇\n濈\n濊\n濋\n濌\n濍\n濎\n濏\n濐\n濓\n濔\n濕\n濖\n濗\n濘\n濙\n濚\n濛\n濜\n濝\n濟\n濢\n濣\n濤\n濥\n濦\n濧\n濨\n濩\n濪\n濫\n濬\n濭\n濰\n濱\n濲\n濳\n濴\n濵\n濶\n濷\n濸\n濹\n濺\n濻\n濼\n濽\n濾\n濿\n瀀\n瀁\n瀂\n瀃\n瀄\n瀅\n瀆\n瀇\n瀈\n瀉\n瀊\n瀋\n瀌\n瀍\n瀎\n瀏\n瀐\n瀒\n瀓\n瀔\n瀕\n瀖\n瀗\n瀘\n瀙\n瀜\n瀝\n瀞\n瀟\n瀠\n瀡\n瀢\n瀤\n瀥\n瀦\n瀧\n瀨\n瀩\n瀪\n瀫\n瀬\n瀭\n瀮\n瀯\n瀰\n瀱\n瀲\n瀳\n瀴\n瀶\n瀷\n瀸\n瀺\n瀻\n瀼\n瀽\n瀾\n瀿\n灀\n灁\n灂\n灃\n灄\n灅\n灆\n灇\n灈\n灉\n灊\n灋\n灍\n灎\n灐\n灑\n灒\n灓\n灔\n灕\n灖\n灗\n灘\n灙\n灚\n灛\n灜\n灝\n灟\n灠\n灡\n灢\n灣\n灤\n灥\n灦\n灧\n灨\n灩\n灪\n灮\n灱\n灲\n灳\n灴\n灷\n灹\n灺\n灻\n災\n炁\n炂\n炃\n炄\n炆\n炇\n炈\n炋\n炌\n炍\n炏\n炐\n炑\n炓\n炗\n炘\n炚\n炛\n炞\n炟\n炠\n炡\n炢\n炣\n炤\n炥\n炦\n炧\n炨\n炩\n炪\n炰\n炲\n炴\n炵\n炶\n為\n炾\n炿\n烄\n烅\n烆\n烇\n烉\n烋\n烌\n烍\n烎\n烏\n烐\n烑\n烒\n烓\n烔\n烕\n烖\n烗\n烚\n烜\n烝\n烞\n烠\n烡\n烢\n烣\n烥\n烪\n烮\n烰\n烱\n烲\n烳\n烴\n烵\n烶\n烸\n烺\n烻\n烼\n烾\n烿\n焀\n焁\n焂\n焃\n焄\n焅\n焆\n焇\n焈\n焋\n焌\n焍\n焎\n焏\n焑\n焒\n焔\n焗\n焛\n焜\n焝\n焞\n焟\n焠\n無\n焢\n焣\n焤\n焥\n焧\n焨\n焩\n焪\n焫\n焬\n焭\n焮\n焲\n焳\n焴\n焵\n焷\n焸\n焹\n焺\n焻\n焼\n焽\n焾\n焿\n煀\n煁\n煂\n煃\n煄\n煆\n煇\n煈\n煉\n煋\n煍\n煏\n煐\n煑\n煒\n煓\n煔\n煕\n煖\n煗\n煘\n煙\n煚\n煛\n煝\n煟\n煠\n煡\n煢\n煣\n煥\n煩\n煪\n煫\n煬\n煭\n煯\n煰\n煱\n煴\n煵\n煶\n煷\n煹\n煻\n煼\n煾\n煿\n熀\n熁\n熂\n熃\n熅\n熆\n熇\n熈\n熉\n熋\n熌\n熍\n熎\n熐\n熑\n熒\n熓\n熕\n熖\n熗\n熚\n熛\n熜\n熝\n熞\n熡\n熢\n熣\n熤\n熥\n熦\n熧\n熩\n熪\n熫\n熭\n熮\n熯\n熰\n熱\n熲\n熴\n熶\n熷\n熸\n熺\n熻\n熼\n熽\n熾\n熿\n燀\n燁\n燂\n燄\n燅\n燆\n燇\n燈\n燉\n燊\n燋\n燌\n燍\n燏\n燐\n燑\n燒\n燓\n燖\n燗\n燘\n燙\n燚\n燛\n燜\n燝\n燞\n營\n燡\n燢\n燣\n燤\n燦\n燨\n燩\n燪\n燫\n燬\n燭\n燯\n燰\n燱\n燲\n燳\n燴\n燵\n燶\n燷\n燸\n燺\n燻\n燼\n燽\n燾\n燿\n爀\n爁\n爂\n爃\n爄\n爅\n爇\n爈\n爉\n爊\n爋\n爌\n爍\n爎\n爏\n爐\n爑\n爒\n爓\n爔\n爕\n爖\n爗\n爘\n爙\n爚\n爛\n爜\n爞\n爟\n爠\n爡\n爢\n爣\n爤\n爥\n爦\n爧\n爩\n爫\n爭\n爮\n爯\n爲\n爳\n爴\n爺\n爼\n爾\n牀\n牁\n牂\n牃\n牄\n牅\n牆\n牉\n牊\n牋\n牎\n牏\n牐\n牑\n牓\n牔\n牕\n牗\n牘\n牚\n牜\n牞\n牠\n牣\n牤\n牥\n牨\n牪\n牫\n牬\n牭\n牰\n牱\n牳\n牴\n牶\n牷\n牸\n牻\n牼\n牽\n犂\n犃\n犅\n犆\n犇\n犈\n犉\n犌\n犎\n犐\n犑\n犓\n犔\n犕\n犖\n犗\n犘\n犙\n犚\n犛\n犜\n犝\n犞\n犠\n犡\n犢\n犣\n犤\n犥\n犦\n犧\n犨\n犩\n犪\n犫\n犮\n犱\n犲\n犳\n犵\n犺\n犻\n犼\n犽\n犾\n犿\n狀\n狅\n狆\n狇\n狉\n狊\n狋\n狌\n狏\n狑\n狓\n狔\n狕\n狖\n狘\n狚\n狛\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n　\n、\n。\n·\nˉ\nˇ\n¨\n〃\n々\n—\n～\n‖\n…\n‘\n’\n“\n”\n〔\n〕\n〈\n〉\n《\n》\n「\n」\n『\n』\n〖\n〗\n【\n】\n±\n×\n÷\n∶\n∧\n∨\n∑\n∏\n∪\n∩\n∈\n∷\n√\n⊥\n∥\n∠\n⌒\n⊙\n∫\n∮\n≡\n≌\n≈\n∽\n∝\n≠\n≮\n≯\n≤\n≥\n∞\n∵\n∴\n♂\n♀\n°\n′\n″\n℃\n＄\n¤\n￠\n￡\n‰\n§\n№\n☆\n★\n○\n●\n◎\n◇\n◆\n□\n■\n△\n▲\n※\n→\n←\n↑\n↓\n〓\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\n\n\n\n\n\n\n⒈\n⒉\n⒊\n⒋\n⒌\n⒍\n⒎\n⒏\n⒐\n⒑\n⒒\n⒓\n⒔\n⒕\n⒖\n⒗\n⒘\n⒙\n⒚\n⒛\n⑴\n⑵\n⑶\n⑷\n⑸\n⑹\n⑺\n⑻\n⑼\n⑽\n⑾\n⑿\n⒀\n⒁\n⒂\n⒃\n⒄\n⒅\n⒆\n⒇\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n€\n\n㈠\n㈡\n㈢\n㈣\n㈤\n㈥\n㈦\n㈧\n㈨\n㈩\n\n\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\nⅪ\nⅫ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n！\n＂\n＃\n￥\n％\n＆\n＇\n（\n）\n＊\n＋\n，\n－\n．\n／\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\n：\n；\n＜\n＝\n＞\n？\n＠\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\n［\n＼\n］\n＾\n＿\n｀\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\n｛\n｜\n｝\n￣\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\n\n\n\n\n\n\n\n\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\n︐\n︒\n︑\n︓\n︔\n︕\n︖\n︵\n︶\n︹\n︺\n︿\n﹀\n︽\n︾\n﹁\n﹂\n﹃\n﹄\n︗\n︘\n︻\n︼\n︷\n︸\n︱\n︙\n︳\n︴\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n\n\n\n\n\n\n\n\n\n\n\n\n\nˊ\nˋ\n˙\n–\n―\n‥\n‵\n℅\n℉\n↖\n↗\n↘\n↙\n∕\n∟\n∣\n≒\n≦\n≧\n⊿\n═\n║\n╒\n╓\n╔\n╕\n╖\n╗\n╘\n╙\n╚\n╛\n╜\n╝\n╞\n╟\n╠\n╡\n╢\n╣\n╤\n╥\n╦\n╧\n╨\n╩\n╪\n╫\n╬\n╭\n╮\n╯\n╰\n╱\n╲\n╳\n▁\n▂\n▃\n▄\n▅\n▆\n▇\n█\n▉\n▊\n▋\n▌\n▍\n▎\n▏\n▓\n▔\n▕\n▼\n▽\n◢\n◣\n◤\n◥\n☉\n⊕\n〒\n〝\n〞\n\n\n\n\n\n\n\n\n\n\n\nā\ná\nǎ\nà\nē\né\ně\nè\nī\ní\nǐ\nì\nō\nó\nǒ\nò\nū\nú\nǔ\nù\nǖ\nǘ\nǚ\nǜ\nü\nê\nɑ\nḿ\nń\nň\nǹ\nɡ\n\n\n\n\nㄅ\nㄆ\nㄇ\nㄈ\nㄉ\nㄊ\nㄋ\nㄌ\nㄍ\nㄎ\nㄏ\nㄐ\nㄑ\nㄒ\nㄓ\nㄔ\nㄕ\nㄖ\nㄗ\nㄘ\nㄙ\nㄚ\nㄛ\nㄜ\nㄝ\nㄞ\nㄟ\nㄠ\nㄡ\nㄢ\nㄣ\nㄤ\nㄥ\nㄦ\nㄧ\nㄨ\nㄩ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n〡\n〢\n〣\n〤\n〥\n〦\n〧\n〨\n〩\n㊣\n㎎\n㎏\n㎜\n㎝\n㎞\n㎡\n㏄\n㏎\n㏑\n㏒\n㏕\n︰\n￢\n￤\n\n℡\n㈱\n\n‐\n\n\n\nー\n゛\n゜\nヽ\nヾ\n〆\nゝ\nゞ\n﹉\n﹊\n﹋\n﹌\n﹍\n﹎\n﹏\n﹐\n﹑\n﹒\n﹔\n﹕\n﹖\n﹗\n﹙\n﹚\n﹛\n﹜\n﹝\n﹞\n﹟\n﹠\n﹡\n﹢\n﹣\n﹤\n﹥\n﹦\n﹨\n﹩\n﹪\n﹫\n〾\n⿰\n⿱\n⿲\n⿳\n⿴\n⿵\n⿶\n⿷\n⿸\n⿹\n⿺\n⿻\n〇\n\n\n\n\n\n\n\n\n\n\n\n\n\n─\n━\n│\n┃\n┄\n┅\n┆\n┇\n┈\n┉\n┊\n┋\n┌\n┍\n┎\n┏\n┐\n┑\n┒\n┓\n└\n┕\n┖\n┗\n┘\n┙\n┚\n┛\n├\n┝\n┞\n┟\n┠\n┡\n┢\n┣\n┤\n┥\n┦\n┧\n┨\n┩\n┪\n┫\n┬\n┭\n┮\n┯\n┰\n┱\n┲\n┳\n┴\n┵\n┶\n┷\n┸\n┹\n┺\n┻\n┼\n┽\n┾\n┿\n╀\n╁\n╂\n╃\n╄\n╅\n╆\n╇\n╈\n╉\n╊\n╋\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n狜\n狝\n狟\n狢\n狣\n狤\n狥\n狦\n狧\n狪\n狫\n狵\n狶\n狹\n狽\n狾\n狿\n猀\n猂\n猄\n猅\n猆\n猇\n猈\n猉\n猋\n猌\n猍\n猏\n猐\n猑\n猒\n猔\n猘\n猙\n猚\n猟\n猠\n猣\n猤\n猦\n猧\n猨\n猭\n猯\n猰\n猲\n猳\n猵\n猶\n猺\n猻\n猼\n猽\n獀\n獁\n獂\n獃\n獄\n獅\n獆\n獇\n獈\n獉\n獊\n獋\n獌\n獎\n獏\n獑\n獓\n獔\n獕\n獖\n獘\n獙\n獚\n獛\n獜\n獝\n獞\n獟\n獡\n獢\n獣\n獤\n獥\n獦\n獧\n獨\n獩\n獪\n獫\n獮\n獰\n獱\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n獲\n獳\n獴\n獵\n獶\n獷\n獸\n獹\n獺\n獻\n獼\n獽\n獿\n玀\n玁\n玂\n玃\n玅\n玆\n玈\n玊\n玌\n玍\n玏\n玐\n玒\n玓\n玔\n玕\n玗\n玘\n玙\n玚\n玜\n玝\n玞\n玠\n玡\n玣\n玤\n玥\n玦\n玧\n玨\n玪\n玬\n玭\n玱\n玴\n玵\n玶\n玸\n玹\n玼\n玽\n玾\n玿\n珁\n珃\n珄\n珅\n珆\n珇\n珋\n珌\n珎\n珒\n珓\n珔\n珕\n珖\n珗\n珘\n珚\n珛\n珜\n珝\n珟\n珡\n珢\n珣\n珤\n珦\n珨\n珪\n珫\n珬\n珮\n珯\n珰\n珱\n珳\n珴\n珵\n珶\n珷\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n珸\n珹\n珺\n珻\n珼\n珽\n現\n珿\n琀\n琁\n琂\n琄\n琇\n琈\n琋\n琌\n琍\n琎\n琑\n琒\n琓\n琔\n琕\n琖\n琗\n琘\n琙\n琜\n琝\n琞\n琟\n琠\n琡\n琣\n琤\n琧\n琩\n琫\n琭\n琯\n琱\n琲\n琷\n琸\n琹\n琺\n琻\n琽\n琾\n琿\n瑀\n瑂\n瑃\n瑄\n瑅\n瑆\n瑇\n瑈\n瑉\n瑊\n瑋\n瑌\n瑍\n瑎\n瑏\n瑐\n瑑\n瑒\n瑓\n瑔\n瑖\n瑘\n瑝\n瑠\n瑡\n瑢\n瑣\n瑤\n瑥\n瑦\n瑧\n瑨\n瑩\n瑪\n瑫\n瑬\n瑮\n瑯\n瑱\n瑲\n瑳\n瑴\n瑵\n瑸\n瑹\n瑺\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n瑻\n瑼\n瑽\n瑿\n璂\n璄\n璅\n璆\n璈\n璉\n璊\n璌\n璍\n璏\n璑\n璒\n璓\n璔\n璕\n璖\n璗\n璘\n璙\n璚\n璛\n璝\n璟\n璠\n璡\n璢\n璣\n璤\n璥\n璦\n璪\n璫\n璬\n璭\n璮\n璯\n環\n璱\n璲\n璳\n璴\n璵\n璶\n璷\n璸\n璹\n璻\n璼\n璽\n璾\n璿\n瓀\n瓁\n瓂\n瓃\n瓄\n瓅\n瓆\n瓇\n瓈\n瓉\n瓊\n瓋\n瓌\n瓍\n瓎\n瓏\n瓐\n瓑\n瓓\n瓔\n瓕\n瓖\n瓗\n瓘\n瓙\n瓚\n瓛\n瓝\n瓟\n瓡\n瓥\n瓧\n瓨\n瓩\n瓪\n瓫\n瓬\n瓭\n瓰\n瓱\n瓲\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n瓳\n瓵\n瓸\n瓹\n瓺\n瓻\n瓼\n瓽\n瓾\n甀\n甁\n甂\n甃\n甅\n甆\n甇\n甈\n甉\n甊\n甋\n甌\n甎\n甐\n甒\n甔\n甕\n甖\n甗\n甛\n甝\n甞\n甠\n甡\n產\n産\n甤\n甦\n甧\n甪\n甮\n甴\n甶\n甹\n甼\n甽\n甿\n畁\n畂\n畃\n畄\n畆\n畇\n畉\n畊\n畍\n畐\n畑\n畒\n畓\n畕\n畖\n畗\n畘\n畝\n畞\n畟\n畠\n畡\n畢\n畣\n畤\n畧\n畨\n畩\n畫\n畬\n畭\n畮\n畯\n異\n畱\n畳\n畵\n當\n畷\n畺\n畻\n畼\n畽\n畾\n疀\n疁\n疂\n疄\n疅\n疇\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n疈\n疉\n疊\n疌\n疍\n疎\n疐\n疓\n疕\n疘\n疛\n疜\n疞\n疢\n疦\n疧\n疨\n疩\n疪\n疭\n疶\n疷\n疺\n疻\n疿\n痀\n痁\n痆\n痋\n痌\n痎\n痏\n痐\n痑\n痓\n痗\n痙\n痚\n痜\n痝\n痟\n痠\n痡\n痥\n痩\n痬\n痭\n痮\n痯\n痲\n痳\n痵\n痶\n痷\n痸\n痺\n痻\n痽\n痾\n瘂\n瘄\n瘆\n瘇\n瘈\n瘉\n瘋\n瘍\n瘎\n瘏\n瘑\n瘒\n瘓\n瘔\n瘖\n瘚\n瘜\n瘝\n瘞\n瘡\n瘣\n瘧\n瘨\n瘬\n瘮\n瘯\n瘱\n瘲\n瘶\n瘷\n瘹\n瘺\n瘻\n瘽\n癁\n療\n癄\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n癅\n癆\n癇\n癈\n癉\n癊\n癋\n癎\n癏\n癐\n癑\n癒\n癓\n癕\n癗\n癘\n癙\n癚\n癛\n癝\n癟\n癠\n癡\n癢\n癤\n癥\n癦\n癧\n癨\n癩\n癪\n癬\n癭\n癮\n癰\n癱\n癲\n癳\n癴\n癵\n癶\n癷\n癹\n発\n發\n癿\n皀\n皁\n皃\n皅\n皉\n皊\n皌\n皍\n皏\n皐\n皒\n皔\n皕\n皗\n皘\n皚\n皛\n皜\n皝\n皞\n皟\n皠\n皡\n皢\n皣\n皥\n皦\n皧\n皨\n皩\n皪\n皫\n皬\n皭\n皯\n皰\n皳\n皵\n皶\n皷\n皸\n皹\n皺\n皻\n皼\n皽\n皾\n盀\n盁\n盃\n啊\n阿\n埃\n挨\n哎\n唉\n哀\n皑\n癌\n蔼\n矮\n艾\n碍\n爱\n隘\n鞍\n氨\n安\n俺\n按\n暗\n岸\n胺\n案\n肮\n昂\n盎\n凹\n敖\n熬\n翱\n袄\n傲\n奥\n懊\n澳\n芭\n捌\n扒\n叭\n吧\n笆\n八\n疤\n巴\n拔\n跋\n靶\n把\n耙\n坝\n霸\n罢\n爸\n白\n柏\n百\n摆\n佰\n败\n拜\n稗\n斑\n班\n搬\n扳\n般\n颁\n板\n版\n扮\n拌\n伴\n瓣\n半\n办\n绊\n邦\n帮\n梆\n榜\n膀\n绑\n棒\n磅\n蚌\n镑\n傍\n谤\n苞\n胞\n包\n褒\n剥\n盄\n盇\n盉\n盋\n盌\n盓\n盕\n盙\n盚\n盜\n盝\n盞\n盠\n盡\n盢\n監\n盤\n盦\n盧\n盨\n盩\n盪\n盫\n盬\n盭\n盰\n盳\n盵\n盶\n盷\n盺\n盻\n盽\n盿\n眀\n眂\n眃\n眅\n眆\n眊\n県\n眎\n眏\n眐\n眑\n眒\n眓\n眔\n眕\n眖\n眗\n眘\n眛\n眜\n眝\n眞\n眡\n眣\n眤\n眥\n眧\n眪\n眫\n眬\n眮\n眰\n眱\n眲\n眳\n眴\n眹\n眻\n眽\n眾\n眿\n睂\n睄\n睅\n睆\n睈\n睉\n睊\n睋\n睌\n睍\n睎\n睏\n睒\n睓\n睔\n睕\n睖\n睗\n睘\n睙\n睜\n薄\n雹\n保\n堡\n饱\n宝\n抱\n报\n暴\n豹\n鲍\n爆\n杯\n碑\n悲\n卑\n北\n辈\n背\n贝\n钡\n倍\n狈\n备\n惫\n焙\n被\n奔\n苯\n本\n笨\n崩\n绷\n甭\n泵\n蹦\n迸\n逼\n鼻\n比\n鄙\n笔\n彼\n碧\n蓖\n蔽\n毕\n毙\n毖\n币\n庇\n痹\n闭\n敝\n弊\n必\n辟\n壁\n臂\n避\n陛\n鞭\n边\n编\n贬\n扁\n便\n变\n卞\n辨\n辩\n辫\n遍\n标\n彪\n膘\n表\n鳖\n憋\n别\n瘪\n彬\n斌\n濒\n滨\n宾\n摈\n兵\n冰\n柄\n丙\n秉\n饼\n炳\n睝\n睞\n睟\n睠\n睤\n睧\n睩\n睪\n睭\n睮\n睯\n睰\n睱\n睲\n睳\n睴\n睵\n睶\n睷\n睸\n睺\n睻\n睼\n瞁\n瞂\n瞃\n瞆\n瞇\n瞈\n瞉\n瞊\n瞋\n瞏\n瞐\n瞓\n瞔\n瞕\n瞖\n瞗\n瞘\n瞙\n瞚\n瞛\n瞜\n瞝\n瞞\n瞡\n瞣\n瞤\n瞦\n瞨\n瞫\n瞭\n瞮\n瞯\n瞱\n瞲\n瞴\n瞶\n瞷\n瞸\n瞹\n瞺\n瞼\n瞾\n矀\n矁\n矂\n矃\n矄\n矅\n矆\n矇\n矈\n矉\n矊\n矋\n矌\n矎\n矏\n矐\n矑\n矒\n矓\n矔\n矕\n矖\n矘\n矙\n矚\n矝\n矞\n矟\n矠\n矡\n矤\n病\n并\n玻\n菠\n播\n拨\n钵\n波\n博\n勃\n搏\n铂\n箔\n伯\n帛\n舶\n脖\n膊\n渤\n泊\n驳\n捕\n卜\n哺\n补\n埠\n不\n布\n步\n簿\n部\n怖\n擦\n猜\n裁\n材\n才\n财\n睬\n踩\n采\n彩\n菜\n蔡\n餐\n参\n蚕\n残\n惭\n惨\n灿\n苍\n舱\n仓\n沧\n藏\n操\n糙\n槽\n曹\n草\n厕\n策\n侧\n册\n测\n层\n蹭\n插\n叉\n茬\n茶\n查\n碴\n搽\n察\n岔\n差\n诧\n拆\n柴\n豺\n搀\n掺\n蝉\n馋\n谗\n缠\n铲\n产\n阐\n颤\n昌\n猖\n矦\n矨\n矪\n矯\n矰\n矱\n矲\n矴\n矵\n矷\n矹\n矺\n矻\n矼\n砃\n砄\n砅\n砆\n砇\n砈\n砊\n砋\n砎\n砏\n砐\n砓\n砕\n砙\n砛\n砞\n砠\n砡\n砢\n砤\n砨\n砪\n砫\n砮\n砯\n砱\n砲\n砳\n砵\n砶\n砽\n砿\n硁\n硂\n硃\n硄\n硆\n硈\n硉\n硊\n硋\n硍\n硏\n硑\n硓\n硔\n硘\n硙\n硚\n硛\n硜\n硞\n硟\n硠\n硡\n硢\n硣\n硤\n硥\n硦\n硧\n硨\n硩\n硯\n硰\n硱\n硲\n硳\n硴\n硵\n硶\n硸\n硹\n硺\n硻\n硽\n硾\n硿\n碀\n碁\n碂\n碃\n场\n尝\n常\n长\n偿\n肠\n厂\n敞\n畅\n唱\n倡\n超\n抄\n钞\n朝\n嘲\n潮\n巢\n吵\n炒\n车\n扯\n撤\n掣\n彻\n澈\n郴\n臣\n辰\n尘\n晨\n忱\n沉\n陈\n趁\n衬\n撑\n称\n城\n橙\n成\n呈\n乘\n程\n惩\n澄\n诚\n承\n逞\n骋\n秤\n吃\n痴\n持\n匙\n池\n迟\n弛\n驰\n耻\n齿\n侈\n尺\n赤\n翅\n斥\n炽\n充\n冲\n虫\n崇\n宠\n抽\n酬\n畴\n踌\n稠\n愁\n筹\n仇\n绸\n瞅\n丑\n臭\n初\n出\n橱\n厨\n躇\n锄\n雏\n滁\n除\n楚\n碄\n碅\n碆\n碈\n碊\n碋\n碏\n碐\n碒\n碔\n碕\n碖\n碙\n碝\n碞\n碠\n碢\n碤\n碦\n碨\n碩\n碪\n碫\n碬\n碭\n碮\n碯\n碵\n碶\n碷\n碸\n確\n碻\n碼\n碽\n碿\n磀\n磂\n磃\n磄\n磆\n磇\n磈\n磌\n磍\n磎\n磏\n磑\n磒\n磓\n磖\n磗\n磘\n磚\n磛\n磜\n磝\n磞\n磟\n磠\n磡\n磢\n磣\n磤\n磥\n磦\n磧\n磩\n磪\n磫\n磭\n磮\n磯\n磰\n磱\n磳\n磵\n磶\n磸\n磹\n磻\n磼\n磽\n磾\n磿\n礀\n礂\n礃\n礄\n礆\n礇\n礈\n礉\n礊\n礋\n礌\n础\n储\n矗\n搐\n触\n处\n揣\n川\n穿\n椽\n传\n船\n喘\n串\n疮\n窗\n幢\n床\n闯\n创\n吹\n炊\n捶\n锤\n垂\n春\n椿\n醇\n唇\n淳\n纯\n蠢\n戳\n绰\n疵\n茨\n磁\n雌\n辞\n慈\n瓷\n词\n此\n刺\n赐\n次\n聪\n葱\n囱\n匆\n从\n丛\n凑\n粗\n醋\n簇\n促\n蹿\n篡\n窜\n摧\n崔\n催\n脆\n瘁\n粹\n淬\n翠\n村\n存\n寸\n磋\n撮\n搓\n措\n挫\n错\n搭\n达\n答\n瘩\n打\n大\n呆\n歹\n傣\n戴\n带\n殆\n代\n贷\n袋\n待\n逮\n礍\n礎\n礏\n礐\n礑\n礒\n礔\n礕\n礖\n礗\n礘\n礙\n礚\n礛\n礜\n礝\n礟\n礠\n礡\n礢\n礣\n礥\n礦\n礧\n礨\n礩\n礪\n礫\n礬\n礭\n礮\n礯\n礰\n礱\n礲\n礳\n礵\n礶\n礷\n礸\n礹\n礽\n礿\n祂\n祃\n祄\n祅\n祇\n祊\n祋\n祌\n祍\n祎\n祏\n祐\n祑\n祒\n祔\n祕\n祘\n祙\n祡\n祣\n祤\n祦\n祩\n祪\n祫\n祬\n祮\n祰\n祱\n祲\n祳\n祴\n祵\n祶\n祹\n祻\n祼\n祽\n祾\n祿\n禂\n禃\n禆\n禇\n禈\n禉\n禋\n禌\n禍\n禎\n禐\n禑\n禒\n怠\n耽\n担\n丹\n单\n郸\n掸\n胆\n旦\n氮\n但\n惮\n淡\n诞\n弹\n蛋\n当\n挡\n党\n荡\n档\n刀\n捣\n蹈\n倒\n岛\n祷\n导\n到\n稻\n悼\n道\n盗\n德\n得\n的\n蹬\n灯\n登\n等\n瞪\n凳\n邓\n堤\n低\n滴\n迪\n敌\n笛\n狄\n涤\n翟\n嫡\n抵\n底\n地\n蒂\n第\n帝\n弟\n递\n缔\n颠\n掂\n滇\n碘\n点\n典\n靛\n垫\n电\n佃\n甸\n店\n惦\n奠\n淀\n殿\n碉\n叼\n雕\n凋\n刁\n掉\n吊\n钓\n调\n跌\n爹\n碟\n蝶\n迭\n谍\n叠\n禓\n禔\n禕\n禖\n禗\n禘\n禙\n禛\n禜\n禝\n禞\n禟\n禠\n禡\n禢\n禣\n禤\n禥\n禦\n禨\n禩\n禪\n禫\n禬\n禭\n禮\n禯\n禰\n禱\n禲\n禴\n禵\n禶\n禷\n禸\n禼\n禿\n秂\n秄\n秅\n秇\n秈\n秊\n秌\n秎\n秏\n秐\n秓\n秔\n秖\n秗\n秙\n秚\n秛\n秜\n秝\n秞\n秠\n秡\n秢\n秥\n秨\n秪\n秬\n秮\n秱\n秲\n秳\n秴\n秵\n秶\n秷\n秹\n秺\n秼\n秾\n秿\n稁\n稄\n稅\n稇\n稈\n稉\n稊\n稌\n稏\n稐\n稑\n稒\n稓\n稕\n稖\n稘\n稙\n稛\n稜\n丁\n盯\n叮\n钉\n顶\n鼎\n锭\n定\n订\n丢\n东\n冬\n董\n懂\n动\n栋\n侗\n恫\n冻\n洞\n兜\n抖\n斗\n陡\n豆\n逗\n痘\n都\n督\n毒\n犊\n独\n读\n堵\n睹\n赌\n杜\n镀\n肚\n度\n渡\n妒\n端\n短\n锻\n段\n断\n缎\n堆\n兑\n队\n对\n墩\n吨\n蹲\n敦\n顿\n囤\n钝\n盾\n遁\n掇\n哆\n多\n夺\n垛\n躲\n朵\n跺\n舵\n剁\n惰\n堕\n蛾\n峨\n鹅\n俄\n额\n讹\n娥\n恶\n厄\n扼\n遏\n鄂\n饿\n恩\n而\n儿\n耳\n尔\n饵\n洱\n二\n稝\n稟\n稡\n稢\n稤\n稥\n稦\n稧\n稨\n稩\n稪\n稫\n稬\n稭\n種\n稯\n稰\n稱\n稲\n稴\n稵\n稶\n稸\n稺\n稾\n穀\n穁\n穂\n穃\n穄\n穅\n穇\n穈\n穉\n穊\n穋\n穌\n積\n穎\n穏\n穐\n穒\n穓\n穔\n穕\n穖\n穘\n穙\n穚\n穛\n穜\n穝\n穞\n穟\n穠\n穡\n穢\n穣\n穤\n穥\n穦\n穧\n穨\n穩\n穪\n穫\n穬\n穭\n穮\n穯\n穱\n穲\n穳\n穵\n穻\n穼\n穽\n穾\n窂\n窅\n窇\n窉\n窊\n窋\n窌\n窎\n窏\n窐\n窓\n窔\n窙\n窚\n窛\n窞\n窡\n窢\n贰\n发\n罚\n筏\n伐\n乏\n阀\n法\n珐\n藩\n帆\n番\n翻\n樊\n矾\n钒\n繁\n凡\n烦\n反\n返\n范\n贩\n犯\n饭\n泛\n坊\n芳\n方\n肪\n房\n防\n妨\n仿\n访\n纺\n放\n菲\n非\n啡\n飞\n肥\n匪\n诽\n吠\n肺\n废\n沸\n费\n芬\n酚\n吩\n氛\n分\n纷\n坟\n焚\n汾\n粉\n奋\n份\n忿\n愤\n粪\n丰\n封\n枫\n蜂\n峰\n锋\n风\n疯\n烽\n逢\n冯\n缝\n讽\n奉\n凤\n佛\n否\n夫\n敷\n肤\n孵\n扶\n拂\n辐\n幅\n氟\n符\n伏\n俘\n服\n窣\n窤\n窧\n窩\n窪\n窫\n窮\n窯\n窰\n窱\n窲\n窴\n窵\n窶\n窷\n窸\n窹\n窺\n窻\n窼\n窽\n窾\n竀\n竁\n竂\n竃\n竄\n竅\n竆\n竇\n竈\n竉\n竊\n竌\n竍\n竎\n竏\n竐\n竑\n竒\n竓\n竔\n竕\n竗\n竘\n竚\n竛\n竜\n竝\n竡\n竢\n竤\n竧\n竨\n竩\n竪\n竫\n竬\n竮\n竰\n竱\n竲\n竳\n竴\n竵\n競\n竷\n竸\n竻\n竼\n竾\n笀\n笁\n笂\n笅\n笇\n笉\n笌\n笍\n笎\n笐\n笒\n笓\n笖\n笗\n笘\n笚\n笜\n笝\n笟\n笡\n笢\n笣\n笧\n笩\n笭\n浮\n涪\n福\n袱\n弗\n甫\n抚\n辅\n俯\n釜\n斧\n脯\n腑\n府\n腐\n赴\n副\n覆\n赋\n复\n傅\n付\n阜\n父\n腹\n负\n富\n讣\n附\n妇\n缚\n咐\n噶\n嘎\n该\n改\n概\n钙\n盖\n溉\n干\n甘\n杆\n柑\n竿\n肝\n赶\n感\n秆\n敢\n赣\n冈\n刚\n钢\n缸\n肛\n纲\n岗\n港\n杠\n篙\n皋\n高\n膏\n羔\n糕\n搞\n镐\n稿\n告\n哥\n歌\n搁\n戈\n鸽\n胳\n疙\n割\n革\n葛\n格\n蛤\n阁\n隔\n铬\n个\n各\n给\n根\n跟\n耕\n更\n庚\n羹\n笯\n笰\n笲\n笴\n笵\n笶\n笷\n笹\n笻\n笽\n笿\n筀\n筁\n筂\n筃\n筄\n筆\n筈\n筊\n筍\n筎\n筓\n筕\n筗\n筙\n筜\n筞\n筟\n筡\n筣\n筤\n筥\n筦\n筧\n筨\n筩\n筪\n筫\n筬\n筭\n筯\n筰\n筳\n筴\n筶\n筸\n筺\n筼\n筽\n筿\n箁\n箂\n箃\n箄\n箆\n箇\n箈\n箉\n箊\n箋\n箌\n箎\n箏\n箑\n箒\n箓\n箖\n箘\n箙\n箚\n箛\n箞\n箟\n箠\n箣\n箤\n箥\n箮\n箯\n箰\n箲\n箳\n箵\n箶\n箷\n箹\n箺\n箻\n箼\n箽\n箾\n箿\n節\n篂\n篃\n範\n埂\n耿\n梗\n工\n攻\n功\n恭\n龚\n供\n躬\n公\n宫\n弓\n巩\n汞\n拱\n贡\n共\n钩\n勾\n沟\n苟\n狗\n垢\n构\n购\n够\n辜\n菇\n咕\n箍\n估\n沽\n孤\n姑\n鼓\n古\n蛊\n骨\n谷\n股\n故\n顾\n固\n雇\n刮\n瓜\n剐\n寡\n挂\n褂\n乖\n拐\n怪\n棺\n关\n官\n冠\n观\n管\n馆\n罐\n惯\n灌\n贯\n光\n广\n逛\n瑰\n规\n圭\n硅\n归\n龟\n闺\n轨\n鬼\n诡\n癸\n桂\n柜\n跪\n贵\n刽\n辊\n滚\n棍\n锅\n郭\n国\n果\n裹\n过\n哈\n篅\n篈\n築\n篊\n篋\n篍\n篎\n篏\n篐\n篒\n篔\n篕\n篖\n篗\n篘\n篛\n篜\n篞\n篟\n篠\n篢\n篣\n篤\n篧\n篨\n篩\n篫\n篬\n篭\n篯\n篰\n篲\n篳\n篴\n篵\n篶\n篸\n篹\n篺\n篻\n篽\n篿\n簀\n簁\n簂\n簃\n簄\n簅\n簆\n簈\n簉\n簊\n簍\n簎\n簐\n簑\n簒\n簓\n簔\n簕\n簗\n簘\n簙\n簚\n簛\n簜\n簝\n簞\n簠\n簡\n簢\n簣\n簤\n簥\n簨\n簩\n簫\n簬\n簭\n簮\n簯\n簰\n簱\n簲\n簳\n簴\n簵\n簶\n簷\n簹\n簺\n簻\n簼\n簽\n簾\n籂\n骸\n孩\n海\n氦\n亥\n害\n骇\n酣\n憨\n邯\n韩\n含\n涵\n寒\n函\n喊\n罕\n翰\n撼\n捍\n旱\n憾\n悍\n焊\n汗\n汉\n夯\n杭\n航\n壕\n嚎\n豪\n毫\n郝\n好\n耗\n号\n浩\n呵\n喝\n荷\n菏\n核\n禾\n和\n何\n合\n盒\n貉\n阂\n河\n涸\n赫\n褐\n鹤\n贺\n嘿\n黑\n痕\n很\n狠\n恨\n哼\n亨\n横\n衡\n恒\n轰\n哄\n烘\n虹\n鸿\n洪\n宏\n弘\n红\n喉\n侯\n猴\n吼\n厚\n候\n后\n呼\n乎\n忽\n瑚\n壶\n葫\n胡\n蝴\n狐\n糊\n湖\n籃\n籄\n籅\n籆\n籇\n籈\n籉\n籊\n籋\n籌\n籎\n籏\n籐\n籑\n籒\n籓\n籔\n籕\n籖\n籗\n籘\n籙\n籚\n籛\n籜\n籝\n籞\n籟\n籠\n籡\n籢\n籣\n籤\n籥\n籦\n籧\n籨\n籩\n籪\n籫\n籬\n籭\n籮\n籯\n籰\n籱\n籲\n籵\n籶\n籷\n籸\n籹\n籺\n籾\n籿\n粀\n粁\n粂\n粃\n粄\n粅\n粆\n粇\n粈\n粊\n粋\n粌\n粍\n粎\n粏\n粐\n粓\n粔\n粖\n粙\n粚\n粛\n粠\n粡\n粣\n粦\n粧\n粨\n粩\n粫\n粬\n粭\n粯\n粰\n粴\n粵\n粶\n粷\n粸\n粺\n粻\n弧\n虎\n唬\n护\n互\n沪\n户\n花\n哗\n华\n猾\n滑\n画\n划\n化\n话\n槐\n徊\n怀\n淮\n坏\n欢\n环\n桓\n还\n缓\n换\n患\n唤\n痪\n豢\n焕\n涣\n宦\n幻\n荒\n慌\n黄\n磺\n蝗\n簧\n皇\n凰\n惶\n煌\n晃\n幌\n恍\n谎\n灰\n挥\n辉\n徽\n恢\n蛔\n回\n毁\n悔\n慧\n卉\n惠\n晦\n贿\n秽\n会\n烩\n汇\n讳\n诲\n绘\n荤\n昏\n婚\n魂\n浑\n混\n豁\n活\n伙\n火\n获\n或\n惑\n霍\n货\n祸\n击\n圾\n基\n机\n畸\n稽\n积\n箕\n粿\n糀\n糂\n糃\n糄\n糆\n糉\n糋\n糎\n糏\n糐\n糑\n糒\n糓\n糔\n糘\n糚\n糛\n糝\n糞\n糡\n糢\n糣\n糤\n糥\n糦\n糧\n糩\n糪\n糫\n糬\n糭\n糮\n糰\n糱\n糲\n糳\n糴\n糵\n糶\n糷\n糹\n糺\n糼\n糽\n糾\n糿\n紀\n紁\n紂\n紃\n約\n紅\n紆\n紇\n紈\n紉\n紋\n紌\n納\n紎\n紏\n紐\n紑\n紒\n紓\n純\n紕\n紖\n紗\n紘\n紙\n級\n紛\n紜\n紝\n紞\n紟\n紡\n紣\n紤\n紥\n紦\n紨\n紩\n紪\n紬\n紭\n紮\n細\n紱\n紲\n紳\n紴\n紵\n紶\n肌\n饥\n迹\n激\n讥\n鸡\n姬\n绩\n缉\n吉\n极\n棘\n辑\n籍\n集\n及\n急\n疾\n汲\n即\n嫉\n级\n挤\n几\n脊\n己\n蓟\n技\n冀\n季\n伎\n祭\n剂\n悸\n济\n寄\n寂\n计\n记\n既\n忌\n际\n妓\n继\n纪\n嘉\n枷\n夹\n佳\n家\n加\n荚\n颊\n贾\n甲\n钾\n假\n稼\n价\n架\n驾\n嫁\n歼\n监\n坚\n尖\n笺\n间\n煎\n兼\n肩\n艰\n奸\n缄\n茧\n检\n柬\n碱\n硷\n拣\n捡\n简\n俭\n剪\n减\n荐\n槛\n鉴\n践\n贱\n见\n键\n箭\n件\n紷\n紸\n紹\n紺\n紻\n紼\n紽\n紾\n紿\n絀\n絁\n終\n絃\n組\n絅\n絆\n絇\n絈\n絉\n絊\n絋\n経\n絍\n絎\n絏\n結\n絑\n絒\n絓\n絔\n絕\n絖\n絗\n絘\n絙\n絚\n絛\n絜\n絝\n絞\n絟\n絠\n絡\n絢\n絣\n絤\n絥\n給\n絧\n絨\n絩\n絪\n絫\n絬\n絭\n絯\n絰\n統\n絲\n絳\n絴\n絵\n絶\n絸\n絹\n絺\n絻\n絼\n絽\n絾\n絿\n綀\n綁\n綂\n綃\n綄\n綅\n綆\n綇\n綈\n綉\n綊\n綋\n綌\n綍\n綎\n綏\n綐\n綑\n綒\n經\n綔\n綕\n綖\n綗\n綘\n健\n舰\n剑\n饯\n渐\n溅\n涧\n建\n僵\n姜\n将\n浆\n江\n疆\n蒋\n桨\n奖\n讲\n匠\n酱\n降\n蕉\n椒\n礁\n焦\n胶\n交\n郊\n浇\n骄\n娇\n嚼\n搅\n铰\n矫\n侥\n脚\n狡\n角\n饺\n缴\n绞\n剿\n教\n酵\n轿\n较\n叫\n窖\n揭\n接\n皆\n秸\n街\n阶\n截\n劫\n节\n桔\n杰\n捷\n睫\n竭\n洁\n结\n解\n姐\n戒\n藉\n芥\n界\n借\n介\n疥\n诫\n届\n巾\n筋\n斤\n金\n今\n津\n襟\n紧\n锦\n仅\n谨\n进\n靳\n晋\n禁\n近\n烬\n浸\n継\n続\n綛\n綜\n綝\n綞\n綟\n綠\n綡\n綢\n綣\n綤\n綥\n綧\n綨\n綩\n綪\n綫\n綬\n維\n綯\n綰\n綱\n網\n綳\n綴\n綵\n綶\n綷\n綸\n綹\n綺\n綻\n綼\n綽\n綾\n綿\n緀\n緁\n緂\n緃\n緄\n緅\n緆\n緇\n緈\n緉\n緊\n緋\n緌\n緍\n緎\n総\n緐\n緑\n緒\n緓\n緔\n緕\n緖\n緗\n緘\n緙\n線\n緛\n緜\n緝\n緞\n緟\n締\n緡\n緢\n緣\n緤\n緥\n緦\n緧\n編\n緩\n緪\n緫\n緬\n緭\n緮\n緯\n緰\n緱\n緲\n緳\n練\n緵\n緶\n緷\n緸\n緹\n緺\n尽\n劲\n荆\n兢\n茎\n睛\n晶\n鲸\n京\n惊\n精\n粳\n经\n井\n警\n景\n颈\n静\n境\n敬\n镜\n径\n痉\n靖\n竟\n竞\n净\n炯\n窘\n揪\n究\n纠\n玖\n韭\n久\n灸\n九\n酒\n厩\n救\n旧\n臼\n舅\n咎\n就\n疚\n鞠\n拘\n狙\n疽\n居\n驹\n菊\n局\n咀\n矩\n举\n沮\n聚\n拒\n据\n巨\n具\n距\n踞\n锯\n俱\n句\n惧\n炬\n剧\n捐\n鹃\n娟\n倦\n眷\n卷\n绢\n撅\n攫\n抉\n掘\n倔\n爵\n觉\n决\n诀\n绝\n均\n菌\n钧\n军\n君\n峻\n緻\n緼\n緽\n緾\n緿\n縀\n縁\n縂\n縃\n縄\n縅\n縆\n縇\n縈\n縉\n縊\n縋\n縌\n縍\n縎\n縏\n縐\n縑\n縒\n縓\n縔\n縕\n縖\n縗\n縘\n縙\n縚\n縛\n縜\n縝\n縞\n縟\n縠\n縡\n縢\n縣\n縤\n縥\n縦\n縧\n縨\n縩\n縪\n縫\n縬\n縭\n縮\n縯\n縰\n縱\n縲\n縳\n縴\n縵\n縶\n縷\n縸\n縹\n縺\n縼\n總\n績\n縿\n繀\n繂\n繃\n繄\n繅\n繆\n繈\n繉\n繊\n繋\n繌\n繍\n繎\n繏\n繐\n繑\n繒\n繓\n織\n繕\n繖\n繗\n繘\n繙\n繚\n繛\n繜\n繝\n俊\n竣\n浚\n郡\n骏\n喀\n咖\n卡\n咯\n开\n揩\n楷\n凯\n慨\n刊\n堪\n勘\n坎\n砍\n看\n康\n慷\n糠\n扛\n抗\n亢\n炕\n考\n拷\n烤\n靠\n坷\n苛\n柯\n棵\n磕\n颗\n科\n壳\n咳\n可\n渴\n克\n刻\n客\n课\n肯\n啃\n垦\n恳\n坑\n吭\n空\n恐\n孔\n控\n抠\n口\n扣\n寇\n枯\n哭\n窟\n苦\n酷\n库\n裤\n夸\n垮\n挎\n跨\n胯\n块\n筷\n侩\n快\n宽\n款\n匡\n筐\n狂\n框\n矿\n眶\n旷\n况\n亏\n盔\n岿\n窥\n葵\n奎\n魁\n傀\n繞\n繟\n繠\n繡\n繢\n繣\n繤\n繥\n繦\n繧\n繨\n繩\n繪\n繫\n繬\n繭\n繮\n繯\n繰\n繱\n繲\n繳\n繴\n繵\n繶\n繷\n繸\n繹\n繺\n繻\n繼\n繽\n繾\n繿\n纀\n纁\n纃\n纄\n纅\n纆\n纇\n纈\n纉\n纊\n纋\n續\n纍\n纎\n纏\n纐\n纑\n纒\n纓\n纔\n纕\n纖\n纗\n纘\n纙\n纚\n纜\n纝\n纞\n纮\n纴\n纻\n纼\n绖\n绤\n绬\n绹\n缊\n缐\n缞\n缷\n缹\n缻\n缼\n缽\n缾\n缿\n罀\n罁\n罃\n罆\n罇\n罈\n罉\n罊\n罋\n罌\n罍\n罎\n罏\n罒\n罓\n馈\n愧\n溃\n坤\n昆\n捆\n困\n括\n扩\n廓\n阔\n垃\n拉\n喇\n蜡\n腊\n辣\n啦\n莱\n来\n赖\n蓝\n婪\n栏\n拦\n篮\n阑\n兰\n澜\n谰\n揽\n览\n懒\n缆\n烂\n滥\n琅\n榔\n狼\n廊\n郎\n朗\n浪\n捞\n劳\n牢\n老\n佬\n姥\n酪\n烙\n涝\n勒\n乐\n雷\n镭\n蕾\n磊\n累\n儡\n垒\n擂\n肋\n类\n泪\n棱\n楞\n冷\n厘\n梨\n犁\n黎\n篱\n狸\n离\n漓\n理\n李\n里\n鲤\n礼\n莉\n荔\n吏\n栗\n丽\n厉\n励\n砾\n历\n利\n傈\n例\n俐\n罖\n罙\n罛\n罜\n罝\n罞\n罠\n罣\n罤\n罥\n罦\n罧\n罫\n罬\n罭\n罯\n罰\n罳\n罵\n罶\n罷\n罸\n罺\n罻\n罼\n罽\n罿\n羀\n羂\n羃\n羄\n羅\n羆\n羇\n羈\n羉\n羋\n羍\n羏\n羐\n羑\n羒\n羓\n羕\n羖\n羗\n羘\n羙\n羛\n羜\n羠\n羢\n羣\n羥\n羦\n羨\n義\n羪\n羫\n羬\n羭\n羮\n羱\n羳\n羴\n羵\n羶\n羷\n羺\n羻\n羾\n翀\n翂\n翃\n翄\n翆\n翇\n翈\n翉\n翋\n翍\n翏\n翐\n翑\n習\n翓\n翖\n翗\n翙\n翚\n翛\n翜\n翝\n翞\n翢\n翣\n痢\n立\n粒\n沥\n隶\n力\n璃\n哩\n俩\n联\n莲\n连\n镰\n廉\n怜\n涟\n帘\n敛\n脸\n链\n恋\n炼\n练\n粮\n凉\n梁\n粱\n良\n两\n辆\n量\n晾\n亮\n谅\n撩\n聊\n僚\n疗\n燎\n寥\n辽\n潦\n了\n撂\n镣\n廖\n料\n列\n裂\n烈\n劣\n猎\n琳\n林\n磷\n霖\n临\n邻\n鳞\n淋\n凛\n赁\n吝\n拎\n玲\n菱\n零\n龄\n铃\n伶\n羚\n凌\n灵\n陵\n岭\n领\n另\n令\n溜\n琉\n榴\n硫\n馏\n留\n刘\n瘤\n流\n柳\n六\n龙\n聋\n咙\n笼\n窿\n翤\n翧\n翨\n翪\n翫\n翬\n翭\n翯\n翲\n翴\n翵\n翶\n翷\n翸\n翹\n翺\n翽\n翾\n翿\n耂\n耇\n耈\n耉\n耊\n耎\n耏\n耑\n耓\n耚\n耛\n耝\n耞\n耟\n耡\n耣\n耤\n耫\n耬\n耭\n耮\n耯\n耰\n耲\n耴\n耹\n耺\n耼\n耾\n聀\n聁\n聄\n聅\n聇\n聈\n聉\n聎\n聏\n聐\n聑\n聓\n聕\n聖\n聗\n聙\n聛\n聜\n聝\n聞\n聟\n聠\n聡\n聢\n聣\n聤\n聥\n聦\n聧\n聨\n聫\n聬\n聭\n聮\n聯\n聰\n聲\n聳\n聴\n聵\n聶\n職\n聸\n聹\n聺\n聻\n聼\n聽\n隆\n垄\n拢\n陇\n楼\n娄\n搂\n篓\n漏\n陋\n芦\n卢\n颅\n庐\n炉\n掳\n卤\n虏\n鲁\n麓\n碌\n露\n路\n赂\n鹿\n潞\n禄\n录\n陆\n戮\n驴\n吕\n铝\n侣\n旅\n履\n屡\n缕\n虑\n氯\n律\n率\n滤\n绿\n峦\n挛\n孪\n滦\n卵\n乱\n掠\n略\n抡\n轮\n伦\n仑\n沦\n纶\n论\n萝\n螺\n罗\n逻\n锣\n箩\n骡\n裸\n落\n洛\n骆\n络\n妈\n麻\n玛\n码\n蚂\n马\n骂\n嘛\n吗\n埋\n买\n麦\n卖\n迈\n脉\n瞒\n馒\n蛮\n满\n蔓\n曼\n慢\n漫\n聾\n肁\n肂\n肅\n肈\n肊\n肍\n肎\n肏\n肐\n肑\n肒\n肔\n肕\n肗\n肙\n肞\n肣\n肦\n肧\n肨\n肬\n肰\n肳\n肵\n肶\n肸\n肹\n肻\n胅\n胇\n胈\n胉\n胊\n胋\n胏\n胐\n胑\n胒\n胓\n胔\n胕\n胘\n胟\n胠\n胢\n胣\n胦\n胮\n胵\n胷\n胹\n胻\n胾\n胿\n脀\n脁\n脃\n脄\n脅\n脇\n脈\n脋\n脌\n脕\n脗\n脙\n脛\n脜\n脝\n脟\n脠\n脡\n脢\n脣\n脤\n脥\n脦\n脧\n脨\n脩\n脪\n脫\n脭\n脮\n脰\n脳\n脴\n脵\n脷\n脹\n脺\n脻\n脼\n脽\n脿\n谩\n芒\n茫\n盲\n氓\n忙\n莽\n猫\n茅\n锚\n毛\n矛\n铆\n卯\n茂\n冒\n帽\n貌\n贸\n么\n玫\n枚\n梅\n酶\n霉\n煤\n没\n眉\n媒\n镁\n每\n美\n昧\n寐\n妹\n媚\n门\n闷\n们\n萌\n蒙\n檬\n盟\n锰\n猛\n梦\n孟\n眯\n醚\n靡\n糜\n迷\n谜\n弥\n米\n秘\n觅\n泌\n蜜\n密\n幂\n棉\n眠\n绵\n冕\n免\n勉\n娩\n缅\n面\n苗\n描\n瞄\n藐\n秒\n渺\n庙\n妙\n蔑\n灭\n民\n抿\n皿\n敏\n悯\n闽\n明\n螟\n鸣\n铭\n名\n命\n谬\n摸\n腀\n腁\n腂\n腃\n腄\n腅\n腇\n腉\n腍\n腎\n腏\n腒\n腖\n腗\n腘\n腛\n腜\n腝\n腞\n腟\n腡\n腢\n腣\n腤\n腦\n腨\n腪\n腫\n腬\n腯\n腲\n腳\n腵\n腶\n腷\n腸\n膁\n膃\n膄\n膅\n膆\n膇\n膉\n膋\n膌\n膍\n膎\n膐\n膒\n膓\n膔\n膕\n膖\n膗\n膙\n膚\n膞\n膟\n膠\n膡\n膢\n膤\n膥\n膧\n膩\n膫\n膬\n膭\n膮\n膯\n膰\n膱\n膲\n膴\n膵\n膶\n膷\n膸\n膹\n膼\n膽\n膾\n膿\n臄\n臅\n臇\n臈\n臉\n臋\n臍\n臎\n臏\n臐\n臑\n臒\n臓\n摹\n蘑\n模\n膜\n磨\n摩\n魔\n抹\n末\n莫\n墨\n默\n沫\n漠\n寞\n陌\n谋\n牟\n某\n拇\n牡\n亩\n姆\n母\n墓\n暮\n幕\n募\n慕\n木\n目\n睦\n牧\n穆\n拿\n哪\n呐\n钠\n那\n娜\n纳\n氖\n乃\n奶\n耐\n奈\n南\n男\n难\n囊\n挠\n脑\n恼\n闹\n淖\n呢\n馁\n内\n嫩\n能\n妮\n霓\n倪\n泥\n尼\n拟\n你\n匿\n腻\n逆\n溺\n蔫\n拈\n年\n碾\n撵\n捻\n念\n娘\n酿\n鸟\n尿\n捏\n聂\n孽\n啮\n镊\n镍\n涅\n您\n柠\n狞\n凝\n宁\n臔\n臕\n臖\n臗\n臘\n臙\n臚\n臛\n臜\n臝\n臞\n臟\n臠\n臡\n臢\n臤\n臥\n臦\n臨\n臩\n臫\n臮\n臯\n臰\n臱\n臲\n臵\n臶\n臷\n臸\n臹\n臺\n臽\n臿\n舃\n與\n興\n舉\n舊\n舋\n舎\n舏\n舑\n舓\n舕\n舖\n舗\n舘\n舙\n舚\n舝\n舠\n舤\n舥\n舦\n舧\n舩\n舮\n舲\n舺\n舼\n舽\n舿\n艀\n艁\n艂\n艃\n艅\n艆\n艈\n艊\n艌\n艍\n艎\n艐\n艑\n艒\n艓\n艔\n艕\n艖\n艗\n艙\n艛\n艜\n艝\n艞\n艠\n艡\n艢\n艣\n艤\n艥\n艦\n艧\n艩\n拧\n泞\n牛\n扭\n钮\n纽\n脓\n浓\n农\n弄\n奴\n努\n怒\n女\n暖\n虐\n疟\n挪\n懦\n糯\n诺\n哦\n欧\n鸥\n殴\n藕\n呕\n偶\n沤\n啪\n趴\n爬\n帕\n怕\n琶\n拍\n排\n牌\n徘\n湃\n派\n攀\n潘\n盘\n磐\n盼\n畔\n判\n叛\n乓\n庞\n旁\n耪\n胖\n抛\n咆\n刨\n炮\n袍\n跑\n泡\n呸\n胚\n培\n裴\n赔\n陪\n配\n佩\n沛\n喷\n盆\n砰\n抨\n烹\n澎\n彭\n蓬\n棚\n硼\n篷\n膨\n朋\n鹏\n捧\n碰\n坯\n砒\n霹\n批\n披\n劈\n琵\n毗\n艪\n艫\n艬\n艭\n艱\n艵\n艶\n艷\n艸\n艻\n艼\n芀\n芁\n芃\n芅\n芆\n芇\n芉\n芌\n芐\n芓\n芔\n芕\n芖\n芚\n芛\n芞\n芠\n芢\n芣\n芧\n芲\n芵\n芶\n芺\n芻\n芼\n芿\n苀\n苂\n苃\n苅\n苆\n苉\n苐\n苖\n苙\n苚\n苝\n苢\n苧\n苨\n苩\n苪\n苬\n苭\n苮\n苰\n苲\n苳\n苵\n苶\n苸\n苺\n苼\n苽\n苾\n苿\n茀\n茊\n茋\n茍\n茐\n茒\n茓\n茖\n茘\n茙\n茝\n茞\n茟\n茠\n茡\n茢\n茣\n茤\n茥\n茦\n茩\n茪\n茮\n茰\n茲\n茷\n茻\n茽\n啤\n脾\n疲\n皮\n匹\n痞\n僻\n屁\n譬\n篇\n偏\n片\n骗\n飘\n漂\n瓢\n票\n撇\n瞥\n拼\n频\n贫\n品\n聘\n乒\n坪\n苹\n萍\n平\n凭\n瓶\n评\n屏\n坡\n泼\n颇\n婆\n破\n魄\n迫\n粕\n剖\n扑\n铺\n仆\n莆\n葡\n菩\n蒲\n埔\n朴\n圃\n普\n浦\n谱\n曝\n瀑\n期\n欺\n栖\n戚\n妻\n七\n凄\n漆\n柒\n沏\n其\n棋\n奇\n歧\n畦\n崎\n脐\n齐\n旗\n祈\n祁\n骑\n起\n岂\n乞\n企\n启\n契\n砌\n器\n气\n迄\n弃\n汽\n泣\n讫\n掐\n茾\n茿\n荁\n荂\n荄\n荅\n荈\n荊\n荋\n荌\n荍\n荎\n荓\n荕\n荖\n荗\n荘\n荙\n荝\n荢\n荰\n荱\n荲\n荳\n荴\n荵\n荶\n荹\n荺\n荾\n荿\n莀\n莁\n莂\n莃\n莄\n莇\n莈\n莊\n莋\n莌\n莍\n莏\n莐\n莑\n莔\n莕\n莖\n莗\n莙\n莚\n莝\n莟\n莡\n莢\n莣\n莤\n莥\n莦\n莧\n莬\n莭\n莮\n莯\n莵\n莻\n莾\n莿\n菂\n菃\n菄\n菆\n菈\n菉\n菋\n菍\n菎\n菐\n菑\n菒\n菓\n菕\n菗\n菙\n菚\n菛\n菞\n菢\n菣\n菤\n菦\n菧\n菨\n菫\n菬\n菭\n恰\n洽\n牵\n扦\n钎\n铅\n千\n迁\n签\n仟\n谦\n乾\n黔\n钱\n钳\n前\n潜\n遣\n浅\n谴\n堑\n嵌\n欠\n歉\n枪\n呛\n腔\n羌\n墙\n蔷\n强\n抢\n橇\n锹\n敲\n悄\n桥\n瞧\n乔\n侨\n巧\n鞘\n撬\n翘\n峭\n俏\n窍\n切\n茄\n且\n怯\n窃\n钦\n侵\n亲\n秦\n琴\n勤\n芹\n擒\n禽\n寝\n沁\n青\n轻\n氢\n倾\n卿\n清\n擎\n晴\n氰\n情\n顷\n请\n庆\n琼\n穷\n秋\n丘\n邱\n球\n求\n囚\n酋\n泅\n趋\n区\n蛆\n曲\n躯\n屈\n驱\n渠\n菮\n華\n菳\n菴\n菵\n菶\n菷\n菺\n菻\n菼\n菾\n菿\n萀\n萂\n萅\n萇\n萈\n萉\n萊\n萐\n萒\n萓\n萔\n萕\n萖\n萗\n萙\n萚\n萛\n萞\n萟\n萠\n萡\n萢\n萣\n萩\n萪\n萫\n萬\n萭\n萮\n萯\n萰\n萲\n萳\n萴\n萵\n萶\n萷\n萹\n萺\n萻\n萾\n萿\n葀\n葁\n葂\n葃\n葄\n葅\n葇\n葈\n葉\n葊\n葋\n葌\n葍\n葎\n葏\n葐\n葒\n葓\n葔\n葕\n葖\n葘\n葝\n葞\n葟\n葠\n葢\n葤\n葥\n葦\n葧\n葨\n葪\n葮\n葯\n葰\n葲\n葴\n葷\n葹\n葻\n葼\n取\n娶\n龋\n趣\n去\n圈\n颧\n权\n醛\n泉\n全\n痊\n拳\n犬\n券\n劝\n缺\n炔\n瘸\n却\n鹊\n榷\n确\n雀\n裙\n群\n然\n燃\n冉\n染\n瓤\n壤\n攘\n嚷\n让\n饶\n扰\n绕\n惹\n热\n壬\n仁\n人\n忍\n韧\n任\n认\n刃\n妊\n纫\n扔\n仍\n日\n戎\n茸\n蓉\n荣\n融\n熔\n溶\n容\n绒\n冗\n揉\n柔\n肉\n茹\n蠕\n儒\n孺\n如\n辱\n乳\n汝\n入\n褥\n软\n阮\n蕊\n瑞\n锐\n闰\n润\n若\n弱\n撒\n洒\n萨\n腮\n鳃\n塞\n赛\n三\n叁\n葽\n葾\n葿\n蒀\n蒁\n蒃\n蒄\n蒅\n蒆\n蒊\n蒍\n蒏\n蒐\n蒑\n蒒\n蒓\n蒔\n蒕\n蒖\n蒘\n蒚\n蒛\n蒝\n蒞\n蒟\n蒠\n蒢\n蒣\n蒤\n蒥\n蒦\n蒧\n蒨\n蒩\n蒪\n蒫\n蒬\n蒭\n蒮\n蒰\n蒱\n蒳\n蒵\n蒶\n蒷\n蒻\n蒼\n蒾\n蓀\n蓂\n蓃\n蓅\n蓆\n蓇\n蓈\n蓋\n蓌\n蓎\n蓏\n蓒\n蓔\n蓕\n蓗\n蓘\n蓙\n蓚\n蓛\n蓜\n蓞\n蓡\n蓢\n蓤\n蓧\n蓨\n蓩\n蓪\n蓫\n蓭\n蓮\n蓯\n蓱\n蓲\n蓳\n蓴\n蓵\n蓶\n蓷\n蓸\n蓹\n蓺\n蓻\n蓽\n蓾\n蔀\n蔁\n蔂\n伞\n散\n桑\n嗓\n丧\n搔\n骚\n扫\n嫂\n瑟\n色\n涩\n森\n僧\n莎\n砂\n杀\n刹\n沙\n纱\n傻\n啥\n煞\n筛\n晒\n珊\n苫\n杉\n山\n删\n煽\n衫\n闪\n陕\n擅\n赡\n膳\n善\n汕\n扇\n缮\n墒\n伤\n商\n赏\n晌\n上\n尚\n裳\n梢\n捎\n稍\n烧\n芍\n勺\n韶\n少\n哨\n邵\n绍\n奢\n赊\n蛇\n舌\n舍\n赦\n摄\n射\n慑\n涉\n社\n设\n砷\n申\n呻\n伸\n身\n深\n娠\n绅\n神\n沈\n审\n婶\n甚\n肾\n慎\n渗\n声\n生\n甥\n牲\n升\n绳\n蔃\n蔄\n蔅\n蔆\n蔇\n蔈\n蔉\n蔊\n蔋\n蔍\n蔎\n蔏\n蔐\n蔒\n蔔\n蔕\n蔖\n蔘\n蔙\n蔛\n蔜\n蔝\n蔞\n蔠\n蔢\n蔣\n蔤\n蔥\n蔦\n蔧\n蔨\n蔩\n蔪\n蔭\n蔮\n蔯\n蔰\n蔱\n蔲\n蔳\n蔴\n蔵\n蔶\n蔾\n蔿\n蕀\n蕁\n蕂\n蕄\n蕅\n蕆\n蕇\n蕋\n蕌\n蕍\n蕎\n蕏\n蕐\n蕑\n蕒\n蕓\n蕔\n蕕\n蕗\n蕘\n蕚\n蕛\n蕜\n蕝\n蕟\n蕠\n蕡\n蕢\n蕣\n蕥\n蕦\n蕧\n蕩\n蕪\n蕫\n蕬\n蕭\n蕮\n蕯\n蕰\n蕱\n蕳\n蕵\n蕶\n蕷\n蕸\n蕼\n蕽\n蕿\n薀\n薁\n省\n盛\n剩\n胜\n圣\n师\n失\n狮\n施\n湿\n诗\n尸\n虱\n十\n石\n拾\n时\n什\n食\n蚀\n实\n识\n史\n矢\n使\n屎\n驶\n始\n式\n示\n士\n世\n柿\n事\n拭\n誓\n逝\n势\n是\n嗜\n噬\n适\n仕\n侍\n释\n饰\n氏\n市\n恃\n室\n视\n试\n收\n手\n首\n守\n寿\n授\n售\n受\n瘦\n兽\n蔬\n枢\n梳\n殊\n抒\n输\n叔\n舒\n淑\n疏\n书\n赎\n孰\n熟\n薯\n暑\n曙\n署\n蜀\n黍\n鼠\n属\n术\n述\n树\n束\n戍\n竖\n墅\n庶\n数\n漱\n薂\n薃\n薆\n薈\n薉\n薊\n薋\n薌\n薍\n薎\n薐\n薑\n薒\n薓\n薔\n薕\n薖\n薗\n薘\n薙\n薚\n薝\n薞\n薟\n薠\n薡\n薢\n薣\n薥\n薦\n薧\n薩\n薫\n薬\n薭\n薱\n薲\n薳\n薴\n薵\n薶\n薸\n薺\n薻\n薼\n薽\n薾\n薿\n藀\n藂\n藃\n藄\n藅\n藆\n藇\n藈\n藊\n藋\n藌\n藍\n藎\n藑\n藒\n藔\n藖\n藗\n藘\n藙\n藚\n藛\n藝\n藞\n藟\n藠\n藡\n藢\n藣\n藥\n藦\n藧\n藨\n藪\n藫\n藬\n藭\n藮\n藯\n藰\n藱\n藲\n藳\n藴\n藵\n藶\n藷\n藸\n恕\n刷\n耍\n摔\n衰\n甩\n帅\n栓\n拴\n霜\n双\n爽\n谁\n水\n睡\n税\n吮\n瞬\n顺\n舜\n说\n硕\n朔\n烁\n斯\n撕\n嘶\n思\n私\n司\n丝\n死\n肆\n寺\n嗣\n四\n伺\n似\n饲\n巳\n松\n耸\n怂\n颂\n送\n宋\n讼\n诵\n搜\n艘\n擞\n嗽\n苏\n酥\n俗\n素\n速\n粟\n僳\n塑\n溯\n宿\n诉\n肃\n酸\n蒜\n算\n虽\n隋\n随\n绥\n髓\n碎\n岁\n穗\n遂\n隧\n祟\n孙\n损\n笋\n蓑\n梭\n唆\n缩\n琐\n索\n锁\n所\n塌\n他\n它\n她\n塔\n藹\n藺\n藼\n藽\n藾\n蘀\n蘁\n蘂\n蘃\n蘄\n蘆\n蘇\n蘈\n蘉\n蘊\n蘋\n蘌\n蘍\n蘎\n蘏\n蘐\n蘒\n蘓\n蘔\n蘕\n蘗\n蘘\n蘙\n蘚\n蘛\n蘜\n蘝\n蘞\n蘟\n蘠\n蘡\n蘢\n蘣\n蘤\n蘥\n蘦\n蘨\n蘪\n蘫\n蘬\n蘭\n蘮\n蘯\n蘰\n蘱\n蘲\n蘳\n蘴\n蘵\n蘶\n蘷\n蘹\n蘺\n蘻\n蘽\n蘾\n蘿\n虀\n虁\n虂\n虃\n虄\n虅\n虆\n虇\n虈\n虉\n虊\n虋\n虌\n虒\n虓\n處\n虖\n虗\n虘\n虙\n虛\n虜\n虝\n號\n虠\n虡\n虣\n虤\n虥\n虦\n虧\n虨\n虩\n虪\n獭\n挞\n蹋\n踏\n胎\n苔\n抬\n台\n泰\n酞\n太\n态\n汰\n坍\n摊\n贪\n瘫\n滩\n坛\n檀\n痰\n潭\n谭\n谈\n坦\n毯\n袒\n碳\n探\n叹\n炭\n汤\n塘\n搪\n堂\n棠\n膛\n唐\n糖\n倘\n躺\n淌\n趟\n烫\n掏\n涛\n滔\n绦\n萄\n桃\n逃\n淘\n陶\n讨\n套\n特\n藤\n腾\n疼\n誊\n梯\n剔\n踢\n锑\n提\n题\n蹄\n啼\n体\n替\n嚏\n惕\n涕\n剃\n屉\n天\n添\n填\n田\n甜\n恬\n舔\n腆\n挑\n条\n迢\n眺\n跳\n贴\n铁\n帖\n厅\n听\n烃\n虭\n虯\n虰\n虲\n虳\n虴\n虵\n虶\n虷\n虸\n蚃\n蚄\n蚅\n蚆\n蚇\n蚈\n蚉\n蚎\n蚏\n蚐\n蚑\n蚒\n蚔\n蚖\n蚗\n蚘\n蚙\n蚚\n蚛\n蚞\n蚟\n蚠\n蚡\n蚢\n蚥\n蚦\n蚫\n蚭\n蚮\n蚲\n蚳\n蚷\n蚸\n蚹\n蚻\n蚼\n蚽\n蚾\n蚿\n蛁\n蛂\n蛃\n蛅\n蛈\n蛌\n蛍\n蛒\n蛓\n蛕\n蛖\n蛗\n蛚\n蛜\n蛝\n蛠\n蛡\n蛢\n蛣\n蛥\n蛦\n蛧\n蛨\n蛪\n蛫\n蛬\n蛯\n蛵\n蛶\n蛷\n蛺\n蛻\n蛼\n蛽\n蛿\n蜁\n蜄\n蜅\n蜆\n蜋\n蜌\n蜎\n蜏\n蜐\n蜑\n蜔\n蜖\n汀\n廷\n停\n亭\n庭\n挺\n艇\n通\n桐\n酮\n瞳\n同\n铜\n彤\n童\n桶\n捅\n筒\n统\n痛\n偷\n投\n头\n透\n凸\n秃\n突\n图\n徒\n途\n涂\n屠\n土\n吐\n兔\n湍\n团\n推\n颓\n腿\n蜕\n褪\n退\n吞\n屯\n臀\n拖\n托\n脱\n鸵\n陀\n驮\n驼\n椭\n妥\n拓\n唾\n挖\n哇\n蛙\n洼\n娃\n瓦\n袜\n歪\n外\n豌\n弯\n湾\n玩\n顽\n丸\n烷\n完\n碗\n挽\n晚\n皖\n惋\n宛\n婉\n万\n腕\n汪\n王\n亡\n枉\n网\n往\n旺\n望\n忘\n妄\n威\n蜙\n蜛\n蜝\n蜟\n蜠\n蜤\n蜦\n蜧\n蜨\n蜪\n蜫\n蜬\n蜭\n蜯\n蜰\n蜲\n蜳\n蜵\n蜶\n蜸\n蜹\n蜺\n蜼\n蜽\n蝀\n蝁\n蝂\n蝃\n蝄\n蝅\n蝆\n蝊\n蝋\n蝍\n蝏\n蝐\n蝑\n蝒\n蝔\n蝕\n蝖\n蝘\n蝚\n蝛\n蝜\n蝝\n蝞\n蝟\n蝡\n蝢\n蝦\n蝧\n蝨\n蝩\n蝪\n蝫\n蝬\n蝭\n蝯\n蝱\n蝲\n蝳\n蝵\n蝷\n蝸\n蝹\n蝺\n蝿\n螀\n螁\n螄\n螆\n螇\n螉\n螊\n螌\n螎\n螏\n螐\n螑\n螒\n螔\n螕\n螖\n螘\n螙\n螚\n螛\n螜\n螝\n螞\n螠\n螡\n螢\n螣\n螤\n巍\n微\n危\n韦\n违\n桅\n围\n唯\n惟\n为\n潍\n维\n苇\n萎\n委\n伟\n伪\n尾\n纬\n未\n蔚\n味\n畏\n胃\n喂\n魏\n位\n渭\n谓\n尉\n慰\n卫\n瘟\n温\n蚊\n文\n闻\n纹\n吻\n稳\n紊\n问\n嗡\n翁\n瓮\n挝\n蜗\n涡\n窝\n我\n斡\n卧\n握\n沃\n巫\n呜\n钨\n乌\n污\n诬\n屋\n无\n芜\n梧\n吾\n吴\n毋\n武\n五\n捂\n午\n舞\n伍\n侮\n坞\n戊\n雾\n晤\n物\n勿\n务\n悟\n误\n昔\n熙\n析\n西\n硒\n矽\n晰\n嘻\n吸\n锡\n牺\n螥\n螦\n螧\n螩\n螪\n螮\n螰\n螱\n螲\n螴\n螶\n螷\n螸\n螹\n螻\n螼\n螾\n螿\n蟁\n蟂\n蟃\n蟄\n蟅\n蟇\n蟈\n蟉\n蟌\n蟍\n蟎\n蟏\n蟐\n蟔\n蟕\n蟖\n蟗\n蟘\n蟙\n蟚\n蟜\n蟝\n蟞\n蟟\n蟡\n蟢\n蟣\n蟤\n蟦\n蟧\n蟨\n蟩\n蟫\n蟬\n蟭\n蟯\n蟰\n蟱\n蟲\n蟳\n蟴\n蟵\n蟶\n蟷\n蟸\n蟺\n蟻\n蟼\n蟽\n蟿\n蠀\n蠁\n蠂\n蠄\n蠅\n蠆\n蠇\n蠈\n蠉\n蠋\n蠌\n蠍\n蠎\n蠏\n蠐\n蠑\n蠒\n蠔\n蠗\n蠘\n蠙\n蠚\n蠜\n蠝\n蠞\n蠟\n蠠\n蠣\n稀\n息\n希\n悉\n膝\n夕\n惜\n熄\n烯\n溪\n汐\n犀\n檄\n袭\n席\n习\n媳\n喜\n铣\n洗\n系\n隙\n戏\n细\n瞎\n虾\n匣\n霞\n辖\n暇\n峡\n侠\n狭\n下\n厦\n夏\n吓\n掀\n锨\n先\n仙\n鲜\n纤\n咸\n贤\n衔\n舷\n闲\n涎\n弦\n嫌\n显\n险\n现\n献\n县\n腺\n馅\n羡\n宪\n陷\n限\n线\n相\n厢\n镶\n香\n箱\n襄\n湘\n乡\n翔\n祥\n详\n想\n响\n享\n项\n巷\n橡\n像\n向\n象\n萧\n硝\n霄\n削\n哮\n嚣\n销\n消\n宵\n淆\n晓\n蠤\n蠥\n蠦\n蠧\n蠨\n蠩\n蠪\n蠫\n蠬\n蠭\n蠮\n蠯\n蠰\n蠱\n蠳\n蠴\n蠵\n蠶\n蠷\n蠸\n蠺\n蠻\n蠽\n蠾\n蠿\n衁\n衂\n衃\n衆\n衇\n衈\n衉\n衊\n衋\n衎\n衏\n衐\n衑\n衒\n術\n衕\n衖\n衘\n衚\n衛\n衜\n衝\n衞\n衟\n衠\n衦\n衧\n衪\n衭\n衯\n衱\n衳\n衴\n衵\n衶\n衸\n衹\n衺\n衻\n衼\n袀\n袃\n袆\n袇\n袉\n袊\n袌\n袎\n袏\n袐\n袑\n袓\n袔\n袕\n袗\n袘\n袙\n袚\n袛\n袝\n袞\n袟\n袠\n袡\n袣\n袥\n袦\n袧\n袨\n袩\n袪\n小\n孝\n校\n肖\n啸\n笑\n效\n楔\n些\n歇\n蝎\n鞋\n协\n挟\n携\n邪\n斜\n胁\n谐\n写\n械\n卸\n蟹\n懈\n泄\n泻\n谢\n屑\n薪\n芯\n锌\n欣\n辛\n新\n忻\n心\n信\n衅\n星\n腥\n猩\n惺\n兴\n刑\n型\n形\n邢\n行\n醒\n幸\n杏\n性\n姓\n兄\n凶\n胸\n匈\n汹\n雄\n熊\n休\n修\n羞\n朽\n嗅\n锈\n秀\n袖\n绣\n墟\n戌\n需\n虚\n嘘\n须\n徐\n许\n蓄\n酗\n叙\n旭\n序\n畜\n恤\n絮\n婿\n绪\n续\n轩\n喧\n宣\n悬\n旋\n玄\n袬\n袮\n袯\n袰\n袲\n袳\n袴\n袵\n袶\n袸\n袹\n袺\n袻\n袽\n袾\n袿\n裀\n裃\n裄\n裇\n裈\n裊\n裋\n裌\n裍\n裏\n裐\n裑\n裓\n裖\n裗\n裚\n裛\n補\n裝\n裞\n裠\n裡\n裦\n裧\n裩\n裪\n裫\n裬\n裭\n裮\n裯\n裲\n裵\n裶\n裷\n裺\n裻\n製\n裿\n褀\n褁\n褃\n褄\n褅\n褆\n複\n褈\n褉\n褋\n褌\n褍\n褎\n褏\n褑\n褔\n褕\n褖\n褗\n褘\n褜\n褝\n褞\n褟\n褠\n褢\n褣\n褤\n褦\n褧\n褨\n褩\n褬\n褭\n褮\n褯\n褱\n褲\n褳\n褵\n褷\n选\n癣\n眩\n绚\n靴\n薛\n学\n穴\n雪\n血\n勋\n熏\n循\n旬\n询\n寻\n驯\n巡\n殉\n汛\n训\n讯\n逊\n迅\n压\n押\n鸦\n鸭\n呀\n丫\n芽\n牙\n蚜\n崖\n衙\n涯\n雅\n哑\n亚\n讶\n焉\n咽\n阉\n烟\n淹\n盐\n严\n研\n蜒\n岩\n延\n言\n颜\n阎\n炎\n沿\n奄\n掩\n眼\n衍\n演\n艳\n堰\n燕\n厌\n砚\n雁\n唁\n彦\n焰\n宴\n谚\n验\n殃\n央\n鸯\n秧\n杨\n扬\n佯\n疡\n羊\n洋\n阳\n氧\n仰\n痒\n养\n样\n漾\n邀\n腰\n妖\n瑶\n褸\n褹\n褺\n褻\n褼\n褽\n褾\n褿\n襀\n襂\n襃\n襅\n襆\n襇\n襈\n襉\n襊\n襋\n襌\n襍\n襎\n襏\n襐\n襑\n襒\n襓\n襔\n襕\n襖\n襗\n襘\n襙\n襚\n襛\n襜\n襝\n襠\n襡\n襢\n襣\n襤\n襥\n襧\n襨\n襩\n襪\n襫\n襬\n襭\n襮\n襯\n襰\n襱\n襲\n襳\n襴\n襵\n襶\n襷\n襸\n襹\n襺\n襼\n襽\n襾\n覀\n覂\n覄\n覅\n覇\n覈\n覉\n覊\n見\n覌\n覍\n覎\n規\n覐\n覑\n覒\n覓\n覔\n覕\n視\n覗\n覘\n覙\n覚\n覛\n覜\n覝\n覞\n覟\n覠\n覡\n摇\n尧\n遥\n窑\n谣\n姚\n咬\n舀\n药\n要\n耀\n椰\n噎\n耶\n爷\n野\n冶\n也\n页\n掖\n业\n叶\n曳\n腋\n夜\n液\n一\n壹\n医\n揖\n铱\n依\n伊\n衣\n颐\n夷\n遗\n移\n仪\n胰\n疑\n沂\n宜\n姨\n彝\n椅\n蚁\n倚\n已\n乙\n矣\n以\n艺\n抑\n易\n邑\n屹\n亿\n役\n臆\n逸\n肄\n疫\n亦\n裔\n意\n毅\n忆\n义\n益\n溢\n诣\n议\n谊\n译\n异\n翼\n翌\n绎\n茵\n荫\n因\n殷\n音\n阴\n姻\n吟\n银\n淫\n寅\n饮\n尹\n引\n隐\n覢\n覣\n覤\n覥\n覦\n覧\n覨\n覩\n親\n覫\n覬\n覭\n覮\n覯\n覰\n覱\n覲\n観\n覴\n覵\n覶\n覷\n覸\n覹\n覺\n覻\n覼\n覽\n覾\n覿\n觀\n觃\n觍\n觓\n觔\n觕\n觗\n觘\n觙\n觛\n觝\n觟\n觠\n觡\n觢\n觤\n觧\n觨\n觩\n觪\n觬\n觭\n觮\n觰\n觱\n觲\n觴\n觵\n觶\n觷\n觸\n觹\n觺\n觻\n觼\n觽\n觾\n觿\n訁\n訂\n訃\n訄\n訅\n訆\n計\n訉\n訊\n訋\n訌\n訍\n討\n訏\n訐\n訑\n訒\n訓\n訔\n訕\n訖\n託\n記\n訙\n訚\n訛\n訜\n訝\n印\n英\n樱\n婴\n鹰\n应\n缨\n莹\n萤\n营\n荧\n蝇\n迎\n赢\n盈\n影\n颖\n硬\n映\n哟\n拥\n佣\n臃\n痈\n庸\n雍\n踊\n蛹\n咏\n泳\n涌\n永\n恿\n勇\n用\n幽\n优\n悠\n忧\n尤\n由\n邮\n铀\n犹\n油\n游\n酉\n有\n友\n右\n佑\n釉\n诱\n又\n幼\n迂\n淤\n于\n盂\n榆\n虞\n愚\n舆\n余\n俞\n逾\n鱼\n愉\n渝\n渔\n隅\n予\n娱\n雨\n与\n屿\n禹\n宇\n语\n羽\n玉\n域\n芋\n郁\n吁\n遇\n喻\n峪\n御\n愈\n欲\n狱\n育\n誉\n訞\n訟\n訠\n訡\n訢\n訣\n訤\n訥\n訦\n訧\n訨\n訩\n訪\n訫\n訬\n設\n訮\n訯\n訰\n許\n訲\n訳\n訴\n訵\n訶\n訷\n訸\n訹\n診\n註\n証\n訽\n訿\n詀\n詁\n詂\n詃\n詄\n詅\n詆\n詇\n詉\n詊\n詋\n詌\n詍\n詎\n詏\n詐\n詑\n詒\n詓\n詔\n評\n詖\n詗\n詘\n詙\n詚\n詛\n詜\n詝\n詞\n詟\n詠\n詡\n詢\n詣\n詤\n詥\n試\n詧\n詨\n詩\n詪\n詫\n詬\n詭\n詮\n詯\n詰\n話\n該\n詳\n詴\n詵\n詶\n詷\n詸\n詺\n詻\n詼\n詽\n詾\n詿\n誀\n浴\n寓\n裕\n预\n豫\n驭\n鸳\n渊\n冤\n元\n垣\n袁\n原\n援\n辕\n园\n员\n圆\n猿\n源\n缘\n远\n苑\n愿\n怨\n院\n曰\n约\n越\n跃\n钥\n岳\n粤\n月\n悦\n阅\n耘\n云\n郧\n匀\n陨\n允\n运\n蕴\n酝\n晕\n韵\n孕\n匝\n砸\n杂\n栽\n哉\n灾\n宰\n载\n再\n在\n咱\n攒\n暂\n赞\n赃\n脏\n葬\n遭\n糟\n凿\n藻\n枣\n早\n澡\n蚤\n躁\n噪\n造\n皂\n灶\n燥\n责\n择\n则\n泽\n贼\n怎\n增\n憎\n曾\n赠\n扎\n喳\n渣\n札\n轧\n誁\n誂\n誃\n誄\n誅\n誆\n誇\n誈\n誋\n誌\n認\n誎\n誏\n誐\n誑\n誒\n誔\n誕\n誖\n誗\n誘\n誙\n誚\n誛\n誜\n誝\n語\n誟\n誠\n誡\n誢\n誣\n誤\n誥\n誦\n誧\n誨\n誩\n說\n誫\n説\n読\n誮\n誯\n誰\n誱\n課\n誳\n誴\n誵\n誶\n誷\n誸\n誹\n誺\n誻\n誼\n誽\n誾\n調\n諀\n諁\n諂\n諃\n諄\n諅\n諆\n談\n諈\n諉\n諊\n請\n諌\n諍\n諎\n諏\n諐\n諑\n諒\n諓\n諔\n諕\n論\n諗\n諘\n諙\n諚\n諛\n諜\n諝\n諞\n諟\n諠\n諡\n諢\n諣\n铡\n闸\n眨\n栅\n榨\n咋\n乍\n炸\n诈\n摘\n斋\n宅\n窄\n债\n寨\n瞻\n毡\n詹\n粘\n沾\n盏\n斩\n辗\n崭\n展\n蘸\n栈\n占\n战\n站\n湛\n绽\n樟\n章\n彰\n漳\n张\n掌\n涨\n杖\n丈\n帐\n账\n仗\n胀\n瘴\n障\n招\n昭\n找\n沼\n赵\n照\n罩\n兆\n肇\n召\n遮\n折\n哲\n蛰\n辙\n者\n锗\n蔗\n这\n浙\n珍\n斟\n真\n甄\n砧\n臻\n贞\n针\n侦\n枕\n疹\n诊\n震\n振\n镇\n阵\n蒸\n挣\n睁\n征\n狰\n争\n怔\n整\n拯\n正\n政\n諤\n諥\n諦\n諧\n諨\n諩\n諪\n諫\n諬\n諭\n諮\n諯\n諰\n諱\n諲\n諳\n諴\n諵\n諶\n諷\n諸\n諹\n諺\n諻\n諼\n諽\n諾\n諿\n謀\n謁\n謂\n謃\n謄\n謅\n謆\n謈\n謉\n謊\n謋\n謌\n謍\n謎\n謏\n謐\n謑\n謒\n謓\n謔\n謕\n謖\n謗\n謘\n謙\n謚\n講\n謜\n謝\n謞\n謟\n謠\n謡\n謢\n謣\n謤\n謥\n謧\n謨\n謩\n謪\n謫\n謬\n謭\n謮\n謯\n謰\n謱\n謲\n謳\n謴\n謵\n謶\n謷\n謸\n謹\n謺\n謻\n謼\n謽\n謾\n謿\n譀\n譁\n譂\n譃\n譄\n譅\n帧\n症\n郑\n证\n芝\n枝\n支\n吱\n蜘\n知\n肢\n脂\n汁\n之\n织\n职\n直\n植\n殖\n执\n值\n侄\n址\n指\n止\n趾\n只\n旨\n纸\n志\n挚\n掷\n至\n致\n置\n帜\n峙\n制\n智\n秩\n稚\n质\n炙\n痔\n滞\n治\n窒\n中\n盅\n忠\n钟\n衷\n终\n种\n肿\n重\n仲\n众\n舟\n周\n州\n洲\n诌\n粥\n轴\n肘\n帚\n咒\n皱\n宙\n昼\n骤\n珠\n株\n蛛\n朱\n猪\n诸\n诛\n逐\n竹\n烛\n煮\n拄\n瞩\n嘱\n主\n著\n柱\n助\n蛀\n贮\n铸\n筑\n譆\n譇\n譈\n證\n譊\n譋\n譌\n譍\n譎\n譏\n譐\n譑\n譒\n譓\n譔\n譕\n譖\n譗\n識\n譙\n譚\n譛\n譜\n譝\n譞\n譟\n譠\n譡\n譢\n譣\n譤\n譥\n譧\n譨\n譩\n譪\n譫\n譭\n譮\n譯\n議\n譱\n譲\n譳\n譴\n譵\n譶\n護\n譸\n譹\n譺\n譻\n譼\n譽\n譾\n譿\n讀\n讁\n讂\n讃\n讄\n讅\n讆\n讇\n讈\n讉\n變\n讋\n讌\n讍\n讎\n讏\n讐\n讑\n讒\n讓\n讔\n讕\n讖\n讗\n讘\n讙\n讚\n讛\n讜\n讝\n讞\n讟\n讬\n讱\n讻\n诇\n诐\n诪\n谉\n谞\n住\n注\n祝\n驻\n抓\n爪\n拽\n专\n砖\n转\n撰\n赚\n篆\n桩\n庄\n装\n妆\n撞\n壮\n状\n椎\n锥\n追\n赘\n坠\n缀\n谆\n准\n捉\n拙\n卓\n桌\n琢\n茁\n酌\n啄\n着\n灼\n浊\n兹\n咨\n资\n姿\n滋\n淄\n孜\n紫\n仔\n籽\n滓\n子\n自\n渍\n字\n鬃\n棕\n踪\n宗\n综\n总\n纵\n邹\n走\n奏\n揍\n租\n足\n卒\n族\n祖\n诅\n阻\n组\n钻\n纂\n嘴\n醉\n最\n罪\n尊\n遵\n昨\n左\n佐\n柞\n做\n作\n坐\n座\n\n\n\n\n\n谸\n谹\n谺\n谻\n谼\n谽\n谾\n谿\n豀\n豂\n豃\n豄\n豅\n豈\n豊\n豋\n豍\n豎\n豏\n豐\n豑\n豒\n豓\n豔\n豖\n豗\n豘\n豙\n豛\n豜\n豝\n豞\n豟\n豠\n豣\n豤\n豥\n豦\n豧\n豨\n豩\n豬\n豭\n豮\n豯\n豰\n豱\n豲\n豴\n豵\n豶\n豷\n豻\n豼\n豽\n豾\n豿\n貀\n貁\n貃\n貄\n貆\n貇\n貈\n貋\n貍\n貎\n貏\n貐\n貑\n貒\n貓\n貕\n貖\n貗\n貙\n貚\n貛\n貜\n貝\n貞\n貟\n負\n財\n貢\n貣\n貤\n貥\n貦\n貧\n貨\n販\n貪\n貫\n責\n貭\n亍\n丌\n兀\n丐\n廿\n卅\n丕\n亘\n丞\n鬲\n孬\n噩\n丨\n禺\n丿\n匕\n乇\n夭\n爻\n卮\n氐\n囟\n胤\n馗\n毓\n睾\n鼗\n丶\n亟\n鼐\n乜\n乩\n亓\n芈\n孛\n啬\n嘏\n仄\n厍\n厝\n厣\n厥\n厮\n靥\n赝\n匚\n叵\n匦\n匮\n匾\n赜\n卦\n卣\n刂\n刈\n刎\n刭\n刳\n刿\n剀\n剌\n剞\n剡\n剜\n蒯\n剽\n劂\n劁\n劐\n劓\n冂\n罔\n亻\n仃\n仉\n仂\n仨\n仡\n仫\n仞\n伛\n仳\n伢\n佤\n仵\n伥\n伧\n伉\n伫\n佞\n佧\n攸\n佚\n佝\n貮\n貯\n貰\n貱\n貲\n貳\n貴\n貵\n貶\n買\n貸\n貹\n貺\n費\n貼\n貽\n貾\n貿\n賀\n賁\n賂\n賃\n賄\n賅\n賆\n資\n賈\n賉\n賊\n賋\n賌\n賍\n賎\n賏\n賐\n賑\n賒\n賓\n賔\n賕\n賖\n賗\n賘\n賙\n賚\n賛\n賜\n賝\n賞\n賟\n賠\n賡\n賢\n賣\n賤\n賥\n賦\n賧\n賨\n賩\n質\n賫\n賬\n賭\n賮\n賯\n賰\n賱\n賲\n賳\n賴\n賵\n賶\n賷\n賸\n賹\n賺\n賻\n購\n賽\n賾\n賿\n贀\n贁\n贂\n贃\n贄\n贅\n贆\n贇\n贈\n贉\n贊\n贋\n贌\n贍\n佟\n佗\n伲\n伽\n佶\n佴\n侑\n侉\n侃\n侏\n佾\n佻\n侪\n佼\n侬\n侔\n俦\n俨\n俪\n俅\n俚\n俣\n俜\n俑\n俟\n俸\n倩\n偌\n俳\n倬\n倏\n倮\n倭\n俾\n倜\n倌\n倥\n倨\n偾\n偃\n偕\n偈\n偎\n偬\n偻\n傥\n傧\n傩\n傺\n僖\n儆\n僭\n僬\n僦\n僮\n儇\n儋\n仝\n氽\n佘\n佥\n俎\n龠\n汆\n籴\n兮\n巽\n黉\n馘\n冁\n夔\n勹\n匍\n訇\n匐\n凫\n夙\n兕\n亠\n兖\n亳\n衮\n袤\n亵\n脔\n裒\n禀\n嬴\n蠃\n羸\n冫\n冱\n冽\n冼\n贎\n贏\n贐\n贑\n贒\n贓\n贔\n贕\n贖\n贗\n贘\n贙\n贚\n贛\n贜\n贠\n赑\n赒\n赗\n赟\n赥\n赨\n赩\n赪\n赬\n赮\n赯\n赱\n赲\n赸\n赹\n赺\n赻\n赼\n赽\n赾\n赿\n趀\n趂\n趃\n趆\n趇\n趈\n趉\n趌\n趍\n趎\n趏\n趐\n趒\n趓\n趕\n趖\n趗\n趘\n趙\n趚\n趛\n趜\n趝\n趞\n趠\n趡\n趢\n趤\n趥\n趦\n趧\n趨\n趩\n趪\n趫\n趬\n趭\n趮\n趯\n趰\n趲\n趶\n趷\n趹\n趻\n趽\n跀\n跁\n跂\n跅\n跇\n跈\n跉\n跊\n跍\n跐\n跒\n跓\n跔\n凇\n冖\n冢\n冥\n讠\n讦\n讧\n讪\n讴\n讵\n讷\n诂\n诃\n诋\n诏\n诎\n诒\n诓\n诔\n诖\n诘\n诙\n诜\n诟\n诠\n诤\n诨\n诩\n诮\n诰\n诳\n诶\n诹\n诼\n诿\n谀\n谂\n谄\n谇\n谌\n谏\n谑\n谒\n谔\n谕\n谖\n谙\n谛\n谘\n谝\n谟\n谠\n谡\n谥\n谧\n谪\n谫\n谮\n谯\n谲\n谳\n谵\n谶\n卩\n卺\n阝\n阢\n阡\n阱\n阪\n阽\n阼\n陂\n陉\n陔\n陟\n陧\n陬\n陲\n陴\n隈\n隍\n隗\n隰\n邗\n邛\n邝\n邙\n邬\n邡\n邴\n邳\n邶\n邺\n跕\n跘\n跙\n跜\n跠\n跡\n跢\n跥\n跦\n跧\n跩\n跭\n跮\n跰\n跱\n跲\n跴\n跶\n跼\n跾\n跿\n踀\n踁\n踂\n踃\n踄\n踆\n踇\n踈\n踋\n踍\n踎\n踐\n踑\n踒\n踓\n踕\n踖\n踗\n踘\n踙\n踚\n踛\n踜\n踠\n踡\n踤\n踥\n踦\n踧\n踨\n踫\n踭\n踰\n踲\n踳\n踴\n踶\n踷\n踸\n踻\n踼\n踾\n踿\n蹃\n蹅\n蹆\n蹌\n蹍\n蹎\n蹏\n蹐\n蹓\n蹔\n蹕\n蹖\n蹗\n蹘\n蹚\n蹛\n蹜\n蹝\n蹞\n蹟\n蹠\n蹡\n蹢\n蹣\n蹤\n蹥\n蹧\n蹨\n蹪\n蹫\n蹮\n蹱\n邸\n邰\n郏\n郅\n邾\n郐\n郄\n郇\n郓\n郦\n郢\n郜\n郗\n郛\n郫\n郯\n郾\n鄄\n鄢\n鄞\n鄣\n鄱\n鄯\n鄹\n酃\n酆\n刍\n奂\n劢\n劬\n劭\n劾\n哿\n勐\n勖\n勰\n叟\n燮\n矍\n廴\n凵\n凼\n鬯\n厶\n弁\n畚\n巯\n坌\n垩\n垡\n塾\n墼\n壅\n壑\n圩\n圬\n圪\n圳\n圹\n圮\n圯\n坜\n圻\n坂\n坩\n垅\n坫\n垆\n坼\n坻\n坨\n坭\n坶\n坳\n垭\n垤\n垌\n垲\n埏\n垧\n垴\n垓\n垠\n埕\n埘\n埚\n埙\n埒\n垸\n埴\n埯\n埸\n埤\n埝\n蹳\n蹵\n蹷\n蹸\n蹹\n蹺\n蹻\n蹽\n蹾\n躀\n躂\n躃\n躄\n躆\n躈\n躉\n躊\n躋\n躌\n躍\n躎\n躑\n躒\n躓\n躕\n躖\n躗\n躘\n躙\n躚\n躛\n躝\n躟\n躠\n躡\n躢\n躣\n躤\n躥\n躦\n躧\n躨\n躩\n躪\n躭\n躮\n躰\n躱\n躳\n躴\n躵\n躶\n躷\n躸\n躹\n躻\n躼\n躽\n躾\n躿\n軀\n軁\n軂\n軃\n軄\n軅\n軆\n軇\n軈\n軉\n車\n軋\n軌\n軍\n軏\n軐\n軑\n軒\n軓\n軔\n軕\n軖\n軗\n軘\n軙\n軚\n軛\n軜\n軝\n軞\n軟\n軠\n軡\n転\n軣\n軤\n堋\n堍\n埽\n埭\n堀\n堞\n堙\n塄\n堠\n塥\n塬\n墁\n墉\n墚\n墀\n馨\n鼙\n懿\n艹\n艽\n艿\n芏\n芊\n芨\n芄\n芎\n芑\n芗\n芙\n芫\n芸\n芾\n芰\n苈\n苊\n苣\n芘\n芷\n芮\n苋\n苌\n苁\n芩\n芴\n芡\n芪\n芟\n苄\n苎\n芤\n苡\n茉\n苷\n苤\n茏\n茇\n苜\n苴\n苒\n苘\n茌\n苻\n苓\n茑\n茚\n茆\n茔\n茕\n苠\n苕\n茜\n荑\n荛\n荜\n茈\n莒\n茼\n茴\n茱\n莛\n荞\n茯\n荏\n荇\n荃\n荟\n荀\n茗\n荠\n茭\n茺\n茳\n荦\n荥\n軥\n軦\n軧\n軨\n軩\n軪\n軫\n軬\n軭\n軮\n軯\n軰\n軱\n軲\n軳\n軴\n軵\n軶\n軷\n軸\n軹\n軺\n軻\n軼\n軽\n軾\n軿\n輀\n輁\n輂\n較\n輄\n輅\n輆\n輇\n輈\n載\n輊\n輋\n輌\n輍\n輎\n輏\n輐\n輑\n輒\n輓\n輔\n輕\n輖\n輗\n輘\n輙\n輚\n輛\n輜\n輝\n輞\n輟\n輠\n輡\n輢\n輣\n輤\n輥\n輦\n輧\n輨\n輩\n輪\n輫\n輬\n輭\n輮\n輯\n輰\n輱\n輲\n輳\n輴\n輵\n輶\n輷\n輸\n輹\n輺\n輻\n輼\n輽\n輾\n輿\n轀\n轁\n轂\n轃\n轄\n荨\n茛\n荩\n荬\n荪\n荭\n荮\n莰\n荸\n莳\n莴\n莠\n莪\n莓\n莜\n莅\n荼\n莶\n莩\n荽\n莸\n荻\n莘\n莞\n莨\n莺\n莼\n菁\n萁\n菥\n菘\n堇\n萘\n萋\n菝\n菽\n菖\n萜\n萸\n萑\n萆\n菔\n菟\n萏\n萃\n菸\n菹\n菪\n菅\n菀\n萦\n菰\n菡\n葜\n葑\n葚\n葙\n葳\n蒇\n蒈\n葺\n蒉\n葸\n萼\n葆\n葩\n葶\n蒌\n蒎\n萱\n葭\n蓁\n蓍\n蓐\n蓦\n蒽\n蓓\n蓊\n蒿\n蒺\n蓠\n蒡\n蒹\n蒴\n蒗\n蓥\n蓣\n蔌\n甍\n蔸\n蓰\n蔹\n蔟\n蔺\n轅\n轆\n轇\n轈\n轉\n轊\n轋\n轌\n轍\n轎\n轏\n轐\n轑\n轒\n轓\n轔\n轕\n轖\n轗\n轘\n轙\n轚\n轛\n轜\n轝\n轞\n轟\n轠\n轡\n轢\n轣\n轤\n轥\n轪\n辀\n辌\n辒\n辝\n辠\n辡\n辢\n辤\n辥\n辦\n辧\n辪\n辬\n辭\n辮\n辯\n農\n辳\n辴\n辵\n辷\n辸\n辺\n辻\n込\n辿\n迀\n迃\n迆\n迉\n迊\n迋\n迌\n迍\n迏\n迒\n迖\n迗\n迚\n迠\n迡\n迣\n迧\n迬\n迯\n迱\n迲\n迴\n迵\n迶\n迺\n迻\n迼\n迾\n迿\n逇\n逈\n逌\n逎\n逓\n逕\n逘\n蕖\n蔻\n蓿\n蓼\n蕙\n蕈\n蕨\n蕤\n蕞\n蕺\n瞢\n蕃\n蕲\n蕻\n薤\n薨\n薇\n薏\n蕹\n薮\n薜\n薅\n薹\n薷\n薰\n藓\n藁\n藜\n藿\n蘧\n蘅\n蘩\n蘖\n蘼\n廾\n弈\n夼\n奁\n耷\n奕\n奚\n奘\n匏\n尢\n尥\n尬\n尴\n扌\n扪\n抟\n抻\n拊\n拚\n拗\n拮\n挢\n拶\n挹\n捋\n捃\n掭\n揶\n捱\n捺\n掎\n掴\n捭\n掬\n掊\n捩\n掮\n掼\n揲\n揸\n揠\n揿\n揄\n揞\n揎\n摒\n揆\n掾\n摅\n摁\n搋\n搛\n搠\n搌\n搦\n搡\n摞\n撄\n摭\n撖\n這\n逜\n連\n逤\n逥\n逧\n逨\n逩\n逪\n逫\n逬\n逰\n週\n進\n逳\n逴\n逷\n逹\n逺\n逽\n逿\n遀\n遃\n遅\n遆\n遈\n遉\n遊\n運\n遌\n過\n達\n違\n遖\n遙\n遚\n遜\n遝\n遞\n遟\n遠\n遡\n遤\n遦\n遧\n適\n遪\n遫\n遬\n遯\n遰\n遱\n遲\n遳\n遶\n遷\n選\n遹\n遺\n遻\n遼\n遾\n邁\n還\n邅\n邆\n邇\n邉\n邊\n邌\n邍\n邎\n邏\n邐\n邒\n邔\n邖\n邘\n邚\n邜\n邞\n邟\n邠\n邤\n邥\n邧\n邨\n邩\n邫\n邭\n邲\n邷\n邼\n邽\n邿\n郀\n摺\n撷\n撸\n撙\n撺\n擀\n擐\n擗\n擤\n擢\n攉\n攥\n攮\n弋\n忒\n甙\n弑\n卟\n叱\n叽\n叩\n叨\n叻\n吒\n吖\n吆\n呋\n呒\n呓\n呔\n呖\n呃\n吡\n呗\n呙\n吣\n吲\n咂\n咔\n呷\n呱\n呤\n咚\n咛\n咄\n呶\n呦\n咝\n哐\n咭\n哂\n咴\n哒\n咧\n咦\n哓\n哔\n呲\n咣\n哕\n咻\n咿\n哌\n哙\n哚\n哜\n咩\n咪\n咤\n哝\n哏\n哞\n唛\n哧\n唠\n哽\n唔\n哳\n唢\n唣\n唏\n唑\n唧\n唪\n啧\n喏\n喵\n啉\n啭\n啁\n啕\n唿\n啐\n唼\n郂\n郃\n郆\n郈\n郉\n郋\n郌\n郍\n郒\n郔\n郕\n郖\n郘\n郙\n郚\n郞\n郟\n郠\n郣\n郤\n郥\n郩\n郪\n郬\n郮\n郰\n郱\n郲\n郳\n郵\n郶\n郷\n郹\n郺\n郻\n郼\n郿\n鄀\n鄁\n鄃\n鄅\n鄆\n鄇\n鄈\n鄉\n鄊\n鄋\n鄌\n鄍\n鄎\n鄏\n鄐\n鄑\n鄒\n鄓\n鄔\n鄕\n鄖\n鄗\n鄘\n鄚\n鄛\n鄜\n鄝\n鄟\n鄠\n鄡\n鄤\n鄥\n鄦\n鄧\n鄨\n鄩\n鄪\n鄫\n鄬\n鄭\n鄮\n鄰\n鄲\n鄳\n鄴\n鄵\n鄶\n鄷\n鄸\n鄺\n鄻\n鄼\n鄽\n鄾\n鄿\n酀\n酁\n酂\n酄\n唷\n啖\n啵\n啶\n啷\n唳\n唰\n啜\n喋\n嗒\n喃\n喱\n喹\n喈\n喁\n喟\n啾\n嗖\n喑\n啻\n嗟\n喽\n喾\n喔\n喙\n嗪\n嗷\n嗉\n嘟\n嗑\n嗫\n嗬\n嗔\n嗦\n嗝\n嗄\n嗯\n嗥\n嗲\n嗳\n嗌\n嗍\n嗨\n嗵\n嗤\n辔\n嘞\n嘈\n嘌\n嘁\n嘤\n嘣\n嗾\n嘀\n嘧\n嘭\n噘\n嘹\n噗\n嘬\n噍\n噢\n噙\n噜\n噌\n噔\n嚆\n噤\n噱\n噫\n噻\n噼\n嚅\n嚓\n嚯\n囔\n囗\n囝\n囡\n囵\n囫\n囹\n囿\n圄\n圊\n圉\n圜\n帏\n帙\n帔\n帑\n帱\n帻\n帼\n酅\n酇\n酈\n酑\n酓\n酔\n酕\n酖\n酘\n酙\n酛\n酜\n酟\n酠\n酦\n酧\n酨\n酫\n酭\n酳\n酺\n酻\n酼\n醀\n醁\n醂\n醃\n醄\n醆\n醈\n醊\n醎\n醏\n醓\n醔\n醕\n醖\n醗\n醘\n醙\n醜\n醝\n醞\n醟\n醠\n醡\n醤\n醥\n醦\n醧\n醨\n醩\n醫\n醬\n醰\n醱\n醲\n醳\n醶\n醷\n醸\n醹\n醻\n醼\n醽\n醾\n醿\n釀\n釁\n釂\n釃\n釄\n釅\n釆\n釈\n釋\n釐\n釒\n釓\n釔\n釕\n釖\n釗\n釘\n釙\n釚\n釛\n針\n釞\n釟\n釠\n釡\n釢\n釣\n釤\n釥\n帷\n幄\n幔\n幛\n幞\n幡\n岌\n屺\n岍\n岐\n岖\n岈\n岘\n岙\n岑\n岚\n岜\n岵\n岢\n岽\n岬\n岫\n岱\n岣\n峁\n岷\n峄\n峒\n峤\n峋\n峥\n崂\n崃\n崧\n崦\n崮\n崤\n崞\n崆\n崛\n嵘\n崾\n崴\n崽\n嵬\n嵛\n嵯\n嵝\n嵫\n嵋\n嵊\n嵩\n嵴\n嶂\n嶙\n嶝\n豳\n嶷\n巅\n彳\n彷\n徂\n徇\n徉\n後\n徕\n徙\n徜\n徨\n徭\n徵\n徼\n衢\n彡\n犭\n犰\n犴\n犷\n犸\n狃\n狁\n狎\n狍\n狒\n狨\n狯\n狩\n狲\n狴\n狷\n猁\n狳\n猃\n狺\n釦\n釧\n釨\n釩\n釪\n釫\n釬\n釭\n釮\n釯\n釰\n釱\n釲\n釳\n釴\n釵\n釶\n釷\n釸\n釹\n釺\n釻\n釼\n釽\n釾\n釿\n鈀\n鈁\n鈂\n鈃\n鈄\n鈅\n鈆\n鈇\n鈈\n鈉\n鈊\n鈋\n鈌\n鈍\n鈎\n鈏\n鈐\n鈑\n鈒\n鈓\n鈔\n鈕\n鈖\n鈗\n鈘\n鈙\n鈚\n鈛\n鈜\n鈝\n鈞\n鈟\n鈠\n鈡\n鈢\n鈣\n鈤\n鈥\n鈦\n鈧\n鈨\n鈩\n鈪\n鈫\n鈬\n鈭\n鈮\n鈯\n鈰\n鈱\n鈲\n鈳\n鈴\n鈵\n鈶\n鈷\n鈸\n鈹\n鈺\n鈻\n鈼\n鈽\n鈾\n鈿\n鉀\n鉁\n鉂\n鉃\n鉄\n鉅\n狻\n猗\n猓\n猡\n猊\n猞\n猝\n猕\n猢\n猹\n猥\n猬\n猸\n猱\n獐\n獍\n獗\n獠\n獬\n獯\n獾\n舛\n夥\n飧\n夤\n夂\n饣\n饧\n饨\n饩\n饪\n饫\n饬\n饴\n饷\n饽\n馀\n馄\n馇\n馊\n馍\n馐\n馑\n馓\n馔\n馕\n庀\n庑\n庋\n庖\n庥\n庠\n庹\n庵\n庾\n庳\n赓\n廒\n廑\n廛\n廨\n廪\n膺\n忄\n忉\n忖\n忏\n怃\n忮\n怄\n忡\n忤\n忾\n怅\n怆\n忪\n忭\n忸\n怙\n怵\n怦\n怛\n怏\n怍\n怩\n怫\n怊\n怿\n怡\n恸\n恹\n恻\n恺\n恂\n鉆\n鉇\n鉈\n鉉\n鉊\n鉋\n鉌\n鉍\n鉎\n鉏\n鉐\n鉑\n鉒\n鉓\n鉔\n鉕\n鉖\n鉗\n鉘\n鉙\n鉚\n鉛\n鉜\n鉝\n鉞\n鉟\n鉠\n鉡\n鉢\n鉣\n鉤\n鉥\n鉦\n鉧\n鉨\n鉩\n鉪\n鉫\n鉬\n鉭\n鉮\n鉯\n鉰\n鉱\n鉲\n鉳\n鉵\n鉶\n鉷\n鉸\n鉹\n鉺\n鉻\n鉼\n鉽\n鉾\n鉿\n銀\n銁\n銂\n銃\n銄\n銅\n銆\n銇\n銈\n銉\n銊\n銋\n銌\n銍\n銏\n銐\n銑\n銒\n銓\n銔\n銕\n銖\n銗\n銘\n銙\n銚\n銛\n銜\n銝\n銞\n銟\n銠\n銡\n銢\n銣\n銤\n銥\n銦\n銧\n恪\n恽\n悖\n悚\n悭\n悝\n悃\n悒\n悌\n悛\n惬\n悻\n悱\n惝\n惘\n惆\n惚\n悴\n愠\n愦\n愕\n愣\n惴\n愀\n愎\n愫\n慊\n慵\n憬\n憔\n憧\n憷\n懔\n懵\n忝\n隳\n闩\n闫\n闱\n闳\n闵\n闶\n闼\n闾\n阃\n阄\n阆\n阈\n阊\n阋\n阌\n阍\n阏\n阒\n阕\n阖\n阗\n阙\n阚\n丬\n爿\n戕\n氵\n汔\n汜\n汊\n沣\n沅\n沐\n沔\n沌\n汨\n汩\n汴\n汶\n沆\n沩\n泐\n泔\n沭\n泷\n泸\n泱\n泗\n沲\n泠\n泖\n泺\n泫\n泮\n沱\n泓\n泯\n泾\n銨\n銩\n銪\n銫\n銬\n銭\n銯\n銰\n銱\n銲\n銳\n銴\n銵\n銶\n銷\n銸\n銹\n銺\n銻\n銼\n銽\n銾\n銿\n鋀\n鋁\n鋂\n鋃\n鋄\n鋅\n鋆\n鋇\n鋉\n鋊\n鋋\n鋌\n鋍\n鋎\n鋏\n鋐\n鋑\n鋒\n鋓\n鋔\n鋕\n鋖\n鋗\n鋘\n鋙\n鋚\n鋛\n鋜\n鋝\n鋞\n鋟\n鋠\n鋡\n鋢\n鋣\n鋤\n鋥\n鋦\n鋧\n鋨\n鋩\n鋪\n鋫\n鋬\n鋭\n鋮\n鋯\n鋰\n鋱\n鋲\n鋳\n鋴\n鋵\n鋶\n鋷\n鋸\n鋹\n鋺\n鋻\n鋼\n鋽\n鋾\n鋿\n錀\n錁\n錂\n錃\n錄\n錅\n錆\n錇\n錈\n錉\n洹\n洧\n洌\n浃\n浈\n洇\n洄\n洙\n洎\n洫\n浍\n洮\n洵\n洚\n浏\n浒\n浔\n洳\n涑\n浯\n涞\n涠\n浞\n涓\n涔\n浜\n浠\n浼\n浣\n渚\n淇\n淅\n淞\n渎\n涿\n淠\n渑\n淦\n淝\n淙\n渖\n涫\n渌\n涮\n渫\n湮\n湎\n湫\n溲\n湟\n溆\n湓\n湔\n渲\n渥\n湄\n滟\n溱\n溘\n滠\n漭\n滢\n溥\n溧\n溽\n溻\n溷\n滗\n溴\n滏\n溏\n滂\n溟\n潢\n潆\n潇\n漤\n漕\n滹\n漯\n漶\n潋\n潴\n漪\n漉\n漩\n澉\n澍\n澌\n潸\n潲\n潼\n潺\n濑\n錊\n錋\n錌\n錍\n錎\n錏\n錐\n錑\n錒\n錓\n錔\n錕\n錖\n錗\n錘\n錙\n錚\n錛\n錜\n錝\n錞\n錟\n錠\n錡\n錢\n錣\n錤\n錥\n錦\n錧\n錨\n錩\n錪\n錫\n錬\n錭\n錮\n錯\n錰\n錱\n録\n錳\n錴\n錵\n錶\n錷\n錸\n錹\n錺\n錻\n錼\n錽\n錿\n鍀\n鍁\n鍂\n鍃\n鍄\n鍅\n鍆\n鍇\n鍈\n鍉\n鍊\n鍋\n鍌\n鍍\n鍎\n鍏\n鍐\n鍑\n鍒\n鍓\n鍔\n鍕\n鍖\n鍗\n鍘\n鍙\n鍚\n鍛\n鍜\n鍝\n鍞\n鍟\n鍠\n鍡\n鍢\n鍣\n鍤\n鍥\n鍦\n鍧\n鍨\n鍩\n鍫\n濉\n澧\n澹\n澶\n濂\n濡\n濮\n濞\n濠\n濯\n瀚\n瀣\n瀛\n瀹\n瀵\n灏\n灞\n宀\n宄\n宕\n宓\n宥\n宸\n甯\n骞\n搴\n寤\n寮\n褰\n寰\n蹇\n謇\n辶\n迓\n迕\n迥\n迮\n迤\n迩\n迦\n迳\n迨\n逅\n逄\n逋\n逦\n逑\n逍\n逖\n逡\n逵\n逶\n逭\n逯\n遄\n遑\n遒\n遐\n遨\n遘\n遢\n遛\n暹\n遴\n遽\n邂\n邈\n邃\n邋\n彐\n彗\n彖\n彘\n尻\n咫\n屐\n屙\n孱\n屣\n屦\n羼\n弪\n弩\n弭\n艴\n弼\n鬻\n屮\n妁\n妃\n妍\n妩\n妪\n妣\n鍬\n鍭\n鍮\n鍯\n鍰\n鍱\n鍲\n鍳\n鍴\n鍵\n鍶\n鍷\n鍸\n鍹\n鍺\n鍻\n鍼\n鍽\n鍾\n鍿\n鎀\n鎁\n鎂\n鎃\n鎄\n鎅\n鎆\n鎇\n鎈\n鎉\n鎊\n鎋\n鎌\n鎍\n鎎\n鎐\n鎑\n鎒\n鎓\n鎔\n鎕\n鎖\n鎗\n鎘\n鎙\n鎚\n鎛\n鎜\n鎝\n鎞\n鎟\n鎠\n鎡\n鎢\n鎣\n鎤\n鎥\n鎦\n鎧\n鎨\n鎩\n鎪\n鎫\n鎬\n鎭\n鎮\n鎯\n鎰\n鎱\n鎲\n鎳\n鎴\n鎵\n鎶\n鎷\n鎸\n鎹\n鎺\n鎻\n鎼\n鎽\n鎾\n鎿\n鏀\n鏁\n鏂\n鏃\n鏄\n鏅\n鏆\n鏇\n鏈\n鏉\n鏋\n鏌\n鏍\n妗\n姊\n妫\n妞\n妤\n姒\n妲\n妯\n姗\n妾\n娅\n娆\n姝\n娈\n姣\n姘\n姹\n娌\n娉\n娲\n娴\n娑\n娣\n娓\n婀\n婧\n婊\n婕\n娼\n婢\n婵\n胬\n媪\n媛\n婷\n婺\n媾\n嫫\n媲\n嫒\n嫔\n媸\n嫠\n嫣\n嫱\n嫖\n嫦\n嫘\n嫜\n嬉\n嬗\n嬖\n嬲\n嬷\n孀\n尕\n尜\n孚\n孥\n孳\n孑\n孓\n孢\n驵\n驷\n驸\n驺\n驿\n驽\n骀\n骁\n骅\n骈\n骊\n骐\n骒\n骓\n骖\n骘\n骛\n骜\n骝\n骟\n骠\n骢\n骣\n骥\n骧\n纟\n纡\n纣\n纥\n纨\n纩\n鏎\n鏏\n鏐\n鏑\n鏒\n鏓\n鏔\n鏕\n鏗\n鏘\n鏙\n鏚\n鏛\n鏜\n鏝\n鏞\n鏟\n鏠\n鏡\n鏢\n鏣\n鏤\n鏥\n鏦\n鏧\n鏨\n鏩\n鏪\n鏫\n鏬\n鏭\n鏮\n鏯\n鏰\n鏱\n鏲\n鏳\n鏴\n鏵\n鏶\n鏷\n鏸\n鏹\n鏺\n鏻\n鏼\n鏽\n鏾\n鏿\n鐀\n鐁\n鐂\n鐃\n鐄\n鐅\n鐆\n鐇\n鐈\n鐉\n鐊\n鐋\n鐌\n鐍\n鐎\n鐏\n鐐\n鐑\n鐒\n鐓\n鐔\n鐕\n鐖\n鐗\n鐘\n鐙\n鐚\n鐛\n鐜\n鐝\n鐞\n鐟\n鐠\n鐡\n鐢\n鐣\n鐤\n鐥\n鐦\n鐧\n鐨\n鐩\n鐪\n鐫\n鐬\n鐭\n鐮\n纭\n纰\n纾\n绀\n绁\n绂\n绉\n绋\n绌\n绐\n绔\n绗\n绛\n绠\n绡\n绨\n绫\n绮\n绯\n绱\n绲\n缍\n绶\n绺\n绻\n绾\n缁\n缂\n缃\n缇\n缈\n缋\n缌\n缏\n缑\n缒\n缗\n缙\n缜\n缛\n缟\n缡\n缢\n缣\n缤\n缥\n缦\n缧\n缪\n缫\n缬\n缭\n缯\n缰\n缱\n缲\n缳\n缵\n幺\n畿\n巛\n甾\n邕\n玎\n玑\n玮\n玢\n玟\n珏\n珂\n珑\n玷\n玳\n珀\n珉\n珈\n珥\n珙\n顼\n琊\n珩\n珧\n珞\n玺\n珲\n琏\n琪\n瑛\n琦\n琥\n琨\n琰\n琮\n琬\n鐯\n鐰\n鐱\n鐲\n鐳\n鐴\n鐵\n鐶\n鐷\n鐸\n鐹\n鐺\n鐻\n鐼\n鐽\n鐿\n鑀\n鑁\n鑂\n鑃\n鑄\n鑅\n鑆\n鑇\n鑈\n鑉\n鑊\n鑋\n鑌\n鑍\n鑎\n鑏\n鑐\n鑑\n鑒\n鑓\n鑔\n鑕\n鑖\n鑗\n鑘\n鑙\n鑚\n鑛\n鑜\n鑝\n鑞\n鑟\n鑠\n鑡\n鑢\n鑣\n鑤\n鑥\n鑦\n鑧\n鑨\n鑩\n鑪\n鑬\n鑭\n鑮\n鑯\n鑰\n鑱\n鑲\n鑳\n鑴\n鑵\n鑶\n鑷\n鑸\n鑹\n鑺\n鑻\n鑼\n鑽\n鑾\n鑿\n钀\n钁\n钂\n钃\n钄\n钑\n钖\n钘\n铇\n铏\n铓\n铔\n铚\n铦\n铻\n锜\n锠\n琛\n琚\n瑁\n瑜\n瑗\n瑕\n瑙\n瑷\n瑭\n瑾\n璜\n璎\n璀\n璁\n璇\n璋\n璞\n璨\n璩\n璐\n璧\n瓒\n璺\n韪\n韫\n韬\n杌\n杓\n杞\n杈\n杩\n枥\n枇\n杪\n杳\n枘\n枧\n杵\n枨\n枞\n枭\n枋\n杷\n杼\n柰\n栉\n柘\n栊\n柩\n枰\n栌\n柙\n枵\n柚\n枳\n柝\n栀\n柃\n枸\n柢\n栎\n柁\n柽\n栲\n栳\n桠\n桡\n桎\n桢\n桄\n桤\n梃\n栝\n桕\n桦\n桁\n桧\n桀\n栾\n桊\n桉\n栩\n梵\n梏\n桴\n桷\n梓\n桫\n棂\n楮\n棼\n椟\n椠\n棹\n锧\n锳\n锽\n镃\n镈\n镋\n镕\n镚\n镠\n镮\n镴\n镵\n長\n镸\n镹\n镺\n镻\n镼\n镽\n镾\n門\n閁\n閂\n閃\n閄\n閅\n閆\n閇\n閈\n閉\n閊\n開\n閌\n閍\n閎\n閏\n閐\n閑\n閒\n間\n閔\n閕\n閖\n閗\n閘\n閙\n閚\n閛\n閜\n閝\n閞\n閟\n閠\n閡\n関\n閣\n閤\n閥\n閦\n閧\n閨\n閩\n閪\n閫\n閬\n閭\n閮\n閯\n閰\n閱\n閲\n閳\n閴\n閵\n閶\n閷\n閸\n閹\n閺\n閻\n閼\n閽\n閾\n閿\n闀\n闁\n闂\n闃\n闄\n闅\n闆\n闇\n闈\n闉\n闊\n闋\n椤\n棰\n椋\n椁\n楗\n棣\n椐\n楱\n椹\n楠\n楂\n楝\n榄\n楫\n榀\n榘\n楸\n椴\n槌\n榇\n榈\n槎\n榉\n楦\n楣\n楹\n榛\n榧\n榻\n榫\n榭\n槔\n榱\n槁\n槊\n槟\n榕\n槠\n榍\n槿\n樯\n槭\n樗\n樘\n橥\n槲\n橄\n樾\n檠\n橐\n橛\n樵\n檎\n橹\n樽\n樨\n橘\n橼\n檑\n檐\n檩\n檗\n檫\n猷\n獒\n殁\n殂\n殇\n殄\n殒\n殓\n殍\n殚\n殛\n殡\n殪\n轫\n轭\n轱\n轲\n轳\n轵\n轶\n轸\n轷\n轹\n轺\n轼\n轾\n辁\n辂\n辄\n辇\n辋\n闌\n闍\n闎\n闏\n闐\n闑\n闒\n闓\n闔\n闕\n闖\n闗\n闘\n闙\n闚\n闛\n關\n闝\n闞\n闟\n闠\n闡\n闢\n闣\n闤\n闥\n闦\n闧\n闬\n闿\n阇\n阓\n阘\n阛\n阞\n阠\n阣\n阤\n阥\n阦\n阧\n阨\n阩\n阫\n阬\n阭\n阯\n阰\n阷\n阸\n阹\n阺\n阾\n陁\n陃\n陊\n陎\n陏\n陑\n陒\n陓\n陖\n陗\n陘\n陙\n陚\n陜\n陝\n陞\n陠\n陣\n陥\n陦\n陫\n陭\n陮\n陯\n陰\n陱\n陳\n陸\n陹\n険\n陻\n陼\n陽\n陾\n陿\n隀\n隁\n隂\n隃\n隄\n隇\n隉\n隊\n辍\n辎\n辏\n辘\n辚\n軎\n戋\n戗\n戛\n戟\n戢\n戡\n戥\n戤\n戬\n臧\n瓯\n瓴\n瓿\n甏\n甑\n甓\n攴\n旮\n旯\n旰\n昊\n昙\n杲\n昃\n昕\n昀\n炅\n曷\n昝\n昴\n昱\n昶\n昵\n耆\n晟\n晔\n晁\n晏\n晖\n晡\n晗\n晷\n暄\n暌\n暧\n暝\n暾\n曛\n曜\n曦\n曩\n贲\n贳\n贶\n贻\n贽\n赀\n赅\n赆\n赈\n赉\n赇\n赍\n赕\n赙\n觇\n觊\n觋\n觌\n觎\n觏\n觐\n觑\n牮\n犟\n牝\n牦\n牯\n牾\n牿\n犄\n犋\n犍\n犏\n犒\n挈\n挲\n掰\n隌\n階\n隑\n隒\n隓\n隕\n隖\n隚\n際\n隝\n隞\n隟\n隠\n隡\n隢\n隣\n隤\n隥\n隦\n隨\n隩\n險\n隫\n隬\n隭\n隮\n隯\n隱\n隲\n隴\n隵\n隷\n隸\n隺\n隻\n隿\n雂\n雃\n雈\n雊\n雋\n雐\n雑\n雓\n雔\n雖\n雗\n雘\n雙\n雚\n雛\n雜\n雝\n雞\n雟\n雡\n離\n難\n雤\n雥\n雦\n雧\n雫\n雬\n雭\n雮\n雰\n雱\n雲\n雴\n雵\n雸\n雺\n電\n雼\n雽\n雿\n霂\n霃\n霅\n霊\n霋\n霌\n霐\n霑\n霒\n霔\n霕\n霗\n霘\n霙\n霚\n霛\n霝\n霟\n霠\n搿\n擘\n耄\n毪\n毳\n毽\n毵\n毹\n氅\n氇\n氆\n氍\n氕\n氘\n氙\n氚\n氡\n氩\n氤\n氪\n氲\n攵\n敕\n敫\n牍\n牒\n牖\n爰\n虢\n刖\n肟\n肜\n肓\n肼\n朊\n肽\n肱\n肫\n肭\n肴\n肷\n胧\n胨\n胩\n胪\n胛\n胂\n胄\n胙\n胍\n胗\n朐\n胝\n胫\n胱\n胴\n胭\n脍\n脎\n胲\n胼\n朕\n脒\n豚\n脶\n脞\n脬\n脘\n脲\n腈\n腌\n腓\n腴\n腙\n腚\n腱\n腠\n腩\n腼\n腽\n腭\n腧\n塍\n媵\n膈\n膂\n膑\n滕\n膣\n膪\n臌\n朦\n臊\n膻\n霡\n霢\n霣\n霤\n霥\n霦\n霧\n霨\n霩\n霫\n霬\n霮\n霯\n霱\n霳\n霴\n霵\n霶\n霷\n霺\n霻\n霼\n霽\n霿\n靀\n靁\n靂\n靃\n靄\n靅\n靆\n靇\n靈\n靉\n靊\n靋\n靌\n靍\n靎\n靏\n靐\n靑\n靔\n靕\n靗\n靘\n靚\n靜\n靝\n靟\n靣\n靤\n靦\n靧\n靨\n靪\n靫\n靬\n靭\n靮\n靯\n靰\n靱\n靲\n靵\n靷\n靸\n靹\n靺\n靻\n靽\n靾\n靿\n鞀\n鞁\n鞂\n鞃\n鞄\n鞆\n鞇\n鞈\n鞉\n鞊\n鞌\n鞎\n鞏\n鞐\n鞓\n鞕\n鞖\n鞗\n鞙\n鞚\n鞛\n鞜\n鞝\n臁\n膦\n欤\n欷\n欹\n歃\n歆\n歙\n飑\n飒\n飓\n飕\n飙\n飚\n殳\n彀\n毂\n觳\n斐\n齑\n斓\n於\n旆\n旄\n旃\n旌\n旎\n旒\n旖\n炀\n炜\n炖\n炝\n炻\n烀\n炷\n炫\n炱\n烨\n烊\n焐\n焓\n焖\n焯\n焱\n煳\n煜\n煨\n煅\n煲\n煊\n煸\n煺\n熘\n熳\n熵\n熨\n熠\n燠\n燔\n燧\n燹\n爝\n爨\n灬\n焘\n煦\n熹\n戾\n戽\n扃\n扈\n扉\n礻\n祀\n祆\n祉\n祛\n祜\n祓\n祚\n祢\n祗\n祠\n祯\n祧\n祺\n禅\n禊\n禚\n禧\n禳\n忑\n忐\n鞞\n鞟\n鞡\n鞢\n鞤\n鞥\n鞦\n鞧\n鞨\n鞩\n鞪\n鞬\n鞮\n鞰\n鞱\n鞳\n鞵\n鞶\n鞷\n鞸\n鞹\n鞺\n鞻\n鞼\n鞽\n鞾\n鞿\n韀\n韁\n韂\n韃\n韄\n韅\n韆\n韇\n韈\n韉\n韊\n韋\n韌\n韍\n韎\n韏\n韐\n韑\n韒\n韓\n韔\n韕\n韖\n韗\n韘\n韙\n韚\n韛\n韜\n韝\n韞\n韟\n韠\n韡\n韢\n韣\n韤\n韥\n韨\n韮\n韯\n韰\n韱\n韲\n韴\n韷\n韸\n韹\n韺\n韻\n韼\n韽\n韾\n響\n頀\n頁\n頂\n頃\n頄\n項\n順\n頇\n須\n頉\n頊\n頋\n頌\n頍\n頎\n怼\n恝\n恚\n恧\n恁\n恙\n恣\n悫\n愆\n愍\n慝\n憩\n憝\n懋\n懑\n戆\n肀\n聿\n沓\n泶\n淼\n矶\n矸\n砀\n砉\n砗\n砘\n砑\n斫\n砭\n砜\n砝\n砹\n砺\n砻\n砟\n砼\n砥\n砬\n砣\n砩\n硎\n硭\n硖\n硗\n砦\n硐\n硇\n硌\n硪\n碛\n碓\n碚\n碇\n碜\n碡\n碣\n碲\n碹\n碥\n磔\n磙\n磉\n磬\n磲\n礅\n磴\n礓\n礤\n礞\n礴\n龛\n黹\n黻\n黼\n盱\n眄\n眍\n盹\n眇\n眈\n眚\n眢\n眙\n眭\n眦\n眵\n眸\n睐\n睑\n睇\n睃\n睚\n睨\n頏\n預\n頑\n頒\n頓\n頔\n頕\n頖\n頗\n領\n頙\n頚\n頛\n頜\n頝\n頞\n頟\n頠\n頡\n頢\n頣\n頤\n頥\n頦\n頧\n頨\n頩\n頪\n頫\n頬\n頭\n頮\n頯\n頰\n頱\n頲\n頳\n頴\n頵\n頶\n頷\n頸\n頹\n頺\n頻\n頼\n頽\n頾\n頿\n顀\n顁\n顂\n顃\n顄\n顅\n顆\n顇\n顈\n顉\n顊\n顋\n題\n額\n顎\n顏\n顐\n顑\n顒\n顓\n顔\n顕\n顖\n顗\n願\n顙\n顚\n顛\n顜\n顝\n類\n顟\n顠\n顡\n顢\n顣\n顤\n顥\n顦\n顧\n顨\n顩\n顪\n顫\n顬\n顭\n顮\n睢\n睥\n睿\n瞍\n睽\n瞀\n瞌\n瞑\n瞟\n瞠\n瞰\n瞵\n瞽\n町\n畀\n畎\n畋\n畈\n畛\n畲\n畹\n疃\n罘\n罡\n罟\n詈\n罨\n罴\n罱\n罹\n羁\n罾\n盍\n盥\n蠲\n钅\n钆\n钇\n钋\n钊\n钌\n钍\n钏\n钐\n钔\n钗\n钕\n钚\n钛\n钜\n钣\n钤\n钫\n钪\n钭\n钬\n钯\n钰\n钲\n钴\n钶\n钷\n钸\n钹\n钺\n钼\n钽\n钿\n铄\n铈\n铉\n铊\n铋\n铌\n铍\n铎\n铐\n铑\n铒\n铕\n铖\n铗\n铙\n铘\n铛\n铞\n铟\n铠\n铢\n铤\n铥\n铧\n铨\n铪\n顯\n顰\n顱\n顲\n顳\n顴\n颋\n颎\n颒\n颕\n颙\n颣\n風\n颩\n颪\n颫\n颬\n颭\n颮\n颯\n颰\n颱\n颲\n颳\n颴\n颵\n颶\n颷\n颸\n颹\n颺\n颻\n颼\n颽\n颾\n颿\n飀\n飁\n飂\n飃\n飄\n飅\n飆\n飇\n飈\n飉\n飊\n飋\n飌\n飍\n飏\n飐\n飔\n飖\n飗\n飛\n飜\n飝\n飠\n飡\n飢\n飣\n飤\n飥\n飦\n飩\n飪\n飫\n飬\n飭\n飮\n飯\n飰\n飱\n飲\n飳\n飴\n飵\n飶\n飷\n飸\n飹\n飺\n飻\n飼\n飽\n飾\n飿\n餀\n餁\n餂\n餃\n餄\n餅\n餆\n餇\n铩\n铫\n铮\n铯\n铳\n铴\n铵\n铷\n铹\n铼\n铽\n铿\n锃\n锂\n锆\n锇\n锉\n锊\n锍\n锎\n锏\n锒\n锓\n锔\n锕\n锖\n锘\n锛\n锝\n锞\n锟\n锢\n锪\n锫\n锩\n锬\n锱\n锲\n锴\n锶\n锷\n锸\n锼\n锾\n锿\n镂\n锵\n镄\n镅\n镆\n镉\n镌\n镎\n镏\n镒\n镓\n镔\n镖\n镗\n镘\n镙\n镛\n镞\n镟\n镝\n镡\n镢\n镤\n镥\n镦\n镧\n镨\n镩\n镪\n镫\n镬\n镯\n镱\n镲\n镳\n锺\n矧\n矬\n雉\n秕\n秭\n秣\n秫\n稆\n嵇\n稃\n稂\n稞\n稔\n餈\n餉\n養\n餋\n餌\n餎\n餏\n餑\n餒\n餓\n餔\n餕\n餖\n餗\n餘\n餙\n餚\n餛\n餜\n餝\n餞\n餟\n餠\n餡\n餢\n餣\n餤\n餥\n餦\n餧\n館\n餩\n餪\n餫\n餬\n餭\n餯\n餰\n餱\n餲\n餳\n餴\n餵\n餶\n餷\n餸\n餹\n餺\n餻\n餼\n餽\n餾\n餿\n饀\n饁\n饂\n饃\n饄\n饅\n饆\n饇\n饈\n饉\n饊\n饋\n饌\n饍\n饎\n饏\n饐\n饑\n饒\n饓\n饖\n饗\n饘\n饙\n饚\n饛\n饜\n饝\n饞\n饟\n饠\n饡\n饢\n饤\n饦\n饳\n饸\n饹\n饻\n饾\n馂\n馃\n馉\n稹\n稷\n穑\n黏\n馥\n穰\n皈\n皎\n皓\n皙\n皤\n瓞\n瓠\n甬\n鸠\n鸢\n鸨\n鸩\n鸪\n鸫\n鸬\n鸲\n鸱\n鸶\n鸸\n鸷\n鸹\n鸺\n鸾\n鹁\n鹂\n鹄\n鹆\n鹇\n鹈\n鹉\n鹋\n鹌\n鹎\n鹑\n鹕\n鹗\n鹚\n鹛\n鹜\n鹞\n鹣\n鹦\n鹧\n鹨\n鹩\n鹪\n鹫\n鹬\n鹱\n鹭\n鹳\n疒\n疔\n疖\n疠\n疝\n疬\n疣\n疳\n疴\n疸\n痄\n疱\n疰\n痃\n痂\n痖\n痍\n痣\n痨\n痦\n痤\n痫\n痧\n瘃\n痱\n痼\n痿\n瘐\n瘀\n瘅\n瘌\n瘗\n瘊\n瘥\n瘘\n瘕\n瘙\n馌\n馎\n馚\n馛\n馜\n馝\n馞\n馟\n馠\n馡\n馢\n馣\n馤\n馦\n馧\n馩\n馪\n馫\n馬\n馭\n馮\n馯\n馰\n馱\n馲\n馳\n馴\n馵\n馶\n馷\n馸\n馹\n馺\n馻\n馼\n馽\n馾\n馿\n駀\n駁\n駂\n駃\n駄\n駅\n駆\n駇\n駈\n駉\n駊\n駋\n駌\n駍\n駎\n駏\n駐\n駑\n駒\n駓\n駔\n駕\n駖\n駗\n駘\n駙\n駚\n駛\n駜\n駝\n駞\n駟\n駠\n駡\n駢\n駣\n駤\n駥\n駦\n駧\n駨\n駩\n駪\n駫\n駬\n駭\n駮\n駯\n駰\n駱\n駲\n駳\n駴\n駵\n駶\n駷\n駸\n駹\n瘛\n瘼\n瘢\n瘠\n癀\n瘭\n瘰\n瘿\n瘵\n癃\n瘾\n瘳\n癍\n癞\n癔\n癜\n癖\n癫\n癯\n翊\n竦\n穸\n穹\n窀\n窆\n窈\n窕\n窦\n窠\n窬\n窨\n窭\n窳\n衤\n衩\n衲\n衽\n衿\n袂\n袢\n裆\n袷\n袼\n裉\n裢\n裎\n裣\n裥\n裱\n褚\n裼\n裨\n裾\n裰\n褡\n褙\n褓\n褛\n褊\n褴\n褫\n褶\n襁\n襦\n襻\n疋\n胥\n皲\n皴\n矜\n耒\n耔\n耖\n耜\n耠\n耢\n耥\n耦\n耧\n耩\n耨\n耱\n耋\n耵\n聃\n聆\n聍\n聒\n聩\n聱\n覃\n顸\n颀\n颃\n駺\n駻\n駼\n駽\n駾\n駿\n騀\n騁\n騂\n騃\n騄\n騅\n騆\n騇\n騈\n騉\n騊\n騋\n騌\n騍\n騎\n騏\n騐\n騑\n騒\n験\n騔\n騕\n騖\n騗\n騘\n騙\n騚\n騛\n騜\n騝\n騞\n騟\n騠\n騡\n騢\n騣\n騤\n騥\n騦\n騧\n騨\n騩\n騪\n騫\n騬\n騭\n騮\n騯\n騰\n騱\n騲\n騳\n騴\n騵\n騶\n騷\n騸\n騹\n騺\n騻\n騼\n騽\n騾\n騿\n驀\n驁\n驂\n驃\n驄\n驅\n驆\n驇\n驈\n驉\n驊\n驋\n驌\n驍\n驎\n驏\n驐\n驑\n驒\n驓\n驔\n驕\n驖\n驗\n驘\n驙\n颉\n颌\n颍\n颏\n颔\n颚\n颛\n颞\n颟\n颡\n颢\n颥\n颦\n虍\n虔\n虬\n虮\n虿\n虺\n虼\n虻\n蚨\n蚍\n蚋\n蚬\n蚝\n蚧\n蚣\n蚪\n蚓\n蚩\n蚶\n蛄\n蚵\n蛎\n蚰\n蚺\n蚱\n蚯\n蛉\n蛏\n蚴\n蛩\n蛱\n蛲\n蛭\n蛳\n蛐\n蜓\n蛞\n蛴\n蛟\n蛘\n蛑\n蜃\n蜇\n蛸\n蜈\n蜊\n蜍\n蜉\n蜣\n蜻\n蜞\n蜥\n蜮\n蜚\n蜾\n蝈\n蜴\n蜱\n蜩\n蜷\n蜿\n螂\n蜢\n蝽\n蝾\n蝻\n蝠\n蝰\n蝌\n蝮\n螋\n蝓\n蝣\n蝼\n蝤\n蝙\n蝥\n螓\n螯\n螨\n蟒\n驚\n驛\n驜\n驝\n驞\n驟\n驠\n驡\n驢\n驣\n驤\n驥\n驦\n驧\n驨\n驩\n驪\n驫\n驲\n骃\n骉\n骍\n骎\n骔\n骕\n骙\n骦\n骩\n骪\n骫\n骬\n骭\n骮\n骯\n骲\n骳\n骴\n骵\n骹\n骻\n骽\n骾\n骿\n髃\n髄\n髆\n髇\n髈\n髉\n髊\n髍\n髎\n髏\n髐\n髒\n體\n髕\n髖\n髗\n髙\n髚\n髛\n髜\n髝\n髞\n髠\n髢\n髣\n髤\n髥\n髧\n髨\n髩\n髪\n髬\n髮\n髰\n髱\n髲\n髳\n髴\n髵\n髶\n髷\n髸\n髺\n髼\n髽\n髾\n髿\n鬀\n鬁\n鬂\n鬄\n鬅\n鬆\n蟆\n螈\n螅\n螭\n螗\n螃\n螫\n蟥\n螬\n螵\n螳\n蟋\n蟓\n螽\n蟑\n蟀\n蟊\n蟛\n蟪\n蟠\n蟮\n蠖\n蠓\n蟾\n蠊\n蠛\n蠡\n蠹\n蠼\n缶\n罂\n罄\n罅\n舐\n竺\n竽\n笈\n笃\n笄\n笕\n笊\n笫\n笏\n筇\n笸\n笪\n笙\n笮\n笱\n笠\n笥\n笤\n笳\n笾\n笞\n筘\n筚\n筅\n筵\n筌\n筝\n筠\n筮\n筻\n筢\n筲\n筱\n箐\n箦\n箧\n箸\n箬\n箝\n箨\n箅\n箪\n箜\n箢\n箫\n箴\n篑\n篁\n篌\n篝\n篚\n篥\n篦\n篪\n簌\n篾\n篼\n簏\n簖\n簋\n鬇\n鬉\n鬊\n鬋\n鬌\n鬍\n鬎\n鬐\n鬑\n鬒\n鬔\n鬕\n鬖\n鬗\n鬘\n鬙\n鬚\n鬛\n鬜\n鬝\n鬞\n鬠\n鬡\n鬢\n鬤\n鬥\n鬦\n鬧\n鬨\n鬩\n鬪\n鬫\n鬬\n鬭\n鬮\n鬰\n鬱\n鬳\n鬴\n鬵\n鬶\n鬷\n鬸\n鬹\n鬺\n鬽\n鬾\n鬿\n魀\n魆\n魊\n魋\n魌\n魎\n魐\n魒\n魓\n魕\n魖\n魗\n魘\n魙\n魚\n魛\n魜\n魝\n魞\n魟\n魠\n魡\n魢\n魣\n魤\n魥\n魦\n魧\n魨\n魩\n魪\n魫\n魬\n魭\n魮\n魯\n魰\n魱\n魲\n魳\n魴\n魵\n魶\n魷\n魸\n魹\n魺\n魻\n簟\n簪\n簦\n簸\n籁\n籀\n臾\n舁\n舂\n舄\n臬\n衄\n舡\n舢\n舣\n舭\n舯\n舨\n舫\n舸\n舻\n舳\n舴\n舾\n艄\n艉\n艋\n艏\n艚\n艟\n艨\n衾\n袅\n袈\n裘\n裟\n襞\n羝\n羟\n羧\n羯\n羰\n羲\n籼\n敉\n粑\n粝\n粜\n粞\n粢\n粲\n粼\n粽\n糁\n糇\n糌\n糍\n糈\n糅\n糗\n糨\n艮\n暨\n羿\n翎\n翕\n翥\n翡\n翦\n翩\n翮\n翳\n糸\n絷\n綦\n綮\n繇\n纛\n麸\n麴\n赳\n趄\n趔\n趑\n趱\n赧\n赭\n豇\n豉\n酊\n酐\n酎\n酏\n酤\n魼\n魽\n魾\n魿\n鮀\n鮁\n鮂\n鮃\n鮄\n鮅\n鮆\n鮇\n鮈\n鮉\n鮊\n鮋\n鮌\n鮍\n鮎\n鮏\n鮐\n鮑\n鮒\n鮓\n鮔\n鮕\n鮖\n鮗\n鮘\n鮙\n鮚\n鮛\n鮜\n鮝\n鮞\n鮟\n鮠\n鮡\n鮢\n鮣\n鮤\n鮥\n鮦\n鮧\n鮨\n鮩\n鮪\n鮫\n鮬\n鮭\n鮮\n鮯\n鮰\n鮱\n鮲\n鮳\n鮴\n鮵\n鮶\n鮷\n鮸\n鮹\n鮺\n鮻\n鮼\n鮽\n鮾\n鮿\n鯀\n鯁\n鯂\n鯃\n鯄\n鯅\n鯆\n鯇\n鯈\n鯉\n鯊\n鯋\n鯌\n鯍\n鯎\n鯏\n鯐\n鯑\n鯒\n鯓\n鯔\n鯕\n鯖\n鯗\n鯘\n鯙\n鯚\n鯛\n酢\n酡\n酰\n酩\n酯\n酽\n酾\n酲\n酴\n酹\n醌\n醅\n醐\n醍\n醑\n醢\n醣\n醪\n醭\n醮\n醯\n醵\n醴\n醺\n豕\n鹾\n趸\n跫\n踅\n蹙\n蹩\n趵\n趿\n趼\n趺\n跄\n跖\n跗\n跚\n跞\n跎\n跏\n跛\n跆\n跬\n跷\n跸\n跣\n跹\n跻\n跤\n踉\n跽\n踔\n踝\n踟\n踬\n踮\n踣\n踯\n踺\n蹀\n踹\n踵\n踽\n踱\n蹉\n蹁\n蹂\n蹑\n蹒\n蹊\n蹰\n蹶\n蹼\n蹯\n蹴\n躅\n躏\n躔\n躐\n躜\n躞\n豸\n貂\n貊\n貅\n貘\n貔\n斛\n觖\n觞\n觚\n觜\n鯜\n鯝\n鯞\n鯟\n鯠\n鯡\n鯢\n鯣\n鯤\n鯥\n鯦\n鯧\n鯨\n鯩\n鯪\n鯫\n鯬\n鯭\n鯮\n鯯\n鯰\n鯱\n鯲\n鯳\n鯴\n鯵\n鯶\n鯷\n鯸\n鯹\n鯺\n鯻\n鯼\n鯽\n鯾\n鯿\n鰀\n鰁\n鰂\n鰃\n鰄\n鰅\n鰆\n鰇\n鰈\n鰉\n鰊\n鰋\n鰌\n鰍\n鰎\n鰏\n鰐\n鰑\n鰒\n鰓\n鰔\n鰕\n鰖\n鰗\n鰘\n鰙\n鰚\n鰛\n鰜\n鰝\n鰞\n鰟\n鰠\n鰡\n鰢\n鰣\n鰤\n鰥\n鰦\n鰧\n鰨\n鰩\n鰪\n鰫\n鰬\n鰭\n鰮\n鰯\n鰰\n鰱\n鰲\n鰳\n鰴\n鰵\n鰶\n鰷\n鰸\n鰹\n鰺\n鰻\n觥\n觫\n觯\n訾\n謦\n靓\n雩\n雳\n雯\n霆\n霁\n霈\n霏\n霎\n霪\n霭\n霰\n霾\n龀\n龃\n龅\n龆\n龇\n龈\n龉\n龊\n龌\n黾\n鼋\n鼍\n隹\n隼\n隽\n雎\n雒\n瞿\n雠\n銎\n銮\n鋈\n錾\n鍪\n鏊\n鎏\n鐾\n鑫\n鱿\n鲂\n鲅\n鲆\n鲇\n鲈\n稣\n鲋\n鲎\n鲐\n鲑\n鲒\n鲔\n鲕\n鲚\n鲛\n鲞\n鲟\n鲠\n鲡\n鲢\n鲣\n鲥\n鲦\n鲧\n鲨\n鲩\n鲫\n鲭\n鲮\n鲰\n鲱\n鲲\n鲳\n鲴\n鲵\n鲶\n鲷\n鲺\n鲻\n鲼\n鲽\n鳄\n鳅\n鳆\n鳇\n鳊\n鳋\n鰼\n鰽\n鰾\n鰿\n鱀\n鱁\n鱂\n鱃\n鱄\n鱅\n鱆\n鱇\n鱈\n鱉\n鱊\n鱋\n鱌\n鱍\n鱎\n鱏\n鱐\n鱑\n鱒\n鱓\n鱔\n鱕\n鱖\n鱗\n鱘\n鱙\n鱚\n鱛\n鱜\n鱝\n鱞\n鱟\n鱠\n鱡\n鱢\n鱣\n鱤\n鱥\n鱦\n鱧\n鱨\n鱩\n鱪\n鱫\n鱬\n鱭\n鱮\n鱯\n鱰\n鱱\n鱲\n鱳\n鱴\n鱵\n鱶\n鱷\n鱸\n鱹\n鱺\n鱻\n鱽\n鱾\n鲀\n鲃\n鲄\n鲉\n鲊\n鲌\n鲏\n鲓\n鲖\n鲗\n鲘\n鲙\n鲝\n鲪\n鲬\n鲯\n鲹\n鲾\n鲿\n鳀\n鳁\n鳂\n鳈\n鳉\n鳑\n鳒\n鳚\n鳛\n鳠\n鳡\n鳌\n鳍\n鳎\n鳏\n鳐\n鳓\n鳔\n鳕\n鳗\n鳘\n鳙\n鳜\n鳝\n鳟\n鳢\n靼\n鞅\n鞑\n鞒\n鞔\n鞯\n鞫\n鞣\n鞲\n鞴\n骱\n骰\n骷\n鹘\n骶\n骺\n骼\n髁\n髀\n髅\n髂\n髋\n髌\n髑\n魅\n魃\n魇\n魉\n魈\n魍\n魑\n飨\n餍\n餮\n饕\n饔\n髟\n髡\n髦\n髯\n髫\n髻\n髭\n髹\n鬈\n鬏\n鬓\n鬟\n鬣\n麽\n麾\n縻\n麂\n麇\n麈\n麋\n麒\n鏖\n麝\n麟\n黛\n黜\n黝\n黠\n黟\n黢\n黩\n黧\n黥\n黪\n黯\n鼢\n鼬\n鼯\n鼹\n鼷\n鼽\n鼾\n齄\n鳣\n鳤\n鳥\n鳦\n鳧\n鳨\n鳩\n鳪\n鳫\n鳬\n鳭\n鳮\n鳯\n鳰\n鳱\n鳲\n鳳\n鳴\n鳵\n鳶\n鳷\n鳸\n鳹\n鳺\n鳻\n鳼\n鳽\n鳾\n鳿\n鴀\n鴁\n鴂\n鴃\n鴄\n鴅\n鴆\n鴇\n鴈\n鴉\n鴊\n鴋\n鴌\n鴍\n鴎\n鴏\n鴐\n鴑\n鴒\n鴓\n鴔\n鴕\n鴖\n鴗\n鴘\n鴙\n鴚\n鴛\n鴜\n鴝\n鴞\n鴟\n鴠\n鴡\n鴢\n鴣\n鴤\n鴥\n鴦\n鴧\n鴨\n鴩\n鴪\n鴫\n鴬\n鴭\n鴮\n鴯\n鴰\n鴱\n鴲\n鴳\n鴴\n鴵\n鴶\n鴷\n鴸\n鴹\n鴺\n鴻\n鴼\n鴽\n鴾\n鴿\n鵀\n鵁\n鵂\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n鵃\n鵄\n鵅\n鵆\n鵇\n鵈\n鵉\n鵊\n鵋\n鵌\n鵍\n鵎\n鵏\n鵐\n鵑\n鵒\n鵓\n鵔\n鵕\n鵖\n鵗\n鵘\n鵙\n鵚\n鵛\n鵜\n鵝\n鵞\n鵟\n鵠\n鵡\n鵢\n鵣\n鵤\n鵥\n鵦\n鵧\n鵨\n鵩\n鵪\n鵫\n鵬\n鵭\n鵮\n鵯\n鵰\n鵱\n鵲\n鵳\n鵴\n鵵\n鵶\n鵷\n鵸\n鵹\n鵺\n鵻\n鵼\n鵽\n鵾\n鵿\n鶀\n鶁\n鶂\n鶃\n鶄\n鶅\n鶆\n鶇\n鶈\n鶉\n鶊\n鶋\n鶌\n鶍\n鶎\n鶏\n鶐\n鶑\n鶒\n鶓\n鶔\n鶕\n鶖\n鶗\n鶘\n鶙\n鶚\n鶛\n鶜\n鶝\n鶞\n鶟\n鶠\n鶡\n鶢\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n鶣\n鶤\n鶥\n鶦\n鶧\n鶨\n鶩\n鶪\n鶫\n鶬\n鶭\n鶮\n鶯\n鶰\n鶱\n鶲\n鶳\n鶴\n鶵\n鶶\n鶷\n鶸\n鶹\n鶺\n鶻\n鶼\n鶽\n鶾\n鶿\n鷀\n鷁\n鷂\n鷃\n鷄\n鷅\n鷆\n鷇\n鷈\n鷉\n鷊\n鷋\n鷌\n鷍\n鷎\n鷏\n鷐\n鷑\n鷒\n鷓\n鷔\n鷕\n鷖\n鷗\n鷘\n鷙\n鷚\n鷛\n鷜\n鷝\n鷞\n鷟\n鷠\n鷡\n鷢\n鷣\n鷤\n鷥\n鷦\n鷧\n鷨\n鷩\n鷪\n鷫\n鷬\n鷭\n鷮\n鷯\n鷰\n鷱\n鷲\n鷳\n鷴\n鷵\n鷶\n鷷\n鷸\n鷹\n鷺\n鷻\n鷼\n鷽\n鷾\n鷿\n鸀\n鸁\n鸂\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n鸃\n鸄\n鸅\n鸆\n鸇\n鸈\n鸉\n鸊\n鸋\n鸌\n鸍\n鸎\n鸏\n鸐\n鸑\n鸒\n鸓\n鸔\n鸕\n鸖\n鸗\n鸘\n鸙\n鸚\n鸛\n鸜\n鸝\n鸞\n鸤\n鸧\n鸮\n鸰\n鸴\n鸻\n鸼\n鹀\n鹍\n鹐\n鹒\n鹓\n鹔\n鹖\n鹙\n鹝\n鹟\n鹠\n鹡\n鹢\n鹥\n鹮\n鹯\n鹲\n鹴\n鹵\n鹶\n鹷\n鹸\n鹹\n鹺\n鹻\n鹼\n鹽\n麀\n麁\n麃\n麄\n麅\n麆\n麉\n麊\n麌\n麍\n麎\n麏\n麐\n麑\n麔\n麕\n麖\n麗\n麘\n麙\n麚\n麛\n麜\n麞\n麠\n麡\n麢\n麣\n麤\n麥\n麧\n麨\n麩\n麪\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n麫\n麬\n麭\n麮\n麯\n麰\n麱\n麲\n麳\n麵\n麶\n麷\n麹\n麺\n麼\n麿\n黀\n黁\n黂\n黃\n黅\n黆\n黇\n黈\n黊\n黋\n黌\n黐\n黒\n黓\n黕\n黖\n黗\n黙\n黚\n點\n黡\n黣\n黤\n黦\n黨\n黫\n黬\n黭\n黮\n黰\n黱\n黲\n黳\n黴\n黵\n黶\n黷\n黸\n黺\n黽\n黿\n鼀\n鼁\n鼂\n鼃\n鼄\n鼅\n鼆\n鼇\n鼈\n鼉\n鼊\n鼌\n鼏\n鼑\n鼒\n鼔\n鼕\n鼖\n鼘\n鼚\n鼛\n鼜\n鼝\n鼞\n鼟\n鼡\n鼣\n鼤\n鼥\n鼦\n鼧\n鼨\n鼩\n鼪\n鼫\n鼭\n鼮\n鼰\n鼱\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n鼲\n鼳\n鼴\n鼵\n鼶\n鼸\n鼺\n鼼\n鼿\n齀\n齁\n齂\n齃\n齅\n齆\n齇\n齈\n齉\n齊\n齋\n齌\n齍\n齎\n齏\n齒\n齓\n齔\n齕\n齖\n齗\n齘\n齙\n齚\n齛\n齜\n齝\n齞\n齟\n齠\n齡\n齢\n齣\n齤\n齥\n齦\n齧\n齨\n齩\n齪\n齫\n齬\n齭\n齮\n齯\n齰\n齱\n齲\n齳\n齴\n齵\n齶\n齷\n齸\n齹\n齺\n齻\n齼\n齽\n齾\n龁\n龂\n龍\n龎\n龏\n龐\n龑\n龒\n龓\n龔\n龕\n龖\n龗\n龘\n龜\n龝\n龞\n龡\n龢\n龣\n龤\n龥\n郎\n凉\n秊\n裏\n隣\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n兀\n嗀\n﨎\n﨏\n﨑\n﨓\n﨔\n礼\n﨟\n蘒\n﨡\n﨣\n﨤\n﨧\n﨨\n﨩\n⺁\n\n\n\n⺄\n㑳\n㑇\n⺈\n⺋\n龴\n㖞\n㘚\n㘎\n⺌\n⺗\n㥮\n㤘\n龵\n㧏\n㧟\n㩳\n㧐\n龶\n龷\n㭎\n㱮\n㳠\n⺧\n\n龸\n⺪\n䁖\n䅟\n⺮\n䌷\n⺳\n⺶\n⺷\n\n䎱\n䎬\n⺻\n䏝\n䓖\n䙡\n䙌\n龹\n䜣\n䜩\n䝼\n䞍\n⻊\n䥇\n䥺\n䥽\n䦂\n䦃\n䦅\n䦆\n䦟\n䦛\n䦷\n䦶\n龺\n\n䲣\n䲟\n䲠\n䲡\n䱷\n䲢\n䴓\n䴔\n䴕\n䴖\n䴗\n䴘\n䴙\n䶮\n龻\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/gb18030_out_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n¡\n¢\n£\n¤\n¥\n¦\n§\n¨\n©\nª\n«\n¬\n­\n®\n¯\n°\n±\n²\n³\n´\nµ\n¶\n·\n¸\n¹\nº\n»\n¼\n½\n¾\n¿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nÀ\nÁ\nÂ\nÃ\nÄ\nÅ\nÆ\nÇ\nÈ\nÉ\nÊ\nË\nÌ\nÍ\nÎ\nÏ\nÐ\nÑ\nÒ\nÓ\nÔ\nÕ\nÖ\n×\nØ\nÙ\nÚ\nÛ\nÜ\nÝ\nÞ\nß\nà\ná\nâ\nã\nä\nå\næ\nç\nè\né\nê\në\nì\ní\nî\nï\nð\nñ\nò\nó\nô\nõ\nö\n÷\nø\nù\nú\nû\nü\ný\nþ\nÿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nĀ\nā\nĂ\nă\nĄ\ną\nĆ\nć\nĈ\nĉ\nĊ\nċ\nČ\nč\nĎ\nď\nĐ\nđ\nĒ\nē\nĔ\nĕ\nĖ\nė\nĘ\nę\nĚ\ně\nĜ\nĝ\nĞ\nğ\nĠ\nġ\nĢ\nģ\nĤ\nĥ\nĦ\nħ\nĨ\nĩ\nĪ\nī\nĬ\nĭ\nĮ\nį\nİ\nı\nĲ\nĳ\nĴ\nĵ\nĶ\nķ\nĸ\nĹ\nĺ\nĻ\nļ\nĽ\nľ\nĿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nŀ\nŁ\nł\nŃ\nń\nŅ\nņ\nŇ\nň\nŉ\nŊ\nŋ\nŌ\nō\nŎ\nŏ\nŐ\nő\nŒ\nœ\nŔ\nŕ\nŖ\nŗ\nŘ\nř\nŚ\nś\nŜ\nŝ\nŞ\nş\nŠ\nš\nŢ\nţ\nŤ\nť\nŦ\nŧ\nŨ\nũ\nŪ\nū\nŬ\nŭ\nŮ\nů\nŰ\nű\nŲ\nų\nŴ\nŵ\nŶ\nŷ\nŸ\nŹ\nź\nŻ\nż\nŽ\nž\nſ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nƀ\nƁ\nƂ\nƃ\nƄ\nƅ\nƆ\nƇ\nƈ\nƉ\nƊ\nƋ\nƌ\nƍ\nƎ\nƏ\nƐ\nƑ\nƒ\nƓ\nƔ\nƕ\nƖ\nƗ\nƘ\nƙ\nƚ\nƛ\nƜ\nƝ\nƞ\nƟ\nƠ\nơ\nƢ\nƣ\nƤ\nƥ\nƦ\nƧ\nƨ\nƩ\nƪ\nƫ\nƬ\nƭ\nƮ\nƯ\nư\nƱ\nƲ\nƳ\nƴ\nƵ\nƶ\nƷ\nƸ\nƹ\nƺ\nƻ\nƼ\nƽ\nƾ\nƿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nǀ\nǁ\nǂ\nǃ\nǄ\nǅ\nǆ\nǇ\nǈ\nǉ\nǊ\nǋ\nǌ\nǍ\nǎ\nǏ\nǐ\nǑ\nǒ\nǓ\nǔ\nǕ\nǖ\nǗ\nǘ\nǙ\nǚ\nǛ\nǜ\nǝ\nǞ\nǟ\nǠ\nǡ\nǢ\nǣ\nǤ\nǥ\nǦ\nǧ\nǨ\nǩ\nǪ\nǫ\nǬ\nǭ\nǮ\nǯ\nǰ\nǱ\nǲ\nǳ\nǴ\nǵ\nǶ\nǷ\nǸ\nǹ\nǺ\nǻ\nǼ\nǽ\nǾ\nǿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nȀ\nȁ\nȂ\nȃ\nȄ\nȅ\nȆ\nȇ\nȈ\nȉ\nȊ\nȋ\nȌ\nȍ\nȎ\nȏ\nȐ\nȑ\nȒ\nȓ\nȔ\nȕ\nȖ\nȗ\nȘ\nș\nȚ\nț\nȜ\nȝ\nȞ\nȟ\nȠ\nȡ\nȢ\nȣ\nȤ\nȥ\nȦ\nȧ\nȨ\nȩ\nȪ\nȫ\nȬ\nȭ\nȮ\nȯ\nȰ\nȱ\nȲ\nȳ\nȴ\nȵ\nȶ\nȷ\nȸ\nȹ\nȺ\nȻ\nȼ\nȽ\nȾ\nȿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nɀ\nɁ\nɂ\nɃ\nɄ\nɅ\nɆ\nɇ\nɈ\nɉ\nɊ\nɋ\nɌ\nɍ\nɎ\nɏ\nɐ\nɑ\nɒ\nɓ\nɔ\nɕ\nɖ\nɗ\nɘ\nə\nɚ\nɛ\nɜ\nɝ\nɞ\nɟ\nɠ\nɡ\nɢ\nɣ\nɤ\nɥ\nɦ\nɧ\nɨ\nɩ\nɪ\nɫ\nɬ\nɭ\nɮ\nɯ\nɰ\nɱ\nɲ\nɳ\nɴ\nɵ\nɶ\nɷ\nɸ\nɹ\nɺ\nɻ\nɼ\nɽ\nɾ\nɿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nʀ\nʁ\nʂ\nʃ\nʄ\nʅ\nʆ\nʇ\nʈ\nʉ\nʊ\nʋ\nʌ\nʍ\nʎ\nʏ\nʐ\nʑ\nʒ\nʓ\nʔ\nʕ\nʖ\nʗ\nʘ\nʙ\nʚ\nʛ\nʜ\nʝ\nʞ\nʟ\nʠ\nʡ\nʢ\nʣ\nʤ\nʥ\nʦ\nʧ\nʨ\nʩ\nʪ\nʫ\nʬ\nʭ\nʮ\nʯ\nʰ\nʱ\nʲ\nʳ\nʴ\nʵ\nʶ\nʷ\nʸ\nʹ\nʺ\nʻ\nʼ\nʽ\nʾ\nʿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nˀ\nˁ\n˂\n˃\n˄\n˅\nˆ\nˇ\nˈ\nˉ\nˊ\nˋ\nˌ\nˍ\nˎ\nˏ\nː\nˑ\n˒\n˓\n˔\n˕\n˖\n˗\n˘\n˙\n˚\n˛\n˜\n˝\n˞\n˟\nˠ\nˡ\nˢ\nˣ\nˤ\n˥\n˦\n˧\n˨\n˩\n˪\n˫\nˬ\n˭\nˮ\n˯\n˰\n˱\n˲\n˳\n˴\n˵\n˶\n˷\n˸\n˹\n˺\n˻\n˼\n˽\n˾\n˿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\ǹ\ń\n̂\ñ\n̄\n̅\n̆\ṅ\n̈\n̉\n̊\n̋\ň\n̍\n̎\n̏\n̐\n̑\n̒\n̓\n̔\n̕\n̖\n̗\n̘\n̙\n̚\n̛\n̜\n̝\n̞\n̟\n̠\n̡\n̢\ṇ\n̤\n̥\n̦\ņ\n̨\n̩\n̪\n̫\n̬\ṋ\n̮\n̯\n̰\ṉ\n̲\n̳\n̴\n̵\n̶\n̷\n̸\n̹\n̺\n̻\n̼\n̽\n̾\n̿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\ǹ\ń\n͂\n̓\n̈́\nͅ\n͆\n͇\n͈\n͉\n͊\n͋\n͌\n͍\n͎\n͏\n͐\n͑\n͒\n͓\n͔\n͕\n͖\n͗\n͘\n͙\n͚\n͛\n͜\n͝\n͞\n͟\n͠\n͡\n͢\nͣ\nͤ\nͥ\nͦ\nͧ\nͨ\nͩ\nͪ\nͫ\nͬ\nͭ\nͮ\nͯ\nͰ\nͱ\nͲ\nͳ\nʹ\n͵\nͶ\nͷ\n͸\n͹\nͺ\nͻ\nͼ\nͽ\n;\nͿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n΀\n΁\n΂\n΃\n΄\n΅\nΆ\n·\nΈ\nΉ\nΊ\n΋\nΌ\n΍\nΎ\nΏ\nΐ\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\n΢\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nΪ\nΫ\nά\nέ\nή\nί\nΰ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nπ\nρ\nς\nσ\nτ\nυ\nφ\nχ\nψ\nω\nϊ\nϋ\nό\nύ\nώ\nϏ\nϐ\nϑ\nϒ\nϓ\nϔ\nϕ\nϖ\nϗ\nϘ\nϙ\nϚ\nϛ\nϜ\nϝ\nϞ\nϟ\nϠ\nϡ\nϢ\nϣ\nϤ\nϥ\nϦ\nϧ\nϨ\nϩ\nϪ\nϫ\nϬ\nϭ\nϮ\nϯ\nϰ\nϱ\nϲ\nϳ\nϴ\nϵ\n϶\nϷ\nϸ\nϹ\nϺ\nϻ\nϼ\nϽ\nϾ\nϿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nЀ\nЁ\nЂ\nЃ\nЄ\nЅ\nІ\nЇ\nЈ\nЉ\nЊ\nЋ\nЌ\nЍ\nЎ\nЏ\nА\nБ\nВ\nГ\nД\nЕ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\nѐ\nё\nђ\nѓ\nє\nѕ\nі\nї\nј\nљ\nњ\nћ\nќ\nѝ\nў\nџ\nѠ\nѡ\nѢ\nѣ\nѤ\nѥ\nѦ\nѧ\nѨ\nѩ\nѪ\nѫ\nѬ\nѭ\nѮ\nѯ\nѰ\nѱ\nѲ\nѳ\nѴ\nѵ\nѶ\nѷ\nѸ\nѹ\nѺ\nѻ\nѼ\nѽ\nѾ\nѿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nҀ\nҁ\n҂\n҃\n҄\n҅\n҆\n҇\n҈\n҉\nҊ\nҋ\nҌ\nҍ\nҎ\nҏ\nҐ\nґ\nҒ\nғ\nҔ\nҕ\nҖ\nҗ\nҘ\nҙ\nҚ\nқ\nҜ\nҝ\nҞ\nҟ\nҠ\nҡ\nҢ\nң\nҤ\nҥ\nҦ\nҧ\nҨ\nҩ\nҪ\nҫ\nҬ\nҭ\nҮ\nү\nҰ\nұ\nҲ\nҳ\nҴ\nҵ\nҶ\nҷ\nҸ\nҹ\nҺ\nһ\nҼ\nҽ\nҾ\nҿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nӀ\nӁ\nӂ\nӃ\nӄ\nӅ\nӆ\nӇ\nӈ\nӉ\nӊ\nӋ\nӌ\nӍ\nӎ\nӏ\nӐ\nӑ\nӒ\nӓ\nӔ\nӕ\nӖ\nӗ\nӘ\nә\nӚ\nӛ\nӜ\nӝ\nӞ\nӟ\nӠ\nӡ\nӢ\nӣ\nӤ\nӥ\nӦ\nӧ\nӨ\nө\nӪ\nӫ\nӬ\nӭ\nӮ\nӯ\nӰ\nӱ\nӲ\nӳ\nӴ\nӵ\nӶ\nӷ\nӸ\nӹ\nӺ\nӻ\nӼ\nӽ\nӾ\nӿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nԀ\nԁ\nԂ\nԃ\nԄ\nԅ\nԆ\nԇ\nԈ\nԉ\nԊ\nԋ\nԌ\nԍ\nԎ\nԏ\nԐ\nԑ\nԒ\nԓ\nԔ\nԕ\nԖ\nԗ\nԘ\nԙ\nԚ\nԛ\nԜ\nԝ\nԞ\nԟ\nԠ\nԡ\nԢ\nԣ\nԤ\nԥ\nԦ\nԧ\nԨ\nԩ\nԪ\nԫ\nԬ\nԭ\nԮ\nԯ\n԰\nԱ\nԲ\nԳ\nԴ\nԵ\nԶ\nԷ\nԸ\nԹ\nԺ\nԻ\nԼ\nԽ\nԾ\nԿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nՀ\nՁ\nՂ\nՃ\nՄ\nՅ\nՆ\nՇ\nՈ\nՉ\nՊ\nՋ\nՌ\nՍ\nՎ\nՏ\nՐ\nՑ\nՒ\nՓ\nՔ\nՕ\nՖ\n՗\n՘\nՙ\n՚\n՛\n՜\n՝\n՞\n՟\nՠ\nա\nբ\nգ\nդ\nե\nզ\nէ\nը\nթ\nժ\nի\nլ\nխ\nծ\nկ\nհ\nձ\nղ\nճ\nմ\nյ\nն\nշ\nո\nչ\nպ\nջ\nռ\nս\nվ\nտ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nր\nց\nւ\nփ\nք\nօ\nֆ\nև\nֈ\n։\n֊\n֋\n֌\n֍\n֎\n֏\n֐\n֑\n֒\n֓\n֔\n֕\n֖\n֗\n֘\n֙\n֚\n֛\n֜\n֝\n֞\n֟\n֠\n֡\n֢\n֣\n֤\n֥\n֦\n֧\n֨\n֩\n֪\n֫\n֬\n֭\n֮\n֯\nְ\nֱ\nֲ\nֳ\nִ\nֵ\nֶ\nַ\nָ\nֹ\nֺ\nֻ\nּ\nֽ\n־\nֿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n׀\nׁ\nׂ\n׃\nׄ\nׅ\n׆\nׇ\n׈\n׉\n׊\n׋\n׌\n׍\n׎\n׏\nא\nב\nג\nד\nה\nו\nז\nח\nט\nי\nך\nכ\nל\nם\nמ\nן\nנ\nס\nע\nף\nפ\nץ\nצ\nק\nר\nש\nת\n׫\n׬\n׭\n׮\nׯ\nװ\nױ\nײ\n׳\n״\n׵\n׶\n׷\n׸\n׹\n׺\n׻\n׼\n׽\n׾\n׿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n؀\n؁\n؂\n؃\n؄\n؅\n؆\n؇\n؈\n؉\n؊\n؋\n،\n؍\n؎\n؏\nؐ\nؑ\nؒ\nؓ\nؔ\nؕ\nؖ\nؗ\nؘ\nؙ\nؚ\n؛\n؜\n؝\n؞\n؟\nؠ\nء\nآ\nأ\nؤ\nإ\nئ\nا\nب\nة\nت\nث\nج\nح\nخ\nد\nذ\nر\nز\nس\nش\nص\nض\nط\nظ\nع\nغ\nػ\nؼ\nؽ\nؾ\nؿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nـ\nف\nق\nك\nل\nم\nن\nه\nو\nى\nي\nً\nٌ\nٍ\nَ\nُ\nِ\nّ\nْ\nٓ\nٔ\nٕ\nٖ\nٗ\n٘\nٙ\nٚ\nٛ\nٜ\nٝ\nٞ\nٟ\n٠\n١\n٢\n٣\n٤\n٥\n٦\n٧\n٨\n٩\n٪\n٫\n٬\n٭\nٮ\nٯ\nٰ\nٱ\nٲ\nٳ\nٴ\nٵ\nٶ\nٷ\nٸ\nٹ\nٺ\nٻ\nټ\nٽ\nپ\nٿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nڀ\nځ\nڂ\nڃ\nڄ\nڅ\nچ\nڇ\nڈ\nډ\nڊ\nڋ\nڌ\nڍ\nڎ\nڏ\nڐ\nڑ\nڒ\nړ\nڔ\nڕ\nږ\nڗ\nژ\nڙ\nښ\nڛ\nڜ\nڝ\nڞ\nڟ\nڠ\nڡ\nڢ\nڣ\nڤ\nڥ\nڦ\nڧ\nڨ\nک\nڪ\nګ\nڬ\nڭ\nڮ\nگ\nڰ\nڱ\nڲ\nڳ\nڴ\nڵ\nڶ\nڷ\nڸ\nڹ\nں\nڻ\nڼ\nڽ\nھ\nڿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nۀ\nہ\nۂ\nۃ\nۄ\nۅ\nۆ\nۇ\nۈ\nۉ\nۊ\nۋ\nی\nۍ\nێ\nۏ\nې\nۑ\nے\nۓ\n۔\nە\nۖ\nۗ\nۘ\nۙ\nۚ\nۛ\nۜ\n۝\n۞\n۟\n۠\nۡ\nۢ\nۣ\nۤ\nۥ\nۦ\nۧ\nۨ\n۩\n۪\n۫\n۬\nۭ\nۮ\nۯ\n۰\n۱\n۲\n۳\n۴\n۵\n۶\n۷\n۸\n۹\nۺ\nۻ\nۼ\n۽\n۾\nۿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n܀\n܁\n܂\n܃\n܄\n܅\n܆\n܇\n܈\n܉\n܊\n܋\n܌\n܍\n܎\n܏\nܐ\nܑ\nܒ\nܓ\nܔ\nܕ\nܖ\nܗ\nܘ\nܙ\nܚ\nܛ\nܜ\nܝ\nܞ\nܟ\nܠ\nܡ\nܢ\nܣ\nܤ\nܥ\nܦ\nܧ\nܨ\nܩ\nܪ\nܫ\nܬ\nܭ\nܮ\nܯ\nܰ\nܱ\nܲ\nܳ\nܴ\nܵ\nܶ\nܷ\nܸ\nܹ\nܺ\nܻ\nܼ\nܽ\nܾ\nܿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n݀\n݁\n݂\n݃\n݄\n݅\n݆\n݇\n݈\n݉\n݊\n݋\n݌\nݍ\nݎ\nݏ\nݐ\nݑ\nݒ\nݓ\nݔ\nݕ\nݖ\nݗ\nݘ\nݙ\nݚ\nݛ\nݜ\nݝ\nݞ\nݟ\nݠ\nݡ\nݢ\nݣ\nݤ\nݥ\nݦ\nݧ\nݨ\nݩ\nݪ\nݫ\nݬ\nݭ\nݮ\nݯ\nݰ\nݱ\nݲ\nݳ\nݴ\nݵ\nݶ\nݷ\nݸ\nݹ\nݺ\nݻ\nݼ\nݽ\nݾ\nݿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\nހ\nށ\nނ\nރ\nބ\nޅ\nކ\nއ\nވ\nމ\nފ\nދ\nތ\nލ\nގ\nޏ\nސ\nޑ\nޒ\nޓ\nޔ\nޕ\nޖ\nޗ\nޘ\nޙ\nޚ\nޛ\nޜ\nޝ\nޞ\nޟ\nޠ\nޡ\nޢ\nޣ\nޤ\nޥ\nަ\nާ\nި\nީ\nު\nޫ\nެ\nޭ\nޮ\nޯ\nް\nޱ\n޲\n޳\n޴\n޵\n޶\n޷\n޸\n޹\n޺\n޻\n޼\n޽\n޾\n޿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n߀\n߁\n߂\n߃\n߄\n߅\n߆\n߇\n߈\n߉\nߊ\nߋ\nߌ\nߍ\nߎ\nߏ\nߐ\nߑ\nߒ\nߓ\nߔ\nߕ\nߖ\nߗ\nߘ\nߙ\nߚ\nߛ\nߜ\nߝ\nߞ\nߟ\nߠ\nߡ\nߢ\nߣ\nߤ\nߥ\nߦ\nߧ\nߨ\nߩ\nߪ\n߫\n߬\n߭\n߮\n߯\n߰\n߱\n߲\n߳\nߴ\nߵ\n߶\n߷\n߸\n߹\nߺ\n߻\n߼\n߽\n߾\n߿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/iso_2022_jp_in.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n\u001b$B!!\u001b(B\n\u001b$B!\"\u001b(B\n\u001b$B!#\u001b(B\n\u001b$B!$\u001b(B\n\u001b$B!%\u001b(B\n\u001b$B!&\u001b(B\n\u001b$B!'\u001b(B\n\u001b$B!(\u001b(B\n\u001b$B!)\u001b(B\n\u001b$B!*\u001b(B\n\u001b$B!+\u001b(B\n\u001b$B!,\u001b(B\n\u001b$B!-\u001b(B\n\u001b$B!.\u001b(B\n\u001b$B!/\u001b(B\n\u001b$B!0\u001b(B\n\u001b$B!1\u001b(B\n\u001b$B!2\u001b(B\n\u001b$B!3\u001b(B\n\u001b$B!4\u001b(B\n\u001b$B!5\u001b(B\n\u001b$B!6\u001b(B\n\u001b$B!7\u001b(B\n\u001b$B!8\u001b(B\n\u001b$B!9\u001b(B\n\u001b$B!:\u001b(B\n\u001b$B!;\u001b(B\n\u001b$B!<\u001b(B\n\u001b$B!=\u001b(B\n\u001b$B!>\u001b(B\n\u001b$B!?\u001b(B\n\u001b$B!@\u001b(B\n\u001b$B!A\u001b(B\n\u001b$B!B\u001b(B\n\u001b$B!C\u001b(B\n\u001b$B!D\u001b(B\n\u001b$B!E\u001b(B\n\u001b$B!F\u001b(B\n\u001b$B!G\u001b(B\n\u001b$B!H\u001b(B\n\u001b$B!I\u001b(B\n\u001b$B!J\u001b(B\n\u001b$B!K\u001b(B\n\u001b$B!L\u001b(B\n\u001b$B!M\u001b(B\n\u001b$B!N\u001b(B\n\u001b$B!O\u001b(B\n\u001b$B!P\u001b(B\n\u001b$B!Q\u001b(B\n\u001b$B!R\u001b(B\n\u001b$B!S\u001b(B\n\u001b$B!T\u001b(B\n\u001b$B!U\u001b(B\n\u001b$B!V\u001b(B\n\u001b$B!W\u001b(B\n\u001b$B!X\u001b(B\n\u001b$B!Y\u001b(B\n\u001b$B!Z\u001b(B\n\u001b$B![\u001b(B\n\u001b$B!\\\u001b(B\n\u001b$B!]\u001b(B\n\u001b$B!^\u001b(B\n\u001b$B!_\u001b(B\n\u001b$B!`\u001b(B\n\u001b$B!a\u001b(B\n\u001b$B!b\u001b(B\n\u001b$B!c\u001b(B\n\u001b$B!d\u001b(B\n\u001b$B!e\u001b(B\n\u001b$B!f\u001b(B\n\u001b$B!g\u001b(B\n\u001b$B!h\u001b(B\n\u001b$B!i\u001b(B\n\u001b$B!j\u001b(B\n\u001b$B!k\u001b(B\n\u001b$B!l\u001b(B\n\u001b$B!m\u001b(B\n\u001b$B!n\u001b(B\n\u001b$B!o\u001b(B\n\u001b$B!p\u001b(B\n\u001b$B!q\u001b(B\n\u001b$B!r\u001b(B\n\u001b$B!s\u001b(B\n\u001b$B!t\u001b(B\n\u001b$B!u\u001b(B\n\u001b$B!v\u001b(B\n\u001b$B!w\u001b(B\n\u001b$B!x\u001b(B\n\u001b$B!y\u001b(B\n\u001b$B!z\u001b(B\n\u001b$B!{\u001b(B\n\u001b$B!|\u001b(B\n\u001b$B!}\u001b(B\n\u001b$B!~\u001b(B\n\u001b$B\"!\u001b(B\n\u001b$B\"\"\u001b(B\n\u001b$B\"#\u001b(B\n\u001b$B\"$\u001b(B\n\u001b$B\"%\u001b(B\n\u001b$B\"&\u001b(B\n\u001b$B\"'\u001b(B\n\u001b$B\"(\u001b(B\n\u001b$B\")\u001b(B\n\u001b$B\"*\u001b(B\n\u001b$B\"+\u001b(B\n\u001b$B\",\u001b(B\n\u001b$B\"-\u001b(B\n\u001b$B\".\u001b(B\n\u001b$B\"/\u001b(B\n\u001b$B\"0\u001b(B\n\u001b$B\"1\u001b(B\n\u001b$B\"2\u001b(B\n\u001b$B\"3\u001b(B\n\u001b$B\"4\u001b(B\n\u001b$B\"5\u001b(B\n\u001b$B\"6\u001b(B\n\u001b$B\"7\u001b(B\n\u001b$B\"8\u001b(B\n\u001b$B\"9\u001b(B\n\u001b$B\":\u001b(B\n\u001b$B\";\u001b(B\n\u001b$B\"<\u001b(B\n\u001b$B\"=\u001b(B\n\u001b$B\">\u001b(B\n\u001b$B\"?\u001b(B\n\u001b$B\"@\u001b(B\n\u001b$B\"A\u001b(B\n\u001b$B\"B\u001b(B\n\u001b$B\"C\u001b(B\n\u001b$B\"D\u001b(B\n\u001b$B\"E\u001b(B\n\u001b$B\"F\u001b(B\n\u001b$B\"G\u001b(B\n\u001b$B\"H\u001b(B\n\u001b$B\"I\u001b(B\n\u001b$B\"J\u001b(B\n\u001b$B\"K\u001b(B\n\u001b$B\"L\u001b(B\n\u001b$B\"M\u001b(B\n\u001b$B\"N\u001b(B\n\u001b$B\"O\u001b(B\n\u001b$B\"P\u001b(B\n\u001b$B\"Q\u001b(B\n\u001b$B\"R\u001b(B\n\u001b$B\"S\u001b(B\n\u001b$B\"T\u001b(B\n\u001b$B\"U\u001b(B\n\u001b$B\"V\u001b(B\n\u001b$B\"W\u001b(B\n\u001b$B\"X\u001b(B\n\u001b$B\"Y\u001b(B\n\u001b$B\"Z\u001b(B\n\u001b$B\"[\u001b(B\n\u001b$B\"\\\u001b(B\n\u001b$B\"]\u001b(B\n\u001b$B\"^\u001b(B\n\u001b$B\"_\u001b(B\n\u001b$B\"`\u001b(B\n\u001b$B\"a\u001b(B\n\u001b$B\"b\u001b(B\n\u001b$B\"c\u001b(B\n\u001b$B\"d\u001b(B\n\u001b$B\"e\u001b(B\n\u001b$B\"f\u001b(B\n\u001b$B\"g\u001b(B\n\u001b$B\"h\u001b(B\n\u001b$B\"i\u001b(B\n\u001b$B\"j\u001b(B\n\u001b$B\"k\u001b(B\n\u001b$B\"l\u001b(B\n\u001b$B\"m\u001b(B\n\u001b$B\"n\u001b(B\n\u001b$B\"o\u001b(B\n\u001b$B\"p\u001b(B\n\u001b$B\"q\u001b(B\n\u001b$B\"r\u001b(B\n\u001b$B\"s\u001b(B\n\u001b$B\"t\u001b(B\n\u001b$B\"u\u001b(B\n\u001b$B\"v\u001b(B\n\u001b$B\"w\u001b(B\n\u001b$B\"x\u001b(B\n\u001b$B\"y\u001b(B\n\u001b$B\"z\u001b(B\n\u001b$B\"{\u001b(B\n\u001b$B\"|\u001b(B\n\u001b$B\"}\u001b(B\n\u001b$B\"~\u001b(B\n\u001b$B#!\u001b(B\n\u001b$B#\"\u001b(B\n\u001b$B##\u001b(B\n\u001b$B#$\u001b(B\n\u001b$B#%\u001b(B\n\u001b$B#&\u001b(B\n\u001b$B#'\u001b(B\n\u001b$B#(\u001b(B\n\u001b$B#)\u001b(B\n\u001b$B#*\u001b(B\n\u001b$B#+\u001b(B\n\u001b$B#,\u001b(B\n\u001b$B#-\u001b(B\n\u001b$B#.\u001b(B\n\u001b$B#/\u001b(B\n\u001b$B#0\u001b(B\n\u001b$B#1\u001b(B\n\u001b$B#2\u001b(B\n\u001b$B#3\u001b(B\n\u001b$B#4\u001b(B\n\u001b$B#5\u001b(B\n\u001b$B#6\u001b(B\n\u001b$B#7\u001b(B\n\u001b$B#8\u001b(B\n\u001b$B#9\u001b(B\n\u001b$B#:\u001b(B\n\u001b$B#;\u001b(B\n\u001b$B#<\u001b(B\n\u001b$B#=\u001b(B\n\u001b$B#>\u001b(B\n\u001b$B#?\u001b(B\n\u001b$B#@\u001b(B\n\u001b$B#A\u001b(B\n\u001b$B#B\u001b(B\n\u001b$B#C\u001b(B\n\u001b$B#D\u001b(B\n\u001b$B#E\u001b(B\n\u001b$B#F\u001b(B\n\u001b$B#G\u001b(B\n\u001b$B#H\u001b(B\n\u001b$B#I\u001b(B\n\u001b$B#J\u001b(B\n\u001b$B#K\u001b(B\n\u001b$B#L\u001b(B\n\u001b$B#M\u001b(B\n\u001b$B#N\u001b(B\n\u001b$B#O\u001b(B\n\u001b$B#P\u001b(B\n\u001b$B#Q\u001b(B\n\u001b$B#R\u001b(B\n\u001b$B#S\u001b(B\n\u001b$B#T\u001b(B\n\u001b$B#U\u001b(B\n\u001b$B#V\u001b(B\n\u001b$B#W\u001b(B\n\u001b$B#X\u001b(B\n\u001b$B#Y\u001b(B\n\u001b$B#Z\u001b(B\n\u001b$B#[\u001b(B\n\u001b$B#\\\u001b(B\n\u001b$B#]\u001b(B\n\u001b$B#^\u001b(B\n\u001b$B#_\u001b(B\n\u001b$B#`\u001b(B\n\u001b$B#a\u001b(B\n\u001b$B#b\u001b(B\n\u001b$B#c\u001b(B\n\u001b$B#d\u001b(B\n\u001b$B#e\u001b(B\n\u001b$B#f\u001b(B\n\u001b$B#g\u001b(B\n\u001b$B#h\u001b(B\n\u001b$B#i\u001b(B\n\u001b$B#j\u001b(B\n\u001b$B#k\u001b(B\n\u001b$B#l\u001b(B\n\u001b$B#m\u001b(B\n\u001b$B#n\u001b(B\n\u001b$B#o\u001b(B\n\u001b$B#p\u001b(B\n\u001b$B#q\u001b(B\n\u001b$B#r\u001b(B\n\u001b$B#s\u001b(B\n\u001b$B#t\u001b(B\n\u001b$B#u\u001b(B\n\u001b$B#v\u001b(B\n\u001b$B#w\u001b(B\n\u001b$B#x\u001b(B\n\u001b$B#y\u001b(B\n\u001b$B#z\u001b(B\n\u001b$B#{\u001b(B\n\u001b$B#|\u001b(B\n\u001b$B#}\u001b(B\n\u001b$B#~\u001b(B\n\u001b$B$!\u001b(B\n\u001b$B$\"\u001b(B\n\u001b$B$#\u001b(B\n\u001b$B$$\u001b(B\n\u001b$B$%\u001b(B\n\u001b$B$&\u001b(B\n\u001b$B$'\u001b(B\n\u001b$B$(\u001b(B\n\u001b$B$)\u001b(B\n\u001b$B$*\u001b(B\n\u001b$B$+\u001b(B\n\u001b$B$,\u001b(B\n\u001b$B$-\u001b(B\n\u001b$B$.\u001b(B\n\u001b$B$/\u001b(B\n\u001b$B$0\u001b(B\n\u001b$B$1\u001b(B\n\u001b$B$2\u001b(B\n\u001b$B$3\u001b(B\n\u001b$B$4\u001b(B\n\u001b$B$5\u001b(B\n\u001b$B$6\u001b(B\n\u001b$B$7\u001b(B\n\u001b$B$8\u001b(B\n\u001b$B$9\u001b(B\n\u001b$B$:\u001b(B\n\u001b$B$;\u001b(B\n\u001b$B$<\u001b(B\n\u001b$B$=\u001b(B\n\u001b$B$>\u001b(B\n\u001b$B$?\u001b(B\n\u001b$B$@\u001b(B\n\u001b$B$A\u001b(B\n\u001b$B$B\u001b(B\n\u001b$B$C\u001b(B\n\u001b$B$D\u001b(B\n\u001b$B$E\u001b(B\n\u001b$B$F\u001b(B\n\u001b$B$G\u001b(B\n\u001b$B$H\u001b(B\n\u001b$B$I\u001b(B\n\u001b$B$J\u001b(B\n\u001b$B$K\u001b(B\n\u001b$B$L\u001b(B\n\u001b$B$M\u001b(B\n\u001b$B$N\u001b(B\n\u001b$B$O\u001b(B\n\u001b$B$P\u001b(B\n\u001b$B$Q\u001b(B\n\u001b$B$R\u001b(B\n\u001b$B$S\u001b(B\n\u001b$B$T\u001b(B\n\u001b$B$U\u001b(B\n\u001b$B$V\u001b(B\n\u001b$B$W\u001b(B\n\u001b$B$X\u001b(B\n\u001b$B$Y\u001b(B\n\u001b$B$Z\u001b(B\n\u001b$B$[\u001b(B\n\u001b$B$\\\u001b(B\n\u001b$B$]\u001b(B\n\u001b$B$^\u001b(B\n\u001b$B$_\u001b(B\n\u001b$B$`\u001b(B\n\u001b$B$a\u001b(B\n\u001b$B$b\u001b(B\n\u001b$B$c\u001b(B\n\u001b$B$d\u001b(B\n\u001b$B$e\u001b(B\n\u001b$B$f\u001b(B\n\u001b$B$g\u001b(B\n\u001b$B$h\u001b(B\n\u001b$B$i\u001b(B\n\u001b$B$j\u001b(B\n\u001b$B$k\u001b(B\n\u001b$B$l\u001b(B\n\u001b$B$m\u001b(B\n\u001b$B$n\u001b(B\n\u001b$B$o\u001b(B\n\u001b$B$p\u001b(B\n\u001b$B$q\u001b(B\n\u001b$B$r\u001b(B\n\u001b$B$s\u001b(B\n\u001b$B$t\u001b(B\n\u001b$B$u\u001b(B\n\u001b$B$v\u001b(B\n\u001b$B$w\u001b(B\n\u001b$B$x\u001b(B\n\u001b$B$y\u001b(B\n\u001b$B$z\u001b(B\n\u001b$B${\u001b(B\n\u001b$B$|\u001b(B\n\u001b$B$}\u001b(B\n\u001b$B$~\u001b(B\n\u001b$B%!\u001b(B\n\u001b$B%\"\u001b(B\n\u001b$B%#\u001b(B\n\u001b$B%$\u001b(B\n\u001b$B%%\u001b(B\n\u001b$B%&\u001b(B\n\u001b$B%'\u001b(B\n\u001b$B%(\u001b(B\n\u001b$B%)\u001b(B\n\u001b$B%*\u001b(B\n\u001b$B%+\u001b(B\n\u001b$B%,\u001b(B\n\u001b$B%-\u001b(B\n\u001b$B%.\u001b(B\n\u001b$B%/\u001b(B\n\u001b$B%0\u001b(B\n\u001b$B%1\u001b(B\n\u001b$B%2\u001b(B\n\u001b$B%3\u001b(B\n\u001b$B%4\u001b(B\n\u001b$B%5\u001b(B\n\u001b$B%6\u001b(B\n\u001b$B%7\u001b(B\n\u001b$B%8\u001b(B\n\u001b$B%9\u001b(B\n\u001b$B%:\u001b(B\n\u001b$B%;\u001b(B\n\u001b$B%<\u001b(B\n\u001b$B%=\u001b(B\n\u001b$B%>\u001b(B\n\u001b$B%?\u001b(B\n\u001b$B%@\u001b(B\n\u001b$B%A\u001b(B\n\u001b$B%B\u001b(B\n\u001b$B%C\u001b(B\n\u001b$B%D\u001b(B\n\u001b$B%E\u001b(B\n\u001b$B%F\u001b(B\n\u001b$B%G\u001b(B\n\u001b$B%H\u001b(B\n\u001b$B%I\u001b(B\n\u001b$B%J\u001b(B\n\u001b$B%K\u001b(B\n\u001b$B%L\u001b(B\n\u001b$B%M\u001b(B\n\u001b$B%N\u001b(B\n\u001b$B%O\u001b(B\n\u001b$B%P\u001b(B\n\u001b$B%Q\u001b(B\n\u001b$B%R\u001b(B\n\u001b$B%S\u001b(B\n\u001b$B%T\u001b(B\n\u001b$B%U\u001b(B\n\u001b$B%V\u001b(B\n\u001b$B%W\u001b(B\n\u001b$B%X\u001b(B\n\u001b$B%Y\u001b(B\n\u001b$B%Z\u001b(B\n\u001b$B%[\u001b(B\n\u001b$B%\\\u001b(B\n\u001b$B%]\u001b(B\n\u001b$B%^\u001b(B\n\u001b$B%_\u001b(B\n\u001b$B%`\u001b(B\n\u001b$B%a\u001b(B\n\u001b$B%b\u001b(B\n\u001b$B%c\u001b(B\n\u001b$B%d\u001b(B\n\u001b$B%e\u001b(B\n\u001b$B%f\u001b(B\n\u001b$B%g\u001b(B\n\u001b$B%h\u001b(B\n\u001b$B%i\u001b(B\n\u001b$B%j\u001b(B\n\u001b$B%k\u001b(B\n\u001b$B%l\u001b(B\n\u001b$B%m\u001b(B\n\u001b$B%n\u001b(B\n\u001b$B%o\u001b(B\n\u001b$B%p\u001b(B\n\u001b$B%q\u001b(B\n\u001b$B%r\u001b(B\n\u001b$B%s\u001b(B\n\u001b$B%t\u001b(B\n\u001b$B%u\u001b(B\n\u001b$B%v\u001b(B\n\u001b$B%w\u001b(B\n\u001b$B%x\u001b(B\n\u001b$B%y\u001b(B\n\u001b$B%z\u001b(B\n\u001b$B%{\u001b(B\n\u001b$B%|\u001b(B\n\u001b$B%}\u001b(B\n\u001b$B%~\u001b(B\n\u001b$B&!\u001b(B\n\u001b$B&\"\u001b(B\n\u001b$B&#\u001b(B\n\u001b$B&$\u001b(B\n\u001b$B&%\u001b(B\n\u001b$B&&\u001b(B\n\u001b$B&'\u001b(B\n\u001b$B&(\u001b(B\n\u001b$B&)\u001b(B\n\u001b$B&*\u001b(B\n\u001b$B&+\u001b(B\n\u001b$B&,\u001b(B\n\u001b$B&-\u001b(B\n\u001b$B&.\u001b(B\n\u001b$B&/\u001b(B\n\u001b$B&0\u001b(B\n\u001b$B&1\u001b(B\n\u001b$B&2\u001b(B\n\u001b$B&3\u001b(B\n\u001b$B&4\u001b(B\n\u001b$B&5\u001b(B\n\u001b$B&6\u001b(B\n\u001b$B&7\u001b(B\n\u001b$B&8\u001b(B\n\u001b$B&9\u001b(B\n\u001b$B&:\u001b(B\n\u001b$B&;\u001b(B\n\u001b$B&<\u001b(B\n\u001b$B&=\u001b(B\n\u001b$B&>\u001b(B\n\u001b$B&?\u001b(B\n\u001b$B&@\u001b(B\n\u001b$B&A\u001b(B\n\u001b$B&B\u001b(B\n\u001b$B&C\u001b(B\n\u001b$B&D\u001b(B\n\u001b$B&E\u001b(B\n\u001b$B&F\u001b(B\n\u001b$B&G\u001b(B\n\u001b$B&H\u001b(B\n\u001b$B&I\u001b(B\n\u001b$B&J\u001b(B\n\u001b$B&K\u001b(B\n\u001b$B&L\u001b(B\n\u001b$B&M\u001b(B\n\u001b$B&N\u001b(B\n\u001b$B&O\u001b(B\n\u001b$B&P\u001b(B\n\u001b$B&Q\u001b(B\n\u001b$B&R\u001b(B\n\u001b$B&S\u001b(B\n\u001b$B&T\u001b(B\n\u001b$B&U\u001b(B\n\u001b$B&V\u001b(B\n\u001b$B&W\u001b(B\n\u001b$B&X\u001b(B\n\u001b$B&Y\u001b(B\n\u001b$B&Z\u001b(B\n\u001b$B&[\u001b(B\n\u001b$B&\\\u001b(B\n\u001b$B&]\u001b(B\n\u001b$B&^\u001b(B\n\u001b$B&_\u001b(B\n\u001b$B&`\u001b(B\n\u001b$B&a\u001b(B\n\u001b$B&b\u001b(B\n\u001b$B&c\u001b(B\n\u001b$B&d\u001b(B\n\u001b$B&e\u001b(B\n\u001b$B&f\u001b(B\n\u001b$B&g\u001b(B\n\u001b$B&h\u001b(B\n\u001b$B&i\u001b(B\n\u001b$B&j\u001b(B\n\u001b$B&k\u001b(B\n\u001b$B&l\u001b(B\n\u001b$B&m\u001b(B\n\u001b$B&n\u001b(B\n\u001b$B&o\u001b(B\n\u001b$B&p\u001b(B\n\u001b$B&q\u001b(B\n\u001b$B&r\u001b(B\n\u001b$B&s\u001b(B\n\u001b$B&t\u001b(B\n\u001b$B&u\u001b(B\n\u001b$B&v\u001b(B\n\u001b$B&w\u001b(B\n\u001b$B&x\u001b(B\n\u001b$B&y\u001b(B\n\u001b$B&z\u001b(B\n\u001b$B&{\u001b(B\n\u001b$B&|\u001b(B\n\u001b$B&}\u001b(B\n\u001b$B&~\u001b(B\n\u001b$B'!\u001b(B\n\u001b$B'\"\u001b(B\n\u001b$B'#\u001b(B\n\u001b$B'$\u001b(B\n\u001b$B'%\u001b(B\n\u001b$B'&\u001b(B\n\u001b$B''\u001b(B\n\u001b$B'(\u001b(B\n\u001b$B')\u001b(B\n\u001b$B'*\u001b(B\n\u001b$B'+\u001b(B\n\u001b$B',\u001b(B\n\u001b$B'-\u001b(B\n\u001b$B'.\u001b(B\n\u001b$B'/\u001b(B\n\u001b$B'0\u001b(B\n\u001b$B'1\u001b(B\n\u001b$B'2\u001b(B\n\u001b$B'3\u001b(B\n\u001b$B'4\u001b(B\n\u001b$B'5\u001b(B\n\u001b$B'6\u001b(B\n\u001b$B'7\u001b(B\n\u001b$B'8\u001b(B\n\u001b$B'9\u001b(B\n\u001b$B':\u001b(B\n\u001b$B';\u001b(B\n\u001b$B'<\u001b(B\n\u001b$B'=\u001b(B\n\u001b$B'>\u001b(B\n\u001b$B'?\u001b(B\n\u001b$B'@\u001b(B\n\u001b$B'A\u001b(B\n\u001b$B'B\u001b(B\n\u001b$B'C\u001b(B\n\u001b$B'D\u001b(B\n\u001b$B'E\u001b(B\n\u001b$B'F\u001b(B\n\u001b$B'G\u001b(B\n\u001b$B'H\u001b(B\n\u001b$B'I\u001b(B\n\u001b$B'J\u001b(B\n\u001b$B'K\u001b(B\n\u001b$B'L\u001b(B\n\u001b$B'M\u001b(B\n\u001b$B'N\u001b(B\n\u001b$B'O\u001b(B\n\u001b$B'P\u001b(B\n\u001b$B'Q\u001b(B\n\u001b$B'R\u001b(B\n\u001b$B'S\u001b(B\n\u001b$B'T\u001b(B\n\u001b$B'U\u001b(B\n\u001b$B'V\u001b(B\n\u001b$B'W\u001b(B\n\u001b$B'X\u001b(B\n\u001b$B'Y\u001b(B\n\u001b$B'Z\u001b(B\n\u001b$B'[\u001b(B\n\u001b$B'\\\u001b(B\n\u001b$B']\u001b(B\n\u001b$B'^\u001b(B\n\u001b$B'_\u001b(B\n\u001b$B'`\u001b(B\n\u001b$B'a\u001b(B\n\u001b$B'b\u001b(B\n\u001b$B'c\u001b(B\n\u001b$B'd\u001b(B\n\u001b$B'e\u001b(B\n\u001b$B'f\u001b(B\n\u001b$B'g\u001b(B\n\u001b$B'h\u001b(B\n\u001b$B'i\u001b(B\n\u001b$B'j\u001b(B\n\u001b$B'k\u001b(B\n\u001b$B'l\u001b(B\n\u001b$B'm\u001b(B\n\u001b$B'n\u001b(B\n\u001b$B'o\u001b(B\n\u001b$B'p\u001b(B\n\u001b$B'q\u001b(B\n\u001b$B'r\u001b(B\n\u001b$B's\u001b(B\n\u001b$B't\u001b(B\n\u001b$B'u\u001b(B\n\u001b$B'v\u001b(B\n\u001b$B'w\u001b(B\n\u001b$B'x\u001b(B\n\u001b$B'y\u001b(B\n\u001b$B'z\u001b(B\n\u001b$B'{\u001b(B\n\u001b$B'|\u001b(B\n\u001b$B'}\u001b(B\n\u001b$B'~\u001b(B\n\u001b$B(!\u001b(B\n\u001b$B(\"\u001b(B\n\u001b$B(#\u001b(B\n\u001b$B($\u001b(B\n\u001b$B(%\u001b(B\n\u001b$B(&\u001b(B\n\u001b$B('\u001b(B\n\u001b$B((\u001b(B\n\u001b$B()\u001b(B\n\u001b$B(*\u001b(B\n\u001b$B(+\u001b(B\n\u001b$B(,\u001b(B\n\u001b$B(-\u001b(B\n\u001b$B(.\u001b(B\n\u001b$B(/\u001b(B\n\u001b$B(0\u001b(B\n\u001b$B(1\u001b(B\n\u001b$B(2\u001b(B\n\u001b$B(3\u001b(B\n\u001b$B(4\u001b(B\n\u001b$B(5\u001b(B\n\u001b$B(6\u001b(B\n\u001b$B(7\u001b(B\n\u001b$B(8\u001b(B\n\u001b$B(9\u001b(B\n\u001b$B(:\u001b(B\n\u001b$B(;\u001b(B\n\u001b$B(<\u001b(B\n\u001b$B(=\u001b(B\n\u001b$B(>\u001b(B\n\u001b$B(?\u001b(B\n\u001b$B(@\u001b(B\n\u001b$B(A\u001b(B\n\u001b$B(B\u001b(B\n\u001b$B(C\u001b(B\n\u001b$B(D\u001b(B\n\u001b$B(E\u001b(B\n\u001b$B(F\u001b(B\n\u001b$B(G\u001b(B\n\u001b$B(H\u001b(B\n\u001b$B(I\u001b(B\n\u001b$B(J\u001b(B\n\u001b$B(K\u001b(B\n\u001b$B(L\u001b(B\n\u001b$B(M\u001b(B\n\u001b$B(N\u001b(B\n\u001b$B(O\u001b(B\n\u001b$B(P\u001b(B\n\u001b$B(Q\u001b(B\n\u001b$B(R\u001b(B\n\u001b$B(S\u001b(B\n\u001b$B(T\u001b(B\n\u001b$B(U\u001b(B\n\u001b$B(V\u001b(B\n\u001b$B(W\u001b(B\n\u001b$B(X\u001b(B\n\u001b$B(Y\u001b(B\n\u001b$B(Z\u001b(B\n\u001b$B([\u001b(B\n\u001b$B(\\\u001b(B\n\u001b$B(]\u001b(B\n\u001b$B(^\u001b(B\n\u001b$B(_\u001b(B\n\u001b$B(`\u001b(B\n\u001b$B(a\u001b(B\n\u001b$B(b\u001b(B\n\u001b$B(c\u001b(B\n\u001b$B(d\u001b(B\n\u001b$B(e\u001b(B\n\u001b$B(f\u001b(B\n\u001b$B(g\u001b(B\n\u001b$B(h\u001b(B\n\u001b$B(i\u001b(B\n\u001b$B(j\u001b(B\n\u001b$B(k\u001b(B\n\u001b$B(l\u001b(B\n\u001b$B(m\u001b(B\n\u001b$B(n\u001b(B\n\u001b$B(o\u001b(B\n\u001b$B(p\u001b(B\n\u001b$B(q\u001b(B\n\u001b$B(r\u001b(B\n\u001b$B(s\u001b(B\n\u001b$B(t\u001b(B\n\u001b$B(u\u001b(B\n\u001b$B(v\u001b(B\n\u001b$B(w\u001b(B\n\u001b$B(x\u001b(B\n\u001b$B(y\u001b(B\n\u001b$B(z\u001b(B\n\u001b$B({\u001b(B\n\u001b$B(|\u001b(B\n\u001b$B(}\u001b(B\n\u001b$B(~\u001b(B\n\u001b$B)!\u001b(B\n\u001b$B)\"\u001b(B\n\u001b$B)#\u001b(B\n\u001b$B)$\u001b(B\n\u001b$B)%\u001b(B\n\u001b$B)&\u001b(B\n\u001b$B)'\u001b(B\n\u001b$B)(\u001b(B\n\u001b$B))\u001b(B\n\u001b$B)*\u001b(B\n\u001b$B)+\u001b(B\n\u001b$B),\u001b(B\n\u001b$B)-\u001b(B\n\u001b$B).\u001b(B\n\u001b$B)/\u001b(B\n\u001b$B)0\u001b(B\n\u001b$B)1\u001b(B\n\u001b$B)2\u001b(B\n\u001b$B)3\u001b(B\n\u001b$B)4\u001b(B\n\u001b$B)5\u001b(B\n\u001b$B)6\u001b(B\n\u001b$B)7\u001b(B\n\u001b$B)8\u001b(B\n\u001b$B)9\u001b(B\n\u001b$B):\u001b(B\n\u001b$B);\u001b(B\n\u001b$B)<\u001b(B\n\u001b$B)=\u001b(B\n\u001b$B)>\u001b(B\n\u001b$B)?\u001b(B\n\u001b$B)@\u001b(B\n\u001b$B)A\u001b(B\n\u001b$B)B\u001b(B\n\u001b$B)C\u001b(B\n\u001b$B)D\u001b(B\n\u001b$B)E\u001b(B\n\u001b$B)F\u001b(B\n\u001b$B)G\u001b(B\n\u001b$B)H\u001b(B\n\u001b$B)I\u001b(B\n\u001b$B)J\u001b(B\n\u001b$B)K\u001b(B\n\u001b$B)L\u001b(B\n\u001b$B)M\u001b(B\n\u001b$B)N\u001b(B\n\u001b$B)O\u001b(B\n\u001b$B)P\u001b(B\n\u001b$B)Q\u001b(B\n\u001b$B)R\u001b(B\n\u001b$B)S\u001b(B\n\u001b$B)T\u001b(B\n\u001b$B)U\u001b(B\n\u001b$B)V\u001b(B\n\u001b$B)W\u001b(B\n\u001b$B)X\u001b(B\n\u001b$B)Y\u001b(B\n\u001b$B)Z\u001b(B\n\u001b$B)[\u001b(B\n\u001b$B)\\\u001b(B\n\u001b$B)]\u001b(B\n\u001b$B)^\u001b(B\n\u001b$B)_\u001b(B\n\u001b$B)`\u001b(B\n\u001b$B)a\u001b(B\n\u001b$B)b\u001b(B\n\u001b$B)c\u001b(B\n\u001b$B)d\u001b(B\n\u001b$B)e\u001b(B\n\u001b$B)f\u001b(B\n\u001b$B)g\u001b(B\n\u001b$B)h\u001b(B\n\u001b$B)i\u001b(B\n\u001b$B)j\u001b(B\n\u001b$B)k\u001b(B\n\u001b$B)l\u001b(B\n\u001b$B)m\u001b(B\n\u001b$B)n\u001b(B\n\u001b$B)o\u001b(B\n\u001b$B)p\u001b(B\n\u001b$B)q\u001b(B\n\u001b$B)r\u001b(B\n\u001b$B)s\u001b(B\n\u001b$B)t\u001b(B\n\u001b$B)u\u001b(B\n\u001b$B)v\u001b(B\n\u001b$B)w\u001b(B\n\u001b$B)x\u001b(B\n\u001b$B)y\u001b(B\n\u001b$B)z\u001b(B\n\u001b$B){\u001b(B\n\u001b$B)|\u001b(B\n\u001b$B)}\u001b(B\n\u001b$B)~\u001b(B\n\u001b$B*!\u001b(B\n\u001b$B*\"\u001b(B\n\u001b$B*#\u001b(B\n\u001b$B*$\u001b(B\n\u001b$B*%\u001b(B\n\u001b$B*&\u001b(B\n\u001b$B*'\u001b(B\n\u001b$B*(\u001b(B\n\u001b$B*)\u001b(B\n\u001b$B**\u001b(B\n\u001b$B*+\u001b(B\n\u001b$B*,\u001b(B\n\u001b$B*-\u001b(B\n\u001b$B*.\u001b(B\n\u001b$B*/\u001b(B\n\u001b$B*0\u001b(B\n\u001b$B*1\u001b(B\n\u001b$B*2\u001b(B\n\u001b$B*3\u001b(B\n\u001b$B*4\u001b(B\n\u001b$B*5\u001b(B\n\u001b$B*6\u001b(B\n\u001b$B*7\u001b(B\n\u001b$B*8\u001b(B\n\u001b$B*9\u001b(B\n\u001b$B*:\u001b(B\n\u001b$B*;\u001b(B\n\u001b$B*<\u001b(B\n\u001b$B*=\u001b(B\n\u001b$B*>\u001b(B\n\u001b$B*?\u001b(B\n\u001b$B*@\u001b(B\n\u001b$B*A\u001b(B\n\u001b$B*B\u001b(B\n\u001b$B*C\u001b(B\n\u001b$B*D\u001b(B\n\u001b$B*E\u001b(B\n\u001b$B*F\u001b(B\n\u001b$B*G\u001b(B\n\u001b$B*H\u001b(B\n\u001b$B*I\u001b(B\n\u001b$B*J\u001b(B\n\u001b$B*K\u001b(B\n\u001b$B*L\u001b(B\n\u001b$B*M\u001b(B\n\u001b$B*N\u001b(B\n\u001b$B*O\u001b(B\n\u001b$B*P\u001b(B\n\u001b$B*Q\u001b(B\n\u001b$B*R\u001b(B\n\u001b$B*S\u001b(B\n\u001b$B*T\u001b(B\n\u001b$B*U\u001b(B\n\u001b$B*V\u001b(B\n\u001b$B*W\u001b(B\n\u001b$B*X\u001b(B\n\u001b$B*Y\u001b(B\n\u001b$B*Z\u001b(B\n\u001b$B*[\u001b(B\n\u001b$B*\\\u001b(B\n\u001b$B*]\u001b(B\n\u001b$B*^\u001b(B\n\u001b$B*_\u001b(B\n\u001b$B*`\u001b(B\n\u001b$B*a\u001b(B\n\u001b$B*b\u001b(B\n\u001b$B*c\u001b(B\n\u001b$B*d\u001b(B\n\u001b$B*e\u001b(B\n\u001b$B*f\u001b(B\n\u001b$B*g\u001b(B\n\u001b$B*h\u001b(B\n\u001b$B*i\u001b(B\n\u001b$B*j\u001b(B\n\u001b$B*k\u001b(B\n\u001b$B*l\u001b(B\n\u001b$B*m\u001b(B\n\u001b$B*n\u001b(B\n\u001b$B*o\u001b(B\n\u001b$B*p\u001b(B\n\u001b$B*q\u001b(B\n\u001b$B*r\u001b(B\n\u001b$B*s\u001b(B\n\u001b$B*t\u001b(B\n\u001b$B*u\u001b(B\n\u001b$B*v\u001b(B\n\u001b$B*w\u001b(B\n\u001b$B*x\u001b(B\n\u001b$B*y\u001b(B\n\u001b$B*z\u001b(B\n\u001b$B*{\u001b(B\n\u001b$B*|\u001b(B\n\u001b$B*}\u001b(B\n\u001b$B*~\u001b(B\n\u001b$B+!\u001b(B\n\u001b$B+\"\u001b(B\n\u001b$B+#\u001b(B\n\u001b$B+$\u001b(B\n\u001b$B+%\u001b(B\n\u001b$B+&\u001b(B\n\u001b$B+'\u001b(B\n\u001b$B+(\u001b(B\n\u001b$B+)\u001b(B\n\u001b$B+*\u001b(B\n\u001b$B++\u001b(B\n\u001b$B+,\u001b(B\n\u001b$B+-\u001b(B\n\u001b$B+.\u001b(B\n\u001b$B+/\u001b(B\n\u001b$B+0\u001b(B\n\u001b$B+1\u001b(B\n\u001b$B+2\u001b(B\n\u001b$B+3\u001b(B\n\u001b$B+4\u001b(B\n\u001b$B+5\u001b(B\n\u001b$B+6\u001b(B\n\u001b$B+7\u001b(B\n\u001b$B+8\u001b(B\n\u001b$B+9\u001b(B\n\u001b$B+:\u001b(B\n\u001b$B+;\u001b(B\n\u001b$B+<\u001b(B\n\u001b$B+=\u001b(B\n\u001b$B+>\u001b(B\n\u001b$B+?\u001b(B\n\u001b$B+@\u001b(B\n\u001b$B+A\u001b(B\n\u001b$B+B\u001b(B\n\u001b$B+C\u001b(B\n\u001b$B+D\u001b(B\n\u001b$B+E\u001b(B\n\u001b$B+F\u001b(B\n\u001b$B+G\u001b(B\n\u001b$B+H\u001b(B\n\u001b$B+I\u001b(B\n\u001b$B+J\u001b(B\n\u001b$B+K\u001b(B\n\u001b$B+L\u001b(B\n\u001b$B+M\u001b(B\n\u001b$B+N\u001b(B\n\u001b$B+O\u001b(B\n\u001b$B+P\u001b(B\n\u001b$B+Q\u001b(B\n\u001b$B+R\u001b(B\n\u001b$B+S\u001b(B\n\u001b$B+T\u001b(B\n\u001b$B+U\u001b(B\n\u001b$B+V\u001b(B\n\u001b$B+W\u001b(B\n\u001b$B+X\u001b(B\n\u001b$B+Y\u001b(B\n\u001b$B+Z\u001b(B\n\u001b$B+[\u001b(B\n\u001b$B+\\\u001b(B\n\u001b$B+]\u001b(B\n\u001b$B+^\u001b(B\n\u001b$B+_\u001b(B\n\u001b$B+`\u001b(B\n\u001b$B+a\u001b(B\n\u001b$B+b\u001b(B\n\u001b$B+c\u001b(B\n\u001b$B+d\u001b(B\n\u001b$B+e\u001b(B\n\u001b$B+f\u001b(B\n\u001b$B+g\u001b(B\n\u001b$B+h\u001b(B\n\u001b$B+i\u001b(B\n\u001b$B+j\u001b(B\n\u001b$B+k\u001b(B\n\u001b$B+l\u001b(B\n\u001b$B+m\u001b(B\n\u001b$B+n\u001b(B\n\u001b$B+o\u001b(B\n\u001b$B+p\u001b(B\n\u001b$B+q\u001b(B\n\u001b$B+r\u001b(B\n\u001b$B+s\u001b(B\n\u001b$B+t\u001b(B\n\u001b$B+u\u001b(B\n\u001b$B+v\u001b(B\n\u001b$B+w\u001b(B\n\u001b$B+x\u001b(B\n\u001b$B+y\u001b(B\n\u001b$B+z\u001b(B\n\u001b$B+{\u001b(B\n\u001b$B+|\u001b(B\n\u001b$B+}\u001b(B\n\u001b$B+~\u001b(B\n\u001b$B,!\u001b(B\n\u001b$B,\"\u001b(B\n\u001b$B,#\u001b(B\n\u001b$B,$\u001b(B\n\u001b$B,%\u001b(B\n\u001b$B,&\u001b(B\n\u001b$B,'\u001b(B\n\u001b$B,(\u001b(B\n\u001b$B,)\u001b(B\n\u001b$B,*\u001b(B\n\u001b$B,+\u001b(B\n\u001b$B,,\u001b(B\n\u001b$B,-\u001b(B\n\u001b$B,.\u001b(B\n\u001b$B,/\u001b(B\n\u001b$B,0\u001b(B\n\u001b$B,1\u001b(B\n\u001b$B,2\u001b(B\n\u001b$B,3\u001b(B\n\u001b$B,4\u001b(B\n\u001b$B,5\u001b(B\n\u001b$B,6\u001b(B\n\u001b$B,7\u001b(B\n\u001b$B,8\u001b(B\n\u001b$B,9\u001b(B\n\u001b$B,:\u001b(B\n\u001b$B,;\u001b(B\n\u001b$B,<\u001b(B\n\u001b$B,=\u001b(B\n\u001b$B,>\u001b(B\n\u001b$B,?\u001b(B\n\u001b$B,@\u001b(B\n\u001b$B,A\u001b(B\n\u001b$B,B\u001b(B\n\u001b$B,C\u001b(B\n\u001b$B,D\u001b(B\n\u001b$B,E\u001b(B\n\u001b$B,F\u001b(B\n\u001b$B,G\u001b(B\n\u001b$B,H\u001b(B\n\u001b$B,I\u001b(B\n\u001b$B,J\u001b(B\n\u001b$B,K\u001b(B\n\u001b$B,L\u001b(B\n\u001b$B,M\u001b(B\n\u001b$B,N\u001b(B\n\u001b$B,O\u001b(B\n\u001b$B,P\u001b(B\n\u001b$B,Q\u001b(B\n\u001b$B,R\u001b(B\n\u001b$B,S\u001b(B\n\u001b$B,T\u001b(B\n\u001b$B,U\u001b(B\n\u001b$B,V\u001b(B\n\u001b$B,W\u001b(B\n\u001b$B,X\u001b(B\n\u001b$B,Y\u001b(B\n\u001b$B,Z\u001b(B\n\u001b$B,[\u001b(B\n\u001b$B,\\\u001b(B\n\u001b$B,]\u001b(B\n\u001b$B,^\u001b(B\n\u001b$B,_\u001b(B\n\u001b$B,`\u001b(B\n\u001b$B,a\u001b(B\n\u001b$B,b\u001b(B\n\u001b$B,c\u001b(B\n\u001b$B,d\u001b(B\n\u001b$B,e\u001b(B\n\u001b$B,f\u001b(B\n\u001b$B,g\u001b(B\n\u001b$B,h\u001b(B\n\u001b$B,i\u001b(B\n\u001b$B,j\u001b(B\n\u001b$B,k\u001b(B\n\u001b$B,l\u001b(B\n\u001b$B,m\u001b(B\n\u001b$B,n\u001b(B\n\u001b$B,o\u001b(B\n\u001b$B,p\u001b(B\n\u001b$B,q\u001b(B\n\u001b$B,r\u001b(B\n\u001b$B,s\u001b(B\n\u001b$B,t\u001b(B\n\u001b$B,u\u001b(B\n\u001b$B,v\u001b(B\n\u001b$B,w\u001b(B\n\u001b$B,x\u001b(B\n\u001b$B,y\u001b(B\n\u001b$B,z\u001b(B\n\u001b$B,{\u001b(B\n\u001b$B,|\u001b(B\n\u001b$B,}\u001b(B\n\u001b$B,~\u001b(B\n\u001b$B-!\u001b(B\n\u001b$B-\"\u001b(B\n\u001b$B-#\u001b(B\n\u001b$B-$\u001b(B\n\u001b$B-%\u001b(B\n\u001b$B-&\u001b(B\n\u001b$B-'\u001b(B\n\u001b$B-(\u001b(B\n\u001b$B-)\u001b(B\n\u001b$B-*\u001b(B\n\u001b$B-+\u001b(B\n\u001b$B-,\u001b(B\n\u001b$B--\u001b(B\n\u001b$B-.\u001b(B\n\u001b$B-/\u001b(B\n\u001b$B-0\u001b(B\n\u001b$B-1\u001b(B\n\u001b$B-2\u001b(B\n\u001b$B-3\u001b(B\n\u001b$B-4\u001b(B\n\u001b$B-5\u001b(B\n\u001b$B-6\u001b(B\n\u001b$B-7\u001b(B\n\u001b$B-8\u001b(B\n\u001b$B-9\u001b(B\n\u001b$B-:\u001b(B\n\u001b$B-;\u001b(B\n\u001b$B-<\u001b(B\n\u001b$B-=\u001b(B\n\u001b$B->\u001b(B\n\u001b$B-?\u001b(B\n\u001b$B-@\u001b(B\n\u001b$B-A\u001b(B\n\u001b$B-B\u001b(B\n\u001b$B-C\u001b(B\n\u001b$B-D\u001b(B\n\u001b$B-E\u001b(B\n\u001b$B-F\u001b(B\n\u001b$B-G\u001b(B\n\u001b$B-H\u001b(B\n\u001b$B-I\u001b(B\n\u001b$B-J\u001b(B\n\u001b$B-K\u001b(B\n\u001b$B-L\u001b(B\n\u001b$B-M\u001b(B\n\u001b$B-N\u001b(B\n\u001b$B-O\u001b(B\n\u001b$B-P\u001b(B\n\u001b$B-Q\u001b(B\n\u001b$B-R\u001b(B\n\u001b$B-S\u001b(B\n\u001b$B-T\u001b(B\n\u001b$B-U\u001b(B\n\u001b$B-V\u001b(B\n\u001b$B-W\u001b(B\n\u001b$B-X\u001b(B\n\u001b$B-Y\u001b(B\n\u001b$B-Z\u001b(B\n\u001b$B-[\u001b(B\n\u001b$B-\\\u001b(B\n\u001b$B-]\u001b(B\n\u001b$B-^\u001b(B\n\u001b$B-_\u001b(B\n\u001b$B-`\u001b(B\n\u001b$B-a\u001b(B\n\u001b$B-b\u001b(B\n\u001b$B-c\u001b(B\n\u001b$B-d\u001b(B\n\u001b$B-e\u001b(B\n\u001b$B-f\u001b(B\n\u001b$B-g\u001b(B\n\u001b$B-h\u001b(B\n\u001b$B-i\u001b(B\n\u001b$B-j\u001b(B\n\u001b$B-k\u001b(B\n\u001b$B-l\u001b(B\n\u001b$B-m\u001b(B\n\u001b$B-n\u001b(B\n\u001b$B-o\u001b(B\n\u001b$B-p\u001b(B\n\u001b$B-q\u001b(B\n\u001b$B-r\u001b(B\n\u001b$B-s\u001b(B\n\u001b$B-t\u001b(B\n\u001b$B-u\u001b(B\n\u001b$B-v\u001b(B\n\u001b$B-w\u001b(B\n\u001b$B-x\u001b(B\n\u001b$B-y\u001b(B\n\u001b$B-z\u001b(B\n\u001b$B-{\u001b(B\n\u001b$B-|\u001b(B\n\u001b$B-}\u001b(B\n\u001b$B-~\u001b(B\n\u001b$B.!\u001b(B\n\u001b$B.\"\u001b(B\n\u001b$B.#\u001b(B\n\u001b$B.$\u001b(B\n\u001b$B.%\u001b(B\n\u001b$B.&\u001b(B\n\u001b$B.'\u001b(B\n\u001b$B.(\u001b(B\n\u001b$B.)\u001b(B\n\u001b$B.*\u001b(B\n\u001b$B.+\u001b(B\n\u001b$B.,\u001b(B\n\u001b$B.-\u001b(B\n\u001b$B..\u001b(B\n\u001b$B./\u001b(B\n\u001b$B.0\u001b(B\n\u001b$B.1\u001b(B\n\u001b$B.2\u001b(B\n\u001b$B.3\u001b(B\n\u001b$B.4\u001b(B\n\u001b$B.5\u001b(B\n\u001b$B.6\u001b(B\n\u001b$B.7\u001b(B\n\u001b$B.8\u001b(B\n\u001b$B.9\u001b(B\n\u001b$B.:\u001b(B\n\u001b$B.;\u001b(B\n\u001b$B.<\u001b(B\n\u001b$B.=\u001b(B\n\u001b$B.>\u001b(B\n\u001b$B.?\u001b(B\n\u001b$B.@\u001b(B\n\u001b$B.A\u001b(B\n\u001b$B.B\u001b(B\n\u001b$B.C\u001b(B\n\u001b$B.D\u001b(B\n\u001b$B.E\u001b(B\n\u001b$B.F\u001b(B\n\u001b$B.G\u001b(B\n\u001b$B.H\u001b(B\n\u001b$B.I\u001b(B\n\u001b$B.J\u001b(B\n\u001b$B.K\u001b(B\n\u001b$B.L\u001b(B\n\u001b$B.M\u001b(B\n\u001b$B.N\u001b(B\n\u001b$B.O\u001b(B\n\u001b$B.P\u001b(B\n\u001b$B.Q\u001b(B\n\u001b$B.R\u001b(B\n\u001b$B.S\u001b(B\n\u001b$B.T\u001b(B\n\u001b$B.U\u001b(B\n\u001b$B.V\u001b(B\n\u001b$B.W\u001b(B\n\u001b$B.X\u001b(B\n\u001b$B.Y\u001b(B\n\u001b$B.Z\u001b(B\n\u001b$B.[\u001b(B\n\u001b$B.\\\u001b(B\n\u001b$B.]\u001b(B\n\u001b$B.^\u001b(B\n\u001b$B._\u001b(B\n\u001b$B.`\u001b(B\n\u001b$B.a\u001b(B\n\u001b$B.b\u001b(B\n\u001b$B.c\u001b(B\n\u001b$B.d\u001b(B\n\u001b$B.e\u001b(B\n\u001b$B.f\u001b(B\n\u001b$B.g\u001b(B\n\u001b$B.h\u001b(B\n\u001b$B.i\u001b(B\n\u001b$B.j\u001b(B\n\u001b$B.k\u001b(B\n\u001b$B.l\u001b(B\n\u001b$B.m\u001b(B\n\u001b$B.n\u001b(B\n\u001b$B.o\u001b(B\n\u001b$B.p\u001b(B\n\u001b$B.q\u001b(B\n\u001b$B.r\u001b(B\n\u001b$B.s\u001b(B\n\u001b$B.t\u001b(B\n\u001b$B.u\u001b(B\n\u001b$B.v\u001b(B\n\u001b$B.w\u001b(B\n\u001b$B.x\u001b(B\n\u001b$B.y\u001b(B\n\u001b$B.z\u001b(B\n\u001b$B.{\u001b(B\n\u001b$B.|\u001b(B\n\u001b$B.}\u001b(B\n\u001b$B.~\u001b(B\n\u001b$B/!\u001b(B\n\u001b$B/\"\u001b(B\n\u001b$B/#\u001b(B\n\u001b$B/$\u001b(B\n\u001b$B/%\u001b(B\n\u001b$B/&\u001b(B\n\u001b$B/'\u001b(B\n\u001b$B/(\u001b(B\n\u001b$B/)\u001b(B\n\u001b$B/*\u001b(B\n\u001b$B/+\u001b(B\n\u001b$B/,\u001b(B\n\u001b$B/-\u001b(B\n\u001b$B/.\u001b(B\n\u001b$B//\u001b(B\n\u001b$B/0\u001b(B\n\u001b$B/1\u001b(B\n\u001b$B/2\u001b(B\n\u001b$B/3\u001b(B\n\u001b$B/4\u001b(B\n\u001b$B/5\u001b(B\n\u001b$B/6\u001b(B\n\u001b$B/7\u001b(B\n\u001b$B/8\u001b(B\n\u001b$B/9\u001b(B\n\u001b$B/:\u001b(B\n\u001b$B/;\u001b(B\n\u001b$B/<\u001b(B\n\u001b$B/=\u001b(B\n\u001b$B/>\u001b(B\n\u001b$B/?\u001b(B\n\u001b$B/@\u001b(B\n\u001b$B/A\u001b(B\n\u001b$B/B\u001b(B\n\u001b$B/C\u001b(B\n\u001b$B/D\u001b(B\n\u001b$B/E\u001b(B\n\u001b$B/F\u001b(B\n\u001b$B/G\u001b(B\n\u001b$B/H\u001b(B\n\u001b$B/I\u001b(B\n\u001b$B/J\u001b(B\n\u001b$B/K\u001b(B\n\u001b$B/L\u001b(B\n\u001b$B/M\u001b(B\n\u001b$B/N\u001b(B\n\u001b$B/O\u001b(B\n\u001b$B/P\u001b(B\n\u001b$B/Q\u001b(B\n\u001b$B/R\u001b(B\n\u001b$B/S\u001b(B\n\u001b$B/T\u001b(B\n\u001b$B/U\u001b(B\n\u001b$B/V\u001b(B\n\u001b$B/W\u001b(B\n\u001b$B/X\u001b(B\n\u001b$B/Y\u001b(B\n\u001b$B/Z\u001b(B\n\u001b$B/[\u001b(B\n\u001b$B/\\\u001b(B\n\u001b$B/]\u001b(B\n\u001b$B/^\u001b(B\n\u001b$B/_\u001b(B\n\u001b$B/`\u001b(B\n\u001b$B/a\u001b(B\n\u001b$B/b\u001b(B\n\u001b$B/c\u001b(B\n\u001b$B/d\u001b(B\n\u001b$B/e\u001b(B\n\u001b$B/f\u001b(B\n\u001b$B/g\u001b(B\n\u001b$B/h\u001b(B\n\u001b$B/i\u001b(B\n\u001b$B/j\u001b(B\n\u001b$B/k\u001b(B\n\u001b$B/l\u001b(B\n\u001b$B/m\u001b(B\n\u001b$B/n\u001b(B\n\u001b$B/o\u001b(B\n\u001b$B/p\u001b(B\n\u001b$B/q\u001b(B\n\u001b$B/r\u001b(B\n\u001b$B/s\u001b(B\n\u001b$B/t\u001b(B\n\u001b$B/u\u001b(B\n\u001b$B/v\u001b(B\n\u001b$B/w\u001b(B\n\u001b$B/x\u001b(B\n\u001b$B/y\u001b(B\n\u001b$B/z\u001b(B\n\u001b$B/{\u001b(B\n\u001b$B/|\u001b(B\n\u001b$B/}\u001b(B\n\u001b$B/~\u001b(B\n\u001b$B0!\u001b(B\n\u001b$B0\"\u001b(B\n\u001b$B0#\u001b(B\n\u001b$B0$\u001b(B\n\u001b$B0%\u001b(B\n\u001b$B0&\u001b(B\n\u001b$B0'\u001b(B\n\u001b$B0(\u001b(B\n\u001b$B0)\u001b(B\n\u001b$B0*\u001b(B\n\u001b$B0+\u001b(B\n\u001b$B0,\u001b(B\n\u001b$B0-\u001b(B\n\u001b$B0.\u001b(B\n\u001b$B0/\u001b(B\n\u001b$B00\u001b(B\n\u001b$B01\u001b(B\n\u001b$B02\u001b(B\n\u001b$B03\u001b(B\n\u001b$B04\u001b(B\n\u001b$B05\u001b(B\n\u001b$B06\u001b(B\n\u001b$B07\u001b(B\n\u001b$B08\u001b(B\n\u001b$B09\u001b(B\n\u001b$B0:\u001b(B\n\u001b$B0;\u001b(B\n\u001b$B0<\u001b(B\n\u001b$B0=\u001b(B\n\u001b$B0>\u001b(B\n\u001b$B0?\u001b(B\n\u001b$B0@\u001b(B\n\u001b$B0A\u001b(B\n\u001b$B0B\u001b(B\n\u001b$B0C\u001b(B\n\u001b$B0D\u001b(B\n\u001b$B0E\u001b(B\n\u001b$B0F\u001b(B\n\u001b$B0G\u001b(B\n\u001b$B0H\u001b(B\n\u001b$B0I\u001b(B\n\u001b$B0J\u001b(B\n\u001b$B0K\u001b(B\n\u001b$B0L\u001b(B\n\u001b$B0M\u001b(B\n\u001b$B0N\u001b(B\n\u001b$B0O\u001b(B\n\u001b$B0P\u001b(B\n\u001b$B0Q\u001b(B\n\u001b$B0R\u001b(B\n\u001b$B0S\u001b(B\n\u001b$B0T\u001b(B\n\u001b$B0U\u001b(B\n\u001b$B0V\u001b(B\n\u001b$B0W\u001b(B\n\u001b$B0X\u001b(B\n\u001b$B0Y\u001b(B\n\u001b$B0Z\u001b(B\n\u001b$B0[\u001b(B\n\u001b$B0\\\u001b(B\n\u001b$B0]\u001b(B\n\u001b$B0^\u001b(B\n\u001b$B0_\u001b(B\n\u001b$B0`\u001b(B\n\u001b$B0a\u001b(B\n\u001b$B0b\u001b(B\n\u001b$B0c\u001b(B\n\u001b$B0d\u001b(B\n\u001b$B0e\u001b(B\n\u001b$B0f\u001b(B\n\u001b$B0g\u001b(B\n\u001b$B0h\u001b(B\n\u001b$B0i\u001b(B\n\u001b$B0j\u001b(B\n\u001b$B0k\u001b(B\n\u001b$B0l\u001b(B\n\u001b$B0m\u001b(B\n\u001b$B0n\u001b(B\n\u001b$B0o\u001b(B\n\u001b$B0p\u001b(B\n\u001b$B0q\u001b(B\n\u001b$B0r\u001b(B\n\u001b$B0s\u001b(B\n\u001b$B0t\u001b(B\n\u001b$B0u\u001b(B\n\u001b$B0v\u001b(B\n\u001b$B0w\u001b(B\n\u001b$B0x\u001b(B\n\u001b$B0y\u001b(B\n\u001b$B0z\u001b(B\n\u001b$B0{\u001b(B\n\u001b$B0|\u001b(B\n\u001b$B0}\u001b(B\n\u001b$B0~\u001b(B\n\u001b$B1!\u001b(B\n\u001b$B1\"\u001b(B\n\u001b$B1#\u001b(B\n\u001b$B1$\u001b(B\n\u001b$B1%\u001b(B\n\u001b$B1&\u001b(B\n\u001b$B1'\u001b(B\n\u001b$B1(\u001b(B\n\u001b$B1)\u001b(B\n\u001b$B1*\u001b(B\n\u001b$B1+\u001b(B\n\u001b$B1,\u001b(B\n\u001b$B1-\u001b(B\n\u001b$B1.\u001b(B\n\u001b$B1/\u001b(B\n\u001b$B10\u001b(B\n\u001b$B11\u001b(B\n\u001b$B12\u001b(B\n\u001b$B13\u001b(B\n\u001b$B14\u001b(B\n\u001b$B15\u001b(B\n\u001b$B16\u001b(B\n\u001b$B17\u001b(B\n\u001b$B18\u001b(B\n\u001b$B19\u001b(B\n\u001b$B1:\u001b(B\n\u001b$B1;\u001b(B\n\u001b$B1<\u001b(B\n\u001b$B1=\u001b(B\n\u001b$B1>\u001b(B\n\u001b$B1?\u001b(B\n\u001b$B1@\u001b(B\n\u001b$B1A\u001b(B\n\u001b$B1B\u001b(B\n\u001b$B1C\u001b(B\n\u001b$B1D\u001b(B\n\u001b$B1E\u001b(B\n\u001b$B1F\u001b(B\n\u001b$B1G\u001b(B\n\u001b$B1H\u001b(B\n\u001b$B1I\u001b(B\n\u001b$B1J\u001b(B\n\u001b$B1K\u001b(B\n\u001b$B1L\u001b(B\n\u001b$B1M\u001b(B\n\u001b$B1N\u001b(B\n\u001b$B1O\u001b(B\n\u001b$B1P\u001b(B\n\u001b$B1Q\u001b(B\n\u001b$B1R\u001b(B\n\u001b$B1S\u001b(B\n\u001b$B1T\u001b(B\n\u001b$B1U\u001b(B\n\u001b$B1V\u001b(B\n\u001b$B1W\u001b(B\n\u001b$B1X\u001b(B\n\u001b$B1Y\u001b(B\n\u001b$B1Z\u001b(B\n\u001b$B1[\u001b(B\n\u001b$B1\\\u001b(B\n\u001b$B1]\u001b(B\n\u001b$B1^\u001b(B\n\u001b$B1_\u001b(B\n\u001b$B1`\u001b(B\n\u001b$B1a\u001b(B\n\u001b$B1b\u001b(B\n\u001b$B1c\u001b(B\n\u001b$B1d\u001b(B\n\u001b$B1e\u001b(B\n\u001b$B1f\u001b(B\n\u001b$B1g\u001b(B\n\u001b$B1h\u001b(B\n\u001b$B1i\u001b(B\n\u001b$B1j\u001b(B\n\u001b$B1k\u001b(B\n\u001b$B1l\u001b(B\n\u001b$B1m\u001b(B\n\u001b$B1n\u001b(B\n\u001b$B1o\u001b(B\n\u001b$B1p\u001b(B\n\u001b$B1q\u001b(B\n\u001b$B1r\u001b(B\n\u001b$B1s\u001b(B\n\u001b$B1t\u001b(B\n\u001b$B1u\u001b(B\n\u001b$B1v\u001b(B\n\u001b$B1w\u001b(B\n\u001b$B1x\u001b(B\n\u001b$B1y\u001b(B\n\u001b$B1z\u001b(B\n\u001b$B1{\u001b(B\n\u001b$B1|\u001b(B\n\u001b$B1}\u001b(B\n\u001b$B1~\u001b(B\n\u001b$B2!\u001b(B\n\u001b$B2\"\u001b(B\n\u001b$B2#\u001b(B\n\u001b$B2$\u001b(B\n\u001b$B2%\u001b(B\n\u001b$B2&\u001b(B\n\u001b$B2'\u001b(B\n\u001b$B2(\u001b(B\n\u001b$B2)\u001b(B\n\u001b$B2*\u001b(B\n\u001b$B2+\u001b(B\n\u001b$B2,\u001b(B\n\u001b$B2-\u001b(B\n\u001b$B2.\u001b(B\n\u001b$B2/\u001b(B\n\u001b$B20\u001b(B\n\u001b$B21\u001b(B\n\u001b$B22\u001b(B\n\u001b$B23\u001b(B\n\u001b$B24\u001b(B\n\u001b$B25\u001b(B\n\u001b$B26\u001b(B\n\u001b$B27\u001b(B\n\u001b$B28\u001b(B\n\u001b$B29\u001b(B\n\u001b$B2:\u001b(B\n\u001b$B2;\u001b(B\n\u001b$B2<\u001b(B\n\u001b$B2=\u001b(B\n\u001b$B2>\u001b(B\n\u001b$B2?\u001b(B\n\u001b$B2@\u001b(B\n\u001b$B2A\u001b(B\n\u001b$B2B\u001b(B\n\u001b$B2C\u001b(B\n\u001b$B2D\u001b(B\n\u001b$B2E\u001b(B\n\u001b$B2F\u001b(B\n\u001b$B2G\u001b(B\n\u001b$B2H\u001b(B\n\u001b$B2I\u001b(B\n\u001b$B2J\u001b(B\n\u001b$B2K\u001b(B\n\u001b$B2L\u001b(B\n\u001b$B2M\u001b(B\n\u001b$B2N\u001b(B\n\u001b$B2O\u001b(B\n\u001b$B2P\u001b(B\n\u001b$B2Q\u001b(B\n\u001b$B2R\u001b(B\n\u001b$B2S\u001b(B\n\u001b$B2T\u001b(B\n\u001b$B2U\u001b(B\n\u001b$B2V\u001b(B\n\u001b$B2W\u001b(B\n\u001b$B2X\u001b(B\n\u001b$B2Y\u001b(B\n\u001b$B2Z\u001b(B\n\u001b$B2[\u001b(B\n\u001b$B2\\\u001b(B\n\u001b$B2]\u001b(B\n\u001b$B2^\u001b(B\n\u001b$B2_\u001b(B\n\u001b$B2`\u001b(B\n\u001b$B2a\u001b(B\n\u001b$B2b\u001b(B\n\u001b$B2c\u001b(B\n\u001b$B2d\u001b(B\n\u001b$B2e\u001b(B\n\u001b$B2f\u001b(B\n\u001b$B2g\u001b(B\n\u001b$B2h\u001b(B\n\u001b$B2i\u001b(B\n\u001b$B2j\u001b(B\n\u001b$B2k\u001b(B\n\u001b$B2l\u001b(B\n\u001b$B2m\u001b(B\n\u001b$B2n\u001b(B\n\u001b$B2o\u001b(B\n\u001b$B2p\u001b(B\n\u001b$B2q\u001b(B\n\u001b$B2r\u001b(B\n\u001b$B2s\u001b(B\n\u001b$B2t\u001b(B\n\u001b$B2u\u001b(B\n\u001b$B2v\u001b(B\n\u001b$B2w\u001b(B\n\u001b$B2x\u001b(B\n\u001b$B2y\u001b(B\n\u001b$B2z\u001b(B\n\u001b$B2{\u001b(B\n\u001b$B2|\u001b(B\n\u001b$B2}\u001b(B\n\u001b$B2~\u001b(B\n\u001b$B3!\u001b(B\n\u001b$B3\"\u001b(B\n\u001b$B3#\u001b(B\n\u001b$B3$\u001b(B\n\u001b$B3%\u001b(B\n\u001b$B3&\u001b(B\n\u001b$B3'\u001b(B\n\u001b$B3(\u001b(B\n\u001b$B3)\u001b(B\n\u001b$B3*\u001b(B\n\u001b$B3+\u001b(B\n\u001b$B3,\u001b(B\n\u001b$B3-\u001b(B\n\u001b$B3.\u001b(B\n\u001b$B3/\u001b(B\n\u001b$B30\u001b(B\n\u001b$B31\u001b(B\n\u001b$B32\u001b(B\n\u001b$B33\u001b(B\n\u001b$B34\u001b(B\n\u001b$B35\u001b(B\n\u001b$B36\u001b(B\n\u001b$B37\u001b(B\n\u001b$B38\u001b(B\n\u001b$B39\u001b(B\n\u001b$B3:\u001b(B\n\u001b$B3;\u001b(B\n\u001b$B3<\u001b(B\n\u001b$B3=\u001b(B\n\u001b$B3>\u001b(B\n\u001b$B3?\u001b(B\n\u001b$B3@\u001b(B\n\u001b$B3A\u001b(B\n\u001b$B3B\u001b(B\n\u001b$B3C\u001b(B\n\u001b$B3D\u001b(B\n\u001b$B3E\u001b(B\n\u001b$B3F\u001b(B\n\u001b$B3G\u001b(B\n\u001b$B3H\u001b(B\n\u001b$B3I\u001b(B\n\u001b$B3J\u001b(B\n\u001b$B3K\u001b(B\n\u001b$B3L\u001b(B\n\u001b$B3M\u001b(B\n\u001b$B3N\u001b(B\n\u001b$B3O\u001b(B\n\u001b$B3P\u001b(B\n\u001b$B3Q\u001b(B\n\u001b$B3R\u001b(B\n\u001b$B3S\u001b(B\n\u001b$B3T\u001b(B\n\u001b$B3U\u001b(B\n\u001b$B3V\u001b(B\n\u001b$B3W\u001b(B\n\u001b$B3X\u001b(B\n\u001b$B3Y\u001b(B\n\u001b$B3Z\u001b(B\n\u001b$B3[\u001b(B\n\u001b$B3\\\u001b(B\n\u001b$B3]\u001b(B\n\u001b$B3^\u001b(B\n\u001b$B3_\u001b(B\n\u001b$B3`\u001b(B\n\u001b$B3a\u001b(B\n\u001b$B3b\u001b(B\n\u001b$B3c\u001b(B\n\u001b$B3d\u001b(B\n\u001b$B3e\u001b(B\n\u001b$B3f\u001b(B\n\u001b$B3g\u001b(B\n\u001b$B3h\u001b(B\n\u001b$B3i\u001b(B\n\u001b$B3j\u001b(B\n\u001b$B3k\u001b(B\n\u001b$B3l\u001b(B\n\u001b$B3m\u001b(B\n\u001b$B3n\u001b(B\n\u001b$B3o\u001b(B\n\u001b$B3p\u001b(B\n\u001b$B3q\u001b(B\n\u001b$B3r\u001b(B\n\u001b$B3s\u001b(B\n\u001b$B3t\u001b(B\n\u001b$B3u\u001b(B\n\u001b$B3v\u001b(B\n\u001b$B3w\u001b(B\n\u001b$B3x\u001b(B\n\u001b$B3y\u001b(B\n\u001b$B3z\u001b(B\n\u001b$B3{\u001b(B\n\u001b$B3|\u001b(B\n\u001b$B3}\u001b(B\n\u001b$B3~\u001b(B\n\u001b$B4!\u001b(B\n\u001b$B4\"\u001b(B\n\u001b$B4#\u001b(B\n\u001b$B4$\u001b(B\n\u001b$B4%\u001b(B\n\u001b$B4&\u001b(B\n\u001b$B4'\u001b(B\n\u001b$B4(\u001b(B\n\u001b$B4)\u001b(B\n\u001b$B4*\u001b(B\n\u001b$B4+\u001b(B\n\u001b$B4,\u001b(B\n\u001b$B4-\u001b(B\n\u001b$B4.\u001b(B\n\u001b$B4/\u001b(B\n\u001b$B40\u001b(B\n\u001b$B41\u001b(B\n\u001b$B42\u001b(B\n\u001b$B43\u001b(B\n\u001b$B44\u001b(B\n\u001b$B45\u001b(B\n\u001b$B46\u001b(B\n\u001b$B47\u001b(B\n\u001b$B48\u001b(B\n\u001b$B49\u001b(B\n\u001b$B4:\u001b(B\n\u001b$B4;\u001b(B\n\u001b$B4<\u001b(B\n\u001b$B4=\u001b(B\n\u001b$B4>\u001b(B\n\u001b$B4?\u001b(B\n\u001b$B4@\u001b(B\n\u001b$B4A\u001b(B\n\u001b$B4B\u001b(B\n\u001b$B4C\u001b(B\n\u001b$B4D\u001b(B\n\u001b$B4E\u001b(B\n\u001b$B4F\u001b(B\n\u001b$B4G\u001b(B\n\u001b$B4H\u001b(B\n\u001b$B4I\u001b(B\n\u001b$B4J\u001b(B\n\u001b$B4K\u001b(B\n\u001b$B4L\u001b(B\n\u001b$B4M\u001b(B\n\u001b$B4N\u001b(B\n\u001b$B4O\u001b(B\n\u001b$B4P\u001b(B\n\u001b$B4Q\u001b(B\n\u001b$B4R\u001b(B\n\u001b$B4S\u001b(B\n\u001b$B4T\u001b(B\n\u001b$B4U\u001b(B\n\u001b$B4V\u001b(B\n\u001b$B4W\u001b(B\n\u001b$B4X\u001b(B\n\u001b$B4Y\u001b(B\n\u001b$B4Z\u001b(B\n\u001b$B4[\u001b(B\n\u001b$B4\\\u001b(B\n\u001b$B4]\u001b(B\n\u001b$B4^\u001b(B\n\u001b$B4_\u001b(B\n\u001b$B4`\u001b(B\n\u001b$B4a\u001b(B\n\u001b$B4b\u001b(B\n\u001b$B4c\u001b(B\n\u001b$B4d\u001b(B\n\u001b$B4e\u001b(B\n\u001b$B4f\u001b(B\n\u001b$B4g\u001b(B\n\u001b$B4h\u001b(B\n\u001b$B4i\u001b(B\n\u001b$B4j\u001b(B\n\u001b$B4k\u001b(B\n\u001b$B4l\u001b(B\n\u001b$B4m\u001b(B\n\u001b$B4n\u001b(B\n\u001b$B4o\u001b(B\n\u001b$B4p\u001b(B\n\u001b$B4q\u001b(B\n\u001b$B4r\u001b(B\n\u001b$B4s\u001b(B\n\u001b$B4t\u001b(B\n\u001b$B4u\u001b(B\n\u001b$B4v\u001b(B\n\u001b$B4w\u001b(B\n\u001b$B4x\u001b(B\n\u001b$B4y\u001b(B\n\u001b$B4z\u001b(B\n\u001b$B4{\u001b(B\n\u001b$B4|\u001b(B\n\u001b$B4}\u001b(B\n\u001b$B4~\u001b(B\n\u001b$B5!\u001b(B\n\u001b$B5\"\u001b(B\n\u001b$B5#\u001b(B\n\u001b$B5$\u001b(B\n\u001b$B5%\u001b(B\n\u001b$B5&\u001b(B\n\u001b$B5'\u001b(B\n\u001b$B5(\u001b(B\n\u001b$B5)\u001b(B\n\u001b$B5*\u001b(B\n\u001b$B5+\u001b(B\n\u001b$B5,\u001b(B\n\u001b$B5-\u001b(B\n\u001b$B5.\u001b(B\n\u001b$B5/\u001b(B\n\u001b$B50\u001b(B\n\u001b$B51\u001b(B\n\u001b$B52\u001b(B\n\u001b$B53\u001b(B\n\u001b$B54\u001b(B\n\u001b$B55\u001b(B\n\u001b$B56\u001b(B\n\u001b$B57\u001b(B\n\u001b$B58\u001b(B\n\u001b$B59\u001b(B\n\u001b$B5:\u001b(B\n\u001b$B5;\u001b(B\n\u001b$B5<\u001b(B\n\u001b$B5=\u001b(B\n\u001b$B5>\u001b(B\n\u001b$B5?\u001b(B\n\u001b$B5@\u001b(B\n\u001b$B5A\u001b(B\n\u001b$B5B\u001b(B\n\u001b$B5C\u001b(B\n\u001b$B5D\u001b(B\n\u001b$B5E\u001b(B\n\u001b$B5F\u001b(B\n\u001b$B5G\u001b(B\n\u001b$B5H\u001b(B\n\u001b$B5I\u001b(B\n\u001b$B5J\u001b(B\n\u001b$B5K\u001b(B\n\u001b$B5L\u001b(B\n\u001b$B5M\u001b(B\n\u001b$B5N\u001b(B\n\u001b$B5O\u001b(B\n\u001b$B5P\u001b(B\n\u001b$B5Q\u001b(B\n\u001b$B5R\u001b(B\n\u001b$B5S\u001b(B\n\u001b$B5T\u001b(B\n\u001b$B5U\u001b(B\n\u001b$B5V\u001b(B\n\u001b$B5W\u001b(B\n\u001b$B5X\u001b(B\n\u001b$B5Y\u001b(B\n\u001b$B5Z\u001b(B\n\u001b$B5[\u001b(B\n\u001b$B5\\\u001b(B\n\u001b$B5]\u001b(B\n\u001b$B5^\u001b(B\n\u001b$B5_\u001b(B\n\u001b$B5`\u001b(B\n\u001b$B5a\u001b(B\n\u001b$B5b\u001b(B\n\u001b$B5c\u001b(B\n\u001b$B5d\u001b(B\n\u001b$B5e\u001b(B\n\u001b$B5f\u001b(B\n\u001b$B5g\u001b(B\n\u001b$B5h\u001b(B\n\u001b$B5i\u001b(B\n\u001b$B5j\u001b(B\n\u001b$B5k\u001b(B\n\u001b$B5l\u001b(B\n\u001b$B5m\u001b(B\n\u001b$B5n\u001b(B\n\u001b$B5o\u001b(B\n\u001b$B5p\u001b(B\n\u001b$B5q\u001b(B\n\u001b$B5r\u001b(B\n\u001b$B5s\u001b(B\n\u001b$B5t\u001b(B\n\u001b$B5u\u001b(B\n\u001b$B5v\u001b(B\n\u001b$B5w\u001b(B\n\u001b$B5x\u001b(B\n\u001b$B5y\u001b(B\n\u001b$B5z\u001b(B\n\u001b$B5{\u001b(B\n\u001b$B5|\u001b(B\n\u001b$B5}\u001b(B\n\u001b$B5~\u001b(B\n\u001b$B6!\u001b(B\n\u001b$B6\"\u001b(B\n\u001b$B6#\u001b(B\n\u001b$B6$\u001b(B\n\u001b$B6%\u001b(B\n\u001b$B6&\u001b(B\n\u001b$B6'\u001b(B\n\u001b$B6(\u001b(B\n\u001b$B6)\u001b(B\n\u001b$B6*\u001b(B\n\u001b$B6+\u001b(B\n\u001b$B6,\u001b(B\n\u001b$B6-\u001b(B\n\u001b$B6.\u001b(B\n\u001b$B6/\u001b(B\n\u001b$B60\u001b(B\n\u001b$B61\u001b(B\n\u001b$B62\u001b(B\n\u001b$B63\u001b(B\n\u001b$B64\u001b(B\n\u001b$B65\u001b(B\n\u001b$B66\u001b(B\n\u001b$B67\u001b(B\n\u001b$B68\u001b(B\n\u001b$B69\u001b(B\n\u001b$B6:\u001b(B\n\u001b$B6;\u001b(B\n\u001b$B6<\u001b(B\n\u001b$B6=\u001b(B\n\u001b$B6>\u001b(B\n\u001b$B6?\u001b(B\n\u001b$B6@\u001b(B\n\u001b$B6A\u001b(B\n\u001b$B6B\u001b(B\n\u001b$B6C\u001b(B\n\u001b$B6D\u001b(B\n\u001b$B6E\u001b(B\n\u001b$B6F\u001b(B\n\u001b$B6G\u001b(B\n\u001b$B6H\u001b(B\n\u001b$B6I\u001b(B\n\u001b$B6J\u001b(B\n\u001b$B6K\u001b(B\n\u001b$B6L\u001b(B\n\u001b$B6M\u001b(B\n\u001b$B6N\u001b(B\n\u001b$B6O\u001b(B\n\u001b$B6P\u001b(B\n\u001b$B6Q\u001b(B\n\u001b$B6R\u001b(B\n\u001b$B6S\u001b(B\n\u001b$B6T\u001b(B\n\u001b$B6U\u001b(B\n\u001b$B6V\u001b(B\n\u001b$B6W\u001b(B\n\u001b$B6X\u001b(B\n\u001b$B6Y\u001b(B\n\u001b$B6Z\u001b(B\n\u001b$B6[\u001b(B\n\u001b$B6\\\u001b(B\n\u001b$B6]\u001b(B\n\u001b$B6^\u001b(B\n\u001b$B6_\u001b(B\n\u001b$B6`\u001b(B\n\u001b$B6a\u001b(B\n\u001b$B6b\u001b(B\n\u001b$B6c\u001b(B\n\u001b$B6d\u001b(B\n\u001b$B6e\u001b(B\n\u001b$B6f\u001b(B\n\u001b$B6g\u001b(B\n\u001b$B6h\u001b(B\n\u001b$B6i\u001b(B\n\u001b$B6j\u001b(B\n\u001b$B6k\u001b(B\n\u001b$B6l\u001b(B\n\u001b$B6m\u001b(B\n\u001b$B6n\u001b(B\n\u001b$B6o\u001b(B\n\u001b$B6p\u001b(B\n\u001b$B6q\u001b(B\n\u001b$B6r\u001b(B\n\u001b$B6s\u001b(B\n\u001b$B6t\u001b(B\n\u001b$B6u\u001b(B\n\u001b$B6v\u001b(B\n\u001b$B6w\u001b(B\n\u001b$B6x\u001b(B\n\u001b$B6y\u001b(B\n\u001b$B6z\u001b(B\n\u001b$B6{\u001b(B\n\u001b$B6|\u001b(B\n\u001b$B6}\u001b(B\n\u001b$B6~\u001b(B\n\u001b$B7!\u001b(B\n\u001b$B7\"\u001b(B\n\u001b$B7#\u001b(B\n\u001b$B7$\u001b(B\n\u001b$B7%\u001b(B\n\u001b$B7&\u001b(B\n\u001b$B7'\u001b(B\n\u001b$B7(\u001b(B\n\u001b$B7)\u001b(B\n\u001b$B7*\u001b(B\n\u001b$B7+\u001b(B\n\u001b$B7,\u001b(B\n\u001b$B7-\u001b(B\n\u001b$B7.\u001b(B\n\u001b$B7/\u001b(B\n\u001b$B70\u001b(B\n\u001b$B71\u001b(B\n\u001b$B72\u001b(B\n\u001b$B73\u001b(B\n\u001b$B74\u001b(B\n\u001b$B75\u001b(B\n\u001b$B76\u001b(B\n\u001b$B77\u001b(B\n\u001b$B78\u001b(B\n\u001b$B79\u001b(B\n\u001b$B7:\u001b(B\n\u001b$B7;\u001b(B\n\u001b$B7<\u001b(B\n\u001b$B7=\u001b(B\n\u001b$B7>\u001b(B\n\u001b$B7?\u001b(B\n\u001b$B7@\u001b(B\n\u001b$B7A\u001b(B\n\u001b$B7B\u001b(B\n\u001b$B7C\u001b(B\n\u001b$B7D\u001b(B\n\u001b$B7E\u001b(B\n\u001b$B7F\u001b(B\n\u001b$B7G\u001b(B\n\u001b$B7H\u001b(B\n\u001b$B7I\u001b(B\n\u001b$B7J\u001b(B\n\u001b$B7K\u001b(B\n\u001b$B7L\u001b(B\n\u001b$B7M\u001b(B\n\u001b$B7N\u001b(B\n\u001b$B7O\u001b(B\n\u001b$B7P\u001b(B\n\u001b$B7Q\u001b(B\n\u001b$B7R\u001b(B\n\u001b$B7S\u001b(B\n\u001b$B7T\u001b(B\n\u001b$B7U\u001b(B\n\u001b$B7V\u001b(B\n\u001b$B7W\u001b(B\n\u001b$B7X\u001b(B\n\u001b$B7Y\u001b(B\n\u001b$B7Z\u001b(B\n\u001b$B7[\u001b(B\n\u001b$B7\\\u001b(B\n\u001b$B7]\u001b(B\n\u001b$B7^\u001b(B\n\u001b$B7_\u001b(B\n\u001b$B7`\u001b(B\n\u001b$B7a\u001b(B\n\u001b$B7b\u001b(B\n\u001b$B7c\u001b(B\n\u001b$B7d\u001b(B\n\u001b$B7e\u001b(B\n\u001b$B7f\u001b(B\n\u001b$B7g\u001b(B\n\u001b$B7h\u001b(B\n\u001b$B7i\u001b(B\n\u001b$B7j\u001b(B\n\u001b$B7k\u001b(B\n\u001b$B7l\u001b(B\n\u001b$B7m\u001b(B\n\u001b$B7n\u001b(B\n\u001b$B7o\u001b(B\n\u001b$B7p\u001b(B\n\u001b$B7q\u001b(B\n\u001b$B7r\u001b(B\n\u001b$B7s\u001b(B\n\u001b$B7t\u001b(B\n\u001b$B7u\u001b(B\n\u001b$B7v\u001b(B\n\u001b$B7w\u001b(B\n\u001b$B7x\u001b(B\n\u001b$B7y\u001b(B\n\u001b$B7z\u001b(B\n\u001b$B7{\u001b(B\n\u001b$B7|\u001b(B\n\u001b$B7}\u001b(B\n\u001b$B7~\u001b(B\n\u001b$B8!\u001b(B\n\u001b$B8\"\u001b(B\n\u001b$B8#\u001b(B\n\u001b$B8$\u001b(B\n\u001b$B8%\u001b(B\n\u001b$B8&\u001b(B\n\u001b$B8'\u001b(B\n\u001b$B8(\u001b(B\n\u001b$B8)\u001b(B\n\u001b$B8*\u001b(B\n\u001b$B8+\u001b(B\n\u001b$B8,\u001b(B\n\u001b$B8-\u001b(B\n\u001b$B8.\u001b(B\n\u001b$B8/\u001b(B\n\u001b$B80\u001b(B\n\u001b$B81\u001b(B\n\u001b$B82\u001b(B\n\u001b$B83\u001b(B\n\u001b$B84\u001b(B\n\u001b$B85\u001b(B\n\u001b$B86\u001b(B\n\u001b$B87\u001b(B\n\u001b$B88\u001b(B\n\u001b$B89\u001b(B\n\u001b$B8:\u001b(B\n\u001b$B8;\u001b(B\n\u001b$B8<\u001b(B\n\u001b$B8=\u001b(B\n\u001b$B8>\u001b(B\n\u001b$B8?\u001b(B\n\u001b$B8@\u001b(B\n\u001b$B8A\u001b(B\n\u001b$B8B\u001b(B\n\u001b$B8C\u001b(B\n\u001b$B8D\u001b(B\n\u001b$B8E\u001b(B\n\u001b$B8F\u001b(B\n\u001b$B8G\u001b(B\n\u001b$B8H\u001b(B\n\u001b$B8I\u001b(B\n\u001b$B8J\u001b(B\n\u001b$B8K\u001b(B\n\u001b$B8L\u001b(B\n\u001b$B8M\u001b(B\n\u001b$B8N\u001b(B\n\u001b$B8O\u001b(B\n\u001b$B8P\u001b(B\n\u001b$B8Q\u001b(B\n\u001b$B8R\u001b(B\n\u001b$B8S\u001b(B\n\u001b$B8T\u001b(B\n\u001b$B8U\u001b(B\n\u001b$B8V\u001b(B\n\u001b$B8W\u001b(B\n\u001b$B8X\u001b(B\n\u001b$B8Y\u001b(B\n\u001b$B8Z\u001b(B\n\u001b$B8[\u001b(B\n\u001b$B8\\\u001b(B\n\u001b$B8]\u001b(B\n\u001b$B8^\u001b(B\n\u001b$B8_\u001b(B\n\u001b$B8`\u001b(B\n\u001b$B8a\u001b(B\n\u001b$B8b\u001b(B\n\u001b$B8c\u001b(B\n\u001b$B8d\u001b(B\n\u001b$B8e\u001b(B\n\u001b$B8f\u001b(B\n\u001b$B8g\u001b(B\n\u001b$B8h\u001b(B\n\u001b$B8i\u001b(B\n\u001b$B8j\u001b(B\n\u001b$B8k\u001b(B\n\u001b$B8l\u001b(B\n\u001b$B8m\u001b(B\n\u001b$B8n\u001b(B\n\u001b$B8o\u001b(B\n\u001b$B8p\u001b(B\n\u001b$B8q\u001b(B\n\u001b$B8r\u001b(B\n\u001b$B8s\u001b(B\n\u001b$B8t\u001b(B\n\u001b$B8u\u001b(B\n\u001b$B8v\u001b(B\n\u001b$B8w\u001b(B\n\u001b$B8x\u001b(B\n\u001b$B8y\u001b(B\n\u001b$B8z\u001b(B\n\u001b$B8{\u001b(B\n\u001b$B8|\u001b(B\n\u001b$B8}\u001b(B\n\u001b$B8~\u001b(B\n\u001b$B9!\u001b(B\n\u001b$B9\"\u001b(B\n\u001b$B9#\u001b(B\n\u001b$B9$\u001b(B\n\u001b$B9%\u001b(B\n\u001b$B9&\u001b(B\n\u001b$B9'\u001b(B\n\u001b$B9(\u001b(B\n\u001b$B9)\u001b(B\n\u001b$B9*\u001b(B\n\u001b$B9+\u001b(B\n\u001b$B9,\u001b(B\n\u001b$B9-\u001b(B\n\u001b$B9.\u001b(B\n\u001b$B9/\u001b(B\n\u001b$B90\u001b(B\n\u001b$B91\u001b(B\n\u001b$B92\u001b(B\n\u001b$B93\u001b(B\n\u001b$B94\u001b(B\n\u001b$B95\u001b(B\n\u001b$B96\u001b(B\n\u001b$B97\u001b(B\n\u001b$B98\u001b(B\n\u001b$B99\u001b(B\n\u001b$B9:\u001b(B\n\u001b$B9;\u001b(B\n\u001b$B9<\u001b(B\n\u001b$B9=\u001b(B\n\u001b$B9>\u001b(B\n\u001b$B9?\u001b(B\n\u001b$B9@\u001b(B\n\u001b$B9A\u001b(B\n\u001b$B9B\u001b(B\n\u001b$B9C\u001b(B\n\u001b$B9D\u001b(B\n\u001b$B9E\u001b(B\n\u001b$B9F\u001b(B\n\u001b$B9G\u001b(B\n\u001b$B9H\u001b(B\n\u001b$B9I\u001b(B\n\u001b$B9J\u001b(B\n\u001b$B9K\u001b(B\n\u001b$B9L\u001b(B\n\u001b$B9M\u001b(B\n\u001b$B9N\u001b(B\n\u001b$B9O\u001b(B\n\u001b$B9P\u001b(B\n\u001b$B9Q\u001b(B\n\u001b$B9R\u001b(B\n\u001b$B9S\u001b(B\n\u001b$B9T\u001b(B\n\u001b$B9U\u001b(B\n\u001b$B9V\u001b(B\n\u001b$B9W\u001b(B\n\u001b$B9X\u001b(B\n\u001b$B9Y\u001b(B\n\u001b$B9Z\u001b(B\n\u001b$B9[\u001b(B\n\u001b$B9\\\u001b(B\n\u001b$B9]\u001b(B\n\u001b$B9^\u001b(B\n\u001b$B9_\u001b(B\n\u001b$B9`\u001b(B\n\u001b$B9a\u001b(B\n\u001b$B9b\u001b(B\n\u001b$B9c\u001b(B\n\u001b$B9d\u001b(B\n\u001b$B9e\u001b(B\n\u001b$B9f\u001b(B\n\u001b$B9g\u001b(B\n\u001b$B9h\u001b(B\n\u001b$B9i\u001b(B\n\u001b$B9j\u001b(B\n\u001b$B9k\u001b(B\n\u001b$B9l\u001b(B\n\u001b$B9m\u001b(B\n\u001b$B9n\u001b(B\n\u001b$B9o\u001b(B\n\u001b$B9p\u001b(B\n\u001b$B9q\u001b(B\n\u001b$B9r\u001b(B\n\u001b$B9s\u001b(B\n\u001b$B9t\u001b(B\n\u001b$B9u\u001b(B\n\u001b$B9v\u001b(B\n\u001b$B9w\u001b(B\n\u001b$B9x\u001b(B\n\u001b$B9y\u001b(B\n\u001b$B9z\u001b(B\n\u001b$B9{\u001b(B\n\u001b$B9|\u001b(B\n\u001b$B9}\u001b(B\n\u001b$B9~\u001b(B\n\u001b$B:!\u001b(B\n\u001b$B:\"\u001b(B\n\u001b$B:#\u001b(B\n\u001b$B:$\u001b(B\n\u001b$B:%\u001b(B\n\u001b$B:&\u001b(B\n\u001b$B:'\u001b(B\n\u001b$B:(\u001b(B\n\u001b$B:)\u001b(B\n\u001b$B:*\u001b(B\n\u001b$B:+\u001b(B\n\u001b$B:,\u001b(B\n\u001b$B:-\u001b(B\n\u001b$B:.\u001b(B\n\u001b$B:/\u001b(B\n\u001b$B:0\u001b(B\n\u001b$B:1\u001b(B\n\u001b$B:2\u001b(B\n\u001b$B:3\u001b(B\n\u001b$B:4\u001b(B\n\u001b$B:5\u001b(B\n\u001b$B:6\u001b(B\n\u001b$B:7\u001b(B\n\u001b$B:8\u001b(B\n\u001b$B:9\u001b(B\n\u001b$B::\u001b(B\n\u001b$B:;\u001b(B\n\u001b$B:<\u001b(B\n\u001b$B:=\u001b(B\n\u001b$B:>\u001b(B\n\u001b$B:?\u001b(B\n\u001b$B:@\u001b(B\n\u001b$B:A\u001b(B\n\u001b$B:B\u001b(B\n\u001b$B:C\u001b(B\n\u001b$B:D\u001b(B\n\u001b$B:E\u001b(B\n\u001b$B:F\u001b(B\n\u001b$B:G\u001b(B\n\u001b$B:H\u001b(B\n\u001b$B:I\u001b(B\n\u001b$B:J\u001b(B\n\u001b$B:K\u001b(B\n\u001b$B:L\u001b(B\n\u001b$B:M\u001b(B\n\u001b$B:N\u001b(B\n\u001b$B:O\u001b(B\n\u001b$B:P\u001b(B\n\u001b$B:Q\u001b(B\n\u001b$B:R\u001b(B\n\u001b$B:S\u001b(B\n\u001b$B:T\u001b(B\n\u001b$B:U\u001b(B\n\u001b$B:V\u001b(B\n\u001b$B:W\u001b(B\n\u001b$B:X\u001b(B\n\u001b$B:Y\u001b(B\n\u001b$B:Z\u001b(B\n\u001b$B:[\u001b(B\n\u001b$B:\\\u001b(B\n\u001b$B:]\u001b(B\n\u001b$B:^\u001b(B\n\u001b$B:_\u001b(B\n\u001b$B:`\u001b(B\n\u001b$B:a\u001b(B\n\u001b$B:b\u001b(B\n\u001b$B:c\u001b(B\n\u001b$B:d\u001b(B\n\u001b$B:e\u001b(B\n\u001b$B:f\u001b(B\n\u001b$B:g\u001b(B\n\u001b$B:h\u001b(B\n\u001b$B:i\u001b(B\n\u001b$B:j\u001b(B\n\u001b$B:k\u001b(B\n\u001b$B:l\u001b(B\n\u001b$B:m\u001b(B\n\u001b$B:n\u001b(B\n\u001b$B:o\u001b(B\n\u001b$B:p\u001b(B\n\u001b$B:q\u001b(B\n\u001b$B:r\u001b(B\n\u001b$B:s\u001b(B\n\u001b$B:t\u001b(B\n\u001b$B:u\u001b(B\n\u001b$B:v\u001b(B\n\u001b$B:w\u001b(B\n\u001b$B:x\u001b(B\n\u001b$B:y\u001b(B\n\u001b$B:z\u001b(B\n\u001b$B:{\u001b(B\n\u001b$B:|\u001b(B\n\u001b$B:}\u001b(B\n\u001b$B:~\u001b(B\n\u001b$B;!\u001b(B\n\u001b$B;\"\u001b(B\n\u001b$B;#\u001b(B\n\u001b$B;$\u001b(B\n\u001b$B;%\u001b(B\n\u001b$B;&\u001b(B\n\u001b$B;'\u001b(B\n\u001b$B;(\u001b(B\n\u001b$B;)\u001b(B\n\u001b$B;*\u001b(B\n\u001b$B;+\u001b(B\n\u001b$B;,\u001b(B\n\u001b$B;-\u001b(B\n\u001b$B;.\u001b(B\n\u001b$B;/\u001b(B\n\u001b$B;0\u001b(B\n\u001b$B;1\u001b(B\n\u001b$B;2\u001b(B\n\u001b$B;3\u001b(B\n\u001b$B;4\u001b(B\n\u001b$B;5\u001b(B\n\u001b$B;6\u001b(B\n\u001b$B;7\u001b(B\n\u001b$B;8\u001b(B\n\u001b$B;9\u001b(B\n\u001b$B;:\u001b(B\n\u001b$B;;\u001b(B\n\u001b$B;<\u001b(B\n\u001b$B;=\u001b(B\n\u001b$B;>\u001b(B\n\u001b$B;?\u001b(B\n\u001b$B;@\u001b(B\n\u001b$B;A\u001b(B\n\u001b$B;B\u001b(B\n\u001b$B;C\u001b(B\n\u001b$B;D\u001b(B\n\u001b$B;E\u001b(B\n\u001b$B;F\u001b(B\n\u001b$B;G\u001b(B\n\u001b$B;H\u001b(B\n\u001b$B;I\u001b(B\n\u001b$B;J\u001b(B\n\u001b$B;K\u001b(B\n\u001b$B;L\u001b(B\n\u001b$B;M\u001b(B\n\u001b$B;N\u001b(B\n\u001b$B;O\u001b(B\n\u001b$B;P\u001b(B\n\u001b$B;Q\u001b(B\n\u001b$B;R\u001b(B\n\u001b$B;S\u001b(B\n\u001b$B;T\u001b(B\n\u001b$B;U\u001b(B\n\u001b$B;V\u001b(B\n\u001b$B;W\u001b(B\n\u001b$B;X\u001b(B\n\u001b$B;Y\u001b(B\n\u001b$B;Z\u001b(B\n\u001b$B;[\u001b(B\n\u001b$B;\\\u001b(B\n\u001b$B;]\u001b(B\n\u001b$B;^\u001b(B\n\u001b$B;_\u001b(B\n\u001b$B;`\u001b(B\n\u001b$B;a\u001b(B\n\u001b$B;b\u001b(B\n\u001b$B;c\u001b(B\n\u001b$B;d\u001b(B\n\u001b$B;e\u001b(B\n\u001b$B;f\u001b(B\n\u001b$B;g\u001b(B\n\u001b$B;h\u001b(B\n\u001b$B;i\u001b(B\n\u001b$B;j\u001b(B\n\u001b$B;k\u001b(B\n\u001b$B;l\u001b(B\n\u001b$B;m\u001b(B\n\u001b$B;n\u001b(B\n\u001b$B;o\u001b(B\n\u001b$B;p\u001b(B\n\u001b$B;q\u001b(B\n\u001b$B;r\u001b(B\n\u001b$B;s\u001b(B\n\u001b$B;t\u001b(B\n\u001b$B;u\u001b(B\n\u001b$B;v\u001b(B\n\u001b$B;w\u001b(B\n\u001b$B;x\u001b(B\n\u001b$B;y\u001b(B\n\u001b$B;z\u001b(B\n\u001b$B;{\u001b(B\n\u001b$B;|\u001b(B\n\u001b$B;}\u001b(B\n\u001b$B;~\u001b(B\n\u001b$B<!\u001b(B\n\u001b$B<\"\u001b(B\n\u001b$B<#\u001b(B\n\u001b$B<$\u001b(B\n\u001b$B<%\u001b(B\n\u001b$B<&\u001b(B\n\u001b$B<'\u001b(B\n\u001b$B<(\u001b(B\n\u001b$B<)\u001b(B\n\u001b$B<*\u001b(B\n\u001b$B<+\u001b(B\n\u001b$B<,\u001b(B\n\u001b$B<-\u001b(B\n\u001b$B<.\u001b(B\n\u001b$B</\u001b(B\n\u001b$B<0\u001b(B\n\u001b$B<1\u001b(B\n\u001b$B<2\u001b(B\n\u001b$B<3\u001b(B\n\u001b$B<4\u001b(B\n\u001b$B<5\u001b(B\n\u001b$B<6\u001b(B\n\u001b$B<7\u001b(B\n\u001b$B<8\u001b(B\n\u001b$B<9\u001b(B\n\u001b$B<:\u001b(B\n\u001b$B<;\u001b(B\n\u001b$B<<\u001b(B\n\u001b$B<=\u001b(B\n\u001b$B<>\u001b(B\n\u001b$B<?\u001b(B\n\u001b$B<@\u001b(B\n\u001b$B<A\u001b(B\n\u001b$B<B\u001b(B\n\u001b$B<C\u001b(B\n\u001b$B<D\u001b(B\n\u001b$B<E\u001b(B\n\u001b$B<F\u001b(B\n\u001b$B<G\u001b(B\n\u001b$B<H\u001b(B\n\u001b$B<I\u001b(B\n\u001b$B<J\u001b(B\n\u001b$B<K\u001b(B\n\u001b$B<L\u001b(B\n\u001b$B<M\u001b(B\n\u001b$B<N\u001b(B\n\u001b$B<O\u001b(B\n\u001b$B<P\u001b(B\n\u001b$B<Q\u001b(B\n\u001b$B<R\u001b(B\n\u001b$B<S\u001b(B\n\u001b$B<T\u001b(B\n\u001b$B<U\u001b(B\n\u001b$B<V\u001b(B\n\u001b$B<W\u001b(B\n\u001b$B<X\u001b(B\n\u001b$B<Y\u001b(B\n\u001b$B<Z\u001b(B\n\u001b$B<[\u001b(B\n\u001b$B<\\\u001b(B\n\u001b$B<]\u001b(B\n\u001b$B<^\u001b(B\n\u001b$B<_\u001b(B\n\u001b$B<`\u001b(B\n\u001b$B<a\u001b(B\n\u001b$B<b\u001b(B\n\u001b$B<c\u001b(B\n\u001b$B<d\u001b(B\n\u001b$B<e\u001b(B\n\u001b$B<f\u001b(B\n\u001b$B<g\u001b(B\n\u001b$B<h\u001b(B\n\u001b$B<i\u001b(B\n\u001b$B<j\u001b(B\n\u001b$B<k\u001b(B\n\u001b$B<l\u001b(B\n\u001b$B<m\u001b(B\n\u001b$B<n\u001b(B\n\u001b$B<o\u001b(B\n\u001b$B<p\u001b(B\n\u001b$B<q\u001b(B\n\u001b$B<r\u001b(B\n\u001b$B<s\u001b(B\n\u001b$B<t\u001b(B\n\u001b$B<u\u001b(B\n\u001b$B<v\u001b(B\n\u001b$B<w\u001b(B\n\u001b$B<x\u001b(B\n\u001b$B<y\u001b(B\n\u001b$B<z\u001b(B\n\u001b$B<{\u001b(B\n\u001b$B<|\u001b(B\n\u001b$B<}\u001b(B\n\u001b$B<~\u001b(B\n\u001b$B=!\u001b(B\n\u001b$B=\"\u001b(B\n\u001b$B=#\u001b(B\n\u001b$B=$\u001b(B\n\u001b$B=%\u001b(B\n\u001b$B=&\u001b(B\n\u001b$B='\u001b(B\n\u001b$B=(\u001b(B\n\u001b$B=)\u001b(B\n\u001b$B=*\u001b(B\n\u001b$B=+\u001b(B\n\u001b$B=,\u001b(B\n\u001b$B=-\u001b(B\n\u001b$B=.\u001b(B\n\u001b$B=/\u001b(B\n\u001b$B=0\u001b(B\n\u001b$B=1\u001b(B\n\u001b$B=2\u001b(B\n\u001b$B=3\u001b(B\n\u001b$B=4\u001b(B\n\u001b$B=5\u001b(B\n\u001b$B=6\u001b(B\n\u001b$B=7\u001b(B\n\u001b$B=8\u001b(B\n\u001b$B=9\u001b(B\n\u001b$B=:\u001b(B\n\u001b$B=;\u001b(B\n\u001b$B=<\u001b(B\n\u001b$B==\u001b(B\n\u001b$B=>\u001b(B\n\u001b$B=?\u001b(B\n\u001b$B=@\u001b(B\n\u001b$B=A\u001b(B\n\u001b$B=B\u001b(B\n\u001b$B=C\u001b(B\n\u001b$B=D\u001b(B\n\u001b$B=E\u001b(B\n\u001b$B=F\u001b(B\n\u001b$B=G\u001b(B\n\u001b$B=H\u001b(B\n\u001b$B=I\u001b(B\n\u001b$B=J\u001b(B\n\u001b$B=K\u001b(B\n\u001b$B=L\u001b(B\n\u001b$B=M\u001b(B\n\u001b$B=N\u001b(B\n\u001b$B=O\u001b(B\n\u001b$B=P\u001b(B\n\u001b$B=Q\u001b(B\n\u001b$B=R\u001b(B\n\u001b$B=S\u001b(B\n\u001b$B=T\u001b(B\n\u001b$B=U\u001b(B\n\u001b$B=V\u001b(B\n\u001b$B=W\u001b(B\n\u001b$B=X\u001b(B\n\u001b$B=Y\u001b(B\n\u001b$B=Z\u001b(B\n\u001b$B=[\u001b(B\n\u001b$B=\\\u001b(B\n\u001b$B=]\u001b(B\n\u001b$B=^\u001b(B\n\u001b$B=_\u001b(B\n\u001b$B=`\u001b(B\n\u001b$B=a\u001b(B\n\u001b$B=b\u001b(B\n\u001b$B=c\u001b(B\n\u001b$B=d\u001b(B\n\u001b$B=e\u001b(B\n\u001b$B=f\u001b(B\n\u001b$B=g\u001b(B\n\u001b$B=h\u001b(B\n\u001b$B=i\u001b(B\n\u001b$B=j\u001b(B\n\u001b$B=k\u001b(B\n\u001b$B=l\u001b(B\n\u001b$B=m\u001b(B\n\u001b$B=n\u001b(B\n\u001b$B=o\u001b(B\n\u001b$B=p\u001b(B\n\u001b$B=q\u001b(B\n\u001b$B=r\u001b(B\n\u001b$B=s\u001b(B\n\u001b$B=t\u001b(B\n\u001b$B=u\u001b(B\n\u001b$B=v\u001b(B\n\u001b$B=w\u001b(B\n\u001b$B=x\u001b(B\n\u001b$B=y\u001b(B\n\u001b$B=z\u001b(B\n\u001b$B={\u001b(B\n\u001b$B=|\u001b(B\n\u001b$B=}\u001b(B\n\u001b$B=~\u001b(B\n\u001b$B>!\u001b(B\n\u001b$B>\"\u001b(B\n\u001b$B>#\u001b(B\n\u001b$B>$\u001b(B\n\u001b$B>%\u001b(B\n\u001b$B>&\u001b(B\n\u001b$B>'\u001b(B\n\u001b$B>(\u001b(B\n\u001b$B>)\u001b(B\n\u001b$B>*\u001b(B\n\u001b$B>+\u001b(B\n\u001b$B>,\u001b(B\n\u001b$B>-\u001b(B\n\u001b$B>.\u001b(B\n\u001b$B>/\u001b(B\n\u001b$B>0\u001b(B\n\u001b$B>1\u001b(B\n\u001b$B>2\u001b(B\n\u001b$B>3\u001b(B\n\u001b$B>4\u001b(B\n\u001b$B>5\u001b(B\n\u001b$B>6\u001b(B\n\u001b$B>7\u001b(B\n\u001b$B>8\u001b(B\n\u001b$B>9\u001b(B\n\u001b$B>:\u001b(B\n\u001b$B>;\u001b(B\n\u001b$B><\u001b(B\n\u001b$B>=\u001b(B\n\u001b$B>>\u001b(B\n\u001b$B>?\u001b(B\n\u001b$B>@\u001b(B\n\u001b$B>A\u001b(B\n\u001b$B>B\u001b(B\n\u001b$B>C\u001b(B\n\u001b$B>D\u001b(B\n\u001b$B>E\u001b(B\n\u001b$B>F\u001b(B\n\u001b$B>G\u001b(B\n\u001b$B>H\u001b(B\n\u001b$B>I\u001b(B\n\u001b$B>J\u001b(B\n\u001b$B>K\u001b(B\n\u001b$B>L\u001b(B\n\u001b$B>M\u001b(B\n\u001b$B>N\u001b(B\n\u001b$B>O\u001b(B\n\u001b$B>P\u001b(B\n\u001b$B>Q\u001b(B\n\u001b$B>R\u001b(B\n\u001b$B>S\u001b(B\n\u001b$B>T\u001b(B\n\u001b$B>U\u001b(B\n\u001b$B>V\u001b(B\n\u001b$B>W\u001b(B\n\u001b$B>X\u001b(B\n\u001b$B>Y\u001b(B\n\u001b$B>Z\u001b(B\n\u001b$B>[\u001b(B\n\u001b$B>\\\u001b(B\n\u001b$B>]\u001b(B\n\u001b$B>^\u001b(B\n\u001b$B>_\u001b(B\n\u001b$B>`\u001b(B\n\u001b$B>a\u001b(B\n\u001b$B>b\u001b(B\n\u001b$B>c\u001b(B\n\u001b$B>d\u001b(B\n\u001b$B>e\u001b(B\n\u001b$B>f\u001b(B\n\u001b$B>g\u001b(B\n\u001b$B>h\u001b(B\n\u001b$B>i\u001b(B\n\u001b$B>j\u001b(B\n\u001b$B>k\u001b(B\n\u001b$B>l\u001b(B\n\u001b$B>m\u001b(B\n\u001b$B>n\u001b(B\n\u001b$B>o\u001b(B\n\u001b$B>p\u001b(B\n\u001b$B>q\u001b(B\n\u001b$B>r\u001b(B\n\u001b$B>s\u001b(B\n\u001b$B>t\u001b(B\n\u001b$B>u\u001b(B\n\u001b$B>v\u001b(B\n\u001b$B>w\u001b(B\n\u001b$B>x\u001b(B\n\u001b$B>y\u001b(B\n\u001b$B>z\u001b(B\n\u001b$B>{\u001b(B\n\u001b$B>|\u001b(B\n\u001b$B>}\u001b(B\n\u001b$B>~\u001b(B\n\u001b$B?!\u001b(B\n\u001b$B?\"\u001b(B\n\u001b$B?#\u001b(B\n\u001b$B?$\u001b(B\n\u001b$B?%\u001b(B\n\u001b$B?&\u001b(B\n\u001b$B?'\u001b(B\n\u001b$B?(\u001b(B\n\u001b$B?)\u001b(B\n\u001b$B?*\u001b(B\n\u001b$B?+\u001b(B\n\u001b$B?,\u001b(B\n\u001b$B?-\u001b(B\n\u001b$B?.\u001b(B\n\u001b$B?/\u001b(B\n\u001b$B?0\u001b(B\n\u001b$B?1\u001b(B\n\u001b$B?2\u001b(B\n\u001b$B?3\u001b(B\n\u001b$B?4\u001b(B\n\u001b$B?5\u001b(B\n\u001b$B?6\u001b(B\n\u001b$B?7\u001b(B\n\u001b$B?8\u001b(B\n\u001b$B?9\u001b(B\n\u001b$B?:\u001b(B\n\u001b$B?;\u001b(B\n\u001b$B?<\u001b(B\n\u001b$B?=\u001b(B\n\u001b$B?>\u001b(B\n\u001b$B??\u001b(B\n\u001b$B?@\u001b(B\n\u001b$B?A\u001b(B\n\u001b$B?B\u001b(B\n\u001b$B?C\u001b(B\n\u001b$B?D\u001b(B\n\u001b$B?E\u001b(B\n\u001b$B?F\u001b(B\n\u001b$B?G\u001b(B\n\u001b$B?H\u001b(B\n\u001b$B?I\u001b(B\n\u001b$B?J\u001b(B\n\u001b$B?K\u001b(B\n\u001b$B?L\u001b(B\n\u001b$B?M\u001b(B\n\u001b$B?N\u001b(B\n\u001b$B?O\u001b(B\n\u001b$B?P\u001b(B\n\u001b$B?Q\u001b(B\n\u001b$B?R\u001b(B\n\u001b$B?S\u001b(B\n\u001b$B?T\u001b(B\n\u001b$B?U\u001b(B\n\u001b$B?V\u001b(B\n\u001b$B?W\u001b(B\n\u001b$B?X\u001b(B\n\u001b$B?Y\u001b(B\n\u001b$B?Z\u001b(B\n\u001b$B?[\u001b(B\n\u001b$B?\\\u001b(B\n\u001b$B?]\u001b(B\n\u001b$B?^\u001b(B\n\u001b$B?_\u001b(B\n\u001b$B?`\u001b(B\n\u001b$B?a\u001b(B\n\u001b$B?b\u001b(B\n\u001b$B?c\u001b(B\n\u001b$B?d\u001b(B\n\u001b$B?e\u001b(B\n\u001b$B?f\u001b(B\n\u001b$B?g\u001b(B\n\u001b$B?h\u001b(B\n\u001b$B?i\u001b(B\n\u001b$B?j\u001b(B\n\u001b$B?k\u001b(B\n\u001b$B?l\u001b(B\n\u001b$B?m\u001b(B\n\u001b$B?n\u001b(B\n\u001b$B?o\u001b(B\n\u001b$B?p\u001b(B\n\u001b$B?q\u001b(B\n\u001b$B?r\u001b(B\n\u001b$B?s\u001b(B\n\u001b$B?t\u001b(B\n\u001b$B?u\u001b(B\n\u001b$B?v\u001b(B\n\u001b$B?w\u001b(B\n\u001b$B?x\u001b(B\n\u001b$B?y\u001b(B\n\u001b$B?z\u001b(B\n\u001b$B?{\u001b(B\n\u001b$B?|\u001b(B\n\u001b$B?}\u001b(B\n\u001b$B?~\u001b(B\n\u001b$B@!\u001b(B\n\u001b$B@\"\u001b(B\n\u001b$B@#\u001b(B\n\u001b$B@$\u001b(B\n\u001b$B@%\u001b(B\n\u001b$B@&\u001b(B\n\u001b$B@'\u001b(B\n\u001b$B@(\u001b(B\n\u001b$B@)\u001b(B\n\u001b$B@*\u001b(B\n\u001b$B@+\u001b(B\n\u001b$B@,\u001b(B\n\u001b$B@-\u001b(B\n\u001b$B@.\u001b(B\n\u001b$B@/\u001b(B\n\u001b$B@0\u001b(B\n\u001b$B@1\u001b(B\n\u001b$B@2\u001b(B\n\u001b$B@3\u001b(B\n\u001b$B@4\u001b(B\n\u001b$B@5\u001b(B\n\u001b$B@6\u001b(B\n\u001b$B@7\u001b(B\n\u001b$B@8\u001b(B\n\u001b$B@9\u001b(B\n\u001b$B@:\u001b(B\n\u001b$B@;\u001b(B\n\u001b$B@<\u001b(B\n\u001b$B@=\u001b(B\n\u001b$B@>\u001b(B\n\u001b$B@?\u001b(B\n\u001b$B@@\u001b(B\n\u001b$B@A\u001b(B\n\u001b$B@B\u001b(B\n\u001b$B@C\u001b(B\n\u001b$B@D\u001b(B\n\u001b$B@E\u001b(B\n\u001b$B@F\u001b(B\n\u001b$B@G\u001b(B\n\u001b$B@H\u001b(B\n\u001b$B@I\u001b(B\n\u001b$B@J\u001b(B\n\u001b$B@K\u001b(B\n\u001b$B@L\u001b(B\n\u001b$B@M\u001b(B\n\u001b$B@N\u001b(B\n\u001b$B@O\u001b(B\n\u001b$B@P\u001b(B\n\u001b$B@Q\u001b(B\n\u001b$B@R\u001b(B\n\u001b$B@S\u001b(B\n\u001b$B@T\u001b(B\n\u001b$B@U\u001b(B\n\u001b$B@V\u001b(B\n\u001b$B@W\u001b(B\n\u001b$B@X\u001b(B\n\u001b$B@Y\u001b(B\n\u001b$B@Z\u001b(B\n\u001b$B@[\u001b(B\n\u001b$B@\\\u001b(B\n\u001b$B@]\u001b(B\n\u001b$B@^\u001b(B\n\u001b$B@_\u001b(B\n\u001b$B@`\u001b(B\n\u001b$B@a\u001b(B\n\u001b$B@b\u001b(B\n\u001b$B@c\u001b(B\n\u001b$B@d\u001b(B\n\u001b$B@e\u001b(B\n\u001b$B@f\u001b(B\n\u001b$B@g\u001b(B\n\u001b$B@h\u001b(B\n\u001b$B@i\u001b(B\n\u001b$B@j\u001b(B\n\u001b$B@k\u001b(B\n\u001b$B@l\u001b(B\n\u001b$B@m\u001b(B\n\u001b$B@n\u001b(B\n\u001b$B@o\u001b(B\n\u001b$B@p\u001b(B\n\u001b$B@q\u001b(B\n\u001b$B@r\u001b(B\n\u001b$B@s\u001b(B\n\u001b$B@t\u001b(B\n\u001b$B@u\u001b(B\n\u001b$B@v\u001b(B\n\u001b$B@w\u001b(B\n\u001b$B@x\u001b(B\n\u001b$B@y\u001b(B\n\u001b$B@z\u001b(B\n\u001b$B@{\u001b(B\n\u001b$B@|\u001b(B\n\u001b$B@}\u001b(B\n\u001b$B@~\u001b(B\n\u001b$BA!\u001b(B\n\u001b$BA\"\u001b(B\n\u001b$BA#\u001b(B\n\u001b$BA$\u001b(B\n\u001b$BA%\u001b(B\n\u001b$BA&\u001b(B\n\u001b$BA'\u001b(B\n\u001b$BA(\u001b(B\n\u001b$BA)\u001b(B\n\u001b$BA*\u001b(B\n\u001b$BA+\u001b(B\n\u001b$BA,\u001b(B\n\u001b$BA-\u001b(B\n\u001b$BA.\u001b(B\n\u001b$BA/\u001b(B\n\u001b$BA0\u001b(B\n\u001b$BA1\u001b(B\n\u001b$BA2\u001b(B\n\u001b$BA3\u001b(B\n\u001b$BA4\u001b(B\n\u001b$BA5\u001b(B\n\u001b$BA6\u001b(B\n\u001b$BA7\u001b(B\n\u001b$BA8\u001b(B\n\u001b$BA9\u001b(B\n\u001b$BA:\u001b(B\n\u001b$BA;\u001b(B\n\u001b$BA<\u001b(B\n\u001b$BA=\u001b(B\n\u001b$BA>\u001b(B\n\u001b$BA?\u001b(B\n\u001b$BA@\u001b(B\n\u001b$BAA\u001b(B\n\u001b$BAB\u001b(B\n\u001b$BAC\u001b(B\n\u001b$BAD\u001b(B\n\u001b$BAE\u001b(B\n\u001b$BAF\u001b(B\n\u001b$BAG\u001b(B\n\u001b$BAH\u001b(B\n\u001b$BAI\u001b(B\n\u001b$BAJ\u001b(B\n\u001b$BAK\u001b(B\n\u001b$BAL\u001b(B\n\u001b$BAM\u001b(B\n\u001b$BAN\u001b(B\n\u001b$BAO\u001b(B\n\u001b$BAP\u001b(B\n\u001b$BAQ\u001b(B\n\u001b$BAR\u001b(B\n\u001b$BAS\u001b(B\n\u001b$BAT\u001b(B\n\u001b$BAU\u001b(B\n\u001b$BAV\u001b(B\n\u001b$BAW\u001b(B\n\u001b$BAX\u001b(B\n\u001b$BAY\u001b(B\n\u001b$BAZ\u001b(B\n\u001b$BA[\u001b(B\n\u001b$BA\\\u001b(B\n\u001b$BA]\u001b(B\n\u001b$BA^\u001b(B\n\u001b$BA_\u001b(B\n\u001b$BA`\u001b(B\n\u001b$BAa\u001b(B\n\u001b$BAb\u001b(B\n\u001b$BAc\u001b(B\n\u001b$BAd\u001b(B\n\u001b$BAe\u001b(B\n\u001b$BAf\u001b(B\n\u001b$BAg\u001b(B\n\u001b$BAh\u001b(B\n\u001b$BAi\u001b(B\n\u001b$BAj\u001b(B\n\u001b$BAk\u001b(B\n\u001b$BAl\u001b(B\n\u001b$BAm\u001b(B\n\u001b$BAn\u001b(B\n\u001b$BAo\u001b(B\n\u001b$BAp\u001b(B\n\u001b$BAq\u001b(B\n\u001b$BAr\u001b(B\n\u001b$BAs\u001b(B\n\u001b$BAt\u001b(B\n\u001b$BAu\u001b(B\n\u001b$BAv\u001b(B\n\u001b$BAw\u001b(B\n\u001b$BAx\u001b(B\n\u001b$BAy\u001b(B\n\u001b$BAz\u001b(B\n\u001b$BA{\u001b(B\n\u001b$BA|\u001b(B\n\u001b$BA}\u001b(B\n\u001b$BA~\u001b(B\n\u001b$BB!\u001b(B\n\u001b$BB\"\u001b(B\n\u001b$BB#\u001b(B\n\u001b$BB$\u001b(B\n\u001b$BB%\u001b(B\n\u001b$BB&\u001b(B\n\u001b$BB'\u001b(B\n\u001b$BB(\u001b(B\n\u001b$BB)\u001b(B\n\u001b$BB*\u001b(B\n\u001b$BB+\u001b(B\n\u001b$BB,\u001b(B\n\u001b$BB-\u001b(B\n\u001b$BB.\u001b(B\n\u001b$BB/\u001b(B\n\u001b$BB0\u001b(B\n\u001b$BB1\u001b(B\n\u001b$BB2\u001b(B\n\u001b$BB3\u001b(B\n\u001b$BB4\u001b(B\n\u001b$BB5\u001b(B\n\u001b$BB6\u001b(B\n\u001b$BB7\u001b(B\n\u001b$BB8\u001b(B\n\u001b$BB9\u001b(B\n\u001b$BB:\u001b(B\n\u001b$BB;\u001b(B\n\u001b$BB<\u001b(B\n\u001b$BB=\u001b(B\n\u001b$BB>\u001b(B\n\u001b$BB?\u001b(B\n\u001b$BB@\u001b(B\n\u001b$BBA\u001b(B\n\u001b$BBB\u001b(B\n\u001b$BBC\u001b(B\n\u001b$BBD\u001b(B\n\u001b$BBE\u001b(B\n\u001b$BBF\u001b(B\n\u001b$BBG\u001b(B\n\u001b$BBH\u001b(B\n\u001b$BBI\u001b(B\n\u001b$BBJ\u001b(B\n\u001b$BBK\u001b(B\n\u001b$BBL\u001b(B\n\u001b$BBM\u001b(B\n\u001b$BBN\u001b(B\n\u001b$BBO\u001b(B\n\u001b$BBP\u001b(B\n\u001b$BBQ\u001b(B\n\u001b$BBR\u001b(B\n\u001b$BBS\u001b(B\n\u001b$BBT\u001b(B\n\u001b$BBU\u001b(B\n\u001b$BBV\u001b(B\n\u001b$BBW\u001b(B\n\u001b$BBX\u001b(B\n\u001b$BBY\u001b(B\n\u001b$BBZ\u001b(B\n\u001b$BB[\u001b(B\n\u001b$BB\\\u001b(B\n\u001b$BB]\u001b(B\n\u001b$BB^\u001b(B\n\u001b$BB_\u001b(B\n\u001b$BB`\u001b(B\n\u001b$BBa\u001b(B\n\u001b$BBb\u001b(B\n\u001b$BBc\u001b(B\n\u001b$BBd\u001b(B\n\u001b$BBe\u001b(B\n\u001b$BBf\u001b(B\n\u001b$BBg\u001b(B\n\u001b$BBh\u001b(B\n\u001b$BBi\u001b(B\n\u001b$BBj\u001b(B\n\u001b$BBk\u001b(B\n\u001b$BBl\u001b(B\n\u001b$BBm\u001b(B\n\u001b$BBn\u001b(B\n\u001b$BBo\u001b(B\n\u001b$BBp\u001b(B\n\u001b$BBq\u001b(B\n\u001b$BBr\u001b(B\n\u001b$BBs\u001b(B\n\u001b$BBt\u001b(B\n\u001b$BBu\u001b(B\n\u001b$BBv\u001b(B\n\u001b$BBw\u001b(B\n\u001b$BBx\u001b(B\n\u001b$BBy\u001b(B\n\u001b$BBz\u001b(B\n\u001b$BB{\u001b(B\n\u001b$BB|\u001b(B\n\u001b$BB}\u001b(B\n\u001b$BB~\u001b(B\n\u001b$BC!\u001b(B\n\u001b$BC\"\u001b(B\n\u001b$BC#\u001b(B\n\u001b$BC$\u001b(B\n\u001b$BC%\u001b(B\n\u001b$BC&\u001b(B\n\u001b$BC'\u001b(B\n\u001b$BC(\u001b(B\n\u001b$BC)\u001b(B\n\u001b$BC*\u001b(B\n\u001b$BC+\u001b(B\n\u001b$BC,\u001b(B\n\u001b$BC-\u001b(B\n\u001b$BC.\u001b(B\n\u001b$BC/\u001b(B\n\u001b$BC0\u001b(B\n\u001b$BC1\u001b(B\n\u001b$BC2\u001b(B\n\u001b$BC3\u001b(B\n\u001b$BC4\u001b(B\n\u001b$BC5\u001b(B\n\u001b$BC6\u001b(B\n\u001b$BC7\u001b(B\n\u001b$BC8\u001b(B\n\u001b$BC9\u001b(B\n\u001b$BC:\u001b(B\n\u001b$BC;\u001b(B\n\u001b$BC<\u001b(B\n\u001b$BC=\u001b(B\n\u001b$BC>\u001b(B\n\u001b$BC?\u001b(B\n\u001b$BC@\u001b(B\n\u001b$BCA\u001b(B\n\u001b$BCB\u001b(B\n\u001b$BCC\u001b(B\n\u001b$BCD\u001b(B\n\u001b$BCE\u001b(B\n\u001b$BCF\u001b(B\n\u001b$BCG\u001b(B\n\u001b$BCH\u001b(B\n\u001b$BCI\u001b(B\n\u001b$BCJ\u001b(B\n\u001b$BCK\u001b(B\n\u001b$BCL\u001b(B\n\u001b$BCM\u001b(B\n\u001b$BCN\u001b(B\n\u001b$BCO\u001b(B\n\u001b$BCP\u001b(B\n\u001b$BCQ\u001b(B\n\u001b$BCR\u001b(B\n\u001b$BCS\u001b(B\n\u001b$BCT\u001b(B\n\u001b$BCU\u001b(B\n\u001b$BCV\u001b(B\n\u001b$BCW\u001b(B\n\u001b$BCX\u001b(B\n\u001b$BCY\u001b(B\n\u001b$BCZ\u001b(B\n\u001b$BC[\u001b(B\n\u001b$BC\\\u001b(B\n\u001b$BC]\u001b(B\n\u001b$BC^\u001b(B\n\u001b$BC_\u001b(B\n\u001b$BC`\u001b(B\n\u001b$BCa\u001b(B\n\u001b$BCb\u001b(B\n\u001b$BCc\u001b(B\n\u001b$BCd\u001b(B\n\u001b$BCe\u001b(B\n\u001b$BCf\u001b(B\n\u001b$BCg\u001b(B\n\u001b$BCh\u001b(B\n\u001b$BCi\u001b(B\n\u001b$BCj\u001b(B\n\u001b$BCk\u001b(B\n\u001b$BCl\u001b(B\n\u001b$BCm\u001b(B\n\u001b$BCn\u001b(B\n\u001b$BCo\u001b(B\n\u001b$BCp\u001b(B\n\u001b$BCq\u001b(B\n\u001b$BCr\u001b(B\n\u001b$BCs\u001b(B\n\u001b$BCt\u001b(B\n\u001b$BCu\u001b(B\n\u001b$BCv\u001b(B\n\u001b$BCw\u001b(B\n\u001b$BCx\u001b(B\n\u001b$BCy\u001b(B\n\u001b$BCz\u001b(B\n\u001b$BC{\u001b(B\n\u001b$BC|\u001b(B\n\u001b$BC}\u001b(B\n\u001b$BC~\u001b(B\n\u001b$BD!\u001b(B\n\u001b$BD\"\u001b(B\n\u001b$BD#\u001b(B\n\u001b$BD$\u001b(B\n\u001b$BD%\u001b(B\n\u001b$BD&\u001b(B\n\u001b$BD'\u001b(B\n\u001b$BD(\u001b(B\n\u001b$BD)\u001b(B\n\u001b$BD*\u001b(B\n\u001b$BD+\u001b(B\n\u001b$BD,\u001b(B\n\u001b$BD-\u001b(B\n\u001b$BD.\u001b(B\n\u001b$BD/\u001b(B\n\u001b$BD0\u001b(B\n\u001b$BD1\u001b(B\n\u001b$BD2\u001b(B\n\u001b$BD3\u001b(B\n\u001b$BD4\u001b(B\n\u001b$BD5\u001b(B\n\u001b$BD6\u001b(B\n\u001b$BD7\u001b(B\n\u001b$BD8\u001b(B\n\u001b$BD9\u001b(B\n\u001b$BD:\u001b(B\n\u001b$BD;\u001b(B\n\u001b$BD<\u001b(B\n\u001b$BD=\u001b(B\n\u001b$BD>\u001b(B\n\u001b$BD?\u001b(B\n\u001b$BD@\u001b(B\n\u001b$BDA\u001b(B\n\u001b$BDB\u001b(B\n\u001b$BDC\u001b(B\n\u001b$BDD\u001b(B\n\u001b$BDE\u001b(B\n\u001b$BDF\u001b(B\n\u001b$BDG\u001b(B\n\u001b$BDH\u001b(B\n\u001b$BDI\u001b(B\n\u001b$BDJ\u001b(B\n\u001b$BDK\u001b(B\n\u001b$BDL\u001b(B\n\u001b$BDM\u001b(B\n\u001b$BDN\u001b(B\n\u001b$BDO\u001b(B\n\u001b$BDP\u001b(B\n\u001b$BDQ\u001b(B\n\u001b$BDR\u001b(B\n\u001b$BDS\u001b(B\n\u001b$BDT\u001b(B\n\u001b$BDU\u001b(B\n\u001b$BDV\u001b(B\n\u001b$BDW\u001b(B\n\u001b$BDX\u001b(B\n\u001b$BDY\u001b(B\n\u001b$BDZ\u001b(B\n\u001b$BD[\u001b(B\n\u001b$BD\\\u001b(B\n\u001b$BD]\u001b(B\n\u001b$BD^\u001b(B\n\u001b$BD_\u001b(B\n\u001b$BD`\u001b(B\n\u001b$BDa\u001b(B\n\u001b$BDb\u001b(B\n\u001b$BDc\u001b(B\n\u001b$BDd\u001b(B\n\u001b$BDe\u001b(B\n\u001b$BDf\u001b(B\n\u001b$BDg\u001b(B\n\u001b$BDh\u001b(B\n\u001b$BDi\u001b(B\n\u001b$BDj\u001b(B\n\u001b$BDk\u001b(B\n\u001b$BDl\u001b(B\n\u001b$BDm\u001b(B\n\u001b$BDn\u001b(B\n\u001b$BDo\u001b(B\n\u001b$BDp\u001b(B\n\u001b$BDq\u001b(B\n\u001b$BDr\u001b(B\n\u001b$BDs\u001b(B\n\u001b$BDt\u001b(B\n\u001b$BDu\u001b(B\n\u001b$BDv\u001b(B\n\u001b$BDw\u001b(B\n\u001b$BDx\u001b(B\n\u001b$BDy\u001b(B\n\u001b$BDz\u001b(B\n\u001b$BD{\u001b(B\n\u001b$BD|\u001b(B\n\u001b$BD}\u001b(B\n\u001b$BD~\u001b(B\n\u001b$BE!\u001b(B\n\u001b$BE\"\u001b(B\n\u001b$BE#\u001b(B\n\u001b$BE$\u001b(B\n\u001b$BE%\u001b(B\n\u001b$BE&\u001b(B\n\u001b$BE'\u001b(B\n\u001b$BE(\u001b(B\n\u001b$BE)\u001b(B\n\u001b$BE*\u001b(B\n\u001b$BE+\u001b(B\n\u001b$BE,\u001b(B\n\u001b$BE-\u001b(B\n\u001b$BE.\u001b(B\n\u001b$BE/\u001b(B\n\u001b$BE0\u001b(B\n\u001b$BE1\u001b(B\n\u001b$BE2\u001b(B\n\u001b$BE3\u001b(B\n\u001b$BE4\u001b(B\n\u001b$BE5\u001b(B\n\u001b$BE6\u001b(B\n\u001b$BE7\u001b(B\n\u001b$BE8\u001b(B\n\u001b$BE9\u001b(B\n\u001b$BE:\u001b(B\n\u001b$BE;\u001b(B\n\u001b$BE<\u001b(B\n\u001b$BE=\u001b(B\n\u001b$BE>\u001b(B\n\u001b$BE?\u001b(B\n\u001b$BE@\u001b(B\n\u001b$BEA\u001b(B\n\u001b$BEB\u001b(B\n\u001b$BEC\u001b(B\n\u001b$BED\u001b(B\n\u001b$BEE\u001b(B\n\u001b$BEF\u001b(B\n\u001b$BEG\u001b(B\n\u001b$BEH\u001b(B\n\u001b$BEI\u001b(B\n\u001b$BEJ\u001b(B\n\u001b$BEK\u001b(B\n\u001b$BEL\u001b(B\n\u001b$BEM\u001b(B\n\u001b$BEN\u001b(B\n\u001b$BEO\u001b(B\n\u001b$BEP\u001b(B\n\u001b$BEQ\u001b(B\n\u001b$BER\u001b(B\n\u001b$BES\u001b(B\n\u001b$BET\u001b(B\n\u001b$BEU\u001b(B\n\u001b$BEV\u001b(B\n\u001b$BEW\u001b(B\n\u001b$BEX\u001b(B\n\u001b$BEY\u001b(B\n\u001b$BEZ\u001b(B\n\u001b$BE[\u001b(B\n\u001b$BE\\\u001b(B\n\u001b$BE]\u001b(B\n\u001b$BE^\u001b(B\n\u001b$BE_\u001b(B\n\u001b$BE`\u001b(B\n\u001b$BEa\u001b(B\n\u001b$BEb\u001b(B\n\u001b$BEc\u001b(B\n\u001b$BEd\u001b(B\n\u001b$BEe\u001b(B\n\u001b$BEf\u001b(B\n\u001b$BEg\u001b(B\n\u001b$BEh\u001b(B\n\u001b$BEi\u001b(B\n\u001b$BEj\u001b(B\n\u001b$BEk\u001b(B\n\u001b$BEl\u001b(B\n\u001b$BEm\u001b(B\n\u001b$BEn\u001b(B\n\u001b$BEo\u001b(B\n\u001b$BEp\u001b(B\n\u001b$BEq\u001b(B\n\u001b$BEr\u001b(B\n\u001b$BEs\u001b(B\n\u001b$BEt\u001b(B\n\u001b$BEu\u001b(B\n\u001b$BEv\u001b(B\n\u001b$BEw\u001b(B\n\u001b$BEx\u001b(B\n\u001b$BEy\u001b(B\n\u001b$BEz\u001b(B\n\u001b$BE{\u001b(B\n\u001b$BE|\u001b(B\n\u001b$BE}\u001b(B\n\u001b$BE~\u001b(B\n\u001b$BF!\u001b(B\n\u001b$BF\"\u001b(B\n\u001b$BF#\u001b(B\n\u001b$BF$\u001b(B\n\u001b$BF%\u001b(B\n\u001b$BF&\u001b(B\n\u001b$BF'\u001b(B\n\u001b$BF(\u001b(B\n\u001b$BF)\u001b(B\n\u001b$BF*\u001b(B\n\u001b$BF+\u001b(B\n\u001b$BF,\u001b(B\n\u001b$BF-\u001b(B\n\u001b$BF.\u001b(B\n\u001b$BF/\u001b(B\n\u001b$BF0\u001b(B\n\u001b$BF1\u001b(B\n\u001b$BF2\u001b(B\n\u001b$BF3\u001b(B\n\u001b$BF4\u001b(B\n\u001b$BF5\u001b(B\n\u001b$BF6\u001b(B\n\u001b$BF7\u001b(B\n\u001b$BF8\u001b(B\n\u001b$BF9\u001b(B\n\u001b$BF:\u001b(B\n\u001b$BF;\u001b(B\n\u001b$BF<\u001b(B\n\u001b$BF=\u001b(B\n\u001b$BF>\u001b(B\n\u001b$BF?\u001b(B\n\u001b$BF@\u001b(B\n\u001b$BFA\u001b(B\n\u001b$BFB\u001b(B\n\u001b$BFC\u001b(B\n\u001b$BFD\u001b(B\n\u001b$BFE\u001b(B\n\u001b$BFF\u001b(B\n\u001b$BFG\u001b(B\n\u001b$BFH\u001b(B\n\u001b$BFI\u001b(B\n\u001b$BFJ\u001b(B\n\u001b$BFK\u001b(B\n\u001b$BFL\u001b(B\n\u001b$BFM\u001b(B\n\u001b$BFN\u001b(B\n\u001b$BFO\u001b(B\n\u001b$BFP\u001b(B\n\u001b$BFQ\u001b(B\n\u001b$BFR\u001b(B\n\u001b$BFS\u001b(B\n\u001b$BFT\u001b(B\n\u001b$BFU\u001b(B\n\u001b$BFV\u001b(B\n\u001b$BFW\u001b(B\n\u001b$BFX\u001b(B\n\u001b$BFY\u001b(B\n\u001b$BFZ\u001b(B\n\u001b$BF[\u001b(B\n\u001b$BF\\\u001b(B\n\u001b$BF]\u001b(B\n\u001b$BF^\u001b(B\n\u001b$BF_\u001b(B\n\u001b$BF`\u001b(B\n\u001b$BFa\u001b(B\n\u001b$BFb\u001b(B\n\u001b$BFc\u001b(B\n\u001b$BFd\u001b(B\n\u001b$BFe\u001b(B\n\u001b$BFf\u001b(B\n\u001b$BFg\u001b(B\n\u001b$BFh\u001b(B\n\u001b$BFi\u001b(B\n\u001b$BFj\u001b(B\n\u001b$BFk\u001b(B\n\u001b$BFl\u001b(B\n\u001b$BFm\u001b(B\n\u001b$BFn\u001b(B\n\u001b$BFo\u001b(B\n\u001b$BFp\u001b(B\n\u001b$BFq\u001b(B\n\u001b$BFr\u001b(B\n\u001b$BFs\u001b(B\n\u001b$BFt\u001b(B\n\u001b$BFu\u001b(B\n\u001b$BFv\u001b(B\n\u001b$BFw\u001b(B\n\u001b$BFx\u001b(B\n\u001b$BFy\u001b(B\n\u001b$BFz\u001b(B\n\u001b$BF{\u001b(B\n\u001b$BF|\u001b(B\n\u001b$BF}\u001b(B\n\u001b$BF~\u001b(B\n\u001b$BG!\u001b(B\n\u001b$BG\"\u001b(B\n\u001b$BG#\u001b(B\n\u001b$BG$\u001b(B\n\u001b$BG%\u001b(B\n\u001b$BG&\u001b(B\n\u001b$BG'\u001b(B\n\u001b$BG(\u001b(B\n\u001b$BG)\u001b(B\n\u001b$BG*\u001b(B\n\u001b$BG+\u001b(B\n\u001b$BG,\u001b(B\n\u001b$BG-\u001b(B\n\u001b$BG.\u001b(B\n\u001b$BG/\u001b(B\n\u001b$BG0\u001b(B\n\u001b$BG1\u001b(B\n\u001b$BG2\u001b(B\n\u001b$BG3\u001b(B\n\u001b$BG4\u001b(B\n\u001b$BG5\u001b(B\n\u001b$BG6\u001b(B\n\u001b$BG7\u001b(B\n\u001b$BG8\u001b(B\n\u001b$BG9\u001b(B\n\u001b$BG:\u001b(B\n\u001b$BG;\u001b(B\n\u001b$BG<\u001b(B\n\u001b$BG=\u001b(B\n\u001b$BG>\u001b(B\n\u001b$BG?\u001b(B\n\u001b$BG@\u001b(B\n\u001b$BGA\u001b(B\n\u001b$BGB\u001b(B\n\u001b$BGC\u001b(B\n\u001b$BGD\u001b(B\n\u001b$BGE\u001b(B\n\u001b$BGF\u001b(B\n\u001b$BGG\u001b(B\n\u001b$BGH\u001b(B\n\u001b$BGI\u001b(B\n\u001b$BGJ\u001b(B\n\u001b$BGK\u001b(B\n\u001b$BGL\u001b(B\n\u001b$BGM\u001b(B\n\u001b$BGN\u001b(B\n\u001b$BGO\u001b(B\n\u001b$BGP\u001b(B\n\u001b$BGQ\u001b(B\n\u001b$BGR\u001b(B\n\u001b$BGS\u001b(B\n\u001b$BGT\u001b(B\n\u001b$BGU\u001b(B\n\u001b$BGV\u001b(B\n\u001b$BGW\u001b(B\n\u001b$BGX\u001b(B\n\u001b$BGY\u001b(B\n\u001b$BGZ\u001b(B\n\u001b$BG[\u001b(B\n\u001b$BG\\\u001b(B\n\u001b$BG]\u001b(B\n\u001b$BG^\u001b(B\n\u001b$BG_\u001b(B\n\u001b$BG`\u001b(B\n\u001b$BGa\u001b(B\n\u001b$BGb\u001b(B\n\u001b$BGc\u001b(B\n\u001b$BGd\u001b(B\n\u001b$BGe\u001b(B\n\u001b$BGf\u001b(B\n\u001b$BGg\u001b(B\n\u001b$BGh\u001b(B\n\u001b$BGi\u001b(B\n\u001b$BGj\u001b(B\n\u001b$BGk\u001b(B\n\u001b$BGl\u001b(B\n\u001b$BGm\u001b(B\n\u001b$BGn\u001b(B\n\u001b$BGo\u001b(B\n\u001b$BGp\u001b(B\n\u001b$BGq\u001b(B\n\u001b$BGr\u001b(B\n\u001b$BGs\u001b(B\n\u001b$BGt\u001b(B\n\u001b$BGu\u001b(B\n\u001b$BGv\u001b(B\n\u001b$BGw\u001b(B\n\u001b$BGx\u001b(B\n\u001b$BGy\u001b(B\n\u001b$BGz\u001b(B\n\u001b$BG{\u001b(B\n\u001b$BG|\u001b(B\n\u001b$BG}\u001b(B\n\u001b$BG~\u001b(B\n\u001b$BH!\u001b(B\n\u001b$BH\"\u001b(B\n\u001b$BH#\u001b(B\n\u001b$BH$\u001b(B\n\u001b$BH%\u001b(B\n\u001b$BH&\u001b(B\n\u001b$BH'\u001b(B\n\u001b$BH(\u001b(B\n\u001b$BH)\u001b(B\n\u001b$BH*\u001b(B\n\u001b$BH+\u001b(B\n\u001b$BH,\u001b(B\n\u001b$BH-\u001b(B\n\u001b$BH.\u001b(B\n\u001b$BH/\u001b(B\n\u001b$BH0\u001b(B\n\u001b$BH1\u001b(B\n\u001b$BH2\u001b(B\n\u001b$BH3\u001b(B\n\u001b$BH4\u001b(B\n\u001b$BH5\u001b(B\n\u001b$BH6\u001b(B\n\u001b$BH7\u001b(B\n\u001b$BH8\u001b(B\n\u001b$BH9\u001b(B\n\u001b$BH:\u001b(B\n\u001b$BH;\u001b(B\n\u001b$BH<\u001b(B\n\u001b$BH=\u001b(B\n\u001b$BH>\u001b(B\n\u001b$BH?\u001b(B\n\u001b$BH@\u001b(B\n\u001b$BHA\u001b(B\n\u001b$BHB\u001b(B\n\u001b$BHC\u001b(B\n\u001b$BHD\u001b(B\n\u001b$BHE\u001b(B\n\u001b$BHF\u001b(B\n\u001b$BHG\u001b(B\n\u001b$BHH\u001b(B\n\u001b$BHI\u001b(B\n\u001b$BHJ\u001b(B\n\u001b$BHK\u001b(B\n\u001b$BHL\u001b(B\n\u001b$BHM\u001b(B\n\u001b$BHN\u001b(B\n\u001b$BHO\u001b(B\n\u001b$BHP\u001b(B\n\u001b$BHQ\u001b(B\n\u001b$BHR\u001b(B\n\u001b$BHS\u001b(B\n\u001b$BHT\u001b(B\n\u001b$BHU\u001b(B\n\u001b$BHV\u001b(B\n\u001b$BHW\u001b(B\n\u001b$BHX\u001b(B\n\u001b$BHY\u001b(B\n\u001b$BHZ\u001b(B\n\u001b$BH[\u001b(B\n\u001b$BH\\\u001b(B\n\u001b$BH]\u001b(B\n\u001b$BH^\u001b(B\n\u001b$BH_\u001b(B\n\u001b$BH`\u001b(B\n\u001b$BHa\u001b(B\n\u001b$BHb\u001b(B\n\u001b$BHc\u001b(B\n\u001b$BHd\u001b(B\n\u001b$BHe\u001b(B\n\u001b$BHf\u001b(B\n\u001b$BHg\u001b(B\n\u001b$BHh\u001b(B\n\u001b$BHi\u001b(B\n\u001b$BHj\u001b(B\n\u001b$BHk\u001b(B\n\u001b$BHl\u001b(B\n\u001b$BHm\u001b(B\n\u001b$BHn\u001b(B\n\u001b$BHo\u001b(B\n\u001b$BHp\u001b(B\n\u001b$BHq\u001b(B\n\u001b$BHr\u001b(B\n\u001b$BHs\u001b(B\n\u001b$BHt\u001b(B\n\u001b$BHu\u001b(B\n\u001b$BHv\u001b(B\n\u001b$BHw\u001b(B\n\u001b$BHx\u001b(B\n\u001b$BHy\u001b(B\n\u001b$BHz\u001b(B\n\u001b$BH{\u001b(B\n\u001b$BH|\u001b(B\n\u001b$BH}\u001b(B\n\u001b$BH~\u001b(B\n\u001b$BI!\u001b(B\n\u001b$BI\"\u001b(B\n\u001b$BI#\u001b(B\n\u001b$BI$\u001b(B\n\u001b$BI%\u001b(B\n\u001b$BI&\u001b(B\n\u001b$BI'\u001b(B\n\u001b$BI(\u001b(B\n\u001b$BI)\u001b(B\n\u001b$BI*\u001b(B\n\u001b$BI+\u001b(B\n\u001b$BI,\u001b(B\n\u001b$BI-\u001b(B\n\u001b$BI.\u001b(B\n\u001b$BI/\u001b(B\n\u001b$BI0\u001b(B\n\u001b$BI1\u001b(B\n\u001b$BI2\u001b(B\n\u001b$BI3\u001b(B\n\u001b$BI4\u001b(B\n\u001b$BI5\u001b(B\n\u001b$BI6\u001b(B\n\u001b$BI7\u001b(B\n\u001b$BI8\u001b(B\n\u001b$BI9\u001b(B\n\u001b$BI:\u001b(B\n\u001b$BI;\u001b(B\n\u001b$BI<\u001b(B\n\u001b$BI=\u001b(B\n\u001b$BI>\u001b(B\n\u001b$BI?\u001b(B\n\u001b$BI@\u001b(B\n\u001b$BIA\u001b(B\n\u001b$BIB\u001b(B\n\u001b$BIC\u001b(B\n\u001b$BID\u001b(B\n\u001b$BIE\u001b(B\n\u001b$BIF\u001b(B\n\u001b$BIG\u001b(B\n\u001b$BIH\u001b(B\n\u001b$BII\u001b(B\n\u001b$BIJ\u001b(B\n\u001b$BIK\u001b(B\n\u001b$BIL\u001b(B\n\u001b$BIM\u001b(B\n\u001b$BIN\u001b(B\n\u001b$BIO\u001b(B\n\u001b$BIP\u001b(B\n\u001b$BIQ\u001b(B\n\u001b$BIR\u001b(B\n\u001b$BIS\u001b(B\n\u001b$BIT\u001b(B\n\u001b$BIU\u001b(B\n\u001b$BIV\u001b(B\n\u001b$BIW\u001b(B\n\u001b$BIX\u001b(B\n\u001b$BIY\u001b(B\n\u001b$BIZ\u001b(B\n\u001b$BI[\u001b(B\n\u001b$BI\\\u001b(B\n\u001b$BI]\u001b(B\n\u001b$BI^\u001b(B\n\u001b$BI_\u001b(B\n\u001b$BI`\u001b(B\n\u001b$BIa\u001b(B\n\u001b$BIb\u001b(B\n\u001b$BIc\u001b(B\n\u001b$BId\u001b(B\n\u001b$BIe\u001b(B\n\u001b$BIf\u001b(B\n\u001b$BIg\u001b(B\n\u001b$BIh\u001b(B\n\u001b$BIi\u001b(B\n\u001b$BIj\u001b(B\n\u001b$BIk\u001b(B\n\u001b$BIl\u001b(B\n\u001b$BIm\u001b(B\n\u001b$BIn\u001b(B\n\u001b$BIo\u001b(B\n\u001b$BIp\u001b(B\n\u001b$BIq\u001b(B\n\u001b$BIr\u001b(B\n\u001b$BIs\u001b(B\n\u001b$BIt\u001b(B\n\u001b$BIu\u001b(B\n\u001b$BIv\u001b(B\n\u001b$BIw\u001b(B\n\u001b$BIx\u001b(B\n\u001b$BIy\u001b(B\n\u001b$BIz\u001b(B\n\u001b$BI{\u001b(B\n\u001b$BI|\u001b(B\n\u001b$BI}\u001b(B\n\u001b$BI~\u001b(B\n\u001b$BJ!\u001b(B\n\u001b$BJ\"\u001b(B\n\u001b$BJ#\u001b(B\n\u001b$BJ$\u001b(B\n\u001b$BJ%\u001b(B\n\u001b$BJ&\u001b(B\n\u001b$BJ'\u001b(B\n\u001b$BJ(\u001b(B\n\u001b$BJ)\u001b(B\n\u001b$BJ*\u001b(B\n\u001b$BJ+\u001b(B\n\u001b$BJ,\u001b(B\n\u001b$BJ-\u001b(B\n\u001b$BJ.\u001b(B\n\u001b$BJ/\u001b(B\n\u001b$BJ0\u001b(B\n\u001b$BJ1\u001b(B\n\u001b$BJ2\u001b(B\n\u001b$BJ3\u001b(B\n\u001b$BJ4\u001b(B\n\u001b$BJ5\u001b(B\n\u001b$BJ6\u001b(B\n\u001b$BJ7\u001b(B\n\u001b$BJ8\u001b(B\n\u001b$BJ9\u001b(B\n\u001b$BJ:\u001b(B\n\u001b$BJ;\u001b(B\n\u001b$BJ<\u001b(B\n\u001b$BJ=\u001b(B\n\u001b$BJ>\u001b(B\n\u001b$BJ?\u001b(B\n\u001b$BJ@\u001b(B\n\u001b$BJA\u001b(B\n\u001b$BJB\u001b(B\n\u001b$BJC\u001b(B\n\u001b$BJD\u001b(B\n\u001b$BJE\u001b(B\n\u001b$BJF\u001b(B\n\u001b$BJG\u001b(B\n\u001b$BJH\u001b(B\n\u001b$BJI\u001b(B\n\u001b$BJJ\u001b(B\n\u001b$BJK\u001b(B\n\u001b$BJL\u001b(B\n\u001b$BJM\u001b(B\n\u001b$BJN\u001b(B\n\u001b$BJO\u001b(B\n\u001b$BJP\u001b(B\n\u001b$BJQ\u001b(B\n\u001b$BJR\u001b(B\n\u001b$BJS\u001b(B\n\u001b$BJT\u001b(B\n\u001b$BJU\u001b(B\n\u001b$BJV\u001b(B\n\u001b$BJW\u001b(B\n\u001b$BJX\u001b(B\n\u001b$BJY\u001b(B\n\u001b$BJZ\u001b(B\n\u001b$BJ[\u001b(B\n\u001b$BJ\\\u001b(B\n\u001b$BJ]\u001b(B\n\u001b$BJ^\u001b(B\n\u001b$BJ_\u001b(B\n\u001b$BJ`\u001b(B\n\u001b$BJa\u001b(B\n\u001b$BJb\u001b(B\n\u001b$BJc\u001b(B\n\u001b$BJd\u001b(B\n\u001b$BJe\u001b(B\n\u001b$BJf\u001b(B\n\u001b$BJg\u001b(B\n\u001b$BJh\u001b(B\n\u001b$BJi\u001b(B\n\u001b$BJj\u001b(B\n\u001b$BJk\u001b(B\n\u001b$BJl\u001b(B\n\u001b$BJm\u001b(B\n\u001b$BJn\u001b(B\n\u001b$BJo\u001b(B\n\u001b$BJp\u001b(B\n\u001b$BJq\u001b(B\n\u001b$BJr\u001b(B\n\u001b$BJs\u001b(B\n\u001b$BJt\u001b(B\n\u001b$BJu\u001b(B\n\u001b$BJv\u001b(B\n\u001b$BJw\u001b(B\n\u001b$BJx\u001b(B\n\u001b$BJy\u001b(B\n\u001b$BJz\u001b(B\n\u001b$BJ{\u001b(B\n\u001b$BJ|\u001b(B\n\u001b$BJ}\u001b(B\n\u001b$BJ~\u001b(B\n\u001b$BK!\u001b(B\n\u001b$BK\"\u001b(B\n\u001b$BK#\u001b(B\n\u001b$BK$\u001b(B\n\u001b$BK%\u001b(B\n\u001b$BK&\u001b(B\n\u001b$BK'\u001b(B\n\u001b$BK(\u001b(B\n\u001b$BK)\u001b(B\n\u001b$BK*\u001b(B\n\u001b$BK+\u001b(B\n\u001b$BK,\u001b(B\n\u001b$BK-\u001b(B\n\u001b$BK.\u001b(B\n\u001b$BK/\u001b(B\n\u001b$BK0\u001b(B\n\u001b$BK1\u001b(B\n\u001b$BK2\u001b(B\n\u001b$BK3\u001b(B\n\u001b$BK4\u001b(B\n\u001b$BK5\u001b(B\n\u001b$BK6\u001b(B\n\u001b$BK7\u001b(B\n\u001b$BK8\u001b(B\n\u001b$BK9\u001b(B\n\u001b$BK:\u001b(B\n\u001b$BK;\u001b(B\n\u001b$BK<\u001b(B\n\u001b$BK=\u001b(B\n\u001b$BK>\u001b(B\n\u001b$BK?\u001b(B\n\u001b$BK@\u001b(B\n\u001b$BKA\u001b(B\n\u001b$BKB\u001b(B\n\u001b$BKC\u001b(B\n\u001b$BKD\u001b(B\n\u001b$BKE\u001b(B\n\u001b$BKF\u001b(B\n\u001b$BKG\u001b(B\n\u001b$BKH\u001b(B\n\u001b$BKI\u001b(B\n\u001b$BKJ\u001b(B\n\u001b$BKK\u001b(B\n\u001b$BKL\u001b(B\n\u001b$BKM\u001b(B\n\u001b$BKN\u001b(B\n\u001b$BKO\u001b(B\n\u001b$BKP\u001b(B\n\u001b$BKQ\u001b(B\n\u001b$BKR\u001b(B\n\u001b$BKS\u001b(B\n\u001b$BKT\u001b(B\n\u001b$BKU\u001b(B\n\u001b$BKV\u001b(B\n\u001b$BKW\u001b(B\n\u001b$BKX\u001b(B\n\u001b$BKY\u001b(B\n\u001b$BKZ\u001b(B\n\u001b$BK[\u001b(B\n\u001b$BK\\\u001b(B\n\u001b$BK]\u001b(B\n\u001b$BK^\u001b(B\n\u001b$BK_\u001b(B\n\u001b$BK`\u001b(B\n\u001b$BKa\u001b(B\n\u001b$BKb\u001b(B\n\u001b$BKc\u001b(B\n\u001b$BKd\u001b(B\n\u001b$BKe\u001b(B\n\u001b$BKf\u001b(B\n\u001b$BKg\u001b(B\n\u001b$BKh\u001b(B\n\u001b$BKi\u001b(B\n\u001b$BKj\u001b(B\n\u001b$BKk\u001b(B\n\u001b$BKl\u001b(B\n\u001b$BKm\u001b(B\n\u001b$BKn\u001b(B\n\u001b$BKo\u001b(B\n\u001b$BKp\u001b(B\n\u001b$BKq\u001b(B\n\u001b$BKr\u001b(B\n\u001b$BKs\u001b(B\n\u001b$BKt\u001b(B\n\u001b$BKu\u001b(B\n\u001b$BKv\u001b(B\n\u001b$BKw\u001b(B\n\u001b$BKx\u001b(B\n\u001b$BKy\u001b(B\n\u001b$BKz\u001b(B\n\u001b$BK{\u001b(B\n\u001b$BK|\u001b(B\n\u001b$BK}\u001b(B\n\u001b$BK~\u001b(B\n\u001b$BL!\u001b(B\n\u001b$BL\"\u001b(B\n\u001b$BL#\u001b(B\n\u001b$BL$\u001b(B\n\u001b$BL%\u001b(B\n\u001b$BL&\u001b(B\n\u001b$BL'\u001b(B\n\u001b$BL(\u001b(B\n\u001b$BL)\u001b(B\n\u001b$BL*\u001b(B\n\u001b$BL+\u001b(B\n\u001b$BL,\u001b(B\n\u001b$BL-\u001b(B\n\u001b$BL.\u001b(B\n\u001b$BL/\u001b(B\n\u001b$BL0\u001b(B\n\u001b$BL1\u001b(B\n\u001b$BL2\u001b(B\n\u001b$BL3\u001b(B\n\u001b$BL4\u001b(B\n\u001b$BL5\u001b(B\n\u001b$BL6\u001b(B\n\u001b$BL7\u001b(B\n\u001b$BL8\u001b(B\n\u001b$BL9\u001b(B\n\u001b$BL:\u001b(B\n\u001b$BL;\u001b(B\n\u001b$BL<\u001b(B\n\u001b$BL=\u001b(B\n\u001b$BL>\u001b(B\n\u001b$BL?\u001b(B\n\u001b$BL@\u001b(B\n\u001b$BLA\u001b(B\n\u001b$BLB\u001b(B\n\u001b$BLC\u001b(B\n\u001b$BLD\u001b(B\n\u001b$BLE\u001b(B\n\u001b$BLF\u001b(B\n\u001b$BLG\u001b(B\n\u001b$BLH\u001b(B\n\u001b$BLI\u001b(B\n\u001b$BLJ\u001b(B\n\u001b$BLK\u001b(B\n\u001b$BLL\u001b(B\n\u001b$BLM\u001b(B\n\u001b$BLN\u001b(B\n\u001b$BLO\u001b(B\n\u001b$BLP\u001b(B\n\u001b$BLQ\u001b(B\n\u001b$BLR\u001b(B\n\u001b$BLS\u001b(B\n\u001b$BLT\u001b(B\n\u001b$BLU\u001b(B\n\u001b$BLV\u001b(B\n\u001b$BLW\u001b(B\n\u001b$BLX\u001b(B\n\u001b$BLY\u001b(B\n\u001b$BLZ\u001b(B\n\u001b$BL[\u001b(B\n\u001b$BL\\\u001b(B\n\u001b$BL]\u001b(B\n\u001b$BL^\u001b(B\n\u001b$BL_\u001b(B\n\u001b$BL`\u001b(B\n\u001b$BLa\u001b(B\n\u001b$BLb\u001b(B\n\u001b$BLc\u001b(B\n\u001b$BLd\u001b(B\n\u001b$BLe\u001b(B\n\u001b$BLf\u001b(B\n\u001b$BLg\u001b(B\n\u001b$BLh\u001b(B\n\u001b$BLi\u001b(B\n\u001b$BLj\u001b(B\n\u001b$BLk\u001b(B\n\u001b$BLl\u001b(B\n\u001b$BLm\u001b(B\n\u001b$BLn\u001b(B\n\u001b$BLo\u001b(B\n\u001b$BLp\u001b(B\n\u001b$BLq\u001b(B\n\u001b$BLr\u001b(B\n\u001b$BLs\u001b(B\n\u001b$BLt\u001b(B\n\u001b$BLu\u001b(B\n\u001b$BLv\u001b(B\n\u001b$BLw\u001b(B\n\u001b$BLx\u001b(B\n\u001b$BLy\u001b(B\n\u001b$BLz\u001b(B\n\u001b$BL{\u001b(B\n\u001b$BL|\u001b(B\n\u001b$BL}\u001b(B\n\u001b$BL~\u001b(B\n\u001b$BM!\u001b(B\n\u001b$BM\"\u001b(B\n\u001b$BM#\u001b(B\n\u001b$BM$\u001b(B\n\u001b$BM%\u001b(B\n\u001b$BM&\u001b(B\n\u001b$BM'\u001b(B\n\u001b$BM(\u001b(B\n\u001b$BM)\u001b(B\n\u001b$BM*\u001b(B\n\u001b$BM+\u001b(B\n\u001b$BM,\u001b(B\n\u001b$BM-\u001b(B\n\u001b$BM.\u001b(B\n\u001b$BM/\u001b(B\n\u001b$BM0\u001b(B\n\u001b$BM1\u001b(B\n\u001b$BM2\u001b(B\n\u001b$BM3\u001b(B\n\u001b$BM4\u001b(B\n\u001b$BM5\u001b(B\n\u001b$BM6\u001b(B\n\u001b$BM7\u001b(B\n\u001b$BM8\u001b(B\n\u001b$BM9\u001b(B\n\u001b$BM:\u001b(B\n\u001b$BM;\u001b(B\n\u001b$BM<\u001b(B\n\u001b$BM=\u001b(B\n\u001b$BM>\u001b(B\n\u001b$BM?\u001b(B\n\u001b$BM@\u001b(B\n\u001b$BMA\u001b(B\n\u001b$BMB\u001b(B\n\u001b$BMC\u001b(B\n\u001b$BMD\u001b(B\n\u001b$BME\u001b(B\n\u001b$BMF\u001b(B\n\u001b$BMG\u001b(B\n\u001b$BMH\u001b(B\n\u001b$BMI\u001b(B\n\u001b$BMJ\u001b(B\n\u001b$BMK\u001b(B\n\u001b$BML\u001b(B\n\u001b$BMM\u001b(B\n\u001b$BMN\u001b(B\n\u001b$BMO\u001b(B\n\u001b$BMP\u001b(B\n\u001b$BMQ\u001b(B\n\u001b$BMR\u001b(B\n\u001b$BMS\u001b(B\n\u001b$BMT\u001b(B\n\u001b$BMU\u001b(B\n\u001b$BMV\u001b(B\n\u001b$BMW\u001b(B\n\u001b$BMX\u001b(B\n\u001b$BMY\u001b(B\n\u001b$BMZ\u001b(B\n\u001b$BM[\u001b(B\n\u001b$BM\\\u001b(B\n\u001b$BM]\u001b(B\n\u001b$BM^\u001b(B\n\u001b$BM_\u001b(B\n\u001b$BM`\u001b(B\n\u001b$BMa\u001b(B\n\u001b$BMb\u001b(B\n\u001b$BMc\u001b(B\n\u001b$BMd\u001b(B\n\u001b$BMe\u001b(B\n\u001b$BMf\u001b(B\n\u001b$BMg\u001b(B\n\u001b$BMh\u001b(B\n\u001b$BMi\u001b(B\n\u001b$BMj\u001b(B\n\u001b$BMk\u001b(B\n\u001b$BMl\u001b(B\n\u001b$BMm\u001b(B\n\u001b$BMn\u001b(B\n\u001b$BMo\u001b(B\n\u001b$BMp\u001b(B\n\u001b$BMq\u001b(B\n\u001b$BMr\u001b(B\n\u001b$BMs\u001b(B\n\u001b$BMt\u001b(B\n\u001b$BMu\u001b(B\n\u001b$BMv\u001b(B\n\u001b$BMw\u001b(B\n\u001b$BMx\u001b(B\n\u001b$BMy\u001b(B\n\u001b$BMz\u001b(B\n\u001b$BM{\u001b(B\n\u001b$BM|\u001b(B\n\u001b$BM}\u001b(B\n\u001b$BM~\u001b(B\n\u001b$BN!\u001b(B\n\u001b$BN\"\u001b(B\n\u001b$BN#\u001b(B\n\u001b$BN$\u001b(B\n\u001b$BN%\u001b(B\n\u001b$BN&\u001b(B\n\u001b$BN'\u001b(B\n\u001b$BN(\u001b(B\n\u001b$BN)\u001b(B\n\u001b$BN*\u001b(B\n\u001b$BN+\u001b(B\n\u001b$BN,\u001b(B\n\u001b$BN-\u001b(B\n\u001b$BN.\u001b(B\n\u001b$BN/\u001b(B\n\u001b$BN0\u001b(B\n\u001b$BN1\u001b(B\n\u001b$BN2\u001b(B\n\u001b$BN3\u001b(B\n\u001b$BN4\u001b(B\n\u001b$BN5\u001b(B\n\u001b$BN6\u001b(B\n\u001b$BN7\u001b(B\n\u001b$BN8\u001b(B\n\u001b$BN9\u001b(B\n\u001b$BN:\u001b(B\n\u001b$BN;\u001b(B\n\u001b$BN<\u001b(B\n\u001b$BN=\u001b(B\n\u001b$BN>\u001b(B\n\u001b$BN?\u001b(B\n\u001b$BN@\u001b(B\n\u001b$BNA\u001b(B\n\u001b$BNB\u001b(B\n\u001b$BNC\u001b(B\n\u001b$BND\u001b(B\n\u001b$BNE\u001b(B\n\u001b$BNF\u001b(B\n\u001b$BNG\u001b(B\n\u001b$BNH\u001b(B\n\u001b$BNI\u001b(B\n\u001b$BNJ\u001b(B\n\u001b$BNK\u001b(B\n\u001b$BNL\u001b(B\n\u001b$BNM\u001b(B\n\u001b$BNN\u001b(B\n\u001b$BNO\u001b(B\n\u001b$BNP\u001b(B\n\u001b$BNQ\u001b(B\n\u001b$BNR\u001b(B\n\u001b$BNS\u001b(B\n\u001b$BNT\u001b(B\n\u001b$BNU\u001b(B\n\u001b$BNV\u001b(B\n\u001b$BNW\u001b(B\n\u001b$BNX\u001b(B\n\u001b$BNY\u001b(B\n\u001b$BNZ\u001b(B\n\u001b$BN[\u001b(B\n\u001b$BN\\\u001b(B\n\u001b$BN]\u001b(B\n\u001b$BN^\u001b(B\n\u001b$BN_\u001b(B\n\u001b$BN`\u001b(B\n\u001b$BNa\u001b(B\n\u001b$BNb\u001b(B\n\u001b$BNc\u001b(B\n\u001b$BNd\u001b(B\n\u001b$BNe\u001b(B\n\u001b$BNf\u001b(B\n\u001b$BNg\u001b(B\n\u001b$BNh\u001b(B\n\u001b$BNi\u001b(B\n\u001b$BNj\u001b(B\n\u001b$BNk\u001b(B\n\u001b$BNl\u001b(B\n\u001b$BNm\u001b(B\n\u001b$BNn\u001b(B\n\u001b$BNo\u001b(B\n\u001b$BNp\u001b(B\n\u001b$BNq\u001b(B\n\u001b$BNr\u001b(B\n\u001b$BNs\u001b(B\n\u001b$BNt\u001b(B\n\u001b$BNu\u001b(B\n\u001b$BNv\u001b(B\n\u001b$BNw\u001b(B\n\u001b$BNx\u001b(B\n\u001b$BNy\u001b(B\n\u001b$BNz\u001b(B\n\u001b$BN{\u001b(B\n\u001b$BN|\u001b(B\n\u001b$BN}\u001b(B\n\u001b$BN~\u001b(B\n\u001b$BO!\u001b(B\n\u001b$BO\"\u001b(B\n\u001b$BO#\u001b(B\n\u001b$BO$\u001b(B\n\u001b$BO%\u001b(B\n\u001b$BO&\u001b(B\n\u001b$BO'\u001b(B\n\u001b$BO(\u001b(B\n\u001b$BO)\u001b(B\n\u001b$BO*\u001b(B\n\u001b$BO+\u001b(B\n\u001b$BO,\u001b(B\n\u001b$BO-\u001b(B\n\u001b$BO.\u001b(B\n\u001b$BO/\u001b(B\n\u001b$BO0\u001b(B\n\u001b$BO1\u001b(B\n\u001b$BO2\u001b(B\n\u001b$BO3\u001b(B\n\u001b$BO4\u001b(B\n\u001b$BO5\u001b(B\n\u001b$BO6\u001b(B\n\u001b$BO7\u001b(B\n\u001b$BO8\u001b(B\n\u001b$BO9\u001b(B\n\u001b$BO:\u001b(B\n\u001b$BO;\u001b(B\n\u001b$BO<\u001b(B\n\u001b$BO=\u001b(B\n\u001b$BO>\u001b(B\n\u001b$BO?\u001b(B\n\u001b$BO@\u001b(B\n\u001b$BOA\u001b(B\n\u001b$BOB\u001b(B\n\u001b$BOC\u001b(B\n\u001b$BOD\u001b(B\n\u001b$BOE\u001b(B\n\u001b$BOF\u001b(B\n\u001b$BOG\u001b(B\n\u001b$BOH\u001b(B\n\u001b$BOI\u001b(B\n\u001b$BOJ\u001b(B\n\u001b$BOK\u001b(B\n\u001b$BOL\u001b(B\n\u001b$BOM\u001b(B\n\u001b$BON\u001b(B\n\u001b$BOO\u001b(B\n\u001b$BOP\u001b(B\n\u001b$BOQ\u001b(B\n\u001b$BOR\u001b(B\n\u001b$BOS\u001b(B\n\u001b$BOT\u001b(B\n\u001b$BOU\u001b(B\n\u001b$BOV\u001b(B\n\u001b$BOW\u001b(B\n\u001b$BOX\u001b(B\n\u001b$BOY\u001b(B\n\u001b$BOZ\u001b(B\n\u001b$BO[\u001b(B\n\u001b$BO\\\u001b(B\n\u001b$BO]\u001b(B\n\u001b$BO^\u001b(B\n\u001b$BO_\u001b(B\n\u001b$BO`\u001b(B\n\u001b$BOa\u001b(B\n\u001b$BOb\u001b(B\n\u001b$BOc\u001b(B\n\u001b$BOd\u001b(B\n\u001b$BOe\u001b(B\n\u001b$BOf\u001b(B\n\u001b$BOg\u001b(B\n\u001b$BOh\u001b(B\n\u001b$BOi\u001b(B\n\u001b$BOj\u001b(B\n\u001b$BOk\u001b(B\n\u001b$BOl\u001b(B\n\u001b$BOm\u001b(B\n\u001b$BOn\u001b(B\n\u001b$BOo\u001b(B\n\u001b$BOp\u001b(B\n\u001b$BOq\u001b(B\n\u001b$BOr\u001b(B\n\u001b$BOs\u001b(B\n\u001b$BOt\u001b(B\n\u001b$BOu\u001b(B\n\u001b$BOv\u001b(B\n\u001b$BOw\u001b(B\n\u001b$BOx\u001b(B\n\u001b$BOy\u001b(B\n\u001b$BOz\u001b(B\n\u001b$BO{\u001b(B\n\u001b$BO|\u001b(B\n\u001b$BO}\u001b(B\n\u001b$BO~\u001b(B\n\u001b$BP!\u001b(B\n\u001b$BP\"\u001b(B\n\u001b$BP#\u001b(B\n\u001b$BP$\u001b(B\n\u001b$BP%\u001b(B\n\u001b$BP&\u001b(B\n\u001b$BP'\u001b(B\n\u001b$BP(\u001b(B\n\u001b$BP)\u001b(B\n\u001b$BP*\u001b(B\n\u001b$BP+\u001b(B\n\u001b$BP,\u001b(B\n\u001b$BP-\u001b(B\n\u001b$BP.\u001b(B\n\u001b$BP/\u001b(B\n\u001b$BP0\u001b(B\n\u001b$BP1\u001b(B\n\u001b$BP2\u001b(B\n\u001b$BP3\u001b(B\n\u001b$BP4\u001b(B\n\u001b$BP5\u001b(B\n\u001b$BP6\u001b(B\n\u001b$BP7\u001b(B\n\u001b$BP8\u001b(B\n\u001b$BP9\u001b(B\n\u001b$BP:\u001b(B\n\u001b$BP;\u001b(B\n\u001b$BP<\u001b(B\n\u001b$BP=\u001b(B\n\u001b$BP>\u001b(B\n\u001b$BP?\u001b(B\n\u001b$BP@\u001b(B\n\u001b$BPA\u001b(B\n\u001b$BPB\u001b(B\n\u001b$BPC\u001b(B\n\u001b$BPD\u001b(B\n\u001b$BPE\u001b(B\n\u001b$BPF\u001b(B\n\u001b$BPG\u001b(B\n\u001b$BPH\u001b(B\n\u001b$BPI\u001b(B\n\u001b$BPJ\u001b(B\n\u001b$BPK\u001b(B\n\u001b$BPL\u001b(B\n\u001b$BPM\u001b(B\n\u001b$BPN\u001b(B\n\u001b$BPO\u001b(B\n\u001b$BPP\u001b(B\n\u001b$BPQ\u001b(B\n\u001b$BPR\u001b(B\n\u001b$BPS\u001b(B\n\u001b$BPT\u001b(B\n\u001b$BPU\u001b(B\n\u001b$BPV\u001b(B\n\u001b$BPW\u001b(B\n\u001b$BPX\u001b(B\n\u001b$BPY\u001b(B\n\u001b$BPZ\u001b(B\n\u001b$BP[\u001b(B\n\u001b$BP\\\u001b(B\n\u001b$BP]\u001b(B\n\u001b$BP^\u001b(B\n\u001b$BP_\u001b(B\n\u001b$BP`\u001b(B\n\u001b$BPa\u001b(B\n\u001b$BPb\u001b(B\n\u001b$BPc\u001b(B\n\u001b$BPd\u001b(B\n\u001b$BPe\u001b(B\n\u001b$BPf\u001b(B\n\u001b$BPg\u001b(B\n\u001b$BPh\u001b(B\n\u001b$BPi\u001b(B\n\u001b$BPj\u001b(B\n\u001b$BPk\u001b(B\n\u001b$BPl\u001b(B\n\u001b$BPm\u001b(B\n\u001b$BPn\u001b(B\n\u001b$BPo\u001b(B\n\u001b$BPp\u001b(B\n\u001b$BPq\u001b(B\n\u001b$BPr\u001b(B\n\u001b$BPs\u001b(B\n\u001b$BPt\u001b(B\n\u001b$BPu\u001b(B\n\u001b$BPv\u001b(B\n\u001b$BPw\u001b(B\n\u001b$BPx\u001b(B\n\u001b$BPy\u001b(B\n\u001b$BPz\u001b(B\n\u001b$BP{\u001b(B\n\u001b$BP|\u001b(B\n\u001b$BP}\u001b(B\n\u001b$BP~\u001b(B\n\u001b$BQ!\u001b(B\n\u001b$BQ\"\u001b(B\n\u001b$BQ#\u001b(B\n\u001b$BQ$\u001b(B\n\u001b$BQ%\u001b(B\n\u001b$BQ&\u001b(B\n\u001b$BQ'\u001b(B\n\u001b$BQ(\u001b(B\n\u001b$BQ)\u001b(B\n\u001b$BQ*\u001b(B\n\u001b$BQ+\u001b(B\n\u001b$BQ,\u001b(B\n\u001b$BQ-\u001b(B\n\u001b$BQ.\u001b(B\n\u001b$BQ/\u001b(B\n\u001b$BQ0\u001b(B\n\u001b$BQ1\u001b(B\n\u001b$BQ2\u001b(B\n\u001b$BQ3\u001b(B\n\u001b$BQ4\u001b(B\n\u001b$BQ5\u001b(B\n\u001b$BQ6\u001b(B\n\u001b$BQ7\u001b(B\n\u001b$BQ8\u001b(B\n\u001b$BQ9\u001b(B\n\u001b$BQ:\u001b(B\n\u001b$BQ;\u001b(B\n\u001b$BQ<\u001b(B\n\u001b$BQ=\u001b(B\n\u001b$BQ>\u001b(B\n\u001b$BQ?\u001b(B\n\u001b$BQ@\u001b(B\n\u001b$BQA\u001b(B\n\u001b$BQB\u001b(B\n\u001b$BQC\u001b(B\n\u001b$BQD\u001b(B\n\u001b$BQE\u001b(B\n\u001b$BQF\u001b(B\n\u001b$BQG\u001b(B\n\u001b$BQH\u001b(B\n\u001b$BQI\u001b(B\n\u001b$BQJ\u001b(B\n\u001b$BQK\u001b(B\n\u001b$BQL\u001b(B\n\u001b$BQM\u001b(B\n\u001b$BQN\u001b(B\n\u001b$BQO\u001b(B\n\u001b$BQP\u001b(B\n\u001b$BQQ\u001b(B\n\u001b$BQR\u001b(B\n\u001b$BQS\u001b(B\n\u001b$BQT\u001b(B\n\u001b$BQU\u001b(B\n\u001b$BQV\u001b(B\n\u001b$BQW\u001b(B\n\u001b$BQX\u001b(B\n\u001b$BQY\u001b(B\n\u001b$BQZ\u001b(B\n\u001b$BQ[\u001b(B\n\u001b$BQ\\\u001b(B\n\u001b$BQ]\u001b(B\n\u001b$BQ^\u001b(B\n\u001b$BQ_\u001b(B\n\u001b$BQ`\u001b(B\n\u001b$BQa\u001b(B\n\u001b$BQb\u001b(B\n\u001b$BQc\u001b(B\n\u001b$BQd\u001b(B\n\u001b$BQe\u001b(B\n\u001b$BQf\u001b(B\n\u001b$BQg\u001b(B\n\u001b$BQh\u001b(B\n\u001b$BQi\u001b(B\n\u001b$BQj\u001b(B\n\u001b$BQk\u001b(B\n\u001b$BQl\u001b(B\n\u001b$BQm\u001b(B\n\u001b$BQn\u001b(B\n\u001b$BQo\u001b(B\n\u001b$BQp\u001b(B\n\u001b$BQq\u001b(B\n\u001b$BQr\u001b(B\n\u001b$BQs\u001b(B\n\u001b$BQt\u001b(B\n\u001b$BQu\u001b(B\n\u001b$BQv\u001b(B\n\u001b$BQw\u001b(B\n\u001b$BQx\u001b(B\n\u001b$BQy\u001b(B\n\u001b$BQz\u001b(B\n\u001b$BQ{\u001b(B\n\u001b$BQ|\u001b(B\n\u001b$BQ}\u001b(B\n\u001b$BQ~\u001b(B\n\u001b$BR!\u001b(B\n\u001b$BR\"\u001b(B\n\u001b$BR#\u001b(B\n\u001b$BR$\u001b(B\n\u001b$BR%\u001b(B\n\u001b$BR&\u001b(B\n\u001b$BR'\u001b(B\n\u001b$BR(\u001b(B\n\u001b$BR)\u001b(B\n\u001b$BR*\u001b(B\n\u001b$BR+\u001b(B\n\u001b$BR,\u001b(B\n\u001b$BR-\u001b(B\n\u001b$BR.\u001b(B\n\u001b$BR/\u001b(B\n\u001b$BR0\u001b(B\n\u001b$BR1\u001b(B\n\u001b$BR2\u001b(B\n\u001b$BR3\u001b(B\n\u001b$BR4\u001b(B\n\u001b$BR5\u001b(B\n\u001b$BR6\u001b(B\n\u001b$BR7\u001b(B\n\u001b$BR8\u001b(B\n\u001b$BR9\u001b(B\n\u001b$BR:\u001b(B\n\u001b$BR;\u001b(B\n\u001b$BR<\u001b(B\n\u001b$BR=\u001b(B\n\u001b$BR>\u001b(B\n\u001b$BR?\u001b(B\n\u001b$BR@\u001b(B\n\u001b$BRA\u001b(B\n\u001b$BRB\u001b(B\n\u001b$BRC\u001b(B\n\u001b$BRD\u001b(B\n\u001b$BRE\u001b(B\n\u001b$BRF\u001b(B\n\u001b$BRG\u001b(B\n\u001b$BRH\u001b(B\n\u001b$BRI\u001b(B\n\u001b$BRJ\u001b(B\n\u001b$BRK\u001b(B\n\u001b$BRL\u001b(B\n\u001b$BRM\u001b(B\n\u001b$BRN\u001b(B\n\u001b$BRO\u001b(B\n\u001b$BRP\u001b(B\n\u001b$BRQ\u001b(B\n\u001b$BRR\u001b(B\n\u001b$BRS\u001b(B\n\u001b$BRT\u001b(B\n\u001b$BRU\u001b(B\n\u001b$BRV\u001b(B\n\u001b$BRW\u001b(B\n\u001b$BRX\u001b(B\n\u001b$BRY\u001b(B\n\u001b$BRZ\u001b(B\n\u001b$BR[\u001b(B\n\u001b$BR\\\u001b(B\n\u001b$BR]\u001b(B\n\u001b$BR^\u001b(B\n\u001b$BR_\u001b(B\n\u001b$BR`\u001b(B\n\u001b$BRa\u001b(B\n\u001b$BRb\u001b(B\n\u001b$BRc\u001b(B\n\u001b$BRd\u001b(B\n\u001b$BRe\u001b(B\n\u001b$BRf\u001b(B\n\u001b$BRg\u001b(B\n\u001b$BRh\u001b(B\n\u001b$BRi\u001b(B\n\u001b$BRj\u001b(B\n\u001b$BRk\u001b(B\n\u001b$BRl\u001b(B\n\u001b$BRm\u001b(B\n\u001b$BRn\u001b(B\n\u001b$BRo\u001b(B\n\u001b$BRp\u001b(B\n\u001b$BRq\u001b(B\n\u001b$BRr\u001b(B\n\u001b$BRs\u001b(B\n\u001b$BRt\u001b(B\n\u001b$BRu\u001b(B\n\u001b$BRv\u001b(B\n\u001b$BRw\u001b(B\n\u001b$BRx\u001b(B\n\u001b$BRy\u001b(B\n\u001b$BRz\u001b(B\n\u001b$BR{\u001b(B\n\u001b$BR|\u001b(B\n\u001b$BR}\u001b(B\n\u001b$BR~\u001b(B\n\u001b$BS!\u001b(B\n\u001b$BS\"\u001b(B\n\u001b$BS#\u001b(B\n\u001b$BS$\u001b(B\n\u001b$BS%\u001b(B\n\u001b$BS&\u001b(B\n\u001b$BS'\u001b(B\n\u001b$BS(\u001b(B\n\u001b$BS)\u001b(B\n\u001b$BS*\u001b(B\n\u001b$BS+\u001b(B\n\u001b$BS,\u001b(B\n\u001b$BS-\u001b(B\n\u001b$BS.\u001b(B\n\u001b$BS/\u001b(B\n\u001b$BS0\u001b(B\n\u001b$BS1\u001b(B\n\u001b$BS2\u001b(B\n\u001b$BS3\u001b(B\n\u001b$BS4\u001b(B\n\u001b$BS5\u001b(B\n\u001b$BS6\u001b(B\n\u001b$BS7\u001b(B\n\u001b$BS8\u001b(B\n\u001b$BS9\u001b(B\n\u001b$BS:\u001b(B\n\u001b$BS;\u001b(B\n\u001b$BS<\u001b(B\n\u001b$BS=\u001b(B\n\u001b$BS>\u001b(B\n\u001b$BS?\u001b(B\n\u001b$BS@\u001b(B\n\u001b$BSA\u001b(B\n\u001b$BSB\u001b(B\n\u001b$BSC\u001b(B\n\u001b$BSD\u001b(B\n\u001b$BSE\u001b(B\n\u001b$BSF\u001b(B\n\u001b$BSG\u001b(B\n\u001b$BSH\u001b(B\n\u001b$BSI\u001b(B\n\u001b$BSJ\u001b(B\n\u001b$BSK\u001b(B\n\u001b$BSL\u001b(B\n\u001b$BSM\u001b(B\n\u001b$BSN\u001b(B\n\u001b$BSO\u001b(B\n\u001b$BSP\u001b(B\n\u001b$BSQ\u001b(B\n\u001b$BSR\u001b(B\n\u001b$BSS\u001b(B\n\u001b$BST\u001b(B\n\u001b$BSU\u001b(B\n\u001b$BSV\u001b(B\n\u001b$BSW\u001b(B\n\u001b$BSX\u001b(B\n\u001b$BSY\u001b(B\n\u001b$BSZ\u001b(B\n\u001b$BS[\u001b(B\n\u001b$BS\\\u001b(B\n\u001b$BS]\u001b(B\n\u001b$BS^\u001b(B\n\u001b$BS_\u001b(B\n\u001b$BS`\u001b(B\n\u001b$BSa\u001b(B\n\u001b$BSb\u001b(B\n\u001b$BSc\u001b(B\n\u001b$BSd\u001b(B\n\u001b$BSe\u001b(B\n\u001b$BSf\u001b(B\n\u001b$BSg\u001b(B\n\u001b$BSh\u001b(B\n\u001b$BSi\u001b(B\n\u001b$BSj\u001b(B\n\u001b$BSk\u001b(B\n\u001b$BSl\u001b(B\n\u001b$BSm\u001b(B\n\u001b$BSn\u001b(B\n\u001b$BSo\u001b(B\n\u001b$BSp\u001b(B\n\u001b$BSq\u001b(B\n\u001b$BSr\u001b(B\n\u001b$BSs\u001b(B\n\u001b$BSt\u001b(B\n\u001b$BSu\u001b(B\n\u001b$BSv\u001b(B\n\u001b$BSw\u001b(B\n\u001b$BSx\u001b(B\n\u001b$BSy\u001b(B\n\u001b$BSz\u001b(B\n\u001b$BS{\u001b(B\n\u001b$BS|\u001b(B\n\u001b$BS}\u001b(B\n\u001b$BS~\u001b(B\n\u001b$BT!\u001b(B\n\u001b$BT\"\u001b(B\n\u001b$BT#\u001b(B\n\u001b$BT$\u001b(B\n\u001b$BT%\u001b(B\n\u001b$BT&\u001b(B\n\u001b$BT'\u001b(B\n\u001b$BT(\u001b(B\n\u001b$BT)\u001b(B\n\u001b$BT*\u001b(B\n\u001b$BT+\u001b(B\n\u001b$BT,\u001b(B\n\u001b$BT-\u001b(B\n\u001b$BT.\u001b(B\n\u001b$BT/\u001b(B\n\u001b$BT0\u001b(B\n\u001b$BT1\u001b(B\n\u001b$BT2\u001b(B\n\u001b$BT3\u001b(B\n\u001b$BT4\u001b(B\n\u001b$BT5\u001b(B\n\u001b$BT6\u001b(B\n\u001b$BT7\u001b(B\n\u001b$BT8\u001b(B\n\u001b$BT9\u001b(B\n\u001b$BT:\u001b(B\n\u001b$BT;\u001b(B\n\u001b$BT<\u001b(B\n\u001b$BT=\u001b(B\n\u001b$BT>\u001b(B\n\u001b$BT?\u001b(B\n\u001b$BT@\u001b(B\n\u001b$BTA\u001b(B\n\u001b$BTB\u001b(B\n\u001b$BTC\u001b(B\n\u001b$BTD\u001b(B\n\u001b$BTE\u001b(B\n\u001b$BTF\u001b(B\n\u001b$BTG\u001b(B\n\u001b$BTH\u001b(B\n\u001b$BTI\u001b(B\n\u001b$BTJ\u001b(B\n\u001b$BTK\u001b(B\n\u001b$BTL\u001b(B\n\u001b$BTM\u001b(B\n\u001b$BTN\u001b(B\n\u001b$BTO\u001b(B\n\u001b$BTP\u001b(B\n\u001b$BTQ\u001b(B\n\u001b$BTR\u001b(B\n\u001b$BTS\u001b(B\n\u001b$BTT\u001b(B\n\u001b$BTU\u001b(B\n\u001b$BTV\u001b(B\n\u001b$BTW\u001b(B\n\u001b$BTX\u001b(B\n\u001b$BTY\u001b(B\n\u001b$BTZ\u001b(B\n\u001b$BT[\u001b(B\n\u001b$BT\\\u001b(B\n\u001b$BT]\u001b(B\n\u001b$BT^\u001b(B\n\u001b$BT_\u001b(B\n\u001b$BT`\u001b(B\n\u001b$BTa\u001b(B\n\u001b$BTb\u001b(B\n\u001b$BTc\u001b(B\n\u001b$BTd\u001b(B\n\u001b$BTe\u001b(B\n\u001b$BTf\u001b(B\n\u001b$BTg\u001b(B\n\u001b$BTh\u001b(B\n\u001b$BTi\u001b(B\n\u001b$BTj\u001b(B\n\u001b$BTk\u001b(B\n\u001b$BTl\u001b(B\n\u001b$BTm\u001b(B\n\u001b$BTn\u001b(B\n\u001b$BTo\u001b(B\n\u001b$BTp\u001b(B\n\u001b$BTq\u001b(B\n\u001b$BTr\u001b(B\n\u001b$BTs\u001b(B\n\u001b$BTt\u001b(B\n\u001b$BTu\u001b(B\n\u001b$BTv\u001b(B\n\u001b$BTw\u001b(B\n\u001b$BTx\u001b(B\n\u001b$BTy\u001b(B\n\u001b$BTz\u001b(B\n\u001b$BT{\u001b(B\n\u001b$BT|\u001b(B\n\u001b$BT}\u001b(B\n\u001b$BT~\u001b(B\n\u001b$BU!\u001b(B\n\u001b$BU\"\u001b(B\n\u001b$BU#\u001b(B\n\u001b$BU$\u001b(B\n\u001b$BU%\u001b(B\n\u001b$BU&\u001b(B\n\u001b$BU'\u001b(B\n\u001b$BU(\u001b(B\n\u001b$BU)\u001b(B\n\u001b$BU*\u001b(B\n\u001b$BU+\u001b(B\n\u001b$BU,\u001b(B\n\u001b$BU-\u001b(B\n\u001b$BU.\u001b(B\n\u001b$BU/\u001b(B\n\u001b$BU0\u001b(B\n\u001b$BU1\u001b(B\n\u001b$BU2\u001b(B\n\u001b$BU3\u001b(B\n\u001b$BU4\u001b(B\n\u001b$BU5\u001b(B\n\u001b$BU6\u001b(B\n\u001b$BU7\u001b(B\n\u001b$BU8\u001b(B\n\u001b$BU9\u001b(B\n\u001b$BU:\u001b(B\n\u001b$BU;\u001b(B\n\u001b$BU<\u001b(B\n\u001b$BU=\u001b(B\n\u001b$BU>\u001b(B\n\u001b$BU?\u001b(B\n\u001b$BU@\u001b(B\n\u001b$BUA\u001b(B\n\u001b$BUB\u001b(B\n\u001b$BUC\u001b(B\n\u001b$BUD\u001b(B\n\u001b$BUE\u001b(B\n\u001b$BUF\u001b(B\n\u001b$BUG\u001b(B\n\u001b$BUH\u001b(B\n\u001b$BUI\u001b(B\n\u001b$BUJ\u001b(B\n\u001b$BUK\u001b(B\n\u001b$BUL\u001b(B\n\u001b$BUM\u001b(B\n\u001b$BUN\u001b(B\n\u001b$BUO\u001b(B\n\u001b$BUP\u001b(B\n\u001b$BUQ\u001b(B\n\u001b$BUR\u001b(B\n\u001b$BUS\u001b(B\n\u001b$BUT\u001b(B\n\u001b$BUU\u001b(B\n\u001b$BUV\u001b(B\n\u001b$BUW\u001b(B\n\u001b$BUX\u001b(B\n\u001b$BUY\u001b(B\n\u001b$BUZ\u001b(B\n\u001b$BU[\u001b(B\n\u001b$BU\\\u001b(B\n\u001b$BU]\u001b(B\n\u001b$BU^\u001b(B\n\u001b$BU_\u001b(B\n\u001b$BU`\u001b(B\n\u001b$BUa\u001b(B\n\u001b$BUb\u001b(B\n\u001b$BUc\u001b(B\n\u001b$BUd\u001b(B\n\u001b$BUe\u001b(B\n\u001b$BUf\u001b(B\n\u001b$BUg\u001b(B\n\u001b$BUh\u001b(B\n\u001b$BUi\u001b(B\n\u001b$BUj\u001b(B\n\u001b$BUk\u001b(B\n\u001b$BUl\u001b(B\n\u001b$BUm\u001b(B\n\u001b$BUn\u001b(B\n\u001b$BUo\u001b(B\n\u001b$BUp\u001b(B\n\u001b$BUq\u001b(B\n\u001b$BUr\u001b(B\n\u001b$BUs\u001b(B\n\u001b$BUt\u001b(B\n\u001b$BUu\u001b(B\n\u001b$BUv\u001b(B\n\u001b$BUw\u001b(B\n\u001b$BUx\u001b(B\n\u001b$BUy\u001b(B\n\u001b$BUz\u001b(B\n\u001b$BU{\u001b(B\n\u001b$BU|\u001b(B\n\u001b$BU}\u001b(B\n\u001b$BU~\u001b(B\n\u001b$BV!\u001b(B\n\u001b$BV\"\u001b(B\n\u001b$BV#\u001b(B\n\u001b$BV$\u001b(B\n\u001b$BV%\u001b(B\n\u001b$BV&\u001b(B\n\u001b$BV'\u001b(B\n\u001b$BV(\u001b(B\n\u001b$BV)\u001b(B\n\u001b$BV*\u001b(B\n\u001b$BV+\u001b(B\n\u001b$BV,\u001b(B\n\u001b$BV-\u001b(B\n\u001b$BV.\u001b(B\n\u001b$BV/\u001b(B\n\u001b$BV0\u001b(B\n\u001b$BV1\u001b(B\n\u001b$BV2\u001b(B\n\u001b$BV3\u001b(B\n\u001b$BV4\u001b(B\n\u001b$BV5\u001b(B\n\u001b$BV6\u001b(B\n\u001b$BV7\u001b(B\n\u001b$BV8\u001b(B\n\u001b$BV9\u001b(B\n\u001b$BV:\u001b(B\n\u001b$BV;\u001b(B\n\u001b$BV<\u001b(B\n\u001b$BV=\u001b(B\n\u001b$BV>\u001b(B\n\u001b$BV?\u001b(B\n\u001b$BV@\u001b(B\n\u001b$BVA\u001b(B\n\u001b$BVB\u001b(B\n\u001b$BVC\u001b(B\n\u001b$BVD\u001b(B\n\u001b$BVE\u001b(B\n\u001b$BVF\u001b(B\n\u001b$BVG\u001b(B\n\u001b$BVH\u001b(B\n\u001b$BVI\u001b(B\n\u001b$BVJ\u001b(B\n\u001b$BVK\u001b(B\n\u001b$BVL\u001b(B\n\u001b$BVM\u001b(B\n\u001b$BVN\u001b(B\n\u001b$BVO\u001b(B\n\u001b$BVP\u001b(B\n\u001b$BVQ\u001b(B\n\u001b$BVR\u001b(B\n\u001b$BVS\u001b(B\n\u001b$BVT\u001b(B\n\u001b$BVU\u001b(B\n\u001b$BVV\u001b(B\n\u001b$BVW\u001b(B\n\u001b$BVX\u001b(B\n\u001b$BVY\u001b(B\n\u001b$BVZ\u001b(B\n\u001b$BV[\u001b(B\n\u001b$BV\\\u001b(B\n\u001b$BV]\u001b(B\n\u001b$BV^\u001b(B\n\u001b$BV_\u001b(B\n\u001b$BV`\u001b(B\n\u001b$BVa\u001b(B\n\u001b$BVb\u001b(B\n\u001b$BVc\u001b(B\n\u001b$BVd\u001b(B\n\u001b$BVe\u001b(B\n\u001b$BVf\u001b(B\n\u001b$BVg\u001b(B\n\u001b$BVh\u001b(B\n\u001b$BVi\u001b(B\n\u001b$BVj\u001b(B\n\u001b$BVk\u001b(B\n\u001b$BVl\u001b(B\n\u001b$BVm\u001b(B\n\u001b$BVn\u001b(B\n\u001b$BVo\u001b(B\n\u001b$BVp\u001b(B\n\u001b$BVq\u001b(B\n\u001b$BVr\u001b(B\n\u001b$BVs\u001b(B\n\u001b$BVt\u001b(B\n\u001b$BVu\u001b(B\n\u001b$BVv\u001b(B\n\u001b$BVw\u001b(B\n\u001b$BVx\u001b(B\n\u001b$BVy\u001b(B\n\u001b$BVz\u001b(B\n\u001b$BV{\u001b(B\n\u001b$BV|\u001b(B\n\u001b$BV}\u001b(B\n\u001b$BV~\u001b(B\n\u001b$BW!\u001b(B\n\u001b$BW\"\u001b(B\n\u001b$BW#\u001b(B\n\u001b$BW$\u001b(B\n\u001b$BW%\u001b(B\n\u001b$BW&\u001b(B\n\u001b$BW'\u001b(B\n\u001b$BW(\u001b(B\n\u001b$BW)\u001b(B\n\u001b$BW*\u001b(B\n\u001b$BW+\u001b(B\n\u001b$BW,\u001b(B\n\u001b$BW-\u001b(B\n\u001b$BW.\u001b(B\n\u001b$BW/\u001b(B\n\u001b$BW0\u001b(B\n\u001b$BW1\u001b(B\n\u001b$BW2\u001b(B\n\u001b$BW3\u001b(B\n\u001b$BW4\u001b(B\n\u001b$BW5\u001b(B\n\u001b$BW6\u001b(B\n\u001b$BW7\u001b(B\n\u001b$BW8\u001b(B\n\u001b$BW9\u001b(B\n\u001b$BW:\u001b(B\n\u001b$BW;\u001b(B\n\u001b$BW<\u001b(B\n\u001b$BW=\u001b(B\n\u001b$BW>\u001b(B\n\u001b$BW?\u001b(B\n\u001b$BW@\u001b(B\n\u001b$BWA\u001b(B\n\u001b$BWB\u001b(B\n\u001b$BWC\u001b(B\n\u001b$BWD\u001b(B\n\u001b$BWE\u001b(B\n\u001b$BWF\u001b(B\n\u001b$BWG\u001b(B\n\u001b$BWH\u001b(B\n\u001b$BWI\u001b(B\n\u001b$BWJ\u001b(B\n\u001b$BWK\u001b(B\n\u001b$BWL\u001b(B\n\u001b$BWM\u001b(B\n\u001b$BWN\u001b(B\n\u001b$BWO\u001b(B\n\u001b$BWP\u001b(B\n\u001b$BWQ\u001b(B\n\u001b$BWR\u001b(B\n\u001b$BWS\u001b(B\n\u001b$BWT\u001b(B\n\u001b$BWU\u001b(B\n\u001b$BWV\u001b(B\n\u001b$BWW\u001b(B\n\u001b$BWX\u001b(B\n\u001b$BWY\u001b(B\n\u001b$BWZ\u001b(B\n\u001b$BW[\u001b(B\n\u001b$BW\\\u001b(B\n\u001b$BW]\u001b(B\n\u001b$BW^\u001b(B\n\u001b$BW_\u001b(B\n\u001b$BW`\u001b(B\n\u001b$BWa\u001b(B\n\u001b$BWb\u001b(B\n\u001b$BWc\u001b(B\n\u001b$BWd\u001b(B\n\u001b$BWe\u001b(B\n\u001b$BWf\u001b(B\n\u001b$BWg\u001b(B\n\u001b$BWh\u001b(B\n\u001b$BWi\u001b(B\n\u001b$BWj\u001b(B\n\u001b$BWk\u001b(B\n\u001b$BWl\u001b(B\n\u001b$BWm\u001b(B\n\u001b$BWn\u001b(B\n\u001b$BWo\u001b(B\n\u001b$BWp\u001b(B\n\u001b$BWq\u001b(B\n\u001b$BWr\u001b(B\n\u001b$BWs\u001b(B\n\u001b$BWt\u001b(B\n\u001b$BWu\u001b(B\n\u001b$BWv\u001b(B\n\u001b$BWw\u001b(B\n\u001b$BWx\u001b(B\n\u001b$BWy\u001b(B\n\u001b$BWz\u001b(B\n\u001b$BW{\u001b(B\n\u001b$BW|\u001b(B\n\u001b$BW}\u001b(B\n\u001b$BW~\u001b(B\n\u001b$BX!\u001b(B\n\u001b$BX\"\u001b(B\n\u001b$BX#\u001b(B\n\u001b$BX$\u001b(B\n\u001b$BX%\u001b(B\n\u001b$BX&\u001b(B\n\u001b$BX'\u001b(B\n\u001b$BX(\u001b(B\n\u001b$BX)\u001b(B\n\u001b$BX*\u001b(B\n\u001b$BX+\u001b(B\n\u001b$BX,\u001b(B\n\u001b$BX-\u001b(B\n\u001b$BX.\u001b(B\n\u001b$BX/\u001b(B\n\u001b$BX0\u001b(B\n\u001b$BX1\u001b(B\n\u001b$BX2\u001b(B\n\u001b$BX3\u001b(B\n\u001b$BX4\u001b(B\n\u001b$BX5\u001b(B\n\u001b$BX6\u001b(B\n\u001b$BX7\u001b(B\n\u001b$BX8\u001b(B\n\u001b$BX9\u001b(B\n\u001b$BX:\u001b(B\n\u001b$BX;\u001b(B\n\u001b$BX<\u001b(B\n\u001b$BX=\u001b(B\n\u001b$BX>\u001b(B\n\u001b$BX?\u001b(B\n\u001b$BX@\u001b(B\n\u001b$BXA\u001b(B\n\u001b$BXB\u001b(B\n\u001b$BXC\u001b(B\n\u001b$BXD\u001b(B\n\u001b$BXE\u001b(B\n\u001b$BXF\u001b(B\n\u001b$BXG\u001b(B\n\u001b$BXH\u001b(B\n\u001b$BXI\u001b(B\n\u001b$BXJ\u001b(B\n\u001b$BXK\u001b(B\n\u001b$BXL\u001b(B\n\u001b$BXM\u001b(B\n\u001b$BXN\u001b(B\n\u001b$BXO\u001b(B\n\u001b$BXP\u001b(B\n\u001b$BXQ\u001b(B\n\u001b$BXR\u001b(B\n\u001b$BXS\u001b(B\n\u001b$BXT\u001b(B\n\u001b$BXU\u001b(B\n\u001b$BXV\u001b(B\n\u001b$BXW\u001b(B\n\u001b$BXX\u001b(B\n\u001b$BXY\u001b(B\n\u001b$BXZ\u001b(B\n\u001b$BX[\u001b(B\n\u001b$BX\\\u001b(B\n\u001b$BX]\u001b(B\n\u001b$BX^\u001b(B\n\u001b$BX_\u001b(B\n\u001b$BX`\u001b(B\n\u001b$BXa\u001b(B\n\u001b$BXb\u001b(B\n\u001b$BXc\u001b(B\n\u001b$BXd\u001b(B\n\u001b$BXe\u001b(B\n\u001b$BXf\u001b(B\n\u001b$BXg\u001b(B\n\u001b$BXh\u001b(B\n\u001b$BXi\u001b(B\n\u001b$BXj\u001b(B\n\u001b$BXk\u001b(B\n\u001b$BXl\u001b(B\n\u001b$BXm\u001b(B\n\u001b$BXn\u001b(B\n\u001b$BXo\u001b(B\n\u001b$BXp\u001b(B\n\u001b$BXq\u001b(B\n\u001b$BXr\u001b(B\n\u001b$BXs\u001b(B\n\u001b$BXt\u001b(B\n\u001b$BXu\u001b(B\n\u001b$BXv\u001b(B\n\u001b$BXw\u001b(B\n\u001b$BXx\u001b(B\n\u001b$BXy\u001b(B\n\u001b$BXz\u001b(B\n\u001b$BX{\u001b(B\n\u001b$BX|\u001b(B\n\u001b$BX}\u001b(B\n\u001b$BX~\u001b(B\n\u001b$BY!\u001b(B\n\u001b$BY\"\u001b(B\n\u001b$BY#\u001b(B\n\u001b$BY$\u001b(B\n\u001b$BY%\u001b(B\n\u001b$BY&\u001b(B\n\u001b$BY'\u001b(B\n\u001b$BY(\u001b(B\n\u001b$BY)\u001b(B\n\u001b$BY*\u001b(B\n\u001b$BY+\u001b(B\n\u001b$BY,\u001b(B\n\u001b$BY-\u001b(B\n\u001b$BY.\u001b(B\n\u001b$BY/\u001b(B\n\u001b$BY0\u001b(B\n\u001b$BY1\u001b(B\n\u001b$BY2\u001b(B\n\u001b$BY3\u001b(B\n\u001b$BY4\u001b(B\n\u001b$BY5\u001b(B\n\u001b$BY6\u001b(B\n\u001b$BY7\u001b(B\n\u001b$BY8\u001b(B\n\u001b$BY9\u001b(B\n\u001b$BY:\u001b(B\n\u001b$BY;\u001b(B\n\u001b$BY<\u001b(B\n\u001b$BY=\u001b(B\n\u001b$BY>\u001b(B\n\u001b$BY?\u001b(B\n\u001b$BY@\u001b(B\n\u001b$BYA\u001b(B\n\u001b$BYB\u001b(B\n\u001b$BYC\u001b(B\n\u001b$BYD\u001b(B\n\u001b$BYE\u001b(B\n\u001b$BYF\u001b(B\n\u001b$BYG\u001b(B\n\u001b$BYH\u001b(B\n\u001b$BYI\u001b(B\n\u001b$BYJ\u001b(B\n\u001b$BYK\u001b(B\n\u001b$BYL\u001b(B\n\u001b$BYM\u001b(B\n\u001b$BYN\u001b(B\n\u001b$BYO\u001b(B\n\u001b$BYP\u001b(B\n\u001b$BYQ\u001b(B\n\u001b$BYR\u001b(B\n\u001b$BYS\u001b(B\n\u001b$BYT\u001b(B\n\u001b$BYU\u001b(B\n\u001b$BYV\u001b(B\n\u001b$BYW\u001b(B\n\u001b$BYX\u001b(B\n\u001b$BYY\u001b(B\n\u001b$BYZ\u001b(B\n\u001b$BY[\u001b(B\n\u001b$BY\\\u001b(B\n\u001b$BY]\u001b(B\n\u001b$BY^\u001b(B\n\u001b$BY_\u001b(B\n\u001b$BY`\u001b(B\n\u001b$BYa\u001b(B\n\u001b$BYb\u001b(B\n\u001b$BYc\u001b(B\n\u001b$BYd\u001b(B\n\u001b$BYe\u001b(B\n\u001b$BYf\u001b(B\n\u001b$BYg\u001b(B\n\u001b$BYh\u001b(B\n\u001b$BYi\u001b(B\n\u001b$BYj\u001b(B\n\u001b$BYk\u001b(B\n\u001b$BYl\u001b(B\n\u001b$BYm\u001b(B\n\u001b$BYn\u001b(B\n\u001b$BYo\u001b(B\n\u001b$BYp\u001b(B\n\u001b$BYq\u001b(B\n\u001b$BYr\u001b(B\n\u001b$BYs\u001b(B\n\u001b$BYt\u001b(B\n\u001b$BYu\u001b(B\n\u001b$BYv\u001b(B\n\u001b$BYw\u001b(B\n\u001b$BYx\u001b(B\n\u001b$BYy\u001b(B\n\u001b$BYz\u001b(B\n\u001b$BY{\u001b(B\n\u001b$BY|\u001b(B\n\u001b$BY}\u001b(B\n\u001b$BY~\u001b(B\n\u001b$BZ!\u001b(B\n\u001b$BZ\"\u001b(B\n\u001b$BZ#\u001b(B\n\u001b$BZ$\u001b(B\n\u001b$BZ%\u001b(B\n\u001b$BZ&\u001b(B\n\u001b$BZ'\u001b(B\n\u001b$BZ(\u001b(B\n\u001b$BZ)\u001b(B\n\u001b$BZ*\u001b(B\n\u001b$BZ+\u001b(B\n\u001b$BZ,\u001b(B\n\u001b$BZ-\u001b(B\n\u001b$BZ.\u001b(B\n\u001b$BZ/\u001b(B\n\u001b$BZ0\u001b(B\n\u001b$BZ1\u001b(B\n\u001b$BZ2\u001b(B\n\u001b$BZ3\u001b(B\n\u001b$BZ4\u001b(B\n\u001b$BZ5\u001b(B\n\u001b$BZ6\u001b(B\n\u001b$BZ7\u001b(B\n\u001b$BZ8\u001b(B\n\u001b$BZ9\u001b(B\n\u001b$BZ:\u001b(B\n\u001b$BZ;\u001b(B\n\u001b$BZ<\u001b(B\n\u001b$BZ=\u001b(B\n\u001b$BZ>\u001b(B\n\u001b$BZ?\u001b(B\n\u001b$BZ@\u001b(B\n\u001b$BZA\u001b(B\n\u001b$BZB\u001b(B\n\u001b$BZC\u001b(B\n\u001b$BZD\u001b(B\n\u001b$BZE\u001b(B\n\u001b$BZF\u001b(B\n\u001b$BZG\u001b(B\n\u001b$BZH\u001b(B\n\u001b$BZI\u001b(B\n\u001b$BZJ\u001b(B\n\u001b$BZK\u001b(B\n\u001b$BZL\u001b(B\n\u001b$BZM\u001b(B\n\u001b$BZN\u001b(B\n\u001b$BZO\u001b(B\n\u001b$BZP\u001b(B\n\u001b$BZQ\u001b(B\n\u001b$BZR\u001b(B\n\u001b$BZS\u001b(B\n\u001b$BZT\u001b(B\n\u001b$BZU\u001b(B\n\u001b$BZV\u001b(B\n\u001b$BZW\u001b(B\n\u001b$BZX\u001b(B\n\u001b$BZY\u001b(B\n\u001b$BZZ\u001b(B\n\u001b$BZ[\u001b(B\n\u001b$BZ\\\u001b(B\n\u001b$BZ]\u001b(B\n\u001b$BZ^\u001b(B\n\u001b$BZ_\u001b(B\n\u001b$BZ`\u001b(B\n\u001b$BZa\u001b(B\n\u001b$BZb\u001b(B\n\u001b$BZc\u001b(B\n\u001b$BZd\u001b(B\n\u001b$BZe\u001b(B\n\u001b$BZf\u001b(B\n\u001b$BZg\u001b(B\n\u001b$BZh\u001b(B\n\u001b$BZi\u001b(B\n\u001b$BZj\u001b(B\n\u001b$BZk\u001b(B\n\u001b$BZl\u001b(B\n\u001b$BZm\u001b(B\n\u001b$BZn\u001b(B\n\u001b$BZo\u001b(B\n\u001b$BZp\u001b(B\n\u001b$BZq\u001b(B\n\u001b$BZr\u001b(B\n\u001b$BZs\u001b(B\n\u001b$BZt\u001b(B\n\u001b$BZu\u001b(B\n\u001b$BZv\u001b(B\n\u001b$BZw\u001b(B\n\u001b$BZx\u001b(B\n\u001b$BZy\u001b(B\n\u001b$BZz\u001b(B\n\u001b$BZ{\u001b(B\n\u001b$BZ|\u001b(B\n\u001b$BZ}\u001b(B\n\u001b$BZ~\u001b(B\n\u001b$B[!\u001b(B\n\u001b$B[\"\u001b(B\n\u001b$B[#\u001b(B\n\u001b$B[$\u001b(B\n\u001b$B[%\u001b(B\n\u001b$B[&\u001b(B\n\u001b$B['\u001b(B\n\u001b$B[(\u001b(B\n\u001b$B[)\u001b(B\n\u001b$B[*\u001b(B\n\u001b$B[+\u001b(B\n\u001b$B[,\u001b(B\n\u001b$B[-\u001b(B\n\u001b$B[.\u001b(B\n\u001b$B[/\u001b(B\n\u001b$B[0\u001b(B\n\u001b$B[1\u001b(B\n\u001b$B[2\u001b(B\n\u001b$B[3\u001b(B\n\u001b$B[4\u001b(B\n\u001b$B[5\u001b(B\n\u001b$B[6\u001b(B\n\u001b$B[7\u001b(B\n\u001b$B[8\u001b(B\n\u001b$B[9\u001b(B\n\u001b$B[:\u001b(B\n\u001b$B[;\u001b(B\n\u001b$B[<\u001b(B\n\u001b$B[=\u001b(B\n\u001b$B[>\u001b(B\n\u001b$B[?\u001b(B\n\u001b$B[@\u001b(B\n\u001b$B[A\u001b(B\n\u001b$B[B\u001b(B\n\u001b$B[C\u001b(B\n\u001b$B[D\u001b(B\n\u001b$B[E\u001b(B\n\u001b$B[F\u001b(B\n\u001b$B[G\u001b(B\n\u001b$B[H\u001b(B\n\u001b$B[I\u001b(B\n\u001b$B[J\u001b(B\n\u001b$B[K\u001b(B\n\u001b$B[L\u001b(B\n\u001b$B[M\u001b(B\n\u001b$B[N\u001b(B\n\u001b$B[O\u001b(B\n\u001b$B[P\u001b(B\n\u001b$B[Q\u001b(B\n\u001b$B[R\u001b(B\n\u001b$B[S\u001b(B\n\u001b$B[T\u001b(B\n\u001b$B[U\u001b(B\n\u001b$B[V\u001b(B\n\u001b$B[W\u001b(B\n\u001b$B[X\u001b(B\n\u001b$B[Y\u001b(B\n\u001b$B[Z\u001b(B\n\u001b$B[[\u001b(B\n\u001b$B[\\\u001b(B\n\u001b$B[]\u001b(B\n\u001b$B[^\u001b(B\n\u001b$B[_\u001b(B\n\u001b$B[`\u001b(B\n\u001b$B[a\u001b(B\n\u001b$B[b\u001b(B\n\u001b$B[c\u001b(B\n\u001b$B[d\u001b(B\n\u001b$B[e\u001b(B\n\u001b$B[f\u001b(B\n\u001b$B[g\u001b(B\n\u001b$B[h\u001b(B\n\u001b$B[i\u001b(B\n\u001b$B[j\u001b(B\n\u001b$B[k\u001b(B\n\u001b$B[l\u001b(B\n\u001b$B[m\u001b(B\n\u001b$B[n\u001b(B\n\u001b$B[o\u001b(B\n\u001b$B[p\u001b(B\n\u001b$B[q\u001b(B\n\u001b$B[r\u001b(B\n\u001b$B[s\u001b(B\n\u001b$B[t\u001b(B\n\u001b$B[u\u001b(B\n\u001b$B[v\u001b(B\n\u001b$B[w\u001b(B\n\u001b$B[x\u001b(B\n\u001b$B[y\u001b(B\n\u001b$B[z\u001b(B\n\u001b$B[{\u001b(B\n\u001b$B[|\u001b(B\n\u001b$B[}\u001b(B\n\u001b$B[~\u001b(B\n\u001b$B\\!\u001b(B\n\u001b$B\\\"\u001b(B\n\u001b$B\\#\u001b(B\n\u001b$B\\$\u001b(B\n\u001b$B\\%\u001b(B\n\u001b$B\\&\u001b(B\n\u001b$B\\'\u001b(B\n\u001b$B\\(\u001b(B\n\u001b$B\\)\u001b(B\n\u001b$B\\*\u001b(B\n\u001b$B\\+\u001b(B\n\u001b$B\\,\u001b(B\n\u001b$B\\-\u001b(B\n\u001b$B\\.\u001b(B\n\u001b$B\\/\u001b(B\n\u001b$B\\0\u001b(B\n\u001b$B\\1\u001b(B\n\u001b$B\\2\u001b(B\n\u001b$B\\3\u001b(B\n\u001b$B\\4\u001b(B\n\u001b$B\\5\u001b(B\n\u001b$B\\6\u001b(B\n\u001b$B\\7\u001b(B\n\u001b$B\\8\u001b(B\n\u001b$B\\9\u001b(B\n\u001b$B\\:\u001b(B\n\u001b$B\\;\u001b(B\n\u001b$B\\<\u001b(B\n\u001b$B\\=\u001b(B\n\u001b$B\\>\u001b(B\n\u001b$B\\?\u001b(B\n\u001b$B\\@\u001b(B\n\u001b$B\\A\u001b(B\n\u001b$B\\B\u001b(B\n\u001b$B\\C\u001b(B\n\u001b$B\\D\u001b(B\n\u001b$B\\E\u001b(B\n\u001b$B\\F\u001b(B\n\u001b$B\\G\u001b(B\n\u001b$B\\H\u001b(B\n\u001b$B\\I\u001b(B\n\u001b$B\\J\u001b(B\n\u001b$B\\K\u001b(B\n\u001b$B\\L\u001b(B\n\u001b$B\\M\u001b(B\n\u001b$B\\N\u001b(B\n\u001b$B\\O\u001b(B\n\u001b$B\\P\u001b(B\n\u001b$B\\Q\u001b(B\n\u001b$B\\R\u001b(B\n\u001b$B\\S\u001b(B\n\u001b$B\\T\u001b(B\n\u001b$B\\U\u001b(B\n\u001b$B\\V\u001b(B\n\u001b$B\\W\u001b(B\n\u001b$B\\X\u001b(B\n\u001b$B\\Y\u001b(B\n\u001b$B\\Z\u001b(B\n\u001b$B\\[\u001b(B\n\u001b$B\\\\\u001b(B\n\u001b$B\\]\u001b(B\n\u001b$B\\^\u001b(B\n\u001b$B\\_\u001b(B\n\u001b$B\\`\u001b(B\n\u001b$B\\a\u001b(B\n\u001b$B\\b\u001b(B\n\u001b$B\\c\u001b(B\n\u001b$B\\d\u001b(B\n\u001b$B\\e\u001b(B\n\u001b$B\\f\u001b(B\n\u001b$B\\g\u001b(B\n\u001b$B\\h\u001b(B\n\u001b$B\\i\u001b(B\n\u001b$B\\j\u001b(B\n\u001b$B\\k\u001b(B\n\u001b$B\\l\u001b(B\n\u001b$B\\m\u001b(B\n\u001b$B\\n\u001b(B\n\u001b$B\\o\u001b(B\n\u001b$B\\p\u001b(B\n\u001b$B\\q\u001b(B\n\u001b$B\\r\u001b(B\n\u001b$B\\s\u001b(B\n\u001b$B\\t\u001b(B\n\u001b$B\\u\u001b(B\n\u001b$B\\v\u001b(B\n\u001b$B\\w\u001b(B\n\u001b$B\\x\u001b(B\n\u001b$B\\y\u001b(B\n\u001b$B\\z\u001b(B\n\u001b$B\\{\u001b(B\n\u001b$B\\|\u001b(B\n\u001b$B\\}\u001b(B\n\u001b$B\\~\u001b(B\n\u001b$B]!\u001b(B\n\u001b$B]\"\u001b(B\n\u001b$B]#\u001b(B\n\u001b$B]$\u001b(B\n\u001b$B]%\u001b(B\n\u001b$B]&\u001b(B\n\u001b$B]'\u001b(B\n\u001b$B](\u001b(B\n\u001b$B])\u001b(B\n\u001b$B]*\u001b(B\n\u001b$B]+\u001b(B\n\u001b$B],\u001b(B\n\u001b$B]-\u001b(B\n\u001b$B].\u001b(B\n\u001b$B]/\u001b(B\n\u001b$B]0\u001b(B\n\u001b$B]1\u001b(B\n\u001b$B]2\u001b(B\n\u001b$B]3\u001b(B\n\u001b$B]4\u001b(B\n\u001b$B]5\u001b(B\n\u001b$B]6\u001b(B\n\u001b$B]7\u001b(B\n\u001b$B]8\u001b(B\n\u001b$B]9\u001b(B\n\u001b$B]:\u001b(B\n\u001b$B];\u001b(B\n\u001b$B]<\u001b(B\n\u001b$B]=\u001b(B\n\u001b$B]>\u001b(B\n\u001b$B]?\u001b(B\n\u001b$B]@\u001b(B\n\u001b$B]A\u001b(B\n\u001b$B]B\u001b(B\n\u001b$B]C\u001b(B\n\u001b$B]D\u001b(B\n\u001b$B]E\u001b(B\n\u001b$B]F\u001b(B\n\u001b$B]G\u001b(B\n\u001b$B]H\u001b(B\n\u001b$B]I\u001b(B\n\u001b$B]J\u001b(B\n\u001b$B]K\u001b(B\n\u001b$B]L\u001b(B\n\u001b$B]M\u001b(B\n\u001b$B]N\u001b(B\n\u001b$B]O\u001b(B\n\u001b$B]P\u001b(B\n\u001b$B]Q\u001b(B\n\u001b$B]R\u001b(B\n\u001b$B]S\u001b(B\n\u001b$B]T\u001b(B\n\u001b$B]U\u001b(B\n\u001b$B]V\u001b(B\n\u001b$B]W\u001b(B\n\u001b$B]X\u001b(B\n\u001b$B]Y\u001b(B\n\u001b$B]Z\u001b(B\n\u001b$B][\u001b(B\n\u001b$B]\\\u001b(B\n\u001b$B]]\u001b(B\n\u001b$B]^\u001b(B\n\u001b$B]_\u001b(B\n\u001b$B]`\u001b(B\n\u001b$B]a\u001b(B\n\u001b$B]b\u001b(B\n\u001b$B]c\u001b(B\n\u001b$B]d\u001b(B\n\u001b$B]e\u001b(B\n\u001b$B]f\u001b(B\n\u001b$B]g\u001b(B\n\u001b$B]h\u001b(B\n\u001b$B]i\u001b(B\n\u001b$B]j\u001b(B\n\u001b$B]k\u001b(B\n\u001b$B]l\u001b(B\n\u001b$B]m\u001b(B\n\u001b$B]n\u001b(B\n\u001b$B]o\u001b(B\n\u001b$B]p\u001b(B\n\u001b$B]q\u001b(B\n\u001b$B]r\u001b(B\n\u001b$B]s\u001b(B\n\u001b$B]t\u001b(B\n\u001b$B]u\u001b(B\n\u001b$B]v\u001b(B\n\u001b$B]w\u001b(B\n\u001b$B]x\u001b(B\n\u001b$B]y\u001b(B\n\u001b$B]z\u001b(B\n\u001b$B]{\u001b(B\n\u001b$B]|\u001b(B\n\u001b$B]}\u001b(B\n\u001b$B]~\u001b(B\n\u001b$B^!\u001b(B\n\u001b$B^\"\u001b(B\n\u001b$B^#\u001b(B\n\u001b$B^$\u001b(B\n\u001b$B^%\u001b(B\n\u001b$B^&\u001b(B\n\u001b$B^'\u001b(B\n\u001b$B^(\u001b(B\n\u001b$B^)\u001b(B\n\u001b$B^*\u001b(B\n\u001b$B^+\u001b(B\n\u001b$B^,\u001b(B\n\u001b$B^-\u001b(B\n\u001b$B^.\u001b(B\n\u001b$B^/\u001b(B\n\u001b$B^0\u001b(B\n\u001b$B^1\u001b(B\n\u001b$B^2\u001b(B\n\u001b$B^3\u001b(B\n\u001b$B^4\u001b(B\n\u001b$B^5\u001b(B\n\u001b$B^6\u001b(B\n\u001b$B^7\u001b(B\n\u001b$B^8\u001b(B\n\u001b$B^9\u001b(B\n\u001b$B^:\u001b(B\n\u001b$B^;\u001b(B\n\u001b$B^<\u001b(B\n\u001b$B^=\u001b(B\n\u001b$B^>\u001b(B\n\u001b$B^?\u001b(B\n\u001b$B^@\u001b(B\n\u001b$B^A\u001b(B\n\u001b$B^B\u001b(B\n\u001b$B^C\u001b(B\n\u001b$B^D\u001b(B\n\u001b$B^E\u001b(B\n\u001b$B^F\u001b(B\n\u001b$B^G\u001b(B\n\u001b$B^H\u001b(B\n\u001b$B^I\u001b(B\n\u001b$B^J\u001b(B\n\u001b$B^K\u001b(B\n\u001b$B^L\u001b(B\n\u001b$B^M\u001b(B\n\u001b$B^N\u001b(B\n\u001b$B^O\u001b(B\n\u001b$B^P\u001b(B\n\u001b$B^Q\u001b(B\n\u001b$B^R\u001b(B\n\u001b$B^S\u001b(B\n\u001b$B^T\u001b(B\n\u001b$B^U\u001b(B\n\u001b$B^V\u001b(B\n\u001b$B^W\u001b(B\n\u001b$B^X\u001b(B\n\u001b$B^Y\u001b(B\n\u001b$B^Z\u001b(B\n\u001b$B^[\u001b(B\n\u001b$B^\\\u001b(B\n\u001b$B^]\u001b(B\n\u001b$B^^\u001b(B\n\u001b$B^_\u001b(B\n\u001b$B^`\u001b(B\n\u001b$B^a\u001b(B\n\u001b$B^b\u001b(B\n\u001b$B^c\u001b(B\n\u001b$B^d\u001b(B\n\u001b$B^e\u001b(B\n\u001b$B^f\u001b(B\n\u001b$B^g\u001b(B\n\u001b$B^h\u001b(B\n\u001b$B^i\u001b(B\n\u001b$B^j\u001b(B\n\u001b$B^k\u001b(B\n\u001b$B^l\u001b(B\n\u001b$B^m\u001b(B\n\u001b$B^n\u001b(B\n\u001b$B^o\u001b(B\n\u001b$B^p\u001b(B\n\u001b$B^q\u001b(B\n\u001b$B^r\u001b(B\n\u001b$B^s\u001b(B\n\u001b$B^t\u001b(B\n\u001b$B^u\u001b(B\n\u001b$B^v\u001b(B\n\u001b$B^w\u001b(B\n\u001b$B^x\u001b(B\n\u001b$B^y\u001b(B\n\u001b$B^z\u001b(B\n\u001b$B^{\u001b(B\n\u001b$B^|\u001b(B\n\u001b$B^}\u001b(B\n\u001b$B^~\u001b(B\n\u001b$B_!\u001b(B\n\u001b$B_\"\u001b(B\n\u001b$B_#\u001b(B\n\u001b$B_$\u001b(B\n\u001b$B_%\u001b(B\n\u001b$B_&\u001b(B\n\u001b$B_'\u001b(B\n\u001b$B_(\u001b(B\n\u001b$B_)\u001b(B\n\u001b$B_*\u001b(B\n\u001b$B_+\u001b(B\n\u001b$B_,\u001b(B\n\u001b$B_-\u001b(B\n\u001b$B_.\u001b(B\n\u001b$B_/\u001b(B\n\u001b$B_0\u001b(B\n\u001b$B_1\u001b(B\n\u001b$B_2\u001b(B\n\u001b$B_3\u001b(B\n\u001b$B_4\u001b(B\n\u001b$B_5\u001b(B\n\u001b$B_6\u001b(B\n\u001b$B_7\u001b(B\n\u001b$B_8\u001b(B\n\u001b$B_9\u001b(B\n\u001b$B_:\u001b(B\n\u001b$B_;\u001b(B\n\u001b$B_<\u001b(B\n\u001b$B_=\u001b(B\n\u001b$B_>\u001b(B\n\u001b$B_?\u001b(B\n\u001b$B_@\u001b(B\n\u001b$B_A\u001b(B\n\u001b$B_B\u001b(B\n\u001b$B_C\u001b(B\n\u001b$B_D\u001b(B\n\u001b$B_E\u001b(B\n\u001b$B_F\u001b(B\n\u001b$B_G\u001b(B\n\u001b$B_H\u001b(B\n\u001b$B_I\u001b(B\n\u001b$B_J\u001b(B\n\u001b$B_K\u001b(B\n\u001b$B_L\u001b(B\n\u001b$B_M\u001b(B\n\u001b$B_N\u001b(B\n\u001b$B_O\u001b(B\n\u001b$B_P\u001b(B\n\u001b$B_Q\u001b(B\n\u001b$B_R\u001b(B\n\u001b$B_S\u001b(B\n\u001b$B_T\u001b(B\n\u001b$B_U\u001b(B\n\u001b$B_V\u001b(B\n\u001b$B_W\u001b(B\n\u001b$B_X\u001b(B\n\u001b$B_Y\u001b(B\n\u001b$B_Z\u001b(B\n\u001b$B_[\u001b(B\n\u001b$B_\\\u001b(B\n\u001b$B_]\u001b(B\n\u001b$B_^\u001b(B\n\u001b$B__\u001b(B\n\u001b$B_`\u001b(B\n\u001b$B_a\u001b(B\n\u001b$B_b\u001b(B\n\u001b$B_c\u001b(B\n\u001b$B_d\u001b(B\n\u001b$B_e\u001b(B\n\u001b$B_f\u001b(B\n\u001b$B_g\u001b(B\n\u001b$B_h\u001b(B\n\u001b$B_i\u001b(B\n\u001b$B_j\u001b(B\n\u001b$B_k\u001b(B\n\u001b$B_l\u001b(B\n\u001b$B_m\u001b(B\n\u001b$B_n\u001b(B\n\u001b$B_o\u001b(B\n\u001b$B_p\u001b(B\n\u001b$B_q\u001b(B\n\u001b$B_r\u001b(B\n\u001b$B_s\u001b(B\n\u001b$B_t\u001b(B\n\u001b$B_u\u001b(B\n\u001b$B_v\u001b(B\n\u001b$B_w\u001b(B\n\u001b$B_x\u001b(B\n\u001b$B_y\u001b(B\n\u001b$B_z\u001b(B\n\u001b$B_{\u001b(B\n\u001b$B_|\u001b(B\n\u001b$B_}\u001b(B\n\u001b$B_~\u001b(B\n\u001b$B`!\u001b(B\n\u001b$B`\"\u001b(B\n\u001b$B`#\u001b(B\n\u001b$B`$\u001b(B\n\u001b$B`%\u001b(B\n\u001b$B`&\u001b(B\n\u001b$B`'\u001b(B\n\u001b$B`(\u001b(B\n\u001b$B`)\u001b(B\n\u001b$B`*\u001b(B\n\u001b$B`+\u001b(B\n\u001b$B`,\u001b(B\n\u001b$B`-\u001b(B\n\u001b$B`.\u001b(B\n\u001b$B`/\u001b(B\n\u001b$B`0\u001b(B\n\u001b$B`1\u001b(B\n\u001b$B`2\u001b(B\n\u001b$B`3\u001b(B\n\u001b$B`4\u001b(B\n\u001b$B`5\u001b(B\n\u001b$B`6\u001b(B\n\u001b$B`7\u001b(B\n\u001b$B`8\u001b(B\n\u001b$B`9\u001b(B\n\u001b$B`:\u001b(B\n\u001b$B`;\u001b(B\n\u001b$B`<\u001b(B\n\u001b$B`=\u001b(B\n\u001b$B`>\u001b(B\n\u001b$B`?\u001b(B\n\u001b$B`@\u001b(B\n\u001b$B`A\u001b(B\n\u001b$B`B\u001b(B\n\u001b$B`C\u001b(B\n\u001b$B`D\u001b(B\n\u001b$B`E\u001b(B\n\u001b$B`F\u001b(B\n\u001b$B`G\u001b(B\n\u001b$B`H\u001b(B\n\u001b$B`I\u001b(B\n\u001b$B`J\u001b(B\n\u001b$B`K\u001b(B\n\u001b$B`L\u001b(B\n\u001b$B`M\u001b(B\n\u001b$B`N\u001b(B\n\u001b$B`O\u001b(B\n\u001b$B`P\u001b(B\n\u001b$B`Q\u001b(B\n\u001b$B`R\u001b(B\n\u001b$B`S\u001b(B\n\u001b$B`T\u001b(B\n\u001b$B`U\u001b(B\n\u001b$B`V\u001b(B\n\u001b$B`W\u001b(B\n\u001b$B`X\u001b(B\n\u001b$B`Y\u001b(B\n\u001b$B`Z\u001b(B\n\u001b$B`[\u001b(B\n\u001b$B`\\\u001b(B\n\u001b$B`]\u001b(B\n\u001b$B`^\u001b(B\n\u001b$B`_\u001b(B\n\u001b$B``\u001b(B\n\u001b$B`a\u001b(B\n\u001b$B`b\u001b(B\n\u001b$B`c\u001b(B\n\u001b$B`d\u001b(B\n\u001b$B`e\u001b(B\n\u001b$B`f\u001b(B\n\u001b$B`g\u001b(B\n\u001b$B`h\u001b(B\n\u001b$B`i\u001b(B\n\u001b$B`j\u001b(B\n\u001b$B`k\u001b(B\n\u001b$B`l\u001b(B\n\u001b$B`m\u001b(B\n\u001b$B`n\u001b(B\n\u001b$B`o\u001b(B\n\u001b$B`p\u001b(B\n\u001b$B`q\u001b(B\n\u001b$B`r\u001b(B\n\u001b$B`s\u001b(B\n\u001b$B`t\u001b(B\n\u001b$B`u\u001b(B\n\u001b$B`v\u001b(B\n\u001b$B`w\u001b(B\n\u001b$B`x\u001b(B\n\u001b$B`y\u001b(B\n\u001b$B`z\u001b(B\n\u001b$B`{\u001b(B\n\u001b$B`|\u001b(B\n\u001b$B`}\u001b(B\n\u001b$B`~\u001b(B\n\u001b$Ba!\u001b(B\n\u001b$Ba\"\u001b(B\n\u001b$Ba#\u001b(B\n\u001b$Ba$\u001b(B\n\u001b$Ba%\u001b(B\n\u001b$Ba&\u001b(B\n\u001b$Ba'\u001b(B\n\u001b$Ba(\u001b(B\n\u001b$Ba)\u001b(B\n\u001b$Ba*\u001b(B\n\u001b$Ba+\u001b(B\n\u001b$Ba,\u001b(B\n\u001b$Ba-\u001b(B\n\u001b$Ba.\u001b(B\n\u001b$Ba/\u001b(B\n\u001b$Ba0\u001b(B\n\u001b$Ba1\u001b(B\n\u001b$Ba2\u001b(B\n\u001b$Ba3\u001b(B\n\u001b$Ba4\u001b(B\n\u001b$Ba5\u001b(B\n\u001b$Ba6\u001b(B\n\u001b$Ba7\u001b(B\n\u001b$Ba8\u001b(B\n\u001b$Ba9\u001b(B\n\u001b$Ba:\u001b(B\n\u001b$Ba;\u001b(B\n\u001b$Ba<\u001b(B\n\u001b$Ba=\u001b(B\n\u001b$Ba>\u001b(B\n\u001b$Ba?\u001b(B\n\u001b$Ba@\u001b(B\n\u001b$BaA\u001b(B\n\u001b$BaB\u001b(B\n\u001b$BaC\u001b(B\n\u001b$BaD\u001b(B\n\u001b$BaE\u001b(B\n\u001b$BaF\u001b(B\n\u001b$BaG\u001b(B\n\u001b$BaH\u001b(B\n\u001b$BaI\u001b(B\n\u001b$BaJ\u001b(B\n\u001b$BaK\u001b(B\n\u001b$BaL\u001b(B\n\u001b$BaM\u001b(B\n\u001b$BaN\u001b(B\n\u001b$BaO\u001b(B\n\u001b$BaP\u001b(B\n\u001b$BaQ\u001b(B\n\u001b$BaR\u001b(B\n\u001b$BaS\u001b(B\n\u001b$BaT\u001b(B\n\u001b$BaU\u001b(B\n\u001b$BaV\u001b(B\n\u001b$BaW\u001b(B\n\u001b$BaX\u001b(B\n\u001b$BaY\u001b(B\n\u001b$BaZ\u001b(B\n\u001b$Ba[\u001b(B\n\u001b$Ba\\\u001b(B\n\u001b$Ba]\u001b(B\n\u001b$Ba^\u001b(B\n\u001b$Ba_\u001b(B\n\u001b$Ba`\u001b(B\n\u001b$Baa\u001b(B\n\u001b$Bab\u001b(B\n\u001b$Bac\u001b(B\n\u001b$Bad\u001b(B\n\u001b$Bae\u001b(B\n\u001b$Baf\u001b(B\n\u001b$Bag\u001b(B\n\u001b$Bah\u001b(B\n\u001b$Bai\u001b(B\n\u001b$Baj\u001b(B\n\u001b$Bak\u001b(B\n\u001b$Bal\u001b(B\n\u001b$Bam\u001b(B\n\u001b$Ban\u001b(B\n\u001b$Bao\u001b(B\n\u001b$Bap\u001b(B\n\u001b$Baq\u001b(B\n\u001b$Bar\u001b(B\n\u001b$Bas\u001b(B\n\u001b$Bat\u001b(B\n\u001b$Bau\u001b(B\n\u001b$Bav\u001b(B\n\u001b$Baw\u001b(B\n\u001b$Bax\u001b(B\n\u001b$Bay\u001b(B\n\u001b$Baz\u001b(B\n\u001b$Ba{\u001b(B\n\u001b$Ba|\u001b(B\n\u001b$Ba}\u001b(B\n\u001b$Ba~\u001b(B\n\u001b$Bb!\u001b(B\n\u001b$Bb\"\u001b(B\n\u001b$Bb#\u001b(B\n\u001b$Bb$\u001b(B\n\u001b$Bb%\u001b(B\n\u001b$Bb&\u001b(B\n\u001b$Bb'\u001b(B\n\u001b$Bb(\u001b(B\n\u001b$Bb)\u001b(B\n\u001b$Bb*\u001b(B\n\u001b$Bb+\u001b(B\n\u001b$Bb,\u001b(B\n\u001b$Bb-\u001b(B\n\u001b$Bb.\u001b(B\n\u001b$Bb/\u001b(B\n\u001b$Bb0\u001b(B\n\u001b$Bb1\u001b(B\n\u001b$Bb2\u001b(B\n\u001b$Bb3\u001b(B\n\u001b$Bb4\u001b(B\n\u001b$Bb5\u001b(B\n\u001b$Bb6\u001b(B\n\u001b$Bb7\u001b(B\n\u001b$Bb8\u001b(B\n\u001b$Bb9\u001b(B\n\u001b$Bb:\u001b(B\n\u001b$Bb;\u001b(B\n\u001b$Bb<\u001b(B\n\u001b$Bb=\u001b(B\n\u001b$Bb>\u001b(B\n\u001b$Bb?\u001b(B\n\u001b$Bb@\u001b(B\n\u001b$BbA\u001b(B\n\u001b$BbB\u001b(B\n\u001b$BbC\u001b(B\n\u001b$BbD\u001b(B\n\u001b$BbE\u001b(B\n\u001b$BbF\u001b(B\n\u001b$BbG\u001b(B\n\u001b$BbH\u001b(B\n\u001b$BbI\u001b(B\n\u001b$BbJ\u001b(B\n\u001b$BbK\u001b(B\n\u001b$BbL\u001b(B\n\u001b$BbM\u001b(B\n\u001b$BbN\u001b(B\n\u001b$BbO\u001b(B\n\u001b$BbP\u001b(B\n\u001b$BbQ\u001b(B\n\u001b$BbR\u001b(B\n\u001b$BbS\u001b(B\n\u001b$BbT\u001b(B\n\u001b$BbU\u001b(B\n\u001b$BbV\u001b(B\n\u001b$BbW\u001b(B\n\u001b$BbX\u001b(B\n\u001b$BbY\u001b(B\n\u001b$BbZ\u001b(B\n\u001b$Bb[\u001b(B\n\u001b$Bb\\\u001b(B\n\u001b$Bb]\u001b(B\n\u001b$Bb^\u001b(B\n\u001b$Bb_\u001b(B\n\u001b$Bb`\u001b(B\n\u001b$Bba\u001b(B\n\u001b$Bbb\u001b(B\n\u001b$Bbc\u001b(B\n\u001b$Bbd\u001b(B\n\u001b$Bbe\u001b(B\n\u001b$Bbf\u001b(B\n\u001b$Bbg\u001b(B\n\u001b$Bbh\u001b(B\n\u001b$Bbi\u001b(B\n\u001b$Bbj\u001b(B\n\u001b$Bbk\u001b(B\n\u001b$Bbl\u001b(B\n\u001b$Bbm\u001b(B\n\u001b$Bbn\u001b(B\n\u001b$Bbo\u001b(B\n\u001b$Bbp\u001b(B\n\u001b$Bbq\u001b(B\n\u001b$Bbr\u001b(B\n\u001b$Bbs\u001b(B\n\u001b$Bbt\u001b(B\n\u001b$Bbu\u001b(B\n\u001b$Bbv\u001b(B\n\u001b$Bbw\u001b(B\n\u001b$Bbx\u001b(B\n\u001b$Bby\u001b(B\n\u001b$Bbz\u001b(B\n\u001b$Bb{\u001b(B\n\u001b$Bb|\u001b(B\n\u001b$Bb}\u001b(B\n\u001b$Bb~\u001b(B\n\u001b$Bc!\u001b(B\n\u001b$Bc\"\u001b(B\n\u001b$Bc#\u001b(B\n\u001b$Bc$\u001b(B\n\u001b$Bc%\u001b(B\n\u001b$Bc&\u001b(B\n\u001b$Bc'\u001b(B\n\u001b$Bc(\u001b(B\n\u001b$Bc)\u001b(B\n\u001b$Bc*\u001b(B\n\u001b$Bc+\u001b(B\n\u001b$Bc,\u001b(B\n\u001b$Bc-\u001b(B\n\u001b$Bc.\u001b(B\n\u001b$Bc/\u001b(B\n\u001b$Bc0\u001b(B\n\u001b$Bc1\u001b(B\n\u001b$Bc2\u001b(B\n\u001b$Bc3\u001b(B\n\u001b$Bc4\u001b(B\n\u001b$Bc5\u001b(B\n\u001b$Bc6\u001b(B\n\u001b$Bc7\u001b(B\n\u001b$Bc8\u001b(B\n\u001b$Bc9\u001b(B\n\u001b$Bc:\u001b(B\n\u001b$Bc;\u001b(B\n\u001b$Bc<\u001b(B\n\u001b$Bc=\u001b(B\n\u001b$Bc>\u001b(B\n\u001b$Bc?\u001b(B\n\u001b$Bc@\u001b(B\n\u001b$BcA\u001b(B\n\u001b$BcB\u001b(B\n\u001b$BcC\u001b(B\n\u001b$BcD\u001b(B\n\u001b$BcE\u001b(B\n\u001b$BcF\u001b(B\n\u001b$BcG\u001b(B\n\u001b$BcH\u001b(B\n\u001b$BcI\u001b(B\n\u001b$BcJ\u001b(B\n\u001b$BcK\u001b(B\n\u001b$BcL\u001b(B\n\u001b$BcM\u001b(B\n\u001b$BcN\u001b(B\n\u001b$BcO\u001b(B\n\u001b$BcP\u001b(B\n\u001b$BcQ\u001b(B\n\u001b$BcR\u001b(B\n\u001b$BcS\u001b(B\n\u001b$BcT\u001b(B\n\u001b$BcU\u001b(B\n\u001b$BcV\u001b(B\n\u001b$BcW\u001b(B\n\u001b$BcX\u001b(B\n\u001b$BcY\u001b(B\n\u001b$BcZ\u001b(B\n\u001b$Bc[\u001b(B\n\u001b$Bc\\\u001b(B\n\u001b$Bc]\u001b(B\n\u001b$Bc^\u001b(B\n\u001b$Bc_\u001b(B\n\u001b$Bc`\u001b(B\n\u001b$Bca\u001b(B\n\u001b$Bcb\u001b(B\n\u001b$Bcc\u001b(B\n\u001b$Bcd\u001b(B\n\u001b$Bce\u001b(B\n\u001b$Bcf\u001b(B\n\u001b$Bcg\u001b(B\n\u001b$Bch\u001b(B\n\u001b$Bci\u001b(B\n\u001b$Bcj\u001b(B\n\u001b$Bck\u001b(B\n\u001b$Bcl\u001b(B\n\u001b$Bcm\u001b(B\n\u001b$Bcn\u001b(B\n\u001b$Bco\u001b(B\n\u001b$Bcp\u001b(B\n\u001b$Bcq\u001b(B\n\u001b$Bcr\u001b(B\n\u001b$Bcs\u001b(B\n\u001b$Bct\u001b(B\n\u001b$Bcu\u001b(B\n\u001b$Bcv\u001b(B\n\u001b$Bcw\u001b(B\n\u001b$Bcx\u001b(B\n\u001b$Bcy\u001b(B\n\u001b$Bcz\u001b(B\n\u001b$Bc{\u001b(B\n\u001b$Bc|\u001b(B\n\u001b$Bc}\u001b(B\n\u001b$Bc~\u001b(B\n\u001b$Bd!\u001b(B\n\u001b$Bd\"\u001b(B\n\u001b$Bd#\u001b(B\n\u001b$Bd$\u001b(B\n\u001b$Bd%\u001b(B\n\u001b$Bd&\u001b(B\n\u001b$Bd'\u001b(B\n\u001b$Bd(\u001b(B\n\u001b$Bd)\u001b(B\n\u001b$Bd*\u001b(B\n\u001b$Bd+\u001b(B\n\u001b$Bd,\u001b(B\n\u001b$Bd-\u001b(B\n\u001b$Bd.\u001b(B\n\u001b$Bd/\u001b(B\n\u001b$Bd0\u001b(B\n\u001b$Bd1\u001b(B\n\u001b$Bd2\u001b(B\n\u001b$Bd3\u001b(B\n\u001b$Bd4\u001b(B\n\u001b$Bd5\u001b(B\n\u001b$Bd6\u001b(B\n\u001b$Bd7\u001b(B\n\u001b$Bd8\u001b(B\n\u001b$Bd9\u001b(B\n\u001b$Bd:\u001b(B\n\u001b$Bd;\u001b(B\n\u001b$Bd<\u001b(B\n\u001b$Bd=\u001b(B\n\u001b$Bd>\u001b(B\n\u001b$Bd?\u001b(B\n\u001b$Bd@\u001b(B\n\u001b$BdA\u001b(B\n\u001b$BdB\u001b(B\n\u001b$BdC\u001b(B\n\u001b$BdD\u001b(B\n\u001b$BdE\u001b(B\n\u001b$BdF\u001b(B\n\u001b$BdG\u001b(B\n\u001b$BdH\u001b(B\n\u001b$BdI\u001b(B\n\u001b$BdJ\u001b(B\n\u001b$BdK\u001b(B\n\u001b$BdL\u001b(B\n\u001b$BdM\u001b(B\n\u001b$BdN\u001b(B\n\u001b$BdO\u001b(B\n\u001b$BdP\u001b(B\n\u001b$BdQ\u001b(B\n\u001b$BdR\u001b(B\n\u001b$BdS\u001b(B\n\u001b$BdT\u001b(B\n\u001b$BdU\u001b(B\n\u001b$BdV\u001b(B\n\u001b$BdW\u001b(B\n\u001b$BdX\u001b(B\n\u001b$BdY\u001b(B\n\u001b$BdZ\u001b(B\n\u001b$Bd[\u001b(B\n\u001b$Bd\\\u001b(B\n\u001b$Bd]\u001b(B\n\u001b$Bd^\u001b(B\n\u001b$Bd_\u001b(B\n\u001b$Bd`\u001b(B\n\u001b$Bda\u001b(B\n\u001b$Bdb\u001b(B\n\u001b$Bdc\u001b(B\n\u001b$Bdd\u001b(B\n\u001b$Bde\u001b(B\n\u001b$Bdf\u001b(B\n\u001b$Bdg\u001b(B\n\u001b$Bdh\u001b(B\n\u001b$Bdi\u001b(B\n\u001b$Bdj\u001b(B\n\u001b$Bdk\u001b(B\n\u001b$Bdl\u001b(B\n\u001b$Bdm\u001b(B\n\u001b$Bdn\u001b(B\n\u001b$Bdo\u001b(B\n\u001b$Bdp\u001b(B\n\u001b$Bdq\u001b(B\n\u001b$Bdr\u001b(B\n\u001b$Bds\u001b(B\n\u001b$Bdt\u001b(B\n\u001b$Bdu\u001b(B\n\u001b$Bdv\u001b(B\n\u001b$Bdw\u001b(B\n\u001b$Bdx\u001b(B\n\u001b$Bdy\u001b(B\n\u001b$Bdz\u001b(B\n\u001b$Bd{\u001b(B\n\u001b$Bd|\u001b(B\n\u001b$Bd}\u001b(B\n\u001b$Bd~\u001b(B\n\u001b$Be!\u001b(B\n\u001b$Be\"\u001b(B\n\u001b$Be#\u001b(B\n\u001b$Be$\u001b(B\n\u001b$Be%\u001b(B\n\u001b$Be&\u001b(B\n\u001b$Be'\u001b(B\n\u001b$Be(\u001b(B\n\u001b$Be)\u001b(B\n\u001b$Be*\u001b(B\n\u001b$Be+\u001b(B\n\u001b$Be,\u001b(B\n\u001b$Be-\u001b(B\n\u001b$Be.\u001b(B\n\u001b$Be/\u001b(B\n\u001b$Be0\u001b(B\n\u001b$Be1\u001b(B\n\u001b$Be2\u001b(B\n\u001b$Be3\u001b(B\n\u001b$Be4\u001b(B\n\u001b$Be5\u001b(B\n\u001b$Be6\u001b(B\n\u001b$Be7\u001b(B\n\u001b$Be8\u001b(B\n\u001b$Be9\u001b(B\n\u001b$Be:\u001b(B\n\u001b$Be;\u001b(B\n\u001b$Be<\u001b(B\n\u001b$Be=\u001b(B\n\u001b$Be>\u001b(B\n\u001b$Be?\u001b(B\n\u001b$Be@\u001b(B\n\u001b$BeA\u001b(B\n\u001b$BeB\u001b(B\n\u001b$BeC\u001b(B\n\u001b$BeD\u001b(B\n\u001b$BeE\u001b(B\n\u001b$BeF\u001b(B\n\u001b$BeG\u001b(B\n\u001b$BeH\u001b(B\n\u001b$BeI\u001b(B\n\u001b$BeJ\u001b(B\n\u001b$BeK\u001b(B\n\u001b$BeL\u001b(B\n\u001b$BeM\u001b(B\n\u001b$BeN\u001b(B\n\u001b$BeO\u001b(B\n\u001b$BeP\u001b(B\n\u001b$BeQ\u001b(B\n\u001b$BeR\u001b(B\n\u001b$BeS\u001b(B\n\u001b$BeT\u001b(B\n\u001b$BeU\u001b(B\n\u001b$BeV\u001b(B\n\u001b$BeW\u001b(B\n\u001b$BeX\u001b(B\n\u001b$BeY\u001b(B\n\u001b$BeZ\u001b(B\n\u001b$Be[\u001b(B\n\u001b$Be\\\u001b(B\n\u001b$Be]\u001b(B\n\u001b$Be^\u001b(B\n\u001b$Be_\u001b(B\n\u001b$Be`\u001b(B\n\u001b$Bea\u001b(B\n\u001b$Beb\u001b(B\n\u001b$Bec\u001b(B\n\u001b$Bed\u001b(B\n\u001b$Bee\u001b(B\n\u001b$Bef\u001b(B\n\u001b$Beg\u001b(B\n\u001b$Beh\u001b(B\n\u001b$Bei\u001b(B\n\u001b$Bej\u001b(B\n\u001b$Bek\u001b(B\n\u001b$Bel\u001b(B\n\u001b$Bem\u001b(B\n\u001b$Ben\u001b(B\n\u001b$Beo\u001b(B\n\u001b$Bep\u001b(B\n\u001b$Beq\u001b(B\n\u001b$Ber\u001b(B\n\u001b$Bes\u001b(B\n\u001b$Bet\u001b(B\n\u001b$Beu\u001b(B\n\u001b$Bev\u001b(B\n\u001b$Bew\u001b(B\n\u001b$Bex\u001b(B\n\u001b$Bey\u001b(B\n\u001b$Bez\u001b(B\n\u001b$Be{\u001b(B\n\u001b$Be|\u001b(B\n\u001b$Be}\u001b(B\n\u001b$Be~\u001b(B\n\u001b$Bf!\u001b(B\n\u001b$Bf\"\u001b(B\n\u001b$Bf#\u001b(B\n\u001b$Bf$\u001b(B\n\u001b$Bf%\u001b(B\n\u001b$Bf&\u001b(B\n\u001b$Bf'\u001b(B\n\u001b$Bf(\u001b(B\n\u001b$Bf)\u001b(B\n\u001b$Bf*\u001b(B\n\u001b$Bf+\u001b(B\n\u001b$Bf,\u001b(B\n\u001b$Bf-\u001b(B\n\u001b$Bf.\u001b(B\n\u001b$Bf/\u001b(B\n\u001b$Bf0\u001b(B\n\u001b$Bf1\u001b(B\n\u001b$Bf2\u001b(B\n\u001b$Bf3\u001b(B\n\u001b$Bf4\u001b(B\n\u001b$Bf5\u001b(B\n\u001b$Bf6\u001b(B\n\u001b$Bf7\u001b(B\n\u001b$Bf8\u001b(B\n\u001b$Bf9\u001b(B\n\u001b$Bf:\u001b(B\n\u001b$Bf;\u001b(B\n\u001b$Bf<\u001b(B\n\u001b$Bf=\u001b(B\n\u001b$Bf>\u001b(B\n\u001b$Bf?\u001b(B\n\u001b$Bf@\u001b(B\n\u001b$BfA\u001b(B\n\u001b$BfB\u001b(B\n\u001b$BfC\u001b(B\n\u001b$BfD\u001b(B\n\u001b$BfE\u001b(B\n\u001b$BfF\u001b(B\n\u001b$BfG\u001b(B\n\u001b$BfH\u001b(B\n\u001b$BfI\u001b(B\n\u001b$BfJ\u001b(B\n\u001b$BfK\u001b(B\n\u001b$BfL\u001b(B\n\u001b$BfM\u001b(B\n\u001b$BfN\u001b(B\n\u001b$BfO\u001b(B\n\u001b$BfP\u001b(B\n\u001b$BfQ\u001b(B\n\u001b$BfR\u001b(B\n\u001b$BfS\u001b(B\n\u001b$BfT\u001b(B\n\u001b$BfU\u001b(B\n\u001b$BfV\u001b(B\n\u001b$BfW\u001b(B\n\u001b$BfX\u001b(B\n\u001b$BfY\u001b(B\n\u001b$BfZ\u001b(B\n\u001b$Bf[\u001b(B\n\u001b$Bf\\\u001b(B\n\u001b$Bf]\u001b(B\n\u001b$Bf^\u001b(B\n\u001b$Bf_\u001b(B\n\u001b$Bf`\u001b(B\n\u001b$Bfa\u001b(B\n\u001b$Bfb\u001b(B\n\u001b$Bfc\u001b(B\n\u001b$Bfd\u001b(B\n\u001b$Bfe\u001b(B\n\u001b$Bff\u001b(B\n\u001b$Bfg\u001b(B\n\u001b$Bfh\u001b(B\n\u001b$Bfi\u001b(B\n\u001b$Bfj\u001b(B\n\u001b$Bfk\u001b(B\n\u001b$Bfl\u001b(B\n\u001b$Bfm\u001b(B\n\u001b$Bfn\u001b(B\n\u001b$Bfo\u001b(B\n\u001b$Bfp\u001b(B\n\u001b$Bfq\u001b(B\n\u001b$Bfr\u001b(B\n\u001b$Bfs\u001b(B\n\u001b$Bft\u001b(B\n\u001b$Bfu\u001b(B\n\u001b$Bfv\u001b(B\n\u001b$Bfw\u001b(B\n\u001b$Bfx\u001b(B\n\u001b$Bfy\u001b(B\n\u001b$Bfz\u001b(B\n\u001b$Bf{\u001b(B\n\u001b$Bf|\u001b(B\n\u001b$Bf}\u001b(B\n\u001b$Bf~\u001b(B\n\u001b$Bg!\u001b(B\n\u001b$Bg\"\u001b(B\n\u001b$Bg#\u001b(B\n\u001b$Bg$\u001b(B\n\u001b$Bg%\u001b(B\n\u001b$Bg&\u001b(B\n\u001b$Bg'\u001b(B\n\u001b$Bg(\u001b(B\n\u001b$Bg)\u001b(B\n\u001b$Bg*\u001b(B\n\u001b$Bg+\u001b(B\n\u001b$Bg,\u001b(B\n\u001b$Bg-\u001b(B\n\u001b$Bg.\u001b(B\n\u001b$Bg/\u001b(B\n\u001b$Bg0\u001b(B\n\u001b$Bg1\u001b(B\n\u001b$Bg2\u001b(B\n\u001b$Bg3\u001b(B\n\u001b$Bg4\u001b(B\n\u001b$Bg5\u001b(B\n\u001b$Bg6\u001b(B\n\u001b$Bg7\u001b(B\n\u001b$Bg8\u001b(B\n\u001b$Bg9\u001b(B\n\u001b$Bg:\u001b(B\n\u001b$Bg;\u001b(B\n\u001b$Bg<\u001b(B\n\u001b$Bg=\u001b(B\n\u001b$Bg>\u001b(B\n\u001b$Bg?\u001b(B\n\u001b$Bg@\u001b(B\n\u001b$BgA\u001b(B\n\u001b$BgB\u001b(B\n\u001b$BgC\u001b(B\n\u001b$BgD\u001b(B\n\u001b$BgE\u001b(B\n\u001b$BgF\u001b(B\n\u001b$BgG\u001b(B\n\u001b$BgH\u001b(B\n\u001b$BgI\u001b(B\n\u001b$BgJ\u001b(B\n\u001b$BgK\u001b(B\n\u001b$BgL\u001b(B\n\u001b$BgM\u001b(B\n\u001b$BgN\u001b(B\n\u001b$BgO\u001b(B\n\u001b$BgP\u001b(B\n\u001b$BgQ\u001b(B\n\u001b$BgR\u001b(B\n\u001b$BgS\u001b(B\n\u001b$BgT\u001b(B\n\u001b$BgU\u001b(B\n\u001b$BgV\u001b(B\n\u001b$BgW\u001b(B\n\u001b$BgX\u001b(B\n\u001b$BgY\u001b(B\n\u001b$BgZ\u001b(B\n\u001b$Bg[\u001b(B\n\u001b$Bg\\\u001b(B\n\u001b$Bg]\u001b(B\n\u001b$Bg^\u001b(B\n\u001b$Bg_\u001b(B\n\u001b$Bg`\u001b(B\n\u001b$Bga\u001b(B\n\u001b$Bgb\u001b(B\n\u001b$Bgc\u001b(B\n\u001b$Bgd\u001b(B\n\u001b$Bge\u001b(B\n\u001b$Bgf\u001b(B\n\u001b$Bgg\u001b(B\n\u001b$Bgh\u001b(B\n\u001b$Bgi\u001b(B\n\u001b$Bgj\u001b(B\n\u001b$Bgk\u001b(B\n\u001b$Bgl\u001b(B\n\u001b$Bgm\u001b(B\n\u001b$Bgn\u001b(B\n\u001b$Bgo\u001b(B\n\u001b$Bgp\u001b(B\n\u001b$Bgq\u001b(B\n\u001b$Bgr\u001b(B\n\u001b$Bgs\u001b(B\n\u001b$Bgt\u001b(B\n\u001b$Bgu\u001b(B\n\u001b$Bgv\u001b(B\n\u001b$Bgw\u001b(B\n\u001b$Bgx\u001b(B\n\u001b$Bgy\u001b(B\n\u001b$Bgz\u001b(B\n\u001b$Bg{\u001b(B\n\u001b$Bg|\u001b(B\n\u001b$Bg}\u001b(B\n\u001b$Bg~\u001b(B\n\u001b$Bh!\u001b(B\n\u001b$Bh\"\u001b(B\n\u001b$Bh#\u001b(B\n\u001b$Bh$\u001b(B\n\u001b$Bh%\u001b(B\n\u001b$Bh&\u001b(B\n\u001b$Bh'\u001b(B\n\u001b$Bh(\u001b(B\n\u001b$Bh)\u001b(B\n\u001b$Bh*\u001b(B\n\u001b$Bh+\u001b(B\n\u001b$Bh,\u001b(B\n\u001b$Bh-\u001b(B\n\u001b$Bh.\u001b(B\n\u001b$Bh/\u001b(B\n\u001b$Bh0\u001b(B\n\u001b$Bh1\u001b(B\n\u001b$Bh2\u001b(B\n\u001b$Bh3\u001b(B\n\u001b$Bh4\u001b(B\n\u001b$Bh5\u001b(B\n\u001b$Bh6\u001b(B\n\u001b$Bh7\u001b(B\n\u001b$Bh8\u001b(B\n\u001b$Bh9\u001b(B\n\u001b$Bh:\u001b(B\n\u001b$Bh;\u001b(B\n\u001b$Bh<\u001b(B\n\u001b$Bh=\u001b(B\n\u001b$Bh>\u001b(B\n\u001b$Bh?\u001b(B\n\u001b$Bh@\u001b(B\n\u001b$BhA\u001b(B\n\u001b$BhB\u001b(B\n\u001b$BhC\u001b(B\n\u001b$BhD\u001b(B\n\u001b$BhE\u001b(B\n\u001b$BhF\u001b(B\n\u001b$BhG\u001b(B\n\u001b$BhH\u001b(B\n\u001b$BhI\u001b(B\n\u001b$BhJ\u001b(B\n\u001b$BhK\u001b(B\n\u001b$BhL\u001b(B\n\u001b$BhM\u001b(B\n\u001b$BhN\u001b(B\n\u001b$BhO\u001b(B\n\u001b$BhP\u001b(B\n\u001b$BhQ\u001b(B\n\u001b$BhR\u001b(B\n\u001b$BhS\u001b(B\n\u001b$BhT\u001b(B\n\u001b$BhU\u001b(B\n\u001b$BhV\u001b(B\n\u001b$BhW\u001b(B\n\u001b$BhX\u001b(B\n\u001b$BhY\u001b(B\n\u001b$BhZ\u001b(B\n\u001b$Bh[\u001b(B\n\u001b$Bh\\\u001b(B\n\u001b$Bh]\u001b(B\n\u001b$Bh^\u001b(B\n\u001b$Bh_\u001b(B\n\u001b$Bh`\u001b(B\n\u001b$Bha\u001b(B\n\u001b$Bhb\u001b(B\n\u001b$Bhc\u001b(B\n\u001b$Bhd\u001b(B\n\u001b$Bhe\u001b(B\n\u001b$Bhf\u001b(B\n\u001b$Bhg\u001b(B\n\u001b$Bhh\u001b(B\n\u001b$Bhi\u001b(B\n\u001b$Bhj\u001b(B\n\u001b$Bhk\u001b(B\n\u001b$Bhl\u001b(B\n\u001b$Bhm\u001b(B\n\u001b$Bhn\u001b(B\n\u001b$Bho\u001b(B\n\u001b$Bhp\u001b(B\n\u001b$Bhq\u001b(B\n\u001b$Bhr\u001b(B\n\u001b$Bhs\u001b(B\n\u001b$Bht\u001b(B\n\u001b$Bhu\u001b(B\n\u001b$Bhv\u001b(B\n\u001b$Bhw\u001b(B\n\u001b$Bhx\u001b(B\n\u001b$Bhy\u001b(B\n\u001b$Bhz\u001b(B\n\u001b$Bh{\u001b(B\n\u001b$Bh|\u001b(B\n\u001b$Bh}\u001b(B\n\u001b$Bh~\u001b(B\n\u001b$Bi!\u001b(B\n\u001b$Bi\"\u001b(B\n\u001b$Bi#\u001b(B\n\u001b$Bi$\u001b(B\n\u001b$Bi%\u001b(B\n\u001b$Bi&\u001b(B\n\u001b$Bi'\u001b(B\n\u001b$Bi(\u001b(B\n\u001b$Bi)\u001b(B\n\u001b$Bi*\u001b(B\n\u001b$Bi+\u001b(B\n\u001b$Bi,\u001b(B\n\u001b$Bi-\u001b(B\n\u001b$Bi.\u001b(B\n\u001b$Bi/\u001b(B\n\u001b$Bi0\u001b(B\n\u001b$Bi1\u001b(B\n\u001b$Bi2\u001b(B\n\u001b$Bi3\u001b(B\n\u001b$Bi4\u001b(B\n\u001b$Bi5\u001b(B\n\u001b$Bi6\u001b(B\n\u001b$Bi7\u001b(B\n\u001b$Bi8\u001b(B\n\u001b$Bi9\u001b(B\n\u001b$Bi:\u001b(B\n\u001b$Bi;\u001b(B\n\u001b$Bi<\u001b(B\n\u001b$Bi=\u001b(B\n\u001b$Bi>\u001b(B\n\u001b$Bi?\u001b(B\n\u001b$Bi@\u001b(B\n\u001b$BiA\u001b(B\n\u001b$BiB\u001b(B\n\u001b$BiC\u001b(B\n\u001b$BiD\u001b(B\n\u001b$BiE\u001b(B\n\u001b$BiF\u001b(B\n\u001b$BiG\u001b(B\n\u001b$BiH\u001b(B\n\u001b$BiI\u001b(B\n\u001b$BiJ\u001b(B\n\u001b$BiK\u001b(B\n\u001b$BiL\u001b(B\n\u001b$BiM\u001b(B\n\u001b$BiN\u001b(B\n\u001b$BiO\u001b(B\n\u001b$BiP\u001b(B\n\u001b$BiQ\u001b(B\n\u001b$BiR\u001b(B\n\u001b$BiS\u001b(B\n\u001b$BiT\u001b(B\n\u001b$BiU\u001b(B\n\u001b$BiV\u001b(B\n\u001b$BiW\u001b(B\n\u001b$BiX\u001b(B\n\u001b$BiY\u001b(B\n\u001b$BiZ\u001b(B\n\u001b$Bi[\u001b(B\n\u001b$Bi\\\u001b(B\n\u001b$Bi]\u001b(B\n\u001b$Bi^\u001b(B\n\u001b$Bi_\u001b(B\n\u001b$Bi`\u001b(B\n\u001b$Bia\u001b(B\n\u001b$Bib\u001b(B\n\u001b$Bic\u001b(B\n\u001b$Bid\u001b(B\n\u001b$Bie\u001b(B\n\u001b$Bif\u001b(B\n\u001b$Big\u001b(B\n\u001b$Bih\u001b(B\n\u001b$Bii\u001b(B\n\u001b$Bij\u001b(B\n\u001b$Bik\u001b(B\n\u001b$Bil\u001b(B\n\u001b$Bim\u001b(B\n\u001b$Bin\u001b(B\n\u001b$Bio\u001b(B\n\u001b$Bip\u001b(B\n\u001b$Biq\u001b(B\n\u001b$Bir\u001b(B\n\u001b$Bis\u001b(B\n\u001b$Bit\u001b(B\n\u001b$Biu\u001b(B\n\u001b$Biv\u001b(B\n\u001b$Biw\u001b(B\n\u001b$Bix\u001b(B\n\u001b$Biy\u001b(B\n\u001b$Biz\u001b(B\n\u001b$Bi{\u001b(B\n\u001b$Bi|\u001b(B\n\u001b$Bi}\u001b(B\n\u001b$Bi~\u001b(B\n\u001b$Bj!\u001b(B\n\u001b$Bj\"\u001b(B\n\u001b$Bj#\u001b(B\n\u001b$Bj$\u001b(B\n\u001b$Bj%\u001b(B\n\u001b$Bj&\u001b(B\n\u001b$Bj'\u001b(B\n\u001b$Bj(\u001b(B\n\u001b$Bj)\u001b(B\n\u001b$Bj*\u001b(B\n\u001b$Bj+\u001b(B\n\u001b$Bj,\u001b(B\n\u001b$Bj-\u001b(B\n\u001b$Bj.\u001b(B\n\u001b$Bj/\u001b(B\n\u001b$Bj0\u001b(B\n\u001b$Bj1\u001b(B\n\u001b$Bj2\u001b(B\n\u001b$Bj3\u001b(B\n\u001b$Bj4\u001b(B\n\u001b$Bj5\u001b(B\n\u001b$Bj6\u001b(B\n\u001b$Bj7\u001b(B\n\u001b$Bj8\u001b(B\n\u001b$Bj9\u001b(B\n\u001b$Bj:\u001b(B\n\u001b$Bj;\u001b(B\n\u001b$Bj<\u001b(B\n\u001b$Bj=\u001b(B\n\u001b$Bj>\u001b(B\n\u001b$Bj?\u001b(B\n\u001b$Bj@\u001b(B\n\u001b$BjA\u001b(B\n\u001b$BjB\u001b(B\n\u001b$BjC\u001b(B\n\u001b$BjD\u001b(B\n\u001b$BjE\u001b(B\n\u001b$BjF\u001b(B\n\u001b$BjG\u001b(B\n\u001b$BjH\u001b(B\n\u001b$BjI\u001b(B\n\u001b$BjJ\u001b(B\n\u001b$BjK\u001b(B\n\u001b$BjL\u001b(B\n\u001b$BjM\u001b(B\n\u001b$BjN\u001b(B\n\u001b$BjO\u001b(B\n\u001b$BjP\u001b(B\n\u001b$BjQ\u001b(B\n\u001b$BjR\u001b(B\n\u001b$BjS\u001b(B\n\u001b$BjT\u001b(B\n\u001b$BjU\u001b(B\n\u001b$BjV\u001b(B\n\u001b$BjW\u001b(B\n\u001b$BjX\u001b(B\n\u001b$BjY\u001b(B\n\u001b$BjZ\u001b(B\n\u001b$Bj[\u001b(B\n\u001b$Bj\\\u001b(B\n\u001b$Bj]\u001b(B\n\u001b$Bj^\u001b(B\n\u001b$Bj_\u001b(B\n\u001b$Bj`\u001b(B\n\u001b$Bja\u001b(B\n\u001b$Bjb\u001b(B\n\u001b$Bjc\u001b(B\n\u001b$Bjd\u001b(B\n\u001b$Bje\u001b(B\n\u001b$Bjf\u001b(B\n\u001b$Bjg\u001b(B\n\u001b$Bjh\u001b(B\n\u001b$Bji\u001b(B\n\u001b$Bjj\u001b(B\n\u001b$Bjk\u001b(B\n\u001b$Bjl\u001b(B\n\u001b$Bjm\u001b(B\n\u001b$Bjn\u001b(B\n\u001b$Bjo\u001b(B\n\u001b$Bjp\u001b(B\n\u001b$Bjq\u001b(B\n\u001b$Bjr\u001b(B\n\u001b$Bjs\u001b(B\n\u001b$Bjt\u001b(B\n\u001b$Bju\u001b(B\n\u001b$Bjv\u001b(B\n\u001b$Bjw\u001b(B\n\u001b$Bjx\u001b(B\n\u001b$Bjy\u001b(B\n\u001b$Bjz\u001b(B\n\u001b$Bj{\u001b(B\n\u001b$Bj|\u001b(B\n\u001b$Bj}\u001b(B\n\u001b$Bj~\u001b(B\n\u001b$Bk!\u001b(B\n\u001b$Bk\"\u001b(B\n\u001b$Bk#\u001b(B\n\u001b$Bk$\u001b(B\n\u001b$Bk%\u001b(B\n\u001b$Bk&\u001b(B\n\u001b$Bk'\u001b(B\n\u001b$Bk(\u001b(B\n\u001b$Bk)\u001b(B\n\u001b$Bk*\u001b(B\n\u001b$Bk+\u001b(B\n\u001b$Bk,\u001b(B\n\u001b$Bk-\u001b(B\n\u001b$Bk.\u001b(B\n\u001b$Bk/\u001b(B\n\u001b$Bk0\u001b(B\n\u001b$Bk1\u001b(B\n\u001b$Bk2\u001b(B\n\u001b$Bk3\u001b(B\n\u001b$Bk4\u001b(B\n\u001b$Bk5\u001b(B\n\u001b$Bk6\u001b(B\n\u001b$Bk7\u001b(B\n\u001b$Bk8\u001b(B\n\u001b$Bk9\u001b(B\n\u001b$Bk:\u001b(B\n\u001b$Bk;\u001b(B\n\u001b$Bk<\u001b(B\n\u001b$Bk=\u001b(B\n\u001b$Bk>\u001b(B\n\u001b$Bk?\u001b(B\n\u001b$Bk@\u001b(B\n\u001b$BkA\u001b(B\n\u001b$BkB\u001b(B\n\u001b$BkC\u001b(B\n\u001b$BkD\u001b(B\n\u001b$BkE\u001b(B\n\u001b$BkF\u001b(B\n\u001b$BkG\u001b(B\n\u001b$BkH\u001b(B\n\u001b$BkI\u001b(B\n\u001b$BkJ\u001b(B\n\u001b$BkK\u001b(B\n\u001b$BkL\u001b(B\n\u001b$BkM\u001b(B\n\u001b$BkN\u001b(B\n\u001b$BkO\u001b(B\n\u001b$BkP\u001b(B\n\u001b$BkQ\u001b(B\n\u001b$BkR\u001b(B\n\u001b$BkS\u001b(B\n\u001b$BkT\u001b(B\n\u001b$BkU\u001b(B\n\u001b$BkV\u001b(B\n\u001b$BkW\u001b(B\n\u001b$BkX\u001b(B\n\u001b$BkY\u001b(B\n\u001b$BkZ\u001b(B\n\u001b$Bk[\u001b(B\n\u001b$Bk\\\u001b(B\n\u001b$Bk]\u001b(B\n\u001b$Bk^\u001b(B\n\u001b$Bk_\u001b(B\n\u001b$Bk`\u001b(B\n\u001b$Bka\u001b(B\n\u001b$Bkb\u001b(B\n\u001b$Bkc\u001b(B\n\u001b$Bkd\u001b(B\n\u001b$Bke\u001b(B\n\u001b$Bkf\u001b(B\n\u001b$Bkg\u001b(B\n\u001b$Bkh\u001b(B\n\u001b$Bki\u001b(B\n\u001b$Bkj\u001b(B\n\u001b$Bkk\u001b(B\n\u001b$Bkl\u001b(B\n\u001b$Bkm\u001b(B\n\u001b$Bkn\u001b(B\n\u001b$Bko\u001b(B\n\u001b$Bkp\u001b(B\n\u001b$Bkq\u001b(B\n\u001b$Bkr\u001b(B\n\u001b$Bks\u001b(B\n\u001b$Bkt\u001b(B\n\u001b$Bku\u001b(B\n\u001b$Bkv\u001b(B\n\u001b$Bkw\u001b(B\n\u001b$Bkx\u001b(B\n\u001b$Bky\u001b(B\n\u001b$Bkz\u001b(B\n\u001b$Bk{\u001b(B\n\u001b$Bk|\u001b(B\n\u001b$Bk}\u001b(B\n\u001b$Bk~\u001b(B\n\u001b$Bl!\u001b(B\n\u001b$Bl\"\u001b(B\n\u001b$Bl#\u001b(B\n\u001b$Bl$\u001b(B\n\u001b$Bl%\u001b(B\n\u001b$Bl&\u001b(B\n\u001b$Bl'\u001b(B\n\u001b$Bl(\u001b(B\n\u001b$Bl)\u001b(B\n\u001b$Bl*\u001b(B\n\u001b$Bl+\u001b(B\n\u001b$Bl,\u001b(B\n\u001b$Bl-\u001b(B\n\u001b$Bl.\u001b(B\n\u001b$Bl/\u001b(B\n\u001b$Bl0\u001b(B\n\u001b$Bl1\u001b(B\n\u001b$Bl2\u001b(B\n\u001b$Bl3\u001b(B\n\u001b$Bl4\u001b(B\n\u001b$Bl5\u001b(B\n\u001b$Bl6\u001b(B\n\u001b$Bl7\u001b(B\n\u001b$Bl8\u001b(B\n\u001b$Bl9\u001b(B\n\u001b$Bl:\u001b(B\n\u001b$Bl;\u001b(B\n\u001b$Bl<\u001b(B\n\u001b$Bl=\u001b(B\n\u001b$Bl>\u001b(B\n\u001b$Bl?\u001b(B\n\u001b$Bl@\u001b(B\n\u001b$BlA\u001b(B\n\u001b$BlB\u001b(B\n\u001b$BlC\u001b(B\n\u001b$BlD\u001b(B\n\u001b$BlE\u001b(B\n\u001b$BlF\u001b(B\n\u001b$BlG\u001b(B\n\u001b$BlH\u001b(B\n\u001b$BlI\u001b(B\n\u001b$BlJ\u001b(B\n\u001b$BlK\u001b(B\n\u001b$BlL\u001b(B\n\u001b$BlM\u001b(B\n\u001b$BlN\u001b(B\n\u001b$BlO\u001b(B\n\u001b$BlP\u001b(B\n\u001b$BlQ\u001b(B\n\u001b$BlR\u001b(B\n\u001b$BlS\u001b(B\n\u001b$BlT\u001b(B\n\u001b$BlU\u001b(B\n\u001b$BlV\u001b(B\n\u001b$BlW\u001b(B\n\u001b$BlX\u001b(B\n\u001b$BlY\u001b(B\n\u001b$BlZ\u001b(B\n\u001b$Bl[\u001b(B\n\u001b$Bl\\\u001b(B\n\u001b$Bl]\u001b(B\n\u001b$Bl^\u001b(B\n\u001b$Bl_\u001b(B\n\u001b$Bl`\u001b(B\n\u001b$Bla\u001b(B\n\u001b$Blb\u001b(B\n\u001b$Blc\u001b(B\n\u001b$Bld\u001b(B\n\u001b$Ble\u001b(B\n\u001b$Blf\u001b(B\n\u001b$Blg\u001b(B\n\u001b$Blh\u001b(B\n\u001b$Bli\u001b(B\n\u001b$Blj\u001b(B\n\u001b$Blk\u001b(B\n\u001b$Bll\u001b(B\n\u001b$Blm\u001b(B\n\u001b$Bln\u001b(B\n\u001b$Blo\u001b(B\n\u001b$Blp\u001b(B\n\u001b$Blq\u001b(B\n\u001b$Blr\u001b(B\n\u001b$Bls\u001b(B\n\u001b$Blt\u001b(B\n\u001b$Blu\u001b(B\n\u001b$Blv\u001b(B\n\u001b$Blw\u001b(B\n\u001b$Blx\u001b(B\n\u001b$Bly\u001b(B\n\u001b$Blz\u001b(B\n\u001b$Bl{\u001b(B\n\u001b$Bl|\u001b(B\n\u001b$Bl}\u001b(B\n\u001b$Bl~\u001b(B\n\u001b$Bm!\u001b(B\n\u001b$Bm\"\u001b(B\n\u001b$Bm#\u001b(B\n\u001b$Bm$\u001b(B\n\u001b$Bm%\u001b(B\n\u001b$Bm&\u001b(B\n\u001b$Bm'\u001b(B\n\u001b$Bm(\u001b(B\n\u001b$Bm)\u001b(B\n\u001b$Bm*\u001b(B\n\u001b$Bm+\u001b(B\n\u001b$Bm,\u001b(B\n\u001b$Bm-\u001b(B\n\u001b$Bm.\u001b(B\n\u001b$Bm/\u001b(B\n\u001b$Bm0\u001b(B\n\u001b$Bm1\u001b(B\n\u001b$Bm2\u001b(B\n\u001b$Bm3\u001b(B\n\u001b$Bm4\u001b(B\n\u001b$Bm5\u001b(B\n\u001b$Bm6\u001b(B\n\u001b$Bm7\u001b(B\n\u001b$Bm8\u001b(B\n\u001b$Bm9\u001b(B\n\u001b$Bm:\u001b(B\n\u001b$Bm;\u001b(B\n\u001b$Bm<\u001b(B\n\u001b$Bm=\u001b(B\n\u001b$Bm>\u001b(B\n\u001b$Bm?\u001b(B\n\u001b$Bm@\u001b(B\n\u001b$BmA\u001b(B\n\u001b$BmB\u001b(B\n\u001b$BmC\u001b(B\n\u001b$BmD\u001b(B\n\u001b$BmE\u001b(B\n\u001b$BmF\u001b(B\n\u001b$BmG\u001b(B\n\u001b$BmH\u001b(B\n\u001b$BmI\u001b(B\n\u001b$BmJ\u001b(B\n\u001b$BmK\u001b(B\n\u001b$BmL\u001b(B\n\u001b$BmM\u001b(B\n\u001b$BmN\u001b(B\n\u001b$BmO\u001b(B\n\u001b$BmP\u001b(B\n\u001b$BmQ\u001b(B\n\u001b$BmR\u001b(B\n\u001b$BmS\u001b(B\n\u001b$BmT\u001b(B\n\u001b$BmU\u001b(B\n\u001b$BmV\u001b(B\n\u001b$BmW\u001b(B\n\u001b$BmX\u001b(B\n\u001b$BmY\u001b(B\n\u001b$BmZ\u001b(B\n\u001b$Bm[\u001b(B\n\u001b$Bm\\\u001b(B\n\u001b$Bm]\u001b(B\n\u001b$Bm^\u001b(B\n\u001b$Bm_\u001b(B\n\u001b$Bm`\u001b(B\n\u001b$Bma\u001b(B\n\u001b$Bmb\u001b(B\n\u001b$Bmc\u001b(B\n\u001b$Bmd\u001b(B\n\u001b$Bme\u001b(B\n\u001b$Bmf\u001b(B\n\u001b$Bmg\u001b(B\n\u001b$Bmh\u001b(B\n\u001b$Bmi\u001b(B\n\u001b$Bmj\u001b(B\n\u001b$Bmk\u001b(B\n\u001b$Bml\u001b(B\n\u001b$Bmm\u001b(B\n\u001b$Bmn\u001b(B\n\u001b$Bmo\u001b(B\n\u001b$Bmp\u001b(B\n\u001b$Bmq\u001b(B\n\u001b$Bmr\u001b(B\n\u001b$Bms\u001b(B\n\u001b$Bmt\u001b(B\n\u001b$Bmu\u001b(B\n\u001b$Bmv\u001b(B\n\u001b$Bmw\u001b(B\n\u001b$Bmx\u001b(B\n\u001b$Bmy\u001b(B\n\u001b$Bmz\u001b(B\n\u001b$Bm{\u001b(B\n\u001b$Bm|\u001b(B\n\u001b$Bm}\u001b(B\n\u001b$Bm~\u001b(B\n\u001b$Bn!\u001b(B\n\u001b$Bn\"\u001b(B\n\u001b$Bn#\u001b(B\n\u001b$Bn$\u001b(B\n\u001b$Bn%\u001b(B\n\u001b$Bn&\u001b(B\n\u001b$Bn'\u001b(B\n\u001b$Bn(\u001b(B\n\u001b$Bn)\u001b(B\n\u001b$Bn*\u001b(B\n\u001b$Bn+\u001b(B\n\u001b$Bn,\u001b(B\n\u001b$Bn-\u001b(B\n\u001b$Bn.\u001b(B\n\u001b$Bn/\u001b(B\n\u001b$Bn0\u001b(B\n\u001b$Bn1\u001b(B\n\u001b$Bn2\u001b(B\n\u001b$Bn3\u001b(B\n\u001b$Bn4\u001b(B\n\u001b$Bn5\u001b(B\n\u001b$Bn6\u001b(B\n\u001b$Bn7\u001b(B\n\u001b$Bn8\u001b(B\n\u001b$Bn9\u001b(B\n\u001b$Bn:\u001b(B\n\u001b$Bn;\u001b(B\n\u001b$Bn<\u001b(B\n\u001b$Bn=\u001b(B\n\u001b$Bn>\u001b(B\n\u001b$Bn?\u001b(B\n\u001b$Bn@\u001b(B\n\u001b$BnA\u001b(B\n\u001b$BnB\u001b(B\n\u001b$BnC\u001b(B\n\u001b$BnD\u001b(B\n\u001b$BnE\u001b(B\n\u001b$BnF\u001b(B\n\u001b$BnG\u001b(B\n\u001b$BnH\u001b(B\n\u001b$BnI\u001b(B\n\u001b$BnJ\u001b(B\n\u001b$BnK\u001b(B\n\u001b$BnL\u001b(B\n\u001b$BnM\u001b(B\n\u001b$BnN\u001b(B\n\u001b$BnO\u001b(B\n\u001b$BnP\u001b(B\n\u001b$BnQ\u001b(B\n\u001b$BnR\u001b(B\n\u001b$BnS\u001b(B\n\u001b$BnT\u001b(B\n\u001b$BnU\u001b(B\n\u001b$BnV\u001b(B\n\u001b$BnW\u001b(B\n\u001b$BnX\u001b(B\n\u001b$BnY\u001b(B\n\u001b$BnZ\u001b(B\n\u001b$Bn[\u001b(B\n\u001b$Bn\\\u001b(B\n\u001b$Bn]\u001b(B\n\u001b$Bn^\u001b(B\n\u001b$Bn_\u001b(B\n\u001b$Bn`\u001b(B\n\u001b$Bna\u001b(B\n\u001b$Bnb\u001b(B\n\u001b$Bnc\u001b(B\n\u001b$Bnd\u001b(B\n\u001b$Bne\u001b(B\n\u001b$Bnf\u001b(B\n\u001b$Bng\u001b(B\n\u001b$Bnh\u001b(B\n\u001b$Bni\u001b(B\n\u001b$Bnj\u001b(B\n\u001b$Bnk\u001b(B\n\u001b$Bnl\u001b(B\n\u001b$Bnm\u001b(B\n\u001b$Bnn\u001b(B\n\u001b$Bno\u001b(B\n\u001b$Bnp\u001b(B\n\u001b$Bnq\u001b(B\n\u001b$Bnr\u001b(B\n\u001b$Bns\u001b(B\n\u001b$Bnt\u001b(B\n\u001b$Bnu\u001b(B\n\u001b$Bnv\u001b(B\n\u001b$Bnw\u001b(B\n\u001b$Bnx\u001b(B\n\u001b$Bny\u001b(B\n\u001b$Bnz\u001b(B\n\u001b$Bn{\u001b(B\n\u001b$Bn|\u001b(B\n\u001b$Bn}\u001b(B\n\u001b$Bn~\u001b(B\n\u001b$Bo!\u001b(B\n\u001b$Bo\"\u001b(B\n\u001b$Bo#\u001b(B\n\u001b$Bo$\u001b(B\n\u001b$Bo%\u001b(B\n\u001b$Bo&\u001b(B\n\u001b$Bo'\u001b(B\n\u001b$Bo(\u001b(B\n\u001b$Bo)\u001b(B\n\u001b$Bo*\u001b(B\n\u001b$Bo+\u001b(B\n\u001b$Bo,\u001b(B\n\u001b$Bo-\u001b(B\n\u001b$Bo.\u001b(B\n\u001b$Bo/\u001b(B\n\u001b$Bo0\u001b(B\n\u001b$Bo1\u001b(B\n\u001b$Bo2\u001b(B\n\u001b$Bo3\u001b(B\n\u001b$Bo4\u001b(B\n\u001b$Bo5\u001b(B\n\u001b$Bo6\u001b(B\n\u001b$Bo7\u001b(B\n\u001b$Bo8\u001b(B\n\u001b$Bo9\u001b(B\n\u001b$Bo:\u001b(B\n\u001b$Bo;\u001b(B\n\u001b$Bo<\u001b(B\n\u001b$Bo=\u001b(B\n\u001b$Bo>\u001b(B\n\u001b$Bo?\u001b(B\n\u001b$Bo@\u001b(B\n\u001b$BoA\u001b(B\n\u001b$BoB\u001b(B\n\u001b$BoC\u001b(B\n\u001b$BoD\u001b(B\n\u001b$BoE\u001b(B\n\u001b$BoF\u001b(B\n\u001b$BoG\u001b(B\n\u001b$BoH\u001b(B\n\u001b$BoI\u001b(B\n\u001b$BoJ\u001b(B\n\u001b$BoK\u001b(B\n\u001b$BoL\u001b(B\n\u001b$BoM\u001b(B\n\u001b$BoN\u001b(B\n\u001b$BoO\u001b(B\n\u001b$BoP\u001b(B\n\u001b$BoQ\u001b(B\n\u001b$BoR\u001b(B\n\u001b$BoS\u001b(B\n\u001b$BoT\u001b(B\n\u001b$BoU\u001b(B\n\u001b$BoV\u001b(B\n\u001b$BoW\u001b(B\n\u001b$BoX\u001b(B\n\u001b$BoY\u001b(B\n\u001b$BoZ\u001b(B\n\u001b$Bo[\u001b(B\n\u001b$Bo\\\u001b(B\n\u001b$Bo]\u001b(B\n\u001b$Bo^\u001b(B\n\u001b$Bo_\u001b(B\n\u001b$Bo`\u001b(B\n\u001b$Boa\u001b(B\n\u001b$Bob\u001b(B\n\u001b$Boc\u001b(B\n\u001b$Bod\u001b(B\n\u001b$Boe\u001b(B\n\u001b$Bof\u001b(B\n\u001b$Bog\u001b(B\n\u001b$Boh\u001b(B\n\u001b$Boi\u001b(B\n\u001b$Boj\u001b(B\n\u001b$Bok\u001b(B\n\u001b$Bol\u001b(B\n\u001b$Bom\u001b(B\n\u001b$Bon\u001b(B\n\u001b$Boo\u001b(B\n\u001b$Bop\u001b(B\n\u001b$Boq\u001b(B\n\u001b$Bor\u001b(B\n\u001b$Bos\u001b(B\n\u001b$Bot\u001b(B\n\u001b$Bou\u001b(B\n\u001b$Bov\u001b(B\n\u001b$Bow\u001b(B\n\u001b$Box\u001b(B\n\u001b$Boy\u001b(B\n\u001b$Boz\u001b(B\n\u001b$Bo{\u001b(B\n\u001b$Bo|\u001b(B\n\u001b$Bo}\u001b(B\n\u001b$Bo~\u001b(B\n\u001b$Bp!\u001b(B\n\u001b$Bp\"\u001b(B\n\u001b$Bp#\u001b(B\n\u001b$Bp$\u001b(B\n\u001b$Bp%\u001b(B\n\u001b$Bp&\u001b(B\n\u001b$Bp'\u001b(B\n\u001b$Bp(\u001b(B\n\u001b$Bp)\u001b(B\n\u001b$Bp*\u001b(B\n\u001b$Bp+\u001b(B\n\u001b$Bp,\u001b(B\n\u001b$Bp-\u001b(B\n\u001b$Bp.\u001b(B\n\u001b$Bp/\u001b(B\n\u001b$Bp0\u001b(B\n\u001b$Bp1\u001b(B\n\u001b$Bp2\u001b(B\n\u001b$Bp3\u001b(B\n\u001b$Bp4\u001b(B\n\u001b$Bp5\u001b(B\n\u001b$Bp6\u001b(B\n\u001b$Bp7\u001b(B\n\u001b$Bp8\u001b(B\n\u001b$Bp9\u001b(B\n\u001b$Bp:\u001b(B\n\u001b$Bp;\u001b(B\n\u001b$Bp<\u001b(B\n\u001b$Bp=\u001b(B\n\u001b$Bp>\u001b(B\n\u001b$Bp?\u001b(B\n\u001b$Bp@\u001b(B\n\u001b$BpA\u001b(B\n\u001b$BpB\u001b(B\n\u001b$BpC\u001b(B\n\u001b$BpD\u001b(B\n\u001b$BpE\u001b(B\n\u001b$BpF\u001b(B\n\u001b$BpG\u001b(B\n\u001b$BpH\u001b(B\n\u001b$BpI\u001b(B\n\u001b$BpJ\u001b(B\n\u001b$BpK\u001b(B\n\u001b$BpL\u001b(B\n\u001b$BpM\u001b(B\n\u001b$BpN\u001b(B\n\u001b$BpO\u001b(B\n\u001b$BpP\u001b(B\n\u001b$BpQ\u001b(B\n\u001b$BpR\u001b(B\n\u001b$BpS\u001b(B\n\u001b$BpT\u001b(B\n\u001b$BpU\u001b(B\n\u001b$BpV\u001b(B\n\u001b$BpW\u001b(B\n\u001b$BpX\u001b(B\n\u001b$BpY\u001b(B\n\u001b$BpZ\u001b(B\n\u001b$Bp[\u001b(B\n\u001b$Bp\\\u001b(B\n\u001b$Bp]\u001b(B\n\u001b$Bp^\u001b(B\n\u001b$Bp_\u001b(B\n\u001b$Bp`\u001b(B\n\u001b$Bpa\u001b(B\n\u001b$Bpb\u001b(B\n\u001b$Bpc\u001b(B\n\u001b$Bpd\u001b(B\n\u001b$Bpe\u001b(B\n\u001b$Bpf\u001b(B\n\u001b$Bpg\u001b(B\n\u001b$Bph\u001b(B\n\u001b$Bpi\u001b(B\n\u001b$Bpj\u001b(B\n\u001b$Bpk\u001b(B\n\u001b$Bpl\u001b(B\n\u001b$Bpm\u001b(B\n\u001b$Bpn\u001b(B\n\u001b$Bpo\u001b(B\n\u001b$Bpp\u001b(B\n\u001b$Bpq\u001b(B\n\u001b$Bpr\u001b(B\n\u001b$Bps\u001b(B\n\u001b$Bpt\u001b(B\n\u001b$Bpu\u001b(B\n\u001b$Bpv\u001b(B\n\u001b$Bpw\u001b(B\n\u001b$Bpx\u001b(B\n\u001b$Bpy\u001b(B\n\u001b$Bpz\u001b(B\n\u001b$Bp{\u001b(B\n\u001b$Bp|\u001b(B\n\u001b$Bp}\u001b(B\n\u001b$Bp~\u001b(B\n\u001b$Bq!\u001b(B\n\u001b$Bq\"\u001b(B\n\u001b$Bq#\u001b(B\n\u001b$Bq$\u001b(B\n\u001b$Bq%\u001b(B\n\u001b$Bq&\u001b(B\n\u001b$Bq'\u001b(B\n\u001b$Bq(\u001b(B\n\u001b$Bq)\u001b(B\n\u001b$Bq*\u001b(B\n\u001b$Bq+\u001b(B\n\u001b$Bq,\u001b(B\n\u001b$Bq-\u001b(B\n\u001b$Bq.\u001b(B\n\u001b$Bq/\u001b(B\n\u001b$Bq0\u001b(B\n\u001b$Bq1\u001b(B\n\u001b$Bq2\u001b(B\n\u001b$Bq3\u001b(B\n\u001b$Bq4\u001b(B\n\u001b$Bq5\u001b(B\n\u001b$Bq6\u001b(B\n\u001b$Bq7\u001b(B\n\u001b$Bq8\u001b(B\n\u001b$Bq9\u001b(B\n\u001b$Bq:\u001b(B\n\u001b$Bq;\u001b(B\n\u001b$Bq<\u001b(B\n\u001b$Bq=\u001b(B\n\u001b$Bq>\u001b(B\n\u001b$Bq?\u001b(B\n\u001b$Bq@\u001b(B\n\u001b$BqA\u001b(B\n\u001b$BqB\u001b(B\n\u001b$BqC\u001b(B\n\u001b$BqD\u001b(B\n\u001b$BqE\u001b(B\n\u001b$BqF\u001b(B\n\u001b$BqG\u001b(B\n\u001b$BqH\u001b(B\n\u001b$BqI\u001b(B\n\u001b$BqJ\u001b(B\n\u001b$BqK\u001b(B\n\u001b$BqL\u001b(B\n\u001b$BqM\u001b(B\n\u001b$BqN\u001b(B\n\u001b$BqO\u001b(B\n\u001b$BqP\u001b(B\n\u001b$BqQ\u001b(B\n\u001b$BqR\u001b(B\n\u001b$BqS\u001b(B\n\u001b$BqT\u001b(B\n\u001b$BqU\u001b(B\n\u001b$BqV\u001b(B\n\u001b$BqW\u001b(B\n\u001b$BqX\u001b(B\n\u001b$BqY\u001b(B\n\u001b$BqZ\u001b(B\n\u001b$Bq[\u001b(B\n\u001b$Bq\\\u001b(B\n\u001b$Bq]\u001b(B\n\u001b$Bq^\u001b(B\n\u001b$Bq_\u001b(B\n\u001b$Bq`\u001b(B\n\u001b$Bqa\u001b(B\n\u001b$Bqb\u001b(B\n\u001b$Bqc\u001b(B\n\u001b$Bqd\u001b(B\n\u001b$Bqe\u001b(B\n\u001b$Bqf\u001b(B\n\u001b$Bqg\u001b(B\n\u001b$Bqh\u001b(B\n\u001b$Bqi\u001b(B\n\u001b$Bqj\u001b(B\n\u001b$Bqk\u001b(B\n\u001b$Bql\u001b(B\n\u001b$Bqm\u001b(B\n\u001b$Bqn\u001b(B\n\u001b$Bqo\u001b(B\n\u001b$Bqp\u001b(B\n\u001b$Bqq\u001b(B\n\u001b$Bqr\u001b(B\n\u001b$Bqs\u001b(B\n\u001b$Bqt\u001b(B\n\u001b$Bqu\u001b(B\n\u001b$Bqv\u001b(B\n\u001b$Bqw\u001b(B\n\u001b$Bqx\u001b(B\n\u001b$Bqy\u001b(B\n\u001b$Bqz\u001b(B\n\u001b$Bq{\u001b(B\n\u001b$Bq|\u001b(B\n\u001b$Bq}\u001b(B\n\u001b$Bq~\u001b(B\n\u001b$Br!\u001b(B\n\u001b$Br\"\u001b(B\n\u001b$Br#\u001b(B\n\u001b$Br$\u001b(B\n\u001b$Br%\u001b(B\n\u001b$Br&\u001b(B\n\u001b$Br'\u001b(B\n\u001b$Br(\u001b(B\n\u001b$Br)\u001b(B\n\u001b$Br*\u001b(B\n\u001b$Br+\u001b(B\n\u001b$Br,\u001b(B\n\u001b$Br-\u001b(B\n\u001b$Br.\u001b(B\n\u001b$Br/\u001b(B\n\u001b$Br0\u001b(B\n\u001b$Br1\u001b(B\n\u001b$Br2\u001b(B\n\u001b$Br3\u001b(B\n\u001b$Br4\u001b(B\n\u001b$Br5\u001b(B\n\u001b$Br6\u001b(B\n\u001b$Br7\u001b(B\n\u001b$Br8\u001b(B\n\u001b$Br9\u001b(B\n\u001b$Br:\u001b(B\n\u001b$Br;\u001b(B\n\u001b$Br<\u001b(B\n\u001b$Br=\u001b(B\n\u001b$Br>\u001b(B\n\u001b$Br?\u001b(B\n\u001b$Br@\u001b(B\n\u001b$BrA\u001b(B\n\u001b$BrB\u001b(B\n\u001b$BrC\u001b(B\n\u001b$BrD\u001b(B\n\u001b$BrE\u001b(B\n\u001b$BrF\u001b(B\n\u001b$BrG\u001b(B\n\u001b$BrH\u001b(B\n\u001b$BrI\u001b(B\n\u001b$BrJ\u001b(B\n\u001b$BrK\u001b(B\n\u001b$BrL\u001b(B\n\u001b$BrM\u001b(B\n\u001b$BrN\u001b(B\n\u001b$BrO\u001b(B\n\u001b$BrP\u001b(B\n\u001b$BrQ\u001b(B\n\u001b$BrR\u001b(B\n\u001b$BrS\u001b(B\n\u001b$BrT\u001b(B\n\u001b$BrU\u001b(B\n\u001b$BrV\u001b(B\n\u001b$BrW\u001b(B\n\u001b$BrX\u001b(B\n\u001b$BrY\u001b(B\n\u001b$BrZ\u001b(B\n\u001b$Br[\u001b(B\n\u001b$Br\\\u001b(B\n\u001b$Br]\u001b(B\n\u001b$Br^\u001b(B\n\u001b$Br_\u001b(B\n\u001b$Br`\u001b(B\n\u001b$Bra\u001b(B\n\u001b$Brb\u001b(B\n\u001b$Brc\u001b(B\n\u001b$Brd\u001b(B\n\u001b$Bre\u001b(B\n\u001b$Brf\u001b(B\n\u001b$Brg\u001b(B\n\u001b$Brh\u001b(B\n\u001b$Bri\u001b(B\n\u001b$Brj\u001b(B\n\u001b$Brk\u001b(B\n\u001b$Brl\u001b(B\n\u001b$Brm\u001b(B\n\u001b$Brn\u001b(B\n\u001b$Bro\u001b(B\n\u001b$Brp\u001b(B\n\u001b$Brq\u001b(B\n\u001b$Brr\u001b(B\n\u001b$Brs\u001b(B\n\u001b$Brt\u001b(B\n\u001b$Bru\u001b(B\n\u001b$Brv\u001b(B\n\u001b$Brw\u001b(B\n\u001b$Brx\u001b(B\n\u001b$Bry\u001b(B\n\u001b$Brz\u001b(B\n\u001b$Br{\u001b(B\n\u001b$Br|\u001b(B\n\u001b$Br}\u001b(B\n\u001b$Br~\u001b(B\n\u001b$Bs!\u001b(B\n\u001b$Bs\"\u001b(B\n\u001b$Bs#\u001b(B\n\u001b$Bs$\u001b(B\n\u001b$Bs%\u001b(B\n\u001b$Bs&\u001b(B\n\u001b$Bs'\u001b(B\n\u001b$Bs(\u001b(B\n\u001b$Bs)\u001b(B\n\u001b$Bs*\u001b(B\n\u001b$Bs+\u001b(B\n\u001b$Bs,\u001b(B\n\u001b$Bs-\u001b(B\n\u001b$Bs.\u001b(B\n\u001b$Bs/\u001b(B\n\u001b$Bs0\u001b(B\n\u001b$Bs1\u001b(B\n\u001b$Bs2\u001b(B\n\u001b$Bs3\u001b(B\n\u001b$Bs4\u001b(B\n\u001b$Bs5\u001b(B\n\u001b$Bs6\u001b(B\n\u001b$Bs7\u001b(B\n\u001b$Bs8\u001b(B\n\u001b$Bs9\u001b(B\n\u001b$Bs:\u001b(B\n\u001b$Bs;\u001b(B\n\u001b$Bs<\u001b(B\n\u001b$Bs=\u001b(B\n\u001b$Bs>\u001b(B\n\u001b$Bs?\u001b(B\n\u001b$Bs@\u001b(B\n\u001b$BsA\u001b(B\n\u001b$BsB\u001b(B\n\u001b$BsC\u001b(B\n\u001b$BsD\u001b(B\n\u001b$BsE\u001b(B\n\u001b$BsF\u001b(B\n\u001b$BsG\u001b(B\n\u001b$BsH\u001b(B\n\u001b$BsI\u001b(B\n\u001b$BsJ\u001b(B\n\u001b$BsK\u001b(B\n\u001b$BsL\u001b(B\n\u001b$BsM\u001b(B\n\u001b$BsN\u001b(B\n\u001b$BsO\u001b(B\n\u001b$BsP\u001b(B\n\u001b$BsQ\u001b(B\n\u001b$BsR\u001b(B\n\u001b$BsS\u001b(B\n\u001b$BsT\u001b(B\n\u001b$BsU\u001b(B\n\u001b$BsV\u001b(B\n\u001b$BsW\u001b(B\n\u001b$BsX\u001b(B\n\u001b$BsY\u001b(B\n\u001b$BsZ\u001b(B\n\u001b$Bs[\u001b(B\n\u001b$Bs\\\u001b(B\n\u001b$Bs]\u001b(B\n\u001b$Bs^\u001b(B\n\u001b$Bs_\u001b(B\n\u001b$Bs`\u001b(B\n\u001b$Bsa\u001b(B\n\u001b$Bsb\u001b(B\n\u001b$Bsc\u001b(B\n\u001b$Bsd\u001b(B\n\u001b$Bse\u001b(B\n\u001b$Bsf\u001b(B\n\u001b$Bsg\u001b(B\n\u001b$Bsh\u001b(B\n\u001b$Bsi\u001b(B\n\u001b$Bsj\u001b(B\n\u001b$Bsk\u001b(B\n\u001b$Bsl\u001b(B\n\u001b$Bsm\u001b(B\n\u001b$Bsn\u001b(B\n\u001b$Bso\u001b(B\n\u001b$Bsp\u001b(B\n\u001b$Bsq\u001b(B\n\u001b$Bsr\u001b(B\n\u001b$Bss\u001b(B\n\u001b$Bst\u001b(B\n\u001b$Bsu\u001b(B\n\u001b$Bsv\u001b(B\n\u001b$Bsw\u001b(B\n\u001b$Bsx\u001b(B\n\u001b$Bsy\u001b(B\n\u001b$Bsz\u001b(B\n\u001b$Bs{\u001b(B\n\u001b$Bs|\u001b(B\n\u001b$Bs}\u001b(B\n\u001b$Bs~\u001b(B\n\u001b$Bt!\u001b(B\n\u001b$Bt\"\u001b(B\n\u001b$Bt#\u001b(B\n\u001b$Bt$\u001b(B\n\u001b$Bt%\u001b(B\n\u001b$Bt&\u001b(B\n\u001b$Bt'\u001b(B\n\u001b$Bt(\u001b(B\n\u001b$Bt)\u001b(B\n\u001b$Bt*\u001b(B\n\u001b$Bt+\u001b(B\n\u001b$Bt,\u001b(B\n\u001b$Bt-\u001b(B\n\u001b$Bt.\u001b(B\n\u001b$Bt/\u001b(B\n\u001b$Bt0\u001b(B\n\u001b$Bt1\u001b(B\n\u001b$Bt2\u001b(B\n\u001b$Bt3\u001b(B\n\u001b$Bt4\u001b(B\n\u001b$Bt5\u001b(B\n\u001b$Bt6\u001b(B\n\u001b$Bt7\u001b(B\n\u001b$Bt8\u001b(B\n\u001b$Bt9\u001b(B\n\u001b$Bt:\u001b(B\n\u001b$Bt;\u001b(B\n\u001b$Bt<\u001b(B\n\u001b$Bt=\u001b(B\n\u001b$Bt>\u001b(B\n\u001b$Bt?\u001b(B\n\u001b$Bt@\u001b(B\n\u001b$BtA\u001b(B\n\u001b$BtB\u001b(B\n\u001b$BtC\u001b(B\n\u001b$BtD\u001b(B\n\u001b$BtE\u001b(B\n\u001b$BtF\u001b(B\n\u001b$BtG\u001b(B\n\u001b$BtH\u001b(B\n\u001b$BtI\u001b(B\n\u001b$BtJ\u001b(B\n\u001b$BtK\u001b(B\n\u001b$BtL\u001b(B\n\u001b$BtM\u001b(B\n\u001b$BtN\u001b(B\n\u001b$BtO\u001b(B\n\u001b$BtP\u001b(B\n\u001b$BtQ\u001b(B\n\u001b$BtR\u001b(B\n\u001b$BtS\u001b(B\n\u001b$BtT\u001b(B\n\u001b$BtU\u001b(B\n\u001b$BtV\u001b(B\n\u001b$BtW\u001b(B\n\u001b$BtX\u001b(B\n\u001b$BtY\u001b(B\n\u001b$BtZ\u001b(B\n\u001b$Bt[\u001b(B\n\u001b$Bt\\\u001b(B\n\u001b$Bt]\u001b(B\n\u001b$Bt^\u001b(B\n\u001b$Bt_\u001b(B\n\u001b$Bt`\u001b(B\n\u001b$Bta\u001b(B\n\u001b$Btb\u001b(B\n\u001b$Btc\u001b(B\n\u001b$Btd\u001b(B\n\u001b$Bte\u001b(B\n\u001b$Btf\u001b(B\n\u001b$Btg\u001b(B\n\u001b$Bth\u001b(B\n\u001b$Bti\u001b(B\n\u001b$Btj\u001b(B\n\u001b$Btk\u001b(B\n\u001b$Btl\u001b(B\n\u001b$Btm\u001b(B\n\u001b$Btn\u001b(B\n\u001b$Bto\u001b(B\n\u001b$Btp\u001b(B\n\u001b$Btq\u001b(B\n\u001b$Btr\u001b(B\n\u001b$Bts\u001b(B\n\u001b$Btt\u001b(B\n\u001b$Btu\u001b(B\n\u001b$Btv\u001b(B\n\u001b$Btw\u001b(B\n\u001b$Btx\u001b(B\n\u001b$Bty\u001b(B\n\u001b$Btz\u001b(B\n\u001b$Bt{\u001b(B\n\u001b$Bt|\u001b(B\n\u001b$Bt}\u001b(B\n\u001b$Bt~\u001b(B\n\u001b$Bu!\u001b(B\n\u001b$Bu\"\u001b(B\n\u001b$Bu#\u001b(B\n\u001b$Bu$\u001b(B\n\u001b$Bu%\u001b(B\n\u001b$Bu&\u001b(B\n\u001b$Bu'\u001b(B\n\u001b$Bu(\u001b(B\n\u001b$Bu)\u001b(B\n\u001b$Bu*\u001b(B\n\u001b$Bu+\u001b(B\n\u001b$Bu,\u001b(B\n\u001b$Bu-\u001b(B\n\u001b$Bu.\u001b(B\n\u001b$Bu/\u001b(B\n\u001b$Bu0\u001b(B\n\u001b$Bu1\u001b(B\n\u001b$Bu2\u001b(B\n\u001b$Bu3\u001b(B\n\u001b$Bu4\u001b(B\n\u001b$Bu5\u001b(B\n\u001b$Bu6\u001b(B\n\u001b$Bu7\u001b(B\n\u001b$Bu8\u001b(B\n\u001b$Bu9\u001b(B\n\u001b$Bu:\u001b(B\n\u001b$Bu;\u001b(B\n\u001b$Bu<\u001b(B\n\u001b$Bu=\u001b(B\n\u001b$Bu>\u001b(B\n\u001b$Bu?\u001b(B\n\u001b$Bu@\u001b(B\n\u001b$BuA\u001b(B\n\u001b$BuB\u001b(B\n\u001b$BuC\u001b(B\n\u001b$BuD\u001b(B\n\u001b$BuE\u001b(B\n\u001b$BuF\u001b(B\n\u001b$BuG\u001b(B\n\u001b$BuH\u001b(B\n\u001b$BuI\u001b(B\n\u001b$BuJ\u001b(B\n\u001b$BuK\u001b(B\n\u001b$BuL\u001b(B\n\u001b$BuM\u001b(B\n\u001b$BuN\u001b(B\n\u001b$BuO\u001b(B\n\u001b$BuP\u001b(B\n\u001b$BuQ\u001b(B\n\u001b$BuR\u001b(B\n\u001b$BuS\u001b(B\n\u001b$BuT\u001b(B\n\u001b$BuU\u001b(B\n\u001b$BuV\u001b(B\n\u001b$BuW\u001b(B\n\u001b$BuX\u001b(B\n\u001b$BuY\u001b(B\n\u001b$BuZ\u001b(B\n\u001b$Bu[\u001b(B\n\u001b$Bu\\\u001b(B\n\u001b$Bu]\u001b(B\n\u001b$Bu^\u001b(B\n\u001b$Bu_\u001b(B\n\u001b$Bu`\u001b(B\n\u001b$Bua\u001b(B\n\u001b$Bub\u001b(B\n\u001b$Buc\u001b(B\n\u001b$Bud\u001b(B\n\u001b$Bue\u001b(B\n\u001b$Buf\u001b(B\n\u001b$Bug\u001b(B\n\u001b$Buh\u001b(B\n\u001b$Bui\u001b(B\n\u001b$Buj\u001b(B\n\u001b$Buk\u001b(B\n\u001b$Bul\u001b(B\n\u001b$Bum\u001b(B\n\u001b$Bun\u001b(B\n\u001b$Buo\u001b(B\n\u001b$Bup\u001b(B\n\u001b$Buq\u001b(B\n\u001b$Bur\u001b(B\n\u001b$Bus\u001b(B\n\u001b$But\u001b(B\n\u001b$Buu\u001b(B\n\u001b$Buv\u001b(B\n\u001b$Buw\u001b(B\n\u001b$Bux\u001b(B\n\u001b$Buy\u001b(B\n\u001b$Buz\u001b(B\n\u001b$Bu{\u001b(B\n\u001b$Bu|\u001b(B\n\u001b$Bu}\u001b(B\n\u001b$Bu~\u001b(B\n\u001b$Bv!\u001b(B\n\u001b$Bv\"\u001b(B\n\u001b$Bv#\u001b(B\n\u001b$Bv$\u001b(B\n\u001b$Bv%\u001b(B\n\u001b$Bv&\u001b(B\n\u001b$Bv'\u001b(B\n\u001b$Bv(\u001b(B\n\u001b$Bv)\u001b(B\n\u001b$Bv*\u001b(B\n\u001b$Bv+\u001b(B\n\u001b$Bv,\u001b(B\n\u001b$Bv-\u001b(B\n\u001b$Bv.\u001b(B\n\u001b$Bv/\u001b(B\n\u001b$Bv0\u001b(B\n\u001b$Bv1\u001b(B\n\u001b$Bv2\u001b(B\n\u001b$Bv3\u001b(B\n\u001b$Bv4\u001b(B\n\u001b$Bv5\u001b(B\n\u001b$Bv6\u001b(B\n\u001b$Bv7\u001b(B\n\u001b$Bv8\u001b(B\n\u001b$Bv9\u001b(B\n\u001b$Bv:\u001b(B\n\u001b$Bv;\u001b(B\n\u001b$Bv<\u001b(B\n\u001b$Bv=\u001b(B\n\u001b$Bv>\u001b(B\n\u001b$Bv?\u001b(B\n\u001b$Bv@\u001b(B\n\u001b$BvA\u001b(B\n\u001b$BvB\u001b(B\n\u001b$BvC\u001b(B\n\u001b$BvD\u001b(B\n\u001b$BvE\u001b(B\n\u001b$BvF\u001b(B\n\u001b$BvG\u001b(B\n\u001b$BvH\u001b(B\n\u001b$BvI\u001b(B\n\u001b$BvJ\u001b(B\n\u001b$BvK\u001b(B\n\u001b$BvL\u001b(B\n\u001b$BvM\u001b(B\n\u001b$BvN\u001b(B\n\u001b$BvO\u001b(B\n\u001b$BvP\u001b(B\n\u001b$BvQ\u001b(B\n\u001b$BvR\u001b(B\n\u001b$BvS\u001b(B\n\u001b$BvT\u001b(B\n\u001b$BvU\u001b(B\n\u001b$BvV\u001b(B\n\u001b$BvW\u001b(B\n\u001b$BvX\u001b(B\n\u001b$BvY\u001b(B\n\u001b$BvZ\u001b(B\n\u001b$Bv[\u001b(B\n\u001b$Bv\\\u001b(B\n\u001b$Bv]\u001b(B\n\u001b$Bv^\u001b(B\n\u001b$Bv_\u001b(B\n\u001b$Bv`\u001b(B\n\u001b$Bva\u001b(B\n\u001b$Bvb\u001b(B\n\u001b$Bvc\u001b(B\n\u001b$Bvd\u001b(B\n\u001b$Bve\u001b(B\n\u001b$Bvf\u001b(B\n\u001b$Bvg\u001b(B\n\u001b$Bvh\u001b(B\n\u001b$Bvi\u001b(B\n\u001b$Bvj\u001b(B\n\u001b$Bvk\u001b(B\n\u001b$Bvl\u001b(B\n\u001b$Bvm\u001b(B\n\u001b$Bvn\u001b(B\n\u001b$Bvo\u001b(B\n\u001b$Bvp\u001b(B\n\u001b$Bvq\u001b(B\n\u001b$Bvr\u001b(B\n\u001b$Bvs\u001b(B\n\u001b$Bvt\u001b(B\n\u001b$Bvu\u001b(B\n\u001b$Bvv\u001b(B\n\u001b$Bvw\u001b(B\n\u001b$Bvx\u001b(B\n\u001b$Bvy\u001b(B\n\u001b$Bvz\u001b(B\n\u001b$Bv{\u001b(B\n\u001b$Bv|\u001b(B\n\u001b$Bv}\u001b(B\n\u001b$Bv~\u001b(B\n\u001b$Bw!\u001b(B\n\u001b$Bw\"\u001b(B\n\u001b$Bw#\u001b(B\n\u001b$Bw$\u001b(B\n\u001b$Bw%\u001b(B\n\u001b$Bw&\u001b(B\n\u001b$Bw'\u001b(B\n\u001b$Bw(\u001b(B\n\u001b$Bw)\u001b(B\n\u001b$Bw*\u001b(B\n\u001b$Bw+\u001b(B\n\u001b$Bw,\u001b(B\n\u001b$Bw-\u001b(B\n\u001b$Bw.\u001b(B\n\u001b$Bw/\u001b(B\n\u001b$Bw0\u001b(B\n\u001b$Bw1\u001b(B\n\u001b$Bw2\u001b(B\n\u001b$Bw3\u001b(B\n\u001b$Bw4\u001b(B\n\u001b$Bw5\u001b(B\n\u001b$Bw6\u001b(B\n\u001b$Bw7\u001b(B\n\u001b$Bw8\u001b(B\n\u001b$Bw9\u001b(B\n\u001b$Bw:\u001b(B\n\u001b$Bw;\u001b(B\n\u001b$Bw<\u001b(B\n\u001b$Bw=\u001b(B\n\u001b$Bw>\u001b(B\n\u001b$Bw?\u001b(B\n\u001b$Bw@\u001b(B\n\u001b$BwA\u001b(B\n\u001b$BwB\u001b(B\n\u001b$BwC\u001b(B\n\u001b$BwD\u001b(B\n\u001b$BwE\u001b(B\n\u001b$BwF\u001b(B\n\u001b$BwG\u001b(B\n\u001b$BwH\u001b(B\n\u001b$BwI\u001b(B\n\u001b$BwJ\u001b(B\n\u001b$BwK\u001b(B\n\u001b$BwL\u001b(B\n\u001b$BwM\u001b(B\n\u001b$BwN\u001b(B\n\u001b$BwO\u001b(B\n\u001b$BwP\u001b(B\n\u001b$BwQ\u001b(B\n\u001b$BwR\u001b(B\n\u001b$BwS\u001b(B\n\u001b$BwT\u001b(B\n\u001b$BwU\u001b(B\n\u001b$BwV\u001b(B\n\u001b$BwW\u001b(B\n\u001b$BwX\u001b(B\n\u001b$BwY\u001b(B\n\u001b$BwZ\u001b(B\n\u001b$Bw[\u001b(B\n\u001b$Bw\\\u001b(B\n\u001b$Bw]\u001b(B\n\u001b$Bw^\u001b(B\n\u001b$Bw_\u001b(B\n\u001b$Bw`\u001b(B\n\u001b$Bwa\u001b(B\n\u001b$Bwb\u001b(B\n\u001b$Bwc\u001b(B\n\u001b$Bwd\u001b(B\n\u001b$Bwe\u001b(B\n\u001b$Bwf\u001b(B\n\u001b$Bwg\u001b(B\n\u001b$Bwh\u001b(B\n\u001b$Bwi\u001b(B\n\u001b$Bwj\u001b(B\n\u001b$Bwk\u001b(B\n\u001b$Bwl\u001b(B\n\u001b$Bwm\u001b(B\n\u001b$Bwn\u001b(B\n\u001b$Bwo\u001b(B\n\u001b$Bwp\u001b(B\n\u001b$Bwq\u001b(B\n\u001b$Bwr\u001b(B\n\u001b$Bws\u001b(B\n\u001b$Bwt\u001b(B\n\u001b$Bwu\u001b(B\n\u001b$Bwv\u001b(B\n\u001b$Bww\u001b(B\n\u001b$Bwx\u001b(B\n\u001b$Bwy\u001b(B\n\u001b$Bwz\u001b(B\n\u001b$Bw{\u001b(B\n\u001b$Bw|\u001b(B\n\u001b$Bw}\u001b(B\n\u001b$Bw~\u001b(B\n\u001b$Bx!\u001b(B\n\u001b$Bx\"\u001b(B\n\u001b$Bx#\u001b(B\n\u001b$Bx$\u001b(B\n\u001b$Bx%\u001b(B\n\u001b$Bx&\u001b(B\n\u001b$Bx'\u001b(B\n\u001b$Bx(\u001b(B\n\u001b$Bx)\u001b(B\n\u001b$Bx*\u001b(B\n\u001b$Bx+\u001b(B\n\u001b$Bx,\u001b(B\n\u001b$Bx-\u001b(B\n\u001b$Bx.\u001b(B\n\u001b$Bx/\u001b(B\n\u001b$Bx0\u001b(B\n\u001b$Bx1\u001b(B\n\u001b$Bx2\u001b(B\n\u001b$Bx3\u001b(B\n\u001b$Bx4\u001b(B\n\u001b$Bx5\u001b(B\n\u001b$Bx6\u001b(B\n\u001b$Bx7\u001b(B\n\u001b$Bx8\u001b(B\n\u001b$Bx9\u001b(B\n\u001b$Bx:\u001b(B\n\u001b$Bx;\u001b(B\n\u001b$Bx<\u001b(B\n\u001b$Bx=\u001b(B\n\u001b$Bx>\u001b(B\n\u001b$Bx?\u001b(B\n\u001b$Bx@\u001b(B\n\u001b$BxA\u001b(B\n\u001b$BxB\u001b(B\n\u001b$BxC\u001b(B\n\u001b$BxD\u001b(B\n\u001b$BxE\u001b(B\n\u001b$BxF\u001b(B\n\u001b$BxG\u001b(B\n\u001b$BxH\u001b(B\n\u001b$BxI\u001b(B\n\u001b$BxJ\u001b(B\n\u001b$BxK\u001b(B\n\u001b$BxL\u001b(B\n\u001b$BxM\u001b(B\n\u001b$BxN\u001b(B\n\u001b$BxO\u001b(B\n\u001b$BxP\u001b(B\n\u001b$BxQ\u001b(B\n\u001b$BxR\u001b(B\n\u001b$BxS\u001b(B\n\u001b$BxT\u001b(B\n\u001b$BxU\u001b(B\n\u001b$BxV\u001b(B\n\u001b$BxW\u001b(B\n\u001b$BxX\u001b(B\n\u001b$BxY\u001b(B\n\u001b$BxZ\u001b(B\n\u001b$Bx[\u001b(B\n\u001b$Bx\\\u001b(B\n\u001b$Bx]\u001b(B\n\u001b$Bx^\u001b(B\n\u001b$Bx_\u001b(B\n\u001b$Bx`\u001b(B\n\u001b$Bxa\u001b(B\n\u001b$Bxb\u001b(B\n\u001b$Bxc\u001b(B\n\u001b$Bxd\u001b(B\n\u001b$Bxe\u001b(B\n\u001b$Bxf\u001b(B\n\u001b$Bxg\u001b(B\n\u001b$Bxh\u001b(B\n\u001b$Bxi\u001b(B\n\u001b$Bxj\u001b(B\n\u001b$Bxk\u001b(B\n\u001b$Bxl\u001b(B\n\u001b$Bxm\u001b(B\n\u001b$Bxn\u001b(B\n\u001b$Bxo\u001b(B\n\u001b$Bxp\u001b(B\n\u001b$Bxq\u001b(B\n\u001b$Bxr\u001b(B\n\u001b$Bxs\u001b(B\n\u001b$Bxt\u001b(B\n\u001b$Bxu\u001b(B\n\u001b$Bxv\u001b(B\n\u001b$Bxw\u001b(B\n\u001b$Bxx\u001b(B\n\u001b$Bxy\u001b(B\n\u001b$Bxz\u001b(B\n\u001b$Bx{\u001b(B\n\u001b$Bx|\u001b(B\n\u001b$Bx}\u001b(B\n\u001b$Bx~\u001b(B\n\u001b$By!\u001b(B\n\u001b$By\"\u001b(B\n\u001b$By#\u001b(B\n\u001b$By$\u001b(B\n\u001b$By%\u001b(B\n\u001b$By&\u001b(B\n\u001b$By'\u001b(B\n\u001b$By(\u001b(B\n\u001b$By)\u001b(B\n\u001b$By*\u001b(B\n\u001b$By+\u001b(B\n\u001b$By,\u001b(B\n\u001b$By-\u001b(B\n\u001b$By.\u001b(B\n\u001b$By/\u001b(B\n\u001b$By0\u001b(B\n\u001b$By1\u001b(B\n\u001b$By2\u001b(B\n\u001b$By3\u001b(B\n\u001b$By4\u001b(B\n\u001b$By5\u001b(B\n\u001b$By6\u001b(B\n\u001b$By7\u001b(B\n\u001b$By8\u001b(B\n\u001b$By9\u001b(B\n\u001b$By:\u001b(B\n\u001b$By;\u001b(B\n\u001b$By<\u001b(B\n\u001b$By=\u001b(B\n\u001b$By>\u001b(B\n\u001b$By?\u001b(B\n\u001b$By@\u001b(B\n\u001b$ByA\u001b(B\n\u001b$ByB\u001b(B\n\u001b$ByC\u001b(B\n\u001b$ByD\u001b(B\n\u001b$ByE\u001b(B\n\u001b$ByF\u001b(B\n\u001b$ByG\u001b(B\n\u001b$ByH\u001b(B\n\u001b$ByI\u001b(B\n\u001b$ByJ\u001b(B\n\u001b$ByK\u001b(B\n\u001b$ByL\u001b(B\n\u001b$ByM\u001b(B\n\u001b$ByN\u001b(B\n\u001b$ByO\u001b(B\n\u001b$ByP\u001b(B\n\u001b$ByQ\u001b(B\n\u001b$ByR\u001b(B\n\u001b$ByS\u001b(B\n\u001b$ByT\u001b(B\n\u001b$ByU\u001b(B\n\u001b$ByV\u001b(B\n\u001b$ByW\u001b(B\n\u001b$ByX\u001b(B\n\u001b$ByY\u001b(B\n\u001b$ByZ\u001b(B\n\u001b$By[\u001b(B\n\u001b$By\\\u001b(B\n\u001b$By]\u001b(B\n\u001b$By^\u001b(B\n\u001b$By_\u001b(B\n\u001b$By`\u001b(B\n\u001b$Bya\u001b(B\n\u001b$Byb\u001b(B\n\u001b$Byc\u001b(B\n\u001b$Byd\u001b(B\n\u001b$Bye\u001b(B\n\u001b$Byf\u001b(B\n\u001b$Byg\u001b(B\n\u001b$Byh\u001b(B\n\u001b$Byi\u001b(B\n\u001b$Byj\u001b(B\n\u001b$Byk\u001b(B\n\u001b$Byl\u001b(B\n\u001b$Bym\u001b(B\n\u001b$Byn\u001b(B\n\u001b$Byo\u001b(B\n\u001b$Byp\u001b(B\n\u001b$Byq\u001b(B\n\u001b$Byr\u001b(B\n\u001b$Bys\u001b(B\n\u001b$Byt\u001b(B\n\u001b$Byu\u001b(B\n\u001b$Byv\u001b(B\n\u001b$Byw\u001b(B\n\u001b$Byx\u001b(B\n\u001b$Byy\u001b(B\n\u001b$Byz\u001b(B\n\u001b$By{\u001b(B\n\u001b$By|\u001b(B\n\u001b$By}\u001b(B\n\u001b$By~\u001b(B\n\u001b$Bz!\u001b(B\n\u001b$Bz\"\u001b(B\n\u001b$Bz#\u001b(B\n\u001b$Bz$\u001b(B\n\u001b$Bz%\u001b(B\n\u001b$Bz&\u001b(B\n\u001b$Bz'\u001b(B\n\u001b$Bz(\u001b(B\n\u001b$Bz)\u001b(B\n\u001b$Bz*\u001b(B\n\u001b$Bz+\u001b(B\n\u001b$Bz,\u001b(B\n\u001b$Bz-\u001b(B\n\u001b$Bz.\u001b(B\n\u001b$Bz/\u001b(B\n\u001b$Bz0\u001b(B\n\u001b$Bz1\u001b(B\n\u001b$Bz2\u001b(B\n\u001b$Bz3\u001b(B\n\u001b$Bz4\u001b(B\n\u001b$Bz5\u001b(B\n\u001b$Bz6\u001b(B\n\u001b$Bz7\u001b(B\n\u001b$Bz8\u001b(B\n\u001b$Bz9\u001b(B\n\u001b$Bz:\u001b(B\n\u001b$Bz;\u001b(B\n\u001b$Bz<\u001b(B\n\u001b$Bz=\u001b(B\n\u001b$Bz>\u001b(B\n\u001b$Bz?\u001b(B\n\u001b$Bz@\u001b(B\n\u001b$BzA\u001b(B\n\u001b$BzB\u001b(B\n\u001b$BzC\u001b(B\n\u001b$BzD\u001b(B\n\u001b$BzE\u001b(B\n\u001b$BzF\u001b(B\n\u001b$BzG\u001b(B\n\u001b$BzH\u001b(B\n\u001b$BzI\u001b(B\n\u001b$BzJ\u001b(B\n\u001b$BzK\u001b(B\n\u001b$BzL\u001b(B\n\u001b$BzM\u001b(B\n\u001b$BzN\u001b(B\n\u001b$BzO\u001b(B\n\u001b$BzP\u001b(B\n\u001b$BzQ\u001b(B\n\u001b$BzR\u001b(B\n\u001b$BzS\u001b(B\n\u001b$BzT\u001b(B\n\u001b$BzU\u001b(B\n\u001b$BzV\u001b(B\n\u001b$BzW\u001b(B\n\u001b$BzX\u001b(B\n\u001b$BzY\u001b(B\n\u001b$BzZ\u001b(B\n\u001b$Bz[\u001b(B\n\u001b$Bz\\\u001b(B\n\u001b$Bz]\u001b(B\n\u001b$Bz^\u001b(B\n\u001b$Bz_\u001b(B\n\u001b$Bz`\u001b(B\n\u001b$Bza\u001b(B\n\u001b$Bzb\u001b(B\n\u001b$Bzc\u001b(B\n\u001b$Bzd\u001b(B\n\u001b$Bze\u001b(B\n\u001b$Bzf\u001b(B\n\u001b$Bzg\u001b(B\n\u001b$Bzh\u001b(B\n\u001b$Bzi\u001b(B\n\u001b$Bzj\u001b(B\n\u001b$Bzk\u001b(B\n\u001b$Bzl\u001b(B\n\u001b$Bzm\u001b(B\n\u001b$Bzn\u001b(B\n\u001b$Bzo\u001b(B\n\u001b$Bzp\u001b(B\n\u001b$Bzq\u001b(B\n\u001b$Bzr\u001b(B\n\u001b$Bzs\u001b(B\n\u001b$Bzt\u001b(B\n\u001b$Bzu\u001b(B\n\u001b$Bzv\u001b(B\n\u001b$Bzw\u001b(B\n\u001b$Bzx\u001b(B\n\u001b$Bzy\u001b(B\n\u001b$Bzz\u001b(B\n\u001b$Bz{\u001b(B\n\u001b$Bz|\u001b(B\n\u001b$Bz}\u001b(B\n\u001b$Bz~\u001b(B\n\u001b$B{!\u001b(B\n\u001b$B{\"\u001b(B\n\u001b$B{#\u001b(B\n\u001b$B{$\u001b(B\n\u001b$B{%\u001b(B\n\u001b$B{&\u001b(B\n\u001b$B{'\u001b(B\n\u001b$B{(\u001b(B\n\u001b$B{)\u001b(B\n\u001b$B{*\u001b(B\n\u001b$B{+\u001b(B\n\u001b$B{,\u001b(B\n\u001b$B{-\u001b(B\n\u001b$B{.\u001b(B\n\u001b$B{/\u001b(B\n\u001b$B{0\u001b(B\n\u001b$B{1\u001b(B\n\u001b$B{2\u001b(B\n\u001b$B{3\u001b(B\n\u001b$B{4\u001b(B\n\u001b$B{5\u001b(B\n\u001b$B{6\u001b(B\n\u001b$B{7\u001b(B\n\u001b$B{8\u001b(B\n\u001b$B{9\u001b(B\n\u001b$B{:\u001b(B\n\u001b$B{;\u001b(B\n\u001b$B{<\u001b(B\n\u001b$B{=\u001b(B\n\u001b$B{>\u001b(B\n\u001b$B{?\u001b(B\n\u001b$B{@\u001b(B\n\u001b$B{A\u001b(B\n\u001b$B{B\u001b(B\n\u001b$B{C\u001b(B\n\u001b$B{D\u001b(B\n\u001b$B{E\u001b(B\n\u001b$B{F\u001b(B\n\u001b$B{G\u001b(B\n\u001b$B{H\u001b(B\n\u001b$B{I\u001b(B\n\u001b$B{J\u001b(B\n\u001b$B{K\u001b(B\n\u001b$B{L\u001b(B\n\u001b$B{M\u001b(B\n\u001b$B{N\u001b(B\n\u001b$B{O\u001b(B\n\u001b$B{P\u001b(B\n\u001b$B{Q\u001b(B\n\u001b$B{R\u001b(B\n\u001b$B{S\u001b(B\n\u001b$B{T\u001b(B\n\u001b$B{U\u001b(B\n\u001b$B{V\u001b(B\n\u001b$B{W\u001b(B\n\u001b$B{X\u001b(B\n\u001b$B{Y\u001b(B\n\u001b$B{Z\u001b(B\n\u001b$B{[\u001b(B\n\u001b$B{\\\u001b(B\n\u001b$B{]\u001b(B\n\u001b$B{^\u001b(B\n\u001b$B{_\u001b(B\n\u001b$B{`\u001b(B\n\u001b$B{a\u001b(B\n\u001b$B{b\u001b(B\n\u001b$B{c\u001b(B\n\u001b$B{d\u001b(B\n\u001b$B{e\u001b(B\n\u001b$B{f\u001b(B\n\u001b$B{g\u001b(B\n\u001b$B{h\u001b(B\n\u001b$B{i\u001b(B\n\u001b$B{j\u001b(B\n\u001b$B{k\u001b(B\n\u001b$B{l\u001b(B\n\u001b$B{m\u001b(B\n\u001b$B{n\u001b(B\n\u001b$B{o\u001b(B\n\u001b$B{p\u001b(B\n\u001b$B{q\u001b(B\n\u001b$B{r\u001b(B\n\u001b$B{s\u001b(B\n\u001b$B{t\u001b(B\n\u001b$B{u\u001b(B\n\u001b$B{v\u001b(B\n\u001b$B{w\u001b(B\n\u001b$B{x\u001b(B\n\u001b$B{y\u001b(B\n\u001b$B{z\u001b(B\n\u001b$B{{\u001b(B\n\u001b$B{|\u001b(B\n\u001b$B{}\u001b(B\n\u001b$B{~\u001b(B\n\u001b$B|!\u001b(B\n\u001b$B|\"\u001b(B\n\u001b$B|#\u001b(B\n\u001b$B|$\u001b(B\n\u001b$B|%\u001b(B\n\u001b$B|&\u001b(B\n\u001b$B|'\u001b(B\n\u001b$B|(\u001b(B\n\u001b$B|)\u001b(B\n\u001b$B|*\u001b(B\n\u001b$B|+\u001b(B\n\u001b$B|,\u001b(B\n\u001b$B|-\u001b(B\n\u001b$B|.\u001b(B\n\u001b$B|/\u001b(B\n\u001b$B|0\u001b(B\n\u001b$B|1\u001b(B\n\u001b$B|2\u001b(B\n\u001b$B|3\u001b(B\n\u001b$B|4\u001b(B\n\u001b$B|5\u001b(B\n\u001b$B|6\u001b(B\n\u001b$B|7\u001b(B\n\u001b$B|8\u001b(B\n\u001b$B|9\u001b(B\n\u001b$B|:\u001b(B\n\u001b$B|;\u001b(B\n\u001b$B|<\u001b(B\n\u001b$B|=\u001b(B\n\u001b$B|>\u001b(B\n\u001b$B|?\u001b(B\n\u001b$B|@\u001b(B\n\u001b$B|A\u001b(B\n\u001b$B|B\u001b(B\n\u001b$B|C\u001b(B\n\u001b$B|D\u001b(B\n\u001b$B|E\u001b(B\n\u001b$B|F\u001b(B\n\u001b$B|G\u001b(B\n\u001b$B|H\u001b(B\n\u001b$B|I\u001b(B\n\u001b$B|J\u001b(B\n\u001b$B|K\u001b(B\n\u001b$B|L\u001b(B\n\u001b$B|M\u001b(B\n\u001b$B|N\u001b(B\n\u001b$B|O\u001b(B\n\u001b$B|P\u001b(B\n\u001b$B|Q\u001b(B\n\u001b$B|R\u001b(B\n\u001b$B|S\u001b(B\n\u001b$B|T\u001b(B\n\u001b$B|U\u001b(B\n\u001b$B|V\u001b(B\n\u001b$B|W\u001b(B\n\u001b$B|X\u001b(B\n\u001b$B|Y\u001b(B\n\u001b$B|Z\u001b(B\n\u001b$B|[\u001b(B\n\u001b$B|\\\u001b(B\n\u001b$B|]\u001b(B\n\u001b$B|^\u001b(B\n\u001b$B|_\u001b(B\n\u001b$B|`\u001b(B\n\u001b$B|a\u001b(B\n\u001b$B|b\u001b(B\n\u001b$B|c\u001b(B\n\u001b$B|d\u001b(B\n\u001b$B|e\u001b(B\n\u001b$B|f\u001b(B\n\u001b$B|g\u001b(B\n\u001b$B|h\u001b(B\n\u001b$B|i\u001b(B\n\u001b$B|j\u001b(B\n\u001b$B|k\u001b(B\n\u001b$B|l\u001b(B\n\u001b$B|m\u001b(B\n\u001b$B|n\u001b(B\n\u001b$B|o\u001b(B\n\u001b$B|p\u001b(B\n\u001b$B|q\u001b(B\n\u001b$B|r\u001b(B\n\u001b$B|s\u001b(B\n\u001b$B|t\u001b(B\n\u001b$B|u\u001b(B\n\u001b$B|v\u001b(B\n\u001b$B|w\u001b(B\n\u001b$B|x\u001b(B\n\u001b$B|y\u001b(B\n\u001b$B|z\u001b(B\n\u001b$B|{\u001b(B\n\u001b$B||\u001b(B\n\u001b$B|}\u001b(B\n\u001b$B|~\u001b(B\n\u001b$B}!\u001b(B\n\u001b$B}\"\u001b(B\n\u001b$B}#\u001b(B\n\u001b$B}$\u001b(B\n\u001b$B}%\u001b(B\n\u001b$B}&\u001b(B\n\u001b$B}'\u001b(B\n\u001b$B}(\u001b(B\n\u001b$B})\u001b(B\n\u001b$B}*\u001b(B\n\u001b$B}+\u001b(B\n\u001b$B},\u001b(B\n\u001b$B}-\u001b(B\n\u001b$B}.\u001b(B\n\u001b$B}/\u001b(B\n\u001b$B}0\u001b(B\n\u001b$B}1\u001b(B\n\u001b$B}2\u001b(B\n\u001b$B}3\u001b(B\n\u001b$B}4\u001b(B\n\u001b$B}5\u001b(B\n\u001b$B}6\u001b(B\n\u001b$B}7\u001b(B\n\u001b$B}8\u001b(B\n\u001b$B}9\u001b(B\n\u001b$B}:\u001b(B\n\u001b$B};\u001b(B\n\u001b$B}<\u001b(B\n\u001b$B}=\u001b(B\n\u001b$B}>\u001b(B\n\u001b$B}?\u001b(B\n\u001b$B}@\u001b(B\n\u001b$B}A\u001b(B\n\u001b$B}B\u001b(B\n\u001b$B}C\u001b(B\n\u001b$B}D\u001b(B\n\u001b$B}E\u001b(B\n\u001b$B}F\u001b(B\n\u001b$B}G\u001b(B\n\u001b$B}H\u001b(B\n\u001b$B}I\u001b(B\n\u001b$B}J\u001b(B\n\u001b$B}K\u001b(B\n\u001b$B}L\u001b(B\n\u001b$B}M\u001b(B\n\u001b$B}N\u001b(B\n\u001b$B}O\u001b(B\n\u001b$B}P\u001b(B\n\u001b$B}Q\u001b(B\n\u001b$B}R\u001b(B\n\u001b$B}S\u001b(B\n\u001b$B}T\u001b(B\n\u001b$B}U\u001b(B\n\u001b$B}V\u001b(B\n\u001b$B}W\u001b(B\n\u001b$B}X\u001b(B\n\u001b$B}Y\u001b(B\n\u001b$B}Z\u001b(B\n\u001b$B}[\u001b(B\n\u001b$B}\\\u001b(B\n\u001b$B}]\u001b(B\n\u001b$B}^\u001b(B\n\u001b$B}_\u001b(B\n\u001b$B}`\u001b(B\n\u001b$B}a\u001b(B\n\u001b$B}b\u001b(B\n\u001b$B}c\u001b(B\n\u001b$B}d\u001b(B\n\u001b$B}e\u001b(B\n\u001b$B}f\u001b(B\n\u001b$B}g\u001b(B\n\u001b$B}h\u001b(B\n\u001b$B}i\u001b(B\n\u001b$B}j\u001b(B\n\u001b$B}k\u001b(B\n\u001b$B}l\u001b(B\n\u001b$B}m\u001b(B\n\u001b$B}n\u001b(B\n\u001b$B}o\u001b(B\n\u001b$B}p\u001b(B\n\u001b$B}q\u001b(B\n\u001b$B}r\u001b(B\n\u001b$B}s\u001b(B\n\u001b$B}t\u001b(B\n\u001b$B}u\u001b(B\n\u001b$B}v\u001b(B\n\u001b$B}w\u001b(B\n\u001b$B}x\u001b(B\n\u001b$B}y\u001b(B\n\u001b$B}z\u001b(B\n\u001b$B}{\u001b(B\n\u001b$B}|\u001b(B\n\u001b$B}}\u001b(B\n\u001b$B}~\u001b(B\n\u001b$B~!\u001b(B\n\u001b$B~\"\u001b(B\n\u001b$B~#\u001b(B\n\u001b$B~$\u001b(B\n\u001b$B~%\u001b(B\n\u001b$B~&\u001b(B\n\u001b$B~'\u001b(B\n\u001b$B~(\u001b(B\n\u001b$B~)\u001b(B\n\u001b$B~*\u001b(B\n\u001b$B~+\u001b(B\n\u001b$B~,\u001b(B\n\u001b$B~-\u001b(B\n\u001b$B~.\u001b(B\n\u001b$B~/\u001b(B\n\u001b$B~0\u001b(B\n\u001b$B~1\u001b(B\n\u001b$B~2\u001b(B\n\u001b$B~3\u001b(B\n\u001b$B~4\u001b(B\n\u001b$B~5\u001b(B\n\u001b$B~6\u001b(B\n\u001b$B~7\u001b(B\n\u001b$B~8\u001b(B\n\u001b$B~9\u001b(B\n\u001b$B~:\u001b(B\n\u001b$B~;\u001b(B\n\u001b$B~<\u001b(B\n\u001b$B~=\u001b(B\n\u001b$B~>\u001b(B\n\u001b$B~?\u001b(B\n\u001b$B~@\u001b(B\n\u001b$B~A\u001b(B\n\u001b$B~B\u001b(B\n\u001b$B~C\u001b(B\n\u001b$B~D\u001b(B\n\u001b$B~E\u001b(B\n\u001b$B~F\u001b(B\n\u001b$B~G\u001b(B\n\u001b$B~H\u001b(B\n\u001b$B~I\u001b(B\n\u001b$B~J\u001b(B\n\u001b$B~K\u001b(B\n\u001b$B~L\u001b(B\n\u001b$B~M\u001b(B\n\u001b$B~N\u001b(B\n\u001b$B~O\u001b(B\n\u001b$B~P\u001b(B\n\u001b$B~Q\u001b(B\n\u001b$B~R\u001b(B\n\u001b$B~S\u001b(B\n\u001b$B~T\u001b(B\n\u001b$B~U\u001b(B\n\u001b$B~V\u001b(B\n\u001b$B~W\u001b(B\n\u001b$B~X\u001b(B\n\u001b$B~Y\u001b(B\n\u001b$B~Z\u001b(B\n\u001b$B~[\u001b(B\n\u001b$B~\\\u001b(B\n\u001b$B~]\u001b(B\n\u001b$B~^\u001b(B\n\u001b$B~_\u001b(B\n\u001b$B~`\u001b(B\n\u001b$B~a\u001b(B\n\u001b$B~b\u001b(B\n\u001b$B~c\u001b(B\n\u001b$B~d\u001b(B\n\u001b$B~e\u001b(B\n\u001b$B~f\u001b(B\n\u001b$B~g\u001b(B\n\u001b$B~h\u001b(B\n\u001b$B~i\u001b(B\n\u001b$B~j\u001b(B\n\u001b$B~k\u001b(B\n\u001b$B~l\u001b(B\n\u001b$B~m\u001b(B\n\u001b$B~n\u001b(B\n\u001b$B~o\u001b(B\n\u001b$B~p\u001b(B\n\u001b$B~q\u001b(B\n\u001b$B~r\u001b(B\n\u001b$B~s\u001b(B\n\u001b$B~t\u001b(B\n\u001b$B~u\u001b(B\n\u001b$B~v\u001b(B\n\u001b$B~w\u001b(B\n\u001b$B~x\u001b(B\n\u001b$B~y\u001b(B\n\u001b$B~z\u001b(B\n\u001b$B~{\u001b(B\n\u001b$B~|\u001b(B\n\u001b$B~}\u001b(B\n\u001b$B~~\u001b(B\n"
  },
  {
    "path": "helix-view/tests/encoding/iso_2022_jp_in_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n　\n、\n。\n，\n．\n・\n：\n；\n？\n！\n゛\n゜\n´\n｀\n¨\n＾\n￣\n＿\nヽ\nヾ\nゝ\nゞ\n〃\n仝\n々\n〆\n〇\nー\n―\n‐\n／\n＼\n～\n∥\n｜\n…\n‥\n‘\n’\n“\n”\n（\n）\n〔\n〕\n［\n］\n｛\n｝\n〈\n〉\n《\n》\n「\n」\n『\n』\n【\n】\n＋\n－\n±\n×\n÷\n＝\n≠\n＜\n＞\n≦\n≧\n∞\n∴\n♂\n♀\n°\n′\n″\n℃\n￥\n＄\n￠\n￡\n％\n＃\n＆\n＊\n＠\n§\n☆\n★\n○\n●\n◎\n◇\n◆\n□\n■\n△\n▲\n▽\n▼\n※\n〒\n→\n←\n↑\n↓\n〓\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n∈\n∋\n⊆\n⊇\n⊂\n⊃\n∪\n∩\n�\n�\n�\n�\n�\n�\n�\n�\n∧\n∨\n￢\n⇒\n⇔\n∀\n∃\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n∠\n⊥\n⌒\n∂\n∇\n≡\n≒\n≪\n≫\n√\n∽\n∝\n∵\n∫\n∬\n�\n�\n�\n�\n�\n�\n�\nÅ\n‰\n♯\n♭\n♪\n†\n‡\n¶\n�\n�\n�\n�\n◯\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\n�\n�\n�\n�\n�\n�\n�\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\n�\n�\n�\n�\n�\n�\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\n�\n�\n�\n�\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\n�\n�\n�\n�\n�\n�\n�\n�\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\n�\n�\n�\n�\n�\n�\n�\n�\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n─\n│\n┌\n┐\n┘\n└\n├\n┬\n┤\n┴\n┼\n━\n┃\n┏\n┓\n┛\n┗\n┣\n┳\n┫\n┻\n╋\n┠\n┯\n┨\n┷\n┿\n┝\n┰\n┥\n┸\n╂\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n⑪\n⑫\n⑬\n⑭\n⑮\n⑯\n⑰\n⑱\n⑲\n⑳\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n�\n㍉\n㌔\n㌢\n㍍\n㌘\n㌧\n㌃\n㌶\n㍑\n㍗\n㌍\n㌦\n㌣\n㌫\n㍊\n㌻\n㎜\n㎝\n㎞\n㎎\n㎏\n㏄\n㎡\n�\n�\n�\n�\n�\n�\n�\n�\n㍻\n〝\n〟\n№\n㏍\n℡\n㊤\n㊥\n㊦\n㊧\n㊨\n㈱\n㈲\n㈹\n㍾\n㍽\n㍼\n≒\n≡\n∫\n∮\n∑\n√\n⊥\n∠\n∟\n⊿\n∵\n∩\n∪\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n亜\n唖\n娃\n阿\n哀\n愛\n挨\n姶\n逢\n葵\n茜\n穐\n悪\n握\n渥\n旭\n葦\n芦\n鯵\n梓\n圧\n斡\n扱\n宛\n姐\n虻\n飴\n絢\n綾\n鮎\n或\n粟\n袷\n安\n庵\n按\n暗\n案\n闇\n鞍\n杏\n以\n伊\n位\n依\n偉\n囲\n夷\n委\n威\n尉\n惟\n意\n慰\n易\n椅\n為\n畏\n異\n移\n維\n緯\n胃\n萎\n衣\n謂\n違\n遺\n医\n井\n亥\n域\n育\n郁\n磯\n一\n壱\n溢\n逸\n稲\n茨\n芋\n鰯\n允\n印\n咽\n員\n因\n姻\n引\n飲\n淫\n胤\n蔭\n院\n陰\n隠\n韻\n吋\n右\n宇\n烏\n羽\n迂\n雨\n卯\n鵜\n窺\n丑\n碓\n臼\n渦\n嘘\n唄\n欝\n蔚\n鰻\n姥\n厩\n浦\n瓜\n閏\n噂\n云\n運\n雲\n荏\n餌\n叡\n営\n嬰\n影\n映\n曳\n栄\n永\n泳\n洩\n瑛\n盈\n穎\n頴\n英\n衛\n詠\n鋭\n液\n疫\n益\n駅\n悦\n謁\n越\n閲\n榎\n厭\n円\n園\n堰\n奄\n宴\n延\n怨\n掩\n援\n沿\n演\n炎\n焔\n煙\n燕\n猿\n縁\n艶\n苑\n薗\n遠\n鉛\n鴛\n塩\n於\n汚\n甥\n凹\n央\n奥\n往\n応\n押\n旺\n横\n欧\n殴\n王\n翁\n襖\n鴬\n鴎\n黄\n岡\n沖\n荻\n億\n屋\n憶\n臆\n桶\n牡\n乙\n俺\n卸\n恩\n温\n穏\n音\n下\n化\n仮\n何\n伽\n価\n佳\n加\n可\n嘉\n夏\n嫁\n家\n寡\n科\n暇\n果\n架\n歌\n河\n火\n珂\n禍\n禾\n稼\n箇\n花\n苛\n茄\n荷\n華\n菓\n蝦\n課\n嘩\n貨\n迦\n過\n霞\n蚊\n俄\n峨\n我\n牙\n画\n臥\n芽\n蛾\n賀\n雅\n餓\n駕\n介\n会\n解\n回\n塊\n壊\n廻\n快\n怪\n悔\n恢\n懐\n戒\n拐\n改\n魁\n晦\n械\n海\n灰\n界\n皆\n絵\n芥\n蟹\n開\n階\n貝\n凱\n劾\n外\n咳\n害\n崖\n慨\n概\n涯\n碍\n蓋\n街\n該\n鎧\n骸\n浬\n馨\n蛙\n垣\n柿\n蛎\n鈎\n劃\n嚇\n各\n廓\n拡\n撹\n格\n核\n殻\n獲\n確\n穫\n覚\n角\n赫\n較\n郭\n閣\n隔\n革\n学\n岳\n楽\n額\n顎\n掛\n笠\n樫\n橿\n梶\n鰍\n潟\n割\n喝\n恰\n括\n活\n渇\n滑\n葛\n褐\n轄\n且\n鰹\n叶\n椛\n樺\n鞄\n株\n兜\n竃\n蒲\n釜\n鎌\n噛\n鴨\n栢\n茅\n萱\n粥\n刈\n苅\n瓦\n乾\n侃\n冠\n寒\n刊\n勘\n勧\n巻\n喚\n堪\n姦\n完\n官\n寛\n干\n幹\n患\n感\n慣\n憾\n換\n敢\n柑\n桓\n棺\n款\n歓\n汗\n漢\n澗\n潅\n環\n甘\n監\n看\n竿\n管\n簡\n緩\n缶\n翰\n肝\n艦\n莞\n観\n諌\n貫\n還\n鑑\n間\n閑\n関\n陥\n韓\n館\n舘\n丸\n含\n岸\n巌\n玩\n癌\n眼\n岩\n翫\n贋\n雁\n頑\n顔\n願\n企\n伎\n危\n喜\n器\n基\n奇\n嬉\n寄\n岐\n希\n幾\n忌\n揮\n机\n旗\n既\n期\n棋\n棄\n機\n帰\n毅\n気\n汽\n畿\n祈\n季\n稀\n紀\n徽\n規\n記\n貴\n起\n軌\n輝\n飢\n騎\n鬼\n亀\n偽\n儀\n妓\n宜\n戯\n技\n擬\n欺\n犠\n疑\n祇\n義\n蟻\n誼\n議\n掬\n菊\n鞠\n吉\n吃\n喫\n桔\n橘\n詰\n砧\n杵\n黍\n却\n客\n脚\n虐\n逆\n丘\n久\n仇\n休\n及\n吸\n宮\n弓\n急\n救\n朽\n求\n汲\n泣\n灸\n球\n究\n窮\n笈\n級\n糾\n給\n旧\n牛\n去\n居\n巨\n拒\n拠\n挙\n渠\n虚\n許\n距\n鋸\n漁\n禦\n魚\n亨\n享\n京\n供\n侠\n僑\n兇\n競\n共\n凶\n協\n匡\n卿\n叫\n喬\n境\n峡\n強\n彊\n怯\n恐\n恭\n挟\n教\n橋\n況\n狂\n狭\n矯\n胸\n脅\n興\n蕎\n郷\n鏡\n響\n饗\n驚\n仰\n凝\n尭\n暁\n業\n局\n曲\n極\n玉\n桐\n粁\n僅\n勤\n均\n巾\n錦\n斤\n欣\n欽\n琴\n禁\n禽\n筋\n緊\n芹\n菌\n衿\n襟\n謹\n近\n金\n吟\n銀\n九\n倶\n句\n区\n狗\n玖\n矩\n苦\n躯\n駆\n駈\n駒\n具\n愚\n虞\n喰\n空\n偶\n寓\n遇\n隅\n串\n櫛\n釧\n屑\n屈\n掘\n窟\n沓\n靴\n轡\n窪\n熊\n隈\n粂\n栗\n繰\n桑\n鍬\n勲\n君\n薫\n訓\n群\n軍\n郡\n卦\n袈\n祁\n係\n傾\n刑\n兄\n啓\n圭\n珪\n型\n契\n形\n径\n恵\n慶\n慧\n憩\n掲\n携\n敬\n景\n桂\n渓\n畦\n稽\n系\n経\n継\n繋\n罫\n茎\n荊\n蛍\n計\n詣\n警\n軽\n頚\n鶏\n芸\n迎\n鯨\n劇\n戟\n撃\n激\n隙\n桁\n傑\n欠\n決\n潔\n穴\n結\n血\n訣\n月\n件\n倹\n倦\n健\n兼\n券\n剣\n喧\n圏\n堅\n嫌\n建\n憲\n懸\n拳\n捲\n検\n権\n牽\n犬\n献\n研\n硯\n絹\n県\n肩\n見\n謙\n賢\n軒\n遣\n鍵\n険\n顕\n験\n鹸\n元\n原\n厳\n幻\n弦\n減\n源\n玄\n現\n絃\n舷\n言\n諺\n限\n乎\n個\n古\n呼\n固\n姑\n孤\n己\n庫\n弧\n戸\n故\n枯\n湖\n狐\n糊\n袴\n股\n胡\n菰\n虎\n誇\n跨\n鈷\n雇\n顧\n鼓\n五\n互\n伍\n午\n呉\n吾\n娯\n後\n御\n悟\n梧\n檎\n瑚\n碁\n語\n誤\n護\n醐\n乞\n鯉\n交\n佼\n侯\n候\n倖\n光\n公\n功\n効\n勾\n厚\n口\n向\n后\n喉\n坑\n垢\n好\n孔\n孝\n宏\n工\n巧\n巷\n幸\n広\n庚\n康\n弘\n恒\n慌\n抗\n拘\n控\n攻\n昂\n晃\n更\n杭\n校\n梗\n構\n江\n洪\n浩\n港\n溝\n甲\n皇\n硬\n稿\n糠\n紅\n紘\n絞\n綱\n耕\n考\n肯\n肱\n腔\n膏\n航\n荒\n行\n衡\n講\n貢\n購\n郊\n酵\n鉱\n砿\n鋼\n閤\n降\n項\n香\n高\n鴻\n剛\n劫\n号\n合\n壕\n拷\n濠\n豪\n轟\n麹\n克\n刻\n告\n国\n穀\n酷\n鵠\n黒\n獄\n漉\n腰\n甑\n忽\n惚\n骨\n狛\n込\n此\n頃\n今\n困\n坤\n墾\n婚\n恨\n懇\n昏\n昆\n根\n梱\n混\n痕\n紺\n艮\n魂\n些\n佐\n叉\n唆\n嵯\n左\n差\n査\n沙\n瑳\n砂\n詐\n鎖\n裟\n坐\n座\n挫\n債\n催\n再\n最\n哉\n塞\n妻\n宰\n彩\n才\n採\n栽\n歳\n済\n災\n采\n犀\n砕\n砦\n祭\n斎\n細\n菜\n裁\n載\n際\n剤\n在\n材\n罪\n財\n冴\n坂\n阪\n堺\n榊\n肴\n咲\n崎\n埼\n碕\n鷺\n作\n削\n咋\n搾\n昨\n朔\n柵\n窄\n策\n索\n錯\n桜\n鮭\n笹\n匙\n冊\n刷\n察\n拶\n撮\n擦\n札\n殺\n薩\n雑\n皐\n鯖\n捌\n錆\n鮫\n皿\n晒\n三\n傘\n参\n山\n惨\n撒\n散\n桟\n燦\n珊\n産\n算\n纂\n蚕\n讃\n賛\n酸\n餐\n斬\n暫\n残\n仕\n仔\n伺\n使\n刺\n司\n史\n嗣\n四\n士\n始\n姉\n姿\n子\n屍\n市\n師\n志\n思\n指\n支\n孜\n斯\n施\n旨\n枝\n止\n死\n氏\n獅\n祉\n私\n糸\n紙\n紫\n肢\n脂\n至\n視\n詞\n詩\n試\n誌\n諮\n資\n賜\n雌\n飼\n歯\n事\n似\n侍\n児\n字\n寺\n慈\n持\n時\n次\n滋\n治\n爾\n璽\n痔\n磁\n示\n而\n耳\n自\n蒔\n辞\n汐\n鹿\n式\n識\n鴫\n竺\n軸\n宍\n雫\n七\n叱\n執\n失\n嫉\n室\n悉\n湿\n漆\n疾\n質\n実\n蔀\n篠\n偲\n柴\n芝\n屡\n蕊\n縞\n舎\n写\n射\n捨\n赦\n斜\n煮\n社\n紗\n者\n謝\n車\n遮\n蛇\n邪\n借\n勺\n尺\n杓\n灼\n爵\n酌\n釈\n錫\n若\n寂\n弱\n惹\n主\n取\n守\n手\n朱\n殊\n狩\n珠\n種\n腫\n趣\n酒\n首\n儒\n受\n呪\n寿\n授\n樹\n綬\n需\n囚\n収\n周\n宗\n就\n州\n修\n愁\n拾\n洲\n秀\n秋\n終\n繍\n習\n臭\n舟\n蒐\n衆\n襲\n讐\n蹴\n輯\n週\n酋\n酬\n集\n醜\n什\n住\n充\n十\n従\n戎\n柔\n汁\n渋\n獣\n縦\n重\n銃\n叔\n夙\n宿\n淑\n祝\n縮\n粛\n塾\n熟\n出\n術\n述\n俊\n峻\n春\n瞬\n竣\n舜\n駿\n准\n循\n旬\n楯\n殉\n淳\n準\n潤\n盾\n純\n巡\n遵\n醇\n順\n処\n初\n所\n暑\n曙\n渚\n庶\n緒\n署\n書\n薯\n藷\n諸\n助\n叙\n女\n序\n徐\n恕\n鋤\n除\n傷\n償\n勝\n匠\n升\n召\n哨\n商\n唱\n嘗\n奨\n妾\n娼\n宵\n将\n小\n少\n尚\n庄\n床\n廠\n彰\n承\n抄\n招\n掌\n捷\n昇\n昌\n昭\n晶\n松\n梢\n樟\n樵\n沼\n消\n渉\n湘\n焼\n焦\n照\n症\n省\n硝\n礁\n祥\n称\n章\n笑\n粧\n紹\n肖\n菖\n蒋\n蕉\n衝\n裳\n訟\n証\n詔\n詳\n象\n賞\n醤\n鉦\n鍾\n鐘\n障\n鞘\n上\n丈\n丞\n乗\n冗\n剰\n城\n場\n壌\n嬢\n常\n情\n擾\n条\n杖\n浄\n状\n畳\n穣\n蒸\n譲\n醸\n錠\n嘱\n埴\n飾\n拭\n植\n殖\n燭\n織\n職\n色\n触\n食\n蝕\n辱\n尻\n伸\n信\n侵\n唇\n娠\n寝\n審\n心\n慎\n振\n新\n晋\n森\n榛\n浸\n深\n申\n疹\n真\n神\n秦\n紳\n臣\n芯\n薪\n親\n診\n身\n辛\n進\n針\n震\n人\n仁\n刃\n塵\n壬\n尋\n甚\n尽\n腎\n訊\n迅\n陣\n靭\n笥\n諏\n須\n酢\n図\n厨\n逗\n吹\n垂\n帥\n推\n水\n炊\n睡\n粋\n翠\n衰\n遂\n酔\n錐\n錘\n随\n瑞\n髄\n崇\n嵩\n数\n枢\n趨\n雛\n据\n杉\n椙\n菅\n頗\n雀\n裾\n澄\n摺\n寸\n世\n瀬\n畝\n是\n凄\n制\n勢\n姓\n征\n性\n成\n政\n整\n星\n晴\n棲\n栖\n正\n清\n牲\n生\n盛\n精\n聖\n声\n製\n西\n誠\n誓\n請\n逝\n醒\n青\n静\n斉\n税\n脆\n隻\n席\n惜\n戚\n斥\n昔\n析\n石\n積\n籍\n績\n脊\n責\n赤\n跡\n蹟\n碩\n切\n拙\n接\n摂\n折\n設\n窃\n節\n説\n雪\n絶\n舌\n蝉\n仙\n先\n千\n占\n宣\n専\n尖\n川\n戦\n扇\n撰\n栓\n栴\n泉\n浅\n洗\n染\n潜\n煎\n煽\n旋\n穿\n箭\n線\n繊\n羨\n腺\n舛\n船\n薦\n詮\n賎\n践\n選\n遷\n銭\n銑\n閃\n鮮\n前\n善\n漸\n然\n全\n禅\n繕\n膳\n糎\n噌\n塑\n岨\n措\n曾\n曽\n楚\n狙\n疏\n疎\n礎\n祖\n租\n粗\n素\n組\n蘇\n訴\n阻\n遡\n鼠\n僧\n創\n双\n叢\n倉\n喪\n壮\n奏\n爽\n宋\n層\n匝\n惣\n想\n捜\n掃\n挿\n掻\n操\n早\n曹\n巣\n槍\n槽\n漕\n燥\n争\n痩\n相\n窓\n糟\n総\n綜\n聡\n草\n荘\n葬\n蒼\n藻\n装\n走\n送\n遭\n鎗\n霜\n騒\n像\n増\n憎\n臓\n蔵\n贈\n造\n促\n側\n則\n即\n息\n捉\n束\n測\n足\n速\n俗\n属\n賊\n族\n続\n卒\n袖\n其\n揃\n存\n孫\n尊\n損\n村\n遜\n他\n多\n太\n汰\n詑\n唾\n堕\n妥\n惰\n打\n柁\n舵\n楕\n陀\n駄\n騨\n体\n堆\n対\n耐\n岱\n帯\n待\n怠\n態\n戴\n替\n泰\n滞\n胎\n腿\n苔\n袋\n貸\n退\n逮\n隊\n黛\n鯛\n代\n台\n大\n第\n醍\n題\n鷹\n滝\n瀧\n卓\n啄\n宅\n托\n択\n拓\n沢\n濯\n琢\n託\n鐸\n濁\n諾\n茸\n凧\n蛸\n只\n叩\n但\n達\n辰\n奪\n脱\n巽\n竪\n辿\n棚\n谷\n狸\n鱈\n樽\n誰\n丹\n単\n嘆\n坦\n担\n探\n旦\n歎\n淡\n湛\n炭\n短\n端\n箪\n綻\n耽\n胆\n蛋\n誕\n鍛\n団\n壇\n弾\n断\n暖\n檀\n段\n男\n談\n値\n知\n地\n弛\n恥\n智\n池\n痴\n稚\n置\n致\n蜘\n遅\n馳\n築\n畜\n竹\n筑\n蓄\n逐\n秩\n窒\n茶\n嫡\n着\n中\n仲\n宙\n忠\n抽\n昼\n柱\n注\n虫\n衷\n註\n酎\n鋳\n駐\n樗\n瀦\n猪\n苧\n著\n貯\n丁\n兆\n凋\n喋\n寵\n帖\n帳\n庁\n弔\n張\n彫\n徴\n懲\n挑\n暢\n朝\n潮\n牒\n町\n眺\n聴\n脹\n腸\n蝶\n調\n諜\n超\n跳\n銚\n長\n頂\n鳥\n勅\n捗\n直\n朕\n沈\n珍\n賃\n鎮\n陳\n津\n墜\n椎\n槌\n追\n鎚\n痛\n通\n塚\n栂\n掴\n槻\n佃\n漬\n柘\n辻\n蔦\n綴\n鍔\n椿\n潰\n坪\n壷\n嬬\n紬\n爪\n吊\n釣\n鶴\n亭\n低\n停\n偵\n剃\n貞\n呈\n堤\n定\n帝\n底\n庭\n廷\n弟\n悌\n抵\n挺\n提\n梯\n汀\n碇\n禎\n程\n締\n艇\n訂\n諦\n蹄\n逓\n邸\n鄭\n釘\n鼎\n泥\n摘\n擢\n敵\n滴\n的\n笛\n適\n鏑\n溺\n哲\n徹\n撤\n轍\n迭\n鉄\n典\n填\n天\n展\n店\n添\n纏\n甜\n貼\n転\n顛\n点\n伝\n殿\n澱\n田\n電\n兎\n吐\n堵\n塗\n妬\n屠\n徒\n斗\n杜\n渡\n登\n菟\n賭\n途\n都\n鍍\n砥\n砺\n努\n度\n土\n奴\n怒\n倒\n党\n冬\n凍\n刀\n唐\n塔\n塘\n套\n宕\n島\n嶋\n悼\n投\n搭\n東\n桃\n梼\n棟\n盗\n淘\n湯\n涛\n灯\n燈\n当\n痘\n祷\n等\n答\n筒\n糖\n統\n到\n董\n蕩\n藤\n討\n謄\n豆\n踏\n逃\n透\n鐙\n陶\n頭\n騰\n闘\n働\n動\n同\n堂\n導\n憧\n撞\n洞\n瞳\n童\n胴\n萄\n道\n銅\n峠\n鴇\n匿\n得\n徳\n涜\n特\n督\n禿\n篤\n毒\n独\n読\n栃\n橡\n凸\n突\n椴\n届\n鳶\n苫\n寅\n酉\n瀞\n噸\n屯\n惇\n敦\n沌\n豚\n遁\n頓\n呑\n曇\n鈍\n奈\n那\n内\n乍\n凪\n薙\n謎\n灘\n捺\n鍋\n楢\n馴\n縄\n畷\n南\n楠\n軟\n難\n汝\n二\n尼\n弐\n迩\n匂\n賑\n肉\n虹\n廿\n日\n乳\n入\n如\n尿\n韮\n任\n妊\n忍\n認\n濡\n禰\n祢\n寧\n葱\n猫\n熱\n年\n念\n捻\n撚\n燃\n粘\n乃\n廼\n之\n埜\n嚢\n悩\n濃\n納\n能\n脳\n膿\n農\n覗\n蚤\n巴\n把\n播\n覇\n杷\n波\n派\n琶\n破\n婆\n罵\n芭\n馬\n俳\n廃\n拝\n排\n敗\n杯\n盃\n牌\n背\n肺\n輩\n配\n倍\n培\n媒\n梅\n楳\n煤\n狽\n買\n売\n賠\n陪\n這\n蝿\n秤\n矧\n萩\n伯\n剥\n博\n拍\n柏\n泊\n白\n箔\n粕\n舶\n薄\n迫\n曝\n漠\n爆\n縛\n莫\n駁\n麦\n函\n箱\n硲\n箸\n肇\n筈\n櫨\n幡\n肌\n畑\n畠\n八\n鉢\n溌\n発\n醗\n髪\n伐\n罰\n抜\n筏\n閥\n鳩\n噺\n塙\n蛤\n隼\n伴\n判\n半\n反\n叛\n帆\n搬\n斑\n板\n氾\n汎\n版\n犯\n班\n畔\n繁\n般\n藩\n販\n範\n釆\n煩\n頒\n飯\n挽\n晩\n番\n盤\n磐\n蕃\n蛮\n匪\n卑\n否\n妃\n庇\n彼\n悲\n扉\n批\n披\n斐\n比\n泌\n疲\n皮\n碑\n秘\n緋\n罷\n肥\n被\n誹\n費\n避\n非\n飛\n樋\n簸\n備\n尾\n微\n枇\n毘\n琵\n眉\n美\n鼻\n柊\n稗\n匹\n疋\n髭\n彦\n膝\n菱\n肘\n弼\n必\n畢\n筆\n逼\n桧\n姫\n媛\n紐\n百\n謬\n俵\n彪\n標\n氷\n漂\n瓢\n票\n表\n評\n豹\n廟\n描\n病\n秒\n苗\n錨\n鋲\n蒜\n蛭\n鰭\n品\n彬\n斌\n浜\n瀕\n貧\n賓\n頻\n敏\n瓶\n不\n付\n埠\n夫\n婦\n富\n冨\n布\n府\n怖\n扶\n敷\n斧\n普\n浮\n父\n符\n腐\n膚\n芙\n譜\n負\n賦\n赴\n阜\n附\n侮\n撫\n武\n舞\n葡\n蕪\n部\n封\n楓\n風\n葺\n蕗\n伏\n副\n復\n幅\n服\n福\n腹\n複\n覆\n淵\n弗\n払\n沸\n仏\n物\n鮒\n分\n吻\n噴\n墳\n憤\n扮\n焚\n奮\n粉\n糞\n紛\n雰\n文\n聞\n丙\n併\n兵\n塀\n幣\n平\n弊\n柄\n並\n蔽\n閉\n陛\n米\n頁\n僻\n壁\n癖\n碧\n別\n瞥\n蔑\n箆\n偏\n変\n片\n篇\n編\n辺\n返\n遍\n便\n勉\n娩\n弁\n鞭\n保\n舗\n鋪\n圃\n捕\n歩\n甫\n補\n輔\n穂\n募\n墓\n慕\n戊\n暮\n母\n簿\n菩\n倣\n俸\n包\n呆\n報\n奉\n宝\n峰\n峯\n崩\n庖\n抱\n捧\n放\n方\n朋\n法\n泡\n烹\n砲\n縫\n胞\n芳\n萌\n蓬\n蜂\n褒\n訪\n豊\n邦\n鋒\n飽\n鳳\n鵬\n乏\n亡\n傍\n剖\n坊\n妨\n帽\n忘\n忙\n房\n暴\n望\n某\n棒\n冒\n紡\n肪\n膨\n謀\n貌\n貿\n鉾\n防\n吠\n頬\n北\n僕\n卜\n墨\n撲\n朴\n牧\n睦\n穆\n釦\n勃\n没\n殆\n堀\n幌\n奔\n本\n翻\n凡\n盆\n摩\n磨\n魔\n麻\n埋\n妹\n昧\n枚\n毎\n哩\n槙\n幕\n膜\n枕\n鮪\n柾\n鱒\n桝\n亦\n俣\n又\n抹\n末\n沫\n迄\n侭\n繭\n麿\n万\n慢\n満\n漫\n蔓\n味\n未\n魅\n巳\n箕\n岬\n密\n蜜\n湊\n蓑\n稔\n脈\n妙\n粍\n民\n眠\n務\n夢\n無\n牟\n矛\n霧\n鵡\n椋\n婿\n娘\n冥\n名\n命\n明\n盟\n迷\n銘\n鳴\n姪\n牝\n滅\n免\n棉\n綿\n緬\n面\n麺\n摸\n模\n茂\n妄\n孟\n毛\n猛\n盲\n網\n耗\n蒙\n儲\n木\n黙\n目\n杢\n勿\n餅\n尤\n戻\n籾\n貰\n問\n悶\n紋\n門\n匁\n也\n冶\n夜\n爺\n耶\n野\n弥\n矢\n厄\n役\n約\n薬\n訳\n躍\n靖\n柳\n薮\n鑓\n愉\n愈\n油\n癒\n諭\n輸\n唯\n佑\n優\n勇\n友\n宥\n幽\n悠\n憂\n揖\n有\n柚\n湧\n涌\n猶\n猷\n由\n祐\n裕\n誘\n遊\n邑\n郵\n雄\n融\n夕\n予\n余\n与\n誉\n輿\n預\n傭\n幼\n妖\n容\n庸\n揚\n揺\n擁\n曜\n楊\n様\n洋\n溶\n熔\n用\n窯\n羊\n耀\n葉\n蓉\n要\n謡\n踊\n遥\n陽\n養\n慾\n抑\n欲\n沃\n浴\n翌\n翼\n淀\n羅\n螺\n裸\n来\n莱\n頼\n雷\n洛\n絡\n落\n酪\n乱\n卵\n嵐\n欄\n濫\n藍\n蘭\n覧\n利\n吏\n履\n李\n梨\n理\n璃\n痢\n裏\n裡\n里\n離\n陸\n律\n率\n立\n葎\n掠\n略\n劉\n流\n溜\n琉\n留\n硫\n粒\n隆\n竜\n龍\n侶\n慮\n旅\n虜\n了\n亮\n僚\n両\n凌\n寮\n料\n梁\n涼\n猟\n療\n瞭\n稜\n糧\n良\n諒\n遼\n量\n陵\n領\n力\n緑\n倫\n厘\n林\n淋\n燐\n琳\n臨\n輪\n隣\n鱗\n麟\n瑠\n塁\n涙\n累\n類\n令\n伶\n例\n冷\n励\n嶺\n怜\n玲\n礼\n苓\n鈴\n隷\n零\n霊\n麗\n齢\n暦\n歴\n列\n劣\n烈\n裂\n廉\n恋\n憐\n漣\n煉\n簾\n練\n聯\n蓮\n連\n錬\n呂\n魯\n櫓\n炉\n賂\n路\n露\n労\n婁\n廊\n弄\n朗\n楼\n榔\n浪\n漏\n牢\n狼\n篭\n老\n聾\n蝋\n郎\n六\n麓\n禄\n肋\n録\n論\n倭\n和\n話\n歪\n賄\n脇\n惑\n枠\n鷲\n亙\n亘\n鰐\n詫\n藁\n蕨\n椀\n湾\n碗\n腕\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n弌\n丐\n丕\n个\n丱\n丶\n丼\n丿\n乂\n乖\n乘\n亂\n亅\n豫\n亊\n舒\n弍\n于\n亞\n亟\n亠\n亢\n亰\n亳\n亶\n从\n仍\n仄\n仆\n仂\n仗\n仞\n仭\n仟\n价\n伉\n佚\n估\n佛\n佝\n佗\n佇\n佶\n侈\n侏\n侘\n佻\n佩\n佰\n侑\n佯\n來\n侖\n儘\n俔\n俟\n俎\n俘\n俛\n俑\n俚\n俐\n俤\n俥\n倚\n倨\n倔\n倪\n倥\n倅\n伜\n俶\n倡\n倩\n倬\n俾\n俯\n們\n倆\n偃\n假\n會\n偕\n偐\n偈\n做\n偖\n偬\n偸\n傀\n傚\n傅\n傴\n傲\n僉\n僊\n傳\n僂\n僖\n僞\n僥\n僭\n僣\n僮\n價\n僵\n儉\n儁\n儂\n儖\n儕\n儔\n儚\n儡\n儺\n儷\n儼\n儻\n儿\n兀\n兒\n兌\n兔\n兢\n竸\n兩\n兪\n兮\n冀\n冂\n囘\n册\n冉\n冏\n冑\n冓\n冕\n冖\n冤\n冦\n冢\n冩\n冪\n冫\n决\n冱\n冲\n冰\n况\n冽\n凅\n凉\n凛\n几\n處\n凩\n凭\n凰\n凵\n凾\n刄\n刋\n刔\n刎\n刧\n刪\n刮\n刳\n刹\n剏\n剄\n剋\n剌\n剞\n剔\n剪\n剴\n剩\n剳\n剿\n剽\n劍\n劔\n劒\n剱\n劈\n劑\n辨\n辧\n劬\n劭\n劼\n劵\n勁\n勍\n勗\n勞\n勣\n勦\n飭\n勠\n勳\n勵\n勸\n勹\n匆\n匈\n甸\n匍\n匐\n匏\n匕\n匚\n匣\n匯\n匱\n匳\n匸\n區\n卆\n卅\n丗\n卉\n卍\n凖\n卞\n卩\n卮\n夘\n卻\n卷\n厂\n厖\n厠\n厦\n厥\n厮\n厰\n厶\n參\n簒\n雙\n叟\n曼\n燮\n叮\n叨\n叭\n叺\n吁\n吽\n呀\n听\n吭\n吼\n吮\n吶\n吩\n吝\n呎\n咏\n呵\n咎\n呟\n呱\n呷\n呰\n咒\n呻\n咀\n呶\n咄\n咐\n咆\n哇\n咢\n咸\n咥\n咬\n哄\n哈\n咨\n咫\n哂\n咤\n咾\n咼\n哘\n哥\n哦\n唏\n唔\n哽\n哮\n哭\n哺\n哢\n唹\n啀\n啣\n啌\n售\n啜\n啅\n啖\n啗\n唸\n唳\n啝\n喙\n喀\n咯\n喊\n喟\n啻\n啾\n喘\n喞\n單\n啼\n喃\n喩\n喇\n喨\n嗚\n嗅\n嗟\n嗄\n嗜\n嗤\n嗔\n嘔\n嗷\n嘖\n嗾\n嗽\n嘛\n嗹\n噎\n噐\n營\n嘴\n嘶\n嘲\n嘸\n噫\n噤\n嘯\n噬\n噪\n嚆\n嚀\n嚊\n嚠\n嚔\n嚏\n嚥\n嚮\n嚶\n嚴\n囂\n嚼\n囁\n囃\n囀\n囈\n囎\n囑\n囓\n囗\n囮\n囹\n圀\n囿\n圄\n圉\n圈\n國\n圍\n圓\n團\n圖\n嗇\n圜\n圦\n圷\n圸\n坎\n圻\n址\n坏\n坩\n埀\n垈\n坡\n坿\n垉\n垓\n垠\n垳\n垤\n垪\n垰\n埃\n埆\n埔\n埒\n埓\n堊\n埖\n埣\n堋\n堙\n堝\n塲\n堡\n塢\n塋\n塰\n毀\n塒\n堽\n塹\n墅\n墹\n墟\n墫\n墺\n壞\n墻\n墸\n墮\n壅\n壓\n壑\n壗\n壙\n壘\n壥\n壜\n壤\n壟\n壯\n壺\n壹\n壻\n壼\n壽\n夂\n夊\n夐\n夛\n梦\n夥\n夬\n夭\n夲\n夸\n夾\n竒\n奕\n奐\n奎\n奚\n奘\n奢\n奠\n奧\n奬\n奩\n奸\n妁\n妝\n佞\n侫\n妣\n妲\n姆\n姨\n姜\n妍\n姙\n姚\n娥\n娟\n娑\n娜\n娉\n娚\n婀\n婬\n婉\n娵\n娶\n婢\n婪\n媚\n媼\n媾\n嫋\n嫂\n媽\n嫣\n嫗\n嫦\n嫩\n嫖\n嫺\n嫻\n嬌\n嬋\n嬖\n嬲\n嫐\n嬪\n嬶\n嬾\n孃\n孅\n孀\n孑\n孕\n孚\n孛\n孥\n孩\n孰\n孳\n孵\n學\n斈\n孺\n宀\n它\n宦\n宸\n寃\n寇\n寉\n寔\n寐\n寤\n實\n寢\n寞\n寥\n寫\n寰\n寶\n寳\n尅\n將\n專\n對\n尓\n尠\n尢\n尨\n尸\n尹\n屁\n屆\n屎\n屓\n屐\n屏\n孱\n屬\n屮\n乢\n屶\n屹\n岌\n岑\n岔\n妛\n岫\n岻\n岶\n岼\n岷\n峅\n岾\n峇\n峙\n峩\n峽\n峺\n峭\n嶌\n峪\n崋\n崕\n崗\n嵜\n崟\n崛\n崑\n崔\n崢\n崚\n崙\n崘\n嵌\n嵒\n嵎\n嵋\n嵬\n嵳\n嵶\n嶇\n嶄\n嶂\n嶢\n嶝\n嶬\n嶮\n嶽\n嶐\n嶷\n嶼\n巉\n巍\n巓\n巒\n巖\n巛\n巫\n已\n巵\n帋\n帚\n帙\n帑\n帛\n帶\n帷\n幄\n幃\n幀\n幎\n幗\n幔\n幟\n幢\n幤\n幇\n幵\n并\n幺\n麼\n广\n庠\n廁\n廂\n廈\n廐\n廏\n廖\n廣\n廝\n廚\n廛\n廢\n廡\n廨\n廩\n廬\n廱\n廳\n廰\n廴\n廸\n廾\n弃\n弉\n彝\n彜\n弋\n弑\n弖\n弩\n弭\n弸\n彁\n彈\n彌\n彎\n弯\n彑\n彖\n彗\n彙\n彡\n彭\n彳\n彷\n徃\n徂\n彿\n徊\n很\n徑\n徇\n從\n徙\n徘\n徠\n徨\n徭\n徼\n忖\n忻\n忤\n忸\n忱\n忝\n悳\n忿\n怡\n恠\n怙\n怐\n怩\n怎\n怱\n怛\n怕\n怫\n怦\n怏\n怺\n恚\n恁\n恪\n恷\n恟\n恊\n恆\n恍\n恣\n恃\n恤\n恂\n恬\n恫\n恙\n悁\n悍\n惧\n悃\n悚\n悄\n悛\n悖\n悗\n悒\n悧\n悋\n惡\n悸\n惠\n惓\n悴\n忰\n悽\n惆\n悵\n惘\n慍\n愕\n愆\n惶\n惷\n愀\n惴\n惺\n愃\n愡\n惻\n惱\n愍\n愎\n慇\n愾\n愨\n愧\n慊\n愿\n愼\n愬\n愴\n愽\n慂\n慄\n慳\n慷\n慘\n慙\n慚\n慫\n慴\n慯\n慥\n慱\n慟\n慝\n慓\n慵\n憙\n憖\n憇\n憬\n憔\n憚\n憊\n憑\n憫\n憮\n懌\n懊\n應\n懷\n懈\n懃\n懆\n憺\n懋\n罹\n懍\n懦\n懣\n懶\n懺\n懴\n懿\n懽\n懼\n懾\n戀\n戈\n戉\n戍\n戌\n戔\n戛\n戞\n戡\n截\n戮\n戰\n戲\n戳\n扁\n扎\n扞\n扣\n扛\n扠\n扨\n扼\n抂\n抉\n找\n抒\n抓\n抖\n拔\n抃\n抔\n拗\n拑\n抻\n拏\n拿\n拆\n擔\n拈\n拜\n拌\n拊\n拂\n拇\n抛\n拉\n挌\n拮\n拱\n挧\n挂\n挈\n拯\n拵\n捐\n挾\n捍\n搜\n捏\n掖\n掎\n掀\n掫\n捶\n掣\n掏\n掉\n掟\n掵\n捫\n捩\n掾\n揩\n揀\n揆\n揣\n揉\n插\n揶\n揄\n搖\n搴\n搆\n搓\n搦\n搶\n攝\n搗\n搨\n搏\n摧\n摯\n摶\n摎\n攪\n撕\n撓\n撥\n撩\n撈\n撼\n據\n擒\n擅\n擇\n撻\n擘\n擂\n擱\n擧\n舉\n擠\n擡\n抬\n擣\n擯\n攬\n擶\n擴\n擲\n擺\n攀\n擽\n攘\n攜\n攅\n攤\n攣\n攫\n攴\n攵\n攷\n收\n攸\n畋\n效\n敖\n敕\n敍\n敘\n敞\n敝\n敲\n數\n斂\n斃\n變\n斛\n斟\n斫\n斷\n旃\n旆\n旁\n旄\n旌\n旒\n旛\n旙\n无\n旡\n旱\n杲\n昊\n昃\n旻\n杳\n昵\n昶\n昴\n昜\n晏\n晄\n晉\n晁\n晞\n晝\n晤\n晧\n晨\n晟\n晢\n晰\n暃\n暈\n暎\n暉\n暄\n暘\n暝\n曁\n暹\n曉\n暾\n暼\n曄\n暸\n曖\n曚\n曠\n昿\n曦\n曩\n曰\n曵\n曷\n朏\n朖\n朞\n朦\n朧\n霸\n朮\n朿\n朶\n杁\n朸\n朷\n杆\n杞\n杠\n杙\n杣\n杤\n枉\n杰\n枩\n杼\n杪\n枌\n枋\n枦\n枡\n枅\n枷\n柯\n枴\n柬\n枳\n柩\n枸\n柤\n柞\n柝\n柢\n柮\n枹\n柎\n柆\n柧\n檜\n栞\n框\n栩\n桀\n桍\n栲\n桎\n梳\n栫\n桙\n档\n桷\n桿\n梟\n梏\n梭\n梔\n條\n梛\n梃\n檮\n梹\n桴\n梵\n梠\n梺\n椏\n梍\n桾\n椁\n棊\n椈\n棘\n椢\n椦\n棡\n椌\n棍\n棔\n棧\n棕\n椶\n椒\n椄\n棗\n棣\n椥\n棹\n棠\n棯\n椨\n椪\n椚\n椣\n椡\n棆\n楹\n楷\n楜\n楸\n楫\n楔\n楾\n楮\n椹\n楴\n椽\n楙\n椰\n楡\n楞\n楝\n榁\n楪\n榲\n榮\n槐\n榿\n槁\n槓\n榾\n槎\n寨\n槊\n槝\n榻\n槃\n榧\n樮\n榑\n榠\n榜\n榕\n榴\n槞\n槨\n樂\n樛\n槿\n權\n槹\n槲\n槧\n樅\n榱\n樞\n槭\n樔\n槫\n樊\n樒\n櫁\n樣\n樓\n橄\n樌\n橲\n樶\n橸\n橇\n橢\n橙\n橦\n橈\n樸\n樢\n檐\n檍\n檠\n檄\n檢\n檣\n檗\n蘗\n檻\n櫃\n櫂\n檸\n檳\n檬\n櫞\n櫑\n櫟\n檪\n櫚\n櫪\n櫻\n欅\n蘖\n櫺\n欒\n欖\n鬱\n欟\n欸\n欷\n盜\n欹\n飮\n歇\n歃\n歉\n歐\n歙\n歔\n歛\n歟\n歡\n歸\n歹\n歿\n殀\n殄\n殃\n殍\n殘\n殕\n殞\n殤\n殪\n殫\n殯\n殲\n殱\n殳\n殷\n殼\n毆\n毋\n毓\n毟\n毬\n毫\n毳\n毯\n麾\n氈\n氓\n气\n氛\n氤\n氣\n汞\n汕\n汢\n汪\n沂\n沍\n沚\n沁\n沛\n汾\n汨\n汳\n沒\n沐\n泄\n泱\n泓\n沽\n泗\n泅\n泝\n沮\n沱\n沾\n沺\n泛\n泯\n泙\n泪\n洟\n衍\n洶\n洫\n洽\n洸\n洙\n洵\n洳\n洒\n洌\n浣\n涓\n浤\n浚\n浹\n浙\n涎\n涕\n濤\n涅\n淹\n渕\n渊\n涵\n淇\n淦\n涸\n淆\n淬\n淞\n淌\n淨\n淒\n淅\n淺\n淙\n淤\n淕\n淪\n淮\n渭\n湮\n渮\n渙\n湲\n湟\n渾\n渣\n湫\n渫\n湶\n湍\n渟\n湃\n渺\n湎\n渤\n滿\n渝\n游\n溂\n溪\n溘\n滉\n溷\n滓\n溽\n溯\n滄\n溲\n滔\n滕\n溏\n溥\n滂\n溟\n潁\n漑\n灌\n滬\n滸\n滾\n漿\n滲\n漱\n滯\n漲\n滌\n漾\n漓\n滷\n澆\n潺\n潸\n澁\n澀\n潯\n潛\n濳\n潭\n澂\n潼\n潘\n澎\n澑\n濂\n潦\n澳\n澣\n澡\n澤\n澹\n濆\n澪\n濟\n濕\n濬\n濔\n濘\n濱\n濮\n濛\n瀉\n瀋\n濺\n瀑\n瀁\n瀏\n濾\n瀛\n瀚\n潴\n瀝\n瀘\n瀟\n瀰\n瀾\n瀲\n灑\n灣\n炙\n炒\n炯\n烱\n炬\n炸\n炳\n炮\n烟\n烋\n烝\n烙\n焉\n烽\n焜\n焙\n煥\n煕\n熈\n煦\n煢\n煌\n煖\n煬\n熏\n燻\n熄\n熕\n熨\n熬\n燗\n熹\n熾\n燒\n燉\n燔\n燎\n燠\n燬\n燧\n燵\n燼\n燹\n燿\n爍\n爐\n爛\n爨\n爭\n爬\n爰\n爲\n爻\n爼\n爿\n牀\n牆\n牋\n牘\n牴\n牾\n犂\n犁\n犇\n犒\n犖\n犢\n犧\n犹\n犲\n狃\n狆\n狄\n狎\n狒\n狢\n狠\n狡\n狹\n狷\n倏\n猗\n猊\n猜\n猖\n猝\n猴\n猯\n猩\n猥\n猾\n獎\n獏\n默\n獗\n獪\n獨\n獰\n獸\n獵\n獻\n獺\n珈\n玳\n珎\n玻\n珀\n珥\n珮\n珞\n璢\n琅\n瑯\n琥\n珸\n琲\n琺\n瑕\n琿\n瑟\n瑙\n瑁\n瑜\n瑩\n瑰\n瑣\n瑪\n瑶\n瑾\n璋\n璞\n璧\n瓊\n瓏\n瓔\n珱\n瓠\n瓣\n瓧\n瓩\n瓮\n瓲\n瓰\n瓱\n瓸\n瓷\n甄\n甃\n甅\n甌\n甎\n甍\n甕\n甓\n甞\n甦\n甬\n甼\n畄\n畍\n畊\n畉\n畛\n畆\n畚\n畩\n畤\n畧\n畫\n畭\n畸\n當\n疆\n疇\n畴\n疊\n疉\n疂\n疔\n疚\n疝\n疥\n疣\n痂\n疳\n痃\n疵\n疽\n疸\n疼\n疱\n痍\n痊\n痒\n痙\n痣\n痞\n痾\n痿\n痼\n瘁\n痰\n痺\n痲\n痳\n瘋\n瘍\n瘉\n瘟\n瘧\n瘠\n瘡\n瘢\n瘤\n瘴\n瘰\n瘻\n癇\n癈\n癆\n癜\n癘\n癡\n癢\n癨\n癩\n癪\n癧\n癬\n癰\n癲\n癶\n癸\n發\n皀\n皃\n皈\n皋\n皎\n皖\n皓\n皙\n皚\n皰\n皴\n皸\n皹\n皺\n盂\n盍\n盖\n盒\n盞\n盡\n盥\n盧\n盪\n蘯\n盻\n眈\n眇\n眄\n眩\n眤\n眞\n眥\n眦\n眛\n眷\n眸\n睇\n睚\n睨\n睫\n睛\n睥\n睿\n睾\n睹\n瞎\n瞋\n瞑\n瞠\n瞞\n瞰\n瞶\n瞹\n瞿\n瞼\n瞽\n瞻\n矇\n矍\n矗\n矚\n矜\n矣\n矮\n矼\n砌\n砒\n礦\n砠\n礪\n硅\n碎\n硴\n碆\n硼\n碚\n碌\n碣\n碵\n碪\n碯\n磑\n磆\n磋\n磔\n碾\n碼\n磅\n磊\n磬\n磧\n磚\n磽\n磴\n礇\n礒\n礑\n礙\n礬\n礫\n祀\n祠\n祗\n祟\n祚\n祕\n祓\n祺\n祿\n禊\n禝\n禧\n齋\n禪\n禮\n禳\n禹\n禺\n秉\n秕\n秧\n秬\n秡\n秣\n稈\n稍\n稘\n稙\n稠\n稟\n禀\n稱\n稻\n稾\n稷\n穃\n穗\n穉\n穡\n穢\n穩\n龝\n穰\n穹\n穽\n窈\n窗\n窕\n窘\n窖\n窩\n竈\n窰\n窶\n竅\n竄\n窿\n邃\n竇\n竊\n竍\n竏\n竕\n竓\n站\n竚\n竝\n竡\n竢\n竦\n竭\n竰\n笂\n笏\n笊\n笆\n笳\n笘\n笙\n笞\n笵\n笨\n笶\n筐\n筺\n笄\n筍\n笋\n筌\n筅\n筵\n筥\n筴\n筧\n筰\n筱\n筬\n筮\n箝\n箘\n箟\n箍\n箜\n箚\n箋\n箒\n箏\n筝\n箙\n篋\n篁\n篌\n篏\n箴\n篆\n篝\n篩\n簑\n簔\n篦\n篥\n籠\n簀\n簇\n簓\n篳\n篷\n簗\n簍\n篶\n簣\n簧\n簪\n簟\n簷\n簫\n簽\n籌\n籃\n籔\n籏\n籀\n籐\n籘\n籟\n籤\n籖\n籥\n籬\n籵\n粃\n粐\n粤\n粭\n粢\n粫\n粡\n粨\n粳\n粲\n粱\n粮\n粹\n粽\n糀\n糅\n糂\n糘\n糒\n糜\n糢\n鬻\n糯\n糲\n糴\n糶\n糺\n紆\n紂\n紜\n紕\n紊\n絅\n絋\n紮\n紲\n紿\n紵\n絆\n絳\n絖\n絎\n絲\n絨\n絮\n絏\n絣\n經\n綉\n絛\n綏\n絽\n綛\n綺\n綮\n綣\n綵\n緇\n綽\n綫\n總\n綢\n綯\n緜\n綸\n綟\n綰\n緘\n緝\n緤\n緞\n緻\n緲\n緡\n縅\n縊\n縣\n縡\n縒\n縱\n縟\n縉\n縋\n縢\n繆\n繦\n縻\n縵\n縹\n繃\n縷\n縲\n縺\n繧\n繝\n繖\n繞\n繙\n繚\n繹\n繪\n繩\n繼\n繻\n纃\n緕\n繽\n辮\n繿\n纈\n纉\n續\n纒\n纐\n纓\n纔\n纖\n纎\n纛\n纜\n缸\n缺\n罅\n罌\n罍\n罎\n罐\n网\n罕\n罔\n罘\n罟\n罠\n罨\n罩\n罧\n罸\n羂\n羆\n羃\n羈\n羇\n羌\n羔\n羞\n羝\n羚\n羣\n羯\n羲\n羹\n羮\n羶\n羸\n譱\n翅\n翆\n翊\n翕\n翔\n翡\n翦\n翩\n翳\n翹\n飜\n耆\n耄\n耋\n耒\n耘\n耙\n耜\n耡\n耨\n耿\n耻\n聊\n聆\n聒\n聘\n聚\n聟\n聢\n聨\n聳\n聲\n聰\n聶\n聹\n聽\n聿\n肄\n肆\n肅\n肛\n肓\n肚\n肭\n冐\n肬\n胛\n胥\n胙\n胝\n胄\n胚\n胖\n脉\n胯\n胱\n脛\n脩\n脣\n脯\n腋\n隋\n腆\n脾\n腓\n腑\n胼\n腱\n腮\n腥\n腦\n腴\n膃\n膈\n膊\n膀\n膂\n膠\n膕\n膤\n膣\n腟\n膓\n膩\n膰\n膵\n膾\n膸\n膽\n臀\n臂\n膺\n臉\n臍\n臑\n臙\n臘\n臈\n臚\n臟\n臠\n臧\n臺\n臻\n臾\n舁\n舂\n舅\n與\n舊\n舍\n舐\n舖\n舩\n舫\n舸\n舳\n艀\n艙\n艘\n艝\n艚\n艟\n艤\n艢\n艨\n艪\n艫\n舮\n艱\n艷\n艸\n艾\n芍\n芒\n芫\n芟\n芻\n芬\n苡\n苣\n苟\n苒\n苴\n苳\n苺\n莓\n范\n苻\n苹\n苞\n茆\n苜\n茉\n苙\n茵\n茴\n茖\n茲\n茱\n荀\n茹\n荐\n荅\n茯\n茫\n茗\n茘\n莅\n莚\n莪\n莟\n莢\n莖\n茣\n莎\n莇\n莊\n荼\n莵\n荳\n荵\n莠\n莉\n莨\n菴\n萓\n菫\n菎\n菽\n萃\n菘\n萋\n菁\n菷\n萇\n菠\n菲\n萍\n萢\n萠\n莽\n萸\n蔆\n菻\n葭\n萪\n萼\n蕚\n蒄\n葷\n葫\n蒭\n葮\n蒂\n葩\n葆\n萬\n葯\n葹\n萵\n蓊\n葢\n蒹\n蒿\n蒟\n蓙\n蓍\n蒻\n蓚\n蓐\n蓁\n蓆\n蓖\n蒡\n蔡\n蓿\n蓴\n蔗\n蔘\n蔬\n蔟\n蔕\n蔔\n蓼\n蕀\n蕣\n蕘\n蕈\n蕁\n蘂\n蕋\n蕕\n薀\n薤\n薈\n薑\n薊\n薨\n蕭\n薔\n薛\n藪\n薇\n薜\n蕷\n蕾\n薐\n藉\n薺\n藏\n薹\n藐\n藕\n藝\n藥\n藜\n藹\n蘊\n蘓\n蘋\n藾\n藺\n蘆\n蘢\n蘚\n蘰\n蘿\n虍\n乕\n虔\n號\n虧\n虱\n蚓\n蚣\n蚩\n蚪\n蚋\n蚌\n蚶\n蚯\n蛄\n蛆\n蚰\n蛉\n蠣\n蚫\n蛔\n蛞\n蛩\n蛬\n蛟\n蛛\n蛯\n蜒\n蜆\n蜈\n蜀\n蜃\n蛻\n蜑\n蜉\n蜍\n蛹\n蜊\n蜴\n蜿\n蜷\n蜻\n蜥\n蜩\n蜚\n蝠\n蝟\n蝸\n蝌\n蝎\n蝴\n蝗\n蝨\n蝮\n蝙\n蝓\n蝣\n蝪\n蠅\n螢\n螟\n螂\n螯\n蟋\n螽\n蟀\n蟐\n雖\n螫\n蟄\n螳\n蟇\n蟆\n螻\n蟯\n蟲\n蟠\n蠏\n蠍\n蟾\n蟶\n蟷\n蠎\n蟒\n蠑\n蠖\n蠕\n蠢\n蠡\n蠱\n蠶\n蠹\n蠧\n蠻\n衄\n衂\n衒\n衙\n衞\n衢\n衫\n袁\n衾\n袞\n衵\n衽\n袵\n衲\n袂\n袗\n袒\n袮\n袙\n袢\n袍\n袤\n袰\n袿\n袱\n裃\n裄\n裔\n裘\n裙\n裝\n裹\n褂\n裼\n裴\n裨\n裲\n褄\n褌\n褊\n褓\n襃\n褞\n褥\n褪\n褫\n襁\n襄\n褻\n褶\n褸\n襌\n褝\n襠\n襞\n襦\n襤\n襭\n襪\n襯\n襴\n襷\n襾\n覃\n覈\n覊\n覓\n覘\n覡\n覩\n覦\n覬\n覯\n覲\n覺\n覽\n覿\n觀\n觚\n觜\n觝\n觧\n觴\n觸\n訃\n訖\n訐\n訌\n訛\n訝\n訥\n訶\n詁\n詛\n詒\n詆\n詈\n詼\n詭\n詬\n詢\n誅\n誂\n誄\n誨\n誡\n誑\n誥\n誦\n誚\n誣\n諄\n諍\n諂\n諚\n諫\n諳\n諧\n諤\n諱\n謔\n諠\n諢\n諷\n諞\n諛\n謌\n謇\n謚\n諡\n謖\n謐\n謗\n謠\n謳\n鞫\n謦\n謫\n謾\n謨\n譁\n譌\n譏\n譎\n證\n譖\n譛\n譚\n譫\n譟\n譬\n譯\n譴\n譽\n讀\n讌\n讎\n讒\n讓\n讖\n讙\n讚\n谺\n豁\n谿\n豈\n豌\n豎\n豐\n豕\n豢\n豬\n豸\n豺\n貂\n貉\n貅\n貊\n貍\n貎\n貔\n豼\n貘\n戝\n貭\n貪\n貽\n貲\n貳\n貮\n貶\n賈\n賁\n賤\n賣\n賚\n賽\n賺\n賻\n贄\n贅\n贊\n贇\n贏\n贍\n贐\n齎\n贓\n賍\n贔\n贖\n赧\n赭\n赱\n赳\n趁\n趙\n跂\n趾\n趺\n跏\n跚\n跖\n跌\n跛\n跋\n跪\n跫\n跟\n跣\n跼\n踈\n踉\n跿\n踝\n踞\n踐\n踟\n蹂\n踵\n踰\n踴\n蹊\n蹇\n蹉\n蹌\n蹐\n蹈\n蹙\n蹤\n蹠\n踪\n蹣\n蹕\n蹶\n蹲\n蹼\n躁\n躇\n躅\n躄\n躋\n躊\n躓\n躑\n躔\n躙\n躪\n躡\n躬\n躰\n軆\n躱\n躾\n軅\n軈\n軋\n軛\n軣\n軼\n軻\n軫\n軾\n輊\n輅\n輕\n輒\n輙\n輓\n輜\n輟\n輛\n輌\n輦\n輳\n輻\n輹\n轅\n轂\n輾\n轌\n轉\n轆\n轎\n轗\n轜\n轢\n轣\n轤\n辜\n辟\n辣\n辭\n辯\n辷\n迚\n迥\n迢\n迪\n迯\n邇\n迴\n逅\n迹\n迺\n逑\n逕\n逡\n逍\n逞\n逖\n逋\n逧\n逶\n逵\n逹\n迸\n遏\n遐\n遑\n遒\n逎\n遉\n逾\n遖\n遘\n遞\n遨\n遯\n遶\n隨\n遲\n邂\n遽\n邁\n邀\n邊\n邉\n邏\n邨\n邯\n邱\n邵\n郢\n郤\n扈\n郛\n鄂\n鄒\n鄙\n鄲\n鄰\n酊\n酖\n酘\n酣\n酥\n酩\n酳\n酲\n醋\n醉\n醂\n醢\n醫\n醯\n醪\n醵\n醴\n醺\n釀\n釁\n釉\n釋\n釐\n釖\n釟\n釡\n釛\n釼\n釵\n釶\n鈞\n釿\n鈔\n鈬\n鈕\n鈑\n鉞\n鉗\n鉅\n鉉\n鉤\n鉈\n銕\n鈿\n鉋\n鉐\n銜\n銖\n銓\n銛\n鉚\n鋏\n銹\n銷\n鋩\n錏\n鋺\n鍄\n錮\n錙\n錢\n錚\n錣\n錺\n錵\n錻\n鍜\n鍠\n鍼\n鍮\n鍖\n鎰\n鎬\n鎭\n鎔\n鎹\n鏖\n鏗\n鏨\n鏥\n鏘\n鏃\n鏝\n鏐\n鏈\n鏤\n鐚\n鐔\n鐓\n鐃\n鐇\n鐐\n鐶\n鐫\n鐵\n鐡\n鐺\n鑁\n鑒\n鑄\n鑛\n鑠\n鑢\n鑞\n鑪\n鈩\n鑰\n鑵\n鑷\n鑽\n鑚\n鑼\n鑾\n钁\n鑿\n閂\n閇\n閊\n閔\n閖\n閘\n閙\n閠\n閨\n閧\n閭\n閼\n閻\n閹\n閾\n闊\n濶\n闃\n闍\n闌\n闕\n闔\n闖\n關\n闡\n闥\n闢\n阡\n阨\n阮\n阯\n陂\n陌\n陏\n陋\n陷\n陜\n陞\n陝\n陟\n陦\n陲\n陬\n隍\n隘\n隕\n隗\n險\n隧\n隱\n隲\n隰\n隴\n隶\n隸\n隹\n雎\n雋\n雉\n雍\n襍\n雜\n霍\n雕\n雹\n霄\n霆\n霈\n霓\n霎\n霑\n霏\n霖\n霙\n霤\n霪\n霰\n霹\n霽\n霾\n靄\n靆\n靈\n靂\n靉\n靜\n靠\n靤\n靦\n靨\n勒\n靫\n靱\n靹\n鞅\n靼\n鞁\n靺\n鞆\n鞋\n鞏\n鞐\n鞜\n鞨\n鞦\n鞣\n鞳\n鞴\n韃\n韆\n韈\n韋\n韜\n韭\n齏\n韲\n竟\n韶\n韵\n頏\n頌\n頸\n頤\n頡\n頷\n頽\n顆\n顏\n顋\n顫\n顯\n顰\n顱\n顴\n顳\n颪\n颯\n颱\n颶\n飄\n飃\n飆\n飩\n飫\n餃\n餉\n餒\n餔\n餘\n餡\n餝\n餞\n餤\n餠\n餬\n餮\n餽\n餾\n饂\n饉\n饅\n饐\n饋\n饑\n饒\n饌\n饕\n馗\n馘\n馥\n馭\n馮\n馼\n駟\n駛\n駝\n駘\n駑\n駭\n駮\n駱\n駲\n駻\n駸\n騁\n騏\n騅\n駢\n騙\n騫\n騷\n驅\n驂\n驀\n驃\n騾\n驕\n驍\n驛\n驗\n驟\n驢\n驥\n驤\n驩\n驫\n驪\n骭\n骰\n骼\n髀\n髏\n髑\n髓\n體\n髞\n髟\n髢\n髣\n髦\n髯\n髫\n髮\n髴\n髱\n髷\n髻\n鬆\n鬘\n鬚\n鬟\n鬢\n鬣\n鬥\n鬧\n鬨\n鬩\n鬪\n鬮\n鬯\n鬲\n魄\n魃\n魏\n魍\n魎\n魑\n魘\n魴\n鮓\n鮃\n鮑\n鮖\n鮗\n鮟\n鮠\n鮨\n鮴\n鯀\n鯊\n鮹\n鯆\n鯏\n鯑\n鯒\n鯣\n鯢\n鯤\n鯔\n鯡\n鰺\n鯲\n鯱\n鯰\n鰕\n鰔\n鰉\n鰓\n鰌\n鰆\n鰈\n鰒\n鰊\n鰄\n鰮\n鰛\n鰥\n鰤\n鰡\n鰰\n鱇\n鰲\n鱆\n鰾\n鱚\n鱠\n鱧\n鱶\n鱸\n鳧\n鳬\n鳰\n鴉\n鴈\n鳫\n鴃\n鴆\n鴪\n鴦\n鶯\n鴣\n鴟\n鵄\n鴕\n鴒\n鵁\n鴿\n鴾\n鵆\n鵈\n鵝\n鵞\n鵤\n鵑\n鵐\n鵙\n鵲\n鶉\n鶇\n鶫\n鵯\n鵺\n鶚\n鶤\n鶩\n鶲\n鷄\n鷁\n鶻\n鶸\n鶺\n鷆\n鷏\n鷂\n鷙\n鷓\n鷸\n鷦\n鷭\n鷯\n鷽\n鸚\n鸛\n鸞\n鹵\n鹹\n鹽\n麁\n麈\n麋\n麌\n麒\n麕\n麑\n麝\n麥\n麩\n麸\n麪\n麭\n靡\n黌\n黎\n黏\n黐\n黔\n黜\n點\n黝\n黠\n黥\n黨\n黯\n黴\n黶\n黷\n黹\n黻\n黼\n黽\n鼇\n鼈\n皷\n鼕\n鼡\n鼬\n鼾\n齊\n齒\n齔\n齣\n齟\n齠\n齡\n齦\n齧\n齬\n齪\n齷\n齲\n齶\n龕\n龜\n龠\n堯\n槇\n遙\n瑤\n凜\n熙\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n纊\n褜\n鍈\n銈\n蓜\n俉\n炻\n昱\n棈\n鋹\n曻\n彅\n丨\n仡\n仼\n伀\n伃\n伹\n佖\n侒\n侊\n侚\n侔\n俍\n偀\n倢\n俿\n倞\n偆\n偰\n偂\n傔\n僴\n僘\n兊\n兤\n冝\n冾\n凬\n刕\n劜\n劦\n勀\n勛\n匀\n匇\n匤\n卲\n厓\n厲\n叝\n﨎\n咜\n咊\n咩\n哿\n喆\n坙\n坥\n垬\n埈\n埇\n﨏\n塚\n增\n墲\n夋\n奓\n奛\n奝\n奣\n妤\n妺\n孖\n寀\n甯\n寘\n寬\n尞\n岦\n岺\n峵\n崧\n嵓\n﨑\n嵂\n嵭\n嶸\n嶹\n巐\n弡\n弴\n彧\n德\n忞\n恝\n悅\n悊\n惞\n惕\n愠\n惲\n愑\n愷\n愰\n憘\n戓\n抦\n揵\n摠\n撝\n擎\n敎\n昀\n昕\n昻\n昉\n昮\n昞\n昤\n晥\n晗\n晙\n晴\n晳\n暙\n暠\n暲\n暿\n曺\n朎\n朗\n杦\n枻\n桒\n柀\n栁\n桄\n棏\n﨓\n楨\n﨔\n榘\n槢\n樰\n橫\n橆\n橳\n橾\n櫢\n櫤\n毖\n氿\n汜\n沆\n汯\n泚\n洄\n涇\n浯\n涖\n涬\n淏\n淸\n淲\n淼\n渹\n湜\n渧\n渼\n溿\n澈\n澵\n濵\n瀅\n瀇\n瀨\n炅\n炫\n焏\n焄\n煜\n煆\n煇\n凞\n燁\n燾\n犱\n犾\n猤\n猪\n獷\n玽\n珉\n珖\n珣\n珒\n琇\n珵\n琦\n琪\n琩\n琮\n瑢\n璉\n璟\n甁\n畯\n皂\n皜\n皞\n皛\n皦\n益\n睆\n劯\n砡\n硎\n硤\n硺\n礰\n礼\n神\n祥\n禔\n福\n禛\n竑\n竧\n靖\n竫\n箞\n精\n絈\n絜\n綷\n綠\n緖\n繒\n罇\n羡\n羽\n茁\n荢\n荿\n菇\n菶\n葈\n蒴\n蕓\n蕙\n蕫\n﨟\n薰\n蘒\n﨡\n蠇\n裵\n訒\n訷\n詹\n誧\n誾\n諟\n諸\n諶\n譓\n譿\n賰\n賴\n贒\n赶\n﨣\n軏\n﨤\n逸\n遧\n郞\n都\n鄕\n鄧\n釚\n釗\n釞\n釭\n釮\n釤\n釥\n鈆\n鈐\n鈊\n鈺\n鉀\n鈼\n鉎\n鉙\n鉑\n鈹\n鉧\n銧\n鉷\n鉸\n鋧\n鋗\n鋙\n鋐\n﨧\n鋕\n鋠\n鋓\n錥\n錡\n鋻\n﨨\n錞\n鋿\n錝\n錂\n鍰\n鍗\n鎤\n鏆\n鏞\n鏸\n鐱\n鑅\n鑈\n閒\n隆\n﨩\n隝\n隯\n霳\n霻\n靃\n靍\n靏\n靑\n靕\n顗\n顥\n飯\n飼\n餧\n館\n馞\n驎\n髙\n髜\n魵\n魲\n鮏\n鮱\n鮻\n鰀\n鵰\n鵫\n鶴\n鸙\n黑\n�\n�\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\n￢\n￤\n＇\n＂\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n"
  },
  {
    "path": "helix-view/tests/encoding/iso_2022_jp_out.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n　\n、\n。\n，\n．\n・\n：\n；\n？\n！\n゛\n゜\n´\n｀\n¨\n＾\n￣\n＿\nヽ\nヾ\nゝ\nゞ\n〃\n仝\n々\n〆\n〇\nー\n―\n‐\n／\n＼\n～\n∥\n｜\n…\n‥\n‘\n’\n“\n”\n（\n）\n〔\n〕\n［\n］\n｛\n｝\n〈\n〉\n《\n》\n「\n」\n『\n』\n【\n】\n＋\n－\n±\n×\n÷\n＝\n≠\n＜\n＞\n≦\n≧\n∞\n∴\n♂\n♀\n°\n′\n″\n℃\n￥\n＄\n￠\n￡\n％\n＃\n＆\n＊\n＠\n§\n☆\n★\n○\n●\n◎\n◇\n◆\n□\n■\n△\n▲\n▽\n▼\n※\n〒\n→\n←\n↑\n↓\n〓\n∈\n∋\n⊆\n⊇\n⊂\n⊃\n∪\n∩\n∧\n∨\n￢\n⇒\n⇔\n∀\n∃\n∠\n⊥\n⌒\n∂\n∇\n≡\n≒\n≪\n≫\n√\n∽\n∝\n∵\n∫\n∬\nÅ\n‰\n♯\n♭\n♪\n†\n‡\n¶\n◯\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n─\n│\n┌\n┐\n┘\n└\n├\n┬\n┤\n┴\n┼\n━\n┃\n┏\n┓\n┛\n┗\n┣\n┳\n┫\n┻\n╋\n┠\n┯\n┨\n┷\n┿\n┝\n┰\n┥\n┸\n╂\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n⑪\n⑫\n⑬\n⑭\n⑮\n⑯\n⑰\n⑱\n⑲\n⑳\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n㍉\n㌔\n㌢\n㍍\n㌘\n㌧\n㌃\n㌶\n㍑\n㍗\n㌍\n㌦\n㌣\n㌫\n㍊\n㌻\n㎜\n㎝\n㎞\n㎎\n㎏\n㏄\n㎡\n㍻\n〝\n〟\n№\n㏍\n℡\n㊤\n㊥\n㊦\n㊧\n㊨\n㈱\n㈲\n㈹\n㍾\n㍽\n㍼\n≒\n≡\n∫\n∮\n∑\n√\n⊥\n∠\n∟\n⊿\n∵\n∩\n∪\n亜\n唖\n娃\n阿\n哀\n愛\n挨\n姶\n逢\n葵\n茜\n穐\n悪\n握\n渥\n旭\n葦\n芦\n鯵\n梓\n圧\n斡\n扱\n宛\n姐\n虻\n飴\n絢\n綾\n鮎\n或\n粟\n袷\n安\n庵\n按\n暗\n案\n闇\n鞍\n杏\n以\n伊\n位\n依\n偉\n囲\n夷\n委\n威\n尉\n惟\n意\n慰\n易\n椅\n為\n畏\n異\n移\n維\n緯\n胃\n萎\n衣\n謂\n違\n遺\n医\n井\n亥\n域\n育\n郁\n磯\n一\n壱\n溢\n逸\n稲\n茨\n芋\n鰯\n允\n印\n咽\n員\n因\n姻\n引\n飲\n淫\n胤\n蔭\n院\n陰\n隠\n韻\n吋\n右\n宇\n烏\n羽\n迂\n雨\n卯\n鵜\n窺\n丑\n碓\n臼\n渦\n嘘\n唄\n欝\n蔚\n鰻\n姥\n厩\n浦\n瓜\n閏\n噂\n云\n運\n雲\n荏\n餌\n叡\n営\n嬰\n影\n映\n曳\n栄\n永\n泳\n洩\n瑛\n盈\n穎\n頴\n英\n衛\n詠\n鋭\n液\n疫\n益\n駅\n悦\n謁\n越\n閲\n榎\n厭\n円\n園\n堰\n奄\n宴\n延\n怨\n掩\n援\n沿\n演\n炎\n焔\n煙\n燕\n猿\n縁\n艶\n苑\n薗\n遠\n鉛\n鴛\n塩\n於\n汚\n甥\n凹\n央\n奥\n往\n応\n押\n旺\n横\n欧\n殴\n王\n翁\n襖\n鴬\n鴎\n黄\n岡\n沖\n荻\n億\n屋\n憶\n臆\n桶\n牡\n乙\n俺\n卸\n恩\n温\n穏\n音\n下\n化\n仮\n何\n伽\n価\n佳\n加\n可\n嘉\n夏\n嫁\n家\n寡\n科\n暇\n果\n架\n歌\n河\n火\n珂\n禍\n禾\n稼\n箇\n花\n苛\n茄\n荷\n華\n菓\n蝦\n課\n嘩\n貨\n迦\n過\n霞\n蚊\n俄\n峨\n我\n牙\n画\n臥\n芽\n蛾\n賀\n雅\n餓\n駕\n介\n会\n解\n回\n塊\n壊\n廻\n快\n怪\n悔\n恢\n懐\n戒\n拐\n改\n魁\n晦\n械\n海\n灰\n界\n皆\n絵\n芥\n蟹\n開\n階\n貝\n凱\n劾\n外\n咳\n害\n崖\n慨\n概\n涯\n碍\n蓋\n街\n該\n鎧\n骸\n浬\n馨\n蛙\n垣\n柿\n蛎\n鈎\n劃\n嚇\n各\n廓\n拡\n撹\n格\n核\n殻\n獲\n確\n穫\n覚\n角\n赫\n較\n郭\n閣\n隔\n革\n学\n岳\n楽\n額\n顎\n掛\n笠\n樫\n橿\n梶\n鰍\n潟\n割\n喝\n恰\n括\n活\n渇\n滑\n葛\n褐\n轄\n且\n鰹\n叶\n椛\n樺\n鞄\n株\n兜\n竃\n蒲\n釜\n鎌\n噛\n鴨\n栢\n茅\n萱\n粥\n刈\n苅\n瓦\n乾\n侃\n冠\n寒\n刊\n勘\n勧\n巻\n喚\n堪\n姦\n完\n官\n寛\n干\n幹\n患\n感\n慣\n憾\n換\n敢\n柑\n桓\n棺\n款\n歓\n汗\n漢\n澗\n潅\n環\n甘\n監\n看\n竿\n管\n簡\n緩\n缶\n翰\n肝\n艦\n莞\n観\n諌\n貫\n還\n鑑\n間\n閑\n関\n陥\n韓\n館\n舘\n丸\n含\n岸\n巌\n玩\n癌\n眼\n岩\n翫\n贋\n雁\n頑\n顔\n願\n企\n伎\n危\n喜\n器\n基\n奇\n嬉\n寄\n岐\n希\n幾\n忌\n揮\n机\n旗\n既\n期\n棋\n棄\n機\n帰\n毅\n気\n汽\n畿\n祈\n季\n稀\n紀\n徽\n規\n記\n貴\n起\n軌\n輝\n飢\n騎\n鬼\n亀\n偽\n儀\n妓\n宜\n戯\n技\n擬\n欺\n犠\n疑\n祇\n義\n蟻\n誼\n議\n掬\n菊\n鞠\n吉\n吃\n喫\n桔\n橘\n詰\n砧\n杵\n黍\n却\n客\n脚\n虐\n逆\n丘\n久\n仇\n休\n及\n吸\n宮\n弓\n急\n救\n朽\n求\n汲\n泣\n灸\n球\n究\n窮\n笈\n級\n糾\n給\n旧\n牛\n去\n居\n巨\n拒\n拠\n挙\n渠\n虚\n許\n距\n鋸\n漁\n禦\n魚\n亨\n享\n京\n供\n侠\n僑\n兇\n競\n共\n凶\n協\n匡\n卿\n叫\n喬\n境\n峡\n強\n彊\n怯\n恐\n恭\n挟\n教\n橋\n況\n狂\n狭\n矯\n胸\n脅\n興\n蕎\n郷\n鏡\n響\n饗\n驚\n仰\n凝\n尭\n暁\n業\n局\n曲\n極\n玉\n桐\n粁\n僅\n勤\n均\n巾\n錦\n斤\n欣\n欽\n琴\n禁\n禽\n筋\n緊\n芹\n菌\n衿\n襟\n謹\n近\n金\n吟\n銀\n九\n倶\n句\n区\n狗\n玖\n矩\n苦\n躯\n駆\n駈\n駒\n具\n愚\n虞\n喰\n空\n偶\n寓\n遇\n隅\n串\n櫛\n釧\n屑\n屈\n掘\n窟\n沓\n靴\n轡\n窪\n熊\n隈\n粂\n栗\n繰\n桑\n鍬\n勲\n君\n薫\n訓\n群\n軍\n郡\n卦\n袈\n祁\n係\n傾\n刑\n兄\n啓\n圭\n珪\n型\n契\n形\n径\n恵\n慶\n慧\n憩\n掲\n携\n敬\n景\n桂\n渓\n畦\n稽\n系\n経\n継\n繋\n罫\n茎\n荊\n蛍\n計\n詣\n警\n軽\n頚\n鶏\n芸\n迎\n鯨\n劇\n戟\n撃\n激\n隙\n桁\n傑\n欠\n決\n潔\n穴\n結\n血\n訣\n月\n件\n倹\n倦\n健\n兼\n券\n剣\n喧\n圏\n堅\n嫌\n建\n憲\n懸\n拳\n捲\n検\n権\n牽\n犬\n献\n研\n硯\n絹\n県\n肩\n見\n謙\n賢\n軒\n遣\n鍵\n険\n顕\n験\n鹸\n元\n原\n厳\n幻\n弦\n減\n源\n玄\n現\n絃\n舷\n言\n諺\n限\n乎\n個\n古\n呼\n固\n姑\n孤\n己\n庫\n弧\n戸\n故\n枯\n湖\n狐\n糊\n袴\n股\n胡\n菰\n虎\n誇\n跨\n鈷\n雇\n顧\n鼓\n五\n互\n伍\n午\n呉\n吾\n娯\n後\n御\n悟\n梧\n檎\n瑚\n碁\n語\n誤\n護\n醐\n乞\n鯉\n交\n佼\n侯\n候\n倖\n光\n公\n功\n効\n勾\n厚\n口\n向\n后\n喉\n坑\n垢\n好\n孔\n孝\n宏\n工\n巧\n巷\n幸\n広\n庚\n康\n弘\n恒\n慌\n抗\n拘\n控\n攻\n昂\n晃\n更\n杭\n校\n梗\n構\n江\n洪\n浩\n港\n溝\n甲\n皇\n硬\n稿\n糠\n紅\n紘\n絞\n綱\n耕\n考\n肯\n肱\n腔\n膏\n航\n荒\n行\n衡\n講\n貢\n購\n郊\n酵\n鉱\n砿\n鋼\n閤\n降\n項\n香\n高\n鴻\n剛\n劫\n号\n合\n壕\n拷\n濠\n豪\n轟\n麹\n克\n刻\n告\n国\n穀\n酷\n鵠\n黒\n獄\n漉\n腰\n甑\n忽\n惚\n骨\n狛\n込\n此\n頃\n今\n困\n坤\n墾\n婚\n恨\n懇\n昏\n昆\n根\n梱\n混\n痕\n紺\n艮\n魂\n些\n佐\n叉\n唆\n嵯\n左\n差\n査\n沙\n瑳\n砂\n詐\n鎖\n裟\n坐\n座\n挫\n債\n催\n再\n最\n哉\n塞\n妻\n宰\n彩\n才\n採\n栽\n歳\n済\n災\n采\n犀\n砕\n砦\n祭\n斎\n細\n菜\n裁\n載\n際\n剤\n在\n材\n罪\n財\n冴\n坂\n阪\n堺\n榊\n肴\n咲\n崎\n埼\n碕\n鷺\n作\n削\n咋\n搾\n昨\n朔\n柵\n窄\n策\n索\n錯\n桜\n鮭\n笹\n匙\n冊\n刷\n察\n拶\n撮\n擦\n札\n殺\n薩\n雑\n皐\n鯖\n捌\n錆\n鮫\n皿\n晒\n三\n傘\n参\n山\n惨\n撒\n散\n桟\n燦\n珊\n産\n算\n纂\n蚕\n讃\n賛\n酸\n餐\n斬\n暫\n残\n仕\n仔\n伺\n使\n刺\n司\n史\n嗣\n四\n士\n始\n姉\n姿\n子\n屍\n市\n師\n志\n思\n指\n支\n孜\n斯\n施\n旨\n枝\n止\n死\n氏\n獅\n祉\n私\n糸\n紙\n紫\n肢\n脂\n至\n視\n詞\n詩\n試\n誌\n諮\n資\n賜\n雌\n飼\n歯\n事\n似\n侍\n児\n字\n寺\n慈\n持\n時\n次\n滋\n治\n爾\n璽\n痔\n磁\n示\n而\n耳\n自\n蒔\n辞\n汐\n鹿\n式\n識\n鴫\n竺\n軸\n宍\n雫\n七\n叱\n執\n失\n嫉\n室\n悉\n湿\n漆\n疾\n質\n実\n蔀\n篠\n偲\n柴\n芝\n屡\n蕊\n縞\n舎\n写\n射\n捨\n赦\n斜\n煮\n社\n紗\n者\n謝\n車\n遮\n蛇\n邪\n借\n勺\n尺\n杓\n灼\n爵\n酌\n釈\n錫\n若\n寂\n弱\n惹\n主\n取\n守\n手\n朱\n殊\n狩\n珠\n種\n腫\n趣\n酒\n首\n儒\n受\n呪\n寿\n授\n樹\n綬\n需\n囚\n収\n周\n宗\n就\n州\n修\n愁\n拾\n洲\n秀\n秋\n終\n繍\n習\n臭\n舟\n蒐\n衆\n襲\n讐\n蹴\n輯\n週\n酋\n酬\n集\n醜\n什\n住\n充\n十\n従\n戎\n柔\n汁\n渋\n獣\n縦\n重\n銃\n叔\n夙\n宿\n淑\n祝\n縮\n粛\n塾\n熟\n出\n術\n述\n俊\n峻\n春\n瞬\n竣\n舜\n駿\n准\n循\n旬\n楯\n殉\n淳\n準\n潤\n盾\n純\n巡\n遵\n醇\n順\n処\n初\n所\n暑\n曙\n渚\n庶\n緒\n署\n書\n薯\n藷\n諸\n助\n叙\n女\n序\n徐\n恕\n鋤\n除\n傷\n償\n勝\n匠\n升\n召\n哨\n商\n唱\n嘗\n奨\n妾\n娼\n宵\n将\n小\n少\n尚\n庄\n床\n廠\n彰\n承\n抄\n招\n掌\n捷\n昇\n昌\n昭\n晶\n松\n梢\n樟\n樵\n沼\n消\n渉\n湘\n焼\n焦\n照\n症\n省\n硝\n礁\n祥\n称\n章\n笑\n粧\n紹\n肖\n菖\n蒋\n蕉\n衝\n裳\n訟\n証\n詔\n詳\n象\n賞\n醤\n鉦\n鍾\n鐘\n障\n鞘\n上\n丈\n丞\n乗\n冗\n剰\n城\n場\n壌\n嬢\n常\n情\n擾\n条\n杖\n浄\n状\n畳\n穣\n蒸\n譲\n醸\n錠\n嘱\n埴\n飾\n拭\n植\n殖\n燭\n織\n職\n色\n触\n食\n蝕\n辱\n尻\n伸\n信\n侵\n唇\n娠\n寝\n審\n心\n慎\n振\n新\n晋\n森\n榛\n浸\n深\n申\n疹\n真\n神\n秦\n紳\n臣\n芯\n薪\n親\n診\n身\n辛\n進\n針\n震\n人\n仁\n刃\n塵\n壬\n尋\n甚\n尽\n腎\n訊\n迅\n陣\n靭\n笥\n諏\n須\n酢\n図\n厨\n逗\n吹\n垂\n帥\n推\n水\n炊\n睡\n粋\n翠\n衰\n遂\n酔\n錐\n錘\n随\n瑞\n髄\n崇\n嵩\n数\n枢\n趨\n雛\n据\n杉\n椙\n菅\n頗\n雀\n裾\n澄\n摺\n寸\n世\n瀬\n畝\n是\n凄\n制\n勢\n姓\n征\n性\n成\n政\n整\n星\n晴\n棲\n栖\n正\n清\n牲\n生\n盛\n精\n聖\n声\n製\n西\n誠\n誓\n請\n逝\n醒\n青\n静\n斉\n税\n脆\n隻\n席\n惜\n戚\n斥\n昔\n析\n石\n積\n籍\n績\n脊\n責\n赤\n跡\n蹟\n碩\n切\n拙\n接\n摂\n折\n設\n窃\n節\n説\n雪\n絶\n舌\n蝉\n仙\n先\n千\n占\n宣\n専\n尖\n川\n戦\n扇\n撰\n栓\n栴\n泉\n浅\n洗\n染\n潜\n煎\n煽\n旋\n穿\n箭\n線\n繊\n羨\n腺\n舛\n船\n薦\n詮\n賎\n践\n選\n遷\n銭\n銑\n閃\n鮮\n前\n善\n漸\n然\n全\n禅\n繕\n膳\n糎\n噌\n塑\n岨\n措\n曾\n曽\n楚\n狙\n疏\n疎\n礎\n祖\n租\n粗\n素\n組\n蘇\n訴\n阻\n遡\n鼠\n僧\n創\n双\n叢\n倉\n喪\n壮\n奏\n爽\n宋\n層\n匝\n惣\n想\n捜\n掃\n挿\n掻\n操\n早\n曹\n巣\n槍\n槽\n漕\n燥\n争\n痩\n相\n窓\n糟\n総\n綜\n聡\n草\n荘\n葬\n蒼\n藻\n装\n走\n送\n遭\n鎗\n霜\n騒\n像\n増\n憎\n臓\n蔵\n贈\n造\n促\n側\n則\n即\n息\n捉\n束\n測\n足\n速\n俗\n属\n賊\n族\n続\n卒\n袖\n其\n揃\n存\n孫\n尊\n損\n村\n遜\n他\n多\n太\n汰\n詑\n唾\n堕\n妥\n惰\n打\n柁\n舵\n楕\n陀\n駄\n騨\n体\n堆\n対\n耐\n岱\n帯\n待\n怠\n態\n戴\n替\n泰\n滞\n胎\n腿\n苔\n袋\n貸\n退\n逮\n隊\n黛\n鯛\n代\n台\n大\n第\n醍\n題\n鷹\n滝\n瀧\n卓\n啄\n宅\n托\n択\n拓\n沢\n濯\n琢\n託\n鐸\n濁\n諾\n茸\n凧\n蛸\n只\n叩\n但\n達\n辰\n奪\n脱\n巽\n竪\n辿\n棚\n谷\n狸\n鱈\n樽\n誰\n丹\n単\n嘆\n坦\n担\n探\n旦\n歎\n淡\n湛\n炭\n短\n端\n箪\n綻\n耽\n胆\n蛋\n誕\n鍛\n団\n壇\n弾\n断\n暖\n檀\n段\n男\n談\n値\n知\n地\n弛\n恥\n智\n池\n痴\n稚\n置\n致\n蜘\n遅\n馳\n築\n畜\n竹\n筑\n蓄\n逐\n秩\n窒\n茶\n嫡\n着\n中\n仲\n宙\n忠\n抽\n昼\n柱\n注\n虫\n衷\n註\n酎\n鋳\n駐\n樗\n瀦\n猪\n苧\n著\n貯\n丁\n兆\n凋\n喋\n寵\n帖\n帳\n庁\n弔\n張\n彫\n徴\n懲\n挑\n暢\n朝\n潮\n牒\n町\n眺\n聴\n脹\n腸\n蝶\n調\n諜\n超\n跳\n銚\n長\n頂\n鳥\n勅\n捗\n直\n朕\n沈\n珍\n賃\n鎮\n陳\n津\n墜\n椎\n槌\n追\n鎚\n痛\n通\n塚\n栂\n掴\n槻\n佃\n漬\n柘\n辻\n蔦\n綴\n鍔\n椿\n潰\n坪\n壷\n嬬\n紬\n爪\n吊\n釣\n鶴\n亭\n低\n停\n偵\n剃\n貞\n呈\n堤\n定\n帝\n底\n庭\n廷\n弟\n悌\n抵\n挺\n提\n梯\n汀\n碇\n禎\n程\n締\n艇\n訂\n諦\n蹄\n逓\n邸\n鄭\n釘\n鼎\n泥\n摘\n擢\n敵\n滴\n的\n笛\n適\n鏑\n溺\n哲\n徹\n撤\n轍\n迭\n鉄\n典\n填\n天\n展\n店\n添\n纏\n甜\n貼\n転\n顛\n点\n伝\n殿\n澱\n田\n電\n兎\n吐\n堵\n塗\n妬\n屠\n徒\n斗\n杜\n渡\n登\n菟\n賭\n途\n都\n鍍\n砥\n砺\n努\n度\n土\n奴\n怒\n倒\n党\n冬\n凍\n刀\n唐\n塔\n塘\n套\n宕\n島\n嶋\n悼\n投\n搭\n東\n桃\n梼\n棟\n盗\n淘\n湯\n涛\n灯\n燈\n当\n痘\n祷\n等\n答\n筒\n糖\n統\n到\n董\n蕩\n藤\n討\n謄\n豆\n踏\n逃\n透\n鐙\n陶\n頭\n騰\n闘\n働\n動\n同\n堂\n導\n憧\n撞\n洞\n瞳\n童\n胴\n萄\n道\n銅\n峠\n鴇\n匿\n得\n徳\n涜\n特\n督\n禿\n篤\n毒\n独\n読\n栃\n橡\n凸\n突\n椴\n届\n鳶\n苫\n寅\n酉\n瀞\n噸\n屯\n惇\n敦\n沌\n豚\n遁\n頓\n呑\n曇\n鈍\n奈\n那\n内\n乍\n凪\n薙\n謎\n灘\n捺\n鍋\n楢\n馴\n縄\n畷\n南\n楠\n軟\n難\n汝\n二\n尼\n弐\n迩\n匂\n賑\n肉\n虹\n廿\n日\n乳\n入\n如\n尿\n韮\n任\n妊\n忍\n認\n濡\n禰\n祢\n寧\n葱\n猫\n熱\n年\n念\n捻\n撚\n燃\n粘\n乃\n廼\n之\n埜\n嚢\n悩\n濃\n納\n能\n脳\n膿\n農\n覗\n蚤\n巴\n把\n播\n覇\n杷\n波\n派\n琶\n破\n婆\n罵\n芭\n馬\n俳\n廃\n拝\n排\n敗\n杯\n盃\n牌\n背\n肺\n輩\n配\n倍\n培\n媒\n梅\n楳\n煤\n狽\n買\n売\n賠\n陪\n這\n蝿\n秤\n矧\n萩\n伯\n剥\n博\n拍\n柏\n泊\n白\n箔\n粕\n舶\n薄\n迫\n曝\n漠\n爆\n縛\n莫\n駁\n麦\n函\n箱\n硲\n箸\n肇\n筈\n櫨\n幡\n肌\n畑\n畠\n八\n鉢\n溌\n発\n醗\n髪\n伐\n罰\n抜\n筏\n閥\n鳩\n噺\n塙\n蛤\n隼\n伴\n判\n半\n反\n叛\n帆\n搬\n斑\n板\n氾\n汎\n版\n犯\n班\n畔\n繁\n般\n藩\n販\n範\n釆\n煩\n頒\n飯\n挽\n晩\n番\n盤\n磐\n蕃\n蛮\n匪\n卑\n否\n妃\n庇\n彼\n悲\n扉\n批\n披\n斐\n比\n泌\n疲\n皮\n碑\n秘\n緋\n罷\n肥\n被\n誹\n費\n避\n非\n飛\n樋\n簸\n備\n尾\n微\n枇\n毘\n琵\n眉\n美\n鼻\n柊\n稗\n匹\n疋\n髭\n彦\n膝\n菱\n肘\n弼\n必\n畢\n筆\n逼\n桧\n姫\n媛\n紐\n百\n謬\n俵\n彪\n標\n氷\n漂\n瓢\n票\n表\n評\n豹\n廟\n描\n病\n秒\n苗\n錨\n鋲\n蒜\n蛭\n鰭\n品\n彬\n斌\n浜\n瀕\n貧\n賓\n頻\n敏\n瓶\n不\n付\n埠\n夫\n婦\n富\n冨\n布\n府\n怖\n扶\n敷\n斧\n普\n浮\n父\n符\n腐\n膚\n芙\n譜\n負\n賦\n赴\n阜\n附\n侮\n撫\n武\n舞\n葡\n蕪\n部\n封\n楓\n風\n葺\n蕗\n伏\n副\n復\n幅\n服\n福\n腹\n複\n覆\n淵\n弗\n払\n沸\n仏\n物\n鮒\n分\n吻\n噴\n墳\n憤\n扮\n焚\n奮\n粉\n糞\n紛\n雰\n文\n聞\n丙\n併\n兵\n塀\n幣\n平\n弊\n柄\n並\n蔽\n閉\n陛\n米\n頁\n僻\n壁\n癖\n碧\n別\n瞥\n蔑\n箆\n偏\n変\n片\n篇\n編\n辺\n返\n遍\n便\n勉\n娩\n弁\n鞭\n保\n舗\n鋪\n圃\n捕\n歩\n甫\n補\n輔\n穂\n募\n墓\n慕\n戊\n暮\n母\n簿\n菩\n倣\n俸\n包\n呆\n報\n奉\n宝\n峰\n峯\n崩\n庖\n抱\n捧\n放\n方\n朋\n法\n泡\n烹\n砲\n縫\n胞\n芳\n萌\n蓬\n蜂\n褒\n訪\n豊\n邦\n鋒\n飽\n鳳\n鵬\n乏\n亡\n傍\n剖\n坊\n妨\n帽\n忘\n忙\n房\n暴\n望\n某\n棒\n冒\n紡\n肪\n膨\n謀\n貌\n貿\n鉾\n防\n吠\n頬\n北\n僕\n卜\n墨\n撲\n朴\n牧\n睦\n穆\n釦\n勃\n没\n殆\n堀\n幌\n奔\n本\n翻\n凡\n盆\n摩\n磨\n魔\n麻\n埋\n妹\n昧\n枚\n毎\n哩\n槙\n幕\n膜\n枕\n鮪\n柾\n鱒\n桝\n亦\n俣\n又\n抹\n末\n沫\n迄\n侭\n繭\n麿\n万\n慢\n満\n漫\n蔓\n味\n未\n魅\n巳\n箕\n岬\n密\n蜜\n湊\n蓑\n稔\n脈\n妙\n粍\n民\n眠\n務\n夢\n無\n牟\n矛\n霧\n鵡\n椋\n婿\n娘\n冥\n名\n命\n明\n盟\n迷\n銘\n鳴\n姪\n牝\n滅\n免\n棉\n綿\n緬\n面\n麺\n摸\n模\n茂\n妄\n孟\n毛\n猛\n盲\n網\n耗\n蒙\n儲\n木\n黙\n目\n杢\n勿\n餅\n尤\n戻\n籾\n貰\n問\n悶\n紋\n門\n匁\n也\n冶\n夜\n爺\n耶\n野\n弥\n矢\n厄\n役\n約\n薬\n訳\n躍\n靖\n柳\n薮\n鑓\n愉\n愈\n油\n癒\n諭\n輸\n唯\n佑\n優\n勇\n友\n宥\n幽\n悠\n憂\n揖\n有\n柚\n湧\n涌\n猶\n猷\n由\n祐\n裕\n誘\n遊\n邑\n郵\n雄\n融\n夕\n予\n余\n与\n誉\n輿\n預\n傭\n幼\n妖\n容\n庸\n揚\n揺\n擁\n曜\n楊\n様\n洋\n溶\n熔\n用\n窯\n羊\n耀\n葉\n蓉\n要\n謡\n踊\n遥\n陽\n養\n慾\n抑\n欲\n沃\n浴\n翌\n翼\n淀\n羅\n螺\n裸\n来\n莱\n頼\n雷\n洛\n絡\n落\n酪\n乱\n卵\n嵐\n欄\n濫\n藍\n蘭\n覧\n利\n吏\n履\n李\n梨\n理\n璃\n痢\n裏\n裡\n里\n離\n陸\n律\n率\n立\n葎\n掠\n略\n劉\n流\n溜\n琉\n留\n硫\n粒\n隆\n竜\n龍\n侶\n慮\n旅\n虜\n了\n亮\n僚\n両\n凌\n寮\n料\n梁\n涼\n猟\n療\n瞭\n稜\n糧\n良\n諒\n遼\n量\n陵\n領\n力\n緑\n倫\n厘\n林\n淋\n燐\n琳\n臨\n輪\n隣\n鱗\n麟\n瑠\n塁\n涙\n累\n類\n令\n伶\n例\n冷\n励\n嶺\n怜\n玲\n礼\n苓\n鈴\n隷\n零\n霊\n麗\n齢\n暦\n歴\n列\n劣\n烈\n裂\n廉\n恋\n憐\n漣\n煉\n簾\n練\n聯\n蓮\n連\n錬\n呂\n魯\n櫓\n炉\n賂\n路\n露\n労\n婁\n廊\n弄\n朗\n楼\n榔\n浪\n漏\n牢\n狼\n篭\n老\n聾\n蝋\n郎\n六\n麓\n禄\n肋\n録\n論\n倭\n和\n話\n歪\n賄\n脇\n惑\n枠\n鷲\n亙\n亘\n鰐\n詫\n藁\n蕨\n椀\n湾\n碗\n腕\n弌\n丐\n丕\n个\n丱\n丶\n丼\n丿\n乂\n乖\n乘\n亂\n亅\n豫\n亊\n舒\n弍\n于\n亞\n亟\n亠\n亢\n亰\n亳\n亶\n从\n仍\n仄\n仆\n仂\n仗\n仞\n仭\n仟\n价\n伉\n佚\n估\n佛\n佝\n佗\n佇\n佶\n侈\n侏\n侘\n佻\n佩\n佰\n侑\n佯\n來\n侖\n儘\n俔\n俟\n俎\n俘\n俛\n俑\n俚\n俐\n俤\n俥\n倚\n倨\n倔\n倪\n倥\n倅\n伜\n俶\n倡\n倩\n倬\n俾\n俯\n們\n倆\n偃\n假\n會\n偕\n偐\n偈\n做\n偖\n偬\n偸\n傀\n傚\n傅\n傴\n傲\n僉\n僊\n傳\n僂\n僖\n僞\n僥\n僭\n僣\n僮\n價\n僵\n儉\n儁\n儂\n儖\n儕\n儔\n儚\n儡\n儺\n儷\n儼\n儻\n儿\n兀\n兒\n兌\n兔\n兢\n竸\n兩\n兪\n兮\n冀\n冂\n囘\n册\n冉\n冏\n冑\n冓\n冕\n冖\n冤\n冦\n冢\n冩\n冪\n冫\n决\n冱\n冲\n冰\n况\n冽\n凅\n凉\n凛\n几\n處\n凩\n凭\n凰\n凵\n凾\n刄\n刋\n刔\n刎\n刧\n刪\n刮\n刳\n刹\n剏\n剄\n剋\n剌\n剞\n剔\n剪\n剴\n剩\n剳\n剿\n剽\n劍\n劔\n劒\n剱\n劈\n劑\n辨\n辧\n劬\n劭\n劼\n劵\n勁\n勍\n勗\n勞\n勣\n勦\n飭\n勠\n勳\n勵\n勸\n勹\n匆\n匈\n甸\n匍\n匐\n匏\n匕\n匚\n匣\n匯\n匱\n匳\n匸\n區\n卆\n卅\n丗\n卉\n卍\n凖\n卞\n卩\n卮\n夘\n卻\n卷\n厂\n厖\n厠\n厦\n厥\n厮\n厰\n厶\n參\n簒\n雙\n叟\n曼\n燮\n叮\n叨\n叭\n叺\n吁\n吽\n呀\n听\n吭\n吼\n吮\n吶\n吩\n吝\n呎\n咏\n呵\n咎\n呟\n呱\n呷\n呰\n咒\n呻\n咀\n呶\n咄\n咐\n咆\n哇\n咢\n咸\n咥\n咬\n哄\n哈\n咨\n咫\n哂\n咤\n咾\n咼\n哘\n哥\n哦\n唏\n唔\n哽\n哮\n哭\n哺\n哢\n唹\n啀\n啣\n啌\n售\n啜\n啅\n啖\n啗\n唸\n唳\n啝\n喙\n喀\n咯\n喊\n喟\n啻\n啾\n喘\n喞\n單\n啼\n喃\n喩\n喇\n喨\n嗚\n嗅\n嗟\n嗄\n嗜\n嗤\n嗔\n嘔\n嗷\n嘖\n嗾\n嗽\n嘛\n嗹\n噎\n噐\n營\n嘴\n嘶\n嘲\n嘸\n噫\n噤\n嘯\n噬\n噪\n嚆\n嚀\n嚊\n嚠\n嚔\n嚏\n嚥\n嚮\n嚶\n嚴\n囂\n嚼\n囁\n囃\n囀\n囈\n囎\n囑\n囓\n囗\n囮\n囹\n圀\n囿\n圄\n圉\n圈\n國\n圍\n圓\n團\n圖\n嗇\n圜\n圦\n圷\n圸\n坎\n圻\n址\n坏\n坩\n埀\n垈\n坡\n坿\n垉\n垓\n垠\n垳\n垤\n垪\n垰\n埃\n埆\n埔\n埒\n埓\n堊\n埖\n埣\n堋\n堙\n堝\n塲\n堡\n塢\n塋\n塰\n毀\n塒\n堽\n塹\n墅\n墹\n墟\n墫\n墺\n壞\n墻\n墸\n墮\n壅\n壓\n壑\n壗\n壙\n壘\n壥\n壜\n壤\n壟\n壯\n壺\n壹\n壻\n壼\n壽\n夂\n夊\n夐\n夛\n梦\n夥\n夬\n夭\n夲\n夸\n夾\n竒\n奕\n奐\n奎\n奚\n奘\n奢\n奠\n奧\n奬\n奩\n奸\n妁\n妝\n佞\n侫\n妣\n妲\n姆\n姨\n姜\n妍\n姙\n姚\n娥\n娟\n娑\n娜\n娉\n娚\n婀\n婬\n婉\n娵\n娶\n婢\n婪\n媚\n媼\n媾\n嫋\n嫂\n媽\n嫣\n嫗\n嫦\n嫩\n嫖\n嫺\n嫻\n嬌\n嬋\n嬖\n嬲\n嫐\n嬪\n嬶\n嬾\n孃\n孅\n孀\n孑\n孕\n孚\n孛\n孥\n孩\n孰\n孳\n孵\n學\n斈\n孺\n宀\n它\n宦\n宸\n寃\n寇\n寉\n寔\n寐\n寤\n實\n寢\n寞\n寥\n寫\n寰\n寶\n寳\n尅\n將\n專\n對\n尓\n尠\n尢\n尨\n尸\n尹\n屁\n屆\n屎\n屓\n屐\n屏\n孱\n屬\n屮\n乢\n屶\n屹\n岌\n岑\n岔\n妛\n岫\n岻\n岶\n岼\n岷\n峅\n岾\n峇\n峙\n峩\n峽\n峺\n峭\n嶌\n峪\n崋\n崕\n崗\n嵜\n崟\n崛\n崑\n崔\n崢\n崚\n崙\n崘\n嵌\n嵒\n嵎\n嵋\n嵬\n嵳\n嵶\n嶇\n嶄\n嶂\n嶢\n嶝\n嶬\n嶮\n嶽\n嶐\n嶷\n嶼\n巉\n巍\n巓\n巒\n巖\n巛\n巫\n已\n巵\n帋\n帚\n帙\n帑\n帛\n帶\n帷\n幄\n幃\n幀\n幎\n幗\n幔\n幟\n幢\n幤\n幇\n幵\n并\n幺\n麼\n广\n庠\n廁\n廂\n廈\n廐\n廏\n廖\n廣\n廝\n廚\n廛\n廢\n廡\n廨\n廩\n廬\n廱\n廳\n廰\n廴\n廸\n廾\n弃\n弉\n彝\n彜\n弋\n弑\n弖\n弩\n弭\n弸\n彁\n彈\n彌\n彎\n弯\n彑\n彖\n彗\n彙\n彡\n彭\n彳\n彷\n徃\n徂\n彿\n徊\n很\n徑\n徇\n從\n徙\n徘\n徠\n徨\n徭\n徼\n忖\n忻\n忤\n忸\n忱\n忝\n悳\n忿\n怡\n恠\n怙\n怐\n怩\n怎\n怱\n怛\n怕\n怫\n怦\n怏\n怺\n恚\n恁\n恪\n恷\n恟\n恊\n恆\n恍\n恣\n恃\n恤\n恂\n恬\n恫\n恙\n悁\n悍\n惧\n悃\n悚\n悄\n悛\n悖\n悗\n悒\n悧\n悋\n惡\n悸\n惠\n惓\n悴\n忰\n悽\n惆\n悵\n惘\n慍\n愕\n愆\n惶\n惷\n愀\n惴\n惺\n愃\n愡\n惻\n惱\n愍\n愎\n慇\n愾\n愨\n愧\n慊\n愿\n愼\n愬\n愴\n愽\n慂\n慄\n慳\n慷\n慘\n慙\n慚\n慫\n慴\n慯\n慥\n慱\n慟\n慝\n慓\n慵\n憙\n憖\n憇\n憬\n憔\n憚\n憊\n憑\n憫\n憮\n懌\n懊\n應\n懷\n懈\n懃\n懆\n憺\n懋\n罹\n懍\n懦\n懣\n懶\n懺\n懴\n懿\n懽\n懼\n懾\n戀\n戈\n戉\n戍\n戌\n戔\n戛\n戞\n戡\n截\n戮\n戰\n戲\n戳\n扁\n扎\n扞\n扣\n扛\n扠\n扨\n扼\n抂\n抉\n找\n抒\n抓\n抖\n拔\n抃\n抔\n拗\n拑\n抻\n拏\n拿\n拆\n擔\n拈\n拜\n拌\n拊\n拂\n拇\n抛\n拉\n挌\n拮\n拱\n挧\n挂\n挈\n拯\n拵\n捐\n挾\n捍\n搜\n捏\n掖\n掎\n掀\n掫\n捶\n掣\n掏\n掉\n掟\n掵\n捫\n捩\n掾\n揩\n揀\n揆\n揣\n揉\n插\n揶\n揄\n搖\n搴\n搆\n搓\n搦\n搶\n攝\n搗\n搨\n搏\n摧\n摯\n摶\n摎\n攪\n撕\n撓\n撥\n撩\n撈\n撼\n據\n擒\n擅\n擇\n撻\n擘\n擂\n擱\n擧\n舉\n擠\n擡\n抬\n擣\n擯\n攬\n擶\n擴\n擲\n擺\n攀\n擽\n攘\n攜\n攅\n攤\n攣\n攫\n攴\n攵\n攷\n收\n攸\n畋\n效\n敖\n敕\n敍\n敘\n敞\n敝\n敲\n數\n斂\n斃\n變\n斛\n斟\n斫\n斷\n旃\n旆\n旁\n旄\n旌\n旒\n旛\n旙\n无\n旡\n旱\n杲\n昊\n昃\n旻\n杳\n昵\n昶\n昴\n昜\n晏\n晄\n晉\n晁\n晞\n晝\n晤\n晧\n晨\n晟\n晢\n晰\n暃\n暈\n暎\n暉\n暄\n暘\n暝\n曁\n暹\n曉\n暾\n暼\n曄\n暸\n曖\n曚\n曠\n昿\n曦\n曩\n曰\n曵\n曷\n朏\n朖\n朞\n朦\n朧\n霸\n朮\n朿\n朶\n杁\n朸\n朷\n杆\n杞\n杠\n杙\n杣\n杤\n枉\n杰\n枩\n杼\n杪\n枌\n枋\n枦\n枡\n枅\n枷\n柯\n枴\n柬\n枳\n柩\n枸\n柤\n柞\n柝\n柢\n柮\n枹\n柎\n柆\n柧\n檜\n栞\n框\n栩\n桀\n桍\n栲\n桎\n梳\n栫\n桙\n档\n桷\n桿\n梟\n梏\n梭\n梔\n條\n梛\n梃\n檮\n梹\n桴\n梵\n梠\n梺\n椏\n梍\n桾\n椁\n棊\n椈\n棘\n椢\n椦\n棡\n椌\n棍\n棔\n棧\n棕\n椶\n椒\n椄\n棗\n棣\n椥\n棹\n棠\n棯\n椨\n椪\n椚\n椣\n椡\n棆\n楹\n楷\n楜\n楸\n楫\n楔\n楾\n楮\n椹\n楴\n椽\n楙\n椰\n楡\n楞\n楝\n榁\n楪\n榲\n榮\n槐\n榿\n槁\n槓\n榾\n槎\n寨\n槊\n槝\n榻\n槃\n榧\n樮\n榑\n榠\n榜\n榕\n榴\n槞\n槨\n樂\n樛\n槿\n權\n槹\n槲\n槧\n樅\n榱\n樞\n槭\n樔\n槫\n樊\n樒\n櫁\n樣\n樓\n橄\n樌\n橲\n樶\n橸\n橇\n橢\n橙\n橦\n橈\n樸\n樢\n檐\n檍\n檠\n檄\n檢\n檣\n檗\n蘗\n檻\n櫃\n櫂\n檸\n檳\n檬\n櫞\n櫑\n櫟\n檪\n櫚\n櫪\n櫻\n欅\n蘖\n櫺\n欒\n欖\n鬱\n欟\n欸\n欷\n盜\n欹\n飮\n歇\n歃\n歉\n歐\n歙\n歔\n歛\n歟\n歡\n歸\n歹\n歿\n殀\n殄\n殃\n殍\n殘\n殕\n殞\n殤\n殪\n殫\n殯\n殲\n殱\n殳\n殷\n殼\n毆\n毋\n毓\n毟\n毬\n毫\n毳\n毯\n麾\n氈\n氓\n气\n氛\n氤\n氣\n汞\n汕\n汢\n汪\n沂\n沍\n沚\n沁\n沛\n汾\n汨\n汳\n沒\n沐\n泄\n泱\n泓\n沽\n泗\n泅\n泝\n沮\n沱\n沾\n沺\n泛\n泯\n泙\n泪\n洟\n衍\n洶\n洫\n洽\n洸\n洙\n洵\n洳\n洒\n洌\n浣\n涓\n浤\n浚\n浹\n浙\n涎\n涕\n濤\n涅\n淹\n渕\n渊\n涵\n淇\n淦\n涸\n淆\n淬\n淞\n淌\n淨\n淒\n淅\n淺\n淙\n淤\n淕\n淪\n淮\n渭\n湮\n渮\n渙\n湲\n湟\n渾\n渣\n湫\n渫\n湶\n湍\n渟\n湃\n渺\n湎\n渤\n滿\n渝\n游\n溂\n溪\n溘\n滉\n溷\n滓\n溽\n溯\n滄\n溲\n滔\n滕\n溏\n溥\n滂\n溟\n潁\n漑\n灌\n滬\n滸\n滾\n漿\n滲\n漱\n滯\n漲\n滌\n漾\n漓\n滷\n澆\n潺\n潸\n澁\n澀\n潯\n潛\n濳\n潭\n澂\n潼\n潘\n澎\n澑\n濂\n潦\n澳\n澣\n澡\n澤\n澹\n濆\n澪\n濟\n濕\n濬\n濔\n濘\n濱\n濮\n濛\n瀉\n瀋\n濺\n瀑\n瀁\n瀏\n濾\n瀛\n瀚\n潴\n瀝\n瀘\n瀟\n瀰\n瀾\n瀲\n灑\n灣\n炙\n炒\n炯\n烱\n炬\n炸\n炳\n炮\n烟\n烋\n烝\n烙\n焉\n烽\n焜\n焙\n煥\n煕\n熈\n煦\n煢\n煌\n煖\n煬\n熏\n燻\n熄\n熕\n熨\n熬\n燗\n熹\n熾\n燒\n燉\n燔\n燎\n燠\n燬\n燧\n燵\n燼\n燹\n燿\n爍\n爐\n爛\n爨\n爭\n爬\n爰\n爲\n爻\n爼\n爿\n牀\n牆\n牋\n牘\n牴\n牾\n犂\n犁\n犇\n犒\n犖\n犢\n犧\n犹\n犲\n狃\n狆\n狄\n狎\n狒\n狢\n狠\n狡\n狹\n狷\n倏\n猗\n猊\n猜\n猖\n猝\n猴\n猯\n猩\n猥\n猾\n獎\n獏\n默\n獗\n獪\n獨\n獰\n獸\n獵\n獻\n獺\n珈\n玳\n珎\n玻\n珀\n珥\n珮\n珞\n璢\n琅\n瑯\n琥\n珸\n琲\n琺\n瑕\n琿\n瑟\n瑙\n瑁\n瑜\n瑩\n瑰\n瑣\n瑪\n瑶\n瑾\n璋\n璞\n璧\n瓊\n瓏\n瓔\n珱\n瓠\n瓣\n瓧\n瓩\n瓮\n瓲\n瓰\n瓱\n瓸\n瓷\n甄\n甃\n甅\n甌\n甎\n甍\n甕\n甓\n甞\n甦\n甬\n甼\n畄\n畍\n畊\n畉\n畛\n畆\n畚\n畩\n畤\n畧\n畫\n畭\n畸\n當\n疆\n疇\n畴\n疊\n疉\n疂\n疔\n疚\n疝\n疥\n疣\n痂\n疳\n痃\n疵\n疽\n疸\n疼\n疱\n痍\n痊\n痒\n痙\n痣\n痞\n痾\n痿\n痼\n瘁\n痰\n痺\n痲\n痳\n瘋\n瘍\n瘉\n瘟\n瘧\n瘠\n瘡\n瘢\n瘤\n瘴\n瘰\n瘻\n癇\n癈\n癆\n癜\n癘\n癡\n癢\n癨\n癩\n癪\n癧\n癬\n癰\n癲\n癶\n癸\n發\n皀\n皃\n皈\n皋\n皎\n皖\n皓\n皙\n皚\n皰\n皴\n皸\n皹\n皺\n盂\n盍\n盖\n盒\n盞\n盡\n盥\n盧\n盪\n蘯\n盻\n眈\n眇\n眄\n眩\n眤\n眞\n眥\n眦\n眛\n眷\n眸\n睇\n睚\n睨\n睫\n睛\n睥\n睿\n睾\n睹\n瞎\n瞋\n瞑\n瞠\n瞞\n瞰\n瞶\n瞹\n瞿\n瞼\n瞽\n瞻\n矇\n矍\n矗\n矚\n矜\n矣\n矮\n矼\n砌\n砒\n礦\n砠\n礪\n硅\n碎\n硴\n碆\n硼\n碚\n碌\n碣\n碵\n碪\n碯\n磑\n磆\n磋\n磔\n碾\n碼\n磅\n磊\n磬\n磧\n磚\n磽\n磴\n礇\n礒\n礑\n礙\n礬\n礫\n祀\n祠\n祗\n祟\n祚\n祕\n祓\n祺\n祿\n禊\n禝\n禧\n齋\n禪\n禮\n禳\n禹\n禺\n秉\n秕\n秧\n秬\n秡\n秣\n稈\n稍\n稘\n稙\n稠\n稟\n禀\n稱\n稻\n稾\n稷\n穃\n穗\n穉\n穡\n穢\n穩\n龝\n穰\n穹\n穽\n窈\n窗\n窕\n窘\n窖\n窩\n竈\n窰\n窶\n竅\n竄\n窿\n邃\n竇\n竊\n竍\n竏\n竕\n竓\n站\n竚\n竝\n竡\n竢\n竦\n竭\n竰\n笂\n笏\n笊\n笆\n笳\n笘\n笙\n笞\n笵\n笨\n笶\n筐\n筺\n笄\n筍\n笋\n筌\n筅\n筵\n筥\n筴\n筧\n筰\n筱\n筬\n筮\n箝\n箘\n箟\n箍\n箜\n箚\n箋\n箒\n箏\n筝\n箙\n篋\n篁\n篌\n篏\n箴\n篆\n篝\n篩\n簑\n簔\n篦\n篥\n籠\n簀\n簇\n簓\n篳\n篷\n簗\n簍\n篶\n簣\n簧\n簪\n簟\n簷\n簫\n簽\n籌\n籃\n籔\n籏\n籀\n籐\n籘\n籟\n籤\n籖\n籥\n籬\n籵\n粃\n粐\n粤\n粭\n粢\n粫\n粡\n粨\n粳\n粲\n粱\n粮\n粹\n粽\n糀\n糅\n糂\n糘\n糒\n糜\n糢\n鬻\n糯\n糲\n糴\n糶\n糺\n紆\n紂\n紜\n紕\n紊\n絅\n絋\n紮\n紲\n紿\n紵\n絆\n絳\n絖\n絎\n絲\n絨\n絮\n絏\n絣\n經\n綉\n絛\n綏\n絽\n綛\n綺\n綮\n綣\n綵\n緇\n綽\n綫\n總\n綢\n綯\n緜\n綸\n綟\n綰\n緘\n緝\n緤\n緞\n緻\n緲\n緡\n縅\n縊\n縣\n縡\n縒\n縱\n縟\n縉\n縋\n縢\n繆\n繦\n縻\n縵\n縹\n繃\n縷\n縲\n縺\n繧\n繝\n繖\n繞\n繙\n繚\n繹\n繪\n繩\n繼\n繻\n纃\n緕\n繽\n辮\n繿\n纈\n纉\n續\n纒\n纐\n纓\n纔\n纖\n纎\n纛\n纜\n缸\n缺\n罅\n罌\n罍\n罎\n罐\n网\n罕\n罔\n罘\n罟\n罠\n罨\n罩\n罧\n罸\n羂\n羆\n羃\n羈\n羇\n羌\n羔\n羞\n羝\n羚\n羣\n羯\n羲\n羹\n羮\n羶\n羸\n譱\n翅\n翆\n翊\n翕\n翔\n翡\n翦\n翩\n翳\n翹\n飜\n耆\n耄\n耋\n耒\n耘\n耙\n耜\n耡\n耨\n耿\n耻\n聊\n聆\n聒\n聘\n聚\n聟\n聢\n聨\n聳\n聲\n聰\n聶\n聹\n聽\n聿\n肄\n肆\n肅\n肛\n肓\n肚\n肭\n冐\n肬\n胛\n胥\n胙\n胝\n胄\n胚\n胖\n脉\n胯\n胱\n脛\n脩\n脣\n脯\n腋\n隋\n腆\n脾\n腓\n腑\n胼\n腱\n腮\n腥\n腦\n腴\n膃\n膈\n膊\n膀\n膂\n膠\n膕\n膤\n膣\n腟\n膓\n膩\n膰\n膵\n膾\n膸\n膽\n臀\n臂\n膺\n臉\n臍\n臑\n臙\n臘\n臈\n臚\n臟\n臠\n臧\n臺\n臻\n臾\n舁\n舂\n舅\n與\n舊\n舍\n舐\n舖\n舩\n舫\n舸\n舳\n艀\n艙\n艘\n艝\n艚\n艟\n艤\n艢\n艨\n艪\n艫\n舮\n艱\n艷\n艸\n艾\n芍\n芒\n芫\n芟\n芻\n芬\n苡\n苣\n苟\n苒\n苴\n苳\n苺\n莓\n范\n苻\n苹\n苞\n茆\n苜\n茉\n苙\n茵\n茴\n茖\n茲\n茱\n荀\n茹\n荐\n荅\n茯\n茫\n茗\n茘\n莅\n莚\n莪\n莟\n莢\n莖\n茣\n莎\n莇\n莊\n荼\n莵\n荳\n荵\n莠\n莉\n莨\n菴\n萓\n菫\n菎\n菽\n萃\n菘\n萋\n菁\n菷\n萇\n菠\n菲\n萍\n萢\n萠\n莽\n萸\n蔆\n菻\n葭\n萪\n萼\n蕚\n蒄\n葷\n葫\n蒭\n葮\n蒂\n葩\n葆\n萬\n葯\n葹\n萵\n蓊\n葢\n蒹\n蒿\n蒟\n蓙\n蓍\n蒻\n蓚\n蓐\n蓁\n蓆\n蓖\n蒡\n蔡\n蓿\n蓴\n蔗\n蔘\n蔬\n蔟\n蔕\n蔔\n蓼\n蕀\n蕣\n蕘\n蕈\n蕁\n蘂\n蕋\n蕕\n薀\n薤\n薈\n薑\n薊\n薨\n蕭\n薔\n薛\n藪\n薇\n薜\n蕷\n蕾\n薐\n藉\n薺\n藏\n薹\n藐\n藕\n藝\n藥\n藜\n藹\n蘊\n蘓\n蘋\n藾\n藺\n蘆\n蘢\n蘚\n蘰\n蘿\n虍\n乕\n虔\n號\n虧\n虱\n蚓\n蚣\n蚩\n蚪\n蚋\n蚌\n蚶\n蚯\n蛄\n蛆\n蚰\n蛉\n蠣\n蚫\n蛔\n蛞\n蛩\n蛬\n蛟\n蛛\n蛯\n蜒\n蜆\n蜈\n蜀\n蜃\n蛻\n蜑\n蜉\n蜍\n蛹\n蜊\n蜴\n蜿\n蜷\n蜻\n蜥\n蜩\n蜚\n蝠\n蝟\n蝸\n蝌\n蝎\n蝴\n蝗\n蝨\n蝮\n蝙\n蝓\n蝣\n蝪\n蠅\n螢\n螟\n螂\n螯\n蟋\n螽\n蟀\n蟐\n雖\n螫\n蟄\n螳\n蟇\n蟆\n螻\n蟯\n蟲\n蟠\n蠏\n蠍\n蟾\n蟶\n蟷\n蠎\n蟒\n蠑\n蠖\n蠕\n蠢\n蠡\n蠱\n蠶\n蠹\n蠧\n蠻\n衄\n衂\n衒\n衙\n衞\n衢\n衫\n袁\n衾\n袞\n衵\n衽\n袵\n衲\n袂\n袗\n袒\n袮\n袙\n袢\n袍\n袤\n袰\n袿\n袱\n裃\n裄\n裔\n裘\n裙\n裝\n裹\n褂\n裼\n裴\n裨\n裲\n褄\n褌\n褊\n褓\n襃\n褞\n褥\n褪\n褫\n襁\n襄\n褻\n褶\n褸\n襌\n褝\n襠\n襞\n襦\n襤\n襭\n襪\n襯\n襴\n襷\n襾\n覃\n覈\n覊\n覓\n覘\n覡\n覩\n覦\n覬\n覯\n覲\n覺\n覽\n覿\n觀\n觚\n觜\n觝\n觧\n觴\n觸\n訃\n訖\n訐\n訌\n訛\n訝\n訥\n訶\n詁\n詛\n詒\n詆\n詈\n詼\n詭\n詬\n詢\n誅\n誂\n誄\n誨\n誡\n誑\n誥\n誦\n誚\n誣\n諄\n諍\n諂\n諚\n諫\n諳\n諧\n諤\n諱\n謔\n諠\n諢\n諷\n諞\n諛\n謌\n謇\n謚\n諡\n謖\n謐\n謗\n謠\n謳\n鞫\n謦\n謫\n謾\n謨\n譁\n譌\n譏\n譎\n證\n譖\n譛\n譚\n譫\n譟\n譬\n譯\n譴\n譽\n讀\n讌\n讎\n讒\n讓\n讖\n讙\n讚\n谺\n豁\n谿\n豈\n豌\n豎\n豐\n豕\n豢\n豬\n豸\n豺\n貂\n貉\n貅\n貊\n貍\n貎\n貔\n豼\n貘\n戝\n貭\n貪\n貽\n貲\n貳\n貮\n貶\n賈\n賁\n賤\n賣\n賚\n賽\n賺\n賻\n贄\n贅\n贊\n贇\n贏\n贍\n贐\n齎\n贓\n賍\n贔\n贖\n赧\n赭\n赱\n赳\n趁\n趙\n跂\n趾\n趺\n跏\n跚\n跖\n跌\n跛\n跋\n跪\n跫\n跟\n跣\n跼\n踈\n踉\n跿\n踝\n踞\n踐\n踟\n蹂\n踵\n踰\n踴\n蹊\n蹇\n蹉\n蹌\n蹐\n蹈\n蹙\n蹤\n蹠\n踪\n蹣\n蹕\n蹶\n蹲\n蹼\n躁\n躇\n躅\n躄\n躋\n躊\n躓\n躑\n躔\n躙\n躪\n躡\n躬\n躰\n軆\n躱\n躾\n軅\n軈\n軋\n軛\n軣\n軼\n軻\n軫\n軾\n輊\n輅\n輕\n輒\n輙\n輓\n輜\n輟\n輛\n輌\n輦\n輳\n輻\n輹\n轅\n轂\n輾\n轌\n轉\n轆\n轎\n轗\n轜\n轢\n轣\n轤\n辜\n辟\n辣\n辭\n辯\n辷\n迚\n迥\n迢\n迪\n迯\n邇\n迴\n逅\n迹\n迺\n逑\n逕\n逡\n逍\n逞\n逖\n逋\n逧\n逶\n逵\n逹\n迸\n遏\n遐\n遑\n遒\n逎\n遉\n逾\n遖\n遘\n遞\n遨\n遯\n遶\n隨\n遲\n邂\n遽\n邁\n邀\n邊\n邉\n邏\n邨\n邯\n邱\n邵\n郢\n郤\n扈\n郛\n鄂\n鄒\n鄙\n鄲\n鄰\n酊\n酖\n酘\n酣\n酥\n酩\n酳\n酲\n醋\n醉\n醂\n醢\n醫\n醯\n醪\n醵\n醴\n醺\n釀\n釁\n釉\n釋\n釐\n釖\n釟\n釡\n釛\n釼\n釵\n釶\n鈞\n釿\n鈔\n鈬\n鈕\n鈑\n鉞\n鉗\n鉅\n鉉\n鉤\n鉈\n銕\n鈿\n鉋\n鉐\n銜\n銖\n銓\n銛\n鉚\n鋏\n銹\n銷\n鋩\n錏\n鋺\n鍄\n錮\n錙\n錢\n錚\n錣\n錺\n錵\n錻\n鍜\n鍠\n鍼\n鍮\n鍖\n鎰\n鎬\n鎭\n鎔\n鎹\n鏖\n鏗\n鏨\n鏥\n鏘\n鏃\n鏝\n鏐\n鏈\n鏤\n鐚\n鐔\n鐓\n鐃\n鐇\n鐐\n鐶\n鐫\n鐵\n鐡\n鐺\n鑁\n鑒\n鑄\n鑛\n鑠\n鑢\n鑞\n鑪\n鈩\n鑰\n鑵\n鑷\n鑽\n鑚\n鑼\n鑾\n钁\n鑿\n閂\n閇\n閊\n閔\n閖\n閘\n閙\n閠\n閨\n閧\n閭\n閼\n閻\n閹\n閾\n闊\n濶\n闃\n闍\n闌\n闕\n闔\n闖\n關\n闡\n闥\n闢\n阡\n阨\n阮\n阯\n陂\n陌\n陏\n陋\n陷\n陜\n陞\n陝\n陟\n陦\n陲\n陬\n隍\n隘\n隕\n隗\n險\n隧\n隱\n隲\n隰\n隴\n隶\n隸\n隹\n雎\n雋\n雉\n雍\n襍\n雜\n霍\n雕\n雹\n霄\n霆\n霈\n霓\n霎\n霑\n霏\n霖\n霙\n霤\n霪\n霰\n霹\n霽\n霾\n靄\n靆\n靈\n靂\n靉\n靜\n靠\n靤\n靦\n靨\n勒\n靫\n靱\n靹\n鞅\n靼\n鞁\n靺\n鞆\n鞋\n鞏\n鞐\n鞜\n鞨\n鞦\n鞣\n鞳\n鞴\n韃\n韆\n韈\n韋\n韜\n韭\n齏\n韲\n竟\n韶\n韵\n頏\n頌\n頸\n頤\n頡\n頷\n頽\n顆\n顏\n顋\n顫\n顯\n顰\n顱\n顴\n顳\n颪\n颯\n颱\n颶\n飄\n飃\n飆\n飩\n飫\n餃\n餉\n餒\n餔\n餘\n餡\n餝\n餞\n餤\n餠\n餬\n餮\n餽\n餾\n饂\n饉\n饅\n饐\n饋\n饑\n饒\n饌\n饕\n馗\n馘\n馥\n馭\n馮\n馼\n駟\n駛\n駝\n駘\n駑\n駭\n駮\n駱\n駲\n駻\n駸\n騁\n騏\n騅\n駢\n騙\n騫\n騷\n驅\n驂\n驀\n驃\n騾\n驕\n驍\n驛\n驗\n驟\n驢\n驥\n驤\n驩\n驫\n驪\n骭\n骰\n骼\n髀\n髏\n髑\n髓\n體\n髞\n髟\n髢\n髣\n髦\n髯\n髫\n髮\n髴\n髱\n髷\n髻\n鬆\n鬘\n鬚\n鬟\n鬢\n鬣\n鬥\n鬧\n鬨\n鬩\n鬪\n鬮\n鬯\n鬲\n魄\n魃\n魏\n魍\n魎\n魑\n魘\n魴\n鮓\n鮃\n鮑\n鮖\n鮗\n鮟\n鮠\n鮨\n鮴\n鯀\n鯊\n鮹\n鯆\n鯏\n鯑\n鯒\n鯣\n鯢\n鯤\n鯔\n鯡\n鰺\n鯲\n鯱\n鯰\n鰕\n鰔\n鰉\n鰓\n鰌\n鰆\n鰈\n鰒\n鰊\n鰄\n鰮\n鰛\n鰥\n鰤\n鰡\n鰰\n鱇\n鰲\n鱆\n鰾\n鱚\n鱠\n鱧\n鱶\n鱸\n鳧\n鳬\n鳰\n鴉\n鴈\n鳫\n鴃\n鴆\n鴪\n鴦\n鶯\n鴣\n鴟\n鵄\n鴕\n鴒\n鵁\n鴿\n鴾\n鵆\n鵈\n鵝\n鵞\n鵤\n鵑\n鵐\n鵙\n鵲\n鶉\n鶇\n鶫\n鵯\n鵺\n鶚\n鶤\n鶩\n鶲\n鷄\n鷁\n鶻\n鶸\n鶺\n鷆\n鷏\n鷂\n鷙\n鷓\n鷸\n鷦\n鷭\n鷯\n鷽\n鸚\n鸛\n鸞\n鹵\n鹹\n鹽\n麁\n麈\n麋\n麌\n麒\n麕\n麑\n麝\n麥\n麩\n麸\n麪\n麭\n靡\n黌\n黎\n黏\n黐\n黔\n黜\n點\n黝\n黠\n黥\n黨\n黯\n黴\n黶\n黷\n黹\n黻\n黼\n黽\n鼇\n鼈\n皷\n鼕\n鼡\n鼬\n鼾\n齊\n齒\n齔\n齣\n齟\n齠\n齡\n齦\n齧\n齬\n齪\n齷\n齲\n齶\n龕\n龜\n龠\n堯\n槇\n遙\n瑤\n凜\n熙\n纊\n褜\n鍈\n銈\n蓜\n俉\n炻\n昱\n棈\n鋹\n曻\n彅\n丨\n仡\n仼\n伀\n伃\n伹\n佖\n侒\n侊\n侚\n侔\n俍\n偀\n倢\n俿\n倞\n偆\n偰\n偂\n傔\n僴\n僘\n兊\n兤\n冝\n冾\n凬\n刕\n劜\n劦\n勀\n勛\n匀\n匇\n匤\n卲\n厓\n厲\n叝\n﨎\n咜\n咊\n咩\n哿\n喆\n坙\n坥\n垬\n埈\n埇\n﨏\n塚\n增\n墲\n夋\n奓\n奛\n奝\n奣\n妤\n妺\n孖\n寀\n甯\n寘\n寬\n尞\n岦\n岺\n峵\n崧\n嵓\n﨑\n嵂\n嵭\n嶸\n嶹\n巐\n弡\n弴\n彧\n德\n忞\n恝\n悅\n悊\n惞\n惕\n愠\n惲\n愑\n愷\n愰\n憘\n戓\n抦\n揵\n摠\n撝\n擎\n敎\n昀\n昕\n昻\n昉\n昮\n昞\n昤\n晥\n晗\n晙\n晴\n晳\n暙\n暠\n暲\n暿\n曺\n朎\n朗\n杦\n枻\n桒\n柀\n栁\n桄\n棏\n﨓\n楨\n﨔\n榘\n槢\n樰\n橫\n橆\n橳\n橾\n櫢\n櫤\n毖\n氿\n汜\n沆\n汯\n泚\n洄\n涇\n浯\n涖\n涬\n淏\n淸\n淲\n淼\n渹\n湜\n渧\n渼\n溿\n澈\n澵\n濵\n瀅\n瀇\n瀨\n炅\n炫\n焏\n焄\n煜\n煆\n煇\n凞\n燁\n燾\n犱\n犾\n猤\n猪\n獷\n玽\n珉\n珖\n珣\n珒\n琇\n珵\n琦\n琪\n琩\n琮\n瑢\n璉\n璟\n甁\n畯\n皂\n皜\n皞\n皛\n皦\n益\n睆\n劯\n砡\n硎\n硤\n硺\n礰\n礼\n神\n祥\n禔\n福\n禛\n竑\n竧\n靖\n竫\n箞\n精\n絈\n絜\n綷\n綠\n緖\n繒\n罇\n羡\n羽\n茁\n荢\n荿\n菇\n菶\n葈\n蒴\n蕓\n蕙\n蕫\n﨟\n薰\n蘒\n﨡\n蠇\n裵\n訒\n訷\n詹\n誧\n誾\n諟\n諸\n諶\n譓\n譿\n賰\n賴\n贒\n赶\n﨣\n軏\n﨤\n逸\n遧\n郞\n都\n鄕\n鄧\n釚\n釗\n釞\n釭\n釮\n釤\n釥\n鈆\n鈐\n鈊\n鈺\n鉀\n鈼\n鉎\n鉙\n鉑\n鈹\n鉧\n銧\n鉷\n鉸\n鋧\n鋗\n鋙\n鋐\n﨧\n鋕\n鋠\n鋓\n錥\n錡\n鋻\n﨨\n錞\n鋿\n錝\n錂\n鍰\n鍗\n鎤\n鏆\n鏞\n鏸\n鐱\n鑅\n鑈\n閒\n隆\n﨩\n隝\n隯\n霳\n霻\n靃\n靍\n靏\n靑\n靕\n顗\n顥\n飯\n飼\n餧\n館\n馞\n驎\n髙\n髜\n魵\n魲\n鮏\n鮱\n鮻\n鰀\n鵰\n鵫\n鶴\n鸙\n黑\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\n￢\n￤\n＇\n＂\n｡\n｢\n｣\n､\n･\nｦ\nｧ\nｨ\nｩ\nｪ\nｫ\nｬ\nｭ\nｮ\nｯ\nｰ\nｱ\nｲ\nｳ\nｴ\nｵ\nｶ\nｷ\nｸ\nｹ\nｺ\nｻ\nｼ\nｽ\nｾ\nｿ\nﾀ\nﾁ\nﾂ\nﾃ\nﾄ\nﾅ\nﾆ\nﾇ\nﾈ\nﾉ\nﾊ\nﾋ\nﾌ\nﾍ\nﾎ\nﾏ\nﾐ\nﾑ\nﾒ\nﾓ\nﾔ\nﾕ\nﾖ\nﾗ\nﾘ\nﾙ\nﾚ\nﾛ\nﾜ\nﾝ\nﾞ\nﾟ\n"
  },
  {
    "path": "helix-view/tests/encoding/iso_2022_jp_out_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n\u001b$B!!\u001b(B\n\u001b$B!\"\u001b(B\n\u001b$B!#\u001b(B\n\u001b$B!$\u001b(B\n\u001b$B!%\u001b(B\n\u001b$B!&\u001b(B\n\u001b$B!'\u001b(B\n\u001b$B!(\u001b(B\n\u001b$B!)\u001b(B\n\u001b$B!*\u001b(B\n\u001b$B!+\u001b(B\n\u001b$B!,\u001b(B\n\u001b$B!-\u001b(B\n\u001b$B!.\u001b(B\n\u001b$B!/\u001b(B\n\u001b$B!0\u001b(B\n\u001b$B!1\u001b(B\n\u001b$B!2\u001b(B\n\u001b$B!3\u001b(B\n\u001b$B!4\u001b(B\n\u001b$B!5\u001b(B\n\u001b$B!6\u001b(B\n\u001b$B!7\u001b(B\n\u001b$B!8\u001b(B\n\u001b$B!9\u001b(B\n\u001b$B!:\u001b(B\n\u001b$B!;\u001b(B\n\u001b$B!<\u001b(B\n\u001b$B!=\u001b(B\n\u001b$B!>\u001b(B\n\u001b$B!?\u001b(B\n\u001b$B!@\u001b(B\n\u001b$B!A\u001b(B\n\u001b$B!B\u001b(B\n\u001b$B!C\u001b(B\n\u001b$B!D\u001b(B\n\u001b$B!E\u001b(B\n\u001b$B!F\u001b(B\n\u001b$B!G\u001b(B\n\u001b$B!H\u001b(B\n\u001b$B!I\u001b(B\n\u001b$B!J\u001b(B\n\u001b$B!K\u001b(B\n\u001b$B!L\u001b(B\n\u001b$B!M\u001b(B\n\u001b$B!N\u001b(B\n\u001b$B!O\u001b(B\n\u001b$B!P\u001b(B\n\u001b$B!Q\u001b(B\n\u001b$B!R\u001b(B\n\u001b$B!S\u001b(B\n\u001b$B!T\u001b(B\n\u001b$B!U\u001b(B\n\u001b$B!V\u001b(B\n\u001b$B!W\u001b(B\n\u001b$B!X\u001b(B\n\u001b$B!Y\u001b(B\n\u001b$B!Z\u001b(B\n\u001b$B![\u001b(B\n\u001b$B!\\\u001b(B\n\u001b$B!]\u001b(B\n\u001b$B!^\u001b(B\n\u001b$B!_\u001b(B\n\u001b$B!`\u001b(B\n\u001b$B!a\u001b(B\n\u001b$B!b\u001b(B\n\u001b$B!c\u001b(B\n\u001b$B!d\u001b(B\n\u001b$B!e\u001b(B\n\u001b$B!f\u001b(B\n\u001b$B!g\u001b(B\n\u001b$B!h\u001b(B\n\u001b$B!i\u001b(B\n\u001b$B!j\u001b(B\n\u001b$B!k\u001b(B\n\u001b$B!l\u001b(B\n\u001b$B!m\u001b(B\n\u001b$B!n\u001b(B\n\u001b$B!o\u001b(B\n\u001b$B!p\u001b(B\n\u001b$B!q\u001b(B\n\u001b$B!r\u001b(B\n\u001b$B!s\u001b(B\n\u001b$B!t\u001b(B\n\u001b$B!u\u001b(B\n\u001b$B!v\u001b(B\n\u001b$B!w\u001b(B\n\u001b$B!x\u001b(B\n\u001b$B!y\u001b(B\n\u001b$B!z\u001b(B\n\u001b$B!{\u001b(B\n\u001b$B!|\u001b(B\n\u001b$B!}\u001b(B\n\u001b$B!~\u001b(B\n\u001b$B\"!\u001b(B\n\u001b$B\"\"\u001b(B\n\u001b$B\"#\u001b(B\n\u001b$B\"$\u001b(B\n\u001b$B\"%\u001b(B\n\u001b$B\"&\u001b(B\n\u001b$B\"'\u001b(B\n\u001b$B\"(\u001b(B\n\u001b$B\")\u001b(B\n\u001b$B\"*\u001b(B\n\u001b$B\"+\u001b(B\n\u001b$B\",\u001b(B\n\u001b$B\"-\u001b(B\n\u001b$B\".\u001b(B\n\u001b$B\":\u001b(B\n\u001b$B\";\u001b(B\n\u001b$B\"<\u001b(B\n\u001b$B\"=\u001b(B\n\u001b$B\">\u001b(B\n\u001b$B\"?\u001b(B\n\u001b$B\"@\u001b(B\n\u001b$B\"A\u001b(B\n\u001b$B\"J\u001b(B\n\u001b$B\"K\u001b(B\n\u001b$B\"L\u001b(B\n\u001b$B\"M\u001b(B\n\u001b$B\"N\u001b(B\n\u001b$B\"O\u001b(B\n\u001b$B\"P\u001b(B\n\u001b$B\"\\\u001b(B\n\u001b$B\"]\u001b(B\n\u001b$B\"^\u001b(B\n\u001b$B\"_\u001b(B\n\u001b$B\"`\u001b(B\n\u001b$B\"a\u001b(B\n\u001b$B\"b\u001b(B\n\u001b$B\"c\u001b(B\n\u001b$B\"d\u001b(B\n\u001b$B\"e\u001b(B\n\u001b$B\"f\u001b(B\n\u001b$B\"g\u001b(B\n\u001b$B\"h\u001b(B\n\u001b$B\"i\u001b(B\n\u001b$B\"j\u001b(B\n\u001b$B\"r\u001b(B\n\u001b$B\"s\u001b(B\n\u001b$B\"t\u001b(B\n\u001b$B\"u\u001b(B\n\u001b$B\"v\u001b(B\n\u001b$B\"w\u001b(B\n\u001b$B\"x\u001b(B\n\u001b$B\"y\u001b(B\n\u001b$B\"~\u001b(B\n\u001b$B#0\u001b(B\n\u001b$B#1\u001b(B\n\u001b$B#2\u001b(B\n\u001b$B#3\u001b(B\n\u001b$B#4\u001b(B\n\u001b$B#5\u001b(B\n\u001b$B#6\u001b(B\n\u001b$B#7\u001b(B\n\u001b$B#8\u001b(B\n\u001b$B#9\u001b(B\n\u001b$B#A\u001b(B\n\u001b$B#B\u001b(B\n\u001b$B#C\u001b(B\n\u001b$B#D\u001b(B\n\u001b$B#E\u001b(B\n\u001b$B#F\u001b(B\n\u001b$B#G\u001b(B\n\u001b$B#H\u001b(B\n\u001b$B#I\u001b(B\n\u001b$B#J\u001b(B\n\u001b$B#K\u001b(B\n\u001b$B#L\u001b(B\n\u001b$B#M\u001b(B\n\u001b$B#N\u001b(B\n\u001b$B#O\u001b(B\n\u001b$B#P\u001b(B\n\u001b$B#Q\u001b(B\n\u001b$B#R\u001b(B\n\u001b$B#S\u001b(B\n\u001b$B#T\u001b(B\n\u001b$B#U\u001b(B\n\u001b$B#V\u001b(B\n\u001b$B#W\u001b(B\n\u001b$B#X\u001b(B\n\u001b$B#Y\u001b(B\n\u001b$B#Z\u001b(B\n\u001b$B#a\u001b(B\n\u001b$B#b\u001b(B\n\u001b$B#c\u001b(B\n\u001b$B#d\u001b(B\n\u001b$B#e\u001b(B\n\u001b$B#f\u001b(B\n\u001b$B#g\u001b(B\n\u001b$B#h\u001b(B\n\u001b$B#i\u001b(B\n\u001b$B#j\u001b(B\n\u001b$B#k\u001b(B\n\u001b$B#l\u001b(B\n\u001b$B#m\u001b(B\n\u001b$B#n\u001b(B\n\u001b$B#o\u001b(B\n\u001b$B#p\u001b(B\n\u001b$B#q\u001b(B\n\u001b$B#r\u001b(B\n\u001b$B#s\u001b(B\n\u001b$B#t\u001b(B\n\u001b$B#u\u001b(B\n\u001b$B#v\u001b(B\n\u001b$B#w\u001b(B\n\u001b$B#x\u001b(B\n\u001b$B#y\u001b(B\n\u001b$B#z\u001b(B\n\u001b$B$!\u001b(B\n\u001b$B$\"\u001b(B\n\u001b$B$#\u001b(B\n\u001b$B$$\u001b(B\n\u001b$B$%\u001b(B\n\u001b$B$&\u001b(B\n\u001b$B$'\u001b(B\n\u001b$B$(\u001b(B\n\u001b$B$)\u001b(B\n\u001b$B$*\u001b(B\n\u001b$B$+\u001b(B\n\u001b$B$,\u001b(B\n\u001b$B$-\u001b(B\n\u001b$B$.\u001b(B\n\u001b$B$/\u001b(B\n\u001b$B$0\u001b(B\n\u001b$B$1\u001b(B\n\u001b$B$2\u001b(B\n\u001b$B$3\u001b(B\n\u001b$B$4\u001b(B\n\u001b$B$5\u001b(B\n\u001b$B$6\u001b(B\n\u001b$B$7\u001b(B\n\u001b$B$8\u001b(B\n\u001b$B$9\u001b(B\n\u001b$B$:\u001b(B\n\u001b$B$;\u001b(B\n\u001b$B$<\u001b(B\n\u001b$B$=\u001b(B\n\u001b$B$>\u001b(B\n\u001b$B$?\u001b(B\n\u001b$B$@\u001b(B\n\u001b$B$A\u001b(B\n\u001b$B$B\u001b(B\n\u001b$B$C\u001b(B\n\u001b$B$D\u001b(B\n\u001b$B$E\u001b(B\n\u001b$B$F\u001b(B\n\u001b$B$G\u001b(B\n\u001b$B$H\u001b(B\n\u001b$B$I\u001b(B\n\u001b$B$J\u001b(B\n\u001b$B$K\u001b(B\n\u001b$B$L\u001b(B\n\u001b$B$M\u001b(B\n\u001b$B$N\u001b(B\n\u001b$B$O\u001b(B\n\u001b$B$P\u001b(B\n\u001b$B$Q\u001b(B\n\u001b$B$R\u001b(B\n\u001b$B$S\u001b(B\n\u001b$B$T\u001b(B\n\u001b$B$U\u001b(B\n\u001b$B$V\u001b(B\n\u001b$B$W\u001b(B\n\u001b$B$X\u001b(B\n\u001b$B$Y\u001b(B\n\u001b$B$Z\u001b(B\n\u001b$B$[\u001b(B\n\u001b$B$\\\u001b(B\n\u001b$B$]\u001b(B\n\u001b$B$^\u001b(B\n\u001b$B$_\u001b(B\n\u001b$B$`\u001b(B\n\u001b$B$a\u001b(B\n\u001b$B$b\u001b(B\n\u001b$B$c\u001b(B\n\u001b$B$d\u001b(B\n\u001b$B$e\u001b(B\n\u001b$B$f\u001b(B\n\u001b$B$g\u001b(B\n\u001b$B$h\u001b(B\n\u001b$B$i\u001b(B\n\u001b$B$j\u001b(B\n\u001b$B$k\u001b(B\n\u001b$B$l\u001b(B\n\u001b$B$m\u001b(B\n\u001b$B$n\u001b(B\n\u001b$B$o\u001b(B\n\u001b$B$p\u001b(B\n\u001b$B$q\u001b(B\n\u001b$B$r\u001b(B\n\u001b$B$s\u001b(B\n\u001b$B%!\u001b(B\n\u001b$B%\"\u001b(B\n\u001b$B%#\u001b(B\n\u001b$B%$\u001b(B\n\u001b$B%%\u001b(B\n\u001b$B%&\u001b(B\n\u001b$B%'\u001b(B\n\u001b$B%(\u001b(B\n\u001b$B%)\u001b(B\n\u001b$B%*\u001b(B\n\u001b$B%+\u001b(B\n\u001b$B%,\u001b(B\n\u001b$B%-\u001b(B\n\u001b$B%.\u001b(B\n\u001b$B%/\u001b(B\n\u001b$B%0\u001b(B\n\u001b$B%1\u001b(B\n\u001b$B%2\u001b(B\n\u001b$B%3\u001b(B\n\u001b$B%4\u001b(B\n\u001b$B%5\u001b(B\n\u001b$B%6\u001b(B\n\u001b$B%7\u001b(B\n\u001b$B%8\u001b(B\n\u001b$B%9\u001b(B\n\u001b$B%:\u001b(B\n\u001b$B%;\u001b(B\n\u001b$B%<\u001b(B\n\u001b$B%=\u001b(B\n\u001b$B%>\u001b(B\n\u001b$B%?\u001b(B\n\u001b$B%@\u001b(B\n\u001b$B%A\u001b(B\n\u001b$B%B\u001b(B\n\u001b$B%C\u001b(B\n\u001b$B%D\u001b(B\n\u001b$B%E\u001b(B\n\u001b$B%F\u001b(B\n\u001b$B%G\u001b(B\n\u001b$B%H\u001b(B\n\u001b$B%I\u001b(B\n\u001b$B%J\u001b(B\n\u001b$B%K\u001b(B\n\u001b$B%L\u001b(B\n\u001b$B%M\u001b(B\n\u001b$B%N\u001b(B\n\u001b$B%O\u001b(B\n\u001b$B%P\u001b(B\n\u001b$B%Q\u001b(B\n\u001b$B%R\u001b(B\n\u001b$B%S\u001b(B\n\u001b$B%T\u001b(B\n\u001b$B%U\u001b(B\n\u001b$B%V\u001b(B\n\u001b$B%W\u001b(B\n\u001b$B%X\u001b(B\n\u001b$B%Y\u001b(B\n\u001b$B%Z\u001b(B\n\u001b$B%[\u001b(B\n\u001b$B%\\\u001b(B\n\u001b$B%]\u001b(B\n\u001b$B%^\u001b(B\n\u001b$B%_\u001b(B\n\u001b$B%`\u001b(B\n\u001b$B%a\u001b(B\n\u001b$B%b\u001b(B\n\u001b$B%c\u001b(B\n\u001b$B%d\u001b(B\n\u001b$B%e\u001b(B\n\u001b$B%f\u001b(B\n\u001b$B%g\u001b(B\n\u001b$B%h\u001b(B\n\u001b$B%i\u001b(B\n\u001b$B%j\u001b(B\n\u001b$B%k\u001b(B\n\u001b$B%l\u001b(B\n\u001b$B%m\u001b(B\n\u001b$B%n\u001b(B\n\u001b$B%o\u001b(B\n\u001b$B%p\u001b(B\n\u001b$B%q\u001b(B\n\u001b$B%r\u001b(B\n\u001b$B%s\u001b(B\n\u001b$B%t\u001b(B\n\u001b$B%u\u001b(B\n\u001b$B%v\u001b(B\n\u001b$B&!\u001b(B\n\u001b$B&\"\u001b(B\n\u001b$B&#\u001b(B\n\u001b$B&$\u001b(B\n\u001b$B&%\u001b(B\n\u001b$B&&\u001b(B\n\u001b$B&'\u001b(B\n\u001b$B&(\u001b(B\n\u001b$B&)\u001b(B\n\u001b$B&*\u001b(B\n\u001b$B&+\u001b(B\n\u001b$B&,\u001b(B\n\u001b$B&-\u001b(B\n\u001b$B&.\u001b(B\n\u001b$B&/\u001b(B\n\u001b$B&0\u001b(B\n\u001b$B&1\u001b(B\n\u001b$B&2\u001b(B\n\u001b$B&3\u001b(B\n\u001b$B&4\u001b(B\n\u001b$B&5\u001b(B\n\u001b$B&6\u001b(B\n\u001b$B&7\u001b(B\n\u001b$B&8\u001b(B\n\u001b$B&A\u001b(B\n\u001b$B&B\u001b(B\n\u001b$B&C\u001b(B\n\u001b$B&D\u001b(B\n\u001b$B&E\u001b(B\n\u001b$B&F\u001b(B\n\u001b$B&G\u001b(B\n\u001b$B&H\u001b(B\n\u001b$B&I\u001b(B\n\u001b$B&J\u001b(B\n\u001b$B&K\u001b(B\n\u001b$B&L\u001b(B\n\u001b$B&M\u001b(B\n\u001b$B&N\u001b(B\n\u001b$B&O\u001b(B\n\u001b$B&P\u001b(B\n\u001b$B&Q\u001b(B\n\u001b$B&R\u001b(B\n\u001b$B&S\u001b(B\n\u001b$B&T\u001b(B\n\u001b$B&U\u001b(B\n\u001b$B&V\u001b(B\n\u001b$B&W\u001b(B\n\u001b$B&X\u001b(B\n\u001b$B'!\u001b(B\n\u001b$B'\"\u001b(B\n\u001b$B'#\u001b(B\n\u001b$B'$\u001b(B\n\u001b$B'%\u001b(B\n\u001b$B'&\u001b(B\n\u001b$B''\u001b(B\n\u001b$B'(\u001b(B\n\u001b$B')\u001b(B\n\u001b$B'*\u001b(B\n\u001b$B'+\u001b(B\n\u001b$B',\u001b(B\n\u001b$B'-\u001b(B\n\u001b$B'.\u001b(B\n\u001b$B'/\u001b(B\n\u001b$B'0\u001b(B\n\u001b$B'1\u001b(B\n\u001b$B'2\u001b(B\n\u001b$B'3\u001b(B\n\u001b$B'4\u001b(B\n\u001b$B'5\u001b(B\n\u001b$B'6\u001b(B\n\u001b$B'7\u001b(B\n\u001b$B'8\u001b(B\n\u001b$B'9\u001b(B\n\u001b$B':\u001b(B\n\u001b$B';\u001b(B\n\u001b$B'<\u001b(B\n\u001b$B'=\u001b(B\n\u001b$B'>\u001b(B\n\u001b$B'?\u001b(B\n\u001b$B'@\u001b(B\n\u001b$B'A\u001b(B\n\u001b$B'Q\u001b(B\n\u001b$B'R\u001b(B\n\u001b$B'S\u001b(B\n\u001b$B'T\u001b(B\n\u001b$B'U\u001b(B\n\u001b$B'V\u001b(B\n\u001b$B'W\u001b(B\n\u001b$B'X\u001b(B\n\u001b$B'Y\u001b(B\n\u001b$B'Z\u001b(B\n\u001b$B'[\u001b(B\n\u001b$B'\\\u001b(B\n\u001b$B']\u001b(B\n\u001b$B'^\u001b(B\n\u001b$B'_\u001b(B\n\u001b$B'`\u001b(B\n\u001b$B'a\u001b(B\n\u001b$B'b\u001b(B\n\u001b$B'c\u001b(B\n\u001b$B'd\u001b(B\n\u001b$B'e\u001b(B\n\u001b$B'f\u001b(B\n\u001b$B'g\u001b(B\n\u001b$B'h\u001b(B\n\u001b$B'i\u001b(B\n\u001b$B'j\u001b(B\n\u001b$B'k\u001b(B\n\u001b$B'l\u001b(B\n\u001b$B'm\u001b(B\n\u001b$B'n\u001b(B\n\u001b$B'o\u001b(B\n\u001b$B'p\u001b(B\n\u001b$B'q\u001b(B\n\u001b$B(!\u001b(B\n\u001b$B(\"\u001b(B\n\u001b$B(#\u001b(B\n\u001b$B($\u001b(B\n\u001b$B(%\u001b(B\n\u001b$B(&\u001b(B\n\u001b$B('\u001b(B\n\u001b$B((\u001b(B\n\u001b$B()\u001b(B\n\u001b$B(*\u001b(B\n\u001b$B(+\u001b(B\n\u001b$B(,\u001b(B\n\u001b$B(-\u001b(B\n\u001b$B(.\u001b(B\n\u001b$B(/\u001b(B\n\u001b$B(0\u001b(B\n\u001b$B(1\u001b(B\n\u001b$B(2\u001b(B\n\u001b$B(3\u001b(B\n\u001b$B(4\u001b(B\n\u001b$B(5\u001b(B\n\u001b$B(6\u001b(B\n\u001b$B(7\u001b(B\n\u001b$B(8\u001b(B\n\u001b$B(9\u001b(B\n\u001b$B(:\u001b(B\n\u001b$B(;\u001b(B\n\u001b$B(<\u001b(B\n\u001b$B(=\u001b(B\n\u001b$B(>\u001b(B\n\u001b$B(?\u001b(B\n\u001b$B(@\u001b(B\n\u001b$B-!\u001b(B\n\u001b$B-\"\u001b(B\n\u001b$B-#\u001b(B\n\u001b$B-$\u001b(B\n\u001b$B-%\u001b(B\n\u001b$B-&\u001b(B\n\u001b$B-'\u001b(B\n\u001b$B-(\u001b(B\n\u001b$B-)\u001b(B\n\u001b$B-*\u001b(B\n\u001b$B-+\u001b(B\n\u001b$B-,\u001b(B\n\u001b$B--\u001b(B\n\u001b$B-.\u001b(B\n\u001b$B-/\u001b(B\n\u001b$B-0\u001b(B\n\u001b$B-1\u001b(B\n\u001b$B-2\u001b(B\n\u001b$B-3\u001b(B\n\u001b$B-4\u001b(B\n\u001b$B-5\u001b(B\n\u001b$B-6\u001b(B\n\u001b$B-7\u001b(B\n\u001b$B-8\u001b(B\n\u001b$B-9\u001b(B\n\u001b$B-:\u001b(B\n\u001b$B-;\u001b(B\n\u001b$B-<\u001b(B\n\u001b$B-=\u001b(B\n\u001b$B->\u001b(B\n\u001b$B-@\u001b(B\n\u001b$B-A\u001b(B\n\u001b$B-B\u001b(B\n\u001b$B-C\u001b(B\n\u001b$B-D\u001b(B\n\u001b$B-E\u001b(B\n\u001b$B-F\u001b(B\n\u001b$B-G\u001b(B\n\u001b$B-H\u001b(B\n\u001b$B-I\u001b(B\n\u001b$B-J\u001b(B\n\u001b$B-K\u001b(B\n\u001b$B-L\u001b(B\n\u001b$B-M\u001b(B\n\u001b$B-N\u001b(B\n\u001b$B-O\u001b(B\n\u001b$B-P\u001b(B\n\u001b$B-Q\u001b(B\n\u001b$B-R\u001b(B\n\u001b$B-S\u001b(B\n\u001b$B-T\u001b(B\n\u001b$B-U\u001b(B\n\u001b$B-V\u001b(B\n\u001b$B-_\u001b(B\n\u001b$B-`\u001b(B\n\u001b$B-a\u001b(B\n\u001b$B-b\u001b(B\n\u001b$B-c\u001b(B\n\u001b$B-d\u001b(B\n\u001b$B-e\u001b(B\n\u001b$B-f\u001b(B\n\u001b$B-g\u001b(B\n\u001b$B-h\u001b(B\n\u001b$B-i\u001b(B\n\u001b$B-j\u001b(B\n\u001b$B-k\u001b(B\n\u001b$B-l\u001b(B\n\u001b$B-m\u001b(B\n\u001b$B-n\u001b(B\n\u001b$B-o\u001b(B\n\u001b$B\"b\u001b(B\n\u001b$B\"a\u001b(B\n\u001b$B\"i\u001b(B\n\u001b$B-s\u001b(B\n\u001b$B-t\u001b(B\n\u001b$B\"e\u001b(B\n\u001b$B\"]\u001b(B\n\u001b$B\"\\\u001b(B\n\u001b$B-x\u001b(B\n\u001b$B-y\u001b(B\n\u001b$B\"h\u001b(B\n\u001b$B\"A\u001b(B\n\u001b$B\"@\u001b(B\n\u001b$B0!\u001b(B\n\u001b$B0\"\u001b(B\n\u001b$B0#\u001b(B\n\u001b$B0$\u001b(B\n\u001b$B0%\u001b(B\n\u001b$B0&\u001b(B\n\u001b$B0'\u001b(B\n\u001b$B0(\u001b(B\n\u001b$B0)\u001b(B\n\u001b$B0*\u001b(B\n\u001b$B0+\u001b(B\n\u001b$B0,\u001b(B\n\u001b$B0-\u001b(B\n\u001b$B0.\u001b(B\n\u001b$B0/\u001b(B\n\u001b$B00\u001b(B\n\u001b$B01\u001b(B\n\u001b$B02\u001b(B\n\u001b$B03\u001b(B\n\u001b$B04\u001b(B\n\u001b$B05\u001b(B\n\u001b$B06\u001b(B\n\u001b$B07\u001b(B\n\u001b$B08\u001b(B\n\u001b$B09\u001b(B\n\u001b$B0:\u001b(B\n\u001b$B0;\u001b(B\n\u001b$B0<\u001b(B\n\u001b$B0=\u001b(B\n\u001b$B0>\u001b(B\n\u001b$B0?\u001b(B\n\u001b$B0@\u001b(B\n\u001b$B0A\u001b(B\n\u001b$B0B\u001b(B\n\u001b$B0C\u001b(B\n\u001b$B0D\u001b(B\n\u001b$B0E\u001b(B\n\u001b$B0F\u001b(B\n\u001b$B0G\u001b(B\n\u001b$B0H\u001b(B\n\u001b$B0I\u001b(B\n\u001b$B0J\u001b(B\n\u001b$B0K\u001b(B\n\u001b$B0L\u001b(B\n\u001b$B0M\u001b(B\n\u001b$B0N\u001b(B\n\u001b$B0O\u001b(B\n\u001b$B0P\u001b(B\n\u001b$B0Q\u001b(B\n\u001b$B0R\u001b(B\n\u001b$B0S\u001b(B\n\u001b$B0T\u001b(B\n\u001b$B0U\u001b(B\n\u001b$B0V\u001b(B\n\u001b$B0W\u001b(B\n\u001b$B0X\u001b(B\n\u001b$B0Y\u001b(B\n\u001b$B0Z\u001b(B\n\u001b$B0[\u001b(B\n\u001b$B0\\\u001b(B\n\u001b$B0]\u001b(B\n\u001b$B0^\u001b(B\n\u001b$B0_\u001b(B\n\u001b$B0`\u001b(B\n\u001b$B0a\u001b(B\n\u001b$B0b\u001b(B\n\u001b$B0c\u001b(B\n\u001b$B0d\u001b(B\n\u001b$B0e\u001b(B\n\u001b$B0f\u001b(B\n\u001b$B0g\u001b(B\n\u001b$B0h\u001b(B\n\u001b$B0i\u001b(B\n\u001b$B0j\u001b(B\n\u001b$B0k\u001b(B\n\u001b$B0l\u001b(B\n\u001b$B0m\u001b(B\n\u001b$B0n\u001b(B\n\u001b$B0o\u001b(B\n\u001b$B0p\u001b(B\n\u001b$B0q\u001b(B\n\u001b$B0r\u001b(B\n\u001b$B0s\u001b(B\n\u001b$B0t\u001b(B\n\u001b$B0u\u001b(B\n\u001b$B0v\u001b(B\n\u001b$B0w\u001b(B\n\u001b$B0x\u001b(B\n\u001b$B0y\u001b(B\n\u001b$B0z\u001b(B\n\u001b$B0{\u001b(B\n\u001b$B0|\u001b(B\n\u001b$B0}\u001b(B\n\u001b$B0~\u001b(B\n\u001b$B1!\u001b(B\n\u001b$B1\"\u001b(B\n\u001b$B1#\u001b(B\n\u001b$B1$\u001b(B\n\u001b$B1%\u001b(B\n\u001b$B1&\u001b(B\n\u001b$B1'\u001b(B\n\u001b$B1(\u001b(B\n\u001b$B1)\u001b(B\n\u001b$B1*\u001b(B\n\u001b$B1+\u001b(B\n\u001b$B1,\u001b(B\n\u001b$B1-\u001b(B\n\u001b$B1.\u001b(B\n\u001b$B1/\u001b(B\n\u001b$B10\u001b(B\n\u001b$B11\u001b(B\n\u001b$B12\u001b(B\n\u001b$B13\u001b(B\n\u001b$B14\u001b(B\n\u001b$B15\u001b(B\n\u001b$B16\u001b(B\n\u001b$B17\u001b(B\n\u001b$B18\u001b(B\n\u001b$B19\u001b(B\n\u001b$B1:\u001b(B\n\u001b$B1;\u001b(B\n\u001b$B1<\u001b(B\n\u001b$B1=\u001b(B\n\u001b$B1>\u001b(B\n\u001b$B1?\u001b(B\n\u001b$B1@\u001b(B\n\u001b$B1A\u001b(B\n\u001b$B1B\u001b(B\n\u001b$B1C\u001b(B\n\u001b$B1D\u001b(B\n\u001b$B1E\u001b(B\n\u001b$B1F\u001b(B\n\u001b$B1G\u001b(B\n\u001b$B1H\u001b(B\n\u001b$B1I\u001b(B\n\u001b$B1J\u001b(B\n\u001b$B1K\u001b(B\n\u001b$B1L\u001b(B\n\u001b$B1M\u001b(B\n\u001b$B1N\u001b(B\n\u001b$B1O\u001b(B\n\u001b$B1P\u001b(B\n\u001b$B1Q\u001b(B\n\u001b$B1R\u001b(B\n\u001b$B1S\u001b(B\n\u001b$B1T\u001b(B\n\u001b$B1U\u001b(B\n\u001b$B1V\u001b(B\n\u001b$B1W\u001b(B\n\u001b$B1X\u001b(B\n\u001b$B1Y\u001b(B\n\u001b$B1Z\u001b(B\n\u001b$B1[\u001b(B\n\u001b$B1\\\u001b(B\n\u001b$B1]\u001b(B\n\u001b$B1^\u001b(B\n\u001b$B1_\u001b(B\n\u001b$B1`\u001b(B\n\u001b$B1a\u001b(B\n\u001b$B1b\u001b(B\n\u001b$B1c\u001b(B\n\u001b$B1d\u001b(B\n\u001b$B1e\u001b(B\n\u001b$B1f\u001b(B\n\u001b$B1g\u001b(B\n\u001b$B1h\u001b(B\n\u001b$B1i\u001b(B\n\u001b$B1j\u001b(B\n\u001b$B1k\u001b(B\n\u001b$B1l\u001b(B\n\u001b$B1m\u001b(B\n\u001b$B1n\u001b(B\n\u001b$B1o\u001b(B\n\u001b$B1p\u001b(B\n\u001b$B1q\u001b(B\n\u001b$B1r\u001b(B\n\u001b$B1s\u001b(B\n\u001b$B1t\u001b(B\n\u001b$B1u\u001b(B\n\u001b$B1v\u001b(B\n\u001b$B1w\u001b(B\n\u001b$B1x\u001b(B\n\u001b$B1y\u001b(B\n\u001b$B1z\u001b(B\n\u001b$B1{\u001b(B\n\u001b$B1|\u001b(B\n\u001b$B1}\u001b(B\n\u001b$B1~\u001b(B\n\u001b$B2!\u001b(B\n\u001b$B2\"\u001b(B\n\u001b$B2#\u001b(B\n\u001b$B2$\u001b(B\n\u001b$B2%\u001b(B\n\u001b$B2&\u001b(B\n\u001b$B2'\u001b(B\n\u001b$B2(\u001b(B\n\u001b$B2)\u001b(B\n\u001b$B2*\u001b(B\n\u001b$B2+\u001b(B\n\u001b$B2,\u001b(B\n\u001b$B2-\u001b(B\n\u001b$B2.\u001b(B\n\u001b$B2/\u001b(B\n\u001b$B20\u001b(B\n\u001b$B21\u001b(B\n\u001b$B22\u001b(B\n\u001b$B23\u001b(B\n\u001b$B24\u001b(B\n\u001b$B25\u001b(B\n\u001b$B26\u001b(B\n\u001b$B27\u001b(B\n\u001b$B28\u001b(B\n\u001b$B29\u001b(B\n\u001b$B2:\u001b(B\n\u001b$B2;\u001b(B\n\u001b$B2<\u001b(B\n\u001b$B2=\u001b(B\n\u001b$B2>\u001b(B\n\u001b$B2?\u001b(B\n\u001b$B2@\u001b(B\n\u001b$B2A\u001b(B\n\u001b$B2B\u001b(B\n\u001b$B2C\u001b(B\n\u001b$B2D\u001b(B\n\u001b$B2E\u001b(B\n\u001b$B2F\u001b(B\n\u001b$B2G\u001b(B\n\u001b$B2H\u001b(B\n\u001b$B2I\u001b(B\n\u001b$B2J\u001b(B\n\u001b$B2K\u001b(B\n\u001b$B2L\u001b(B\n\u001b$B2M\u001b(B\n\u001b$B2N\u001b(B\n\u001b$B2O\u001b(B\n\u001b$B2P\u001b(B\n\u001b$B2Q\u001b(B\n\u001b$B2R\u001b(B\n\u001b$B2S\u001b(B\n\u001b$B2T\u001b(B\n\u001b$B2U\u001b(B\n\u001b$B2V\u001b(B\n\u001b$B2W\u001b(B\n\u001b$B2X\u001b(B\n\u001b$B2Y\u001b(B\n\u001b$B2Z\u001b(B\n\u001b$B2[\u001b(B\n\u001b$B2\\\u001b(B\n\u001b$B2]\u001b(B\n\u001b$B2^\u001b(B\n\u001b$B2_\u001b(B\n\u001b$B2`\u001b(B\n\u001b$B2a\u001b(B\n\u001b$B2b\u001b(B\n\u001b$B2c\u001b(B\n\u001b$B2d\u001b(B\n\u001b$B2e\u001b(B\n\u001b$B2f\u001b(B\n\u001b$B2g\u001b(B\n\u001b$B2h\u001b(B\n\u001b$B2i\u001b(B\n\u001b$B2j\u001b(B\n\u001b$B2k\u001b(B\n\u001b$B2l\u001b(B\n\u001b$B2m\u001b(B\n\u001b$B2n\u001b(B\n\u001b$B2o\u001b(B\n\u001b$B2p\u001b(B\n\u001b$B2q\u001b(B\n\u001b$B2r\u001b(B\n\u001b$B2s\u001b(B\n\u001b$B2t\u001b(B\n\u001b$B2u\u001b(B\n\u001b$B2v\u001b(B\n\u001b$B2w\u001b(B\n\u001b$B2x\u001b(B\n\u001b$B2y\u001b(B\n\u001b$B2z\u001b(B\n\u001b$B2{\u001b(B\n\u001b$B2|\u001b(B\n\u001b$B2}\u001b(B\n\u001b$B2~\u001b(B\n\u001b$B3!\u001b(B\n\u001b$B3\"\u001b(B\n\u001b$B3#\u001b(B\n\u001b$B3$\u001b(B\n\u001b$B3%\u001b(B\n\u001b$B3&\u001b(B\n\u001b$B3'\u001b(B\n\u001b$B3(\u001b(B\n\u001b$B3)\u001b(B\n\u001b$B3*\u001b(B\n\u001b$B3+\u001b(B\n\u001b$B3,\u001b(B\n\u001b$B3-\u001b(B\n\u001b$B3.\u001b(B\n\u001b$B3/\u001b(B\n\u001b$B30\u001b(B\n\u001b$B31\u001b(B\n\u001b$B32\u001b(B\n\u001b$B33\u001b(B\n\u001b$B34\u001b(B\n\u001b$B35\u001b(B\n\u001b$B36\u001b(B\n\u001b$B37\u001b(B\n\u001b$B38\u001b(B\n\u001b$B39\u001b(B\n\u001b$B3:\u001b(B\n\u001b$B3;\u001b(B\n\u001b$B3<\u001b(B\n\u001b$B3=\u001b(B\n\u001b$B3>\u001b(B\n\u001b$B3?\u001b(B\n\u001b$B3@\u001b(B\n\u001b$B3A\u001b(B\n\u001b$B3B\u001b(B\n\u001b$B3C\u001b(B\n\u001b$B3D\u001b(B\n\u001b$B3E\u001b(B\n\u001b$B3F\u001b(B\n\u001b$B3G\u001b(B\n\u001b$B3H\u001b(B\n\u001b$B3I\u001b(B\n\u001b$B3J\u001b(B\n\u001b$B3K\u001b(B\n\u001b$B3L\u001b(B\n\u001b$B3M\u001b(B\n\u001b$B3N\u001b(B\n\u001b$B3O\u001b(B\n\u001b$B3P\u001b(B\n\u001b$B3Q\u001b(B\n\u001b$B3R\u001b(B\n\u001b$B3S\u001b(B\n\u001b$B3T\u001b(B\n\u001b$B3U\u001b(B\n\u001b$B3V\u001b(B\n\u001b$B3W\u001b(B\n\u001b$B3X\u001b(B\n\u001b$B3Y\u001b(B\n\u001b$B3Z\u001b(B\n\u001b$B3[\u001b(B\n\u001b$B3\\\u001b(B\n\u001b$B3]\u001b(B\n\u001b$B3^\u001b(B\n\u001b$B3_\u001b(B\n\u001b$B3`\u001b(B\n\u001b$B3a\u001b(B\n\u001b$B3b\u001b(B\n\u001b$B3c\u001b(B\n\u001b$B3d\u001b(B\n\u001b$B3e\u001b(B\n\u001b$B3f\u001b(B\n\u001b$B3g\u001b(B\n\u001b$B3h\u001b(B\n\u001b$B3i\u001b(B\n\u001b$B3j\u001b(B\n\u001b$B3k\u001b(B\n\u001b$B3l\u001b(B\n\u001b$B3m\u001b(B\n\u001b$B3n\u001b(B\n\u001b$B3o\u001b(B\n\u001b$B3p\u001b(B\n\u001b$B3q\u001b(B\n\u001b$B3r\u001b(B\n\u001b$B3s\u001b(B\n\u001b$B3t\u001b(B\n\u001b$B3u\u001b(B\n\u001b$B3v\u001b(B\n\u001b$B3w\u001b(B\n\u001b$B3x\u001b(B\n\u001b$B3y\u001b(B\n\u001b$B3z\u001b(B\n\u001b$B3{\u001b(B\n\u001b$B3|\u001b(B\n\u001b$B3}\u001b(B\n\u001b$B3~\u001b(B\n\u001b$B4!\u001b(B\n\u001b$B4\"\u001b(B\n\u001b$B4#\u001b(B\n\u001b$B4$\u001b(B\n\u001b$B4%\u001b(B\n\u001b$B4&\u001b(B\n\u001b$B4'\u001b(B\n\u001b$B4(\u001b(B\n\u001b$B4)\u001b(B\n\u001b$B4*\u001b(B\n\u001b$B4+\u001b(B\n\u001b$B4,\u001b(B\n\u001b$B4-\u001b(B\n\u001b$B4.\u001b(B\n\u001b$B4/\u001b(B\n\u001b$B40\u001b(B\n\u001b$B41\u001b(B\n\u001b$B42\u001b(B\n\u001b$B43\u001b(B\n\u001b$B44\u001b(B\n\u001b$B45\u001b(B\n\u001b$B46\u001b(B\n\u001b$B47\u001b(B\n\u001b$B48\u001b(B\n\u001b$B49\u001b(B\n\u001b$B4:\u001b(B\n\u001b$B4;\u001b(B\n\u001b$B4<\u001b(B\n\u001b$B4=\u001b(B\n\u001b$B4>\u001b(B\n\u001b$B4?\u001b(B\n\u001b$B4@\u001b(B\n\u001b$B4A\u001b(B\n\u001b$B4B\u001b(B\n\u001b$B4C\u001b(B\n\u001b$B4D\u001b(B\n\u001b$B4E\u001b(B\n\u001b$B4F\u001b(B\n\u001b$B4G\u001b(B\n\u001b$B4H\u001b(B\n\u001b$B4I\u001b(B\n\u001b$B4J\u001b(B\n\u001b$B4K\u001b(B\n\u001b$B4L\u001b(B\n\u001b$B4M\u001b(B\n\u001b$B4N\u001b(B\n\u001b$B4O\u001b(B\n\u001b$B4P\u001b(B\n\u001b$B4Q\u001b(B\n\u001b$B4R\u001b(B\n\u001b$B4S\u001b(B\n\u001b$B4T\u001b(B\n\u001b$B4U\u001b(B\n\u001b$B4V\u001b(B\n\u001b$B4W\u001b(B\n\u001b$B4X\u001b(B\n\u001b$B4Y\u001b(B\n\u001b$B4Z\u001b(B\n\u001b$B4[\u001b(B\n\u001b$B4\\\u001b(B\n\u001b$B4]\u001b(B\n\u001b$B4^\u001b(B\n\u001b$B4_\u001b(B\n\u001b$B4`\u001b(B\n\u001b$B4a\u001b(B\n\u001b$B4b\u001b(B\n\u001b$B4c\u001b(B\n\u001b$B4d\u001b(B\n\u001b$B4e\u001b(B\n\u001b$B4f\u001b(B\n\u001b$B4g\u001b(B\n\u001b$B4h\u001b(B\n\u001b$B4i\u001b(B\n\u001b$B4j\u001b(B\n\u001b$B4k\u001b(B\n\u001b$B4l\u001b(B\n\u001b$B4m\u001b(B\n\u001b$B4n\u001b(B\n\u001b$B4o\u001b(B\n\u001b$B4p\u001b(B\n\u001b$B4q\u001b(B\n\u001b$B4r\u001b(B\n\u001b$B4s\u001b(B\n\u001b$B4t\u001b(B\n\u001b$B4u\u001b(B\n\u001b$B4v\u001b(B\n\u001b$B4w\u001b(B\n\u001b$B4x\u001b(B\n\u001b$B4y\u001b(B\n\u001b$B4z\u001b(B\n\u001b$B4{\u001b(B\n\u001b$B4|\u001b(B\n\u001b$B4}\u001b(B\n\u001b$B4~\u001b(B\n\u001b$B5!\u001b(B\n\u001b$B5\"\u001b(B\n\u001b$B5#\u001b(B\n\u001b$B5$\u001b(B\n\u001b$B5%\u001b(B\n\u001b$B5&\u001b(B\n\u001b$B5'\u001b(B\n\u001b$B5(\u001b(B\n\u001b$B5)\u001b(B\n\u001b$B5*\u001b(B\n\u001b$B5+\u001b(B\n\u001b$B5,\u001b(B\n\u001b$B5-\u001b(B\n\u001b$B5.\u001b(B\n\u001b$B5/\u001b(B\n\u001b$B50\u001b(B\n\u001b$B51\u001b(B\n\u001b$B52\u001b(B\n\u001b$B53\u001b(B\n\u001b$B54\u001b(B\n\u001b$B55\u001b(B\n\u001b$B56\u001b(B\n\u001b$B57\u001b(B\n\u001b$B58\u001b(B\n\u001b$B59\u001b(B\n\u001b$B5:\u001b(B\n\u001b$B5;\u001b(B\n\u001b$B5<\u001b(B\n\u001b$B5=\u001b(B\n\u001b$B5>\u001b(B\n\u001b$B5?\u001b(B\n\u001b$B5@\u001b(B\n\u001b$B5A\u001b(B\n\u001b$B5B\u001b(B\n\u001b$B5C\u001b(B\n\u001b$B5D\u001b(B\n\u001b$B5E\u001b(B\n\u001b$B5F\u001b(B\n\u001b$B5G\u001b(B\n\u001b$B5H\u001b(B\n\u001b$B5I\u001b(B\n\u001b$B5J\u001b(B\n\u001b$B5K\u001b(B\n\u001b$B5L\u001b(B\n\u001b$B5M\u001b(B\n\u001b$B5N\u001b(B\n\u001b$B5O\u001b(B\n\u001b$B5P\u001b(B\n\u001b$B5Q\u001b(B\n\u001b$B5R\u001b(B\n\u001b$B5S\u001b(B\n\u001b$B5T\u001b(B\n\u001b$B5U\u001b(B\n\u001b$B5V\u001b(B\n\u001b$B5W\u001b(B\n\u001b$B5X\u001b(B\n\u001b$B5Y\u001b(B\n\u001b$B5Z\u001b(B\n\u001b$B5[\u001b(B\n\u001b$B5\\\u001b(B\n\u001b$B5]\u001b(B\n\u001b$B5^\u001b(B\n\u001b$B5_\u001b(B\n\u001b$B5`\u001b(B\n\u001b$B5a\u001b(B\n\u001b$B5b\u001b(B\n\u001b$B5c\u001b(B\n\u001b$B5d\u001b(B\n\u001b$B5e\u001b(B\n\u001b$B5f\u001b(B\n\u001b$B5g\u001b(B\n\u001b$B5h\u001b(B\n\u001b$B5i\u001b(B\n\u001b$B5j\u001b(B\n\u001b$B5k\u001b(B\n\u001b$B5l\u001b(B\n\u001b$B5m\u001b(B\n\u001b$B5n\u001b(B\n\u001b$B5o\u001b(B\n\u001b$B5p\u001b(B\n\u001b$B5q\u001b(B\n\u001b$B5r\u001b(B\n\u001b$B5s\u001b(B\n\u001b$B5t\u001b(B\n\u001b$B5u\u001b(B\n\u001b$B5v\u001b(B\n\u001b$B5w\u001b(B\n\u001b$B5x\u001b(B\n\u001b$B5y\u001b(B\n\u001b$B5z\u001b(B\n\u001b$B5{\u001b(B\n\u001b$B5|\u001b(B\n\u001b$B5}\u001b(B\n\u001b$B5~\u001b(B\n\u001b$B6!\u001b(B\n\u001b$B6\"\u001b(B\n\u001b$B6#\u001b(B\n\u001b$B6$\u001b(B\n\u001b$B6%\u001b(B\n\u001b$B6&\u001b(B\n\u001b$B6'\u001b(B\n\u001b$B6(\u001b(B\n\u001b$B6)\u001b(B\n\u001b$B6*\u001b(B\n\u001b$B6+\u001b(B\n\u001b$B6,\u001b(B\n\u001b$B6-\u001b(B\n\u001b$B6.\u001b(B\n\u001b$B6/\u001b(B\n\u001b$B60\u001b(B\n\u001b$B61\u001b(B\n\u001b$B62\u001b(B\n\u001b$B63\u001b(B\n\u001b$B64\u001b(B\n\u001b$B65\u001b(B\n\u001b$B66\u001b(B\n\u001b$B67\u001b(B\n\u001b$B68\u001b(B\n\u001b$B69\u001b(B\n\u001b$B6:\u001b(B\n\u001b$B6;\u001b(B\n\u001b$B6<\u001b(B\n\u001b$B6=\u001b(B\n\u001b$B6>\u001b(B\n\u001b$B6?\u001b(B\n\u001b$B6@\u001b(B\n\u001b$B6A\u001b(B\n\u001b$B6B\u001b(B\n\u001b$B6C\u001b(B\n\u001b$B6D\u001b(B\n\u001b$B6E\u001b(B\n\u001b$B6F\u001b(B\n\u001b$B6G\u001b(B\n\u001b$B6H\u001b(B\n\u001b$B6I\u001b(B\n\u001b$B6J\u001b(B\n\u001b$B6K\u001b(B\n\u001b$B6L\u001b(B\n\u001b$B6M\u001b(B\n\u001b$B6N\u001b(B\n\u001b$B6O\u001b(B\n\u001b$B6P\u001b(B\n\u001b$B6Q\u001b(B\n\u001b$B6R\u001b(B\n\u001b$B6S\u001b(B\n\u001b$B6T\u001b(B\n\u001b$B6U\u001b(B\n\u001b$B6V\u001b(B\n\u001b$B6W\u001b(B\n\u001b$B6X\u001b(B\n\u001b$B6Y\u001b(B\n\u001b$B6Z\u001b(B\n\u001b$B6[\u001b(B\n\u001b$B6\\\u001b(B\n\u001b$B6]\u001b(B\n\u001b$B6^\u001b(B\n\u001b$B6_\u001b(B\n\u001b$B6`\u001b(B\n\u001b$B6a\u001b(B\n\u001b$B6b\u001b(B\n\u001b$B6c\u001b(B\n\u001b$B6d\u001b(B\n\u001b$B6e\u001b(B\n\u001b$B6f\u001b(B\n\u001b$B6g\u001b(B\n\u001b$B6h\u001b(B\n\u001b$B6i\u001b(B\n\u001b$B6j\u001b(B\n\u001b$B6k\u001b(B\n\u001b$B6l\u001b(B\n\u001b$B6m\u001b(B\n\u001b$B6n\u001b(B\n\u001b$B6o\u001b(B\n\u001b$B6p\u001b(B\n\u001b$B6q\u001b(B\n\u001b$B6r\u001b(B\n\u001b$B6s\u001b(B\n\u001b$B6t\u001b(B\n\u001b$B6u\u001b(B\n\u001b$B6v\u001b(B\n\u001b$B6w\u001b(B\n\u001b$B6x\u001b(B\n\u001b$B6y\u001b(B\n\u001b$B6z\u001b(B\n\u001b$B6{\u001b(B\n\u001b$B6|\u001b(B\n\u001b$B6}\u001b(B\n\u001b$B6~\u001b(B\n\u001b$B7!\u001b(B\n\u001b$B7\"\u001b(B\n\u001b$B7#\u001b(B\n\u001b$B7$\u001b(B\n\u001b$B7%\u001b(B\n\u001b$B7&\u001b(B\n\u001b$B7'\u001b(B\n\u001b$B7(\u001b(B\n\u001b$B7)\u001b(B\n\u001b$B7*\u001b(B\n\u001b$B7+\u001b(B\n\u001b$B7,\u001b(B\n\u001b$B7-\u001b(B\n\u001b$B7.\u001b(B\n\u001b$B7/\u001b(B\n\u001b$B70\u001b(B\n\u001b$B71\u001b(B\n\u001b$B72\u001b(B\n\u001b$B73\u001b(B\n\u001b$B74\u001b(B\n\u001b$B75\u001b(B\n\u001b$B76\u001b(B\n\u001b$B77\u001b(B\n\u001b$B78\u001b(B\n\u001b$B79\u001b(B\n\u001b$B7:\u001b(B\n\u001b$B7;\u001b(B\n\u001b$B7<\u001b(B\n\u001b$B7=\u001b(B\n\u001b$B7>\u001b(B\n\u001b$B7?\u001b(B\n\u001b$B7@\u001b(B\n\u001b$B7A\u001b(B\n\u001b$B7B\u001b(B\n\u001b$B7C\u001b(B\n\u001b$B7D\u001b(B\n\u001b$B7E\u001b(B\n\u001b$B7F\u001b(B\n\u001b$B7G\u001b(B\n\u001b$B7H\u001b(B\n\u001b$B7I\u001b(B\n\u001b$B7J\u001b(B\n\u001b$B7K\u001b(B\n\u001b$B7L\u001b(B\n\u001b$B7M\u001b(B\n\u001b$B7N\u001b(B\n\u001b$B7O\u001b(B\n\u001b$B7P\u001b(B\n\u001b$B7Q\u001b(B\n\u001b$B7R\u001b(B\n\u001b$B7S\u001b(B\n\u001b$B7T\u001b(B\n\u001b$B7U\u001b(B\n\u001b$B7V\u001b(B\n\u001b$B7W\u001b(B\n\u001b$B7X\u001b(B\n\u001b$B7Y\u001b(B\n\u001b$B7Z\u001b(B\n\u001b$B7[\u001b(B\n\u001b$B7\\\u001b(B\n\u001b$B7]\u001b(B\n\u001b$B7^\u001b(B\n\u001b$B7_\u001b(B\n\u001b$B7`\u001b(B\n\u001b$B7a\u001b(B\n\u001b$B7b\u001b(B\n\u001b$B7c\u001b(B\n\u001b$B7d\u001b(B\n\u001b$B7e\u001b(B\n\u001b$B7f\u001b(B\n\u001b$B7g\u001b(B\n\u001b$B7h\u001b(B\n\u001b$B7i\u001b(B\n\u001b$B7j\u001b(B\n\u001b$B7k\u001b(B\n\u001b$B7l\u001b(B\n\u001b$B7m\u001b(B\n\u001b$B7n\u001b(B\n\u001b$B7o\u001b(B\n\u001b$B7p\u001b(B\n\u001b$B7q\u001b(B\n\u001b$B7r\u001b(B\n\u001b$B7s\u001b(B\n\u001b$B7t\u001b(B\n\u001b$B7u\u001b(B\n\u001b$B7v\u001b(B\n\u001b$B7w\u001b(B\n\u001b$B7x\u001b(B\n\u001b$B7y\u001b(B\n\u001b$B7z\u001b(B\n\u001b$B7{\u001b(B\n\u001b$B7|\u001b(B\n\u001b$B7}\u001b(B\n\u001b$B7~\u001b(B\n\u001b$B8!\u001b(B\n\u001b$B8\"\u001b(B\n\u001b$B8#\u001b(B\n\u001b$B8$\u001b(B\n\u001b$B8%\u001b(B\n\u001b$B8&\u001b(B\n\u001b$B8'\u001b(B\n\u001b$B8(\u001b(B\n\u001b$B8)\u001b(B\n\u001b$B8*\u001b(B\n\u001b$B8+\u001b(B\n\u001b$B8,\u001b(B\n\u001b$B8-\u001b(B\n\u001b$B8.\u001b(B\n\u001b$B8/\u001b(B\n\u001b$B80\u001b(B\n\u001b$B81\u001b(B\n\u001b$B82\u001b(B\n\u001b$B83\u001b(B\n\u001b$B84\u001b(B\n\u001b$B85\u001b(B\n\u001b$B86\u001b(B\n\u001b$B87\u001b(B\n\u001b$B88\u001b(B\n\u001b$B89\u001b(B\n\u001b$B8:\u001b(B\n\u001b$B8;\u001b(B\n\u001b$B8<\u001b(B\n\u001b$B8=\u001b(B\n\u001b$B8>\u001b(B\n\u001b$B8?\u001b(B\n\u001b$B8@\u001b(B\n\u001b$B8A\u001b(B\n\u001b$B8B\u001b(B\n\u001b$B8C\u001b(B\n\u001b$B8D\u001b(B\n\u001b$B8E\u001b(B\n\u001b$B8F\u001b(B\n\u001b$B8G\u001b(B\n\u001b$B8H\u001b(B\n\u001b$B8I\u001b(B\n\u001b$B8J\u001b(B\n\u001b$B8K\u001b(B\n\u001b$B8L\u001b(B\n\u001b$B8M\u001b(B\n\u001b$B8N\u001b(B\n\u001b$B8O\u001b(B\n\u001b$B8P\u001b(B\n\u001b$B8Q\u001b(B\n\u001b$B8R\u001b(B\n\u001b$B8S\u001b(B\n\u001b$B8T\u001b(B\n\u001b$B8U\u001b(B\n\u001b$B8V\u001b(B\n\u001b$B8W\u001b(B\n\u001b$B8X\u001b(B\n\u001b$B8Y\u001b(B\n\u001b$B8Z\u001b(B\n\u001b$B8[\u001b(B\n\u001b$B8\\\u001b(B\n\u001b$B8]\u001b(B\n\u001b$B8^\u001b(B\n\u001b$B8_\u001b(B\n\u001b$B8`\u001b(B\n\u001b$B8a\u001b(B\n\u001b$B8b\u001b(B\n\u001b$B8c\u001b(B\n\u001b$B8d\u001b(B\n\u001b$B8e\u001b(B\n\u001b$B8f\u001b(B\n\u001b$B8g\u001b(B\n\u001b$B8h\u001b(B\n\u001b$B8i\u001b(B\n\u001b$B8j\u001b(B\n\u001b$B8k\u001b(B\n\u001b$B8l\u001b(B\n\u001b$B8m\u001b(B\n\u001b$B8n\u001b(B\n\u001b$B8o\u001b(B\n\u001b$B8p\u001b(B\n\u001b$B8q\u001b(B\n\u001b$B8r\u001b(B\n\u001b$B8s\u001b(B\n\u001b$B8t\u001b(B\n\u001b$B8u\u001b(B\n\u001b$B8v\u001b(B\n\u001b$B8w\u001b(B\n\u001b$B8x\u001b(B\n\u001b$B8y\u001b(B\n\u001b$B8z\u001b(B\n\u001b$B8{\u001b(B\n\u001b$B8|\u001b(B\n\u001b$B8}\u001b(B\n\u001b$B8~\u001b(B\n\u001b$B9!\u001b(B\n\u001b$B9\"\u001b(B\n\u001b$B9#\u001b(B\n\u001b$B9$\u001b(B\n\u001b$B9%\u001b(B\n\u001b$B9&\u001b(B\n\u001b$B9'\u001b(B\n\u001b$B9(\u001b(B\n\u001b$B9)\u001b(B\n\u001b$B9*\u001b(B\n\u001b$B9+\u001b(B\n\u001b$B9,\u001b(B\n\u001b$B9-\u001b(B\n\u001b$B9.\u001b(B\n\u001b$B9/\u001b(B\n\u001b$B90\u001b(B\n\u001b$B91\u001b(B\n\u001b$B92\u001b(B\n\u001b$B93\u001b(B\n\u001b$B94\u001b(B\n\u001b$B95\u001b(B\n\u001b$B96\u001b(B\n\u001b$B97\u001b(B\n\u001b$B98\u001b(B\n\u001b$B99\u001b(B\n\u001b$B9:\u001b(B\n\u001b$B9;\u001b(B\n\u001b$B9<\u001b(B\n\u001b$B9=\u001b(B\n\u001b$B9>\u001b(B\n\u001b$B9?\u001b(B\n\u001b$B9@\u001b(B\n\u001b$B9A\u001b(B\n\u001b$B9B\u001b(B\n\u001b$B9C\u001b(B\n\u001b$B9D\u001b(B\n\u001b$B9E\u001b(B\n\u001b$B9F\u001b(B\n\u001b$B9G\u001b(B\n\u001b$B9H\u001b(B\n\u001b$B9I\u001b(B\n\u001b$B9J\u001b(B\n\u001b$B9K\u001b(B\n\u001b$B9L\u001b(B\n\u001b$B9M\u001b(B\n\u001b$B9N\u001b(B\n\u001b$B9O\u001b(B\n\u001b$B9P\u001b(B\n\u001b$B9Q\u001b(B\n\u001b$B9R\u001b(B\n\u001b$B9S\u001b(B\n\u001b$B9T\u001b(B\n\u001b$B9U\u001b(B\n\u001b$B9V\u001b(B\n\u001b$B9W\u001b(B\n\u001b$B9X\u001b(B\n\u001b$B9Y\u001b(B\n\u001b$B9Z\u001b(B\n\u001b$B9[\u001b(B\n\u001b$B9\\\u001b(B\n\u001b$B9]\u001b(B\n\u001b$B9^\u001b(B\n\u001b$B9_\u001b(B\n\u001b$B9`\u001b(B\n\u001b$B9a\u001b(B\n\u001b$B9b\u001b(B\n\u001b$B9c\u001b(B\n\u001b$B9d\u001b(B\n\u001b$B9e\u001b(B\n\u001b$B9f\u001b(B\n\u001b$B9g\u001b(B\n\u001b$B9h\u001b(B\n\u001b$B9i\u001b(B\n\u001b$B9j\u001b(B\n\u001b$B9k\u001b(B\n\u001b$B9l\u001b(B\n\u001b$B9m\u001b(B\n\u001b$B9n\u001b(B\n\u001b$B9o\u001b(B\n\u001b$B9p\u001b(B\n\u001b$B9q\u001b(B\n\u001b$B9r\u001b(B\n\u001b$B9s\u001b(B\n\u001b$B9t\u001b(B\n\u001b$B9u\u001b(B\n\u001b$B9v\u001b(B\n\u001b$B9w\u001b(B\n\u001b$B9x\u001b(B\n\u001b$B9y\u001b(B\n\u001b$B9z\u001b(B\n\u001b$B9{\u001b(B\n\u001b$B9|\u001b(B\n\u001b$B9}\u001b(B\n\u001b$B9~\u001b(B\n\u001b$B:!\u001b(B\n\u001b$B:\"\u001b(B\n\u001b$B:#\u001b(B\n\u001b$B:$\u001b(B\n\u001b$B:%\u001b(B\n\u001b$B:&\u001b(B\n\u001b$B:'\u001b(B\n\u001b$B:(\u001b(B\n\u001b$B:)\u001b(B\n\u001b$B:*\u001b(B\n\u001b$B:+\u001b(B\n\u001b$B:,\u001b(B\n\u001b$B:-\u001b(B\n\u001b$B:.\u001b(B\n\u001b$B:/\u001b(B\n\u001b$B:0\u001b(B\n\u001b$B:1\u001b(B\n\u001b$B:2\u001b(B\n\u001b$B:3\u001b(B\n\u001b$B:4\u001b(B\n\u001b$B:5\u001b(B\n\u001b$B:6\u001b(B\n\u001b$B:7\u001b(B\n\u001b$B:8\u001b(B\n\u001b$B:9\u001b(B\n\u001b$B::\u001b(B\n\u001b$B:;\u001b(B\n\u001b$B:<\u001b(B\n\u001b$B:=\u001b(B\n\u001b$B:>\u001b(B\n\u001b$B:?\u001b(B\n\u001b$B:@\u001b(B\n\u001b$B:A\u001b(B\n\u001b$B:B\u001b(B\n\u001b$B:C\u001b(B\n\u001b$B:D\u001b(B\n\u001b$B:E\u001b(B\n\u001b$B:F\u001b(B\n\u001b$B:G\u001b(B\n\u001b$B:H\u001b(B\n\u001b$B:I\u001b(B\n\u001b$B:J\u001b(B\n\u001b$B:K\u001b(B\n\u001b$B:L\u001b(B\n\u001b$B:M\u001b(B\n\u001b$B:N\u001b(B\n\u001b$B:O\u001b(B\n\u001b$B:P\u001b(B\n\u001b$B:Q\u001b(B\n\u001b$B:R\u001b(B\n\u001b$B:S\u001b(B\n\u001b$B:T\u001b(B\n\u001b$B:U\u001b(B\n\u001b$B:V\u001b(B\n\u001b$B:W\u001b(B\n\u001b$B:X\u001b(B\n\u001b$B:Y\u001b(B\n\u001b$B:Z\u001b(B\n\u001b$B:[\u001b(B\n\u001b$B:\\\u001b(B\n\u001b$B:]\u001b(B\n\u001b$B:^\u001b(B\n\u001b$B:_\u001b(B\n\u001b$B:`\u001b(B\n\u001b$B:a\u001b(B\n\u001b$B:b\u001b(B\n\u001b$B:c\u001b(B\n\u001b$B:d\u001b(B\n\u001b$B:e\u001b(B\n\u001b$B:f\u001b(B\n\u001b$B:g\u001b(B\n\u001b$B:h\u001b(B\n\u001b$B:i\u001b(B\n\u001b$B:j\u001b(B\n\u001b$B:k\u001b(B\n\u001b$B:l\u001b(B\n\u001b$B:m\u001b(B\n\u001b$B:n\u001b(B\n\u001b$B:o\u001b(B\n\u001b$B:p\u001b(B\n\u001b$B:q\u001b(B\n\u001b$B:r\u001b(B\n\u001b$B:s\u001b(B\n\u001b$B:t\u001b(B\n\u001b$B:u\u001b(B\n\u001b$B:v\u001b(B\n\u001b$B:w\u001b(B\n\u001b$B:x\u001b(B\n\u001b$B:y\u001b(B\n\u001b$B:z\u001b(B\n\u001b$B:{\u001b(B\n\u001b$B:|\u001b(B\n\u001b$B:}\u001b(B\n\u001b$B:~\u001b(B\n\u001b$B;!\u001b(B\n\u001b$B;\"\u001b(B\n\u001b$B;#\u001b(B\n\u001b$B;$\u001b(B\n\u001b$B;%\u001b(B\n\u001b$B;&\u001b(B\n\u001b$B;'\u001b(B\n\u001b$B;(\u001b(B\n\u001b$B;)\u001b(B\n\u001b$B;*\u001b(B\n\u001b$B;+\u001b(B\n\u001b$B;,\u001b(B\n\u001b$B;-\u001b(B\n\u001b$B;.\u001b(B\n\u001b$B;/\u001b(B\n\u001b$B;0\u001b(B\n\u001b$B;1\u001b(B\n\u001b$B;2\u001b(B\n\u001b$B;3\u001b(B\n\u001b$B;4\u001b(B\n\u001b$B;5\u001b(B\n\u001b$B;6\u001b(B\n\u001b$B;7\u001b(B\n\u001b$B;8\u001b(B\n\u001b$B;9\u001b(B\n\u001b$B;:\u001b(B\n\u001b$B;;\u001b(B\n\u001b$B;<\u001b(B\n\u001b$B;=\u001b(B\n\u001b$B;>\u001b(B\n\u001b$B;?\u001b(B\n\u001b$B;@\u001b(B\n\u001b$B;A\u001b(B\n\u001b$B;B\u001b(B\n\u001b$B;C\u001b(B\n\u001b$B;D\u001b(B\n\u001b$B;E\u001b(B\n\u001b$B;F\u001b(B\n\u001b$B;G\u001b(B\n\u001b$B;H\u001b(B\n\u001b$B;I\u001b(B\n\u001b$B;J\u001b(B\n\u001b$B;K\u001b(B\n\u001b$B;L\u001b(B\n\u001b$B;M\u001b(B\n\u001b$B;N\u001b(B\n\u001b$B;O\u001b(B\n\u001b$B;P\u001b(B\n\u001b$B;Q\u001b(B\n\u001b$B;R\u001b(B\n\u001b$B;S\u001b(B\n\u001b$B;T\u001b(B\n\u001b$B;U\u001b(B\n\u001b$B;V\u001b(B\n\u001b$B;W\u001b(B\n\u001b$B;X\u001b(B\n\u001b$B;Y\u001b(B\n\u001b$B;Z\u001b(B\n\u001b$B;[\u001b(B\n\u001b$B;\\\u001b(B\n\u001b$B;]\u001b(B\n\u001b$B;^\u001b(B\n\u001b$B;_\u001b(B\n\u001b$B;`\u001b(B\n\u001b$B;a\u001b(B\n\u001b$B;b\u001b(B\n\u001b$B;c\u001b(B\n\u001b$B;d\u001b(B\n\u001b$B;e\u001b(B\n\u001b$B;f\u001b(B\n\u001b$B;g\u001b(B\n\u001b$B;h\u001b(B\n\u001b$B;i\u001b(B\n\u001b$B;j\u001b(B\n\u001b$B;k\u001b(B\n\u001b$B;l\u001b(B\n\u001b$B;m\u001b(B\n\u001b$B;n\u001b(B\n\u001b$B;o\u001b(B\n\u001b$B;p\u001b(B\n\u001b$B;q\u001b(B\n\u001b$B;r\u001b(B\n\u001b$B;s\u001b(B\n\u001b$B;t\u001b(B\n\u001b$B;u\u001b(B\n\u001b$B;v\u001b(B\n\u001b$B;w\u001b(B\n\u001b$B;x\u001b(B\n\u001b$B;y\u001b(B\n\u001b$B;z\u001b(B\n\u001b$B;{\u001b(B\n\u001b$B;|\u001b(B\n\u001b$B;}\u001b(B\n\u001b$B;~\u001b(B\n\u001b$B<!\u001b(B\n\u001b$B<\"\u001b(B\n\u001b$B<#\u001b(B\n\u001b$B<$\u001b(B\n\u001b$B<%\u001b(B\n\u001b$B<&\u001b(B\n\u001b$B<'\u001b(B\n\u001b$B<(\u001b(B\n\u001b$B<)\u001b(B\n\u001b$B<*\u001b(B\n\u001b$B<+\u001b(B\n\u001b$B<,\u001b(B\n\u001b$B<-\u001b(B\n\u001b$B<.\u001b(B\n\u001b$B</\u001b(B\n\u001b$B<0\u001b(B\n\u001b$B<1\u001b(B\n\u001b$B<2\u001b(B\n\u001b$B<3\u001b(B\n\u001b$B<4\u001b(B\n\u001b$B<5\u001b(B\n\u001b$B<6\u001b(B\n\u001b$B<7\u001b(B\n\u001b$B<8\u001b(B\n\u001b$B<9\u001b(B\n\u001b$B<:\u001b(B\n\u001b$B<;\u001b(B\n\u001b$B<<\u001b(B\n\u001b$B<=\u001b(B\n\u001b$B<>\u001b(B\n\u001b$B<?\u001b(B\n\u001b$B<@\u001b(B\n\u001b$B<A\u001b(B\n\u001b$B<B\u001b(B\n\u001b$B<C\u001b(B\n\u001b$B<D\u001b(B\n\u001b$B<E\u001b(B\n\u001b$B<F\u001b(B\n\u001b$B<G\u001b(B\n\u001b$B<H\u001b(B\n\u001b$B<I\u001b(B\n\u001b$B<J\u001b(B\n\u001b$B<K\u001b(B\n\u001b$B<L\u001b(B\n\u001b$B<M\u001b(B\n\u001b$B<N\u001b(B\n\u001b$B<O\u001b(B\n\u001b$B<P\u001b(B\n\u001b$B<Q\u001b(B\n\u001b$B<R\u001b(B\n\u001b$B<S\u001b(B\n\u001b$B<T\u001b(B\n\u001b$B<U\u001b(B\n\u001b$B<V\u001b(B\n\u001b$B<W\u001b(B\n\u001b$B<X\u001b(B\n\u001b$B<Y\u001b(B\n\u001b$B<Z\u001b(B\n\u001b$B<[\u001b(B\n\u001b$B<\\\u001b(B\n\u001b$B<]\u001b(B\n\u001b$B<^\u001b(B\n\u001b$B<_\u001b(B\n\u001b$B<`\u001b(B\n\u001b$B<a\u001b(B\n\u001b$B<b\u001b(B\n\u001b$B<c\u001b(B\n\u001b$B<d\u001b(B\n\u001b$B<e\u001b(B\n\u001b$B<f\u001b(B\n\u001b$B<g\u001b(B\n\u001b$B<h\u001b(B\n\u001b$B<i\u001b(B\n\u001b$B<j\u001b(B\n\u001b$B<k\u001b(B\n\u001b$B<l\u001b(B\n\u001b$B<m\u001b(B\n\u001b$B<n\u001b(B\n\u001b$B<o\u001b(B\n\u001b$B<p\u001b(B\n\u001b$B<q\u001b(B\n\u001b$B<r\u001b(B\n\u001b$B<s\u001b(B\n\u001b$B<t\u001b(B\n\u001b$B<u\u001b(B\n\u001b$B<v\u001b(B\n\u001b$B<w\u001b(B\n\u001b$B<x\u001b(B\n\u001b$B<y\u001b(B\n\u001b$B<z\u001b(B\n\u001b$B<{\u001b(B\n\u001b$B<|\u001b(B\n\u001b$B<}\u001b(B\n\u001b$B<~\u001b(B\n\u001b$B=!\u001b(B\n\u001b$B=\"\u001b(B\n\u001b$B=#\u001b(B\n\u001b$B=$\u001b(B\n\u001b$B=%\u001b(B\n\u001b$B=&\u001b(B\n\u001b$B='\u001b(B\n\u001b$B=(\u001b(B\n\u001b$B=)\u001b(B\n\u001b$B=*\u001b(B\n\u001b$B=+\u001b(B\n\u001b$B=,\u001b(B\n\u001b$B=-\u001b(B\n\u001b$B=.\u001b(B\n\u001b$B=/\u001b(B\n\u001b$B=0\u001b(B\n\u001b$B=1\u001b(B\n\u001b$B=2\u001b(B\n\u001b$B=3\u001b(B\n\u001b$B=4\u001b(B\n\u001b$B=5\u001b(B\n\u001b$B=6\u001b(B\n\u001b$B=7\u001b(B\n\u001b$B=8\u001b(B\n\u001b$B=9\u001b(B\n\u001b$B=:\u001b(B\n\u001b$B=;\u001b(B\n\u001b$B=<\u001b(B\n\u001b$B==\u001b(B\n\u001b$B=>\u001b(B\n\u001b$B=?\u001b(B\n\u001b$B=@\u001b(B\n\u001b$B=A\u001b(B\n\u001b$B=B\u001b(B\n\u001b$B=C\u001b(B\n\u001b$B=D\u001b(B\n\u001b$B=E\u001b(B\n\u001b$B=F\u001b(B\n\u001b$B=G\u001b(B\n\u001b$B=H\u001b(B\n\u001b$B=I\u001b(B\n\u001b$B=J\u001b(B\n\u001b$B=K\u001b(B\n\u001b$B=L\u001b(B\n\u001b$B=M\u001b(B\n\u001b$B=N\u001b(B\n\u001b$B=O\u001b(B\n\u001b$B=P\u001b(B\n\u001b$B=Q\u001b(B\n\u001b$B=R\u001b(B\n\u001b$B=S\u001b(B\n\u001b$B=T\u001b(B\n\u001b$B=U\u001b(B\n\u001b$B=V\u001b(B\n\u001b$B=W\u001b(B\n\u001b$B=X\u001b(B\n\u001b$B=Y\u001b(B\n\u001b$B=Z\u001b(B\n\u001b$B=[\u001b(B\n\u001b$B=\\\u001b(B\n\u001b$B=]\u001b(B\n\u001b$B=^\u001b(B\n\u001b$B=_\u001b(B\n\u001b$B=`\u001b(B\n\u001b$B=a\u001b(B\n\u001b$B=b\u001b(B\n\u001b$B=c\u001b(B\n\u001b$B=d\u001b(B\n\u001b$B=e\u001b(B\n\u001b$B=f\u001b(B\n\u001b$B=g\u001b(B\n\u001b$B=h\u001b(B\n\u001b$B=i\u001b(B\n\u001b$B=j\u001b(B\n\u001b$B=k\u001b(B\n\u001b$B=l\u001b(B\n\u001b$B=m\u001b(B\n\u001b$B=n\u001b(B\n\u001b$B=o\u001b(B\n\u001b$B=p\u001b(B\n\u001b$B=q\u001b(B\n\u001b$B=r\u001b(B\n\u001b$B=s\u001b(B\n\u001b$B=t\u001b(B\n\u001b$B=u\u001b(B\n\u001b$B=v\u001b(B\n\u001b$B=w\u001b(B\n\u001b$B=x\u001b(B\n\u001b$B=y\u001b(B\n\u001b$B=z\u001b(B\n\u001b$B={\u001b(B\n\u001b$B=|\u001b(B\n\u001b$B=}\u001b(B\n\u001b$B=~\u001b(B\n\u001b$B>!\u001b(B\n\u001b$B>\"\u001b(B\n\u001b$B>#\u001b(B\n\u001b$B>$\u001b(B\n\u001b$B>%\u001b(B\n\u001b$B>&\u001b(B\n\u001b$B>'\u001b(B\n\u001b$B>(\u001b(B\n\u001b$B>)\u001b(B\n\u001b$B>*\u001b(B\n\u001b$B>+\u001b(B\n\u001b$B>,\u001b(B\n\u001b$B>-\u001b(B\n\u001b$B>.\u001b(B\n\u001b$B>/\u001b(B\n\u001b$B>0\u001b(B\n\u001b$B>1\u001b(B\n\u001b$B>2\u001b(B\n\u001b$B>3\u001b(B\n\u001b$B>4\u001b(B\n\u001b$B>5\u001b(B\n\u001b$B>6\u001b(B\n\u001b$B>7\u001b(B\n\u001b$B>8\u001b(B\n\u001b$B>9\u001b(B\n\u001b$B>:\u001b(B\n\u001b$B>;\u001b(B\n\u001b$B><\u001b(B\n\u001b$B>=\u001b(B\n\u001b$B>>\u001b(B\n\u001b$B>?\u001b(B\n\u001b$B>@\u001b(B\n\u001b$B>A\u001b(B\n\u001b$B>B\u001b(B\n\u001b$B>C\u001b(B\n\u001b$B>D\u001b(B\n\u001b$B>E\u001b(B\n\u001b$B>F\u001b(B\n\u001b$B>G\u001b(B\n\u001b$B>H\u001b(B\n\u001b$B>I\u001b(B\n\u001b$B>J\u001b(B\n\u001b$B>K\u001b(B\n\u001b$B>L\u001b(B\n\u001b$B>M\u001b(B\n\u001b$B>N\u001b(B\n\u001b$B>O\u001b(B\n\u001b$B>P\u001b(B\n\u001b$B>Q\u001b(B\n\u001b$B>R\u001b(B\n\u001b$B>S\u001b(B\n\u001b$B>T\u001b(B\n\u001b$B>U\u001b(B\n\u001b$B>V\u001b(B\n\u001b$B>W\u001b(B\n\u001b$B>X\u001b(B\n\u001b$B>Y\u001b(B\n\u001b$B>Z\u001b(B\n\u001b$B>[\u001b(B\n\u001b$B>\\\u001b(B\n\u001b$B>]\u001b(B\n\u001b$B>^\u001b(B\n\u001b$B>_\u001b(B\n\u001b$B>`\u001b(B\n\u001b$B>a\u001b(B\n\u001b$B>b\u001b(B\n\u001b$B>c\u001b(B\n\u001b$B>d\u001b(B\n\u001b$B>e\u001b(B\n\u001b$B>f\u001b(B\n\u001b$B>g\u001b(B\n\u001b$B>h\u001b(B\n\u001b$B>i\u001b(B\n\u001b$B>j\u001b(B\n\u001b$B>k\u001b(B\n\u001b$B>l\u001b(B\n\u001b$B>m\u001b(B\n\u001b$B>n\u001b(B\n\u001b$B>o\u001b(B\n\u001b$B>p\u001b(B\n\u001b$B>q\u001b(B\n\u001b$B>r\u001b(B\n\u001b$B>s\u001b(B\n\u001b$B>t\u001b(B\n\u001b$B>u\u001b(B\n\u001b$B>v\u001b(B\n\u001b$B>w\u001b(B\n\u001b$B>x\u001b(B\n\u001b$B>y\u001b(B\n\u001b$B>z\u001b(B\n\u001b$B>{\u001b(B\n\u001b$B>|\u001b(B\n\u001b$B>}\u001b(B\n\u001b$B>~\u001b(B\n\u001b$B?!\u001b(B\n\u001b$B?\"\u001b(B\n\u001b$B?#\u001b(B\n\u001b$B?$\u001b(B\n\u001b$B?%\u001b(B\n\u001b$B?&\u001b(B\n\u001b$B?'\u001b(B\n\u001b$B?(\u001b(B\n\u001b$B?)\u001b(B\n\u001b$B?*\u001b(B\n\u001b$B?+\u001b(B\n\u001b$B?,\u001b(B\n\u001b$B?-\u001b(B\n\u001b$B?.\u001b(B\n\u001b$B?/\u001b(B\n\u001b$B?0\u001b(B\n\u001b$B?1\u001b(B\n\u001b$B?2\u001b(B\n\u001b$B?3\u001b(B\n\u001b$B?4\u001b(B\n\u001b$B?5\u001b(B\n\u001b$B?6\u001b(B\n\u001b$B?7\u001b(B\n\u001b$B?8\u001b(B\n\u001b$B?9\u001b(B\n\u001b$B?:\u001b(B\n\u001b$B?;\u001b(B\n\u001b$B?<\u001b(B\n\u001b$B?=\u001b(B\n\u001b$B?>\u001b(B\n\u001b$B??\u001b(B\n\u001b$B?@\u001b(B\n\u001b$B?A\u001b(B\n\u001b$B?B\u001b(B\n\u001b$B?C\u001b(B\n\u001b$B?D\u001b(B\n\u001b$B?E\u001b(B\n\u001b$B?F\u001b(B\n\u001b$B?G\u001b(B\n\u001b$B?H\u001b(B\n\u001b$B?I\u001b(B\n\u001b$B?J\u001b(B\n\u001b$B?K\u001b(B\n\u001b$B?L\u001b(B\n\u001b$B?M\u001b(B\n\u001b$B?N\u001b(B\n\u001b$B?O\u001b(B\n\u001b$B?P\u001b(B\n\u001b$B?Q\u001b(B\n\u001b$B?R\u001b(B\n\u001b$B?S\u001b(B\n\u001b$B?T\u001b(B\n\u001b$B?U\u001b(B\n\u001b$B?V\u001b(B\n\u001b$B?W\u001b(B\n\u001b$B?X\u001b(B\n\u001b$B?Y\u001b(B\n\u001b$B?Z\u001b(B\n\u001b$B?[\u001b(B\n\u001b$B?\\\u001b(B\n\u001b$B?]\u001b(B\n\u001b$B?^\u001b(B\n\u001b$B?_\u001b(B\n\u001b$B?`\u001b(B\n\u001b$B?a\u001b(B\n\u001b$B?b\u001b(B\n\u001b$B?c\u001b(B\n\u001b$B?d\u001b(B\n\u001b$B?e\u001b(B\n\u001b$B?f\u001b(B\n\u001b$B?g\u001b(B\n\u001b$B?h\u001b(B\n\u001b$B?i\u001b(B\n\u001b$B?j\u001b(B\n\u001b$B?k\u001b(B\n\u001b$B?l\u001b(B\n\u001b$B?m\u001b(B\n\u001b$B?n\u001b(B\n\u001b$B?o\u001b(B\n\u001b$B?p\u001b(B\n\u001b$B?q\u001b(B\n\u001b$B?r\u001b(B\n\u001b$B?s\u001b(B\n\u001b$B?t\u001b(B\n\u001b$B?u\u001b(B\n\u001b$B?v\u001b(B\n\u001b$B?w\u001b(B\n\u001b$B?x\u001b(B\n\u001b$B?y\u001b(B\n\u001b$B?z\u001b(B\n\u001b$B?{\u001b(B\n\u001b$B?|\u001b(B\n\u001b$B?}\u001b(B\n\u001b$B?~\u001b(B\n\u001b$B@!\u001b(B\n\u001b$B@\"\u001b(B\n\u001b$B@#\u001b(B\n\u001b$B@$\u001b(B\n\u001b$B@%\u001b(B\n\u001b$B@&\u001b(B\n\u001b$B@'\u001b(B\n\u001b$B@(\u001b(B\n\u001b$B@)\u001b(B\n\u001b$B@*\u001b(B\n\u001b$B@+\u001b(B\n\u001b$B@,\u001b(B\n\u001b$B@-\u001b(B\n\u001b$B@.\u001b(B\n\u001b$B@/\u001b(B\n\u001b$B@0\u001b(B\n\u001b$B@1\u001b(B\n\u001b$B@2\u001b(B\n\u001b$B@3\u001b(B\n\u001b$B@4\u001b(B\n\u001b$B@5\u001b(B\n\u001b$B@6\u001b(B\n\u001b$B@7\u001b(B\n\u001b$B@8\u001b(B\n\u001b$B@9\u001b(B\n\u001b$B@:\u001b(B\n\u001b$B@;\u001b(B\n\u001b$B@<\u001b(B\n\u001b$B@=\u001b(B\n\u001b$B@>\u001b(B\n\u001b$B@?\u001b(B\n\u001b$B@@\u001b(B\n\u001b$B@A\u001b(B\n\u001b$B@B\u001b(B\n\u001b$B@C\u001b(B\n\u001b$B@D\u001b(B\n\u001b$B@E\u001b(B\n\u001b$B@F\u001b(B\n\u001b$B@G\u001b(B\n\u001b$B@H\u001b(B\n\u001b$B@I\u001b(B\n\u001b$B@J\u001b(B\n\u001b$B@K\u001b(B\n\u001b$B@L\u001b(B\n\u001b$B@M\u001b(B\n\u001b$B@N\u001b(B\n\u001b$B@O\u001b(B\n\u001b$B@P\u001b(B\n\u001b$B@Q\u001b(B\n\u001b$B@R\u001b(B\n\u001b$B@S\u001b(B\n\u001b$B@T\u001b(B\n\u001b$B@U\u001b(B\n\u001b$B@V\u001b(B\n\u001b$B@W\u001b(B\n\u001b$B@X\u001b(B\n\u001b$B@Y\u001b(B\n\u001b$B@Z\u001b(B\n\u001b$B@[\u001b(B\n\u001b$B@\\\u001b(B\n\u001b$B@]\u001b(B\n\u001b$B@^\u001b(B\n\u001b$B@_\u001b(B\n\u001b$B@`\u001b(B\n\u001b$B@a\u001b(B\n\u001b$B@b\u001b(B\n\u001b$B@c\u001b(B\n\u001b$B@d\u001b(B\n\u001b$B@e\u001b(B\n\u001b$B@f\u001b(B\n\u001b$B@g\u001b(B\n\u001b$B@h\u001b(B\n\u001b$B@i\u001b(B\n\u001b$B@j\u001b(B\n\u001b$B@k\u001b(B\n\u001b$B@l\u001b(B\n\u001b$B@m\u001b(B\n\u001b$B@n\u001b(B\n\u001b$B@o\u001b(B\n\u001b$B@p\u001b(B\n\u001b$B@q\u001b(B\n\u001b$B@r\u001b(B\n\u001b$B@s\u001b(B\n\u001b$B@t\u001b(B\n\u001b$B@u\u001b(B\n\u001b$B@v\u001b(B\n\u001b$B@w\u001b(B\n\u001b$B@x\u001b(B\n\u001b$B@y\u001b(B\n\u001b$B@z\u001b(B\n\u001b$B@{\u001b(B\n\u001b$B@|\u001b(B\n\u001b$B@}\u001b(B\n\u001b$B@~\u001b(B\n\u001b$BA!\u001b(B\n\u001b$BA\"\u001b(B\n\u001b$BA#\u001b(B\n\u001b$BA$\u001b(B\n\u001b$BA%\u001b(B\n\u001b$BA&\u001b(B\n\u001b$BA'\u001b(B\n\u001b$BA(\u001b(B\n\u001b$BA)\u001b(B\n\u001b$BA*\u001b(B\n\u001b$BA+\u001b(B\n\u001b$BA,\u001b(B\n\u001b$BA-\u001b(B\n\u001b$BA.\u001b(B\n\u001b$BA/\u001b(B\n\u001b$BA0\u001b(B\n\u001b$BA1\u001b(B\n\u001b$BA2\u001b(B\n\u001b$BA3\u001b(B\n\u001b$BA4\u001b(B\n\u001b$BA5\u001b(B\n\u001b$BA6\u001b(B\n\u001b$BA7\u001b(B\n\u001b$BA8\u001b(B\n\u001b$BA9\u001b(B\n\u001b$BA:\u001b(B\n\u001b$BA;\u001b(B\n\u001b$BA<\u001b(B\n\u001b$BA=\u001b(B\n\u001b$BA>\u001b(B\n\u001b$BA?\u001b(B\n\u001b$BA@\u001b(B\n\u001b$BAA\u001b(B\n\u001b$BAB\u001b(B\n\u001b$BAC\u001b(B\n\u001b$BAD\u001b(B\n\u001b$BAE\u001b(B\n\u001b$BAF\u001b(B\n\u001b$BAG\u001b(B\n\u001b$BAH\u001b(B\n\u001b$BAI\u001b(B\n\u001b$BAJ\u001b(B\n\u001b$BAK\u001b(B\n\u001b$BAL\u001b(B\n\u001b$BAM\u001b(B\n\u001b$BAN\u001b(B\n\u001b$BAO\u001b(B\n\u001b$BAP\u001b(B\n\u001b$BAQ\u001b(B\n\u001b$BAR\u001b(B\n\u001b$BAS\u001b(B\n\u001b$BAT\u001b(B\n\u001b$BAU\u001b(B\n\u001b$BAV\u001b(B\n\u001b$BAW\u001b(B\n\u001b$BAX\u001b(B\n\u001b$BAY\u001b(B\n\u001b$BAZ\u001b(B\n\u001b$BA[\u001b(B\n\u001b$BA\\\u001b(B\n\u001b$BA]\u001b(B\n\u001b$BA^\u001b(B\n\u001b$BA_\u001b(B\n\u001b$BA`\u001b(B\n\u001b$BAa\u001b(B\n\u001b$BAb\u001b(B\n\u001b$BAc\u001b(B\n\u001b$BAd\u001b(B\n\u001b$BAe\u001b(B\n\u001b$BAf\u001b(B\n\u001b$BAg\u001b(B\n\u001b$BAh\u001b(B\n\u001b$BAi\u001b(B\n\u001b$BAj\u001b(B\n\u001b$BAk\u001b(B\n\u001b$BAl\u001b(B\n\u001b$BAm\u001b(B\n\u001b$BAn\u001b(B\n\u001b$BAo\u001b(B\n\u001b$BAp\u001b(B\n\u001b$BAq\u001b(B\n\u001b$BAr\u001b(B\n\u001b$BAs\u001b(B\n\u001b$BAt\u001b(B\n\u001b$BAu\u001b(B\n\u001b$BAv\u001b(B\n\u001b$BAw\u001b(B\n\u001b$BAx\u001b(B\n\u001b$BAy\u001b(B\n\u001b$BAz\u001b(B\n\u001b$BA{\u001b(B\n\u001b$BA|\u001b(B\n\u001b$BA}\u001b(B\n\u001b$BA~\u001b(B\n\u001b$BB!\u001b(B\n\u001b$BB\"\u001b(B\n\u001b$BB#\u001b(B\n\u001b$BB$\u001b(B\n\u001b$BB%\u001b(B\n\u001b$BB&\u001b(B\n\u001b$BB'\u001b(B\n\u001b$BB(\u001b(B\n\u001b$BB)\u001b(B\n\u001b$BB*\u001b(B\n\u001b$BB+\u001b(B\n\u001b$BB,\u001b(B\n\u001b$BB-\u001b(B\n\u001b$BB.\u001b(B\n\u001b$BB/\u001b(B\n\u001b$BB0\u001b(B\n\u001b$BB1\u001b(B\n\u001b$BB2\u001b(B\n\u001b$BB3\u001b(B\n\u001b$BB4\u001b(B\n\u001b$BB5\u001b(B\n\u001b$BB6\u001b(B\n\u001b$BB7\u001b(B\n\u001b$BB8\u001b(B\n\u001b$BB9\u001b(B\n\u001b$BB:\u001b(B\n\u001b$BB;\u001b(B\n\u001b$BB<\u001b(B\n\u001b$BB=\u001b(B\n\u001b$BB>\u001b(B\n\u001b$BB?\u001b(B\n\u001b$BB@\u001b(B\n\u001b$BBA\u001b(B\n\u001b$BBB\u001b(B\n\u001b$BBC\u001b(B\n\u001b$BBD\u001b(B\n\u001b$BBE\u001b(B\n\u001b$BBF\u001b(B\n\u001b$BBG\u001b(B\n\u001b$BBH\u001b(B\n\u001b$BBI\u001b(B\n\u001b$BBJ\u001b(B\n\u001b$BBK\u001b(B\n\u001b$BBL\u001b(B\n\u001b$BBM\u001b(B\n\u001b$BBN\u001b(B\n\u001b$BBO\u001b(B\n\u001b$BBP\u001b(B\n\u001b$BBQ\u001b(B\n\u001b$BBR\u001b(B\n\u001b$BBS\u001b(B\n\u001b$BBT\u001b(B\n\u001b$BBU\u001b(B\n\u001b$BBV\u001b(B\n\u001b$BBW\u001b(B\n\u001b$BBX\u001b(B\n\u001b$BBY\u001b(B\n\u001b$BBZ\u001b(B\n\u001b$BB[\u001b(B\n\u001b$BB\\\u001b(B\n\u001b$BB]\u001b(B\n\u001b$BB^\u001b(B\n\u001b$BB_\u001b(B\n\u001b$BB`\u001b(B\n\u001b$BBa\u001b(B\n\u001b$BBb\u001b(B\n\u001b$BBc\u001b(B\n\u001b$BBd\u001b(B\n\u001b$BBe\u001b(B\n\u001b$BBf\u001b(B\n\u001b$BBg\u001b(B\n\u001b$BBh\u001b(B\n\u001b$BBi\u001b(B\n\u001b$BBj\u001b(B\n\u001b$BBk\u001b(B\n\u001b$BBl\u001b(B\n\u001b$BBm\u001b(B\n\u001b$BBn\u001b(B\n\u001b$BBo\u001b(B\n\u001b$BBp\u001b(B\n\u001b$BBq\u001b(B\n\u001b$BBr\u001b(B\n\u001b$BBs\u001b(B\n\u001b$BBt\u001b(B\n\u001b$BBu\u001b(B\n\u001b$BBv\u001b(B\n\u001b$BBw\u001b(B\n\u001b$BBx\u001b(B\n\u001b$BBy\u001b(B\n\u001b$BBz\u001b(B\n\u001b$BB{\u001b(B\n\u001b$BB|\u001b(B\n\u001b$BB}\u001b(B\n\u001b$BB~\u001b(B\n\u001b$BC!\u001b(B\n\u001b$BC\"\u001b(B\n\u001b$BC#\u001b(B\n\u001b$BC$\u001b(B\n\u001b$BC%\u001b(B\n\u001b$BC&\u001b(B\n\u001b$BC'\u001b(B\n\u001b$BC(\u001b(B\n\u001b$BC)\u001b(B\n\u001b$BC*\u001b(B\n\u001b$BC+\u001b(B\n\u001b$BC,\u001b(B\n\u001b$BC-\u001b(B\n\u001b$BC.\u001b(B\n\u001b$BC/\u001b(B\n\u001b$BC0\u001b(B\n\u001b$BC1\u001b(B\n\u001b$BC2\u001b(B\n\u001b$BC3\u001b(B\n\u001b$BC4\u001b(B\n\u001b$BC5\u001b(B\n\u001b$BC6\u001b(B\n\u001b$BC7\u001b(B\n\u001b$BC8\u001b(B\n\u001b$BC9\u001b(B\n\u001b$BC:\u001b(B\n\u001b$BC;\u001b(B\n\u001b$BC<\u001b(B\n\u001b$BC=\u001b(B\n\u001b$BC>\u001b(B\n\u001b$BC?\u001b(B\n\u001b$BC@\u001b(B\n\u001b$BCA\u001b(B\n\u001b$BCB\u001b(B\n\u001b$BCC\u001b(B\n\u001b$BCD\u001b(B\n\u001b$BCE\u001b(B\n\u001b$BCF\u001b(B\n\u001b$BCG\u001b(B\n\u001b$BCH\u001b(B\n\u001b$BCI\u001b(B\n\u001b$BCJ\u001b(B\n\u001b$BCK\u001b(B\n\u001b$BCL\u001b(B\n\u001b$BCM\u001b(B\n\u001b$BCN\u001b(B\n\u001b$BCO\u001b(B\n\u001b$BCP\u001b(B\n\u001b$BCQ\u001b(B\n\u001b$BCR\u001b(B\n\u001b$BCS\u001b(B\n\u001b$BCT\u001b(B\n\u001b$BCU\u001b(B\n\u001b$BCV\u001b(B\n\u001b$BCW\u001b(B\n\u001b$BCX\u001b(B\n\u001b$BCY\u001b(B\n\u001b$BCZ\u001b(B\n\u001b$BC[\u001b(B\n\u001b$BC\\\u001b(B\n\u001b$BC]\u001b(B\n\u001b$BC^\u001b(B\n\u001b$BC_\u001b(B\n\u001b$BC`\u001b(B\n\u001b$BCa\u001b(B\n\u001b$BCb\u001b(B\n\u001b$BCc\u001b(B\n\u001b$BCd\u001b(B\n\u001b$BCe\u001b(B\n\u001b$BCf\u001b(B\n\u001b$BCg\u001b(B\n\u001b$BCh\u001b(B\n\u001b$BCi\u001b(B\n\u001b$BCj\u001b(B\n\u001b$BCk\u001b(B\n\u001b$BCl\u001b(B\n\u001b$BCm\u001b(B\n\u001b$BCn\u001b(B\n\u001b$BCo\u001b(B\n\u001b$BCp\u001b(B\n\u001b$BCq\u001b(B\n\u001b$BCr\u001b(B\n\u001b$BCs\u001b(B\n\u001b$BCt\u001b(B\n\u001b$BCu\u001b(B\n\u001b$BCv\u001b(B\n\u001b$BCw\u001b(B\n\u001b$BCx\u001b(B\n\u001b$BCy\u001b(B\n\u001b$BCz\u001b(B\n\u001b$BC{\u001b(B\n\u001b$BC|\u001b(B\n\u001b$BC}\u001b(B\n\u001b$BC~\u001b(B\n\u001b$BD!\u001b(B\n\u001b$BD\"\u001b(B\n\u001b$BD#\u001b(B\n\u001b$BD$\u001b(B\n\u001b$BD%\u001b(B\n\u001b$BD&\u001b(B\n\u001b$BD'\u001b(B\n\u001b$BD(\u001b(B\n\u001b$BD)\u001b(B\n\u001b$BD*\u001b(B\n\u001b$BD+\u001b(B\n\u001b$BD,\u001b(B\n\u001b$BD-\u001b(B\n\u001b$BD.\u001b(B\n\u001b$BD/\u001b(B\n\u001b$BD0\u001b(B\n\u001b$BD1\u001b(B\n\u001b$BD2\u001b(B\n\u001b$BD3\u001b(B\n\u001b$BD4\u001b(B\n\u001b$BD5\u001b(B\n\u001b$BD6\u001b(B\n\u001b$BD7\u001b(B\n\u001b$BD8\u001b(B\n\u001b$BD9\u001b(B\n\u001b$BD:\u001b(B\n\u001b$BD;\u001b(B\n\u001b$BD<\u001b(B\n\u001b$BD=\u001b(B\n\u001b$BD>\u001b(B\n\u001b$BD?\u001b(B\n\u001b$BD@\u001b(B\n\u001b$BDA\u001b(B\n\u001b$BDB\u001b(B\n\u001b$BDC\u001b(B\n\u001b$BDD\u001b(B\n\u001b$BDE\u001b(B\n\u001b$BDF\u001b(B\n\u001b$BDG\u001b(B\n\u001b$BDH\u001b(B\n\u001b$BDI\u001b(B\n\u001b$BDJ\u001b(B\n\u001b$BDK\u001b(B\n\u001b$BDL\u001b(B\n\u001b$BDM\u001b(B\n\u001b$BDN\u001b(B\n\u001b$BDO\u001b(B\n\u001b$BDP\u001b(B\n\u001b$BDQ\u001b(B\n\u001b$BDR\u001b(B\n\u001b$BDS\u001b(B\n\u001b$BDT\u001b(B\n\u001b$BDU\u001b(B\n\u001b$BDV\u001b(B\n\u001b$BDW\u001b(B\n\u001b$BDX\u001b(B\n\u001b$BDY\u001b(B\n\u001b$BDZ\u001b(B\n\u001b$BD[\u001b(B\n\u001b$BD\\\u001b(B\n\u001b$BD]\u001b(B\n\u001b$BD^\u001b(B\n\u001b$BD_\u001b(B\n\u001b$BD`\u001b(B\n\u001b$BDa\u001b(B\n\u001b$BDb\u001b(B\n\u001b$BDc\u001b(B\n\u001b$BDd\u001b(B\n\u001b$BDe\u001b(B\n\u001b$BDf\u001b(B\n\u001b$BDg\u001b(B\n\u001b$BDh\u001b(B\n\u001b$BDi\u001b(B\n\u001b$BDj\u001b(B\n\u001b$BDk\u001b(B\n\u001b$BDl\u001b(B\n\u001b$BDm\u001b(B\n\u001b$BDn\u001b(B\n\u001b$BDo\u001b(B\n\u001b$BDp\u001b(B\n\u001b$BDq\u001b(B\n\u001b$BDr\u001b(B\n\u001b$BDs\u001b(B\n\u001b$BDt\u001b(B\n\u001b$BDu\u001b(B\n\u001b$BDv\u001b(B\n\u001b$BDw\u001b(B\n\u001b$BDx\u001b(B\n\u001b$BDy\u001b(B\n\u001b$BDz\u001b(B\n\u001b$BD{\u001b(B\n\u001b$BD|\u001b(B\n\u001b$BD}\u001b(B\n\u001b$BD~\u001b(B\n\u001b$BE!\u001b(B\n\u001b$BE\"\u001b(B\n\u001b$BE#\u001b(B\n\u001b$BE$\u001b(B\n\u001b$BE%\u001b(B\n\u001b$BE&\u001b(B\n\u001b$BE'\u001b(B\n\u001b$BE(\u001b(B\n\u001b$BE)\u001b(B\n\u001b$BE*\u001b(B\n\u001b$BE+\u001b(B\n\u001b$BE,\u001b(B\n\u001b$BE-\u001b(B\n\u001b$BE.\u001b(B\n\u001b$BE/\u001b(B\n\u001b$BE0\u001b(B\n\u001b$BE1\u001b(B\n\u001b$BE2\u001b(B\n\u001b$BE3\u001b(B\n\u001b$BE4\u001b(B\n\u001b$BE5\u001b(B\n\u001b$BE6\u001b(B\n\u001b$BE7\u001b(B\n\u001b$BE8\u001b(B\n\u001b$BE9\u001b(B\n\u001b$BE:\u001b(B\n\u001b$BE;\u001b(B\n\u001b$BE<\u001b(B\n\u001b$BE=\u001b(B\n\u001b$BE>\u001b(B\n\u001b$BE?\u001b(B\n\u001b$BE@\u001b(B\n\u001b$BEA\u001b(B\n\u001b$BEB\u001b(B\n\u001b$BEC\u001b(B\n\u001b$BED\u001b(B\n\u001b$BEE\u001b(B\n\u001b$BEF\u001b(B\n\u001b$BEG\u001b(B\n\u001b$BEH\u001b(B\n\u001b$BEI\u001b(B\n\u001b$BEJ\u001b(B\n\u001b$BEK\u001b(B\n\u001b$BEL\u001b(B\n\u001b$BEM\u001b(B\n\u001b$BEN\u001b(B\n\u001b$BEO\u001b(B\n\u001b$BEP\u001b(B\n\u001b$BEQ\u001b(B\n\u001b$BER\u001b(B\n\u001b$BES\u001b(B\n\u001b$BET\u001b(B\n\u001b$BEU\u001b(B\n\u001b$BEV\u001b(B\n\u001b$BEW\u001b(B\n\u001b$BEX\u001b(B\n\u001b$BEY\u001b(B\n\u001b$BEZ\u001b(B\n\u001b$BE[\u001b(B\n\u001b$BE\\\u001b(B\n\u001b$BE]\u001b(B\n\u001b$BE^\u001b(B\n\u001b$BE_\u001b(B\n\u001b$BE`\u001b(B\n\u001b$BEa\u001b(B\n\u001b$BEb\u001b(B\n\u001b$BEc\u001b(B\n\u001b$BEd\u001b(B\n\u001b$BEe\u001b(B\n\u001b$BEf\u001b(B\n\u001b$BEg\u001b(B\n\u001b$BEh\u001b(B\n\u001b$BEi\u001b(B\n\u001b$BEj\u001b(B\n\u001b$BEk\u001b(B\n\u001b$BEl\u001b(B\n\u001b$BEm\u001b(B\n\u001b$BEn\u001b(B\n\u001b$BEo\u001b(B\n\u001b$BEp\u001b(B\n\u001b$BEq\u001b(B\n\u001b$BEr\u001b(B\n\u001b$BEs\u001b(B\n\u001b$BEt\u001b(B\n\u001b$BEu\u001b(B\n\u001b$BEv\u001b(B\n\u001b$BEw\u001b(B\n\u001b$BEx\u001b(B\n\u001b$BEy\u001b(B\n\u001b$BEz\u001b(B\n\u001b$BE{\u001b(B\n\u001b$BE|\u001b(B\n\u001b$BE}\u001b(B\n\u001b$BE~\u001b(B\n\u001b$BF!\u001b(B\n\u001b$BF\"\u001b(B\n\u001b$BF#\u001b(B\n\u001b$BF$\u001b(B\n\u001b$BF%\u001b(B\n\u001b$BF&\u001b(B\n\u001b$BF'\u001b(B\n\u001b$BF(\u001b(B\n\u001b$BF)\u001b(B\n\u001b$BF*\u001b(B\n\u001b$BF+\u001b(B\n\u001b$BF,\u001b(B\n\u001b$BF-\u001b(B\n\u001b$BF.\u001b(B\n\u001b$BF/\u001b(B\n\u001b$BF0\u001b(B\n\u001b$BF1\u001b(B\n\u001b$BF2\u001b(B\n\u001b$BF3\u001b(B\n\u001b$BF4\u001b(B\n\u001b$BF5\u001b(B\n\u001b$BF6\u001b(B\n\u001b$BF7\u001b(B\n\u001b$BF8\u001b(B\n\u001b$BF9\u001b(B\n\u001b$BF:\u001b(B\n\u001b$BF;\u001b(B\n\u001b$BF<\u001b(B\n\u001b$BF=\u001b(B\n\u001b$BF>\u001b(B\n\u001b$BF?\u001b(B\n\u001b$BF@\u001b(B\n\u001b$BFA\u001b(B\n\u001b$BFB\u001b(B\n\u001b$BFC\u001b(B\n\u001b$BFD\u001b(B\n\u001b$BFE\u001b(B\n\u001b$BFF\u001b(B\n\u001b$BFG\u001b(B\n\u001b$BFH\u001b(B\n\u001b$BFI\u001b(B\n\u001b$BFJ\u001b(B\n\u001b$BFK\u001b(B\n\u001b$BFL\u001b(B\n\u001b$BFM\u001b(B\n\u001b$BFN\u001b(B\n\u001b$BFO\u001b(B\n\u001b$BFP\u001b(B\n\u001b$BFQ\u001b(B\n\u001b$BFR\u001b(B\n\u001b$BFS\u001b(B\n\u001b$BFT\u001b(B\n\u001b$BFU\u001b(B\n\u001b$BFV\u001b(B\n\u001b$BFW\u001b(B\n\u001b$BFX\u001b(B\n\u001b$BFY\u001b(B\n\u001b$BFZ\u001b(B\n\u001b$BF[\u001b(B\n\u001b$BF\\\u001b(B\n\u001b$BF]\u001b(B\n\u001b$BF^\u001b(B\n\u001b$BF_\u001b(B\n\u001b$BF`\u001b(B\n\u001b$BFa\u001b(B\n\u001b$BFb\u001b(B\n\u001b$BFc\u001b(B\n\u001b$BFd\u001b(B\n\u001b$BFe\u001b(B\n\u001b$BFf\u001b(B\n\u001b$BFg\u001b(B\n\u001b$BFh\u001b(B\n\u001b$BFi\u001b(B\n\u001b$BFj\u001b(B\n\u001b$BFk\u001b(B\n\u001b$BFl\u001b(B\n\u001b$BFm\u001b(B\n\u001b$BFn\u001b(B\n\u001b$BFo\u001b(B\n\u001b$BFp\u001b(B\n\u001b$BFq\u001b(B\n\u001b$BFr\u001b(B\n\u001b$BFs\u001b(B\n\u001b$BFt\u001b(B\n\u001b$BFu\u001b(B\n\u001b$BFv\u001b(B\n\u001b$BFw\u001b(B\n\u001b$BFx\u001b(B\n\u001b$BFy\u001b(B\n\u001b$BFz\u001b(B\n\u001b$BF{\u001b(B\n\u001b$BF|\u001b(B\n\u001b$BF}\u001b(B\n\u001b$BF~\u001b(B\n\u001b$BG!\u001b(B\n\u001b$BG\"\u001b(B\n\u001b$BG#\u001b(B\n\u001b$BG$\u001b(B\n\u001b$BG%\u001b(B\n\u001b$BG&\u001b(B\n\u001b$BG'\u001b(B\n\u001b$BG(\u001b(B\n\u001b$BG)\u001b(B\n\u001b$BG*\u001b(B\n\u001b$BG+\u001b(B\n\u001b$BG,\u001b(B\n\u001b$BG-\u001b(B\n\u001b$BG.\u001b(B\n\u001b$BG/\u001b(B\n\u001b$BG0\u001b(B\n\u001b$BG1\u001b(B\n\u001b$BG2\u001b(B\n\u001b$BG3\u001b(B\n\u001b$BG4\u001b(B\n\u001b$BG5\u001b(B\n\u001b$BG6\u001b(B\n\u001b$BG7\u001b(B\n\u001b$BG8\u001b(B\n\u001b$BG9\u001b(B\n\u001b$BG:\u001b(B\n\u001b$BG;\u001b(B\n\u001b$BG<\u001b(B\n\u001b$BG=\u001b(B\n\u001b$BG>\u001b(B\n\u001b$BG?\u001b(B\n\u001b$BG@\u001b(B\n\u001b$BGA\u001b(B\n\u001b$BGB\u001b(B\n\u001b$BGC\u001b(B\n\u001b$BGD\u001b(B\n\u001b$BGE\u001b(B\n\u001b$BGF\u001b(B\n\u001b$BGG\u001b(B\n\u001b$BGH\u001b(B\n\u001b$BGI\u001b(B\n\u001b$BGJ\u001b(B\n\u001b$BGK\u001b(B\n\u001b$BGL\u001b(B\n\u001b$BGM\u001b(B\n\u001b$BGN\u001b(B\n\u001b$BGO\u001b(B\n\u001b$BGP\u001b(B\n\u001b$BGQ\u001b(B\n\u001b$BGR\u001b(B\n\u001b$BGS\u001b(B\n\u001b$BGT\u001b(B\n\u001b$BGU\u001b(B\n\u001b$BGV\u001b(B\n\u001b$BGW\u001b(B\n\u001b$BGX\u001b(B\n\u001b$BGY\u001b(B\n\u001b$BGZ\u001b(B\n\u001b$BG[\u001b(B\n\u001b$BG\\\u001b(B\n\u001b$BG]\u001b(B\n\u001b$BG^\u001b(B\n\u001b$BG_\u001b(B\n\u001b$BG`\u001b(B\n\u001b$BGa\u001b(B\n\u001b$BGb\u001b(B\n\u001b$BGc\u001b(B\n\u001b$BGd\u001b(B\n\u001b$BGe\u001b(B\n\u001b$BGf\u001b(B\n\u001b$BGg\u001b(B\n\u001b$BGh\u001b(B\n\u001b$BGi\u001b(B\n\u001b$BGj\u001b(B\n\u001b$BGk\u001b(B\n\u001b$BGl\u001b(B\n\u001b$BGm\u001b(B\n\u001b$BGn\u001b(B\n\u001b$BGo\u001b(B\n\u001b$BGp\u001b(B\n\u001b$BGq\u001b(B\n\u001b$BGr\u001b(B\n\u001b$BGs\u001b(B\n\u001b$BGt\u001b(B\n\u001b$BGu\u001b(B\n\u001b$BGv\u001b(B\n\u001b$BGw\u001b(B\n\u001b$BGx\u001b(B\n\u001b$BGy\u001b(B\n\u001b$BGz\u001b(B\n\u001b$BG{\u001b(B\n\u001b$BG|\u001b(B\n\u001b$BG}\u001b(B\n\u001b$BG~\u001b(B\n\u001b$BH!\u001b(B\n\u001b$BH\"\u001b(B\n\u001b$BH#\u001b(B\n\u001b$BH$\u001b(B\n\u001b$BH%\u001b(B\n\u001b$BH&\u001b(B\n\u001b$BH'\u001b(B\n\u001b$BH(\u001b(B\n\u001b$BH)\u001b(B\n\u001b$BH*\u001b(B\n\u001b$BH+\u001b(B\n\u001b$BH,\u001b(B\n\u001b$BH-\u001b(B\n\u001b$BH.\u001b(B\n\u001b$BH/\u001b(B\n\u001b$BH0\u001b(B\n\u001b$BH1\u001b(B\n\u001b$BH2\u001b(B\n\u001b$BH3\u001b(B\n\u001b$BH4\u001b(B\n\u001b$BH5\u001b(B\n\u001b$BH6\u001b(B\n\u001b$BH7\u001b(B\n\u001b$BH8\u001b(B\n\u001b$BH9\u001b(B\n\u001b$BH:\u001b(B\n\u001b$BH;\u001b(B\n\u001b$BH<\u001b(B\n\u001b$BH=\u001b(B\n\u001b$BH>\u001b(B\n\u001b$BH?\u001b(B\n\u001b$BH@\u001b(B\n\u001b$BHA\u001b(B\n\u001b$BHB\u001b(B\n\u001b$BHC\u001b(B\n\u001b$BHD\u001b(B\n\u001b$BHE\u001b(B\n\u001b$BHF\u001b(B\n\u001b$BHG\u001b(B\n\u001b$BHH\u001b(B\n\u001b$BHI\u001b(B\n\u001b$BHJ\u001b(B\n\u001b$BHK\u001b(B\n\u001b$BHL\u001b(B\n\u001b$BHM\u001b(B\n\u001b$BHN\u001b(B\n\u001b$BHO\u001b(B\n\u001b$BHP\u001b(B\n\u001b$BHQ\u001b(B\n\u001b$BHR\u001b(B\n\u001b$BHS\u001b(B\n\u001b$BHT\u001b(B\n\u001b$BHU\u001b(B\n\u001b$BHV\u001b(B\n\u001b$BHW\u001b(B\n\u001b$BHX\u001b(B\n\u001b$BHY\u001b(B\n\u001b$BHZ\u001b(B\n\u001b$BH[\u001b(B\n\u001b$BH\\\u001b(B\n\u001b$BH]\u001b(B\n\u001b$BH^\u001b(B\n\u001b$BH_\u001b(B\n\u001b$BH`\u001b(B\n\u001b$BHa\u001b(B\n\u001b$BHb\u001b(B\n\u001b$BHc\u001b(B\n\u001b$BHd\u001b(B\n\u001b$BHe\u001b(B\n\u001b$BHf\u001b(B\n\u001b$BHg\u001b(B\n\u001b$BHh\u001b(B\n\u001b$BHi\u001b(B\n\u001b$BHj\u001b(B\n\u001b$BHk\u001b(B\n\u001b$BHl\u001b(B\n\u001b$BHm\u001b(B\n\u001b$BHn\u001b(B\n\u001b$BHo\u001b(B\n\u001b$BHp\u001b(B\n\u001b$BHq\u001b(B\n\u001b$BHr\u001b(B\n\u001b$BHs\u001b(B\n\u001b$BHt\u001b(B\n\u001b$BHu\u001b(B\n\u001b$BHv\u001b(B\n\u001b$BHw\u001b(B\n\u001b$BHx\u001b(B\n\u001b$BHy\u001b(B\n\u001b$BHz\u001b(B\n\u001b$BH{\u001b(B\n\u001b$BH|\u001b(B\n\u001b$BH}\u001b(B\n\u001b$BH~\u001b(B\n\u001b$BI!\u001b(B\n\u001b$BI\"\u001b(B\n\u001b$BI#\u001b(B\n\u001b$BI$\u001b(B\n\u001b$BI%\u001b(B\n\u001b$BI&\u001b(B\n\u001b$BI'\u001b(B\n\u001b$BI(\u001b(B\n\u001b$BI)\u001b(B\n\u001b$BI*\u001b(B\n\u001b$BI+\u001b(B\n\u001b$BI,\u001b(B\n\u001b$BI-\u001b(B\n\u001b$BI.\u001b(B\n\u001b$BI/\u001b(B\n\u001b$BI0\u001b(B\n\u001b$BI1\u001b(B\n\u001b$BI2\u001b(B\n\u001b$BI3\u001b(B\n\u001b$BI4\u001b(B\n\u001b$BI5\u001b(B\n\u001b$BI6\u001b(B\n\u001b$BI7\u001b(B\n\u001b$BI8\u001b(B\n\u001b$BI9\u001b(B\n\u001b$BI:\u001b(B\n\u001b$BI;\u001b(B\n\u001b$BI<\u001b(B\n\u001b$BI=\u001b(B\n\u001b$BI>\u001b(B\n\u001b$BI?\u001b(B\n\u001b$BI@\u001b(B\n\u001b$BIA\u001b(B\n\u001b$BIB\u001b(B\n\u001b$BIC\u001b(B\n\u001b$BID\u001b(B\n\u001b$BIE\u001b(B\n\u001b$BIF\u001b(B\n\u001b$BIG\u001b(B\n\u001b$BIH\u001b(B\n\u001b$BII\u001b(B\n\u001b$BIJ\u001b(B\n\u001b$BIK\u001b(B\n\u001b$BIL\u001b(B\n\u001b$BIM\u001b(B\n\u001b$BIN\u001b(B\n\u001b$BIO\u001b(B\n\u001b$BIP\u001b(B\n\u001b$BIQ\u001b(B\n\u001b$BIR\u001b(B\n\u001b$BIS\u001b(B\n\u001b$BIT\u001b(B\n\u001b$BIU\u001b(B\n\u001b$BIV\u001b(B\n\u001b$BIW\u001b(B\n\u001b$BIX\u001b(B\n\u001b$BIY\u001b(B\n\u001b$BIZ\u001b(B\n\u001b$BI[\u001b(B\n\u001b$BI\\\u001b(B\n\u001b$BI]\u001b(B\n\u001b$BI^\u001b(B\n\u001b$BI_\u001b(B\n\u001b$BI`\u001b(B\n\u001b$BIa\u001b(B\n\u001b$BIb\u001b(B\n\u001b$BIc\u001b(B\n\u001b$BId\u001b(B\n\u001b$BIe\u001b(B\n\u001b$BIf\u001b(B\n\u001b$BIg\u001b(B\n\u001b$BIh\u001b(B\n\u001b$BIi\u001b(B\n\u001b$BIj\u001b(B\n\u001b$BIk\u001b(B\n\u001b$BIl\u001b(B\n\u001b$BIm\u001b(B\n\u001b$BIn\u001b(B\n\u001b$BIo\u001b(B\n\u001b$BIp\u001b(B\n\u001b$BIq\u001b(B\n\u001b$BIr\u001b(B\n\u001b$BIs\u001b(B\n\u001b$BIt\u001b(B\n\u001b$BIu\u001b(B\n\u001b$BIv\u001b(B\n\u001b$BIw\u001b(B\n\u001b$BIx\u001b(B\n\u001b$BIy\u001b(B\n\u001b$BIz\u001b(B\n\u001b$BI{\u001b(B\n\u001b$BI|\u001b(B\n\u001b$BI}\u001b(B\n\u001b$BI~\u001b(B\n\u001b$BJ!\u001b(B\n\u001b$BJ\"\u001b(B\n\u001b$BJ#\u001b(B\n\u001b$BJ$\u001b(B\n\u001b$BJ%\u001b(B\n\u001b$BJ&\u001b(B\n\u001b$BJ'\u001b(B\n\u001b$BJ(\u001b(B\n\u001b$BJ)\u001b(B\n\u001b$BJ*\u001b(B\n\u001b$BJ+\u001b(B\n\u001b$BJ,\u001b(B\n\u001b$BJ-\u001b(B\n\u001b$BJ.\u001b(B\n\u001b$BJ/\u001b(B\n\u001b$BJ0\u001b(B\n\u001b$BJ1\u001b(B\n\u001b$BJ2\u001b(B\n\u001b$BJ3\u001b(B\n\u001b$BJ4\u001b(B\n\u001b$BJ5\u001b(B\n\u001b$BJ6\u001b(B\n\u001b$BJ7\u001b(B\n\u001b$BJ8\u001b(B\n\u001b$BJ9\u001b(B\n\u001b$BJ:\u001b(B\n\u001b$BJ;\u001b(B\n\u001b$BJ<\u001b(B\n\u001b$BJ=\u001b(B\n\u001b$BJ>\u001b(B\n\u001b$BJ?\u001b(B\n\u001b$BJ@\u001b(B\n\u001b$BJA\u001b(B\n\u001b$BJB\u001b(B\n\u001b$BJC\u001b(B\n\u001b$BJD\u001b(B\n\u001b$BJE\u001b(B\n\u001b$BJF\u001b(B\n\u001b$BJG\u001b(B\n\u001b$BJH\u001b(B\n\u001b$BJI\u001b(B\n\u001b$BJJ\u001b(B\n\u001b$BJK\u001b(B\n\u001b$BJL\u001b(B\n\u001b$BJM\u001b(B\n\u001b$BJN\u001b(B\n\u001b$BJO\u001b(B\n\u001b$BJP\u001b(B\n\u001b$BJQ\u001b(B\n\u001b$BJR\u001b(B\n\u001b$BJS\u001b(B\n\u001b$BJT\u001b(B\n\u001b$BJU\u001b(B\n\u001b$BJV\u001b(B\n\u001b$BJW\u001b(B\n\u001b$BJX\u001b(B\n\u001b$BJY\u001b(B\n\u001b$BJZ\u001b(B\n\u001b$BJ[\u001b(B\n\u001b$BJ\\\u001b(B\n\u001b$BJ]\u001b(B\n\u001b$BJ^\u001b(B\n\u001b$BJ_\u001b(B\n\u001b$BJ`\u001b(B\n\u001b$BJa\u001b(B\n\u001b$BJb\u001b(B\n\u001b$BJc\u001b(B\n\u001b$BJd\u001b(B\n\u001b$BJe\u001b(B\n\u001b$BJf\u001b(B\n\u001b$BJg\u001b(B\n\u001b$BJh\u001b(B\n\u001b$BJi\u001b(B\n\u001b$BJj\u001b(B\n\u001b$BJk\u001b(B\n\u001b$BJl\u001b(B\n\u001b$BJm\u001b(B\n\u001b$BJn\u001b(B\n\u001b$BJo\u001b(B\n\u001b$BJp\u001b(B\n\u001b$BJq\u001b(B\n\u001b$BJr\u001b(B\n\u001b$BJs\u001b(B\n\u001b$BJt\u001b(B\n\u001b$BJu\u001b(B\n\u001b$BJv\u001b(B\n\u001b$BJw\u001b(B\n\u001b$BJx\u001b(B\n\u001b$BJy\u001b(B\n\u001b$BJz\u001b(B\n\u001b$BJ{\u001b(B\n\u001b$BJ|\u001b(B\n\u001b$BJ}\u001b(B\n\u001b$BJ~\u001b(B\n\u001b$BK!\u001b(B\n\u001b$BK\"\u001b(B\n\u001b$BK#\u001b(B\n\u001b$BK$\u001b(B\n\u001b$BK%\u001b(B\n\u001b$BK&\u001b(B\n\u001b$BK'\u001b(B\n\u001b$BK(\u001b(B\n\u001b$BK)\u001b(B\n\u001b$BK*\u001b(B\n\u001b$BK+\u001b(B\n\u001b$BK,\u001b(B\n\u001b$BK-\u001b(B\n\u001b$BK.\u001b(B\n\u001b$BK/\u001b(B\n\u001b$BK0\u001b(B\n\u001b$BK1\u001b(B\n\u001b$BK2\u001b(B\n\u001b$BK3\u001b(B\n\u001b$BK4\u001b(B\n\u001b$BK5\u001b(B\n\u001b$BK6\u001b(B\n\u001b$BK7\u001b(B\n\u001b$BK8\u001b(B\n\u001b$BK9\u001b(B\n\u001b$BK:\u001b(B\n\u001b$BK;\u001b(B\n\u001b$BK<\u001b(B\n\u001b$BK=\u001b(B\n\u001b$BK>\u001b(B\n\u001b$BK?\u001b(B\n\u001b$BK@\u001b(B\n\u001b$BKA\u001b(B\n\u001b$BKB\u001b(B\n\u001b$BKC\u001b(B\n\u001b$BKD\u001b(B\n\u001b$BKE\u001b(B\n\u001b$BKF\u001b(B\n\u001b$BKG\u001b(B\n\u001b$BKH\u001b(B\n\u001b$BKI\u001b(B\n\u001b$BKJ\u001b(B\n\u001b$BKK\u001b(B\n\u001b$BKL\u001b(B\n\u001b$BKM\u001b(B\n\u001b$BKN\u001b(B\n\u001b$BKO\u001b(B\n\u001b$BKP\u001b(B\n\u001b$BKQ\u001b(B\n\u001b$BKR\u001b(B\n\u001b$BKS\u001b(B\n\u001b$BKT\u001b(B\n\u001b$BKU\u001b(B\n\u001b$BKV\u001b(B\n\u001b$BKW\u001b(B\n\u001b$BKX\u001b(B\n\u001b$BKY\u001b(B\n\u001b$BKZ\u001b(B\n\u001b$BK[\u001b(B\n\u001b$BK\\\u001b(B\n\u001b$BK]\u001b(B\n\u001b$BK^\u001b(B\n\u001b$BK_\u001b(B\n\u001b$BK`\u001b(B\n\u001b$BKa\u001b(B\n\u001b$BKb\u001b(B\n\u001b$BKc\u001b(B\n\u001b$BKd\u001b(B\n\u001b$BKe\u001b(B\n\u001b$BKf\u001b(B\n\u001b$BKg\u001b(B\n\u001b$BKh\u001b(B\n\u001b$BKi\u001b(B\n\u001b$BKj\u001b(B\n\u001b$BKk\u001b(B\n\u001b$BKl\u001b(B\n\u001b$BKm\u001b(B\n\u001b$BKn\u001b(B\n\u001b$BKo\u001b(B\n\u001b$BKp\u001b(B\n\u001b$BKq\u001b(B\n\u001b$BKr\u001b(B\n\u001b$BKs\u001b(B\n\u001b$BKt\u001b(B\n\u001b$BKu\u001b(B\n\u001b$BKv\u001b(B\n\u001b$BKw\u001b(B\n\u001b$BKx\u001b(B\n\u001b$BKy\u001b(B\n\u001b$BKz\u001b(B\n\u001b$BK{\u001b(B\n\u001b$BK|\u001b(B\n\u001b$BK}\u001b(B\n\u001b$BK~\u001b(B\n\u001b$BL!\u001b(B\n\u001b$BL\"\u001b(B\n\u001b$BL#\u001b(B\n\u001b$BL$\u001b(B\n\u001b$BL%\u001b(B\n\u001b$BL&\u001b(B\n\u001b$BL'\u001b(B\n\u001b$BL(\u001b(B\n\u001b$BL)\u001b(B\n\u001b$BL*\u001b(B\n\u001b$BL+\u001b(B\n\u001b$BL,\u001b(B\n\u001b$BL-\u001b(B\n\u001b$BL.\u001b(B\n\u001b$BL/\u001b(B\n\u001b$BL0\u001b(B\n\u001b$BL1\u001b(B\n\u001b$BL2\u001b(B\n\u001b$BL3\u001b(B\n\u001b$BL4\u001b(B\n\u001b$BL5\u001b(B\n\u001b$BL6\u001b(B\n\u001b$BL7\u001b(B\n\u001b$BL8\u001b(B\n\u001b$BL9\u001b(B\n\u001b$BL:\u001b(B\n\u001b$BL;\u001b(B\n\u001b$BL<\u001b(B\n\u001b$BL=\u001b(B\n\u001b$BL>\u001b(B\n\u001b$BL?\u001b(B\n\u001b$BL@\u001b(B\n\u001b$BLA\u001b(B\n\u001b$BLB\u001b(B\n\u001b$BLC\u001b(B\n\u001b$BLD\u001b(B\n\u001b$BLE\u001b(B\n\u001b$BLF\u001b(B\n\u001b$BLG\u001b(B\n\u001b$BLH\u001b(B\n\u001b$BLI\u001b(B\n\u001b$BLJ\u001b(B\n\u001b$BLK\u001b(B\n\u001b$BLL\u001b(B\n\u001b$BLM\u001b(B\n\u001b$BLN\u001b(B\n\u001b$BLO\u001b(B\n\u001b$BLP\u001b(B\n\u001b$BLQ\u001b(B\n\u001b$BLR\u001b(B\n\u001b$BLS\u001b(B\n\u001b$BLT\u001b(B\n\u001b$BLU\u001b(B\n\u001b$BLV\u001b(B\n\u001b$BLW\u001b(B\n\u001b$BLX\u001b(B\n\u001b$BLY\u001b(B\n\u001b$BLZ\u001b(B\n\u001b$BL[\u001b(B\n\u001b$BL\\\u001b(B\n\u001b$BL]\u001b(B\n\u001b$BL^\u001b(B\n\u001b$BL_\u001b(B\n\u001b$BL`\u001b(B\n\u001b$BLa\u001b(B\n\u001b$BLb\u001b(B\n\u001b$BLc\u001b(B\n\u001b$BLd\u001b(B\n\u001b$BLe\u001b(B\n\u001b$BLf\u001b(B\n\u001b$BLg\u001b(B\n\u001b$BLh\u001b(B\n\u001b$BLi\u001b(B\n\u001b$BLj\u001b(B\n\u001b$BLk\u001b(B\n\u001b$BLl\u001b(B\n\u001b$BLm\u001b(B\n\u001b$BLn\u001b(B\n\u001b$BLo\u001b(B\n\u001b$BLp\u001b(B\n\u001b$BLq\u001b(B\n\u001b$BLr\u001b(B\n\u001b$BLs\u001b(B\n\u001b$BLt\u001b(B\n\u001b$BLu\u001b(B\n\u001b$BLv\u001b(B\n\u001b$BLw\u001b(B\n\u001b$BLx\u001b(B\n\u001b$BLy\u001b(B\n\u001b$BLz\u001b(B\n\u001b$BL{\u001b(B\n\u001b$BL|\u001b(B\n\u001b$BL}\u001b(B\n\u001b$BL~\u001b(B\n\u001b$BM!\u001b(B\n\u001b$BM\"\u001b(B\n\u001b$BM#\u001b(B\n\u001b$BM$\u001b(B\n\u001b$BM%\u001b(B\n\u001b$BM&\u001b(B\n\u001b$BM'\u001b(B\n\u001b$BM(\u001b(B\n\u001b$BM)\u001b(B\n\u001b$BM*\u001b(B\n\u001b$BM+\u001b(B\n\u001b$BM,\u001b(B\n\u001b$BM-\u001b(B\n\u001b$BM.\u001b(B\n\u001b$BM/\u001b(B\n\u001b$BM0\u001b(B\n\u001b$BM1\u001b(B\n\u001b$BM2\u001b(B\n\u001b$BM3\u001b(B\n\u001b$BM4\u001b(B\n\u001b$BM5\u001b(B\n\u001b$BM6\u001b(B\n\u001b$BM7\u001b(B\n\u001b$BM8\u001b(B\n\u001b$BM9\u001b(B\n\u001b$BM:\u001b(B\n\u001b$BM;\u001b(B\n\u001b$BM<\u001b(B\n\u001b$BM=\u001b(B\n\u001b$BM>\u001b(B\n\u001b$BM?\u001b(B\n\u001b$BM@\u001b(B\n\u001b$BMA\u001b(B\n\u001b$BMB\u001b(B\n\u001b$BMC\u001b(B\n\u001b$BMD\u001b(B\n\u001b$BME\u001b(B\n\u001b$BMF\u001b(B\n\u001b$BMG\u001b(B\n\u001b$BMH\u001b(B\n\u001b$BMI\u001b(B\n\u001b$BMJ\u001b(B\n\u001b$BMK\u001b(B\n\u001b$BML\u001b(B\n\u001b$BMM\u001b(B\n\u001b$BMN\u001b(B\n\u001b$BMO\u001b(B\n\u001b$BMP\u001b(B\n\u001b$BMQ\u001b(B\n\u001b$BMR\u001b(B\n\u001b$BMS\u001b(B\n\u001b$BMT\u001b(B\n\u001b$BMU\u001b(B\n\u001b$BMV\u001b(B\n\u001b$BMW\u001b(B\n\u001b$BMX\u001b(B\n\u001b$BMY\u001b(B\n\u001b$BMZ\u001b(B\n\u001b$BM[\u001b(B\n\u001b$BM\\\u001b(B\n\u001b$BM]\u001b(B\n\u001b$BM^\u001b(B\n\u001b$BM_\u001b(B\n\u001b$BM`\u001b(B\n\u001b$BMa\u001b(B\n\u001b$BMb\u001b(B\n\u001b$BMc\u001b(B\n\u001b$BMd\u001b(B\n\u001b$BMe\u001b(B\n\u001b$BMf\u001b(B\n\u001b$BMg\u001b(B\n\u001b$BMh\u001b(B\n\u001b$BMi\u001b(B\n\u001b$BMj\u001b(B\n\u001b$BMk\u001b(B\n\u001b$BMl\u001b(B\n\u001b$BMm\u001b(B\n\u001b$BMn\u001b(B\n\u001b$BMo\u001b(B\n\u001b$BMp\u001b(B\n\u001b$BMq\u001b(B\n\u001b$BMr\u001b(B\n\u001b$BMs\u001b(B\n\u001b$BMt\u001b(B\n\u001b$BMu\u001b(B\n\u001b$BMv\u001b(B\n\u001b$BMw\u001b(B\n\u001b$BMx\u001b(B\n\u001b$BMy\u001b(B\n\u001b$BMz\u001b(B\n\u001b$BM{\u001b(B\n\u001b$BM|\u001b(B\n\u001b$BM}\u001b(B\n\u001b$BM~\u001b(B\n\u001b$BN!\u001b(B\n\u001b$BN\"\u001b(B\n\u001b$BN#\u001b(B\n\u001b$BN$\u001b(B\n\u001b$BN%\u001b(B\n\u001b$BN&\u001b(B\n\u001b$BN'\u001b(B\n\u001b$BN(\u001b(B\n\u001b$BN)\u001b(B\n\u001b$BN*\u001b(B\n\u001b$BN+\u001b(B\n\u001b$BN,\u001b(B\n\u001b$BN-\u001b(B\n\u001b$BN.\u001b(B\n\u001b$BN/\u001b(B\n\u001b$BN0\u001b(B\n\u001b$BN1\u001b(B\n\u001b$BN2\u001b(B\n\u001b$BN3\u001b(B\n\u001b$BN4\u001b(B\n\u001b$BN5\u001b(B\n\u001b$BN6\u001b(B\n\u001b$BN7\u001b(B\n\u001b$BN8\u001b(B\n\u001b$BN9\u001b(B\n\u001b$BN:\u001b(B\n\u001b$BN;\u001b(B\n\u001b$BN<\u001b(B\n\u001b$BN=\u001b(B\n\u001b$BN>\u001b(B\n\u001b$BN?\u001b(B\n\u001b$BN@\u001b(B\n\u001b$BNA\u001b(B\n\u001b$BNB\u001b(B\n\u001b$BNC\u001b(B\n\u001b$BND\u001b(B\n\u001b$BNE\u001b(B\n\u001b$BNF\u001b(B\n\u001b$BNG\u001b(B\n\u001b$BNH\u001b(B\n\u001b$BNI\u001b(B\n\u001b$BNJ\u001b(B\n\u001b$BNK\u001b(B\n\u001b$BNL\u001b(B\n\u001b$BNM\u001b(B\n\u001b$BNN\u001b(B\n\u001b$BNO\u001b(B\n\u001b$BNP\u001b(B\n\u001b$BNQ\u001b(B\n\u001b$BNR\u001b(B\n\u001b$BNS\u001b(B\n\u001b$BNT\u001b(B\n\u001b$BNU\u001b(B\n\u001b$BNV\u001b(B\n\u001b$BNW\u001b(B\n\u001b$BNX\u001b(B\n\u001b$BNY\u001b(B\n\u001b$BNZ\u001b(B\n\u001b$BN[\u001b(B\n\u001b$BN\\\u001b(B\n\u001b$BN]\u001b(B\n\u001b$BN^\u001b(B\n\u001b$BN_\u001b(B\n\u001b$BN`\u001b(B\n\u001b$BNa\u001b(B\n\u001b$BNb\u001b(B\n\u001b$BNc\u001b(B\n\u001b$BNd\u001b(B\n\u001b$BNe\u001b(B\n\u001b$BNf\u001b(B\n\u001b$BNg\u001b(B\n\u001b$BNh\u001b(B\n\u001b$BNi\u001b(B\n\u001b$BNj\u001b(B\n\u001b$BNk\u001b(B\n\u001b$BNl\u001b(B\n\u001b$BNm\u001b(B\n\u001b$BNn\u001b(B\n\u001b$BNo\u001b(B\n\u001b$BNp\u001b(B\n\u001b$BNq\u001b(B\n\u001b$BNr\u001b(B\n\u001b$BNs\u001b(B\n\u001b$BNt\u001b(B\n\u001b$BNu\u001b(B\n\u001b$BNv\u001b(B\n\u001b$BNw\u001b(B\n\u001b$BNx\u001b(B\n\u001b$BNy\u001b(B\n\u001b$BNz\u001b(B\n\u001b$BN{\u001b(B\n\u001b$BN|\u001b(B\n\u001b$BN}\u001b(B\n\u001b$BN~\u001b(B\n\u001b$BO!\u001b(B\n\u001b$BO\"\u001b(B\n\u001b$BO#\u001b(B\n\u001b$BO$\u001b(B\n\u001b$BO%\u001b(B\n\u001b$BO&\u001b(B\n\u001b$BO'\u001b(B\n\u001b$BO(\u001b(B\n\u001b$BO)\u001b(B\n\u001b$BO*\u001b(B\n\u001b$BO+\u001b(B\n\u001b$BO,\u001b(B\n\u001b$BO-\u001b(B\n\u001b$BO.\u001b(B\n\u001b$BO/\u001b(B\n\u001b$BO0\u001b(B\n\u001b$BO1\u001b(B\n\u001b$BO2\u001b(B\n\u001b$BO3\u001b(B\n\u001b$BO4\u001b(B\n\u001b$BO5\u001b(B\n\u001b$BO6\u001b(B\n\u001b$BO7\u001b(B\n\u001b$BO8\u001b(B\n\u001b$BO9\u001b(B\n\u001b$BO:\u001b(B\n\u001b$BO;\u001b(B\n\u001b$BO<\u001b(B\n\u001b$BO=\u001b(B\n\u001b$BO>\u001b(B\n\u001b$BO?\u001b(B\n\u001b$BO@\u001b(B\n\u001b$BOA\u001b(B\n\u001b$BOB\u001b(B\n\u001b$BOC\u001b(B\n\u001b$BOD\u001b(B\n\u001b$BOE\u001b(B\n\u001b$BOF\u001b(B\n\u001b$BOG\u001b(B\n\u001b$BOH\u001b(B\n\u001b$BOI\u001b(B\n\u001b$BOJ\u001b(B\n\u001b$BOK\u001b(B\n\u001b$BOL\u001b(B\n\u001b$BOM\u001b(B\n\u001b$BON\u001b(B\n\u001b$BOO\u001b(B\n\u001b$BOP\u001b(B\n\u001b$BOQ\u001b(B\n\u001b$BOR\u001b(B\n\u001b$BOS\u001b(B\n\u001b$BP!\u001b(B\n\u001b$BP\"\u001b(B\n\u001b$BP#\u001b(B\n\u001b$BP$\u001b(B\n\u001b$BP%\u001b(B\n\u001b$BP&\u001b(B\n\u001b$BP'\u001b(B\n\u001b$BP(\u001b(B\n\u001b$BP)\u001b(B\n\u001b$BP*\u001b(B\n\u001b$BP+\u001b(B\n\u001b$BP,\u001b(B\n\u001b$BP-\u001b(B\n\u001b$BP.\u001b(B\n\u001b$BP/\u001b(B\n\u001b$BP0\u001b(B\n\u001b$BP1\u001b(B\n\u001b$BP2\u001b(B\n\u001b$BP3\u001b(B\n\u001b$BP4\u001b(B\n\u001b$BP5\u001b(B\n\u001b$BP6\u001b(B\n\u001b$BP7\u001b(B\n\u001b$BP8\u001b(B\n\u001b$BP9\u001b(B\n\u001b$BP:\u001b(B\n\u001b$BP;\u001b(B\n\u001b$BP<\u001b(B\n\u001b$BP=\u001b(B\n\u001b$BP>\u001b(B\n\u001b$BP?\u001b(B\n\u001b$BP@\u001b(B\n\u001b$BPA\u001b(B\n\u001b$BPB\u001b(B\n\u001b$BPC\u001b(B\n\u001b$BPD\u001b(B\n\u001b$BPE\u001b(B\n\u001b$BPF\u001b(B\n\u001b$BPG\u001b(B\n\u001b$BPH\u001b(B\n\u001b$BPI\u001b(B\n\u001b$BPJ\u001b(B\n\u001b$BPK\u001b(B\n\u001b$BPL\u001b(B\n\u001b$BPM\u001b(B\n\u001b$BPN\u001b(B\n\u001b$BPO\u001b(B\n\u001b$BPP\u001b(B\n\u001b$BPQ\u001b(B\n\u001b$BPR\u001b(B\n\u001b$BPS\u001b(B\n\u001b$BPT\u001b(B\n\u001b$BPU\u001b(B\n\u001b$BPV\u001b(B\n\u001b$BPW\u001b(B\n\u001b$BPX\u001b(B\n\u001b$BPY\u001b(B\n\u001b$BPZ\u001b(B\n\u001b$BP[\u001b(B\n\u001b$BP\\\u001b(B\n\u001b$BP]\u001b(B\n\u001b$BP^\u001b(B\n\u001b$BP_\u001b(B\n\u001b$BP`\u001b(B\n\u001b$BPa\u001b(B\n\u001b$BPb\u001b(B\n\u001b$BPc\u001b(B\n\u001b$BPd\u001b(B\n\u001b$BPe\u001b(B\n\u001b$BPf\u001b(B\n\u001b$BPg\u001b(B\n\u001b$BPh\u001b(B\n\u001b$BPi\u001b(B\n\u001b$BPj\u001b(B\n\u001b$BPk\u001b(B\n\u001b$BPl\u001b(B\n\u001b$BPm\u001b(B\n\u001b$BPn\u001b(B\n\u001b$BPo\u001b(B\n\u001b$BPp\u001b(B\n\u001b$BPq\u001b(B\n\u001b$BPr\u001b(B\n\u001b$BPs\u001b(B\n\u001b$BPt\u001b(B\n\u001b$BPu\u001b(B\n\u001b$BPv\u001b(B\n\u001b$BPw\u001b(B\n\u001b$BPx\u001b(B\n\u001b$BPy\u001b(B\n\u001b$BPz\u001b(B\n\u001b$BP{\u001b(B\n\u001b$BP|\u001b(B\n\u001b$BP}\u001b(B\n\u001b$BP~\u001b(B\n\u001b$BQ!\u001b(B\n\u001b$BQ\"\u001b(B\n\u001b$BQ#\u001b(B\n\u001b$BQ$\u001b(B\n\u001b$BQ%\u001b(B\n\u001b$BQ&\u001b(B\n\u001b$BQ'\u001b(B\n\u001b$BQ(\u001b(B\n\u001b$BQ)\u001b(B\n\u001b$BQ*\u001b(B\n\u001b$BQ+\u001b(B\n\u001b$BQ,\u001b(B\n\u001b$BQ-\u001b(B\n\u001b$BQ.\u001b(B\n\u001b$BQ/\u001b(B\n\u001b$BQ0\u001b(B\n\u001b$BQ1\u001b(B\n\u001b$BQ2\u001b(B\n\u001b$BQ3\u001b(B\n\u001b$BQ4\u001b(B\n\u001b$BQ5\u001b(B\n\u001b$BQ6\u001b(B\n\u001b$BQ7\u001b(B\n\u001b$BQ8\u001b(B\n\u001b$BQ9\u001b(B\n\u001b$BQ:\u001b(B\n\u001b$BQ;\u001b(B\n\u001b$BQ<\u001b(B\n\u001b$BQ=\u001b(B\n\u001b$BQ>\u001b(B\n\u001b$BQ?\u001b(B\n\u001b$BQ@\u001b(B\n\u001b$BQA\u001b(B\n\u001b$BQB\u001b(B\n\u001b$BQC\u001b(B\n\u001b$BQD\u001b(B\n\u001b$BQE\u001b(B\n\u001b$BQF\u001b(B\n\u001b$BQG\u001b(B\n\u001b$BQH\u001b(B\n\u001b$BQI\u001b(B\n\u001b$BQJ\u001b(B\n\u001b$BQK\u001b(B\n\u001b$BQL\u001b(B\n\u001b$BQM\u001b(B\n\u001b$BQN\u001b(B\n\u001b$BQO\u001b(B\n\u001b$BQP\u001b(B\n\u001b$BQQ\u001b(B\n\u001b$BQR\u001b(B\n\u001b$BQS\u001b(B\n\u001b$BQT\u001b(B\n\u001b$BQU\u001b(B\n\u001b$BQV\u001b(B\n\u001b$BQW\u001b(B\n\u001b$BQX\u001b(B\n\u001b$BQY\u001b(B\n\u001b$BQZ\u001b(B\n\u001b$BQ[\u001b(B\n\u001b$BQ\\\u001b(B\n\u001b$BQ]\u001b(B\n\u001b$BQ^\u001b(B\n\u001b$BQ_\u001b(B\n\u001b$BQ`\u001b(B\n\u001b$BQa\u001b(B\n\u001b$BQb\u001b(B\n\u001b$BQc\u001b(B\n\u001b$BQd\u001b(B\n\u001b$BQe\u001b(B\n\u001b$BQf\u001b(B\n\u001b$BQg\u001b(B\n\u001b$BQh\u001b(B\n\u001b$BQi\u001b(B\n\u001b$BQj\u001b(B\n\u001b$BQk\u001b(B\n\u001b$BQl\u001b(B\n\u001b$BQm\u001b(B\n\u001b$BQn\u001b(B\n\u001b$BQo\u001b(B\n\u001b$BQp\u001b(B\n\u001b$BQq\u001b(B\n\u001b$BQr\u001b(B\n\u001b$BQs\u001b(B\n\u001b$BQt\u001b(B\n\u001b$BQu\u001b(B\n\u001b$BQv\u001b(B\n\u001b$BQw\u001b(B\n\u001b$BQx\u001b(B\n\u001b$BQy\u001b(B\n\u001b$BQz\u001b(B\n\u001b$BQ{\u001b(B\n\u001b$BQ|\u001b(B\n\u001b$BQ}\u001b(B\n\u001b$BQ~\u001b(B\n\u001b$BR!\u001b(B\n\u001b$BR\"\u001b(B\n\u001b$BR#\u001b(B\n\u001b$BR$\u001b(B\n\u001b$BR%\u001b(B\n\u001b$BR&\u001b(B\n\u001b$BR'\u001b(B\n\u001b$BR(\u001b(B\n\u001b$BR)\u001b(B\n\u001b$BR*\u001b(B\n\u001b$BR+\u001b(B\n\u001b$BR,\u001b(B\n\u001b$BR-\u001b(B\n\u001b$BR.\u001b(B\n\u001b$BR/\u001b(B\n\u001b$BR0\u001b(B\n\u001b$BR1\u001b(B\n\u001b$BR2\u001b(B\n\u001b$BR3\u001b(B\n\u001b$BR4\u001b(B\n\u001b$BR5\u001b(B\n\u001b$BR6\u001b(B\n\u001b$BR7\u001b(B\n\u001b$BR8\u001b(B\n\u001b$BR9\u001b(B\n\u001b$BR:\u001b(B\n\u001b$BR;\u001b(B\n\u001b$BR<\u001b(B\n\u001b$BR=\u001b(B\n\u001b$BR>\u001b(B\n\u001b$BR?\u001b(B\n\u001b$BR@\u001b(B\n\u001b$BRA\u001b(B\n\u001b$BRB\u001b(B\n\u001b$BRC\u001b(B\n\u001b$BRD\u001b(B\n\u001b$BRE\u001b(B\n\u001b$BRF\u001b(B\n\u001b$BRG\u001b(B\n\u001b$BRH\u001b(B\n\u001b$BRI\u001b(B\n\u001b$BRJ\u001b(B\n\u001b$BRK\u001b(B\n\u001b$BRL\u001b(B\n\u001b$BRM\u001b(B\n\u001b$BRN\u001b(B\n\u001b$BRO\u001b(B\n\u001b$BRP\u001b(B\n\u001b$BRQ\u001b(B\n\u001b$BRR\u001b(B\n\u001b$BRS\u001b(B\n\u001b$BRT\u001b(B\n\u001b$BRU\u001b(B\n\u001b$BRV\u001b(B\n\u001b$BRW\u001b(B\n\u001b$BRX\u001b(B\n\u001b$BRY\u001b(B\n\u001b$BRZ\u001b(B\n\u001b$BR[\u001b(B\n\u001b$BR\\\u001b(B\n\u001b$BR]\u001b(B\n\u001b$BR^\u001b(B\n\u001b$BR_\u001b(B\n\u001b$BR`\u001b(B\n\u001b$BRa\u001b(B\n\u001b$BRb\u001b(B\n\u001b$BRc\u001b(B\n\u001b$BRd\u001b(B\n\u001b$BRe\u001b(B\n\u001b$BRf\u001b(B\n\u001b$BRg\u001b(B\n\u001b$BRh\u001b(B\n\u001b$BRi\u001b(B\n\u001b$BRj\u001b(B\n\u001b$BRk\u001b(B\n\u001b$BRl\u001b(B\n\u001b$BRm\u001b(B\n\u001b$BRn\u001b(B\n\u001b$BRo\u001b(B\n\u001b$BRp\u001b(B\n\u001b$BRq\u001b(B\n\u001b$BRr\u001b(B\n\u001b$BRs\u001b(B\n\u001b$BRt\u001b(B\n\u001b$BRu\u001b(B\n\u001b$BRv\u001b(B\n\u001b$BRw\u001b(B\n\u001b$BRx\u001b(B\n\u001b$BRy\u001b(B\n\u001b$BRz\u001b(B\n\u001b$BR{\u001b(B\n\u001b$BR|\u001b(B\n\u001b$BR}\u001b(B\n\u001b$BR~\u001b(B\n\u001b$BS!\u001b(B\n\u001b$BS\"\u001b(B\n\u001b$BS#\u001b(B\n\u001b$BS$\u001b(B\n\u001b$BS%\u001b(B\n\u001b$BS&\u001b(B\n\u001b$BS'\u001b(B\n\u001b$BS(\u001b(B\n\u001b$BS)\u001b(B\n\u001b$BS*\u001b(B\n\u001b$BS+\u001b(B\n\u001b$BS,\u001b(B\n\u001b$BS-\u001b(B\n\u001b$BS.\u001b(B\n\u001b$BS/\u001b(B\n\u001b$BS0\u001b(B\n\u001b$BS1\u001b(B\n\u001b$BS2\u001b(B\n\u001b$BS3\u001b(B\n\u001b$BS4\u001b(B\n\u001b$BS5\u001b(B\n\u001b$BS6\u001b(B\n\u001b$BS7\u001b(B\n\u001b$BS8\u001b(B\n\u001b$BS9\u001b(B\n\u001b$BS:\u001b(B\n\u001b$BS;\u001b(B\n\u001b$BS<\u001b(B\n\u001b$BS=\u001b(B\n\u001b$BS>\u001b(B\n\u001b$BS?\u001b(B\n\u001b$BS@\u001b(B\n\u001b$BSA\u001b(B\n\u001b$BSB\u001b(B\n\u001b$BSC\u001b(B\n\u001b$BSD\u001b(B\n\u001b$BSE\u001b(B\n\u001b$BSF\u001b(B\n\u001b$BSG\u001b(B\n\u001b$BSH\u001b(B\n\u001b$BSI\u001b(B\n\u001b$BSJ\u001b(B\n\u001b$BSK\u001b(B\n\u001b$BSL\u001b(B\n\u001b$BSM\u001b(B\n\u001b$BSN\u001b(B\n\u001b$BSO\u001b(B\n\u001b$BSP\u001b(B\n\u001b$BSQ\u001b(B\n\u001b$BSR\u001b(B\n\u001b$BSS\u001b(B\n\u001b$BST\u001b(B\n\u001b$BSU\u001b(B\n\u001b$BSV\u001b(B\n\u001b$BSW\u001b(B\n\u001b$BSX\u001b(B\n\u001b$BSY\u001b(B\n\u001b$BSZ\u001b(B\n\u001b$BS[\u001b(B\n\u001b$BS\\\u001b(B\n\u001b$BS]\u001b(B\n\u001b$BS^\u001b(B\n\u001b$BS_\u001b(B\n\u001b$BS`\u001b(B\n\u001b$BSa\u001b(B\n\u001b$BSb\u001b(B\n\u001b$BSc\u001b(B\n\u001b$BSd\u001b(B\n\u001b$BSe\u001b(B\n\u001b$BSf\u001b(B\n\u001b$BSg\u001b(B\n\u001b$BSh\u001b(B\n\u001b$BSi\u001b(B\n\u001b$BSj\u001b(B\n\u001b$BSk\u001b(B\n\u001b$BSl\u001b(B\n\u001b$BSm\u001b(B\n\u001b$BSn\u001b(B\n\u001b$BSo\u001b(B\n\u001b$BSp\u001b(B\n\u001b$BSq\u001b(B\n\u001b$BSr\u001b(B\n\u001b$BSs\u001b(B\n\u001b$BSt\u001b(B\n\u001b$BSu\u001b(B\n\u001b$BSv\u001b(B\n\u001b$BSw\u001b(B\n\u001b$BSx\u001b(B\n\u001b$BSy\u001b(B\n\u001b$BSz\u001b(B\n\u001b$BS{\u001b(B\n\u001b$BS|\u001b(B\n\u001b$BS}\u001b(B\n\u001b$BS~\u001b(B\n\u001b$BT!\u001b(B\n\u001b$BT\"\u001b(B\n\u001b$BT#\u001b(B\n\u001b$BT$\u001b(B\n\u001b$BT%\u001b(B\n\u001b$BT&\u001b(B\n\u001b$BT'\u001b(B\n\u001b$BT(\u001b(B\n\u001b$BT)\u001b(B\n\u001b$BT*\u001b(B\n\u001b$BT+\u001b(B\n\u001b$BT,\u001b(B\n\u001b$BT-\u001b(B\n\u001b$BT.\u001b(B\n\u001b$BT/\u001b(B\n\u001b$BT0\u001b(B\n\u001b$BT1\u001b(B\n\u001b$BT2\u001b(B\n\u001b$BT3\u001b(B\n\u001b$BT4\u001b(B\n\u001b$BT5\u001b(B\n\u001b$BT6\u001b(B\n\u001b$BT7\u001b(B\n\u001b$BT8\u001b(B\n\u001b$BT9\u001b(B\n\u001b$BT:\u001b(B\n\u001b$BT;\u001b(B\n\u001b$BT<\u001b(B\n\u001b$BT=\u001b(B\n\u001b$BT>\u001b(B\n\u001b$BT?\u001b(B\n\u001b$BT@\u001b(B\n\u001b$BTA\u001b(B\n\u001b$BTB\u001b(B\n\u001b$BTC\u001b(B\n\u001b$BTD\u001b(B\n\u001b$BTE\u001b(B\n\u001b$BTF\u001b(B\n\u001b$BTG\u001b(B\n\u001b$BTH\u001b(B\n\u001b$BTI\u001b(B\n\u001b$BTJ\u001b(B\n\u001b$BTK\u001b(B\n\u001b$BTL\u001b(B\n\u001b$BTM\u001b(B\n\u001b$BTN\u001b(B\n\u001b$BTO\u001b(B\n\u001b$BTP\u001b(B\n\u001b$BTQ\u001b(B\n\u001b$BTR\u001b(B\n\u001b$BTS\u001b(B\n\u001b$BTT\u001b(B\n\u001b$BTU\u001b(B\n\u001b$BTV\u001b(B\n\u001b$BTW\u001b(B\n\u001b$BTX\u001b(B\n\u001b$BTY\u001b(B\n\u001b$BTZ\u001b(B\n\u001b$BT[\u001b(B\n\u001b$BT\\\u001b(B\n\u001b$BT]\u001b(B\n\u001b$BT^\u001b(B\n\u001b$BT_\u001b(B\n\u001b$BT`\u001b(B\n\u001b$BTa\u001b(B\n\u001b$BTb\u001b(B\n\u001b$BTc\u001b(B\n\u001b$BTd\u001b(B\n\u001b$BTe\u001b(B\n\u001b$BTf\u001b(B\n\u001b$BTg\u001b(B\n\u001b$BTh\u001b(B\n\u001b$BTi\u001b(B\n\u001b$BTj\u001b(B\n\u001b$BTk\u001b(B\n\u001b$BTl\u001b(B\n\u001b$BTm\u001b(B\n\u001b$BTn\u001b(B\n\u001b$BTo\u001b(B\n\u001b$BTp\u001b(B\n\u001b$BTq\u001b(B\n\u001b$BTr\u001b(B\n\u001b$BTs\u001b(B\n\u001b$BTt\u001b(B\n\u001b$BTu\u001b(B\n\u001b$BTv\u001b(B\n\u001b$BTw\u001b(B\n\u001b$BTx\u001b(B\n\u001b$BTy\u001b(B\n\u001b$BTz\u001b(B\n\u001b$BT{\u001b(B\n\u001b$BT|\u001b(B\n\u001b$BT}\u001b(B\n\u001b$BT~\u001b(B\n\u001b$BU!\u001b(B\n\u001b$BU\"\u001b(B\n\u001b$BU#\u001b(B\n\u001b$BU$\u001b(B\n\u001b$BU%\u001b(B\n\u001b$BU&\u001b(B\n\u001b$BU'\u001b(B\n\u001b$BU(\u001b(B\n\u001b$BU)\u001b(B\n\u001b$BU*\u001b(B\n\u001b$BU+\u001b(B\n\u001b$BU,\u001b(B\n\u001b$BU-\u001b(B\n\u001b$BU.\u001b(B\n\u001b$BU/\u001b(B\n\u001b$BU0\u001b(B\n\u001b$BU1\u001b(B\n\u001b$BU2\u001b(B\n\u001b$BU3\u001b(B\n\u001b$BU4\u001b(B\n\u001b$BU5\u001b(B\n\u001b$BU6\u001b(B\n\u001b$BU7\u001b(B\n\u001b$BU8\u001b(B\n\u001b$BU9\u001b(B\n\u001b$BU:\u001b(B\n\u001b$BU;\u001b(B\n\u001b$BU<\u001b(B\n\u001b$BU=\u001b(B\n\u001b$BU>\u001b(B\n\u001b$BU?\u001b(B\n\u001b$BU@\u001b(B\n\u001b$BUA\u001b(B\n\u001b$BUB\u001b(B\n\u001b$BUC\u001b(B\n\u001b$BUD\u001b(B\n\u001b$BUE\u001b(B\n\u001b$BUF\u001b(B\n\u001b$BUG\u001b(B\n\u001b$BUH\u001b(B\n\u001b$BUI\u001b(B\n\u001b$BUJ\u001b(B\n\u001b$BUK\u001b(B\n\u001b$BUL\u001b(B\n\u001b$BUM\u001b(B\n\u001b$BUN\u001b(B\n\u001b$BUO\u001b(B\n\u001b$BUP\u001b(B\n\u001b$BUQ\u001b(B\n\u001b$BUR\u001b(B\n\u001b$BUS\u001b(B\n\u001b$BUT\u001b(B\n\u001b$BUU\u001b(B\n\u001b$BUV\u001b(B\n\u001b$BUW\u001b(B\n\u001b$BUX\u001b(B\n\u001b$BUY\u001b(B\n\u001b$BUZ\u001b(B\n\u001b$BU[\u001b(B\n\u001b$BU\\\u001b(B\n\u001b$BU]\u001b(B\n\u001b$BU^\u001b(B\n\u001b$BU_\u001b(B\n\u001b$BU`\u001b(B\n\u001b$BUa\u001b(B\n\u001b$BUb\u001b(B\n\u001b$BUc\u001b(B\n\u001b$BUd\u001b(B\n\u001b$BUe\u001b(B\n\u001b$BUf\u001b(B\n\u001b$BUg\u001b(B\n\u001b$BUh\u001b(B\n\u001b$BUi\u001b(B\n\u001b$BUj\u001b(B\n\u001b$BUk\u001b(B\n\u001b$BUl\u001b(B\n\u001b$BUm\u001b(B\n\u001b$BUn\u001b(B\n\u001b$BUo\u001b(B\n\u001b$BUp\u001b(B\n\u001b$BUq\u001b(B\n\u001b$BUr\u001b(B\n\u001b$BUs\u001b(B\n\u001b$BUt\u001b(B\n\u001b$BUu\u001b(B\n\u001b$BUv\u001b(B\n\u001b$BUw\u001b(B\n\u001b$BUx\u001b(B\n\u001b$BUy\u001b(B\n\u001b$BUz\u001b(B\n\u001b$BU{\u001b(B\n\u001b$BU|\u001b(B\n\u001b$BU}\u001b(B\n\u001b$BU~\u001b(B\n\u001b$BV!\u001b(B\n\u001b$BV\"\u001b(B\n\u001b$BV#\u001b(B\n\u001b$BV$\u001b(B\n\u001b$BV%\u001b(B\n\u001b$BV&\u001b(B\n\u001b$BV'\u001b(B\n\u001b$BV(\u001b(B\n\u001b$BV)\u001b(B\n\u001b$BV*\u001b(B\n\u001b$BV+\u001b(B\n\u001b$BV,\u001b(B\n\u001b$BV-\u001b(B\n\u001b$BV.\u001b(B\n\u001b$BV/\u001b(B\n\u001b$BV0\u001b(B\n\u001b$BV1\u001b(B\n\u001b$BV2\u001b(B\n\u001b$BV3\u001b(B\n\u001b$BV4\u001b(B\n\u001b$BV5\u001b(B\n\u001b$BV6\u001b(B\n\u001b$BV7\u001b(B\n\u001b$BV8\u001b(B\n\u001b$BV9\u001b(B\n\u001b$BV:\u001b(B\n\u001b$BV;\u001b(B\n\u001b$BV<\u001b(B\n\u001b$BV=\u001b(B\n\u001b$BV>\u001b(B\n\u001b$BV?\u001b(B\n\u001b$BV@\u001b(B\n\u001b$BVA\u001b(B\n\u001b$BVB\u001b(B\n\u001b$BVC\u001b(B\n\u001b$BVD\u001b(B\n\u001b$BVE\u001b(B\n\u001b$BVF\u001b(B\n\u001b$BVG\u001b(B\n\u001b$BVH\u001b(B\n\u001b$BVI\u001b(B\n\u001b$BVJ\u001b(B\n\u001b$BVK\u001b(B\n\u001b$BVL\u001b(B\n\u001b$BVM\u001b(B\n\u001b$BVN\u001b(B\n\u001b$BVO\u001b(B\n\u001b$BVP\u001b(B\n\u001b$BVQ\u001b(B\n\u001b$BVR\u001b(B\n\u001b$BVS\u001b(B\n\u001b$BVT\u001b(B\n\u001b$BVU\u001b(B\n\u001b$BVV\u001b(B\n\u001b$BVW\u001b(B\n\u001b$BVX\u001b(B\n\u001b$BVY\u001b(B\n\u001b$BVZ\u001b(B\n\u001b$BV[\u001b(B\n\u001b$BV\\\u001b(B\n\u001b$BV]\u001b(B\n\u001b$BV^\u001b(B\n\u001b$BV_\u001b(B\n\u001b$BV`\u001b(B\n\u001b$BVa\u001b(B\n\u001b$BVb\u001b(B\n\u001b$BVc\u001b(B\n\u001b$BVd\u001b(B\n\u001b$BVe\u001b(B\n\u001b$BVf\u001b(B\n\u001b$BVg\u001b(B\n\u001b$BVh\u001b(B\n\u001b$BVi\u001b(B\n\u001b$BVj\u001b(B\n\u001b$BVk\u001b(B\n\u001b$BVl\u001b(B\n\u001b$BVm\u001b(B\n\u001b$BVn\u001b(B\n\u001b$BVo\u001b(B\n\u001b$BVp\u001b(B\n\u001b$BVq\u001b(B\n\u001b$BVr\u001b(B\n\u001b$BVs\u001b(B\n\u001b$BVt\u001b(B\n\u001b$BVu\u001b(B\n\u001b$BVv\u001b(B\n\u001b$BVw\u001b(B\n\u001b$BVx\u001b(B\n\u001b$BVy\u001b(B\n\u001b$BVz\u001b(B\n\u001b$BV{\u001b(B\n\u001b$BV|\u001b(B\n\u001b$BV}\u001b(B\n\u001b$BV~\u001b(B\n\u001b$BW!\u001b(B\n\u001b$BW\"\u001b(B\n\u001b$BW#\u001b(B\n\u001b$BW$\u001b(B\n\u001b$BW%\u001b(B\n\u001b$BW&\u001b(B\n\u001b$BW'\u001b(B\n\u001b$BW(\u001b(B\n\u001b$BW)\u001b(B\n\u001b$BW*\u001b(B\n\u001b$BW+\u001b(B\n\u001b$BW,\u001b(B\n\u001b$BW-\u001b(B\n\u001b$BW.\u001b(B\n\u001b$BW/\u001b(B\n\u001b$BW0\u001b(B\n\u001b$BW1\u001b(B\n\u001b$BW2\u001b(B\n\u001b$BW3\u001b(B\n\u001b$BW4\u001b(B\n\u001b$BW5\u001b(B\n\u001b$BW6\u001b(B\n\u001b$BW7\u001b(B\n\u001b$BW8\u001b(B\n\u001b$BW9\u001b(B\n\u001b$BW:\u001b(B\n\u001b$BW;\u001b(B\n\u001b$BW<\u001b(B\n\u001b$BW=\u001b(B\n\u001b$BW>\u001b(B\n\u001b$BW?\u001b(B\n\u001b$BW@\u001b(B\n\u001b$BWA\u001b(B\n\u001b$BWB\u001b(B\n\u001b$BWC\u001b(B\n\u001b$BWD\u001b(B\n\u001b$BWE\u001b(B\n\u001b$BWF\u001b(B\n\u001b$BWG\u001b(B\n\u001b$BWH\u001b(B\n\u001b$BWI\u001b(B\n\u001b$BWJ\u001b(B\n\u001b$BWK\u001b(B\n\u001b$BWL\u001b(B\n\u001b$BWM\u001b(B\n\u001b$BWN\u001b(B\n\u001b$BWO\u001b(B\n\u001b$BWP\u001b(B\n\u001b$BWQ\u001b(B\n\u001b$BWR\u001b(B\n\u001b$BWS\u001b(B\n\u001b$BWT\u001b(B\n\u001b$BWU\u001b(B\n\u001b$BWV\u001b(B\n\u001b$BWW\u001b(B\n\u001b$BWX\u001b(B\n\u001b$BWY\u001b(B\n\u001b$BWZ\u001b(B\n\u001b$BW[\u001b(B\n\u001b$BW\\\u001b(B\n\u001b$BW]\u001b(B\n\u001b$BW^\u001b(B\n\u001b$BW_\u001b(B\n\u001b$BW`\u001b(B\n\u001b$BWa\u001b(B\n\u001b$BWb\u001b(B\n\u001b$BWc\u001b(B\n\u001b$BWd\u001b(B\n\u001b$BWe\u001b(B\n\u001b$BWf\u001b(B\n\u001b$BWg\u001b(B\n\u001b$BWh\u001b(B\n\u001b$BWi\u001b(B\n\u001b$BWj\u001b(B\n\u001b$BWk\u001b(B\n\u001b$BWl\u001b(B\n\u001b$BWm\u001b(B\n\u001b$BWn\u001b(B\n\u001b$BWo\u001b(B\n\u001b$BWp\u001b(B\n\u001b$BWq\u001b(B\n\u001b$BWr\u001b(B\n\u001b$BWs\u001b(B\n\u001b$BWt\u001b(B\n\u001b$BWu\u001b(B\n\u001b$BWv\u001b(B\n\u001b$BWw\u001b(B\n\u001b$BWx\u001b(B\n\u001b$BWy\u001b(B\n\u001b$BWz\u001b(B\n\u001b$BW{\u001b(B\n\u001b$BW|\u001b(B\n\u001b$BW}\u001b(B\n\u001b$BW~\u001b(B\n\u001b$BX!\u001b(B\n\u001b$BX\"\u001b(B\n\u001b$BX#\u001b(B\n\u001b$BX$\u001b(B\n\u001b$BX%\u001b(B\n\u001b$BX&\u001b(B\n\u001b$BX'\u001b(B\n\u001b$BX(\u001b(B\n\u001b$BX)\u001b(B\n\u001b$BX*\u001b(B\n\u001b$BX+\u001b(B\n\u001b$BX,\u001b(B\n\u001b$BX-\u001b(B\n\u001b$BX.\u001b(B\n\u001b$BX/\u001b(B\n\u001b$BX0\u001b(B\n\u001b$BX1\u001b(B\n\u001b$BX2\u001b(B\n\u001b$BX3\u001b(B\n\u001b$BX4\u001b(B\n\u001b$BX5\u001b(B\n\u001b$BX6\u001b(B\n\u001b$BX7\u001b(B\n\u001b$BX8\u001b(B\n\u001b$BX9\u001b(B\n\u001b$BX:\u001b(B\n\u001b$BX;\u001b(B\n\u001b$BX<\u001b(B\n\u001b$BX=\u001b(B\n\u001b$BX>\u001b(B\n\u001b$BX?\u001b(B\n\u001b$BX@\u001b(B\n\u001b$BXA\u001b(B\n\u001b$BXB\u001b(B\n\u001b$BXC\u001b(B\n\u001b$BXD\u001b(B\n\u001b$BXE\u001b(B\n\u001b$BXF\u001b(B\n\u001b$BXG\u001b(B\n\u001b$BXH\u001b(B\n\u001b$BXI\u001b(B\n\u001b$BXJ\u001b(B\n\u001b$BXK\u001b(B\n\u001b$BXL\u001b(B\n\u001b$BXM\u001b(B\n\u001b$BXN\u001b(B\n\u001b$BXO\u001b(B\n\u001b$BXP\u001b(B\n\u001b$BXQ\u001b(B\n\u001b$BXR\u001b(B\n\u001b$BXS\u001b(B\n\u001b$BXT\u001b(B\n\u001b$BXU\u001b(B\n\u001b$BXV\u001b(B\n\u001b$BXW\u001b(B\n\u001b$BXX\u001b(B\n\u001b$BXY\u001b(B\n\u001b$BXZ\u001b(B\n\u001b$BX[\u001b(B\n\u001b$BX\\\u001b(B\n\u001b$BX]\u001b(B\n\u001b$BX^\u001b(B\n\u001b$BX_\u001b(B\n\u001b$BX`\u001b(B\n\u001b$BXa\u001b(B\n\u001b$BXb\u001b(B\n\u001b$BXc\u001b(B\n\u001b$BXd\u001b(B\n\u001b$BXe\u001b(B\n\u001b$BXf\u001b(B\n\u001b$BXg\u001b(B\n\u001b$BXh\u001b(B\n\u001b$BXi\u001b(B\n\u001b$BXj\u001b(B\n\u001b$BXk\u001b(B\n\u001b$BXl\u001b(B\n\u001b$BXm\u001b(B\n\u001b$BXn\u001b(B\n\u001b$BXo\u001b(B\n\u001b$BXp\u001b(B\n\u001b$BXq\u001b(B\n\u001b$BXr\u001b(B\n\u001b$BXs\u001b(B\n\u001b$BXt\u001b(B\n\u001b$BXu\u001b(B\n\u001b$BXv\u001b(B\n\u001b$BXw\u001b(B\n\u001b$BXx\u001b(B\n\u001b$BXy\u001b(B\n\u001b$BXz\u001b(B\n\u001b$BX{\u001b(B\n\u001b$BX|\u001b(B\n\u001b$BX}\u001b(B\n\u001b$BX~\u001b(B\n\u001b$BY!\u001b(B\n\u001b$BY\"\u001b(B\n\u001b$BY#\u001b(B\n\u001b$BY$\u001b(B\n\u001b$BY%\u001b(B\n\u001b$BY&\u001b(B\n\u001b$BY'\u001b(B\n\u001b$BY(\u001b(B\n\u001b$BY)\u001b(B\n\u001b$BY*\u001b(B\n\u001b$BY+\u001b(B\n\u001b$BY,\u001b(B\n\u001b$BY-\u001b(B\n\u001b$BY.\u001b(B\n\u001b$BY/\u001b(B\n\u001b$BY0\u001b(B\n\u001b$BY1\u001b(B\n\u001b$BY2\u001b(B\n\u001b$BY3\u001b(B\n\u001b$BY4\u001b(B\n\u001b$BY5\u001b(B\n\u001b$BY6\u001b(B\n\u001b$BY7\u001b(B\n\u001b$BY8\u001b(B\n\u001b$BY9\u001b(B\n\u001b$BY:\u001b(B\n\u001b$BY;\u001b(B\n\u001b$BY<\u001b(B\n\u001b$BY=\u001b(B\n\u001b$BY>\u001b(B\n\u001b$BY?\u001b(B\n\u001b$BY@\u001b(B\n\u001b$BYA\u001b(B\n\u001b$BYB\u001b(B\n\u001b$BYC\u001b(B\n\u001b$BYD\u001b(B\n\u001b$BYE\u001b(B\n\u001b$BYF\u001b(B\n\u001b$BYG\u001b(B\n\u001b$BYH\u001b(B\n\u001b$BYI\u001b(B\n\u001b$BYJ\u001b(B\n\u001b$BYK\u001b(B\n\u001b$BYL\u001b(B\n\u001b$BYM\u001b(B\n\u001b$BYN\u001b(B\n\u001b$BYO\u001b(B\n\u001b$BYP\u001b(B\n\u001b$BYQ\u001b(B\n\u001b$BYR\u001b(B\n\u001b$BYS\u001b(B\n\u001b$BYT\u001b(B\n\u001b$BYU\u001b(B\n\u001b$BYV\u001b(B\n\u001b$BYW\u001b(B\n\u001b$BYX\u001b(B\n\u001b$BYY\u001b(B\n\u001b$BYZ\u001b(B\n\u001b$BY[\u001b(B\n\u001b$BY\\\u001b(B\n\u001b$BY]\u001b(B\n\u001b$BY^\u001b(B\n\u001b$BY_\u001b(B\n\u001b$BY`\u001b(B\n\u001b$BYa\u001b(B\n\u001b$BYb\u001b(B\n\u001b$BYc\u001b(B\n\u001b$BYd\u001b(B\n\u001b$BYe\u001b(B\n\u001b$BYf\u001b(B\n\u001b$BYg\u001b(B\n\u001b$BYh\u001b(B\n\u001b$BYi\u001b(B\n\u001b$BYj\u001b(B\n\u001b$BYk\u001b(B\n\u001b$BYl\u001b(B\n\u001b$BYm\u001b(B\n\u001b$BYn\u001b(B\n\u001b$BYo\u001b(B\n\u001b$BYp\u001b(B\n\u001b$BYq\u001b(B\n\u001b$BYr\u001b(B\n\u001b$BYs\u001b(B\n\u001b$BYt\u001b(B\n\u001b$BYu\u001b(B\n\u001b$BYv\u001b(B\n\u001b$BYw\u001b(B\n\u001b$BYx\u001b(B\n\u001b$BYy\u001b(B\n\u001b$BYz\u001b(B\n\u001b$BY{\u001b(B\n\u001b$BY|\u001b(B\n\u001b$BY}\u001b(B\n\u001b$BY~\u001b(B\n\u001b$BZ!\u001b(B\n\u001b$BZ\"\u001b(B\n\u001b$BZ#\u001b(B\n\u001b$BZ$\u001b(B\n\u001b$BZ%\u001b(B\n\u001b$BZ&\u001b(B\n\u001b$BZ'\u001b(B\n\u001b$BZ(\u001b(B\n\u001b$BZ)\u001b(B\n\u001b$BZ*\u001b(B\n\u001b$BZ+\u001b(B\n\u001b$BZ,\u001b(B\n\u001b$BZ-\u001b(B\n\u001b$BZ.\u001b(B\n\u001b$BZ/\u001b(B\n\u001b$BZ0\u001b(B\n\u001b$BZ1\u001b(B\n\u001b$BZ2\u001b(B\n\u001b$BZ3\u001b(B\n\u001b$BZ4\u001b(B\n\u001b$BZ5\u001b(B\n\u001b$BZ6\u001b(B\n\u001b$BZ7\u001b(B\n\u001b$BZ8\u001b(B\n\u001b$BZ9\u001b(B\n\u001b$BZ:\u001b(B\n\u001b$BZ;\u001b(B\n\u001b$BZ<\u001b(B\n\u001b$BZ=\u001b(B\n\u001b$BZ>\u001b(B\n\u001b$BZ?\u001b(B\n\u001b$BZ@\u001b(B\n\u001b$BZA\u001b(B\n\u001b$BZB\u001b(B\n\u001b$BZC\u001b(B\n\u001b$BZD\u001b(B\n\u001b$BZE\u001b(B\n\u001b$BZF\u001b(B\n\u001b$BZG\u001b(B\n\u001b$BZH\u001b(B\n\u001b$BZI\u001b(B\n\u001b$BZJ\u001b(B\n\u001b$BZK\u001b(B\n\u001b$BZL\u001b(B\n\u001b$BZM\u001b(B\n\u001b$BZN\u001b(B\n\u001b$BZO\u001b(B\n\u001b$BZP\u001b(B\n\u001b$BZQ\u001b(B\n\u001b$BZR\u001b(B\n\u001b$BZS\u001b(B\n\u001b$BZT\u001b(B\n\u001b$BZU\u001b(B\n\u001b$BZV\u001b(B\n\u001b$BZW\u001b(B\n\u001b$BZX\u001b(B\n\u001b$BZY\u001b(B\n\u001b$BZZ\u001b(B\n\u001b$BZ[\u001b(B\n\u001b$BZ\\\u001b(B\n\u001b$BZ]\u001b(B\n\u001b$BZ^\u001b(B\n\u001b$BZ_\u001b(B\n\u001b$BZ`\u001b(B\n\u001b$BZa\u001b(B\n\u001b$BZb\u001b(B\n\u001b$BZc\u001b(B\n\u001b$BZd\u001b(B\n\u001b$BZe\u001b(B\n\u001b$BZf\u001b(B\n\u001b$BZg\u001b(B\n\u001b$BZh\u001b(B\n\u001b$BZi\u001b(B\n\u001b$BZj\u001b(B\n\u001b$BZk\u001b(B\n\u001b$BZl\u001b(B\n\u001b$BZm\u001b(B\n\u001b$BZn\u001b(B\n\u001b$BZo\u001b(B\n\u001b$BZp\u001b(B\n\u001b$BZq\u001b(B\n\u001b$BZr\u001b(B\n\u001b$BZs\u001b(B\n\u001b$BZt\u001b(B\n\u001b$BZu\u001b(B\n\u001b$BZv\u001b(B\n\u001b$BZw\u001b(B\n\u001b$BZx\u001b(B\n\u001b$BZy\u001b(B\n\u001b$BZz\u001b(B\n\u001b$BZ{\u001b(B\n\u001b$BZ|\u001b(B\n\u001b$BZ}\u001b(B\n\u001b$BZ~\u001b(B\n\u001b$B[!\u001b(B\n\u001b$B[\"\u001b(B\n\u001b$B[#\u001b(B\n\u001b$B[$\u001b(B\n\u001b$B[%\u001b(B\n\u001b$B[&\u001b(B\n\u001b$B['\u001b(B\n\u001b$B[(\u001b(B\n\u001b$B[)\u001b(B\n\u001b$B[*\u001b(B\n\u001b$B[+\u001b(B\n\u001b$B[,\u001b(B\n\u001b$B[-\u001b(B\n\u001b$B[.\u001b(B\n\u001b$B[/\u001b(B\n\u001b$B[0\u001b(B\n\u001b$B[1\u001b(B\n\u001b$B[2\u001b(B\n\u001b$B[3\u001b(B\n\u001b$B[4\u001b(B\n\u001b$B[5\u001b(B\n\u001b$B[6\u001b(B\n\u001b$B[7\u001b(B\n\u001b$B[8\u001b(B\n\u001b$B[9\u001b(B\n\u001b$B[:\u001b(B\n\u001b$B[;\u001b(B\n\u001b$B[<\u001b(B\n\u001b$B[=\u001b(B\n\u001b$B[>\u001b(B\n\u001b$B[?\u001b(B\n\u001b$B[@\u001b(B\n\u001b$B[A\u001b(B\n\u001b$B[B\u001b(B\n\u001b$B[C\u001b(B\n\u001b$B[D\u001b(B\n\u001b$B[E\u001b(B\n\u001b$B[F\u001b(B\n\u001b$B[G\u001b(B\n\u001b$B[H\u001b(B\n\u001b$B[I\u001b(B\n\u001b$B[J\u001b(B\n\u001b$B[K\u001b(B\n\u001b$B[L\u001b(B\n\u001b$B[M\u001b(B\n\u001b$B[N\u001b(B\n\u001b$B[O\u001b(B\n\u001b$B[P\u001b(B\n\u001b$B[Q\u001b(B\n\u001b$B[R\u001b(B\n\u001b$B[S\u001b(B\n\u001b$B[T\u001b(B\n\u001b$B[U\u001b(B\n\u001b$B[V\u001b(B\n\u001b$B[W\u001b(B\n\u001b$B[X\u001b(B\n\u001b$B[Y\u001b(B\n\u001b$B[Z\u001b(B\n\u001b$B[[\u001b(B\n\u001b$B[\\\u001b(B\n\u001b$B[]\u001b(B\n\u001b$B[^\u001b(B\n\u001b$B[_\u001b(B\n\u001b$B[`\u001b(B\n\u001b$B[a\u001b(B\n\u001b$B[b\u001b(B\n\u001b$B[c\u001b(B\n\u001b$B[d\u001b(B\n\u001b$B[e\u001b(B\n\u001b$B[f\u001b(B\n\u001b$B[g\u001b(B\n\u001b$B[h\u001b(B\n\u001b$B[i\u001b(B\n\u001b$B[j\u001b(B\n\u001b$B[k\u001b(B\n\u001b$B[l\u001b(B\n\u001b$B[m\u001b(B\n\u001b$B[n\u001b(B\n\u001b$B[o\u001b(B\n\u001b$B[p\u001b(B\n\u001b$B[q\u001b(B\n\u001b$B[r\u001b(B\n\u001b$B[s\u001b(B\n\u001b$B[t\u001b(B\n\u001b$B[u\u001b(B\n\u001b$B[v\u001b(B\n\u001b$B[w\u001b(B\n\u001b$B[x\u001b(B\n\u001b$B[y\u001b(B\n\u001b$B[z\u001b(B\n\u001b$B[{\u001b(B\n\u001b$B[|\u001b(B\n\u001b$B[}\u001b(B\n\u001b$B[~\u001b(B\n\u001b$B\\!\u001b(B\n\u001b$B\\\"\u001b(B\n\u001b$B\\#\u001b(B\n\u001b$B\\$\u001b(B\n\u001b$B\\%\u001b(B\n\u001b$B\\&\u001b(B\n\u001b$B\\'\u001b(B\n\u001b$B\\(\u001b(B\n\u001b$B\\)\u001b(B\n\u001b$B\\*\u001b(B\n\u001b$B\\+\u001b(B\n\u001b$B\\,\u001b(B\n\u001b$B\\-\u001b(B\n\u001b$B\\.\u001b(B\n\u001b$B\\/\u001b(B\n\u001b$B\\0\u001b(B\n\u001b$B\\1\u001b(B\n\u001b$B\\2\u001b(B\n\u001b$B\\3\u001b(B\n\u001b$B\\4\u001b(B\n\u001b$B\\5\u001b(B\n\u001b$B\\6\u001b(B\n\u001b$B\\7\u001b(B\n\u001b$B\\8\u001b(B\n\u001b$B\\9\u001b(B\n\u001b$B\\:\u001b(B\n\u001b$B\\;\u001b(B\n\u001b$B\\<\u001b(B\n\u001b$B\\=\u001b(B\n\u001b$B\\>\u001b(B\n\u001b$B\\?\u001b(B\n\u001b$B\\@\u001b(B\n\u001b$B\\A\u001b(B\n\u001b$B\\B\u001b(B\n\u001b$B\\C\u001b(B\n\u001b$B\\D\u001b(B\n\u001b$B\\E\u001b(B\n\u001b$B\\F\u001b(B\n\u001b$B\\G\u001b(B\n\u001b$B\\H\u001b(B\n\u001b$B\\I\u001b(B\n\u001b$B\\J\u001b(B\n\u001b$B\\K\u001b(B\n\u001b$B\\L\u001b(B\n\u001b$B\\M\u001b(B\n\u001b$B\\N\u001b(B\n\u001b$B\\O\u001b(B\n\u001b$B\\P\u001b(B\n\u001b$B\\Q\u001b(B\n\u001b$B\\R\u001b(B\n\u001b$B\\S\u001b(B\n\u001b$B\\T\u001b(B\n\u001b$B\\U\u001b(B\n\u001b$B\\V\u001b(B\n\u001b$B\\W\u001b(B\n\u001b$B\\X\u001b(B\n\u001b$B\\Y\u001b(B\n\u001b$B\\Z\u001b(B\n\u001b$B\\[\u001b(B\n\u001b$B\\\\\u001b(B\n\u001b$B\\]\u001b(B\n\u001b$B\\^\u001b(B\n\u001b$B\\_\u001b(B\n\u001b$B\\`\u001b(B\n\u001b$B\\a\u001b(B\n\u001b$B\\b\u001b(B\n\u001b$B\\c\u001b(B\n\u001b$B\\d\u001b(B\n\u001b$B\\e\u001b(B\n\u001b$B\\f\u001b(B\n\u001b$B\\g\u001b(B\n\u001b$B\\h\u001b(B\n\u001b$B\\i\u001b(B\n\u001b$B\\j\u001b(B\n\u001b$B\\k\u001b(B\n\u001b$B\\l\u001b(B\n\u001b$B\\m\u001b(B\n\u001b$B\\n\u001b(B\n\u001b$B\\o\u001b(B\n\u001b$B\\p\u001b(B\n\u001b$B\\q\u001b(B\n\u001b$B\\r\u001b(B\n\u001b$B\\s\u001b(B\n\u001b$B\\t\u001b(B\n\u001b$B\\u\u001b(B\n\u001b$B\\v\u001b(B\n\u001b$B\\w\u001b(B\n\u001b$B\\x\u001b(B\n\u001b$B\\y\u001b(B\n\u001b$B\\z\u001b(B\n\u001b$B\\{\u001b(B\n\u001b$B\\|\u001b(B\n\u001b$B\\}\u001b(B\n\u001b$B\\~\u001b(B\n\u001b$B]!\u001b(B\n\u001b$B]\"\u001b(B\n\u001b$B]#\u001b(B\n\u001b$B]$\u001b(B\n\u001b$B]%\u001b(B\n\u001b$B]&\u001b(B\n\u001b$B]'\u001b(B\n\u001b$B](\u001b(B\n\u001b$B])\u001b(B\n\u001b$B]*\u001b(B\n\u001b$B]+\u001b(B\n\u001b$B],\u001b(B\n\u001b$B]-\u001b(B\n\u001b$B].\u001b(B\n\u001b$B]/\u001b(B\n\u001b$B]0\u001b(B\n\u001b$B]1\u001b(B\n\u001b$B]2\u001b(B\n\u001b$B]3\u001b(B\n\u001b$B]4\u001b(B\n\u001b$B]5\u001b(B\n\u001b$B]6\u001b(B\n\u001b$B]7\u001b(B\n\u001b$B]8\u001b(B\n\u001b$B]9\u001b(B\n\u001b$B]:\u001b(B\n\u001b$B];\u001b(B\n\u001b$B]<\u001b(B\n\u001b$B]=\u001b(B\n\u001b$B]>\u001b(B\n\u001b$B]?\u001b(B\n\u001b$B]@\u001b(B\n\u001b$B]A\u001b(B\n\u001b$B]B\u001b(B\n\u001b$B]C\u001b(B\n\u001b$B]D\u001b(B\n\u001b$B]E\u001b(B\n\u001b$B]F\u001b(B\n\u001b$B]G\u001b(B\n\u001b$B]H\u001b(B\n\u001b$B]I\u001b(B\n\u001b$B]J\u001b(B\n\u001b$B]K\u001b(B\n\u001b$B]L\u001b(B\n\u001b$B]M\u001b(B\n\u001b$B]N\u001b(B\n\u001b$B]O\u001b(B\n\u001b$B]P\u001b(B\n\u001b$B]Q\u001b(B\n\u001b$B]R\u001b(B\n\u001b$B]S\u001b(B\n\u001b$B]T\u001b(B\n\u001b$B]U\u001b(B\n\u001b$B]V\u001b(B\n\u001b$B]W\u001b(B\n\u001b$B]X\u001b(B\n\u001b$B]Y\u001b(B\n\u001b$B]Z\u001b(B\n\u001b$B][\u001b(B\n\u001b$B]\\\u001b(B\n\u001b$B]]\u001b(B\n\u001b$B]^\u001b(B\n\u001b$B]_\u001b(B\n\u001b$B]`\u001b(B\n\u001b$B]a\u001b(B\n\u001b$B]b\u001b(B\n\u001b$B]c\u001b(B\n\u001b$B]d\u001b(B\n\u001b$B]e\u001b(B\n\u001b$B]f\u001b(B\n\u001b$B]g\u001b(B\n\u001b$B]h\u001b(B\n\u001b$B]i\u001b(B\n\u001b$B]j\u001b(B\n\u001b$B]k\u001b(B\n\u001b$B]l\u001b(B\n\u001b$B]m\u001b(B\n\u001b$B]n\u001b(B\n\u001b$B]o\u001b(B\n\u001b$B]p\u001b(B\n\u001b$B]q\u001b(B\n\u001b$B]r\u001b(B\n\u001b$B]s\u001b(B\n\u001b$B]t\u001b(B\n\u001b$B]u\u001b(B\n\u001b$B]v\u001b(B\n\u001b$B]w\u001b(B\n\u001b$B]x\u001b(B\n\u001b$B]y\u001b(B\n\u001b$B]z\u001b(B\n\u001b$B]{\u001b(B\n\u001b$B]|\u001b(B\n\u001b$B]}\u001b(B\n\u001b$B]~\u001b(B\n\u001b$B^!\u001b(B\n\u001b$B^\"\u001b(B\n\u001b$B^#\u001b(B\n\u001b$B^$\u001b(B\n\u001b$B^%\u001b(B\n\u001b$B^&\u001b(B\n\u001b$B^'\u001b(B\n\u001b$B^(\u001b(B\n\u001b$B^)\u001b(B\n\u001b$B^*\u001b(B\n\u001b$B^+\u001b(B\n\u001b$B^,\u001b(B\n\u001b$B^-\u001b(B\n\u001b$B^.\u001b(B\n\u001b$B^/\u001b(B\n\u001b$B^0\u001b(B\n\u001b$B^1\u001b(B\n\u001b$B^2\u001b(B\n\u001b$B^3\u001b(B\n\u001b$B^4\u001b(B\n\u001b$B^5\u001b(B\n\u001b$B^6\u001b(B\n\u001b$B^7\u001b(B\n\u001b$B^8\u001b(B\n\u001b$B^9\u001b(B\n\u001b$B^:\u001b(B\n\u001b$B^;\u001b(B\n\u001b$B^<\u001b(B\n\u001b$B^=\u001b(B\n\u001b$B^>\u001b(B\n\u001b$B^?\u001b(B\n\u001b$B^@\u001b(B\n\u001b$B^A\u001b(B\n\u001b$B^B\u001b(B\n\u001b$B^C\u001b(B\n\u001b$B^D\u001b(B\n\u001b$B^E\u001b(B\n\u001b$B^F\u001b(B\n\u001b$B^G\u001b(B\n\u001b$B^H\u001b(B\n\u001b$B^I\u001b(B\n\u001b$B^J\u001b(B\n\u001b$B^K\u001b(B\n\u001b$B^L\u001b(B\n\u001b$B^M\u001b(B\n\u001b$B^N\u001b(B\n\u001b$B^O\u001b(B\n\u001b$B^P\u001b(B\n\u001b$B^Q\u001b(B\n\u001b$B^R\u001b(B\n\u001b$B^S\u001b(B\n\u001b$B^T\u001b(B\n\u001b$B^U\u001b(B\n\u001b$B^V\u001b(B\n\u001b$B^W\u001b(B\n\u001b$B^X\u001b(B\n\u001b$B^Y\u001b(B\n\u001b$B^Z\u001b(B\n\u001b$B^[\u001b(B\n\u001b$B^\\\u001b(B\n\u001b$B^]\u001b(B\n\u001b$B^^\u001b(B\n\u001b$B^_\u001b(B\n\u001b$B^`\u001b(B\n\u001b$B^a\u001b(B\n\u001b$B^b\u001b(B\n\u001b$B^c\u001b(B\n\u001b$B^d\u001b(B\n\u001b$B^e\u001b(B\n\u001b$B^f\u001b(B\n\u001b$B^g\u001b(B\n\u001b$B^h\u001b(B\n\u001b$B^i\u001b(B\n\u001b$B^j\u001b(B\n\u001b$B^k\u001b(B\n\u001b$B^l\u001b(B\n\u001b$B^m\u001b(B\n\u001b$B^n\u001b(B\n\u001b$B^o\u001b(B\n\u001b$B^p\u001b(B\n\u001b$B^q\u001b(B\n\u001b$B^r\u001b(B\n\u001b$B^s\u001b(B\n\u001b$B^t\u001b(B\n\u001b$B^u\u001b(B\n\u001b$B^v\u001b(B\n\u001b$B^w\u001b(B\n\u001b$B^x\u001b(B\n\u001b$B^y\u001b(B\n\u001b$B^z\u001b(B\n\u001b$B^{\u001b(B\n\u001b$B^|\u001b(B\n\u001b$B^}\u001b(B\n\u001b$B^~\u001b(B\n\u001b$B_!\u001b(B\n\u001b$B_\"\u001b(B\n\u001b$B_#\u001b(B\n\u001b$B_$\u001b(B\n\u001b$B_%\u001b(B\n\u001b$B_&\u001b(B\n\u001b$B_'\u001b(B\n\u001b$B_(\u001b(B\n\u001b$B_)\u001b(B\n\u001b$B_*\u001b(B\n\u001b$B_+\u001b(B\n\u001b$B_,\u001b(B\n\u001b$B_-\u001b(B\n\u001b$B_.\u001b(B\n\u001b$B_/\u001b(B\n\u001b$B_0\u001b(B\n\u001b$B_1\u001b(B\n\u001b$B_2\u001b(B\n\u001b$B_3\u001b(B\n\u001b$B_4\u001b(B\n\u001b$B_5\u001b(B\n\u001b$B_6\u001b(B\n\u001b$B_7\u001b(B\n\u001b$B_8\u001b(B\n\u001b$B_9\u001b(B\n\u001b$B_:\u001b(B\n\u001b$B_;\u001b(B\n\u001b$B_<\u001b(B\n\u001b$B_=\u001b(B\n\u001b$B_>\u001b(B\n\u001b$B_?\u001b(B\n\u001b$B_@\u001b(B\n\u001b$B_A\u001b(B\n\u001b$B_B\u001b(B\n\u001b$B_C\u001b(B\n\u001b$B_D\u001b(B\n\u001b$B_E\u001b(B\n\u001b$B_F\u001b(B\n\u001b$B_G\u001b(B\n\u001b$B_H\u001b(B\n\u001b$B_I\u001b(B\n\u001b$B_J\u001b(B\n\u001b$B_K\u001b(B\n\u001b$B_L\u001b(B\n\u001b$B_M\u001b(B\n\u001b$B_N\u001b(B\n\u001b$B_O\u001b(B\n\u001b$B_P\u001b(B\n\u001b$B_Q\u001b(B\n\u001b$B_R\u001b(B\n\u001b$B_S\u001b(B\n\u001b$B_T\u001b(B\n\u001b$B_U\u001b(B\n\u001b$B_V\u001b(B\n\u001b$B_W\u001b(B\n\u001b$B_X\u001b(B\n\u001b$B_Y\u001b(B\n\u001b$B_Z\u001b(B\n\u001b$B_[\u001b(B\n\u001b$B_\\\u001b(B\n\u001b$B_]\u001b(B\n\u001b$B_^\u001b(B\n\u001b$B__\u001b(B\n\u001b$B_`\u001b(B\n\u001b$B_a\u001b(B\n\u001b$B_b\u001b(B\n\u001b$B_c\u001b(B\n\u001b$B_d\u001b(B\n\u001b$B_e\u001b(B\n\u001b$B_f\u001b(B\n\u001b$B_g\u001b(B\n\u001b$B_h\u001b(B\n\u001b$B_i\u001b(B\n\u001b$B_j\u001b(B\n\u001b$B_k\u001b(B\n\u001b$B_l\u001b(B\n\u001b$B_m\u001b(B\n\u001b$B_n\u001b(B\n\u001b$B_o\u001b(B\n\u001b$B_p\u001b(B\n\u001b$B_q\u001b(B\n\u001b$B_r\u001b(B\n\u001b$B_s\u001b(B\n\u001b$B_t\u001b(B\n\u001b$B_u\u001b(B\n\u001b$B_v\u001b(B\n\u001b$B_w\u001b(B\n\u001b$B_x\u001b(B\n\u001b$B_y\u001b(B\n\u001b$B_z\u001b(B\n\u001b$B_{\u001b(B\n\u001b$B_|\u001b(B\n\u001b$B_}\u001b(B\n\u001b$B_~\u001b(B\n\u001b$B`!\u001b(B\n\u001b$B`\"\u001b(B\n\u001b$B`#\u001b(B\n\u001b$B`$\u001b(B\n\u001b$B`%\u001b(B\n\u001b$B`&\u001b(B\n\u001b$B`'\u001b(B\n\u001b$B`(\u001b(B\n\u001b$B`)\u001b(B\n\u001b$B`*\u001b(B\n\u001b$B`+\u001b(B\n\u001b$B`,\u001b(B\n\u001b$B`-\u001b(B\n\u001b$B`.\u001b(B\n\u001b$B`/\u001b(B\n\u001b$B`0\u001b(B\n\u001b$B`1\u001b(B\n\u001b$B`2\u001b(B\n\u001b$B`3\u001b(B\n\u001b$B`4\u001b(B\n\u001b$B`5\u001b(B\n\u001b$B`6\u001b(B\n\u001b$B`7\u001b(B\n\u001b$B`8\u001b(B\n\u001b$B`9\u001b(B\n\u001b$B`:\u001b(B\n\u001b$B`;\u001b(B\n\u001b$B`<\u001b(B\n\u001b$B`=\u001b(B\n\u001b$B`>\u001b(B\n\u001b$B`?\u001b(B\n\u001b$B`@\u001b(B\n\u001b$B`A\u001b(B\n\u001b$B`B\u001b(B\n\u001b$B`C\u001b(B\n\u001b$B`D\u001b(B\n\u001b$B`E\u001b(B\n\u001b$B`F\u001b(B\n\u001b$B`G\u001b(B\n\u001b$B`H\u001b(B\n\u001b$B`I\u001b(B\n\u001b$B`J\u001b(B\n\u001b$B`K\u001b(B\n\u001b$B`L\u001b(B\n\u001b$B`M\u001b(B\n\u001b$B`N\u001b(B\n\u001b$B`O\u001b(B\n\u001b$B`P\u001b(B\n\u001b$B`Q\u001b(B\n\u001b$B`R\u001b(B\n\u001b$B`S\u001b(B\n\u001b$B`T\u001b(B\n\u001b$B`U\u001b(B\n\u001b$B`V\u001b(B\n\u001b$B`W\u001b(B\n\u001b$B`X\u001b(B\n\u001b$B`Y\u001b(B\n\u001b$B`Z\u001b(B\n\u001b$B`[\u001b(B\n\u001b$B`\\\u001b(B\n\u001b$B`]\u001b(B\n\u001b$B`^\u001b(B\n\u001b$B`_\u001b(B\n\u001b$B``\u001b(B\n\u001b$B`a\u001b(B\n\u001b$B`b\u001b(B\n\u001b$B`c\u001b(B\n\u001b$B`d\u001b(B\n\u001b$B`e\u001b(B\n\u001b$B`f\u001b(B\n\u001b$B`g\u001b(B\n\u001b$B`h\u001b(B\n\u001b$B`i\u001b(B\n\u001b$B`j\u001b(B\n\u001b$B`k\u001b(B\n\u001b$B`l\u001b(B\n\u001b$B`m\u001b(B\n\u001b$B`n\u001b(B\n\u001b$B`o\u001b(B\n\u001b$B`p\u001b(B\n\u001b$B`q\u001b(B\n\u001b$B`r\u001b(B\n\u001b$B`s\u001b(B\n\u001b$B`t\u001b(B\n\u001b$B`u\u001b(B\n\u001b$B`v\u001b(B\n\u001b$B`w\u001b(B\n\u001b$B`x\u001b(B\n\u001b$B`y\u001b(B\n\u001b$B`z\u001b(B\n\u001b$B`{\u001b(B\n\u001b$B`|\u001b(B\n\u001b$B`}\u001b(B\n\u001b$B`~\u001b(B\n\u001b$Ba!\u001b(B\n\u001b$Ba\"\u001b(B\n\u001b$Ba#\u001b(B\n\u001b$Ba$\u001b(B\n\u001b$Ba%\u001b(B\n\u001b$Ba&\u001b(B\n\u001b$Ba'\u001b(B\n\u001b$Ba(\u001b(B\n\u001b$Ba)\u001b(B\n\u001b$Ba*\u001b(B\n\u001b$Ba+\u001b(B\n\u001b$Ba,\u001b(B\n\u001b$Ba-\u001b(B\n\u001b$Ba.\u001b(B\n\u001b$Ba/\u001b(B\n\u001b$Ba0\u001b(B\n\u001b$Ba1\u001b(B\n\u001b$Ba2\u001b(B\n\u001b$Ba3\u001b(B\n\u001b$Ba4\u001b(B\n\u001b$Ba5\u001b(B\n\u001b$Ba6\u001b(B\n\u001b$Ba7\u001b(B\n\u001b$Ba8\u001b(B\n\u001b$Ba9\u001b(B\n\u001b$Ba:\u001b(B\n\u001b$Ba;\u001b(B\n\u001b$Ba<\u001b(B\n\u001b$Ba=\u001b(B\n\u001b$Ba>\u001b(B\n\u001b$Ba?\u001b(B\n\u001b$Ba@\u001b(B\n\u001b$BaA\u001b(B\n\u001b$BaB\u001b(B\n\u001b$BaC\u001b(B\n\u001b$BaD\u001b(B\n\u001b$BaE\u001b(B\n\u001b$BaF\u001b(B\n\u001b$BaG\u001b(B\n\u001b$BaH\u001b(B\n\u001b$BaI\u001b(B\n\u001b$BaJ\u001b(B\n\u001b$BaK\u001b(B\n\u001b$BaL\u001b(B\n\u001b$BaM\u001b(B\n\u001b$BaN\u001b(B\n\u001b$BaO\u001b(B\n\u001b$BaP\u001b(B\n\u001b$BaQ\u001b(B\n\u001b$BaR\u001b(B\n\u001b$BaS\u001b(B\n\u001b$BaT\u001b(B\n\u001b$BaU\u001b(B\n\u001b$BaV\u001b(B\n\u001b$BaW\u001b(B\n\u001b$BaX\u001b(B\n\u001b$BaY\u001b(B\n\u001b$BaZ\u001b(B\n\u001b$Ba[\u001b(B\n\u001b$Ba\\\u001b(B\n\u001b$Ba]\u001b(B\n\u001b$Ba^\u001b(B\n\u001b$Ba_\u001b(B\n\u001b$Ba`\u001b(B\n\u001b$Baa\u001b(B\n\u001b$Bab\u001b(B\n\u001b$Bac\u001b(B\n\u001b$Bad\u001b(B\n\u001b$Bae\u001b(B\n\u001b$Baf\u001b(B\n\u001b$Bag\u001b(B\n\u001b$Bah\u001b(B\n\u001b$Bai\u001b(B\n\u001b$Baj\u001b(B\n\u001b$Bak\u001b(B\n\u001b$Bal\u001b(B\n\u001b$Bam\u001b(B\n\u001b$Ban\u001b(B\n\u001b$Bao\u001b(B\n\u001b$Bap\u001b(B\n\u001b$Baq\u001b(B\n\u001b$Bar\u001b(B\n\u001b$Bas\u001b(B\n\u001b$Bat\u001b(B\n\u001b$Bau\u001b(B\n\u001b$Bav\u001b(B\n\u001b$Baw\u001b(B\n\u001b$Bax\u001b(B\n\u001b$Bay\u001b(B\n\u001b$Baz\u001b(B\n\u001b$Ba{\u001b(B\n\u001b$Ba|\u001b(B\n\u001b$Ba}\u001b(B\n\u001b$Ba~\u001b(B\n\u001b$Bb!\u001b(B\n\u001b$Bb\"\u001b(B\n\u001b$Bb#\u001b(B\n\u001b$Bb$\u001b(B\n\u001b$Bb%\u001b(B\n\u001b$Bb&\u001b(B\n\u001b$Bb'\u001b(B\n\u001b$Bb(\u001b(B\n\u001b$Bb)\u001b(B\n\u001b$Bb*\u001b(B\n\u001b$Bb+\u001b(B\n\u001b$Bb,\u001b(B\n\u001b$Bb-\u001b(B\n\u001b$Bb.\u001b(B\n\u001b$Bb/\u001b(B\n\u001b$Bb0\u001b(B\n\u001b$Bb1\u001b(B\n\u001b$Bb2\u001b(B\n\u001b$Bb3\u001b(B\n\u001b$Bb4\u001b(B\n\u001b$Bb5\u001b(B\n\u001b$Bb6\u001b(B\n\u001b$Bb7\u001b(B\n\u001b$Bb8\u001b(B\n\u001b$Bb9\u001b(B\n\u001b$Bb:\u001b(B\n\u001b$Bb;\u001b(B\n\u001b$Bb<\u001b(B\n\u001b$Bb=\u001b(B\n\u001b$Bb>\u001b(B\n\u001b$Bb?\u001b(B\n\u001b$Bb@\u001b(B\n\u001b$BbA\u001b(B\n\u001b$BbB\u001b(B\n\u001b$BbC\u001b(B\n\u001b$BbD\u001b(B\n\u001b$BbE\u001b(B\n\u001b$BbF\u001b(B\n\u001b$BbG\u001b(B\n\u001b$BbH\u001b(B\n\u001b$BbI\u001b(B\n\u001b$BbJ\u001b(B\n\u001b$BbK\u001b(B\n\u001b$BbL\u001b(B\n\u001b$BbM\u001b(B\n\u001b$BbN\u001b(B\n\u001b$BbO\u001b(B\n\u001b$BbP\u001b(B\n\u001b$BbQ\u001b(B\n\u001b$BbR\u001b(B\n\u001b$BbS\u001b(B\n\u001b$BbT\u001b(B\n\u001b$BbU\u001b(B\n\u001b$BbV\u001b(B\n\u001b$BbW\u001b(B\n\u001b$BbX\u001b(B\n\u001b$BbY\u001b(B\n\u001b$BbZ\u001b(B\n\u001b$Bb[\u001b(B\n\u001b$Bb\\\u001b(B\n\u001b$Bb]\u001b(B\n\u001b$Bb^\u001b(B\n\u001b$Bb_\u001b(B\n\u001b$Bb`\u001b(B\n\u001b$Bba\u001b(B\n\u001b$Bbb\u001b(B\n\u001b$Bbc\u001b(B\n\u001b$Bbd\u001b(B\n\u001b$Bbe\u001b(B\n\u001b$Bbf\u001b(B\n\u001b$Bbg\u001b(B\n\u001b$Bbh\u001b(B\n\u001b$Bbi\u001b(B\n\u001b$Bbj\u001b(B\n\u001b$Bbk\u001b(B\n\u001b$Bbl\u001b(B\n\u001b$Bbm\u001b(B\n\u001b$Bbn\u001b(B\n\u001b$Bbo\u001b(B\n\u001b$Bbp\u001b(B\n\u001b$Bbq\u001b(B\n\u001b$Bbr\u001b(B\n\u001b$Bbs\u001b(B\n\u001b$Bbt\u001b(B\n\u001b$Bbu\u001b(B\n\u001b$Bbv\u001b(B\n\u001b$Bbw\u001b(B\n\u001b$Bbx\u001b(B\n\u001b$Bby\u001b(B\n\u001b$Bbz\u001b(B\n\u001b$Bb{\u001b(B\n\u001b$Bb|\u001b(B\n\u001b$Bb}\u001b(B\n\u001b$Bb~\u001b(B\n\u001b$Bc!\u001b(B\n\u001b$Bc\"\u001b(B\n\u001b$Bc#\u001b(B\n\u001b$Bc$\u001b(B\n\u001b$Bc%\u001b(B\n\u001b$Bc&\u001b(B\n\u001b$Bc'\u001b(B\n\u001b$Bc(\u001b(B\n\u001b$Bc)\u001b(B\n\u001b$Bc*\u001b(B\n\u001b$Bc+\u001b(B\n\u001b$Bc,\u001b(B\n\u001b$Bc-\u001b(B\n\u001b$Bc.\u001b(B\n\u001b$Bc/\u001b(B\n\u001b$Bc0\u001b(B\n\u001b$Bc1\u001b(B\n\u001b$Bc2\u001b(B\n\u001b$Bc3\u001b(B\n\u001b$Bc4\u001b(B\n\u001b$Bc5\u001b(B\n\u001b$Bc6\u001b(B\n\u001b$Bc7\u001b(B\n\u001b$Bc8\u001b(B\n\u001b$Bc9\u001b(B\n\u001b$Bc:\u001b(B\n\u001b$Bc;\u001b(B\n\u001b$Bc<\u001b(B\n\u001b$Bc=\u001b(B\n\u001b$Bc>\u001b(B\n\u001b$Bc?\u001b(B\n\u001b$Bc@\u001b(B\n\u001b$BcA\u001b(B\n\u001b$BcB\u001b(B\n\u001b$BcC\u001b(B\n\u001b$BcD\u001b(B\n\u001b$BcE\u001b(B\n\u001b$BcF\u001b(B\n\u001b$BcG\u001b(B\n\u001b$BcH\u001b(B\n\u001b$BcI\u001b(B\n\u001b$BcJ\u001b(B\n\u001b$BcK\u001b(B\n\u001b$BcL\u001b(B\n\u001b$BcM\u001b(B\n\u001b$BcN\u001b(B\n\u001b$BcO\u001b(B\n\u001b$BcP\u001b(B\n\u001b$BcQ\u001b(B\n\u001b$BcR\u001b(B\n\u001b$BcS\u001b(B\n\u001b$BcT\u001b(B\n\u001b$BcU\u001b(B\n\u001b$BcV\u001b(B\n\u001b$BcW\u001b(B\n\u001b$BcX\u001b(B\n\u001b$BcY\u001b(B\n\u001b$BcZ\u001b(B\n\u001b$Bc[\u001b(B\n\u001b$Bc\\\u001b(B\n\u001b$Bc]\u001b(B\n\u001b$Bc^\u001b(B\n\u001b$Bc_\u001b(B\n\u001b$Bc`\u001b(B\n\u001b$Bca\u001b(B\n\u001b$Bcb\u001b(B\n\u001b$Bcc\u001b(B\n\u001b$Bcd\u001b(B\n\u001b$Bce\u001b(B\n\u001b$Bcf\u001b(B\n\u001b$Bcg\u001b(B\n\u001b$Bch\u001b(B\n\u001b$Bci\u001b(B\n\u001b$Bcj\u001b(B\n\u001b$Bck\u001b(B\n\u001b$Bcl\u001b(B\n\u001b$Bcm\u001b(B\n\u001b$Bcn\u001b(B\n\u001b$Bco\u001b(B\n\u001b$Bcp\u001b(B\n\u001b$Bcq\u001b(B\n\u001b$Bcr\u001b(B\n\u001b$Bcs\u001b(B\n\u001b$Bct\u001b(B\n\u001b$Bcu\u001b(B\n\u001b$Bcv\u001b(B\n\u001b$Bcw\u001b(B\n\u001b$Bcx\u001b(B\n\u001b$Bcy\u001b(B\n\u001b$Bcz\u001b(B\n\u001b$Bc{\u001b(B\n\u001b$Bc|\u001b(B\n\u001b$Bc}\u001b(B\n\u001b$Bc~\u001b(B\n\u001b$Bd!\u001b(B\n\u001b$Bd\"\u001b(B\n\u001b$Bd#\u001b(B\n\u001b$Bd$\u001b(B\n\u001b$Bd%\u001b(B\n\u001b$Bd&\u001b(B\n\u001b$Bd'\u001b(B\n\u001b$Bd(\u001b(B\n\u001b$Bd)\u001b(B\n\u001b$Bd*\u001b(B\n\u001b$Bd+\u001b(B\n\u001b$Bd,\u001b(B\n\u001b$Bd-\u001b(B\n\u001b$Bd.\u001b(B\n\u001b$Bd/\u001b(B\n\u001b$Bd0\u001b(B\n\u001b$Bd1\u001b(B\n\u001b$Bd2\u001b(B\n\u001b$Bd3\u001b(B\n\u001b$Bd4\u001b(B\n\u001b$Bd5\u001b(B\n\u001b$Bd6\u001b(B\n\u001b$Bd7\u001b(B\n\u001b$Bd8\u001b(B\n\u001b$Bd9\u001b(B\n\u001b$Bd:\u001b(B\n\u001b$Bd;\u001b(B\n\u001b$Bd<\u001b(B\n\u001b$Bd=\u001b(B\n\u001b$Bd>\u001b(B\n\u001b$Bd?\u001b(B\n\u001b$Bd@\u001b(B\n\u001b$BdA\u001b(B\n\u001b$BdB\u001b(B\n\u001b$BdC\u001b(B\n\u001b$BdD\u001b(B\n\u001b$BdE\u001b(B\n\u001b$BdF\u001b(B\n\u001b$BdG\u001b(B\n\u001b$BdH\u001b(B\n\u001b$BdI\u001b(B\n\u001b$BdJ\u001b(B\n\u001b$BdK\u001b(B\n\u001b$BdL\u001b(B\n\u001b$BdM\u001b(B\n\u001b$BdN\u001b(B\n\u001b$BdO\u001b(B\n\u001b$BdP\u001b(B\n\u001b$BdQ\u001b(B\n\u001b$BdR\u001b(B\n\u001b$BdS\u001b(B\n\u001b$BdT\u001b(B\n\u001b$BdU\u001b(B\n\u001b$BdV\u001b(B\n\u001b$BdW\u001b(B\n\u001b$BdX\u001b(B\n\u001b$BdY\u001b(B\n\u001b$BdZ\u001b(B\n\u001b$Bd[\u001b(B\n\u001b$Bd\\\u001b(B\n\u001b$Bd]\u001b(B\n\u001b$Bd^\u001b(B\n\u001b$Bd_\u001b(B\n\u001b$Bd`\u001b(B\n\u001b$Bda\u001b(B\n\u001b$Bdb\u001b(B\n\u001b$Bdc\u001b(B\n\u001b$Bdd\u001b(B\n\u001b$Bde\u001b(B\n\u001b$Bdf\u001b(B\n\u001b$Bdg\u001b(B\n\u001b$Bdh\u001b(B\n\u001b$Bdi\u001b(B\n\u001b$Bdj\u001b(B\n\u001b$Bdk\u001b(B\n\u001b$Bdl\u001b(B\n\u001b$Bdm\u001b(B\n\u001b$Bdn\u001b(B\n\u001b$Bdo\u001b(B\n\u001b$Bdp\u001b(B\n\u001b$Bdq\u001b(B\n\u001b$Bdr\u001b(B\n\u001b$Bds\u001b(B\n\u001b$Bdt\u001b(B\n\u001b$Bdu\u001b(B\n\u001b$Bdv\u001b(B\n\u001b$Bdw\u001b(B\n\u001b$Bdx\u001b(B\n\u001b$Bdy\u001b(B\n\u001b$Bdz\u001b(B\n\u001b$Bd{\u001b(B\n\u001b$Bd|\u001b(B\n\u001b$Bd}\u001b(B\n\u001b$Bd~\u001b(B\n\u001b$Be!\u001b(B\n\u001b$Be\"\u001b(B\n\u001b$Be#\u001b(B\n\u001b$Be$\u001b(B\n\u001b$Be%\u001b(B\n\u001b$Be&\u001b(B\n\u001b$Be'\u001b(B\n\u001b$Be(\u001b(B\n\u001b$Be)\u001b(B\n\u001b$Be*\u001b(B\n\u001b$Be+\u001b(B\n\u001b$Be,\u001b(B\n\u001b$Be-\u001b(B\n\u001b$Be.\u001b(B\n\u001b$Be/\u001b(B\n\u001b$Be0\u001b(B\n\u001b$Be1\u001b(B\n\u001b$Be2\u001b(B\n\u001b$Be3\u001b(B\n\u001b$Be4\u001b(B\n\u001b$Be5\u001b(B\n\u001b$Be6\u001b(B\n\u001b$Be7\u001b(B\n\u001b$Be8\u001b(B\n\u001b$Be9\u001b(B\n\u001b$Be:\u001b(B\n\u001b$Be;\u001b(B\n\u001b$Be<\u001b(B\n\u001b$Be=\u001b(B\n\u001b$Be>\u001b(B\n\u001b$Be?\u001b(B\n\u001b$Be@\u001b(B\n\u001b$BeA\u001b(B\n\u001b$BeB\u001b(B\n\u001b$BeC\u001b(B\n\u001b$BeD\u001b(B\n\u001b$BeE\u001b(B\n\u001b$BeF\u001b(B\n\u001b$BeG\u001b(B\n\u001b$BeH\u001b(B\n\u001b$BeI\u001b(B\n\u001b$BeJ\u001b(B\n\u001b$BeK\u001b(B\n\u001b$BeL\u001b(B\n\u001b$BeM\u001b(B\n\u001b$BeN\u001b(B\n\u001b$BeO\u001b(B\n\u001b$BeP\u001b(B\n\u001b$BeQ\u001b(B\n\u001b$BeR\u001b(B\n\u001b$BeS\u001b(B\n\u001b$BeT\u001b(B\n\u001b$BeU\u001b(B\n\u001b$BeV\u001b(B\n\u001b$BeW\u001b(B\n\u001b$BeX\u001b(B\n\u001b$BeY\u001b(B\n\u001b$BeZ\u001b(B\n\u001b$Be[\u001b(B\n\u001b$Be\\\u001b(B\n\u001b$Be]\u001b(B\n\u001b$Be^\u001b(B\n\u001b$Be_\u001b(B\n\u001b$Be`\u001b(B\n\u001b$Bea\u001b(B\n\u001b$Beb\u001b(B\n\u001b$Bec\u001b(B\n\u001b$Bed\u001b(B\n\u001b$Bee\u001b(B\n\u001b$Bef\u001b(B\n\u001b$Beg\u001b(B\n\u001b$Beh\u001b(B\n\u001b$Bei\u001b(B\n\u001b$Bej\u001b(B\n\u001b$Bek\u001b(B\n\u001b$Bel\u001b(B\n\u001b$Bem\u001b(B\n\u001b$Ben\u001b(B\n\u001b$Beo\u001b(B\n\u001b$Bep\u001b(B\n\u001b$Beq\u001b(B\n\u001b$Ber\u001b(B\n\u001b$Bes\u001b(B\n\u001b$Bet\u001b(B\n\u001b$Beu\u001b(B\n\u001b$Bev\u001b(B\n\u001b$Bew\u001b(B\n\u001b$Bex\u001b(B\n\u001b$Bey\u001b(B\n\u001b$Bez\u001b(B\n\u001b$Be{\u001b(B\n\u001b$Be|\u001b(B\n\u001b$Be}\u001b(B\n\u001b$Be~\u001b(B\n\u001b$Bf!\u001b(B\n\u001b$Bf\"\u001b(B\n\u001b$Bf#\u001b(B\n\u001b$Bf$\u001b(B\n\u001b$Bf%\u001b(B\n\u001b$Bf&\u001b(B\n\u001b$Bf'\u001b(B\n\u001b$Bf(\u001b(B\n\u001b$Bf)\u001b(B\n\u001b$Bf*\u001b(B\n\u001b$Bf+\u001b(B\n\u001b$Bf,\u001b(B\n\u001b$Bf-\u001b(B\n\u001b$Bf.\u001b(B\n\u001b$Bf/\u001b(B\n\u001b$Bf0\u001b(B\n\u001b$Bf1\u001b(B\n\u001b$Bf2\u001b(B\n\u001b$Bf3\u001b(B\n\u001b$Bf4\u001b(B\n\u001b$Bf5\u001b(B\n\u001b$Bf6\u001b(B\n\u001b$Bf7\u001b(B\n\u001b$Bf8\u001b(B\n\u001b$Bf9\u001b(B\n\u001b$Bf:\u001b(B\n\u001b$Bf;\u001b(B\n\u001b$Bf<\u001b(B\n\u001b$Bf=\u001b(B\n\u001b$Bf>\u001b(B\n\u001b$Bf?\u001b(B\n\u001b$Bf@\u001b(B\n\u001b$BfA\u001b(B\n\u001b$BfB\u001b(B\n\u001b$BfC\u001b(B\n\u001b$BfD\u001b(B\n\u001b$BfE\u001b(B\n\u001b$BfF\u001b(B\n\u001b$BfG\u001b(B\n\u001b$BfH\u001b(B\n\u001b$BfI\u001b(B\n\u001b$BfJ\u001b(B\n\u001b$BfK\u001b(B\n\u001b$BfL\u001b(B\n\u001b$BfM\u001b(B\n\u001b$BfN\u001b(B\n\u001b$BfO\u001b(B\n\u001b$BfP\u001b(B\n\u001b$BfQ\u001b(B\n\u001b$BfR\u001b(B\n\u001b$BfS\u001b(B\n\u001b$BfT\u001b(B\n\u001b$BfU\u001b(B\n\u001b$BfV\u001b(B\n\u001b$BfW\u001b(B\n\u001b$BfX\u001b(B\n\u001b$BfY\u001b(B\n\u001b$BfZ\u001b(B\n\u001b$Bf[\u001b(B\n\u001b$Bf\\\u001b(B\n\u001b$Bf]\u001b(B\n\u001b$Bf^\u001b(B\n\u001b$Bf_\u001b(B\n\u001b$Bf`\u001b(B\n\u001b$Bfa\u001b(B\n\u001b$Bfb\u001b(B\n\u001b$Bfc\u001b(B\n\u001b$Bfd\u001b(B\n\u001b$Bfe\u001b(B\n\u001b$Bff\u001b(B\n\u001b$Bfg\u001b(B\n\u001b$Bfh\u001b(B\n\u001b$Bfi\u001b(B\n\u001b$Bfj\u001b(B\n\u001b$Bfk\u001b(B\n\u001b$Bfl\u001b(B\n\u001b$Bfm\u001b(B\n\u001b$Bfn\u001b(B\n\u001b$Bfo\u001b(B\n\u001b$Bfp\u001b(B\n\u001b$Bfq\u001b(B\n\u001b$Bfr\u001b(B\n\u001b$Bfs\u001b(B\n\u001b$Bft\u001b(B\n\u001b$Bfu\u001b(B\n\u001b$Bfv\u001b(B\n\u001b$Bfw\u001b(B\n\u001b$Bfx\u001b(B\n\u001b$Bfy\u001b(B\n\u001b$Bfz\u001b(B\n\u001b$Bf{\u001b(B\n\u001b$Bf|\u001b(B\n\u001b$Bf}\u001b(B\n\u001b$Bf~\u001b(B\n\u001b$Bg!\u001b(B\n\u001b$Bg\"\u001b(B\n\u001b$Bg#\u001b(B\n\u001b$Bg$\u001b(B\n\u001b$Bg%\u001b(B\n\u001b$Bg&\u001b(B\n\u001b$Bg'\u001b(B\n\u001b$Bg(\u001b(B\n\u001b$Bg)\u001b(B\n\u001b$Bg*\u001b(B\n\u001b$Bg+\u001b(B\n\u001b$Bg,\u001b(B\n\u001b$Bg-\u001b(B\n\u001b$Bg.\u001b(B\n\u001b$Bg/\u001b(B\n\u001b$Bg0\u001b(B\n\u001b$Bg1\u001b(B\n\u001b$Bg2\u001b(B\n\u001b$Bg3\u001b(B\n\u001b$Bg4\u001b(B\n\u001b$Bg5\u001b(B\n\u001b$Bg6\u001b(B\n\u001b$Bg7\u001b(B\n\u001b$Bg8\u001b(B\n\u001b$Bg9\u001b(B\n\u001b$Bg:\u001b(B\n\u001b$Bg;\u001b(B\n\u001b$Bg<\u001b(B\n\u001b$Bg=\u001b(B\n\u001b$Bg>\u001b(B\n\u001b$Bg?\u001b(B\n\u001b$Bg@\u001b(B\n\u001b$BgA\u001b(B\n\u001b$BgB\u001b(B\n\u001b$BgC\u001b(B\n\u001b$BgD\u001b(B\n\u001b$BgE\u001b(B\n\u001b$BgF\u001b(B\n\u001b$BgG\u001b(B\n\u001b$BgH\u001b(B\n\u001b$BgI\u001b(B\n\u001b$BgJ\u001b(B\n\u001b$BgK\u001b(B\n\u001b$BgL\u001b(B\n\u001b$BgM\u001b(B\n\u001b$BgN\u001b(B\n\u001b$BgO\u001b(B\n\u001b$BgP\u001b(B\n\u001b$BgQ\u001b(B\n\u001b$BgR\u001b(B\n\u001b$BgS\u001b(B\n\u001b$BgT\u001b(B\n\u001b$BgU\u001b(B\n\u001b$BgV\u001b(B\n\u001b$BgW\u001b(B\n\u001b$BgX\u001b(B\n\u001b$BgY\u001b(B\n\u001b$BgZ\u001b(B\n\u001b$Bg[\u001b(B\n\u001b$Bg\\\u001b(B\n\u001b$Bg]\u001b(B\n\u001b$Bg^\u001b(B\n\u001b$Bg_\u001b(B\n\u001b$Bg`\u001b(B\n\u001b$Bga\u001b(B\n\u001b$Bgb\u001b(B\n\u001b$Bgc\u001b(B\n\u001b$Bgd\u001b(B\n\u001b$Bge\u001b(B\n\u001b$Bgf\u001b(B\n\u001b$Bgg\u001b(B\n\u001b$Bgh\u001b(B\n\u001b$Bgi\u001b(B\n\u001b$Bgj\u001b(B\n\u001b$Bgk\u001b(B\n\u001b$Bgl\u001b(B\n\u001b$Bgm\u001b(B\n\u001b$Bgn\u001b(B\n\u001b$Bgo\u001b(B\n\u001b$Bgp\u001b(B\n\u001b$Bgq\u001b(B\n\u001b$Bgr\u001b(B\n\u001b$Bgs\u001b(B\n\u001b$Bgt\u001b(B\n\u001b$Bgu\u001b(B\n\u001b$Bgv\u001b(B\n\u001b$Bgw\u001b(B\n\u001b$Bgx\u001b(B\n\u001b$Bgy\u001b(B\n\u001b$Bgz\u001b(B\n\u001b$Bg{\u001b(B\n\u001b$Bg|\u001b(B\n\u001b$Bg}\u001b(B\n\u001b$Bg~\u001b(B\n\u001b$Bh!\u001b(B\n\u001b$Bh\"\u001b(B\n\u001b$Bh#\u001b(B\n\u001b$Bh$\u001b(B\n\u001b$Bh%\u001b(B\n\u001b$Bh&\u001b(B\n\u001b$Bh'\u001b(B\n\u001b$Bh(\u001b(B\n\u001b$Bh)\u001b(B\n\u001b$Bh*\u001b(B\n\u001b$Bh+\u001b(B\n\u001b$Bh,\u001b(B\n\u001b$Bh-\u001b(B\n\u001b$Bh.\u001b(B\n\u001b$Bh/\u001b(B\n\u001b$Bh0\u001b(B\n\u001b$Bh1\u001b(B\n\u001b$Bh2\u001b(B\n\u001b$Bh3\u001b(B\n\u001b$Bh4\u001b(B\n\u001b$Bh5\u001b(B\n\u001b$Bh6\u001b(B\n\u001b$Bh7\u001b(B\n\u001b$Bh8\u001b(B\n\u001b$Bh9\u001b(B\n\u001b$Bh:\u001b(B\n\u001b$Bh;\u001b(B\n\u001b$Bh<\u001b(B\n\u001b$Bh=\u001b(B\n\u001b$Bh>\u001b(B\n\u001b$Bh?\u001b(B\n\u001b$Bh@\u001b(B\n\u001b$BhA\u001b(B\n\u001b$BhB\u001b(B\n\u001b$BhC\u001b(B\n\u001b$BhD\u001b(B\n\u001b$BhE\u001b(B\n\u001b$BhF\u001b(B\n\u001b$BhG\u001b(B\n\u001b$BhH\u001b(B\n\u001b$BhI\u001b(B\n\u001b$BhJ\u001b(B\n\u001b$BhK\u001b(B\n\u001b$BhL\u001b(B\n\u001b$BhM\u001b(B\n\u001b$BhN\u001b(B\n\u001b$BhO\u001b(B\n\u001b$BhP\u001b(B\n\u001b$BhQ\u001b(B\n\u001b$BhR\u001b(B\n\u001b$BhS\u001b(B\n\u001b$BhT\u001b(B\n\u001b$BhU\u001b(B\n\u001b$BhV\u001b(B\n\u001b$BhW\u001b(B\n\u001b$BhX\u001b(B\n\u001b$BhY\u001b(B\n\u001b$BhZ\u001b(B\n\u001b$Bh[\u001b(B\n\u001b$Bh\\\u001b(B\n\u001b$Bh]\u001b(B\n\u001b$Bh^\u001b(B\n\u001b$Bh_\u001b(B\n\u001b$Bh`\u001b(B\n\u001b$Bha\u001b(B\n\u001b$Bhb\u001b(B\n\u001b$Bhc\u001b(B\n\u001b$Bhd\u001b(B\n\u001b$Bhe\u001b(B\n\u001b$Bhf\u001b(B\n\u001b$Bhg\u001b(B\n\u001b$Bhh\u001b(B\n\u001b$Bhi\u001b(B\n\u001b$Bhj\u001b(B\n\u001b$Bhk\u001b(B\n\u001b$Bhl\u001b(B\n\u001b$Bhm\u001b(B\n\u001b$Bhn\u001b(B\n\u001b$Bho\u001b(B\n\u001b$Bhp\u001b(B\n\u001b$Bhq\u001b(B\n\u001b$Bhr\u001b(B\n\u001b$Bhs\u001b(B\n\u001b$Bht\u001b(B\n\u001b$Bhu\u001b(B\n\u001b$Bhv\u001b(B\n\u001b$Bhw\u001b(B\n\u001b$Bhx\u001b(B\n\u001b$Bhy\u001b(B\n\u001b$Bhz\u001b(B\n\u001b$Bh{\u001b(B\n\u001b$Bh|\u001b(B\n\u001b$Bh}\u001b(B\n\u001b$Bh~\u001b(B\n\u001b$Bi!\u001b(B\n\u001b$Bi\"\u001b(B\n\u001b$Bi#\u001b(B\n\u001b$Bi$\u001b(B\n\u001b$Bi%\u001b(B\n\u001b$Bi&\u001b(B\n\u001b$Bi'\u001b(B\n\u001b$Bi(\u001b(B\n\u001b$Bi)\u001b(B\n\u001b$Bi*\u001b(B\n\u001b$Bi+\u001b(B\n\u001b$Bi,\u001b(B\n\u001b$Bi-\u001b(B\n\u001b$Bi.\u001b(B\n\u001b$Bi/\u001b(B\n\u001b$Bi0\u001b(B\n\u001b$Bi1\u001b(B\n\u001b$Bi2\u001b(B\n\u001b$Bi3\u001b(B\n\u001b$Bi4\u001b(B\n\u001b$Bi5\u001b(B\n\u001b$Bi6\u001b(B\n\u001b$Bi7\u001b(B\n\u001b$Bi8\u001b(B\n\u001b$Bi9\u001b(B\n\u001b$Bi:\u001b(B\n\u001b$Bi;\u001b(B\n\u001b$Bi<\u001b(B\n\u001b$Bi=\u001b(B\n\u001b$Bi>\u001b(B\n\u001b$Bi?\u001b(B\n\u001b$Bi@\u001b(B\n\u001b$BiA\u001b(B\n\u001b$BiB\u001b(B\n\u001b$BiC\u001b(B\n\u001b$BiD\u001b(B\n\u001b$BiE\u001b(B\n\u001b$BiF\u001b(B\n\u001b$BiG\u001b(B\n\u001b$BiH\u001b(B\n\u001b$BiI\u001b(B\n\u001b$BiJ\u001b(B\n\u001b$BiK\u001b(B\n\u001b$BiL\u001b(B\n\u001b$BiM\u001b(B\n\u001b$BiN\u001b(B\n\u001b$BiO\u001b(B\n\u001b$BiP\u001b(B\n\u001b$BiQ\u001b(B\n\u001b$BiR\u001b(B\n\u001b$BiS\u001b(B\n\u001b$BiT\u001b(B\n\u001b$BiU\u001b(B\n\u001b$BiV\u001b(B\n\u001b$BiW\u001b(B\n\u001b$BiX\u001b(B\n\u001b$BiY\u001b(B\n\u001b$BiZ\u001b(B\n\u001b$Bi[\u001b(B\n\u001b$Bi\\\u001b(B\n\u001b$Bi]\u001b(B\n\u001b$Bi^\u001b(B\n\u001b$Bi_\u001b(B\n\u001b$Bi`\u001b(B\n\u001b$Bia\u001b(B\n\u001b$Bib\u001b(B\n\u001b$Bic\u001b(B\n\u001b$Bid\u001b(B\n\u001b$Bie\u001b(B\n\u001b$Bif\u001b(B\n\u001b$Big\u001b(B\n\u001b$Bih\u001b(B\n\u001b$Bii\u001b(B\n\u001b$Bij\u001b(B\n\u001b$Bik\u001b(B\n\u001b$Bil\u001b(B\n\u001b$Bim\u001b(B\n\u001b$Bin\u001b(B\n\u001b$Bio\u001b(B\n\u001b$Bip\u001b(B\n\u001b$Biq\u001b(B\n\u001b$Bir\u001b(B\n\u001b$Bis\u001b(B\n\u001b$Bit\u001b(B\n\u001b$Biu\u001b(B\n\u001b$Biv\u001b(B\n\u001b$Biw\u001b(B\n\u001b$Bix\u001b(B\n\u001b$Biy\u001b(B\n\u001b$Biz\u001b(B\n\u001b$Bi{\u001b(B\n\u001b$Bi|\u001b(B\n\u001b$Bi}\u001b(B\n\u001b$Bi~\u001b(B\n\u001b$Bj!\u001b(B\n\u001b$Bj\"\u001b(B\n\u001b$Bj#\u001b(B\n\u001b$Bj$\u001b(B\n\u001b$Bj%\u001b(B\n\u001b$Bj&\u001b(B\n\u001b$Bj'\u001b(B\n\u001b$Bj(\u001b(B\n\u001b$Bj)\u001b(B\n\u001b$Bj*\u001b(B\n\u001b$Bj+\u001b(B\n\u001b$Bj,\u001b(B\n\u001b$Bj-\u001b(B\n\u001b$Bj.\u001b(B\n\u001b$Bj/\u001b(B\n\u001b$Bj0\u001b(B\n\u001b$Bj1\u001b(B\n\u001b$Bj2\u001b(B\n\u001b$Bj3\u001b(B\n\u001b$Bj4\u001b(B\n\u001b$Bj5\u001b(B\n\u001b$Bj6\u001b(B\n\u001b$Bj7\u001b(B\n\u001b$Bj8\u001b(B\n\u001b$Bj9\u001b(B\n\u001b$Bj:\u001b(B\n\u001b$Bj;\u001b(B\n\u001b$Bj<\u001b(B\n\u001b$Bj=\u001b(B\n\u001b$Bj>\u001b(B\n\u001b$Bj?\u001b(B\n\u001b$Bj@\u001b(B\n\u001b$BjA\u001b(B\n\u001b$BjB\u001b(B\n\u001b$BjC\u001b(B\n\u001b$BjD\u001b(B\n\u001b$BjE\u001b(B\n\u001b$BjF\u001b(B\n\u001b$BjG\u001b(B\n\u001b$BjH\u001b(B\n\u001b$BjI\u001b(B\n\u001b$BjJ\u001b(B\n\u001b$BjK\u001b(B\n\u001b$BjL\u001b(B\n\u001b$BjM\u001b(B\n\u001b$BjN\u001b(B\n\u001b$BjO\u001b(B\n\u001b$BjP\u001b(B\n\u001b$BjQ\u001b(B\n\u001b$BjR\u001b(B\n\u001b$BjS\u001b(B\n\u001b$BjT\u001b(B\n\u001b$BjU\u001b(B\n\u001b$BjV\u001b(B\n\u001b$BjW\u001b(B\n\u001b$BjX\u001b(B\n\u001b$BjY\u001b(B\n\u001b$BjZ\u001b(B\n\u001b$Bj[\u001b(B\n\u001b$Bj\\\u001b(B\n\u001b$Bj]\u001b(B\n\u001b$Bj^\u001b(B\n\u001b$Bj_\u001b(B\n\u001b$Bj`\u001b(B\n\u001b$Bja\u001b(B\n\u001b$Bjb\u001b(B\n\u001b$Bjc\u001b(B\n\u001b$Bjd\u001b(B\n\u001b$Bje\u001b(B\n\u001b$Bjf\u001b(B\n\u001b$Bjg\u001b(B\n\u001b$Bjh\u001b(B\n\u001b$Bji\u001b(B\n\u001b$Bjj\u001b(B\n\u001b$Bjk\u001b(B\n\u001b$Bjl\u001b(B\n\u001b$Bjm\u001b(B\n\u001b$Bjn\u001b(B\n\u001b$Bjo\u001b(B\n\u001b$Bjp\u001b(B\n\u001b$Bjq\u001b(B\n\u001b$Bjr\u001b(B\n\u001b$Bjs\u001b(B\n\u001b$Bjt\u001b(B\n\u001b$Bju\u001b(B\n\u001b$Bjv\u001b(B\n\u001b$Bjw\u001b(B\n\u001b$Bjx\u001b(B\n\u001b$Bjy\u001b(B\n\u001b$Bjz\u001b(B\n\u001b$Bj{\u001b(B\n\u001b$Bj|\u001b(B\n\u001b$Bj}\u001b(B\n\u001b$Bj~\u001b(B\n\u001b$Bk!\u001b(B\n\u001b$Bk\"\u001b(B\n\u001b$Bk#\u001b(B\n\u001b$Bk$\u001b(B\n\u001b$Bk%\u001b(B\n\u001b$Bk&\u001b(B\n\u001b$Bk'\u001b(B\n\u001b$Bk(\u001b(B\n\u001b$Bk)\u001b(B\n\u001b$Bk*\u001b(B\n\u001b$Bk+\u001b(B\n\u001b$Bk,\u001b(B\n\u001b$Bk-\u001b(B\n\u001b$Bk.\u001b(B\n\u001b$Bk/\u001b(B\n\u001b$Bk0\u001b(B\n\u001b$Bk1\u001b(B\n\u001b$Bk2\u001b(B\n\u001b$Bk3\u001b(B\n\u001b$Bk4\u001b(B\n\u001b$Bk5\u001b(B\n\u001b$Bk6\u001b(B\n\u001b$Bk7\u001b(B\n\u001b$Bk8\u001b(B\n\u001b$Bk9\u001b(B\n\u001b$Bk:\u001b(B\n\u001b$Bk;\u001b(B\n\u001b$Bk<\u001b(B\n\u001b$Bk=\u001b(B\n\u001b$Bk>\u001b(B\n\u001b$Bk?\u001b(B\n\u001b$Bk@\u001b(B\n\u001b$BkA\u001b(B\n\u001b$BkB\u001b(B\n\u001b$BkC\u001b(B\n\u001b$BkD\u001b(B\n\u001b$BkE\u001b(B\n\u001b$BkF\u001b(B\n\u001b$BkG\u001b(B\n\u001b$BkH\u001b(B\n\u001b$BkI\u001b(B\n\u001b$BkJ\u001b(B\n\u001b$BkK\u001b(B\n\u001b$BkL\u001b(B\n\u001b$BkM\u001b(B\n\u001b$BkN\u001b(B\n\u001b$BkO\u001b(B\n\u001b$BkP\u001b(B\n\u001b$BkQ\u001b(B\n\u001b$BkR\u001b(B\n\u001b$BkS\u001b(B\n\u001b$BkT\u001b(B\n\u001b$BkU\u001b(B\n\u001b$BkV\u001b(B\n\u001b$BkW\u001b(B\n\u001b$BkX\u001b(B\n\u001b$BkY\u001b(B\n\u001b$BkZ\u001b(B\n\u001b$Bk[\u001b(B\n\u001b$Bk\\\u001b(B\n\u001b$Bk]\u001b(B\n\u001b$Bk^\u001b(B\n\u001b$Bk_\u001b(B\n\u001b$Bk`\u001b(B\n\u001b$Bka\u001b(B\n\u001b$Bkb\u001b(B\n\u001b$Bkc\u001b(B\n\u001b$Bkd\u001b(B\n\u001b$Bke\u001b(B\n\u001b$Bkf\u001b(B\n\u001b$Bkg\u001b(B\n\u001b$Bkh\u001b(B\n\u001b$Bki\u001b(B\n\u001b$Bkj\u001b(B\n\u001b$Bkk\u001b(B\n\u001b$Bkl\u001b(B\n\u001b$Bkm\u001b(B\n\u001b$Bkn\u001b(B\n\u001b$Bko\u001b(B\n\u001b$Bkp\u001b(B\n\u001b$Bkq\u001b(B\n\u001b$Bkr\u001b(B\n\u001b$Bks\u001b(B\n\u001b$Bkt\u001b(B\n\u001b$Bku\u001b(B\n\u001b$Bkv\u001b(B\n\u001b$Bkw\u001b(B\n\u001b$Bkx\u001b(B\n\u001b$Bky\u001b(B\n\u001b$Bkz\u001b(B\n\u001b$Bk{\u001b(B\n\u001b$Bk|\u001b(B\n\u001b$Bk}\u001b(B\n\u001b$Bk~\u001b(B\n\u001b$Bl!\u001b(B\n\u001b$Bl\"\u001b(B\n\u001b$Bl#\u001b(B\n\u001b$Bl$\u001b(B\n\u001b$Bl%\u001b(B\n\u001b$Bl&\u001b(B\n\u001b$Bl'\u001b(B\n\u001b$Bl(\u001b(B\n\u001b$Bl)\u001b(B\n\u001b$Bl*\u001b(B\n\u001b$Bl+\u001b(B\n\u001b$Bl,\u001b(B\n\u001b$Bl-\u001b(B\n\u001b$Bl.\u001b(B\n\u001b$Bl/\u001b(B\n\u001b$Bl0\u001b(B\n\u001b$Bl1\u001b(B\n\u001b$Bl2\u001b(B\n\u001b$Bl3\u001b(B\n\u001b$Bl4\u001b(B\n\u001b$Bl5\u001b(B\n\u001b$Bl6\u001b(B\n\u001b$Bl7\u001b(B\n\u001b$Bl8\u001b(B\n\u001b$Bl9\u001b(B\n\u001b$Bl:\u001b(B\n\u001b$Bl;\u001b(B\n\u001b$Bl<\u001b(B\n\u001b$Bl=\u001b(B\n\u001b$Bl>\u001b(B\n\u001b$Bl?\u001b(B\n\u001b$Bl@\u001b(B\n\u001b$BlA\u001b(B\n\u001b$BlB\u001b(B\n\u001b$BlC\u001b(B\n\u001b$BlD\u001b(B\n\u001b$BlE\u001b(B\n\u001b$BlF\u001b(B\n\u001b$BlG\u001b(B\n\u001b$BlH\u001b(B\n\u001b$BlI\u001b(B\n\u001b$BlJ\u001b(B\n\u001b$BlK\u001b(B\n\u001b$BlL\u001b(B\n\u001b$BlM\u001b(B\n\u001b$BlN\u001b(B\n\u001b$BlO\u001b(B\n\u001b$BlP\u001b(B\n\u001b$BlQ\u001b(B\n\u001b$BlR\u001b(B\n\u001b$BlS\u001b(B\n\u001b$BlT\u001b(B\n\u001b$BlU\u001b(B\n\u001b$BlV\u001b(B\n\u001b$BlW\u001b(B\n\u001b$BlX\u001b(B\n\u001b$BlY\u001b(B\n\u001b$BlZ\u001b(B\n\u001b$Bl[\u001b(B\n\u001b$Bl\\\u001b(B\n\u001b$Bl]\u001b(B\n\u001b$Bl^\u001b(B\n\u001b$Bl_\u001b(B\n\u001b$Bl`\u001b(B\n\u001b$Bla\u001b(B\n\u001b$Blb\u001b(B\n\u001b$Blc\u001b(B\n\u001b$Bld\u001b(B\n\u001b$Ble\u001b(B\n\u001b$Blf\u001b(B\n\u001b$Blg\u001b(B\n\u001b$Blh\u001b(B\n\u001b$Bli\u001b(B\n\u001b$Blj\u001b(B\n\u001b$Blk\u001b(B\n\u001b$Bll\u001b(B\n\u001b$Blm\u001b(B\n\u001b$Bln\u001b(B\n\u001b$Blo\u001b(B\n\u001b$Blp\u001b(B\n\u001b$Blq\u001b(B\n\u001b$Blr\u001b(B\n\u001b$Bls\u001b(B\n\u001b$Blt\u001b(B\n\u001b$Blu\u001b(B\n\u001b$Blv\u001b(B\n\u001b$Blw\u001b(B\n\u001b$Blx\u001b(B\n\u001b$Bly\u001b(B\n\u001b$Blz\u001b(B\n\u001b$Bl{\u001b(B\n\u001b$Bl|\u001b(B\n\u001b$Bl}\u001b(B\n\u001b$Bl~\u001b(B\n\u001b$Bm!\u001b(B\n\u001b$Bm\"\u001b(B\n\u001b$Bm#\u001b(B\n\u001b$Bm$\u001b(B\n\u001b$Bm%\u001b(B\n\u001b$Bm&\u001b(B\n\u001b$Bm'\u001b(B\n\u001b$Bm(\u001b(B\n\u001b$Bm)\u001b(B\n\u001b$Bm*\u001b(B\n\u001b$Bm+\u001b(B\n\u001b$Bm,\u001b(B\n\u001b$Bm-\u001b(B\n\u001b$Bm.\u001b(B\n\u001b$Bm/\u001b(B\n\u001b$Bm0\u001b(B\n\u001b$Bm1\u001b(B\n\u001b$Bm2\u001b(B\n\u001b$Bm3\u001b(B\n\u001b$Bm4\u001b(B\n\u001b$Bm5\u001b(B\n\u001b$Bm6\u001b(B\n\u001b$Bm7\u001b(B\n\u001b$Bm8\u001b(B\n\u001b$Bm9\u001b(B\n\u001b$Bm:\u001b(B\n\u001b$Bm;\u001b(B\n\u001b$Bm<\u001b(B\n\u001b$Bm=\u001b(B\n\u001b$Bm>\u001b(B\n\u001b$Bm?\u001b(B\n\u001b$Bm@\u001b(B\n\u001b$BmA\u001b(B\n\u001b$BmB\u001b(B\n\u001b$BmC\u001b(B\n\u001b$BmD\u001b(B\n\u001b$BmE\u001b(B\n\u001b$BmF\u001b(B\n\u001b$BmG\u001b(B\n\u001b$BmH\u001b(B\n\u001b$BmI\u001b(B\n\u001b$BmJ\u001b(B\n\u001b$BmK\u001b(B\n\u001b$BmL\u001b(B\n\u001b$BmM\u001b(B\n\u001b$BmN\u001b(B\n\u001b$BmO\u001b(B\n\u001b$BmP\u001b(B\n\u001b$BmQ\u001b(B\n\u001b$BmR\u001b(B\n\u001b$BmS\u001b(B\n\u001b$BmT\u001b(B\n\u001b$BmU\u001b(B\n\u001b$BmV\u001b(B\n\u001b$BmW\u001b(B\n\u001b$BmX\u001b(B\n\u001b$BmY\u001b(B\n\u001b$BmZ\u001b(B\n\u001b$Bm[\u001b(B\n\u001b$Bm\\\u001b(B\n\u001b$Bm]\u001b(B\n\u001b$Bm^\u001b(B\n\u001b$Bm_\u001b(B\n\u001b$Bm`\u001b(B\n\u001b$Bma\u001b(B\n\u001b$Bmb\u001b(B\n\u001b$Bmc\u001b(B\n\u001b$Bmd\u001b(B\n\u001b$Bme\u001b(B\n\u001b$Bmf\u001b(B\n\u001b$Bmg\u001b(B\n\u001b$Bmh\u001b(B\n\u001b$Bmi\u001b(B\n\u001b$Bmj\u001b(B\n\u001b$Bmk\u001b(B\n\u001b$Bml\u001b(B\n\u001b$Bmm\u001b(B\n\u001b$Bmn\u001b(B\n\u001b$Bmo\u001b(B\n\u001b$Bmp\u001b(B\n\u001b$Bmq\u001b(B\n\u001b$Bmr\u001b(B\n\u001b$Bms\u001b(B\n\u001b$Bmt\u001b(B\n\u001b$Bmu\u001b(B\n\u001b$Bmv\u001b(B\n\u001b$Bmw\u001b(B\n\u001b$Bmx\u001b(B\n\u001b$Bmy\u001b(B\n\u001b$Bmz\u001b(B\n\u001b$Bm{\u001b(B\n\u001b$Bm|\u001b(B\n\u001b$Bm}\u001b(B\n\u001b$Bm~\u001b(B\n\u001b$Bn!\u001b(B\n\u001b$Bn\"\u001b(B\n\u001b$Bn#\u001b(B\n\u001b$Bn$\u001b(B\n\u001b$Bn%\u001b(B\n\u001b$Bn&\u001b(B\n\u001b$Bn'\u001b(B\n\u001b$Bn(\u001b(B\n\u001b$Bn)\u001b(B\n\u001b$Bn*\u001b(B\n\u001b$Bn+\u001b(B\n\u001b$Bn,\u001b(B\n\u001b$Bn-\u001b(B\n\u001b$Bn.\u001b(B\n\u001b$Bn/\u001b(B\n\u001b$Bn0\u001b(B\n\u001b$Bn1\u001b(B\n\u001b$Bn2\u001b(B\n\u001b$Bn3\u001b(B\n\u001b$Bn4\u001b(B\n\u001b$Bn5\u001b(B\n\u001b$Bn6\u001b(B\n\u001b$Bn7\u001b(B\n\u001b$Bn8\u001b(B\n\u001b$Bn9\u001b(B\n\u001b$Bn:\u001b(B\n\u001b$Bn;\u001b(B\n\u001b$Bn<\u001b(B\n\u001b$Bn=\u001b(B\n\u001b$Bn>\u001b(B\n\u001b$Bn?\u001b(B\n\u001b$Bn@\u001b(B\n\u001b$BnA\u001b(B\n\u001b$BnB\u001b(B\n\u001b$BnC\u001b(B\n\u001b$BnD\u001b(B\n\u001b$BnE\u001b(B\n\u001b$BnF\u001b(B\n\u001b$BnG\u001b(B\n\u001b$BnH\u001b(B\n\u001b$BnI\u001b(B\n\u001b$BnJ\u001b(B\n\u001b$BnK\u001b(B\n\u001b$BnL\u001b(B\n\u001b$BnM\u001b(B\n\u001b$BnN\u001b(B\n\u001b$BnO\u001b(B\n\u001b$BnP\u001b(B\n\u001b$BnQ\u001b(B\n\u001b$BnR\u001b(B\n\u001b$BnS\u001b(B\n\u001b$BnT\u001b(B\n\u001b$BnU\u001b(B\n\u001b$BnV\u001b(B\n\u001b$BnW\u001b(B\n\u001b$BnX\u001b(B\n\u001b$BnY\u001b(B\n\u001b$BnZ\u001b(B\n\u001b$Bn[\u001b(B\n\u001b$Bn\\\u001b(B\n\u001b$Bn]\u001b(B\n\u001b$Bn^\u001b(B\n\u001b$Bn_\u001b(B\n\u001b$Bn`\u001b(B\n\u001b$Bna\u001b(B\n\u001b$Bnb\u001b(B\n\u001b$Bnc\u001b(B\n\u001b$Bnd\u001b(B\n\u001b$Bne\u001b(B\n\u001b$Bnf\u001b(B\n\u001b$Bng\u001b(B\n\u001b$Bnh\u001b(B\n\u001b$Bni\u001b(B\n\u001b$Bnj\u001b(B\n\u001b$Bnk\u001b(B\n\u001b$Bnl\u001b(B\n\u001b$Bnm\u001b(B\n\u001b$Bnn\u001b(B\n\u001b$Bno\u001b(B\n\u001b$Bnp\u001b(B\n\u001b$Bnq\u001b(B\n\u001b$Bnr\u001b(B\n\u001b$Bns\u001b(B\n\u001b$Bnt\u001b(B\n\u001b$Bnu\u001b(B\n\u001b$Bnv\u001b(B\n\u001b$Bnw\u001b(B\n\u001b$Bnx\u001b(B\n\u001b$Bny\u001b(B\n\u001b$Bnz\u001b(B\n\u001b$Bn{\u001b(B\n\u001b$Bn|\u001b(B\n\u001b$Bn}\u001b(B\n\u001b$Bn~\u001b(B\n\u001b$Bo!\u001b(B\n\u001b$Bo\"\u001b(B\n\u001b$Bo#\u001b(B\n\u001b$Bo$\u001b(B\n\u001b$Bo%\u001b(B\n\u001b$Bo&\u001b(B\n\u001b$Bo'\u001b(B\n\u001b$Bo(\u001b(B\n\u001b$Bo)\u001b(B\n\u001b$Bo*\u001b(B\n\u001b$Bo+\u001b(B\n\u001b$Bo,\u001b(B\n\u001b$Bo-\u001b(B\n\u001b$Bo.\u001b(B\n\u001b$Bo/\u001b(B\n\u001b$Bo0\u001b(B\n\u001b$Bo1\u001b(B\n\u001b$Bo2\u001b(B\n\u001b$Bo3\u001b(B\n\u001b$Bo4\u001b(B\n\u001b$Bo5\u001b(B\n\u001b$Bo6\u001b(B\n\u001b$Bo7\u001b(B\n\u001b$Bo8\u001b(B\n\u001b$Bo9\u001b(B\n\u001b$Bo:\u001b(B\n\u001b$Bo;\u001b(B\n\u001b$Bo<\u001b(B\n\u001b$Bo=\u001b(B\n\u001b$Bo>\u001b(B\n\u001b$Bo?\u001b(B\n\u001b$Bo@\u001b(B\n\u001b$BoA\u001b(B\n\u001b$BoB\u001b(B\n\u001b$BoC\u001b(B\n\u001b$BoD\u001b(B\n\u001b$BoE\u001b(B\n\u001b$BoF\u001b(B\n\u001b$BoG\u001b(B\n\u001b$BoH\u001b(B\n\u001b$BoI\u001b(B\n\u001b$BoJ\u001b(B\n\u001b$BoK\u001b(B\n\u001b$BoL\u001b(B\n\u001b$BoM\u001b(B\n\u001b$BoN\u001b(B\n\u001b$BoO\u001b(B\n\u001b$BoP\u001b(B\n\u001b$BoQ\u001b(B\n\u001b$BoR\u001b(B\n\u001b$BoS\u001b(B\n\u001b$BoT\u001b(B\n\u001b$BoU\u001b(B\n\u001b$BoV\u001b(B\n\u001b$BoW\u001b(B\n\u001b$BoX\u001b(B\n\u001b$BoY\u001b(B\n\u001b$BoZ\u001b(B\n\u001b$Bo[\u001b(B\n\u001b$Bo\\\u001b(B\n\u001b$Bo]\u001b(B\n\u001b$Bo^\u001b(B\n\u001b$Bo_\u001b(B\n\u001b$Bo`\u001b(B\n\u001b$Boa\u001b(B\n\u001b$Bob\u001b(B\n\u001b$Boc\u001b(B\n\u001b$Bod\u001b(B\n\u001b$Boe\u001b(B\n\u001b$Bof\u001b(B\n\u001b$Bog\u001b(B\n\u001b$Boh\u001b(B\n\u001b$Boi\u001b(B\n\u001b$Boj\u001b(B\n\u001b$Bok\u001b(B\n\u001b$Bol\u001b(B\n\u001b$Bom\u001b(B\n\u001b$Bon\u001b(B\n\u001b$Boo\u001b(B\n\u001b$Bop\u001b(B\n\u001b$Boq\u001b(B\n\u001b$Bor\u001b(B\n\u001b$Bos\u001b(B\n\u001b$Bot\u001b(B\n\u001b$Bou\u001b(B\n\u001b$Bov\u001b(B\n\u001b$Bow\u001b(B\n\u001b$Box\u001b(B\n\u001b$Boy\u001b(B\n\u001b$Boz\u001b(B\n\u001b$Bo{\u001b(B\n\u001b$Bo|\u001b(B\n\u001b$Bo}\u001b(B\n\u001b$Bo~\u001b(B\n\u001b$Bp!\u001b(B\n\u001b$Bp\"\u001b(B\n\u001b$Bp#\u001b(B\n\u001b$Bp$\u001b(B\n\u001b$Bp%\u001b(B\n\u001b$Bp&\u001b(B\n\u001b$Bp'\u001b(B\n\u001b$Bp(\u001b(B\n\u001b$Bp)\u001b(B\n\u001b$Bp*\u001b(B\n\u001b$Bp+\u001b(B\n\u001b$Bp,\u001b(B\n\u001b$Bp-\u001b(B\n\u001b$Bp.\u001b(B\n\u001b$Bp/\u001b(B\n\u001b$Bp0\u001b(B\n\u001b$Bp1\u001b(B\n\u001b$Bp2\u001b(B\n\u001b$Bp3\u001b(B\n\u001b$Bp4\u001b(B\n\u001b$Bp5\u001b(B\n\u001b$Bp6\u001b(B\n\u001b$Bp7\u001b(B\n\u001b$Bp8\u001b(B\n\u001b$Bp9\u001b(B\n\u001b$Bp:\u001b(B\n\u001b$Bp;\u001b(B\n\u001b$Bp<\u001b(B\n\u001b$Bp=\u001b(B\n\u001b$Bp>\u001b(B\n\u001b$Bp?\u001b(B\n\u001b$Bp@\u001b(B\n\u001b$BpA\u001b(B\n\u001b$BpB\u001b(B\n\u001b$BpC\u001b(B\n\u001b$BpD\u001b(B\n\u001b$BpE\u001b(B\n\u001b$BpF\u001b(B\n\u001b$BpG\u001b(B\n\u001b$BpH\u001b(B\n\u001b$BpI\u001b(B\n\u001b$BpJ\u001b(B\n\u001b$BpK\u001b(B\n\u001b$BpL\u001b(B\n\u001b$BpM\u001b(B\n\u001b$BpN\u001b(B\n\u001b$BpO\u001b(B\n\u001b$BpP\u001b(B\n\u001b$BpQ\u001b(B\n\u001b$BpR\u001b(B\n\u001b$BpS\u001b(B\n\u001b$BpT\u001b(B\n\u001b$BpU\u001b(B\n\u001b$BpV\u001b(B\n\u001b$BpW\u001b(B\n\u001b$BpX\u001b(B\n\u001b$BpY\u001b(B\n\u001b$BpZ\u001b(B\n\u001b$Bp[\u001b(B\n\u001b$Bp\\\u001b(B\n\u001b$Bp]\u001b(B\n\u001b$Bp^\u001b(B\n\u001b$Bp_\u001b(B\n\u001b$Bp`\u001b(B\n\u001b$Bpa\u001b(B\n\u001b$Bpb\u001b(B\n\u001b$Bpc\u001b(B\n\u001b$Bpd\u001b(B\n\u001b$Bpe\u001b(B\n\u001b$Bpf\u001b(B\n\u001b$Bpg\u001b(B\n\u001b$Bph\u001b(B\n\u001b$Bpi\u001b(B\n\u001b$Bpj\u001b(B\n\u001b$Bpk\u001b(B\n\u001b$Bpl\u001b(B\n\u001b$Bpm\u001b(B\n\u001b$Bpn\u001b(B\n\u001b$Bpo\u001b(B\n\u001b$Bpp\u001b(B\n\u001b$Bpq\u001b(B\n\u001b$Bpr\u001b(B\n\u001b$Bps\u001b(B\n\u001b$Bpt\u001b(B\n\u001b$Bpu\u001b(B\n\u001b$Bpv\u001b(B\n\u001b$Bpw\u001b(B\n\u001b$Bpx\u001b(B\n\u001b$Bpy\u001b(B\n\u001b$Bpz\u001b(B\n\u001b$Bp{\u001b(B\n\u001b$Bp|\u001b(B\n\u001b$Bp}\u001b(B\n\u001b$Bp~\u001b(B\n\u001b$Bq!\u001b(B\n\u001b$Bq\"\u001b(B\n\u001b$Bq#\u001b(B\n\u001b$Bq$\u001b(B\n\u001b$Bq%\u001b(B\n\u001b$Bq&\u001b(B\n\u001b$Bq'\u001b(B\n\u001b$Bq(\u001b(B\n\u001b$Bq)\u001b(B\n\u001b$Bq*\u001b(B\n\u001b$Bq+\u001b(B\n\u001b$Bq,\u001b(B\n\u001b$Bq-\u001b(B\n\u001b$Bq.\u001b(B\n\u001b$Bq/\u001b(B\n\u001b$Bq0\u001b(B\n\u001b$Bq1\u001b(B\n\u001b$Bq2\u001b(B\n\u001b$Bq3\u001b(B\n\u001b$Bq4\u001b(B\n\u001b$Bq5\u001b(B\n\u001b$Bq6\u001b(B\n\u001b$Bq7\u001b(B\n\u001b$Bq8\u001b(B\n\u001b$Bq9\u001b(B\n\u001b$Bq:\u001b(B\n\u001b$Bq;\u001b(B\n\u001b$Bq<\u001b(B\n\u001b$Bq=\u001b(B\n\u001b$Bq>\u001b(B\n\u001b$Bq?\u001b(B\n\u001b$Bq@\u001b(B\n\u001b$BqA\u001b(B\n\u001b$BqB\u001b(B\n\u001b$BqC\u001b(B\n\u001b$BqD\u001b(B\n\u001b$BqE\u001b(B\n\u001b$BqF\u001b(B\n\u001b$BqG\u001b(B\n\u001b$BqH\u001b(B\n\u001b$BqI\u001b(B\n\u001b$BqJ\u001b(B\n\u001b$BqK\u001b(B\n\u001b$BqL\u001b(B\n\u001b$BqM\u001b(B\n\u001b$BqN\u001b(B\n\u001b$BqO\u001b(B\n\u001b$BqP\u001b(B\n\u001b$BqQ\u001b(B\n\u001b$BqR\u001b(B\n\u001b$BqS\u001b(B\n\u001b$BqT\u001b(B\n\u001b$BqU\u001b(B\n\u001b$BqV\u001b(B\n\u001b$BqW\u001b(B\n\u001b$BqX\u001b(B\n\u001b$BqY\u001b(B\n\u001b$BqZ\u001b(B\n\u001b$Bq[\u001b(B\n\u001b$Bq\\\u001b(B\n\u001b$Bq]\u001b(B\n\u001b$Bq^\u001b(B\n\u001b$Bq_\u001b(B\n\u001b$Bq`\u001b(B\n\u001b$Bqa\u001b(B\n\u001b$Bqb\u001b(B\n\u001b$Bqc\u001b(B\n\u001b$Bqd\u001b(B\n\u001b$Bqe\u001b(B\n\u001b$Bqf\u001b(B\n\u001b$Bqg\u001b(B\n\u001b$Bqh\u001b(B\n\u001b$Bqi\u001b(B\n\u001b$Bqj\u001b(B\n\u001b$Bqk\u001b(B\n\u001b$Bql\u001b(B\n\u001b$Bqm\u001b(B\n\u001b$Bqn\u001b(B\n\u001b$Bqo\u001b(B\n\u001b$Bqp\u001b(B\n\u001b$Bqq\u001b(B\n\u001b$Bqr\u001b(B\n\u001b$Bqs\u001b(B\n\u001b$Bqt\u001b(B\n\u001b$Bqu\u001b(B\n\u001b$Bqv\u001b(B\n\u001b$Bqw\u001b(B\n\u001b$Bqx\u001b(B\n\u001b$Bqy\u001b(B\n\u001b$Bqz\u001b(B\n\u001b$Bq{\u001b(B\n\u001b$Bq|\u001b(B\n\u001b$Bq}\u001b(B\n\u001b$Bq~\u001b(B\n\u001b$Br!\u001b(B\n\u001b$Br\"\u001b(B\n\u001b$Br#\u001b(B\n\u001b$Br$\u001b(B\n\u001b$Br%\u001b(B\n\u001b$Br&\u001b(B\n\u001b$Br'\u001b(B\n\u001b$Br(\u001b(B\n\u001b$Br)\u001b(B\n\u001b$Br*\u001b(B\n\u001b$Br+\u001b(B\n\u001b$Br,\u001b(B\n\u001b$Br-\u001b(B\n\u001b$Br.\u001b(B\n\u001b$Br/\u001b(B\n\u001b$Br0\u001b(B\n\u001b$Br1\u001b(B\n\u001b$Br2\u001b(B\n\u001b$Br3\u001b(B\n\u001b$Br4\u001b(B\n\u001b$Br5\u001b(B\n\u001b$Br6\u001b(B\n\u001b$Br7\u001b(B\n\u001b$Br8\u001b(B\n\u001b$Br9\u001b(B\n\u001b$Br:\u001b(B\n\u001b$Br;\u001b(B\n\u001b$Br<\u001b(B\n\u001b$Br=\u001b(B\n\u001b$Br>\u001b(B\n\u001b$Br?\u001b(B\n\u001b$Br@\u001b(B\n\u001b$BrA\u001b(B\n\u001b$BrB\u001b(B\n\u001b$BrC\u001b(B\n\u001b$BrD\u001b(B\n\u001b$BrE\u001b(B\n\u001b$BrF\u001b(B\n\u001b$BrG\u001b(B\n\u001b$BrH\u001b(B\n\u001b$BrI\u001b(B\n\u001b$BrJ\u001b(B\n\u001b$BrK\u001b(B\n\u001b$BrL\u001b(B\n\u001b$BrM\u001b(B\n\u001b$BrN\u001b(B\n\u001b$BrO\u001b(B\n\u001b$BrP\u001b(B\n\u001b$BrQ\u001b(B\n\u001b$BrR\u001b(B\n\u001b$BrS\u001b(B\n\u001b$BrT\u001b(B\n\u001b$BrU\u001b(B\n\u001b$BrV\u001b(B\n\u001b$BrW\u001b(B\n\u001b$BrX\u001b(B\n\u001b$BrY\u001b(B\n\u001b$BrZ\u001b(B\n\u001b$Br[\u001b(B\n\u001b$Br\\\u001b(B\n\u001b$Br]\u001b(B\n\u001b$Br^\u001b(B\n\u001b$Br_\u001b(B\n\u001b$Br`\u001b(B\n\u001b$Bra\u001b(B\n\u001b$Brb\u001b(B\n\u001b$Brc\u001b(B\n\u001b$Brd\u001b(B\n\u001b$Bre\u001b(B\n\u001b$Brf\u001b(B\n\u001b$Brg\u001b(B\n\u001b$Brh\u001b(B\n\u001b$Bri\u001b(B\n\u001b$Brj\u001b(B\n\u001b$Brk\u001b(B\n\u001b$Brl\u001b(B\n\u001b$Brm\u001b(B\n\u001b$Brn\u001b(B\n\u001b$Bro\u001b(B\n\u001b$Brp\u001b(B\n\u001b$Brq\u001b(B\n\u001b$Brr\u001b(B\n\u001b$Brs\u001b(B\n\u001b$Brt\u001b(B\n\u001b$Bru\u001b(B\n\u001b$Brv\u001b(B\n\u001b$Brw\u001b(B\n\u001b$Brx\u001b(B\n\u001b$Bry\u001b(B\n\u001b$Brz\u001b(B\n\u001b$Br{\u001b(B\n\u001b$Br|\u001b(B\n\u001b$Br}\u001b(B\n\u001b$Br~\u001b(B\n\u001b$Bs!\u001b(B\n\u001b$Bs\"\u001b(B\n\u001b$Bs#\u001b(B\n\u001b$Bs$\u001b(B\n\u001b$Bs%\u001b(B\n\u001b$Bs&\u001b(B\n\u001b$Bs'\u001b(B\n\u001b$Bs(\u001b(B\n\u001b$Bs)\u001b(B\n\u001b$Bs*\u001b(B\n\u001b$Bs+\u001b(B\n\u001b$Bs,\u001b(B\n\u001b$Bs-\u001b(B\n\u001b$Bs.\u001b(B\n\u001b$Bs/\u001b(B\n\u001b$Bs0\u001b(B\n\u001b$Bs1\u001b(B\n\u001b$Bs2\u001b(B\n\u001b$Bs3\u001b(B\n\u001b$Bs4\u001b(B\n\u001b$Bs5\u001b(B\n\u001b$Bs6\u001b(B\n\u001b$Bs7\u001b(B\n\u001b$Bs8\u001b(B\n\u001b$Bs9\u001b(B\n\u001b$Bs:\u001b(B\n\u001b$Bs;\u001b(B\n\u001b$Bs<\u001b(B\n\u001b$Bs=\u001b(B\n\u001b$Bs>\u001b(B\n\u001b$Bs?\u001b(B\n\u001b$Bs@\u001b(B\n\u001b$BsA\u001b(B\n\u001b$BsB\u001b(B\n\u001b$BsC\u001b(B\n\u001b$BsD\u001b(B\n\u001b$BsE\u001b(B\n\u001b$BsF\u001b(B\n\u001b$BsG\u001b(B\n\u001b$BsH\u001b(B\n\u001b$BsI\u001b(B\n\u001b$BsJ\u001b(B\n\u001b$BsK\u001b(B\n\u001b$BsL\u001b(B\n\u001b$BsM\u001b(B\n\u001b$BsN\u001b(B\n\u001b$BsO\u001b(B\n\u001b$BsP\u001b(B\n\u001b$BsQ\u001b(B\n\u001b$BsR\u001b(B\n\u001b$BsS\u001b(B\n\u001b$BsT\u001b(B\n\u001b$BsU\u001b(B\n\u001b$BsV\u001b(B\n\u001b$BsW\u001b(B\n\u001b$BsX\u001b(B\n\u001b$BsY\u001b(B\n\u001b$BsZ\u001b(B\n\u001b$Bs[\u001b(B\n\u001b$Bs\\\u001b(B\n\u001b$Bs]\u001b(B\n\u001b$Bs^\u001b(B\n\u001b$Bs_\u001b(B\n\u001b$Bs`\u001b(B\n\u001b$Bsa\u001b(B\n\u001b$Bsb\u001b(B\n\u001b$Bsc\u001b(B\n\u001b$Bsd\u001b(B\n\u001b$Bse\u001b(B\n\u001b$Bsf\u001b(B\n\u001b$Bsg\u001b(B\n\u001b$Bsh\u001b(B\n\u001b$Bsi\u001b(B\n\u001b$Bsj\u001b(B\n\u001b$Bsk\u001b(B\n\u001b$Bsl\u001b(B\n\u001b$Bsm\u001b(B\n\u001b$Bsn\u001b(B\n\u001b$Bso\u001b(B\n\u001b$Bsp\u001b(B\n\u001b$Bsq\u001b(B\n\u001b$Bsr\u001b(B\n\u001b$Bss\u001b(B\n\u001b$Bst\u001b(B\n\u001b$Bsu\u001b(B\n\u001b$Bsv\u001b(B\n\u001b$Bsw\u001b(B\n\u001b$Bsx\u001b(B\n\u001b$Bsy\u001b(B\n\u001b$Bsz\u001b(B\n\u001b$Bs{\u001b(B\n\u001b$Bs|\u001b(B\n\u001b$Bs}\u001b(B\n\u001b$Bs~\u001b(B\n\u001b$Bt!\u001b(B\n\u001b$Bt\"\u001b(B\n\u001b$Bt#\u001b(B\n\u001b$Bt$\u001b(B\n\u001b$Bt%\u001b(B\n\u001b$Bt&\u001b(B\n\u001b$By!\u001b(B\n\u001b$By\"\u001b(B\n\u001b$By#\u001b(B\n\u001b$By$\u001b(B\n\u001b$By%\u001b(B\n\u001b$By&\u001b(B\n\u001b$By'\u001b(B\n\u001b$By(\u001b(B\n\u001b$By)\u001b(B\n\u001b$By*\u001b(B\n\u001b$By+\u001b(B\n\u001b$By,\u001b(B\n\u001b$By-\u001b(B\n\u001b$By.\u001b(B\n\u001b$By/\u001b(B\n\u001b$By0\u001b(B\n\u001b$By1\u001b(B\n\u001b$By2\u001b(B\n\u001b$By3\u001b(B\n\u001b$By4\u001b(B\n\u001b$By5\u001b(B\n\u001b$By6\u001b(B\n\u001b$By7\u001b(B\n\u001b$By8\u001b(B\n\u001b$By9\u001b(B\n\u001b$By:\u001b(B\n\u001b$By;\u001b(B\n\u001b$By<\u001b(B\n\u001b$By=\u001b(B\n\u001b$By>\u001b(B\n\u001b$By?\u001b(B\n\u001b$By@\u001b(B\n\u001b$ByA\u001b(B\n\u001b$ByB\u001b(B\n\u001b$ByC\u001b(B\n\u001b$ByD\u001b(B\n\u001b$ByE\u001b(B\n\u001b$ByF\u001b(B\n\u001b$ByG\u001b(B\n\u001b$ByH\u001b(B\n\u001b$ByI\u001b(B\n\u001b$ByJ\u001b(B\n\u001b$ByK\u001b(B\n\u001b$ByL\u001b(B\n\u001b$ByM\u001b(B\n\u001b$ByN\u001b(B\n\u001b$ByO\u001b(B\n\u001b$ByP\u001b(B\n\u001b$ByQ\u001b(B\n\u001b$ByR\u001b(B\n\u001b$ByS\u001b(B\n\u001b$ByT\u001b(B\n\u001b$ByU\u001b(B\n\u001b$ByV\u001b(B\n\u001b$ByW\u001b(B\n\u001b$ByX\u001b(B\n\u001b$ByY\u001b(B\n\u001b$ByZ\u001b(B\n\u001b$By[\u001b(B\n\u001b$By\\\u001b(B\n\u001b$By]\u001b(B\n\u001b$By^\u001b(B\n\u001b$By_\u001b(B\n\u001b$By`\u001b(B\n\u001b$Bya\u001b(B\n\u001b$Byb\u001b(B\n\u001b$Byc\u001b(B\n\u001b$Byd\u001b(B\n\u001b$Bye\u001b(B\n\u001b$Byf\u001b(B\n\u001b$Byg\u001b(B\n\u001b$Byh\u001b(B\n\u001b$Byi\u001b(B\n\u001b$Byj\u001b(B\n\u001b$Byk\u001b(B\n\u001b$Byl\u001b(B\n\u001b$Bym\u001b(B\n\u001b$Byn\u001b(B\n\u001b$Byo\u001b(B\n\u001b$Byp\u001b(B\n\u001b$Byq\u001b(B\n\u001b$Byr\u001b(B\n\u001b$Bys\u001b(B\n\u001b$Byt\u001b(B\n\u001b$Byu\u001b(B\n\u001b$Byv\u001b(B\n\u001b$Byw\u001b(B\n\u001b$Byx\u001b(B\n\u001b$Byy\u001b(B\n\u001b$Byz\u001b(B\n\u001b$By{\u001b(B\n\u001b$By|\u001b(B\n\u001b$By}\u001b(B\n\u001b$By~\u001b(B\n\u001b$Bz!\u001b(B\n\u001b$Bz\"\u001b(B\n\u001b$Bz#\u001b(B\n\u001b$Bz$\u001b(B\n\u001b$Bz%\u001b(B\n\u001b$Bz&\u001b(B\n\u001b$Bz'\u001b(B\n\u001b$Bz(\u001b(B\n\u001b$Bz)\u001b(B\n\u001b$Bz*\u001b(B\n\u001b$Bz+\u001b(B\n\u001b$Bz,\u001b(B\n\u001b$Bz-\u001b(B\n\u001b$Bz.\u001b(B\n\u001b$Bz/\u001b(B\n\u001b$Bz0\u001b(B\n\u001b$Bz1\u001b(B\n\u001b$Bz2\u001b(B\n\u001b$Bz3\u001b(B\n\u001b$Bz4\u001b(B\n\u001b$Bz5\u001b(B\n\u001b$Bz6\u001b(B\n\u001b$Bz7\u001b(B\n\u001b$Bz8\u001b(B\n\u001b$Bz9\u001b(B\n\u001b$Bz:\u001b(B\n\u001b$Bz;\u001b(B\n\u001b$Bz<\u001b(B\n\u001b$Bz=\u001b(B\n\u001b$Bz>\u001b(B\n\u001b$Bz?\u001b(B\n\u001b$Bz@\u001b(B\n\u001b$BzA\u001b(B\n\u001b$BzB\u001b(B\n\u001b$BzC\u001b(B\n\u001b$BzD\u001b(B\n\u001b$BzE\u001b(B\n\u001b$BzF\u001b(B\n\u001b$BzG\u001b(B\n\u001b$BzH\u001b(B\n\u001b$BzI\u001b(B\n\u001b$BzJ\u001b(B\n\u001b$BzK\u001b(B\n\u001b$BzL\u001b(B\n\u001b$BzM\u001b(B\n\u001b$BzN\u001b(B\n\u001b$BzO\u001b(B\n\u001b$BzP\u001b(B\n\u001b$BzQ\u001b(B\n\u001b$BzR\u001b(B\n\u001b$BzS\u001b(B\n\u001b$BzT\u001b(B\n\u001b$BzU\u001b(B\n\u001b$BzV\u001b(B\n\u001b$BzW\u001b(B\n\u001b$BzX\u001b(B\n\u001b$BzY\u001b(B\n\u001b$BzZ\u001b(B\n\u001b$Bz[\u001b(B\n\u001b$Bz\\\u001b(B\n\u001b$Bz]\u001b(B\n\u001b$Bz^\u001b(B\n\u001b$Bz_\u001b(B\n\u001b$Bz`\u001b(B\n\u001b$Bza\u001b(B\n\u001b$Bzb\u001b(B\n\u001b$Bzc\u001b(B\n\u001b$Bzd\u001b(B\n\u001b$Bze\u001b(B\n\u001b$Bzf\u001b(B\n\u001b$Bzg\u001b(B\n\u001b$Bzh\u001b(B\n\u001b$Bzi\u001b(B\n\u001b$Bzj\u001b(B\n\u001b$Bzk\u001b(B\n\u001b$Bzl\u001b(B\n\u001b$Bzm\u001b(B\n\u001b$Bzn\u001b(B\n\u001b$Bzo\u001b(B\n\u001b$Bzp\u001b(B\n\u001b$Bzq\u001b(B\n\u001b$Bzr\u001b(B\n\u001b$Bzs\u001b(B\n\u001b$Bzt\u001b(B\n\u001b$Bzu\u001b(B\n\u001b$Bzv\u001b(B\n\u001b$Bzw\u001b(B\n\u001b$Bzx\u001b(B\n\u001b$Bzy\u001b(B\n\u001b$Bzz\u001b(B\n\u001b$Bz{\u001b(B\n\u001b$Bz|\u001b(B\n\u001b$Bz}\u001b(B\n\u001b$Bz~\u001b(B\n\u001b$B{!\u001b(B\n\u001b$B{\"\u001b(B\n\u001b$B{#\u001b(B\n\u001b$B{$\u001b(B\n\u001b$B{%\u001b(B\n\u001b$B{&\u001b(B\n\u001b$B{'\u001b(B\n\u001b$B{(\u001b(B\n\u001b$B{)\u001b(B\n\u001b$B{*\u001b(B\n\u001b$B{+\u001b(B\n\u001b$B{,\u001b(B\n\u001b$B{-\u001b(B\n\u001b$B{.\u001b(B\n\u001b$B{/\u001b(B\n\u001b$B{0\u001b(B\n\u001b$B{1\u001b(B\n\u001b$B{2\u001b(B\n\u001b$B{3\u001b(B\n\u001b$B{4\u001b(B\n\u001b$B{5\u001b(B\n\u001b$B{6\u001b(B\n\u001b$B{7\u001b(B\n\u001b$B{8\u001b(B\n\u001b$B{9\u001b(B\n\u001b$B{:\u001b(B\n\u001b$B{;\u001b(B\n\u001b$B{<\u001b(B\n\u001b$B{=\u001b(B\n\u001b$B{>\u001b(B\n\u001b$B{?\u001b(B\n\u001b$B{@\u001b(B\n\u001b$B{A\u001b(B\n\u001b$B{B\u001b(B\n\u001b$B{C\u001b(B\n\u001b$B{D\u001b(B\n\u001b$B{E\u001b(B\n\u001b$B{F\u001b(B\n\u001b$B{G\u001b(B\n\u001b$B{H\u001b(B\n\u001b$B{I\u001b(B\n\u001b$B{J\u001b(B\n\u001b$B{K\u001b(B\n\u001b$B{L\u001b(B\n\u001b$B{M\u001b(B\n\u001b$B{N\u001b(B\n\u001b$B{O\u001b(B\n\u001b$B{P\u001b(B\n\u001b$B{Q\u001b(B\n\u001b$B{R\u001b(B\n\u001b$B{S\u001b(B\n\u001b$B{T\u001b(B\n\u001b$B{U\u001b(B\n\u001b$B{V\u001b(B\n\u001b$B{W\u001b(B\n\u001b$B{X\u001b(B\n\u001b$B{Y\u001b(B\n\u001b$B{Z\u001b(B\n\u001b$B{[\u001b(B\n\u001b$B{\\\u001b(B\n\u001b$B{]\u001b(B\n\u001b$B{^\u001b(B\n\u001b$B{_\u001b(B\n\u001b$B{`\u001b(B\n\u001b$B{a\u001b(B\n\u001b$B{b\u001b(B\n\u001b$B{c\u001b(B\n\u001b$B{d\u001b(B\n\u001b$B{e\u001b(B\n\u001b$B{f\u001b(B\n\u001b$B{g\u001b(B\n\u001b$B{h\u001b(B\n\u001b$B{i\u001b(B\n\u001b$B{j\u001b(B\n\u001b$B{k\u001b(B\n\u001b$B{l\u001b(B\n\u001b$B{m\u001b(B\n\u001b$B{n\u001b(B\n\u001b$B{o\u001b(B\n\u001b$B{p\u001b(B\n\u001b$B{q\u001b(B\n\u001b$B{r\u001b(B\n\u001b$B{s\u001b(B\n\u001b$B{t\u001b(B\n\u001b$B{u\u001b(B\n\u001b$B{v\u001b(B\n\u001b$B{w\u001b(B\n\u001b$B{x\u001b(B\n\u001b$B{y\u001b(B\n\u001b$B{z\u001b(B\n\u001b$B{{\u001b(B\n\u001b$B{|\u001b(B\n\u001b$B{}\u001b(B\n\u001b$B{~\u001b(B\n\u001b$B|!\u001b(B\n\u001b$B|\"\u001b(B\n\u001b$B|#\u001b(B\n\u001b$B|$\u001b(B\n\u001b$B|%\u001b(B\n\u001b$B|&\u001b(B\n\u001b$B|'\u001b(B\n\u001b$B|(\u001b(B\n\u001b$B|)\u001b(B\n\u001b$B|*\u001b(B\n\u001b$B|+\u001b(B\n\u001b$B|,\u001b(B\n\u001b$B|-\u001b(B\n\u001b$B|.\u001b(B\n\u001b$B|/\u001b(B\n\u001b$B|0\u001b(B\n\u001b$B|1\u001b(B\n\u001b$B|2\u001b(B\n\u001b$B|3\u001b(B\n\u001b$B|4\u001b(B\n\u001b$B|5\u001b(B\n\u001b$B|6\u001b(B\n\u001b$B|7\u001b(B\n\u001b$B|8\u001b(B\n\u001b$B|9\u001b(B\n\u001b$B|:\u001b(B\n\u001b$B|;\u001b(B\n\u001b$B|<\u001b(B\n\u001b$B|=\u001b(B\n\u001b$B|>\u001b(B\n\u001b$B|?\u001b(B\n\u001b$B|@\u001b(B\n\u001b$B|A\u001b(B\n\u001b$B|B\u001b(B\n\u001b$B|C\u001b(B\n\u001b$B|D\u001b(B\n\u001b$B|E\u001b(B\n\u001b$B|F\u001b(B\n\u001b$B|G\u001b(B\n\u001b$B|H\u001b(B\n\u001b$B|I\u001b(B\n\u001b$B|J\u001b(B\n\u001b$B|K\u001b(B\n\u001b$B|L\u001b(B\n\u001b$B|M\u001b(B\n\u001b$B|N\u001b(B\n\u001b$B|O\u001b(B\n\u001b$B|P\u001b(B\n\u001b$B|Q\u001b(B\n\u001b$B|R\u001b(B\n\u001b$B|S\u001b(B\n\u001b$B|T\u001b(B\n\u001b$B|U\u001b(B\n\u001b$B|V\u001b(B\n\u001b$B|W\u001b(B\n\u001b$B|X\u001b(B\n\u001b$B|Y\u001b(B\n\u001b$B|Z\u001b(B\n\u001b$B|[\u001b(B\n\u001b$B|\\\u001b(B\n\u001b$B|]\u001b(B\n\u001b$B|^\u001b(B\n\u001b$B|_\u001b(B\n\u001b$B|`\u001b(B\n\u001b$B|a\u001b(B\n\u001b$B|b\u001b(B\n\u001b$B|c\u001b(B\n\u001b$B|d\u001b(B\n\u001b$B|e\u001b(B\n\u001b$B|f\u001b(B\n\u001b$B|g\u001b(B\n\u001b$B|h\u001b(B\n\u001b$B|i\u001b(B\n\u001b$B|j\u001b(B\n\u001b$B|k\u001b(B\n\u001b$B|l\u001b(B\n\u001b$B|m\u001b(B\n\u001b$B|n\u001b(B\n\u001b$B|q\u001b(B\n\u001b$B|r\u001b(B\n\u001b$B|s\u001b(B\n\u001b$B|t\u001b(B\n\u001b$B|u\u001b(B\n\u001b$B|v\u001b(B\n\u001b$B|w\u001b(B\n\u001b$B|x\u001b(B\n\u001b$B|y\u001b(B\n\u001b$B|z\u001b(B\n\u001b$B\"L\u001b(B\n\u001b$B||\u001b(B\n\u001b$B|}\u001b(B\n\u001b$B|~\u001b(B\n\u001b$B!#\u001b(B\n\u001b$B!V\u001b(B\n\u001b$B!W\u001b(B\n\u001b$B!\"\u001b(B\n\u001b$B!&\u001b(B\n\u001b$B%r\u001b(B\n\u001b$B%!\u001b(B\n\u001b$B%#\u001b(B\n\u001b$B%%\u001b(B\n\u001b$B%'\u001b(B\n\u001b$B%)\u001b(B\n\u001b$B%c\u001b(B\n\u001b$B%e\u001b(B\n\u001b$B%g\u001b(B\n\u001b$B%C\u001b(B\n\u001b$B!<\u001b(B\n\u001b$B%\"\u001b(B\n\u001b$B%$\u001b(B\n\u001b$B%&\u001b(B\n\u001b$B%(\u001b(B\n\u001b$B%*\u001b(B\n\u001b$B%+\u001b(B\n\u001b$B%-\u001b(B\n\u001b$B%/\u001b(B\n\u001b$B%1\u001b(B\n\u001b$B%3\u001b(B\n\u001b$B%5\u001b(B\n\u001b$B%7\u001b(B\n\u001b$B%9\u001b(B\n\u001b$B%;\u001b(B\n\u001b$B%=\u001b(B\n\u001b$B%?\u001b(B\n\u001b$B%A\u001b(B\n\u001b$B%D\u001b(B\n\u001b$B%F\u001b(B\n\u001b$B%H\u001b(B\n\u001b$B%J\u001b(B\n\u001b$B%K\u001b(B\n\u001b$B%L\u001b(B\n\u001b$B%M\u001b(B\n\u001b$B%N\u001b(B\n\u001b$B%O\u001b(B\n\u001b$B%R\u001b(B\n\u001b$B%U\u001b(B\n\u001b$B%X\u001b(B\n\u001b$B%[\u001b(B\n\u001b$B%^\u001b(B\n\u001b$B%_\u001b(B\n\u001b$B%`\u001b(B\n\u001b$B%a\u001b(B\n\u001b$B%b\u001b(B\n\u001b$B%d\u001b(B\n\u001b$B%f\u001b(B\n\u001b$B%h\u001b(B\n\u001b$B%i\u001b(B\n\u001b$B%j\u001b(B\n\u001b$B%k\u001b(B\n\u001b$B%l\u001b(B\n\u001b$B%m\u001b(B\n\u001b$B%o\u001b(B\n\u001b$B%s\u001b(B\n\u001b$B!+\u001b(B\n\u001b$B!,\u001b(B\n"
  },
  {
    "path": "helix-view/tests/encoding/jis0208_in.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n¡\n¢\n£\n¤\n¥\n¦\n§\n¨\n©\nª\n«\n¬\n­\n®\n¯\n°\n±\n²\n³\n´\nµ\n¶\n·\n¸\n¹\nº\n»\n¼\n½\n¾\n¿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ná\nâ\nã\nä\nå\næ\nç\nè\né\nê\në\nì\ní\nî\nï\nð\nñ\nò\nó\nô\nõ\nö\n÷\nø\nù\nú\nû\nü\ný\nþ\nÿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nġ\nĢ\nģ\nĤ\nĥ\nĦ\nħ\nĨ\nĩ\nĪ\nī\nĬ\nĭ\nĮ\nį\nİ\nı\nĲ\nĳ\nĴ\nĵ\nĶ\nķ\nĸ\nĹ\nĺ\nĻ\nļ\nĽ\nľ\nĿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nš\nŢ\nţ\nŤ\nť\nŦ\nŧ\nŨ\nũ\nŪ\nū\nŬ\nŭ\nŮ\nů\nŰ\nű\nŲ\nų\nŴ\nŵ\nŶ\nŷ\nŸ\nŹ\nź\nŻ\nż\nŽ\nž\nſ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nơ\nƢ\nƣ\nƤ\nƥ\nƦ\nƧ\nƨ\nƩ\nƪ\nƫ\nƬ\nƭ\nƮ\nƯ\nư\nƱ\nƲ\nƳ\nƴ\nƵ\nƶ\nƷ\nƸ\nƹ\nƺ\nƻ\nƼ\nƽ\nƾ\nƿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nǡ\nǢ\nǣ\nǤ\nǥ\nǦ\nǧ\nǨ\nǩ\nǪ\nǫ\nǬ\nǭ\nǮ\nǯ\nǰ\nǱ\nǲ\nǳ\nǴ\nǵ\nǶ\nǷ\nǸ\nǹ\nǺ\nǻ\nǼ\nǽ\nǾ\nǿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nȡ\nȢ\nȣ\nȤ\nȥ\nȦ\nȧ\nȨ\nȩ\nȪ\nȫ\nȬ\nȭ\nȮ\nȯ\nȰ\nȱ\nȲ\nȳ\nȴ\nȵ\nȶ\nȷ\nȸ\nȹ\nȺ\nȻ\nȼ\nȽ\nȾ\nȿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nɡ\nɢ\nɣ\nɤ\nɥ\nɦ\nɧ\nɨ\nɩ\nɪ\nɫ\nɬ\nɭ\nɮ\nɯ\nɰ\nɱ\nɲ\nɳ\nɴ\nɵ\nɶ\nɷ\nɸ\nɹ\nɺ\nɻ\nɼ\nɽ\nɾ\nɿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nʡ\nʢ\nʣ\nʤ\nʥ\nʦ\nʧ\nʨ\nʩ\nʪ\nʫ\nʬ\nʭ\nʮ\nʯ\nʰ\nʱ\nʲ\nʳ\nʴ\nʵ\nʶ\nʷ\nʸ\nʹ\nʺ\nʻ\nʼ\nʽ\nʾ\nʿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nˡ\nˢ\nˣ\nˤ\n˥\n˦\n˧\n˨\n˩\n˪\n˫\nˬ\n˭\nˮ\n˯\n˰\n˱\n˲\n˳\n˴\n˵\n˶\n˷\n˸\n˹\n˺\n˻\n˼\n˽\n˾\n˿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n̡\n̢\ṇ\n̤\n̥\n̦\ņ\n̨\n̩\n̪\n̫\n̬\ṋ\n̮\n̯\n̰\ṉ\n̲\n̳\n̴\n̵\n̶\n̷\n̸\n̹\n̺\n̻\n̼\n̽\n̾\n̿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n͡\n͢\nͣ\nͤ\nͥ\nͦ\nͧ\nͨ\nͩ\nͪ\nͫ\nͬ\nͭ\nͮ\nͯ\nͰ\nͱ\nͲ\nͳ\nʹ\n͵\nͶ\nͷ\n͸\n͹\nͺ\nͻ\nͼ\nͽ\n;\nͿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nΡ\n΢\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nΪ\nΫ\nά\nέ\nή\nί\nΰ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nϡ\nϢ\nϣ\nϤ\nϥ\nϦ\nϧ\nϨ\nϩ\nϪ\nϫ\nϬ\nϭ\nϮ\nϯ\nϰ\nϱ\nϲ\nϳ\nϴ\nϵ\n϶\nϷ\nϸ\nϹ\nϺ\nϻ\nϼ\nϽ\nϾ\nϿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nѡ\nѢ\nѣ\nѤ\nѥ\nѦ\nѧ\nѨ\nѩ\nѪ\nѫ\nѬ\nѭ\nѮ\nѯ\nѰ\nѱ\nѲ\nѳ\nѴ\nѵ\nѶ\nѷ\nѸ\nѹ\nѺ\nѻ\nѼ\nѽ\nѾ\nѿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nҡ\nҢ\nң\nҤ\nҥ\nҦ\nҧ\nҨ\nҩ\nҪ\nҫ\nҬ\nҭ\nҮ\nү\nҰ\nұ\nҲ\nҳ\nҴ\nҵ\nҶ\nҷ\nҸ\nҹ\nҺ\nһ\nҼ\nҽ\nҾ\nҿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nӡ\nӢ\nӣ\nӤ\nӥ\nӦ\nӧ\nӨ\nө\nӪ\nӫ\nӬ\nӭ\nӮ\nӯ\nӰ\nӱ\nӲ\nӳ\nӴ\nӵ\nӶ\nӷ\nӸ\nӹ\nӺ\nӻ\nӼ\nӽ\nӾ\nӿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nԡ\nԢ\nԣ\nԤ\nԥ\nԦ\nԧ\nԨ\nԩ\nԪ\nԫ\nԬ\nԭ\nԮ\nԯ\n԰\nԱ\nԲ\nԳ\nԴ\nԵ\nԶ\nԷ\nԸ\nԹ\nԺ\nԻ\nԼ\nԽ\nԾ\nԿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nա\nբ\nգ\nդ\nե\nզ\nէ\nը\nթ\nժ\nի\nլ\nխ\nծ\nկ\nհ\nձ\nղ\nճ\nմ\nյ\nն\nշ\nո\nչ\nպ\nջ\nռ\nս\nվ\nտ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n֡\n֢\n֣\n֤\n֥\n֦\n֧\n֨\n֩\n֪\n֫\n֬\n֭\n֮\n֯\nְ\nֱ\nֲ\nֳ\nִ\nֵ\nֶ\nַ\nָ\nֹ\nֺ\nֻ\nּ\nֽ\n־\nֿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nס\nע\nף\nפ\nץ\nצ\nק\nר\nש\nת\n׫\n׬\n׭\n׮\nׯ\nװ\nױ\nײ\n׳\n״\n׵\n׶\n׷\n׸\n׹\n׺\n׻\n׼\n׽\n׾\n׿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nء\nآ\nأ\nؤ\nإ\nئ\nا\nب\nة\nت\nث\nج\nح\nخ\nد\nذ\nر\nز\nس\nش\nص\nض\nط\nظ\nع\nغ\nػ\nؼ\nؽ\nؾ\nؿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n١\n٢\n٣\n٤\n٥\n٦\n٧\n٨\n٩\n٪\n٫\n٬\n٭\nٮ\nٯ\nٰ\nٱ\nٲ\nٳ\nٴ\nٵ\nٶ\nٷ\nٸ\nٹ\nٺ\nٻ\nټ\nٽ\nپ\nٿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nڡ\nڢ\nڣ\nڤ\nڥ\nڦ\nڧ\nڨ\nک\nڪ\nګ\nڬ\nڭ\nڮ\nگ\nڰ\nڱ\nڲ\nڳ\nڴ\nڵ\nڶ\nڷ\nڸ\nڹ\nں\nڻ\nڼ\nڽ\nھ\nڿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nۡ\nۢ\nۣ\nۤ\nۥ\nۦ\nۧ\nۨ\n۩\n۪\n۫\n۬\nۭ\nۮ\nۯ\n۰\n۱\n۲\n۳\n۴\n۵\n۶\n۷\n۸\n۹\nۺ\nۻ\nۼ\n۽\n۾\nۿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nܡ\nܢ\nܣ\nܤ\nܥ\nܦ\nܧ\nܨ\nܩ\nܪ\nܫ\nܬ\nܭ\nܮ\nܯ\nܰ\nܱ\nܲ\nܳ\nܴ\nܵ\nܶ\nܷ\nܸ\nܹ\nܺ\nܻ\nܼ\nܽ\nܾ\nܿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nݡ\nݢ\nݣ\nݤ\nݥ\nݦ\nݧ\nݨ\nݩ\nݪ\nݫ\nݬ\nݭ\nݮ\nݯ\nݰ\nݱ\nݲ\nݳ\nݴ\nݵ\nݶ\nݷ\nݸ\nݹ\nݺ\nݻ\nݼ\nݽ\nݾ\nݿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nޡ\nޢ\nޣ\nޤ\nޥ\nަ\nާ\nި\nީ\nު\nޫ\nެ\nޭ\nޮ\nޯ\nް\nޱ\n޲\n޳\n޴\n޵\n޶\n޷\n޸\n޹\n޺\n޻\n޼\n޽\n޾\n޿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nߡ\nߢ\nߣ\nߤ\nߥ\nߦ\nߧ\nߨ\nߩ\nߪ\n߫\n߬\n߭\n߮\n߯\n߰\n߱\n߲\n߳\nߴ\nߵ\n߶\n߷\n߸\n߹\nߺ\n߻\n߼\n߽\n߾\n߿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/jis0208_in_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n　\n、\n。\n，\n．\n・\n：\n；\n？\n！\n゛\n゜\n´\n｀\n¨\n＾\n￣\n＿\nヽ\nヾ\nゝ\nゞ\n〃\n仝\n々\n〆\n〇\nー\n―\n‐\n／\n＼\n～\n∥\n｜\n…\n‥\n‘\n’\n“\n”\n（\n）\n〔\n〕\n［\n］\n｛\n｝\n〈\n〉\n《\n》\n「\n」\n『\n』\n【\n】\n＋\n－\n±\n×\n÷\n＝\n≠\n＜\n＞\n≦\n≧\n∞\n∴\n♂\n♀\n°\n′\n″\n℃\n￥\n＄\n￠\n￡\n％\n＃\n＆\n＊\n＠\n§\n☆\n★\n○\n●\n◎\n◇\n◆\n□\n■\n△\n▲\n▽\n▼\n※\n〒\n→\n←\n↑\n↓\n〓\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n∈\n∋\n⊆\n⊇\n⊂\n⊃\n∪\n∩\n�\n�\n�\n�\n�\n�\n�\n�\n∧\n∨\n￢\n⇒\n⇔\n∀\n∃\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n∠\n⊥\n⌒\n∂\n∇\n≡\n≒\n≪\n≫\n√\n∽\n∝\n∵\n∫\n∬\n�\n�\n�\n�\n�\n�\n�\nÅ\n‰\n♯\n♭\n♪\n†\n‡\n¶\n�\n�\n�\n�\n◯\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\n�\n�\n�\n�\n�\n�\n�\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\n�\n�\n�\n�\n�\n�\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\n�\n�\n�\n�\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\n�\n�\n�\n�\n�\n�\n�\n�\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\n�\n�\n�\n�\n�\n�\n�\n�\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n─\n│\n┌\n┐\n┘\n└\n├\n┬\n┤\n┴\n┼\n━\n┃\n┏\n┓\n┛\n┗\n┣\n┳\n┫\n┻\n╋\n┠\n┯\n┨\n┷\n┿\n┝\n┰\n┥\n┸\n╂\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n⑪\n⑫\n⑬\n⑭\n⑮\n⑯\n⑰\n⑱\n⑲\n⑳\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n�\n㍉\n㌔\n㌢\n㍍\n㌘\n㌧\n㌃\n㌶\n㍑\n㍗\n㌍\n㌦\n㌣\n㌫\n㍊\n㌻\n㎜\n㎝\n㎞\n㎎\n㎏\n㏄\n㎡\n�\n�\n�\n�\n�\n�\n�\n�\n㍻\n〝\n〟\n№\n㏍\n℡\n㊤\n㊥\n㊦\n㊧\n㊨\n㈱\n㈲\n㈹\n㍾\n㍽\n㍼\n≒\n≡\n∫\n∮\n∑\n√\n⊥\n∠\n∟\n⊿\n∵\n∩\n∪\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n亜\n唖\n娃\n阿\n哀\n愛\n挨\n姶\n逢\n葵\n茜\n穐\n悪\n握\n渥\n旭\n葦\n芦\n鯵\n梓\n圧\n斡\n扱\n宛\n姐\n虻\n飴\n絢\n綾\n鮎\n或\n粟\n袷\n安\n庵\n按\n暗\n案\n闇\n鞍\n杏\n以\n伊\n位\n依\n偉\n囲\n夷\n委\n威\n尉\n惟\n意\n慰\n易\n椅\n為\n畏\n異\n移\n維\n緯\n胃\n萎\n衣\n謂\n違\n遺\n医\n井\n亥\n域\n育\n郁\n磯\n一\n壱\n溢\n逸\n稲\n茨\n芋\n鰯\n允\n印\n咽\n員\n因\n姻\n引\n飲\n淫\n胤\n蔭\n院\n陰\n隠\n韻\n吋\n右\n宇\n烏\n羽\n迂\n雨\n卯\n鵜\n窺\n丑\n碓\n臼\n渦\n嘘\n唄\n欝\n蔚\n鰻\n姥\n厩\n浦\n瓜\n閏\n噂\n云\n運\n雲\n荏\n餌\n叡\n営\n嬰\n影\n映\n曳\n栄\n永\n泳\n洩\n瑛\n盈\n穎\n頴\n英\n衛\n詠\n鋭\n液\n疫\n益\n駅\n悦\n謁\n越\n閲\n榎\n厭\n円\n園\n堰\n奄\n宴\n延\n怨\n掩\n援\n沿\n演\n炎\n焔\n煙\n燕\n猿\n縁\n艶\n苑\n薗\n遠\n鉛\n鴛\n塩\n於\n汚\n甥\n凹\n央\n奥\n往\n応\n押\n旺\n横\n欧\n殴\n王\n翁\n襖\n鴬\n鴎\n黄\n岡\n沖\n荻\n億\n屋\n憶\n臆\n桶\n牡\n乙\n俺\n卸\n恩\n温\n穏\n音\n下\n化\n仮\n何\n伽\n価\n佳\n加\n可\n嘉\n夏\n嫁\n家\n寡\n科\n暇\n果\n架\n歌\n河\n火\n珂\n禍\n禾\n稼\n箇\n花\n苛\n茄\n荷\n華\n菓\n蝦\n課\n嘩\n貨\n迦\n過\n霞\n蚊\n俄\n峨\n我\n牙\n画\n臥\n芽\n蛾\n賀\n雅\n餓\n駕\n介\n会\n解\n回\n塊\n壊\n廻\n快\n怪\n悔\n恢\n懐\n戒\n拐\n改\n魁\n晦\n械\n海\n灰\n界\n皆\n絵\n芥\n蟹\n開\n階\n貝\n凱\n劾\n外\n咳\n害\n崖\n慨\n概\n涯\n碍\n蓋\n街\n該\n鎧\n骸\n浬\n馨\n蛙\n垣\n柿\n蛎\n鈎\n劃\n嚇\n各\n廓\n拡\n撹\n格\n核\n殻\n獲\n確\n穫\n覚\n角\n赫\n較\n郭\n閣\n隔\n革\n学\n岳\n楽\n額\n顎\n掛\n笠\n樫\n橿\n梶\n鰍\n潟\n割\n喝\n恰\n括\n活\n渇\n滑\n葛\n褐\n轄\n且\n鰹\n叶\n椛\n樺\n鞄\n株\n兜\n竃\n蒲\n釜\n鎌\n噛\n鴨\n栢\n茅\n萱\n粥\n刈\n苅\n瓦\n乾\n侃\n冠\n寒\n刊\n勘\n勧\n巻\n喚\n堪\n姦\n完\n官\n寛\n干\n幹\n患\n感\n慣\n憾\n換\n敢\n柑\n桓\n棺\n款\n歓\n汗\n漢\n澗\n潅\n環\n甘\n監\n看\n竿\n管\n簡\n緩\n缶\n翰\n肝\n艦\n莞\n観\n諌\n貫\n還\n鑑\n間\n閑\n関\n陥\n韓\n館\n舘\n丸\n含\n岸\n巌\n玩\n癌\n眼\n岩\n翫\n贋\n雁\n頑\n顔\n願\n企\n伎\n危\n喜\n器\n基\n奇\n嬉\n寄\n岐\n希\n幾\n忌\n揮\n机\n旗\n既\n期\n棋\n棄\n機\n帰\n毅\n気\n汽\n畿\n祈\n季\n稀\n紀\n徽\n規\n記\n貴\n起\n軌\n輝\n飢\n騎\n鬼\n亀\n偽\n儀\n妓\n宜\n戯\n技\n擬\n欺\n犠\n疑\n祇\n義\n蟻\n誼\n議\n掬\n菊\n鞠\n吉\n吃\n喫\n桔\n橘\n詰\n砧\n杵\n黍\n却\n客\n脚\n虐\n逆\n丘\n久\n仇\n休\n及\n吸\n宮\n弓\n急\n救\n朽\n求\n汲\n泣\n灸\n球\n究\n窮\n笈\n級\n糾\n給\n旧\n牛\n去\n居\n巨\n拒\n拠\n挙\n渠\n虚\n許\n距\n鋸\n漁\n禦\n魚\n亨\n享\n京\n供\n侠\n僑\n兇\n競\n共\n凶\n協\n匡\n卿\n叫\n喬\n境\n峡\n強\n彊\n怯\n恐\n恭\n挟\n教\n橋\n況\n狂\n狭\n矯\n胸\n脅\n興\n蕎\n郷\n鏡\n響\n饗\n驚\n仰\n凝\n尭\n暁\n業\n局\n曲\n極\n玉\n桐\n粁\n僅\n勤\n均\n巾\n錦\n斤\n欣\n欽\n琴\n禁\n禽\n筋\n緊\n芹\n菌\n衿\n襟\n謹\n近\n金\n吟\n銀\n九\n倶\n句\n区\n狗\n玖\n矩\n苦\n躯\n駆\n駈\n駒\n具\n愚\n虞\n喰\n空\n偶\n寓\n遇\n隅\n串\n櫛\n釧\n屑\n屈\n掘\n窟\n沓\n靴\n轡\n窪\n熊\n隈\n粂\n栗\n繰\n桑\n鍬\n勲\n君\n薫\n訓\n群\n軍\n郡\n卦\n袈\n祁\n係\n傾\n刑\n兄\n啓\n圭\n珪\n型\n契\n形\n径\n恵\n慶\n慧\n憩\n掲\n携\n敬\n景\n桂\n渓\n畦\n稽\n系\n経\n継\n繋\n罫\n茎\n荊\n蛍\n計\n詣\n警\n軽\n頚\n鶏\n芸\n迎\n鯨\n劇\n戟\n撃\n激\n隙\n桁\n傑\n欠\n決\n潔\n穴\n結\n血\n訣\n月\n件\n倹\n倦\n健\n兼\n券\n剣\n喧\n圏\n堅\n嫌\n建\n憲\n懸\n拳\n捲\n検\n権\n牽\n犬\n献\n研\n硯\n絹\n県\n肩\n見\n謙\n賢\n軒\n遣\n鍵\n険\n顕\n験\n鹸\n元\n原\n厳\n幻\n弦\n減\n源\n玄\n現\n絃\n舷\n言\n諺\n限\n乎\n個\n古\n呼\n固\n姑\n孤\n己\n庫\n弧\n戸\n故\n枯\n湖\n狐\n糊\n袴\n股\n胡\n菰\n虎\n誇\n跨\n鈷\n雇\n顧\n鼓\n五\n互\n伍\n午\n呉\n吾\n娯\n後\n御\n悟\n梧\n檎\n瑚\n碁\n語\n誤\n護\n醐\n乞\n鯉\n交\n佼\n侯\n候\n倖\n光\n公\n功\n効\n勾\n厚\n口\n向\n后\n喉\n坑\n垢\n好\n孔\n孝\n宏\n工\n巧\n巷\n幸\n広\n庚\n康\n弘\n恒\n慌\n抗\n拘\n控\n攻\n昂\n晃\n更\n杭\n校\n梗\n構\n江\n洪\n浩\n港\n溝\n甲\n皇\n硬\n稿\n糠\n紅\n紘\n絞\n綱\n耕\n考\n肯\n肱\n腔\n膏\n航\n荒\n行\n衡\n講\n貢\n購\n郊\n酵\n鉱\n砿\n鋼\n閤\n降\n項\n香\n高\n鴻\n剛\n劫\n号\n合\n壕\n拷\n濠\n豪\n轟\n麹\n克\n刻\n告\n国\n穀\n酷\n鵠\n黒\n獄\n漉\n腰\n甑\n忽\n惚\n骨\n狛\n込\n此\n頃\n今\n困\n坤\n墾\n婚\n恨\n懇\n昏\n昆\n根\n梱\n混\n痕\n紺\n艮\n魂\n些\n佐\n叉\n唆\n嵯\n左\n差\n査\n沙\n瑳\n砂\n詐\n鎖\n裟\n坐\n座\n挫\n債\n催\n再\n最\n哉\n塞\n妻\n宰\n彩\n才\n採\n栽\n歳\n済\n災\n采\n犀\n砕\n砦\n祭\n斎\n細\n菜\n裁\n載\n際\n剤\n在\n材\n罪\n財\n冴\n坂\n阪\n堺\n榊\n肴\n咲\n崎\n埼\n碕\n鷺\n作\n削\n咋\n搾\n昨\n朔\n柵\n窄\n策\n索\n錯\n桜\n鮭\n笹\n匙\n冊\n刷\n察\n拶\n撮\n擦\n札\n殺\n薩\n雑\n皐\n鯖\n捌\n錆\n鮫\n皿\n晒\n三\n傘\n参\n山\n惨\n撒\n散\n桟\n燦\n珊\n産\n算\n纂\n蚕\n讃\n賛\n酸\n餐\n斬\n暫\n残\n仕\n仔\n伺\n使\n刺\n司\n史\n嗣\n四\n士\n始\n姉\n姿\n子\n屍\n市\n師\n志\n思\n指\n支\n孜\n斯\n施\n旨\n枝\n止\n死\n氏\n獅\n祉\n私\n糸\n紙\n紫\n肢\n脂\n至\n視\n詞\n詩\n試\n誌\n諮\n資\n賜\n雌\n飼\n歯\n事\n似\n侍\n児\n字\n寺\n慈\n持\n時\n次\n滋\n治\n爾\n璽\n痔\n磁\n示\n而\n耳\n自\n蒔\n辞\n汐\n鹿\n式\n識\n鴫\n竺\n軸\n宍\n雫\n七\n叱\n執\n失\n嫉\n室\n悉\n湿\n漆\n疾\n質\n実\n蔀\n篠\n偲\n柴\n芝\n屡\n蕊\n縞\n舎\n写\n射\n捨\n赦\n斜\n煮\n社\n紗\n者\n謝\n車\n遮\n蛇\n邪\n借\n勺\n尺\n杓\n灼\n爵\n酌\n釈\n錫\n若\n寂\n弱\n惹\n主\n取\n守\n手\n朱\n殊\n狩\n珠\n種\n腫\n趣\n酒\n首\n儒\n受\n呪\n寿\n授\n樹\n綬\n需\n囚\n収\n周\n宗\n就\n州\n修\n愁\n拾\n洲\n秀\n秋\n終\n繍\n習\n臭\n舟\n蒐\n衆\n襲\n讐\n蹴\n輯\n週\n酋\n酬\n集\n醜\n什\n住\n充\n十\n従\n戎\n柔\n汁\n渋\n獣\n縦\n重\n銃\n叔\n夙\n宿\n淑\n祝\n縮\n粛\n塾\n熟\n出\n術\n述\n俊\n峻\n春\n瞬\n竣\n舜\n駿\n准\n循\n旬\n楯\n殉\n淳\n準\n潤\n盾\n純\n巡\n遵\n醇\n順\n処\n初\n所\n暑\n曙\n渚\n庶\n緒\n署\n書\n薯\n藷\n諸\n助\n叙\n女\n序\n徐\n恕\n鋤\n除\n傷\n償\n勝\n匠\n升\n召\n哨\n商\n唱\n嘗\n奨\n妾\n娼\n宵\n将\n小\n少\n尚\n庄\n床\n廠\n彰\n承\n抄\n招\n掌\n捷\n昇\n昌\n昭\n晶\n松\n梢\n樟\n樵\n沼\n消\n渉\n湘\n焼\n焦\n照\n症\n省\n硝\n礁\n祥\n称\n章\n笑\n粧\n紹\n肖\n菖\n蒋\n蕉\n衝\n裳\n訟\n証\n詔\n詳\n象\n賞\n醤\n鉦\n鍾\n鐘\n障\n鞘\n上\n丈\n丞\n乗\n冗\n剰\n城\n場\n壌\n嬢\n常\n情\n擾\n条\n杖\n浄\n状\n畳\n穣\n蒸\n譲\n醸\n錠\n嘱\n埴\n飾\n拭\n植\n殖\n燭\n織\n職\n色\n触\n食\n蝕\n辱\n尻\n伸\n信\n侵\n唇\n娠\n寝\n審\n心\n慎\n振\n新\n晋\n森\n榛\n浸\n深\n申\n疹\n真\n神\n秦\n紳\n臣\n芯\n薪\n親\n診\n身\n辛\n進\n針\n震\n人\n仁\n刃\n塵\n壬\n尋\n甚\n尽\n腎\n訊\n迅\n陣\n靭\n笥\n諏\n須\n酢\n図\n厨\n逗\n吹\n垂\n帥\n推\n水\n炊\n睡\n粋\n翠\n衰\n遂\n酔\n錐\n錘\n随\n瑞\n髄\n崇\n嵩\n数\n枢\n趨\n雛\n据\n杉\n椙\n菅\n頗\n雀\n裾\n澄\n摺\n寸\n世\n瀬\n畝\n是\n凄\n制\n勢\n姓\n征\n性\n成\n政\n整\n星\n晴\n棲\n栖\n正\n清\n牲\n生\n盛\n精\n聖\n声\n製\n西\n誠\n誓\n請\n逝\n醒\n青\n静\n斉\n税\n脆\n隻\n席\n惜\n戚\n斥\n昔\n析\n石\n積\n籍\n績\n脊\n責\n赤\n跡\n蹟\n碩\n切\n拙\n接\n摂\n折\n設\n窃\n節\n説\n雪\n絶\n舌\n蝉\n仙\n先\n千\n占\n宣\n専\n尖\n川\n戦\n扇\n撰\n栓\n栴\n泉\n浅\n洗\n染\n潜\n煎\n煽\n旋\n穿\n箭\n線\n繊\n羨\n腺\n舛\n船\n薦\n詮\n賎\n践\n選\n遷\n銭\n銑\n閃\n鮮\n前\n善\n漸\n然\n全\n禅\n繕\n膳\n糎\n噌\n塑\n岨\n措\n曾\n曽\n楚\n狙\n疏\n疎\n礎\n祖\n租\n粗\n素\n組\n蘇\n訴\n阻\n遡\n鼠\n僧\n創\n双\n叢\n倉\n喪\n壮\n奏\n爽\n宋\n層\n匝\n惣\n想\n捜\n掃\n挿\n掻\n操\n早\n曹\n巣\n槍\n槽\n漕\n燥\n争\n痩\n相\n窓\n糟\n総\n綜\n聡\n草\n荘\n葬\n蒼\n藻\n装\n走\n送\n遭\n鎗\n霜\n騒\n像\n増\n憎\n臓\n蔵\n贈\n造\n促\n側\n則\n即\n息\n捉\n束\n測\n足\n速\n俗\n属\n賊\n族\n続\n卒\n袖\n其\n揃\n存\n孫\n尊\n損\n村\n遜\n他\n多\n太\n汰\n詑\n唾\n堕\n妥\n惰\n打\n柁\n舵\n楕\n陀\n駄\n騨\n体\n堆\n対\n耐\n岱\n帯\n待\n怠\n態\n戴\n替\n泰\n滞\n胎\n腿\n苔\n袋\n貸\n退\n逮\n隊\n黛\n鯛\n代\n台\n大\n第\n醍\n題\n鷹\n滝\n瀧\n卓\n啄\n宅\n托\n択\n拓\n沢\n濯\n琢\n託\n鐸\n濁\n諾\n茸\n凧\n蛸\n只\n叩\n但\n達\n辰\n奪\n脱\n巽\n竪\n辿\n棚\n谷\n狸\n鱈\n樽\n誰\n丹\n単\n嘆\n坦\n担\n探\n旦\n歎\n淡\n湛\n炭\n短\n端\n箪\n綻\n耽\n胆\n蛋\n誕\n鍛\n団\n壇\n弾\n断\n暖\n檀\n段\n男\n談\n値\n知\n地\n弛\n恥\n智\n池\n痴\n稚\n置\n致\n蜘\n遅\n馳\n築\n畜\n竹\n筑\n蓄\n逐\n秩\n窒\n茶\n嫡\n着\n中\n仲\n宙\n忠\n抽\n昼\n柱\n注\n虫\n衷\n註\n酎\n鋳\n駐\n樗\n瀦\n猪\n苧\n著\n貯\n丁\n兆\n凋\n喋\n寵\n帖\n帳\n庁\n弔\n張\n彫\n徴\n懲\n挑\n暢\n朝\n潮\n牒\n町\n眺\n聴\n脹\n腸\n蝶\n調\n諜\n超\n跳\n銚\n長\n頂\n鳥\n勅\n捗\n直\n朕\n沈\n珍\n賃\n鎮\n陳\n津\n墜\n椎\n槌\n追\n鎚\n痛\n通\n塚\n栂\n掴\n槻\n佃\n漬\n柘\n辻\n蔦\n綴\n鍔\n椿\n潰\n坪\n壷\n嬬\n紬\n爪\n吊\n釣\n鶴\n亭\n低\n停\n偵\n剃\n貞\n呈\n堤\n定\n帝\n底\n庭\n廷\n弟\n悌\n抵\n挺\n提\n梯\n汀\n碇\n禎\n程\n締\n艇\n訂\n諦\n蹄\n逓\n邸\n鄭\n釘\n鼎\n泥\n摘\n擢\n敵\n滴\n的\n笛\n適\n鏑\n溺\n哲\n徹\n撤\n轍\n迭\n鉄\n典\n填\n天\n展\n店\n添\n纏\n甜\n貼\n転\n顛\n点\n伝\n殿\n澱\n田\n電\n兎\n吐\n堵\n塗\n妬\n屠\n徒\n斗\n杜\n渡\n登\n菟\n賭\n途\n都\n鍍\n砥\n砺\n努\n度\n土\n奴\n怒\n倒\n党\n冬\n凍\n刀\n唐\n塔\n塘\n套\n宕\n島\n嶋\n悼\n投\n搭\n東\n桃\n梼\n棟\n盗\n淘\n湯\n涛\n灯\n燈\n当\n痘\n祷\n等\n答\n筒\n糖\n統\n到\n董\n蕩\n藤\n討\n謄\n豆\n踏\n逃\n透\n鐙\n陶\n頭\n騰\n闘\n働\n動\n同\n堂\n導\n憧\n撞\n洞\n瞳\n童\n胴\n萄\n道\n銅\n峠\n鴇\n匿\n得\n徳\n涜\n特\n督\n禿\n篤\n毒\n独\n読\n栃\n橡\n凸\n突\n椴\n届\n鳶\n苫\n寅\n酉\n瀞\n噸\n屯\n惇\n敦\n沌\n豚\n遁\n頓\n呑\n曇\n鈍\n奈\n那\n内\n乍\n凪\n薙\n謎\n灘\n捺\n鍋\n楢\n馴\n縄\n畷\n南\n楠\n軟\n難\n汝\n二\n尼\n弐\n迩\n匂\n賑\n肉\n虹\n廿\n日\n乳\n入\n如\n尿\n韮\n任\n妊\n忍\n認\n濡\n禰\n祢\n寧\n葱\n猫\n熱\n年\n念\n捻\n撚\n燃\n粘\n乃\n廼\n之\n埜\n嚢\n悩\n濃\n納\n能\n脳\n膿\n農\n覗\n蚤\n巴\n把\n播\n覇\n杷\n波\n派\n琶\n破\n婆\n罵\n芭\n馬\n俳\n廃\n拝\n排\n敗\n杯\n盃\n牌\n背\n肺\n輩\n配\n倍\n培\n媒\n梅\n楳\n煤\n狽\n買\n売\n賠\n陪\n這\n蝿\n秤\n矧\n萩\n伯\n剥\n博\n拍\n柏\n泊\n白\n箔\n粕\n舶\n薄\n迫\n曝\n漠\n爆\n縛\n莫\n駁\n麦\n函\n箱\n硲\n箸\n肇\n筈\n櫨\n幡\n肌\n畑\n畠\n八\n鉢\n溌\n発\n醗\n髪\n伐\n罰\n抜\n筏\n閥\n鳩\n噺\n塙\n蛤\n隼\n伴\n判\n半\n反\n叛\n帆\n搬\n斑\n板\n氾\n汎\n版\n犯\n班\n畔\n繁\n般\n藩\n販\n範\n釆\n煩\n頒\n飯\n挽\n晩\n番\n盤\n磐\n蕃\n蛮\n匪\n卑\n否\n妃\n庇\n彼\n悲\n扉\n批\n披\n斐\n比\n泌\n疲\n皮\n碑\n秘\n緋\n罷\n肥\n被\n誹\n費\n避\n非\n飛\n樋\n簸\n備\n尾\n微\n枇\n毘\n琵\n眉\n美\n鼻\n柊\n稗\n匹\n疋\n髭\n彦\n膝\n菱\n肘\n弼\n必\n畢\n筆\n逼\n桧\n姫\n媛\n紐\n百\n謬\n俵\n彪\n標\n氷\n漂\n瓢\n票\n表\n評\n豹\n廟\n描\n病\n秒\n苗\n錨\n鋲\n蒜\n蛭\n鰭\n品\n彬\n斌\n浜\n瀕\n貧\n賓\n頻\n敏\n瓶\n不\n付\n埠\n夫\n婦\n富\n冨\n布\n府\n怖\n扶\n敷\n斧\n普\n浮\n父\n符\n腐\n膚\n芙\n譜\n負\n賦\n赴\n阜\n附\n侮\n撫\n武\n舞\n葡\n蕪\n部\n封\n楓\n風\n葺\n蕗\n伏\n副\n復\n幅\n服\n福\n腹\n複\n覆\n淵\n弗\n払\n沸\n仏\n物\n鮒\n分\n吻\n噴\n墳\n憤\n扮\n焚\n奮\n粉\n糞\n紛\n雰\n文\n聞\n丙\n併\n兵\n塀\n幣\n平\n弊\n柄\n並\n蔽\n閉\n陛\n米\n頁\n僻\n壁\n癖\n碧\n別\n瞥\n蔑\n箆\n偏\n変\n片\n篇\n編\n辺\n返\n遍\n便\n勉\n娩\n弁\n鞭\n保\n舗\n鋪\n圃\n捕\n歩\n甫\n補\n輔\n穂\n募\n墓\n慕\n戊\n暮\n母\n簿\n菩\n倣\n俸\n包\n呆\n報\n奉\n宝\n峰\n峯\n崩\n庖\n抱\n捧\n放\n方\n朋\n法\n泡\n烹\n砲\n縫\n胞\n芳\n萌\n蓬\n蜂\n褒\n訪\n豊\n邦\n鋒\n飽\n鳳\n鵬\n乏\n亡\n傍\n剖\n坊\n妨\n帽\n忘\n忙\n房\n暴\n望\n某\n棒\n冒\n紡\n肪\n膨\n謀\n貌\n貿\n鉾\n防\n吠\n頬\n北\n僕\n卜\n墨\n撲\n朴\n牧\n睦\n穆\n釦\n勃\n没\n殆\n堀\n幌\n奔\n本\n翻\n凡\n盆\n摩\n磨\n魔\n麻\n埋\n妹\n昧\n枚\n毎\n哩\n槙\n幕\n膜\n枕\n鮪\n柾\n鱒\n桝\n亦\n俣\n又\n抹\n末\n沫\n迄\n侭\n繭\n麿\n万\n慢\n満\n漫\n蔓\n味\n未\n魅\n巳\n箕\n岬\n密\n蜜\n湊\n蓑\n稔\n脈\n妙\n粍\n民\n眠\n務\n夢\n無\n牟\n矛\n霧\n鵡\n椋\n婿\n娘\n冥\n名\n命\n明\n盟\n迷\n銘\n鳴\n姪\n牝\n滅\n免\n棉\n綿\n緬\n面\n麺\n摸\n模\n茂\n妄\n孟\n毛\n猛\n盲\n網\n耗\n蒙\n儲\n木\n黙\n目\n杢\n勿\n餅\n尤\n戻\n籾\n貰\n問\n悶\n紋\n門\n匁\n也\n冶\n夜\n爺\n耶\n野\n弥\n矢\n厄\n役\n約\n薬\n訳\n躍\n靖\n柳\n薮\n鑓\n愉\n愈\n油\n癒\n諭\n輸\n唯\n佑\n優\n勇\n友\n宥\n幽\n悠\n憂\n揖\n有\n柚\n湧\n涌\n猶\n猷\n由\n祐\n裕\n誘\n遊\n邑\n郵\n雄\n融\n夕\n予\n余\n与\n誉\n輿\n預\n傭\n幼\n妖\n容\n庸\n揚\n揺\n擁\n曜\n楊\n様\n洋\n溶\n熔\n用\n窯\n羊\n耀\n葉\n蓉\n要\n謡\n踊\n遥\n陽\n養\n慾\n抑\n欲\n沃\n浴\n翌\n翼\n淀\n羅\n螺\n裸\n来\n莱\n頼\n雷\n洛\n絡\n落\n酪\n乱\n卵\n嵐\n欄\n濫\n藍\n蘭\n覧\n利\n吏\n履\n李\n梨\n理\n璃\n痢\n裏\n裡\n里\n離\n陸\n律\n率\n立\n葎\n掠\n略\n劉\n流\n溜\n琉\n留\n硫\n粒\n隆\n竜\n龍\n侶\n慮\n旅\n虜\n了\n亮\n僚\n両\n凌\n寮\n料\n梁\n涼\n猟\n療\n瞭\n稜\n糧\n良\n諒\n遼\n量\n陵\n領\n力\n緑\n倫\n厘\n林\n淋\n燐\n琳\n臨\n輪\n隣\n鱗\n麟\n瑠\n塁\n涙\n累\n類\n令\n伶\n例\n冷\n励\n嶺\n怜\n玲\n礼\n苓\n鈴\n隷\n零\n霊\n麗\n齢\n暦\n歴\n列\n劣\n烈\n裂\n廉\n恋\n憐\n漣\n煉\n簾\n練\n聯\n蓮\n連\n錬\n呂\n魯\n櫓\n炉\n賂\n路\n露\n労\n婁\n廊\n弄\n朗\n楼\n榔\n浪\n漏\n牢\n狼\n篭\n老\n聾\n蝋\n郎\n六\n麓\n禄\n肋\n録\n論\n倭\n和\n話\n歪\n賄\n脇\n惑\n枠\n鷲\n亙\n亘\n鰐\n詫\n藁\n蕨\n椀\n湾\n碗\n腕\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n弌\n丐\n丕\n个\n丱\n丶\n丼\n丿\n乂\n乖\n乘\n亂\n亅\n豫\n亊\n舒\n弍\n于\n亞\n亟\n亠\n亢\n亰\n亳\n亶\n从\n仍\n仄\n仆\n仂\n仗\n仞\n仭\n仟\n价\n伉\n佚\n估\n佛\n佝\n佗\n佇\n佶\n侈\n侏\n侘\n佻\n佩\n佰\n侑\n佯\n來\n侖\n儘\n俔\n俟\n俎\n俘\n俛\n俑\n俚\n俐\n俤\n俥\n倚\n倨\n倔\n倪\n倥\n倅\n伜\n俶\n倡\n倩\n倬\n俾\n俯\n們\n倆\n偃\n假\n會\n偕\n偐\n偈\n做\n偖\n偬\n偸\n傀\n傚\n傅\n傴\n傲\n僉\n僊\n傳\n僂\n僖\n僞\n僥\n僭\n僣\n僮\n價\n僵\n儉\n儁\n儂\n儖\n儕\n儔\n儚\n儡\n儺\n儷\n儼\n儻\n儿\n兀\n兒\n兌\n兔\n兢\n竸\n兩\n兪\n兮\n冀\n冂\n囘\n册\n冉\n冏\n冑\n冓\n冕\n冖\n冤\n冦\n冢\n冩\n冪\n冫\n决\n冱\n冲\n冰\n况\n冽\n凅\n凉\n凛\n几\n處\n凩\n凭\n凰\n凵\n凾\n刄\n刋\n刔\n刎\n刧\n刪\n刮\n刳\n刹\n剏\n剄\n剋\n剌\n剞\n剔\n剪\n剴\n剩\n剳\n剿\n剽\n劍\n劔\n劒\n剱\n劈\n劑\n辨\n辧\n劬\n劭\n劼\n劵\n勁\n勍\n勗\n勞\n勣\n勦\n飭\n勠\n勳\n勵\n勸\n勹\n匆\n匈\n甸\n匍\n匐\n匏\n匕\n匚\n匣\n匯\n匱\n匳\n匸\n區\n卆\n卅\n丗\n卉\n卍\n凖\n卞\n卩\n卮\n夘\n卻\n卷\n厂\n厖\n厠\n厦\n厥\n厮\n厰\n厶\n參\n簒\n雙\n叟\n曼\n燮\n叮\n叨\n叭\n叺\n吁\n吽\n呀\n听\n吭\n吼\n吮\n吶\n吩\n吝\n呎\n咏\n呵\n咎\n呟\n呱\n呷\n呰\n咒\n呻\n咀\n呶\n咄\n咐\n咆\n哇\n咢\n咸\n咥\n咬\n哄\n哈\n咨\n咫\n哂\n咤\n咾\n咼\n哘\n哥\n哦\n唏\n唔\n哽\n哮\n哭\n哺\n哢\n唹\n啀\n啣\n啌\n售\n啜\n啅\n啖\n啗\n唸\n唳\n啝\n喙\n喀\n咯\n喊\n喟\n啻\n啾\n喘\n喞\n單\n啼\n喃\n喩\n喇\n喨\n嗚\n嗅\n嗟\n嗄\n嗜\n嗤\n嗔\n嘔\n嗷\n嘖\n嗾\n嗽\n嘛\n嗹\n噎\n噐\n營\n嘴\n嘶\n嘲\n嘸\n噫\n噤\n嘯\n噬\n噪\n嚆\n嚀\n嚊\n嚠\n嚔\n嚏\n嚥\n嚮\n嚶\n嚴\n囂\n嚼\n囁\n囃\n囀\n囈\n囎\n囑\n囓\n囗\n囮\n囹\n圀\n囿\n圄\n圉\n圈\n國\n圍\n圓\n團\n圖\n嗇\n圜\n圦\n圷\n圸\n坎\n圻\n址\n坏\n坩\n埀\n垈\n坡\n坿\n垉\n垓\n垠\n垳\n垤\n垪\n垰\n埃\n埆\n埔\n埒\n埓\n堊\n埖\n埣\n堋\n堙\n堝\n塲\n堡\n塢\n塋\n塰\n毀\n塒\n堽\n塹\n墅\n墹\n墟\n墫\n墺\n壞\n墻\n墸\n墮\n壅\n壓\n壑\n壗\n壙\n壘\n壥\n壜\n壤\n壟\n壯\n壺\n壹\n壻\n壼\n壽\n夂\n夊\n夐\n夛\n梦\n夥\n夬\n夭\n夲\n夸\n夾\n竒\n奕\n奐\n奎\n奚\n奘\n奢\n奠\n奧\n奬\n奩\n奸\n妁\n妝\n佞\n侫\n妣\n妲\n姆\n姨\n姜\n妍\n姙\n姚\n娥\n娟\n娑\n娜\n娉\n娚\n婀\n婬\n婉\n娵\n娶\n婢\n婪\n媚\n媼\n媾\n嫋\n嫂\n媽\n嫣\n嫗\n嫦\n嫩\n嫖\n嫺\n嫻\n嬌\n嬋\n嬖\n嬲\n嫐\n嬪\n嬶\n嬾\n孃\n孅\n孀\n孑\n孕\n孚\n孛\n孥\n孩\n孰\n孳\n孵\n學\n斈\n孺\n宀\n它\n宦\n宸\n寃\n寇\n寉\n寔\n寐\n寤\n實\n寢\n寞\n寥\n寫\n寰\n寶\n寳\n尅\n將\n專\n對\n尓\n尠\n尢\n尨\n尸\n尹\n屁\n屆\n屎\n屓\n屐\n屏\n孱\n屬\n屮\n乢\n屶\n屹\n岌\n岑\n岔\n妛\n岫\n岻\n岶\n岼\n岷\n峅\n岾\n峇\n峙\n峩\n峽\n峺\n峭\n嶌\n峪\n崋\n崕\n崗\n嵜\n崟\n崛\n崑\n崔\n崢\n崚\n崙\n崘\n嵌\n嵒\n嵎\n嵋\n嵬\n嵳\n嵶\n嶇\n嶄\n嶂\n嶢\n嶝\n嶬\n嶮\n嶽\n嶐\n嶷\n嶼\n巉\n巍\n巓\n巒\n巖\n巛\n巫\n已\n巵\n帋\n帚\n帙\n帑\n帛\n帶\n帷\n幄\n幃\n幀\n幎\n幗\n幔\n幟\n幢\n幤\n幇\n幵\n并\n幺\n麼\n广\n庠\n廁\n廂\n廈\n廐\n廏\n廖\n廣\n廝\n廚\n廛\n廢\n廡\n廨\n廩\n廬\n廱\n廳\n廰\n廴\n廸\n廾\n弃\n弉\n彝\n彜\n弋\n弑\n弖\n弩\n弭\n弸\n彁\n彈\n彌\n彎\n弯\n彑\n彖\n彗\n彙\n彡\n彭\n彳\n彷\n徃\n徂\n彿\n徊\n很\n徑\n徇\n從\n徙\n徘\n徠\n徨\n徭\n徼\n忖\n忻\n忤\n忸\n忱\n忝\n悳\n忿\n怡\n恠\n怙\n怐\n怩\n怎\n怱\n怛\n怕\n怫\n怦\n怏\n怺\n恚\n恁\n恪\n恷\n恟\n恊\n恆\n恍\n恣\n恃\n恤\n恂\n恬\n恫\n恙\n悁\n悍\n惧\n悃\n悚\n悄\n悛\n悖\n悗\n悒\n悧\n悋\n惡\n悸\n惠\n惓\n悴\n忰\n悽\n惆\n悵\n惘\n慍\n愕\n愆\n惶\n惷\n愀\n惴\n惺\n愃\n愡\n惻\n惱\n愍\n愎\n慇\n愾\n愨\n愧\n慊\n愿\n愼\n愬\n愴\n愽\n慂\n慄\n慳\n慷\n慘\n慙\n慚\n慫\n慴\n慯\n慥\n慱\n慟\n慝\n慓\n慵\n憙\n憖\n憇\n憬\n憔\n憚\n憊\n憑\n憫\n憮\n懌\n懊\n應\n懷\n懈\n懃\n懆\n憺\n懋\n罹\n懍\n懦\n懣\n懶\n懺\n懴\n懿\n懽\n懼\n懾\n戀\n戈\n戉\n戍\n戌\n戔\n戛\n戞\n戡\n截\n戮\n戰\n戲\n戳\n扁\n扎\n扞\n扣\n扛\n扠\n扨\n扼\n抂\n抉\n找\n抒\n抓\n抖\n拔\n抃\n抔\n拗\n拑\n抻\n拏\n拿\n拆\n擔\n拈\n拜\n拌\n拊\n拂\n拇\n抛\n拉\n挌\n拮\n拱\n挧\n挂\n挈\n拯\n拵\n捐\n挾\n捍\n搜\n捏\n掖\n掎\n掀\n掫\n捶\n掣\n掏\n掉\n掟\n掵\n捫\n捩\n掾\n揩\n揀\n揆\n揣\n揉\n插\n揶\n揄\n搖\n搴\n搆\n搓\n搦\n搶\n攝\n搗\n搨\n搏\n摧\n摯\n摶\n摎\n攪\n撕\n撓\n撥\n撩\n撈\n撼\n據\n擒\n擅\n擇\n撻\n擘\n擂\n擱\n擧\n舉\n擠\n擡\n抬\n擣\n擯\n攬\n擶\n擴\n擲\n擺\n攀\n擽\n攘\n攜\n攅\n攤\n攣\n攫\n攴\n攵\n攷\n收\n攸\n畋\n效\n敖\n敕\n敍\n敘\n敞\n敝\n敲\n數\n斂\n斃\n變\n斛\n斟\n斫\n斷\n旃\n旆\n旁\n旄\n旌\n旒\n旛\n旙\n无\n旡\n旱\n杲\n昊\n昃\n旻\n杳\n昵\n昶\n昴\n昜\n晏\n晄\n晉\n晁\n晞\n晝\n晤\n晧\n晨\n晟\n晢\n晰\n暃\n暈\n暎\n暉\n暄\n暘\n暝\n曁\n暹\n曉\n暾\n暼\n曄\n暸\n曖\n曚\n曠\n昿\n曦\n曩\n曰\n曵\n曷\n朏\n朖\n朞\n朦\n朧\n霸\n朮\n朿\n朶\n杁\n朸\n朷\n杆\n杞\n杠\n杙\n杣\n杤\n枉\n杰\n枩\n杼\n杪\n枌\n枋\n枦\n枡\n枅\n枷\n柯\n枴\n柬\n枳\n柩\n枸\n柤\n柞\n柝\n柢\n柮\n枹\n柎\n柆\n柧\n檜\n栞\n框\n栩\n桀\n桍\n栲\n桎\n梳\n栫\n桙\n档\n桷\n桿\n梟\n梏\n梭\n梔\n條\n梛\n梃\n檮\n梹\n桴\n梵\n梠\n梺\n椏\n梍\n桾\n椁\n棊\n椈\n棘\n椢\n椦\n棡\n椌\n棍\n棔\n棧\n棕\n椶\n椒\n椄\n棗\n棣\n椥\n棹\n棠\n棯\n椨\n椪\n椚\n椣\n椡\n棆\n楹\n楷\n楜\n楸\n楫\n楔\n楾\n楮\n椹\n楴\n椽\n楙\n椰\n楡\n楞\n楝\n榁\n楪\n榲\n榮\n槐\n榿\n槁\n槓\n榾\n槎\n寨\n槊\n槝\n榻\n槃\n榧\n樮\n榑\n榠\n榜\n榕\n榴\n槞\n槨\n樂\n樛\n槿\n權\n槹\n槲\n槧\n樅\n榱\n樞\n槭\n樔\n槫\n樊\n樒\n櫁\n樣\n樓\n橄\n樌\n橲\n樶\n橸\n橇\n橢\n橙\n橦\n橈\n樸\n樢\n檐\n檍\n檠\n檄\n檢\n檣\n檗\n蘗\n檻\n櫃\n櫂\n檸\n檳\n檬\n櫞\n櫑\n櫟\n檪\n櫚\n櫪\n櫻\n欅\n蘖\n櫺\n欒\n欖\n鬱\n欟\n欸\n欷\n盜\n欹\n飮\n歇\n歃\n歉\n歐\n歙\n歔\n歛\n歟\n歡\n歸\n歹\n歿\n殀\n殄\n殃\n殍\n殘\n殕\n殞\n殤\n殪\n殫\n殯\n殲\n殱\n殳\n殷\n殼\n毆\n毋\n毓\n毟\n毬\n毫\n毳\n毯\n麾\n氈\n氓\n气\n氛\n氤\n氣\n汞\n汕\n汢\n汪\n沂\n沍\n沚\n沁\n沛\n汾\n汨\n汳\n沒\n沐\n泄\n泱\n泓\n沽\n泗\n泅\n泝\n沮\n沱\n沾\n沺\n泛\n泯\n泙\n泪\n洟\n衍\n洶\n洫\n洽\n洸\n洙\n洵\n洳\n洒\n洌\n浣\n涓\n浤\n浚\n浹\n浙\n涎\n涕\n濤\n涅\n淹\n渕\n渊\n涵\n淇\n淦\n涸\n淆\n淬\n淞\n淌\n淨\n淒\n淅\n淺\n淙\n淤\n淕\n淪\n淮\n渭\n湮\n渮\n渙\n湲\n湟\n渾\n渣\n湫\n渫\n湶\n湍\n渟\n湃\n渺\n湎\n渤\n滿\n渝\n游\n溂\n溪\n溘\n滉\n溷\n滓\n溽\n溯\n滄\n溲\n滔\n滕\n溏\n溥\n滂\n溟\n潁\n漑\n灌\n滬\n滸\n滾\n漿\n滲\n漱\n滯\n漲\n滌\n漾\n漓\n滷\n澆\n潺\n潸\n澁\n澀\n潯\n潛\n濳\n潭\n澂\n潼\n潘\n澎\n澑\n濂\n潦\n澳\n澣\n澡\n澤\n澹\n濆\n澪\n濟\n濕\n濬\n濔\n濘\n濱\n濮\n濛\n瀉\n瀋\n濺\n瀑\n瀁\n瀏\n濾\n瀛\n瀚\n潴\n瀝\n瀘\n瀟\n瀰\n瀾\n瀲\n灑\n灣\n炙\n炒\n炯\n烱\n炬\n炸\n炳\n炮\n烟\n烋\n烝\n烙\n焉\n烽\n焜\n焙\n煥\n煕\n熈\n煦\n煢\n煌\n煖\n煬\n熏\n燻\n熄\n熕\n熨\n熬\n燗\n熹\n熾\n燒\n燉\n燔\n燎\n燠\n燬\n燧\n燵\n燼\n燹\n燿\n爍\n爐\n爛\n爨\n爭\n爬\n爰\n爲\n爻\n爼\n爿\n牀\n牆\n牋\n牘\n牴\n牾\n犂\n犁\n犇\n犒\n犖\n犢\n犧\n犹\n犲\n狃\n狆\n狄\n狎\n狒\n狢\n狠\n狡\n狹\n狷\n倏\n猗\n猊\n猜\n猖\n猝\n猴\n猯\n猩\n猥\n猾\n獎\n獏\n默\n獗\n獪\n獨\n獰\n獸\n獵\n獻\n獺\n珈\n玳\n珎\n玻\n珀\n珥\n珮\n珞\n璢\n琅\n瑯\n琥\n珸\n琲\n琺\n瑕\n琿\n瑟\n瑙\n瑁\n瑜\n瑩\n瑰\n瑣\n瑪\n瑶\n瑾\n璋\n璞\n璧\n瓊\n瓏\n瓔\n珱\n瓠\n瓣\n瓧\n瓩\n瓮\n瓲\n瓰\n瓱\n瓸\n瓷\n甄\n甃\n甅\n甌\n甎\n甍\n甕\n甓\n甞\n甦\n甬\n甼\n畄\n畍\n畊\n畉\n畛\n畆\n畚\n畩\n畤\n畧\n畫\n畭\n畸\n當\n疆\n疇\n畴\n疊\n疉\n疂\n疔\n疚\n疝\n疥\n疣\n痂\n疳\n痃\n疵\n疽\n疸\n疼\n疱\n痍\n痊\n痒\n痙\n痣\n痞\n痾\n痿\n痼\n瘁\n痰\n痺\n痲\n痳\n瘋\n瘍\n瘉\n瘟\n瘧\n瘠\n瘡\n瘢\n瘤\n瘴\n瘰\n瘻\n癇\n癈\n癆\n癜\n癘\n癡\n癢\n癨\n癩\n癪\n癧\n癬\n癰\n癲\n癶\n癸\n發\n皀\n皃\n皈\n皋\n皎\n皖\n皓\n皙\n皚\n皰\n皴\n皸\n皹\n皺\n盂\n盍\n盖\n盒\n盞\n盡\n盥\n盧\n盪\n蘯\n盻\n眈\n眇\n眄\n眩\n眤\n眞\n眥\n眦\n眛\n眷\n眸\n睇\n睚\n睨\n睫\n睛\n睥\n睿\n睾\n睹\n瞎\n瞋\n瞑\n瞠\n瞞\n瞰\n瞶\n瞹\n瞿\n瞼\n瞽\n瞻\n矇\n矍\n矗\n矚\n矜\n矣\n矮\n矼\n砌\n砒\n礦\n砠\n礪\n硅\n碎\n硴\n碆\n硼\n碚\n碌\n碣\n碵\n碪\n碯\n磑\n磆\n磋\n磔\n碾\n碼\n磅\n磊\n磬\n磧\n磚\n磽\n磴\n礇\n礒\n礑\n礙\n礬\n礫\n祀\n祠\n祗\n祟\n祚\n祕\n祓\n祺\n祿\n禊\n禝\n禧\n齋\n禪\n禮\n禳\n禹\n禺\n秉\n秕\n秧\n秬\n秡\n秣\n稈\n稍\n稘\n稙\n稠\n稟\n禀\n稱\n稻\n稾\n稷\n穃\n穗\n穉\n穡\n穢\n穩\n龝\n穰\n穹\n穽\n窈\n窗\n窕\n窘\n窖\n窩\n竈\n窰\n窶\n竅\n竄\n窿\n邃\n竇\n竊\n竍\n竏\n竕\n竓\n站\n竚\n竝\n竡\n竢\n竦\n竭\n竰\n笂\n笏\n笊\n笆\n笳\n笘\n笙\n笞\n笵\n笨\n笶\n筐\n筺\n笄\n筍\n笋\n筌\n筅\n筵\n筥\n筴\n筧\n筰\n筱\n筬\n筮\n箝\n箘\n箟\n箍\n箜\n箚\n箋\n箒\n箏\n筝\n箙\n篋\n篁\n篌\n篏\n箴\n篆\n篝\n篩\n簑\n簔\n篦\n篥\n籠\n簀\n簇\n簓\n篳\n篷\n簗\n簍\n篶\n簣\n簧\n簪\n簟\n簷\n簫\n簽\n籌\n籃\n籔\n籏\n籀\n籐\n籘\n籟\n籤\n籖\n籥\n籬\n籵\n粃\n粐\n粤\n粭\n粢\n粫\n粡\n粨\n粳\n粲\n粱\n粮\n粹\n粽\n糀\n糅\n糂\n糘\n糒\n糜\n糢\n鬻\n糯\n糲\n糴\n糶\n糺\n紆\n紂\n紜\n紕\n紊\n絅\n絋\n紮\n紲\n紿\n紵\n絆\n絳\n絖\n絎\n絲\n絨\n絮\n絏\n絣\n經\n綉\n絛\n綏\n絽\n綛\n綺\n綮\n綣\n綵\n緇\n綽\n綫\n總\n綢\n綯\n緜\n綸\n綟\n綰\n緘\n緝\n緤\n緞\n緻\n緲\n緡\n縅\n縊\n縣\n縡\n縒\n縱\n縟\n縉\n縋\n縢\n繆\n繦\n縻\n縵\n縹\n繃\n縷\n縲\n縺\n繧\n繝\n繖\n繞\n繙\n繚\n繹\n繪\n繩\n繼\n繻\n纃\n緕\n繽\n辮\n繿\n纈\n纉\n續\n纒\n纐\n纓\n纔\n纖\n纎\n纛\n纜\n缸\n缺\n罅\n罌\n罍\n罎\n罐\n网\n罕\n罔\n罘\n罟\n罠\n罨\n罩\n罧\n罸\n羂\n羆\n羃\n羈\n羇\n羌\n羔\n羞\n羝\n羚\n羣\n羯\n羲\n羹\n羮\n羶\n羸\n譱\n翅\n翆\n翊\n翕\n翔\n翡\n翦\n翩\n翳\n翹\n飜\n耆\n耄\n耋\n耒\n耘\n耙\n耜\n耡\n耨\n耿\n耻\n聊\n聆\n聒\n聘\n聚\n聟\n聢\n聨\n聳\n聲\n聰\n聶\n聹\n聽\n聿\n肄\n肆\n肅\n肛\n肓\n肚\n肭\n冐\n肬\n胛\n胥\n胙\n胝\n胄\n胚\n胖\n脉\n胯\n胱\n脛\n脩\n脣\n脯\n腋\n隋\n腆\n脾\n腓\n腑\n胼\n腱\n腮\n腥\n腦\n腴\n膃\n膈\n膊\n膀\n膂\n膠\n膕\n膤\n膣\n腟\n膓\n膩\n膰\n膵\n膾\n膸\n膽\n臀\n臂\n膺\n臉\n臍\n臑\n臙\n臘\n臈\n臚\n臟\n臠\n臧\n臺\n臻\n臾\n舁\n舂\n舅\n與\n舊\n舍\n舐\n舖\n舩\n舫\n舸\n舳\n艀\n艙\n艘\n艝\n艚\n艟\n艤\n艢\n艨\n艪\n艫\n舮\n艱\n艷\n艸\n艾\n芍\n芒\n芫\n芟\n芻\n芬\n苡\n苣\n苟\n苒\n苴\n苳\n苺\n莓\n范\n苻\n苹\n苞\n茆\n苜\n茉\n苙\n茵\n茴\n茖\n茲\n茱\n荀\n茹\n荐\n荅\n茯\n茫\n茗\n茘\n莅\n莚\n莪\n莟\n莢\n莖\n茣\n莎\n莇\n莊\n荼\n莵\n荳\n荵\n莠\n莉\n莨\n菴\n萓\n菫\n菎\n菽\n萃\n菘\n萋\n菁\n菷\n萇\n菠\n菲\n萍\n萢\n萠\n莽\n萸\n蔆\n菻\n葭\n萪\n萼\n蕚\n蒄\n葷\n葫\n蒭\n葮\n蒂\n葩\n葆\n萬\n葯\n葹\n萵\n蓊\n葢\n蒹\n蒿\n蒟\n蓙\n蓍\n蒻\n蓚\n蓐\n蓁\n蓆\n蓖\n蒡\n蔡\n蓿\n蓴\n蔗\n蔘\n蔬\n蔟\n蔕\n蔔\n蓼\n蕀\n蕣\n蕘\n蕈\n蕁\n蘂\n蕋\n蕕\n薀\n薤\n薈\n薑\n薊\n薨\n蕭\n薔\n薛\n藪\n薇\n薜\n蕷\n蕾\n薐\n藉\n薺\n藏\n薹\n藐\n藕\n藝\n藥\n藜\n藹\n蘊\n蘓\n蘋\n藾\n藺\n蘆\n蘢\n蘚\n蘰\n蘿\n虍\n乕\n虔\n號\n虧\n虱\n蚓\n蚣\n蚩\n蚪\n蚋\n蚌\n蚶\n蚯\n蛄\n蛆\n蚰\n蛉\n蠣\n蚫\n蛔\n蛞\n蛩\n蛬\n蛟\n蛛\n蛯\n蜒\n蜆\n蜈\n蜀\n蜃\n蛻\n蜑\n蜉\n蜍\n蛹\n蜊\n蜴\n蜿\n蜷\n蜻\n蜥\n蜩\n蜚\n蝠\n蝟\n蝸\n蝌\n蝎\n蝴\n蝗\n蝨\n蝮\n蝙\n蝓\n蝣\n蝪\n蠅\n螢\n螟\n螂\n螯\n蟋\n螽\n蟀\n蟐\n雖\n螫\n蟄\n螳\n蟇\n蟆\n螻\n蟯\n蟲\n蟠\n蠏\n蠍\n蟾\n蟶\n蟷\n蠎\n蟒\n蠑\n蠖\n蠕\n蠢\n蠡\n蠱\n蠶\n蠹\n蠧\n蠻\n衄\n衂\n衒\n衙\n衞\n衢\n衫\n袁\n衾\n袞\n衵\n衽\n袵\n衲\n袂\n袗\n袒\n袮\n袙\n袢\n袍\n袤\n袰\n袿\n袱\n裃\n裄\n裔\n裘\n裙\n裝\n裹\n褂\n裼\n裴\n裨\n裲\n褄\n褌\n褊\n褓\n襃\n褞\n褥\n褪\n褫\n襁\n襄\n褻\n褶\n褸\n襌\n褝\n襠\n襞\n襦\n襤\n襭\n襪\n襯\n襴\n襷\n襾\n覃\n覈\n覊\n覓\n覘\n覡\n覩\n覦\n覬\n覯\n覲\n覺\n覽\n覿\n觀\n觚\n觜\n觝\n觧\n觴\n觸\n訃\n訖\n訐\n訌\n訛\n訝\n訥\n訶\n詁\n詛\n詒\n詆\n詈\n詼\n詭\n詬\n詢\n誅\n誂\n誄\n誨\n誡\n誑\n誥\n誦\n誚\n誣\n諄\n諍\n諂\n諚\n諫\n諳\n諧\n諤\n諱\n謔\n諠\n諢\n諷\n諞\n諛\n謌\n謇\n謚\n諡\n謖\n謐\n謗\n謠\n謳\n鞫\n謦\n謫\n謾\n謨\n譁\n譌\n譏\n譎\n證\n譖\n譛\n譚\n譫\n譟\n譬\n譯\n譴\n譽\n讀\n讌\n讎\n讒\n讓\n讖\n讙\n讚\n谺\n豁\n谿\n豈\n豌\n豎\n豐\n豕\n豢\n豬\n豸\n豺\n貂\n貉\n貅\n貊\n貍\n貎\n貔\n豼\n貘\n戝\n貭\n貪\n貽\n貲\n貳\n貮\n貶\n賈\n賁\n賤\n賣\n賚\n賽\n賺\n賻\n贄\n贅\n贊\n贇\n贏\n贍\n贐\n齎\n贓\n賍\n贔\n贖\n赧\n赭\n赱\n赳\n趁\n趙\n跂\n趾\n趺\n跏\n跚\n跖\n跌\n跛\n跋\n跪\n跫\n跟\n跣\n跼\n踈\n踉\n跿\n踝\n踞\n踐\n踟\n蹂\n踵\n踰\n踴\n蹊\n蹇\n蹉\n蹌\n蹐\n蹈\n蹙\n蹤\n蹠\n踪\n蹣\n蹕\n蹶\n蹲\n蹼\n躁\n躇\n躅\n躄\n躋\n躊\n躓\n躑\n躔\n躙\n躪\n躡\n躬\n躰\n軆\n躱\n躾\n軅\n軈\n軋\n軛\n軣\n軼\n軻\n軫\n軾\n輊\n輅\n輕\n輒\n輙\n輓\n輜\n輟\n輛\n輌\n輦\n輳\n輻\n輹\n轅\n轂\n輾\n轌\n轉\n轆\n轎\n轗\n轜\n轢\n轣\n轤\n辜\n辟\n辣\n辭\n辯\n辷\n迚\n迥\n迢\n迪\n迯\n邇\n迴\n逅\n迹\n迺\n逑\n逕\n逡\n逍\n逞\n逖\n逋\n逧\n逶\n逵\n逹\n迸\n遏\n遐\n遑\n遒\n逎\n遉\n逾\n遖\n遘\n遞\n遨\n遯\n遶\n隨\n遲\n邂\n遽\n邁\n邀\n邊\n邉\n邏\n邨\n邯\n邱\n邵\n郢\n郤\n扈\n郛\n鄂\n鄒\n鄙\n鄲\n鄰\n酊\n酖\n酘\n酣\n酥\n酩\n酳\n酲\n醋\n醉\n醂\n醢\n醫\n醯\n醪\n醵\n醴\n醺\n釀\n釁\n釉\n釋\n釐\n釖\n釟\n釡\n釛\n釼\n釵\n釶\n鈞\n釿\n鈔\n鈬\n鈕\n鈑\n鉞\n鉗\n鉅\n鉉\n鉤\n鉈\n銕\n鈿\n鉋\n鉐\n銜\n銖\n銓\n銛\n鉚\n鋏\n銹\n銷\n鋩\n錏\n鋺\n鍄\n錮\n錙\n錢\n錚\n錣\n錺\n錵\n錻\n鍜\n鍠\n鍼\n鍮\n鍖\n鎰\n鎬\n鎭\n鎔\n鎹\n鏖\n鏗\n鏨\n鏥\n鏘\n鏃\n鏝\n鏐\n鏈\n鏤\n鐚\n鐔\n鐓\n鐃\n鐇\n鐐\n鐶\n鐫\n鐵\n鐡\n鐺\n鑁\n鑒\n鑄\n鑛\n鑠\n鑢\n鑞\n鑪\n鈩\n鑰\n鑵\n鑷\n鑽\n鑚\n鑼\n鑾\n钁\n鑿\n閂\n閇\n閊\n閔\n閖\n閘\n閙\n閠\n閨\n閧\n閭\n閼\n閻\n閹\n閾\n闊\n濶\n闃\n闍\n闌\n闕\n闔\n闖\n關\n闡\n闥\n闢\n阡\n阨\n阮\n阯\n陂\n陌\n陏\n陋\n陷\n陜\n陞\n陝\n陟\n陦\n陲\n陬\n隍\n隘\n隕\n隗\n險\n隧\n隱\n隲\n隰\n隴\n隶\n隸\n隹\n雎\n雋\n雉\n雍\n襍\n雜\n霍\n雕\n雹\n霄\n霆\n霈\n霓\n霎\n霑\n霏\n霖\n霙\n霤\n霪\n霰\n霹\n霽\n霾\n靄\n靆\n靈\n靂\n靉\n靜\n靠\n靤\n靦\n靨\n勒\n靫\n靱\n靹\n鞅\n靼\n鞁\n靺\n鞆\n鞋\n鞏\n鞐\n鞜\n鞨\n鞦\n鞣\n鞳\n鞴\n韃\n韆\n韈\n韋\n韜\n韭\n齏\n韲\n竟\n韶\n韵\n頏\n頌\n頸\n頤\n頡\n頷\n頽\n顆\n顏\n顋\n顫\n顯\n顰\n顱\n顴\n顳\n颪\n颯\n颱\n颶\n飄\n飃\n飆\n飩\n飫\n餃\n餉\n餒\n餔\n餘\n餡\n餝\n餞\n餤\n餠\n餬\n餮\n餽\n餾\n饂\n饉\n饅\n饐\n饋\n饑\n饒\n饌\n饕\n馗\n馘\n馥\n馭\n馮\n馼\n駟\n駛\n駝\n駘\n駑\n駭\n駮\n駱\n駲\n駻\n駸\n騁\n騏\n騅\n駢\n騙\n騫\n騷\n驅\n驂\n驀\n驃\n騾\n驕\n驍\n驛\n驗\n驟\n驢\n驥\n驤\n驩\n驫\n驪\n骭\n骰\n骼\n髀\n髏\n髑\n髓\n體\n髞\n髟\n髢\n髣\n髦\n髯\n髫\n髮\n髴\n髱\n髷\n髻\n鬆\n鬘\n鬚\n鬟\n鬢\n鬣\n鬥\n鬧\n鬨\n鬩\n鬪\n鬮\n鬯\n鬲\n魄\n魃\n魏\n魍\n魎\n魑\n魘\n魴\n鮓\n鮃\n鮑\n鮖\n鮗\n鮟\n鮠\n鮨\n鮴\n鯀\n鯊\n鮹\n鯆\n鯏\n鯑\n鯒\n鯣\n鯢\n鯤\n鯔\n鯡\n鰺\n鯲\n鯱\n鯰\n鰕\n鰔\n鰉\n鰓\n鰌\n鰆\n鰈\n鰒\n鰊\n鰄\n鰮\n鰛\n鰥\n鰤\n鰡\n鰰\n鱇\n鰲\n鱆\n鰾\n鱚\n鱠\n鱧\n鱶\n鱸\n鳧\n鳬\n鳰\n鴉\n鴈\n鳫\n鴃\n鴆\n鴪\n鴦\n鶯\n鴣\n鴟\n鵄\n鴕\n鴒\n鵁\n鴿\n鴾\n鵆\n鵈\n鵝\n鵞\n鵤\n鵑\n鵐\n鵙\n鵲\n鶉\n鶇\n鶫\n鵯\n鵺\n鶚\n鶤\n鶩\n鶲\n鷄\n鷁\n鶻\n鶸\n鶺\n鷆\n鷏\n鷂\n鷙\n鷓\n鷸\n鷦\n鷭\n鷯\n鷽\n鸚\n鸛\n鸞\n鹵\n鹹\n鹽\n麁\n麈\n麋\n麌\n麒\n麕\n麑\n麝\n麥\n麩\n麸\n麪\n麭\n靡\n黌\n黎\n黏\n黐\n黔\n黜\n點\n黝\n黠\n黥\n黨\n黯\n黴\n黶\n黷\n黹\n黻\n黼\n黽\n鼇\n鼈\n皷\n鼕\n鼡\n鼬\n鼾\n齊\n齒\n齔\n齣\n齟\n齠\n齡\n齦\n齧\n齬\n齪\n齷\n齲\n齶\n龕\n龜\n龠\n堯\n槇\n遙\n瑤\n凜\n熙\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n纊\n褜\n鍈\n銈\n蓜\n俉\n炻\n昱\n棈\n鋹\n曻\n彅\n丨\n仡\n仼\n伀\n伃\n伹\n佖\n侒\n侊\n侚\n侔\n俍\n偀\n倢\n俿\n倞\n偆\n偰\n偂\n傔\n僴\n僘\n兊\n兤\n冝\n冾\n凬\n刕\n劜\n劦\n勀\n勛\n匀\n匇\n匤\n卲\n厓\n厲\n叝\n﨎\n咜\n咊\n咩\n哿\n喆\n坙\n坥\n垬\n埈\n埇\n﨏\n塚\n增\n墲\n夋\n奓\n奛\n奝\n奣\n妤\n妺\n孖\n寀\n甯\n寘\n寬\n尞\n岦\n岺\n峵\n崧\n嵓\n﨑\n嵂\n嵭\n嶸\n嶹\n巐\n弡\n弴\n彧\n德\n忞\n恝\n悅\n悊\n惞\n惕\n愠\n惲\n愑\n愷\n愰\n憘\n戓\n抦\n揵\n摠\n撝\n擎\n敎\n昀\n昕\n昻\n昉\n昮\n昞\n昤\n晥\n晗\n晙\n晴\n晳\n暙\n暠\n暲\n暿\n曺\n朎\n朗\n杦\n枻\n桒\n柀\n栁\n桄\n棏\n﨓\n楨\n﨔\n榘\n槢\n樰\n橫\n橆\n橳\n橾\n櫢\n櫤\n毖\n氿\n汜\n沆\n汯\n泚\n洄\n涇\n浯\n涖\n涬\n淏\n淸\n淲\n淼\n渹\n湜\n渧\n渼\n溿\n澈\n澵\n濵\n瀅\n瀇\n瀨\n炅\n炫\n焏\n焄\n煜\n煆\n煇\n凞\n燁\n燾\n犱\n犾\n猤\n猪\n獷\n玽\n珉\n珖\n珣\n珒\n琇\n珵\n琦\n琪\n琩\n琮\n瑢\n璉\n璟\n甁\n畯\n皂\n皜\n皞\n皛\n皦\n益\n睆\n劯\n砡\n硎\n硤\n硺\n礰\n礼\n神\n祥\n禔\n福\n禛\n竑\n竧\n靖\n竫\n箞\n精\n絈\n絜\n綷\n綠\n緖\n繒\n罇\n羡\n羽\n茁\n荢\n荿\n菇\n菶\n葈\n蒴\n蕓\n蕙\n蕫\n﨟\n薰\n蘒\n﨡\n蠇\n裵\n訒\n訷\n詹\n誧\n誾\n諟\n諸\n諶\n譓\n譿\n賰\n賴\n贒\n赶\n﨣\n軏\n﨤\n逸\n遧\n郞\n都\n鄕\n鄧\n釚\n釗\n釞\n釭\n釮\n釤\n釥\n鈆\n鈐\n鈊\n鈺\n鉀\n鈼\n鉎\n鉙\n鉑\n鈹\n鉧\n銧\n鉷\n鉸\n鋧\n鋗\n鋙\n鋐\n﨧\n鋕\n鋠\n鋓\n錥\n錡\n鋻\n﨨\n錞\n鋿\n錝\n錂\n鍰\n鍗\n鎤\n鏆\n鏞\n鏸\n鐱\n鑅\n鑈\n閒\n隆\n﨩\n隝\n隯\n霳\n霻\n靃\n靍\n靏\n靑\n靕\n顗\n顥\n飯\n飼\n餧\n館\n馞\n驎\n髙\n髜\n魵\n魲\n鮏\n鮱\n鮻\n鰀\n鵰\n鵫\n鶴\n鸙\n黑\n�\n�\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\n￢\n￤\n＇\n＂\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n"
  },
  {
    "path": "helix-view/tests/encoding/jis0208_out.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n　\n、\n。\n，\n．\n・\n：\n；\n？\n！\n゛\n゜\n´\n｀\n¨\n＾\n￣\n＿\nヽ\nヾ\nゝ\nゞ\n〃\n仝\n々\n〆\n〇\nー\n―\n‐\n／\n＼\n～\n∥\n｜\n…\n‥\n‘\n’\n“\n”\n（\n）\n〔\n〕\n［\n］\n｛\n｝\n〈\n〉\n《\n》\n「\n」\n『\n』\n【\n】\n＋\n－\n±\n×\n÷\n＝\n≠\n＜\n＞\n≦\n≧\n∞\n∴\n♂\n♀\n°\n′\n″\n℃\n￥\n＄\n￠\n￡\n％\n＃\n＆\n＊\n＠\n§\n☆\n★\n○\n●\n◎\n◇\n◆\n□\n■\n△\n▲\n▽\n▼\n※\n〒\n→\n←\n↑\n↓\n〓\n∈\n∋\n⊆\n⊇\n⊂\n⊃\n∪\n∩\n∧\n∨\n￢\n⇒\n⇔\n∀\n∃\n∠\n⊥\n⌒\n∂\n∇\n≡\n≒\n≪\n≫\n√\n∽\n∝\n∵\n∫\n∬\nÅ\n‰\n♯\n♭\n♪\n†\n‡\n¶\n◯\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n─\n│\n┌\n┐\n┘\n└\n├\n┬\n┤\n┴\n┼\n━\n┃\n┏\n┓\n┛\n┗\n┣\n┳\n┫\n┻\n╋\n┠\n┯\n┨\n┷\n┿\n┝\n┰\n┥\n┸\n╂\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n⑪\n⑫\n⑬\n⑭\n⑮\n⑯\n⑰\n⑱\n⑲\n⑳\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n㍉\n㌔\n㌢\n㍍\n㌘\n㌧\n㌃\n㌶\n㍑\n㍗\n㌍\n㌦\n㌣\n㌫\n㍊\n㌻\n㎜\n㎝\n㎞\n㎎\n㎏\n㏄\n㎡\n㍻\n〝\n〟\n№\n㏍\n℡\n㊤\n㊥\n㊦\n㊧\n㊨\n㈱\n㈲\n㈹\n㍾\n㍽\n㍼\n≒\n≡\n∫\n∮\n∑\n√\n⊥\n∠\n∟\n⊿\n∵\n∩\n∪\n亜\n唖\n娃\n阿\n哀\n愛\n挨\n姶\n逢\n葵\n茜\n穐\n悪\n握\n渥\n旭\n葦\n芦\n鯵\n梓\n圧\n斡\n扱\n宛\n姐\n虻\n飴\n絢\n綾\n鮎\n或\n粟\n袷\n安\n庵\n按\n暗\n案\n闇\n鞍\n杏\n以\n伊\n位\n依\n偉\n囲\n夷\n委\n威\n尉\n惟\n意\n慰\n易\n椅\n為\n畏\n異\n移\n維\n緯\n胃\n萎\n衣\n謂\n違\n遺\n医\n井\n亥\n域\n育\n郁\n磯\n一\n壱\n溢\n逸\n稲\n茨\n芋\n鰯\n允\n印\n咽\n員\n因\n姻\n引\n飲\n淫\n胤\n蔭\n院\n陰\n隠\n韻\n吋\n右\n宇\n烏\n羽\n迂\n雨\n卯\n鵜\n窺\n丑\n碓\n臼\n渦\n嘘\n唄\n欝\n蔚\n鰻\n姥\n厩\n浦\n瓜\n閏\n噂\n云\n運\n雲\n荏\n餌\n叡\n営\n嬰\n影\n映\n曳\n栄\n永\n泳\n洩\n瑛\n盈\n穎\n頴\n英\n衛\n詠\n鋭\n液\n疫\n益\n駅\n悦\n謁\n越\n閲\n榎\n厭\n円\n園\n堰\n奄\n宴\n延\n怨\n掩\n援\n沿\n演\n炎\n焔\n煙\n燕\n猿\n縁\n艶\n苑\n薗\n遠\n鉛\n鴛\n塩\n於\n汚\n甥\n凹\n央\n奥\n往\n応\n押\n旺\n横\n欧\n殴\n王\n翁\n襖\n鴬\n鴎\n黄\n岡\n沖\n荻\n億\n屋\n憶\n臆\n桶\n牡\n乙\n俺\n卸\n恩\n温\n穏\n音\n下\n化\n仮\n何\n伽\n価\n佳\n加\n可\n嘉\n夏\n嫁\n家\n寡\n科\n暇\n果\n架\n歌\n河\n火\n珂\n禍\n禾\n稼\n箇\n花\n苛\n茄\n荷\n華\n菓\n蝦\n課\n嘩\n貨\n迦\n過\n霞\n蚊\n俄\n峨\n我\n牙\n画\n臥\n芽\n蛾\n賀\n雅\n餓\n駕\n介\n会\n解\n回\n塊\n壊\n廻\n快\n怪\n悔\n恢\n懐\n戒\n拐\n改\n魁\n晦\n械\n海\n灰\n界\n皆\n絵\n芥\n蟹\n開\n階\n貝\n凱\n劾\n外\n咳\n害\n崖\n慨\n概\n涯\n碍\n蓋\n街\n該\n鎧\n骸\n浬\n馨\n蛙\n垣\n柿\n蛎\n鈎\n劃\n嚇\n各\n廓\n拡\n撹\n格\n核\n殻\n獲\n確\n穫\n覚\n角\n赫\n較\n郭\n閣\n隔\n革\n学\n岳\n楽\n額\n顎\n掛\n笠\n樫\n橿\n梶\n鰍\n潟\n割\n喝\n恰\n括\n活\n渇\n滑\n葛\n褐\n轄\n且\n鰹\n叶\n椛\n樺\n鞄\n株\n兜\n竃\n蒲\n釜\n鎌\n噛\n鴨\n栢\n茅\n萱\n粥\n刈\n苅\n瓦\n乾\n侃\n冠\n寒\n刊\n勘\n勧\n巻\n喚\n堪\n姦\n完\n官\n寛\n干\n幹\n患\n感\n慣\n憾\n換\n敢\n柑\n桓\n棺\n款\n歓\n汗\n漢\n澗\n潅\n環\n甘\n監\n看\n竿\n管\n簡\n緩\n缶\n翰\n肝\n艦\n莞\n観\n諌\n貫\n還\n鑑\n間\n閑\n関\n陥\n韓\n館\n舘\n丸\n含\n岸\n巌\n玩\n癌\n眼\n岩\n翫\n贋\n雁\n頑\n顔\n願\n企\n伎\n危\n喜\n器\n基\n奇\n嬉\n寄\n岐\n希\n幾\n忌\n揮\n机\n旗\n既\n期\n棋\n棄\n機\n帰\n毅\n気\n汽\n畿\n祈\n季\n稀\n紀\n徽\n規\n記\n貴\n起\n軌\n輝\n飢\n騎\n鬼\n亀\n偽\n儀\n妓\n宜\n戯\n技\n擬\n欺\n犠\n疑\n祇\n義\n蟻\n誼\n議\n掬\n菊\n鞠\n吉\n吃\n喫\n桔\n橘\n詰\n砧\n杵\n黍\n却\n客\n脚\n虐\n逆\n丘\n久\n仇\n休\n及\n吸\n宮\n弓\n急\n救\n朽\n求\n汲\n泣\n灸\n球\n究\n窮\n笈\n級\n糾\n給\n旧\n牛\n去\n居\n巨\n拒\n拠\n挙\n渠\n虚\n許\n距\n鋸\n漁\n禦\n魚\n亨\n享\n京\n供\n侠\n僑\n兇\n競\n共\n凶\n協\n匡\n卿\n叫\n喬\n境\n峡\n強\n彊\n怯\n恐\n恭\n挟\n教\n橋\n況\n狂\n狭\n矯\n胸\n脅\n興\n蕎\n郷\n鏡\n響\n饗\n驚\n仰\n凝\n尭\n暁\n業\n局\n曲\n極\n玉\n桐\n粁\n僅\n勤\n均\n巾\n錦\n斤\n欣\n欽\n琴\n禁\n禽\n筋\n緊\n芹\n菌\n衿\n襟\n謹\n近\n金\n吟\n銀\n九\n倶\n句\n区\n狗\n玖\n矩\n苦\n躯\n駆\n駈\n駒\n具\n愚\n虞\n喰\n空\n偶\n寓\n遇\n隅\n串\n櫛\n釧\n屑\n屈\n掘\n窟\n沓\n靴\n轡\n窪\n熊\n隈\n粂\n栗\n繰\n桑\n鍬\n勲\n君\n薫\n訓\n群\n軍\n郡\n卦\n袈\n祁\n係\n傾\n刑\n兄\n啓\n圭\n珪\n型\n契\n形\n径\n恵\n慶\n慧\n憩\n掲\n携\n敬\n景\n桂\n渓\n畦\n稽\n系\n経\n継\n繋\n罫\n茎\n荊\n蛍\n計\n詣\n警\n軽\n頚\n鶏\n芸\n迎\n鯨\n劇\n戟\n撃\n激\n隙\n桁\n傑\n欠\n決\n潔\n穴\n結\n血\n訣\n月\n件\n倹\n倦\n健\n兼\n券\n剣\n喧\n圏\n堅\n嫌\n建\n憲\n懸\n拳\n捲\n検\n権\n牽\n犬\n献\n研\n硯\n絹\n県\n肩\n見\n謙\n賢\n軒\n遣\n鍵\n険\n顕\n験\n鹸\n元\n原\n厳\n幻\n弦\n減\n源\n玄\n現\n絃\n舷\n言\n諺\n限\n乎\n個\n古\n呼\n固\n姑\n孤\n己\n庫\n弧\n戸\n故\n枯\n湖\n狐\n糊\n袴\n股\n胡\n菰\n虎\n誇\n跨\n鈷\n雇\n顧\n鼓\n五\n互\n伍\n午\n呉\n吾\n娯\n後\n御\n悟\n梧\n檎\n瑚\n碁\n語\n誤\n護\n醐\n乞\n鯉\n交\n佼\n侯\n候\n倖\n光\n公\n功\n効\n勾\n厚\n口\n向\n后\n喉\n坑\n垢\n好\n孔\n孝\n宏\n工\n巧\n巷\n幸\n広\n庚\n康\n弘\n恒\n慌\n抗\n拘\n控\n攻\n昂\n晃\n更\n杭\n校\n梗\n構\n江\n洪\n浩\n港\n溝\n甲\n皇\n硬\n稿\n糠\n紅\n紘\n絞\n綱\n耕\n考\n肯\n肱\n腔\n膏\n航\n荒\n行\n衡\n講\n貢\n購\n郊\n酵\n鉱\n砿\n鋼\n閤\n降\n項\n香\n高\n鴻\n剛\n劫\n号\n合\n壕\n拷\n濠\n豪\n轟\n麹\n克\n刻\n告\n国\n穀\n酷\n鵠\n黒\n獄\n漉\n腰\n甑\n忽\n惚\n骨\n狛\n込\n此\n頃\n今\n困\n坤\n墾\n婚\n恨\n懇\n昏\n昆\n根\n梱\n混\n痕\n紺\n艮\n魂\n些\n佐\n叉\n唆\n嵯\n左\n差\n査\n沙\n瑳\n砂\n詐\n鎖\n裟\n坐\n座\n挫\n債\n催\n再\n最\n哉\n塞\n妻\n宰\n彩\n才\n採\n栽\n歳\n済\n災\n采\n犀\n砕\n砦\n祭\n斎\n細\n菜\n裁\n載\n際\n剤\n在\n材\n罪\n財\n冴\n坂\n阪\n堺\n榊\n肴\n咲\n崎\n埼\n碕\n鷺\n作\n削\n咋\n搾\n昨\n朔\n柵\n窄\n策\n索\n錯\n桜\n鮭\n笹\n匙\n冊\n刷\n察\n拶\n撮\n擦\n札\n殺\n薩\n雑\n皐\n鯖\n捌\n錆\n鮫\n皿\n晒\n三\n傘\n参\n山\n惨\n撒\n散\n桟\n燦\n珊\n産\n算\n纂\n蚕\n讃\n賛\n酸\n餐\n斬\n暫\n残\n仕\n仔\n伺\n使\n刺\n司\n史\n嗣\n四\n士\n始\n姉\n姿\n子\n屍\n市\n師\n志\n思\n指\n支\n孜\n斯\n施\n旨\n枝\n止\n死\n氏\n獅\n祉\n私\n糸\n紙\n紫\n肢\n脂\n至\n視\n詞\n詩\n試\n誌\n諮\n資\n賜\n雌\n飼\n歯\n事\n似\n侍\n児\n字\n寺\n慈\n持\n時\n次\n滋\n治\n爾\n璽\n痔\n磁\n示\n而\n耳\n自\n蒔\n辞\n汐\n鹿\n式\n識\n鴫\n竺\n軸\n宍\n雫\n七\n叱\n執\n失\n嫉\n室\n悉\n湿\n漆\n疾\n質\n実\n蔀\n篠\n偲\n柴\n芝\n屡\n蕊\n縞\n舎\n写\n射\n捨\n赦\n斜\n煮\n社\n紗\n者\n謝\n車\n遮\n蛇\n邪\n借\n勺\n尺\n杓\n灼\n爵\n酌\n釈\n錫\n若\n寂\n弱\n惹\n主\n取\n守\n手\n朱\n殊\n狩\n珠\n種\n腫\n趣\n酒\n首\n儒\n受\n呪\n寿\n授\n樹\n綬\n需\n囚\n収\n周\n宗\n就\n州\n修\n愁\n拾\n洲\n秀\n秋\n終\n繍\n習\n臭\n舟\n蒐\n衆\n襲\n讐\n蹴\n輯\n週\n酋\n酬\n集\n醜\n什\n住\n充\n十\n従\n戎\n柔\n汁\n渋\n獣\n縦\n重\n銃\n叔\n夙\n宿\n淑\n祝\n縮\n粛\n塾\n熟\n出\n術\n述\n俊\n峻\n春\n瞬\n竣\n舜\n駿\n准\n循\n旬\n楯\n殉\n淳\n準\n潤\n盾\n純\n巡\n遵\n醇\n順\n処\n初\n所\n暑\n曙\n渚\n庶\n緒\n署\n書\n薯\n藷\n諸\n助\n叙\n女\n序\n徐\n恕\n鋤\n除\n傷\n償\n勝\n匠\n升\n召\n哨\n商\n唱\n嘗\n奨\n妾\n娼\n宵\n将\n小\n少\n尚\n庄\n床\n廠\n彰\n承\n抄\n招\n掌\n捷\n昇\n昌\n昭\n晶\n松\n梢\n樟\n樵\n沼\n消\n渉\n湘\n焼\n焦\n照\n症\n省\n硝\n礁\n祥\n称\n章\n笑\n粧\n紹\n肖\n菖\n蒋\n蕉\n衝\n裳\n訟\n証\n詔\n詳\n象\n賞\n醤\n鉦\n鍾\n鐘\n障\n鞘\n上\n丈\n丞\n乗\n冗\n剰\n城\n場\n壌\n嬢\n常\n情\n擾\n条\n杖\n浄\n状\n畳\n穣\n蒸\n譲\n醸\n錠\n嘱\n埴\n飾\n拭\n植\n殖\n燭\n織\n職\n色\n触\n食\n蝕\n辱\n尻\n伸\n信\n侵\n唇\n娠\n寝\n審\n心\n慎\n振\n新\n晋\n森\n榛\n浸\n深\n申\n疹\n真\n神\n秦\n紳\n臣\n芯\n薪\n親\n診\n身\n辛\n進\n針\n震\n人\n仁\n刃\n塵\n壬\n尋\n甚\n尽\n腎\n訊\n迅\n陣\n靭\n笥\n諏\n須\n酢\n図\n厨\n逗\n吹\n垂\n帥\n推\n水\n炊\n睡\n粋\n翠\n衰\n遂\n酔\n錐\n錘\n随\n瑞\n髄\n崇\n嵩\n数\n枢\n趨\n雛\n据\n杉\n椙\n菅\n頗\n雀\n裾\n澄\n摺\n寸\n世\n瀬\n畝\n是\n凄\n制\n勢\n姓\n征\n性\n成\n政\n整\n星\n晴\n棲\n栖\n正\n清\n牲\n生\n盛\n精\n聖\n声\n製\n西\n誠\n誓\n請\n逝\n醒\n青\n静\n斉\n税\n脆\n隻\n席\n惜\n戚\n斥\n昔\n析\n石\n積\n籍\n績\n脊\n責\n赤\n跡\n蹟\n碩\n切\n拙\n接\n摂\n折\n設\n窃\n節\n説\n雪\n絶\n舌\n蝉\n仙\n先\n千\n占\n宣\n専\n尖\n川\n戦\n扇\n撰\n栓\n栴\n泉\n浅\n洗\n染\n潜\n煎\n煽\n旋\n穿\n箭\n線\n繊\n羨\n腺\n舛\n船\n薦\n詮\n賎\n践\n選\n遷\n銭\n銑\n閃\n鮮\n前\n善\n漸\n然\n全\n禅\n繕\n膳\n糎\n噌\n塑\n岨\n措\n曾\n曽\n楚\n狙\n疏\n疎\n礎\n祖\n租\n粗\n素\n組\n蘇\n訴\n阻\n遡\n鼠\n僧\n創\n双\n叢\n倉\n喪\n壮\n奏\n爽\n宋\n層\n匝\n惣\n想\n捜\n掃\n挿\n掻\n操\n早\n曹\n巣\n槍\n槽\n漕\n燥\n争\n痩\n相\n窓\n糟\n総\n綜\n聡\n草\n荘\n葬\n蒼\n藻\n装\n走\n送\n遭\n鎗\n霜\n騒\n像\n増\n憎\n臓\n蔵\n贈\n造\n促\n側\n則\n即\n息\n捉\n束\n測\n足\n速\n俗\n属\n賊\n族\n続\n卒\n袖\n其\n揃\n存\n孫\n尊\n損\n村\n遜\n他\n多\n太\n汰\n詑\n唾\n堕\n妥\n惰\n打\n柁\n舵\n楕\n陀\n駄\n騨\n体\n堆\n対\n耐\n岱\n帯\n待\n怠\n態\n戴\n替\n泰\n滞\n胎\n腿\n苔\n袋\n貸\n退\n逮\n隊\n黛\n鯛\n代\n台\n大\n第\n醍\n題\n鷹\n滝\n瀧\n卓\n啄\n宅\n托\n択\n拓\n沢\n濯\n琢\n託\n鐸\n濁\n諾\n茸\n凧\n蛸\n只\n叩\n但\n達\n辰\n奪\n脱\n巽\n竪\n辿\n棚\n谷\n狸\n鱈\n樽\n誰\n丹\n単\n嘆\n坦\n担\n探\n旦\n歎\n淡\n湛\n炭\n短\n端\n箪\n綻\n耽\n胆\n蛋\n誕\n鍛\n団\n壇\n弾\n断\n暖\n檀\n段\n男\n談\n値\n知\n地\n弛\n恥\n智\n池\n痴\n稚\n置\n致\n蜘\n遅\n馳\n築\n畜\n竹\n筑\n蓄\n逐\n秩\n窒\n茶\n嫡\n着\n中\n仲\n宙\n忠\n抽\n昼\n柱\n注\n虫\n衷\n註\n酎\n鋳\n駐\n樗\n瀦\n猪\n苧\n著\n貯\n丁\n兆\n凋\n喋\n寵\n帖\n帳\n庁\n弔\n張\n彫\n徴\n懲\n挑\n暢\n朝\n潮\n牒\n町\n眺\n聴\n脹\n腸\n蝶\n調\n諜\n超\n跳\n銚\n長\n頂\n鳥\n勅\n捗\n直\n朕\n沈\n珍\n賃\n鎮\n陳\n津\n墜\n椎\n槌\n追\n鎚\n痛\n通\n塚\n栂\n掴\n槻\n佃\n漬\n柘\n辻\n蔦\n綴\n鍔\n椿\n潰\n坪\n壷\n嬬\n紬\n爪\n吊\n釣\n鶴\n亭\n低\n停\n偵\n剃\n貞\n呈\n堤\n定\n帝\n底\n庭\n廷\n弟\n悌\n抵\n挺\n提\n梯\n汀\n碇\n禎\n程\n締\n艇\n訂\n諦\n蹄\n逓\n邸\n鄭\n釘\n鼎\n泥\n摘\n擢\n敵\n滴\n的\n笛\n適\n鏑\n溺\n哲\n徹\n撤\n轍\n迭\n鉄\n典\n填\n天\n展\n店\n添\n纏\n甜\n貼\n転\n顛\n点\n伝\n殿\n澱\n田\n電\n兎\n吐\n堵\n塗\n妬\n屠\n徒\n斗\n杜\n渡\n登\n菟\n賭\n途\n都\n鍍\n砥\n砺\n努\n度\n土\n奴\n怒\n倒\n党\n冬\n凍\n刀\n唐\n塔\n塘\n套\n宕\n島\n嶋\n悼\n投\n搭\n東\n桃\n梼\n棟\n盗\n淘\n湯\n涛\n灯\n燈\n当\n痘\n祷\n等\n答\n筒\n糖\n統\n到\n董\n蕩\n藤\n討\n謄\n豆\n踏\n逃\n透\n鐙\n陶\n頭\n騰\n闘\n働\n動\n同\n堂\n導\n憧\n撞\n洞\n瞳\n童\n胴\n萄\n道\n銅\n峠\n鴇\n匿\n得\n徳\n涜\n特\n督\n禿\n篤\n毒\n独\n読\n栃\n橡\n凸\n突\n椴\n届\n鳶\n苫\n寅\n酉\n瀞\n噸\n屯\n惇\n敦\n沌\n豚\n遁\n頓\n呑\n曇\n鈍\n奈\n那\n内\n乍\n凪\n薙\n謎\n灘\n捺\n鍋\n楢\n馴\n縄\n畷\n南\n楠\n軟\n難\n汝\n二\n尼\n弐\n迩\n匂\n賑\n肉\n虹\n廿\n日\n乳\n入\n如\n尿\n韮\n任\n妊\n忍\n認\n濡\n禰\n祢\n寧\n葱\n猫\n熱\n年\n念\n捻\n撚\n燃\n粘\n乃\n廼\n之\n埜\n嚢\n悩\n濃\n納\n能\n脳\n膿\n農\n覗\n蚤\n巴\n把\n播\n覇\n杷\n波\n派\n琶\n破\n婆\n罵\n芭\n馬\n俳\n廃\n拝\n排\n敗\n杯\n盃\n牌\n背\n肺\n輩\n配\n倍\n培\n媒\n梅\n楳\n煤\n狽\n買\n売\n賠\n陪\n這\n蝿\n秤\n矧\n萩\n伯\n剥\n博\n拍\n柏\n泊\n白\n箔\n粕\n舶\n薄\n迫\n曝\n漠\n爆\n縛\n莫\n駁\n麦\n函\n箱\n硲\n箸\n肇\n筈\n櫨\n幡\n肌\n畑\n畠\n八\n鉢\n溌\n発\n醗\n髪\n伐\n罰\n抜\n筏\n閥\n鳩\n噺\n塙\n蛤\n隼\n伴\n判\n半\n反\n叛\n帆\n搬\n斑\n板\n氾\n汎\n版\n犯\n班\n畔\n繁\n般\n藩\n販\n範\n釆\n煩\n頒\n飯\n挽\n晩\n番\n盤\n磐\n蕃\n蛮\n匪\n卑\n否\n妃\n庇\n彼\n悲\n扉\n批\n披\n斐\n比\n泌\n疲\n皮\n碑\n秘\n緋\n罷\n肥\n被\n誹\n費\n避\n非\n飛\n樋\n簸\n備\n尾\n微\n枇\n毘\n琵\n眉\n美\n鼻\n柊\n稗\n匹\n疋\n髭\n彦\n膝\n菱\n肘\n弼\n必\n畢\n筆\n逼\n桧\n姫\n媛\n紐\n百\n謬\n俵\n彪\n標\n氷\n漂\n瓢\n票\n表\n評\n豹\n廟\n描\n病\n秒\n苗\n錨\n鋲\n蒜\n蛭\n鰭\n品\n彬\n斌\n浜\n瀕\n貧\n賓\n頻\n敏\n瓶\n不\n付\n埠\n夫\n婦\n富\n冨\n布\n府\n怖\n扶\n敷\n斧\n普\n浮\n父\n符\n腐\n膚\n芙\n譜\n負\n賦\n赴\n阜\n附\n侮\n撫\n武\n舞\n葡\n蕪\n部\n封\n楓\n風\n葺\n蕗\n伏\n副\n復\n幅\n服\n福\n腹\n複\n覆\n淵\n弗\n払\n沸\n仏\n物\n鮒\n分\n吻\n噴\n墳\n憤\n扮\n焚\n奮\n粉\n糞\n紛\n雰\n文\n聞\n丙\n併\n兵\n塀\n幣\n平\n弊\n柄\n並\n蔽\n閉\n陛\n米\n頁\n僻\n壁\n癖\n碧\n別\n瞥\n蔑\n箆\n偏\n変\n片\n篇\n編\n辺\n返\n遍\n便\n勉\n娩\n弁\n鞭\n保\n舗\n鋪\n圃\n捕\n歩\n甫\n補\n輔\n穂\n募\n墓\n慕\n戊\n暮\n母\n簿\n菩\n倣\n俸\n包\n呆\n報\n奉\n宝\n峰\n峯\n崩\n庖\n抱\n捧\n放\n方\n朋\n法\n泡\n烹\n砲\n縫\n胞\n芳\n萌\n蓬\n蜂\n褒\n訪\n豊\n邦\n鋒\n飽\n鳳\n鵬\n乏\n亡\n傍\n剖\n坊\n妨\n帽\n忘\n忙\n房\n暴\n望\n某\n棒\n冒\n紡\n肪\n膨\n謀\n貌\n貿\n鉾\n防\n吠\n頬\n北\n僕\n卜\n墨\n撲\n朴\n牧\n睦\n穆\n釦\n勃\n没\n殆\n堀\n幌\n奔\n本\n翻\n凡\n盆\n摩\n磨\n魔\n麻\n埋\n妹\n昧\n枚\n毎\n哩\n槙\n幕\n膜\n枕\n鮪\n柾\n鱒\n桝\n亦\n俣\n又\n抹\n末\n沫\n迄\n侭\n繭\n麿\n万\n慢\n満\n漫\n蔓\n味\n未\n魅\n巳\n箕\n岬\n密\n蜜\n湊\n蓑\n稔\n脈\n妙\n粍\n民\n眠\n務\n夢\n無\n牟\n矛\n霧\n鵡\n椋\n婿\n娘\n冥\n名\n命\n明\n盟\n迷\n銘\n鳴\n姪\n牝\n滅\n免\n棉\n綿\n緬\n面\n麺\n摸\n模\n茂\n妄\n孟\n毛\n猛\n盲\n網\n耗\n蒙\n儲\n木\n黙\n目\n杢\n勿\n餅\n尤\n戻\n籾\n貰\n問\n悶\n紋\n門\n匁\n也\n冶\n夜\n爺\n耶\n野\n弥\n矢\n厄\n役\n約\n薬\n訳\n躍\n靖\n柳\n薮\n鑓\n愉\n愈\n油\n癒\n諭\n輸\n唯\n佑\n優\n勇\n友\n宥\n幽\n悠\n憂\n揖\n有\n柚\n湧\n涌\n猶\n猷\n由\n祐\n裕\n誘\n遊\n邑\n郵\n雄\n融\n夕\n予\n余\n与\n誉\n輿\n預\n傭\n幼\n妖\n容\n庸\n揚\n揺\n擁\n曜\n楊\n様\n洋\n溶\n熔\n用\n窯\n羊\n耀\n葉\n蓉\n要\n謡\n踊\n遥\n陽\n養\n慾\n抑\n欲\n沃\n浴\n翌\n翼\n淀\n羅\n螺\n裸\n来\n莱\n頼\n雷\n洛\n絡\n落\n酪\n乱\n卵\n嵐\n欄\n濫\n藍\n蘭\n覧\n利\n吏\n履\n李\n梨\n理\n璃\n痢\n裏\n裡\n里\n離\n陸\n律\n率\n立\n葎\n掠\n略\n劉\n流\n溜\n琉\n留\n硫\n粒\n隆\n竜\n龍\n侶\n慮\n旅\n虜\n了\n亮\n僚\n両\n凌\n寮\n料\n梁\n涼\n猟\n療\n瞭\n稜\n糧\n良\n諒\n遼\n量\n陵\n領\n力\n緑\n倫\n厘\n林\n淋\n燐\n琳\n臨\n輪\n隣\n鱗\n麟\n瑠\n塁\n涙\n累\n類\n令\n伶\n例\n冷\n励\n嶺\n怜\n玲\n礼\n苓\n鈴\n隷\n零\n霊\n麗\n齢\n暦\n歴\n列\n劣\n烈\n裂\n廉\n恋\n憐\n漣\n煉\n簾\n練\n聯\n蓮\n連\n錬\n呂\n魯\n櫓\n炉\n賂\n路\n露\n労\n婁\n廊\n弄\n朗\n楼\n榔\n浪\n漏\n牢\n狼\n篭\n老\n聾\n蝋\n郎\n六\n麓\n禄\n肋\n録\n論\n倭\n和\n話\n歪\n賄\n脇\n惑\n枠\n鷲\n亙\n亘\n鰐\n詫\n藁\n蕨\n椀\n湾\n碗\n腕\n弌\n丐\n丕\n个\n丱\n丶\n丼\n丿\n乂\n乖\n乘\n亂\n亅\n豫\n亊\n舒\n弍\n于\n亞\n亟\n亠\n亢\n亰\n亳\n亶\n从\n仍\n仄\n仆\n仂\n仗\n仞\n仭\n仟\n价\n伉\n佚\n估\n佛\n佝\n佗\n佇\n佶\n侈\n侏\n侘\n佻\n佩\n佰\n侑\n佯\n來\n侖\n儘\n俔\n俟\n俎\n俘\n俛\n俑\n俚\n俐\n俤\n俥\n倚\n倨\n倔\n倪\n倥\n倅\n伜\n俶\n倡\n倩\n倬\n俾\n俯\n們\n倆\n偃\n假\n會\n偕\n偐\n偈\n做\n偖\n偬\n偸\n傀\n傚\n傅\n傴\n傲\n僉\n僊\n傳\n僂\n僖\n僞\n僥\n僭\n僣\n僮\n價\n僵\n儉\n儁\n儂\n儖\n儕\n儔\n儚\n儡\n儺\n儷\n儼\n儻\n儿\n兀\n兒\n兌\n兔\n兢\n竸\n兩\n兪\n兮\n冀\n冂\n囘\n册\n冉\n冏\n冑\n冓\n冕\n冖\n冤\n冦\n冢\n冩\n冪\n冫\n决\n冱\n冲\n冰\n况\n冽\n凅\n凉\n凛\n几\n處\n凩\n凭\n凰\n凵\n凾\n刄\n刋\n刔\n刎\n刧\n刪\n刮\n刳\n刹\n剏\n剄\n剋\n剌\n剞\n剔\n剪\n剴\n剩\n剳\n剿\n剽\n劍\n劔\n劒\n剱\n劈\n劑\n辨\n辧\n劬\n劭\n劼\n劵\n勁\n勍\n勗\n勞\n勣\n勦\n飭\n勠\n勳\n勵\n勸\n勹\n匆\n匈\n甸\n匍\n匐\n匏\n匕\n匚\n匣\n匯\n匱\n匳\n匸\n區\n卆\n卅\n丗\n卉\n卍\n凖\n卞\n卩\n卮\n夘\n卻\n卷\n厂\n厖\n厠\n厦\n厥\n厮\n厰\n厶\n參\n簒\n雙\n叟\n曼\n燮\n叮\n叨\n叭\n叺\n吁\n吽\n呀\n听\n吭\n吼\n吮\n吶\n吩\n吝\n呎\n咏\n呵\n咎\n呟\n呱\n呷\n呰\n咒\n呻\n咀\n呶\n咄\n咐\n咆\n哇\n咢\n咸\n咥\n咬\n哄\n哈\n咨\n咫\n哂\n咤\n咾\n咼\n哘\n哥\n哦\n唏\n唔\n哽\n哮\n哭\n哺\n哢\n唹\n啀\n啣\n啌\n售\n啜\n啅\n啖\n啗\n唸\n唳\n啝\n喙\n喀\n咯\n喊\n喟\n啻\n啾\n喘\n喞\n單\n啼\n喃\n喩\n喇\n喨\n嗚\n嗅\n嗟\n嗄\n嗜\n嗤\n嗔\n嘔\n嗷\n嘖\n嗾\n嗽\n嘛\n嗹\n噎\n噐\n營\n嘴\n嘶\n嘲\n嘸\n噫\n噤\n嘯\n噬\n噪\n嚆\n嚀\n嚊\n嚠\n嚔\n嚏\n嚥\n嚮\n嚶\n嚴\n囂\n嚼\n囁\n囃\n囀\n囈\n囎\n囑\n囓\n囗\n囮\n囹\n圀\n囿\n圄\n圉\n圈\n國\n圍\n圓\n團\n圖\n嗇\n圜\n圦\n圷\n圸\n坎\n圻\n址\n坏\n坩\n埀\n垈\n坡\n坿\n垉\n垓\n垠\n垳\n垤\n垪\n垰\n埃\n埆\n埔\n埒\n埓\n堊\n埖\n埣\n堋\n堙\n堝\n塲\n堡\n塢\n塋\n塰\n毀\n塒\n堽\n塹\n墅\n墹\n墟\n墫\n墺\n壞\n墻\n墸\n墮\n壅\n壓\n壑\n壗\n壙\n壘\n壥\n壜\n壤\n壟\n壯\n壺\n壹\n壻\n壼\n壽\n夂\n夊\n夐\n夛\n梦\n夥\n夬\n夭\n夲\n夸\n夾\n竒\n奕\n奐\n奎\n奚\n奘\n奢\n奠\n奧\n奬\n奩\n奸\n妁\n妝\n佞\n侫\n妣\n妲\n姆\n姨\n姜\n妍\n姙\n姚\n娥\n娟\n娑\n娜\n娉\n娚\n婀\n婬\n婉\n娵\n娶\n婢\n婪\n媚\n媼\n媾\n嫋\n嫂\n媽\n嫣\n嫗\n嫦\n嫩\n嫖\n嫺\n嫻\n嬌\n嬋\n嬖\n嬲\n嫐\n嬪\n嬶\n嬾\n孃\n孅\n孀\n孑\n孕\n孚\n孛\n孥\n孩\n孰\n孳\n孵\n學\n斈\n孺\n宀\n它\n宦\n宸\n寃\n寇\n寉\n寔\n寐\n寤\n實\n寢\n寞\n寥\n寫\n寰\n寶\n寳\n尅\n將\n專\n對\n尓\n尠\n尢\n尨\n尸\n尹\n屁\n屆\n屎\n屓\n屐\n屏\n孱\n屬\n屮\n乢\n屶\n屹\n岌\n岑\n岔\n妛\n岫\n岻\n岶\n岼\n岷\n峅\n岾\n峇\n峙\n峩\n峽\n峺\n峭\n嶌\n峪\n崋\n崕\n崗\n嵜\n崟\n崛\n崑\n崔\n崢\n崚\n崙\n崘\n嵌\n嵒\n嵎\n嵋\n嵬\n嵳\n嵶\n嶇\n嶄\n嶂\n嶢\n嶝\n嶬\n嶮\n嶽\n嶐\n嶷\n嶼\n巉\n巍\n巓\n巒\n巖\n巛\n巫\n已\n巵\n帋\n帚\n帙\n帑\n帛\n帶\n帷\n幄\n幃\n幀\n幎\n幗\n幔\n幟\n幢\n幤\n幇\n幵\n并\n幺\n麼\n广\n庠\n廁\n廂\n廈\n廐\n廏\n廖\n廣\n廝\n廚\n廛\n廢\n廡\n廨\n廩\n廬\n廱\n廳\n廰\n廴\n廸\n廾\n弃\n弉\n彝\n彜\n弋\n弑\n弖\n弩\n弭\n弸\n彁\n彈\n彌\n彎\n弯\n彑\n彖\n彗\n彙\n彡\n彭\n彳\n彷\n徃\n徂\n彿\n徊\n很\n徑\n徇\n從\n徙\n徘\n徠\n徨\n徭\n徼\n忖\n忻\n忤\n忸\n忱\n忝\n悳\n忿\n怡\n恠\n怙\n怐\n怩\n怎\n怱\n怛\n怕\n怫\n怦\n怏\n怺\n恚\n恁\n恪\n恷\n恟\n恊\n恆\n恍\n恣\n恃\n恤\n恂\n恬\n恫\n恙\n悁\n悍\n惧\n悃\n悚\n悄\n悛\n悖\n悗\n悒\n悧\n悋\n惡\n悸\n惠\n惓\n悴\n忰\n悽\n惆\n悵\n惘\n慍\n愕\n愆\n惶\n惷\n愀\n惴\n惺\n愃\n愡\n惻\n惱\n愍\n愎\n慇\n愾\n愨\n愧\n慊\n愿\n愼\n愬\n愴\n愽\n慂\n慄\n慳\n慷\n慘\n慙\n慚\n慫\n慴\n慯\n慥\n慱\n慟\n慝\n慓\n慵\n憙\n憖\n憇\n憬\n憔\n憚\n憊\n憑\n憫\n憮\n懌\n懊\n應\n懷\n懈\n懃\n懆\n憺\n懋\n罹\n懍\n懦\n懣\n懶\n懺\n懴\n懿\n懽\n懼\n懾\n戀\n戈\n戉\n戍\n戌\n戔\n戛\n戞\n戡\n截\n戮\n戰\n戲\n戳\n扁\n扎\n扞\n扣\n扛\n扠\n扨\n扼\n抂\n抉\n找\n抒\n抓\n抖\n拔\n抃\n抔\n拗\n拑\n抻\n拏\n拿\n拆\n擔\n拈\n拜\n拌\n拊\n拂\n拇\n抛\n拉\n挌\n拮\n拱\n挧\n挂\n挈\n拯\n拵\n捐\n挾\n捍\n搜\n捏\n掖\n掎\n掀\n掫\n捶\n掣\n掏\n掉\n掟\n掵\n捫\n捩\n掾\n揩\n揀\n揆\n揣\n揉\n插\n揶\n揄\n搖\n搴\n搆\n搓\n搦\n搶\n攝\n搗\n搨\n搏\n摧\n摯\n摶\n摎\n攪\n撕\n撓\n撥\n撩\n撈\n撼\n據\n擒\n擅\n擇\n撻\n擘\n擂\n擱\n擧\n舉\n擠\n擡\n抬\n擣\n擯\n攬\n擶\n擴\n擲\n擺\n攀\n擽\n攘\n攜\n攅\n攤\n攣\n攫\n攴\n攵\n攷\n收\n攸\n畋\n效\n敖\n敕\n敍\n敘\n敞\n敝\n敲\n數\n斂\n斃\n變\n斛\n斟\n斫\n斷\n旃\n旆\n旁\n旄\n旌\n旒\n旛\n旙\n无\n旡\n旱\n杲\n昊\n昃\n旻\n杳\n昵\n昶\n昴\n昜\n晏\n晄\n晉\n晁\n晞\n晝\n晤\n晧\n晨\n晟\n晢\n晰\n暃\n暈\n暎\n暉\n暄\n暘\n暝\n曁\n暹\n曉\n暾\n暼\n曄\n暸\n曖\n曚\n曠\n昿\n曦\n曩\n曰\n曵\n曷\n朏\n朖\n朞\n朦\n朧\n霸\n朮\n朿\n朶\n杁\n朸\n朷\n杆\n杞\n杠\n杙\n杣\n杤\n枉\n杰\n枩\n杼\n杪\n枌\n枋\n枦\n枡\n枅\n枷\n柯\n枴\n柬\n枳\n柩\n枸\n柤\n柞\n柝\n柢\n柮\n枹\n柎\n柆\n柧\n檜\n栞\n框\n栩\n桀\n桍\n栲\n桎\n梳\n栫\n桙\n档\n桷\n桿\n梟\n梏\n梭\n梔\n條\n梛\n梃\n檮\n梹\n桴\n梵\n梠\n梺\n椏\n梍\n桾\n椁\n棊\n椈\n棘\n椢\n椦\n棡\n椌\n棍\n棔\n棧\n棕\n椶\n椒\n椄\n棗\n棣\n椥\n棹\n棠\n棯\n椨\n椪\n椚\n椣\n椡\n棆\n楹\n楷\n楜\n楸\n楫\n楔\n楾\n楮\n椹\n楴\n椽\n楙\n椰\n楡\n楞\n楝\n榁\n楪\n榲\n榮\n槐\n榿\n槁\n槓\n榾\n槎\n寨\n槊\n槝\n榻\n槃\n榧\n樮\n榑\n榠\n榜\n榕\n榴\n槞\n槨\n樂\n樛\n槿\n權\n槹\n槲\n槧\n樅\n榱\n樞\n槭\n樔\n槫\n樊\n樒\n櫁\n樣\n樓\n橄\n樌\n橲\n樶\n橸\n橇\n橢\n橙\n橦\n橈\n樸\n樢\n檐\n檍\n檠\n檄\n檢\n檣\n檗\n蘗\n檻\n櫃\n櫂\n檸\n檳\n檬\n櫞\n櫑\n櫟\n檪\n櫚\n櫪\n櫻\n欅\n蘖\n櫺\n欒\n欖\n鬱\n欟\n欸\n欷\n盜\n欹\n飮\n歇\n歃\n歉\n歐\n歙\n歔\n歛\n歟\n歡\n歸\n歹\n歿\n殀\n殄\n殃\n殍\n殘\n殕\n殞\n殤\n殪\n殫\n殯\n殲\n殱\n殳\n殷\n殼\n毆\n毋\n毓\n毟\n毬\n毫\n毳\n毯\n麾\n氈\n氓\n气\n氛\n氤\n氣\n汞\n汕\n汢\n汪\n沂\n沍\n沚\n沁\n沛\n汾\n汨\n汳\n沒\n沐\n泄\n泱\n泓\n沽\n泗\n泅\n泝\n沮\n沱\n沾\n沺\n泛\n泯\n泙\n泪\n洟\n衍\n洶\n洫\n洽\n洸\n洙\n洵\n洳\n洒\n洌\n浣\n涓\n浤\n浚\n浹\n浙\n涎\n涕\n濤\n涅\n淹\n渕\n渊\n涵\n淇\n淦\n涸\n淆\n淬\n淞\n淌\n淨\n淒\n淅\n淺\n淙\n淤\n淕\n淪\n淮\n渭\n湮\n渮\n渙\n湲\n湟\n渾\n渣\n湫\n渫\n湶\n湍\n渟\n湃\n渺\n湎\n渤\n滿\n渝\n游\n溂\n溪\n溘\n滉\n溷\n滓\n溽\n溯\n滄\n溲\n滔\n滕\n溏\n溥\n滂\n溟\n潁\n漑\n灌\n滬\n滸\n滾\n漿\n滲\n漱\n滯\n漲\n滌\n漾\n漓\n滷\n澆\n潺\n潸\n澁\n澀\n潯\n潛\n濳\n潭\n澂\n潼\n潘\n澎\n澑\n濂\n潦\n澳\n澣\n澡\n澤\n澹\n濆\n澪\n濟\n濕\n濬\n濔\n濘\n濱\n濮\n濛\n瀉\n瀋\n濺\n瀑\n瀁\n瀏\n濾\n瀛\n瀚\n潴\n瀝\n瀘\n瀟\n瀰\n瀾\n瀲\n灑\n灣\n炙\n炒\n炯\n烱\n炬\n炸\n炳\n炮\n烟\n烋\n烝\n烙\n焉\n烽\n焜\n焙\n煥\n煕\n熈\n煦\n煢\n煌\n煖\n煬\n熏\n燻\n熄\n熕\n熨\n熬\n燗\n熹\n熾\n燒\n燉\n燔\n燎\n燠\n燬\n燧\n燵\n燼\n燹\n燿\n爍\n爐\n爛\n爨\n爭\n爬\n爰\n爲\n爻\n爼\n爿\n牀\n牆\n牋\n牘\n牴\n牾\n犂\n犁\n犇\n犒\n犖\n犢\n犧\n犹\n犲\n狃\n狆\n狄\n狎\n狒\n狢\n狠\n狡\n狹\n狷\n倏\n猗\n猊\n猜\n猖\n猝\n猴\n猯\n猩\n猥\n猾\n獎\n獏\n默\n獗\n獪\n獨\n獰\n獸\n獵\n獻\n獺\n珈\n玳\n珎\n玻\n珀\n珥\n珮\n珞\n璢\n琅\n瑯\n琥\n珸\n琲\n琺\n瑕\n琿\n瑟\n瑙\n瑁\n瑜\n瑩\n瑰\n瑣\n瑪\n瑶\n瑾\n璋\n璞\n璧\n瓊\n瓏\n瓔\n珱\n瓠\n瓣\n瓧\n瓩\n瓮\n瓲\n瓰\n瓱\n瓸\n瓷\n甄\n甃\n甅\n甌\n甎\n甍\n甕\n甓\n甞\n甦\n甬\n甼\n畄\n畍\n畊\n畉\n畛\n畆\n畚\n畩\n畤\n畧\n畫\n畭\n畸\n當\n疆\n疇\n畴\n疊\n疉\n疂\n疔\n疚\n疝\n疥\n疣\n痂\n疳\n痃\n疵\n疽\n疸\n疼\n疱\n痍\n痊\n痒\n痙\n痣\n痞\n痾\n痿\n痼\n瘁\n痰\n痺\n痲\n痳\n瘋\n瘍\n瘉\n瘟\n瘧\n瘠\n瘡\n瘢\n瘤\n瘴\n瘰\n瘻\n癇\n癈\n癆\n癜\n癘\n癡\n癢\n癨\n癩\n癪\n癧\n癬\n癰\n癲\n癶\n癸\n發\n皀\n皃\n皈\n皋\n皎\n皖\n皓\n皙\n皚\n皰\n皴\n皸\n皹\n皺\n盂\n盍\n盖\n盒\n盞\n盡\n盥\n盧\n盪\n蘯\n盻\n眈\n眇\n眄\n眩\n眤\n眞\n眥\n眦\n眛\n眷\n眸\n睇\n睚\n睨\n睫\n睛\n睥\n睿\n睾\n睹\n瞎\n瞋\n瞑\n瞠\n瞞\n瞰\n瞶\n瞹\n瞿\n瞼\n瞽\n瞻\n矇\n矍\n矗\n矚\n矜\n矣\n矮\n矼\n砌\n砒\n礦\n砠\n礪\n硅\n碎\n硴\n碆\n硼\n碚\n碌\n碣\n碵\n碪\n碯\n磑\n磆\n磋\n磔\n碾\n碼\n磅\n磊\n磬\n磧\n磚\n磽\n磴\n礇\n礒\n礑\n礙\n礬\n礫\n祀\n祠\n祗\n祟\n祚\n祕\n祓\n祺\n祿\n禊\n禝\n禧\n齋\n禪\n禮\n禳\n禹\n禺\n秉\n秕\n秧\n秬\n秡\n秣\n稈\n稍\n稘\n稙\n稠\n稟\n禀\n稱\n稻\n稾\n稷\n穃\n穗\n穉\n穡\n穢\n穩\n龝\n穰\n穹\n穽\n窈\n窗\n窕\n窘\n窖\n窩\n竈\n窰\n窶\n竅\n竄\n窿\n邃\n竇\n竊\n竍\n竏\n竕\n竓\n站\n竚\n竝\n竡\n竢\n竦\n竭\n竰\n笂\n笏\n笊\n笆\n笳\n笘\n笙\n笞\n笵\n笨\n笶\n筐\n筺\n笄\n筍\n笋\n筌\n筅\n筵\n筥\n筴\n筧\n筰\n筱\n筬\n筮\n箝\n箘\n箟\n箍\n箜\n箚\n箋\n箒\n箏\n筝\n箙\n篋\n篁\n篌\n篏\n箴\n篆\n篝\n篩\n簑\n簔\n篦\n篥\n籠\n簀\n簇\n簓\n篳\n篷\n簗\n簍\n篶\n簣\n簧\n簪\n簟\n簷\n簫\n簽\n籌\n籃\n籔\n籏\n籀\n籐\n籘\n籟\n籤\n籖\n籥\n籬\n籵\n粃\n粐\n粤\n粭\n粢\n粫\n粡\n粨\n粳\n粲\n粱\n粮\n粹\n粽\n糀\n糅\n糂\n糘\n糒\n糜\n糢\n鬻\n糯\n糲\n糴\n糶\n糺\n紆\n紂\n紜\n紕\n紊\n絅\n絋\n紮\n紲\n紿\n紵\n絆\n絳\n絖\n絎\n絲\n絨\n絮\n絏\n絣\n經\n綉\n絛\n綏\n絽\n綛\n綺\n綮\n綣\n綵\n緇\n綽\n綫\n總\n綢\n綯\n緜\n綸\n綟\n綰\n緘\n緝\n緤\n緞\n緻\n緲\n緡\n縅\n縊\n縣\n縡\n縒\n縱\n縟\n縉\n縋\n縢\n繆\n繦\n縻\n縵\n縹\n繃\n縷\n縲\n縺\n繧\n繝\n繖\n繞\n繙\n繚\n繹\n繪\n繩\n繼\n繻\n纃\n緕\n繽\n辮\n繿\n纈\n纉\n續\n纒\n纐\n纓\n纔\n纖\n纎\n纛\n纜\n缸\n缺\n罅\n罌\n罍\n罎\n罐\n网\n罕\n罔\n罘\n罟\n罠\n罨\n罩\n罧\n罸\n羂\n羆\n羃\n羈\n羇\n羌\n羔\n羞\n羝\n羚\n羣\n羯\n羲\n羹\n羮\n羶\n羸\n譱\n翅\n翆\n翊\n翕\n翔\n翡\n翦\n翩\n翳\n翹\n飜\n耆\n耄\n耋\n耒\n耘\n耙\n耜\n耡\n耨\n耿\n耻\n聊\n聆\n聒\n聘\n聚\n聟\n聢\n聨\n聳\n聲\n聰\n聶\n聹\n聽\n聿\n肄\n肆\n肅\n肛\n肓\n肚\n肭\n冐\n肬\n胛\n胥\n胙\n胝\n胄\n胚\n胖\n脉\n胯\n胱\n脛\n脩\n脣\n脯\n腋\n隋\n腆\n脾\n腓\n腑\n胼\n腱\n腮\n腥\n腦\n腴\n膃\n膈\n膊\n膀\n膂\n膠\n膕\n膤\n膣\n腟\n膓\n膩\n膰\n膵\n膾\n膸\n膽\n臀\n臂\n膺\n臉\n臍\n臑\n臙\n臘\n臈\n臚\n臟\n臠\n臧\n臺\n臻\n臾\n舁\n舂\n舅\n與\n舊\n舍\n舐\n舖\n舩\n舫\n舸\n舳\n艀\n艙\n艘\n艝\n艚\n艟\n艤\n艢\n艨\n艪\n艫\n舮\n艱\n艷\n艸\n艾\n芍\n芒\n芫\n芟\n芻\n芬\n苡\n苣\n苟\n苒\n苴\n苳\n苺\n莓\n范\n苻\n苹\n苞\n茆\n苜\n茉\n苙\n茵\n茴\n茖\n茲\n茱\n荀\n茹\n荐\n荅\n茯\n茫\n茗\n茘\n莅\n莚\n莪\n莟\n莢\n莖\n茣\n莎\n莇\n莊\n荼\n莵\n荳\n荵\n莠\n莉\n莨\n菴\n萓\n菫\n菎\n菽\n萃\n菘\n萋\n菁\n菷\n萇\n菠\n菲\n萍\n萢\n萠\n莽\n萸\n蔆\n菻\n葭\n萪\n萼\n蕚\n蒄\n葷\n葫\n蒭\n葮\n蒂\n葩\n葆\n萬\n葯\n葹\n萵\n蓊\n葢\n蒹\n蒿\n蒟\n蓙\n蓍\n蒻\n蓚\n蓐\n蓁\n蓆\n蓖\n蒡\n蔡\n蓿\n蓴\n蔗\n蔘\n蔬\n蔟\n蔕\n蔔\n蓼\n蕀\n蕣\n蕘\n蕈\n蕁\n蘂\n蕋\n蕕\n薀\n薤\n薈\n薑\n薊\n薨\n蕭\n薔\n薛\n藪\n薇\n薜\n蕷\n蕾\n薐\n藉\n薺\n藏\n薹\n藐\n藕\n藝\n藥\n藜\n藹\n蘊\n蘓\n蘋\n藾\n藺\n蘆\n蘢\n蘚\n蘰\n蘿\n虍\n乕\n虔\n號\n虧\n虱\n蚓\n蚣\n蚩\n蚪\n蚋\n蚌\n蚶\n蚯\n蛄\n蛆\n蚰\n蛉\n蠣\n蚫\n蛔\n蛞\n蛩\n蛬\n蛟\n蛛\n蛯\n蜒\n蜆\n蜈\n蜀\n蜃\n蛻\n蜑\n蜉\n蜍\n蛹\n蜊\n蜴\n蜿\n蜷\n蜻\n蜥\n蜩\n蜚\n蝠\n蝟\n蝸\n蝌\n蝎\n蝴\n蝗\n蝨\n蝮\n蝙\n蝓\n蝣\n蝪\n蠅\n螢\n螟\n螂\n螯\n蟋\n螽\n蟀\n蟐\n雖\n螫\n蟄\n螳\n蟇\n蟆\n螻\n蟯\n蟲\n蟠\n蠏\n蠍\n蟾\n蟶\n蟷\n蠎\n蟒\n蠑\n蠖\n蠕\n蠢\n蠡\n蠱\n蠶\n蠹\n蠧\n蠻\n衄\n衂\n衒\n衙\n衞\n衢\n衫\n袁\n衾\n袞\n衵\n衽\n袵\n衲\n袂\n袗\n袒\n袮\n袙\n袢\n袍\n袤\n袰\n袿\n袱\n裃\n裄\n裔\n裘\n裙\n裝\n裹\n褂\n裼\n裴\n裨\n裲\n褄\n褌\n褊\n褓\n襃\n褞\n褥\n褪\n褫\n襁\n襄\n褻\n褶\n褸\n襌\n褝\n襠\n襞\n襦\n襤\n襭\n襪\n襯\n襴\n襷\n襾\n覃\n覈\n覊\n覓\n覘\n覡\n覩\n覦\n覬\n覯\n覲\n覺\n覽\n覿\n觀\n觚\n觜\n觝\n觧\n觴\n觸\n訃\n訖\n訐\n訌\n訛\n訝\n訥\n訶\n詁\n詛\n詒\n詆\n詈\n詼\n詭\n詬\n詢\n誅\n誂\n誄\n誨\n誡\n誑\n誥\n誦\n誚\n誣\n諄\n諍\n諂\n諚\n諫\n諳\n諧\n諤\n諱\n謔\n諠\n諢\n諷\n諞\n諛\n謌\n謇\n謚\n諡\n謖\n謐\n謗\n謠\n謳\n鞫\n謦\n謫\n謾\n謨\n譁\n譌\n譏\n譎\n證\n譖\n譛\n譚\n譫\n譟\n譬\n譯\n譴\n譽\n讀\n讌\n讎\n讒\n讓\n讖\n讙\n讚\n谺\n豁\n谿\n豈\n豌\n豎\n豐\n豕\n豢\n豬\n豸\n豺\n貂\n貉\n貅\n貊\n貍\n貎\n貔\n豼\n貘\n戝\n貭\n貪\n貽\n貲\n貳\n貮\n貶\n賈\n賁\n賤\n賣\n賚\n賽\n賺\n賻\n贄\n贅\n贊\n贇\n贏\n贍\n贐\n齎\n贓\n賍\n贔\n贖\n赧\n赭\n赱\n赳\n趁\n趙\n跂\n趾\n趺\n跏\n跚\n跖\n跌\n跛\n跋\n跪\n跫\n跟\n跣\n跼\n踈\n踉\n跿\n踝\n踞\n踐\n踟\n蹂\n踵\n踰\n踴\n蹊\n蹇\n蹉\n蹌\n蹐\n蹈\n蹙\n蹤\n蹠\n踪\n蹣\n蹕\n蹶\n蹲\n蹼\n躁\n躇\n躅\n躄\n躋\n躊\n躓\n躑\n躔\n躙\n躪\n躡\n躬\n躰\n軆\n躱\n躾\n軅\n軈\n軋\n軛\n軣\n軼\n軻\n軫\n軾\n輊\n輅\n輕\n輒\n輙\n輓\n輜\n輟\n輛\n輌\n輦\n輳\n輻\n輹\n轅\n轂\n輾\n轌\n轉\n轆\n轎\n轗\n轜\n轢\n轣\n轤\n辜\n辟\n辣\n辭\n辯\n辷\n迚\n迥\n迢\n迪\n迯\n邇\n迴\n逅\n迹\n迺\n逑\n逕\n逡\n逍\n逞\n逖\n逋\n逧\n逶\n逵\n逹\n迸\n遏\n遐\n遑\n遒\n逎\n遉\n逾\n遖\n遘\n遞\n遨\n遯\n遶\n隨\n遲\n邂\n遽\n邁\n邀\n邊\n邉\n邏\n邨\n邯\n邱\n邵\n郢\n郤\n扈\n郛\n鄂\n鄒\n鄙\n鄲\n鄰\n酊\n酖\n酘\n酣\n酥\n酩\n酳\n酲\n醋\n醉\n醂\n醢\n醫\n醯\n醪\n醵\n醴\n醺\n釀\n釁\n釉\n釋\n釐\n釖\n釟\n釡\n釛\n釼\n釵\n釶\n鈞\n釿\n鈔\n鈬\n鈕\n鈑\n鉞\n鉗\n鉅\n鉉\n鉤\n鉈\n銕\n鈿\n鉋\n鉐\n銜\n銖\n銓\n銛\n鉚\n鋏\n銹\n銷\n鋩\n錏\n鋺\n鍄\n錮\n錙\n錢\n錚\n錣\n錺\n錵\n錻\n鍜\n鍠\n鍼\n鍮\n鍖\n鎰\n鎬\n鎭\n鎔\n鎹\n鏖\n鏗\n鏨\n鏥\n鏘\n鏃\n鏝\n鏐\n鏈\n鏤\n鐚\n鐔\n鐓\n鐃\n鐇\n鐐\n鐶\n鐫\n鐵\n鐡\n鐺\n鑁\n鑒\n鑄\n鑛\n鑠\n鑢\n鑞\n鑪\n鈩\n鑰\n鑵\n鑷\n鑽\n鑚\n鑼\n鑾\n钁\n鑿\n閂\n閇\n閊\n閔\n閖\n閘\n閙\n閠\n閨\n閧\n閭\n閼\n閻\n閹\n閾\n闊\n濶\n闃\n闍\n闌\n闕\n闔\n闖\n關\n闡\n闥\n闢\n阡\n阨\n阮\n阯\n陂\n陌\n陏\n陋\n陷\n陜\n陞\n陝\n陟\n陦\n陲\n陬\n隍\n隘\n隕\n隗\n險\n隧\n隱\n隲\n隰\n隴\n隶\n隸\n隹\n雎\n雋\n雉\n雍\n襍\n雜\n霍\n雕\n雹\n霄\n霆\n霈\n霓\n霎\n霑\n霏\n霖\n霙\n霤\n霪\n霰\n霹\n霽\n霾\n靄\n靆\n靈\n靂\n靉\n靜\n靠\n靤\n靦\n靨\n勒\n靫\n靱\n靹\n鞅\n靼\n鞁\n靺\n鞆\n鞋\n鞏\n鞐\n鞜\n鞨\n鞦\n鞣\n鞳\n鞴\n韃\n韆\n韈\n韋\n韜\n韭\n齏\n韲\n竟\n韶\n韵\n頏\n頌\n頸\n頤\n頡\n頷\n頽\n顆\n顏\n顋\n顫\n顯\n顰\n顱\n顴\n顳\n颪\n颯\n颱\n颶\n飄\n飃\n飆\n飩\n飫\n餃\n餉\n餒\n餔\n餘\n餡\n餝\n餞\n餤\n餠\n餬\n餮\n餽\n餾\n饂\n饉\n饅\n饐\n饋\n饑\n饒\n饌\n饕\n馗\n馘\n馥\n馭\n馮\n馼\n駟\n駛\n駝\n駘\n駑\n駭\n駮\n駱\n駲\n駻\n駸\n騁\n騏\n騅\n駢\n騙\n騫\n騷\n驅\n驂\n驀\n驃\n騾\n驕\n驍\n驛\n驗\n驟\n驢\n驥\n驤\n驩\n驫\n驪\n骭\n骰\n骼\n髀\n髏\n髑\n髓\n體\n髞\n髟\n髢\n髣\n髦\n髯\n髫\n髮\n髴\n髱\n髷\n髻\n鬆\n鬘\n鬚\n鬟\n鬢\n鬣\n鬥\n鬧\n鬨\n鬩\n鬪\n鬮\n鬯\n鬲\n魄\n魃\n魏\n魍\n魎\n魑\n魘\n魴\n鮓\n鮃\n鮑\n鮖\n鮗\n鮟\n鮠\n鮨\n鮴\n鯀\n鯊\n鮹\n鯆\n鯏\n鯑\n鯒\n鯣\n鯢\n鯤\n鯔\n鯡\n鰺\n鯲\n鯱\n鯰\n鰕\n鰔\n鰉\n鰓\n鰌\n鰆\n鰈\n鰒\n鰊\n鰄\n鰮\n鰛\n鰥\n鰤\n鰡\n鰰\n鱇\n鰲\n鱆\n鰾\n鱚\n鱠\n鱧\n鱶\n鱸\n鳧\n鳬\n鳰\n鴉\n鴈\n鳫\n鴃\n鴆\n鴪\n鴦\n鶯\n鴣\n鴟\n鵄\n鴕\n鴒\n鵁\n鴿\n鴾\n鵆\n鵈\n鵝\n鵞\n鵤\n鵑\n鵐\n鵙\n鵲\n鶉\n鶇\n鶫\n鵯\n鵺\n鶚\n鶤\n鶩\n鶲\n鷄\n鷁\n鶻\n鶸\n鶺\n鷆\n鷏\n鷂\n鷙\n鷓\n鷸\n鷦\n鷭\n鷯\n鷽\n鸚\n鸛\n鸞\n鹵\n鹹\n鹽\n麁\n麈\n麋\n麌\n麒\n麕\n麑\n麝\n麥\n麩\n麸\n麪\n麭\n靡\n黌\n黎\n黏\n黐\n黔\n黜\n點\n黝\n黠\n黥\n黨\n黯\n黴\n黶\n黷\n黹\n黻\n黼\n黽\n鼇\n鼈\n皷\n鼕\n鼡\n鼬\n鼾\n齊\n齒\n齔\n齣\n齟\n齠\n齡\n齦\n齧\n齬\n齪\n齷\n齲\n齶\n龕\n龜\n龠\n堯\n槇\n遙\n瑤\n凜\n熙\n纊\n褜\n鍈\n銈\n蓜\n俉\n炻\n昱\n棈\n鋹\n曻\n彅\n丨\n仡\n仼\n伀\n伃\n伹\n佖\n侒\n侊\n侚\n侔\n俍\n偀\n倢\n俿\n倞\n偆\n偰\n偂\n傔\n僴\n僘\n兊\n兤\n冝\n冾\n凬\n刕\n劜\n劦\n勀\n勛\n匀\n匇\n匤\n卲\n厓\n厲\n叝\n﨎\n咜\n咊\n咩\n哿\n喆\n坙\n坥\n垬\n埈\n埇\n﨏\n塚\n增\n墲\n夋\n奓\n奛\n奝\n奣\n妤\n妺\n孖\n寀\n甯\n寘\n寬\n尞\n岦\n岺\n峵\n崧\n嵓\n﨑\n嵂\n嵭\n嶸\n嶹\n巐\n弡\n弴\n彧\n德\n忞\n恝\n悅\n悊\n惞\n惕\n愠\n惲\n愑\n愷\n愰\n憘\n戓\n抦\n揵\n摠\n撝\n擎\n敎\n昀\n昕\n昻\n昉\n昮\n昞\n昤\n晥\n晗\n晙\n晴\n晳\n暙\n暠\n暲\n暿\n曺\n朎\n朗\n杦\n枻\n桒\n柀\n栁\n桄\n棏\n﨓\n楨\n﨔\n榘\n槢\n樰\n橫\n橆\n橳\n橾\n櫢\n櫤\n毖\n氿\n汜\n沆\n汯\n泚\n洄\n涇\n浯\n涖\n涬\n淏\n淸\n淲\n淼\n渹\n湜\n渧\n渼\n溿\n澈\n澵\n濵\n瀅\n瀇\n瀨\n炅\n炫\n焏\n焄\n煜\n煆\n煇\n凞\n燁\n燾\n犱\n犾\n猤\n猪\n獷\n玽\n珉\n珖\n珣\n珒\n琇\n珵\n琦\n琪\n琩\n琮\n瑢\n璉\n璟\n甁\n畯\n皂\n皜\n皞\n皛\n皦\n益\n睆\n劯\n砡\n硎\n硤\n硺\n礰\n礼\n神\n祥\n禔\n福\n禛\n竑\n竧\n靖\n竫\n箞\n精\n絈\n絜\n綷\n綠\n緖\n繒\n罇\n羡\n羽\n茁\n荢\n荿\n菇\n菶\n葈\n蒴\n蕓\n蕙\n蕫\n﨟\n薰\n蘒\n﨡\n蠇\n裵\n訒\n訷\n詹\n誧\n誾\n諟\n諸\n諶\n譓\n譿\n賰\n賴\n贒\n赶\n﨣\n軏\n﨤\n逸\n遧\n郞\n都\n鄕\n鄧\n釚\n釗\n釞\n釭\n釮\n釤\n釥\n鈆\n鈐\n鈊\n鈺\n鉀\n鈼\n鉎\n鉙\n鉑\n鈹\n鉧\n銧\n鉷\n鉸\n鋧\n鋗\n鋙\n鋐\n﨧\n鋕\n鋠\n鋓\n錥\n錡\n鋻\n﨨\n錞\n鋿\n錝\n錂\n鍰\n鍗\n鎤\n鏆\n鏞\n鏸\n鐱\n鑅\n鑈\n閒\n隆\n﨩\n隝\n隯\n霳\n霻\n靃\n靍\n靏\n靑\n靕\n顗\n顥\n飯\n飼\n餧\n館\n馞\n驎\n髙\n髜\n魵\n魲\n鮏\n鮱\n鮻\n鰀\n鵰\n鵫\n鶴\n鸙\n黑\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\n￢\n￤\n＇\n＂\n"
  },
  {
    "path": "helix-view/tests/encoding/jis0208_out_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n¡\n¢\n£\n¤\n¥\n¦\n§\n¨\n©\nª\n«\n¬\n­\n®\n¯\n°\n±\n²\n³\n´\nµ\n¶\n·\n¸\n¹\nº\n»\n¼\n½\n¾\n¿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ná\nâ\nã\nä\nå\næ\nç\nè\né\nê\në\nì\ní\nî\nï\nð\nñ\nò\nó\nô\nõ\nö\n÷\nø\nù\nú\nû\nü\ný\nþ\nÿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nġ\nĢ\nģ\nĤ\nĥ\nĦ\nħ\nĨ\nĩ\nĪ\nī\nĬ\nĭ\nĮ\nį\nİ\nı\nĲ\nĳ\nĴ\nĵ\nĶ\nķ\nĸ\nĹ\nĺ\nĻ\nļ\nĽ\nľ\nĿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nš\nŢ\nţ\nŤ\nť\nŦ\nŧ\nŨ\nũ\nŪ\nū\nŬ\nŭ\nŮ\nů\nŰ\nű\nŲ\nų\nŴ\nŵ\nŶ\nŷ\nŸ\nŹ\nź\nŻ\nż\nŽ\nž\nſ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nơ\nƢ\nƣ\nƤ\nƥ\nƦ\nƧ\nƨ\nƩ\nƪ\nƫ\nƬ\nƭ\nƮ\nƯ\nư\nƱ\nƲ\nƳ\nƴ\nƵ\nƶ\nƷ\nƸ\nƹ\nƺ\nƻ\nƼ\nƽ\nƾ\nƿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nǡ\nǢ\nǣ\nǤ\nǥ\nǦ\nǧ\nǨ\nǩ\nǪ\nǫ\nǬ\nǭ\nǮ\nǯ\nǰ\nǱ\nǲ\nǳ\nǴ\nǵ\nǶ\nǷ\nǸ\nǹ\nǺ\nǻ\nǼ\nǽ\nǾ\nǿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nȡ\nȢ\nȣ\nȤ\nȥ\nȦ\nȧ\nȨ\nȩ\nȪ\nȫ\nȬ\nȭ\nȮ\nȯ\nȰ\nȱ\nȲ\nȳ\nȴ\nȵ\nȶ\nȷ\nȸ\nȹ\nȺ\nȻ\nȼ\nȽ\nȾ\nȿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nɡ\nɢ\nɣ\nɤ\nɥ\nɦ\nɧ\nɨ\nɩ\nɪ\nɫ\nɬ\nɭ\nɮ\nɯ\nɰ\nɱ\nɲ\nɳ\nɴ\nɵ\nɶ\nɷ\nɸ\nɹ\nɺ\nɻ\nɼ\nɽ\nɾ\nɿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nʡ\nʢ\nʣ\nʤ\nʥ\nʦ\nʧ\nʨ\nʩ\nʪ\nʫ\nʬ\nʭ\nʮ\nʯ\nʰ\nʱ\nʲ\nʳ\nʴ\nʵ\nʶ\nʷ\nʸ\nʹ\nʺ\nʻ\nʼ\nʽ\nʾ\nʿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nˡ\nˢ\nˣ\nˤ\n˥\n˦\n˧\n˨\n˩\n˪\n˫\nˬ\n˭\nˮ\n˯\n˰\n˱\n˲\n˳\n˴\n˵\n˶\n˷\n˸\n˹\n˺\n˻\n˼\n˽\n˾\n˿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n̡\n̢\ṇ\n̤\n̥\n̦\ņ\n̨\n̩\n̪\n̫\n̬\ṋ\n̮\n̯\n̰\ṉ\n̲\n̳\n̴\n̵\n̶\n̷\n̸\n̹\n̺\n̻\n̼\n̽\n̾\n̿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n͡\n͢\nͣ\nͤ\nͥ\nͦ\nͧ\nͨ\nͩ\nͪ\nͫ\nͬ\nͭ\nͮ\nͯ\nͰ\nͱ\nͲ\nͳ\nʹ\n͵\nͶ\nͷ\n͸\n͹\nͺ\nͻ\nͼ\nͽ\n;\nͿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nΡ\n΢\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nΪ\nΫ\nά\nέ\nή\nί\nΰ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nϡ\nϢ\nϣ\nϤ\nϥ\nϦ\nϧ\nϨ\nϩ\nϪ\nϫ\nϬ\nϭ\nϮ\nϯ\nϰ\nϱ\nϲ\nϳ\nϴ\nϵ\n϶\nϷ\nϸ\nϹ\nϺ\nϻ\nϼ\nϽ\nϾ\nϿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nѡ\nѢ\nѣ\nѤ\nѥ\nѦ\nѧ\nѨ\nѩ\nѪ\nѫ\nѬ\nѭ\nѮ\nѯ\nѰ\nѱ\nѲ\nѳ\nѴ\nѵ\nѶ\nѷ\nѸ\nѹ\nѺ\nѻ\nѼ\nѽ\nѾ\nѿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nҡ\nҢ\nң\nҤ\nҥ\nҦ\nҧ\nҨ\nҩ\nҪ\nҫ\nҬ\nҭ\nҮ\nү\nҰ\nұ\nҲ\nҳ\nҴ\nҵ\nҶ\nҷ\nҸ\nҹ\nҺ\nһ\nҼ\nҽ\nҾ\nҿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nӡ\nӢ\nӣ\nӤ\nӥ\nӦ\nӧ\nӨ\nө\nӪ\nӫ\nӬ\nӭ\nӮ\nӯ\nӰ\nӱ\nӲ\nӳ\nӴ\nӵ\nӶ\nӷ\nӸ\nӹ\nӺ\nӻ\nӼ\nӽ\nӾ\nӿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nԡ\nԢ\nԣ\nԤ\nԥ\nԦ\nԧ\nԨ\nԩ\nԪ\nԫ\nԬ\nԭ\nԮ\nԯ\n԰\nԱ\nԲ\nԳ\nԴ\nԵ\nԶ\nԷ\nԸ\nԹ\nԺ\nԻ\nԼ\nԽ\nԾ\nԿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nա\nբ\nգ\nդ\nե\nզ\nէ\nը\nթ\nժ\nի\nլ\nխ\nծ\nկ\nհ\nձ\nղ\nճ\nմ\nյ\nն\nշ\nո\nչ\nպ\nջ\nռ\nս\nվ\nտ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n֡\n֢\n֣\n֤\n֥\n֦\n֧\n֨\n֩\n֪\n֫\n֬\n֭\n֮\n֯\nְ\nֱ\nֲ\nֳ\nִ\nֵ\nֶ\nַ\nָ\nֹ\nֺ\nֻ\nּ\nֽ\n־\nֿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nס\nע\nף\nפ\nץ\nצ\nק\nר\nש\nת\n׫\n׬\n׭\n׮\nׯ\nװ\nױ\nײ\n׳\n״\n׵\n׶\n׷\n׸\n׹\n׺\n׻\n׼\n׽\n׾\n׿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nء\nآ\nأ\nؤ\nإ\nئ\nا\nب\nة\nت\nث\nج\nح\nخ\nد\nذ\nر\nز\nس\nش\nص\nض\nط\nظ\nع\nغ\nػ\nؼ\nؽ\nؾ\nؿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n١\n٢\n٣\n٤\n٥\n٦\n٧\n٨\n٩\n٪\n٫\n٬\n٭\nٮ\nٯ\nٰ\nٱ\nٲ\nٳ\nٴ\nٵ\nٶ\nٷ\nٸ\nٹ\nٺ\nٻ\nټ\nٽ\nپ\nٿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nڡ\nڢ\nڣ\nڤ\nڥ\nڦ\nڧ\nڨ\nک\nڪ\nګ\nڬ\nڭ\nڮ\nگ\nڰ\nڱ\nڲ\nڳ\nڴ\nڵ\nڶ\nڷ\nڸ\nڹ\nں\nڻ\nڼ\nڽ\nھ\nڿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nۡ\nۢ\nۣ\nۤ\nۥ\nۦ\nۧ\nۨ\n۩\n۪\n۫\n۬\nۭ\nۮ\nۯ\n۰\n۱\n۲\n۳\n۴\n۵\n۶\n۷\n۸\n۹\nۺ\nۻ\nۼ\n۽\n۾\nۿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nܡ\nܢ\nܣ\nܤ\nܥ\nܦ\nܧ\nܨ\nܩ\nܪ\nܫ\nܬ\nܭ\nܮ\nܯ\nܰ\nܱ\nܲ\nܳ\nܴ\nܵ\nܶ\nܷ\nܸ\nܹ\nܺ\nܻ\nܼ\nܽ\nܾ\nܿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nݡ\nݢ\nݣ\nݤ\nݥ\nݦ\nݧ\nݨ\nݩ\nݪ\nݫ\nݬ\nݭ\nݮ\nݯ\nݰ\nݱ\nݲ\nݳ\nݴ\nݵ\nݶ\nݷ\nݸ\nݹ\nݺ\nݻ\nݼ\nݽ\nݾ\nݿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nޡ\nޢ\nޣ\nޤ\nޥ\nަ\nާ\nި\nީ\nު\nޫ\nެ\nޭ\nޮ\nޯ\nް\nޱ\n޲\n޳\n޴\n޵\n޶\n޷\n޸\n޹\n޺\n޻\n޼\n޽\n޾\n޿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nߡ\nߢ\nߣ\nߤ\nߥ\nߦ\nߧ\nߨ\nߩ\nߪ\n߫\n߬\n߭\n߮\n߯\n߰\n߱\n߲\n߳\nߴ\nߵ\n߶\n߷\n߸\n߹\nߺ\n߻\n߼\n߽\n߾\n߿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/jis0212_in.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n¡\n¢\n£\n¤\n¥\n¦\n§\n¨\n©\nª\n«\n¬\n­\n®\n¯\n°\n±\n²\n³\n´\nµ\n¶\n·\n¸\n¹\nº\n»\n¼\n½\n¾\n¿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ná\nâ\nã\nä\nå\næ\nç\nè\né\nê\në\nì\ní\nî\nï\nð\nñ\nò\nó\nô\nõ\nö\n÷\nø\nù\nú\nû\nü\ný\nþ\nÿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nġ\nĢ\nģ\nĤ\nĥ\nĦ\nħ\nĨ\nĩ\nĪ\nī\nĬ\nĭ\nĮ\nį\nİ\nı\nĲ\nĳ\nĴ\nĵ\nĶ\nķ\nĸ\nĹ\nĺ\nĻ\nļ\nĽ\nľ\nĿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nš\nŢ\nţ\nŤ\nť\nŦ\nŧ\nŨ\nũ\nŪ\nū\nŬ\nŭ\nŮ\nů\nŰ\nű\nŲ\nų\nŴ\nŵ\nŶ\nŷ\nŸ\nŹ\nź\nŻ\nż\nŽ\nž\nſ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nơ\nƢ\nƣ\nƤ\nƥ\nƦ\nƧ\nƨ\nƩ\nƪ\nƫ\nƬ\nƭ\nƮ\nƯ\nư\nƱ\nƲ\nƳ\nƴ\nƵ\nƶ\nƷ\nƸ\nƹ\nƺ\nƻ\nƼ\nƽ\nƾ\nƿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nǡ\nǢ\nǣ\nǤ\nǥ\nǦ\nǧ\nǨ\nǩ\nǪ\nǫ\nǬ\nǭ\nǮ\nǯ\nǰ\nǱ\nǲ\nǳ\nǴ\nǵ\nǶ\nǷ\nǸ\nǹ\nǺ\nǻ\nǼ\nǽ\nǾ\nǿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nȡ\nȢ\nȣ\nȤ\nȥ\nȦ\nȧ\nȨ\nȩ\nȪ\nȫ\nȬ\nȭ\nȮ\nȯ\nȰ\nȱ\nȲ\nȳ\nȴ\nȵ\nȶ\nȷ\nȸ\nȹ\nȺ\nȻ\nȼ\nȽ\nȾ\nȿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nɡ\nɢ\nɣ\nɤ\nɥ\nɦ\nɧ\nɨ\nɩ\nɪ\nɫ\nɬ\nɭ\nɮ\nɯ\nɰ\nɱ\nɲ\nɳ\nɴ\nɵ\nɶ\nɷ\nɸ\nɹ\nɺ\nɻ\nɼ\nɽ\nɾ\nɿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nʡ\nʢ\nʣ\nʤ\nʥ\nʦ\nʧ\nʨ\nʩ\nʪ\nʫ\nʬ\nʭ\nʮ\nʯ\nʰ\nʱ\nʲ\nʳ\nʴ\nʵ\nʶ\nʷ\nʸ\nʹ\nʺ\nʻ\nʼ\nʽ\nʾ\nʿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nˡ\nˢ\nˣ\nˤ\n˥\n˦\n˧\n˨\n˩\n˪\n˫\nˬ\n˭\nˮ\n˯\n˰\n˱\n˲\n˳\n˴\n˵\n˶\n˷\n˸\n˹\n˺\n˻\n˼\n˽\n˾\n˿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n̡\n̢\ṇ\n̤\n̥\n̦\ņ\n̨\n̩\n̪\n̫\n̬\ṋ\n̮\n̯\n̰\ṉ\n̲\n̳\n̴\n̵\n̶\n̷\n̸\n̹\n̺\n̻\n̼\n̽\n̾\n̿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n͡\n͢\nͣ\nͤ\nͥ\nͦ\nͧ\nͨ\nͩ\nͪ\nͫ\nͬ\nͭ\nͮ\nͯ\nͰ\nͱ\nͲ\nͳ\nʹ\n͵\nͶ\nͷ\n͸\n͹\nͺ\nͻ\nͼ\nͽ\n;\nͿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nΡ\n΢\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nΪ\nΫ\nά\nέ\nή\nί\nΰ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nϡ\nϢ\nϣ\nϤ\nϥ\nϦ\nϧ\nϨ\nϩ\nϪ\nϫ\nϬ\nϭ\nϮ\nϯ\nϰ\nϱ\nϲ\nϳ\nϴ\nϵ\n϶\nϷ\nϸ\nϹ\nϺ\nϻ\nϼ\nϽ\nϾ\nϿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nѡ\nѢ\nѣ\nѤ\nѥ\nѦ\nѧ\nѨ\nѩ\nѪ\nѫ\nѬ\nѭ\nѮ\nѯ\nѰ\nѱ\nѲ\nѳ\nѴ\nѵ\nѶ\nѷ\nѸ\nѹ\nѺ\nѻ\nѼ\nѽ\nѾ\nѿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nҡ\nҢ\nң\nҤ\nҥ\nҦ\nҧ\nҨ\nҩ\nҪ\nҫ\nҬ\nҭ\nҮ\nү\nҰ\nұ\nҲ\nҳ\nҴ\nҵ\nҶ\nҷ\nҸ\nҹ\nҺ\nһ\nҼ\nҽ\nҾ\nҿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nӡ\nӢ\nӣ\nӤ\nӥ\nӦ\nӧ\nӨ\nө\nӪ\nӫ\nӬ\nӭ\nӮ\nӯ\nӰ\nӱ\nӲ\nӳ\nӴ\nӵ\nӶ\nӷ\nӸ\nӹ\nӺ\nӻ\nӼ\nӽ\nӾ\nӿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nԡ\nԢ\nԣ\nԤ\nԥ\nԦ\nԧ\nԨ\nԩ\nԪ\nԫ\nԬ\nԭ\nԮ\nԯ\n԰\nԱ\nԲ\nԳ\nԴ\nԵ\nԶ\nԷ\nԸ\nԹ\nԺ\nԻ\nԼ\nԽ\nԾ\nԿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nա\nբ\nգ\nդ\nե\nզ\nէ\nը\nթ\nժ\nի\nլ\nխ\nծ\nկ\nհ\nձ\nղ\nճ\nմ\nյ\nն\nշ\nո\nչ\nպ\nջ\nռ\nս\nվ\nտ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n֡\n֢\n֣\n֤\n֥\n֦\n֧\n֨\n֩\n֪\n֫\n֬\n֭\n֮\n֯\nְ\nֱ\nֲ\nֳ\nִ\nֵ\nֶ\nַ\nָ\nֹ\nֺ\nֻ\nּ\nֽ\n־\nֿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nס\nע\nף\nפ\nץ\nצ\nק\nר\nש\nת\n׫\n׬\n׭\n׮\nׯ\nװ\nױ\nײ\n׳\n״\n׵\n׶\n׷\n׸\n׹\n׺\n׻\n׼\n׽\n׾\n׿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nء\nآ\nأ\nؤ\nإ\nئ\nا\nب\nة\nت\nث\nج\nح\nخ\nد\nذ\nر\nز\nس\nش\nص\nض\nط\nظ\nع\nغ\nػ\nؼ\nؽ\nؾ\nؿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n١\n٢\n٣\n٤\n٥\n٦\n٧\n٨\n٩\n٪\n٫\n٬\n٭\nٮ\nٯ\nٰ\nٱ\nٲ\nٳ\nٴ\nٵ\nٶ\nٷ\nٸ\nٹ\nٺ\nٻ\nټ\nٽ\nپ\nٿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nڡ\nڢ\nڣ\nڤ\nڥ\nڦ\nڧ\nڨ\nک\nڪ\nګ\nڬ\nڭ\nڮ\nگ\nڰ\nڱ\nڲ\nڳ\nڴ\nڵ\nڶ\nڷ\nڸ\nڹ\nں\nڻ\nڼ\nڽ\nھ\nڿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nۡ\nۢ\nۣ\nۤ\nۥ\nۦ\nۧ\nۨ\n۩\n۪\n۫\n۬\nۭ\nۮ\nۯ\n۰\n۱\n۲\n۳\n۴\n۵\n۶\n۷\n۸\n۹\nۺ\nۻ\nۼ\n۽\n۾\nۿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nܡ\nܢ\nܣ\nܤ\nܥ\nܦ\nܧ\nܨ\nܩ\nܪ\nܫ\nܬ\nܭ\nܮ\nܯ\nܰ\nܱ\nܲ\nܳ\nܴ\nܵ\nܶ\nܷ\nܸ\nܹ\nܺ\nܻ\nܼ\nܽ\nܾ\nܿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nݡ\nݢ\nݣ\nݤ\nݥ\nݦ\nݧ\nݨ\nݩ\nݪ\nݫ\nݬ\nݭ\nݮ\nݯ\nݰ\nݱ\nݲ\nݳ\nݴ\nݵ\nݶ\nݷ\nݸ\nݹ\nݺ\nݻ\nݼ\nݽ\nݾ\nݿ\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nޡ\nޢ\nޣ\nޤ\nޥ\nަ\nާ\nި\nީ\nު\nޫ\nެ\nޭ\nޮ\nޯ\nް\nޱ\n޲\n޳\n޴\n޵\n޶\n޷\n޸\n޹\n޺\n޻\n޼\n޽\n޾\n޿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nߡ\nߢ\nߣ\nߤ\nߥ\nߦ\nߧ\nߨ\nߩ\nߪ\n߫\n߬\n߭\n߮\n߯\n߰\n߱\n߲\n߳\nߴ\nߵ\n߶\n߷\n߸\n߹\nߺ\n߻\n߼\n߽\n߾\n߿\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/jis0212_in_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n˘\nˇ\n¸\n˙\n˝\n¯\n˛\n˚\n～\n΄\n΅\n�\n�\n�\n�\n�\n�\n�\n�\n¡\n¦\n¿\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nº\nª\n©\n®\n™\n¤\n№\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nΆ\nΈ\nΉ\nΊ\nΪ\n�\nΌ\n�\nΎ\nΫ\n�\nΏ\n�\n�\n�\n�\nά\nέ\nή\nί\nϊ\nΐ\nό\nς\nύ\nϋ\nΰ\nώ\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nЂ\nЃ\nЄ\nЅ\nІ\nЇ\nЈ\nЉ\nЊ\nЋ\nЌ\nЎ\nЏ\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nђ\nѓ\nє\nѕ\nі\nї\nј\nљ\nњ\nћ\nќ\nў\nџ\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nÆ\nĐ\n�\nĦ\n�\nĲ\n�\nŁ\nĿ\n�\nŊ\nØ\nŒ\n�\nŦ\nÞ\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\næ\nđ\nð\nħ\nı\nĳ\nĸ\nł\nŀ\nŉ\nŋ\nø\nœ\nß\nŧ\nþ\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nÁ\nÀ\nÄ\nÂ\nĂ\nǍ\nĀ\nĄ\nÅ\nÃ\nĆ\nĈ\nČ\nÇ\nĊ\nĎ\nÉ\nÈ\nË\nÊ\nĚ\nĖ\nĒ\nĘ\n�\nĜ\nĞ\nĢ\nĠ\nĤ\nÍ\nÌ\nÏ\nÎ\nǏ\nİ\nĪ\nĮ\nĨ\nĴ\nĶ\nĹ\nĽ\nĻ\nŃ\nŇ\nŅ\nÑ\nÓ\nÒ\nÖ\nÔ\nǑ\nŐ\nŌ\nÕ\nŔ\nŘ\nŖ\nŚ\nŜ\nŠ\nŞ\nŤ\nŢ\nÚ\nÙ\nÜ\nÛ\nŬ\nǓ\nŰ\nŪ\nŲ\nŮ\nŨ\nǗ\nǛ\nǙ\nǕ\nŴ\nÝ\nŸ\nŶ\nŹ\nŽ\nŻ\n�\n�\n�\n�\n�\n�\n�\ná\nà\nä\nâ\nă\nǎ\nā\ną\nå\nã\nć\nĉ\nč\nç\nċ\nď\né\nè\në\nê\ně\nė\nē\nę\nǵ\nĝ\nğ\n�\nġ\nĥ\ní\nì\nï\nî\nǐ\n�\nī\nį\nĩ\nĵ\nķ\nĺ\nľ\nļ\nń\nň\nņ\nñ\nó\nò\nö\nô\nǒ\nő\nō\nõ\nŕ\nř\nŗ\nś\nŝ\nš\nş\nť\nţ\nú\nù\nü\nû\nŭ\nǔ\nű\nū\nų\nů\nũ\nǘ\nǜ\nǚ\nǖ\nŵ\ný\nÿ\nŷ\nź\nž\nż\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n丂\n丄\n丅\n丌\n丒\n丟\n丣\n两\n丨\n丫\n丮\n丯\n丰\n丵\n乀\n乁\n乄\n乇\n乑\n乚\n乜\n乣\n乨\n乩\n乴\n乵\n乹\n乿\n亍\n亖\n亗\n亝\n亯\n亹\n仃\n仐\n仚\n仛\n仠\n仡\n仢\n仨\n仯\n仱\n仳\n仵\n份\n仾\n仿\n伀\n伂\n伃\n伈\n伋\n伌\n伒\n伕\n伖\n众\n伙\n伮\n伱\n你\n伳\n伵\n伷\n伹\n伻\n伾\n佀\n佂\n佈\n佉\n佋\n佌\n佒\n佔\n佖\n佘\n佟\n佣\n佪\n佬\n佮\n佱\n佷\n佸\n佹\n佺\n佽\n佾\n侁\n侂\n侄\n侅\n侉\n侊\n侌\n侎\n侐\n侒\n侓\n侔\n侗\n侙\n侚\n侞\n侟\n侲\n侷\n侹\n侻\n侼\n侽\n侾\n俀\n俁\n俅\n俆\n俈\n俉\n俋\n俌\n俍\n俏\n俒\n俜\n俠\n俢\n俰\n俲\n俼\n俽\n俿\n倀\n倁\n倄\n倇\n倊\n倌\n倎\n倐\n倓\n倗\n倘\n倛\n倜\n倝\n倞\n倢\n倧\n倮\n倰\n倲\n倳\n倵\n偀\n偁\n偂\n偅\n偆\n偊\n偌\n偎\n偑\n偒\n偓\n偗\n偙\n偟\n偠\n偢\n偣\n偦\n偧\n偪\n偭\n偰\n偱\n倻\n傁\n傃\n傄\n傆\n傊\n傎\n傏\n傐\n傒\n傓\n傔\n傖\n傛\n傜\n傞\n傟\n傠\n傡\n傢\n傪\n傯\n傰\n傹\n傺\n傽\n僀\n僃\n僄\n僇\n僌\n僎\n僐\n僓\n僔\n僘\n僜\n僝\n僟\n僢\n僤\n僦\n僨\n僩\n僯\n僱\n僶\n僺\n僾\n儃\n儆\n儇\n儈\n儋\n儌\n儍\n儎\n僲\n儐\n儗\n儙\n儛\n儜\n儝\n儞\n儣\n儧\n儨\n儬\n儭\n儯\n儱\n儳\n儴\n儵\n儸\n儹\n兂\n兊\n兏\n兓\n兕\n兗\n兘\n兟\n兤\n兦\n兾\n冃\n冄\n冋\n冎\n冘\n冝\n冡\n冣\n冭\n冸\n冺\n冼\n冾\n冿\n凂\n凈\n减\n凑\n凒\n凓\n凕\n凘\n凞\n凢\n凥\n凮\n凲\n凳\n凴\n凷\n刁\n刂\n刅\n划\n刓\n刕\n刖\n刘\n刢\n刨\n刱\n刲\n刵\n刼\n剅\n剉\n剕\n剗\n剘\n剚\n剜\n剟\n剠\n剡\n剦\n剮\n剷\n剸\n剹\n劀\n劂\n劅\n劊\n劌\n劓\n劕\n劖\n劗\n劘\n劚\n劜\n劤\n劥\n劦\n劧\n劯\n劰\n劶\n劷\n劸\n劺\n劻\n劽\n勀\n勄\n勆\n勈\n勌\n勏\n勑\n勔\n勖\n勛\n勜\n勡\n勥\n勨\n勩\n勪\n勬\n勰\n勱\n勴\n勶\n勷\n匀\n匃\n匊\n匋\n匌\n匑\n匓\n匘\n匛\n匜\n匞\n匟\n匥\n匧\n匨\n匩\n匫\n匬\n匭\n匰\n匲\n匵\n匼\n匽\n匾\n卂\n卌\n卋\n卙\n卛\n卡\n卣\n卥\n卬\n卭\n卲\n卹\n卾\n厃\n厇\n厈\n厎\n厓\n厔\n厙\n厝\n厡\n厤\n厪\n厫\n厯\n厲\n厴\n厵\n厷\n厸\n厺\n厽\n叀\n叅\n叏\n叒\n叓\n叕\n叚\n叝\n叞\n叠\n另\n叧\n叵\n吂\n吓\n吚\n吡\n吧\n吨\n吪\n启\n吱\n吴\n吵\n呃\n呄\n呇\n呍\n呏\n呞\n呢\n呤\n呦\n呧\n呩\n呫\n呭\n呮\n呴\n呿\n咁\n咃\n咅\n咈\n咉\n咍\n咑\n咕\n咖\n咜\n咟\n咡\n咦\n咧\n咩\n咪\n咭\n咮\n咱\n咷\n咹\n咺\n咻\n咿\n哆\n哊\n响\n哎\n哠\n哪\n哬\n哯\n哶\n哼\n哾\n哿\n唀\n唁\n唅\n唈\n唉\n唌\n唍\n唎\n唕\n唪\n唫\n唲\n唵\n唶\n唻\n唼\n唽\n啁\n啇\n啉\n啊\n啍\n啐\n啑\n啘\n啚\n啛\n啞\n啠\n啡\n啤\n啦\n啿\n喁\n喂\n喆\n喈\n喎\n喏\n喑\n喒\n喓\n喔\n喗\n喣\n喤\n喭\n喲\n喿\n嗁\n嗃\n嗆\n嗉\n嗋\n嗌\n嗎\n嗑\n嗒\n嗓\n嗗\n嗘\n嗛\n嗞\n嗢\n嗩\n嗶\n嗿\n嘅\n嘈\n嘊\n嘍\n嘎\n嘏\n嘐\n嘑\n嘒\n嘙\n嘬\n嘰\n嘳\n嘵\n嘷\n嘹\n嘻\n嘼\n嘽\n嘿\n噀\n噁\n噃\n噄\n噆\n噉\n噋\n噍\n噏\n噔\n噞\n噠\n噡\n噢\n噣\n噦\n噩\n噭\n噯\n噱\n噲\n噵\n嚄\n嚅\n嚈\n嚋\n嚌\n嚕\n嚙\n嚚\n嚝\n嚞\n嚟\n嚦\n嚧\n嚨\n嚩\n嚫\n嚬\n嚭\n嚱\n嚳\n嚷\n嚾\n囅\n囉\n囊\n囋\n囏\n囐\n囌\n囍\n囙\n囜\n囝\n囟\n囡\n囤\n囥\n囦\n囧\n囨\n囱\n囫\n园\n囶\n囷\n圁\n圂\n圇\n圊\n圌\n圑\n圕\n圚\n圛\n圝\n圠\n圢\n圣\n圤\n圥\n圩\n圪\n圬\n圮\n圯\n圳\n圴\n圽\n圾\n圿\n坅\n坆\n坌\n坍\n坒\n坢\n坥\n坧\n坨\n坫\n坭\n坮\n坯\n坰\n坱\n坳\n坴\n坵\n坷\n坹\n坺\n坻\n坼\n坾\n垁\n垃\n垌\n垔\n垗\n垙\n垚\n垜\n垝\n垞\n垟\n垡\n垕\n垧\n垨\n垩\n垬\n垸\n垽\n埇\n埈\n埌\n埏\n埕\n埝\n埞\n埤\n埦\n埧\n埩\n埭\n埰\n埵\n埶\n埸\n埽\n埾\n埿\n堃\n堄\n堈\n堉\n埡\n堌\n堍\n堛\n堞\n堟\n堠\n堦\n堧\n堭\n堲\n堹\n堿\n塉\n塌\n塍\n塏\n塐\n塕\n塟\n塡\n塤\n塧\n塨\n塸\n塼\n塿\n墀\n墁\n墇\n墈\n墉\n墊\n墌\n墍\n墏\n墐\n墔\n墖\n墝\n墠\n墡\n墢\n墦\n墩\n墱\n墲\n壄\n墼\n壂\n壈\n壍\n壎\n壐\n壒\n壔\n壖\n壚\n壝\n壡\n壢\n壩\n壳\n夅\n夆\n夋\n夌\n夒\n夓\n夔\n虁\n夝\n夡\n夣\n夤\n夨\n夯\n夰\n夳\n夵\n夶\n夿\n奃\n奆\n奒\n奓\n奙\n奛\n奝\n奞\n奟\n奡\n奣\n奫\n奭\n奯\n奲\n奵\n奶\n她\n奻\n奼\n妋\n妌\n妎\n妒\n妕\n妗\n妟\n妤\n妧\n妭\n妮\n妯\n妰\n妳\n妷\n妺\n妼\n姁\n姃\n姄\n姈\n姊\n姍\n姒\n姝\n姞\n姟\n姣\n姤\n姧\n姮\n姯\n姱\n姲\n姴\n姷\n娀\n娄\n娌\n娍\n娎\n娒\n娓\n娞\n娣\n娤\n娧\n娨\n娪\n娭\n娰\n婄\n婅\n婇\n婈\n婌\n婐\n婕\n婞\n婣\n婥\n婧\n婭\n婷\n婺\n婻\n婾\n媋\n媐\n媓\n媖\n媙\n媜\n媞\n媟\n媠\n媢\n媧\n媬\n媱\n媲\n媳\n媵\n媸\n媺\n媻\n媿\n嫄\n嫆\n嫈\n嫏\n嫚\n嫜\n嫠\n嫥\n嫪\n嫮\n嫵\n嫶\n嫽\n嬀\n嬁\n嬈\n嬗\n嬴\n嬙\n嬛\n嬝\n嬡\n嬥\n嬭\n嬸\n孁\n孋\n孌\n孒\n孖\n孞\n孨\n孮\n孯\n孼\n孽\n孾\n孿\n宁\n宄\n宆\n宊\n宎\n宐\n宑\n宓\n宔\n宖\n宨\n宩\n宬\n宭\n宯\n宱\n宲\n宷\n宺\n宼\n寀\n寁\n寍\n寏\n寖\n寗\n寘\n寙\n寚\n寠\n寯\n寱\n寴\n寽\n尌\n尗\n尞\n尟\n尣\n尦\n尩\n尫\n尬\n尮\n尰\n尲\n尵\n尶\n屙\n屚\n屜\n屢\n屣\n屧\n屨\n屩\n屭\n屰\n屴\n屵\n屺\n屻\n屼\n屽\n岇\n岈\n岊\n岏\n岒\n岝\n岟\n岠\n岢\n岣\n岦\n岪\n岲\n岴\n岵\n岺\n峉\n峋\n峒\n峝\n峗\n峮\n峱\n峲\n峴\n崁\n崆\n崍\n崒\n崫\n崣\n崤\n崦\n崧\n崱\n崴\n崹\n崽\n崿\n嵂\n嵃\n嵆\n嵈\n嵕\n嵑\n嵙\n嵊\n嵟\n嵠\n嵡\n嵢\n嵤\n嵪\n嵭\n嵰\n嵹\n嵺\n嵾\n嵿\n嶁\n嶃\n嶈\n嶊\n嶒\n嶓\n嶔\n嶕\n嶙\n嶛\n嶟\n嶠\n嶧\n嶫\n嶰\n嶴\n嶸\n嶹\n巃\n巇\n巋\n巐\n巎\n巘\n巙\n巠\n巤\n巩\n巸\n巹\n帀\n帇\n帍\n帒\n帔\n帕\n帘\n帟\n帠\n帮\n帨\n帲\n帵\n帾\n幋\n幐\n幉\n幑\n幖\n幘\n幛\n幜\n幞\n幨\n幪\n幫\n幬\n幭\n幮\n幰\n庀\n庋\n庎\n庢\n庤\n庥\n庨\n庪\n庬\n庱\n庳\n庽\n庾\n庿\n廆\n廌\n廋\n廎\n廑\n廒\n廔\n廕\n廜\n廞\n廥\n廫\n异\n弆\n弇\n弈\n弎\n弙\n弜\n弝\n弡\n弢\n弣\n弤\n弨\n弫\n弬\n弮\n弰\n弴\n弶\n弻\n弽\n弿\n彀\n彄\n彅\n彇\n彍\n彐\n彔\n彘\n彛\n彠\n彣\n彤\n彧\n彯\n彲\n彴\n彵\n彸\n彺\n彽\n彾\n徉\n徍\n徏\n徖\n徜\n徝\n徢\n徧\n徫\n徤\n徬\n徯\n徰\n徱\n徸\n忄\n忇\n忈\n忉\n忋\n忐\n忑\n忒\n忓\n忔\n忞\n忡\n忢\n忨\n忩\n忪\n忬\n忭\n忮\n忯\n忲\n忳\n忶\n忺\n忼\n怇\n怊\n怍\n怓\n怔\n怗\n怘\n怚\n怟\n怤\n怭\n怳\n怵\n恀\n恇\n恈\n恉\n恌\n恑\n恔\n恖\n恗\n恝\n恡\n恧\n恱\n恾\n恿\n悂\n悆\n悈\n悊\n悎\n悑\n悓\n悕\n悘\n悝\n悞\n悢\n悤\n悥\n您\n悰\n悱\n悷\n悻\n悾\n惂\n惄\n惈\n惉\n惊\n惋\n惎\n惏\n惔\n惕\n惙\n惛\n惝\n惞\n惢\n惥\n惲\n惵\n惸\n惼\n惽\n愂\n愇\n愊\n愌\n愐\n愑\n愒\n愓\n愔\n愖\n愗\n愙\n愜\n愞\n愢\n愪\n愫\n愰\n愱\n愵\n愶\n愷\n愹\n慁\n慅\n慆\n慉\n慞\n慠\n慬\n慲\n慸\n慻\n慼\n慿\n憀\n憁\n憃\n憄\n憋\n憍\n憒\n憓\n憗\n憘\n憜\n憝\n憟\n憠\n憥\n憨\n憪\n憭\n憸\n憹\n憼\n懀\n懁\n懂\n懎\n懏\n懕\n懜\n懝\n懞\n懟\n懡\n懢\n懧\n懩\n懥\n懬\n懭\n懯\n戁\n戃\n戄\n戇\n戓\n戕\n戜\n戠\n戢\n戣\n戧\n戩\n戫\n戹\n戽\n扂\n扃\n扄\n扆\n扌\n扐\n扑\n扒\n扔\n扖\n扚\n扜\n扤\n扭\n扯\n扳\n扺\n扽\n抍\n抎\n抏\n抐\n抦\n抨\n抳\n抶\n抷\n抺\n抾\n抿\n拄\n拎\n拕\n拖\n拚\n拪\n拲\n拴\n拼\n拽\n挃\n挄\n挊\n挋\n挍\n挐\n挓\n挖\n挘\n挩\n挪\n挭\n挵\n挶\n挹\n挼\n捁\n捂\n捃\n捄\n捆\n捊\n捋\n捎\n捒\n捓\n捔\n捘\n捛\n捥\n捦\n捬\n捭\n捱\n捴\n捵\n捸\n捼\n捽\n捿\n掂\n掄\n掇\n掊\n掐\n掔\n掕\n掙\n掚\n掞\n掤\n掦\n掭\n掮\n掯\n掽\n揁\n揅\n揈\n揎\n揑\n揓\n揔\n揕\n揜\n揠\n揥\n揪\n揬\n揲\n揳\n揵\n揸\n揹\n搉\n搊\n搐\n搒\n搔\n搘\n搞\n搠\n搢\n搤\n搥\n搩\n搪\n搯\n搰\n搵\n搽\n搿\n摋\n摏\n摑\n摒\n摓\n摔\n摚\n摛\n摜\n摝\n摟\n摠\n摡\n摣\n摭\n摳\n摴\n摻\n摽\n撅\n撇\n撏\n撐\n撑\n撘\n撙\n撛\n撝\n撟\n撡\n撣\n撦\n撨\n撬\n撳\n撽\n撾\n撿\n擄\n擉\n擊\n擋\n擌\n擎\n擐\n擑\n擕\n擗\n擤\n擥\n擩\n擪\n擭\n擰\n擵\n擷\n擻\n擿\n攁\n攄\n攈\n攉\n攊\n攏\n攓\n攔\n攖\n攙\n攛\n攞\n攟\n攢\n攦\n攩\n攮\n攱\n攺\n攼\n攽\n敃\n敇\n敉\n敐\n敒\n敔\n敟\n敠\n敧\n敫\n敺\n敽\n斁\n斅\n斊\n斒\n斕\n斘\n斝\n斠\n斣\n斦\n斮\n斲\n斳\n斴\n斿\n旂\n旈\n旉\n旎\n旐\n旔\n旖\n旘\n旟\n旰\n旲\n旴\n旵\n旹\n旾\n旿\n昀\n昄\n昈\n昉\n昍\n昑\n昒\n昕\n昖\n昝\n昞\n昡\n昢\n昣\n昤\n昦\n昩\n昪\n昫\n昬\n昮\n昰\n昱\n昳\n昹\n昷\n晀\n晅\n晆\n晊\n晌\n晑\n晎\n晗\n晘\n晙\n晛\n晜\n晠\n晡\n曻\n晪\n晫\n晬\n晾\n晳\n晵\n晿\n晷\n晸\n晹\n晻\n暀\n晼\n暋\n暌\n暍\n暐\n暒\n暙\n暚\n暛\n暜\n暟\n暠\n暤\n暭\n暱\n暲\n暵\n暻\n暿\n曀\n曂\n曃\n曈\n曌\n曎\n曏\n曔\n曛\n曟\n曨\n曫\n曬\n曮\n曺\n朅\n朇\n朎\n朓\n朙\n朜\n朠\n朢\n朳\n朾\n杅\n杇\n杈\n杌\n杔\n杕\n杝\n杦\n杬\n杮\n杴\n杶\n杻\n极\n构\n枎\n枏\n枑\n枓\n枖\n枘\n枙\n枛\n枰\n枱\n枲\n枵\n枻\n枼\n枽\n柹\n柀\n柂\n柃\n柅\n柈\n柉\n柒\n柗\n柙\n柜\n柡\n柦\n柰\n柲\n柶\n柷\n桒\n栔\n栙\n栝\n栟\n栨\n栧\n栬\n栭\n栯\n栰\n栱\n栳\n栻\n栿\n桄\n桅\n桊\n桌\n桕\n桗\n桘\n桛\n桫\n桮\n桯\n桰\n桱\n桲\n桵\n桹\n桺\n桻\n桼\n梂\n梄\n梆\n梈\n梖\n梘\n梚\n梜\n梡\n梣\n梥\n梩\n梪\n梮\n梲\n梻\n棅\n棈\n棌\n棏\n棐\n棑\n棓\n棖\n棙\n棜\n棝\n棥\n棨\n棪\n棫\n棬\n棭\n棰\n棱\n棵\n棶\n棻\n棼\n棽\n椆\n椉\n椊\n椐\n椑\n椓\n椖\n椗\n椱\n椳\n椵\n椸\n椻\n楂\n楅\n楉\n楎\n楗\n楛\n楣\n楤\n楥\n楦\n楨\n楩\n楬\n楰\n楱\n楲\n楺\n楻\n楿\n榀\n榍\n榒\n榖\n榘\n榡\n榥\n榦\n榨\n榫\n榭\n榯\n榷\n榸\n榺\n榼\n槅\n槈\n槑\n槖\n槗\n槢\n槥\n槮\n槯\n槱\n槳\n槵\n槾\n樀\n樁\n樃\n樏\n樑\n樕\n樚\n樝\n樠\n樤\n樨\n樰\n樲\n樴\n樷\n樻\n樾\n樿\n橅\n橆\n橉\n橊\n橎\n橐\n橑\n橒\n橕\n橖\n橛\n橤\n橧\n橪\n橱\n橳\n橾\n檁\n檃\n檆\n檇\n檉\n檋\n檑\n檛\n檝\n檞\n檟\n檥\n檫\n檯\n檰\n檱\n檴\n檽\n檾\n檿\n櫆\n櫉\n櫈\n櫌\n櫐\n櫔\n櫕\n櫖\n櫜\n櫝\n櫤\n櫧\n櫬\n櫰\n櫱\n櫲\n櫼\n櫽\n欂\n欃\n欆\n欇\n欉\n欏\n欐\n欑\n欗\n欛\n欞\n欤\n欨\n欫\n欬\n欯\n欵\n欶\n欻\n欿\n歆\n歊\n歍\n歒\n歖\n歘\n歝\n歠\n歧\n歫\n歮\n歰\n歵\n歽\n歾\n殂\n殅\n殗\n殛\n殟\n殠\n殢\n殣\n殨\n殩\n殬\n殭\n殮\n殰\n殸\n殹\n殽\n殾\n毃\n毄\n毉\n毌\n毖\n毚\n毡\n毣\n毦\n毧\n毮\n毱\n毷\n毹\n毿\n氂\n氄\n氅\n氉\n氍\n氎\n氐\n氒\n氙\n氟\n氦\n氧\n氨\n氬\n氮\n氳\n氵\n氶\n氺\n氻\n氿\n汊\n汋\n汍\n汏\n汒\n汔\n汙\n汛\n汜\n汫\n汭\n汯\n汴\n汶\n汸\n汹\n汻\n沅\n沆\n沇\n沉\n沔\n沕\n沗\n沘\n沜\n沟\n沰\n沲\n沴\n泂\n泆\n泍\n泏\n泐\n泑\n泒\n泔\n泖\n泚\n泜\n泠\n泧\n泩\n泫\n泬\n泮\n泲\n泴\n洄\n洇\n洊\n洎\n洏\n洑\n洓\n洚\n洦\n洧\n洨\n汧\n洮\n洯\n洱\n洹\n洼\n洿\n浗\n浞\n浟\n浡\n浥\n浧\n浯\n浰\n浼\n涂\n涇\n涑\n涒\n涔\n涖\n涗\n涘\n涪\n涬\n涴\n涷\n涹\n涽\n涿\n淄\n淈\n淊\n淎\n淏\n淖\n淛\n淝\n淟\n淠\n淢\n淥\n淩\n淯\n淰\n淴\n淶\n淼\n渀\n渄\n渞\n渢\n渧\n渲\n渶\n渹\n渻\n渼\n湄\n湅\n湈\n湉\n湋\n湏\n湑\n湒\n湓\n湔\n湗\n湜\n湝\n湞\n湢\n湣\n湨\n湳\n湻\n湽\n溍\n溓\n溙\n溠\n溧\n溭\n溮\n溱\n溳\n溻\n溿\n滀\n滁\n滃\n滇\n滈\n滊\n滍\n滎\n滏\n滫\n滭\n滮\n滹\n滻\n滽\n漄\n漈\n漊\n漌\n漍\n漖\n漘\n漚\n漛\n漦\n漩\n漪\n漯\n漰\n漳\n漶\n漻\n漼\n漭\n潏\n潑\n潒\n潓\n潗\n潙\n潚\n潝\n潞\n潡\n潢\n潨\n潬\n潽\n潾\n澃\n澇\n澈\n澋\n澌\n澍\n澐\n澒\n澓\n澔\n澖\n澚\n澟\n澠\n澥\n澦\n澧\n澨\n澮\n澯\n澰\n澵\n澶\n澼\n濅\n濇\n濈\n濊\n濚\n濞\n濨\n濩\n濰\n濵\n濹\n濼\n濽\n瀀\n瀅\n瀆\n瀇\n瀍\n瀗\n瀠\n瀣\n瀯\n瀴\n瀷\n瀹\n瀼\n灃\n灄\n灈\n灉\n灊\n灋\n灔\n灕\n灝\n灞\n灎\n灤\n灥\n灬\n灮\n灵\n灶\n灾\n炁\n炅\n炆\n炔\n炕\n炖\n炗\n炘\n炛\n炤\n炫\n炰\n炱\n炴\n炷\n烊\n烑\n烓\n烔\n烕\n烖\n烘\n烜\n烤\n烺\n焃\n焄\n焅\n焆\n焇\n焋\n焌\n焏\n焞\n焠\n焫\n焭\n焯\n焰\n焱\n焸\n煁\n煅\n煆\n煇\n煊\n煋\n煐\n煒\n煗\n煚\n煜\n煞\n煠\n煨\n煹\n熀\n熅\n熇\n熌\n熒\n熚\n熛\n熠\n熢\n熯\n熰\n熲\n熳\n熺\n熿\n燀\n燁\n燄\n燋\n燌\n燓\n燖\n燙\n燚\n燜\n燸\n燾\n爀\n爇\n爈\n爉\n爓\n爗\n爚\n爝\n爟\n爤\n爫\n爯\n爴\n爸\n爹\n牁\n牂\n牃\n牅\n牎\n牏\n牐\n牓\n牕\n牖\n牚\n牜\n牞\n牠\n牣\n牨\n牫\n牮\n牯\n牱\n牷\n牸\n牻\n牼\n牿\n犄\n犉\n犍\n犎\n犓\n犛\n犨\n犭\n犮\n犱\n犴\n犾\n狁\n狇\n狉\n狌\n狕\n狖\n狘\n狟\n狥\n狳\n狴\n狺\n狻\n狾\n猂\n猄\n猅\n猇\n猋\n猍\n猒\n猓\n猘\n猙\n猞\n猢\n猤\n猧\n猨\n猬\n猱\n猲\n猵\n猺\n猻\n猽\n獃\n獍\n獐\n獒\n獖\n獘\n獝\n獞\n獟\n獠\n獦\n獧\n獩\n獫\n獬\n獮\n獯\n獱\n獷\n獹\n獼\n玀\n玁\n玃\n玅\n玆\n玎\n玐\n玓\n玕\n玗\n玘\n玜\n玞\n玟\n玠\n玢\n玥\n玦\n玪\n玫\n玭\n玵\n玷\n玹\n玼\n玽\n玿\n珅\n珆\n珉\n珋\n珌\n珏\n珒\n珓\n珖\n珙\n珝\n珡\n珣\n珦\n珧\n珩\n珴\n珵\n珷\n珹\n珺\n珻\n珽\n珿\n琀\n琁\n琄\n琇\n琊\n琑\n琚\n琛\n琤\n琦\n琨\n琩\n琪\n琫\n琬\n琭\n琮\n琯\n琰\n琱\n琹\n瑀\n瑃\n瑄\n瑆\n瑇\n瑋\n瑍\n瑑\n瑒\n瑗\n瑝\n瑢\n瑦\n瑧\n瑨\n瑫\n瑭\n瑮\n瑱\n瑲\n璀\n璁\n璅\n璆\n璇\n璉\n璏\n璐\n璑\n璒\n璘\n璙\n璚\n璜\n璟\n璠\n璡\n璣\n璦\n璨\n璩\n璪\n璫\n璮\n璯\n璱\n璲\n璵\n璹\n璻\n璿\n瓈\n瓉\n瓌\n瓐\n瓓\n瓘\n瓚\n瓛\n瓞\n瓟\n瓤\n瓨\n瓪\n瓫\n瓯\n瓴\n瓺\n瓻\n瓼\n瓿\n甆\n甒\n甖\n甗\n甠\n甡\n甤\n甧\n甩\n甪\n甯\n甶\n甹\n甽\n甾\n甿\n畀\n畃\n畇\n畈\n畎\n畐\n畒\n畗\n畞\n畟\n畡\n畯\n畱\n畹\n畺\n畻\n畼\n畽\n畾\n疁\n疅\n疐\n疒\n疓\n疕\n疙\n疜\n疢\n疤\n疴\n疺\n疿\n痀\n痁\n痄\n痆\n痌\n痎\n痏\n痗\n痜\n痟\n痠\n痡\n痤\n痧\n痬\n痮\n痯\n痱\n痹\n瘀\n瘂\n瘃\n瘄\n瘇\n瘈\n瘊\n瘌\n瘏\n瘒\n瘓\n瘕\n瘖\n瘙\n瘛\n瘜\n瘝\n瘞\n瘣\n瘥\n瘦\n瘩\n瘭\n瘲\n瘳\n瘵\n瘸\n瘹\n瘺\n瘼\n癊\n癀\n癁\n癃\n癄\n癅\n癉\n癋\n癕\n癙\n癟\n癤\n癥\n癭\n癮\n癯\n癱\n癴\n皁\n皅\n皌\n皍\n皕\n皛\n皜\n皝\n皟\n皠\n皢\n皣\n皤\n皥\n皦\n皧\n皨\n皪\n皭\n皽\n盁\n盅\n盉\n盋\n盌\n盎\n盔\n盙\n盠\n盦\n盨\n盬\n盰\n盱\n盶\n盹\n盼\n眀\n眆\n眊\n眎\n眒\n眔\n眕\n眗\n眙\n眚\n眜\n眢\n眨\n眭\n眮\n眯\n眴\n眵\n眶\n眹\n眽\n眾\n睂\n睅\n睆\n睊\n睍\n睎\n睏\n睒\n睖\n睗\n睜\n睞\n睟\n睠\n睢\n睤\n睧\n睪\n睬\n睰\n睲\n睳\n睴\n睺\n睽\n瞀\n瞄\n瞌\n瞍\n瞔\n瞕\n瞖\n瞚\n瞟\n瞢\n瞧\n瞪\n瞮\n瞯\n瞱\n瞵\n瞾\n矃\n矉\n矑\n矒\n矕\n矙\n矞\n矟\n矠\n矤\n矦\n矪\n矬\n矰\n矱\n矴\n矸\n矻\n砅\n砆\n砉\n砍\n砎\n砑\n砝\n砡\n砢\n砣\n砭\n砮\n砰\n砵\n砷\n硃\n硄\n硇\n硈\n硌\n硎\n硒\n硜\n硞\n硠\n硡\n硣\n硤\n硨\n硪\n确\n硺\n硾\n碊\n碏\n碔\n碘\n碡\n碝\n碞\n碟\n碤\n碨\n碬\n碭\n碰\n碱\n碲\n碳\n碻\n碽\n碿\n磇\n磈\n磉\n磌\n磎\n磒\n磓\n磕\n磖\n磤\n磛\n磟\n磠\n磡\n磦\n磪\n磲\n磳\n礀\n磶\n磷\n磺\n磻\n磿\n礆\n礌\n礐\n礚\n礜\n礞\n礟\n礠\n礥\n礧\n礩\n礭\n礱\n礴\n礵\n礻\n礽\n礿\n祄\n祅\n祆\n祊\n祋\n祏\n祑\n祔\n祘\n祛\n祜\n祧\n祩\n祫\n祲\n祹\n祻\n祼\n祾\n禋\n禌\n禑\n禓\n禔\n禕\n禖\n禘\n禛\n禜\n禡\n禨\n禩\n禫\n禯\n禱\n禴\n禸\n离\n秂\n秄\n秇\n秈\n秊\n秏\n秔\n秖\n秚\n秝\n秞\n秠\n秢\n秥\n秪\n秫\n秭\n秱\n秸\n秼\n稂\n稃\n稇\n稉\n稊\n稌\n稑\n稕\n稛\n稞\n稡\n稧\n稫\n稭\n稯\n稰\n稴\n稵\n稸\n稹\n稺\n穄\n穅\n穇\n穈\n穌\n穕\n穖\n穙\n穜\n穝\n穟\n穠\n穥\n穧\n穪\n穭\n穵\n穸\n穾\n窀\n窂\n窅\n窆\n窊\n窋\n窐\n窑\n窔\n窞\n窠\n窣\n窬\n窳\n窵\n窹\n窻\n窼\n竆\n竉\n竌\n竎\n竑\n竛\n竨\n竩\n竫\n竬\n竱\n竴\n竻\n竽\n竾\n笇\n笔\n笟\n笣\n笧\n笩\n笪\n笫\n笭\n笮\n笯\n笰\n笱\n笴\n笽\n笿\n筀\n筁\n筇\n筎\n筕\n筠\n筤\n筦\n筩\n筪\n筭\n筯\n筲\n筳\n筷\n箄\n箉\n箎\n箐\n箑\n箖\n箛\n箞\n箠\n箥\n箬\n箯\n箰\n箲\n箵\n箶\n箺\n箻\n箼\n箽\n篂\n篅\n篈\n篊\n篔\n篖\n篗\n篙\n篚\n篛\n篨\n篪\n篲\n篴\n篵\n篸\n篹\n篺\n篼\n篾\n簁\n簂\n簃\n簄\n簆\n簉\n簋\n簌\n簎\n簏\n簙\n簛\n簠\n簥\n簦\n簨\n簬\n簱\n簳\n簴\n簶\n簹\n簺\n籆\n籊\n籕\n籑\n籒\n籓\n籙\n籚\n籛\n籜\n籝\n籞\n籡\n籣\n籧\n籩\n籭\n籮\n籰\n籲\n籹\n籼\n籽\n粆\n粇\n粏\n粔\n粞\n粠\n粦\n粰\n粶\n粷\n粺\n粻\n粼\n粿\n糄\n糇\n糈\n糉\n糍\n糏\n糓\n糔\n糕\n糗\n糙\n糚\n糝\n糦\n糩\n糫\n糵\n紃\n紇\n紈\n紉\n紏\n紑\n紒\n紓\n紖\n紝\n紞\n紣\n紦\n紪\n紭\n紱\n紼\n紽\n紾\n絀\n絁\n絇\n絈\n絍\n絑\n絓\n絗\n絙\n絚\n絜\n絝\n絥\n絧\n絪\n絰\n絸\n絺\n絻\n絿\n綁\n綂\n綃\n綅\n綆\n綈\n綋\n綌\n綍\n綑\n綖\n綗\n綝\n綞\n綦\n綧\n綪\n綳\n綶\n綷\n綹\n緂\n緃\n緄\n緅\n緆\n緌\n緍\n緎\n緗\n緙\n縀\n緢\n緥\n緦\n緪\n緫\n緭\n緱\n緵\n緶\n緹\n緺\n縈\n縐\n縑\n縕\n縗\n縜\n縝\n縠\n縧\n縨\n縬\n縭\n縯\n縳\n縶\n縿\n繄\n繅\n繇\n繎\n繐\n繒\n繘\n繟\n繡\n繢\n繥\n繫\n繮\n繯\n繳\n繸\n繾\n纁\n纆\n纇\n纊\n纍\n纑\n纕\n纘\n纚\n纝\n纞\n缼\n缻\n缽\n缾\n缿\n罃\n罄\n罇\n罏\n罒\n罓\n罛\n罜\n罝\n罡\n罣\n罤\n罥\n罦\n罭\n罱\n罽\n罾\n罿\n羀\n羋\n羍\n羏\n羐\n羑\n羖\n羗\n羜\n羡\n羢\n羦\n羪\n羭\n羴\n羼\n羿\n翀\n翃\n翈\n翎\n翏\n翛\n翟\n翣\n翥\n翨\n翬\n翮\n翯\n翲\n翺\n翽\n翾\n翿\n耇\n耈\n耊\n耍\n耎\n耏\n耑\n耓\n耔\n耖\n耝\n耞\n耟\n耠\n耤\n耦\n耬\n耮\n耰\n耴\n耵\n耷\n耹\n耺\n耼\n耾\n聀\n聄\n聠\n聤\n聦\n聭\n聱\n聵\n肁\n肈\n肎\n肜\n肞\n肦\n肧\n肫\n肸\n肹\n胈\n胍\n胏\n胒\n胔\n胕\n胗\n胘\n胠\n胭\n胮\n胰\n胲\n胳\n胶\n胹\n胺\n胾\n脃\n脋\n脖\n脗\n脘\n脜\n脞\n脠\n脤\n脧\n脬\n脰\n脵\n脺\n脼\n腅\n腇\n腊\n腌\n腒\n腗\n腠\n腡\n腧\n腨\n腩\n腭\n腯\n腷\n膁\n膐\n膄\n膅\n膆\n膋\n膎\n膖\n膘\n膛\n膞\n膢\n膮\n膲\n膴\n膻\n臋\n臃\n臅\n臊\n臎\n臏\n臕\n臗\n臛\n臝\n臞\n臡\n臤\n臫\n臬\n臰\n臱\n臲\n臵\n臶\n臸\n臹\n臽\n臿\n舀\n舃\n舏\n舓\n舔\n舙\n舚\n舝\n舡\n舢\n舨\n舲\n舴\n舺\n艃\n艄\n艅\n艆\n艋\n艎\n艏\n艑\n艖\n艜\n艠\n艣\n艧\n艭\n艴\n艻\n艽\n艿\n芀\n芁\n芃\n芄\n芇\n芉\n芊\n芎\n芑\n芔\n芖\n芘\n芚\n芛\n芠\n芡\n芣\n芤\n芧\n芨\n芩\n芪\n芮\n芰\n芲\n芴\n芷\n芺\n芼\n芾\n芿\n苆\n苐\n苕\n苚\n苠\n苢\n苤\n苨\n苪\n苭\n苯\n苶\n苷\n苽\n苾\n茀\n茁\n茇\n茈\n茊\n茋\n荔\n茛\n茝\n茞\n茟\n茡\n茢\n茬\n茭\n茮\n茰\n茳\n茷\n茺\n茼\n茽\n荂\n荃\n荄\n荇\n荍\n荎\n荑\n荕\n荖\n荗\n荰\n荸\n荽\n荿\n莀\n莂\n莄\n莆\n莍\n莒\n莔\n莕\n莘\n莙\n莛\n莜\n莝\n莦\n莧\n莩\n莬\n莾\n莿\n菀\n菇\n菉\n菏\n菐\n菑\n菔\n菝\n荓\n菨\n菪\n菶\n菸\n菹\n菼\n萁\n萆\n萊\n萏\n萑\n萕\n萙\n莭\n萯\n萹\n葅\n葇\n葈\n葊\n葍\n葏\n葑\n葒\n葖\n葘\n葙\n葚\n葜\n葠\n葤\n葥\n葧\n葪\n葰\n葳\n葴\n葶\n葸\n葼\n葽\n蒁\n蒅\n蒒\n蒓\n蒕\n蒞\n蒦\n蒨\n蒩\n蒪\n蒯\n蒱\n蒴\n蒺\n蒽\n蒾\n蓀\n蓂\n蓇\n蓈\n蓌\n蓏\n蓓\n蓜\n蓧\n蓪\n蓯\n蓰\n蓱\n蓲\n蓷\n蔲\n蓺\n蓻\n蓽\n蔂\n蔃\n蔇\n蔌\n蔎\n蔐\n蔜\n蔞\n蔢\n蔣\n蔤\n蔥\n蔧\n蔪\n蔫\n蔯\n蔳\n蔴\n蔶\n蔿\n蕆\n蕏\n蕐\n蕑\n蕒\n蕓\n蕖\n蕙\n蕜\n蕝\n蕞\n蕟\n蕠\n蕡\n蕢\n蕤\n蕫\n蕯\n蕹\n蕺\n蕻\n蕽\n蕿\n薁\n薅\n薆\n薉\n薋\n薌\n薏\n薓\n薘\n薝\n薟\n薠\n薢\n薥\n薧\n薴\n薶\n薷\n薸\n薼\n薽\n薾\n薿\n藂\n藇\n藊\n藋\n藎\n薭\n藘\n藚\n藟\n藠\n藦\n藨\n藭\n藳\n藶\n藼\n藿\n蘀\n蘄\n蘅\n蘍\n蘎\n蘐\n蘑\n蘒\n蘘\n蘙\n蘛\n蘞\n蘡\n蘧\n蘩\n蘶\n蘸\n蘺\n蘼\n蘽\n虀\n虂\n虆\n虒\n虓\n虖\n虗\n虘\n虙\n虝\n虠\n虡\n虢\n虣\n虤\n虩\n虬\n虯\n虵\n虶\n虷\n虺\n蚍\n蚑\n蚖\n蚘\n蚚\n蚜\n蚡\n蚦\n蚧\n蚨\n蚭\n蚱\n蚳\n蚴\n蚵\n蚷\n蚸\n蚹\n蚿\n蛀\n蛁\n蛃\n蛅\n蛑\n蛒\n蛕\n蛗\n蛚\n蛜\n蛠\n蛣\n蛥\n蛧\n蚈\n蛺\n蛼\n蛽\n蜄\n蜅\n蜇\n蜋\n蜎\n蜏\n蜐\n蜓\n蜔\n蜙\n蜞\n蜟\n蜡\n蜣\n蜨\n蜮\n蜯\n蜱\n蜲\n蜹\n蜺\n蜼\n蜽\n蜾\n蝀\n蝃\n蝅\n蝍\n蝘\n蝝\n蝡\n蝤\n蝥\n蝯\n蝱\n蝲\n蝻\n螃\n螄\n螅\n螆\n螇\n螈\n螉\n螋\n螌\n螐\n螓\n螕\n螗\n螘\n螙\n螞\n螠\n螣\n螧\n螬\n螭\n螮\n螱\n螵\n螾\n螿\n蟁\n蟈\n蟉\n蟊\n蟎\n蟕\n蟖\n蟙\n蟚\n蟜\n蟟\n蟢\n蟣\n蟤\n蟪\n蟫\n蟭\n蟱\n蟳\n蟸\n蟺\n蟿\n蠁\n蠃\n蠆\n蠉\n蠊\n蠋\n蠐\n蠙\n蠒\n蠓\n蠔\n蠘\n蠚\n蠛\n蠜\n蠞\n蠟\n蠨\n蠭\n蠮\n蠰\n蠲\n蠵\n蠺\n蠼\n衁\n衃\n衅\n衈\n衉\n衊\n衋\n衎\n衑\n衕\n衖\n衘\n衚\n衜\n衟\n衠\n衤\n衩\n衱\n衹\n衻\n袀\n袘\n袚\n袛\n袜\n袟\n袠\n袨\n袪\n袺\n袽\n袾\n裀\n裊\n裋\n裌\n裍\n裎\n裑\n裒\n裓\n裛\n裞\n裧\n裯\n裰\n裱\n裵\n裷\n褁\n褆\n褍\n褎\n褏\n褕\n褖\n褘\n褙\n褚\n褜\n褠\n褦\n褧\n褨\n褰\n褱\n褲\n褵\n褹\n褺\n褾\n襀\n襂\n襅\n襆\n襉\n襏\n襒\n襗\n襚\n襛\n襜\n襡\n襢\n襣\n襫\n襮\n襰\n襳\n襵\n襺\n襻\n襼\n襽\n覉\n覍\n覐\n覔\n覕\n覛\n覜\n覟\n覠\n覥\n覰\n覴\n覵\n覶\n覷\n覼\n觔\n觕\n觖\n觗\n觘\n觥\n觩\n觫\n觭\n觱\n觳\n觶\n觹\n觽\n觿\n訄\n訅\n訇\n訏\n訑\n訒\n訔\n訕\n訞\n訠\n訢\n訤\n訦\n訫\n訬\n訯\n訵\n訷\n訽\n訾\n詀\n詃\n詅\n詇\n詉\n詍\n詎\n詓\n詖\n詗\n詘\n詜\n詝\n詡\n詥\n詧\n詵\n詶\n詷\n詹\n詺\n詻\n詾\n詿\n誀\n誃\n誆\n誋\n誏\n誐\n誒\n誖\n誗\n誙\n誟\n誧\n誩\n誮\n誯\n誳\n誶\n誷\n誻\n誾\n諃\n諆\n諈\n諉\n諊\n諑\n諓\n諔\n諕\n諗\n諝\n諟\n諬\n諰\n諴\n諵\n諶\n諼\n諿\n謅\n謆\n謋\n謑\n謜\n謞\n謟\n謊\n謭\n謰\n謷\n謼\n譂\n譃\n譄\n譅\n譆\n譈\n譒\n譓\n譔\n譙\n譍\n譞\n譣\n譭\n譶\n譸\n譹\n譼\n譾\n讁\n讄\n讅\n讋\n讍\n讏\n讔\n讕\n讜\n讞\n讟\n谸\n谹\n谽\n谾\n豅\n豇\n豉\n豋\n豏\n豑\n豓\n豔\n豗\n豘\n豛\n豝\n豙\n豣\n豤\n豦\n豨\n豩\n豭\n豳\n豵\n豶\n豻\n豾\n貆\n貇\n貋\n貐\n貒\n貓\n貙\n貛\n貜\n貤\n貹\n貺\n賅\n賆\n賉\n賋\n賏\n賖\n賕\n賙\n賝\n賡\n賨\n賬\n賯\n賰\n賲\n賵\n賷\n賸\n賾\n賿\n贁\n贃\n贉\n贒\n贗\n贛\n赥\n赩\n赬\n赮\n赿\n趂\n趄\n趈\n趍\n趐\n趑\n趕\n趞\n趟\n趠\n趦\n趫\n趬\n趯\n趲\n趵\n趷\n趹\n趻\n跀\n跅\n跆\n跇\n跈\n跊\n跎\n跑\n跔\n跕\n跗\n跙\n跤\n跥\n跧\n跬\n跰\n趼\n跱\n跲\n跴\n跽\n踁\n踄\n踅\n踆\n踋\n踑\n踔\n踖\n踠\n踡\n踢\n踣\n踦\n踧\n踱\n踳\n踶\n踷\n踸\n踹\n踽\n蹀\n蹁\n蹋\n蹍\n蹎\n蹏\n蹔\n蹛\n蹜\n蹝\n蹞\n蹡\n蹢\n蹩\n蹬\n蹭\n蹯\n蹰\n蹱\n蹹\n蹺\n蹻\n躂\n躃\n躉\n躐\n躒\n躕\n躚\n躛\n躝\n躞\n躢\n躧\n躩\n躭\n躮\n躳\n躵\n躺\n躻\n軀\n軁\n軃\n軄\n軇\n軏\n軑\n軔\n軜\n軨\n軮\n軰\n軱\n軷\n軹\n軺\n軭\n輀\n輂\n輇\n輈\n輏\n輐\n輖\n輗\n輘\n輞\n輠\n輡\n輣\n輥\n輧\n輨\n輬\n輭\n輮\n輴\n輵\n輶\n輷\n輺\n轀\n轁\n轃\n轇\n轏\n轑\n轒\n轓\n轔\n轕\n轘\n轝\n轞\n轥\n辝\n辠\n辡\n辤\n辥\n辦\n辵\n辶\n辸\n达\n迀\n迁\n迆\n迊\n迋\n迍\n运\n迒\n迓\n迕\n迠\n迣\n迤\n迨\n迮\n迱\n迵\n迶\n迻\n迾\n适\n逄\n逈\n逌\n逘\n逛\n逨\n逩\n逯\n逪\n逬\n逭\n逳\n逴\n逷\n逿\n遃\n遄\n遌\n遛\n遝\n遢\n遦\n遧\n遬\n遰\n遴\n遹\n邅\n邈\n邋\n邌\n邎\n邐\n邕\n邗\n邘\n邙\n邛\n邠\n邡\n邢\n邥\n邰\n邲\n邳\n邴\n邶\n邽\n郌\n邾\n郃\n郄\n郅\n郇\n郈\n郕\n郗\n郘\n郙\n郜\n郝\n郟\n郥\n郒\n郶\n郫\n郯\n郰\n郴\n郾\n郿\n鄀\n鄄\n鄅\n鄆\n鄈\n鄍\n鄐\n鄔\n鄖\n鄗\n鄘\n鄚\n鄜\n鄞\n鄠\n鄥\n鄢\n鄣\n鄧\n鄩\n鄮\n鄯\n鄱\n鄴\n鄶\n鄷\n鄹\n鄺\n鄼\n鄽\n酃\n酇\n酈\n酏\n酓\n酗\n酙\n酚\n酛\n酡\n酤\n酧\n酭\n酴\n酹\n酺\n酻\n醁\n醃\n醅\n醆\n醊\n醎\n醑\n醓\n醔\n醕\n醘\n醞\n醡\n醦\n醨\n醬\n醭\n醮\n醰\n醱\n醲\n醳\n醶\n醻\n醼\n醽\n醿\n釂\n釃\n釅\n釓\n釔\n釗\n釙\n釚\n釞\n釤\n釥\n釩\n釪\n釬\n釭\n釮\n釯\n釰\n釱\n釷\n釹\n釻\n釽\n鈀\n鈁\n鈄\n鈅\n鈆\n鈇\n鈉\n鈊\n鈌\n鈐\n鈒\n鈓\n鈖\n鈘\n鈜\n鈝\n鈣\n鈤\n鈥\n鈦\n鈨\n鈮\n鈯\n鈰\n鈳\n鈵\n鈶\n鈸\n鈹\n鈺\n鈼\n鈾\n鉀\n鉂\n鉃\n鉆\n鉇\n鉊\n鉍\n鉎\n鉏\n鉑\n鉘\n鉙\n鉜\n鉝\n鉠\n鉡\n鉥\n鉧\n鉨\n鉩\n鉮\n鉯\n鉰\n鉵\n鉶\n鉷\n鉸\n鉹\n鉻\n鉼\n鉽\n鉿\n銈\n銉\n銊\n銍\n銎\n銒\n銗\n銙\n銟\n銠\n銤\n銥\n銧\n銨\n銫\n銯\n銲\n銶\n銸\n銺\n銻\n銼\n銽\n銿\n鋀\n鋁\n鋂\n鋃\n鋅\n鋆\n鋇\n鋈\n鋋\n鋌\n鋍\n鋎\n鋐\n鋓\n鋕\n鋗\n鋘\n鋙\n鋜\n鋝\n鋟\n鋠\n鋡\n鋣\n鋥\n鋧\n鋨\n鋬\n鋮\n鋰\n鋹\n鋻\n鋿\n錀\n錂\n錈\n錍\n錑\n錔\n錕\n錜\n錝\n錞\n錟\n錡\n錤\n錥\n錧\n錩\n錪\n錳\n錴\n錶\n錷\n鍇\n鍈\n鍉\n鍐\n鍑\n鍒\n鍕\n鍗\n鍘\n鍚\n鍞\n鍤\n鍥\n鍧\n鍩\n鍪\n鍭\n鍯\n鍰\n鍱\n鍳\n鍴\n鍶\n鍺\n鍽\n鍿\n鎀\n鎁\n鎂\n鎈\n鎊\n鎋\n鎍\n鎏\n鎒\n鎕\n鎘\n鎛\n鎞\n鎡\n鎣\n鎤\n鎦\n鎨\n鎫\n鎴\n鎵\n鎶\n鎺\n鎩\n鏁\n鏄\n鏅\n鏆\n鏇\n鏉\n鏊\n鏋\n鏌\n鏍\n鏓\n鏙\n鏜\n鏞\n鏟\n鏢\n鏦\n鏧\n鏹\n鏷\n鏸\n鏺\n鏻\n鏽\n鐁\n鐂\n鐄\n鐈\n鐉\n鐍\n鐎\n鐏\n鐕\n鐖\n鐗\n鐟\n鐮\n鐯\n鐱\n鐲\n鐳\n鐴\n鐻\n鐿\n鐽\n鑃\n鑅\n鑈\n鑊\n鑌\n鑕\n鑙\n鑜\n鑟\n鑡\n鑣\n鑨\n鑫\n鑭\n鑮\n鑯\n鑱\n鑲\n钄\n钃\n镸\n镹\n镾\n閄\n閈\n閌\n閍\n閎\n閝\n閞\n閟\n閡\n閦\n閩\n閫\n閬\n閴\n閶\n閺\n閽\n閿\n闆\n闈\n闉\n闋\n闐\n闑\n闒\n闓\n闙\n闚\n闝\n闞\n闟\n闠\n闤\n闦\n阝\n阞\n阢\n阤\n阥\n阦\n阬\n阱\n阳\n阷\n阸\n阹\n阺\n阼\n阽\n陁\n陒\n陔\n陖\n陗\n陘\n陡\n陮\n陴\n陻\n陼\n陾\n陿\n隁\n隂\n隃\n隄\n隉\n隑\n隖\n隚\n隝\n隟\n隤\n隥\n隦\n隩\n隮\n隯\n隳\n隺\n雊\n雒\n嶲\n雘\n雚\n雝\n雞\n雟\n雩\n雯\n雱\n雺\n霂\n霃\n霅\n霉\n霚\n霛\n霝\n霡\n霢\n霣\n霨\n霱\n霳\n靁\n靃\n靊\n靎\n靏\n靕\n靗\n靘\n靚\n靛\n靣\n靧\n靪\n靮\n靳\n靶\n靷\n靸\n靻\n靽\n靿\n鞀\n鞉\n鞕\n鞖\n鞗\n鞙\n鞚\n鞞\n鞟\n鞢\n鞬\n鞮\n鞱\n鞲\n鞵\n鞶\n鞸\n鞹\n鞺\n鞼\n鞾\n鞿\n韁\n韄\n韅\n韇\n韉\n韊\n韌\n韍\n韎\n韐\n韑\n韔\n韗\n韘\n韙\n韝\n韞\n韠\n韛\n韡\n韤\n韯\n韱\n韴\n韷\n韸\n韺\n頇\n頊\n頙\n頍\n頎\n頔\n頖\n頜\n頞\n頠\n頣\n頦\n頫\n頮\n頯\n頰\n頲\n頳\n頵\n頥\n頾\n顄\n顇\n顊\n顑\n顒\n顓\n顖\n顗\n顙\n顚\n顢\n顣\n顥\n顦\n顪\n顬\n颫\n颭\n颮\n颰\n颴\n颷\n颸\n颺\n颻\n颿\n飂\n飅\n飈\n飌\n飡\n飣\n飥\n飦\n飧\n飪\n飳\n飶\n餂\n餇\n餈\n餑\n餕\n餖\n餗\n餚\n餛\n餜\n餟\n餢\n餦\n餧\n餫\n餱\n餲\n餳\n餴\n餵\n餹\n餺\n餻\n餼\n饀\n饁\n饆\n饇\n饈\n饍\n饎\n饔\n饘\n饙\n饛\n饜\n饞\n饟\n饠\n馛\n馝\n馟\n馦\n馰\n馱\n馲\n馵\n馹\n馺\n馽\n馿\n駃\n駉\n駓\n駔\n駙\n駚\n駜\n駞\n駧\n駪\n駫\n駬\n駰\n駴\n駵\n駹\n駽\n駾\n騂\n騃\n騄\n騋\n騌\n騐\n騑\n騖\n騞\n騠\n騢\n騣\n騤\n騧\n騭\n騮\n騳\n騵\n騶\n騸\n驇\n驁\n驄\n驊\n驋\n驌\n驎\n驑\n驔\n驖\n驝\n骪\n骬\n骮\n骯\n骲\n骴\n骵\n骶\n骹\n骻\n骾\n骿\n髁\n髃\n髆\n髈\n髎\n髐\n髒\n髕\n髖\n髗\n髛\n髜\n髠\n髤\n髥\n髧\n髩\n髬\n髲\n髳\n髵\n髹\n髺\n髽\n髿\n鬀\n鬁\n鬂\n鬃\n鬄\n鬅\n鬈\n鬉\n鬋\n鬌\n鬍\n鬎\n鬐\n鬒\n鬖\n鬙\n鬛\n鬜\n鬠\n鬦\n鬫\n鬭\n鬳\n鬴\n鬵\n鬷\n鬹\n鬺\n鬽\n魈\n魋\n魌\n魕\n魖\n魗\n魛\n魞\n魡\n魣\n魥\n魦\n魨\n魪\n魫\n魬\n魭\n魮\n魳\n魵\n魷\n魸\n魹\n魿\n鮀\n鮄\n鮅\n鮆\n鮇\n鮉\n鮊\n鮋\n鮍\n鮏\n鮐\n鮔\n鮚\n鮝\n鮞\n鮦\n鮧\n鮩\n鮬\n鮰\n鮱\n鮲\n鮷\n鮸\n鮻\n鮼\n鮾\n鮿\n鯁\n鯇\n鯈\n鯎\n鯐\n鯗\n鯘\n鯝\n鯟\n鯥\n鯧\n鯪\n鯫\n鯯\n鯳\n鯷\n鯸\n鯹\n鯺\n鯽\n鯿\n鰀\n鰂\n鰋\n鰏\n鰑\n鰖\n鰘\n鰙\n鰚\n鰜\n鰞\n鰢\n鰣\n鰦\n鰧\n鰨\n鰩\n鰪\n鰱\n鰵\n鰶\n鰷\n鰽\n鱁\n鱃\n鱄\n鱅\n鱉\n鱊\n鱎\n鱏\n鱐\n鱓\n鱔\n鱖\n鱘\n鱛\n鱝\n鱞\n鱟\n鱣\n鱩\n鱪\n鱜\n鱫\n鱨\n鱮\n鱰\n鱲\n鱵\n鱷\n鱻\n鳦\n鳲\n鳷\n鳹\n鴋\n鴂\n鴑\n鴗\n鴘\n鴜\n鴝\n鴞\n鴯\n鴰\n鴲\n鴳\n鴴\n鴺\n鴼\n鵅\n鴽\n鵂\n鵃\n鵇\n鵊\n鵓\n鵔\n鵟\n鵣\n鵢\n鵥\n鵩\n鵪\n鵫\n鵰\n鵶\n鵷\n鵻\n鵼\n鵾\n鶃\n鶄\n鶆\n鶊\n鶍\n鶎\n鶒\n鶓\n鶕\n鶖\n鶗\n鶘\n鶡\n鶪\n鶬\n鶮\n鶱\n鶵\n鶹\n鶼\n鶿\n鷃\n鷇\n鷉\n鷊\n鷔\n鷕\n鷖\n鷗\n鷚\n鷞\n鷟\n鷠\n鷥\n鷧\n鷩\n鷫\n鷮\n鷰\n鷳\n鷴\n鷾\n鸊\n鸂\n鸇\n鸎\n鸐\n鸑\n鸒\n鸕\n鸖\n鸙\n鸜\n鸝\n鹺\n鹻\n鹼\n麀\n麂\n麃\n麄\n麅\n麇\n麎\n麏\n麖\n麘\n麛\n麞\n麤\n麨\n麬\n麮\n麯\n麰\n麳\n麴\n麵\n黆\n黈\n黋\n黕\n黟\n黤\n黧\n黬\n黭\n黮\n黰\n黱\n黲\n黵\n黸\n黿\n鼂\n鼃\n鼉\n鼏\n鼐\n鼑\n鼒\n鼔\n鼖\n鼗\n鼙\n鼚\n鼛\n鼟\n鼢\n鼦\n鼪\n鼫\n鼯\n鼱\n鼲\n鼴\n鼷\n鼹\n鼺\n鼼\n鼽\n鼿\n齁\n齃\n齄\n齅\n齆\n齇\n齓\n齕\n齖\n齗\n齘\n齚\n齝\n齞\n齨\n齩\n齭\n齮\n齯\n齰\n齱\n齳\n齵\n齺\n齽\n龏\n龐\n龑\n龒\n龔\n龖\n龗\n龞\n龡\n龢\n龣\n龥\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n"
  },
  {
    "path": "helix-view/tests/encoding/shift_jis_in.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "helix-view/tests/encoding/shift_jis_in_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n　\n、\n。\n，\n．\n・\n：\n；\n？\n！\n゛\n゜\n´\n｀\n¨\n＾\n￣\n＿\nヽ\nヾ\nゝ\nゞ\n〃\n仝\n々\n〆\n〇\nー\n―\n‐\n／\n＼\n～\n∥\n｜\n…\n‥\n‘\n’\n“\n”\n（\n）\n〔\n〕\n［\n］\n｛\n｝\n〈\n〉\n《\n》\n「\n」\n『\n』\n【\n】\n＋\n－\n±\n×\n÷\n＝\n≠\n＜\n＞\n≦\n≧\n∞\n∴\n♂\n♀\n°\n′\n″\n℃\n￥\n＄\n￠\n￡\n％\n＃\n＆\n＊\n＠\n§\n☆\n★\n○\n●\n◎\n◇\n◆\n□\n■\n△\n▲\n▽\n▼\n※\n〒\n→\n←\n↑\n↓\n〓\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n∈\n∋\n⊆\n⊇\n⊂\n⊃\n∪\n∩\n�\n�\n�\n�\n�\n�\n�\n�\n∧\n∨\n￢\n⇒\n⇔\n∀\n∃\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n∠\n⊥\n⌒\n∂\n∇\n≡\n≒\n≪\n≫\n√\n∽\n∝\n∵\n∫\n∬\n�\n�\n�\n�\n�\n�\n�\nÅ\n‰\n♯\n♭\n♪\n†\n‡\n¶\n�\n�\n�\n�\n◯\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\n�z\n�{\n�|\n�}\n�~\n�\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\n�\n�\n�\n�\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\n�\n�\n�\n�\n�\n�\n�\n�\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\n�\n�\n�\n�\n�\n�\n�\n�\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n─\n│\n┌\n┐\n┘\n└\n├\n┬\n┤\n┴\n┼\n━\n┃\n┏\n┓\n┛\n┗\n┣\n┳\n┫\n┻\n╋\n┠\n┯\n┨\n┷\n┿\n┝\n┰\n┥\n┸\n╂\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n⑪\n⑫\n⑬\n⑭\n⑮\n⑯\n⑰\n⑱\n⑲\n⑳\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n�^\n㍉\n㌔\n㌢\n㍍\n㌘\n㌧\n㌃\n㌶\n㍑\n㍗\n㌍\n㌦\n㌣\n㌫\n㍊\n㌻\n㎜\n㎝\n㎞\n㎎\n㎏\n㏄\n㎡\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n㍻\n〝\n〟\n№\n㏍\n℡\n㊤\n㊥\n㊦\n㊧\n㊨\n㈱\n㈲\n㈹\n㍾\n㍽\n㍼\n≒\n≡\n∫\n∮\n∑\n√\n⊥\n∠\n∟\n⊿\n∵\n∩\n∪\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n亜\n唖\n娃\n阿\n哀\n愛\n挨\n姶\n逢\n葵\n茜\n穐\n悪\n握\n渥\n旭\n葦\n芦\n鯵\n梓\n圧\n斡\n扱\n宛\n姐\n虻\n飴\n絢\n綾\n鮎\n或\n粟\n袷\n安\n庵\n按\n暗\n案\n闇\n鞍\n杏\n以\n伊\n位\n依\n偉\n囲\n夷\n委\n威\n尉\n惟\n意\n慰\n易\n椅\n為\n畏\n異\n移\n維\n緯\n胃\n萎\n衣\n謂\n違\n遺\n医\n井\n亥\n域\n育\n郁\n磯\n一\n壱\n溢\n逸\n稲\n茨\n芋\n鰯\n允\n印\n咽\n員\n因\n姻\n引\n飲\n淫\n胤\n蔭\n院\n陰\n隠\n韻\n吋\n右\n宇\n烏\n羽\n迂\n雨\n卯\n鵜\n窺\n丑\n碓\n臼\n渦\n嘘\n唄\n欝\n蔚\n鰻\n姥\n厩\n浦\n瓜\n閏\n噂\n云\n運\n雲\n荏\n餌\n叡\n営\n嬰\n影\n映\n曳\n栄\n永\n泳\n洩\n瑛\n盈\n穎\n頴\n英\n衛\n詠\n鋭\n液\n疫\n益\n駅\n悦\n謁\n越\n閲\n榎\n厭\n円\n園\n堰\n奄\n宴\n延\n怨\n掩\n援\n沿\n演\n炎\n焔\n煙\n燕\n猿\n縁\n艶\n苑\n薗\n遠\n鉛\n鴛\n塩\n於\n汚\n甥\n凹\n央\n奥\n往\n応\n押\n旺\n横\n欧\n殴\n王\n翁\n襖\n鴬\n鴎\n黄\n岡\n沖\n荻\n億\n屋\n憶\n臆\n桶\n牡\n乙\n俺\n卸\n恩\n温\n穏\n音\n下\n化\n仮\n何\n伽\n価\n佳\n加\n可\n嘉\n夏\n嫁\n家\n寡\n科\n暇\n果\n架\n歌\n河\n火\n珂\n禍\n禾\n稼\n箇\n花\n苛\n茄\n荷\n華\n菓\n蝦\n課\n嘩\n貨\n迦\n過\n霞\n蚊\n俄\n峨\n我\n牙\n画\n臥\n芽\n蛾\n賀\n雅\n餓\n駕\n介\n会\n解\n回\n塊\n壊\n廻\n快\n怪\n悔\n恢\n懐\n戒\n拐\n改\n魁\n晦\n械\n海\n灰\n界\n皆\n絵\n芥\n蟹\n開\n階\n貝\n凱\n劾\n外\n咳\n害\n崖\n慨\n概\n涯\n碍\n蓋\n街\n該\n鎧\n骸\n浬\n馨\n蛙\n垣\n柿\n蛎\n鈎\n劃\n嚇\n各\n廓\n拡\n撹\n格\n核\n殻\n獲\n確\n穫\n覚\n角\n赫\n較\n郭\n閣\n隔\n革\n学\n岳\n楽\n額\n顎\n掛\n笠\n樫\n橿\n梶\n鰍\n潟\n割\n喝\n恰\n括\n活\n渇\n滑\n葛\n褐\n轄\n且\n鰹\n叶\n椛\n樺\n鞄\n株\n兜\n竃\n蒲\n釜\n鎌\n噛\n鴨\n栢\n茅\n萱\n粥\n刈\n苅\n瓦\n乾\n侃\n冠\n寒\n刊\n勘\n勧\n巻\n喚\n堪\n姦\n完\n官\n寛\n干\n幹\n患\n感\n慣\n憾\n換\n敢\n柑\n桓\n棺\n款\n歓\n汗\n漢\n澗\n潅\n環\n甘\n監\n看\n竿\n管\n簡\n緩\n缶\n翰\n肝\n艦\n莞\n観\n諌\n貫\n還\n鑑\n間\n閑\n関\n陥\n韓\n館\n舘\n丸\n含\n岸\n巌\n玩\n癌\n眼\n岩\n翫\n贋\n雁\n頑\n顔\n願\n企\n伎\n危\n喜\n器\n基\n奇\n嬉\n寄\n岐\n希\n幾\n忌\n揮\n机\n旗\n既\n期\n棋\n棄\n機\n帰\n毅\n気\n汽\n畿\n祈\n季\n稀\n紀\n徽\n規\n記\n貴\n起\n軌\n輝\n飢\n騎\n鬼\n亀\n偽\n儀\n妓\n宜\n戯\n技\n擬\n欺\n犠\n疑\n祇\n義\n蟻\n誼\n議\n掬\n菊\n鞠\n吉\n吃\n喫\n桔\n橘\n詰\n砧\n杵\n黍\n却\n客\n脚\n虐\n逆\n丘\n久\n仇\n休\n及\n吸\n宮\n弓\n急\n救\n朽\n求\n汲\n泣\n灸\n球\n究\n窮\n笈\n級\n糾\n給\n旧\n牛\n去\n居\n巨\n拒\n拠\n挙\n渠\n虚\n許\n距\n鋸\n漁\n禦\n魚\n亨\n享\n京\n供\n侠\n僑\n兇\n競\n共\n凶\n協\n匡\n卿\n叫\n喬\n境\n峡\n強\n彊\n怯\n恐\n恭\n挟\n教\n橋\n況\n狂\n狭\n矯\n胸\n脅\n興\n蕎\n郷\n鏡\n響\n饗\n驚\n仰\n凝\n尭\n暁\n業\n局\n曲\n極\n玉\n桐\n粁\n僅\n勤\n均\n巾\n錦\n斤\n欣\n欽\n琴\n禁\n禽\n筋\n緊\n芹\n菌\n衿\n襟\n謹\n近\n金\n吟\n銀\n九\n倶\n句\n区\n狗\n玖\n矩\n苦\n躯\n駆\n駈\n駒\n具\n愚\n虞\n喰\n空\n偶\n寓\n遇\n隅\n串\n櫛\n釧\n屑\n屈\n掘\n窟\n沓\n靴\n轡\n窪\n熊\n隈\n粂\n栗\n繰\n桑\n鍬\n勲\n君\n薫\n訓\n群\n軍\n郡\n卦\n袈\n祁\n係\n傾\n刑\n兄\n啓\n圭\n珪\n型\n契\n形\n径\n恵\n慶\n慧\n憩\n掲\n携\n敬\n景\n桂\n渓\n畦\n稽\n系\n経\n継\n繋\n罫\n茎\n荊\n蛍\n計\n詣\n警\n軽\n頚\n鶏\n芸\n迎\n鯨\n劇\n戟\n撃\n激\n隙\n桁\n傑\n欠\n決\n潔\n穴\n結\n血\n訣\n月\n件\n倹\n倦\n健\n兼\n券\n剣\n喧\n圏\n堅\n嫌\n建\n憲\n懸\n拳\n捲\n検\n権\n牽\n犬\n献\n研\n硯\n絹\n県\n肩\n見\n謙\n賢\n軒\n遣\n鍵\n険\n顕\n験\n鹸\n元\n原\n厳\n幻\n弦\n減\n源\n玄\n現\n絃\n舷\n言\n諺\n限\n乎\n個\n古\n呼\n固\n姑\n孤\n己\n庫\n弧\n戸\n故\n枯\n湖\n狐\n糊\n袴\n股\n胡\n菰\n虎\n誇\n跨\n鈷\n雇\n顧\n鼓\n五\n互\n伍\n午\n呉\n吾\n娯\n後\n御\n悟\n梧\n檎\n瑚\n碁\n語\n誤\n護\n醐\n乞\n鯉\n交\n佼\n侯\n候\n倖\n光\n公\n功\n効\n勾\n厚\n口\n向\n后\n喉\n坑\n垢\n好\n孔\n孝\n宏\n工\n巧\n巷\n幸\n広\n庚\n康\n弘\n恒\n慌\n抗\n拘\n控\n攻\n昂\n晃\n更\n杭\n校\n梗\n構\n江\n洪\n浩\n港\n溝\n甲\n皇\n硬\n稿\n糠\n紅\n紘\n絞\n綱\n耕\n考\n肯\n肱\n腔\n膏\n航\n荒\n行\n衡\n講\n貢\n購\n郊\n酵\n鉱\n砿\n鋼\n閤\n降\n項\n香\n高\n鴻\n剛\n劫\n号\n合\n壕\n拷\n濠\n豪\n轟\n麹\n克\n刻\n告\n国\n穀\n酷\n鵠\n黒\n獄\n漉\n腰\n甑\n忽\n惚\n骨\n狛\n込\n此\n頃\n今\n困\n坤\n墾\n婚\n恨\n懇\n昏\n昆\n根\n梱\n混\n痕\n紺\n艮\n魂\n些\n佐\n叉\n唆\n嵯\n左\n差\n査\n沙\n瑳\n砂\n詐\n鎖\n裟\n坐\n座\n挫\n債\n催\n再\n最\n哉\n塞\n妻\n宰\n彩\n才\n採\n栽\n歳\n済\n災\n采\n犀\n砕\n砦\n祭\n斎\n細\n菜\n裁\n載\n際\n剤\n在\n材\n罪\n財\n冴\n坂\n阪\n堺\n榊\n肴\n咲\n崎\n埼\n碕\n鷺\n作\n削\n咋\n搾\n昨\n朔\n柵\n窄\n策\n索\n錯\n桜\n鮭\n笹\n匙\n冊\n刷\n察\n拶\n撮\n擦\n札\n殺\n薩\n雑\n皐\n鯖\n捌\n錆\n鮫\n皿\n晒\n三\n傘\n参\n山\n惨\n撒\n散\n桟\n燦\n珊\n産\n算\n纂\n蚕\n讃\n賛\n酸\n餐\n斬\n暫\n残\n仕\n仔\n伺\n使\n刺\n司\n史\n嗣\n四\n士\n始\n姉\n姿\n子\n屍\n市\n師\n志\n思\n指\n支\n孜\n斯\n施\n旨\n枝\n止\n死\n氏\n獅\n祉\n私\n糸\n紙\n紫\n肢\n脂\n至\n視\n詞\n詩\n試\n誌\n諮\n資\n賜\n雌\n飼\n歯\n事\n似\n侍\n児\n字\n寺\n慈\n持\n時\n次\n滋\n治\n爾\n璽\n痔\n磁\n示\n而\n耳\n自\n蒔\n辞\n汐\n鹿\n式\n識\n鴫\n竺\n軸\n宍\n雫\n七\n叱\n執\n失\n嫉\n室\n悉\n湿\n漆\n疾\n質\n実\n蔀\n篠\n偲\n柴\n芝\n屡\n蕊\n縞\n舎\n写\n射\n捨\n赦\n斜\n煮\n社\n紗\n者\n謝\n車\n遮\n蛇\n邪\n借\n勺\n尺\n杓\n灼\n爵\n酌\n釈\n錫\n若\n寂\n弱\n惹\n主\n取\n守\n手\n朱\n殊\n狩\n珠\n種\n腫\n趣\n酒\n首\n儒\n受\n呪\n寿\n授\n樹\n綬\n需\n囚\n収\n周\n宗\n就\n州\n修\n愁\n拾\n洲\n秀\n秋\n終\n繍\n習\n臭\n舟\n蒐\n衆\n襲\n讐\n蹴\n輯\n週\n酋\n酬\n集\n醜\n什\n住\n充\n十\n従\n戎\n柔\n汁\n渋\n獣\n縦\n重\n銃\n叔\n夙\n宿\n淑\n祝\n縮\n粛\n塾\n熟\n出\n術\n述\n俊\n峻\n春\n瞬\n竣\n舜\n駿\n准\n循\n旬\n楯\n殉\n淳\n準\n潤\n盾\n純\n巡\n遵\n醇\n順\n処\n初\n所\n暑\n曙\n渚\n庶\n緒\n署\n書\n薯\n藷\n諸\n助\n叙\n女\n序\n徐\n恕\n鋤\n除\n傷\n償\n勝\n匠\n升\n召\n哨\n商\n唱\n嘗\n奨\n妾\n娼\n宵\n将\n小\n少\n尚\n庄\n床\n廠\n彰\n承\n抄\n招\n掌\n捷\n昇\n昌\n昭\n晶\n松\n梢\n樟\n樵\n沼\n消\n渉\n湘\n焼\n焦\n照\n症\n省\n硝\n礁\n祥\n称\n章\n笑\n粧\n紹\n肖\n菖\n蒋\n蕉\n衝\n裳\n訟\n証\n詔\n詳\n象\n賞\n醤\n鉦\n鍾\n鐘\n障\n鞘\n上\n丈\n丞\n乗\n冗\n剰\n城\n場\n壌\n嬢\n常\n情\n擾\n条\n杖\n浄\n状\n畳\n穣\n蒸\n譲\n醸\n錠\n嘱\n埴\n飾\n拭\n植\n殖\n燭\n織\n職\n色\n触\n食\n蝕\n辱\n尻\n伸\n信\n侵\n唇\n娠\n寝\n審\n心\n慎\n振\n新\n晋\n森\n榛\n浸\n深\n申\n疹\n真\n神\n秦\n紳\n臣\n芯\n薪\n親\n診\n身\n辛\n進\n針\n震\n人\n仁\n刃\n塵\n壬\n尋\n甚\n尽\n腎\n訊\n迅\n陣\n靭\n笥\n諏\n須\n酢\n図\n厨\n逗\n吹\n垂\n帥\n推\n水\n炊\n睡\n粋\n翠\n衰\n遂\n酔\n錐\n錘\n随\n瑞\n髄\n崇\n嵩\n数\n枢\n趨\n雛\n据\n杉\n椙\n菅\n頗\n雀\n裾\n澄\n摺\n寸\n世\n瀬\n畝\n是\n凄\n制\n勢\n姓\n征\n性\n成\n政\n整\n星\n晴\n棲\n栖\n正\n清\n牲\n生\n盛\n精\n聖\n声\n製\n西\n誠\n誓\n請\n逝\n醒\n青\n静\n斉\n税\n脆\n隻\n席\n惜\n戚\n斥\n昔\n析\n石\n積\n籍\n績\n脊\n責\n赤\n跡\n蹟\n碩\n切\n拙\n接\n摂\n折\n設\n窃\n節\n説\n雪\n絶\n舌\n蝉\n仙\n先\n千\n占\n宣\n専\n尖\n川\n戦\n扇\n撰\n栓\n栴\n泉\n浅\n洗\n染\n潜\n煎\n煽\n旋\n穿\n箭\n線\n繊\n羨\n腺\n舛\n船\n薦\n詮\n賎\n践\n選\n遷\n銭\n銑\n閃\n鮮\n前\n善\n漸\n然\n全\n禅\n繕\n膳\n糎\n噌\n塑\n岨\n措\n曾\n曽\n楚\n狙\n疏\n疎\n礎\n祖\n租\n粗\n素\n組\n蘇\n訴\n阻\n遡\n鼠\n僧\n創\n双\n叢\n倉\n喪\n壮\n奏\n爽\n宋\n層\n匝\n惣\n想\n捜\n掃\n挿\n掻\n操\n早\n曹\n巣\n槍\n槽\n漕\n燥\n争\n痩\n相\n窓\n糟\n総\n綜\n聡\n草\n荘\n葬\n蒼\n藻\n装\n走\n送\n遭\n鎗\n霜\n騒\n像\n増\n憎\n臓\n蔵\n贈\n造\n促\n側\n則\n即\n息\n捉\n束\n測\n足\n速\n俗\n属\n賊\n族\n続\n卒\n袖\n其\n揃\n存\n孫\n尊\n損\n村\n遜\n他\n多\n太\n汰\n詑\n唾\n堕\n妥\n惰\n打\n柁\n舵\n楕\n陀\n駄\n騨\n体\n堆\n対\n耐\n岱\n帯\n待\n怠\n態\n戴\n替\n泰\n滞\n胎\n腿\n苔\n袋\n貸\n退\n逮\n隊\n黛\n鯛\n代\n台\n大\n第\n醍\n題\n鷹\n滝\n瀧\n卓\n啄\n宅\n托\n択\n拓\n沢\n濯\n琢\n託\n鐸\n濁\n諾\n茸\n凧\n蛸\n只\n叩\n但\n達\n辰\n奪\n脱\n巽\n竪\n辿\n棚\n谷\n狸\n鱈\n樽\n誰\n丹\n単\n嘆\n坦\n担\n探\n旦\n歎\n淡\n湛\n炭\n短\n端\n箪\n綻\n耽\n胆\n蛋\n誕\n鍛\n団\n壇\n弾\n断\n暖\n檀\n段\n男\n談\n値\n知\n地\n弛\n恥\n智\n池\n痴\n稚\n置\n致\n蜘\n遅\n馳\n築\n畜\n竹\n筑\n蓄\n逐\n秩\n窒\n茶\n嫡\n着\n中\n仲\n宙\n忠\n抽\n昼\n柱\n注\n虫\n衷\n註\n酎\n鋳\n駐\n樗\n瀦\n猪\n苧\n著\n貯\n丁\n兆\n凋\n喋\n寵\n帖\n帳\n庁\n弔\n張\n彫\n徴\n懲\n挑\n暢\n朝\n潮\n牒\n町\n眺\n聴\n脹\n腸\n蝶\n調\n諜\n超\n跳\n銚\n長\n頂\n鳥\n勅\n捗\n直\n朕\n沈\n珍\n賃\n鎮\n陳\n津\n墜\n椎\n槌\n追\n鎚\n痛\n通\n塚\n栂\n掴\n槻\n佃\n漬\n柘\n辻\n蔦\n綴\n鍔\n椿\n潰\n坪\n壷\n嬬\n紬\n爪\n吊\n釣\n鶴\n亭\n低\n停\n偵\n剃\n貞\n呈\n堤\n定\n帝\n底\n庭\n廷\n弟\n悌\n抵\n挺\n提\n梯\n汀\n碇\n禎\n程\n締\n艇\n訂\n諦\n蹄\n逓\n邸\n鄭\n釘\n鼎\n泥\n摘\n擢\n敵\n滴\n的\n笛\n適\n鏑\n溺\n哲\n徹\n撤\n轍\n迭\n鉄\n典\n填\n天\n展\n店\n添\n纏\n甜\n貼\n転\n顛\n点\n伝\n殿\n澱\n田\n電\n兎\n吐\n堵\n塗\n妬\n屠\n徒\n斗\n杜\n渡\n登\n菟\n賭\n途\n都\n鍍\n砥\n砺\n努\n度\n土\n奴\n怒\n倒\n党\n冬\n凍\n刀\n唐\n塔\n塘\n套\n宕\n島\n嶋\n悼\n投\n搭\n東\n桃\n梼\n棟\n盗\n淘\n湯\n涛\n灯\n燈\n当\n痘\n祷\n等\n答\n筒\n糖\n統\n到\n董\n蕩\n藤\n討\n謄\n豆\n踏\n逃\n透\n鐙\n陶\n頭\n騰\n闘\n働\n動\n同\n堂\n導\n憧\n撞\n洞\n瞳\n童\n胴\n萄\n道\n銅\n峠\n鴇\n匿\n得\n徳\n涜\n特\n督\n禿\n篤\n毒\n独\n読\n栃\n橡\n凸\n突\n椴\n届\n鳶\n苫\n寅\n酉\n瀞\n噸\n屯\n惇\n敦\n沌\n豚\n遁\n頓\n呑\n曇\n鈍\n奈\n那\n内\n乍\n凪\n薙\n謎\n灘\n捺\n鍋\n楢\n馴\n縄\n畷\n南\n楠\n軟\n難\n汝\n二\n尼\n弐\n迩\n匂\n賑\n肉\n虹\n廿\n日\n乳\n入\n如\n尿\n韮\n任\n妊\n忍\n認\n濡\n禰\n祢\n寧\n葱\n猫\n熱\n年\n念\n捻\n撚\n燃\n粘\n乃\n廼\n之\n埜\n嚢\n悩\n濃\n納\n能\n脳\n膿\n農\n覗\n蚤\n巴\n把\n播\n覇\n杷\n波\n派\n琶\n破\n婆\n罵\n芭\n馬\n俳\n廃\n拝\n排\n敗\n杯\n盃\n牌\n背\n肺\n輩\n配\n倍\n培\n媒\n梅\n楳\n煤\n狽\n買\n売\n賠\n陪\n這\n蝿\n秤\n矧\n萩\n伯\n剥\n博\n拍\n柏\n泊\n白\n箔\n粕\n舶\n薄\n迫\n曝\n漠\n爆\n縛\n莫\n駁\n麦\n函\n箱\n硲\n箸\n肇\n筈\n櫨\n幡\n肌\n畑\n畠\n八\n鉢\n溌\n発\n醗\n髪\n伐\n罰\n抜\n筏\n閥\n鳩\n噺\n塙\n蛤\n隼\n伴\n判\n半\n反\n叛\n帆\n搬\n斑\n板\n氾\n汎\n版\n犯\n班\n畔\n繁\n般\n藩\n販\n範\n釆\n煩\n頒\n飯\n挽\n晩\n番\n盤\n磐\n蕃\n蛮\n匪\n卑\n否\n妃\n庇\n彼\n悲\n扉\n批\n披\n斐\n比\n泌\n疲\n皮\n碑\n秘\n緋\n罷\n肥\n被\n誹\n費\n避\n非\n飛\n樋\n簸\n備\n尾\n微\n枇\n毘\n琵\n眉\n美\n鼻\n柊\n稗\n匹\n疋\n髭\n彦\n膝\n菱\n肘\n弼\n必\n畢\n筆\n逼\n桧\n姫\n媛\n紐\n百\n謬\n俵\n彪\n標\n氷\n漂\n瓢\n票\n表\n評\n豹\n廟\n描\n病\n秒\n苗\n錨\n鋲\n蒜\n蛭\n鰭\n品\n彬\n斌\n浜\n瀕\n貧\n賓\n頻\n敏\n瓶\n不\n付\n埠\n夫\n婦\n富\n冨\n布\n府\n怖\n扶\n敷\n斧\n普\n浮\n父\n符\n腐\n膚\n芙\n譜\n負\n賦\n赴\n阜\n附\n侮\n撫\n武\n舞\n葡\n蕪\n部\n封\n楓\n風\n葺\n蕗\n伏\n副\n復\n幅\n服\n福\n腹\n複\n覆\n淵\n弗\n払\n沸\n仏\n物\n鮒\n分\n吻\n噴\n墳\n憤\n扮\n焚\n奮\n粉\n糞\n紛\n雰\n文\n聞\n丙\n併\n兵\n塀\n幣\n平\n弊\n柄\n並\n蔽\n閉\n陛\n米\n頁\n僻\n壁\n癖\n碧\n別\n瞥\n蔑\n箆\n偏\n変\n片\n篇\n編\n辺\n返\n遍\n便\n勉\n娩\n弁\n鞭\n保\n舗\n鋪\n圃\n捕\n歩\n甫\n補\n輔\n穂\n募\n墓\n慕\n戊\n暮\n母\n簿\n菩\n倣\n俸\n包\n呆\n報\n奉\n宝\n峰\n峯\n崩\n庖\n抱\n捧\n放\n方\n朋\n法\n泡\n烹\n砲\n縫\n胞\n芳\n萌\n蓬\n蜂\n褒\n訪\n豊\n邦\n鋒\n飽\n鳳\n鵬\n乏\n亡\n傍\n剖\n坊\n妨\n帽\n忘\n忙\n房\n暴\n望\n某\n棒\n冒\n紡\n肪\n膨\n謀\n貌\n貿\n鉾\n防\n吠\n頬\n北\n僕\n卜\n墨\n撲\n朴\n牧\n睦\n穆\n釦\n勃\n没\n殆\n堀\n幌\n奔\n本\n翻\n凡\n盆\n摩\n磨\n魔\n麻\n埋\n妹\n昧\n枚\n毎\n哩\n槙\n幕\n膜\n枕\n鮪\n柾\n鱒\n桝\n亦\n俣\n又\n抹\n末\n沫\n迄\n侭\n繭\n麿\n万\n慢\n満\n漫\n蔓\n味\n未\n魅\n巳\n箕\n岬\n密\n蜜\n湊\n蓑\n稔\n脈\n妙\n粍\n民\n眠\n務\n夢\n無\n牟\n矛\n霧\n鵡\n椋\n婿\n娘\n冥\n名\n命\n明\n盟\n迷\n銘\n鳴\n姪\n牝\n滅\n免\n棉\n綿\n緬\n面\n麺\n摸\n模\n茂\n妄\n孟\n毛\n猛\n盲\n網\n耗\n蒙\n儲\n木\n黙\n目\n杢\n勿\n餅\n尤\n戻\n籾\n貰\n問\n悶\n紋\n門\n匁\n也\n冶\n夜\n爺\n耶\n野\n弥\n矢\n厄\n役\n約\n薬\n訳\n躍\n靖\n柳\n薮\n鑓\n愉\n愈\n油\n癒\n諭\n輸\n唯\n佑\n優\n勇\n友\n宥\n幽\n悠\n憂\n揖\n有\n柚\n湧\n涌\n猶\n猷\n由\n祐\n裕\n誘\n遊\n邑\n郵\n雄\n融\n夕\n予\n余\n与\n誉\n輿\n預\n傭\n幼\n妖\n容\n庸\n揚\n揺\n擁\n曜\n楊\n様\n洋\n溶\n熔\n用\n窯\n羊\n耀\n葉\n蓉\n要\n謡\n踊\n遥\n陽\n養\n慾\n抑\n欲\n沃\n浴\n翌\n翼\n淀\n羅\n螺\n裸\n来\n莱\n頼\n雷\n洛\n絡\n落\n酪\n乱\n卵\n嵐\n欄\n濫\n藍\n蘭\n覧\n利\n吏\n履\n李\n梨\n理\n璃\n痢\n裏\n裡\n里\n離\n陸\n律\n率\n立\n葎\n掠\n略\n劉\n流\n溜\n琉\n留\n硫\n粒\n隆\n竜\n龍\n侶\n慮\n旅\n虜\n了\n亮\n僚\n両\n凌\n寮\n料\n梁\n涼\n猟\n療\n瞭\n稜\n糧\n良\n諒\n遼\n量\n陵\n領\n力\n緑\n倫\n厘\n林\n淋\n燐\n琳\n臨\n輪\n隣\n鱗\n麟\n瑠\n塁\n涙\n累\n類\n令\n伶\n例\n冷\n励\n嶺\n怜\n玲\n礼\n苓\n鈴\n隷\n零\n霊\n麗\n齢\n暦\n歴\n列\n劣\n烈\n裂\n廉\n恋\n憐\n漣\n煉\n簾\n練\n聯\n蓮\n連\n錬\n呂\n魯\n櫓\n炉\n賂\n路\n露\n労\n婁\n廊\n弄\n朗\n楼\n榔\n浪\n漏\n牢\n狼\n篭\n老\n聾\n蝋\n郎\n六\n麓\n禄\n肋\n録\n論\n倭\n和\n話\n歪\n賄\n脇\n惑\n枠\n鷲\n亙\n亘\n鰐\n詫\n藁\n蕨\n椀\n湾\n碗\n腕\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n弌\n丐\n丕\n个\n丱\n丶\n丼\n丿\n乂\n乖\n乘\n亂\n亅\n豫\n亊\n舒\n弍\n于\n亞\n亟\n亠\n亢\n亰\n亳\n亶\n从\n仍\n仄\n仆\n仂\n仗\n仞\n仭\n仟\n价\n伉\n佚\n估\n佛\n佝\n佗\n佇\n佶\n侈\n侏\n侘\n佻\n佩\n佰\n侑\n佯\n來\n侖\n儘\n俔\n俟\n俎\n俘\n俛\n俑\n俚\n俐\n俤\n俥\n倚\n倨\n倔\n倪\n倥\n倅\n伜\n俶\n倡\n倩\n倬\n俾\n俯\n們\n倆\n偃\n假\n會\n偕\n偐\n偈\n做\n偖\n偬\n偸\n傀\n傚\n傅\n傴\n傲\n僉\n僊\n傳\n僂\n僖\n僞\n僥\n僭\n僣\n僮\n價\n僵\n儉\n儁\n儂\n儖\n儕\n儔\n儚\n儡\n儺\n儷\n儼\n儻\n儿\n兀\n兒\n兌\n兔\n兢\n竸\n兩\n兪\n兮\n冀\n冂\n囘\n册\n冉\n冏\n冑\n冓\n冕\n冖\n冤\n冦\n冢\n冩\n冪\n冫\n决\n冱\n冲\n冰\n况\n冽\n凅\n凉\n凛\n几\n處\n凩\n凭\n凰\n凵\n凾\n刄\n刋\n刔\n刎\n刧\n刪\n刮\n刳\n刹\n剏\n剄\n剋\n剌\n剞\n剔\n剪\n剴\n剩\n剳\n剿\n剽\n劍\n劔\n劒\n剱\n劈\n劑\n辨\n辧\n劬\n劭\n劼\n劵\n勁\n勍\n勗\n勞\n勣\n勦\n飭\n勠\n勳\n勵\n勸\n勹\n匆\n匈\n甸\n匍\n匐\n匏\n匕\n匚\n匣\n匯\n匱\n匳\n匸\n區\n卆\n卅\n丗\n卉\n卍\n凖\n卞\n卩\n卮\n夘\n卻\n卷\n厂\n厖\n厠\n厦\n厥\n厮\n厰\n厶\n參\n簒\n雙\n叟\n曼\n燮\n叮\n叨\n叭\n叺\n吁\n吽\n呀\n听\n吭\n吼\n吮\n吶\n吩\n吝\n呎\n咏\n呵\n咎\n呟\n呱\n呷\n呰\n咒\n呻\n咀\n呶\n咄\n咐\n咆\n哇\n咢\n咸\n咥\n咬\n哄\n哈\n咨\n咫\n哂\n咤\n咾\n咼\n哘\n哥\n哦\n唏\n唔\n哽\n哮\n哭\n哺\n哢\n唹\n啀\n啣\n啌\n售\n啜\n啅\n啖\n啗\n唸\n唳\n啝\n喙\n喀\n咯\n喊\n喟\n啻\n啾\n喘\n喞\n單\n啼\n喃\n喩\n喇\n喨\n嗚\n嗅\n嗟\n嗄\n嗜\n嗤\n嗔\n嘔\n嗷\n嘖\n嗾\n嗽\n嘛\n嗹\n噎\n噐\n營\n嘴\n嘶\n嘲\n嘸\n噫\n噤\n嘯\n噬\n噪\n嚆\n嚀\n嚊\n嚠\n嚔\n嚏\n嚥\n嚮\n嚶\n嚴\n囂\n嚼\n囁\n囃\n囀\n囈\n囎\n囑\n囓\n囗\n囮\n囹\n圀\n囿\n圄\n圉\n圈\n國\n圍\n圓\n團\n圖\n嗇\n圜\n圦\n圷\n圸\n坎\n圻\n址\n坏\n坩\n埀\n垈\n坡\n坿\n垉\n垓\n垠\n垳\n垤\n垪\n垰\n埃\n埆\n埔\n埒\n埓\n堊\n埖\n埣\n堋\n堙\n堝\n塲\n堡\n塢\n塋\n塰\n毀\n塒\n堽\n塹\n墅\n墹\n墟\n墫\n墺\n壞\n墻\n墸\n墮\n壅\n壓\n壑\n壗\n壙\n壘\n壥\n壜\n壤\n壟\n壯\n壺\n壹\n壻\n壼\n壽\n夂\n夊\n夐\n夛\n梦\n夥\n夬\n夭\n夲\n夸\n夾\n竒\n奕\n奐\n奎\n奚\n奘\n奢\n奠\n奧\n奬\n奩\n奸\n妁\n妝\n佞\n侫\n妣\n妲\n姆\n姨\n姜\n妍\n姙\n姚\n娥\n娟\n娑\n娜\n娉\n娚\n婀\n婬\n婉\n娵\n娶\n婢\n婪\n媚\n媼\n媾\n嫋\n嫂\n媽\n嫣\n嫗\n嫦\n嫩\n嫖\n嫺\n嫻\n嬌\n嬋\n嬖\n嬲\n嫐\n嬪\n嬶\n嬾\n孃\n孅\n孀\n孑\n孕\n孚\n孛\n孥\n孩\n孰\n孳\n孵\n學\n斈\n孺\n宀\n它\n宦\n宸\n寃\n寇\n寉\n寔\n寐\n寤\n實\n寢\n寞\n寥\n寫\n寰\n寶\n寳\n尅\n將\n專\n對\n尓\n尠\n尢\n尨\n尸\n尹\n屁\n屆\n屎\n屓\n屐\n屏\n孱\n屬\n屮\n乢\n屶\n屹\n岌\n岑\n岔\n妛\n岫\n岻\n岶\n岼\n岷\n峅\n岾\n峇\n峙\n峩\n峽\n峺\n峭\n嶌\n峪\n崋\n崕\n崗\n嵜\n崟\n崛\n崑\n崔\n崢\n崚\n崙\n崘\n嵌\n嵒\n嵎\n嵋\n嵬\n嵳\n嵶\n嶇\n嶄\n嶂\n嶢\n嶝\n嶬\n嶮\n嶽\n嶐\n嶷\n嶼\n巉\n巍\n巓\n巒\n巖\n巛\n巫\n已\n巵\n帋\n帚\n帙\n帑\n帛\n帶\n帷\n幄\n幃\n幀\n幎\n幗\n幔\n幟\n幢\n幤\n幇\n幵\n并\n幺\n麼\n广\n庠\n廁\n廂\n廈\n廐\n廏\n廖\n廣\n廝\n廚\n廛\n廢\n廡\n廨\n廩\n廬\n廱\n廳\n廰\n廴\n廸\n廾\n弃\n弉\n彝\n彜\n弋\n弑\n弖\n弩\n弭\n弸\n彁\n彈\n彌\n彎\n弯\n彑\n彖\n彗\n彙\n彡\n彭\n彳\n彷\n徃\n徂\n彿\n徊\n很\n徑\n徇\n從\n徙\n徘\n徠\n徨\n徭\n徼\n忖\n忻\n忤\n忸\n忱\n忝\n悳\n忿\n怡\n恠\n怙\n怐\n怩\n怎\n怱\n怛\n怕\n怫\n怦\n怏\n怺\n恚\n恁\n恪\n恷\n恟\n恊\n恆\n恍\n恣\n恃\n恤\n恂\n恬\n恫\n恙\n悁\n悍\n惧\n悃\n悚\n悄\n悛\n悖\n悗\n悒\n悧\n悋\n惡\n悸\n惠\n惓\n悴\n忰\n悽\n惆\n悵\n惘\n慍\n愕\n愆\n惶\n惷\n愀\n惴\n惺\n愃\n愡\n惻\n惱\n愍\n愎\n慇\n愾\n愨\n愧\n慊\n愿\n愼\n愬\n愴\n愽\n慂\n慄\n慳\n慷\n慘\n慙\n慚\n慫\n慴\n慯\n慥\n慱\n慟\n慝\n慓\n慵\n憙\n憖\n憇\n憬\n憔\n憚\n憊\n憑\n憫\n憮\n懌\n懊\n應\n懷\n懈\n懃\n懆\n憺\n懋\n罹\n懍\n懦\n懣\n懶\n懺\n懴\n懿\n懽\n懼\n懾\n戀\n戈\n戉\n戍\n戌\n戔\n戛\n戞\n戡\n截\n戮\n戰\n戲\n戳\n扁\n扎\n扞\n扣\n扛\n扠\n扨\n扼\n抂\n抉\n找\n抒\n抓\n抖\n拔\n抃\n抔\n拗\n拑\n抻\n拏\n拿\n拆\n擔\n拈\n拜\n拌\n拊\n拂\n拇\n抛\n拉\n挌\n拮\n拱\n挧\n挂\n挈\n拯\n拵\n捐\n挾\n捍\n搜\n捏\n掖\n掎\n掀\n掫\n捶\n掣\n掏\n掉\n掟\n掵\n捫\n捩\n掾\n揩\n揀\n揆\n揣\n揉\n插\n揶\n揄\n搖\n搴\n搆\n搓\n搦\n搶\n攝\n搗\n搨\n搏\n摧\n摯\n摶\n摎\n攪\n撕\n撓\n撥\n撩\n撈\n撼\n據\n擒\n擅\n擇\n撻\n擘\n擂\n擱\n擧\n舉\n擠\n擡\n抬\n擣\n擯\n攬\n擶\n擴\n擲\n擺\n攀\n擽\n攘\n攜\n攅\n攤\n攣\n攫\n攴\n攵\n攷\n收\n攸\n畋\n效\n敖\n敕\n敍\n敘\n敞\n敝\n敲\n數\n斂\n斃\n變\n斛\n斟\n斫\n斷\n旃\n旆\n旁\n旄\n旌\n旒\n旛\n旙\n无\n旡\n旱\n杲\n昊\n昃\n旻\n杳\n昵\n昶\n昴\n昜\n晏\n晄\n晉\n晁\n晞\n晝\n晤\n晧\n晨\n晟\n晢\n晰\n暃\n暈\n暎\n暉\n暄\n暘\n暝\n曁\n暹\n曉\n暾\n暼\n曄\n暸\n曖\n曚\n曠\n昿\n曦\n曩\n曰\n曵\n曷\n朏\n朖\n朞\n朦\n朧\n霸\n朮\n朿\n朶\n杁\n朸\n朷\n杆\n杞\n杠\n杙\n杣\n杤\n枉\n杰\n枩\n杼\n杪\n枌\n枋\n枦\n枡\n枅\n枷\n柯\n枴\n柬\n枳\n柩\n枸\n柤\n柞\n柝\n柢\n柮\n枹\n柎\n柆\n柧\n檜\n栞\n框\n栩\n桀\n桍\n栲\n桎\n梳\n栫\n桙\n档\n桷\n桿\n梟\n梏\n梭\n梔\n條\n梛\n梃\n檮\n梹\n桴\n梵\n梠\n梺\n椏\n梍\n桾\n椁\n棊\n椈\n棘\n椢\n椦\n棡\n椌\n棍\n棔\n棧\n棕\n椶\n椒\n椄\n棗\n棣\n椥\n棹\n棠\n棯\n椨\n椪\n椚\n椣\n椡\n棆\n楹\n楷\n楜\n楸\n楫\n楔\n楾\n楮\n椹\n楴\n椽\n楙\n椰\n楡\n楞\n楝\n榁\n楪\n榲\n榮\n槐\n榿\n槁\n槓\n榾\n槎\n寨\n槊\n槝\n榻\n槃\n榧\n樮\n榑\n榠\n榜\n榕\n榴\n槞\n槨\n樂\n樛\n槿\n權\n槹\n槲\n槧\n樅\n榱\n樞\n槭\n樔\n槫\n樊\n樒\n櫁\n樣\n樓\n橄\n樌\n橲\n樶\n橸\n橇\n橢\n橙\n橦\n橈\n樸\n樢\n檐\n檍\n檠\n檄\n檢\n檣\n檗\n蘗\n檻\n櫃\n櫂\n檸\n檳\n檬\n櫞\n櫑\n櫟\n檪\n櫚\n櫪\n櫻\n欅\n蘖\n櫺\n欒\n欖\n鬱\n欟\n欸\n欷\n盜\n欹\n飮\n歇\n歃\n歉\n歐\n歙\n歔\n歛\n歟\n歡\n歸\n歹\n歿\n殀\n殄\n殃\n殍\n殘\n殕\n殞\n殤\n殪\n殫\n殯\n殲\n殱\n殳\n殷\n殼\n毆\n毋\n毓\n毟\n毬\n毫\n毳\n毯\n麾\n氈\n氓\n气\n氛\n氤\n氣\n汞\n汕\n汢\n汪\n沂\n沍\n沚\n沁\n沛\n汾\n汨\n汳\n沒\n沐\n泄\n泱\n泓\n沽\n泗\n泅\n泝\n沮\n沱\n沾\n沺\n泛\n泯\n泙\n泪\n洟\n衍\n洶\n洫\n洽\n洸\n洙\n洵\n洳\n洒\n洌\n浣\n涓\n浤\n浚\n浹\n浙\n涎\n涕\n濤\n涅\n淹\n渕\n渊\n涵\n淇\n淦\n涸\n淆\n淬\n淞\n淌\n淨\n淒\n淅\n淺\n淙\n淤\n淕\n淪\n淮\n渭\n湮\n渮\n渙\n湲\n湟\n渾\n渣\n湫\n渫\n湶\n湍\n渟\n湃\n渺\n湎\n渤\n滿\n渝\n游\n溂\n溪\n溘\n滉\n溷\n滓\n溽\n溯\n滄\n溲\n滔\n滕\n溏\n溥\n滂\n溟\n潁\n漑\n灌\n滬\n滸\n滾\n漿\n滲\n漱\n滯\n漲\n滌\n漾\n漓\n滷\n澆\n潺\n潸\n澁\n澀\n潯\n潛\n濳\n潭\n澂\n潼\n潘\n澎\n澑\n濂\n潦\n澳\n澣\n澡\n澤\n澹\n濆\n澪\n濟\n濕\n濬\n濔\n濘\n濱\n濮\n濛\n瀉\n瀋\n濺\n瀑\n瀁\n瀏\n濾\n瀛\n瀚\n潴\n瀝\n瀘\n瀟\n瀰\n瀾\n瀲\n灑\n灣\n炙\n炒\n炯\n烱\n炬\n炸\n炳\n炮\n烟\n烋\n烝\n烙\n焉\n烽\n焜\n焙\n煥\n煕\n熈\n煦\n煢\n煌\n煖\n煬\n熏\n燻\n熄\n熕\n熨\n熬\n燗\n熹\n熾\n燒\n燉\n燔\n燎\n燠\n燬\n燧\n燵\n燼\n燹\n燿\n爍\n爐\n爛\n爨\n爭\n爬\n爰\n爲\n爻\n爼\n爿\n牀\n牆\n牋\n牘\n牴\n牾\n犂\n犁\n犇\n犒\n犖\n犢\n犧\n犹\n犲\n狃\n狆\n狄\n狎\n狒\n狢\n狠\n狡\n狹\n狷\n倏\n猗\n猊\n猜\n猖\n猝\n猴\n猯\n猩\n猥\n猾\n獎\n獏\n默\n獗\n獪\n獨\n獰\n獸\n獵\n獻\n獺\n珈\n玳\n珎\n玻\n珀\n珥\n珮\n珞\n璢\n琅\n瑯\n琥\n珸\n琲\n琺\n瑕\n琿\n瑟\n瑙\n瑁\n瑜\n瑩\n瑰\n瑣\n瑪\n瑶\n瑾\n璋\n璞\n璧\n瓊\n瓏\n瓔\n珱\n瓠\n瓣\n瓧\n瓩\n瓮\n瓲\n瓰\n瓱\n瓸\n瓷\n甄\n甃\n甅\n甌\n甎\n甍\n甕\n甓\n甞\n甦\n甬\n甼\n畄\n畍\n畊\n畉\n畛\n畆\n畚\n畩\n畤\n畧\n畫\n畭\n畸\n當\n疆\n疇\n畴\n疊\n疉\n疂\n疔\n疚\n疝\n疥\n疣\n痂\n疳\n痃\n疵\n疽\n疸\n疼\n疱\n痍\n痊\n痒\n痙\n痣\n痞\n痾\n痿\n痼\n瘁\n痰\n痺\n痲\n痳\n瘋\n瘍\n瘉\n瘟\n瘧\n瘠\n瘡\n瘢\n瘤\n瘴\n瘰\n瘻\n癇\n癈\n癆\n癜\n癘\n癡\n癢\n癨\n癩\n癪\n癧\n癬\n癰\n癲\n癶\n癸\n發\n皀\n皃\n皈\n皋\n皎\n皖\n皓\n皙\n皚\n皰\n皴\n皸\n皹\n皺\n盂\n盍\n盖\n盒\n盞\n盡\n盥\n盧\n盪\n蘯\n盻\n眈\n眇\n眄\n眩\n眤\n眞\n眥\n眦\n眛\n眷\n眸\n睇\n睚\n睨\n睫\n睛\n睥\n睿\n睾\n睹\n瞎\n瞋\n瞑\n瞠\n瞞\n瞰\n瞶\n瞹\n瞿\n瞼\n瞽\n瞻\n矇\n矍\n矗\n矚\n矜\n矣\n矮\n矼\n砌\n砒\n礦\n砠\n礪\n硅\n碎\n硴\n碆\n硼\n碚\n碌\n碣\n碵\n碪\n碯\n磑\n磆\n磋\n磔\n碾\n碼\n磅\n磊\n磬\n磧\n磚\n磽\n磴\n礇\n礒\n礑\n礙\n礬\n礫\n祀\n祠\n祗\n祟\n祚\n祕\n祓\n祺\n祿\n禊\n禝\n禧\n齋\n禪\n禮\n禳\n禹\n禺\n秉\n秕\n秧\n秬\n秡\n秣\n稈\n稍\n稘\n稙\n稠\n稟\n禀\n稱\n稻\n稾\n稷\n穃\n穗\n穉\n穡\n穢\n穩\n龝\n穰\n穹\n穽\n窈\n窗\n窕\n窘\n窖\n窩\n竈\n窰\n窶\n竅\n竄\n窿\n邃\n竇\n竊\n竍\n竏\n竕\n竓\n站\n竚\n竝\n竡\n竢\n竦\n竭\n竰\n笂\n笏\n笊\n笆\n笳\n笘\n笙\n笞\n笵\n笨\n笶\n筐\n筺\n笄\n筍\n笋\n筌\n筅\n筵\n筥\n筴\n筧\n筰\n筱\n筬\n筮\n箝\n箘\n箟\n箍\n箜\n箚\n箋\n箒\n箏\n筝\n箙\n篋\n篁\n篌\n篏\n箴\n篆\n篝\n篩\n簑\n簔\n篦\n篥\n籠\n簀\n簇\n簓\n篳\n篷\n簗\n簍\n篶\n簣\n簧\n簪\n簟\n簷\n簫\n簽\n籌\n籃\n籔\n籏\n籀\n籐\n籘\n籟\n籤\n籖\n籥\n籬\n籵\n粃\n粐\n粤\n粭\n粢\n粫\n粡\n粨\n粳\n粲\n粱\n粮\n粹\n粽\n糀\n糅\n糂\n糘\n糒\n糜\n糢\n鬻\n糯\n糲\n糴\n糶\n糺\n紆\n紂\n紜\n紕\n紊\n絅\n絋\n紮\n紲\n紿\n紵\n絆\n絳\n絖\n絎\n絲\n絨\n絮\n絏\n絣\n經\n綉\n絛\n綏\n絽\n綛\n綺\n綮\n綣\n綵\n緇\n綽\n綫\n總\n綢\n綯\n緜\n綸\n綟\n綰\n緘\n緝\n緤\n緞\n緻\n緲\n緡\n縅\n縊\n縣\n縡\n縒\n縱\n縟\n縉\n縋\n縢\n繆\n繦\n縻\n縵\n縹\n繃\n縷\n縲\n縺\n繧\n繝\n繖\n繞\n繙\n繚\n繹\n繪\n繩\n繼\n繻\n纃\n緕\n繽\n辮\n繿\n纈\n纉\n續\n纒\n纐\n纓\n纔\n纖\n纎\n纛\n纜\n缸\n缺\n罅\n罌\n罍\n罎\n罐\n网\n罕\n罔\n罘\n罟\n罠\n罨\n罩\n罧\n罸\n羂\n羆\n羃\n羈\n羇\n羌\n羔\n羞\n羝\n羚\n羣\n羯\n羲\n羹\n羮\n羶\n羸\n譱\n翅\n翆\n翊\n翕\n翔\n翡\n翦\n翩\n翳\n翹\n飜\n耆\n耄\n耋\n耒\n耘\n耙\n耜\n耡\n耨\n耿\n耻\n聊\n聆\n聒\n聘\n聚\n聟\n聢\n聨\n聳\n聲\n聰\n聶\n聹\n聽\n聿\n肄\n肆\n肅\n肛\n肓\n肚\n肭\n冐\n肬\n胛\n胥\n胙\n胝\n胄\n胚\n胖\n脉\n胯\n胱\n脛\n脩\n脣\n脯\n腋\n隋\n腆\n脾\n腓\n腑\n胼\n腱\n腮\n腥\n腦\n腴\n膃\n膈\n膊\n膀\n膂\n膠\n膕\n膤\n膣\n腟\n膓\n膩\n膰\n膵\n膾\n膸\n膽\n臀\n臂\n膺\n臉\n臍\n臑\n臙\n臘\n臈\n臚\n臟\n臠\n臧\n臺\n臻\n臾\n舁\n舂\n舅\n與\n舊\n舍\n舐\n舖\n舩\n舫\n舸\n舳\n艀\n艙\n艘\n艝\n艚\n艟\n艤\n艢\n艨\n艪\n艫\n舮\n艱\n艷\n艸\n艾\n芍\n芒\n芫\n芟\n芻\n芬\n苡\n苣\n苟\n苒\n苴\n苳\n苺\n莓\n范\n苻\n苹\n苞\n茆\n苜\n茉\n苙\n茵\n茴\n茖\n茲\n茱\n荀\n茹\n荐\n荅\n茯\n茫\n茗\n茘\n莅\n莚\n莪\n莟\n莢\n莖\n茣\n莎\n莇\n莊\n荼\n莵\n荳\n荵\n莠\n莉\n莨\n菴\n萓\n菫\n菎\n菽\n萃\n菘\n萋\n菁\n菷\n萇\n菠\n菲\n萍\n萢\n萠\n莽\n萸\n蔆\n菻\n葭\n萪\n萼\n蕚\n蒄\n葷\n葫\n蒭\n葮\n蒂\n葩\n葆\n萬\n葯\n葹\n萵\n蓊\n葢\n蒹\n蒿\n蒟\n蓙\n蓍\n蒻\n蓚\n蓐\n蓁\n蓆\n蓖\n蒡\n蔡\n蓿\n蓴\n蔗\n蔘\n蔬\n蔟\n蔕\n蔔\n蓼\n蕀\n蕣\n蕘\n蕈\n蕁\n蘂\n蕋\n蕕\n薀\n薤\n薈\n薑\n薊\n薨\n蕭\n薔\n薛\n藪\n薇\n薜\n蕷\n蕾\n薐\n藉\n薺\n藏\n薹\n藐\n藕\n藝\n藥\n藜\n藹\n蘊\n蘓\n蘋\n藾\n藺\n蘆\n蘢\n蘚\n蘰\n蘿\n虍\n乕\n虔\n號\n虧\n虱\n蚓\n蚣\n蚩\n蚪\n蚋\n蚌\n蚶\n蚯\n蛄\n蛆\n蚰\n蛉\n蠣\n蚫\n蛔\n蛞\n蛩\n蛬\n蛟\n蛛\n蛯\n蜒\n蜆\n蜈\n蜀\n蜃\n蛻\n蜑\n蜉\n蜍\n蛹\n蜊\n蜴\n蜿\n蜷\n蜻\n蜥\n蜩\n蜚\n蝠\n蝟\n蝸\n蝌\n蝎\n蝴\n蝗\n蝨\n蝮\n蝙\n蝓\n蝣\n蝪\n蠅\n螢\n螟\n螂\n螯\n蟋\n螽\n蟀\n蟐\n雖\n螫\n蟄\n螳\n蟇\n蟆\n螻\n蟯\n蟲\n蟠\n蠏\n蠍\n蟾\n蟶\n蟷\n蠎\n蟒\n蠑\n蠖\n蠕\n蠢\n蠡\n蠱\n蠶\n蠹\n蠧\n蠻\n衄\n衂\n衒\n衙\n衞\n衢\n衫\n袁\n衾\n袞\n衵\n衽\n袵\n衲\n袂\n袗\n袒\n袮\n袙\n袢\n袍\n袤\n袰\n袿\n袱\n裃\n裄\n裔\n裘\n裙\n裝\n裹\n褂\n裼\n裴\n裨\n裲\n褄\n褌\n褊\n褓\n襃\n褞\n褥\n褪\n褫\n襁\n襄\n褻\n褶\n褸\n襌\n褝\n襠\n襞\n襦\n襤\n襭\n襪\n襯\n襴\n襷\n襾\n覃\n覈\n覊\n覓\n覘\n覡\n覩\n覦\n覬\n覯\n覲\n覺\n覽\n覿\n觀\n觚\n觜\n觝\n觧\n觴\n觸\n訃\n訖\n訐\n訌\n訛\n訝\n訥\n訶\n詁\n詛\n詒\n詆\n詈\n詼\n詭\n詬\n詢\n誅\n誂\n誄\n誨\n誡\n誑\n誥\n誦\n誚\n誣\n諄\n諍\n諂\n諚\n諫\n諳\n諧\n諤\n諱\n謔\n諠\n諢\n諷\n諞\n諛\n謌\n謇\n謚\n諡\n謖\n謐\n謗\n謠\n謳\n鞫\n謦\n謫\n謾\n謨\n譁\n譌\n譏\n譎\n證\n譖\n譛\n譚\n譫\n譟\n譬\n譯\n譴\n譽\n讀\n讌\n讎\n讒\n讓\n讖\n讙\n讚\n谺\n豁\n谿\n豈\n豌\n豎\n豐\n豕\n豢\n豬\n豸\n豺\n貂\n貉\n貅\n貊\n貍\n貎\n貔\n豼\n貘\n戝\n貭\n貪\n貽\n貲\n貳\n貮\n貶\n賈\n賁\n賤\n賣\n賚\n賽\n賺\n賻\n贄\n贅\n贊\n贇\n贏\n贍\n贐\n齎\n贓\n賍\n贔\n贖\n赧\n赭\n赱\n赳\n趁\n趙\n跂\n趾\n趺\n跏\n跚\n跖\n跌\n跛\n跋\n跪\n跫\n跟\n跣\n跼\n踈\n踉\n跿\n踝\n踞\n踐\n踟\n蹂\n踵\n踰\n踴\n蹊\n蹇\n蹉\n蹌\n蹐\n蹈\n蹙\n蹤\n蹠\n踪\n蹣\n蹕\n蹶\n蹲\n蹼\n躁\n躇\n躅\n躄\n躋\n躊\n躓\n躑\n躔\n躙\n躪\n躡\n躬\n躰\n軆\n躱\n躾\n軅\n軈\n軋\n軛\n軣\n軼\n軻\n軫\n軾\n輊\n輅\n輕\n輒\n輙\n輓\n輜\n輟\n輛\n輌\n輦\n輳\n輻\n輹\n轅\n轂\n輾\n轌\n轉\n轆\n轎\n轗\n轜\n轢\n轣\n轤\n辜\n辟\n辣\n辭\n辯\n辷\n迚\n迥\n迢\n迪\n迯\n邇\n迴\n逅\n迹\n迺\n逑\n逕\n逡\n逍\n逞\n逖\n逋\n逧\n逶\n逵\n逹\n迸\n遏\n遐\n遑\n遒\n逎\n遉\n逾\n遖\n遘\n遞\n遨\n遯\n遶\n隨\n遲\n邂\n遽\n邁\n邀\n邊\n邉\n邏\n邨\n邯\n邱\n邵\n郢\n郤\n扈\n郛\n鄂\n鄒\n鄙\n鄲\n鄰\n酊\n酖\n酘\n酣\n酥\n酩\n酳\n酲\n醋\n醉\n醂\n醢\n醫\n醯\n醪\n醵\n醴\n醺\n釀\n釁\n釉\n釋\n釐\n釖\n釟\n釡\n釛\n釼\n釵\n釶\n鈞\n釿\n鈔\n鈬\n鈕\n鈑\n鉞\n鉗\n鉅\n鉉\n鉤\n鉈\n銕\n鈿\n鉋\n鉐\n銜\n銖\n銓\n銛\n鉚\n鋏\n銹\n銷\n鋩\n錏\n鋺\n鍄\n錮\n錙\n錢\n錚\n錣\n錺\n錵\n錻\n鍜\n鍠\n鍼\n鍮\n鍖\n鎰\n鎬\n鎭\n鎔\n鎹\n鏖\n鏗\n鏨\n鏥\n鏘\n鏃\n鏝\n鏐\n鏈\n鏤\n鐚\n鐔\n鐓\n鐃\n鐇\n鐐\n鐶\n鐫\n鐵\n鐡\n鐺\n鑁\n鑒\n鑄\n鑛\n鑠\n鑢\n鑞\n鑪\n鈩\n鑰\n鑵\n鑷\n鑽\n鑚\n鑼\n鑾\n钁\n鑿\n閂\n閇\n閊\n閔\n閖\n閘\n閙\n閠\n閨\n閧\n閭\n閼\n閻\n閹\n閾\n闊\n濶\n闃\n闍\n闌\n闕\n闔\n闖\n關\n闡\n闥\n闢\n阡\n阨\n阮\n阯\n陂\n陌\n陏\n陋\n陷\n陜\n陞\n陝\n陟\n陦\n陲\n陬\n隍\n隘\n隕\n隗\n險\n隧\n隱\n隲\n隰\n隴\n隶\n隸\n隹\n雎\n雋\n雉\n雍\n襍\n雜\n霍\n雕\n雹\n霄\n霆\n霈\n霓\n霎\n霑\n霏\n霖\n霙\n霤\n霪\n霰\n霹\n霽\n霾\n靄\n靆\n靈\n靂\n靉\n靜\n靠\n靤\n靦\n靨\n勒\n靫\n靱\n靹\n鞅\n靼\n鞁\n靺\n鞆\n鞋\n鞏\n鞐\n鞜\n鞨\n鞦\n鞣\n鞳\n鞴\n韃\n韆\n韈\n韋\n韜\n韭\n齏\n韲\n竟\n韶\n韵\n頏\n頌\n頸\n頤\n頡\n頷\n頽\n顆\n顏\n顋\n顫\n顯\n顰\n顱\n顴\n顳\n颪\n颯\n颱\n颶\n飄\n飃\n飆\n飩\n飫\n餃\n餉\n餒\n餔\n餘\n餡\n餝\n餞\n餤\n餠\n餬\n餮\n餽\n餾\n饂\n饉\n饅\n饐\n饋\n饑\n饒\n饌\n饕\n馗\n馘\n馥\n馭\n馮\n馼\n駟\n駛\n駝\n駘\n駑\n駭\n駮\n駱\n駲\n駻\n駸\n騁\n騏\n騅\n駢\n騙\n騫\n騷\n驅\n驂\n驀\n驃\n騾\n驕\n驍\n驛\n驗\n驟\n驢\n驥\n驤\n驩\n驫\n驪\n骭\n骰\n骼\n髀\n髏\n髑\n髓\n體\n髞\n髟\n髢\n髣\n髦\n髯\n髫\n髮\n髴\n髱\n髷\n髻\n鬆\n鬘\n鬚\n鬟\n鬢\n鬣\n鬥\n鬧\n鬨\n鬩\n鬪\n鬮\n鬯\n鬲\n魄\n魃\n魏\n魍\n魎\n魑\n魘\n魴\n鮓\n鮃\n鮑\n鮖\n鮗\n鮟\n鮠\n鮨\n鮴\n鯀\n鯊\n鮹\n鯆\n鯏\n鯑\n鯒\n鯣\n鯢\n鯤\n鯔\n鯡\n鰺\n鯲\n鯱\n鯰\n鰕\n鰔\n鰉\n鰓\n鰌\n鰆\n鰈\n鰒\n鰊\n鰄\n鰮\n鰛\n鰥\n鰤\n鰡\n鰰\n鱇\n鰲\n鱆\n鰾\n鱚\n鱠\n鱧\n鱶\n鱸\n鳧\n鳬\n鳰\n鴉\n鴈\n鳫\n鴃\n鴆\n鴪\n鴦\n鶯\n鴣\n鴟\n鵄\n鴕\n鴒\n鵁\n鴿\n鴾\n鵆\n鵈\n鵝\n鵞\n鵤\n鵑\n鵐\n鵙\n鵲\n鶉\n鶇\n鶫\n鵯\n鵺\n鶚\n鶤\n鶩\n鶲\n鷄\n鷁\n鶻\n鶸\n鶺\n鷆\n鷏\n鷂\n鷙\n鷓\n鷸\n鷦\n鷭\n鷯\n鷽\n鸚\n鸛\n鸞\n鹵\n鹹\n鹽\n麁\n麈\n麋\n麌\n麒\n麕\n麑\n麝\n麥\n麩\n麸\n麪\n麭\n靡\n黌\n黎\n黏\n黐\n黔\n黜\n點\n黝\n黠\n黥\n黨\n黯\n黴\n黶\n黷\n黹\n黻\n黼\n黽\n鼇\n鼈\n皷\n鼕\n鼡\n鼬\n鼾\n齊\n齒\n齔\n齣\n齟\n齠\n齡\n齦\n齧\n齬\n齪\n齷\n齲\n齶\n龕\n龜\n龠\n堯\n槇\n遙\n瑤\n凜\n熙\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n纊\n褜\n鍈\n銈\n蓜\n俉\n炻\n昱\n棈\n鋹\n曻\n彅\n丨\n仡\n仼\n伀\n伃\n伹\n佖\n侒\n侊\n侚\n侔\n俍\n偀\n倢\n俿\n倞\n偆\n偰\n偂\n傔\n僴\n僘\n兊\n兤\n冝\n冾\n凬\n刕\n劜\n劦\n勀\n勛\n匀\n匇\n匤\n卲\n厓\n厲\n叝\n﨎\n咜\n咊\n咩\n哿\n喆\n坙\n坥\n垬\n埈\n埇\n﨏\n塚\n增\n墲\n夋\n奓\n奛\n奝\n奣\n妤\n妺\n孖\n寀\n甯\n寘\n寬\n尞\n岦\n岺\n峵\n崧\n嵓\n﨑\n嵂\n嵭\n嶸\n嶹\n巐\n弡\n弴\n彧\n德\n忞\n恝\n悅\n悊\n惞\n惕\n愠\n惲\n愑\n愷\n愰\n憘\n戓\n抦\n揵\n摠\n撝\n擎\n敎\n昀\n昕\n昻\n昉\n昮\n昞\n昤\n晥\n晗\n晙\n晴\n晳\n暙\n暠\n暲\n暿\n曺\n朎\n朗\n杦\n枻\n桒\n柀\n栁\n桄\n棏\n﨓\n楨\n﨔\n榘\n槢\n樰\n橫\n橆\n橳\n橾\n櫢\n櫤\n毖\n氿\n汜\n沆\n汯\n泚\n洄\n涇\n浯\n涖\n涬\n淏\n淸\n淲\n淼\n渹\n湜\n渧\n渼\n溿\n澈\n澵\n濵\n瀅\n瀇\n瀨\n炅\n炫\n焏\n焄\n煜\n煆\n煇\n凞\n燁\n燾\n犱\n犾\n猤\n猪\n獷\n玽\n珉\n珖\n珣\n珒\n琇\n珵\n琦\n琪\n琩\n琮\n瑢\n璉\n璟\n甁\n畯\n皂\n皜\n皞\n皛\n皦\n益\n睆\n劯\n砡\n硎\n硤\n硺\n礰\n礼\n神\n祥\n禔\n福\n禛\n竑\n竧\n靖\n竫\n箞\n精\n絈\n絜\n綷\n綠\n緖\n繒\n罇\n羡\n羽\n茁\n荢\n荿\n菇\n菶\n葈\n蒴\n蕓\n蕙\n蕫\n﨟\n薰\n蘒\n﨡\n蠇\n裵\n訒\n訷\n詹\n誧\n誾\n諟\n諸\n諶\n譓\n譿\n賰\n賴\n贒\n赶\n﨣\n軏\n﨤\n逸\n遧\n郞\n都\n鄕\n鄧\n釚\n釗\n釞\n釭\n釮\n釤\n釥\n鈆\n鈐\n鈊\n鈺\n鉀\n鈼\n鉎\n鉙\n鉑\n鈹\n鉧\n銧\n鉷\n鉸\n鋧\n鋗\n鋙\n鋐\n﨧\n鋕\n鋠\n鋓\n錥\n錡\n鋻\n﨨\n錞\n鋿\n錝\n錂\n鍰\n鍗\n鎤\n鏆\n鏞\n鏸\n鐱\n鑅\n鑈\n閒\n隆\n﨩\n隝\n隯\n霳\n霻\n靃\n靍\n靏\n靑\n靕\n顗\n顥\n飯\n飼\n餧\n館\n馞\n驎\n髙\n髜\n魵\n魲\n鮏\n鮱\n鮻\n鰀\n鵰\n鵫\n鶴\n鸙\n黑\n�\n�\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\n￢\n￤\n＇\n＂\n�@\n�A\n�B\n�C\n�D\n�E\n�F\n�G\n�H\n�I\n�J\n�K\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n￢\n￤\n＇\n＂\n㈱\n№\n℡\n∵\n纊\n褜\n鍈\n銈\n蓜\n俉\n炻\n昱\n棈\n鋹\n曻\n彅\n丨\n仡\n仼\n伀\n伃\n伹\n佖\n侒\n侊\n侚\n侔\n俍\n偀\n倢\n俿\n倞\n偆\n偰\n偂\n傔\n僴\n僘\n兊\n兤\n冝\n冾\n凬\n刕\n劜\n劦\n勀\n勛\n匀\n匇\n匤\n卲\n厓\n厲\n叝\n﨎\n咜\n咊\n咩\n哿\n喆\n坙\n坥\n垬\n埈\n埇\n﨏\n塚\n增\n墲\n夋\n奓\n奛\n奝\n奣\n妤\n妺\n孖\n寀\n甯\n寘\n寬\n尞\n岦\n岺\n峵\n崧\n嵓\n﨑\n嵂\n嵭\n嶸\n嶹\n巐\n弡\n弴\n彧\n德\n忞\n恝\n悅\n悊\n惞\n惕\n愠\n惲\n愑\n愷\n愰\n憘\n戓\n抦\n揵\n摠\n撝\n擎\n敎\n昀\n昕\n昻\n昉\n昮\n昞\n昤\n晥\n晗\n晙\n晴\n晳\n暙\n暠\n暲\n暿\n曺\n朎\n朗\n杦\n枻\n桒\n柀\n栁\n桄\n棏\n﨓\n楨\n﨔\n榘\n槢\n樰\n橫\n橆\n橳\n橾\n櫢\n櫤\n毖\n氿\n汜\n沆\n汯\n泚\n洄\n涇\n浯\n涖\n涬\n淏\n淸\n淲\n淼\n渹\n湜\n渧\n渼\n溿\n澈\n澵\n濵\n瀅\n瀇\n瀨\n炅\n炫\n焏\n焄\n煜\n煆\n煇\n凞\n燁\n燾\n犱\n犾\n猤\n猪\n獷\n玽\n珉\n珖\n珣\n珒\n琇\n珵\n琦\n琪\n琩\n琮\n瑢\n璉\n璟\n甁\n畯\n皂\n皜\n皞\n皛\n皦\n益\n睆\n劯\n砡\n硎\n硤\n硺\n礰\n礼\n神\n祥\n禔\n福\n禛\n竑\n竧\n靖\n竫\n箞\n精\n絈\n絜\n綷\n綠\n緖\n繒\n罇\n羡\n羽\n茁\n荢\n荿\n菇\n菶\n葈\n蒴\n蕓\n蕙\n蕫\n﨟\n薰\n蘒\n﨡\n蠇\n裵\n訒\n訷\n詹\n誧\n誾\n諟\n諸\n諶\n譓\n譿\n賰\n賴\n贒\n赶\n﨣\n軏\n﨤\n逸\n遧\n郞\n都\n鄕\n鄧\n釚\n釗\n釞\n釭\n釮\n釤\n釥\n鈆\n鈐\n鈊\n鈺\n鉀\n鈼\n鉎\n鉙\n鉑\n鈹\n鉧\n銧\n鉷\n鉸\n鋧\n鋗\n鋙\n鋐\n﨧\n鋕\n鋠\n鋓\n錥\n錡\n鋻\n﨨\n錞\n鋿\n錝\n錂\n鍰\n鍗\n鎤\n鏆\n鏞\n鏸\n鐱\n鑅\n鑈\n閒\n隆\n﨩\n隝\n隯\n霳\n霻\n靃\n靍\n靏\n靑\n靕\n顗\n顥\n飯\n飼\n餧\n館\n馞\n驎\n髙\n髜\n魵\n魲\n鮏\n鮱\n鮻\n鰀\n鵰\n鵫\n鶴\n鸙\n黑\n�L\n�M\n�N\n�O\n�P\n�Q\n�R\n�S\n�T\n�U\n�V\n�W\n�X\n�Y\n�Z\n�[\n�\\\n�]\n�^\n�_\n�`\n�a\n�b\n�c\n�d\n�e\n�f\n�g\n�h\n�i\n�j\n�k\n�l\n�m\n�n\n�o\n�p\n�q\n�r\n�s\n�t\n�u\n�v\n�w\n�x\n�y\n�z\n�{\n�|\n�}\n�~\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n�\n"
  },
  {
    "path": "helix-view/tests/encoding/shift_jis_out.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n　\n、\n。\n，\n．\n・\n：\n；\n？\n！\n゛\n゜\n´\n｀\n¨\n＾\n￣\n＿\nヽ\nヾ\nゝ\nゞ\n〃\n仝\n々\n〆\n〇\nー\n―\n‐\n／\n＼\n～\n∥\n｜\n…\n‥\n‘\n’\n“\n”\n（\n）\n〔\n〕\n［\n］\n｛\n｝\n〈\n〉\n《\n》\n「\n」\n『\n』\n【\n】\n＋\n－\n±\n×\n÷\n＝\n≠\n＜\n＞\n≦\n≧\n∞\n∴\n♂\n♀\n°\n′\n″\n℃\n￥\n＄\n￠\n￡\n％\n＃\n＆\n＊\n＠\n§\n☆\n★\n○\n●\n◎\n◇\n◆\n□\n■\n△\n▲\n▽\n▼\n※\n〒\n→\n←\n↑\n↓\n〓\n∈\n∋\n⊆\n⊇\n⊂\n⊃\n∪\n∩\n∧\n∨\n￢\n⇒\n⇔\n∀\n∃\n∠\n⊥\n⌒\n∂\n∇\n≡\n≒\n≪\n≫\n√\n∽\n∝\n∵\n∫\n∬\nÅ\n‰\n♯\n♭\n♪\n†\n‡\n¶\n◯\n０\n１\n２\n３\n４\n５\n６\n７\n８\n９\nＡ\nＢ\nＣ\nＤ\nＥ\nＦ\nＧ\nＨ\nＩ\nＪ\nＫ\nＬ\nＭ\nＮ\nＯ\nＰ\nＱ\nＲ\nＳ\nＴ\nＵ\nＶ\nＷ\nＸ\nＹ\nＺ\nａ\nｂ\nｃ\nｄ\nｅ\nｆ\nｇ\nｈ\nｉ\nｊ\nｋ\nｌ\nｍ\nｎ\nｏ\nｐ\nｑ\nｒ\nｓ\nｔ\nｕ\nｖ\nｗ\nｘ\nｙ\nｚ\nぁ\nあ\nぃ\nい\nぅ\nう\nぇ\nえ\nぉ\nお\nか\nが\nき\nぎ\nく\nぐ\nけ\nげ\nこ\nご\nさ\nざ\nし\nじ\nす\nず\nせ\nぜ\nそ\nぞ\nた\nだ\nち\nぢ\nっ\nつ\nづ\nて\nで\nと\nど\nな\nに\nぬ\nね\nの\nは\nば\nぱ\nひ\nび\nぴ\nふ\nぶ\nぷ\nへ\nべ\nぺ\nほ\nぼ\nぽ\nま\nみ\nむ\nめ\nも\nゃ\nや\nゅ\nゆ\nょ\nよ\nら\nり\nる\nれ\nろ\nゎ\nわ\nゐ\nゑ\nを\nん\nァ\nア\nィ\nイ\nゥ\nウ\nェ\nエ\nォ\nオ\nカ\nガ\nキ\nギ\nク\nグ\nケ\nゲ\nコ\nゴ\nサ\nザ\nシ\nジ\nス\nズ\nセ\nゼ\nソ\nゾ\nタ\nダ\nチ\nヂ\nッ\nツ\nヅ\nテ\nデ\nト\nド\nナ\nニ\nヌ\nネ\nノ\nハ\nバ\nパ\nヒ\nビ\nピ\nフ\nブ\nプ\nヘ\nベ\nペ\nホ\nボ\nポ\nマ\nミ\nム\nメ\nモ\nャ\nヤ\nュ\nユ\nョ\nヨ\nラ\nリ\nル\nレ\nロ\nヮ\nワ\nヰ\nヱ\nヲ\nン\nヴ\nヵ\nヶ\nΑ\nΒ\nΓ\nΔ\nΕ\nΖ\nΗ\nΘ\nΙ\nΚ\nΛ\nΜ\nΝ\nΞ\nΟ\nΠ\nΡ\nΣ\nΤ\nΥ\nΦ\nΧ\nΨ\nΩ\nα\nβ\nγ\nδ\nε\nζ\nη\nθ\nι\nκ\nλ\nμ\nν\nξ\nο\nπ\nρ\nσ\nτ\nυ\nφ\nχ\nψ\nω\nА\nБ\nВ\nГ\nД\nЕ\nЁ\nЖ\nЗ\nИ\nЙ\nК\nЛ\nМ\nН\nО\nП\nР\nС\nТ\nУ\nФ\nХ\nЦ\nЧ\nШ\nЩ\nЪ\nЫ\nЬ\nЭ\nЮ\nЯ\nа\nб\nв\nг\nд\nе\nё\nж\nз\nи\nй\nк\nл\nм\nн\nо\nп\nр\nс\nт\nу\nф\nх\nц\nч\nш\nщ\nъ\nы\nь\nэ\nю\nя\n─\n│\n┌\n┐\n┘\n└\n├\n┬\n┤\n┴\n┼\n━\n┃\n┏\n┓\n┛\n┗\n┣\n┳\n┫\n┻\n╋\n┠\n┯\n┨\n┷\n┿\n┝\n┰\n┥\n┸\n╂\n①\n②\n③\n④\n⑤\n⑥\n⑦\n⑧\n⑨\n⑩\n⑪\n⑫\n⑬\n⑭\n⑮\n⑯\n⑰\n⑱\n⑲\n⑳\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n㍉\n㌔\n㌢\n㍍\n㌘\n㌧\n㌃\n㌶\n㍑\n㍗\n㌍\n㌦\n㌣\n㌫\n㍊\n㌻\n㎜\n㎝\n㎞\n㎎\n㎏\n㏄\n㎡\n㍻\n〝\n〟\n№\n㏍\n℡\n㊤\n㊥\n㊦\n㊧\n㊨\n㈱\n㈲\n㈹\n㍾\n㍽\n㍼\n≒\n≡\n∫\n∮\n∑\n√\n⊥\n∠\n∟\n⊿\n∵\n∩\n∪\n亜\n唖\n娃\n阿\n哀\n愛\n挨\n姶\n逢\n葵\n茜\n穐\n悪\n握\n渥\n旭\n葦\n芦\n鯵\n梓\n圧\n斡\n扱\n宛\n姐\n虻\n飴\n絢\n綾\n鮎\n或\n粟\n袷\n安\n庵\n按\n暗\n案\n闇\n鞍\n杏\n以\n伊\n位\n依\n偉\n囲\n夷\n委\n威\n尉\n惟\n意\n慰\n易\n椅\n為\n畏\n異\n移\n維\n緯\n胃\n萎\n衣\n謂\n違\n遺\n医\n井\n亥\n域\n育\n郁\n磯\n一\n壱\n溢\n逸\n稲\n茨\n芋\n鰯\n允\n印\n咽\n員\n因\n姻\n引\n飲\n淫\n胤\n蔭\n院\n陰\n隠\n韻\n吋\n右\n宇\n烏\n羽\n迂\n雨\n卯\n鵜\n窺\n丑\n碓\n臼\n渦\n嘘\n唄\n欝\n蔚\n鰻\n姥\n厩\n浦\n瓜\n閏\n噂\n云\n運\n雲\n荏\n餌\n叡\n営\n嬰\n影\n映\n曳\n栄\n永\n泳\n洩\n瑛\n盈\n穎\n頴\n英\n衛\n詠\n鋭\n液\n疫\n益\n駅\n悦\n謁\n越\n閲\n榎\n厭\n円\n園\n堰\n奄\n宴\n延\n怨\n掩\n援\n沿\n演\n炎\n焔\n煙\n燕\n猿\n縁\n艶\n苑\n薗\n遠\n鉛\n鴛\n塩\n於\n汚\n甥\n凹\n央\n奥\n往\n応\n押\n旺\n横\n欧\n殴\n王\n翁\n襖\n鴬\n鴎\n黄\n岡\n沖\n荻\n億\n屋\n憶\n臆\n桶\n牡\n乙\n俺\n卸\n恩\n温\n穏\n音\n下\n化\n仮\n何\n伽\n価\n佳\n加\n可\n嘉\n夏\n嫁\n家\n寡\n科\n暇\n果\n架\n歌\n河\n火\n珂\n禍\n禾\n稼\n箇\n花\n苛\n茄\n荷\n華\n菓\n蝦\n課\n嘩\n貨\n迦\n過\n霞\n蚊\n俄\n峨\n我\n牙\n画\n臥\n芽\n蛾\n賀\n雅\n餓\n駕\n介\n会\n解\n回\n塊\n壊\n廻\n快\n怪\n悔\n恢\n懐\n戒\n拐\n改\n魁\n晦\n械\n海\n灰\n界\n皆\n絵\n芥\n蟹\n開\n階\n貝\n凱\n劾\n外\n咳\n害\n崖\n慨\n概\n涯\n碍\n蓋\n街\n該\n鎧\n骸\n浬\n馨\n蛙\n垣\n柿\n蛎\n鈎\n劃\n嚇\n各\n廓\n拡\n撹\n格\n核\n殻\n獲\n確\n穫\n覚\n角\n赫\n較\n郭\n閣\n隔\n革\n学\n岳\n楽\n額\n顎\n掛\n笠\n樫\n橿\n梶\n鰍\n潟\n割\n喝\n恰\n括\n活\n渇\n滑\n葛\n褐\n轄\n且\n鰹\n叶\n椛\n樺\n鞄\n株\n兜\n竃\n蒲\n釜\n鎌\n噛\n鴨\n栢\n茅\n萱\n粥\n刈\n苅\n瓦\n乾\n侃\n冠\n寒\n刊\n勘\n勧\n巻\n喚\n堪\n姦\n完\n官\n寛\n干\n幹\n患\n感\n慣\n憾\n換\n敢\n柑\n桓\n棺\n款\n歓\n汗\n漢\n澗\n潅\n環\n甘\n監\n看\n竿\n管\n簡\n緩\n缶\n翰\n肝\n艦\n莞\n観\n諌\n貫\n還\n鑑\n間\n閑\n関\n陥\n韓\n館\n舘\n丸\n含\n岸\n巌\n玩\n癌\n眼\n岩\n翫\n贋\n雁\n頑\n顔\n願\n企\n伎\n危\n喜\n器\n基\n奇\n嬉\n寄\n岐\n希\n幾\n忌\n揮\n机\n旗\n既\n期\n棋\n棄\n機\n帰\n毅\n気\n汽\n畿\n祈\n季\n稀\n紀\n徽\n規\n記\n貴\n起\n軌\n輝\n飢\n騎\n鬼\n亀\n偽\n儀\n妓\n宜\n戯\n技\n擬\n欺\n犠\n疑\n祇\n義\n蟻\n誼\n議\n掬\n菊\n鞠\n吉\n吃\n喫\n桔\n橘\n詰\n砧\n杵\n黍\n却\n客\n脚\n虐\n逆\n丘\n久\n仇\n休\n及\n吸\n宮\n弓\n急\n救\n朽\n求\n汲\n泣\n灸\n球\n究\n窮\n笈\n級\n糾\n給\n旧\n牛\n去\n居\n巨\n拒\n拠\n挙\n渠\n虚\n許\n距\n鋸\n漁\n禦\n魚\n亨\n享\n京\n供\n侠\n僑\n兇\n競\n共\n凶\n協\n匡\n卿\n叫\n喬\n境\n峡\n強\n彊\n怯\n恐\n恭\n挟\n教\n橋\n況\n狂\n狭\n矯\n胸\n脅\n興\n蕎\n郷\n鏡\n響\n饗\n驚\n仰\n凝\n尭\n暁\n業\n局\n曲\n極\n玉\n桐\n粁\n僅\n勤\n均\n巾\n錦\n斤\n欣\n欽\n琴\n禁\n禽\n筋\n緊\n芹\n菌\n衿\n襟\n謹\n近\n金\n吟\n銀\n九\n倶\n句\n区\n狗\n玖\n矩\n苦\n躯\n駆\n駈\n駒\n具\n愚\n虞\n喰\n空\n偶\n寓\n遇\n隅\n串\n櫛\n釧\n屑\n屈\n掘\n窟\n沓\n靴\n轡\n窪\n熊\n隈\n粂\n栗\n繰\n桑\n鍬\n勲\n君\n薫\n訓\n群\n軍\n郡\n卦\n袈\n祁\n係\n傾\n刑\n兄\n啓\n圭\n珪\n型\n契\n形\n径\n恵\n慶\n慧\n憩\n掲\n携\n敬\n景\n桂\n渓\n畦\n稽\n系\n経\n継\n繋\n罫\n茎\n荊\n蛍\n計\n詣\n警\n軽\n頚\n鶏\n芸\n迎\n鯨\n劇\n戟\n撃\n激\n隙\n桁\n傑\n欠\n決\n潔\n穴\n結\n血\n訣\n月\n件\n倹\n倦\n健\n兼\n券\n剣\n喧\n圏\n堅\n嫌\n建\n憲\n懸\n拳\n捲\n検\n権\n牽\n犬\n献\n研\n硯\n絹\n県\n肩\n見\n謙\n賢\n軒\n遣\n鍵\n険\n顕\n験\n鹸\n元\n原\n厳\n幻\n弦\n減\n源\n玄\n現\n絃\n舷\n言\n諺\n限\n乎\n個\n古\n呼\n固\n姑\n孤\n己\n庫\n弧\n戸\n故\n枯\n湖\n狐\n糊\n袴\n股\n胡\n菰\n虎\n誇\n跨\n鈷\n雇\n顧\n鼓\n五\n互\n伍\n午\n呉\n吾\n娯\n後\n御\n悟\n梧\n檎\n瑚\n碁\n語\n誤\n護\n醐\n乞\n鯉\n交\n佼\n侯\n候\n倖\n光\n公\n功\n効\n勾\n厚\n口\n向\n后\n喉\n坑\n垢\n好\n孔\n孝\n宏\n工\n巧\n巷\n幸\n広\n庚\n康\n弘\n恒\n慌\n抗\n拘\n控\n攻\n昂\n晃\n更\n杭\n校\n梗\n構\n江\n洪\n浩\n港\n溝\n甲\n皇\n硬\n稿\n糠\n紅\n紘\n絞\n綱\n耕\n考\n肯\n肱\n腔\n膏\n航\n荒\n行\n衡\n講\n貢\n購\n郊\n酵\n鉱\n砿\n鋼\n閤\n降\n項\n香\n高\n鴻\n剛\n劫\n号\n合\n壕\n拷\n濠\n豪\n轟\n麹\n克\n刻\n告\n国\n穀\n酷\n鵠\n黒\n獄\n漉\n腰\n甑\n忽\n惚\n骨\n狛\n込\n此\n頃\n今\n困\n坤\n墾\n婚\n恨\n懇\n昏\n昆\n根\n梱\n混\n痕\n紺\n艮\n魂\n些\n佐\n叉\n唆\n嵯\n左\n差\n査\n沙\n瑳\n砂\n詐\n鎖\n裟\n坐\n座\n挫\n債\n催\n再\n最\n哉\n塞\n妻\n宰\n彩\n才\n採\n栽\n歳\n済\n災\n采\n犀\n砕\n砦\n祭\n斎\n細\n菜\n裁\n載\n際\n剤\n在\n材\n罪\n財\n冴\n坂\n阪\n堺\n榊\n肴\n咲\n崎\n埼\n碕\n鷺\n作\n削\n咋\n搾\n昨\n朔\n柵\n窄\n策\n索\n錯\n桜\n鮭\n笹\n匙\n冊\n刷\n察\n拶\n撮\n擦\n札\n殺\n薩\n雑\n皐\n鯖\n捌\n錆\n鮫\n皿\n晒\n三\n傘\n参\n山\n惨\n撒\n散\n桟\n燦\n珊\n産\n算\n纂\n蚕\n讃\n賛\n酸\n餐\n斬\n暫\n残\n仕\n仔\n伺\n使\n刺\n司\n史\n嗣\n四\n士\n始\n姉\n姿\n子\n屍\n市\n師\n志\n思\n指\n支\n孜\n斯\n施\n旨\n枝\n止\n死\n氏\n獅\n祉\n私\n糸\n紙\n紫\n肢\n脂\n至\n視\n詞\n詩\n試\n誌\n諮\n資\n賜\n雌\n飼\n歯\n事\n似\n侍\n児\n字\n寺\n慈\n持\n時\n次\n滋\n治\n爾\n璽\n痔\n磁\n示\n而\n耳\n自\n蒔\n辞\n汐\n鹿\n式\n識\n鴫\n竺\n軸\n宍\n雫\n七\n叱\n執\n失\n嫉\n室\n悉\n湿\n漆\n疾\n質\n実\n蔀\n篠\n偲\n柴\n芝\n屡\n蕊\n縞\n舎\n写\n射\n捨\n赦\n斜\n煮\n社\n紗\n者\n謝\n車\n遮\n蛇\n邪\n借\n勺\n尺\n杓\n灼\n爵\n酌\n釈\n錫\n若\n寂\n弱\n惹\n主\n取\n守\n手\n朱\n殊\n狩\n珠\n種\n腫\n趣\n酒\n首\n儒\n受\n呪\n寿\n授\n樹\n綬\n需\n囚\n収\n周\n宗\n就\n州\n修\n愁\n拾\n洲\n秀\n秋\n終\n繍\n習\n臭\n舟\n蒐\n衆\n襲\n讐\n蹴\n輯\n週\n酋\n酬\n集\n醜\n什\n住\n充\n十\n従\n戎\n柔\n汁\n渋\n獣\n縦\n重\n銃\n叔\n夙\n宿\n淑\n祝\n縮\n粛\n塾\n熟\n出\n術\n述\n俊\n峻\n春\n瞬\n竣\n舜\n駿\n准\n循\n旬\n楯\n殉\n淳\n準\n潤\n盾\n純\n巡\n遵\n醇\n順\n処\n初\n所\n暑\n曙\n渚\n庶\n緒\n署\n書\n薯\n藷\n諸\n助\n叙\n女\n序\n徐\n恕\n鋤\n除\n傷\n償\n勝\n匠\n升\n召\n哨\n商\n唱\n嘗\n奨\n妾\n娼\n宵\n将\n小\n少\n尚\n庄\n床\n廠\n彰\n承\n抄\n招\n掌\n捷\n昇\n昌\n昭\n晶\n松\n梢\n樟\n樵\n沼\n消\n渉\n湘\n焼\n焦\n照\n症\n省\n硝\n礁\n祥\n称\n章\n笑\n粧\n紹\n肖\n菖\n蒋\n蕉\n衝\n裳\n訟\n証\n詔\n詳\n象\n賞\n醤\n鉦\n鍾\n鐘\n障\n鞘\n上\n丈\n丞\n乗\n冗\n剰\n城\n場\n壌\n嬢\n常\n情\n擾\n条\n杖\n浄\n状\n畳\n穣\n蒸\n譲\n醸\n錠\n嘱\n埴\n飾\n拭\n植\n殖\n燭\n織\n職\n色\n触\n食\n蝕\n辱\n尻\n伸\n信\n侵\n唇\n娠\n寝\n審\n心\n慎\n振\n新\n晋\n森\n榛\n浸\n深\n申\n疹\n真\n神\n秦\n紳\n臣\n芯\n薪\n親\n診\n身\n辛\n進\n針\n震\n人\n仁\n刃\n塵\n壬\n尋\n甚\n尽\n腎\n訊\n迅\n陣\n靭\n笥\n諏\n須\n酢\n図\n厨\n逗\n吹\n垂\n帥\n推\n水\n炊\n睡\n粋\n翠\n衰\n遂\n酔\n錐\n錘\n随\n瑞\n髄\n崇\n嵩\n数\n枢\n趨\n雛\n据\n杉\n椙\n菅\n頗\n雀\n裾\n澄\n摺\n寸\n世\n瀬\n畝\n是\n凄\n制\n勢\n姓\n征\n性\n成\n政\n整\n星\n晴\n棲\n栖\n正\n清\n牲\n生\n盛\n精\n聖\n声\n製\n西\n誠\n誓\n請\n逝\n醒\n青\n静\n斉\n税\n脆\n隻\n席\n惜\n戚\n斥\n昔\n析\n石\n積\n籍\n績\n脊\n責\n赤\n跡\n蹟\n碩\n切\n拙\n接\n摂\n折\n設\n窃\n節\n説\n雪\n絶\n舌\n蝉\n仙\n先\n千\n占\n宣\n専\n尖\n川\n戦\n扇\n撰\n栓\n栴\n泉\n浅\n洗\n染\n潜\n煎\n煽\n旋\n穿\n箭\n線\n繊\n羨\n腺\n舛\n船\n薦\n詮\n賎\n践\n選\n遷\n銭\n銑\n閃\n鮮\n前\n善\n漸\n然\n全\n禅\n繕\n膳\n糎\n噌\n塑\n岨\n措\n曾\n曽\n楚\n狙\n疏\n疎\n礎\n祖\n租\n粗\n素\n組\n蘇\n訴\n阻\n遡\n鼠\n僧\n創\n双\n叢\n倉\n喪\n壮\n奏\n爽\n宋\n層\n匝\n惣\n想\n捜\n掃\n挿\n掻\n操\n早\n曹\n巣\n槍\n槽\n漕\n燥\n争\n痩\n相\n窓\n糟\n総\n綜\n聡\n草\n荘\n葬\n蒼\n藻\n装\n走\n送\n遭\n鎗\n霜\n騒\n像\n増\n憎\n臓\n蔵\n贈\n造\n促\n側\n則\n即\n息\n捉\n束\n測\n足\n速\n俗\n属\n賊\n族\n続\n卒\n袖\n其\n揃\n存\n孫\n尊\n損\n村\n遜\n他\n多\n太\n汰\n詑\n唾\n堕\n妥\n惰\n打\n柁\n舵\n楕\n陀\n駄\n騨\n体\n堆\n対\n耐\n岱\n帯\n待\n怠\n態\n戴\n替\n泰\n滞\n胎\n腿\n苔\n袋\n貸\n退\n逮\n隊\n黛\n鯛\n代\n台\n大\n第\n醍\n題\n鷹\n滝\n瀧\n卓\n啄\n宅\n托\n択\n拓\n沢\n濯\n琢\n託\n鐸\n濁\n諾\n茸\n凧\n蛸\n只\n叩\n但\n達\n辰\n奪\n脱\n巽\n竪\n辿\n棚\n谷\n狸\n鱈\n樽\n誰\n丹\n単\n嘆\n坦\n担\n探\n旦\n歎\n淡\n湛\n炭\n短\n端\n箪\n綻\n耽\n胆\n蛋\n誕\n鍛\n団\n壇\n弾\n断\n暖\n檀\n段\n男\n談\n値\n知\n地\n弛\n恥\n智\n池\n痴\n稚\n置\n致\n蜘\n遅\n馳\n築\n畜\n竹\n筑\n蓄\n逐\n秩\n窒\n茶\n嫡\n着\n中\n仲\n宙\n忠\n抽\n昼\n柱\n注\n虫\n衷\n註\n酎\n鋳\n駐\n樗\n瀦\n猪\n苧\n著\n貯\n丁\n兆\n凋\n喋\n寵\n帖\n帳\n庁\n弔\n張\n彫\n徴\n懲\n挑\n暢\n朝\n潮\n牒\n町\n眺\n聴\n脹\n腸\n蝶\n調\n諜\n超\n跳\n銚\n長\n頂\n鳥\n勅\n捗\n直\n朕\n沈\n珍\n賃\n鎮\n陳\n津\n墜\n椎\n槌\n追\n鎚\n痛\n通\n塚\n栂\n掴\n槻\n佃\n漬\n柘\n辻\n蔦\n綴\n鍔\n椿\n潰\n坪\n壷\n嬬\n紬\n爪\n吊\n釣\n鶴\n亭\n低\n停\n偵\n剃\n貞\n呈\n堤\n定\n帝\n底\n庭\n廷\n弟\n悌\n抵\n挺\n提\n梯\n汀\n碇\n禎\n程\n締\n艇\n訂\n諦\n蹄\n逓\n邸\n鄭\n釘\n鼎\n泥\n摘\n擢\n敵\n滴\n的\n笛\n適\n鏑\n溺\n哲\n徹\n撤\n轍\n迭\n鉄\n典\n填\n天\n展\n店\n添\n纏\n甜\n貼\n転\n顛\n点\n伝\n殿\n澱\n田\n電\n兎\n吐\n堵\n塗\n妬\n屠\n徒\n斗\n杜\n渡\n登\n菟\n賭\n途\n都\n鍍\n砥\n砺\n努\n度\n土\n奴\n怒\n倒\n党\n冬\n凍\n刀\n唐\n塔\n塘\n套\n宕\n島\n嶋\n悼\n投\n搭\n東\n桃\n梼\n棟\n盗\n淘\n湯\n涛\n灯\n燈\n当\n痘\n祷\n等\n答\n筒\n糖\n統\n到\n董\n蕩\n藤\n討\n謄\n豆\n踏\n逃\n透\n鐙\n陶\n頭\n騰\n闘\n働\n動\n同\n堂\n導\n憧\n撞\n洞\n瞳\n童\n胴\n萄\n道\n銅\n峠\n鴇\n匿\n得\n徳\n涜\n特\n督\n禿\n篤\n毒\n独\n読\n栃\n橡\n凸\n突\n椴\n届\n鳶\n苫\n寅\n酉\n瀞\n噸\n屯\n惇\n敦\n沌\n豚\n遁\n頓\n呑\n曇\n鈍\n奈\n那\n内\n乍\n凪\n薙\n謎\n灘\n捺\n鍋\n楢\n馴\n縄\n畷\n南\n楠\n軟\n難\n汝\n二\n尼\n弐\n迩\n匂\n賑\n肉\n虹\n廿\n日\n乳\n入\n如\n尿\n韮\n任\n妊\n忍\n認\n濡\n禰\n祢\n寧\n葱\n猫\n熱\n年\n念\n捻\n撚\n燃\n粘\n乃\n廼\n之\n埜\n嚢\n悩\n濃\n納\n能\n脳\n膿\n農\n覗\n蚤\n巴\n把\n播\n覇\n杷\n波\n派\n琶\n破\n婆\n罵\n芭\n馬\n俳\n廃\n拝\n排\n敗\n杯\n盃\n牌\n背\n肺\n輩\n配\n倍\n培\n媒\n梅\n楳\n煤\n狽\n買\n売\n賠\n陪\n這\n蝿\n秤\n矧\n萩\n伯\n剥\n博\n拍\n柏\n泊\n白\n箔\n粕\n舶\n薄\n迫\n曝\n漠\n爆\n縛\n莫\n駁\n麦\n函\n箱\n硲\n箸\n肇\n筈\n櫨\n幡\n肌\n畑\n畠\n八\n鉢\n溌\n発\n醗\n髪\n伐\n罰\n抜\n筏\n閥\n鳩\n噺\n塙\n蛤\n隼\n伴\n判\n半\n反\n叛\n帆\n搬\n斑\n板\n氾\n汎\n版\n犯\n班\n畔\n繁\n般\n藩\n販\n範\n釆\n煩\n頒\n飯\n挽\n晩\n番\n盤\n磐\n蕃\n蛮\n匪\n卑\n否\n妃\n庇\n彼\n悲\n扉\n批\n披\n斐\n比\n泌\n疲\n皮\n碑\n秘\n緋\n罷\n肥\n被\n誹\n費\n避\n非\n飛\n樋\n簸\n備\n尾\n微\n枇\n毘\n琵\n眉\n美\n鼻\n柊\n稗\n匹\n疋\n髭\n彦\n膝\n菱\n肘\n弼\n必\n畢\n筆\n逼\n桧\n姫\n媛\n紐\n百\n謬\n俵\n彪\n標\n氷\n漂\n瓢\n票\n表\n評\n豹\n廟\n描\n病\n秒\n苗\n錨\n鋲\n蒜\n蛭\n鰭\n品\n彬\n斌\n浜\n瀕\n貧\n賓\n頻\n敏\n瓶\n不\n付\n埠\n夫\n婦\n富\n冨\n布\n府\n怖\n扶\n敷\n斧\n普\n浮\n父\n符\n腐\n膚\n芙\n譜\n負\n賦\n赴\n阜\n附\n侮\n撫\n武\n舞\n葡\n蕪\n部\n封\n楓\n風\n葺\n蕗\n伏\n副\n復\n幅\n服\n福\n腹\n複\n覆\n淵\n弗\n払\n沸\n仏\n物\n鮒\n分\n吻\n噴\n墳\n憤\n扮\n焚\n奮\n粉\n糞\n紛\n雰\n文\n聞\n丙\n併\n兵\n塀\n幣\n平\n弊\n柄\n並\n蔽\n閉\n陛\n米\n頁\n僻\n壁\n癖\n碧\n別\n瞥\n蔑\n箆\n偏\n変\n片\n篇\n編\n辺\n返\n遍\n便\n勉\n娩\n弁\n鞭\n保\n舗\n鋪\n圃\n捕\n歩\n甫\n補\n輔\n穂\n募\n墓\n慕\n戊\n暮\n母\n簿\n菩\n倣\n俸\n包\n呆\n報\n奉\n宝\n峰\n峯\n崩\n庖\n抱\n捧\n放\n方\n朋\n法\n泡\n烹\n砲\n縫\n胞\n芳\n萌\n蓬\n蜂\n褒\n訪\n豊\n邦\n鋒\n飽\n鳳\n鵬\n乏\n亡\n傍\n剖\n坊\n妨\n帽\n忘\n忙\n房\n暴\n望\n某\n棒\n冒\n紡\n肪\n膨\n謀\n貌\n貿\n鉾\n防\n吠\n頬\n北\n僕\n卜\n墨\n撲\n朴\n牧\n睦\n穆\n釦\n勃\n没\n殆\n堀\n幌\n奔\n本\n翻\n凡\n盆\n摩\n磨\n魔\n麻\n埋\n妹\n昧\n枚\n毎\n哩\n槙\n幕\n膜\n枕\n鮪\n柾\n鱒\n桝\n亦\n俣\n又\n抹\n末\n沫\n迄\n侭\n繭\n麿\n万\n慢\n満\n漫\n蔓\n味\n未\n魅\n巳\n箕\n岬\n密\n蜜\n湊\n蓑\n稔\n脈\n妙\n粍\n民\n眠\n務\n夢\n無\n牟\n矛\n霧\n鵡\n椋\n婿\n娘\n冥\n名\n命\n明\n盟\n迷\n銘\n鳴\n姪\n牝\n滅\n免\n棉\n綿\n緬\n面\n麺\n摸\n模\n茂\n妄\n孟\n毛\n猛\n盲\n網\n耗\n蒙\n儲\n木\n黙\n目\n杢\n勿\n餅\n尤\n戻\n籾\n貰\n問\n悶\n紋\n門\n匁\n也\n冶\n夜\n爺\n耶\n野\n弥\n矢\n厄\n役\n約\n薬\n訳\n躍\n靖\n柳\n薮\n鑓\n愉\n愈\n油\n癒\n諭\n輸\n唯\n佑\n優\n勇\n友\n宥\n幽\n悠\n憂\n揖\n有\n柚\n湧\n涌\n猶\n猷\n由\n祐\n裕\n誘\n遊\n邑\n郵\n雄\n融\n夕\n予\n余\n与\n誉\n輿\n預\n傭\n幼\n妖\n容\n庸\n揚\n揺\n擁\n曜\n楊\n様\n洋\n溶\n熔\n用\n窯\n羊\n耀\n葉\n蓉\n要\n謡\n踊\n遥\n陽\n養\n慾\n抑\n欲\n沃\n浴\n翌\n翼\n淀\n羅\n螺\n裸\n来\n莱\n頼\n雷\n洛\n絡\n落\n酪\n乱\n卵\n嵐\n欄\n濫\n藍\n蘭\n覧\n利\n吏\n履\n李\n梨\n理\n璃\n痢\n裏\n裡\n里\n離\n陸\n律\n率\n立\n葎\n掠\n略\n劉\n流\n溜\n琉\n留\n硫\n粒\n隆\n竜\n龍\n侶\n慮\n旅\n虜\n了\n亮\n僚\n両\n凌\n寮\n料\n梁\n涼\n猟\n療\n瞭\n稜\n糧\n良\n諒\n遼\n量\n陵\n領\n力\n緑\n倫\n厘\n林\n淋\n燐\n琳\n臨\n輪\n隣\n鱗\n麟\n瑠\n塁\n涙\n累\n類\n令\n伶\n例\n冷\n励\n嶺\n怜\n玲\n礼\n苓\n鈴\n隷\n零\n霊\n麗\n齢\n暦\n歴\n列\n劣\n烈\n裂\n廉\n恋\n憐\n漣\n煉\n簾\n練\n聯\n蓮\n連\n錬\n呂\n魯\n櫓\n炉\n賂\n路\n露\n労\n婁\n廊\n弄\n朗\n楼\n榔\n浪\n漏\n牢\n狼\n篭\n老\n聾\n蝋\n郎\n六\n麓\n禄\n肋\n録\n論\n倭\n和\n話\n歪\n賄\n脇\n惑\n枠\n鷲\n亙\n亘\n鰐\n詫\n藁\n蕨\n椀\n湾\n碗\n腕\n弌\n丐\n丕\n个\n丱\n丶\n丼\n丿\n乂\n乖\n乘\n亂\n亅\n豫\n亊\n舒\n弍\n于\n亞\n亟\n亠\n亢\n亰\n亳\n亶\n从\n仍\n仄\n仆\n仂\n仗\n仞\n仭\n仟\n价\n伉\n佚\n估\n佛\n佝\n佗\n佇\n佶\n侈\n侏\n侘\n佻\n佩\n佰\n侑\n佯\n來\n侖\n儘\n俔\n俟\n俎\n俘\n俛\n俑\n俚\n俐\n俤\n俥\n倚\n倨\n倔\n倪\n倥\n倅\n伜\n俶\n倡\n倩\n倬\n俾\n俯\n們\n倆\n偃\n假\n會\n偕\n偐\n偈\n做\n偖\n偬\n偸\n傀\n傚\n傅\n傴\n傲\n僉\n僊\n傳\n僂\n僖\n僞\n僥\n僭\n僣\n僮\n價\n僵\n儉\n儁\n儂\n儖\n儕\n儔\n儚\n儡\n儺\n儷\n儼\n儻\n儿\n兀\n兒\n兌\n兔\n兢\n竸\n兩\n兪\n兮\n冀\n冂\n囘\n册\n冉\n冏\n冑\n冓\n冕\n冖\n冤\n冦\n冢\n冩\n冪\n冫\n决\n冱\n冲\n冰\n况\n冽\n凅\n凉\n凛\n几\n處\n凩\n凭\n凰\n凵\n凾\n刄\n刋\n刔\n刎\n刧\n刪\n刮\n刳\n刹\n剏\n剄\n剋\n剌\n剞\n剔\n剪\n剴\n剩\n剳\n剿\n剽\n劍\n劔\n劒\n剱\n劈\n劑\n辨\n辧\n劬\n劭\n劼\n劵\n勁\n勍\n勗\n勞\n勣\n勦\n飭\n勠\n勳\n勵\n勸\n勹\n匆\n匈\n甸\n匍\n匐\n匏\n匕\n匚\n匣\n匯\n匱\n匳\n匸\n區\n卆\n卅\n丗\n卉\n卍\n凖\n卞\n卩\n卮\n夘\n卻\n卷\n厂\n厖\n厠\n厦\n厥\n厮\n厰\n厶\n參\n簒\n雙\n叟\n曼\n燮\n叮\n叨\n叭\n叺\n吁\n吽\n呀\n听\n吭\n吼\n吮\n吶\n吩\n吝\n呎\n咏\n呵\n咎\n呟\n呱\n呷\n呰\n咒\n呻\n咀\n呶\n咄\n咐\n咆\n哇\n咢\n咸\n咥\n咬\n哄\n哈\n咨\n咫\n哂\n咤\n咾\n咼\n哘\n哥\n哦\n唏\n唔\n哽\n哮\n哭\n哺\n哢\n唹\n啀\n啣\n啌\n售\n啜\n啅\n啖\n啗\n唸\n唳\n啝\n喙\n喀\n咯\n喊\n喟\n啻\n啾\n喘\n喞\n單\n啼\n喃\n喩\n喇\n喨\n嗚\n嗅\n嗟\n嗄\n嗜\n嗤\n嗔\n嘔\n嗷\n嘖\n嗾\n嗽\n嘛\n嗹\n噎\n噐\n營\n嘴\n嘶\n嘲\n嘸\n噫\n噤\n嘯\n噬\n噪\n嚆\n嚀\n嚊\n嚠\n嚔\n嚏\n嚥\n嚮\n嚶\n嚴\n囂\n嚼\n囁\n囃\n囀\n囈\n囎\n囑\n囓\n囗\n囮\n囹\n圀\n囿\n圄\n圉\n圈\n國\n圍\n圓\n團\n圖\n嗇\n圜\n圦\n圷\n圸\n坎\n圻\n址\n坏\n坩\n埀\n垈\n坡\n坿\n垉\n垓\n垠\n垳\n垤\n垪\n垰\n埃\n埆\n埔\n埒\n埓\n堊\n埖\n埣\n堋\n堙\n堝\n塲\n堡\n塢\n塋\n塰\n毀\n塒\n堽\n塹\n墅\n墹\n墟\n墫\n墺\n壞\n墻\n墸\n墮\n壅\n壓\n壑\n壗\n壙\n壘\n壥\n壜\n壤\n壟\n壯\n壺\n壹\n壻\n壼\n壽\n夂\n夊\n夐\n夛\n梦\n夥\n夬\n夭\n夲\n夸\n夾\n竒\n奕\n奐\n奎\n奚\n奘\n奢\n奠\n奧\n奬\n奩\n奸\n妁\n妝\n佞\n侫\n妣\n妲\n姆\n姨\n姜\n妍\n姙\n姚\n娥\n娟\n娑\n娜\n娉\n娚\n婀\n婬\n婉\n娵\n娶\n婢\n婪\n媚\n媼\n媾\n嫋\n嫂\n媽\n嫣\n嫗\n嫦\n嫩\n嫖\n嫺\n嫻\n嬌\n嬋\n嬖\n嬲\n嫐\n嬪\n嬶\n嬾\n孃\n孅\n孀\n孑\n孕\n孚\n孛\n孥\n孩\n孰\n孳\n孵\n學\n斈\n孺\n宀\n它\n宦\n宸\n寃\n寇\n寉\n寔\n寐\n寤\n實\n寢\n寞\n寥\n寫\n寰\n寶\n寳\n尅\n將\n專\n對\n尓\n尠\n尢\n尨\n尸\n尹\n屁\n屆\n屎\n屓\n屐\n屏\n孱\n屬\n屮\n乢\n屶\n屹\n岌\n岑\n岔\n妛\n岫\n岻\n岶\n岼\n岷\n峅\n岾\n峇\n峙\n峩\n峽\n峺\n峭\n嶌\n峪\n崋\n崕\n崗\n嵜\n崟\n崛\n崑\n崔\n崢\n崚\n崙\n崘\n嵌\n嵒\n嵎\n嵋\n嵬\n嵳\n嵶\n嶇\n嶄\n嶂\n嶢\n嶝\n嶬\n嶮\n嶽\n嶐\n嶷\n嶼\n巉\n巍\n巓\n巒\n巖\n巛\n巫\n已\n巵\n帋\n帚\n帙\n帑\n帛\n帶\n帷\n幄\n幃\n幀\n幎\n幗\n幔\n幟\n幢\n幤\n幇\n幵\n并\n幺\n麼\n广\n庠\n廁\n廂\n廈\n廐\n廏\n廖\n廣\n廝\n廚\n廛\n廢\n廡\n廨\n廩\n廬\n廱\n廳\n廰\n廴\n廸\n廾\n弃\n弉\n彝\n彜\n弋\n弑\n弖\n弩\n弭\n弸\n彁\n彈\n彌\n彎\n弯\n彑\n彖\n彗\n彙\n彡\n彭\n彳\n彷\n徃\n徂\n彿\n徊\n很\n徑\n徇\n從\n徙\n徘\n徠\n徨\n徭\n徼\n忖\n忻\n忤\n忸\n忱\n忝\n悳\n忿\n怡\n恠\n怙\n怐\n怩\n怎\n怱\n怛\n怕\n怫\n怦\n怏\n怺\n恚\n恁\n恪\n恷\n恟\n恊\n恆\n恍\n恣\n恃\n恤\n恂\n恬\n恫\n恙\n悁\n悍\n惧\n悃\n悚\n悄\n悛\n悖\n悗\n悒\n悧\n悋\n惡\n悸\n惠\n惓\n悴\n忰\n悽\n惆\n悵\n惘\n慍\n愕\n愆\n惶\n惷\n愀\n惴\n惺\n愃\n愡\n惻\n惱\n愍\n愎\n慇\n愾\n愨\n愧\n慊\n愿\n愼\n愬\n愴\n愽\n慂\n慄\n慳\n慷\n慘\n慙\n慚\n慫\n慴\n慯\n慥\n慱\n慟\n慝\n慓\n慵\n憙\n憖\n憇\n憬\n憔\n憚\n憊\n憑\n憫\n憮\n懌\n懊\n應\n懷\n懈\n懃\n懆\n憺\n懋\n罹\n懍\n懦\n懣\n懶\n懺\n懴\n懿\n懽\n懼\n懾\n戀\n戈\n戉\n戍\n戌\n戔\n戛\n戞\n戡\n截\n戮\n戰\n戲\n戳\n扁\n扎\n扞\n扣\n扛\n扠\n扨\n扼\n抂\n抉\n找\n抒\n抓\n抖\n拔\n抃\n抔\n拗\n拑\n抻\n拏\n拿\n拆\n擔\n拈\n拜\n拌\n拊\n拂\n拇\n抛\n拉\n挌\n拮\n拱\n挧\n挂\n挈\n拯\n拵\n捐\n挾\n捍\n搜\n捏\n掖\n掎\n掀\n掫\n捶\n掣\n掏\n掉\n掟\n掵\n捫\n捩\n掾\n揩\n揀\n揆\n揣\n揉\n插\n揶\n揄\n搖\n搴\n搆\n搓\n搦\n搶\n攝\n搗\n搨\n搏\n摧\n摯\n摶\n摎\n攪\n撕\n撓\n撥\n撩\n撈\n撼\n據\n擒\n擅\n擇\n撻\n擘\n擂\n擱\n擧\n舉\n擠\n擡\n抬\n擣\n擯\n攬\n擶\n擴\n擲\n擺\n攀\n擽\n攘\n攜\n攅\n攤\n攣\n攫\n攴\n攵\n攷\n收\n攸\n畋\n效\n敖\n敕\n敍\n敘\n敞\n敝\n敲\n數\n斂\n斃\n變\n斛\n斟\n斫\n斷\n旃\n旆\n旁\n旄\n旌\n旒\n旛\n旙\n无\n旡\n旱\n杲\n昊\n昃\n旻\n杳\n昵\n昶\n昴\n昜\n晏\n晄\n晉\n晁\n晞\n晝\n晤\n晧\n晨\n晟\n晢\n晰\n暃\n暈\n暎\n暉\n暄\n暘\n暝\n曁\n暹\n曉\n暾\n暼\n曄\n暸\n曖\n曚\n曠\n昿\n曦\n曩\n曰\n曵\n曷\n朏\n朖\n朞\n朦\n朧\n霸\n朮\n朿\n朶\n杁\n朸\n朷\n杆\n杞\n杠\n杙\n杣\n杤\n枉\n杰\n枩\n杼\n杪\n枌\n枋\n枦\n枡\n枅\n枷\n柯\n枴\n柬\n枳\n柩\n枸\n柤\n柞\n柝\n柢\n柮\n枹\n柎\n柆\n柧\n檜\n栞\n框\n栩\n桀\n桍\n栲\n桎\n梳\n栫\n桙\n档\n桷\n桿\n梟\n梏\n梭\n梔\n條\n梛\n梃\n檮\n梹\n桴\n梵\n梠\n梺\n椏\n梍\n桾\n椁\n棊\n椈\n棘\n椢\n椦\n棡\n椌\n棍\n棔\n棧\n棕\n椶\n椒\n椄\n棗\n棣\n椥\n棹\n棠\n棯\n椨\n椪\n椚\n椣\n椡\n棆\n楹\n楷\n楜\n楸\n楫\n楔\n楾\n楮\n椹\n楴\n椽\n楙\n椰\n楡\n楞\n楝\n榁\n楪\n榲\n榮\n槐\n榿\n槁\n槓\n榾\n槎\n寨\n槊\n槝\n榻\n槃\n榧\n樮\n榑\n榠\n榜\n榕\n榴\n槞\n槨\n樂\n樛\n槿\n權\n槹\n槲\n槧\n樅\n榱\n樞\n槭\n樔\n槫\n樊\n樒\n櫁\n樣\n樓\n橄\n樌\n橲\n樶\n橸\n橇\n橢\n橙\n橦\n橈\n樸\n樢\n檐\n檍\n檠\n檄\n檢\n檣\n檗\n蘗\n檻\n櫃\n櫂\n檸\n檳\n檬\n櫞\n櫑\n櫟\n檪\n櫚\n櫪\n櫻\n欅\n蘖\n櫺\n欒\n欖\n鬱\n欟\n欸\n欷\n盜\n欹\n飮\n歇\n歃\n歉\n歐\n歙\n歔\n歛\n歟\n歡\n歸\n歹\n歿\n殀\n殄\n殃\n殍\n殘\n殕\n殞\n殤\n殪\n殫\n殯\n殲\n殱\n殳\n殷\n殼\n毆\n毋\n毓\n毟\n毬\n毫\n毳\n毯\n麾\n氈\n氓\n气\n氛\n氤\n氣\n汞\n汕\n汢\n汪\n沂\n沍\n沚\n沁\n沛\n汾\n汨\n汳\n沒\n沐\n泄\n泱\n泓\n沽\n泗\n泅\n泝\n沮\n沱\n沾\n沺\n泛\n泯\n泙\n泪\n洟\n衍\n洶\n洫\n洽\n洸\n洙\n洵\n洳\n洒\n洌\n浣\n涓\n浤\n浚\n浹\n浙\n涎\n涕\n濤\n涅\n淹\n渕\n渊\n涵\n淇\n淦\n涸\n淆\n淬\n淞\n淌\n淨\n淒\n淅\n淺\n淙\n淤\n淕\n淪\n淮\n渭\n湮\n渮\n渙\n湲\n湟\n渾\n渣\n湫\n渫\n湶\n湍\n渟\n湃\n渺\n湎\n渤\n滿\n渝\n游\n溂\n溪\n溘\n滉\n溷\n滓\n溽\n溯\n滄\n溲\n滔\n滕\n溏\n溥\n滂\n溟\n潁\n漑\n灌\n滬\n滸\n滾\n漿\n滲\n漱\n滯\n漲\n滌\n漾\n漓\n滷\n澆\n潺\n潸\n澁\n澀\n潯\n潛\n濳\n潭\n澂\n潼\n潘\n澎\n澑\n濂\n潦\n澳\n澣\n澡\n澤\n澹\n濆\n澪\n濟\n濕\n濬\n濔\n濘\n濱\n濮\n濛\n瀉\n瀋\n濺\n瀑\n瀁\n瀏\n濾\n瀛\n瀚\n潴\n瀝\n瀘\n瀟\n瀰\n瀾\n瀲\n灑\n灣\n炙\n炒\n炯\n烱\n炬\n炸\n炳\n炮\n烟\n烋\n烝\n烙\n焉\n烽\n焜\n焙\n煥\n煕\n熈\n煦\n煢\n煌\n煖\n煬\n熏\n燻\n熄\n熕\n熨\n熬\n燗\n熹\n熾\n燒\n燉\n燔\n燎\n燠\n燬\n燧\n燵\n燼\n燹\n燿\n爍\n爐\n爛\n爨\n爭\n爬\n爰\n爲\n爻\n爼\n爿\n牀\n牆\n牋\n牘\n牴\n牾\n犂\n犁\n犇\n犒\n犖\n犢\n犧\n犹\n犲\n狃\n狆\n狄\n狎\n狒\n狢\n狠\n狡\n狹\n狷\n倏\n猗\n猊\n猜\n猖\n猝\n猴\n猯\n猩\n猥\n猾\n獎\n獏\n默\n獗\n獪\n獨\n獰\n獸\n獵\n獻\n獺\n珈\n玳\n珎\n玻\n珀\n珥\n珮\n珞\n璢\n琅\n瑯\n琥\n珸\n琲\n琺\n瑕\n琿\n瑟\n瑙\n瑁\n瑜\n瑩\n瑰\n瑣\n瑪\n瑶\n瑾\n璋\n璞\n璧\n瓊\n瓏\n瓔\n珱\n瓠\n瓣\n瓧\n瓩\n瓮\n瓲\n瓰\n瓱\n瓸\n瓷\n甄\n甃\n甅\n甌\n甎\n甍\n甕\n甓\n甞\n甦\n甬\n甼\n畄\n畍\n畊\n畉\n畛\n畆\n畚\n畩\n畤\n畧\n畫\n畭\n畸\n當\n疆\n疇\n畴\n疊\n疉\n疂\n疔\n疚\n疝\n疥\n疣\n痂\n疳\n痃\n疵\n疽\n疸\n疼\n疱\n痍\n痊\n痒\n痙\n痣\n痞\n痾\n痿\n痼\n瘁\n痰\n痺\n痲\n痳\n瘋\n瘍\n瘉\n瘟\n瘧\n瘠\n瘡\n瘢\n瘤\n瘴\n瘰\n瘻\n癇\n癈\n癆\n癜\n癘\n癡\n癢\n癨\n癩\n癪\n癧\n癬\n癰\n癲\n癶\n癸\n發\n皀\n皃\n皈\n皋\n皎\n皖\n皓\n皙\n皚\n皰\n皴\n皸\n皹\n皺\n盂\n盍\n盖\n盒\n盞\n盡\n盥\n盧\n盪\n蘯\n盻\n眈\n眇\n眄\n眩\n眤\n眞\n眥\n眦\n眛\n眷\n眸\n睇\n睚\n睨\n睫\n睛\n睥\n睿\n睾\n睹\n瞎\n瞋\n瞑\n瞠\n瞞\n瞰\n瞶\n瞹\n瞿\n瞼\n瞽\n瞻\n矇\n矍\n矗\n矚\n矜\n矣\n矮\n矼\n砌\n砒\n礦\n砠\n礪\n硅\n碎\n硴\n碆\n硼\n碚\n碌\n碣\n碵\n碪\n碯\n磑\n磆\n磋\n磔\n碾\n碼\n磅\n磊\n磬\n磧\n磚\n磽\n磴\n礇\n礒\n礑\n礙\n礬\n礫\n祀\n祠\n祗\n祟\n祚\n祕\n祓\n祺\n祿\n禊\n禝\n禧\n齋\n禪\n禮\n禳\n禹\n禺\n秉\n秕\n秧\n秬\n秡\n秣\n稈\n稍\n稘\n稙\n稠\n稟\n禀\n稱\n稻\n稾\n稷\n穃\n穗\n穉\n穡\n穢\n穩\n龝\n穰\n穹\n穽\n窈\n窗\n窕\n窘\n窖\n窩\n竈\n窰\n窶\n竅\n竄\n窿\n邃\n竇\n竊\n竍\n竏\n竕\n竓\n站\n竚\n竝\n竡\n竢\n竦\n竭\n竰\n笂\n笏\n笊\n笆\n笳\n笘\n笙\n笞\n笵\n笨\n笶\n筐\n筺\n笄\n筍\n笋\n筌\n筅\n筵\n筥\n筴\n筧\n筰\n筱\n筬\n筮\n箝\n箘\n箟\n箍\n箜\n箚\n箋\n箒\n箏\n筝\n箙\n篋\n篁\n篌\n篏\n箴\n篆\n篝\n篩\n簑\n簔\n篦\n篥\n籠\n簀\n簇\n簓\n篳\n篷\n簗\n簍\n篶\n簣\n簧\n簪\n簟\n簷\n簫\n簽\n籌\n籃\n籔\n籏\n籀\n籐\n籘\n籟\n籤\n籖\n籥\n籬\n籵\n粃\n粐\n粤\n粭\n粢\n粫\n粡\n粨\n粳\n粲\n粱\n粮\n粹\n粽\n糀\n糅\n糂\n糘\n糒\n糜\n糢\n鬻\n糯\n糲\n糴\n糶\n糺\n紆\n紂\n紜\n紕\n紊\n絅\n絋\n紮\n紲\n紿\n紵\n絆\n絳\n絖\n絎\n絲\n絨\n絮\n絏\n絣\n經\n綉\n絛\n綏\n絽\n綛\n綺\n綮\n綣\n綵\n緇\n綽\n綫\n總\n綢\n綯\n緜\n綸\n綟\n綰\n緘\n緝\n緤\n緞\n緻\n緲\n緡\n縅\n縊\n縣\n縡\n縒\n縱\n縟\n縉\n縋\n縢\n繆\n繦\n縻\n縵\n縹\n繃\n縷\n縲\n縺\n繧\n繝\n繖\n繞\n繙\n繚\n繹\n繪\n繩\n繼\n繻\n纃\n緕\n繽\n辮\n繿\n纈\n纉\n續\n纒\n纐\n纓\n纔\n纖\n纎\n纛\n纜\n缸\n缺\n罅\n罌\n罍\n罎\n罐\n网\n罕\n罔\n罘\n罟\n罠\n罨\n罩\n罧\n罸\n羂\n羆\n羃\n羈\n羇\n羌\n羔\n羞\n羝\n羚\n羣\n羯\n羲\n羹\n羮\n羶\n羸\n譱\n翅\n翆\n翊\n翕\n翔\n翡\n翦\n翩\n翳\n翹\n飜\n耆\n耄\n耋\n耒\n耘\n耙\n耜\n耡\n耨\n耿\n耻\n聊\n聆\n聒\n聘\n聚\n聟\n聢\n聨\n聳\n聲\n聰\n聶\n聹\n聽\n聿\n肄\n肆\n肅\n肛\n肓\n肚\n肭\n冐\n肬\n胛\n胥\n胙\n胝\n胄\n胚\n胖\n脉\n胯\n胱\n脛\n脩\n脣\n脯\n腋\n隋\n腆\n脾\n腓\n腑\n胼\n腱\n腮\n腥\n腦\n腴\n膃\n膈\n膊\n膀\n膂\n膠\n膕\n膤\n膣\n腟\n膓\n膩\n膰\n膵\n膾\n膸\n膽\n臀\n臂\n膺\n臉\n臍\n臑\n臙\n臘\n臈\n臚\n臟\n臠\n臧\n臺\n臻\n臾\n舁\n舂\n舅\n與\n舊\n舍\n舐\n舖\n舩\n舫\n舸\n舳\n艀\n艙\n艘\n艝\n艚\n艟\n艤\n艢\n艨\n艪\n艫\n舮\n艱\n艷\n艸\n艾\n芍\n芒\n芫\n芟\n芻\n芬\n苡\n苣\n苟\n苒\n苴\n苳\n苺\n莓\n范\n苻\n苹\n苞\n茆\n苜\n茉\n苙\n茵\n茴\n茖\n茲\n茱\n荀\n茹\n荐\n荅\n茯\n茫\n茗\n茘\n莅\n莚\n莪\n莟\n莢\n莖\n茣\n莎\n莇\n莊\n荼\n莵\n荳\n荵\n莠\n莉\n莨\n菴\n萓\n菫\n菎\n菽\n萃\n菘\n萋\n菁\n菷\n萇\n菠\n菲\n萍\n萢\n萠\n莽\n萸\n蔆\n菻\n葭\n萪\n萼\n蕚\n蒄\n葷\n葫\n蒭\n葮\n蒂\n葩\n葆\n萬\n葯\n葹\n萵\n蓊\n葢\n蒹\n蒿\n蒟\n蓙\n蓍\n蒻\n蓚\n蓐\n蓁\n蓆\n蓖\n蒡\n蔡\n蓿\n蓴\n蔗\n蔘\n蔬\n蔟\n蔕\n蔔\n蓼\n蕀\n蕣\n蕘\n蕈\n蕁\n蘂\n蕋\n蕕\n薀\n薤\n薈\n薑\n薊\n薨\n蕭\n薔\n薛\n藪\n薇\n薜\n蕷\n蕾\n薐\n藉\n薺\n藏\n薹\n藐\n藕\n藝\n藥\n藜\n藹\n蘊\n蘓\n蘋\n藾\n藺\n蘆\n蘢\n蘚\n蘰\n蘿\n虍\n乕\n虔\n號\n虧\n虱\n蚓\n蚣\n蚩\n蚪\n蚋\n蚌\n蚶\n蚯\n蛄\n蛆\n蚰\n蛉\n蠣\n蚫\n蛔\n蛞\n蛩\n蛬\n蛟\n蛛\n蛯\n蜒\n蜆\n蜈\n蜀\n蜃\n蛻\n蜑\n蜉\n蜍\n蛹\n蜊\n蜴\n蜿\n蜷\n蜻\n蜥\n蜩\n蜚\n蝠\n蝟\n蝸\n蝌\n蝎\n蝴\n蝗\n蝨\n蝮\n蝙\n蝓\n蝣\n蝪\n蠅\n螢\n螟\n螂\n螯\n蟋\n螽\n蟀\n蟐\n雖\n螫\n蟄\n螳\n蟇\n蟆\n螻\n蟯\n蟲\n蟠\n蠏\n蠍\n蟾\n蟶\n蟷\n蠎\n蟒\n蠑\n蠖\n蠕\n蠢\n蠡\n蠱\n蠶\n蠹\n蠧\n蠻\n衄\n衂\n衒\n衙\n衞\n衢\n衫\n袁\n衾\n袞\n衵\n衽\n袵\n衲\n袂\n袗\n袒\n袮\n袙\n袢\n袍\n袤\n袰\n袿\n袱\n裃\n裄\n裔\n裘\n裙\n裝\n裹\n褂\n裼\n裴\n裨\n裲\n褄\n褌\n褊\n褓\n襃\n褞\n褥\n褪\n褫\n襁\n襄\n褻\n褶\n褸\n襌\n褝\n襠\n襞\n襦\n襤\n襭\n襪\n襯\n襴\n襷\n襾\n覃\n覈\n覊\n覓\n覘\n覡\n覩\n覦\n覬\n覯\n覲\n覺\n覽\n覿\n觀\n觚\n觜\n觝\n觧\n觴\n觸\n訃\n訖\n訐\n訌\n訛\n訝\n訥\n訶\n詁\n詛\n詒\n詆\n詈\n詼\n詭\n詬\n詢\n誅\n誂\n誄\n誨\n誡\n誑\n誥\n誦\n誚\n誣\n諄\n諍\n諂\n諚\n諫\n諳\n諧\n諤\n諱\n謔\n諠\n諢\n諷\n諞\n諛\n謌\n謇\n謚\n諡\n謖\n謐\n謗\n謠\n謳\n鞫\n謦\n謫\n謾\n謨\n譁\n譌\n譏\n譎\n證\n譖\n譛\n譚\n譫\n譟\n譬\n譯\n譴\n譽\n讀\n讌\n讎\n讒\n讓\n讖\n讙\n讚\n谺\n豁\n谿\n豈\n豌\n豎\n豐\n豕\n豢\n豬\n豸\n豺\n貂\n貉\n貅\n貊\n貍\n貎\n貔\n豼\n貘\n戝\n貭\n貪\n貽\n貲\n貳\n貮\n貶\n賈\n賁\n賤\n賣\n賚\n賽\n賺\n賻\n贄\n贅\n贊\n贇\n贏\n贍\n贐\n齎\n贓\n賍\n贔\n贖\n赧\n赭\n赱\n赳\n趁\n趙\n跂\n趾\n趺\n跏\n跚\n跖\n跌\n跛\n跋\n跪\n跫\n跟\n跣\n跼\n踈\n踉\n跿\n踝\n踞\n踐\n踟\n蹂\n踵\n踰\n踴\n蹊\n蹇\n蹉\n蹌\n蹐\n蹈\n蹙\n蹤\n蹠\n踪\n蹣\n蹕\n蹶\n蹲\n蹼\n躁\n躇\n躅\n躄\n躋\n躊\n躓\n躑\n躔\n躙\n躪\n躡\n躬\n躰\n軆\n躱\n躾\n軅\n軈\n軋\n軛\n軣\n軼\n軻\n軫\n軾\n輊\n輅\n輕\n輒\n輙\n輓\n輜\n輟\n輛\n輌\n輦\n輳\n輻\n輹\n轅\n轂\n輾\n轌\n轉\n轆\n轎\n轗\n轜\n轢\n轣\n轤\n辜\n辟\n辣\n辭\n辯\n辷\n迚\n迥\n迢\n迪\n迯\n邇\n迴\n逅\n迹\n迺\n逑\n逕\n逡\n逍\n逞\n逖\n逋\n逧\n逶\n逵\n逹\n迸\n遏\n遐\n遑\n遒\n逎\n遉\n逾\n遖\n遘\n遞\n遨\n遯\n遶\n隨\n遲\n邂\n遽\n邁\n邀\n邊\n邉\n邏\n邨\n邯\n邱\n邵\n郢\n郤\n扈\n郛\n鄂\n鄒\n鄙\n鄲\n鄰\n酊\n酖\n酘\n酣\n酥\n酩\n酳\n酲\n醋\n醉\n醂\n醢\n醫\n醯\n醪\n醵\n醴\n醺\n釀\n釁\n釉\n釋\n釐\n釖\n釟\n釡\n釛\n釼\n釵\n釶\n鈞\n釿\n鈔\n鈬\n鈕\n鈑\n鉞\n鉗\n鉅\n鉉\n鉤\n鉈\n銕\n鈿\n鉋\n鉐\n銜\n銖\n銓\n銛\n鉚\n鋏\n銹\n銷\n鋩\n錏\n鋺\n鍄\n錮\n錙\n錢\n錚\n錣\n錺\n錵\n錻\n鍜\n鍠\n鍼\n鍮\n鍖\n鎰\n鎬\n鎭\n鎔\n鎹\n鏖\n鏗\n鏨\n鏥\n鏘\n鏃\n鏝\n鏐\n鏈\n鏤\n鐚\n鐔\n鐓\n鐃\n鐇\n鐐\n鐶\n鐫\n鐵\n鐡\n鐺\n鑁\n鑒\n鑄\n鑛\n鑠\n鑢\n鑞\n鑪\n鈩\n鑰\n鑵\n鑷\n鑽\n鑚\n鑼\n鑾\n钁\n鑿\n閂\n閇\n閊\n閔\n閖\n閘\n閙\n閠\n閨\n閧\n閭\n閼\n閻\n閹\n閾\n闊\n濶\n闃\n闍\n闌\n闕\n闔\n闖\n關\n闡\n闥\n闢\n阡\n阨\n阮\n阯\n陂\n陌\n陏\n陋\n陷\n陜\n陞\n陝\n陟\n陦\n陲\n陬\n隍\n隘\n隕\n隗\n險\n隧\n隱\n隲\n隰\n隴\n隶\n隸\n隹\n雎\n雋\n雉\n雍\n襍\n雜\n霍\n雕\n雹\n霄\n霆\n霈\n霓\n霎\n霑\n霏\n霖\n霙\n霤\n霪\n霰\n霹\n霽\n霾\n靄\n靆\n靈\n靂\n靉\n靜\n靠\n靤\n靦\n靨\n勒\n靫\n靱\n靹\n鞅\n靼\n鞁\n靺\n鞆\n鞋\n鞏\n鞐\n鞜\n鞨\n鞦\n鞣\n鞳\n鞴\n韃\n韆\n韈\n韋\n韜\n韭\n齏\n韲\n竟\n韶\n韵\n頏\n頌\n頸\n頤\n頡\n頷\n頽\n顆\n顏\n顋\n顫\n顯\n顰\n顱\n顴\n顳\n颪\n颯\n颱\n颶\n飄\n飃\n飆\n飩\n飫\n餃\n餉\n餒\n餔\n餘\n餡\n餝\n餞\n餤\n餠\n餬\n餮\n餽\n餾\n饂\n饉\n饅\n饐\n饋\n饑\n饒\n饌\n饕\n馗\n馘\n馥\n馭\n馮\n馼\n駟\n駛\n駝\n駘\n駑\n駭\n駮\n駱\n駲\n駻\n駸\n騁\n騏\n騅\n駢\n騙\n騫\n騷\n驅\n驂\n驀\n驃\n騾\n驕\n驍\n驛\n驗\n驟\n驢\n驥\n驤\n驩\n驫\n驪\n骭\n骰\n骼\n髀\n髏\n髑\n髓\n體\n髞\n髟\n髢\n髣\n髦\n髯\n髫\n髮\n髴\n髱\n髷\n髻\n鬆\n鬘\n鬚\n鬟\n鬢\n鬣\n鬥\n鬧\n鬨\n鬩\n鬪\n鬮\n鬯\n鬲\n魄\n魃\n魏\n魍\n魎\n魑\n魘\n魴\n鮓\n鮃\n鮑\n鮖\n鮗\n鮟\n鮠\n鮨\n鮴\n鯀\n鯊\n鮹\n鯆\n鯏\n鯑\n鯒\n鯣\n鯢\n鯤\n鯔\n鯡\n鰺\n鯲\n鯱\n鯰\n鰕\n鰔\n鰉\n鰓\n鰌\n鰆\n鰈\n鰒\n鰊\n鰄\n鰮\n鰛\n鰥\n鰤\n鰡\n鰰\n鱇\n鰲\n鱆\n鰾\n鱚\n鱠\n鱧\n鱶\n鱸\n鳧\n鳬\n鳰\n鴉\n鴈\n鳫\n鴃\n鴆\n鴪\n鴦\n鶯\n鴣\n鴟\n鵄\n鴕\n鴒\n鵁\n鴿\n鴾\n鵆\n鵈\n鵝\n鵞\n鵤\n鵑\n鵐\n鵙\n鵲\n鶉\n鶇\n鶫\n鵯\n鵺\n鶚\n鶤\n鶩\n鶲\n鷄\n鷁\n鶻\n鶸\n鶺\n鷆\n鷏\n鷂\n鷙\n鷓\n鷸\n鷦\n鷭\n鷯\n鷽\n鸚\n鸛\n鸞\n鹵\n鹹\n鹽\n麁\n麈\n麋\n麌\n麒\n麕\n麑\n麝\n麥\n麩\n麸\n麪\n麭\n靡\n黌\n黎\n黏\n黐\n黔\n黜\n點\n黝\n黠\n黥\n黨\n黯\n黴\n黶\n黷\n黹\n黻\n黼\n黽\n鼇\n鼈\n皷\n鼕\n鼡\n鼬\n鼾\n齊\n齒\n齔\n齣\n齟\n齠\n齡\n齦\n齧\n齬\n齪\n齷\n齲\n齶\n龕\n龜\n龠\n堯\n槇\n遙\n瑤\n凜\n熙\nⅰ\nⅱ\nⅲ\nⅳ\nⅴ\nⅵ\nⅶ\nⅷ\nⅸ\nⅹ\nⅠ\nⅡ\nⅢ\nⅣ\nⅤ\nⅥ\nⅦ\nⅧ\nⅨ\nⅩ\n￢\n￤\n＇\n＂\n㈱\n№\n℡\n∵\n纊\n褜\n鍈\n銈\n蓜\n俉\n炻\n昱\n棈\n鋹\n曻\n彅\n丨\n仡\n仼\n伀\n伃\n伹\n佖\n侒\n侊\n侚\n侔\n俍\n偀\n倢\n俿\n倞\n偆\n偰\n偂\n傔\n僴\n僘\n兊\n兤\n冝\n冾\n凬\n刕\n劜\n劦\n勀\n勛\n匀\n匇\n匤\n卲\n厓\n厲\n叝\n﨎\n咜\n咊\n咩\n哿\n喆\n坙\n坥\n垬\n埈\n埇\n﨏\n塚\n增\n墲\n夋\n奓\n奛\n奝\n奣\n妤\n妺\n孖\n寀\n甯\n寘\n寬\n尞\n岦\n岺\n峵\n崧\n嵓\n﨑\n嵂\n嵭\n嶸\n嶹\n巐\n弡\n弴\n彧\n德\n忞\n恝\n悅\n悊\n惞\n惕\n愠\n惲\n愑\n愷\n愰\n憘\n戓\n抦\n揵\n摠\n撝\n擎\n敎\n昀\n昕\n昻\n昉\n昮\n昞\n昤\n晥\n晗\n晙\n晴\n晳\n暙\n暠\n暲\n暿\n曺\n朎\n朗\n杦\n枻\n桒\n柀\n栁\n桄\n棏\n﨓\n楨\n﨔\n榘\n槢\n樰\n橫\n橆\n橳\n橾\n櫢\n櫤\n毖\n氿\n汜\n沆\n汯\n泚\n洄\n涇\n浯\n涖\n涬\n淏\n淸\n淲\n淼\n渹\n湜\n渧\n渼\n溿\n澈\n澵\n濵\n瀅\n瀇\n瀨\n炅\n炫\n焏\n焄\n煜\n煆\n煇\n凞\n燁\n燾\n犱\n犾\n猤\n猪\n獷\n玽\n珉\n珖\n珣\n珒\n琇\n珵\n琦\n琪\n琩\n琮\n瑢\n璉\n璟\n甁\n畯\n皂\n皜\n皞\n皛\n皦\n益\n睆\n劯\n砡\n硎\n硤\n硺\n礰\n礼\n神\n祥\n禔\n福\n禛\n竑\n竧\n靖\n竫\n箞\n精\n絈\n絜\n綷\n綠\n緖\n繒\n罇\n羡\n羽\n茁\n荢\n荿\n菇\n菶\n葈\n蒴\n蕓\n蕙\n蕫\n﨟\n薰\n蘒\n﨡\n蠇\n裵\n訒\n訷\n詹\n誧\n誾\n諟\n諸\n諶\n譓\n譿\n賰\n賴\n贒\n赶\n﨣\n軏\n﨤\n逸\n遧\n郞\n都\n鄕\n鄧\n釚\n釗\n釞\n釭\n釮\n釤\n釥\n鈆\n鈐\n鈊\n鈺\n鉀\n鈼\n鉎\n鉙\n鉑\n鈹\n鉧\n銧\n鉷\n鉸\n鋧\n鋗\n鋙\n鋐\n﨧\n鋕\n鋠\n鋓\n錥\n錡\n鋻\n﨨\n錞\n鋿\n錝\n錂\n鍰\n鍗\n鎤\n鏆\n鏞\n鏸\n鐱\n鑅\n鑈\n閒\n隆\n﨩\n隝\n隯\n霳\n霻\n靃\n靍\n靏\n靑\n靕\n顗\n顥\n飯\n飼\n餧\n館\n馞\n驎\n髙\n髜\n魵\n魲\n鮏\n鮱\n鮻\n鰀\n鵰\n鵫\n鶴\n鸙\n黑\n"
  },
  {
    "path": "helix-view/tests/encoding/shift_jis_out_ref.txt",
    "content": "Generated from WHATWG indexes.json; see LICENSE-WHATWG.\n\nThis is a generated file. Please do not edit.\nInstead, please regenerate using generate-encoding-data.py\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n\nU\nV\nW\n\n\n\n\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ\n[\n\\\n]\n^\n_\n`\na\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n{\n|\n}\n~\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\n"
  },
  {
    "path": "languages.toml",
    "content": "# Language support configuration.\n# See the languages documentation: https://docs.helix-editor.com/master/languages.html\n\nuse-grammars = { except = [ \"wren\", \"gemini\" ] }\n\n[language-server]\n\nada-gpr-language-server = {command = \"ada_language_server\", args = [\"--language-gpr\"]}\nada-language-server = { command = \"ada_language_server\" }\nals = { command = \"als\" }\namber-lsp = { command = \"amber-lsp\" }\nameba-ls = { command = \"ameba-ls\" }\nangular = {command = \"ngserver\", args = [\"--stdio\", \"--tsProbeLocations\", \".\", \"--ngProbeLocations\", \".\",]}\nasm-lsp = { command = \"asm-lsp\" }\nawk-language-server = { command = \"awk-language-server\" }\nbash-language-server = { command = \"bash-language-server\", args = [\"start\"] }\nbass = { command = \"bass\", args = [\"--lsp\"] }\nbeancount-language-server = { command = \"beancount-language-server\" }\nbicep-langserver = { command = \"bicep-langserver\" }\nbitbake-language-server = { command = \"bitbake-language-server\" }\nbuf = { command = \"buf\", args = [\"lsp\", \"serve\", \"--timeout\", \"0\"] }\nc3-lsp = { command = \"c3-lsp\" }\ncairo-language-server = { command = \"cairo-language-server\", args = [] }\ncircom-lsp = { command = \"circom-lsp\" }\ncl-lsp = { command = \"cl-lsp\" }\nclangd = { command = \"clangd\" }\nclojure-lsp = { command = \"clojure-lsp\" }\ncmake-language-server = { command = \"cmake-language-server\" }\ncodeql = { command = \"codeql\", args = [\"execute\", \"language-server\", \"--check-errors=ON_CHANGE\"] }\ncommit-lsp = { command = \"commit-lsp\", args = [\"run\"] }\ncrystalline = { command = \"crystalline\", args = [\"--stdio\"] }\ncs = { command = \"cs\", args = [\"launch\", \"--contrib\", \"smithy-language-server\", \"--\", \"0\"] }\ncsharp-ls = { command = \"csharp-ls\" }\ncuelsp = { command = \"cue\", args = [\"lsp\", \"serve\"] }\ndart = { command = \"dart\", args = [\"language-server\", \"--client-id=helix\"] }\ndhall-lsp-server = { command = \"dhall-lsp-server\" }\ndjlsp = { command = \"djlsp\" }\ndocker-langserver = { command = \"docker-langserver\", args = [\"--stdio\"] }\ndocker-compose-langserver = { command = \"docker-compose-langserver\", args = [\"--stdio\"]}\ndot-language-server = { command = \"dot-language-server\", args = [\"--stdio\"] }\ndts-lsp = { command = \"dts-lsp\" }\nearthlyls = { command = \"earthlyls\" }\neiffel-language-server = {command = \"eiffel-language-server\"}\nelixir-ls = { command = \"elixir-ls\", config = { elixirLS.dialyzerEnabled = false } }\nelm-language-server = { command = \"elm-language-server\" }\nelp = { command = \"elp\", args = [\"server\"] }\nelvish = { command = \"elvish\", args = [\"-lsp\"] }\nerlang-ls = { command = \"erlang_ls\" }\nexpert = { command = \"expert\" }\nfennel-ls = { command = \"fennel-ls\" }\nfish-lsp = { command = \"fish-lsp\", args = [\"start\"] }\nforc = { command = \"forc\", args = [\"lsp\"] }\nforth-lsp = { command = \"forth-lsp\" }\nfortls = { command = \"fortls\", args = [\"--lowercase_intrinsics\"] }\nfsharp-ls = { command = \"fsautocomplete\", config = { AutomaticWorkspaceInit = true } }\ngitlab-ci-ls = { command = \"gitlab-ci-ls\" }\ngleam = { command = \"gleam\", args = [\"lsp\"] }\nglsl_analyzer = { command = \"glsl_analyzer\" }\nglsld = { command = \"glsld\", args = [\"--stdio\"] }\ngraphql-language-service = { command = \"graphql-lsp\", args = [\"server\", \"-m\", \"stream\"] }\nhare-lsp = { command = \"hare-lsp\", args = [\"-S\"] }\nharper-ls = { command = \"harper-ls\", args = [\"--stdio\"] }\nhaskell-language-server = { command = \"haskell-language-server-wrapper\", args = [\"--lsp\"] }\nhdls = { command = \"hdls\" }\nhyprls = { command = \"hyprls\" }\nhyuga = { command = \"hyuga\" }\nidris2-lsp = { command = \"idris2-lsp\" }\nintelephense = { command = \"intelephense\", args = [\"--stdio\"] }\njdtls = { command = \"jdtls\" }\njedi = { command = \"jedi-language-server\" }\njq-lsp = { command = \"jq-lsp\" }\njsonnet-language-server = { command = \"jsonnet-language-server\", args= [\"-t\", \"--lint\"] }\njulia = { command = \"julia\", timeout = 60, args = [ \"--startup-file=no\", \"--history-file=no\", \"--quiet\", \"-e\", \"using LanguageServer; runserver()\", ] }\njust-lsp = { command = \"just-lsp\" }\nkoka = { command = \"koka\", args = [\"--language-server\", \"--lsstdio\"] }\nkoto-ls = { command = \"koto-ls\" }\nkotlin-lsp = { command = \"kotlin-lsp\", args = [\"--stdio\"] }\nkotlin-language-server = { command = \"kotlin-language-server\" }\nlean = { command = \"lake\", args = [\"serve\"] }\nltex-ls = { command = \"ltex-ls\" }\nltex-ls-plus = { command = \"ltex-ls-plus\" }\nmarkdoc-ls = { command = \"markdoc-ls\", args = [\"--stdio\"] }\nmarkdown-oxide = { command = \"markdown-oxide\" }\nmarksman = { command = \"marksman\", args = [\"server\"] }\nmetals = { command = \"metals\", config = { \"isHttpEnabled\" = true, metals = { inlayHints = { typeParameters = {enable = true} , hintsInPatternMatch = {enable = true} }  } } }\nmesonlsp = { command = \"mesonlsp\", args = [\"--lsp\"] }\nmint = { command = \"mint\", args = [\"tool\", \"ls\"] }\nmojo-lsp-server = { command = \"pixi\", args = [\"run\", \"mojo-lsp-server\"] }\nneocmakelsp = { command = \"neocmakelsp\", args = [\"stdio\"] }\nnil = { command = \"nil\" }\nnimlangserver = { command = \"nimlangserver\" }\nnimlsp = { command = \"nimlsp\" }\nnixd = { command = \"nixd\" }\nnls = { command = \"nls\" }\nnu-lint = { command = \"nu-lint\", args = [\"--lsp\"] }\nnu-lsp = { command = \"nu\", args = [ \"--lsp\" ] }\nocamllsp = { command = \"ocamllsp\" }\nols = { command = \"ols\", args = [] }\noxlint-language-server = {command = \"oxlint\", args = [\"--lsp\"]}\nomnisharp = { command = \"OmniSharp\", args = [ \"--languageserver\" ] }\nopenscad-lsp = { command = \"openscad-lsp\", args = [\"--stdio\"] }\npasls = { command = \"pasls\", args = [] }\npbkit = { command = \"pb\", args = [ \"lsp\" ] }\nperlnavigator = { command = \"perlnavigator\", args= [\"--stdio\"] }\npest-language-server = { command = \"pest-language-server\" }\npkl-lsp = { command = \"pkl-lsp\" }\npony-lsp = { command = \"pony-lsp\", args = [\"--stdio\"], config = {defines = [], ponypath = []}}\nprisma-language-server = { command = \"prisma-language-server\", args = [\"--stdio\"], config.prisma.enableDiagnostics = true }\npurescript-language-server = { command = \"purescript-language-server\", args = [\"--stdio\"] }\npylsp = { command = \"pylsp\" }\npyrefly = { command = \"pyrefly\", args = [\"lsp\"] }\npyright = { command = \"pyright-langserver\", args = [\"--stdio\"], config = {} }\nprotols = { command = \"protols\", args = [] }\nbasedpyright = { command = \"basedpyright-langserver\", args = [\"--stdio\"], config = {} }\npylyzer = { command = \"pylyzer\", args = [\"--server\"] }\npytest-language-server = { command = \"pytest-language-server\" }\nqmlls = { command = \"qmlls\" }\nquint-language-server = { command = \"quint-language-server\", args = [\"--stdio\"] }\nr = { command = \"R\", args = [\"--no-echo\", \"-e\", \"languageserver::run()\"] }\nracket = { command = \"racket\", args = [\"-l\", \"racket-langserver\"] }\nregols = { command = \"regols\" }\nrescript-language-server = { command = \"rescript-language-server\", args = [\"--stdio\"] }\nripple-lsp = { command = \"ripple-language-server\", args = [\"--stdio\"] }\nrobotcode = { command = \"robotcode\", args = [\"language-server\", \"--stdio\"] }\nrobotframework_ls = { command = \"robotframework_ls\" }\nron-lsp = { command = \"ron-lsp\" }\nroslyn-language-server = { command = \"roslyn-language-server\", args = [\"--stdio\", \"--autoLoadProjects\"] }\nruff = { command = \"ruff\", args = [\"server\"] }\nruby-lsp = { command = \"ruby-lsp\" }\nrshtml-analyzer = { command = \"rshtml-analyzer\", args = [\"--stdio\"] }\nrumdl = { command = \"rumdl\", args = [\"server\"] }\nserve-d = { command = \"serve-d\" }\nslangd = { command = \"slangd\" }\nslint-lsp = { command = \"slint-lsp\", args = [] }\nsmalisp = { command = \"smalisp\" }\nsystemd-lsp = { command = \"systemd-lsp\" }\nsolargraph = { command = \"solargraph\", args = [\"stdio\"] }\nsolc = { command = \"solc\", args = [\"--lsp\"] }\nsourcekit-lsp = { command = \"sourcekit-lsp\" }\nspade-language-server = {command = \"spade-language-server\"}\nstarpls = {command = \"starpls\"}\nstyx = { command = \"styx\", args = [\"lsp\"] }\nsvlangserver = { command = \"svlangserver\", args = [], config.systemverilog.includeIndexing = [\"*.{v,vh,sv,svh}\", \"**/*.{v,vh,sv,svh}\"] }\nswipl = { command = \"swipl\", args = [ \"-g\", \"use_module(library(lsp_server))\", \"-g\", \"lsp_server:main\", \"-t\", \"halt\", \"--\", \"stdio\" ] }\nsuperhtml = {  command = \"superhtml\", args = [\"lsp\"]}\ntailwindcss-ls = { command = \"tailwindcss-language-server\", args = [\"--stdio\"] }\ntaplo = { command = \"taplo\", args = [\"lsp\", \"stdio\"] }\ntempl = { command = \"templ\", args = [\"lsp\"] }\nterraform-ls = { command = \"terraform-ls\", args = [\"serve\"] }\ntexlab = { command = \"texlab\" }\ntilt = { command = \"tilt\", args = [\"lsp\", \"start\"] }\ntombi = { command = \"tombi\", args = [\"lsp\"] }\nty = { command = \"ty\", args = [\"server\"] }\ntypespec = { command = \"tsp-server\", args = [\"--stdio\"] }\nvala-language-server = { command = \"vala-language-server\" }\nvale-ls = { command = \"vale-ls\" }\nverible-verilog-ls = { command = \"verible-verilog-ls\" }\nvhdl_ls = { command = \"vhdl_ls\", args = [] }\nvlang-language-server = { command = \"v-analyzer\" }\nvscode-css-language-server = { command = \"vscode-css-language-server\", args = [\"--stdio\"], config = { provideFormatter = true, css = { validate = { enable = true } } } }\nvscode-html-language-server = { command = \"vscode-html-language-server\", args = [\"--stdio\"], config = { provideFormatter = true } }\nvscode-json-language-server = { command = \"vscode-json-language-server\", args = [\"--stdio\"], config = { provideFormatter = true, json = { validate = { enable = true } } } }\nvuels = { command = \"vue-language-server\", args = [\"--stdio\"], config = { typescript = { tsdk = \"node_modules/typescript/lib/\" } } }\nwgsl-analyzer = { command = \"wgsl-analyzer\" }\nwikitext-lsp = { command = \"wikitext-lsp\", args = [\"--stdio\"]}\nyaml-language-server = { command = \"yaml-language-server\", args = [\"--stdio\"] }\nyls = { command = \"yls\", args = [\"-vv\"] }\nzls = { command = \"zls\" }\nblueprint-compiler = { command = \"blueprint-compiler\", args = [\"lsp\"] }\ntinymist = { command = \"tinymist\" }\nts_query_ls = { command = \"ts_query_ls\" }\ntermux-language-server = { command = \"termux-language-server\" }\nhelm_ls = { command = \"helm_ls\", args = [\"serve\"] }\nember-language-server = { command = \"ember-language-server\", args = [\"--stdio\"] }\nteal-language-server = { command = \"teal-language-server\" }\nwasm-language-tools = { command = \"wat_server\" }\nsourcepawn-studio = { command = \"sourcepawn-studio\" }\nluau = { command = \"luau-lsp\", args = [\"lsp\"] }\nzizmor = { command = \"zizmor\", args = [\"--lsp\"]}\n\n[language-server.actions-language-server]\ncommand = \"actions-languageserver\"\nargs = [\"--stdio\"]\n\n[language-server.actions-language-server.config.actions-language-server]\nsessionToken = \"\"\n\n[language-server.ansible-language-server]\ncommand = \"ansible-language-server\"\nargs = [\"--stdio\"]\n\n[language-server.astro-ls]\ncommand = \"astro-ls\"\nargs = [ \"--stdio\" ]\nconfig = { typescript = { tsdk = \"node_modules/typescript/lib\" } }\n\n[language-server.lua-language-server]\ncommand = \"lua-language-server\"\n\n[language-server.lua-language-server.config.Lua.hint]\nenable = true\narrayIndex = \"Enable\"\nsetType = true\nparamName = \"All\"\nparamType = true\nawait = true\n\n[language-server.gopls]\ncommand = \"gopls\"\n\n[language-server.gopls.config.hints]\nassignVariableTypes = true\ncompositeLiteralFields = true\nconstantValues = true\nfunctionTypeParameters = true\nparameterNames = true\nrangeVariableTypes = true\n\n[language-server.golangci-lint-lsp]\ncommand = \"golangci-lint-langserver\"\n\n[language-server.golangci-lint-lsp.config]\ncommand = [\"golangci-lint\", \"run\", \"--output.json.path=stdout\", \"--show-stats=false\", \"--issues-exit-code=1\"]\n\n[language-server.rust-analyzer]\ncommand = \"rust-analyzer\"\n\n[language-server.rust-analyzer.config]\ninlayHints.bindingModeHints.enable = false\ninlayHints.closingBraceHints.minLines = 10\ninlayHints.closureReturnTypeHints.enable = \"with_block\"\ninlayHints.discriminantHints.enable = \"fieldless\"\ninlayHints.lifetimeElisionHints.enable = \"skip_trivial\"\ninlayHints.typeHints.hideClosureInitialization = false\n\n[language-server.rust-analyzer.config.files]\nwatcher = \"server\"\n\n[language-server.typescript-language-server]\ncommand = \"typescript-language-server\"\nargs = [\"--stdio\"]\nconfig.hostInfo = \"helix\"\n\n[language-server.typescript-language-server.config.typescript.inlayHints]\nincludeInlayEnumMemberValueHints = true\nincludeInlayFunctionLikeReturnTypeHints = true\nincludeInlayFunctionParameterTypeHints = true\nincludeInlayParameterNameHints = \"all\"\nincludeInlayParameterNameHintsWhenArgumentMatchesName = true\nincludeInlayPropertyDeclarationTypeHints = true\nincludeInlayVariableTypeHints = true\n\n[language-server.typescript-language-server.config.javascript.inlayHints]\nincludeInlayEnumMemberValueHints = true\nincludeInlayFunctionLikeReturnTypeHints = true\nincludeInlayFunctionParameterTypeHints = true\nincludeInlayParameterNameHints = \"all\"\nincludeInlayParameterNameHintsWhenArgumentMatchesName = true\nincludeInlayPropertyDeclarationTypeHints = true\nincludeInlayVariableTypeHints = true\n\n[language-server.svelteserver]\ncommand = \"svelteserver\"\nargs = [\"--stdio\"]\n\n[language-server.svelteserver.config.configuration.typescript]\ninlayHints.parameterTypes.enabled = true\ninlayHints.variableTypes.enabled = true\ninlayHints.propertyDeclarationTypes.enabled = true\ninlayHints.functionLikeReturnTypes.enabled = true\ninlayHints.enumMemberValues.enabled = true\ninlayHints.parameterNames.enabled = \"all\"\n\n[language-server.svelteserver.config.configuration.javascript]\ninlayHints.parameterTypes.enabled = true\ninlayHints.variableTypes.enabled = true\ninlayHints.propertyDeclarationTypes.enabled = true\ninlayHints.functionLikeReturnTypes.enabled = true\ninlayHints.enumMemberValues.enabled = true\ninlayHints.parameterNames.enabled = \"all\"\n\n[language-server.vscode-eslint-language-server]\ncommand = \"vscode-eslint-language-server\"\nargs = [\"--stdio\"]\n\n[language-server.vscode-eslint-language-server.config]\nvalidate = \"on\"\nexperimental = { useFlatConfig = false }\nrulesCustomizations = []\nrun = \"onType\"\nproblems = { shortenToSingleLine = false }\nnodePath = \"\"\n\n[language-server.vscode-eslint-language-server.config.codeAction.disableRuleComment]\nenable = true\nlocation = \"separateLine\"\n\n[language-server.vscode-eslint-language-server.config.codeAction.showDocumentation]\nenable = true\n\n[language-server.vscode-eslint-language-server.config.workingDirectory]\nmode = \"location\"\n\n[language-server.clarinet]\ncommand = \"clarinet\"\nargs = [\"lsp\"]\n\n[language-server.docker-language-server]\ncommand = \"docker-language-server\"\nargs = [\"start\", \"--stdio\"]\n\n[language-server.kcl-lsp]\ncommand = \"kcl-language-server\"\nargs = [\"server\", \"--stdio\"]\n\n[language-server.drools-lsp]\ncommand = \"drools-lsp\"\n\n[[language]]\nname = \"rust\"\nscope = \"source.rust\"\ninjection-regex = \"rs|rust\"\nfile-types = [\"rs\"]\nroots = [\"Cargo.toml\", \"Cargo.lock\"]\nshebangs = [\"rust-script\", \"cargo\"]\nauto-format = true\ncomment-tokens = [\"//\", \"///\", \"//!\"]\nblock-comment-tokens = [\n  { start = \"/*\", end = \"*/\" },\n  { start = \"/**\", end = \"*/\" },\n  { start = \"/*!\", end = \"*/\" },\n]\nlanguage-servers = [ \"rust-analyzer\" ]\nindent = { tab-width = 4, unit = \"    \" }\npersistent-diagnostic-sources = [\"rustc\", \"clippy\"]\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n'`' = '`'\n\n[language.debugger]\nname = \"lldb-dap\"\ntransport = \"stdio\"\ncommand = \"lldb-dap\"\n\n[[language.debugger.templates]]\nname = \"binary\"\nrequest = \"launch\"\ncompletion = [ { name = \"binary\", completion = \"filename\" } ]\nargs = { program = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"binary (terminal)\"\nrequest = \"launch\"\ncompletion = [ { name = \"binary\", completion = \"filename\" } ]\nargs = { program = \"{0}\", runInTerminal = true }\n\n[[language.debugger.templates]]\nname = \"attach\"\nrequest = \"attach\"\ncompletion = [ \"pid\" ]\nargs = { pid = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"gdbserver attach\"\nrequest = \"attach\"\ncompletion = [ { name = \"lldb connect url\", default = \"connect://localhost:3333\" }, { name = \"file\", completion = \"filename\" }, \"pid\" ]\nargs = { attachCommands = [ \"platform select remote-gdb-server\", \"platform connect {0}\", \"file {1}\", \"attach {2}\" ] }\n\n[[grammar]]\nname = \"rust\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-rust\", rev = \"261b20226c04ef601adbdf185a800512a5f66291\" }\n\n[[language]]\nname = \"sway\"\nscope = \"source.sway\"\ninjection-regex = \"sway\"\nfile-types = [\"sw\"]\nlanguage-servers = [ \"forc\" ]\nroots = [\"Forc.toml\", \"Forc.lock\"]\nindent = { tab-width = 4, unit = \"    \" }\ncomment-token = \"//\"\n\n[[grammar]]\nname = \"sway\"\nsource = { git = \"https://github.com/FuelLabs/tree-sitter-sway\", rev = \"e491a005ee1d310f4c138bf215afd44cfebf959c\" }\n\n[[language]]\nname = \"toml\"\nscope = \"source.toml\"\ninjection-regex = \"toml\"\nfile-types = [\n  \"toml\",\n  { glob = \"pdm.lock\" },\n  { glob = \"poetry.lock\" },\n  { glob = \"Cargo.lock\" },\n  { glob = \"uv.lock\" },\n  { glob = \"containers.conf\" },\n  { glob = \"containers.conf.d/*.conf\" },\n  { glob = \"containers.conf.modules/*.conf\" },\n  { glob = \"mounts.conf\" },\n  { glob = \"policy.conf\" },\n  { glob = \"registries.conf\" },\n  { glob = \"storage.conf\" },\n]\ncomment-token = \"#\"\nlanguage-servers = [ \"taplo\", \"tombi\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"toml\"\nsource = { git = \"https://github.com/ikatyang/tree-sitter-toml\", rev = \"7cff70bbcbbc62001b465603ca1ea88edd668704\" }\n\n[[language]]\nname = \"awk\"\nscope = \"source.awk\"\ninjection-regex = \"awk\"\nfile-types = [\"awk\", \"gawk\", \"nawk\", \"mawk\"]\ncomment-token = \"#\"\nlanguage-servers = [ \"awk-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"awk\"\nsource = { git = \"https://github.com/Beaglefoot/tree-sitter-awk\", rev = \"a799bc5da7c2a84bc9a06ba5f3540cf1191e4ee3\" }\n\n[[language]]\nname = \"protobuf\"\nscope = \"source.proto\"\ninjection-regex = \"proto\"\nfile-types = [\"proto\"]\nlanguage-servers = [ \"buf\", \"pbkit\", \"protols\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"proto\"\n\n[[grammar]]\nname = \"proto\"\nsource = { git = \"https://github.com/sdoerner/tree-sitter-proto\", rev = \"778ab6ed18a7fcf82c83805a87d63376c51e80bc\"}\n\n[[language]]\nname = \"textproto\"\nfile-types = [\"txtpb\", \"textpb\", \"textproto\"]\ncomment-token = \"#\"\nscope = \"source.textproto\"\nindent = { tab-width = 2, unit = \"  \" }\nformatter = { command = \"txtpbfmt\" }\nauto-format = true\n\n[[grammar]]\nname = \"textproto\"\nsource = { git = \"https://github.com/PorterAtGoogle/tree-sitter-textproto\", rev = \"568471b80fd8793d37ed01865d8c2208a9fefd1b\"}\n\n[[language]]\nname = \"eiffel\"\nscope = \"source.eiffel\"\nfile-types = [\"e\"]\ncomment-token = \"--\"\nlanguage-servers = [\"eiffel-language-server\"]\n\n[[grammar]]\nname = \"eiffel\"\nsource = { git = \"https://github.com/imustafin/tree-sitter-eiffel\", rev = \"d934fb44f1d22bb76be6b56a7b2425ab3b1daf8b\" }\n\n[[language]]\nname = \"elixir\"\nscope = \"source.elixir\"\ninjection-regex = \"(elixir|ex)\"\nfile-types = [\"ex\", \"exs\", { glob = \"mix.lock\" }]\nshebangs = [\"elixir\"]\nroots = [\"mix.exs\", \"mix.lock\"]\ncomment-token = \"#\"\nlanguage-servers = [ \"elixir-ls\", \"expert\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"elixir\"\nsource = { git = \"https://github.com/elixir-lang/tree-sitter-elixir\", rev = \"02a6f7fd4be28dd94ee4dd2ca19cb777053ea74e\" }\n\n[[language]]\nname = \"fennel\"\nscope = \"source.fennel\"\nfile-types = [\"fnl\", \"fnlm\"]\nshebangs = [\"fennel\"]\ncomment-token = \";\"\nlanguage-servers = [\"fennel-ls\"]\nformatter = { command = \"fnlfmt\", args = [\"-\"]}\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"fennel\"\nsource = { git = \"https://github.com/alexmozaidze/tree-sitter-fennel\", rev = \"cfbfa478dc2dbef267ee94ae4323d9c886f45e94\" }\n\n[[language]]\nname = \"fish\"\nscope = \"source.fish\"\ninjection-regex = \"fish\"\nfile-types = [\"fish\"]\nshebangs = [\"fish\"]\ncomment-token = \"#\"\nlanguage-servers = [\"fish-lsp\"]\nindent = { tab-width = 4, unit = \"    \" }\nauto-format = true\nformatter = { command = \"fish_indent\" }\n\n[[grammar]]\nname = \"fish\"\nsource = { git = \"https://github.com/ram02z/tree-sitter-fish\", rev = \"a78aef9abc395c600c38a037ac779afc7e3cc9e0\" }\n\n[[language]]\nname = \"flatbuffers\"\nscope = \"source.flatbuffers\"\ninjection-regex = \"(flatbuffers?|fbs)\"\nfile-types = [\"fbs\"]\ncomment-token = \"//\"\nindent = { tab-width = 2, unit = \" \" }\n\n[[grammar]]\nname = \"flatbuffers\"\nsource = { git = \"https://github.com/yuanchenxi95/tree-sitter-flatbuffers\", rev = \"95e6f9ef101ea97e870bf6eebc0bd1fdfbaf5490\" }\n\n[[language]]\nname = \"mint\"\nscope = \"source.mint\"\ninjection-regex = \"mint\"\nfile-types = [\"mint\"]\nshebangs = []\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"mint\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[language]]\nname = \"mojo\"\nscope = \"source.mojo\"\nroots = [\"pixi.toml\", \"pixi.lock\"]\ninjection-regex = \"mojo\"\nfile-types = [\"mojo\", \"🔥\"]\nlanguage-servers = [ \"mojo-lsp-server\" ]\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\nauto-format = true\nformatter = { command = \"pixi\", args = [\"run\", \"mojo\" , \"format\", \"-q\", \"-\"]}\n\n[[grammar]]\nname = \"mojo\"\nsource = { git = \"https://github.com/lsh/tree-sitter-mojo\", rev = \"3d7c53b8038f9ebbb57cd2e61296180aa5c1cf64\" }\n\n[[language]]\nname = \"janet\"\nscope = \"source.janet\"\ninjection-regex = \"janet\"\nfile-types = [\"cgen\", \"janet\", \"jdn\"]\nshebangs = [\"janet\"]\nroots = [\"project.janet\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nformatter = { command = \"janet-format\" }\ngrammar = \"janet-simple\"\n\n[language.auto-pairs]\n'\"' = '\"'\n'(' = ')'\n'[' = ']'\n'{' = '}'\n\"`\" = \"`\"\n\n[[grammar]]\nname = \"janet-simple\"\nsource = { git = \"https://github.com/sogaiu/tree-sitter-janet-simple\", rev = \"51271e260346878e1a1aa6c506ce6a797b7c25e2\" }\n\n[[language]]\nname = \"json\"\nscope = \"source.json\"\ninjection-regex = \"json\"\nfile-types = [\n  \"json\",\n  \"arb\",\n  \"ipynb\",\n  \"geojson\",\n  \"gltf\",\n  \"webmanifest\",\n  { glob = \"flake.lock\" },\n  { glob = \".babelrc\" },\n  { glob = \".bowerrc\" },\n  { glob = \".jscrc\" },\n  \"js.map\",\n  \"ts.map\",\n  \"css.map\",\n  { glob = \".jslintrc\" },\n  \"jsonl\",\n  { glob = \".vuerc\" },\n  { glob = \"composer.lock\" },\n  { glob = \".watchmanconfig\" },\n  \"avsc\",\n  \"ldtk\",\n  \"ldtkl\",\n  { glob = \".swift-format\" },\n  \"sublime-build\",\n  \"sublime-color-scheme\",\n  \"sublime-commands\",\n  \"sublime-completions\",\n  \"sublime-keymap\",\n  \"sublime-macro\",\n  \"sublime-menu\",\n  \"sublime-mousemap\",\n  \"sublime-project\",\n  \"sublime-settings\",\n  \"sublime-theme\",\n  \"sublime-workspace\",\n  \"code-workspace\",\n  { glob = \".pytest_cache/v/cache/*\" }, # https://docs.pytest.org/en/latest/reference/reference.html#confval-cache_dir\n  { glob = \"devenv.lock\" }, # https://devenv.sh/\n  { glob = \"devbox.lock\" }, # https://www.jetify.com/docs/devbox/\n  { glob = \"manifest.lock\" }, # https://flox.dev/docs/\n  { glob = \"deno.lock\" }, # https://deno.com/\n]\nlanguage-servers = [ \"vscode-json-language-server\" ]\nauto-format = true\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"json\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-json\", rev = \"73076754005a460947cafe8e03a8cf5fa4fa2938\" }\n\n[[language]]\nname = \"jsonc\"\nscope = \"source.json\"\ninjection-regex = \"jsonc\"\nfile-types = [\n  \"jsonc\",\n  { glob = \"{t,j}sconfig.json\" },\n  { glob = \"bun.lock\" },\n  { glob = \".devcontainer.json\" },\n  { glob = \"devcontainer.json\" },\n  { glob = \".vscode/*.json\" },\n]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\ngrammar = \"json\"\nlanguage-servers = [ \"vscode-json-language-server\" ]\nauto-format = true\nindent = { tab-width = 2, unit = \"  \" }\n\n# https://www.w3.org/TR/json-ld/\n[[language]]\nname = \"json-ld\"\nscope = \"source.json-ld\"\ninjection-regex = \"json-ld\"\ngrammar = \"json\"\nfile-types = [\"jsonld\"]\nlanguage-servers = [\"vscode-json-language-server\"]\nauto-format = true\nindent = { tab-width = 2, unit = \"  \" }\n\n[[language]]\nname = \"json5\"\nscope = \"source.json5\"\ninjection-regex = \"json5\"\nfile-types = [\"json5\"]\nlanguage-servers = []\ncomment-token = \"//\"\nindent = { tab-width = 4, unit = \"    \" }\n# https://json5.org\n\n[[grammar]]\nname = \"json5\"\nsource = { git = \"https://github.com/Joakker/tree-sitter-json5\", rev = \"c23f7a9b1ee7d45f516496b1e0e4be067264fa0d\" }\n\n[[language]]\nname = \"c\"\nscope = \"source.c\"\ninjection-regex = \"c\"\nfile-types = [\"c\"] # TODO: [\"h\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"clangd\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.debugger]\nname = \"lldb-dap\"\ntransport = \"stdio\"\ncommand = \"lldb-dap\"\n\n[[language.debugger.templates]]\nname = \"binary\"\nrequest = \"launch\"\ncompletion = [ { name = \"binary\", completion = \"filename\" } ]\nargs = { console = \"internalConsole\", program = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"attach\"\nrequest = \"attach\"\ncompletion = [ \"pid\" ]\nargs = { console = \"internalConsole\", pid = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"gdbserver attach\"\nrequest = \"attach\"\ncompletion = [ { name = \"lldb connect url\", default = \"connect://localhost:3333\" }, { name = \"file\", completion = \"filename\" }, \"pid\" ]\nargs = { console = \"internalConsole\", attachCommands = [ \"platform select remote-gdb-server\", \"platform connect {0}\", \"file {1}\", \"attach {2}\" ] }\n\n[[grammar]]\nname = \"c\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-c\", rev = \"7fa1be1b694b6e763686793d97da01f36a0e5c12\" }\n\n[[language]]\nname = \"cpp\"\nscope = \"source.cpp\"\ninjection-regex = \"cpp\"\nfile-types = [\"cc\", \"hh\", \"c++\", \"cpp\", \"hpp\", \"h\", \"ipp\", \"tpp\", \"cxx\", \"hxx\", \"ixx\", \"txx\", \"ino\", \"C\", \"H\", \"cu\", \"cuh\", \"cppm\", \"h++\", \"ii\", \"inl\", { glob = \".hpp.in\" }, { glob = \".h.in\" }]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"clangd\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.debugger]\nname = \"lldb-dap\"\ntransport = \"stdio\"\ncommand = \"lldb-dap\"\n\n[[language.debugger.templates]]\nname = \"binary\"\nrequest = \"launch\"\ncompletion = [ { name = \"binary\", completion = \"filename\" } ]\nargs = { console = \"internalConsole\", program = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"attach\"\nrequest = \"attach\"\ncompletion = [ \"pid\" ]\nargs = { console = \"internalConsole\", pid = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"gdbserver attach\"\nrequest = \"attach\"\ncompletion = [ { name = \"lldb connect url\", default = \"connect://localhost:3333\" }, { name = \"file\", completion = \"filename\" }, \"pid\" ]\nargs = { console = \"internalConsole\", attachCommands = [ \"platform select remote-gdb-server\", \"platform connect {0}\", \"file {1}\", \"attach {2}\" ] }\n\n[[grammar]]\nname = \"cpp\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-cpp\", rev = \"56455f4245baf4ea4e0881c5169de69d7edd5ae7\" }\n\n[[language]]\nname = \"crystal\"\nscope = \"source.cr\"\nfile-types = [\"cr\"]\nroots = [\"shard.yml\", \"shard.lock\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"crystalline\", \"ameba-ls\" ]\nformatter = { command = \"crystal\", args = [\"tool\", \"format\", \"-\"] }\n\n[[grammar]]\nname = \"crystal\"\nsource = { git = \"https://github.com/crystal-lang-tools/tree-sitter-crystal\", rev = \"76afc1f53518a2b68b51a5abcde01d268a9cb47c\" }\n\n[[language]]\nname = \"c-sharp\"\nscope = \"source.csharp\"\ninjection-regex = \"c-?sharp\"\nfile-types = [\"cs\", \"csx\", \"cake\"]\nroots = [\"*.slnx\", \"*.sln\", \"*.csproj\"]\ncomment-tokens = [\"//\", \"///\"]\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"\\t\" }\nlanguage-servers = [ \"roslyn-language-server\", \"omnisharp\", \"csharp-ls\" ]\n\n[language.debugger]\nname = \"netcoredbg\"\ntransport = \"tcp\"\ncommand = \"netcoredbg\"\nargs = [ \"--interpreter=vscode\" ]\nport-arg = \"--server={}\"\n\n[[language.debugger.templates]]\nname = \"launch\"\nrequest = \"launch\"\ncompletion = [ { name = \"path to dll\", completion = \"filename\" } ]\nargs = { type = \"coreclr\", console = \"internalConsole\", internalConsoleOptions = \"openOnSessionStart\", program = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"attach\"\nrequest = \"attach\"\ncompletion = [ \"pid\" ]\nargs = { processId = \"{0}\" }\n\n[[grammar]]\nname = \"c-sharp\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-c-sharp\", rev = \"b5eb5742f6a7e9438bee22ce8026d6b927be2cd7\" }\n\n[[language]]\nname = \"c3\"\nscope = \"source.c3\"\ninjection-regex = \"c3\"\nfile-types = [ \"c3\", \"c3i\", \"c3t\" ]\nroots = [ \"project.json\" ]\ncomment-token = \"//\"\nblock-comment-tokens = [\n  { start = \"/*\", end = \"*/\" },\n  { start = \"<*\", end = \"*>\" },\n]\nindent = { tab-width = 4, unit = \"\\t\" }\nlanguage-servers = [ \"c3-lsp\" ]\n\n[language.debugger]\nname = \"lldb-dap\"\ntransport = \"stdio\"\ncommand = \"lldb-dap\"\n\n[[language.debugger.templates]]\nname = \"binary\"\nrequest = \"launch\"\ncompletion = [ { name = \"binary\", completion = \"filename\" } ]\nargs = { console = \"internalConsole\", program = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"attach\"\nrequest = \"attach\"\ncompletion = [ \"pid\" ]\nargs = { console = \"internalConsole\", pid = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"gdbserver attach\"\nrequest = \"attach\"\ncompletion = [ { name = \"lldb connect url\", default = \"connect://localhost:3333\" }, { name = \"file\", completion = \"filename\" }, \"pid\" ]\nargs = { console = \"internalConsole\", attachCommands = [ \"platform select remote-gdb-server\", \"platform connect {0}\", \"file {1}\", \"attach {2}\" ] }\n\n[[grammar]]\nname = \"c3\"\nsource = { git = \"https://github.com/c3lang/tree-sitter-c3\", rev = \"15d3502510af0a6c888c663ec8d6aca8791216ce\" }\n\n[[language]]\nname = \"cel\"\nscope = \"source.cel\"\ninjection-regex = \"cel\"\nfile-types = [\"cel\"]\ncomment-token = \"//\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"cel\"\nsource = { git = \"https://github.com/bufbuild/tree-sitter-cel\", rev = \"9f2b65da14c216df53933748e489db0f11121464\" }\n\n[[language]]\nname = \"spicedb\"\nscope = \"source.zed\"\ninjection-regex = \"spicedb\"\nfile-types = [\"zed\"]\ncomment-token = \"//\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"spicedb\"\nsource = { git = \"https://github.com/jzelinskie/tree-sitter-spicedb\", rev = \"a4e4645651f86d6684c15dfa9931b7841dc52a66\" }\n\n[[language]]\nname = \"go\"\nscope = \"source.go\"\ninjection-regex = \"go\"\nfile-types = [\"go\"]\nroots = [\"go.work\", \"go.mod\"]\nauto-format = true\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"gopls\", \"golangci-lint-lsp\" ]\n# TODO: gopls needs utf-8 offsets?\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[language.debugger]\nname = \"go\"\ntransport = \"tcp\"\ncommand = \"dlv\"\nargs = [\"dap\"]\nport-arg = \"-l 127.0.0.1:{}\"\n\n[[language.debugger.templates]]\nname = \"source\"\nrequest = \"launch\"\ncompletion = [ { name = \"entrypoint\", completion = \"filename\", default = \".\" } ]\nargs = { mode = \"debug\", program = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"binary\"\nrequest = \"launch\"\ncompletion = [ { name = \"binary\", completion = \"filename\" } ]\nargs = { mode = \"exec\", program = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"test\"\nrequest = \"launch\"\ncompletion = [ { name = \"tests\", completion = \"directory\", default = \".\" } ]\nargs = { mode = \"test\", program = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"attach\"\nrequest = \"attach\"\ncompletion = [ \"pid\" ]\nargs = { mode = \"local\", processId = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"core\"\nrequest = \"launch\"\ncompletion = [ { name = \"binary\", completion = \"filename\" }, { name = \"core\", completion = \"filename\" } ]\nargs = { mode = \"core\", program = \"{0}\", coreFilePath = \"{1}\" }\n\n[[grammar]]\nname = \"go\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-go\", rev = \"12fe553fdaaa7449f764bc876fd777704d4fb752\" }\n\n[[language]]\nname = \"gomod\"\nscope = \"source.gomod\"\ninjection-regex = \"gomod\"\nfile-types = [{ glob = \"go.mod\" }]\nauto-format = true\ncomment-token = \"//\"\nlanguage-servers = [ \"gopls\" ]\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[[grammar]]\nname = \"gomod\"\nsource = { git = \"https://github.com/camdencheek/tree-sitter-go-mod\", rev = \"6efb59652d30e0e9cd5f3b3a669afd6f1a926d3c\" }\n\n[[language]]\nname = \"gotmpl\"\nscope = \"source.gotmpl\"\ninjection-regex = \"gotmpl\"\nfile-types = [\"gotmpl\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"gopls\" ]\nindent = { tab-width = 2, unit = \" \" }\n\n[[grammar]]\nname = \"gotmpl\"\nsource = { git = \"https://github.com/ngalaiko/tree-sitter-go-template\", rev = \"ca26229bafcd3f37698a2496c2a5efa2f07e86bc\" }\n\n[[language]]\nname = \"gowork\"\nscope = \"source.gowork\"\ninjection-regex = \"gowork\"\nfile-types = [{ glob = \"go.work\" }]\nauto-format = true\ncomment-token = \"//\"\nlanguage-servers = [ \"gopls\" ]\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[[grammar]]\nname = \"gowork\"\nsource = { git = \"https://github.com/omertuc/tree-sitter-go-work\", rev = \"6dd9dd79fb51e9f2abc829d5e97b15015b6a8ae2\" }\n\n[[language]]\nname = \"go-format-string\"\nscope = \"source.go-format-string\"\nfile-types = []\ninjection-regex = \"go-format-string\"\n\n[[grammar]]\nname = \"go-format-string\"\nsource = { git = \"https://codeberg.org/kpbaks/tree-sitter-go-format-string\", rev = \"06587ea641155db638f46a32c959d68796cd36bb\" }\n\n[[language]]\nname = \"javascript\"\nscope = \"source.js\"\ninjection-regex = \"(js|javascript)\"\nlanguage-id = \"javascript\"\nfile-types = [\"js\", \"mjs\", \"cjs\", \"rules\", \"es6\", \"pac\", \"gs\", { glob = \".node_repl_history\" }, { glob = \"jakefile\" }]\nshebangs = [\"node\"]\nroots = [ \"package.json\", \"jsconfig.json\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"typescript-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.debugger]\nname = \"js-debug-dap\"\ntransport = \"tcp\"\nport-arg = \"{} 127.0.0.1\"\n# args consisting of cmd (node) and path to adapter should be added to user's configuration\nquirks = { absolute-paths = true }\n\n[[language.debugger.templates]]\nname = \"source\"\nrequest = \"launch\"\ncompletion = [ { name = \"main\", completion = \"filename\", default = \"index.js\" } ]\nargs = { program = \"{0}\", skipFiles = [ \"<node_internals>/**\" ] }\n\n[[grammar]]\nname = \"javascript\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-javascript\", rev = \"3a837b6f3658ca3618f2022f8707e29739c91364\" }\n\n[[language]]\nname = \"jsx\"\nscope = \"source.jsx\"\ninjection-regex = \"jsx\"\nlanguage-id = \"javascriptreact\"\nfile-types = [\"jsx\"]\nroots = [ \"package.json\", \"jsconfig.json\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"typescript-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"javascript\"\n\n[[language]]\nname = \"typescript\"\nscope = \"source.ts\"\ninjection-regex = \"(ts|typescript)\"\nlanguage-id = \"typescript\"\nfile-types = [\"ts\", \"mts\", \"cts\"]\nshebangs = [\"deno\", \"bun\", \"ts-node\"]\nroots = [ \"package.json\", \"tsconfig.json\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"typescript-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"typescript\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-typescript\", rev = \"75b3874edb2dc714fb1fd77a32013d0f8699989f\", subpath = \"typescript\" }\n\n[[language]]\nname = \"typespec\"\nscope = \"source.typespec\"\ninjection-regex = \"(tsp|typespec)\"\nlanguage-id = \"typespec\"\nfile-types = [\"tsp\"]\nroots = [\"tspconfig.yaml\"]\nauto-format = true\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [\"typespec\"]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"typespec\"\nsource = { git = \"https://github.com/happenslol/tree-sitter-typespec\", rev = \"0ee05546d73d8eb64635ed8125de6f35c77759fe\" }\n\n[[language]]\nname = \"tsx\"\nscope = \"source.tsx\"\ninjection-regex = \"(tsx)\" # |typescript\nlanguage-id = \"typescriptreact\"\nfile-types = [\"tsx\"]\nroots = [ \"package.json\", \"tsconfig.json\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"typescript-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"tsx\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-typescript\", rev = \"75b3874edb2dc714fb1fd77a32013d0f8699989f\", subpath = \"tsx\" }\n\n[[language]]\nname = \"css\"\nscope = \"source.css\"\ninjection-regex = \"css\"\nfile-types = [\"css\"]\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"vscode-css-language-server\" ]\nauto-format = true\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"css\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-css\", rev = \"6e327db434fec0ee90f006697782e43ec855adf5\" }\n\n[[language]]\nname = \"scss\"\nscope = \"source.scss\"\ninjection-regex = \"scss\"\nfile-types = [\"scss\"]\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"vscode-css-language-server\" ]\nauto-format = true\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"scss\"\nsource = { git = \"https://github.com/serenadeai/tree-sitter-scss\", rev = \"c478c6868648eff49eb04a4df90d703dc45b312a\" }\n\n[[language]]\nname = \"less\"\nscope = \"source.less\"\ninjection-regex = \"less\"\nfile-types = [\"less\"]\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"vscode-css-language-server\" ]\nauto-format = true\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"less\"\nsource = { git = \"https://github.com/jimliang/tree-sitter-less\", rev = \"e5ae6245f841b5778c79ac93b28fa4f56b679c5d\" }\n\n[[language]]\nname = \"html\"\nscope = \"text.html.basic\"\ninjection-regex = \"html\"\nfile-types = [\"html\", \"htm\", \"shtml\", \"xhtml\", \"xht\", \"jsp\", \"asp\", \"aspx\", \"jshtm\", \"volt\", \"rhtml\", \"cshtml\"]\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nlanguage-servers = [ \"vscode-html-language-server\", \"superhtml\" ]\nauto-format = true\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\"'\" = \"'\"\n\"<\" = \">\"\n\n[[grammar]]\nname = \"html\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-html\", rev = \"cbb91a0ff3621245e890d1c50cc811bffb77a26b\" }\n\n[[language]]\nname = \"htmldjango\"\nscope = \"source.htmldjango\"\ninjection-regex = \"htmldjango\"\nlanguage-servers = [\"djlsp\", \"vscode-html-language-server\", \"superhtml\"]\nfile-types = []\nroots = [\"manage.py\"]\n\n[language.auto-pairs]\n'\"' = '\"'\n'(' = ')'\n'[' = ']'\n'{' = '}'\n'%' = '%'\n'<' = '>'\n\n[[grammar]]\nname = \"htmldjango\"\nsource = { git = \"https://github.com/interdependence/tree-sitter-htmldjango\", rev = \"3a643167ad9afac5d61e092f08ff5b054576fadf\" }\n\n[[language]]\nname = \"python\"\nscope = \"source.python\"\ninjection-regex = \"py(thon)?\"\nfile-types = [\"py\", \"pyi\", \"py3\", \"pyw\", \"ptl\", \"rpy\", \"cpy\", \"ipy\", \"pyt\", { glob = \".python_history\" }, { glob = \".pythonstartup\" }, { glob = \".pythonrc\" }, { glob = \"*SConstruct\" }, { glob = \"*SConscript\" }, { glob = \"*sconstruct\" }]\nshebangs = [\"python\", \"uv\"]\nroots = [\"pyproject.toml\", \"setup.py\", \"poetry.lock\", \"pyrightconfig.json\"]\ncomment-token = \"#\"\nlanguage-servers = [\"ty\", \"ruff\", \"jedi\", \"pylsp\"]\n# TODO: pyls needs utf-8 offsets\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"python\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-python\", rev = \"293fdc02038ee2bf0e2e206711b69c90ac0d413f\" }\n\n[[language]]\nname = \"nickel\"\nscope = \"source.nickel\"\ninjection-regex = \"nickel\"\nfile-types = [\"ncl\"]\nshebangs = []\ncomment-token = \"#\"\nlanguage-servers = [ \"nls\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\n[[grammar]]\nname = \"nickel\"\nsource = { git = \"https://github.com/nickel-lang/tree-sitter-nickel\", rev = \"88d836a24b3b11c8720874a1a9286b8ae838d30a\" }\n\n[[language]]\nname = \"nix\"\nscope = \"source.nix\"\ninjection-regex = \"nix\"\nfile-types = [\"nix\"]\nshebangs = []\ncomment-token = \"#\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"nil\", \"nixd\" ]\nindent = { tab-width = 2, unit = \"  \" }\nformatter = { command = \"nixfmt\" }\n\n[[grammar]]\nname = \"nix\"\nsource = { git = \"https://github.com/nix-community/tree-sitter-nix\", rev = \"1b69cf1fa92366eefbe6863c184e5d2ece5f187d\" }\n\n[[language]]\nname = \"ruby\"\nscope = \"source.ruby\"\ninjection-regex = \"ruby\"\nfile-types = [\n  \"rb\",\n  \"rake\",\n  \"irb\",\n  \"gemspec\",\n  \"rabl\",\n  \"jbuilder\",\n  \"jb\",\n  \"podspec\",\n  \"rjs\",\n  \"rbi\",\n  \"rbs\",\n  { glob = \"rakefile\" },\n  { glob = \"gemfile\" },\n  { glob = \"Rakefile\" },\n  { glob = \"Gemfile\" },\n  { glob = \"Podfile\" },\n  { glob = \"Vagrantfile\" },\n  { glob = \"Brewfile\" },\n  { glob = \"*.Brewfile\" },\n  { glob = \"Guardfile\" },\n  { glob = \"Capfile\" },\n  { glob = \"Cheffile\" },\n  { glob = \"Hobofile\" },\n  { glob = \"Appraisals\" },\n  { glob = \"Rantfile\" },\n  { glob = \"Berksfile\" },\n  { glob = \"Berksfile.lock\" },\n  { glob = \"Thorfile\" },\n  { glob = \"Puppetfile\" },\n  { glob = \"Fastfile\" },\n  { glob = \"Appfile\" },\n  { glob = \"Deliverfile\" },\n  { glob = \"Matchfile\" },\n  { glob = \"Scanfile\" },\n  { glob = \"Snapfile\" },\n  { glob = \"Gymfile\" },\n  { glob = \".irbrc\" },\n]\nshebangs = [\"ruby\"]\ncomment-token = \"#\"\nlanguage-servers = [ \"ruby-lsp\", \"solargraph\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"ruby\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-ruby\", rev = \"206c7077164372c596ffa8eaadb9435c28941364\" }\n\n[[language]]\nname = \"rshtml\"\nfile-types = [{ glob = \"*.rs.html\" }]\nscope = \"source.rshtml\"\nlanguage-servers = [\n  \"rshtml-analyzer\",\n  \"vscode-html-language-server\",\n  \"superhtml\",\n]\nroots = [\"Cargo.lock\", \"Cargo.toml\"]\nblock-comment-tokens = { start = \"@*\", end = \"*@\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"rshtml\"\nsource = { git = \"https://github.com/rshtml/tree-sitter-rshtml\", rev = \"89ae0f3a5e221a83aad243def85e822616d3b3c2\" }\n\n[[language]]\nname = \"bash\"\nscope = \"source.bash\"\ninjection-regex = \"(shell|bash|zsh|sh)\"\nfile-types = [\n  \"sh\",\n  \"bash\",\n  \"ash\",\n  \"dash\",\n  \"ksh\",\n  \"mksh\",\n  \"zsh\",\n  \"zshenv\",\n  \"zlogin\",\n  \"zlogout\",\n  \"zprofile\",\n  \"zshrc\",\n  \"eclass\",\n  \"ebuild\",\n  \"bazelrc\",\n  \"Renviron\",\n  \"zsh-theme\",\n  \"cshrc\",\n  \"tcshrc\",\n  \"bashrc_Apple_Terminal\",\n  \"zshrc_Apple_Terminal\",\n  { glob = \"i3/config\" },\n  { glob = \"sway/config\" },\n  { glob = \".tmux.conf\" },\n  { glob = \"tmux.conf\" },\n  { glob = \".sh_history\" },\n  { glob = \".bash_history\" },\n  { glob = \".bash_login\" },\n  { glob = \".bash_logout\" },\n  { glob = \".bash_profile\" },\n  { glob = \".bashrc\" },\n  { glob = \".profile\" },\n  { glob = \".zshenv\" },\n  { glob = \".zlogin\" },\n  { glob = \".zlogout\" },\n  { glob = \".zprofile\" },\n  { glob = \".zshrc\" },\n  { glob = \".zimrc\" },\n  { glob = \"APKBUILD\" },\n  { glob = \".bash_aliases\" },\n  { glob = \"bash_completion\" },\n  { glob = \"bash-completion/completions/*\" },\n  { glob = \"bash_completion.d/*\" },\n  { glob = \".Renviron\" },\n  { glob = \".xprofile\" },\n  { glob = \".xsession\" },\n  { glob = \".xsessionrc\" },\n  { glob = \".yashrc\" },\n  { glob = \".yash_profile\" },\n  { glob = \".hushlogin\" },\n  { glob = \".xinitrc\" }, # ~/.xinitrc\n  { glob = \"xinitrc\" }, # /etc/X11/xinit/xinitrc\n  { glob = \".xserverrc\" }, # ~/.xserverrc\n  { glob = \"xserverrc\" }, # /etc/X11/xinit/xserverrc\n  { glob = \"direnvrc\" }, # ~/.config/direnv/direnvrc\n]\nshebangs = [\"sh\", \"bash\", \"dash\", \"zsh\"]\ncomment-token = \"#\"\nlanguage-servers = [ \"bash-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"bash\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-bash\", rev = \"487734f87fd87118028a65a4599352fa99c9cde8\" }\n\n[[language]]\nname = \"php\"\nscope = \"source.php\"\ninjection-regex = \"php\"\nfile-types = [\"php\", \"inc\", \"php4\", \"php5\", \"phtml\", \"ctp\"]\nshebangs = [\"php\"]\nroots = [\"composer.json\", \"index.php\"]\ncomment-token = \"//\"\nblock-comment-tokens = [{start = \"/**\", end = \"*/\"}, {start = \"/*\", end = \"*/\"}]\nlanguage-servers = [ \"intelephense\" ]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"php\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-php\", rev = \"f860e598194f4a71747f91789bf536b393ad4a56\" }\n\n[[language]]\nname = \"php-only\"\nscope = \"source.php-only\"\ninjection-regex = \"php-only\"\nfile-types = []\nindent = { tab-width = 4, unit = \"    \" }\nroots = [\"composer.json\", \"index.php\"]\n\n[[grammar]]\nname = \"php-only\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-php\", rev = \"cf1f4a0f1c01c705c1d6cf992b104028d5df0b53\", subpath = \"php_only\" }\n\n[[language]]\nname = \"blade\"\nscope = \"source.blade.php\"\nfile-types = [{ glob = \"*.blade.php\" }, \"blade\"]\ninjection-regex = \"blade\"\nroots = [\"composer.json\", \"index.php\"]\n\n[[grammar]]\nname = \"blade\"\nsource = { git = \"https://github.com/EmranMR/tree-sitter-blade\", rev = \"59ce5b68e288002e3aee6cf5a379bbef21adbe6c\" }\n\n[[language]]\nname = \"twig\"\nscope = \"source.twig\"\ninjection-regex = \"twig\"\nfile-types = [\"twig\"]\nblock-comment-tokens = { start = \"{#\", end = \"#}\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"twig\"\nsource = { git = \"https://github.com/gbprod/tree-sitter-twig\", rev = \"085648e01d1422163a1702a44e72303b4e2a0bd1\" }\n\n[[language]]\nname = \"latex\"\nscope = \"source.tex\"\ninjection-regex = \"tex\"\nfile-types = [\"tex\", \"sty\", \"cls\", \"Rd\", \"bbx\", \"cbx\"]\ncomment-token = \"%\"\nlanguage-servers = [ \"texlab\" ]\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[[grammar]]\nname = \"latex\"\nsource = { git = \"https://github.com/latex-lsp/tree-sitter-latex\", rev = \"8c75e93cd08ccb7ce1ccab22c1fbd6360e3bcea6\" }\n\n[[language]]\nname = \"bibtex\"\nscope = \"source.bib\"\ninjection-regex = \"bib\"\nfile-types = [\"bib\"]\ncomment-token = \"%\"\nlanguage-servers = [ \"texlab\" ]\nindent = { tab-width = 4, unit = \"\\t\" }\nauto-format = true\n\n[language.formatter]\ncommand = 'bibtex-tidy'\nargs = [\n  \"-\",\n  \"--curly\",\n  \"--drop-all-caps\",\n  \"--remove-empty-fields\",\n  \"--sort-fields\",\n  \"--sort=year,author,id\",\n  \"--strip-enclosing-braces\",\n  \"--trailing-commas\",\n]\n\n[[grammar]]\nname = \"bibtex\"\nsource = { git = \"https://github.com/latex-lsp/tree-sitter-bibtex\", rev = \"ccfd77db0ed799b6c22c214fe9d2937f47bc8b34\" }\n\n[[language]]\nname = \"lean\"\nscope = \"source.lean\"\ninjection-regex = \"lean\"\nfile-types = [\"lean\"]\nroots = [ \"lakefile.lean\", \"lakefile.toml\" ]\ncomment-token = \"--\"\nblock-comment-tokens = { start = \"/-\", end = \"-/\" }\nlanguage-servers = [ \"lean\" ]\nindent = { tab-width = 2, unit = \"  \" }\nrulers = [101]\ntext-width = 100\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n'⟨' = '⟩'\n\n[[grammar]]\nname = \"lean\"\nsource = { git = \"https://github.com/Julian/tree-sitter-lean\", rev = \"d98426109258b266e1e92358c5f11716d2e8f638\" }\n\n[[language]]\nname = \"lpf\"\ncomment-token = \"#\"\nscope = \"source.lpf\"\nfile-types = [\"lpf\"]\n\n[[grammar]]\nname = \"lpf\"\nsource = { git = \"https://gitlab.com/TheZoq2/tree-sitter-lpf\", rev = \"db7372e60c722ca7f12ab359e57e6bf7611ab126\" }\n\n[[language]]\nname = \"julia\"\nscope = \"source.julia\"\ninjection-regex = \"julia\"\nfile-types = [\"jl\"]\nshebangs = [\"julia\"]\nroots = [\"Manifest.toml\", \"Project.toml\"]\ncomment-token = \"#\"\nblock-comment-tokens = { start = \"#=\", end = \"=#\" }\nlanguage-servers = [ \"julia\" ]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"julia\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-julia\", rev = \"e84f10db8eeb8b9807786bfc658808edaa1b4fa2\" }\n\n[[language]]\nname = \"java\"\nscope = \"source.java\"\ninjection-regex = \"java\"\nfile-types = [\"java\", \"jav\", \"pde\"]\nroots = [\"pom.xml\", \"build.gradle\", \"build.gradle.kts\"]\nlanguage-servers = [ \"jdtls\" ]\nindent = { tab-width = 2, unit = \"  \" }\ncomment-tokens = [\"//\"]\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\n\n[[grammar]]\nname = \"java\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-java\", rev = \"09d650def6cdf7f479f4b78f595e9ef5b58ce31e\" }\n\n[[language]]\nname = \"smali\"\nscope = \"source.smali\"\ninjection-regex = \"smali\"\nfile-types = [\"smali\"]\ncomment-token = \"#\"\nroots = []\nlanguage-servers = [ \"smalisp\" ]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"smali\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-smali\", rev = \"fdfa6a1febc43c7467aa7e937b87b607956f2346\" }\n\n[[language]]\nname = \"ledger\"\nscope = \"source.ledger\"\ninjection-regex = \"ledger\"\nfile-types = [\"ldg\", \"ledger\", \"journal\"]\ncomment-token = \";\"\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"ledger\"\nsource = { git = \"https://github.com/cbarrete/tree-sitter-ledger\", rev = \"1f864fb2bf6a87fe1b48545cc6adc6d23090adf7\" }\n\n[[language]]\nname = \"beancount\"\nscope = \"source.beancount\"\ninjection-regex = \"beancount\"\nfile-types = [\"beancount\", \"bean\"]\ncomment-token = \";\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"beancount-language-server\" ]\n\n[[grammar]]\nname = \"beancount\"\nsource = { git = \"https://github.com/polarmutex/tree-sitter-beancount\", rev = \"f3741a3a68ade59ec894ed84a64673494d2ba8f3\" }\n\n[[language]]\nname = \"ocaml\"\nscope = \"source.ocaml\"\ninjection-regex = \"ocaml\"\nfile-types = [\"ml\"]\nshebangs = [\"ocaml\", \"ocamlrun\", \"ocamlscript\"]\nblock-comment-tokens = { start = \"(*\", end = \"*)\" }\nlanguage-servers = [ \"ocamllsp\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\n[[grammar]]\nname = \"ocaml\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-ocaml\", rev = \"9965d208337d88bbf1a38ad0b0fe49e5f5ec9677\", subpath = \"ocaml\" }\n\n[[language]]\nname = \"ocaml-interface\"\nscope = \"source.ocaml.interface\"\nfile-types = [\"mli\"]\nshebangs = []\nblock-comment-tokens = { start = \"(*\", end = \"*)\" }\ncomment-token = \"(**)\"\nlanguage-servers = [ \"ocamllsp\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\n[[grammar]]\nname = \"ocaml-interface\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-ocaml\", rev = \"9965d208337d88bbf1a38ad0b0fe49e5f5ec9677\", subpath = \"interface\" }\n\n[[language]]\nname = \"dune\"\nscope = \"source.dune\"\nroots = [\"dune-project\"]\nfile-types = [{ glob = \"dune-project\" }, { glob = \"dune\" }]\ncomment-token = \";\"\nindent = { tab-width = 1, unit = \" \" }\ngrammar = \"scheme\"\nauto-format = true\nformatter = { command = \"dune\", args = [\"format-dune-file\"] }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\n[[language]]\nname = \"lua\"\ninjection-regex = \"lua\"\nscope = \"source.lua\"\nfile-types = [\"lua\", \"rockspec\"]\nshebangs = [\"lua\", \"luajit\"]\nroots = [\".luarc.json\", \".luacheckrc\", \".stylua.toml\", \"selene.toml\", \".git\"]\ncomment-token = \"--\"\nblock-comment-tokens = { start = \"--[[\", end = \"--]]\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"lua-language-server\" ]\n\n[[grammar]]\nname = \"lua\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-lua\", rev = \"e40f5b6e6df9c2d1d6d664ff5d346a75d71ee6b2\" }\n\n[[language]]\nname = \"luap\"\nscope = \"source.luap\"\nfile-types = []\ninjection-regex = \"luap\"\n\n[[grammar]]\nname = \"luap\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-luap\", rev = \"c134aaec6acf4fa95fe4aa0dc9aba3eacdbbe55a\" }\n\n[[language]]\nname = \"lua-format-string\"\nscope = \"source.lua-format-string\"\nfile-types = []\ninjection-regex = \"lua-format-string\"\n\n[[grammar]]\nname = \"lua-format-string\"\nsource = { git = \"https://codeberg.org/kpbaks/tree-sitter-lua-format-string\", rev = \"b667c8cab109df307e1b4d56b0b43f5c4a353533\" }\n\n[[grammar]]\nname = \"teal\"\nsource = { git = \"https://github.com/euclidianAce/tree-sitter-teal\", rev = \"3db655924b2ff1c54fdf6371b5425ea6b5dccefe\" }\n\n[[language]]\nname = \"teal\"\nscope = \"source.tl\"\ninjection-regex = \"teal\"\nfile-types = [\"tl\"]\ncomment-tokens = \"--\"\nblock-comment-tokens = { start = \"--[[\", end = \"--]]\" }\nroots = [ \"tlconfig.lua\" ]\nlanguage-servers = [ \"teal-language-server\" ]\n\n[[language]]\nname = \"svelte\"\nscope = \"source.svelte\"\ninjection-regex = \"svelte\"\nfile-types = [\"svelte\"]\nindent = { tab-width = 2, unit = \"  \" }\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"svelteserver\" ]\n\n[[grammar]]\nname = \"svelte\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-svelte\", rev = \"ae5199db47757f785e43a14b332118a5474de1a2\" }\n\n[[language]]\nname = \"vue\"\nscope = \"source.vue\"\ninjection-regex = \"vue\"\nfile-types = [\"vue\"]\nroots = [\"package.json\"]\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"vuels\" ]\n\n[[grammar]]\nname = \"vue\"\nsource = { git = \"https://github.com/ikatyang/tree-sitter-vue\", rev = \"91fe2754796cd8fba5f229505a23fa08f3546c06\" }\n\n[[language]]\nname = \"yaml\"\nscope = \"source.yaml\"\nfile-types = [\n  \"yml\",\n  \"yaml\",\n  { glob = \".prettierrc\" },\n  { glob = \".clangd\" },\n  { glob = \".clang-format\" },\n  { glob = \".clang-tidy\" },\n  { glob = \".gem/credentials\" },\n  { glob = \".kube/config\" },\n  { glob = \".kube/kuberc\" },\n  { glob = \"yarn.lock\" },\n  \"sublime-syntax\",\n  \"bu\",\n  { glob = \".stylelintrc\" },  # https://stylelint.io/user-guide/configure/\n  { glob = \".puppeteerrc\" },  # https://pptr.dev/guides/configuration\n]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"yaml-language-server\", \"ansible-language-server\" ]\ninjection-regex = \"yml|yaml\"\nformatter = { command = \"yamlfmt\", args = ['-'] }\nauto-format = true\n\n[[grammar]]\nname = \"yaml\"\nsource = { git = \"https://github.com/ikatyang/tree-sitter-yaml\", rev = \"0e36bed171768908f331ff7dff9d956bae016efb\" }\n\n[[language]]\nname = \"nestedtext\"\nscope = \"text.nested\"\ninjection-regex = \"nestedtext\"\nfile-types = [\"nt\"]\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\ngrammar = \"yaml\"\n\n[[language]]\nname = \"haskell\"\nscope = \"source.haskell\"\ninjection-regex = \"hs|haskell\"\nfile-types = [\"hs\", \"hs-boot\", \"hsc\"]\nroots = [\"Setup.hs\", \"stack.yaml\", \"cabal.project\", \"hie.yaml\"]\nshebangs = [\"runhaskell\", \"stack\"]\ncomment-token = \"--\"\nblock-comment-tokens = { start = \"{-\", end = \"-}\" }\nlanguage-servers = [ \"haskell-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"haskell\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-haskell\", rev = \"0975ef72fc3c47b530309ca93937d7d143523628\" }\n\n[[language]]\nname = \"haskell-persistent\"\nscope = \"source.persistentmodels\"\nfile-types = [\"persistentmodels\"]\ncomment-token = \"--\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"haskell-persistent\"\nsource = { git = \"https://github.com/MercuryTechnologies/tree-sitter-haskell-persistent\", rev = \"58a6ccfd56d9f1de8fb9f77e6c42151f8f0d0f3d\" }\n\n[[language]]\nname = \"haskell-literate\"\nscope = \"source.haskell-literate\"\ninjection-regex = \"lhs\"\nfile-types = [\"lhs\"]\nroots = [\"Setup.hs\", \"stack.yaml\", \"cabal.project\", \"hie.yaml\"]\nshebangs = [\"runhaskell\", \"stack\"]\ncomment-token = \"--\"\nblock-comment-tokens = { start = \"{-\", end = \"-}\" }\nlanguage-servers = [ \"haskell-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"haskell-literate\"\nsource = { git = \"https://github.com/LaurentRDC/tree-sitter-haskell-literate\", rev = \"8ad7bd1b1595f4cc1a4ccc775d4a3c460f43a596\" }\n\n[[language]]\nname = \"purescript\"\nscope = \"source.purescript\"\ninjection-regex = \"purescript\"\nfile-types = [\"purs\"]\nroots = [\"spago.yaml\", \"spago.dhall\", \"bower.json\"]\ncomment-token = \"--\"\nblock-comment-tokens = { start = \"{-\", end = \"-}\" }\nlanguage-servers = [ \"purescript-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\nauto-format = true\nformatter = { command = \"purs-tidy\", args = [\"format\"] }\n\n[[grammar]]\nname = \"purescript\"\nsource = { git = \"https://github.com/postsolar/tree-sitter-purescript\", rev = \"f541f95ffd6852fbbe88636317c613285bc105af\" }\n\n[[language]]\nname = \"zig\"\nscope = \"source.zig\"\ninjection-regex = \"zig\"\nfile-types = [\"zig\", \"zon\"]\nroots = [\"build.zig\"]\nauto-format = true\ncomment-tokens = [\"//\", \"///\", \"//!\"]\nlanguage-servers = [ \"zls\" ]\nindent = { tab-width = 4, unit = \"    \" }\nformatter = { command = \"zig\" , args = [\"fmt\", \"--stdin\"] }\n\n[language.debugger]\nname = \"lldb-dap\"\ntransport = \"stdio\"\ncommand = \"lldb-dap\"\n\n[[language.debugger.templates]]\nname = \"binary\"\nrequest = \"launch\"\ncompletion = [ { name = \"binary\", completion = \"filename\" } ]\nargs = { console = \"internalConsole\", program = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"attach\"\nrequest = \"attach\"\ncompletion = [ \"pid\" ]\nargs = { console = \"internalConsole\", pid = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"gdbserver attach\"\nrequest = \"attach\"\ncompletion = [ { name = \"lldb connect url\", default = \"connect://localhost:3333\" }, { name = \"file\", completion = \"filename\" }, \"pid\" ]\nargs = { console = \"internalConsole\", attachCommands = [ \"platform select remote-gdb-server\", \"platform connect {0}\", \"file {1}\", \"attach {2}\" ] }\n\n[[grammar]]\nname = \"zig\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-zig\", rev = \"6479aa13f32f701c383083d8b28360ebd682fb7d\" }\n\n[[grammar]]\nname = \"picat\"\nsource = { git = \"https://github.com/dlr-ft/tree-sitter-picat\", rev = \"ecb6b07d280f2cef8214bc4b999ad83ac1d9205c\" }\n\n[[language]]\nname = \"picat\"\nscope = \"source.picat\"\ninjection-regex = \"(pi|picat)\"\nlanguage-id = \"picat\"\nfile-types = [\"pi\", \"picat\"]\nshebangs = [\"picat\"]\ncomment-token = \"%\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\n\n[[language]]\nname = \"prolog\"\nscope = \"source.prolog\"\nfile-types = [\"pl\", \"prolog\"]\nshebangs = [\"swipl\"]\ncomment-token = \"%\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"swipl\" ]\n\n[[grammar]]\nname = \"prolog\"\nsource = { git = \"https://codeberg.org/foxy/tree-sitter-prolog\", subpath = \"grammars/prolog\", rev = \"d8d415f6a1cf80ca138524bcc395810b176d40fa\" }\n\n[[language]]\nname = \"tsq\"\nscope = \"source.tsq\"\nfile-types = [{ glob = \"queries/*.scm\" }, { glob = \"injections.scm\" },  { glob = \"highlights.scm\" },  { glob = \"indents.scm\" },  { glob = \"textobjects.scm\" },  { glob = \"locals.scm\" },  { glob = \"tags.scm\" }]\ncomment-token = \";\"\ninjection-regex = \"tsq\"\nlanguage-servers = [\"ts_query_ls\"]\ngrammar = \"query\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'(' = ')'\n'[' = ']'\n'\"' = '\"'\n\n[[grammar]]\nname = \"query\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-query\", rev = \"a6674e279b14958625d7a530cabe06119c7a1532\" }\n\n[[language]]\nname = \"cmake\"\nscope = \"source.cmake\"\nfile-types = [\"cmake\", { glob = \"CMakeLists.txt\" }]\ncomment-token = \"#\"\nblock-comment-tokens = { start = \"#[[\", end = \"]]\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [\"neocmakelsp\", \"cmake-language-server\"]\ninjection-regex = \"cmake\"\n\n[[grammar]]\nname = \"cmake\"\nsource = { git = \"https://github.com/uyha/tree-sitter-cmake\", rev = \"6e51463ef3052dd3b328322c22172eda093727ad\" }\n\n[[language]]\nname = \"make\"\nscope = \"source.make\"\nfile-types = [{ glob = \"Makefile\" }, { glob = \"makefile\" }, \"make\", \"mk\", \"mak\", {glob = \"GNUmakefile\" }, { glob = \"OCamlMakefile\" }]\nshebangs = [\"make\", \"gmake\"]\ninjection-regex = \"(make|makefile|Makefile|mk)\"\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[[grammar]]\nname = \"make\"\nsource = { git = \"https://github.com/alemuller/tree-sitter-make\", rev = \"a4b9187417d6be349ee5fd4b6e77b4172c6827dd\" }\n\n[[language]]\nname = \"glsl\"\nscope = \"source.glsl\"\nfile-types = [\"glsl\", \"vert\", \"tesc\", \"tese\", \"geom\", \"frag\", \"comp\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [ \"glsl_analyzer\", \"glsld\" ]\ninjection-regex = \"glsl\"\n\n[[grammar]]\nname = \"glsl\"\nsource = { git = \"https://github.com/theHamsta/tree-sitter-glsl\", rev = \"24a6c8ef698e4480fecf8340d771fbcb5de8fbb4\" }\n\n[[language]]\nname = \"penrose\"\nscope = \"source.penrose\"\nauto-format = false\nfile-types = [\"substance\", \"style\", \"domain\"]\ncomment-tokens = \"--\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"penrose\"\nsource = { git = \"https://github.com/klukaszek/tree-sitter-penrose\", rev = \"d9368ff7f743b2ac2145a3342db13b1ad950cba5\" }\n\n[[language]]\nname = \"perl\"\nscope = \"source.perl\"\nfile-types =[\n  \"pl\",\n  \"pm\",\n  \"t\",\n  \"psgi\",\n  \"raku\",\n  \"rakumod\",\n  \"rakutest\",\n  \"rakudoc\",\n  \"nqp\",\n  \"p6\",\n  \"pl6\",\n  \"pm6\",\n  {glob = \"latexmkrc\"},\n  {glob = \".latexmkrc\"},\n]\nshebangs = [\"perl\"]\ncomment-token = \"#\"\nlanguage-servers = [ \"perlnavigator\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"perl\"\nsource = { git = \"https://github.com/tree-sitter-perl/tree-sitter-perl\", rev = \"72a08a496a23212f23802490ef6f4700d68cfd0e\" }\n\n[[language]]\nname = \"embedded-perl\"\nscope = \"text.html.ep\"\ninjection-regex = \"embedded-perl\"\nfile-types = [\"ep\", { glob = \"*.html.ep\" }]\ncomment-token = \"%#\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"embedded-perl\"\nsource = { git = \"https://github.com/jobindex-open/tree-sitter-embedded-perl\", rev = \"14b9a948030edd99c132b78a3d3dc2c7537a061b\" }\n\n[[language]]\nname = \"pod\"\nscope = \"source.pod\"\ninjection-regex = \"pod\"\nfile-types = [\"pod\"]\n\n[[grammar]]\nname = \"pod\"\nsource = { git = \"https://github.com/tree-sitter-perl/tree-sitter-pod\", rev = \"0bf8387987c21bf2f8ed41d2575a8f22b139687f\" }\n\n[[language]]\nname = \"racket\"\nscope = \"source.racket\"\nfile-types = [\"rkt\", \"rktd\", \"rktl\", \"scrbl\", \"zuo\"]\nshebangs = [\"racket\", \"zuo\"]\ncomment-token = \";\"\nindent = { tab-width = 2, unit = \"  \" }\nblock-comment-tokens = { start = \"#|\", end = \"|#\" }\nlanguage-servers = [ \"racket\" ]\ngrammar = \"scheme\"\n\n[[language]]\nname = \"common-lisp\"\nscope = \"source.commonlisp\"\nfile-types = [\"lisp\", \"asd\", \"cl\", \"l\", \"lsp\", \"ny\", \"podsl\", \"ros\", \"sexp\"]\nshebangs = [\"lisp\", \"sbcl\", \"ccl\", \"clisp\", \"ecl\"]\ncomment-token = \";\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"cl-lsp\" ]\ngrammar = \"commonlisp\"\n\n[[grammar]]\nname = \"commonlisp\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-commonlisp\", rev = \"32323509b3d9fe96607d151c2da2c9009eb13a2f\" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\n[[language]]\nname = \"comment\"\nscope = \"scope.comment\"\nfile-types = []\ninjection-regex = \"comment\"\n\n[[grammar]]\nname = \"comment\"\nsource = { git = \"https://github.com/stsewd/tree-sitter-comment\", rev = \"aefcc2813392eb6ffe509aa0fc8b4e9b57413ee1\" }\n\n[[language]]\nname = \"wesl\"\nscope = \"source.wesl\"\nfile-types = [\"wesl\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"wesl\"\nsource = { git = \"https://github.com/wgsl-tooling-wg/tree-sitter-wesl\", rev = \"94ee6122680ef8ce2173853ca7c99f7aaeeda8ce\" }\n\n[[language]]\nname = \"wgsl\"\nscope = \"source.wgsl\"\nfile-types = [\"wgsl\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"wgsl-analyzer\" ]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"wgsl\"\nsource = { git = \"https://github.com/szebniok/tree-sitter-wgsl\", rev = \"272e89ef2aeac74178edb9db4a83c1ffef80a463\" }\n\n[[language]]\nname = \"llvm\"\nscope = \"source.llvm\"\nfile-types = [\"ll\"]\ncomment-token = \";\"\nindent = { tab-width = 2, unit = \"  \" }\ninjection-regex = \"llvm\"\n\n[[grammar]]\nname = \"llvm\"\nsource = { git = \"https://github.com/benwilliamgraham/tree-sitter-llvm\", rev = \"c14cb839003348692158b845db9edda201374548\" }\n\n[[language]]\nname = \"llvm-mir\"\nscope = \"source.llvm_mir\"\nfile-types = []\ncomment-token = \";\"\nindent = { tab-width = 2, unit = \"  \" }\ninjection-regex = \"mir\"\n\n[[grammar]]\nname = \"llvm-mir\"\nsource = { git = \"https://github.com/Flakebi/tree-sitter-llvm-mir\", rev = \"d166ff8c5950f80b0a476956e7a0ad2f27c12505\" }\n\n[[language]]\nname = \"llvm-mir-yaml\"\n# TODO allow languages to point to their grammar like so:\n#\n#     grammar = \"yaml\"\nscope = \"source.yaml\"\nfile-types = [\"mir\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[language]]\nname = \"tablegen\"\nscope = \"source.tablegen\"\nfile-types = [\"td\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\ninjection-regex = \"tablegen\"\n\n[[grammar]]\nname = \"tablegen\"\nsource = { git = \"https://github.com/Flakebi/tree-sitter-tablegen\", rev = \"3e9c4822ab5cdcccf4f8aa9dcd42117f736d51d9\" }\n\n[[language]]\nname = \"mail\"\nscope = \"text.mail\"\nfile-types = [\"eml\"]\ninjection-regex = \"mail|eml|email\"\n\n[[grammar]]\nname = \"mail\"\nsource = { git = \"https://codeberg.org/ficd/tree-sitter-mail\", rev = \"5eddbfdbec4c893182c79047499901c196332e78\" }\n\n[[language]]\nname = \"markdown\"\nscope = \"source.md\"\ninjection-regex = \"md|markdown\"\nfile-types = [\"md\", \"livemd\", \"markdown\", \"mdx\", \"mkd\", \"mkdn\", \"mdwn\", \"mdown\", \"markdn\", \"mdtxt\", \"mdtext\", \"workbook\", { glob = \"PULLREQ_EDITMSG\" }]\nroots = [\".marksman.toml\"]\nlanguage-servers = [ \"marksman\", \"markdown-oxide\", \"rumdl\" ]\nindent = { tab-width = 2, unit = \"  \" }\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nword-completion.trigger-length = 4\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\"'\" = \"'\"\n'`' = '`'\n'‘' = '’'\n'«' = '»'\n'“' = '”'\n\n[[grammar]]\nname = \"markdown\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-markdown\", rev = \"2dfd57f547f06ca5631a80f601e129d73fc8e9f0\", subpath = \"tree-sitter-markdown\" }\n\n[[language]]\nname = \"markdown-rustdoc\"\nscope = \"source.markdown-rustdoc\"\ngrammar = \"markdown\"\ninjection-regex = \"markdown-rustdoc\"\nfile-types = []\nindent = { tab-width = 2, unit = \"  \" }\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\n\n[[language]]\nname = \"markdown.inline\"\nscope = \"source.markdown.inline\"\ninjection-regex = \"markdown\\\\.inline\"\nfile-types = []\ngrammar = \"markdown_inline\"\n\n[[grammar]]\nname = \"markdown_inline\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-markdown\", rev = \"2dfd57f547f06ca5631a80f601e129d73fc8e9f0\", subpath = \"tree-sitter-markdown-inline\" }\n\n[[language]]\nname = \"djot\"\nscope = \"source.djot\"\ninjection-regex = \"dj|djot\"\nfile-types = [\"dj\", \"djot\"]\nindent = { tab-width = 2, unit = \"  \" }\nblock-comment-tokens = { start = \"{%\", end = \"%}\" }\n\n[[grammar]]\nname = \"djot\"\nsource = { git = \"https://github.com/treeman/tree-sitter-djot\", rev = \"67e6e23ba7be81a4373e0f49e21207bdc32d12a5\" }\n\n[[language]]\nname = \"dart\"\nscope = \"source.dart\"\nfile-types = [\"dart\"]\nroots = [\"pubspec.yaml\"]\nauto-format = true\ncomment-tokens = [\"//\", \"///\"]\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"dart\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"dart\"\nsource = { git = \"https://github.com/UserNobody14/tree-sitter-dart\", rev = \"e398400a0b785af3cf571f5a57eccab242f0cdf9\" }\n\n[[language]]\nname = \"scala\"\nscope = \"source.scala\"\nroots = [\"build.sbt\", \"build.sc\", \"build.gradle\", \"build.gradle.kts\", \"pom.xml\", \".scala-build\"]\nfile-types = [\"scala\", \"sbt\", \"sc\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"metals\" ]\n\n[[grammar]]\nname = \"scala\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-scala\", rev = \"2d55e74b0485fe05058ffe5e8155506c9710c767\" }\n\n[[language]]\nname = \"dockerfile\"\nscope = \"source.dockerfile\"\ninjection-regex = \"docker|dockerfile\"\nroots = [\"Dockerfile\", \"Containerfile\"]\nfile-types = [\n  \"Dockerfile\",\n  { glob = \"Dockerfile\" },\n  { glob = \"Dockerfile.*\" },\n  \"dockerfile\",\n  { glob = \"dockerfile\" },\n  { glob = \"dockerfile.*\" },\n  \"Containerfile\",\n  { glob = \"Containerfile\" },\n  { glob = \"Containerfile.*\" },\n  \"containerfile\",\n  { glob = \"containerfile\" },\n  { glob = \"containerfile.*\" },\n]\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"  \" }\nformatter = { command = \"dockerfmt\" }\nlanguage-servers = [ \"docker-langserver\", \"docker-language-server\" ]\n\n[[grammar]]\nname = \"dockerfile\"\nsource = { git = \"https://github.com/camdencheek/tree-sitter-dockerfile\", rev = \"087daa20438a6cc01fa5e6fe6906d77c869d19fe\" }\n\n[[language]]\nname = \"docker-compose\"\nlanguage-id = \"dockercompose\"\nscope = \"source.yaml.docker-compose\"\nroots = [\"docker-compose.yaml\", \"docker-compose.yml\", \"compose.yaml\", \"compose.yml\"]\nlanguage-servers = [ \"docker-compose-langserver\", \"yaml-language-server\", \"docker-language-server\" ]\nfile-types = [{ glob = \"docker-compose.yaml\" }, { glob = \"docker-compose.yml\" }, { glob = \"compose.yaml\" }, { glob = \"compose.yml\" }]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"yaml\"\n\n[[language]]\nname = \"git-commit\"\nscope = \"git.commitmsg\"\nfile-types = [{ glob = \"COMMIT_EDITMSG\" }, { glob = \"MERGE_MSG\" }, { glob = \"TAG_EDITMSG\" }]\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\nrulers = [51, 73]\ntext-width = 72\ngrammar = \"gitcommit\"\nlanguage-servers = [ \"commit-lsp\" ]\n\n[[grammar]]\nname = \"gitcommit\"\nsource = { git = \"https://github.com/gbprod/tree-sitter-gitcommit\", rev = \"a716678c0f00645fed1e6f1d0eb221481dbd6f6d\" }\n\n[[language]]\nname = \"git-notes\"\nscope = \"git.notesmsg\"\nfile-types = [{ glob = \"NOTES_EDITMSG\" }, { glob = \"EDIT_DESCRIPTION\" }]\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\nrulers = [73]\ntext-width = 72\ngrammar = \"gitcommit\"\n\n[[language]]\nname = \"github-action\"\nscope = \"source.yaml.github-action\"\nlanguage-servers = [ \"actions-language-server\", \"yaml-language-server\", \"zizmor\" ]\nfile-types = [{ glob = \".github/workflows/*.yaml\" }, { glob = \".github/workflows/*.yml\" }]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"yaml\"\n\n[[language]]\nname = \"diff\"\nscope = \"source.diff\"\nfile-types = [\"diff\", \"patch\", \"rej\"]\ninjection-regex = \"diff\"\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"diff\"\nsource = { git = \"https://github.com/the-mikedavis/tree-sitter-diff\", rev = \"fd74c78fa88a20085dbc7bbeaba066f4d1692b63\" }\n\n[[language]]\nname = \"git-rebase\"\nscope = \"source.gitrebase\"\nfile-types = [{ glob = \"git-rebase-todo\" }]\ninjection-regex = \"git-rebase\"\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"\\t\" }\n\n[[grammar]]\nname = \"git-rebase\"\nsource = { git = \"https://github.com/the-mikedavis/tree-sitter-git-rebase\", rev = \"d8a4207ebbc47bd78bacdf48f883db58283f9fd8\" }\n\n[[language]]\nname = \"regex\"\nscope = \"source.regex\"\ninjection-regex = \"regex\"\nfile-types = [\"regex\", { glob = \".Rbuildignore\" }]\n\n[[grammar]]\nname = \"regex\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-regex\", rev = \"e1cfca3c79896ff79842f057ea13e529b66af636\" }\n\n[[language]]\nname = \"git-config\"\nscope = \"source.gitconfig\"\nfile-types = [\"gitconfig\", { glob = \".gitmodules\" }, { glob = \"gitconfig\" }, { glob = \".gitconfig\" }, { glob = \".git/config\" }, { glob = \".config/git/config\" }, { glob = \".git/modules/*/config\" }, { glob = \"config.worktree\" }]\ninjection-regex = \"git-config\"\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[[grammar]]\nname = \"git-config\"\nsource = { git = \"https://github.com/the-mikedavis/tree-sitter-git-config\", rev = \"9c2a1b7894e6d9eedfe99805b829b4ecd871375e\" }\n\n[[language]]\nname = \"git-attributes\"\nscope = \"source.gitattributes\"\nfile-types = [{ glob = \".gitattributes\" }, { glob = \".config/git/attributes\" }]\ninjection-regex = \"git-attributes\"\ncomment-token = \"#\"\ngrammar = \"gitattributes\"\n\n[[grammar]]\nname = \"gitattributes\"\nsource = { git = \"https://github.com/mtoohey31/tree-sitter-gitattributes\", rev = \"3dd50808e3096f93dccd5e9dc7dc3dba2eb12dc4\" }\n\n[[language]]\nname = \"git-ignore\"\nscope = \"source.gitignore\"\nfile-types = [{ glob = \".gitignore_global\" }, { glob = \"git/ignore\" }, { glob = \".git/info/exclude\" }, { glob = \".ignore\" }, { glob = \"CODEOWNERS\" }, { glob = \".config/helix/ignore\" }, { glob = \".helix/ignore\" }, { glob = \".*ignore\" }, { glob = \".git-blame-ignore-revs\" }]\ninjection-regex = \"git-ignore\"\ncomment-token = \"#\"\ngrammar = \"gitignore\"\n\n[[grammar]]\nname = \"gitignore\"\nsource = { git = \"https://github.com/shunsambongi/tree-sitter-gitignore\", rev = \"f4685bf11ac466dd278449bcfe5fd014e94aa504\" }\n\n[[language]]\nname = \"graphql\"\nscope = \"source.graphql\"\ninjection-regex = \"graphql\"\nfile-types = [\"gql\", \"graphql\", \"graphqls\"]\nlanguage-servers = [ \"graphql-language-service\" ]\ncomment-token = \"#\"\nblock-comment-tokens = { start = \"\\\"\\\"\\\"\", end = \"\\\"\\\"\\\"\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"graphql\"\nsource = { git = \"https://github.com/bkegley/tree-sitter-graphql\", rev = \"5e66e961eee421786bdda8495ed1db045e06b5fe\" }\n\n[[language]]\nname = \"elm\"\nscope = \"source.elm\"\ninjection-regex = \"elm\"\nfile-types = [\"elm\"]\nroots = [\"elm.json\"]\nauto-format = true\ncomment-token = \"--\"\nblock-comment-tokens = { start = \"{-\", end = \"-}\" }\nlanguage-servers = [ \"elm-language-server\" ]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"elm\"\nsource = { git = \"https://github.com/elm-tooling/tree-sitter-elm\", rev = \"df4cb639c01b76bc9ac9cc66788709a6da20002c\" }\n\n[[language]]\nname = \"iex\"\nscope = \"source.iex\"\ninjection-regex = \"iex\"\nfile-types = [\"iex\"]\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"iex\"\nsource = { git = \"https://github.com/elixir-lang/tree-sitter-iex\", rev = \"39f20bb51f502e32058684e893c0c0b00bb2332c\" }\n\n[[language]]\nname = \"rescript\"\nscope = \"source.rescript\"\ninjection-regex = \"rescript\"\nfile-types = [\"res\"]\nroots = [\"bsconfig.json\"]\nauto-format = true\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"rescript-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"rescript\"\nsource = { git = \"https://github.com/rescript-lang/tree-sitter-rescript\", rev = \"5e2a44a9d886b0a509f5bfd0437d33b4871fbac5\" }\n\n[[language]]\nname = \"erlang\"\nscope = \"source.erlang\"\ninjection-regex = \"erl(ang)?\"\nfile-types = [\"erl\", \"hrl\", \"app\", { glob = \"rebar.config\" }, { glob = \"rebar.lock\" }, { glob = \"*.app.src\" }]\nroots = [\"rebar.config\"]\nshebangs = [\"escript\"]\ncomment-token = \"%%\"\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [\n  { name = \"erlang-ls\", except-features = [\"document-symbols\", \"workspace-symbols\"] },\n  { name = \"elp\", except-features = [\"document-symbols\", \"workspace-symbols\"] }\n]\n\n[[grammar]]\nname = \"erlang\"\nsource = { git = \"https://github.com/the-mikedavis/tree-sitter-erlang\", rev = \"33a3e4f1fa77a3e1a2736813f4b27c358f6c0b63\" }\n\n[[language]]\nname = \"kotlin\"\nscope = \"source.kotlin\"\nfile-types = [\"kt\", \"kts\"]\nroots = [\"settings.gradle\", \"settings.gradle.kts\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [ \"kotlin-language-server\" ]\n\n[[grammar]]\nname = \"kotlin\"\nsource = { git = \"https://github.com/fwcd/tree-sitter-kotlin\", rev = \"c4ddea359a7ff4d92360b2efcd6cfce5dc25afe6\" }\n\n[[language]]\nname = \"hcl\"\nscope = \"source.hcl\"\ninjection-regex = \"(hcl|tf|nomad)\"\nlanguage-id = \"terraform\"\nfile-types = [\"hcl\", \"tf\", \"nomad\"]\ncomment-token = \"#\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"terraform-ls\" ]\nauto-format = true\n\n[[grammar]]\nname = \"hcl\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-hcl\", rev = \"9e3ec9848f28d26845ba300fd73c740459b83e9b\" }\n\n[[language]]\nname = \"tfvars\"\nscope = \"source.tfvars\"\nlanguage-id = \"terraform-vars\"\nfile-types = [\"tfvars\"]\ncomment-token = \"#\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"terraform-ls\" ]\nauto-format = true\ngrammar = \"hcl\"\n\n[[language]]\nname = \"org\"\nscope = \"source.org\"\ninjection-regex = \"org\"\nfile-types = [\"org\"]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"org\"\nsource = { git = \"https://github.com/milisims/tree-sitter-org\", rev = \"698bb1a34331e68f83fc24bdd1b6f97016bb30de\" }\n\n[[language]]\nname = \"solidity\"\nscope = \"source.sol\"\ninjection-regex = \"(sol|solidity)\"\nfile-types = [\"sol\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [ \"solc\" ]\n\n[[grammar]]\nname = \"solidity\"\nsource = { git = \"https://github.com/JoranHonig/tree-sitter-solidity\", rev = \"f7f5251a3f5b1d04f0799b3571b12918af177fc8\" }\n\n[[language]]\nname = \"gleam\"\nscope = \"source.gleam\"\ninjection-regex = \"gleam\"\nfile-types = [\"gleam\"]\nroots = [\"gleam.toml\"]\ncomment-tokens = [\"//\", \"///\", \"////\"]\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"gleam\" ]\nauto-format = true\n\n[[grammar]]\nname = \"gleam\"\nsource = { git = \"https://github.com/gleam-lang/tree-sitter-gleam\", rev = \"dae1551a9911b24f41d876c23f2ab05ece0a9d4c\" }\n\n[[language]]\nname = \"quarto\"\nscope = \"source.qmd\"\nlanguage-id = \"qmd\"\ninjection-regex = \"qmd\"\nfile-types = [\"qmd\"]\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"markdown\"\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\n\n[[language]]\nname = \"ron\"\nscope = \"source.ron\"\ninjection-regex = \"ron\"\nfile-types = [\"ron\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\nroots = [ \"Cargo.toml\" ]\nlanguage-servers = [ \"ron-lsp\" ]\n\n[[grammar]]\nname = \"ron\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-ron\", rev = \"78938553b93075e638035f624973083451b29055\" }\n\n[[language]]\nname = \"robot\"\nscope = \"source.robot\"\ninjection-regex = \"robot\"\nfile-types = [\"robot\", \"resource\"]\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \" \" }\nlanguage-servers = [ \"robotcode\", \"robotframework_ls\" ]\n\n[[grammar]]\nname = \"robot\"\nsource = { git = \"https://github.com/Hubro/tree-sitter-robot\", rev = \"322e4cc65754d2b3fdef4f2f8a71e0762e3d13af\" }\n\n[[language]]\nname = \"r\"\nscope = \"source.r\"\ninjection-regex = \"(r|R)\"\nfile-types = [\"r\", \"R\", { glob = \".Rprofile\" }, { glob = \"Rprofile.site\" }, { glob = \".RHistory\" }]\nshebangs = [\"r\", \"R\"]\ncomment-tokens = [\"#\", \"#'\"]\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"r\" ]\n\n[[grammar]]\nname = \"r\"\nsource = { git = \"https://github.com/r-lib/tree-sitter-r\", rev = \"cc04302e1bff76fa02e129f332f44636813b0c3c\" }\n\n[[language]]\nname = \"rmarkdown\"\nscope = \"source.rmd\"\nlanguage-id = \"rmd\"\ninjection-regex = \"(r|R)md\"\nfile-types = [\"rmd\", \"Rmd\"]\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"markdown\"\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nlanguage-servers = [ \"r\" ]\n\n[[language]]\nname = \"swift\"\nscope = \"source.swift\"\ninjection-regex = \"swift\"\nfile-types = [\"swift\", \"swiftinterface\"]\nroots = [ \"Package.swift\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nformatter = { command = \"swift-format\" }\nlanguage-servers = [ \"sourcekit-lsp\" ]\n\n[[grammar]]\nname = \"swift\"\nsource = { git = \"https://github.com/alex-pinkus/tree-sitter-swift\", rev = \"57c1c6d6ffa1c44b330182d41717e6fe37430704\" }\n\n[[language]]\nname = \"erb\"\nscope = \"text.html.erb\"\ninjection-regex = \"erb\"\nfile-types = [\"erb\"]\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"embedded-template\"\n\n[[language]]\nname = \"ejs\"\nscope = \"text.html.ejs\"\ninjection-regex = \"ejs\"\nfile-types = [\"ejs\"]\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"embedded-template\"\n\n[[grammar]]\nname = \"embedded-template\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-embedded-template\", rev = \"d21df11b0ecc6fd211dbe11278e92ef67bd17e97\" }\n\n[[language]]\nname = \"eex\"\nscope = \"source.eex\"\ninjection-regex = \"eex\"\nfile-types = [\"eex\"]\nroots = [\"mix.exs\", \"mix.lock\"]\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"eex\"\nsource = { git = \"https://github.com/connorlay/tree-sitter-eex\", rev = \"f742f2fe327463335e8671a87c0b9b396905d1d1\" }\n\n[[language]]\nname = \"heex\"\nscope = \"source.heex\"\ninjection-regex = \"heex\"\nfile-types = [\"heex\"]\nroots = [\"mix.exs\", \"mix.lock\"]\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"elixir-ls\", \"expert\" ]\n\n[[grammar]]\nname = \"heex\"\nsource = { git = \"https://github.com/phoenixframework/tree-sitter-heex\", rev = \"f6b83f305a755cd49cf5f6a66b2b789be93dc7b9\" }\n\n[[language]]\nname = \"sql\"\nscope = \"source.sql\"\nfile-types = [\"sql\", \"dsql\"]\ncomment-token = \"--\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\ninjection-regex = \"sql\"\n\n[[grammar]]\nname = \"sql\"\n# from gh-pages branch, as the main branch does not provide the `src` directory\nsource = { git = \"https://github.com/DerekStride/tree-sitter-sql\", rev = \"86e3d03837d282544439620eb74d224586074b8b\" }\n\n[[language]]\nname = \"gdscript\"\nscope = \"source.gdscript\"\ninjection-regex = \"gdscript\"\nfile-types = [\"gd\"]\nshebangs = []\nroots = [\"project.godot\"]\nauto-format = true\nformatter = { command = \"gdformat\", args = [\"-\"] }\ncomment-tokens = [\"#\", \"##\"]\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[[grammar]]\nname = \"gdscript\"\nsource = { git = \"https://github.com/PrestonKnopp/tree-sitter-gdscript\", rev = \"1f1e782fe2600f50ae57b53876505b8282388d77\" }\n\n[[language]]\nname = \"godot-resource\"\nscope = \"source.tscn\"\ninjection-regex = \"godot\"\nfile-types = [\"tscn\", \"tres\", \"godot\", \"gdextension\"]\nshebangs = []\nroots = [\"project.godot\"]\nauto-format = false\ncomment-token = \";\"\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[[grammar]]\nname = \"godot-resource\"\nsource = { git = \"https://github.com/PrestonKnopp/tree-sitter-godot-resource\", rev = \"2ffb90de47417018651fc3b970e5f6b67214dc9d\" }\n\n[[language]]\nname = \"nu\"\nscope = \"source.nu\"\ninjection-regex = \"nu\"\nfile-types = [\"nu\", \"nuon\"]\nshebangs = [\"nu\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"nu-lsp\", \"nu-lint\" ]\nformatter = { command = \"nufmt\", args = [\"--stdin\"] } # https://github.com/nushell/nufmt\nauto-format = false\n\n[[grammar]]\nname = \"nu\"\nsource = { git = \"https://github.com/nushell/tree-sitter-nu\", rev = \"cc4624fbc6ec3563d98fbe8f215a8b8e10b16f32\" }\n\n[[language]]\nname = \"vala\"\nscope = \"source.vala\"\ninjection-regex = \"vala\"\nfile-types = [\"vala\", \"vapi\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"vala-language-server\" ]\n\n[[grammar]]\nname = \"vala\"\nsource = { git = \"https://github.com/vala-lang/tree-sitter-vala\", rev = \"c9eea93ba2ec4ec1485392db11945819779745b3\" }\n\n[[language]]\nname = \"hare\"\nscope = \"source.hare\"\ninjection-regex = \"hare\"\nfile-types = [\"ha\"]\ncomment-token = \"//\"\nindent = { tab-width = 8, unit = \"\\t\" }\nlanguage-servers = [\n  { except-features = [\n    \"code-action\", \"completion\", \"format\", \"inlay-hints\", \"rename-symbol\", \"workspace-symbols\",\n  ], name = \"hare-lsp\" },\n]\n\n[[grammar]]\nname = \"hare\"\nsource = { git = \"https://git.sr.ht/~ecs/tree-sitter-hare\", rev = \"07035a248943575444aa0b893ffe306e1444c0ab\" }\n\n[[language]]\nname = \"devicetree\"\nscope = \"source.devicetree\"\ninjection-regex = \"(dtsi?|devicetree|fdt)\"\nfile-types = [\"dts\", \"dtsi\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"\\t\" }\nlanguage-servers = [ \"dts-lsp\" ]\n\n[[grammar]]\nname = \"devicetree\"\nsource = { git = \"https://github.com/joelspadin/tree-sitter-devicetree\", rev = \"877adbfa0174d25894c40fa75ad52d4515a36368\" }\n\n[[language]]\nname = \"cairo\"\nscope = \"source.cairo\"\ninjection-regex = \"cairo\"\nfile-types = [\"cairo\"]\ncomment-token = \"//\"\nindent = { tab-width = 4, unit = \"    \" }\n# auto-format = true\nlanguage-servers = [ \"cairo-language-server\" ]\n\n[[grammar]]\nname = \"cairo\"\nsource = { git = \"https://github.com/starkware-libs/tree-sitter-cairo\", rev = \"4c6a25680546761b80a710ead1dd34e76c203125\" }\n\n[[language]]\nname = \"cpon\"\nscope = \"scope.cpon\"\ninjection-regex = \"cpon\"\nfile-types = [\"cpon\", \"cp\"]\nauto-format = true\ncomment-token = \"//\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"cpon\"\nsource = { git = \"https://github.com/fvacek/tree-sitter-cpon\", rev = \"0d01fcdae5a53191df5b1349f9bce053833270e7\" }\n\n[[language]]\nname = \"odin\"\nauto-format = true\nscope = \"source.odin\"\nfile-types = [\"odin\"]\nroots = [\"ols.json\", \"main.odin\"]\nlanguage-servers = [ \"ols\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"\\t\" }\nformatter = { command = \"odinfmt\", args = [ \"-stdin\" ] }\n\n[language.debugger]\nname = \"lldb-dap\"\ntransport = \"stdio\"\ncommand = \"lldb-dap\"\n\n[[language.debugger.templates]]\nname = \"binary\"\nrequest = \"launch\"\ncompletion = [ { name = \"binary\", completion = \"filename\" } ]\nargs = { console = \"internalConsole\", program = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"attach\"\nrequest = \"attach\"\ncompletion = [ \"pid\" ]\nargs = { console = \"internalConsole\", pid = \"{0}\" }\n\n[[language.debugger.templates]]\nname = \"gdbserver attach\"\nrequest = \"attach\"\ncompletion = [ { name = \"lldb connect url\", default = \"connect://localhost:3333\" }, { name = \"file\", completion = \"filename\" }, \"pid\" ]\nargs = { console = \"internalConsole\", attachCommands = [ \"platform select remote-gdb-server\", \"platform connect {0}\", \"file {1}\", \"attach {2}\" ] }\n\n[[grammar]]\nname = \"odin\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-odin\", rev = \"6c6b07e354a52f8f2a9bc776cbc262a74e74fd26\" }\n\n[[language]]\nname = \"meson\"\nscope = \"source.meson\"\ninjection-regex = \"meson\"\nfile-types = [{ glob = \"meson.build\" }, { glob = \"meson.options\" }, { glob = \"meson_options.txt\" }]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [\"mesonlsp\"]\n\n[[grammar]]\nname = \"meson\"\nsource = { git = \"https://github.com/staysail/tree-sitter-meson\", rev = \"32a83e8f200c347232fa795636cfe60dde22957a\" }\n\n[[language]]\nname = \"sshclientconfig\"\nscope = \"source.sshclientconfig\"\nfile-types = [{ glob = \".ssh/config\" }, { glob = \"/etc/ssh/ssh_config\" }, { glob = \"ssh_config.d/*.conf\" } ]\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"sshclientconfig\"\nsource = { git = \"https://github.com/metio/tree-sitter-ssh-client-config\", rev = \"e45c6d5c71657344d4ecaf87dafae7736f776c57\" }\n\n[[language]]\nname = \"scheme\"\nscope = \"source.scheme\"\ninjection-regex = \"scheme\"\nfile-types = [\"ss\", \"scm\", \"sld\"]\nshebangs = [\"scheme\", \"guile\", \"chicken\"]\ncomment-token = \";\"\nblock-comment-tokens = { start = \"#|\", end = \"|#\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\n[[grammar]]\nname = \"scheme\"\nsource = { git = \"https://github.com/6cdh/tree-sitter-scheme\", rev = \"af3af6c9356b936f8a515a1e449c32e804c2b1a8\" }\n\n[[language]]\nname = \"v\"\nscope = \"source.v\"\nfile-types = [\"v\", \"vv\", \"vsh\"]\nshebangs = [\"v run\"]\nroots = [\"v.mod\"]\nlanguage-servers = [ \"vlang-language-server\" ]\nauto-format = true\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[[grammar]]\nname = \"v\"\nsource = {git = \"https://github.com/vlang/v-analyzer\", subpath = \"tree_sitter_v\", rev = \"59a8889d84a293d7c0366d14c8dbb0eec24fe889\"}\n\n[[language]]\nname = \"verilog\"\nscope = \"source.verilog\"\nfile-types = [\"v\", \"vh\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [\"verible-verilog-ls\"]\nindent = { tab-width = 2, unit = \"  \" }\ninjection-regex = \"verilog\"\n\n[[grammar]]\nname = \"verilog\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-verilog\", rev = \"4457145e795b363f072463e697dfe2f6973c9a52\" }\n\n[[language]]\nname = \"systemverilog\"\nscope = \"source.systemverilog\"\nfile-types = [\"sv\", \"svh\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [\"svlangserver\", \"verible-verilog-ls\"]\n\n[[grammar]]\nname = \"systemverilog\"\nsource = { git = \"https://github.com/gmlarumbe/tree-sitter-systemverilog\", rev = \"3bd2c5d2f60ed7b07c2177b34e2976ad9a87c659\" }\n\n[[language]]\nname = \"edoc\"\nscope = \"source.edoc\"\nfile-types = [\"edoc\", \"edoc.in\"]\ninjection-regex = \"edoc\"\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"edoc\"\nsource = { git = \"https://github.com/the-mikedavis/tree-sitter-edoc\", rev = \"74774af7b45dd9cefbf9510328fc6ff2374afc50\" }\n\n[[language]]\nname = \"jsdoc\"\nscope = \"source.jsdoc\"\ninjection-regex = \"jsdoc\"\nfile-types = [\"jsdoc\"]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"jsdoc\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-jsdoc\", rev = \"189a6a4829beb9cdbe837260653b4a3dfb0cc3db\" }\n\n[[language]]\nname = \"openscad\"\nscope = \"source.openscad\"\ninjection-regex = \"openscad\"\nfile-types = [\"scad\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"openscad-lsp\" ]\nindent = { tab-width = 2, unit = \"\\t\" }\n\n[[grammar]]\nname = \"openscad\"\nsource = { git = \"https://github.com/openscad/tree-sitter-openscad\", rev = \"acc196e969a169cadd8b7f8d9f81ff2d30e3e253\" }\n\n[[language]]\nname = \"prisma\"\nscope = \"source.prisma\"\ninjection-regex = \"prisma\"\nfile-types = [\"prisma\"]\nroots = [\"package.json\"]\ncomment-token = \"//\"\nlanguage-servers = [ \"prisma-language-server\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"prisma\"\nsource = { git = \"https://github.com/victorhqc/tree-sitter-prisma\", rev = \"eca2596a355b1a9952b4f80f8f9caed300a272b5\" }\n\n[[language]]\nname = \"clojure\"\nscope = \"source.clojure\"\ninjection-regex = \"(clojure|clj|edn|boot)\"\nfile-types = [\"clj\", \"cljs\", \"cljc\", \"clje\", \"cljr\", \"cljx\", \"edn\", \"boot\"]\nroots = [\"project.clj\", \"build.boot\", \"deps.edn\", \"shadow-cljs.edn\"]\ncomment-token = \";\"\nlanguage-servers = [ \"clojure-lsp\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"clojure\"\nsource = { git = \"https://github.com/sogaiu/tree-sitter-clojure\", rev = \"e57c569ae332ca365da623712ae1f50f84daeae2\" }\n\n[[language]]\nname = \"starlark\"\nscope = \"source.starlark\"\ninjection-regex = \"(starlark|bzl|bazel|buck)\"\nfile-types = [\"bzl\", \"bazel\", \"star\", { glob = \"BUILD\" }, { glob = \"BUCK\" }, { glob = \"BUILD.*\" }, { glob = \"WORKSPACE\" }, { glob = \"WORKSPACE.bzlmod\" }, { glob = \"PACKAGE\" }]\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [ \"starpls\" ]\ngrammar = \"python\"\n\n[[language]]\nname = \"elvish\"\nscope = \"source.elvish\"\nshebangs = [\"elvish\"]\nfile-types = [\"elv\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"elvish\" ]\ngrammar = \"elvish\"\n\n[[grammar]]\nname = \"elvish\"\nsource = { git = \"https://github.com/ckafi/tree-sitter-elvish\", rev = \"e50787cadd3bc54f6d9c0704493a79078bb8a4e5\" }\n\n[[language]]\nname = \"idris\"\nscope = \"source.idr\"\ninjection-regex = \"idr\"\nfile-types = [\"idr\"]\nshebangs = []\ncomment-token = \"--\"\nblock-comment-tokens = { start = \"{-\", end = \"-}\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"idris2-lsp\" ]\n\n[[language]]\nname = \"fortran\"\nscope = \"source.fortran\"\ninjection-regex = \"fortran\"\nfile-types = [\"f\", \"for\", \"f90\", \"f95\", \"f03\", \"F\", \"F90\", \"F95\", \"F03\"]\nroots = [\"fpm.toml\"]\ncomment-token = \"!\"\nindent = { tab-width = 4, unit = \"    \"}\nlanguage-servers = [ \"fortls\" ]\n\n[[grammar]]\nname = \"fortran\"\nsource = { git = \"https://github.com/stadelmanma/tree-sitter-fortran\", rev = \"2880b7aab4fb7cc618de1ef3d4c6d93b2396c031\" }\n\n[[language]]\nname = \"ungrammar\"\nscope = \"source.ungrammar\"\ninjection-regex = \"ungrammar\"\nfile-types = [\"ungram\", \"ungrammar\"]\ncomment-token = \"//\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"ungrammar\"\nsource = { git = \"https://github.com/Philipp-M/tree-sitter-ungrammar\", rev = \"a7e104629cff5a8b7367187610631e8f5eb7c6ea\" }\n\n[[language]]\nname = \"dot\"\nscope = \"source.dot\"\ninjection-regex = \"dot\"\nfile-types = [\"dot\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [ \"dot-language-server\" ]\n\n[[grammar]]\nname = \"dot\"\nsource = { git = \"https://github.com/rydesun/tree-sitter-dot\", rev = \"917230743aa10f45a408fea2ddb54bbbf5fbe7b7\" }\n\n[[language]]\nname = \"cue\"\nscope = \"source.cue\"\ninjection-regex = \"cue\"\nfile-types = [\"cue\"]\nroots = [\"cue.mod\"]\nauto-format = true\ncomment-token = \"//\"\nlanguage-servers = [ \"cuelsp\" ]\nindent = { tab-width = 4, unit = \"\\t\" }\nformatter = { command = \"cue\", args = [\"fmt\", \"-\"] }\n\n[[grammar]]\nname = \"cue\"\nsource = { git = \"https://github.com/eonpatapon/tree-sitter-cue\", rev = \"8a5f273bfa281c66354da562f2307c2d394b6c81\" }\n\n[[language]]\nname = \"slang\"\nscope = \"source.lang\"\ninjection-regex = \"slang\"\nfile-types = [\"slang\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"slangd\" ]\nindent = { tab-width = 4, unit = \"  \" }\n\n[[grammar]]\nname = \"slang\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-slang\", rev = \"327b1b821c255867a4fb724c8eee48887e3d014b\" }\n\n[[language]]\nname = \"slint\"\nscope = \"source.slint\"\ninjection-regex = \"slint\"\nfile-types = [\"slint\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [ \"slint-lsp\" ]\n\n[[grammar]]\nname = \"slint\"\nsource = { git = \"https://github.com/slint-ui/tree-sitter-slint\", rev = \"f11da7e62051ba8b9d4faa299c26de8aeedfc1cd\" }\n\n[[language]]\nname = \"task\"\nscope = \"source.task\"\ninjection-regex = \"task\"\nfile-types = [\"task\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"task\"\nsource = { git = \"https://github.com/alexanderbrevig/tree-sitter-task\", rev = \"f2cb435c5dbf3ee19493e224485d977cb2d36d8b\" }\n\n[[language]]\nname = \"xit\"\nscope = \"source.xit\"\ninjection-regex = \"xit\"\nfile-types = [\"xit\"]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"xit\"\nsource = { git = \"https://github.com/synaptiko/tree-sitter-xit\", rev = \"7d7902456061bc2ad21c64c44054f67b5515734c\" }\n\n[[language]]\nname = \"esdl\"\nscope = \"source.esdl\"\ninjection-regex = \"esdl\"\nfile-types = [\"gel\", \"esdl\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nroots = [\"gel.toml\", \"edgedb.toml\"]\n\n[[grammar]]\nname =\"esdl\"\nsource = { git = \"https://github.com/hongquan/tree-sitter-esdl\", rev = \"c824fe2bbbed6b29e50c694420aa2b377782f80a\" }\n\n[[language]]\nname = \"pascal\"\nscope = \"source.pascal\"\ninjection-regex = \"pascal\"\nfile-types = [\"pas\", \"pp\", \"inc\", \"lpr\", \"lfm\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"{\", end = \"}\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"pasls\" ]\n\n[[grammar]]\nname = \"pascal\"\nsource = { git = \"https://github.com/Isopod/tree-sitter-pascal\", rev = \"2fd40f477d3e2794af152618ccfac8d92eb72a66\" }\n\n[[language]]\nname = \"sml\"\nscope = \"source.sml\"\ninjection-regex = \"sml\"\nfile-types = [\"sml\"]\nblock-comment-tokens = { start = \"(*\", end = \"*)\" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\n[[grammar]]\nname = \"sml\"\nsource = { git = \"https://github.com/Giorbo/tree-sitter-sml\", rev = \"bd4055d5554614520d4a0706b34dc0c317c6b608\" }\n\n[[language]]\nname = \"jsonnet\"\nscope = \"source.jsonnet\"\nfile-types = [\"libsonnet\", \"jsonnet\"]\nroots = [\"jsonnetfile.json\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"jsonnet-language-server\" ]\n\n[[grammar]]\nname = \"jsonnet\"\nsource = { git = \"https://github.com/sourcegraph/tree-sitter-jsonnet\", rev = \"0475a5017ad7dc84845d1d33187f2321abcb261d\" }\n\n[[language]]\nname = \"ada\"\nscope = \"source.ada\"\ninjection-regex = \"ada\"\nfile-types = [\"adb\", \"ads\"]\nroots = [\"alire.toml\"]\ncomment-token = \"--\"\nindent = { tab-width = 3, unit = \"   \" }\nlanguage-servers = [\"ada-language-server\"]\n\n[[grammar]]\nname = \"ada\"\nsource = { git = \"https://github.com/briot/tree-sitter-ada\", rev = \"ba0894efa03beb70780156b91e28c716b7a4764d\" }\n\n[[language]]\nname = \"astro\"\nscope = \"source.astro\"\ninjection-regex = \"astro\"\nfile-types = [\"astro\"]\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"astro-ls\" ]\n\n[[grammar]]\nname = \"astro\"\nsource = { git = \"https://github.com/virchau13/tree-sitter-astro\", rev = \"947e93089e60c66e681eba22283f4037841451e7\" }\n\n[[language]]\nname = \"bass\"\nscope = \"source.bass\"\ninjection-regex = \"bass\"\nfile-types = [\"bass\"]\ncomment-token = \";\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"bass\" ]\n\n[[grammar]]\nname = \"bass\"\nsource = { git = \"https://github.com/vito/tree-sitter-bass\", rev = \"501133e260d768ed4e1fd7374912ed5c86d6fd90\" }\n\n[[language]]\nname = \"wat\"\nscope = \"source.wat\"\ncomment-token = \";;\"\nblock-comment-tokens = { start = \"(;\", end = \";)\" }\nfile-types = [\"wat\"]\nlanguage-servers = [\"wasm-language-tools\"]\n\n[[grammar]]\nname = \"wat\"\nsource = { git = \"https://github.com/wasm-lsp/tree-sitter-wasm\", rev = \"2ca28a9f9d709847bf7a3de0942a84e912f59088\", subpath = \"wat\" }\n\n[[language]]\nname = \"wast\"\nscope = \"source.wast\"\ncomment-token = \";;\"\nblock-comment-tokens = { start = \"(;\", end = \";)\" }\nfile-types = [\"wast\"]\n\n[[grammar]]\nname = \"wast\"\nsource = { git = \"https://github.com/wasm-lsp/tree-sitter-wasm\", rev = \"2ca28a9f9d709847bf7a3de0942a84e912f59088\", subpath = \"wast\" }\n\n[[language]]\nname = \"d\"\nscope = \"source.d\"\nfile-types = [ \"d\", \"dd\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\ninjection-regex = \"d\"\nindent = { tab-width = 4, unit = \"    \"}\nlanguage-servers = [ \"serve-d\" ]\nformatter = { command = \"dfmt\" }\n\n[[grammar]]\nname = \"d\"\nsource = { git = \"https://github.com/gdamore/tree-sitter-d\", rev = \"5566f8ce8fc24186fad06170bbb3c8d97c935d74\" }\n\n[[language]]\nname = \"vhs\"\nscope = \"source.vhs\"\nfile-types = [\"tape\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"vhs\"\n\n[[grammar]]\nname = \"vhs\"\nsource = { git = \"https://github.com/charmbracelet/tree-sitter-vhs\", rev = \"9534865e614c95eb9418e5e73f061c32fa4d9540\" }\n\n[[language]]\nname = \"kdl\"\nscope = \"source.kdl\"\nfile-types = [\"kdl\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\ninjection-regex = \"kdl\"\nformatter = { command = \"kdlfmt\", args = [\"format\", \"-\"] }\n\n[[grammar]]\nname = \"kdl\"\nsource = { git = \"https://github.com/amaanq/tree-sitter-kdl\", rev = \"3ca569b9f9af43593c24f9e7a21f02f43a13bb88\" }\n\n[[language]]\nname = \"xml\"\nscope = \"source.xml\"\ninjection-regex = \"xml\"\nfile-types = [\n  \"ascx\",\n  \"atom\",\n  \"axaml\",\n  \"axml\",\n  \"bpmn\",\n  \"checkstyle\",\n  \"cpt\",\n  \"csl\",\n  \"csproj.user\",\n  \"dita\",\n  \"ditamap\",\n  \"dtml\",\n  \"fods\",\n  \"fodt\",\n  \"fxml\",\n  \"gir\",\n  \"glif\",\n  \"gml\",\n  \"gpx\",\n  \"iml\",\n  \"isml\",\n  \"itermcolors\",\n  \"jmx\",\n  \"kml\",\n  \"launch\",\n  \"menu\",\n  \"mobileconfig\",\n  \"mpd\",\n  \"musicxml\",\n  \"mxml\",\n  \"ncx\",\n  \"nuspec\",\n  \"opml\",\n  \"osc\",\n  \"osm\",\n  \"plist\",\n  \"policy\",\n  \"pt\",\n  \"publishsettings\",\n  \"pubxml\",\n  \"pubxml.user\",\n  \"rbxlx\",\n  \"rbxmx\",\n  \"resx\",\n  \"rng\",\n  \"rss\",\n  \"shproj\",\n  \"smil\",\n  \"storyboard\",\n  \"sublime-snippet\",\n  \"svg\",\n  \"terminal\",\n  \"tld\",\n  \"tmx\",\n  \"ui\",\n  \"vbproj.user\",\n  \"vcxproj\",\n  \"vcxproj.filters\",\n  \"wixproj\",\n  \"wsdl\",\n  \"wxi\",\n  \"wxs\",\n  \"xaml\",\n  \"xbl\",\n  \"xib\",\n  \"xlf\",\n  \"xliff\",\n  \"xml\",\n  \"xmp\",\n  \"xoml\",\n  \"xpdl\",\n  \"xrc\",\n  \"xsd\",\n  \"xsl\",\n  \"xul\",\n  { glob = \"*.tm[Ll]anguage\" },\n  { glob = \"*.tm[Pp]references\" },\n  { glob = \"*.tm[Tt]heme\" },\n]\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\"'\" = \"'\"\n\"<\" = \">\"\n\n[[grammar]]\nname = \"xml\"\nsource = { git = \"https://github.com/RenjiSann/tree-sitter-xml\", rev = \"48a7c2b6fb9d515577e115e6788937e837815651\" }\n\n[[language]]\nname = \"dtd\"\nscope = \"source.dtd\"\ninjection-regex = \"dtd\"\nfile-types = [\"dtd\", \"ent\"]\nindent = {tab-width = 2, unit = \"  \"}\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\n\n[language.auto-pairs]\n'(' = ')'\n'[' = ']'\n'\"' = '\"'\n\"'\" = \"'\"\n'<' = '>'\n\n[[grammar]]\nname = \"dtd\"\nsource = { git = \"https://github.com/KMikeeU/tree-sitter-dtd\", rev = \"6116becb02a6b8e9588ef73d300a9ba4622e156f\"}\n\n[[language]]\nname = \"wit\"\nscope = \"source.wit\"\ninjection-regex = \"wit\"\nfile-types = [\"wit\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\"'\" = \"'\"\n\"<\" = \">\"\n\n[[grammar]]\nname = \"wit\"\nsource = { git = \"https://github.com/hh9527/tree-sitter-wit\", rev = \"c917790ab9aec50c5fd664cbfad8dd45110cfff3\" }\n\n[[language]]\nname = \"env\"\nscope = \"source.env\"\nfile-types = [\n  { glob = \".env\" },\n  { glob = \".env.*\" },\n  { glob = \".envrc\" },\n  { glob = \".envrc.*\" },\n  { glob = \"_environment\" }, # https://quarto.org/docs/projects/environment.html#environment-file\n  { glob = \"_environment-*\" }, # https://quarto.org/docs/projects/environment.html#profile-environments\n  { glob = \"_environment.local\" }, # https://quarto.org/docs/projects/environment.html#local-environment\n  { glob = \"_environment.required\" }, # https://quarto.org/docs/projects/environment.html#required-variables\n  { glob = \".bazeliskrc\" }, # https://github.com/bazelbuild/bazelisk#bazeliskrc-configuration-file\n]\ninjection-regex = \"env\"\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"\\t\" }\ngrammar = \"bash\"\n\n[[language]]\nname = \"systemd\"\nscope = \"source.ini\"\nfile-types = [\n  # Systemd unit files\n  \"service\",\n  \"automount\",\n  \"device\",\n  \"mount\",\n  \"nspawn\",\n  \"path\",\n  \"scope\",\n  \"slice\",\n  \"socket\",\n  \"swap\",\n  \"target\",\n  \"timer\",\n  { glob = \"systemd/**/*.conf\" },\n]\ninjection-regex = \"systemd\"\ncomment-token = \"#\"\ngrammar = \"ini\"\nlanguage-servers = [\"systemd-lsp\"]\n\n[[language]]\nname = \"ini\"\nscope = \"source.ini\"\nfile-types = [\n  \"ini\",\n  \"desktop\",\n  { glob = \"mimeapps.list\" },\n  # Podman quadlets\n  \"container\",\n  \"volume\",\n  \"kube\",\n  \"network\",\n  { glob = \".editorconfig\" },\n  { glob = \".npmrc\" },\n  { glob = \"hgrc\" },\n  { glob = \"npmrc\" },\n  { glob = \"rclone.conf\" },\n  { glob = \".aws/config\" },\n  \"properties\",\n  \"cfg\",\n  \"directory\",\n  { glob = \".wslconfig\" },\n]\ninjection-regex = \"ini\"\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[[grammar]]\nname = \"ini\"\nsource = { git = \"https://github.com/justinmk/tree-sitter-ini\", rev = \"32b31863f222bf22eb43b07d4e9be8017e36fb31\" }\n\n[[language]]\nname = \"inko\"\nauto-format = true\nscope = \"source.inko\"\ninjection-regex = \"inko\"\nfile-types = [\"inko\"]\nroots = [\"inko.pkg\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nformatter = { command = \"inko\", args = [\"fmt\", \"-\"] }\n\n[[grammar]]\nname = \"inko\"\nsource = { git = \"https://github.com/inko-lang/tree-sitter-inko\", rev = \"f58a87ac4dc6a7955c64c9e4408fbd693e804686\" }\n\n[[language]]\nname = \"bicep\"\nscope = \"source.bicep\"\nfile-types = [\"bicep\",\"bicepparam\"]\nauto-format = true\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \" \"}\nlanguage-servers = [ \"bicep-langserver\" ]\n\n[[grammar]]\nname = \"bicep\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-bicep\", rev = \"0092c7d1bd6bb22ce0a6f78497d50ea2b87f19c0\" }\n\n[[language]]\nname = \"qml\"\nscope = \"source.qml\"\nfile-types = [\"qml\"]\nlanguage-servers = [ \"qmlls\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\ngrammar = \"qmljs\"\n\n[[grammar]]\nname = \"qmljs\"\nsource = { git = \"https://github.com/yuja/tree-sitter-qmljs\", rev = \"0b2b25bcaa7d4925d5f0dda16f6a99c588a437f1\" }\n\n[[language]]\nname = \"mermaid\"\nscope = \"source.mermaid\"\ninjection-regex = \"mermaid\"\nfile-types = [\"mermaid\", \"mmd\"]\ncomment-token = \"%%\"\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"mermaid\"\nsource = { git = \"https://github.com/monaqa/tree-sitter-mermaid\", rev = \"d787c66276e7e95899230539f556e8b83ee16f6d\" }\n\n[[language]]\nname = \"matlab\"\nscope = \"source.m\"\nfile-types = [\"m\"]\ncomment-token = \"%\"\nshebangs = [\"octave-cli\", \"matlab\"]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"matlab\"\nsource = { git = \"https://github.com/acristoffers/tree-sitter-matlab\", rev = \"55d89cb322c9bc49bfd953b2a9d29ff03b072eac\" }\n\n[[language]]\nname = \"ponylang\"\nscope = \"source.pony\"\nfile-types = [\"pony\"]\ninjection-regex = \"pony\"\nroots = [\"corral.json\", \"lock.json\"]\nindent = { tab-width = 2, unit = \"  \" }\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"pony-lsp\" ]\n\n[[grammar]]\nname = \"ponylang\"\nsource = { git = \"https://github.com/mfelsche/tree-sitter-ponylang\", rev = \"ef66b151bc2604f431b5668fcec4747db4290e11\" }\n\n[[language]]\nname = \"dhall\"\nscope = \"source.dhall\"\ninjection-regex = \"dhall\"\nfile-types = [\"dhall\"]\ncomment-token = \"--\"\nblock-comment-tokens = { start = \"{-\", end = \"-}\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"dhall-lsp-server\" ]\nformatter = { command = \"dhall\" , args = [\"format\"] }\n\n[[grammar]]\nname = \"dhall\"\nsource = { git = \"https://github.com/jbellerb/tree-sitter-dhall\", rev = \"affb6ee38d629c9296749767ab832d69bb0d9ea8\" }\n\n[[language]]\nname = \"sage\"\nscope = \"source.sage\"\nfile-types = [\"sage\"]\ninjection-regex = \"sage\"\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\ngrammar = \"python\"\n\n[[language]]\nname = \"msbuild\"\nscope = \"source.msbuild\"\ninjection-regex = \"msbuild\"\nfile-types = [\"proj\", \"vbproj\", \"csproj\", \"fsproj\", \"targets\", \"props\"]\nindent = { tab-width = 2, unit = \"  \" }\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\ngrammar = \"xml\"\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\"'\" = \"'\"\n\"<\" = \">\"\n\n[[language]]\nname = \"pem\"\nscope = \"source.pem\"\nfile-types = [\"pem\", \"cert\", \"crt\"]\ninjection-regex = \"pem\"\ngrammar = \"pem\"\n\n[[grammar]]\nname = \"pem\"\nsource = { git = \"https://github.com/mtoohey31/tree-sitter-pem\", rev = \"be67a4330a1aa507c7297bc322204f936ec1132c\" }\n\n[[language]]\nname = \"passwd\"\nscope = \"source.passwd\"\nfile-types = [{ glob = \"passwd\" }]\n\n[[grammar]]\nname = \"passwd\"\nsource = { git = \"https://github.com/ath3/tree-sitter-passwd\", rev = \"20239395eacdc2e0923a7e5683ad3605aee7b716\" }\n\n[[language]]\nname = \"hosts\"\nscope = \"source.hosts\"\nfile-types = [{ glob = \"hosts\" }]\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"hosts\"\nsource = { git = \"https://github.com/ath3/tree-sitter-hosts\", rev = \"301b9379ce7dfc8bdbe2c2699a6887dcb73953f9\" }\n\n[[language]]\nname = \"uxntal\"\nscope = \"source.tal\"\ninjection-regex = \"tal\"\nfile-types = [\"tal\"]\nauto-format = false\nblock-comment-tokens = { start = \"(\", end = \")\" }\n\n[[grammar]]\nname = \"uxntal\"\nsource = { git = \"https://github.com/Jummit/tree-sitter-uxntal\", rev = \"d68406066648cd6db4c6a2f11ec305af02079884\" }\n\n[[language]]\nname = \"yuck\"\nscope = \"source.yuck\"\ninjection-regex = \"yuck\"\nfile-types = [\"yuck\"]\ncomment-token = \";\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"yuck\"\nsource = { git = \"https://github.com/Philipp-M/tree-sitter-yuck\", rev = \"e3d91a3c65decdea467adebe4127b8366fa47919\" }\n\n[[language]]\nname = \"prql\"\nscope = \"source.prql\"\ninjection-regex = \"prql\"\nfile-types = [\"prql\"]\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"prql\"\nsource = { git = \"https://github.com/PRQL/tree-sitter-prql\", rev = \"09e158cd3650581c0af4c49c2e5b10c4834c8646\" }\n\n[[language]]\nname = \"po\"\nscope = \"source.po\"\nfile-types = [\"po\", \"pot\"]\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"po\"\nsource = { git = \"https://github.com/erasin/tree-sitter-po\", rev = \"417cee9abb2053ed26b19e7de972398f2da9b29e\" }\n\n[[language]]\nname = \"nasm\"\nscope = \"source.nasm\"\nfile-types = [\"asm\", \"S\", \"nasm\"]\ninjection-regex = \"n?asm\"\ncomment-token = \";\"\nindent = { tab-width = 8, unit = \"        \" }\nlanguage-servers = [\"asm-lsp\"]\n\n[[grammar]]\nname = \"nasm\"\nsource = { git = \"https://github.com/naclsn/tree-sitter-nasm\", rev = \"570f3d7be01fffc751237f4cfcf52d04e20532d1\" }\n\n[[language]]\nname = \"gas\"\nscope = \"source.gas\"\nfile-types = [\"s\"]\ninjection-regex = \"gas\"\ncomment-token = \"#\"\nindent = { tab-width = 8, unit = \"        \" }\nlanguage-servers = [\"asm-lsp\"]\n\n[[grammar]]\nname = \"gas\"\nsource = { git = \"https://github.com/sirius94/tree-sitter-gas\", rev = \"60f443646b20edee3b7bf18f3a4fb91dc214259a\" }\n\n[[language]]\nname = \"rst\"\nscope = \"source.rst\"\ncomment-token = \"..\"\nfile-types = [\"rst\"]\n\n[[grammar]]\nname = \"rst\"\nsource = { git = \"https://github.com/stsewd/tree-sitter-rst\", rev = \"ab09cab886a947c62a8c6fa94d3ad375f3f6a73d\" }\n\n[[language]]\nname = \"capnp\"\nscope = \"source.capnp\"\ninjection-regex = \"capnp\"\nfile-types = [\"capnp\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"capnp\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-capnp\", rev = \"7b0883c03e5edd34ef7bcf703194204299d7099f\" }\n\n[[language]]\nname = \"smithy\"\nscope = \"source.smithy\"\ninjection-regex = \"smithy\"\nfile-types = [\"smithy\"]\nroots = [\"smithy-build.json\"]\ncomment-token = \"//\"\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [ \"cs\" ]\n\n[[grammar]]\nname = \"smithy\"\nsource = { git = \"https://github.com/indoorvivants/tree-sitter-smithy\", rev = \"8327eb84d55639ffbe08c9dc82da7fff72a1ad07\" }\n\n[[language]]\nname = \"hdl\"\nscope = \"source.hdl\"\nfile-types = [\"hdl\"]\nindent = { tab-width = 4, unit = \"    \" }\ninjection-regex = \"hdl\"\nlanguage-servers = [ \"hdls\" ]\n\n[[grammar]]\nname = \"hdl\"\nsource = { git = \"https://github.com/quantonganh/tree-sitter-hdl\", rev=\"293902330423b2cd36ab1ec4b6b967163a4ed57b\" }\n\n[[language]]\nname = \"vhdl\"\nscope = \"source.vhdl\"\nfile-types = [\"vhd\", \"vhdl\"]\ncomment-token = \"--\"\nlanguage-servers = [ \"vhdl_ls\" ]\nindent = { tab-width = 2, unit = \"  \" }\ninjection-regex = \"vhdl\"\n\n[[grammar]]\nname = \"vhdl\"\nsource = { git = \"https://github.com/jpt13653903/tree-sitter-vhdl\", rev = \"32d3e3daa745bf9f1665676f323be968444619e1\" }\n\n[[language]]\nname = \"rego\"\nscope = \"source.rego\"\ninjection-regex = \"rego\"\nfile-types = [\"rego\"]\nauto-format = true\ncomment-token = \"#\"\nlanguage-servers = [ \"regols\" ]\ngrammar = \"rego\"\n\n[[grammar]]\nname = \"rego\"\nsource = { git = \"https://github.com/FallenAngel97/tree-sitter-rego\", rev = \"ddd39af81fe8b0288102a7cb97959dfce723e0f3\" }\n\n[[language]]\nname = \"nim\"\nscope = \"source.nim\"\ninjection-regex = \"nim\"\nfile-types = [\"nim\", \"nims\", \"nimble\"]\nshebangs = []\ncomment-token = \"#\"\nblock-comment-tokens = { start = \"#[\", end = \"]#\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"nimlangserver\" ]\n\n[language.auto-pairs]\n'(' = ')'\n'[' = ']'\n'\"' = '\"'\n\"'\" = \"'\"\n'{' = '}'\n\n[[grammar]]\nname = \"nim\"\nsource = { git = \"https://github.com/alaviss/tree-sitter-nim\", rev = \"c5f0ce3b65222f5dbb1a12f9fe894524881ad590\" }\n\n[[language]]\nname = \"cabal\"\nscope = \"source.cabal\"\nfile-types = [ \"cabal\" ]\nroots = [\"cabal.project\", \"Setup.hs\"]\nindent = { tab-width = 2, unit = \"  \" }\ncomment-token = \"--\"\nlanguage-servers = [ \"haskell-language-server\" ]\n\n[[language]]\nname = \"hurl\"\nscope = \"source.hurl\"\ninjection-regex = \"hurl\"\nfile-types = [\"hurl\"]\ncomment-token = \"#\"\nformatter = { command = \"hurlfmt\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"hurl\"\nsource = { git = \"https://github.com/pfeiferj/tree-sitter-hurl\", rev = \"1124058cd192e80d80914652a5850a5b1887cc10\" }\n\n[[language]]\nname = \"markdoc\"\nscope = \"text.markdoc\"\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nfile-types = [\"mdoc\"]\nlanguage-servers = [ \"markdoc-ls\" ]\n\n[[grammar]]\nname = \"markdoc\"\nsource = { git = \"https://github.com/markdoc-extra/tree-sitter-markdoc\", rev = \"5ffe71b29e8a3f94823913ea9cea51fcfa7e3bf8\" }\n\n[[language]]\nname = \"opencl\"\nscope = \"source.cl\"\ninjection-regex = \"(cl|opencl)\"\nfile-types = [\"cl\"]\ncomment-token = \"//\"\nlanguage-servers = [ \"clangd\" ]\n\n[[grammar]]\nname = \"opencl\"\nsource = { git = \"https://github.com/lefp/tree-sitter-opencl\", rev = \"8e1d24a57066b3cd1bb9685bbc1ca9de5c1b78fb\" }\n\n[[language]]\nname = \"just\"\nscope = \"source.just\"\nfile-types = [\"just\", { glob = \"justfile\" }, { glob = \"Justfile\" }, { glob = \".justfile\" }, { glob = \".Justfile\" }]\ninjection-regex = \"just\"\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [\"just-lsp\"]\n# auto-format = true\n# formatter = { command = \"just\", args = [\"--dump\"] } # Please see: https://github.com/helix-editor/helix/issues/9703\n\n[[grammar]]\nname = \"just\"\nsource = { git = \"https://github.com/poliorcetics/tree-sitter-just\", rev = \"b75dace757e5d122d25c1a1a7772cb87b560f829\" }\n\n[[language]]\nname = \"gn\"\nscope = \"source.gn\"\ninjection-regex = \"gn\"\nfile-types = [\"gn\", \"gni\"]\nroots = []\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nformatter = { command = \"gn\", args = [\"format\", \"--stdin\"] }\n\n[[grammar]]\nname = \"gn\"\nsource = { git = \"https://github.com/willcassella/tree-sitter-gn\", rev = \"e18d6e36a79b20dafb58f19d407bd38b0e60260e\" }\n\n[[language]]\nname = \"blueprint\"\nscope = \"source.blueprint\"\ninjection-regex = \"blueprint\"\nfile-types = [\"blp\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [ \"blueprint-compiler\" ]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"blueprint\"\nsource = { git = \"https://gitlab.com/gabmus/tree-sitter-blueprint\", rev = \"355ef84ef8a958ac822117b652cf4d49bac16c79\" }\n\n[[language]]\nname = \"forth\"\nscope = \"source.forth\"\ninjection-regex = \"forth\"\nfile-types = [\"fs\", \"forth\", \"fth\", \"4th\"]\ncomment-token = \"\\\\\"\nlanguage-servers = [ \"forth-lsp\" ]\nindent = { tab-width = 3, unit = \"   \" }\n\n[[grammar]]\nname = \"forth\"\nsource = { git = \"https://github.com/alexanderbrevig/tree-sitter-forth\", rev = \"360ef13f8c609ec6d2e80782af69958b84e36cd0\" }\n\n[[language]]\nname = \"fsharp\"\nscope = \"source.fs\"\nroots = [\"*.slnx\", \"*.sln\", \"*.fsproj\"]\ninjection-regex = \"fsharp\"\nfile-types = [\"fs\", \"fsx\", \"fsi\", \"fsscript\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"(*\", end = \"*)\" }\nindent = { tab-width = 4, unit = \"    \" }\nauto-format = true\nlanguage-servers = [\"fsharp-ls\"]\n\n[[grammar]]\nname = \"fsharp\"\nsource = { git = \"https://github.com/ionide/tree-sitter-fsharp\", rev = \"996ea9982bd4e490029f84682016b6793940113b\" }\n\n[[language]]\nname = \"t32\"\nscope = \"source.t32\"\ninjection-regex = \"t32\"\nfile-types = [\"cmm\", \"t32\"]\ncomment-token = \";\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"t32\"\nsource = { git = \"https://gitlab.com/xasc/tree-sitter-t32\", rev = \"6da5e3cbabd376b566d04282005e52ffe67ef74a\" }\n\n[[language]]\nname = \"webc\"\nscope = \"text.html.webc\"\ninjection-regex = \"webc\"\nfile-types = [\"webc\"]\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"html\"\n\n[[language]]\nname = \"typst\"\nscope = \"source.typst\"\ninjection-regex = \"typ(st)?\"\nfile-types = [\"typst\", \"typ\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [\"tinymist\"]\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'$' = '$'\n'\"' = '\"'\n\n[[grammar]]\nname = \"typst\"\nsource = { git = \"https://github.com/uben0/tree-sitter-typst\", rev = \"13863ddcbaa7b68ee6221cea2e3143415e64aea4\" }\n\n[[language]]\nname = \"nunjucks\"\nscope = \"text.html.nunjucks\"\ninjection-regex = \"nunjucks\"\nfile-types = [\"njk\"]\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"jinja2\"\nblock-comment-tokens = { start = \"{#\", end = \"#}\" }\n\n[[language]]\nname = \"jinja\"\nscope = \"text.html.jinja\"\ninjection-regex = \"jinja\"\nfile-types = [\"jinja\", \"jinja2\", \"j2\"]\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"jinja2\"\nblock-comment-tokens = { start = \"{#\", end = \"#}\" }\n\n[[grammar]]\nname = \"jinja2\"\nsource = { git = \"https://github.com/varpeti/tree-sitter-jinja2\", rev = \"a533cd3c33aea6acb0f9bf9a56f35dcfe6a8eb53\" }\n\n[[language]]\nname = \"jjconfig\"\nscope = \"source.jjconfig\"\ninjection-regex = \"jjconfig\"\ngrammar = \"toml\"\nfile-types = [{ glob = \"jj/config.toml\" }, { glob = \"jj/**/*.toml\" }, { glob = \".jj/repo/*.toml\" }]\ncomment-token = \"#\"\nlanguage-servers = [ \"taplo\", \"tombi\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[language]]\nname = \"jjdescription\"\nscope = \"jj.description\"\nfile-types = [{ glob = \"*.jjdescription\" }]\ncomment-token = \"JJ:\"\nindent = { tab-width = 4, unit = \"    \" }\nrulers = [51, 73]\ntext-width = 72\n\n[[grammar]]\nname = \"jjdescription\"\nsource = { git = \"https://github.com/kareigu/tree-sitter-jjdescription\", rev = \"1613b8c85b6ead48464d73668f39910dcbb41911\" }\n\n[[language]]\nname = \"jjrevset\"\nscope = \"jj.revset\"\nfile-types = [\"jjrevset\"]\n\n[[grammar]]\nname = \"jjrevset\"\nsource = { git = \"https://github.com/bryceberger/tree-sitter-jjrevset\", rev = \"d9af23944b884ec528b505f41d81923bb3136a51\" }\n\n[[language]]\nname = \"jjtemplate\"\nscope = \"jj.template\"\nfile-types = [\"jjtemplate\"]\n\n[[grammar]]\nname = \"jjtemplate\"\nsource = { git = \"https://github.com/bryceberger/tree-sitter-jjtemplate\", rev = \"4313eda8ac31c60e550e3ad5841b100a0a686715\" }\n\n[[language]]\nname = \"miseconfig\"\nscope = \"source.miseconfig\"\ninjection-regex = \"miseconfig\"\ngrammar = \"toml\"\nfile-types = [\n  { glob = \"mise.toml\" },\n  { glob = \".mise.toml\" },\n  { glob = \"mise.*.toml\" },\n  { glob = \".mise.*.toml\" },\n  { glob = \"mise/config.toml\" },\n  { glob = \".mise/config.toml\" },\n  { glob = \".config/mise.toml\" },\n  { glob = \".config/mise/conf.d/*.toml\" },\n]\ncomment-token = \"#\"\nlanguage-servers = [ \"taplo\", \"tombi\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[language]]\nname = \"jq\"\nscope = \"source.jq\"\ninjection-regex = \"jq\"\nfile-types = [\"jq\"]\ncomment-token = \"#\"\nlanguage-servers = [\"jq-lsp\"]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"jq\"\nsource = { git = \"https://github.com/flurie/tree-sitter-jq\", rev = \"13990f530e8e6709b7978503da9bc8701d366791\" }\n\n[[grammar]]\nname = \"wren\"\nsource = { git = \"https://git.sr.ht/~jummit/tree-sitter-wren\", rev = \"6748694be32f11e7ec6b5faeb1b48ca6156d4e06\" }\n\n[[language]]\nname = \"wren\"\nscope = \"source.wren\"\ninjection-regex = \"wren\"\nfile-types = [\"wren\"]\nindent = { tab-width = 2, unit = \"  \"}\n\n[[language]]\nname = \"unison\"\nscope = \"source.unison\"\ninjection-regex = \"unison\"\nfile-types = [\"u\"]\nshebangs = []\nauto-format = false\ncomment-token = \"--\"\nindent = { tab-width = 4, unit = \"    \" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n'`' = '`'\n\n[[grammar]]\nname = \"unison\"\nsource = { git = \"https://github.com/kylegoetz/tree-sitter-unison\", rev = \"3c97db76d3cdbd002dfba493620c2d5df2fd6fa9\" }\n\n[[language]]\nname = \"todotxt\"\nscope = \"text.todotxt\"\n# glob = \"todo.txt\" is too common and can conflict regular files, define in user config if necessary\nfile-types = [{ glob = \"*.todo.txt\" }, \"todotxt\"]\nformatter = { command = \"sort\" }\nauto-format = true\n\n[[grammar]]\nname = \"todotxt\"\nsource = { git = \"https://github.com/arnarg/tree-sitter-todotxt\", rev = \"3937c5cd105ec4127448651a21aef45f52d19609\" }\n\n[[language]]\nname = \"strace\"\nscope = \"source.strace\"\nfile-types = [\"strace\"]\n\n[[grammar]]\nname = \"strace\"\nsource = { git = \"https://github.com/sigmaSd/tree-sitter-strace\", rev = \"2b18fdf9a01e7ec292cc6006724942c81beb7fd5\" }\n\n[[language]]\nname = \"gemini\"\nscope = \"source.gmi\"\nfile-types = [\"gmi\"]\n\n[[grammar]]\nname = \"gemini\"\nsource = { git = \"https://git.sr.ht/~nbsp/tree-sitter-gemini\", rev = \"3cc5e4bdf572d5df4277fc2e54d6299bd59a54b3\" }\n\n[[language]]\nname = \"agda\"\nscope = \"source.agda\"\ninjection-regex = \"agda\"\nfile-types = [\"agda\"]\nroots = []\ncomment-token = \"--\"\n# language-servers = [ \"als\" ]\n# the agda language server is of questionable functionality.\nauto-format = false\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'\"' = '\"'\n\"'\" = \"'\"\n'{' = '}'\n'(' = ')'\n'[' = ']'\n\n# [language.debugger]\n# ?? can this be used for proof assistant support? explore\n\n[[grammar]]\nname = \"agda\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-agda\", rev = \"c21c3a0f996363ed17b8ac99d827fe5a4821f217\" }\n\n[[language]]\nname = \"templ\"\nscope = \"source.templ\"\nfile-types = [\"templ\"]\nroots = [\"go.work\", \"go.mod\"]\ncomment-token = \"//\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"templ\" ]\n\n[[grammar]]\nname = \"templ\"\nsource = { git = \"https://github.com/vrischmann/tree-sitter-templ\", rev = \"47594c5cbef941e6a3ccf4ddb934a68cf4c68075\" }\n\n[[language]]\nname = \"dbml\"\nscope = \"source.dbml\"\ninjection-regex = \"dbml\"\nfile-types = [\"dbml\"]\ncomment-token = \";\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"dbml\"\nsource = { git = \"https://github.com/dynamotn/tree-sitter-dbml\", rev = \"2e2fa5640268c33c3d3f27f7e676f631a9c68fd9\" }\n\n[[language]]\nname = \"bitbake\"\nlanguage-servers = [ \"bitbake-language-server\" ]\nscope = \"source.bitbake\"\nfile-types = [\"bb\", \"bbappend\", \"bbclass\", {glob = \"conf/*.conf\" }, {glob = \"conf/*/*.{inc,conf}\" }, { glob = \"recipe-*/*/*.inc\" }]\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"bitbake\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-bitbake\", rev = \"10bacac929ff36a1e8f4056503fe4f8717b21b94\" }\n\n[[language]]\nname = \"log\"\nscope = \"source.log\"\nfile-types = [\"log\"]\n\n[[grammar]]\nname = \"log\"\nsource = { git = \"https://github.com/Tudyx/tree-sitter-log\", rev = \"62cfe307e942af3417171243b599cc7deac5eab9\" }\n\n[[language]]\nname = \"hoon\"\nscope = \"source.hoon\"\ninjection-regex = \"hoon\"\nfile-types = [\"hoon\"]\ncomment-token = \"::\"\nindent = {tab-width = 2, unit = \"  \"}\n\n[[grammar]]\nname = \"hoon\"\nsource = { git = \"https://github.com/urbit-pilled/tree-sitter-hoon\", rev = \"1d5df35af3e0afe592832a67b9fb3feeeba1f7b6\" }\n\n[[language]]\nname = \"hocon\"\nscope = \"source.conf\"\nfile-types = [\n  { glob = \"**/src/*/resources/**/*.conf\" },\n  { glob = \"*scalafmt*.conf\" },\n  { glob = \"*scalafix*.conf\" },\n]\ncomment-token = \"#\"\nauto-format = true\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"hocon\"\nsource = { git = \"https://github.com/antosha417/tree-sitter-hocon\", rev = \"c390f10519ae69fdb03b3e5764f5592fb6924bcc\" }\n\n[[language]]\nname = \"koka\"\nscope = \"source.koka\"\ninjection-regex = \"koka\"\nfile-types = [\"kk\"]\ncomment-token = \"//\"\nindent = { tab-width = 8, unit = \"  \" }\nlanguage-servers = [\"koka\"]\n\n[[grammar]]\nname = \"koka\"\nsource = { git = \"https://github.com/koka-community/tree-sitter-koka\", rev = \"fd3b482274d6988349ba810ea5740e29153b1baf\" }\n\n[[language]]\nname = \"tact\"\nscope = \"source.tact\"\ninjection-regex = \"tact\"\nfile-types = [\"tact\"]\ncomment-token = \"//\"\nindent = { tab-width = 4, unit = \"    \" }\n\n[language.auto-pairs]\n'\"' = '\"'\n'{' = '}'\n'(' = ')'\n'<' = '>'\n\n[[grammar]]\nname = \"tact\"\nsource = { git = \"https://github.com/tact-lang/tree-sitter-tact\", rev = \"ec57ab29c86d632639726631fb2bb178d23e1c91\" }\n\n[[language]]\nname = \"pkl\"\nscope = \"source.pkl\"\ninjection-regex = \"pkl\"\nfile-types = [\"pkl\", \"pcf\", { glob = \"PklProject\" }]\ncomment-token = \"//\"\nlanguage-servers = [\"pkl-lsp\"]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"pkl\"\nsource = { git = \"https://github.com/apple/tree-sitter-pkl\", rev = \"c03f04a313b712f8ab00a2d862c10b37318699ae\" }\n\n[[language]]\nname = \"groovy\"\nlanguage-id = \"groovy\"\nscope = \"source.groovy\"\nfile-types = [\"gradle\", \"groovy\", \"jenkinsfile\", { glob = \"Jenkinsfile\" },  { glob = \"Jenkinsfile.*\" }]\nshebangs = [\"groovy\"]\ncomment-token = \"//\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"groovy\"\nsource = { git = \"https://github.com/murtaza64/tree-sitter-groovy\", rev = \"235009aad0f580211fc12014bb0846c3910130c1\" }\n\n[[language]]\nname = \"fidl\"\nscope = \"source.fidl\"\ninjection-regex = \"fidl\"\nfile-types = [\"fidl\"]\ncomment-token = \"//\"\nindent = { tab-width = 4, unit = \"    \" }\n\n[language.auto-pairs]\n'\"' = '\"'\n'{' = '}'\n'(' = ')'\n'<' = '>'\n\n[[grammar]]\nname = \"fidl\"\nsource = { git = \"https://github.com/google/tree-sitter-fidl\", rev = \"bdbb635a7f5035e424f6173f2f11b9cd79703f8d\" }\n\n[[language]]\nname = \"powershell\"\nscope = \"source.powershell\"\ninjection-regex = \"(pwsh|powershell)\"\nfile-types = [ \"ps1\", \"psm1\", \"psd1\", \"pscc\", \"psrc\" ]\nshebangs = [ \"pwsh\", \"powershell\" ]\ncomment-token = '#'\nblock-comment-tokens = { start = \"<#\", end = \"#>\" }\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"powershell\"\nsource = { git = \"https://github.com/airbus-cert/tree-sitter-powershell\", rev = \"c9316be0faca5d5b9fd3b57350de650755f42dc0\" }\n\n[[language]]\nname = \"ld\"\nscope = \"source.ld\"\ninjection-regex = \"ld\"\nfile-types = [\"ld\"]\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"ld\"\nsource = { git = \"https://github.com/mtoohey31/tree-sitter-ld\", rev = \"0e9695ae0ede47b8744a8e2ad44d4d40c5d4e4c9\" }\n\n[[language]]\nname = \"hy\"\nscope = \"source.hy\"\nroots = [\"pyproject.toml\"]\nfile-types = [\"hy\"]\ncomment-token = \";\"\nindent = { tab-width = 1, unit = \" \" }\ngrammar = \"scheme\"\nlanguage-servers = [\"hyuga\"]\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\n[[language]]\nname = \"hyprlang\"\nscope = \"source.hyprlang\"\nroots = [\"hyprland.conf\"]\nfile-types = [ { glob = \"hypr/*.conf\" }]\ncomment-token = \"#\"\ngrammar = \"hyprlang\"\nlanguage-servers = [\"hyprls\"]\n\n[[grammar]]\nname = \"hyprlang\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-hyprlang\", rev = \"27af9b74acf89fa6bed4fb8cb8631994fcb2e6f3\"}\n\n[[language]]\nname = \"tcl\"\nscope = \"source.tcl\"\ninjection-regex = \"tcl\"\nfile-types = [ \"tcl\" ]\nshebangs = [ \"tclsh\", \"tclish\", \"jimsh\", \"wish\" ]\ncomment-token = '#'\n\n[[grammar]]\nname = \"tcl\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-tcl\", rev = \"56ad1fa6a34ba800e5495d1025a9b0fda338d5b8\" }\n\n[[language]]\nname = \"supercollider\"\nscope = \"source.supercollider\"\ninjection-regex = \"supercollider\"\nfile-types = [\"scd\", \"sc\", \"quark\"]\ncomment-token = \"//\"\nindent = { tab-width = 4, unit = \"\\t\" }\n\n[[grammar]]\nname = \"supercollider\"\nsource = { git = \"https://github.com/madskjeldgaard/tree-sitter-supercollider\", rev = \"3b35bd0fded4423c8fb30e9585c7bacbcd0e8095\" }\n\n[[language]]\nname = \"rpmspec\"\nscope = \"source.rpmspec\"\nfile-types = [\"spec\"]\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"rpmspec\"\nsource = { git = \"https://gitlab.com/cryptomilk/tree-sitter-rpmspec\", rev = \"d0275cd1316d9b7a2e0fae028ce95a5a18741e1d\" }\n\n[[language]]\nname = \"pkgbuild\"\nscope = \"source.bash\"\nfile-types = [{ glob = \"PKGBUILD\" }]\ncomment-token = \"#\"\ngrammar = \"bash\"\nlanguage-servers = [\n  \"termux-language-server\",\n  { except-features = [\n    \"diagnostics\",\n  ], name = \"bash-language-server\" },\n]\n\n[[language]]\nname = \"helm\"\ngrammar = \"gotmpl\"\nscope = \"source.helm\"\nroots = [\"Chart.yaml\"]\ncomment-token = \"#\"\nlanguage-servers = [\"helm_ls\"]\nfile-types = [ { glob = \"templates/*.yaml\" }, { glob = \"templates/*.yml\" }, { glob = \"templates/_*.tpl\"}, { glob = \"templates/NOTES.txt\" } ]\n\n[[language]]\nname = \"glimmer\"\nscope = \"source.glimmer\"\ninjection-regex = \"hbs\"\nfile-types = [{ glob = \"{app,addon}/{components,templates}/*.hbs\" }]\nblock-comment-tokens = { start = \"{{!\", end = \"}}\" }\nroots = [\"package.json\", \"ember-cli-build.js\"]\ngrammar = \"glimmer\"\nlanguage-servers = [\"ember-language-server\"]\nformatter = { command = \"prettier\", args = ['--parser', 'glimmer'] }\n\n[language.auto-pairs]\n'\"' = '\"'\n'{' = '}'\n'(' = ')'\n'<' = '>'\n\"'\" = \"'\"\n\n[[grammar]]\nname = \"glimmer\"\nsource = { git = \"https://github.com/ember-tooling/tree-sitter-glimmer\", rev = \"5dc6d1040e8ff8978ff3680e818d85447bbc10aa\" }\n\n[[language]]\nname = \"ohm\"\nscope = \"source.ohm\"\ninjection-regex = \"ohm\"\nfile-types = [\"ohm\"]\ncomment-token = \"//\"\nblock-comment-tokens = [\n  { start = \"/*\", end = \"*/\" },\n  { start = \"/**\", end = \"*/\" },\n]\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'\"' = '\"'\n'{' = '}'\n'(' = ')'\n'<' = '>'\n\n[[grammar]]\nname = \"ohm\"\nsource = { git = \"https://github.com/novusnota/tree-sitter-ohm\", rev = \"80f14f0e477ddacc1e137d5ed8e830329e3fb7a3\" }\n\n[[language]]\nname = \"earthfile\"\nscope = \"source.earthfile\"\ninjection-regex = \"earthfile\"\nroots = [\"Earthfile\"]\nfile-types = [\n  { glob = \"Earthfile\" },\n]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [\"earthlyls\"]\n\n[[grammar]]\nname = \"earthfile\"\nsource = { git = \"https://github.com/glehmann/tree-sitter-earthfile\", rev = \"dbfb970a59cd87b628d087eb8e3fbe19c8e20601\" }\n\n[[language]]\nname = \"adl\"\nscope = \"source.adl\"\ninjection-regex = \"adl\"\nfile-types = [\"adl\"]\nroots = []\ncomment-token = \"//\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[language.auto-pairs]\n'\"' = '\"'\n'{' = '}'\n'<' = '>'\n\n[[grammar]]\nname = \"adl\"\nsource = { git = \"https://github.com/adl-lang/tree-sitter-adl\", rev = \"2787d04beadfbe154d3f2da6e98dc45a1b134bbf\" }\n\n[[language]]\nname = \"ldif\"\nscope = \"source.ldif\"\ninjection-regex = \"ldif\"\nfile-types = [\"ldif\"]\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"ldif\"\nsource = { git = \"https://github.com/kepet19/tree-sitter-ldif\", rev = \"0a917207f65ba3e3acfa9cda16142ee39c4c1aaa\" }\n\n[[language]]\nname = \"xtc\"\nscope = \"source.xtc\"\n# Accept Xena Traffic Configuration, Xena Port Configuration and Xena OpenAutomation\nfile-types = [ \"xtc\", \"xpc\", \"xoa\" ]\ncomment-token = \";\"\n\n[[grammar]]\nname = \"xtc\"\nsource = { git = \"https://github.com/Alexis-Lapierre/tree-sitter-xtc\", rev = \"7bc11b736250c45e25cfb0215db2f8393779957e\" }\n\n[[language]]\nname = \"move\"\nscope = \"source.move\"\ninjection-regex = \"move\"\nroots = [\"Move.toml\"]\nfile-types = [\"move\"]\ncomment-token = \"//\"\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = []\n\n[[grammar]]\nname = \"move\"\nsource = { git = \"https://github.com/tzakian/tree-sitter-move\", rev = \"8bc0d1692caa8763fef54d48068238d9bf3c0264\" }\n\n[[language]]\nname = \"pest\"\nscope = \"source.pest\"\ninjection-regex = \"pest\"\nfile-types = [\"pest\"]\ncomment-tokens = [\"//\", \"///\", \"//!\"]\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [\"pest-language-server\"]\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n\n[[grammar]]\nname = \"pest\"\nsource = { git = \"https://github.com/pest-parser/tree-sitter-pest\", rev = \"c19629a0c50e6ca2485c3b154b1dde841a08d169\" }\n\n[[language]]\nname = \"elisp\"\nscope = \"source.elisp\"\nfile-types = [\"el\"]\ncomment-tokens = [\";\"]\n\n[language.auto-pairs]\n'(' = ')'\n'\"' = '\"'\n\n[[grammar]]\nname = \"elisp\"\nsource = { git = \"https://github.com/Wilfred/tree-sitter-elisp\", rev = \"e5524fdccf8c22fc726474a910e4ade976dfc7bb\" }\n\n[[language]]\nname = \"gjs\"\nscope = \"source.gjs\"\nfile-types = [\"gjs\"]\nroots = [\"package.json\", \"ember-cli-build.js\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [\n    { except-features = [\n        \"format\", \"diagnostics\",\n    ], name = \"typescript-language-server\" },\n    \"vscode-eslint-language-server\",\n    \"ember-language-server\",\n]\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"glimmer-javascript\"\n\n[language.auto-pairs]\n'<' = '>'\n\"'\" = \"'\"\n\"{\" = \"}\"\n\"(\" = \")\"\n'\"' = '\"'\n\n[[grammar]]\nname = \"glimmer-javascript\"\nsource = { git = \"https://github.com/ember-tooling/tree-sitter-glimmer-javascript\", rev = \"5cc865a2a0a77cbfaf5062c8fcf2a9919bd54f87\" }\n\n[[language]]\nname = \"gts\"\nscope = \"source.gts\"\nfile-types = [\"gts\"]\nroots = [\"package.json\", \"ember-cli-build.js\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nlanguage-servers = [\n    { except-features = [\n        \"format\", \"diagnostics\",\n    ], name = \"typescript-language-server\" },\n    \"vscode-eslint-language-server\",\n    \"ember-language-server\",\n]\nindent = { tab-width = 2, unit = \"  \" }\ngrammar = \"glimmer-typescript\"\n\n[language.auto-pairs]\n'<' = '>'\n\"'\" = \"'\"\n\"{\" = \"}\"\n\"(\" = \")\"\n'\"' = '\"'\n\n[[grammar]]\nname = \"glimmer-typescript\"\nsource = { git = \"https://github.com/ember-tooling/tree-sitter-glimmer-typescript\", rev = \"12d98944c1d5077b957cbdb90d663a7c4d50118c\" }\n\n[[language]]\nname = \"gherkin\"\nscope = \"source.feature\"\nfile-types = [\"feature\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"gherkin\"\nsource = { git = \"https://github.com/SamyAB/tree-sitter-gherkin\", rev = \"43873ee8de16476635b48d52c46f5b6407cb5c09\" }\n\n[[language]]\nname = \"thrift\"\nscope = \"source.thrift\"\nfile-types = [\"thrift\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"thrift\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-thrift\" , rev = \"68fd0d80943a828d9e6f49c58a74be1e9ca142cf\" }\n\n[[language]]\nname             = \"circom\"\nscope            = \"source.circom\"\ninjection-regex  = \"circom\"\nfile-types       = [\"circom\"]\nroots            = [\"package.json\"]\ncomment-tokens   = \"//\"\nindent           = { tab-width = 4, unit = \"    \" }\nauto-format      = false\nlanguage-servers = [\"circom-lsp\"]\n\n[[grammar]]\nname   = \"circom\"\nsource = { git = \"https://github.com/Decurity/tree-sitter-circom\", rev = \"02150524228b1e6afef96949f2d6b7cc0aaf999e\" }\n\n[[language]]\nname = \"snakemake\"\nscope = \"source.snakemake\"\nroots = [\"Snakefile\", \"config.yaml\", \"environment.yaml\", \"workflow/\"]\nfile-types = [\"smk\", { glob = \"Snakefile\" } ]\ncomment-tokens = [\"#\", \"##\"]\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [\"pylsp\" ]\n\n[language.formatter]\ncommand = \"snakefmt\"\nargs = [\"-\"]\n\n[[grammar]]\nname = \"snakemake\"\nsource = { git = \"https://github.com/osthomas/tree-sitter-snakemake\", rev = \"e909815acdbe37e69440261ebb1091ed52e1dec6\" }\n\n[[language]]\nname = \"cylc\"\nscope = \"source.cylc\"\ninjection-regex = \"cylc\"\nfile-types = [\"cylc\", { glob = \"suite.rc\" }]\ncomment-tokens = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"cylc\"\nsource = { git = \"https://github.com/elliotfontaine/tree-sitter-cylc\", rev = \"30dd40d9bf23912e4aefa93eeb4c7090bda3d0f6\" }\n\n[[language]]\nname = \"quint\"\nscope = \"source.quint\"\nfile-types = [\"qnt\"]\nlanguage-servers = [\"quint-language-server\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"quint\"\nsource = { git = \"https://github.com/gruhn/tree-sitter-quint\", rev = \"eebbd01edfeff6404778c92efe5554e42e506a18\" }\n\n[[language]]\nname = \"spade\"\nscope = \"source.spade\"\nroots = [\"swim.toml\"]\nfile-types = ['spade']\ninjection-regex = \"spade\"\ncomment-tokens = [\"//\", \"///\"]\nblock-comment-tokens = [\n  { start = \"/*\", end = \"*/\" },\n  { start = \"/**\", end = \"*/\" },\n]\nlanguage-servers = [ \"spade-language-server\" ]\nindent = { tab-width = 4, unit = \"    \" }\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n'\"' = '\"'\n'<' = '>'\n\n[[grammar]]\nname = \"spade\"\nsource = { git = \"https://codeberg.org/spade-lang/tree-sitter-spade\", rev = \"996aaabea9a9fbe498ae0876356028a78e6ef8db\" }\n\n[[language]]\nname = \"amber\"\nscope = \"source.ab\"\nfile-types = [\"ab\"]\ncomment-token = [\"//\", \"///\"]\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [\"amber-lsp\"]\n\n[[grammar]]\nname = \"amber\"\nsource = { git = \"https://github.com/amber-lang/tree-sitter-amber\", rev = \"dc69f42449fd3c807bacefa398263f62e581f755\" }\n\n[[language]]\nname = \"koto\"\nscope = \"source.koto\"\ninjection-regex = \"koto\"\nfile-types = [\"koto\"]\ncomment-token = \"#\"\nblock-comment-tokens = [\"#-\", \"-#\"]\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [\"koto-ls\"]\nformatter = {command = \"koto\", args = [\"--format\"]}\n\n[[grammar]]\nname = \"koto\"\nsource = { git = \"https://github.com/koto-lang/tree-sitter-koto\", rev = \"633744bca404ae4edb961a3c2d7bc947a987afa4\" }\n\n[[language]]\nname = \"gpr\"\nscope = \"source.gpr\"\ninjection-regex = \"gpr\"\nfile-types = [\"gpr\"]\nroots = [\"alire.toml\"]\ncomment-token = \"--\"\nindent = { tab-width = 3, unit = \"   \" }\nlanguage-servers = [\"ada-gpr-language-server\"]\n\n[[grammar]]\nname = \"gpr\"\nsource = { git = \"https://github.com/brownts/tree-sitter-gpr\", rev = \"cea857d3c18d1385d1f5b66cd09ea1e44173945c\" }\n\n[[language]]\nname = \"vento\"\nscope = \"text.html.vto\"\nfile-types = [\"vto\"]\nblock-comment-tokens = { start = \"{{#\", end = \"#}}\" }\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"vento\"\nsource = { git = \"https://github.com/ventojs/tree-sitter-vento\", rev = \"3b32474bc29584ea214e4e84b47102408263fe0e\" }\n\n[[language]]\nname = \"nginx\"\nscope = \"source.nginx\"\ninjection-regex = \"nginx\"\nfile-types = [\n  { glob = \"sites-available/*.conf\" },\n  { glob = \"sites-enabled/*.conf\" },\n  { glob = \"nginx.conf\" },\n  { glob = \"conf.d/*.conf\" }\n]\nroots = [\"nginx.conf\"]\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"nginx\"\nsource = { git = \"https://gitlab.com/joncoole/tree-sitter-nginx\", rev = \"b4b61db443602b69410ab469c122c01b1e685aa0\" }\n\n[[language]]\nname = \"codeql\"\nscope = \"source.ql\"\nfile-types = [\"ql\", \"qll\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\ninjection-regex = \"codeql\"\ngrammar = \"ql\"\nlanguage-servers = [\"codeql\"]\n\n[[grammar]]\nname = \"ql\"\nsource = { git = \"https://github.com/tree-sitter/tree-sitter-ql\", rev = \"1fd627a4e8bff8c24c11987474bd33112bead857\" }\n\n[[language]]\nname = \"gren\"\nscope = \"source.gren\"\ninjection-regex = \"gren\"\nfile-types = [\"gren\"]\nroots = [\"gren.json\"]\ncomment-tokens = \"--\"\nblock-comment-tokens = { start = \"{-\", end = \"-}\" }\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"gren\"\nsource = { git = \"https://github.com/MaeBrooks/tree-sitter-gren\", rev = \"76554f4f2339f5a24eed19c58f2079b51c694152\" }\n\n[[language]]\nname = \"ghostty\"\nscope = \"source.ghostty\"\nfile-types = [\"ghostty\", { glob = \"ghostty/config\" }]\ncomment-tokens = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"ghostty\"\nsource = { git = \"https://github.com/bezhermoso/tree-sitter-ghostty\" , rev = \"8438a93b44367e962b2ea3a3b6511885bebd196a\" }\n\n[[language]]\nname = \"tera\"\nscope = \"source.tera\"\nfile-types = [\"tera\"]\nblock-comment-tokens = [\n  { start = \"{#\", end = \"#}\" },\n  { start = \"{#-\", end = \"-#}\" },\n  { start = \"{#\", end = \"-#}\" },\n  { start = \"{#-\", end = \"#}\" },\n]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"tera\"\nsource = { git = \"https://github.com/uncenter/tree-sitter-tera\", rev = \"e8d679a29c03e64656463a892a30da626e19ed8e\" }\n\n[[language]]\nname = \"fga\"\nscope = \"source.fga\"\ninjection-regex = \"fga\"\nfile-types = [\"fga\", { glob = \"fga.mod\" } ]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"fga\"\nsource = { git = \"https://github.com/matoous/tree-sitter-fga\", rev = \"ce72d1c484ba133a18e966d67be66bce85695451\" }\n\n[[language]]\nname = \"csv\"\nfile-types = [\"csv\"]\nscope = \"source.csv\"\n\n[[grammar]]\nname = \"csv\"\nsource = { git = \"https://github.com/weartist/rainbow-csv-tree-sitter\", rev = \"d3dbf916446131417e4c2ea9eb8591b23b466d27\" }\n\n[[language]]\nname = \"yara\"\nscope = \"source.yara\"\nfile-types = [\"yara\", \"yar\"]\nindent = { tab-width = 2, unit = \"  \" }\ncomment-tokens = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\"}\nlanguage-servers = [ \"yls\" ]\n\n[[grammar]]\nname = \"yara\"\nsource = { git = \"https://github.com/egibs/tree-sitter-yara\", rev = \"eb3ede203275c38000177f72ec0f9965312806ef\" }\n\n[[language]]\nname = \"ink\"\nscope = \"source.ink\"\nfile-types = [\"ink\"]\ninjection-regex = \"ink\"\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\"}\nindent = { tab-width = 4, unit = \"\\t\" }\nsoft-wrap = { enable = true }\n\n[[grammar]]\nname = \"ink\"\nsource = { git = \"https://github.com/rhizoome/tree-sitter-ink\", rev = \"8486e9b1627b0bc6b2deb9ee8102277a7c1281ac\" }\n\n[[language]]\nname = \"sourcepawn\"\nscope = \"source.sourcepawn\"\nfile-types = [\"sp\", \"inc\"]\ncomment-token = \"//\"\nindent = {tab-width = 4, unit = \"  \"}\nlanguage-servers = [\"sourcepawn-studio\"]\n\n[[grammar]]\nname = \"sourcepawn\"\nsource = { git = \"https://github.com/nilshelmig/tree-sitter-sourcepawn\", rev = \"f2af8d0dc14c6790130cceb2a20027eb41a8297c\" }\n\n[[grammar]]\nname = \"vim\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-vim\", rev = \"f3cd62d8bd043ef20507e84bb6b4b53731ccf3a7\" }\n\n[[language]]\nname = \"vim\"\nscope = \"source.vim\"\ninjection-regex = \"vim\"\ncomment-token = '\"'\nindent = { tab-width = 4, unit = \"\\t\" }\nfile-types = [\n  \"vim\",\n  { glob = \".vimrc\" },\n  { glob = \".nvimrc\" },\n  { glob = \".exrc\" }\n]\n\n[[language]]\nname = \"tlaplus\"\nscope = \"scope.tlaplus\"\ninjection-regex = \"tla\"\nfile-types = [\"tla\"]\ncomment-tokens = \"\\\\*\"\nblock-comment-tokens = {start = \"(*\", end=\"*)\"}\nindent = {tab-width = 4, unit = \" \"}\nformatter = {command = \"tlafmt\", args = [\"--stdin\"]}\n\n[[grammar]]\nname = \"tlaplus\"\nsource = { git = \"https://github.com/tlaplus-community/tree-sitter-tlaplus\", rev = \"4ba91b07b97741a67f61221d0d50e6d962e4987e\"}\n\n[[language]]\nname = \"werk\"\nscope = \"source.werk\"\nfile-types = [ \"werk\", { glob = \"Werkfile\" } ]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"werk\"\nsource = { git = \"https://github.com/little-bonsai/tree-sitter-werk\", rev = \"92b0f7fe98465c4c435794a58e961306193d1c1e\" }\n\n[[language]]\nname = \"debian\"\nscope = \"text.debian\"\nfile-types = [\n  \"dsc\",\n  \"changes\",\n  { glob = \"debian/**/control\" },\n  { glob = \"etc/apt/sources.list.d/*.sources\"}\n]\ncomment-tokens = \"#\"\n\n[[grammar]]\nname = \"debian\"\nsource = { git = \"https://gitlab.com/MggMuggins/tree-sitter-debian\", rev = \"9b3f4b78c45aab8a2f25a5f9e7bbc00995bc3dde\" }\n\n[[language]]\nname = \"pug\"\nscope = \"source.pug\"\nfile-types = [\"pug\"]\ncomment-tokens = [\"//\", \"//-\"]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"pug\"\nsource = { git = \"https://github.com/zealot128/tree-sitter-pug\", rev = \"13e9195370172c86a8b88184cc358b23b677cc46\" }\n\n[[language]]\nname = \"dunstrc\"\nscope = \"source.dunstrc\"\ncomment-tokens = [\"#\", \";\"]\nfile-types = [ { glob = \"dunst/dunstrc\" } ]\n\n[[grammar]]\nname = \"dunstrc\"\nsource = { git = \"https://github.com/rotmh/tree-sitter-dunstrc\", rev = \"9cb9d5cc51cf5e2a47bb2a0e2f2e519ff11c1431\" }\n\n[[language]]\nname = \"rust-format-args\"\nscope = \"source.rust-format-args\"\nfile-types = []\ninjection-regex = \"rust-format-args\"\n\n[[grammar]]\nname = \"rust-format-args\"\nsource = { git = \"https://github.com/nik-rev/tree-sitter-rust-format-args\", rev = \"84ffe550e261cf5ea40a0ec31849ba2443bae99f\" }\n\n[[language]]\nname = \"rust-format-args-macro\"\nscope = \"source.rust-format-args-macro\"\nfile-types = []\ngrammar = \"rust\"\n\n[[language]]\nname = \"clarity\"\nscope = \"source.clar\"\ninjection-regex = \"clarity\"\nfile-types = [\"clar\"]\nroots = [\"Clarinet.toml\"]\ncomment-tokens = \";;\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [ \"clarinet\" ]\n\n[[grammar]]\nname = \"clarity\"\nsource = { git = \"https://github.com/xlittlerag/tree-sitter-clarity\", rev = \"7fa54825fdd971a1a676f885384f024fe2b7384a\" }\n\n[[language]]\nname = \"alloy\"\nscope = \"source.alloy\"\ninjection-regex = \"alloy\"\nfile-types = [\"alloy\"]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"alloy\"\nsource = { git = \"https://github.com/mattsre/tree-sitter-alloy\", rev = \"58d462b1cdb077682b130caa324f3822aeb00b8e\" }\n\n[[language]]\nname = \"luau\"\nscope = \"source.luau\"\ninjection-regex = \"^luau$\"\nfile-types = [\"luau\"]\ncomment-tokens = [\"--\", \"---\"]\nblock-comment-tokens = [\n  {start = \"--[[\", end = \"]]\"},\n  {start = \"--[=[\", end = \"]=]\"},\n  {start = \"--[==[\", end = \"]==]\"}\n]\nindent = { tab-width = 2, unit = \"  \"}\nroots = [ \"aftman.toml\", \"default.project.json\", \"wally.toml\", \"rokit.toml\", \"selene.toml\", \".darklua.json\", \"foreman.toml\", \".luaurc\" ]\nlanguage-servers = [ \"luau\" ]\n\n[[grammar]]\nname = \"luau\"\nsource = { git = \"https://github.com/polychromatist/tree-sitter-luau\", rev = \"ec187cafba510cddac265329ca7831ec6f3b9955\" }\n\n[[language]]\nname = \"caddyfile\"\nscope = \"source.caddyfile\"\ninjection-regex = \"caddyfile\"\nfile-types = [\n  \"Caddyfile\",\n  { glob = \"Caddyfile\" },\n  { glob = \"Caddyfile.*\" },\n  \"caddyfile\",\n  { glob = \"caddyfile\" },\n  { glob = \"caddyfile.*\" },\n]\ncomment-tokens = [\"#\"]\nindent = { tab-width = 4, unit = \"    \" }\nformatter = { command = \"caddy\", args = [\"fmt\", \"-\"] }\nauto-format = true\n\n[[grammar]]\nname = \"caddyfile\"\nsource = { git = \"https://github.com/caddyserver/tree-sitter-caddyfile\", rev = \"b04bdb4ec53e40c44afbf001e15540f60a296aef\" }\n\n[[language]]\nname = \"properties\"\nscope = \"source.properties\"\ninjection-regex = \"properties\"\nfile-types = [\"properties\", \"prefs\"]\ncomment-tokens = [\"#\"]\n\n[[grammar]]\nname = \"properties\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-properties\", rev = \"579b62f5ad8d96c2bb331f07d1408c92767531d9\" }\n\n[[language]]\nname = \"robots.txt\"\nscope = \"source.robots.txt\"\nfile-types = [{ glob = \"robots.txt\" }]\ninjection-regex = \"robots[\\\\.-]txt\"\ngrammar = \"robots\"\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"robots\"\nsource = { git = \"https://github.com/opa-oz/tree-sitter-robots-txt\", rev = \"8e3a4205b76236bb6dbebdbee5afc262ce38bb62\" }\n\n[[language]]\nname = \"pip-requirements\"\nscope = \"source.pip-requirements\"\ninjection-regex = \"(pip-)?requirements(\\\\.txt)?\"\ngrammar = \"requirements\"\nfile-types = [{ glob = \"requirements.txt\" }, { glob = \"constraints.txt\" }]\n\n[[grammar]]\nname = \"requirements\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-requirements\", rev = \"caeb2ba854dea55931f76034978de1fd79362939\" }\n\n[[language]]\nname = \"kconfig\"\nfile-types = [\"Kconfig\", { glob = \"Kconfig.*\" }]\nscope = \"source.kconfig\"\n\n[[grammar]]\nname = \"kconfig\"\nsource = { git = \"https://github.com/tree-sitter-grammars/tree-sitter-kconfig\" , rev = \"9ac99fe4c0c27a35dc6f757cef534c646e944881\" }\n\n[[language]]\nname = \"doxyfile\"\nscope = \"source.doxyfile\"\ninjection-regex = \"[Dd]oxyfile\"\nfile-types = [{ glob = \"Doxyfile\" }]\ncomment-token = \"#\"\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"doxyfile\"\nsource = { git = \"https://github.com/tingerrr/tree-sitter-doxyfile/\", rev = \"18e44c6da639632a4e42264c7193df34be915f34\" }\n\n[[language]]\nname = \"cross-config\"\nscope = \"source.cross-config\"\ninjection-regex = \"cross(-config)\"\ngrammar = \"toml\"\ncomment-token = \"#\"\nfile-types = [{glob = \"Cross.toml\"}]\nlanguage-servers = [ \"taplo\", \"tombi\" ]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[language]]\nname = \"git-cliff-config\"\nscope = \"source.git-cliff-config\"\ninjection-regex = \"git-cliff(-config)\"\ngrammar = \"toml\"\ncomment-token = \"#\"\nfile-types = [{ glob = \"cliff.toml\" }]\nlanguage-servers = [\"taplo\", \"tombi\"]\nindent = { tab-width = 2, unit = \"  \" }\n\n[[language]]\nname = \"cython\"\nscope = \"source.cython\"\nfile-types = [\"pxd\", \"pxi\", \"pyx\"]\ncomment-token = \"#\"\nroots = [\"pyproject.toml\", \"setup.py\", \"poetry.lock\"]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"cython\"\nsource = { git = \"https://github.com/b0o/tree-sitter-cython\", rev = \"62f44f5e7e41dde03c5f0a05f035e293bcf2bcf8\" }\n\n[[language]]\nname = \"shellcheckrc\"\nscope = \"source.shellcheckrc\"\ninjection-regex = \"shellcheck(rc)?\"\nfile-types = [{glob = \"shellcheckrc\"}, {glob = \".shellcheckrc\"}]\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"shellcheckrc\"\nsource = {git = \"https://codeberg.org/kpbaks/tree-sitter-shellcheckrc\", rev = \"ad3da4e8f7fd72dcc5e93a6b89822c59a7cd10ff\"}\n\n[[grammar]]\nname = \"strictdoc\"\nsource = { git = \"https://github.com/manueldiagostino/tree-sitter-strictdoc\", rev = \"070edcf23f7c85af355437706048f73833e0ea10\" }\n\n[[language]]\nname = \"strictdoc\"\nscope = \"source.strictdoc\"\ninjection-regex = \"strictdoc\"\nfile-types = [\"sdoc\", \"sgra\"]\ncomment-token = \"..\"\n\n[[language]]\nname = \"docker-bake\"\nlanguage-id = \"dockerbake\"\nscope = \"source.docker-bake\"\ninjection-regex = \"docker-bake\"\ngrammar = \"hcl\"\nfile-types = [\n  { glob = \"docker-bake.hcl\" },\n  { glob = \"docker-bake.override.hcl\" },\n]\ncomment-token = \"#\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [\"docker-language-server\"]\n\n[[language]]\nname = \"gitlab-ci\"\nscope = \"source.gitlab-ci\"\ninjection-regex = \"^gitlab-ci$\"\nfile-types = [{ glob = \".gitlab-ci.yml\" }]\ngrammar = \"yaml\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [\"yaml-language-server\", \"gitlab-ci-ls\"]\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"wikitext\"\nsource = { git = \"https://github.com/santhoshtr/tree-sitter-wikitext\", rev = \"444214b31695e9dd4d32fb06247397fb8778a9d2\"}\n\n[[language]]\nname = \"wikitext\"\nscope = \"source.wikitext\"\nfile-types = [\"wikimedia\", \"mediawiki\", \"wikitext\"]\nlanguage-servers = [\"wikitext-lsp\"]\nindent = { tab-width = 2, unit = \"  \" }\nblock-comment-tokens = { start = \"<!--\", end = \"-->\" }\nword-completion.trigger-length = 4\n\n[[language]]\nname = \"slisp\"\nscope = \"source.sl\"\ninjection-regex = \"sl\"\nfile-types = [\"sl\"]\ncomment-token = \";\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"slisp\"\nsource = { git = \"https://github.com/xenogenics/tree-sitter-slisp\", rev = \"29f9c6707ce9dfc2fc915d175ec720b207f179f3\" }\n\n[[language]]\nname = \"nearley\"\nscope = \"source.nearley\"\nfile-types = [\"ne\"]\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"nearley\"\nsource = { git = \"https://github.com/mi2ebi/tree-sitter-nearley\", rev = \"12d01113e194c8e83f6341aab8c2a5f21db9cac9\" }\n\n[[language]]\nname = \"kcl\"\nscope = \"source.kcl\"\ninjection-regex = \"kcl\"\nfile-types = [\"kcl\"]\ncomment-tokens = \"//\"\nindent = { tab-width = 2, unit = \"  \" }\nformatter = { command = \"zoo\" , args = [\"kcl\", \"fmt\", \"-\"] }\nlanguage-servers = [ \"kcl-lsp\" ]\nblock-comment-tokens = { start = \"/*\", end = \"*/\"}\n\n[[grammar]]\nname = \"kcl\"\nsource = { git = \"https://github.com/KittyCAD/tree-sitter-kcl\", rev = \"8905e0bdbf5870b50bc3f24345f1af27746f42e8\"}\n\n[[language]]\nname = \"bovex\"\nscope = \"source.bovex\"\nfile-types = [\"bovex\", \"bibvex\"]\ncomment-tokens = []\nblock-comment-tokens = [{start = \"(*\", end = \"*)\"}, {start = \"[*\", end = \"*]\"}]\nindent = {tab-width = 2, unit = \"  \"}\n[language.auto-pairs]\n'(' = ')'\n'[' = ']'\n'{' = '}'\n'\"' = '\"'\n'“' = '”'\n'‘' = '’'\n\n[[language]]\nname = \"haxe\"\nscope = \"source.haxe\"\ninjection-regex = \"hx|haxe\"\nfile-types = [\"hx\"]\nroots = [\"haxelib.json\", \"project.xml\", \"build.hxml\"]\nshebangs = []\nauto-format = true\ncomment-tokens = [\"//\", \"///\"]\nblock-comment-tokens = [\n  { start = \"/*\", end = \"*/\" },\n  { start = \"/**\", end = \"*/\" },\n]\nlanguage-servers = [\"haxe-language-server\"]\nindent = { tab-width = 4, unit = \"    \" }\npersistent-diagnostic-sources = [\"haxe\"]\n\n[[grammar]]\nname = \"haxe\"\nsource = { git = \"https://github.com/vantreeseba/tree-sitter-haxe\", rev = \"a55f3e2cf1e4449200fd089a80d3af642bcf5f94\" }\n\n[[language]]\nname = \"basic\"\nscope = \"source.basic\"\ninjection-regex = \"basic\"\nfile-types = [\"bas\"]\ncomment-token = \"REM\"\nindent = { tab-width = 2, unit = \"  \" }\n\n[[grammar]]\nname = \"basic\"\nsource = { git = \"https://github.com/Ra77a3l3-jar/tree-sitter-basic\", rev = \"a98449c11d6c688b54c1ca132148a62d7e586a2a\" }\n\n[[language]]\nname = \"freebasic\"\nscope = \"source.freebasic\"\ninjection-regex = \"freebasic\"\nfile-types = [\"bas\", \"bi\"]\ncomment-tokens = [\"'\", \"REM\"]\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"freebasic\"\nsource = { git = \"https://github.com/Ra77a3l3-jar/tree-sitter-freebasic\", rev = \"dbf696adb4c0b9c020074e75043c90592981ee7f\" }\n\n[[language]]\nname = \"scfg\"\nscope = \"source.scfg\"\nfile-types = [{ glob = \"kanshi/config\" }]\ncomment-token = \"#\"\n\n[[grammar]]\nname = \"scfg\"\nsource = { git = \"https://github.com/rockorager/tree-sitter-scfg\", rev = \"d850fd470445d73de318a21d734d1e09e29b773c\" }\n\n[[language]]\nname = \"ripple\"\nscope = \"source.ripple\"\nfile-types = [ \"ripple\" ]\nroots = [ \"package.json\" ]\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit=\"    \"}\nlanguage-servers = [ \"ripple-lsp\" ]\n\n[[grammar]]\nname = \"ripple\"\nsource = { git = \"https://github.com/Ripple-TS/ripple\", rev = \"49762f0a63de0d1845fcd2e6632639c095995336\", subpath = \"packages/tree-sitter\" }\n\n[[language]]\nname = \"woodpecker-ci\"\nscope = \"source.woodpecker-ci\"\ninjection-regex = \"^woodpecker-ci$\"\n# https://woodpecker-ci.org/docs/usage/workflows\nfile-types = [\n  { glob = \".woodpecker.yaml\" },\n  { glob = \".woodpecker/*.yaml\" },\n  { glob = \".woodpecker/*.yml\" },\n]\ngrammar = \"yaml\"\nindent = { tab-width = 2, unit = \"  \" }\nlanguage-servers = [\"yaml-language-server\"]\ncomment-token = \"#\"\nformatter = { command = \"yamlfmt\", args = ['-'] }\nauto-format = true\n\n[[language]]\nname = \"chuck\"\nscope = \"source.ck\"\ncomment-tokens = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nfile-types = [{ glob = \"*.ck\" }]\nindent = { tab-width = 4, unit=\"    \"}\ninjection-regex = \"^chuck$|^ck$\"\n\n[[grammar]]\nname = \"chuck\"\nsource = { git = \"https://github.com/tymbalodeon/tree-sitter-chuck\", rev = \"2fd18bcd48e7b23ee47f854e639020df90b1270b\" }\n\n[[language]]\nname = \"qmv\"\nscope = \"source.qmv\"\nfile-types = [ { glob = \"/tmp/qmv*\" } ]\nindent = { tab-width = 8, unit = \"        \" }\nsoft-wrap = { enable = false }\n\n[[language]]\nname = \"klog\"\nscope = \"source.klg\"\nfile-types = [ \"klg\" ]\ninjection-regex = \"klg\"\nindent = { tab-width = 4, unit=\"    \"}\n[language.auto-pairs]\n'(' = ')'\n'\"' = '\"'\n\"'\" = \"'\"\n\n[[grammar]]\nname = \"klog\"\nsource = { git = \"https://github.com/Ansimorph/tree-sitter-klog/\", rev = \"0b215fe75bdeb8368546e3cee36aca8c19212d06\" }\n\n[[language]]\nname = \"styx\"\nscope = \"source.styx\"\ninjection-regex = \"styx\"\nfile-types = [\"styx\"]\ncomment-tokens = [\"//\", \"///\"]\nlanguage-servers = [\"styx\"]\nindent = { tab-width = 2, unit = \"  \" }\nauto-format = true\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'\"' = '\"'\n\"'\" = \"'\"\n\n[[grammar]]\nname = \"styx\"\nsource = { git = \"https://github.com/bearcove/styx\", subpath = \"crates/tree-sitter-styx\" , rev = \"ff7f49629a20a308111810a0c5e6228617133ea7\" }\n\n# https://docs.tilt.dev/editor.html\n[[language]]\nname = \"tilt\"\nscope = \"source.tilt\"\ninjection-regex = \"[Tt]ilt(file)?\"\nfile-types = [{ glob = \"Tiltfile\" }, \"tiltfile\"]\ncomment-token = \"#\"\ngrammar = \"python\" # Uses starlark as grammar\nindent = { tab-width = 4, unit = \"    \" }\nlanguage-servers = [\"tilt\"]\nformatter = {command = \"buildifier\"} # Official formatter tool for starlark/bazel\nauto-format = true\n\n[[language]]\nname = \"gnuplot\"\nscope = \"source.gnuplot\"\nfile-types = [ \"gnuplot\", \"plot\", \"plt\" ]\ninjection-regex = \"gnuplot\"\nindent = { tab-width = 4, unit=\"    \"}\ncomment-token = \"#\"\n[language.auto-pairs]\n'(' = ')'\n'\"' = '\"'\n\"'\" = \"'\"\n\n[[grammar]]\nname = \"gnuplot\"\nsource = { git = \"https://codeberg.org/maribu/tree-sitter-gnuplot\", rev = \"21a3a3929facb964b3592daeb69119294ff84cf2\" }\n\n[[language]]\nname = \"drools\"\nscope = \"source.drools\"\nfile-types = [\"drl\"]\nroots = [\"pom.xml\", \".git\"]\ncomment-tokens = \"//\"\nlanguage-servers = [ \"drools-lsp\" ]\nformatter = { command = \"drools-fmt\" }\n\n[[grammar]]\nname = \"drools\"\nsource = { git = \"https://github.com/iByteABit256/tree-sitter-drools\", rev = \"f1404d2a3974dfcfd4193246e763edeeb4b399c1\" }\n\n[[language]]\nname = \"proverif\"\nscope = \"source.proverif\"\nfile-types = [ \"pv\" ]\ninjection-regex = \"proverif\"\nindent = { tab-width = 8, unit=\"        \"}\nblock-comment-tokens = { start = \"(*\", end = \"*)\" }\n[language.auto-pairs]\n'(' = ')'\n'\"' = '\"'\n\"'\" = \"'\"\n\n[[grammar]]\nname = \"proverif\"\nsource = { git = \"https://codeberg.org/maribu/tree-sitter-proverif\", rev = \"7741807092c4009c1fe4c3648da60ca72b1b80f1\" }\n\n[[language]]\nname = \"ptx\"\nscope = \"source.ptx\"\ninjection-regex = \"ptx\"\nfile-types = [\"ptx\"]\nlanguage-servers = []\ncomment-token = \"//\"\nblock-comment-tokens = { start = \"/*\", end = \"*/\" }\nindent = { tab-width = 4, unit = \"    \" }\n\n[[grammar]]\nname = \"ptx\"\nsource = { git = \"https://codeberg.org/jer-gremlin/tree-sitter-ptx\", rev = \"3dfa6758d4c15832d051f933101992b9e01d6611\" }\n\n[[language]]\nname = \"tql\"\nscope = \"source.tql\"\nfile-types = [ \"tql\" ]\ninjection-regex = \"tql\"\nindent = {tab-width = 2, unit = \"  \"}\ncomment-token = \"//\"\n\n[[grammar]]\nname = \"tql\"\nsource = { git = \"https://github.com/tenzir/tree-sitter-tql\", rev = \"d3b3b2699bc09fd0c63e2c13f15f6e474665c62e\" }\n"
  },
  {
    "path": "runtime/queries/_gjs/highlights.scm",
    "content": "[\n  (glimmer_opening_tag)\n  (glimmer_closing_tag)\n] @constant.builtin\n\n"
  },
  {
    "path": "runtime/queries/_gjs/injections.scm",
    "content": "; PARSE GLIMMER TEMPLATES\n(call_expression\n  function: [\n    (identifier) @injection.language\n    (member_expression\n      property: (property_identifier) @injection.language)\n  ]\n  arguments: (template_string) @injection.content)\n\n; e.g.: <template><SomeComponent @arg={{double @value}} /></template>\n((glimmer_template) @injection.content\n (#set! injection.language \"glimmer\")\n (#set! injection.include-children))\n\n; Parse Ember/Glimmer/Handlebars/HTMLBars/etc. template literals\n; e.g.: await render(hbs`<SomeComponent />`)\n((call_expression\n   function: ((identifier) @_name\n              (#eq? @_name \"hbs\"))\n   arguments: (template_string) @injection.content)\n (#set! injection.language \"glimmer\"))\n"
  },
  {
    "path": "runtime/queries/_javascript/highlights.scm",
    "content": "; Function and method parameters\n;-------------------------------\n\n; Javascript and Typescript Treesitter grammars deviate when defining the\n; tree structure for parameters, so we need to address them in each specific\n; language instead of ecma.\n\n; (p)\n(formal_parameters \n  (identifier) @variable.parameter)\n\n; (...p)\n(formal_parameters\n  (rest_pattern\n    (identifier) @variable.parameter))\n\n; ({ p })\n(formal_parameters\n  (object_pattern\n    (shorthand_property_identifier_pattern) @variable.parameter))\n\n; ({ a: p })\n(formal_parameters\n  (object_pattern\n    (pair_pattern\n      value: (identifier) @variable.parameter)))\n\n; ([ p ])\n(formal_parameters\n  (array_pattern\n    (identifier) @variable.parameter))\n\n; (p = 1)\n(formal_parameters\n  (assignment_pattern\n    left: (identifier) @variable.parameter))\n"
  },
  {
    "path": "runtime/queries/_javascript/locals.scm",
    "content": "; Definitions\n;------------\n; Javascript and Typescript Treesitter grammars deviate when defining the\n; tree structure for parameters, so we need to address them in each specific\n; language instead of ecma.\n\n; (i)\n(formal_parameters \n  (identifier) @local.definition.variable.parameter)\n\n; (i = 1)\n(formal_parameters \n  (assignment_pattern\n    left: (identifier) @local.definition.variable.parameter))\n"
  },
  {
    "path": "runtime/queries/_javascript/tags.scm",
    "content": "(\n  (comment)* @doc\n  .\n  (method_definition\n    name: (property_identifier) @name) @definition.method\n  (#not-eq? @name \"constructor\")\n  (#strip! @doc \"^[\\\\s\\\\*/]+|^[\\\\s\\\\*/]$\")\n  (#select-adjacent! @doc @definition.method)\n)\n\n(\n  (comment)* @doc\n  .\n  [\n    (class\n      name: (_) @name)\n    (class_declaration\n      name: (_) @name)\n  ] @definition.class\n  (#strip! @doc \"^[\\\\s\\\\*/]+|^[\\\\s\\\\*/]$\")\n  (#select-adjacent! @doc @definition.class)\n)\n\n(\n  (comment)* @doc\n  .\n  [\n    (function_expression\n      name: (identifier) @name)\n    (function_declaration\n      name: (identifier) @name)\n    (generator_function\n      name: (identifier) @name)\n    (generator_function_declaration\n      name: (identifier) @name)\n  ] @definition.function\n  (#strip! @doc \"^[\\\\s\\\\*/]+|^[\\\\s\\\\*/]$\")\n  (#select-adjacent! @doc @definition.function)\n)\n\n(\n  (comment)* @doc\n  .\n  (lexical_declaration\n    (variable_declarator\n      name: (identifier) @name\n      value: [(arrow_function) (function_expression)]) @definition.function)\n  (#strip! @doc \"^[\\\\s\\\\*/]+|^[\\\\s\\\\*/]$\")\n  (#select-adjacent! @doc @definition.function)\n)\n\n(\n  (comment)* @doc\n  .\n  (variable_declaration\n    (variable_declarator\n      name: (identifier) @name\n      value: [(arrow_function) (function_expression)]) @definition.function)\n  (#strip! @doc \"^[\\\\s\\\\*/]+|^[\\\\s\\\\*/]$\")\n  (#select-adjacent! @doc @definition.function)\n)\n\n(assignment_expression\n  left: [\n    (identifier) @name\n    (member_expression\n      property: (property_identifier) @name)\n  ]\n  right: [(arrow_function) (function_expression)]\n) @definition.function\n\n(pair\n  key: (property_identifier) @name\n  value: [(arrow_function) (function_expression)]) @definition.function\n\n(\n  (call_expression\n    function: (identifier) @name) @reference.call\n  (#not-match? @name \"^(require)$\")\n)\n\n(call_expression\n  function: (member_expression\n    property: (property_identifier) @name)\n  arguments: (_) @reference.call)\n\n(new_expression\n  constructor: (_) @name) @reference.class\n"
  },
  {
    "path": "runtime/queries/_jsx/highlights.scm",
    "content": "; Punctuation\n; -----------\n\n; Handle attribute delimiter (<Component color=\"red\"/>)\n(jsx_attribute \"=\" @punctuation.delimiter)\n\n; <Component>\n(jsx_opening_element [\"<\" \">\"] @punctuation.bracket)\n\n; </Component>\n(jsx_closing_element [\"</\" \">\"] @punctuation.bracket)\n\n; <Component />\n(jsx_self_closing_element [\"<\" \"/>\"] @punctuation.bracket)\n\n; Attributes\n; ----------\n\n(jsx_attribute (property_identifier) @attribute)\n\n; Opening elements\n; ----------------\n\n(jsx_opening_element (identifier) @tag)\n\n(jsx_opening_element ((identifier) @constructor\n (#match? @constructor \"^[A-Z]\")))\n\n; Closing elements\n; ----------------\n\n(jsx_closing_element (identifier) @tag)\n\n(jsx_closing_element ((identifier) @constructor\n (#match? @constructor \"^[A-Z]\")))\n\n; Self-closing elements\n; ---------------------\n\n(jsx_self_closing_element (identifier) @tag)\n\n(jsx_self_closing_element ((identifier) @constructor\n (#match? @constructor \"^[A-Z]\")))\n"
  },
  {
    "path": "runtime/queries/_jsx/indents.scm",
    "content": "[\n  (jsx_element)\n  (jsx_self_closing_element)\n] @indent\n\n(parenthesized_expression) @indent\n"
  },
  {
    "path": "runtime/queries/_jsx/textobjects.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n(jsx_self_closing_element) @xml-element.around @xml-element.inside\n\n(jsx_element (jsx_opening_element) (_)* @xml-element.inside (jsx_closing_element))\n\n(jsx_element) @xml-element.around\n"
  },
  {
    "path": "runtime/queries/_typescript/highlights.scm",
    "content": "; Namespaces\n; ----------\n\n(internal_module\n  [((identifier) @namespace) ((nested_identifier (identifier) @namespace))])\n\n(ambient_declaration \"global\" @namespace)\n\n; Parameters\n; ----------\n; Javascript and Typescript Treesitter grammars deviate when defining the\n; tree structure for parameters, so we need to address them in each specific\n; language instead of ecma.\n\n; (p: t)\n; (p: t = 1)\n(required_parameter \n  (identifier) @variable.parameter)\n\n; (...p: t)\n(required_parameter\n  (rest_pattern\n    (identifier) @variable.parameter))\n\n; ({ p }: { p: t })\n(required_parameter\n  (object_pattern\n    (shorthand_property_identifier_pattern) @variable.parameter))\n\n; ({ a: p }: { a: t })\n(required_parameter\n  (object_pattern\n    (pair_pattern\n      value: (identifier) @variable.parameter)))\n\n; ([ p ]: t[])\n(required_parameter\n  (array_pattern\n    (identifier) @variable.parameter))\n\n; (p?: t)\n; (p?: t = 1) // Invalid but still possible to highlight.\n(optional_parameter \n  (identifier) @variable.parameter)\n\n; (...p?: t) // Invalid but still possible to highlight.\n(optional_parameter\n  (rest_pattern\n    (identifier) @variable.parameter))\n\n; ({ p }: { p?: t})\n(optional_parameter\n  (object_pattern\n    (shorthand_property_identifier_pattern) @variable.parameter))\n\n; ({ a: p }: { a?: t })\n(optional_parameter\n  (object_pattern\n    (pair_pattern\n      value: (identifier) @variable.parameter)))\n\n; ([ p ]?: t[]) // Invalid but still possible to highlight.\n(optional_parameter\n  (array_pattern\n    (identifier) @variable.parameter))\n\n(public_field_definition) @punctuation.special\n(this_type) @variable.builtin\n(type_predicate) @keyword.operator\n\n; Punctuation\n; -----------\n\n[\n  \":\"\n] @punctuation.delimiter\n\n(optional_parameter \"?\" @punctuation.special)\n(property_signature \"?\" @punctuation.special)\n\n(conditional_type [\"?\" \":\"] @operator)\n(ternary_expression [\"?\" \":\"] @operator)\n\n; Keywords\n; --------\n\n[\n  \"abstract\"\n  \"declare\"\n  \"module\"\n  \"export\"\n  \"infer\"\n  \"implements\"\n  \"keyof\"\n  \"namespace\"\n  \"override\"\n  \"satisfies\"\n] @keyword\n\n[\n  \"type\"\n  \"interface\"\n  \"enum\"\n] @keyword.storage.type\n\n[\n  \"public\"\n  \"private\"\n  \"protected\"\n  \"readonly\"\n] @keyword.storage.modifier\n\n; Types\n; -----\n\n(type_identifier) @type\n(type_parameter\n  name: (type_identifier) @type.parameter)\n(predefined_type) @type.builtin\n\n; Type arguments and parameters\n; -----------------------------\n\n(type_arguments\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n(type_parameters\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n(omitting_type_annotation) @punctuation.special\n(opting_type_annotation) @punctuation.special\n\n; Literals\n; --------\n\n[\n  (template_literal_type)\n] @string\n\n(import_require_clause\n  (identifier) \"=\"\n  (\"require\") @keyword)\n"
  },
  {
    "path": "runtime/queries/_typescript/indents.scm",
    "content": "[\n  (enum_declaration) \n  (interface_declaration)\n  (object_type)\n] @indent\n"
  },
  {
    "path": "runtime/queries/_typescript/locals.scm",
    "content": "; Scopes\n;-------\n\n[\n  (type_alias_declaration)\n  (class_declaration)\n  (interface_declaration)\n] @local.scope\n\n; Definitions\n;------------\n\n(type_parameter\n  name: (type_identifier) @local.definition.type.parameter)\n\n; Javascript and Typescript Treesitter grammars deviate when defining the\n; tree structure for parameters, so we need to address them in each specific\n; language instead of ecma.\n\n; (i: t)\n; (i: t = 1)\n(required_parameter\n  (identifier) @local.definition.variable.parameter)\n\n; (i?: t)\n; (i?: t = 1) // Invalid but still possible to highlight.\n(optional_parameter\n  (identifier) @local.definition.variable.parameter)\n\n; References\n;-----------\n\n(type_identifier) @local.reference\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/_typescript/tags.scm",
    "content": "(function_signature\n  name: (identifier) @name) @definition.function\n\n(method_signature\n  name: (property_identifier) @name) @definition.method\n\n(abstract_method_signature\n  name: (property_identifier) @name) @definition.method\n\n(abstract_class_declaration\n  name: (type_identifier) @name) @definition.class\n\n(module\n  name: (identifier) @name) @definition.module\n\n(interface_declaration\n  name: (type_identifier) @name) @definition.interface\n\n(type_annotation\n  (type_identifier) @name) @reference.type\n\n(new_expression\n  constructor: (identifier) @name) @reference.class\n"
  },
  {
    "path": "runtime/queries/_typescript/textobjects.scm",
    "content": "[\n  (interface_declaration \n    body:(_) @class.inside)\n  (type_alias_declaration \n    value: (_) @class.inside)\n] @class.around\n\n(enum_body\n  (_) @entry.around)\n\n(enum_assignment (_) @entry.inside)\n\n"
  },
  {
    "path": "runtime/queries/ada/folds.scm",
    "content": "; Support for folding in Ada\n;;    za     toggles folding a package, subprogram, if statement or loop\n\n[\n   (package_declaration)\n   (generic_package_declaration)\n   (package_body)\n   (subprogram_declaration)\n   (subprogram_body)\n   (block_statement)\n   (if_statement)\n   (loop_statement)\n   (gnatprep_declarative_if_statement)\n   (gnatprep_if_statement)\n] @fold\n"
  },
  {
    "path": "runtime/queries/ada/highlights.scm",
    "content": "[\n   \"abort\"\n   \"abs\"\n   \"abstract\"\n   \"accept\"\n   \"access\"\n   \"all\"\n   \"array\"\n   \"at\"\n   \"begin\"\n   \"declare\"\n   \"delay\"\n   \"delta\"\n   \"digits\"\n   \"do\"\n   \"end\"\n   \"entry\"\n   \"exit\"\n   \"generic\"\n   \"interface\"\n   \"is\"\n   \"limited\"\n   \"of\"\n   \"others\"\n   \"out\"\n   \"pragma\"\n   \"private\"\n   \"range\"\n   \"synchronized\"\n   \"tagged\"\n   \"task\"\n   \"terminate\"\n   \"until\"\n   \"when\"\n] @keyword\n[\n   \"null\"\n] @constant.builtin\n[\n   \"aliased\"\n   \"constant\"\n   \"renames\"\n] @keyword.storage\n[\n   \"mod\"\n   \"new\"\n   \"protected\"\n   \"record\"\n   \"subtype\"\n   \"type\"\n] @type.builtin\n[\n   \"with\"\n   \"use\"\n] @keyword.control.import\n[\n   \"body\"\n   \"function\"\n   \"overriding\"\n   \"procedure\"\n   \"package\"\n   \"separate\"\n] @keyword.function\n[\n   \"and\"\n   \"in\"\n   \"not\"\n   \"or\"\n   \"xor\"\n] @operator\n[\n   \"while\"\n   \"loop\"\n   \"for\"\n   \"parallel\"\n   \"reverse\"\n   \"some\"\n] @keyword.control.repeat\n[\n   \"return\"\n] @keyword.control.return\n[\n   \"case\"\n   \"if\"\n   \"else\"\n   \"then\"\n   \"elsif\"\n   \"select\"\n] @keyword.control.conditional\n[\n   \"exception\"\n   \"raise\"\n] @keyword.control.exception\n(comment)         @comment\n(string_literal)  @string\n(character_literal) @string\n(numeric_literal) @constant.numeric\n\n;; Highlight the name of subprograms\n(procedure_specification name: (_) @function.builtin)\n(function_specification name: (_) @function.builtin)\n(package_declaration name: (_) @function.builtin)\n(package_body name: (_) @function.builtin)\n(generic_instantiation name: (_) @function.builtin)\n(entry_declaration . (identifier) @function.builtin)\n\n;; Some keywords should take different categories depending on the context\n(use_clause \"use\"  @keyword.control.import \"type\" @keyword.control.import)\n(with_clause \"private\" @keyword.control.import)\n(with_clause \"limited\" @keyword.control.import)\n(use_clause (_) @namespace)\n(with_clause (_) @namespace)\n\n(loop_statement \"end\" @keyword.control.repeat)\n(if_statement \"end\" @keyword.control.conditional)\n(loop_parameter_specification \"in\" @keyword.control.repeat)\n(iterator_specification [\"in\" \"of\"] @keyword.control.repeat)\n(range_attribute_designator \"range\" @keyword.control.repeat)\n\n(raise_statement \"with\" @keyword.control.exception)\n\n(gnatprep_declarative_if_statement)  @keyword.directive\n(gnatprep_if_statement)              @keyword.directive\n(gnatprep_identifier)                @keyword.directive\n\n(subprogram_declaration \"is\" @keyword.function \"abstract\"  @keyword.function)\n(aspect_specification \"with\" @keyword.function)\n\n(full_type_declaration \"is\" @type.builtin)\n(subtype_declaration \"is\" @type.builtin)\n(record_definition \"end\" @type.builtin)\n(full_type_declaration (_ \"access\" @type.builtin))\n(array_type_definition \"array\" @type.builtin \"of\" @type.builtin)\n(access_to_object_definition \"access\" @type.builtin)\n(access_to_object_definition \"access\" @type.builtin\n   [\n      (general_access_modifier \"constant\" @type.builtin)\n      (general_access_modifier \"all\" @type.builtin)\n   ]\n)\n(range_constraint \"range\" @type.builtin)\n(signed_integer_type_definition \"range\" @type.builtin)\n(index_subtype_definition \"range\" @type.builtin)\n(record_type_definition \"abstract\" @type.builtin)\n(record_type_definition \"tagged\" @type.builtin)\n(record_type_definition \"limited\" @type.builtin)\n(record_type_definition (record_definition \"null\" @type.builtin))\n(private_type_declaration \"is\" @type.builtin \"private\" @type.builtin)\n(private_type_declaration \"tagged\" @type.builtin)\n(private_type_declaration \"limited\" @type.builtin)\n(task_type_declaration \"task\" @type.builtin \"is\" @type.builtin)\n\n;; Gray the body of expression functions\n(expression_function_declaration\n   (function_specification)\n   \"is\"\n   (_) @attribute\n)\n(subprogram_declaration (aspect_specification) @attribute)\n\n;; Highlight full subprogram specifications\n; (subprogram_body\n;     [\n;        (procedure_specification)\n;        (function_specification)\n;     ] @function.builtin.spec\n; )\n\n\n"
  },
  {
    "path": "runtime/queries/ada/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/ada/locals.scm",
    "content": "(compilation) @local.scope\n(package_declaration) @local.scope\n(package_body) @local.scope\n(subprogram_declaration) @local.scope\n(subprogram_body) @local.scope\n(block_statement) @local.scope\n\n(parameter_specification . (identifier) @local.definition.variable.parameter)\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/ada/textobjects.scm",
    "content": ";; Support for high-level text objects selections.\n;; For instance:\n;;    maf     (v)isually select (a) (f)unction or subprogram\n;;    mif     (v)isually select (i)nside a (f)unction or subprogram\n;;    mai     (v)isually select (a) (i)f statement (or loop)\n;;    mii     (v)isually select (i)nside an (i)f statement (or loop)\n;;\n;; For navigations using textobjects, check link below:\n;; https://docs.helix-editor.com/master/usage.html#navigating-using-tree-sitter-textobjects\n;;\n;; For Textobject queries explanation, check out link below:\n;; https://docs.helix-editor.com/master/guides/textobject.html\n\n(subprogram_body) @function.around\n(subprogram_body (non_empty_declarative_part) @function.inside)\n(subprogram_body (handled_sequence_of_statements) @function.inside)\n(function_specification) @function.around\n(procedure_specification) @function.around\n(package_declaration) @function.around\n(generic_package_declaration) @function.around\n(package_body) @function.around\n"
  },
  {
    "path": "runtime/queries/adl/highlights.scm",
    "content": "; adl\n\n[\n\"module\"\n\"struct\"\n\"union\"\n\"type\"\n\"newtype\"\n\"annotation\"\n] @keyword\n\n(adl (scoped_name)) @namespace\n(comment) @comment\n(doc_comment) @comment.block.documentation\n(name) @type\n\n(fname) @variable.other.member\n\n(type_expr (scoped_name) @type)\n\n(type_expr_params (param (scoped_name) @type.parameter))\n\n; json\n(key) @string.special\n\n(string) @string\n\n(number) @constant.numeric\n\n[\n  (null)\n  (true)\n  (false)\n] @constant.builtin\n\n(escape_sequence) @constant.character.escape\n\n"
  },
  {
    "path": "runtime/queries/adl/indents.scm",
    "content": "[\n  (struct)\n  (union)\n  \n  (array)\n  (object)\n] @indent\n\n; [\n;  \"}\"\n;  \"]\"\n; ] @outdent\n"
  },
  {
    "path": "runtime/queries/adl/textobjects.scm",
    "content": "(struct (_) @function.inside) @function.around\n"
  },
  {
    "path": "runtime/queries/agda/highlights.scm",
    "content": ";; Punctuation\n[ \".\" \";\" \":\"] @punctuation.delimiter\n[ \"(\" \")\" \"{\" \"}\" ] @punctuation.bracket\n\n;; Constants\n(integer) @constant.numeric.integer\n; (float) @constant.numeric.float\n(literal) @string\n\n;; Pragmas and comments\n(comment) @comment\n(pragma) @attribute\n(macro) @function.macro\n\n;; Imports\n(module_name) @namespace\n(import_directive (id) @namespace)\n[(module) (import) (open)] @keyword.control.import\n\n;; Types\n(typed_binding (expr) @type)\n(record        (expr) @type)\n(data          (expr) @type)\n(signature     (expr) @type)\n(function (rhs (expr) @type))\n; todo: these are too general. ideally, any nested (atom)\n; https://github.com/tree-sitter/tree-sitter/issues/880\n\n;; Variables\n(untyped_binding (atom) @variable)\n(typed_binding   (atom) @variable)\n(field_name) @variable.other.member\n\n;; Functions\n(function_name) @function\n;(function (lhs\n;  . (atom) @function\n;    (atom) @variable.parameter))\n; todo: currently fails to parse, upstream tree-sitter bug\n\n;; Data\n[(data_name) (record_name)] @constructor\n((atom) @constant.builtin.boolean\n  (#any-of? @constant.builtin.boolean \"true\" \"false\" \"True\" \"False\"))\n\n\"Set\" @type.builtin\n\n; postulate\n; type_signature\n; pattern\n; id\n; bid\n; typed_binding\n; primitive\n; private\n; record_signature\n; record_assignments\n; field_assignment\n; module_assignment\n; renaming\n; import_directive\n; lambda\n; let\n; instance\n; generalize\n; record\n; fields\n; syntax\n; hole_name\n; data_signature\n\n;; Keywords\n[\n  \"where\"\n  \"data\"\n  \"rewrite\"\n  \"postulate\"\n  \"public\"\n  \"private\"\n  \"tactic\"\n  \"Prop\"\n  \"quote\"\n  \"renaming\"\n  \"in\"\n  \"hiding\"\n  \"constructor\"\n  \"abstract\"\n  \"let\"\n  \"field\"\n  \"mutual\"\n  \"infix\"\n  \"infixl\"\n  \"infixr\"\n  \"record\"\n  \"overlap\"\n  \"instance\"\n  \"do\"\n] @keyword\n\n[\n  \"=\"\n] @operator\n\n; = | -> : ? \\ .. ... λ ∀ →\n; (_LAMBDA) (_FORALL) (_ARROW)\n; \"coinductive\"\n; \"eta-equality\"\n; \"field\"\n; \"inductive\"\n; \"interleaved\"\n; \"macro\"\n; \"no-eta-equality\"\n; \"pattern\"\n; \"primitive\"\n; \"quoteTerm\"\n; \"rewrite\"\n; \"syntax\"\n; \"unquote\"\n; \"unquoteDecl\"\n; \"unquoteDef\"\n; \"using\"\n; \"variable\"\n; \"with\"\n\n"
  },
  {
    "path": "runtime/queries/alloy/highlights.scm",
    "content": "; Literals\n; --------\n\n(boolean) @constant.builtin.boolean\n(comment) @comment\n(string) @string\n(number) @constant.numeric\n(null) @constant.builtin\n\n; Punctuation\n; -----------\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n]  @punctuation.bracket\n\n[\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"=\"\n] @operator\n\n; Function definitions\n;---------------------\n\n(function\n  name: (identifier) @function)\n\n\n(attribute (identifier) @variable.other.member)\n(block (identifier) @type.builtin)\n"
  },
  {
    "path": "runtime/queries/amber/highlights.scm",
    "content": "(comment) @comment\n\n[\n    \"if\"\n    \"loop\"\n    \"for\"\n    \"return\"\n    \"fun\"\n    \"else\"\n    \"then\"\n    \"break\"\n    \"continue\"\n    \"and\"\n    \"or\"\n    \"not\"\n    \"let\"\n    \"pub\"\n    \"main\"\n    \"echo\"\n    \"exit\"\n    \"fun\"\n    \"import\"\n    \"from\"\n    \"as\"\n    \"in\"\n    \"fail\"\n    \"failed\"\n    \"silent\"\n    \"nameof\"\n    \"is\"\n    \"unsafe\"\n    \"trust\"\n] @keyword\n\n; Literals\n(boolean) @constant.builtin.boolean\n(number) @constant.numeric\n(null) @constant.builtin\n(string) @string\n(status) @keyword\n; Highlight only command delimiters, not content (bash injection handles content)\n(command\n  [\"$\"] @string)\n(handler) @keyword\n(block) @punctuation.delimiter\n(variable_init) @keyword\n(variable_assignment) @punctuation.delimiter\n(variable) @variable\n(escape_sequence) @constant.character.escape\n(type_name_symbol) @type\n(interpolation) @punctuation.delimiter\n(reference) @keyword\n(preprocessor_directive) @comment\n(shebang) @comment\n(function_definition\n    name: (variable) @function.method)\n(function_call\n    name: (variable) @function.method)\n(import_statement\n    \"pub\" @keyword\n    \"import\" @keyword\n    \"from\" @keyword)\n"
  },
  {
    "path": "runtime/queries/amber/indents.scm",
    "content": "; Block structures that increase indent\n[\n  (function_definition)\n  (block)\n  (main_block)\n\n  ; Control flow\n  (if_cond)\n  (if_chain)\n  (for_loop)\n  (while_loop)\n  (loop_infinite)\n\n  ; Collections\n  (array)\n  (parameter_list)\n  (function_parameter_list)\n  (parentheses)\n\n  ; Amber-specific\n  (command_modifier_block)\n  (handler_failed)\n  (handler_succeeded)\n  (handler_exited)\n] @indent\n\n; Closing delimiters\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n\n; Multi-line construct support\n[\n  (function_definition)\n  (if_cond)\n  (if_chain)\n  (for_loop)\n  (while_loop)\n  (loop_infinite)\n  (main_block)\n] @extend\n\n; Prevent premature outdent\n[\n  (function_control_flow)\n  (loop_control_flow)\n] @extend.prevent-once\n"
  },
  {
    "path": "runtime/queries/amber/injections.scm",
    "content": "; Inject bash into command content\n((command_content) @injection.content\n (#set! injection.language \"bash\"))\n\n; Inject markdown into documentation comments (///)\n((comment) @injection.content\n (#match? @injection.content \"^///\")\n (#set! injection.language \"markdown\")\n (#set! injection.combined))\n\n; Regular comments (excluding doc comments)\n((comment) @injection.content\n (#not-match? @injection.content \"^///\")\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/amber/rainbows.scm",
    "content": "[ \"(\" \")\" \"[\" \"]\" \"{\" \"}\" ] @rainbow.bracket\n\n[\n  ; Functions and main block\n  (function_definition)\n  (main_block)\n\n  ; Control flow blocks\n  (if_cond)\n  (if_chain)\n  (if_ternary)\n  (for_loop)\n  (while_loop)\n  (loop_infinite)\n\n  ; General blocks\n  (block)\n  (command_modifier_block)\n\n  ; Collections and grouping\n  (array)\n  (parameter_list)\n  (function_parameter_list)\n  (parentheses)\n\n  ; Handlers\n  (handler_failed)\n  (handler_succeeded)\n  (handler_exited)\n] @rainbow.scope\n"
  },
  {
    "path": "runtime/queries/amber/tags.scm",
    "content": "; Function definitions\n(function_definition\n  name: (variable) @name) @definition.function\n\n; Function calls\n(function_call\n  name: (variable) @name) @reference.call\n\n; Main block as entry point\n(main_block) @definition.function\n"
  },
  {
    "path": "runtime/queries/amber/textobjects.scm",
    "content": "; Functions - capture both definition and body\n(function_definition\n  body: (_) @function.inside) @function.around\n\n; Function parameters in definitions\n(function_parameter_list\n  (function_parameter_list_item) @parameter.inside)\n\n; Function call arguments\n(parameter_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n; Comments\n(comment) @comment.inside\n(comment)+ @comment.around\n\n; Arrays\n(array\n  (_) @entry.around)\n\n; Main Block looks like a function\n(main_block\n  (block) @function.inside) @function.around\n"
  },
  {
    "path": "runtime/queries/astro/highlights.scm",
    "content": "(tag_name) @tag\n(erroneous_end_tag_name) @error\n(doctype) @constant\n(attribute_name) @attribute\n(comment) @comment\n\n((attribute\n  (attribute_name) @attribute\n  (quoted_attribute_value (attribute_value) @markup.link.url))\n (#any-of? @attribute \"href\" \"src\"))\n\n((element\n  (start_tag\n    (tag_name) @tag)\n  (text) @markup.link.label)\n  (#eq? @tag \"a\"))\n\n(attribute [(attribute_value) (quoted_attribute_value)] @string)\n\n((element\n  (start_tag\n    (tag_name) @tag)\n  (text) @markup.bold)\n  (#any-of? @tag \"strong\" \"b\"))\n\n((element\n  (start_tag\n    (tag_name) @tag)\n  (text) @markup.italic)\n  (#any-of? @tag \"em\" \"i\"))\n\n((element\n  (start_tag\n    (tag_name) @tag)\n  (text) @markup.strikethrough)\n  (#any-of? @tag \"s\" \"del\"))\n\n[\n  \"<\"\n  \">\"\n  \"</\"\n  \"/>\"\n  \"<!\"\n] @punctuation.bracket\n\n\"=\" @punctuation.delimiter\n\n[\"---\"] @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/astro/injections.scm",
    "content": "; inherits: html\n\n((frontmatter\n\t(raw_text) @injection.content)\n (#set! injection.language \"typescript\"))\n\n((interpolation\n\t(raw_text) @injection.content)\n (#set! injection.language \"tsx\"))\n"
  },
  {
    "path": "runtime/queries/awk/highlights.scm",
    "content": "; tree-sitter-awk v0.5.1\n\n; Order matters\n\n[\n  \";\"\n  \",\"\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @operator\n\n(piped_io_statement [\n  \"|\"\n  \"|&\"\n] @operator)\n\n(redirected_io_statement [\n  \">\"\n  \">>\"\n] @operator)\n\n(update_exp [\n  \"++\"\n  \"--\"\n] @operator)\n\n(ternary_exp [\n  \"?\"\n  \":\"\n] @operator)\n\n(assignment_exp [\n  \"=\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"^=\"\n] @operator)\n\n(unary_exp [\n  \"!\"\n  \"+\"\n  \"-\"\n] @operator)\n\n(binary_exp [\n  \"^\"\n  \"**\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"+\"\n  \"-\"\n  \"<\"\n  \">\"\n  \"<=\"\n  \">=\"\n  \"==\"\n  \"!=\"\n  \"~\"\n  \"!~\"\n  \"in\"\n  \"&&\"\n  \"||\"\n] @operator)\n\n[\n  \"@include\"\n  \"@load\"\n  \"@namespace\"\n  (pattern)\n] @namespace\n\n[\n  \"function\"\n  \"func\"\n  \"print\"\n  \"printf\"\n  \"if\"\n  \"else\"\n  \"do\"\n  \"while\"\n  \"for\"\n  \"in\"\n  \"delete\"\n  \"return\"\n  \"exit\"\n  \"switch\"\n  \"case\"\n  \"default\"\n  (break_statement)\n  (continue_statement)\n  (next_statement)\n  (nextfile_statement)\n  (getline_input)\n  (getline_file)\n] @keyword\n\n(comment) @comment\n(regex) @string.regexp\n(number) @constant.numeric\n(string) @string\n\n[\n  (identifier)\n  (field_ref)\n] @variable\n\n(func_call name: (identifier) @function)\n(func_def name: (identifier) @function)\n\n(field_ref (_) @variable)\n\n(ns_qualified_name \"::\" @operator)\n(ns_qualified_name (namespace) @namespace)\n"
  },
  {
    "path": "runtime/queries/awk/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((regex_pattern) @injection.content\n (#set! injection.language \"regex\"))\n"
  },
  {
    "path": "runtime/queries/awk/textobjects.scm",
    "content": "\n(func_def name: (identifier) (block) @function.inside) @function.around\n\n(param_list (_) @parameter.inside) @parameter.around\n\n(args (_) @parameter.inside) @parameter.around\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/bash/highlights.scm",
    "content": "[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"[[\"\n  \"]]\"\n  \"((\"\n  \"))\"\n] @punctuation.bracket\n\n[\n  \";\"\n  \";;\"\n  \";&\"\n  \";;&\"\n  \"&\"\n] @punctuation.delimiter\n\n[\n  \">\"\n  \">>\"\n  \"<\"\n  \"<<\"\n  \"&&\"\n  \"|\"\n  \"|&\"\n  \"||\"\n  \"=\"\n  \"+=\"\n  \"=~\"\n  \"==\"\n  \"!=\"\n  \"&>\"\n  \"&>>\"\n  \"<&\"\n  \">&\"\n  \">|\"\n  \"<&-\"\n  \">&-\"\n  \"<<-\"\n  \"<<<\"\n  \"..\"\n  \"!\"\n] @operator\n\n[\n  (string)\n  (raw_string)\n  (ansi_c_string)\n  (heredoc_body)\n] @string\n\n[\n  (heredoc_start)\n  (heredoc_end)\n] @label\n\n(variable_assignment\n  (word) @string)\n\n(command\n  argument: \"$\" @string) ; bare dollar\n\n(concatenation\n  (word) @string)\n\n[\n  \"if\"\n  \"then\"\n  \"else\"\n  \"elif\"\n  \"fi\"\n  \"case\"\n  \"in\"\n  \"esac\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n  \"do\"\n  \"done\"\n  \"select\"\n  \"until\"\n  \"while\"\n] @keyword.control.repeat\n\n[\n  \"declare\"\n  \"typeset\"\n  \"readonly\"\n  \"local\"\n  \"unset\"\n  \"unsetenv\"\n] @keyword\n\n\"export\" @keyword.control.import\n\n\"function\" @keyword.function\n\n(special_variable_name) @constant\n\n; trap -l\n((word) @constant.builtin\n  (#any-of? @constant.builtin\n    \"SIGHUP\" \"SIGINT\" \"SIGQUIT\" \"SIGILL\" \"SIGTRAP\" \"SIGABRT\" \"SIGBUS\" \"SIGFPE\" \"SIGKILL\" \"SIGUSR1\"\n    \"SIGSEGV\" \"SIGUSR2\" \"SIGPIPE\" \"SIGALRM\" \"SIGTERM\" \"SIGSTKFLT\" \"SIGCHLD\" \"SIGCONT\" \"SIGSTOP\"\n    \"SIGTSTP\" \"SIGTTIN\" \"SIGTTOU\" \"SIGURG\" \"SIGXCPU\" \"SIGXFSZ\" \"SIGVTALRM\" \"SIGPROF\" \"SIGWINCH\"\n    \"SIGIO\" \"SIGPWR\" \"SIGSYS\" \"SIGRTMIN\" \"SIGRTMIN+1\" \"SIGRTMIN+2\" \"SIGRTMIN+3\" \"SIGRTMIN+4\"\n    \"SIGRTMIN+5\" \"SIGRTMIN+6\" \"SIGRTMIN+7\" \"SIGRTMIN+8\" \"SIGRTMIN+9\" \"SIGRTMIN+10\" \"SIGRTMIN+11\"\n    \"SIGRTMIN+12\" \"SIGRTMIN+13\" \"SIGRTMIN+14\" \"SIGRTMIN+15\" \"SIGRTMAX-14\" \"SIGRTMAX-13\"\n    \"SIGRTMAX-12\" \"SIGRTMAX-11\" \"SIGRTMAX-10\" \"SIGRTMAX-9\" \"SIGRTMAX-8\" \"SIGRTMAX-7\" \"SIGRTMAX-6\"\n    \"SIGRTMAX-5\" \"SIGRTMAX-4\" \"SIGRTMAX-3\" \"SIGRTMAX-2\" \"SIGRTMAX-1\" \"SIGRTMAX\"))\n\n((word) @constant.builtin.boolean\n  (#any-of? @constant.builtin.boolean \"true\" \"false\"))\n\n(comment) @comment\n\n(test_operator) @operator\n\n(command_substitution\n  \"$(\" @punctuation.special\n  \")\" @punctuation.special)\n\n(process_substitution\n  [\n    \"<(\"\n    \">(\"\n  ] @punctuation.special\n  \")\" @punctuation.special)\n\n(arithmetic_expansion\n  [\n    \"$((\"\n    \"((\"\n  ] @punctuation.special\n  \"))\" @punctuation.special)\n\n(arithmetic_expansion\n  \",\" @punctuation.delimiter)\n\n(ternary_expression\n  [\n    \"?\"\n    \":\"\n  ] @keyword.control.conditional)\n\n(binary_expression\n  operator: _ @operator)\n\n(unary_expression\n  operator: _ @operator)\n\n(postfix_expression\n  operator: _ @operator)\n\n(function_definition\n  name: (word) @function)\n\n(command_name\n  (word) @function)\n\n(command_name\n  (word) @function.builtin\n  (#any-of? @function.builtin\n    \".\" \":\" \"alias\" \"bg\" \"bind\" \"break\" \"builtin\" \"caller\" \"cd\" \"command\" \"compgen\" \"complete\"\n    \"compopt\" \"continue\" \"coproc\" \"dirs\" \"disown\" \"echo\" \"enable\" \"eval\" \"exec\" \"exit\" \"false\" \"fc\"\n    \"fg\" \"getopts\" \"hash\" \"help\" \"history\" \"jobs\" \"kill\" \"let\" \"logout\" \"mapfile\" \"popd\" \"printf\"\n    \"pushd\" \"pwd\" \"read\" \"readarray\" \"return\" \"set\" \"shift\" \"shopt\" \"source\" \"suspend\" \"test\" \"time\"\n    \"times\" \"trap\" \"true\" \"type\" \"typeset\" \"ulimit\" \"umask\" \"unalias\" \"wait\"))\n\n(command\n  argument: [\n    (word) @variable.parameter\n    (concatenation\n      (word) @variable.parameter)\n  ])\n\n(declaration_command\n  (word) @variable.parameter)\n\n(unset_command\n  (word) @variable.parameter)\n\n(number) @constant.numeric\n\n(file_redirect\n  (word) @string.special.path)\n\n(herestring_redirect\n  (word) @string)\n\n(file_descriptor) @operator\n\n(simple_expansion\n  \"$\" @punctuation.special) @none\n\n(expansion\n  \"${\" @punctuation.special\n  \"}\" @punctuation.special) @none\n\n(expansion\n  operator: _ @punctuation.special)\n\n(expansion\n  \"@\"\n  .\n  operator: _ @constant.character)\n\n((expansion\n  (subscript\n    index: (word) @constant.character))\n  (#any-of? @constant.character \"@\" \"*\"))\n\n\"``\" @punctuation.special\n\n(variable_name) @variable\n\n((variable_name) @constant\n  (#match? @constant \"^[A-Z][A-Z_0-9]*$\"))\n\n((variable_name) @variable.builtin\n  (#any-of? @variable.builtin\n    ; https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Variables.html\n    \"CDPATH\" \"HOME\" \"IFS\" \"MAIL\" \"MAILPATH\" \"OPTARG\" \"OPTIND\" \"PATH\" \"PS1\" \"PS2\"\n    ; https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html\n    \"_\" \"BASH\" \"BASHOPTS\" \"BASHPID\" \"BASH_ALIASES\" \"BASH_ARGC\" \"BASH_ARGV\" \"BASH_ARGV0\" \"BASH_CMDS\"\n    \"BASH_COMMAND\" \"BASH_COMPAT\" \"BASH_ENV\" \"BASH_EXECUTION_STRING\" \"BASH_LINENO\"\n    \"BASH_LOADABLES_PATH\" \"BASH_REMATCH\" \"BASH_SOURCE\" \"BASH_SUBSHELL\" \"BASH_VERSINFO\"\n    \"BASH_VERSION\" \"BASH_XTRACEFD\" \"CHILD_MAX\" \"COLUMNS\" \"COMP_CWORD\" \"COMP_LINE\" \"COMP_POINT\"\n    \"COMP_TYPE\" \"COMP_KEY\" \"COMP_WORDBREAKS\" \"COMP_WORDS\" \"COMPREPLY\" \"COPROC\" \"DIRSTACK\" \"EMACS\"\n    \"ENV\" \"EPOCHREALTIME\" \"EPOCHSECONDS\" \"EUID\" \"EXECIGNORE\" \"FCEDIT\" \"FIGNORE\" \"FUNCNAME\"\n    \"FUNCNEST\" \"GLOBIGNORE\" \"GROUPS\" \"histchars\" \"HISTCMD\" \"HISTCONTROL\" \"HISTFILE\" \"HISTFILESIZE\"\n    \"HISTIGNORE\" \"HISTSIZE\" \"HISTTIMEFORMAT\" \"HOSTFILE\" \"HOSTNAME\" \"HOSTTYPE\" \"IGNOREEOF\" \"INPUTRC\"\n    \"INSIDE_EMACS\" \"LANG\" \"LC_ALL\" \"LC_COLLATE\" \"LC_CTYPE\" \"LC_MESSAGES\" \"LC_NUMERIC\" \"LC_TIME\"\n    \"LINENO\" \"LINES\" \"MACHTYPE\" \"MAILCHECK\" \"MAPFILE\" \"OLDPWD\" \"OPTERR\" \"OSTYPE\" \"PIPESTATUS\"\n    \"POSIXLY_CORRECT\" \"PPID\" \"PROMPT_COMMAND\" \"PROMPT_DIRTRIM\" \"PS0\" \"PS3\" \"PS4\" \"PWD\" \"RANDOM\"\n    \"READLINE_ARGUMENT\" \"READLINE_LINE\" \"READLINE_MARK\" \"READLINE_POINT\" \"REPLY\" \"SECONDS\" \"SHELL\"\n    \"SHELLOPTS\" \"SHLVL\" \"SRANDOM\" \"TIMEFORMAT\" \"TMOUT\" \"TMPDIR\" \"UID\"))\n\n(case_item\n  value: (word) @variable.parameter)\n\n[\n  (regex)\n  (extglob_pattern)\n] @string.regexp\n"
  },
  {
    "path": "runtime/queries/bash/indents.scm",
    "content": "[\n  (function_definition)\n  (if_statement)\n  (for_statement)\n  (while_statement)\n  (case_statement)\n  (pipeline)\n] @indent\n\n[\n  \"}\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/bash/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n(command\n  name: (command_name (word) @_command)\n  argument: (raw_string) @injection.content\n (#match? @_command \"^[gnm]?awk$\")\n (#set! injection.language \"awk\"))\n\n((regex) @injection.content\n  (#set! injection.language \"regex\"))\n\n(command\n  name: (command_name (word) @_command (#any-of? @_command \"jq\" \"jaq\"))\n  argument: [\n    (raw_string) @injection.content\n    (string (string_content) @injection.content)\n  ]\n  (#set! injection.language \"jq\"))\n\n(command\n  name: (command_name (word) @_command (#eq? @_command \"alias\"))\n  argument: (concatenation\n    (word)\n    [\n      (raw_string) @injection.content\n      (string (string_content) @injection.content)\n    ])\n  (#set! injection.language \"bash\"))\n\n(command\n  name: (command_name (word) @_command (#any-of? @_command \"eval\" \"trap\"))\n  .\n  argument: [\n    (raw_string) @injection.content\n    (string (string_content) @injection.content)\n  ]\n  (#set! injection.language \"bash\"))\n"
  },
  {
    "path": "runtime/queries/bash/rainbows.scm",
    "content": "[\n  (function_definition)\n  (compound_statement)\n  (subshell)\n  (test_command)\n  (subscript)\n  (parenthesized_expression)\n  (array)\n  (expansion)\n  (command_substitution)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"((\" \"))\"\n  \"${\" \"$(\"\n  \"{\" \"}\"\n  \"[\" \"]\"\n  \"[[\" \"]]\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/bash/tags.scm",
    "content": "(function_definition name: (word) @definition.function)\n"
  },
  {
    "path": "runtime/queries/bash/textobjects.scm",
    "content": "(function_definition\n  body: (_) @function.inside) @function.around\n\n(command\n  argument: (_) @parameter.inside)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(array\n  (_) @entry.around)\n"
  },
  {
    "path": "runtime/queries/basic/highlights.scm",
    "content": "; Keywords\n[\n  \"PRINT\"\n  \"LET\"\n  \"IF\"\n  \"THEN\"\n  \"GOTO\"\n  \"GOSUB\"\n  \"RETURN\"\n  \"FOR\"\n  \"TO\"\n  \"STEP\"\n  \"NEXT\"\n  \"INPUT\"\n  \"END\"\n  \"REM\"\n  \"DATA\"\n  \"READ\"\n  \"DIM\"\n] @keyword\n\n; Logical operators\n[\n  \"AND\"\n  \"and\"\n  \"OR\"\n  \"or\"\n  \"NOT\"\n] @keyword.operator\n\n; Comments\n(comment) @comment\n(rem_statement) @comment\n\n; Function calls\n(function_call) @function.call\n\n; Numbers\n(line_number) @constant.numeric\n(number) @constant.numeric\n\n; Strings\n(string) @string\n\n; Operators\n[\n  \"=\"\n  \"<>\"\n  \"<\"\n  \">\"\n  \"<=\"\n  \">=\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"^\"\n] @operator\n\n; Punctuation\n[\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \";\"\n] @punctuation.delimiter\n\n; Variables\n(identifier) @variable\n"
  },
  {
    "path": "runtime/queries/basic/indents.scm",
    "content": "[\n  (for_statement)\n] @indent\n\n[\n  \"NEXT\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/basic/tags.scm",
    "content": "(for_statement\n   variable: (identifier) @definition.variable)\n\n(let_statement\n  variable: (identifier) @definition.variable)\n"
  },
  {
    "path": "runtime/queries/basic/textobjects.scm",
    "content": "(for_statement) @function.around\n\n(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/bass/highlights.scm",
    "content": "; GENERATED VIA https://github.com/vito/tree-sitter-bass\n\n;;; comments\n\n(comment) @comment.line\n\n;;; punctuation\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n\n;;; constants\n\n[(ignore) (null)] @constant.builtin\n\n(bool) @constant.builtin.boolean\n\n(int) @constant.numeric.integer\n\n;;; strings\n\n;; string literals\n\n(string) @string\n(string (string_escape) @constant.character.escape)\n\n;; keywords (symbol literals)\n\n(keyword) @string.special.symbol\n\n;; paths\n\n(dot) @string.special.path\n(dotdot) @string.special.path\n(command) @string.special.path\n(subpath (symbol) @string.special.path)\n\n; slashes in a path denote a combiner call\n(subpath (slash) @function)\n\n\n;;; generic highlighting for all forms\n\n; first symbol in a list form is a combiner call\n(list . (symbol) @function)\n\n; highlight symbols as vars only when they're clearly vars\n(cons (symbol) @variable)\n(scope (symbol) @variable)\n(path form: (symbol) @variable)\n(symbind form: (symbol) @variable)\n\n\n;;; specific highlighting for builtins & special forms\n\n;; symbol classification based highlighting\n\n(list . (symbol) @keyword.control.conditional (#match? @keyword.control.conditional \"^(if|case|cond|when)$\"))\n(cons . (symbol) @keyword.control.conditional (#match? @keyword.control.conditional \"^(if|case|cond|when)$\"))\n\n(list . (symbol) @keyword.control.repeat (#match? @keyword.control.repeat \"^(each)$\"))\n(cons . (symbol) @keyword.control.repeat (#match? @keyword.control.repeat \"^(each)$\"))\n\n(list . (symbol) @label (#match? @label \"^(def|defop|defn)$\"))\n(cons . (symbol) @label (#match? @label \"^(def|defop|defn)$\"))\n\n(list . (symbol) @function.builtin (#match? @function.builtin \"^(dump|mkfs|json|log|error|now|cons|wrap|unwrap|eval|make-scope|bind|meta|with-meta|null\\\\?|ignore\\\\?|boolean\\\\?|number\\\\?|string\\\\?|symbol\\\\?|scope\\\\?|sink\\\\?|source\\\\?|list\\\\?|pair\\\\?|applicative\\\\?|operative\\\\?|combiner\\\\?|path\\\\?|empty\\\\?|thunk\\\\?|\\\\+|\\\\*|quot|-|max|min|=|>|>=|<|<=|list->source|across|emit|next|reduce-kv|assoc|symbol->string|string->symbol|str|substring|trim|scope->list|string->fs-path|string->cmd-path|string->dir|subpath|path-name|path-stem|with-image|with-dir|with-args|with-cmd|with-stdin|with-env|with-insecure|with-label|with-port|with-tls|with-mount|thunk-cmd|thunk-args|resolve|start|addr|wait|read|cache-dir|binds\\\\?|recall-memo|store-memo|mask|list|list\\\\*|first|rest|length|second|third|map|map-pairs|foldr|foldl|append|filter|conj|list->scope|merge|apply|id|always|vals|keys|memo|succeeds\\\\?|run|last|take|take-all|insecure!|from|cd|wrap-cmd|mkfile|path-base|not)$\"))\n(cons . (symbol) @function.builtin (#match? @function.builtin \"^(dump|mkfs|json|log|error|now|cons|wrap|unwrap|eval|make-scope|bind|meta|with-meta|null\\\\?|ignore\\\\?|boolean\\\\?|number\\\\?|string\\\\?|symbol\\\\?|scope\\\\?|sink\\\\?|source\\\\?|list\\\\?|pair\\\\?|applicative\\\\?|operative\\\\?|combiner\\\\?|path\\\\?|empty\\\\?|thunk\\\\?|\\\\+|\\\\*|quot|-|max|min|=|>|>=|<|<=|list->source|across|emit|next|reduce-kv|assoc|symbol->string|string->symbol|str|substring|trim|scope->list|string->fs-path|string->cmd-path|string->dir|subpath|path-name|path-stem|with-image|with-dir|with-args|with-cmd|with-stdin|with-env|with-insecure|with-label|with-port|with-tls|with-mount|thunk-cmd|thunk-args|resolve|start|addr|wait|read|cache-dir|binds\\\\?|recall-memo|store-memo|mask|list|list\\\\*|first|rest|length|second|third|map|map-pairs|foldr|foldl|append|filter|conj|list->scope|merge|apply|id|always|vals|keys|memo|succeeds\\\\?|run|last|take|take-all|insecure!|from|cd|wrap-cmd|mkfile|path-base|not)$\"))\n\n(list . (symbol) @function.macro (#match? @function.macro \"^(op|fn|current-scope|quote|let|provide|module|or|and|->|curryfn|for|\\\\$|linux)$\"))\n(cons . (symbol) @function.macro (#match? @function.macro \"^(op|fn|current-scope|quote|let|provide|module|or|and|->|curryfn|for|\\\\$|linux)$\"))\n\n(list . (symbol) @keyword.builtin (#match? @keyword.builtin \"^(do|doc)$\"))\n(cons . (symbol) @keyword.builtin (#match? @keyword.builtin \"^(do|doc)$\"))\n\n(list . (symbol) @keyword.control.import (#match? @keyword.control.import \"^(use|import|load)$\"))\n(cons . (symbol) @keyword.control.import (#match? @keyword.control.import \"^(use|import|load)$\"))\n\n\n;; special cases\n\n; [a & b] highlights & as operator rather than a regular symbol\n(list (symbol) @operator (#match? @operator \"&\"))\n(cons (symbol) @operator (#match? @operator \"&\"))\n\n; (-> x y z) highlights first x as var, y z as function\n(list\n  .\n  (symbol) @function.macro\n  (#eq? @function.macro \"->\")\n  .\n  (symbol) @variable.parameter\n  (symbol) @function)\n\n; (-> 42 x y) highlights 42 as regular number\n(list\n  .\n  (symbol) @function.macro\n  (#eq? @function.macro \"->\")\n  .\n  (_)\n  (symbol) @function)\n"
  },
  {
    "path": "runtime/queries/beancount/folds.scm",
    "content": "[\n  (transaction)\n  (section)\n] @fold\n"
  },
  {
    "path": "runtime/queries/beancount/highlights.scm",
    "content": "(date) @variable.builtin\n(txn) @variable.builtin\n\n(account) @type\n\n[\n  (amount)\n  (incomplete_amount)\n  (amount_tolerance)\n  (number)\n] @constant.numeric\n\n\n[(key_value) (key)] @variable.other.member\n(string) @string\n\n[\n  (currency)\n  (tag)\n  (link)\n] @constant\n\n(comment) @comment\n\n[\n  (minus)\n  (plus)\n] @operator\n\n[\n  (balance) (open) (close) (commodity) (pad)\n  (event) (price) (note) (document) (query)\n  (custom) (pushtag) (poptag) (pushmeta)\n  (popmeta) (option) (include) (plugin)\n] @keyword\n\n\n((headline item: (item) @markup.heading.6) @markup.heading.marker\n (#match? @markup.heading.marker \"^\\\\*\\\\*\\\\*\\\\*\\\\*\\\\*\"))\n((headline item: (item) @markup.heading.5) @markup.heading.marker\n (#match? @markup.heading.marker \"^\\\\*\\\\*\\\\*\\\\*\\\\*\"))\n((headline item: (item) @markup.heading.4) @markup.heading.marker\n (#match? @markup.heading.marker \"^\\\\*\\\\*\\\\*\\\\*\"))\n((headline item: (item) @markup.heading.3) @markup.heading.marker\n (#match? @markup.heading.marker \"^\\\\*\\\\*\\\\*\"))\n((headline item: (item) @markup.heading.2) @markup.heading.marker\n (#match? @markup.heading.marker \"^\\\\*\\\\*\"))\n((headline item: (item) @markup.heading.1) @markup.heading.marker\n (#match? @markup.heading.marker \"^\\\\*\"))\n"
  },
  {
    "path": "runtime/queries/bibtex/highlights.scm",
    "content": "[\n  (string_type)\n  (preamble_type)\n  (entry_type)\n] @keyword\n\n[\n  (junk)\n  (comment)\n] @comment\n\n[\n  \"=\"\n  \"#\"\n] @operator\n\n(command) @function.builtin\n\n(number) @constant.numeric\n\n(field\n  name: (identifier) @variable.builtin)\n\n(token\n  (identifier) @variable.parameter)\n\n[\n  (brace_word)\n  (quote_word)\n] @string\n\n[\n  (key_brace)\n  (key_paren)\n] @attribute\n\n(string\n  name: (identifier) @constant)\n\n[\n  \"{\"\n  \"}\"\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n\",\" @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/bicep/highlights.scm",
    "content": "; Includes\n[\n  \"import\"\n  \"provider\"\n  \"with\"\n  \"as\"\n  \"from\"\n] @keyword.control.import\n\n; Namespaces\n(module_declaration\n  (identifier) @namespace)\n\n; Builtins\n(primitive_type) @type.builtin\n\n((member_expression\n  object: (identifier) @type.builtin)\n  (#eq? @type.builtin \"sys\"))\n\n; Functions\n(call_expression\n  function: (identifier) @function)\n\n(user_defined_function\n  name: (identifier) @function)\n\n; Properties\n(object_property\n  (identifier) @function.method\n  \":\" @punctuation.delimiter\n  (_))\n\n(object_property\n  (compatible_identifier) @function.method\n  \":\" @punctuation.delimiter\n  (_))\n\n(property_identifier) @function.method\n\n; Attributes\n(decorator\n  \"@\" @attribute)\n\n(decorator\n  (call_expression\n    (identifier) @attribute))\n\n(decorator\n  (call_expression\n    (member_expression\n      object: (identifier) @attribute\n      property: (property_identifier) @attribute)))\n\n; Types\n(type_declaration\n  (identifier) @type)\n\n(type_declaration\n  (identifier)\n  \"=\"\n  (identifier) @type)\n\n(type\n  (identifier) @type)\n\n(resource_declaration\n  (identifier) @type)\n\n(resource_expression\n  (identifier) @type)\n\n; Parameters\n(parameter_declaration\n  (identifier) @variable.parameter\n  (_))\n\n(call_expression\n  function: (_)\n  (arguments\n    (identifier) @variable.parameter))\n\n(call_expression\n  function: (_)\n  (arguments\n    (member_expression\n      object: (identifier) @variable.parameter)))\n\n(parameter\n  .\n  (identifier) @variable.parameter)\n\n; Variables\n(variable_declaration\n  (identifier) @variable\n  (_))\n\n(metadata_declaration\n  (identifier) @variable\n  (_))\n\n(output_declaration\n  (identifier) @variable\n  (_))\n\n(object_property\n  (_)\n  \":\"\n  (identifier) @variable)\n\n(for_statement\n  \"for\"\n  (for_loop_parameters\n    (loop_variable) @variable\n    (loop_enumerator) @variable))\n\n; Conditionals\n\"if\" @keyword.conditional\n\n(ternary_expression\n  \"?\" @keyword.control.conditional\n  \":\" @keyword.control.conditional)\n\n; Loops\n(for_statement\n  \"for\" @keyword.control.repeat\n  \"in\"\n  \":\" @punctuation.delimiter)\n\n; Keywords\n[\n  \"module\"\n  \"metadata\"\n  \"output\"\n  \"param\"\n  \"resource\"\n  \"existing\"\n  \"targetScope\"\n  \"type\"\n  \"var\"\n  \"using\"\n  \"test\"\n] @keyword\n\n\"func\" @keyword.function\n\n\"assert\" @keyword.control.exception\n\n; Operators\n[\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"||\"\n  \"&&\"\n  \"|\"\n  \"==\"\n  \"!=\"\n  \"=~\"\n  \"!~\"\n  \">\"\n  \">=\"\n  \"<=\"\n  \"<\"\n  \"??\"\n  \"=\"\n  \"!\"\n  \".?\"\n] @operator\n\n(subscript_expression\n  \"?\" @operator)\n\n(nullable_type\n  \"?\" @operator)\n\n\"in\" @keyword.operator\n\n; Literals\n(string) @string\n\n(escape_sequence) @constant.character\n\n(number) @constant.number\n\n(boolean) @constant.builtin.boolean\n\n(null) @constant.builtin\n\n; Misc\n(compatible_identifier\n  \"?\" @punctuation.special)\n\n(nullable_return_type) @punctuation.special\n\n[\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n[\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n[\n  \".\"\n  \":\"\n  \"::\"\n  \"=>\"\n] @punctuation.delimiter\n\n; Interpolation\n(interpolation\n  \"${\" @punctuation.special\n  \"}\" @punctuation.special)\n\n(interpolation\n  (identifier) @variable)\n\n; Comments\n[\n  (comment)\n  (diagnostic_comment)\n] @comment\n"
  },
  {
    "path": "runtime/queries/bitbake/highlights.scm",
    "content": "\n; variables\n(variable_assignment (identifier) @variable.other.member)\n(variable_assignment (concatenation (identifier) @variable.other.member))\n(unset_statement (identifier) @variable.other.member)\n(export_statement (identifier) @variable.other.member)\n(variable_expansion (identifier) @variable.other.member)\n(python_function_definition (parameters (python_identifier) @variable.other.member))\n\n(variable_assignment (override) @keyword.storage.modifier)\n(overrides_statement (identifier) @keyword.storage.modifier)\n(flag) @keyword.storage.modifier\n\n[\n  \"=\"\n  \"?=\"\n  \"??=\"\n  \":=\"\n  \"=+\"\n  \"+=\"\n  \".=\"\n  \"=.\"\n\n] @operator\n\n[ \"(\" \")\" \"{\" \"}\" \"[\" \"]\" ] @punctuation.bracket\n(variable_expansion [ \"${\" \"}\" ] @punctuation.special)\n\n[\n  \"noexec\"\n  \"INHERIT\"\n  \"OVERRIDES\"\n  \"$BB_ENV_PASSTHROUGH\"\n  \"$BB_ENV_PASSTHROUGH_ADDITIONS\"\n] @variable.builtin\n\n; functions\n\n(python_function_definition (python_identifier) @function)\n(anonymous_python_function (identifier) @function)\n(function_definition (identifier) @function)\n(export_functions_statement (identifier) @function)\n(addtask_statement (identifier) @function)\n(deltask_statement (identifier) @function)\n(addhandler_statement (identifier) @function)\n(function_definition (override) @keyword.storage.modifier)\n\n[\n  \"addtask\"\n  \"deltask\"\n  \"addhandler\"\n  \"unset\"\n  \"EXPORT_FUNCTIONS\"\n  \"python\"\n  \"def\"\n] @keyword.function\n\n[\n  \"append\"\n  \"prepend\"\n  \"remove\"\n\n  \"before\"\n  \"after\"\n] @keyword.operator\n\n; imports\n\n[\n  \"inherit\"\n  \"include\"\n  \"require\"\n  \"export\"\n  \"import\"\n] @keyword.control.import\n\n(inherit_path) @namespace\n(include_path) @namespace\n\n\n(string) @string\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/bitbake/injections.scm",
    "content": "((python_function_definition) @injection.content\n  (#set! injection.language \"python\")\n  (#set! injection.include-children))\n\n((anonymous_python_function (block) @injection.content)\n  (#set! injection.language \"python\")\n  (#set! injection.include-children))\n\n((inline_python) @injection.content\n  (#set! injection.language \"python\")\n  (#set! injection.include-children))\n\n((function_definition) @injection.content\n  (#set! injection.language \"bash\")\n  (#set! injection.include-children))\n\n((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/blade/folds.scm",
    "content": "; inherits: html\n\n((directive_start) @start\n    (directive_end) @end.after\n    (#set! role block))\n\n((bracket_start) @start\n    (bracket_end) @end\n    (#set! role block))\n"
  },
  {
    "path": "runtime/queries/blade/highlights.scm",
    "content": "; inherits: html\n\n(directive) @keyword.directive\n(directive_start) @keyword.directive\n(directive_end) @keyword.directive\n(comment) @comment\n\n; merged with blade punctuation\n[\n  \"{{\"\n  \"}}\"\n  \"{!!\"\n  \"!!}\"\n  \"(\"\n  \")\"\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/blade/injections.scm",
    "content": "; inherits: html\n\n; tree-sitter-comment injection\n; if available\n((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((php_only) @injection.content\n    (#set! injection.language \"php-only\"))\n\n((parameter) @injection.content\n    (#set! injection.include-children) ; You may need this, depending on your editor e.g Helix\n    (#set! injection.language \"php-only\"))\n\n; ; Livewire attributes\n(attribute\n  (attribute_name) @_attr\n    (#any-of? @_attr\n      \"wire:click\"\n      \"wire:submit\"\n      \"wire:model\"\n      \"wire:loading\"\n      \"wire:navigate\"\n      \"wire:current\"\n      \"wire:cloak\"\n      \"wire:dirty\"\n      \"wire:confirm\"\n      \"wire:transition\"\n      \"wire:init\"\n      \"wire:poll\"\n      \"wire:offline\"\n      \"wire:ignore\"\n      \"wire:replace\"\n      \"wire:show\"\n      \"wire:stream\"\n      \"wire:text\"\n    )\n  (quoted_attribute_value\n    (attribute_value) @injection.content)\n  (#set! injection.language \"javascript\"))\n\n; ; See #33\n; ; AlpineJS attributes\n(attribute\n  (attribute_name) @_attr\n    (#match? @_attr \"^x-[a-z]+\")\n  (quoted_attribute_value\n    (attribute_value) @injection.content)\n  (#set! injection.language \"javascript\"))\n\n; ; Apline Events\n(attribute\n  (attribute_name) @_attr\n    (#match? @_attr \"^@[a-z]+\")\n  (quoted_attribute_value\n    (attribute_value) @injection.content)\n  (#set! injection.language \"javascript\"))\n\n; ; normal HTML element alpine attributes\n(element\n  (_\n    (tag_name) @_tag\n      (#match? @_tag \"[^x][^-]\")\n    (attribute\n      (attribute_name) @_attr\n        (#match? @_attr \"^:[a-z]+\")\n      (quoted_attribute_value\n        (attribute_value) @injection.content)\n      (#set! injection.combined)\n      (#set! injection.language \"javascript\"))))\n\n; ; ; Blade escaped JS attributes\n; ; <x-foo ::bar=\"baz\" />\n(element\n  (_\n    (tag_name) @_tag\n      (#match? @_tag \"^x-[a-z]+\")\n    (attribute\n      (attribute_name) @_attr\n        (#match? @_attr \"^::[a-z]+\")\n      (quoted_attribute_value\n        (attribute_value) @injection.content)\n      (#set! injection.language \"javascript\"))))\n\n\n; ; ; Blade escaped JS attributes\n; ; <htmlTag :class=\"baz\" />\n(element\n  (_\n    (attribute_name) @_attr\n      (#match? @_attr \"^:[a-z]+\")\n    (quoted_attribute_value\n      (attribute_value) @injection.content)\n    (#set! injection.language \"javascript\")))\n\n\n; Blade PHP attributes\n(element\n  (_\n    (tag_name) @_tag\n      (#match? @_tag \"^x-[a-z]+\")\n    (attribute\n      (attribute_name) @_attr\n        (#match? @_attr \"^:[a-z]+\")\n      (quoted_attribute_value\n        (attribute_value) @injection.content)\n      (#set! injection.language \"php-only\"))))\n\n"
  },
  {
    "path": "runtime/queries/blade/rainbows.scm",
    "content": "; inherits: html\n"
  },
  {
    "path": "runtime/queries/blade/textobjects.scm",
    "content": "; inherits: html\n"
  },
  {
    "path": "runtime/queries/blueprint/highlights.scm",
    "content": "(object_id) @attribute\n\n(string) @string\n(escape_sequence) @constant.character.escape\n\n(comment) @comment\n\n(constant) @constant.builtin\n(boolean) @constant.builtin.boolean\n\n(template) @keyword\n\n(using) @keyword.control.import\n\n(decorator) @attribute\n\n(property_definition (property_name) @variable.other.member)\n(property_definition\n  (property_binding\n    \"bind\" @keyword\n    (property_name) @variable.other.member\n    [\"no-sync-create\" \"bidirectional\" \"inverted\"]* @keyword))\n\n(object) @type\n\n(signal_binding (signal_name) @function.builtin)\n(signal_binding (function (identifier)) @function)\n(signal_binding \"swapped\" @keyword)\n\n(styles_list \"styles\" @function.macro)\n(layout_definition \"layout\" @function.macro)\n\n(gettext_string \"_\" @function.builtin)\n\n(menu_definition \"menu\" @keyword)\n(menu_section \"section\" @keyword)\n(menu_item \"item\" @function.macro)\n\n(condition \"condition\" @keyword)\n\n(template_definition (template_name_qualifier) @keyword.storage.type)\n\n(import_statement (gobject_library) @namespace)\n\n(import_statement (version_number) @constant.numeric.float)\n\n(float) @constant.numeric.float\n(number) @constant.numeric\n\n[\n  \";\"\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/c/highlights.scm",
    "content": "\n(identifier) @variable\n\n((identifier) @constant\n  (#match? @constant \"^[A-Z][A-Z\\\\d_]*$\"))\n\n\"sizeof\" @keyword\n\n[\n  \"enum\"\n  \"struct\"\n  \"typedef\"\n  \"union\"\n] @keyword.storage.type\n\n[\n  (type_qualifier)\n  (storage_class_specifier)\n] @keyword.storage.modifier\n\n[\n  \"goto\"\n  \"break\"\n  \"continue\"\n] @keyword.control\n\n[\n  \"do\"\n  \"for\"\n  \"while\"\n] @keyword.control.repeat\n\n[\n  \"if\"\n  \"else\"\n  \"switch\"\n  \"case\"\n  \"default\"\n] @keyword.control.conditional\n\n\"return\" @keyword.control.return\n\n[\n  \"defined\"\n  \"#define\"\n  \"#elif\"\n  \"#else\"\n  \"#endif\"\n  \"#if\"\n  \"#ifdef\"\n  \"#ifndef\"\n  \"#include\"\n  (preproc_directive)\n] @keyword.directive\n\n\"...\" @punctuation\n\n[\",\" \".\" \":\" \"::\" \";\" \"->\"] @punctuation.delimiter\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\" \"[[\" \"]]\"] @punctuation.bracket\n\n[\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"++\"\n  \"--\"\n  \"%\"\n  \"==\"\n  \"!=\"\n  \">\"\n  \"<\"\n  \">=\"\n  \"<=\"\n  \"&&\"\n  \"||\"\n  \"!\"\n  \"&\"\n  \"|\"\n  \"^\"\n  \"~\"\n  \"<<\"\n  \">>\"\n  \"=\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"<<=\"\n  \">>=\"\n  \"&=\"\n  \"^=\"\n  \"|=\"\n  \"?\"\n] @operator\n\n(conditional_expression \":\" @operator) ; After punctuation\n\n(pointer_declarator \"*\" @type.builtin) ; After Operators\n(abstract_pointer_declarator \"*\" @type.builtin)\n\n\n[(true) (false)] @constant.builtin.boolean\n\n(enumerator name: (identifier) @type.enum.variant)\n\n(string_literal) @string\n(system_lib_string) @string\n\n(null) @constant.builtin\n(number_literal) @constant.numeric\n(char_literal) @constant.character\n(escape_sequence) @constant.character.escape\n\n(field_identifier) @variable.other.member\n(statement_identifier) @label\n(type_identifier) @type\n(primitive_type) @type.builtin\n(sized_type_specifier) @type.builtin\n\n(call_expression\n  function: (identifier) @function)\n(call_expression\n  function: (field_expression\n    field: (field_identifier) @function))\n(call_expression (argument_list (identifier) @variable))\n(function_declarator\n  declarator: [(identifier) (field_identifier)] @function)\n\n; Up to 6 layers of declarators\n(parameter_declaration\n  declarator: (identifier) @variable.parameter)\n(parameter_declaration\n  (_\n    (identifier) @variable.parameter))\n(parameter_declaration\n  (_\n    (_\n      (identifier) @variable.parameter)))\n(parameter_declaration\n  (_\n    (_\n      (_\n        (identifier) @variable.parameter))))\n(parameter_declaration\n  (_\n    (_\n      (_\n        (_\n          (identifier) @variable.parameter)))))\n(parameter_declaration\n  (_\n    (_\n      (_\n        (_\n          (_\n            (identifier) @variable.parameter))))))\n\n(preproc_function_def\n  name: (identifier) @function.special)\n\n(attribute\n  name: (identifier) @attribute)\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/c/indents.scm",
    "content": "[\n  (compound_statement)\n  (declaration_list)\n  (field_declaration_list)\n  (enumerator_list)\n  (parameter_list)\n  (init_declarator)\n  (expression_statement)\n] @indent\n\n[\n  \"case\"\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n\n(if_statement\n  consequence: (_) @indent\n  (#not-kind-eq? @indent \"compound_statement\")\n  (#set! \"scope\" \"all\"))\n(while_statement\n  body: (_) @indent\n  (#not-kind-eq? @indent \"compound_statement\")\n  (#set! \"scope\" \"all\"))\n(do_statement\n  body: (_) @indent\n  (#not-kind-eq? @indent \"compound_statement\")\n  (#set! \"scope\" \"all\"))\n(for_statement\n  \")\"\n  (_) @indent\n  (#not-kind-eq? @indent \"compound_statement\")\n  (#set! \"scope\" \"all\"))\n\n(parameter_list\n  . (parameter_declaration) @anchor\n  (#set! \"scope\" \"tail\")) @align\n(argument_list\n  . (_) @anchor\n  (#set! \"scope\" \"tail\")) @align\n; These are a bit opinionated since some people just indent binary/ternary expressions spanning multiple lines.\n; Since they are only triggered when a newline is inserted into an already complete binary/ternary expression,\n; this should happen rarely, so it is not a big deal either way.\n; Additionally, adding these queries has the advantage of preventing such continuation lines from being used\n; as the baseline when the `hybrid` indent heuristic is used (which is desirable since their indentation is so inconsistent). \n(binary_expression\n  (#set! \"scope\" \"tail\")) @anchor @align\n(conditional_expression\n  \"?\" @anchor\n  (#set! \"scope\" \"tail\")) @align\n"
  },
  {
    "path": "runtime/queries/c/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((preproc_arg) @injection.content\n (#set! injection.language \"c\")\n (#set! injection.include-children))\n"
  },
  {
    "path": "runtime/queries/c/locals.scm",
    "content": ";; Scopes\n(function_definition) @local.scope\n(declaration) @local.scope\n\n;; Definitions\n\n; Parameters\n; Up to 6 layers of declarators\n(parameter_declaration\n  (identifier) @local.definition.variable.parameter)\n(parameter_declaration\n  (_\n    (identifier) @local.definition.variable.parameter))\n(parameter_declaration\n  (_\n    (_\n      (identifier) @local.definition.variable.parameter)))\n(parameter_declaration\n  (_\n    (_\n      (_\n        (identifier) @local.definition.variable.parameter))))\n(parameter_declaration\n  (_\n    (_\n      (_\n        (_\n          (identifier) @local.definition.variable.parameter)))))\n(parameter_declaration\n  (_\n    (_\n      (_\n        (_\n          (_\n            (identifier) @local.definition.variable.parameter))))))\n\n;; References\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/c/rainbows.scm",
    "content": "[\n  (preproc_params)\n  (preproc_defined)\n  (argument_list)\n  (attribute_specifier)\n  (ms_declspec_modifier)\n  (declaration_list)\n  (parenthesized_declarator)\n  (parenthesized_expression)\n  (abstract_parenthesized_declarator)\n  (array_declarator)\n  (compound_statement)\n  (initializer_list)\n  (compound_literal_expression)\n  (enumerator_list)\n  (field_declaration_list)\n  (parameter_list)\n  (for_statement)\n  (macro_type_specifier)\n  (subscript_expression)\n  (subscript_designator)\n  (cast_expression)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"{\" \"}\"\n  \"[\" \"]\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/c/tags.scm",
    "content": "(function_declarator\n  declarator: [(identifier) (field_identifier)] @definition.function)\n\n(preproc_function_def name: (identifier) @definition.function)\n\n(preproc_def name: (identifier) @definition.constant)\n\n(type_definition\n  declarator: (type_identifier) @definition.type)\n\n(struct_specifier\n  name: (type_identifier) @definition.struct)\n\n(enum_specifier\n  name: (type_identifier) @definition.enum)\n"
  },
  {
    "path": "runtime/queries/c/textobjects.scm",
    "content": "(function_definition\n  body: (_) @function.inside) @function.around\n\n(struct_specifier\n  body: (_) @class.inside) @class.around\n\n(enum_specifier\n  body: (_) @class.inside) @class.around\n\n(union_specifier\n  body: (_) @class.inside) @class.around\n\n(parameter_list \n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(argument_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(enumerator\n  (_) @entry.inside) @entry.around\n\n(initializer_list\n  (_) @entry.around)\n"
  },
  {
    "path": "runtime/queries/c-sharp/highlights.scm",
    "content": "(identifier) @variable\n\n;; Methods\n\n(method_declaration name: (identifier) @function)\n(local_function_statement name: (identifier) @function)\n\n;; Types\n\n(interface_declaration name: (identifier) @type)\n(class_declaration name: (identifier) @type)\n(enum_declaration name: (identifier) @type)\n(struct_declaration (identifier) @type)\n(record_declaration (identifier) @type)\n(namespace_declaration name: (identifier) @namespace)\n\n(generic_name (identifier) @type)\n(type_parameter (identifier) @type.parameter)\n(parameter type: (identifier) @type)\n(type_argument_list (identifier) @type)\n(as_expression right: (identifier) @type)\n(is_expression right: (identifier) @type)\n\n(constructor_declaration name: (identifier) @constructor)\n(destructor_declaration name: (identifier) @constructor)\n\n(_ type: (identifier) @type)\n\n(base_list (identifier) @type)\n\n(predefined_type) @type.builtin\n\n;; Enum\n(enum_member_declaration (identifier) @type.enum.variant)\n\n;; Literals\n\n(real_literal) @constant.numeric.float\n(integer_literal) @constant.numeric.integer\n(character_literal) @constant.character\n\n[\n  (string_literal)\n  (raw_string_literal)\n  (verbatim_string_literal)\n  (interpolated_string_expression)\n  (interpolation_start)\n  (interpolation_quote)\n ] @string\n\n(escape_sequence) @constant.character.escape\n\n(boolean_literal) @constant.builtin.boolean\n(null_literal) @constant.builtin\n\n;; Comments\n\n(comment) @comment\n\n;; Tokens\n\n[\n  \";\"\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"--\"\n  \"-\"\n  \"-=\"\n  \"&\"\n  \"&=\"\n  \"&&\"\n  \"+\"\n  \"++\"\n  \"+=\"\n  \"<\"\n  \"<=\"\n  \"<<\"\n  \"<<=\"\n  \"=\"\n  \"==\"\n  \"!\"\n  \"!=\"\n  \"=>\"\n  \">\"\n  \">=\"\n  \">>\"\n  \">>=\"\n  \">>>\"\n  \">>>=\"\n  \"|\"\n  \"|=\"\n  \"||\"\n  \"?\"\n  \"??\"\n  \"??=\"\n  \"^\"\n  \"^=\"\n  \"~\"\n  \"*\"\n  \"*=\"\n  \"/\"\n  \"/=\"\n  \"%\"\n  \"%=\"\n  \":\"\n] @operator\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  (interpolation_brace)\n]  @punctuation.bracket\n\n;; Keywords\n\n[\n  (modifier)\n  \"this\"\n  (implicit_type)\n] @keyword\n\n[\n  \"add\"\n  \"alias\"\n  \"as\"\n  \"base\"\n  \"break\"\n  \"case\"\n  \"catch\"\n  \"checked\"\n  \"class\"\n  \"continue\"\n  \"default\"\n  \"delegate\"\n  \"do\"\n  \"else\"\n  \"enum\"\n  \"event\"\n  \"explicit\"\n  \"extern\"\n  \"finally\"\n  \"for\"\n  \"foreach\"\n  \"global\"\n  \"goto\"\n  \"if\"\n  \"implicit\"\n  \"interface\"\n  \"is\"\n  \"lock\"\n  \"namespace\"\n  \"notnull\"\n  \"operator\"\n  \"params\"\n  \"return\"\n  \"remove\"\n  \"sizeof\"\n  \"stackalloc\"\n  \"static\"\n  \"struct\"\n  \"switch\"\n  \"throw\"\n  \"try\"\n  \"typeof\"\n  \"unchecked\"\n  \"using\"\n  \"while\"\n  \"new\"\n  \"await\"\n  \"in\"\n  \"yield\"\n  \"get\"\n  \"set\"\n  \"when\"\n  \"out\"\n  \"ref\"\n  \"from\"\n  \"where\"\n  \"select\"\n  \"record\"\n  \"init\"\n  \"with\"\n  \"let\"\n] @keyword\n\n;; Attribute\n\n(attribute name: (identifier) @attribute)\n\n;; Parameters\n\n(parameter\n  name: (identifier) @variable.parameter)\n\n;; Type constraints\n\n(type_parameter_constraints_clause (identifier) @type.parameter)\n\n;; Method calls\n\n(invocation_expression (member_access_expression name: (identifier) @function))\n"
  },
  {
    "path": "runtime/queries/c-sharp/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/c-sharp/tags.scm",
    "content": "(class_declaration name: (identifier) @name) @definition.class\n\n(class_declaration (base_list (_) @name)) @reference.class\n\n(interface_declaration name: (identifier) @name) @definition.interface\n\n(interface_declaration (base_list (_) @name)) @reference.interface\n\n(method_declaration name: (identifier) @name) @definition.method\n\n(object_creation_expression type: (identifier) @name) @reference.class\n\n(type_parameter_constraints_clause (identifier) @name) @reference.class\n\n(type_parameter_constraint (type type: (identifier) @name)) @reference.class\n\n(variable_declaration type: (identifier) @name) @reference.class\n\n(invocation_expression function: (member_access_expression name: (identifier) @name)) @reference.send\n\n(namespace_declaration name: (identifier) @name) @definition.module\n"
  },
  {
    "path": "runtime/queries/c-sharp/textobjects.scm",
    "content": "[\n  (class_declaration body: (_) @class.inside)\n  (struct_declaration body: (_) @class.inside)\n  (interface_declaration body: (_) @class.inside)\n  (enum_declaration body: (_) @class.inside)\n  (delegate_declaration)\n  (record_declaration body: (_) @class.inside)\n] @class.around\n\n(constructor_declaration body: (_) @function.inside) @function.around\n\n(destructor_declaration body: (_) @function.inside) @function.around\n\n(method_declaration body: (_) @function.inside) @function.around\n\n(property_declaration (_) @function.inside) @function.around\n\n(parameter (_) @parameter.inside) @parameter.around\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/c3/highlights.scm",
    "content": "; Punctuation\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"[<\"\n  \">]\"\n] @punctuation.bracket\n\n[\n  \";\"\n  \",\"\n  \":\"\n  \"::\"\n] @punctuation.delimiter\n\n; Constant\n(const_ident) @constant\n\n[\n  \"true\"\n  \"false\"\n] @constant.builtin.boolean\n\n\"null\" @constant.builtin\n\n; Variable\n[\n  (ident)\n  (ct_ident)\n  (hash_ident)\n] @variable\n\n; 1) Member\n(field_expr\n  field: (access_ident\n    (ident) @variable.other.member))\n\n(struct_member_declaration\n  (ident) @variable.other.member)\n\n(struct_member_declaration\n  (identifier_list\n    (ident) @variable.other.member))\n\n(bitstruct_member_declaration\n  (ident) @variable.other.member)\n\n(initializer_list\n  (initializer_element\n    (param_path\n      (param_path_element\n        (access_ident\n          (ident) @variable.other.member)))))\n\n; 2) Parameter\n(param\n  name: (_) @variable.parameter)\n\n(trailing_block_param\n  (at_ident) @variable.parameter)\n\n(call_arg_list\n  (call_arg\n    name: (_) @variable.parameter))\n\n(enum_param\n  (ident) @variable.parameter)\n\n; Keyword (from `c3c --list-keywords`)\n[\n  \"alias\"\n  \"asm\"\n  \"attrdef\"\n  \"catch\"\n  \"defer\"\n  \"try\"\n  \"var\"\n] @keyword\n\n[\n  \"$alignof\"\n  \"$assert\"\n  \"$assignable\"\n  \"$case\"\n  \"$default\"\n  \"$defined\"\n  \"$echo\"\n  \"$else\"\n  \"$embed\"\n  \"$endfor\"\n  \"$endforeach\"\n  \"$endif\"\n  \"$endswitch\"\n  \"$eval\"\n  \"$evaltype\"\n  \"$error\"\n  \"$exec\"\n  \"$extnameof\"\n  \"$feature\"\n  \"$for\"\n  \"$foreach\"\n  \"$if\"\n  \"$include\"\n  \"$is_const\"\n  \"$kindof\"\n  \"$nameof\"\n  \"$offsetof\"\n  \"$qnameof\"\n  \"$sizeof\"\n  \"$stringify\"\n  \"$switch\"\n  \"$typefrom\"\n  \"$typeof\"\n  \"$vacount\"\n  \"$vatype\"\n  \"$vaconst\"\n  \"$vaarg\"\n  \"$vaexpr\"\n  \"$vasplat\"\n] @keyword.directive\n\n\"assert\" @keyword.debug\n\n\"fn\" @keyword.function\n\n\"macro\" @keyword.function\n\n\"return\" @keyword.control.return\n\n[\n  \"import\"\n  \"module\"\n] @keyword.control.import\n\n[\n  \"bitstruct\"\n  \"enum\"\n  \"faultdef\"\n  \"interface\"\n  \"struct\"\n  \"typedef\"\n  \"union\"\n] @keyword.storage.type\n\n[\n  \"case\"\n  \"default\"\n  \"else\"\n  \"if\"\n  \"nextcase\"\n  \"switch\"\n] @keyword.control.conditional\n\n[\n  \"break\"\n  \"continue\"\n  \"do\"\n  \"for\"\n  \"foreach\"\n  \"foreach_r\"\n  \"while\"\n] @keyword.control.repeat\n\n[\n  \"const\"\n  \"extern\"\n  \"inline\"\n  \"static\"\n  \"tlocal\"\n] @keyword.storage.modifier\n\n; Operator (from `c3c --list-operators`)\n[\n  \"&\"\n  \"!\"\n  \"~\"\n  \"|\"\n  \"^\"\n  \"=\"\n  \">\"\n  \"/\"\n  \".\"\n  \"<\"\n  \"-\"\n  \"%\"\n  \"+\"\n  \"?\"\n  \"*\"\n  \"&&\"\n  \"!!\"\n  \"&=\"\n  \"|=\"\n  \"^=\"\n  \"/=\"\n  \"..\"\n  \"?:\"\n  \"==\"\n  \">=\"\n  \"=>\"\n  \"<=\"\n  \"-=\"\n  \"--\"\n  \"%=\"\n  \"*=\"\n  \"!=\"\n  \"||\"\n  \"+=\"\n  \"++\"\n  \"??\"\n  \"<<\"\n  \">>\"\n  \"...\"\n  \"<<=\"\n  \">>=\"\n  \"&&&\"\n  \"+++\"\n  \"|||\"\n  \"???\"\n  \"+++=\"\n] @operator\n\n(range_expr\n  \":\" @operator)\n\n(foreach_cond\n  \":\" @operator)\n\n(ct_foreach_cond\n  \":\" @operator)\n\n(ternary_expr\n  [\n    \"?\"\n    \"???\"\n    \":\"\n  ] @keyword.control.conditional.ternary)\n\n(elvis_orelse_expr\n  [\n    \"?:\"\n    \"??\"\n  ] @keyword.control.conditional.ternary)\n\n; Literal\n(integer_literal) @constant.numeric.integer\n\n(real_literal) @constant.numeric.float\n\n(char_literal) @constant.character\n\n(bytes_literal) @constant.numeric\n\n; String\n(string_literal) @string\n\n(raw_string_literal) @string\n\n; Escape Sequence\n(escape_sequence) @constant.character.escape\n\n; Builtin (constants)\n(builtin_const) @constant.builtin\n\n; Type Property (from `c3c --list-type-properties`)\n(type_access_expr\n  (access_ident\n    (ident) @variable.builtin\n    (#any-of? @variable.builtin\n      \"alignof\" \"associated\" \"elements\" \"extnameof\" \"from_ordinal\" \"get\" \"inf\" \"is_eq\" \"is_ordered\"\n      \"is_substruct\" \"len\" \"lookup\" \"lookup_field\" \"max\" \"membersof\" \"methodsof\" \"min\" \"nan\" \"inner\"\n      \"kindof\" \"names\" \"nameof\" \"params\" \"paramsof\" \"parentof\" \"qnameof\" \"returns\" \"sizeof\" \"set\"\n      \"tagof\" \"has_tagof\" \"values\" \"typeid\")))\n\n; Label\n(label\n  (const_ident) @label)\n\n(label_target\n  (const_ident) @label)\n\n; Module\n(module_resolution\n  (ident) @namespace)\n\n(module_declaration\n  (path_ident\n    (ident) @namespace))\n\n(import_path\n  (path_ident\n    (ident) @namespace))\n\n; Attribute\n(attribute\n  name: (at_ident) @attribute)\n\n(at_type_ident) @attribute\n\n(call_inline_attributes\n  (at_ident) @attribute)\n\n(type_suffix\n  (at_ident) @attribute)\n\n(asm_block_stmt\n  (at_ident) @attribute)\n\n; Type\n[\n  (type_ident)\n  (ct_type_ident)\n] @type\n\n(base_type_name) @type.builtin\n\n; Function Definition\n(func_header\n  name: (_) @function)\n\n(func_header\n  method_type: (_)\n  name: (_) @function.method)\n\n(macro_header\n  name: (_) @function)\n\n(macro_header\n  method_type: (_)\n  name: (_) @function.method)\n\n; Function Call\n(call_expr\n  function: (ident_expr\n    [\n      (ident)\n      (at_ident)\n    ] @function))\n\n(call_expr\n  function: (trailing_generic_expr\n    argument: (ident_expr\n      [\n        (ident)\n        (at_ident)\n      ] @function)))\n\n; Method call\n(call_expr\n  function: (field_expr\n    field: (access_ident\n      [\n        (ident)\n        (at_ident)\n      ] @function)))\n\n; Method on type\n(call_expr\n  function: (type_access_expr\n    field: (access_ident\n      [\n        (ident)\n        (at_ident)\n      ] @function)))\n\n; Builtin call\n(call_expr\n  function: (builtin) @function.builtin)\n\n; Asm\n(asm_instr\n  [\n    (ident)\n    \"int\"\n  ] @function.builtin)\n\n(asm_expr\n  [\n    (ct_ident)\n    (ct_const_ident)\n  ] @variable.builtin)\n\n; Comment\n(line_comment) @comment.line\n(block_comment) @comment.block\n(doc_comment) @comment.block.documentation\n\n(doc_comment_contract\n  name: (_) @attribute)\n\n(doc_comment_contract\n  parameter: [\n    (ident)\n    (ct_ident)\n    (hash_ident)\n  ] @variable.parameter)\n\n(doc_comment_contract\n  [\n    \":\"\n    \"?\"\n  ] @comment.block.documentation)\n\n(doc_comment_contract\n  description: (string_expr\n    [\n      (string_literal)\n      (raw_string_literal)\n    ] @comment.block.documentation))\n"
  },
  {
    "path": "runtime/queries/c3/injections.scm",
    "content": "([\n  (line_comment)\n  (block_comment)\n] @injection.content\n  (#set! injection.language \"comment\"))"
  },
  {
    "path": "runtime/queries/caddyfile/highlights.scm",
    "content": "(comment) @comment\n[\n  (environment_variable)\n  (placeholder)\n] @constant\n\n[\n  (network_address)\n  (ip_address_or_cidr)\n] @string.special.url\n\n(path) @string.special.path\n\n[\n  (snippet_name)\n  (named_route_identifier)\n  (site_address)\n] @keyword\n\n(directive (directive_name) @variable.other.member)\n\n; declaration of a named matcher\n(named_matcher (matcher_identifier (matcher_name)) @function.macro)\n\n; reference to a named matcher\n(matcher (matcher_identifier (matcher_name)) @function.macro)\n\n; directive within a named matcher declaration\n(matcher_directive (matcher_directive_name) @function.method)\n\n; any other matcher (wildcard and path)\n(matcher) @function.macro\n\n[\n  (interpreted_string_literal)\n  (raw_string_literal)\n  (heredoc)\n  (cel_expression)\n] @string\n(escape_sequence) @constant.character.escape\n\n[\n  (duration_literal)\n  (int_literal)\n] @constant.numeric\n\n[\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n(global_options\n  (directive) @keyword.directive)\n\n(directive\n  name: (directive_name)\n  (argument) @type)\n\n; matches directive arguments that looks like an absolute path\n; e.g.\n; log {\n;     output file /var/log/caddy.log\n; }\n(directive\n  (argument) @string.special.path\n  (#match? @string.special.path \"^/\"))\n\n((argument) @constant.builtin.boolean\n  (#any-of? @constant.builtin.boolean \"on\" \"off\"))\n\n((argument) @type.enum.variant\n  (#any-of? @type.enum.variant \"tcp\" \"udp\" \"ipv4\" \"ipv6\"))\n"
  },
  {
    "path": "runtime/queries/caddyfile/indents.scm",
    "content": "[\n  (block)\n  (matcher_block)\n] @indent\n\n((global_options) @indent)\n\n\"}\" @outdent\n"
  },
  {
    "path": "runtime/queries/caddyfile/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/caddyfile/locals.scm",
    "content": "(block) @local.scope\n\n(named_matcher (matcher_identifier (matcher_name)) @local.definition.function.macro)\n\n(matcher) @local.reference\n"
  },
  {
    "path": "runtime/queries/caddyfile/textobjects.scm",
    "content": "(comment) @comment.inside\n(comment)+ @comment.around\n\n(directive\n  name: (directive_name) @parameter.inside) @parameter.around\n\n(global_options\n  \"{\" (_)* @class.inside \"}\") @class.around\n\n(snippet_definition\n  (block) @class.inside) @class.around\n\n(named_route\n  (block) @class.inside) @class.around\n\n(site_definition (block) @class.inside) @class.around\n"
  },
  {
    "path": "runtime/queries/cairo/highlights.scm",
    "content": "; -------\n; Tree-Sitter doesn't allow overrides in regards to captures,\n; though it is possible to affect the child node of a captured\n; node. Thus, the approach here is to flip the order so that\n; overrides are unnecessary.\n; -------\n\n; -------\n; Types\n; -------\n\n(type_parameters\n  (type_identifier) @type.parameter)\n(constrained_type_parameter\n  left: (type_identifier) @type.parameter)\n\n; ---\n; Primitives\n; ---\n\n(primitive_type) @type.builtin\n(boolean_literal) @constant.builtin.boolean\n(numeric_literal) @constant.numeric.integer\n[\n  (string_literal)\n  (shortstring_literal)\n] @string\n[\n  (line_comment)\n] @comment\n\n; ---\n; Extraneous\n; ---\n\n(enum_variant (identifier) @type.enum.variant)\n\n(field_initializer\n  (field_identifier) @variable.other.member)\n(shorthand_field_initializer\n  (identifier) @variable.other.member)\n(shorthand_field_identifier) @variable.other.member\n\n\n; ---\n; Punctuation\n; ---\n\n[\n  \"::\"\n  \".\"\n  \";\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n(type_arguments\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n(type_parameters\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n(closure_parameters\n  \"|\" @punctuation.bracket)\n\n; ---\n; Variables\n; ---\n\n(let_declaration\n  pattern: [\n    ((identifier) @variable)\n    ((tuple_pattern\n      (identifier) @variable))\n  ])\n  \n; It needs to be anonymous to not conflict with `call_expression` further below. \n(_\n value: (field_expression\n  value: (identifier)? @variable\n  field: (field_identifier) @variable.other.member))\n\n(parameter\n\tpattern: (identifier) @variable.parameter)\n\n(closure_parameters\n\t(identifier) @variable.parameter)\n; -------\n; Keywords\n; -------\n\n(for_expression\n  \"for\" @keyword.control.repeat)\n\n\"in\" @keyword.control\n\n[\n  \"match\"\n  \"if\"\n  \"else\"\n] @keyword.control.conditional\n\n[\n  \"while\"\n  \"loop\"\n] @keyword.control.repeat\n\n[\n  \"break\"\n  \"continue\"\n  \"return\"\n] @keyword.control.return\n\n\"use\" @keyword.control.import\n(mod_item \"mod\" @keyword.control.import !body)\n(use_as_clause \"as\" @keyword.control.import)\n\n\n[\n  (crate)\n  (super)\n  \"as\"\n  \"pub\"\n  \"mod\"\n  (extern)\n  (nopanic)\n\n  \"impl\"\n  \"trait\"\n  \"of\"\n\n  \"default\"\n] @keyword\n\n[\n  \"struct\"\n  \"enum\"\n  \"type\"\n] @keyword.storage.type\n\n\"let\" @keyword.storage\n\"fn\" @keyword.function\n\n(mutable_specifier) @keyword.storage.modifier.mut\n(ref_specifier) @keyword.storage.modifier.ref\n\n(snapshot_type \"@\" @keyword.storage.modifier.ref)\n\n[\n  \"const\"\n  \"ref\"\n] @keyword.storage.modifier\n\n; TODO: variable.mut to highlight mutable identifiers via locals.scm\n\n; -------\n; Constructors\n; -------\n; TODO: this is largely guesswork, remove it once we get actual info from locals.scm or r-a\n\n(struct_expression\n  name: (type_identifier) @constructor)\n\n(tuple_enum_pattern\n  type: [\n    (identifier) @constructor\n    (scoped_identifier\n      name: (identifier) @constructor)\n  ])\n(struct_pattern\n  type: [\n    ((type_identifier) @constructor)\n    (scoped_type_identifier\n      name: (type_identifier) @constructor)\n  ])\n(match_pattern\n  ((identifier) @constructor) (#match? @constructor \"^[A-Z]\"))\n(or_pattern\n  ((identifier) @constructor)\n  ((identifier) @constructor)\n  (#match? @constructor \"^[A-Z]\"))\n\n; -------\n; Guess Other Types\n; -------\n\n((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z\\\\d_]*$\"))\n\n; ---\n; PascalCase identifiers in call_expressions (e.g. `Ok()`)\n; are assumed to be enum constructors.\n; ---\n\n(call_expression\n  function: [\n    ((identifier) @constructor\n      (#match? @constructor \"^[A-Z]\"))\n    (scoped_identifier\n      name: ((identifier) @constructor\n        (#match? @constructor \"^[A-Z]\")))\n  ])\n\n; ---\n; PascalCase identifiers under a path which is also PascalCase\n; are assumed to be constructors if they have methods or fields.\n; ---\n\n(field_expression\n  value: (scoped_identifier\n    path: [\n      (identifier) @type\n      (scoped_identifier\n        name: (identifier) @type)\n    ]\n    name: (identifier) @constructor\n      (#match? @type \"^[A-Z]\")\n      (#match? @constructor \"^[A-Z]\")))\n\n; ---\n; Other PascalCase identifiers are assumed to be structs.\n; ---\n\n((identifier) @type\n  (#match? @type \"^[A-Z]\"))\n\n; -------\n; Functions\n; -------\n\n(call_expression\n  function: [\n    ((identifier) @function)\n    (scoped_identifier\n      name: (identifier) @function)\n    (field_expression\n      field: (field_identifier) @function)\n  ])\n(generic_function\n  function: [\n    ((identifier) @function)\n    (scoped_identifier\n      name: (identifier) @function)\n    (field_expression\n      field: (field_identifier) @function.method)\n  ])\n(function_item\n  (function\n    name: (identifier) @function))\n\n(function_signature_item\n  (function\n    name: (identifier) @function))\n\n(external_function_item\n  (function\n    name: (identifier) @function))\n\n; ---\n; Macros\n; ---\n\n(attribute\n  (identifier) @special\n  arguments: (token_tree (identifier) @type)\n  (#eq? @special \"derive\")\n)\n\n(attribute\n  (identifier) @function.macro)\n(attribute\n  [\n    (identifier) @function.macro\n    (scoped_identifier\n      name: (identifier) @function.macro)\n  ]\n  (token_tree (identifier) @function.macro)?)\n\n(inner_attribute_item) @attribute\n\n(macro_invocation\n  macro: [\n    ((identifier) @function.macro)\n    (scoped_identifier\n      name: (identifier) @function.macro)\n  ]\n  \"!\" @function.macro)\n\n\n; -------\n; Operators\n; -------\n\n[\n  \"*\"\n  \"->\"\n  \"=>\"\n  \"<=\"\n  \"=\"\n  \"==\"\n  \"!\"\n  \"!=\"\n  \"%\"\n  \"%=\"\n  \"@\"\n  \"&&\"\n  \"|\"\n  \"||\"\n  \"^\"\n  \"*\"\n  \"*=\"\n  \"-\"\n  \"-=\"\n  \"+\"\n  \"+=\"\n  \"/\"\n  \"/=\"\n  \">\"\n  \"<\"\n  \">=\"\n  \">>\"\n  \"<<\"\n] @operator\n\n; -------\n; Paths\n; -------\n\n(use_declaration\n  argument: (identifier) @namespace)\n(use_wildcard\n  (identifier) @namespace)\n(mod_item\n  name: (identifier) @namespace)\n(scoped_use_list\n  path: (identifier)? @namespace)\n(use_list\n  (identifier) @namespace)\n(use_as_clause\n  path: (identifier)? @namespace\n  alias: (identifier) @namespace)\n\n; ---\n; Remaining Paths\n; ---\n\n(scoped_identifier\n  path: (identifier)? @namespace\n  name: (identifier) @namespace)\n(scoped_type_identifier\n  path: (identifier) @namespace)\n\n; -------\n; Remaining Identifiers\n; -------\n\n\"?\" @special\n\n(type_identifier) @type\n(identifier) @variable\n(field_identifier) @variable.other.member\n"
  },
  {
    "path": "runtime/queries/cairo/indents.scm",
    "content": "[\n  (use_list)\n  (block)\n  (match_block)\n  (arguments)\n  (parameters)\n  (declaration_list)\n  (field_declaration_list)\n  (field_initializer_list)\n  (struct_pattern)\n  (tuple_pattern)\n  (unit_expression)\n  (enum_variant_list)\n  (call_expression)\n  (binary_expression)\n  (field_expression)\n  (tuple_expression)\n  (array_expression)\n\n  (token_tree)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n\n; Indent the right side of assignments.\n; The #not-same-line? predicate is required to prevent an extra indent for e.g.\n; an else-clause where the previous if-clause starts on the same line as the assignment.\n(assignment_expression\n  .\n  (_) @expr-start\n  right: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(compound_assignment_expr\n  .\n  (_) @expr-start\n  right: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(let_declaration\n  \"let\" @expr-start\n  value: (_) @indent\n  alternative: (_)? @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(let_condition\n  .\n  (_) @expr-start\n  value: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(if_expression\n  .\n  (_) @expr-start\n  condition: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(field_pattern\n  .\n  (_) @expr-start\n  pattern: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n; Indent type aliases that span multiple lines, similar to\n; regular assignment expressions\n(type_item\n  .\n  (_) @expr-start\n  type: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n\n; Some field expressions where the left part is a multiline expression are not\n; indented by cargo fmt.\n; Because this multiline expression might be nested in an arbitrary number of\n; field expressions, this can only be matched using a Regex.\n(field_expression\n  value: (_) @val\n  \".\" @outdent\n  ; Check whether the first line ends with `(`, `{` or `[` (up to whitespace).\n  (#match? @val \"(\\\\A[^\\\\n\\\\r]+(\\\\(|\\\\{|\\\\[)[\\\\t ]*(\\\\n|\\\\r))\")\n)\n; Same as above, but with an additional `call_expression`. This is required since otherwise\n; the arguments of the function call won't be outdented.\n(call_expression\n  function: (field_expression\n    value: (_) @val\n    \".\" @outdent\n    (#match? @val \"(\\\\A[^\\\\n\\\\r]+(\\\\(|\\\\{|\\\\[)[\\\\t ]*(\\\\n|\\\\r))\")\n  )\n  arguments: (_) @outdent\n)\n\n\n; Indent if guards in patterns.\n; Since the tree-sitter grammar doesn't create a node for the if expression,\n; it's not possible to do this correctly in all cases. Indenting the tail of the\n; whole pattern whenever it contains an `if` only fails if the `if` appears after\n; the second line of the pattern (which should only rarely be the case)\n(match_pattern\n  .\n  (_) @expr-start\n  \"if\" @pattern-guard\n  (#not-same-line? @expr-start @pattern-guard)\n) @indent\n\n; Align closure parameters if they span more than one line\n(closure_parameters\n  \"|\"\n  .\n  (_) @anchor\n  (_) @expr-end\n  .\n  (#not-same-line? @anchor @expr-end)\n) @align\n\n(for_expression\n  \"in\" @in\n  .\n  (_) @indent\n  (#not-same-line? @in @indent)\n  (#set! \"scope\" \"all\")\n)  \n"
  },
  {
    "path": "runtime/queries/cairo/injections.scm",
    "content": "([(line_comment)] @injection.content\n (#set! injection.language \"comment\"))\n\n"
  },
  {
    "path": "runtime/queries/cairo/locals.scm",
    "content": "; Scopes\n\n[\n  (function_item)\n  (struct_item)\n  (enum_item)\n  (type_item)\n  (trait_item)\n  (impl_item)\n  (closure_expression)\n  (block)\n] @local.scope\n\n; Definitions\n\n(parameter\n  (identifier) @local.definition.variable.parameter)\n\n(type_parameters\n  (type_identifier) @local.definition.type.parameter)\n(constrained_type_parameter\n  left: (type_identifier) @local.definition.type.parameter)\n\n(closure_parameters (identifier) @local.definition.variable.parameter)\n\n; References\n(identifier) @local.reference\n(type_identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/cairo/textobjects.scm",
    "content": "(function_item\n  body: (_) @function.inside) @function.around\n\n(closure_expression\n  body: (_) @function.inside) @function.around\n\n(struct_item\n  body: (_) @class.inside) @class.around\n\n(enum_item\n  body: (_) @class.inside) @class.around\n\n(trait_item\n  body: (_) @class.inside) @class.around\n\n(impl_item\n  body: (_) @class.inside) @class.around\n\n(parameters \n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(closure_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(field_initializer_list  \n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n[\n  (line_comment)\n] @comment.inside\n\n(line_comment)+ @comment.around\n\n(; #[test]\n (attribute_item\n   (attribute\n     (identifier) @_test_attribute))\n ; allow other attributes like #[should_panic] and comments\n [\n   (attribute_item)\n   (line_comment)\n ]*\n ; the test function\n (function_item\n   body: (_) @test.inside) @test.around\n (#eq? @_test_attribute \"test\"))\n\n(array_expression\n  (_) @entry.around)\n\n(tuple_expression\n  (_) @entry.around)\n\n(tuple_pattern\n  (_) @entry.around)\n\n; Commonly used vec macro initializer is special cased\n(macro_invocation\n  (identifier) @_id (token_tree (_) @entry.around)\n  (#eq? @_id \"array\"))\n\n(enum_variant) @entry.around\n\n(field_declaration\n  (_) @entry.inside) @entry.around\n\n(field_initializer\n  (_) @entry.inside) @entry.around\n\n(shorthand_field_initializer) @entry.around\n"
  },
  {
    "path": "runtime/queries/capnp/folds.scm",
    "content": "[\n  (annotation_targets)\n  (const_list)\n  (enum)\n  (interface)\n  (implicit_generics)\n  (generics)\n  (group)\n  (method_parameters)\n  (named_return_types)\n  (struct)\n  (struct_shorthand)\n  (union)\n] @fold\n"
  },
  {
    "path": "runtime/queries/capnp/highlights.scm",
    "content": "; Preproc\n\n[\n  (unique_id)\n  (top_level_annotation_body)\n] @keyword.directive\n\n; Includes\n\n[\n  \"import\"\n  \"$import\"\n  \"embed\"\n  \"using\"\n] @keyword.control.import\n\n(import_path) @string\n\n; Builtins\n\n[\n  (primitive_type)\n  \"List\"\n] @type.builtin\n\n; Typedefs\n\n(type_definition) @type\n\n; Labels (@number, @number!)\n\n(field_version) @label\n\n; Methods\n\n(annotation_definition_identifier) @function.method\n(method_identifier) @function.method\n\n; Fields\n\n(field_identifier) @variable.other.member\n\n; Properties\n\n(property) @label\n\n; Parameters\n\n(param_identifier) @variable.parameter\n(return_identifier) @variable.parameter\n\n; Constants\n\n(const_identifier) @variable\n(local_const) @constant\n(enum_member) @type.enum.variant\n\n(void) @constant.builtin\n\n; Types\n\n(enum_identifier) @type.enum\n(extend_type) @type\n(type_identifier) @type\n\n; Attributes\n\n(annotation_identifier) @attribute\n(attribute) @attribute\n\n; Operators\n\n[\n ; @ ! -\n  \"=\"\n] @operator\n\n; Keywords\n\n\n[\n  \"annotation\"\n  \"enum\"\n  \"group\"\n  \"interface\"\n  \"struct\"\n  \"union\"\n] @keyword.storage.type\n\n\"extends\" @keyword\n\n[\n  \"namespace\"\n  (annotation_target)\n] @special\n\n; Literals\n\n[\n  (string)\n  (concatenated_string)\n  (block_text)\n  (namespace)\n] @string\n\n(escape_sequence) @constant.character.escape\n\n(data_string) @string.special\n\n(number) @constant.numeric.integer\n\n(float) @constant.numeric.float\n\n(boolean) @constant.builtin.boolean\n\n; Misc\n\n[\n  \"const\"\n] @keyword.storage.modifier\n\n[\n  \"*\"\n  \"$\"\n  \":\"\n] @string.special.symbol\n\n[\"{\" \"}\"] @punctuation.bracket\n\n[\"(\" \")\"] @punctuation.bracket\n\n[\"[\" \"]\"] @punctuation.bracket\n\n[\n  \",\"\n  \";\"\n  \"->\"\n] @punctuation.delimiter\n\n(data_hex) @constant\n\n; Comments\n\n(comment) @comment.line\n"
  },
  {
    "path": "runtime/queries/capnp/indents.scm",
    "content": "[\n  (annotation_targets)\n  (const_list)\n  (enum)\n  (interface)\n  (implicit_generics)\n  (generics)\n  (group)\n  (method_parameters)\n  (named_return_types)\n  (struct)\n  (struct_shorthand)\n  (union)\n] @indent\n\n[\n  \"}\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/capnp/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/capnp/locals.scm",
    "content": "; Scopes\n\n[\n  (message)\n  (annotation_targets)\n  (const_list)\n  (enum)\n  (interface)\n  (implicit_generics)\n  (generics)\n  (group)\n  (method_parameters)\n  (named_return_types)\n  (struct)\n  (struct_shorthand)\n  (union)\n] @local.scope\n\n; References\n\n[\n  (extend_type)\n  (field_type)\n] @local.reference\n(custom_type (type_identifier) @local.reference)\n(custom_type\n  (generics\n    (generic_parameters \n      (generic_identifier) @local.reference)))\n\n; Definitions\n\n[\n  (param_identifier)\n  (return_identifier)\n] @local.definition.variable.parameter\n"
  },
  {
    "path": "runtime/queries/cel/highlights.scm",
    "content": "; Operators\n\n[\n  \"-\"\n  \"!\"\n  \"*\"\n  \"/\"\n  \"&&\"\n  \"%\"\n  \"+\"\n  \"<\"\n  \"<=\"\n  \"==\"\n  \">\"\n  \">=\"\n  \"||\"\n] @operator\n\n; Keywords\n\n[\n\"in\"\n] @keyword\n\n; Identifiers\n\n(identifier) @variable.other.member\n\n(select_expression\n  operand: (identifier) @type)\n\n(select_expression\n  operand: (select_expression\n    member: (identifier) @type))\n\n; Function calls\n\n(call_expression\n  function: (identifier) @function)\n\n(member_call_expression\n  function: (identifier) @function)\n\n; Literals\n\n[\n  (double_quote_string_literal)\n  (single_quoted_string_literal)\n  (triple_double_quote_string_literal)\n  (triple_single_quoted_string_literal)\n] @string\n\n[\n  (int_literal)\n  (uint_literal)\n] @constant.numeric.integer\n(float_literal) @constant.numeric.float\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(null) @constant.builtin\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/chuck/highlights.scm",
    "content": "; Copied from https://github.com/tymbalodeon/tree-sitter-chuck/blob/trunk/queries/highlights.scm\n\n\"@doc\" @special\n\"do\" @keyword.control.repeat\n\"fun\" @keyword.function\n\"function\" @keyword.function\n\"if\" @keyword.control.conditionl\n\"repeat\" @keyword.control.repeat\n\"return\" @keyword.control.return\n\"spork\" @function.builtin\n\"until\" @keyword.control.repeat\n\"while\" @keyword.control.repeat\n\n(block_comment) @comment.block\n(boolean_literal_value) @constant.builtin.boolean\n(chuck_operator) @operator\n(class_identifier) @type\n(duration_identifier) @type\n(float) @constant.numeric.float\n\n(function_definition name: [\n  (class_identifier)\n  (variable_identifier)\n] @function)\n\n(global_unit_generator) @variable.builtin\n(hexidecimal) @constant.numeric\n(int) @constant.numeric.integer\n(keyword) @keyword\n(line_comment) @comment.line\n(operator) @operator\n(primitive_type) @type.builtin\n(special_literal_value) @constant.builtin\n(string) @string\n"
  },
  {
    "path": "runtime/queries/circom/highlights.scm",
    "content": "; identifiers\n; -----------\n(identifier) @variable\n\n; Pragma\n; -----------\n(pragma_directive) @keyword.directive\n\n; Include\n; -----------\n(include_directive) @keyword.directive\n\n; Literals\n; --------\n(string) @string\n(int_literal) @constant.numeric.integer\n(comment) @comment\n\n; Definitions\n; -----------\n(function_definition\n  name:  (identifier) @keyword.function)\n\n(template_definition\n  name:  (identifier) @keyword.function)\n\n; Use constructor coloring for special functions\n(main_component_definition) @constructor\n\n; Invocations\n(call_expression . (identifier) @function)\n\n; Function parameters\n(parameter name: (identifier) @variable.parameter)\n\n; Members\n(member_expression property: (property_identifier) @variable.other.member)\n\n; Tokens\n; -------\n\n; Keywords\n[\n \"signal\"\n \"var\"\n \"component\"\n] @keyword.storage.type\n\n[  \"include\" ] @keyword.control.import\n\n[\n \"public\"\n \"input\"\n \"output\"\n ] @keyword.storage.modifier\n\n[\n \"for\"\n \"while\"\n] @keyword.control.repeat\n\n[\n \"if\"\n \"else\"\n] @keyword.control.conditional\n\n[\n \"return\"\n] @keyword.control.return\n\n[\n  \"function\"\n  \"template\"\n] @keyword.function\n\n; Punctuation\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \".\"\n  \",\"\n  \";\"\n] @punctuation.delimiter\n\n; Operators\n; https://docs.circom.io/circom-language/basic-operators\n[\n  \"=\"\n  \"?\"\n  \"&&\"\n  \"||\"\n  \"!\"\n  \"<\" \n  \">\" \n  \"<=\" \n  \">=\" \n  \"==\" \n  \"!=\" \n  \"+\"\n  \"-\"\n  \"*\"\n  \"**\"\n  \"/\"\n  \"\\\\\"\n  \"%\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"**=\"\n  \"/=\"\n  \"\\\\=\"\n  \"%=\"\n  \"++\"\n  \"--\"\n  \"&\"\n  \"|\"\n  \"~\"\n  \"^\"\n  \">>\"\n  \"<<\"\n  \"&=\"\n  \"|=\"\n  ; \"\\~=\" ; bug, uncomment and circom will not highlight\n  \"^=\"\n  \">>=\"\n  \"<<=\"\n] @operator\n\n[\n  \"<==\"\n  \"==>\"\n  \"<--\"\n  \"-->\"\n  \"===\"\n] @operator\n"
  },
  {
    "path": "runtime/queries/circom/locals.scm",
    "content": "(function_definition) @local.scope\n(template_definition) @local.scope\n(main_component_definition) @local.scope\n(block_statement) @local.scope\n\n(parameter name: (identifier) @local.definition.variable.parameter)\n\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/clarity/highlights.scm",
    "content": "; Comments\n(comment) @comment\n\n; Literals\n[\n  (int_lit)\n  (uint_lit)\n] @constant.numeric.integer\n\n[\n  (bool_lit)\n  (none_lit)\n] @constant.builtin\n\n[\n  (ascii_string_lit)\n  (utf8_string_lit)\n] @string\n\n[\n  (buffer_lit)\n  (standard_principal_lit)\n  (contract_principal_lit)\n] @string.special\n\n; Types\n[\n  (native_type)\n  (trait_type)\n] @type\n\n; Punctuation\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"<\"\n  \">\"\n] @punctuation.bracket\n\n[\n  \",\"\n] @punctuation.delimiter\n\n; Keywords\n(list_lit_token) @keyword\n(some_lit (\"some\") @keyword)\n(response_lit [\n  \"ok\"\n  \"err\"\n] @keyword)\n\n[\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"mod\"\n  \"pow\"\n  \"<\"\n  \"<=\"\n  \">\"\n  \">=\"\n  \"and\"\n  \"or\"\n  \"xor\"\n] @keyword.operator\n\n; Functions\n(function_signature (identifier) @function)\n(function_signature_for_trait (identifier) @function)\n(contract_function_call operator: (identifier) @function)\n\n(basic_native_form operator: (native_identifier) @function.builtin)\n[\n  \"let\"\n] @function.builtin\n\n[\n  \"impl-trait\"\n  \"use-trait\"\n  \"define-trait\"\n  \"define-read-only\"\n  \"define-private\"\n  \"define-public\"\n  \"define-data-var\"\n  \"define-fungible-token\"\n  \"define-non-fungible-token\"\n  \"define-constant\"\n  \"define-map\"\n] @function.special\n\n; Variables and parameters\n(function_parameter) @variable.parameter\n(trait_usage trait_alias: (identifier) @type.parameter)\n\n(tuple_lit key: (identifier) @variable)\n(tuple_type key: (identifier) @variable)\n(tuple_type_for_trait key: (identifier) @variable)\n\n(global) @variable.builtin\n\n"
  },
  {
    "path": "runtime/queries/clojure/highlights.scm",
    "content": "(dis_expr) @comment\n\n(kwd_lit) @string.special.symbol\n\n(str_lit) @string\n\n(num_lit) @constant.numeric\n\n[(bool_lit) (nil_lit)] @constant.builtin\n\n(comment) @comment\n\n;; other symbols\n(sym_lit) @variable\n\n;; other calls\n(list_lit\n .\n (sym_lit) @function)\n\n;; metadata experiment\n(meta_lit\n marker: \"^\" @punctuation)\n\n;; dynamic variables\n((sym_lit) @variable\n (#match? @variable \"^\\\\*.+\\\\*$\"))\n\n;; parameter-related\n((sym_lit) @variable.parameter\n (#match? @variable.parameter \"^&.*$\"))\n\n;; gensym\n((sym_lit) @variable\n (#match? @variable \"^.*#$\"))\n\n;; def-like things\n(list_lit\n .\n (sym_lit) @function.macro\n .\n (sym_lit) @function\n (#match? @function.macro \"^(declare|def|definline|definterface|defmacro|defmethod|defmulti|defn|defn-|defonce|defprotocol|defstruct|deftype|ns)$\"))\n\n;; other macros\n(list_lit\n .\n (sym_lit) @function.macro\n (#match? @function.macro \"^(\\\\.|\\\\.\\\\.|\\\\->|\\\\->>|amap|and|areduce|as\\\\->|assert|binding|bound\\\\-fn|case|catch|comment|cond|cond\\\\->|cond\\\\->>|condp|delay|do|doseq|dosync|dotimes|doto|extend-protocol|extend-type|finally|fn|fn\\\\*|for|future|gen-class|gen-interface|if|if\\\\-let|if\\\\-not|if\\\\-some|import|io!|lazy\\\\-cat|lazy\\\\-seq|let|letfn|locking|loop|memfn|monitor\\\\-enter|monitor\\\\-exit|or|proxy|proxy-super|pvalues|quote|recur|refer\\\\-clojure|reify|set!|some\\\\->|some\\\\->>|sync|throw|time|try|unquote|unquote\\\\-splicing|var|vswap!|when|when\\\\-first|when\\\\-let|when\\\\-not|when\\\\-some|while|with\\\\-bindings|with\\\\-in\\\\-str|with\\\\-loading\\\\-context|with\\\\-local\\\\-vars|with\\\\-open|with\\\\-out\\\\-str|with\\\\-precision|with\\\\-redefs)$\"))\n\n(anon_fn_lit\n .\n (sym_lit) @function.macro\n (#match? @function.macro \"^(\\\\.|\\\\.\\\\.|\\\\->|\\\\->>|amap|and|areduce|as\\\\->|assert|binding|bound\\\\-fn|case|catch|comment|cond|cond\\\\->|cond\\\\->>|condp|delay|do|doseq|dosync|dotimes|doto|extend-protocol|extend-type|finally|fn|fn\\\\*|for|future|gen-class|gen-interface|if|if\\\\-let|if\\\\-not|if\\\\-some|import|io!|lazy\\\\-cat|lazy\\\\-seq|let|letfn|locking|loop|memfn|monitor\\\\-enter|monitor\\\\-exit|or|proxy|proxy-super|pvalues|quote|recur|refer\\\\-clojure|reify|set!|some\\\\->|some\\\\->>|sync|throw|time|try|unquote|unquote\\\\-splicing|var|vswap!|when|when\\\\-first|when\\\\-let|when\\\\-not|when\\\\-some|while|with\\\\-bindings|with\\\\-in\\\\-str|with\\\\-loading\\\\-context|with\\\\-local\\\\-vars|with\\\\-open|with\\\\-out\\\\-str|with\\\\-precision|with\\\\-redefs)$\"))\n\n;; clojure.core=> (cp/pprint (sort (keep (fn [[s v]] (when-not (:macro (meta v)) s)) (ns-publics *ns*))))\n;; ...and then some manual filtering...\n(list_lit\n .\n (sym_lit) @function.builtin\n (#match? @function.builtin \"^(\\\\*|\\\\*'|\\\\+|\\\\+'|\\\\-|\\\\-'|\\\\->ArrayChunk|\\\\->Eduction|\\\\->Vec|\\\\->VecNode|\\\\->VecSeq|\\\\-cache\\\\-protocol\\\\-fn|\\\\-reset\\\\-methods|/|<|<=|=|==|>|>=|PrintWriter\\\\-on|StackTraceElement\\\\->vec|Throwable\\\\->map|accessor|aclone|add\\\\-classpath|add\\\\-tap|add\\\\-watch|agent|agent\\\\-error|agent\\\\-errors|aget|alength|alias|all\\\\-ns|alter|alter\\\\-meta!|alter\\\\-var\\\\-root|ancestors|any\\\\?|apply|array\\\\-map|aset|aset\\\\-boolean|aset\\\\-byte|aset\\\\-char|aset\\\\-double|aset\\\\-float|aset\\\\-int|aset\\\\-long|aset\\\\-short|assoc|assoc!|assoc\\\\-in|associative\\\\?|atom|await|await\\\\-for|await1|bases|bean|bigdec|bigint|biginteger|bit\\\\-and|bit\\\\-and\\\\-not|bit\\\\-clear|bit\\\\-flip|bit\\\\-not|bit\\\\-or|bit\\\\-set|bit\\\\-shift\\\\-left|bit\\\\-shift\\\\-right|bit\\\\-test|bit\\\\-xor|boolean|boolean\\\\-array|boolean\\\\?|booleans|bound\\\\-fn\\\\*|bound\\\\?|bounded\\\\-count|butlast|byte|byte\\\\-array|bytes|bytes\\\\?|cast|cat|char|char\\\\-array|char\\\\-escape\\\\-string|char\\\\-name\\\\-string|char\\\\?|chars|chunk|chunk\\\\-append|chunk\\\\-buffer|chunk\\\\-cons|chunk\\\\-first|chunk\\\\-next|chunk\\\\-rest|chunked\\\\-seq\\\\?|class|class\\\\?|clear\\\\-agent\\\\-errors|clojure\\\\-version|coll\\\\?|commute|comp|comparator|compare|compare\\\\-and\\\\-set!|compile|complement|completing|concat|conj|conj!|cons|constantly|construct\\\\-proxy|contains\\\\?|count|counted\\\\?|create\\\\-ns|create\\\\-struct|cycle|dec|dec'|decimal\\\\?|dedupe|default\\\\-data\\\\-readers|delay\\\\?|deliver|denominator|deref|derive|descendants|destructure|disj|disj!|dissoc|dissoc!|distinct|distinct\\\\?|doall|dorun|double|double\\\\-array|double\\\\?|doubles|drop|drop\\\\-last|drop\\\\-while|eduction|empty|empty\\\\?|ensure|ensure\\\\-reduced|enumeration\\\\-seq|error\\\\-handler|error\\\\-mode|eval|even\\\\?|every\\\\-pred|every\\\\?|ex\\\\-cause|ex\\\\-data|ex\\\\-info|ex\\\\-message|extend|extenders|extends\\\\?|false\\\\?|ffirst|file\\\\-seq|filter|filterv|find|find\\\\-keyword|find\\\\-ns|find\\\\-protocol\\\\-impl|find\\\\-protocol\\\\-method|find\\\\-var|first|flatten|float|float\\\\-array|float\\\\?|floats|flush|fn\\\\?|fnext|fnil|force|format|frequencies|future\\\\-call|future\\\\-cancel|future\\\\-cancelled\\\\?|future\\\\-done\\\\?|future\\\\?|gensym|get|get\\\\-in|get\\\\-method|get\\\\-proxy\\\\-class|get\\\\-thread\\\\-bindings|get\\\\-validator|group\\\\-by|halt\\\\-when|hash|hash\\\\-combine|hash\\\\-map|hash\\\\-ordered\\\\-coll|hash\\\\-set|hash\\\\-unordered\\\\-coll|ident\\\\?|identical\\\\?|identity|ifn\\\\?|in\\\\-ns|inc|inc'|indexed\\\\?|init\\\\-proxy|inst\\\\-ms|inst\\\\-ms\\\\*|inst\\\\?|instance\\\\?|int|int\\\\-array|int\\\\?|integer\\\\?|interleave|intern|interpose|into|into\\\\-array|ints|isa\\\\?|iterate|iterator\\\\-seq|juxt|keep|keep\\\\-indexed|key|keys|keyword|keyword\\\\?|last|line\\\\-seq|list|list\\\\*|list\\\\?|load|load\\\\-file|load\\\\-reader|load\\\\-string|loaded\\\\-libs|long|long\\\\-array|longs|macroexpand|macroexpand\\\\-1|make\\\\-array|make\\\\-hierarchy|map|map\\\\-entry\\\\?|map\\\\-indexed|map\\\\?|mapcat|mapv|max|max\\\\-key|memoize|merge|merge\\\\-with|meta|method\\\\-sig|methods|min|min\\\\-key|mix\\\\-collection\\\\-hash|mod|munge|name|namespace|namespace\\\\-munge|nat\\\\-int\\\\?|neg\\\\-int\\\\?|neg\\\\?|newline|next|nfirst|nil\\\\?|nnext|not|not\\\\-any\\\\?|not\\\\-empty|not\\\\-every\\\\?|not=|ns\\\\-aliases|ns\\\\-imports|ns\\\\-interns|ns\\\\-map|ns\\\\-name|ns\\\\-publics|ns\\\\-refers|ns\\\\-resolve|ns\\\\-unalias|ns\\\\-unmap|nth|nthnext|nthrest|num|number\\\\?|numerator|object\\\\-array|odd\\\\?|parents|partial|partition|partition\\\\-all|partition\\\\-by|pcalls|peek|persistent!|pmap|pop|pop!|pop\\\\-thread\\\\-bindings|pos\\\\-int\\\\?|pos\\\\?|pr|pr\\\\-str|prefer\\\\-method|prefers|primitives\\\\-classnames|print|print\\\\-ctor|print\\\\-dup|print\\\\-method|print\\\\-simple|print\\\\-str|printf|println|println\\\\-str|prn|prn\\\\-str|promise|proxy\\\\-call\\\\-with\\\\-super|proxy\\\\-mappings|proxy\\\\-name|push\\\\-thread\\\\-bindings|qualified\\\\-ident\\\\?|qualified\\\\-keyword\\\\?|qualified\\\\-symbol\\\\?|quot|rand|rand\\\\-int|rand\\\\-nth|random\\\\-sample|range|ratio\\\\?|rational\\\\?|rationalize|re\\\\-find|re\\\\-groups|re\\\\-matcher|re\\\\-matches|re\\\\-pattern|re\\\\-seq|read|read+string|read\\\\-line|read\\\\-string|reader\\\\-conditional|reader\\\\-conditional\\\\?|realized\\\\?|record\\\\?|reduce|reduce\\\\-kv|reduced|reduced\\\\?|reductions|ref|ref\\\\-history\\\\-count|ref\\\\-max\\\\-history|ref\\\\-min\\\\-history|ref\\\\-set|refer|release\\\\-pending\\\\-sends|rem|remove|remove\\\\-all\\\\-methods|remove\\\\-method|remove\\\\-ns|remove\\\\-tap|remove\\\\-watch|repeat|repeatedly|replace|replicate|require|requiring\\\\-resolve|reset!|reset\\\\-meta!|reset\\\\-vals!|resolve|rest|restart\\\\-agent|resultset\\\\-seq|reverse|reversible\\\\?|rseq|rsubseq|run!|satisfies\\\\?|second|select\\\\-keys|send|send\\\\-off|send\\\\-via|seq|seq\\\\?|seqable\\\\?|seque|sequence|sequential\\\\?|set|set\\\\-agent\\\\-send\\\\-executor!|set\\\\-agent\\\\-send\\\\-off\\\\-executor!|set\\\\-error\\\\-handler!|set\\\\-error\\\\-mode!|set\\\\-validator!|set\\\\?|short|short\\\\-array|shorts|shuffle|shutdown\\\\-agents|simple\\\\-ident\\\\?|simple\\\\-keyword\\\\?|simple\\\\-symbol\\\\?|slurp|some|some\\\\-fn|some\\\\?|sort|sort\\\\-by|sorted\\\\-map|sorted\\\\-map\\\\-by|sorted\\\\-set|sorted\\\\-set\\\\-by|sorted\\\\?|special\\\\-symbol\\\\?|spit|split\\\\-at|split\\\\-with|str|string\\\\?|struct|struct\\\\-map|subs|subseq|subvec|supers|swap!|swap\\\\-vals!|symbol|symbol\\\\?|tagged\\\\-literal|tagged\\\\-literal\\\\?|take|take\\\\-last|take\\\\-nth|take\\\\-while|tap>|test|the\\\\-ns|thread\\\\-bound\\\\?|to\\\\-array|to\\\\-array\\\\-2d|trampoline|transduce|transient|tree\\\\-seq|true\\\\?|type|unchecked\\\\-add|unchecked\\\\-add\\\\-int|unchecked\\\\-byte|unchecked\\\\-char|unchecked\\\\-dec|unchecked\\\\-dec\\\\-int|unchecked\\\\-divide\\\\-int|unchecked\\\\-double|unchecked\\\\-float|unchecked\\\\-inc|unchecked\\\\-inc\\\\-int|unchecked\\\\-int|unchecked\\\\-long|unchecked\\\\-multiply|unchecked\\\\-multiply\\\\-int|unchecked\\\\-negate|unchecked\\\\-negate\\\\-int|unchecked\\\\-remainder\\\\-int|unchecked\\\\-short|unchecked\\\\-subtract|unchecked\\\\-subtract\\\\-int|underive|unquote|unquote\\\\-splicing|unreduced|unsigned\\\\-bit\\\\-shift\\\\-right|update|update\\\\-in|update\\\\-proxy|uri\\\\?|use|uuid\\\\?|val|vals|var\\\\-get|var\\\\-set|var\\\\?|vary\\\\-meta|vec|vector|vector\\\\-of|vector\\\\?|volatile!|volatile\\\\?|vreset!|with\\\\-bindings\\\\*|with\\\\-meta|with\\\\-redefs\\\\-fn|xml\\\\-seq|zero\\\\?|zipmap)$\"))\n\n(anon_fn_lit\n .\n (sym_lit) @function.builtin\n (#match? @function.builtin \"^(\\\\*|\\\\*'|\\\\+|\\\\+'|\\\\-|\\\\-'|\\\\->ArrayChunk|\\\\->Eduction|\\\\->Vec|\\\\->VecNode|\\\\->VecSeq|\\\\-cache\\\\-protocol\\\\-fn|\\\\-reset\\\\-methods|/|<|<=|=|==|>|>=|PrintWriter\\\\-on|StackTraceElement\\\\->vec|Throwable\\\\->map|accessor|aclone|add\\\\-classpath|add\\\\-tap|add\\\\-watch|agent|agent\\\\-error|agent\\\\-errors|aget|alength|alias|all\\\\-ns|alter|alter\\\\-meta!|alter\\\\-var\\\\-root|ancestors|any\\\\?|apply|array\\\\-map|aset|aset\\\\-boolean|aset\\\\-byte|aset\\\\-char|aset\\\\-double|aset\\\\-float|aset\\\\-int|aset\\\\-long|aset\\\\-short|assoc|assoc!|assoc\\\\-in|associative\\\\?|atom|await|await\\\\-for|await1|bases|bean|bigdec|bigint|biginteger|bit\\\\-and|bit\\\\-and\\\\-not|bit\\\\-clear|bit\\\\-flip|bit\\\\-not|bit\\\\-or|bit\\\\-set|bit\\\\-shift\\\\-left|bit\\\\-shift\\\\-right|bit\\\\-test|bit\\\\-xor|boolean|boolean\\\\-array|boolean\\\\?|booleans|bound\\\\-fn\\\\*|bound\\\\?|bounded\\\\-count|butlast|byte|byte\\\\-array|bytes|bytes\\\\?|cast|cat|char|char\\\\-array|char\\\\-escape\\\\-string|char\\\\-name\\\\-string|char\\\\?|chars|chunk|chunk\\\\-append|chunk\\\\-buffer|chunk\\\\-cons|chunk\\\\-first|chunk\\\\-next|chunk\\\\-rest|chunked\\\\-seq\\\\?|class|class\\\\?|clear\\\\-agent\\\\-errors|clojure\\\\-version|coll\\\\?|commute|comp|comparator|compare|compare\\\\-and\\\\-set!|compile|complement|completing|concat|conj|conj!|cons|constantly|construct\\\\-proxy|contains\\\\?|count|counted\\\\?|create\\\\-ns|create\\\\-struct|cycle|dec|dec'|decimal\\\\?|dedupe|default\\\\-data\\\\-readers|delay\\\\?|deliver|denominator|deref|derive|descendants|destructure|disj|disj!|dissoc|dissoc!|distinct|distinct\\\\?|doall|dorun|double|double\\\\-array|double\\\\?|doubles|drop|drop\\\\-last|drop\\\\-while|eduction|empty|empty\\\\?|ensure|ensure\\\\-reduced|enumeration\\\\-seq|error\\\\-handler|error\\\\-mode|eval|even\\\\?|every\\\\-pred|every\\\\?|ex\\\\-cause|ex\\\\-data|ex\\\\-info|ex\\\\-message|extend|extenders|extends\\\\?|false\\\\?|ffirst|file\\\\-seq|filter|filterv|find|find\\\\-keyword|find\\\\-ns|find\\\\-protocol\\\\-impl|find\\\\-protocol\\\\-method|find\\\\-var|first|flatten|float|float\\\\-array|float\\\\?|floats|flush|fn\\\\?|fnext|fnil|force|format|frequencies|future\\\\-call|future\\\\-cancel|future\\\\-cancelled\\\\?|future\\\\-done\\\\?|future\\\\?|gensym|get|get\\\\-in|get\\\\-method|get\\\\-proxy\\\\-class|get\\\\-thread\\\\-bindings|get\\\\-validator|group\\\\-by|halt\\\\-when|hash|hash\\\\-combine|hash\\\\-map|hash\\\\-ordered\\\\-coll|hash\\\\-set|hash\\\\-unordered\\\\-coll|ident\\\\?|identical\\\\?|identity|ifn\\\\?|in\\\\-ns|inc|inc'|indexed\\\\?|init\\\\-proxy|inst\\\\-ms|inst\\\\-ms\\\\*|inst\\\\?|instance\\\\?|int|int\\\\-array|int\\\\?|integer\\\\?|interleave|intern|interpose|into|into\\\\-array|ints|isa\\\\?|iterate|iterator\\\\-seq|juxt|keep|keep\\\\-indexed|key|keys|keyword|keyword\\\\?|last|line\\\\-seq|list|list\\\\*|list\\\\?|load|load\\\\-file|load\\\\-reader|load\\\\-string|loaded\\\\-libs|long|long\\\\-array|longs|macroexpand|macroexpand\\\\-1|make\\\\-array|make\\\\-hierarchy|map|map\\\\-entry\\\\?|map\\\\-indexed|map\\\\?|mapcat|mapv|max|max\\\\-key|memoize|merge|merge\\\\-with|meta|method\\\\-sig|methods|min|min\\\\-key|mix\\\\-collection\\\\-hash|mod|munge|name|namespace|namespace\\\\-munge|nat\\\\-int\\\\?|neg\\\\-int\\\\?|neg\\\\?|newline|next|nfirst|nil\\\\?|nnext|not|not\\\\-any\\\\?|not\\\\-empty|not\\\\-every\\\\?|not=|ns\\\\-aliases|ns\\\\-imports|ns\\\\-interns|ns\\\\-map|ns\\\\-name|ns\\\\-publics|ns\\\\-refers|ns\\\\-resolve|ns\\\\-unalias|ns\\\\-unmap|nth|nthnext|nthrest|num|number\\\\?|numerator|object\\\\-array|odd\\\\?|parents|partial|partition|partition\\\\-all|partition\\\\-by|pcalls|peek|persistent!|pmap|pop|pop!|pop\\\\-thread\\\\-bindings|pos\\\\-int\\\\?|pos\\\\?|pr|pr\\\\-str|prefer\\\\-method|prefers|primitives\\\\-classnames|print|print\\\\-ctor|print\\\\-dup|print\\\\-method|print\\\\-simple|print\\\\-str|printf|println|println\\\\-str|prn|prn\\\\-str|promise|proxy\\\\-call\\\\-with\\\\-super|proxy\\\\-mappings|proxy\\\\-name|push\\\\-thread\\\\-bindings|qualified\\\\-ident\\\\?|qualified\\\\-keyword\\\\?|qualified\\\\-symbol\\\\?|quot|rand|rand\\\\-int|rand\\\\-nth|random\\\\-sample|range|ratio\\\\?|rational\\\\?|rationalize|re\\\\-find|re\\\\-groups|re\\\\-matcher|re\\\\-matches|re\\\\-pattern|re\\\\-seq|read|read+string|read\\\\-line|read\\\\-string|reader\\\\-conditional|reader\\\\-conditional\\\\?|realized\\\\?|record\\\\?|reduce|reduce\\\\-kv|reduced|reduced\\\\?|reductions|ref|ref\\\\-history\\\\-count|ref\\\\-max\\\\-history|ref\\\\-min\\\\-history|ref\\\\-set|refer|release\\\\-pending\\\\-sends|rem|remove|remove\\\\-all\\\\-methods|remove\\\\-method|remove\\\\-ns|remove\\\\-tap|remove\\\\-watch|repeat|repeatedly|replace|replicate|require|requiring\\\\-resolve|reset!|reset\\\\-meta!|reset\\\\-vals!|resolve|rest|restart\\\\-agent|resultset\\\\-seq|reverse|reversible\\\\?|rseq|rsubseq|run!|satisfies\\\\?|second|select\\\\-keys|send|send\\\\-off|send\\\\-via|seq|seq\\\\?|seqable\\\\?|seque|sequence|sequential\\\\?|set|set\\\\-agent\\\\-send\\\\-executor!|set\\\\-agent\\\\-send\\\\-off\\\\-executor!|set\\\\-error\\\\-handler!|set\\\\-error\\\\-mode!|set\\\\-validator!|set\\\\?|short|short\\\\-array|shorts|shuffle|shutdown\\\\-agents|simple\\\\-ident\\\\?|simple\\\\-keyword\\\\?|simple\\\\-symbol\\\\?|slurp|some|some\\\\-fn|some\\\\?|sort|sort\\\\-by|sorted\\\\-map|sorted\\\\-map\\\\-by|sorted\\\\-set|sorted\\\\-set\\\\-by|sorted\\\\?|special\\\\-symbol\\\\?|spit|split\\\\-at|split\\\\-with|str|string\\\\?|struct|struct\\\\-map|subs|subseq|subvec|supers|swap!|swap\\\\-vals!|symbol|symbol\\\\?|tagged\\\\-literal|tagged\\\\-literal\\\\?|take|take\\\\-last|take\\\\-nth|take\\\\-while|tap>|test|the\\\\-ns|thread\\\\-bound\\\\?|to\\\\-array|to\\\\-array\\\\-2d|trampoline|transduce|transient|tree\\\\-seq|true\\\\?|type|unchecked\\\\-add|unchecked\\\\-add\\\\-int|unchecked\\\\-byte|unchecked\\\\-char|unchecked\\\\-dec|unchecked\\\\-dec\\\\-int|unchecked\\\\-divide\\\\-int|unchecked\\\\-double|unchecked\\\\-float|unchecked\\\\-inc|unchecked\\\\-inc\\\\-int|unchecked\\\\-int|unchecked\\\\-long|unchecked\\\\-multiply|unchecked\\\\-multiply\\\\-int|unchecked\\\\-negate|unchecked\\\\-negate\\\\-int|unchecked\\\\-remainder\\\\-int|unchecked\\\\-short|unchecked\\\\-subtract|unchecked\\\\-subtract\\\\-int|underive|unquote|unquote\\\\-splicing|unreduced|unsigned\\\\-bit\\\\-shift\\\\-right|update|update\\\\-in|update\\\\-proxy|uri\\\\?|use|uuid\\\\?|val|vals|var\\\\-get|var\\\\-set|var\\\\?|vary\\\\-meta|vec|vector|vector\\\\-of|vector\\\\?|volatile!|volatile\\\\?|vreset!|with\\\\-bindings\\\\*|with\\\\-meta|with\\\\-redefs\\\\-fn|xml\\\\-seq|zero\\\\?|zipmap)$\"))\n\n;; anonymous function positional arguments\n((sym_lit) @operator\n (#match? @operator \"^%\"))\n\n;; interop-ish\n(list_lit\n .\n (sym_lit) @function.method\n (#match? @function.method \"^\\\\.\"))\n\n;; quote\n(quoting_lit) @constant.character.escape\n\n;; syntax quote\n[\"{\" \"}\" \"(\" \")\" \"[\" \"]\"] @punctuation.bracket\n[\"~\" \"~@\" \"#'\" \"@\"] @operator\n(syn_quoting_lit) @constant.character.escape\n"
  },
  {
    "path": "runtime/queries/clojure/indents.scm",
    "content": "; If a list has 2 elements on the first line, align to the second element.\n; Exclude literals and special keywords that have different indentation rules.\n(list_lit . (_) @first . (_) @anchor\n  (#same-line? @first @anchor)\n  (#set! \"scope\" \"tail\")\n  (#not-kind-eq? @first \"bool_lit\")\n  (#not-kind-eq? @first \"nil_lit\")\n  (#not-kind-eq? @first \"str_lit\")\n  (#not-kind-eq? @first \"num_lit\")\n  (#not-kind-eq? @first \"kwd_lit\")\n  (#not-match? @first \"^(def|defn|defn-|defmacro|defmethod|defmulti|defonce|defprotocol|deftype|defrecord|defstruct|definline|definterface|deftest|ns|let|letfn|binding|loop|for|doseq|dotimes|when-let|if-let|when-some|if-some|with-.*|fn)$\")) @align\n\n; If the first element in a list is also a list and on a line by itself,\n; the outer list is aligned to it\n(list_lit . (list_lit) @anchor .\n  (#set! \"scope\" \"tail\")) @align\n\n(list_lit . (list_lit) @anchor . (_) @second\n  (#not-same-line? @anchor @second)\n  (#set! \"scope\" \"tail\")) @align\n\n; If the first element in a list is not a list and on a line by itself,\n; indent the list body by one level\n(list_lit . (_) @first .\n  (#not-kind-eq? @first \"bool_lit\")\n  (#not-kind-eq? @first \"nil_lit\")\n  (#not-kind-eq? @first \"str_lit\")\n  (#not-kind-eq? @first \"num_lit\")\n  (#not-kind-eq? @first \"kwd_lit\")\n  (#not-match? @first \"^(def|defn|defn-|defmacro|defmethod|defmulti|defonce|defprotocol|deftype|defrecord|defstruct|definline|definterface|deftest|ns|let|letfn|binding|loop|for|doseq|dotimes|when-let|if-let|when-some|if-some|with-.*|fn)$\")) @indent\n\n(list_lit . (_) @first . (_) @second\n  (#not-same-line? @first @second)\n  (#not-kind-eq? @first \"bool_lit\")\n  (#not-kind-eq? @first \"nil_lit\")\n  (#not-kind-eq? @first \"str_lit\")\n  (#not-kind-eq? @first \"num_lit\")\n  (#not-kind-eq? @first \"kwd_lit\")\n  (#not-match? @first \"^(def|defn|defn-|defmacro|defmethod|defmulti|defonce|defprotocol|deftype|defrecord|defstruct|definline|definterface|deftest|ns|let|letfn|binding|loop|for|doseq|dotimes|when-let|if-let|when-some|if-some|with-.*|fn)$\")) @indent\n\n; If the first element is a literal, align the list to it\n(list_lit . [(bool_lit) (nil_lit) (str_lit) (num_lit) (kwd_lit)] @anchor\n  (#set! \"scope\" \"tail\")) @align\n\n; Special indentation for def-like forms, let bindings, and other special forms\n; These forms typically have the body indented by one level after the name/bindings\n(list_lit . (sym_lit) @first\n  (#match? @first \"^(def|defn|defn-|defmacro|defmethod|defmulti|defonce|defprotocol|deftype|defrecord|defstruct|definline|definterface|deftest|ns|let|letfn|binding|loop|for|doseq|dotimes|when-let|if-let|when-some|if-some|with-.*|fn)$\")) @indent\n\n; Align vector/map elements when first two are on same line (e.g., let bindings)\n(vec_lit . (_) @anchor . (_) @second\n  (#same-line? @anchor @second)\n  (#set! \"scope\" \"tail\")) @align\n\n(map_lit . (_) @anchor . (_) @second\n  (#same-line? @anchor @second)\n  (#set! \"scope\" \"tail\")) @align\n\n; Indent vectors, maps, and sets\n[(vec_lit) (map_lit) (set_lit)] @indent\n"
  },
  {
    "path": "runtime/queries/clojure/injections.scm",
    "content": "((regex_lit) @injection.content\n (#set! injection.language \"regex\"))\n"
  },
  {
    "path": "runtime/queries/clojure/rainbows.scm",
    "content": "[\n  (list_lit)\n  (map_lit)\n  (vec_lit)\n  (anon_fn_lit)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"#\"\n  \"{\" \"}\"\n  \"[\" \"]\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/clojure/textobjects.scm",
    "content": "; Function definitions (defn, defn-, defmacro, defmethod, etc.)\n(list_lit\n  .\n  (sym_lit) @_keyword\n  .\n  (sym_lit)\n  (_)* @function.inside\n  (#match? @_keyword \"^(defn|defn-|defmacro|defmethod|defmulti|definline)$\")) @function.around\n\n; Anonymous functions (fn)\n(list_lit\n  .\n  (sym_lit) @_fn\n  (_)* @function.inside\n  (#match? @_fn \"^fn$\")) @function.around\n\n; Anonymous function shorthand #()\n(anon_fn_lit\n  (_)* @function.inside) @function.around\n\n; deftype, defrecord, defprotocol\n(list_lit\n  .\n  (sym_lit) @_keyword\n  .\n  (sym_lit)\n  (_)* @class.inside\n  (#match? @_keyword \"^(deftype|defrecord|defprotocol|definterface|defstruct)$\")) @class.around\n\n; Test definitions (deftest)\n(list_lit\n  .\n  (sym_lit) @_keyword\n  .\n  (sym_lit)\n  (_)* @test.inside\n  (#match? @_keyword \"^deftest$\")) @test.around\n\n; Function parameters in vectors\n(vec_lit\n  (_)* @parameter.inside) @parameter.around\n\n; List entries\n(list_lit\n  (_) @entry.inside @entry.around)\n\n; Vector entries\n(vec_lit\n  (_) @entry.inside @entry.around)\n\n; Map entries\n(map_lit\n  (_) @entry.inside @entry.around)\n\n; Set entries\n(set_lit\n  (_) @entry.inside @entry.around)\n\n; Comments\n(comment) @comment.inside\n(comment)+ @comment.around\n\n; Discard expressions (also treated as comments)\n(dis_expr) @comment.inside\n\n; Comment special form (comment ...)\n(list_lit\n  .\n  (sym_lit) @_comment\n  (_)* @comment.inside\n  (#match? @_comment \"^comment$\")) @comment.around\n"
  },
  {
    "path": "runtime/queries/cmake/highlights.scm",
    "content": "[\n  (quoted_argument)\n  (bracket_argument)\n ] @string\n\n(variable) @variable\n\n[\n  (bracket_comment)\n  (line_comment)\n ] @comment\n\n(normal_command (identifier) @function)\n\n[\"ENV\" \"CACHE\"] @string.special.symbol\n[\"$\" \"{\" \"}\" \"<\" \">\"] @punctuation\n[\"(\" \")\"] @punctuation.bracket\n\n[\n  (function)\n  (endfunction)\n  (macro)\n  (endmacro)\n ] @keyword.function\n\n[\n  (if)\n  (elseif)\n  (else)\n  (endif)\n ] @keyword.control.conditional\n\n[\n  (foreach)\n  (endforeach)\n  (while)\n  (endwhile)\n ] @keyword.control.repeat\n\n(function_command\n   (function)\n   . (argument) @function\n   (argument)* @variable.parameter\n )\n\n(macro_command\n   (macro)\n   . (argument) @function.macro\n   (argument)* @variable.parameter\n )\n\n(normal_command\n  (identifier) @function.builtin\n  . (argument) @variable\n  (#match? @function.builtin \"^(?i)(set)$\"))\n\n(normal_command\n  (identifier) @function.builtin\n  . (argument)\n  (argument) @constant\n  (#match? @constant \"^(?:PARENT_SCOPE|CACHE)$\")\n  (#match? @function.builtin \"^(?i)(unset)$\"))\n\n(normal_command\n  (identifier) @function.builtin\n  . (argument)\n  . (argument)\n  (argument) @constant\n  (#match? @constant \"^(?:PARENT_SCOPE|CACHE|FORCE)$\")\n  (#match? @function.builtin \"^(?i)(set)$\")\n )\n\n((argument) @constant.builtin.boolean\n   (#match? @constant.builtin.boolean \"^(?i)(?:1|on|yes|true|y|0|off|no|false|n|ignore|notfound|.*-notfound)$\")\n )\n\n(if_command\n   (if)\n   (argument) @operator\n   (#match? @operator \"^(?:NOT|AND|OR|COMMAND|POLICY|TARGET|TEST|DEFINED|IN_LIST|EXISTS|IS_NEWER_THAN|IS_DIRECTORY|IS_SYMLINK|IS_ABSOLUTE|MATCHES|LESS|GREATER|EQUAL|LESS_EQUAL|GREATER_EQUAL|STRLESS|STRGREATER|STREQUAL|STRLESS_EQUAL|STRGREATER_EQUAL|VERSION_LESS|VERSION_GREATER|VERSION_EQUAL|VERSION_LESS_EQUAL|VERSION_GREATER_EQUAL)$\")\n)\n\n(normal_command\n   (identifier) @function.builtin\n   . (argument)\n   (argument) @constant\n   (#match? @constant \"^(?:ALL|COMMAND|DEPENDS|BYPRODUCTS|WORKING_DIRECTORY|COMMENT|JOB_POOL|VERBATIM|USES_TERMINAL|COMMAND_EXPAND_LISTS|SOURCES)$\")\n   (#match? @function.builtin \"^(?i)(add_custom_target)$\")\n )\n\n(normal_command\n   (identifier) @function.builtin\n   (argument) @constant\n   (#match? @constant \"^(?:OUTPUT|COMMAND|MAIN_DEPENDENCY|DEPENDS|BYPRODUCTS|IMPLICIT_DEPENDS|WORKING_DIRECTORY|COMMENT|DEPFILE|JOB_POOL|VERBATIM|APPEND|USES_TERMINAL|COMMAND_EXPAND_LISTS)$\")\n   (#match? @function.builtin \"^(?i)(add_custom_command)$\")\n )\n\n"
  },
  {
    "path": "runtime/queries/cmake/indents.scm",
    "content": "[\n  (if_condition)\n  (foreach_loop)\n  (while_loop)\n  (function_def)\n  (macro_def)\n  (normal_command)\n] @indent\n\n\")\" @outdent\n"
  },
  {
    "path": "runtime/queries/cmake/injections.scm",
    "content": "((line_comment) @injection.content\n (#set! injection.language \"comment\"))\n((bracket_comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/cmake/textobjects.scm",
    "content": "[\n  (macro_def)\n  (function_def)\n] @function.around\n\n(argument) @parameter.inside\n\n[\n  (bracket_comment)\n  (line_comment)\n] @comment.inside\n\n(line_comment)+ @comment.around\n\n(bracket_comment) @comment.around"
  },
  {
    "path": "runtime/queries/codeql/highlights.scm",
    "content": "[\n  \"and\"\n  \"any\"\n  \"as\"\n  \"asc\"\n  \"avg\"\n  \"by\"\n  \"class\"\n  \"concat\"\n  \"count\"\n  \"desc\"\n  \"else\"\n  \"exists\"\n  \"extends\"\n  \"forall\"\n  \"forex\"\n  \"from\"\n  \"if\"\n  \"implements\"\n  \"implies\"\n  \"import\"\n  \"in\"\n  \"instanceof\"\n  \"max\"\n  \"min\"\n  \"module\"\n  \"newtype\"\n  \"not\"\n  \"or\"\n  \"order\"\n  \"rank\"\n  \"select\"\n  \"strictconcat\"\n  \"strictcount\"\n  \"strictsum\"\n  \"sum\"\n  \"then\"\n  \"where\"\n\n  (false)\n  (predicate)\n  (result)\n  (specialId)\n  (super)\n  (this)\n  (true)\n] @keyword\n\n[\n  \"boolean\"\n  \"float\"\n  \"int\"\n  \"date\"\n  \"string\"\n] @type.builtin\n\n(annotName) @attribute\n\n[\n  \"<\"\n  \"<=\"\n  \"=\"\n  \">\"\n  \">=\"\n  \"-\"\n  \"!=\"\n  \"/\"\n  \"*\"\n  \"%\"\n  \"+\"\n  \"::\"\n] @operator\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \"|\"\n] @punctuation.delimiter\n\n(className) @type\n\n(varName) @variable\n\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n\n(string) @string\n\n(aritylessPredicateExpr (literalId) @function)\n(predicateName) @function\n\n[\n  (line_comment)\n  (block_comment)\n  (qldoc)\n] @comment\n"
  },
  {
    "path": "runtime/queries/codeql/textobjects.scm",
    "content": "(qldoc) @comment.around\n(block_comment) @comment.around\n(line_comment) @comment.inside\n(line_comment)+ @comment.around\n\n(classlessPredicate\n  ((varDecl) @parameter.inside . \",\"?) @parameter.around\n  (body \"{\" (_)* @function.inside \"}\")) @function.around\n(memberPredicate\n  ((varDecl) @parameter.inside . \",\"?) @parameter.around\n  (body \"{\" (_)* @function.inside \"}\")) @function.around\n\n(dataclass\n  (\"{\" (_)* @class.inside \"}\")?) @class.around\n(datatype) @class.around\n(datatypeBranch) @class.around\n"
  },
  {
    "path": "runtime/queries/comment/highlights.scm",
    "content": "(tag\n (name) @ui.text\n (user)? @constant)\n\n; Hint level tags\n((tag (name) @hint)\n (#any-of? @hint \"HINT\" \"MARK\" \"PASSED\" \"STUB\" \"MOCK\" \"TIP\"))\n\n(\"text\" @hint\n (#any-of? @hint \"HINT\" \"MARK\" \"PASSED\" \"STUB\" \"MOCK\" \"TIP\"))\n\n; Info level tags\n((tag (name) @info)\n (#any-of? @info \"INFO\" \"NOTE\" \"TODO\" \"TO-DO\" \"PERF\" \"OPTIMIZE\" \"PERFORMANCE\" \"QUESTION\" \"ASK\" \"REVIEW\" \"PR\" \"CR\"))\n\n(\"text\" @info\n (#any-of? @info \"INFO\" \"NOTE\" \"TODO\" \"TO-DO\" \"PERF\" \"OPTIMIZE\" \"PERFORMANCE\" \"QUESTION\" \"ASK\" \"REVIEW\" \"PR\" \"CR\"))\n\n; Warning level tags\n((tag (name) @warning)\n (#any-of? @warning \"HACK\" \"WARN\" \"WARNING\" \"TEST\" \"TEMP\"))\n\n(\"text\" @warning\n (#any-of? @warning \"HACK\" \"WARN\" \"WARNING\" \"TEST\" \"TEMP\"))\n\n; Error level tags\n((tag (name) @error)\n (#any-of? @error \"BUG\" \"FIXME\" \"ISSUE\" \"XXX\" \"FIX\" \"SAFETY\" \"FIXIT\" \"FAILED\" \"DEBUG\" \"INVARIANT\" \"COMPLIANCE\" \"PANIC\"))\n\n(\"text\" @error\n (#any-of? @error \"BUG\" \"FIXME\" \"ISSUE\" \"XXX\" \"FIX\" \"SAFETY\" \"FIXIT\" \"FAILED\" \"DEBUG\" \"INVARIANT\" \"COMPLIANCE\" \"PANIC\"))\n\n; Issue number (#123)\n(\"text\" @constant.numeric\n (#match? @constant.numeric \"^#[0-9]+$\"))\n\n; User mention (@user)\n(\"text\" @tag\n (#match? @tag \"^[@][a-zA-Z0-9_-]+$\"))\n\n(uri) @markup.link.url\n"
  },
  {
    "path": "runtime/queries/common-lisp/highlights.scm",
    "content": "(sym_lit) @variable\n\n[\n  (accumulation_verb)\n  \"thereis\"\n  \"always\"\n  \"below\"\n  \"into\"\n  \"as\"\n] @keyword\n\n\"and\" @keyword.operator\n\n[\n  \"when\"\n  \"if\"\n  \"unless\"\n  \"else\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n  \"loop\"\n  \"while\"\n  \"until\"\n  \"do\"\n  \"repeat\"\n] @keyword.control.loop\n\n[\n  \"in\"\n  \"across\"\n  \"being\"\n  \"from\"\n\n  \"finally\"\n  \"initially\"\n\n  \"with\"\n] @keyword.control\n\n\"return\" @keyword.control.return\n\n(include_reader_macro) @keyword.directive\n\n(defun_keyword) @keyword.function\n\n(defun_header\n  function_name: (_) @function)\n\n(defun_header\n  lambda_list: (list_lit\n    (sym_lit) @variable.parameter))\n\n(defun_header\n  lambda_list: (list_lit\n    (list_lit\n      . (sym_lit) @variable.parameter)\n      . (_)))\n\n\"=\" @operator\n\n; quote\n(format_specifier) @operator\n\n(quoting_lit \"'\" @operator)\n(syn_quoting_lit \"`\" @operator)\n(unquoting_lit \",\" @operator)\n(unquote_splicing_lit \",@\" @operator)\n\n(var_quoting_lit\n  marker: \"#'\" @operator)\n\n(list_lit\n  . (sym_lit) @operator\n  (#any-of? @operator \"+\" \"*\" \"-\" \"=\" \"<\" \">\" \"<=\" \">=\" \"/=\"))\n\n(package_lit\n  package: (_) @namespace)\n\"cl\" @namespace\n\n(str_lit) @string\n\n(num_lit) @constant.numeric\n[\"#c\" \"#C\"] @constant.numeric\n[\n  (array_dimension)\n  \"#0A\"\n  \"#0a\"\n] @constant.numeric\n\n(nil_lit) @constant.builtin\n(char_lit) @constant.character\n\n[(comment) (block_comment)] @comment\n(dis_expr) @comment\n\n[\"(\" \")\"] @punctuaton.bracket\n[\":\" \"::\" \".\"] @punctuation.special\n"
  },
  {
    "path": "runtime/queries/common-lisp/injections.scm",
    "content": "([(comment) (block_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/common-lisp/rainbows.scm",
    "content": "[\n  (list_lit)\n  (vec_lit)\n  (defun)\n  (loop_macro)\n  (complex_num_lit)\n] @rainbow.scope\n\n(vec_lit \"#\" @rainbow.bracket)\n[\"(\" \")\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/common-lisp/tags.scm",
    "content": "(defun (defun_header\n  function_name: (_) @name)) @definition.function\n"
  },
  {
    "path": "runtime/queries/common-lisp/textobjects.scm",
    "content": "[\n  (comment)\n  (block_comment)\n] @comment.inside\n\n(comment)+ @comment.around\n(block_comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/cpon/highlights.scm",
    "content": "[\n  (true)\n  (false)\n] @constant.builtin.boolean\n(null) @constant.builtin\n(number) @constant.numeric\n(pair\n  key: (_) @keyword)\n(ipair\n  key: (_) @keyword)\n(mpair\n  key: (_) @keyword)\n\n(string) @string\n(escape_sequence) @constant.character.escape\n\n\",\" @punctuation.delimiter\n[\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"<\"\n  \">\"\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/cpon/indents.scm",
    "content": "[\n  (meta)\n  (map)\n  (imap)\n  (array)\n] @indent\n\n[\n  \"]\"\n  \"}\"\n  \">\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/cpp/highlights.scm",
    "content": "; inherits: c\n\n; Constants\n\n(this) @variable.builtin\n(null) @constant.builtin\n\n; Types\n\n(using_declaration (\"using\" \"namespace\" (identifier) @namespace))\n(using_declaration (\"using\" \"namespace\" (qualified_identifier name: (identifier) @namespace)))\n(namespace_definition name: (namespace_identifier) @namespace)\n(namespace_identifier) @namespace\n\n(auto) @type\n\"decltype\" @type\n\n(ref_qualifier [\"&\" \"&&\"] @type.builtin)\n(reference_declarator [\"&\" \"&&\"] @type.builtin)\n(abstract_reference_declarator [\"&\" \"&&\"] @type.builtin)\n\n; -------\n; Functions\n; -------\n; Support up to 4 levels of nesting of qualifiers\n; i.e. a::b::c::d::func();\n(call_expression\n  function: (qualified_identifier\n    name: (identifier) @function))\n(call_expression\n  function: (qualified_identifier\n    name: (qualified_identifier\n      name: (identifier) @function)))\n(call_expression\n  function: (qualified_identifier\n    name: (qualified_identifier\n      name: (qualified_identifier\n        name: (identifier) @function))))\n(call_expression\n  function: (qualified_identifier\n    name: (qualified_identifier\n      name: (qualified_identifier\n        name: (qualified_identifier\n          name: (identifier) @function)))))\n\n(template_function\n  name: (identifier) @function)\n\n(template_method\n  name: (field_identifier) @function)\n\n; Support up to 4 levels of nesting of qualifiers\n; i.e. a::b::c::d::func();\n(function_declarator\n  declarator: (qualified_identifier\n    name: (identifier) @function))\n(function_declarator\n  declarator: (qualified_identifier\n    name: (qualified_identifier\n      name: (identifier) @function)))\n(function_declarator\n  declarator: (qualified_identifier\n    name: (qualified_identifier\n      name: (qualified_identifier\n        name: (identifier) @function))))\n(function_declarator\n  declarator: (qualified_identifier\n    name: (qualified_identifier\n      name: (qualified_identifier\n        name: (qualified_identifier\n          name: (identifier) @function)))))\n\n(function_declarator\n  declarator: (field_identifier) @function)\n\n; Constructors\n\n(class_specifier\n  (type_identifier) @type\n  (field_declaration_list\n    (function_definition\n      (function_declarator\n        (identifier) @constructor)))\n        (#eq? @type @constructor)) \n(destructor_name \"~\" @constructor\n  (identifier) @constructor)\n\n; Parameters\n\n(parameter_declaration\n  declarator: (reference_declarator (identifier) @variable.parameter))\n(optional_parameter_declaration\n  declarator: (identifier) @variable.parameter)\n\n; Keywords\n\n(template_argument_list ([\"<\" \">\"] @punctuation.bracket))\n(template_parameter_list ([\"<\" \">\"] @punctuation.bracket))\n(default_method_clause \"default\" @keyword)\n\n\"static_assert\" @function.special\n\n[\n  \"<=>\"\n  \"[]\"\n  \"()\"\n] @operator\n\n\n; These casts are parsed as function calls, but are not.\n((identifier) @keyword (#eq? @keyword \"static_cast\"))\n((identifier) @keyword (#eq? @keyword \"dynamic_cast\"))\n((identifier) @keyword (#eq? @keyword \"reinterpret_cast\"))\n((identifier) @keyword (#eq? @keyword \"const_cast\"))\n\n[\n  \"co_await\"\n  \"co_return\"\n  \"co_yield\"\n  \"concept\"\n  \"delete\"\n  \"new\"\n  \"operator\"\n  \"requires\"\n  \"using\"\n] @keyword\n\n[\n  \"catch\"\n  \"noexcept\"\n  \"throw\"\n  \"try\"\n] @keyword.control.exception\n\n\n[\n  \"and\"\n  \"and_eq\"\n  \"bitor\"\n  \"bitand\"\n  \"not\"\n  \"not_eq\"\n  \"or\"\n  \"or_eq\"\n  \"xor\"\n  \"xor_eq\"\n] @keyword.operator\n\n[\n  \"class\"  \n  \"namespace\"\n  \"typename\"\n  \"template\"\n] @keyword.storage.type\n\n[\n  \"constexpr\"\n  \"constinit\"\n  \"consteval\"\n  \"mutable\"\n] @keyword.storage.modifier\n\n; Modifiers that aren't plausibly type/storage related.\n[\n  \"explicit\"\n  \"friend\"\n  \"virtual\"\n  (virtual_specifier) ; override/final\n  \"private\"\n  \"protected\"\n  \"public\"\n  \"inline\" ; C++ meaning differs from C!\n] @keyword\n\n; Strings\n\n(raw_string_literal) @string\n"
  },
  {
    "path": "runtime/queries/cpp/indents.scm",
    "content": "; inherits: c\n\n(access_specifier) @outdent\n"
  },
  {
    "path": "runtime/queries/cpp/injections.scm",
    "content": "; inherits: c\n\n((preproc_arg) @injection.content\n (#set! injection.language \"cpp\")\n (#set! injection.include-children))\n\n(raw_string_literal\n  delimiter: (raw_string_delimiter) @injection.language\n  (raw_string_content) @injection.content)\n"
  },
  {
    "path": "runtime/queries/cpp/rainbows.scm",
    "content": "[\n  ; c\n  (preproc_params)\n  (preproc_defined)\n  (argument_list)\n  (attribute_specifier)\n  (ms_declspec_modifier)\n  (declaration_list)\n  (parenthesized_declarator)\n  (parenthesized_expression)\n  (abstract_parenthesized_declarator)\n  (array_declarator)\n  (compound_statement)\n  (initializer_list)\n  (compound_literal_expression)\n  (enumerator_list)\n  (field_declaration_list)\n  (parameter_list)\n  (for_statement)\n  ; (macro_type_specifier) - not part of cpp\n  (subscript_expression)\n  (subscript_designator)\n  (cast_expression)\n\n  ; cpp\n  (decltype)\n  (explicit_function_specifier)\n  (template_parameter_list)\n  (template_argument_list)\n  (parameter_list)\n  (argument_list)\n  (structured_binding_declarator)\n  (noexcept)\n  (throw_specifier)\n  (static_assert_declaration)\n  (condition_clause)\n  (for_range_loop)\n  (new_declarator)\n  (delete_expression \"[\" \"]\")\n  (lambda_capture_specifier)\n  (sizeof_expression)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"{\" \"}\"\n  \"[\" \"]\"\n  \"<\" \">\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/cpp/tags.scm",
    "content": "; inherits: c\n\n(function_declarator\n  declarator: (qualified_identifier name: (identifier) @definition.function))\n\n(class_specifier\n  name: (type_identifier) @definition.class\n  body: (field_declaration_list))\n"
  },
  {
    "path": "runtime/queries/cpp/textobjects.scm",
    "content": "; inherits: c\n\n(lambda_expression\n  body: (_) @function.inside) @function.around\n\n(class_specifier\n  body: (_) @class.inside) @class.around\n"
  },
  {
    "path": "runtime/queries/cross-config/highlights.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/cross-config/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; https://github.com/cross-rs/cross/blob/main/docs/config_file.md\n(pair\n  (bare_key) @_key (#eq? @_key \"pre-build\")\n  (array\n    (string) @injection.content)\n  (#set! injection.language \"bash\"))\n"
  },
  {
    "path": "runtime/queries/cross-config/rainbows.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/cross-config/textobjects.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/crystal/highlights.scm",
    "content": "[\n  \",\"\n  \";\"\n  \".\"\n  \":\"\n  \"*\"\n  \"**\"\n] @punctuation.delimiter\n\n[\n  \"alias\"\n  \"alignof\"\n  \"annotation\"\n  \"asm\"\n  \"begin\"\n  \"case\"\n  \"def\"\n  \"do\"\n  \"end\"\n  \"extend\"\n  \"forall\"\n  \"fun\"\n  \"in\"\n  \"include\"\n  \"instance_alignof\"\n  \"instance_sizeof\"\n  \"macro\"\n  \"of\"\n  \"offsetof\"\n  \"out\"\n  \"pointerof\"\n  \"select\"\n  \"sizeof\"\n  \"then\"\n  \"type\"\n  \"typeof\"\n  \"uninitialized\"\n  \"verbatim\"\n  \"when\"\n  \"with\"\n] @keyword\n\n[\n  \"else\"\n  \"elsif\"\n  \"if\"\n  \"unless\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n  \"until\"\n  \"while\"\n] @keyword.control.repeat\n\n[\"require\"] @keyword.control.import\n\n[\n  \"break\"\n  \"next\"\n  \"return\"\n  \"yield\"\n] @keyword.control.return\n\n[\n  \"ensure\"\n  \"rescue\"\n] @keyword.control.exception\n\n[\n  \"class\"\n  \"enum\"\n  \"lib\"\n  \"module\"\n  \"struct\"\n  \"union\"\n] @keyword.storage.type\n\n(conditional\n  [\n    \"?\"\n    \":\"\n  ] @keyword.control.conditional)\n\n[\n  (private)\n  (protected)\n  \"abstract\"\n] @keyword\n\n(pseudo_constant) @constant.builtin\n\n; literals\n(char\n  [\"'\" (literal_content)] @string)\n\n(char\n  (escape_sequence) @constant.character.escape)\n\n(string\n  [\"\\\"\" (literal_content)] @string)\n\n(string\n  (escape_sequence) @constant.character.escape)\n\n(symbol\n  [\n    \":\"\n    \":\\\"\"\n    \"\\\"\"\n    (literal_content)\n  ] @string.special.symbol)\n\n(symbol\n  (escape_sequence) @constant.character.escape)\n\n(command\n  [\"`\" (literal_content)] @string.special)\n\n(command\n  (escape_sequence) @constant.character.escape)\n\n(regex\n  \"/\" @punctuation.bracket)\n\n(regex\n  (literal_content) @string.regexp)\n\n(regex_modifier) @string.special.symbol\n\n(heredoc_body\n  (literal_content) @string)\n\n(heredoc_body\n  (escape_sequence) @constant.character.escape)\n\n[\n  (heredoc_start)\n  (heredoc_end)\n] @string.symbol\n\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(nil) @constant.builtin\n\n(self) @variable.builtin\n\n(\n  (comment)+ @comment.block.documentation\n  .\n  [\n    (class_def)\n    (struct_def)\n    (method_def)\n    (abstract_method_def)\n    (macro_def)\n    (module_def)\n    (enum_def)\n    (annotation_def)\n    (lib_def)\n    (type_def)\n    (c_struct_def)\n    (union_def)\n    (alias)\n    (const_assign)\n  ]\n)\n\n(comment) @comment\n\n; Operators and punctuation\n[\n  \"=\"\n  \"=>\"\n  \"->\"\n  \"&\"\n  (operator)\n] @operator\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"@[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n(index_call\n  method: (operator) @punctuation.bracket\n  [\n    \"]\"\n    \"]?\"\n  ] @punctuation.bracket)\n\n(block\n    \"|\" @punctuation.bracket)\n\n[\n  \"{%\"\n  \"%}\"\n  \"{{\"\n  \"}}\"\n] @keyword.directive\n\n(interpolation\n  \"#{\" @punctuation.special\n  \"}\" @punctuation.special)\n\n; TODO: {splat,double_splat,block,fun}_param + rescue param\n\n; Types\n\n(nilable_constant\n  \"?\" @type)\n\n(nilable_type\n  \"?\" @type)\n\n(union_type\n  \"|\" @operator)\n\n(annotation\n  (constant) @attribute)\n\n(identifier) @variable\n(param name: (identifier) @variable.parameter)\n\n(method_def\n  name: (identifier) @function.method)\n\n(macro_def\n  name: (identifier) @function.method)\n\n(abstract_method_def\n  name: (identifier) @function.method)\n\n(fun_def\n  name: (identifier) @function.method\n  real_name: (identifier)? @function.method)\n\n(macro_var) @variable\n\n[\n  (class_var)\n  (instance_var)\n] @variable.other.member\n\n(named_expr\n  name: (identifier) @variable.other.member\n  \":\" @variable.other.member)\n\n(named_type\n    name: (identifier) @variable.other.member)\n\n(underscore) @variable.special\n\n; function calls\n\n(call\n    method: (_) @keyword\n    arguments: (argument_list\n      [\n        (type_declaration\n          var: (_) @function.method)\n        (assign\n          lhs: (_) @function.method)\n        (_) @function.method\n      ])\n    (#match? @keyword \"^(class_)?(getter|setter|property)[?!]?$\"))\n\n(call\n    method: (_) @keyword\n    (#match? @keyword \"^(record|is_a\\\\?|as|as\\\\?|responds_to\\\\?|nil\\\\?|\\\\!)$\"))\n\n(call\n  method: (_) @function.method)\n\n(implicit_object_call\n  method: (_) @function.method)\n\n(method_proc\n  method: (_) @function.method)\n\n(assign_call\n  method: (_) @function.method)\n\n((identifier) @variable.builtin\n  (#match? @variable.builtin \"^(previous_def|super)$\"))\n\n[\n  (constant)\n  (generic_instance_type)\n  (generic_type)\n] @type\n"
  },
  {
    "path": "runtime/queries/crystal/indents.scm",
    "content": "[\n  (param_list)\n  (array)\n  (block)\n  (call)\n  (class_def)\n  (struct_def)\n  (module_def)\n  (enum_def)\n  (lib_def)\n  (fun_def)\n  (method_def)\n  (case)\n  (select)\n  (elsif)\n  (if)\n  (unless)\n  (hash)\n  (tuple)\n] @indent\n\n[\n  \")\"\n  \"}\"\n  \"]\"\n  \"end\"\n  \"when\"\n  \"in\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/crystal/injections.scm",
    "content": "((heredoc_body\n  (literal_content) @injection.content\n  (heredoc_end) @name\n  (#set! injection.language \"sql\"))\n  (#eq? @name \"SQL\"))\n\n((heredoc_body\n  (literal_content) @injection.content\n  (heredoc_end) @name\n  (#set! injection.language \"html\"))\n  (#eq? @name \"HTML\"))\n"
  },
  {
    "path": "runtime/queries/crystal/locals.scm",
    "content": "((method_def) @local.scope\n (#set! local.scope-inherits false))\n((fun_def) @local.scope\n (#set! local.scope-inherits false))\n\n(block) @local.scope\n\n(param\n  name: (identifier) @local.definition.variable.parameter)\n\n(assign\n  lhs: (identifier) @local.definition.variable)\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/crystal/tags.scm",
    "content": ";;\n"
  },
  {
    "path": "runtime/queries/crystal/textobjects.scm",
    "content": "(class_def\n  name: (_)\n  (_) @class.inside) @class.around\n\n(struct_def\n  name: (_)\n  (_) @class.inside) @class.around\n\n(module_def\n  name: (_)\n  (_) @class.inside) @class.around\n\n(lib_def\n  name: (_)\n  (_) @class.inside) @class.around\n\n(enum_def\n  name: (_)\n  (_) @class.inside) @class.around\n\n(block\n  params: (_) @parameter.inside) @parameter.around\n\n(method_def\n  params: (_) @parameter.inside) @parameter.around\n\n(method_def\n  name: (_)\n  (_) @function.inside) @function.around\n\n(block\n  (_) @function.inside) @function.around\n\n(comment) @comment.inside\n(comment)+ @comment.around\n\n(array\n  (_) @entry.around)\n"
  },
  {
    "path": "runtime/queries/css/highlights.scm",
    "content": "(comment) @comment\n\n[\n  (tag_name)\n  (nesting_selector)\n  (universal_selector)\n] @tag\n\n[\n  \"~\"\n  \">\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"=\"\n  \"^=\"\n  \"|=\"\n  \"~=\"\n  \"$=\"\n  \"*=\"\n] @operator\n\n[\n  \"and\"\n  \"not\"\n  \"only\"\n  \"or\"\n] @keyword.operator\n\n(attribute_selector (plain_value) @string)\n\n(property_name) @variable.other.member\n(plain_value) @constant\n\n((property_name) @variable\n  (#match? @variable \"^--\"))\n((plain_value) @variable\n  (#match? @variable \"^--\"))\n\n(class_name) @label\n(feature_name) @variable.other.member\n(function_name) @function\n(id_name) @label\n(namespace_name) @namespace\n\n(attribute_name) @attribute\n(pseudo_element_selector (tag_name) @attribute)\n(pseudo_class_selector (class_name) @attribute)\n\n[\n  \"@charset\"\n  \"@import\"\n  \"@keyframes\"\n  \"@media\"\n  \"@namespace\"\n  \"@supports\"\n  (at_keyword)\n  (from)\n  (important)\n  (to)\n  (keyword_query)\n  (keyframes_name)\n  (unit)\n] @keyword\n\n; @apply something;\n(at_rule\n  . (at_keyword) @keyword\n  . (keyword_query) @constant\n  (#eq? @keyword \"@apply\"))\n\n[\n  \"#\"\n  \".\"\n] @punctuation\n\n(string_value) @string\n(color_value \"#\" @string.special)\n(color_value) @string.special\n\n(integer_value) @constant.numeric.integer\n(float_value) @constant.numeric.float\n\n[\n  \")\"\n  \"(\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \";\"\n  \":\"\n  \"::\"\n] @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/css/indents.scm",
    "content": "[\n  (block)\n] @indent\n\n[\n \"}\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/css/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/css/rainbows.scm",
    "content": "[\n  (keyframe_block_list)\n  (block)\n  (attribute_selector)\n  (feature_query)\n  (parenthesized_query)\n  (selector_query)\n  (parenthesized_value)\n  (arguments)\n] @rainbow.scope\n\n[\n  \"{\" \"}\"\n  \"(\" \")\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/csv/highlights.scm",
    "content": "(first)@type\n(second)@function\n(third)@constant\n(fourth)@operator\n(fifth)@type\n(sixth)@function\n(seventh)@constant\n\n[\n  \";\"\n  \",\"\n  \"|\"\n] @punctuation.delimiter\n\n"
  },
  {
    "path": "runtime/queries/cue/highlights.scm",
    "content": "; Includes\n[\n  \"package\"\n  \"import\"\n] @keyword.control.import\n\n; Namespaces\n(package_identifier) @namespace\n\n(import_spec\n  [\n    \".\"\n    \"_\"\n  ] @punctuation.special)\n\n[\n  (attr_path)\n  (package_path)\n] @string.special.url ; In attributes\n\n; Attributes\n(attribute) @attribute\n\n; Conditionals\n\"if\" @keyword.control.conditional\n\n; Repeats\n\"for\" @keyword.control.repeat\n\n(for_clause\n  \"_\" @punctuation.special)\n\n; Keywords\n\"let\" @keyword\n\n\"in\" @keyword.operator\n\n; Operators\n[\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"|\"\n  \"&\"\n  \"||\"\n  \"&&\"\n  \"==\"\n  \"!=\"\n  \"<\"\n  \"<=\"\n  \">\"\n  \">=\"\n  \"=~\"\n  \"!~\"\n  \"!\"\n  \"=\"\n] @operator\n\n; Fields & Properties\n(field\n  (label\n    (identifier) @variable.other.member))\n\n(selector_expression\n  (_)\n  (identifier) @variable.other.member)\n\n; Functions\n(call_expression\n  function: (identifier) @function)\n\n(call_expression\n  function: (selector_expression\n    (_)\n    (identifier) @function))\n\n(call_expression\n  function: (builtin_function) @function)\n\n(builtin_function) @function.builtin\n\n; Variables\n(identifier) @variable\n\n; Types\n(primitive_type) @type.builtin\n\n((identifier) @type\n  (#match? @type \"^_?#\"))\n\n[\n  (slice_type)\n  (pointer_type)\n] @type ; In attributes\n\n; Punctuation\n[\n  \",\"\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"(\"\n  \")\"\n  \"<\"\n  \">\"\n] @punctuation.bracket\n\n[\n  (ellipsis)\n  \"?\"\n] @punctuation.special\n\n; Literals\n(string) @string\n\n[\n  (escape_char)\n  (escape_unicode)\n] @constant.character.escape\n\n(number) @constant.numeric\n\n(float) @constant.numeric.float\n\n(si_unit\n  (float)\n  (_) @string.special.symbol)\n\n(boolean) @constant.builtin.boolean\n\n[\n  (null)\n  (top)\n  (bottom)\n] @constant.builtin\n\n; Interpolations\n(interpolation\n  \"\\\\(\" @punctuation.special\n  (_)\n  \")\" @punctuation.special)\n\n(interpolation\n  \"\\\\(\"\n  (identifier) @variable\n  \")\")\n\n; Comments\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/cylc/highlights.scm",
    "content": "[\n  (jinja2_expression)\n  (jinja2_statement)\n  (jinja2_comment)\n  (jinja2_shebang)\n] @special\n\n(include_statement\n  directive: _ @keyword.directive\n  path: _ @string.special.path)\n\n(comment) @comment.line\n\n(graph_section\n  name: _? @label)\n\n(task_section\n  name: (_\n    (task_name) @namespace))\n\n(top_section\n  brackets_open: _ @punctuation.bracket\n  name: _? @label\n  brackets_close: _ @punctuation.bracket)\n\n(sub_section_1\n  brackets_open: _ @punctuation.bracket\n  name: _? @label\n  brackets_close: _ @punctuation.bracket)\n\n(sub_section_2\n  brackets_open: _ @punctuation.bracket\n  name: _? @label\n  brackets_close: _ @punctuation.bracket)\n\n(runtime_section\n  brackets_open: _ @punctuation.bracket\n  name: _? @label\n  brackets_close: _ @punctuation.bracket)\n\n(graph_setting\n  key: (_) @constant.numeric.integer\n  operator: (_)? @operator)\n\n(quoted_graph_string\n  quotes_open: _ @string\n  quotes_close: _ @string)\n\n(multiline_graph_string\n  quotes_open: _ @string\n  quotes_close: _ @string)\n\n[\n  (graph_logical)\n  (graph_arrow)\n  (graph_parenthesis)\n] @operator\n\n(intercycle_annotation\n  (recurrence) @constant.numeric.integer)\n\n(graph_task\n  xtrigger: _? @operator\n  suicide: _? @operator\n  name: _ @namespace)\n\n(task_parameter\n  \"<\" @tag\n  name: (_)? @special\n  \",\"? @tag\n  \"=\"? @tag\n  selection: (_)? @special\n  \">\" @tag)\n\n(intercycle_annotation\n  \"[\" @tag\n  (recurrence)? @constant.numeric.integer\n  \"]\" @tag)\n\n(task_output\n  \":\" @tag\n  (nametag) @variable.other)\n\n(task_output\n  \"?\"? @tag)\n\n(setting\n  key: (key) @variable\n  operator: (_)? @operator\n  value: [\n    (unquoted_string) @string\n    (quoted_string) @string\n    (multiline_string) @string\n    (boolean) @constant.builtin.boolean\n    (integer) @constant.numeric.integer\n  ]?)\n\n(datetime) @constant.numeric.float\n"
  },
  {
    "path": "runtime/queries/cylc/indents.scm",
    "content": "[\n  (top_section)\n  (sub_section_1)\n  (sub_section_2)\n  (graph_section)\n  (runtime_section)\n  (task_section)\n] @indent\n\n[\n  (top_section)\n  (sub_section_1)\n  (sub_section_2)\n  (graph_section)\n  (runtime_section)\n  (task_section)\n] @extend\n\n(line_continuation) @indent.always\n"
  },
  {
    "path": "runtime/queries/cylc/injections.scm",
    "content": "((setting\n  key: (key) @key\n  (#match? @key \"^script$|-script$|^script-\")\n  value: (_\n    (string_content) @injection.content))\n  (#set! \"injection.language\" \"bash\"))\n\n; Requires no spacing around \"=\" in environment settings for proper highlighting.\n; Could be improved if Tree-sitter allowed to specify the target node of the injected\n; language, instead of always using the root node.\n; See this proposal:\n; https://github.com/tree-sitter/tree-sitter/issues/3625\n((task_section\n  (sub_section_2\n    name: (_) @section_name\n    (#eq? @section_name \"environment\")\n    (setting) @injection.content))\n  (#set! \"injection.language\" \"bash\")\n  (#set! injection.combined)\n  (#set! injection.include-children))\n"
  },
  {
    "path": "runtime/queries/cylc/textobjects.scm",
    "content": "(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(_\n  brackets_open: _\n  name: _?\n  brackets_close: _\n  _* @class.inside) @class.around\n\n(setting\n  value: _? @function.inside) @function.around\n\n(graph_setting\n  value: _? @function.inside) @function.around\n\n(graph_string_content\n  (graph_task) @entry.inside)\n\n(task_parameter\n  ((_) @parameter.inside\n    .\n    \",\"? @parameter.around) @parameter.around)\n"
  },
  {
    "path": "runtime/queries/cython/folds.scm",
    "content": "[\n  (function_definition)\n  (class_definition)\n  (while_statement)\n  (for_statement)\n  (if_statement)\n  (with_statement)\n  (try_statement)\n  (match_statement)\n  (import_from_statement)\n  (parameters)\n  (argument_list)\n  (parenthesized_expression)\n  (generator_expression)\n  (list_comprehension)\n  (set_comprehension)\n  (dictionary_comprehension)\n  (tuple)\n  (list)\n  (set)\n  (dictionary)\n  (string)\n] @fold\n\n[\n  (import_statement)\n  (import_from_statement)\n]+ @fold\n"
  },
  {
    "path": "runtime/queries/cython/highlights.scm",
    "content": "; Punctuation\n\n[\",\" \".\" \":\" \";\" (ellipsis)] @punctuation.delimiter\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n(interpolation\n  \"{\" @punctuation.special\n  \"}\" @punctuation.special)\n\n; Identifier naming conventions\n\n(identifier) @variable\n\n((identifier) @constructor\n (#match? @constructor \"^[A-Z]\"))\n\n((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z_]*$\"))\n\n; Function calls\n\n(decorator) @function\n\n(call\n  function: (attribute attribute: (identifier) @function.method))\n(call\n  function: (identifier) @function)\n\n; Builtin functions\n\n((call\n  function: (identifier) @function.builtin)\n (#any-of?\n   @function.builtin\n   \"abs\" \"all\" \"any\" \"ascii\" \"bin\" \"bool\" \"breakpoint\" \"bytearray\" \"bytes\" \"callable\" \"chr\" \"classmethod\" \"compile\" \"complex\" \"delattr\" \"dict\" \"dir\" \"divmod\" \"enumerate\" \"eval\" \"exec\" \"filter\" \"float\" \"format\" \"frozenset\" \"getattr\" \"globals\" \"hasattr\" \"hash\" \"help\" \"hex\" \"id\" \"input\" \"int\" \"isinstance\" \"issubclass\" \"iter\" \"len\" \"list\" \"locals\" \"map\" \"max\" \"memoryview\" \"min\" \"next\" \"object\" \"oct\" \"open\" \"ord\" \"pow\" \"print\" \"property\" \"range\" \"repr\" \"reversed\" \"round\" \"set\" \"setattr\" \"slice\" \"sorted\" \"staticmethod\" \"str\" \"sum\" \"super\" \"tuple\" \"type\" \"vars\" \"zip\" \"__import__\"))\n\n; Types\n\n(maybe_typed_name\n  type: ((_) @type))\n\n(type\n  (identifier) @type)\n\n(c_type\n  type: ((_) @type))\n(c_type\n  ((identifier) @type))\n(c_type\n  ((int_type) @type))\n\n(maybe_typed_name\n  name: ((identifier) @variable))\n\n; Function definitions\n\n(function_definition\n  name: (identifier) @function)\n\n(cdef_statement\n  (cvar_def\n    (maybe_typed_name\n      name: ((identifier) @function))\n    (c_function_definition)))\n\n(cvar_decl\n  (c_type\n    ([(identifier) (int_type)]))\n  (c_name\n    ((identifier) @function))\n  (c_function_definition))\n\n(attribute attribute: (identifier) @variable.other.member)\n\n; Literals\n\n[\n  (none)\n] @constant.builtin\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n\n(comment) @comment\n(string) @string\n(escape_sequence) @constant.character.escape\n\n(interpolation\n  \"{\" @punctuation.special\n  \"}\" @punctuation.special) @embedded\n\n[\n  \"-\"\n  \"-=\"\n  \"!=\"\n  \"*\"\n  \"**\"\n  \"**=\"\n  \"*=\"\n  \"/\"\n  \"//\"\n  \"//=\"\n  \"/=\"\n  \"&\"\n  \"&=\"\n  \"%\"\n  \"%=\"\n  \"^\"\n  \"^=\"\n  \"+\"\n  \"->\"\n  \"+=\"\n  \"<\"\n  \"<<\"\n  \"<<=\"\n  \"<=\"\n  \"<>\"\n  \"=\"\n  \":=\"\n  \"==\"\n  \">\"\n  \">=\"\n  \">>\"\n  \">>=\"\n  \"|\"\n  \"|=\"\n  \"~\"\n  \"@=\"\n  \"and\"\n  \"in\"\n  \"is\"\n  \"not\"\n  \"or\"\n \"@\"\n] @operator\n\n[\n  \"as\"\n  \"assert\"\n  \"async\"\n  \"await\"\n  \"break\"\n  \"class\"\n  \"continue\"\n  \"def\"\n  \"del\"\n  \"elif\"\n  \"else\"\n  \"except\"\n  \"exec\"\n  \"finally\"\n  \"for\"\n  \"from\"\n  \"global\"\n  \"if\"\n  \"import\"\n  \"lambda\"\n  \"nonlocal\"\n  \"pass\"\n  \"print\"\n  \"raise\"\n  \"return\"\n  \"try\"\n  \"while\"\n  \"with\"\n  \"yield\"\n  \"match\"\n  \"case\"\n\n  ; cython-specific\n  \"cdef\"\n  \"cpdef\"\n  \"ctypedef\"\n  \"cimport\"\n  \"nogil\"\n  \"gil\"\n  \"extern\"\n  \"inline\"\n  \"public\"\n  \"readonly\"\n  \"struct\"\n  \"union\"\n  \"enum\"\n  \"fused\"\n  \"property\"\n  \"namespace\"\n  \"cppclass\"\n  \"const\"\n] @keyword.control\n\n(dotted_name\n  (identifier)* @namespace)\n\n(aliased_import\n  alias: (identifier) @namespace)\n"
  },
  {
    "path": "runtime/queries/cython/indents.scm",
    "content": "[\n  (list)\n  (tuple)\n  (dictionary)\n  (set)\n  (if_statement)\n  (for_statement)\n  (while_statement)\n  (with_statement)\n  (try_statement)\n  (match_statement)\n  (case_clause)\n  (import_from_statement)\n\n  (parenthesized_expression)\n  (generator_expression)\n  (list_comprehension)\n  (set_comprehension)\n  (dictionary_comprehension)\n\n  (tuple_pattern)\n  (list_pattern)\n  (argument_list)\n  (parameters)\n  (binary_operator)\n\n  (function_definition)\n  (cdef_statement)\n  (class_definition)\n] @indent\n\n; Workaround for the tree-sitter grammar creating large errors when a\n; try_statement is missing the except/finally clause\n\n(ERROR\n  \"try\"\n  .\n  \":\" @indent @extend)\n(ERROR\n  .\n  \"def\") @indent @extend\n(ERROR\n  (block) @indent @extend\n  (#set! \"scope\" \"all\"))\n\n(ERROR\n  \"try\"\n  .\n  \":\"\n  (ERROR\n    (block\n      (expression_statement\n        (identifier) @_except) @indent.branch))\n  (#eq? @_except \"except\"))\n\n[\n  (if_statement)\n  (for_statement)\n  (while_statement)\n  (with_statement)\n  (try_statement)\n  (match_statement)\n  (case_clause)\n\n  (cdef_statement)\n  (function_definition)\n  (class_definition)\n] @extend\n\n[\n  (return_statement)\n  (break_statement)\n  (continue_statement)\n  (raise_statement)\n  (pass_statement)\n] @extend.prevent-once\n\n[\n  \")\"\n  \"]\"\n  \"}\"\n] @outdent\n(elif_clause\n  \"elif\" @outdent)\n(else_clause\n  \"else\" @outdent)\n\n(parameters\n  .\n  (identifier) @anchor\n  (#set! \"scope\" \"tail\")) @align\n\n(argument_list\n  .\n  (_) @anchor\n  (#set! \"scope\" \"tail\")) @align\n"
  },
  {
    "path": "runtime/queries/cython/injections.scm",
    "content": "(call\n  function: (attribute\n    object: (identifier) @_re)\n  arguments: (argument_list\n    .\n    (string\n      (string_content) @injection.content))\n  (#eq? @_re \"re\")\n  (#set! injection.language \"regex\"))\n\n((binary_operator\n  left: (string\n    (string_content) @injection.content)\n  operator: \"%\")\n  (#set! injection.language \"printf\"))\n\n((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/cython/locals.scm",
    "content": "; Program structure\n(module) @local.scope\n\n(class_definition\n  body: (block\n    (expression_statement\n      (assignment\n        left: (identifier) @local.definition)))) @local.scope\n\n(class_definition\n  body: (block\n    (expression_statement\n      (assignment\n        left: (_\n          (identifier) @local.definition))))) @local.scope\n\n; Imports\n(aliased_import\n  alias: (identifier) @local.definition.namespace)\n\n(import_statement\n  name: (dotted_name\n    (identifier) @local.definition.namespace))\n\n(import_from_statement\n  name: (dotted_name\n    (identifier) @local.definition.namespace))\n\n; Function with parameters, defines parameters\n(parameters\n  (identifier) @local.definition.variable.parameter)\n\n(default_parameter\n  (identifier) @local.definition.variable.parameter)\n\n(typed_parameter\n  (identifier) @local.definition.variable.parameter)\n\n(typed_default_parameter\n  (identifier) @local.definition.variable.parameter)\n\n; *args parameter\n(parameters\n  (list_splat_pattern\n    (identifier) @local.definition))\n\n; **kwargs parameter\n(parameters\n  (dictionary_splat_pattern\n    (identifier) @local.definition.variable.parameter))\n\n(class_definition\n  body: (block\n    (function_definition\n      name: (identifier) @local.definition.function)))\n\n; Loops\n; not a scope!\n(for_in_loop\n  left: (pattern_list\n    (identifier) @local.definition.variable))\n\n(for_in_loop\n  left: (tuple_pattern\n    (identifier) @local.definition.variable))\n\n(for_in_loop\n  left: (identifier) @local.definition.variable)\n\n; not a scope!\n;(while_statement) @local.scope\n; for in list comprehension\n(for_in_clause\n  left: (identifier) @local.definition.variable)\n\n(for_in_clause\n  left: (tuple_pattern\n    (identifier) @local.definition.variable))\n\n(for_in_clause\n  left: (pattern_list\n    (identifier) @local.definition.variable))\n\n(dictionary_comprehension) @local.scope\n\n(list_comprehension) @local.scope\n\n(set_comprehension) @local.scope\n\n; Assignments\n(assignment\n  left: (identifier) @local.definition.variable)\n\n(assignment\n  left: (pattern_list\n    (identifier) @local.definition.variable))\n\n(assignment\n  left: (tuple_pattern\n    (identifier) @local.definition.variable))\n\n(assignment\n  left: (attribute\n    (identifier)\n    (identifier) @local.definition.variable))\n\n; Walrus operator  x := 1\n(named_expression\n  (identifier) @local.definition.variable)\n\n(as_pattern\n  alias: (as_pattern_target) @local.definition.variable)\n\n; REFERENCES\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/cython/tags.scm",
    "content": "(module (expression_statement (assignment left: (identifier) @name) @definition.constant))\n\n(class_definition\n  name: (identifier) @name) @definition.class\n\n(function_definition\n  name: (identifier) @name) @definition.function\n\n(call\n  function: [\n      (identifier) @name\n      (attribute\n        attribute: (identifier) @name)\n  ]) @reference.call\n"
  },
  {
    "path": "runtime/queries/d/highlights.scm",
    "content": "; highlights.scm\n;\n; Highlighting queries for D code for use by Tree-Sitter.\n;\n; Copyright 2022 Garrett D'Amore\n;\n; Distributed under the MIT License.\n; (See accompanying file LICENSE.txt or https://opensource.org/licenses/MIT)\n; SPDX-License-Identifier: MIT\n\n; these are listed first, because they override keyword queries\n(identity_expression (in) @operator)\n(identity_expression (is) @operator)\n\n(storage_class) @keyword.storage\n\n(function_declaration (identifier) @function)\n\n(call_expression (identifier) @function)\n(call_expression (type (identifier) @function))\n\n(module_fqn) @namespace\n\n[\n    (abstract)\n    (alias)\n    (align)\n    (asm)\n    (assert)\n    (auto)\n    (cast)\n    (const)\n    (debug)\n    (delete)\n    (deprecated)\n    (export)\n    (extern)\n    (final)\n    (immutable)\n    (in)\n    (inout)\n    (invariant)\n    (is)\n    (lazy)\n    ; \"macro\" - obsolete\n    (mixin)\n    (module)\n    (new)\n    (nothrow)\n    (out)\n    (override)\n    (package)\n    (pragma)\n    (private)\n    (protected)\n    (public)\n    (pure)\n    (ref)\n    (scope)\n    (shared)\n    (static)\n    (super)\n    (synchronized)\n    (template)\n    (this)\n    (throw)\n    (typeid)\n    (typeof)\n    (unittest)\n    (version)\n    (with)\n    (gshared)\n    (traits)\n    (vector)\n    (parameters_)\n] @keyword\n\n[\n    (class)\n    (struct)\n    (interface)\n    (union)\n    (enum)\n    (function)\n    (delegate)\n] @keyword.storage.type\n\n[\n    (break)\n    (case)\n    (catch)\n    (continue)\n    (do)\n    (default)\n    (finally)\n    (else)\n    (goto)\n    (if)\n    (switch)\n    (try)\n] @keyword.control\n\n(return) @keyword.control.return\n\n(import) @keyword.control.import\n\n[\n    (for)\n    (foreach)\n    (foreach_reverse)\n    (while)\n] @keyword.control.repeat\n\n[\n    (not_in)\n    (not_is)\n    \"/=\"\n    \"/\"\n    \"..\"\n    \"...\"\n    \"&\"\n    \"&=\"\n    \"&&\"\n    \"|\"\n    \"|=\"\n    \"||\"\n    \"-\"\n    \"-=\"\n    \"--\"\n    \"+\"\n    \"+=\"\n    \"++\"\n    \"<\"\n    \"<=\"\n    \"<<\"\n    \"<<=\"\n    \">\"\n    \">=\"\n    \">>=\"\n    \">>>=\"\n    \">>\"\n    \">>>\"\n    \"!\"\n    \"!=\"\n    \"?\"\n    \"$\"\n    \"=\"\n    \"==\"\n    \"*\"\n    \"*=\"\n    \"%\"\n    \"%=\"\n    \"^\"\n    \"^=\"\n    \"^^\"\n    \"^^=\"\n    \"~\"\n    \"~=\"\n    \"@\"\n    \"=>\"\n] @operator\n\n[\n    \"(\"\n    \")\"\n    \"[\"\n    \"]\"\n] @punctuation.bracket\n\n[\n    \";\"\n    \".\"\n    \":\"\n    \",\"\n] @punctuation.delimiter\n\n[\n    (true)\n    (false)\n] @constant.builtin.boolean\n\n(null) @constant.builtin\n\n(special_keyword) @constant.builtin\n\n(directive) @keyword.directive\n(shebang) @keyword.directive\n\n(comment) @comment\n\n[\n    (void)\n    (bool)\n    (byte)\n    (ubyte)\n    (char)\n    (short)\n    (ushort)\n    (wchar)\n    (dchar)\n    (int)\n    (uint)\n    (long)\n    (ulong)\n    (real)\n    (double)\n] @type.builtin\n\n[\n    (cent)\n    (ucent)\n    (ireal)\n    (idouble)\n    (ifloat)\n    (creal)\n    (double)\n    (cfloat)\n] @warning ; these types are deprecated\n\n(identifier) @variable\n\n(label (identifier) @label)\n(goto_statement (goto) @keyword (identifier) @label)\n\n(string_literal) @string\n(int_literal) @constant.numeric.integer\n(float_literal) @constant.numeric.float\n(char_literal) @constant.character\n(at_attribute) @attribute\n\n; everything after __EOF_ is plain text\n(end_file) @ui.text\n"
  },
  {
    "path": "runtime/queries/d/indents.scm",
    "content": "[\n  (parameters)\n  (template_parameters)\n  (expression_statement)\n  (aggregate_body)\n  (function_body)\n  (scope_statement)\n  (block_statement)\n  (case_statement)\n] @indent\n\n[\n  (case)\n  (default)\n  \"}\"\n  \"]\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/d/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/d/textobjects.scm",
    "content": "(function_declaration (function_body) @function.inside) @function.around\n(comment) @comment.inside\n(comment)+ @comment.around\n(class_declaration (aggregate_body) @class.inside) @class.around\n(interface_declaration (aggregate_body) @class.inside) @class.around\n(struct_declaration (aggregate_body) @class.inside) @class.around\n(unittest_declaration (block_statement) @test.inside) @test.around\n(parameter) @parameter.inside\n(template_parameter) @parameter.inside\n"
  },
  {
    "path": "runtime/queries/dart/highlights.scm",
    "content": "(dotted_identifier_list) @string\n\n; Methods\n; --------------------\n(super) @function.builtin\n\n(function_expression_body (identifier) @function.method)\n((identifier)(selector (argument_part)) @function.method)\n\n; Annotations\n; --------------------\n(annotation\n  name: (identifier) @attribute)\n(marker_annotation\n  name: (identifier) @attribute)\n\n; Types\n; --------------------\n(class_definition\n  name: (identifier) @type)\n\n(constructor_signature\n  name: (identifier) @function.method)\n\n(function_signature\n  name: (identifier) @function.method)\n\n(getter_signature\n  (identifier) @function.builtin)\n\n(setter_signature\n  name: (identifier) @function.builtin)\n\n(enum_declaration\n  name: (identifier) @type)\n\n(enum_constant\n  name: (identifier) @type.builtin)\n\n(void_type) @type.builtin\n\n((scoped_identifier\n  scope: (identifier) @type)\n (#match? @type \"^[a-zA-Z]\"))\n\n((scoped_identifier\n  scope: (identifier) @type\n  name: (identifier) @type)\n (#match? @type \"^[a-zA-Z]\"))\n\n; the DisabledDrawerButtons in : const DisabledDrawerButtons(history: true),\n(type_identifier) @type.builtin\n\n; Variables\n; --------------------\n; the \"File\" in var file = File();\n((identifier) @namespace\n (#match? @namespace \"^_?[A-Z].*[a-z]\")) ; catch Classes or IClasses not CLASSES\n\n(\"Function\" @type.builtin)\n(inferred_type) @type.builtin\n\n; properties\n(unconditional_assignable_selector\n  (identifier) @variable.other.member)\n\n(conditional_assignable_selector\n  (identifier) @variable.other.member)\n\n; assignments\n; --------------------\n; the \"strings\" in : strings = \"some string\"\n(assignment_expression\n  left: (assignable_expression) @variable)\n\n(this) @variable.builtin\n\n; Parameters\n; --------------------\n(formal_parameter\n    name: (identifier) @variable)\n\n(named_argument\n  (label (identifier) @variable))\n\n; Literals\n; --------------------\n[\n  (hex_integer_literal)\n  (decimal_integer_literal)\n  (decimal_floating_point_literal)\n  ;(octal_integer_literal)\n  ;(hex_floating_point_literal)\n] @constant.numeric.integer\n\n(symbol_literal) @string.special.symbol\n(string_literal) @string\n\n[\n  (const_builtin)\n  (final_builtin)\n] @variable.builtin\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(null_literal) @constant.builtin\n\n(comment) @comment.line\n(documentation_comment) @comment.block.documentation\n\n; Tokens\n; --------------------\n(template_substitution\n  \"$\" @punctuation.special\n  \"{\" @punctuation.special\n  \"}\" @punctuation.special\n) @embedded\n\n(template_substitution\n  \"$\" @punctuation.special\n  (identifier_dollar_escaped) @variable\n) @embedded\n\n(escape_sequence) @constant.character.escape\n\n; Punctuation\n;---------------------\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n]  @punctuation.bracket\n\n[\n  \";\"\n  \".\"\n  \",\"\n  \":\"\n] @punctuation.delimiter\n\n; Operators\n;---------------------\n[\n \"@\"\n \"?\"\n \"=>\"\n \"..\"\n \"==\"\n \"&&\"\n \"%\"\n \"<\"\n \">\"\n \"=\"\n \">=\"\n \"<=\"\n \"||\"\n (multiplicative_operator)\n (increment_operator)\n (is_operator)\n (prefix_operator)\n (equality_operator)\n (additive_operator)\n] @operator\n\n; Keywords\n; --------------------\n[\"import\" \"library\" \"export\"] @keyword.control.import\n[\"do\" \"while\" \"continue\" \"for\"] @keyword.control.repeat\n[\"return\" \"yield\"] @keyword.control.return\n[\"as\" \"in\" \"is\"] @keyword.operator\n\n[\n  \"?.\"\n  \"??\"\n  \"if\"\n  \"else\"\n  \"switch\"\n  \"default\"\n  \"late\"\n] @keyword.control.conditional\n\n[\n  \"try\"\n  \"throw\"\n  \"catch\"\n  \"finally\"\n  (break_statement)\n] @keyword.control.exception\n\n; Reserved words (cannot be used as identifiers)\n[\n    (case_builtin)\n    \"abstract\"\n    \"async\"\n    \"async*\"\n    \"await\"\n    \"base\"\n    \"class\"\n    \"covariant\"\n    \"deferred\"\n    \"dynamic\"\n    \"enum\"\n    \"extends\"\n    \"extension\"\n    \"external\"\n    \"factory\"\n    \"final\"\n    \"Function\"\n    \"get\"\n    \"implements\"\n    \"interface\"\n    \"mixin\"\n    \"new\"\n    \"on\"\n    \"operator\"\n    \"part\"\n    \"required\"\n    \"sealed\"\n    \"set\"\n    \"show\"\n    \"static\"\n    \"super\"\n    \"sync*\"\n    \"typedef\"\n    \"with\"\n] @keyword\n\n; when used as an identifier:\n((identifier) @variable.builtin\n (#match? @variable.builtin \"^(abstract|as|base|covariant|deferred|dynamic|export|external|factory|final|Function|get|implements|import|interface|library|operator|mixin|part|sealed|set|static|typedef)$\"))\n"
  },
  {
    "path": "runtime/queries/dart/indents.scm",
    "content": "; things surrounded by ({[]})\n[\n  (template_substitution)\n  (list_literal)\n  (set_or_map_literal)\n  (parenthesized_expression)\n  (arguments)\n  (index_selector)\n  (block)\n  (assertion_arguments)\n  (switch_block)\n  (catch_parameters)\n  (for_loop_parts)\n  (configuration_uri_condition)\n  (enum_body)\n  (class_body)\n  (extension_body)\n  (parameter_type_list)\n  (optional_positional_parameter_types)\n  (named_parameter_types)\n  (formal_parameter_list)\n  (optional_formal_parameters)\n] @indent\n\n; control flow statement which accept one line as body\n\n(for_statement\n  body: _ @indent\n  (#not-kind-eq? @indent block)\n  (#set! \"scope\" \"all\")\n)\n\n(while_statement\n  body: _ @indent\n  (#not-kind-eq? @indent block)\n  (#set! \"scope\" \"all\")\n)\n\n(do_statement\n  body: _ @indent\n  (#not-kind-eq? @indent block)\n  (#set! \"scope\" \"all\")\n)\n\n(if_statement\n  consequence: _ @indent\n  (#not-kind-eq? @indent block)\n  (#set! \"scope\" \"all\")\n)\n(if_statement\n  alternative: _ @indent\n  (#not-kind-eq? @indent if_statement)\n  (#not-kind-eq? @indent block)\n  (#set! \"scope\" \"all\")\n)\n(if_statement\n  \"else\" @else\n  alternative: (if_statement) @indent\n  (#not-same-line? @indent @else)\n  (#set! \"scope\" \"all\")\n)\n\n(if_element\n  consequence: _ @indent\n  (#set! \"scope\" \"all\")\n)\n(if_element\n  alternative: _ @indent\n  (#not-kind-eq? @indent if_element)\n  (#set! \"scope\" \"all\")\n)\n(if_element\n  \"else\" @else\n  alternative: (if_element) @indent\n  (#not-same-line? @indent @else)\n  (#set! \"scope\" \"all\")\n)\n\n(for_element\n  body: _ @indent\n  (#set! \"scope\" \"all\")\n)\n\n; simple statements\n[\n  (local_variable_declaration)\n  (break_statement)\n  (continue_statement)\n  (return_statement)\n  (yield_statement)\n  (yield_each_statement)\n  (expression_statement)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n\n"
  },
  {
    "path": "runtime/queries/dart/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/dart/locals.scm",
    "content": "; Scopes\n;-------\n\n[\n (block)\n (try_statement)\n (catch_clause)\n (finally_clause)\n] @local.scope\n\n; Definitions\n;------------\n\n(class_definition\n body: (_) @local.definition.type)\n\n; References\n;------------\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/dart/rainbows.scm",
    "content": "[\n  (configuration_uri_condition)\n  (class_body)\n  (block)\n  (arguments)\n  (list_literal)\n  (formal_parameter_list)\n  (optional_formal_parameters)\n  (parameter_type_list)\n  (record_type)\n  (template_substitution)\n  (index_selector)\n  (if_statement)\n  (assertion_arguments)\n] @rainbow.scope\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/dart/textobjects.scm",
    "content": "(class_definition\n  body: (_) @class.inside) @class.around\n\n(mixin_declaration\n  (class_body) @class.inside) @class.around\n\n(extension_declaration\n  (extension_body) @class.inside) @class.around\n\n(enum_declaration\n  body: (_) @class.inside) @class.around\n\n(type_alias) @class.around\n\n(_\n  (\n    [\n      (getter_signature)\n      (setter_signature)\n      (function_signature)\n      (method_signature)\n      (constructor_signature)\n    ]\n    .\n    (function_body) @function.inside @function.around\n  )  @function.around\n)\n\n(declaration\n  [\n    (constant_constructor_signature)\n    (constructor_signature)\n    (factory_constructor_signature)\n    (redirecting_factory_constructor_signature)\n    (getter_signature)\n    (setter_signature)\n    (operator_signature)\n    (function_signature)\n  ]\n) @function.around\n\n(lambda_expression\n    body: (_) @function.inside\n) @function.around\n\n(function_expression\n    body: (_) @function.inside\n) @function.around\n\n[\n  (comment)\n  (documentation_comment)\n] @comment.inside\n\n(comment)+ @comment.around\n\n(documentation_comment)+ @comment.around\n\n(formal_parameter_list\n  (\n    (formal_parameter) @parameter.inside . \",\"? @parameter.around\n  ) @parameter.around\n)\n\n(optional_formal_parameters\n  (\n    (formal_parameter) @parameter.inside . \",\"? @parameter.around\n  ) @parameter.around\n)\n\n(arguments\n  (\n    [\n      (argument) @parameter.inside\n      (named_argument (label) . (_)* @parameter.inside)\n    ]\n    . \",\"? @parameter.around\n  ) @parameter.around\n)\n\n(type_arguments\n  (\n    ((_) . (\".\" . (_) @parameter.inside @parameter.around)?) @parameter.inside\n    . \",\"? @parameter.around\n  ) @parameter.around\n)\n\n(expression_statement\n  ((identifier) @_name (#any-of? @_name \"test\" \"testWidgets\"))\n  .\n  (selector (argument_part (arguments . (_) . (argument) @test.inside)))\n) @test.around\n\n"
  },
  {
    "path": "runtime/queries/dbml/highlights.scm",
    "content": "\n; comments highlighting\n(comment) @comment\n\n; keyword highlighting\n(keyword_def) @keyword\n(keyword_enum) @keyword\n(keyword_ref) @keyword\n\n; identify blocks and definitions\n(definition) @function\n\n; for identifiers\n(identifier) @variable\n(type) @keyword\n\n; Highlight special types for database/data types\n(\"Project\" ) @type\n(\"Table\" ) @type\n(\"TableGroup\" ) @type\n(\"database_type\" ) @variable\n\n; string and number constants\n(\"'''\") @constant.character.escape\n(string) @string\n(number) @constant.numeric\n\n; brackets\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n; brackets\n[\n  \":\"\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n"
  },
  {
    "path": "runtime/queries/debian/highlights.scm",
    "content": "(comment) @comment\n(field_name) @tag\n"
  },
  {
    "path": "runtime/queries/devicetree/highlights.scm",
    "content": "[\n  \"/dts-v1/\"\n  \"/memreserve/\"\n  \"/delete-node/\"\n  \"/delete-property/\"\n] @keyword\n\n[\n  \"#define\"\n  \"#include\"\n] @keyword.directive\n\n[\n  \"!\"\n  \"~\"\n  \"-\"\n  \"+\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"||\"\n  \"&&\"\n  \"|\"\n  \"^\"\n  \"&\"\n  \"==\"\n  \"!=\"\n  \">\"\n  \">=\"\n  \"<=\"\n  \">\"\n  \"<<\"\n  \">>\"\n] @operator\n\n[\n  \",\"\n  \";\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"<\"\n  \">\"\n] @punctuation.bracket\n\n(string_literal) @string\n\n(integer_literal) @constant.numeric.integer\n\n(identifier) @variable\n\n(call_expression\n  function: (identifier) @function)\n\n(labeled_item\n  label: (identifier) @label)\n\n(unit_address) @tag\n\n(reference) @constant\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/dhall/highlights.scm",
    "content": ";; Literals\n(integer_literal) @constant.numeric.integer\n(natural_literal) @constant.numeric.integer\n(double_literal) @constant.numeric.float\n(boolean_literal) @constant.builtin.boolean\n(builtin \"None\") @constant.builtin\n\n;; Text\n(text_literal) @string\n(interpolation \"}\" @string)\n(double_quote_escaped) @constant.character.escape\n(single_quote_escaped) @constant.character.escape\n\n;; Imports\n(local_import) @string.special.path\n(http_import) @string.special.url\n(env_import) @keyword\n(env_variable) @string.special\n(import_hash) @string.special\n(missing_import) @keyword.control.import\n[ (import_as_location) (import_as_text) ] @type\n\n;; Comments\n(block_comment) @comment.block\n(line_comment) @comment.line\n\n;; Types\n([\n  (let_binding (label) @type)\n  (union_type_entry (label) @type)\n] (#match? @type \"^[A-Z]\"))\n((primitive_expression\n  (identifier (label) @type)\n  (selector (label) @type)?) @whole_identifier\n  (#match? @whole_identifier \"(?:^|\\\\.)[A-Z][^.]*$\"))\n\n;; Variables\n(identifier [\n  (label) @variable\n  (de_bruijn_index) @operator\n])\n(let_binding label: (label) @variable)\n(lambda_expression label: (label) @variable.parameter)\n(record_literal_entry (label) @variable.other.member)\n(record_type_entry (label) @variable.other.member)\n(selector) @variable.other.member\n\n;; Keywords\n[\n  \"let\"\n  \"in\"\n  \"assert\"\n] @keyword\n[\n  \"using\"\n  \"as\"\n  \"with\"\n] @keyword.operator\n\n;; Operators\n[\n  (type_operator)\n  (assign_operator)\n  (lambda_operator)\n  (arrow_operator)\n  (infix_operator)\n  (completion_operator)\n  (assert_operator)\n  (forall_operator)\n  (empty_record_literal)\n] @operator\n\n;; Builtins\n(builtin_function) @function.builtin\n(builtin [\n  \"Bool\"\n  \"Optional\"\n  \"Natural\"\n  \"Integer\"\n  \"Double\"\n  \"Text\"\n  \"Date\"\n  \"Time\"\n  \"TimeZone\"\n  \"List\"\n  \"Type\"\n  \"Kind\"\n  \"Sort\"\n] @type.builtin)\n\n;; Punctuation\n[ \",\" \"|\" ] @punctuation.delimiter\n(selector_dot) @punctuation.delimiter\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"<\"\n  \">\"\n] @punctuation.bracket\n\n;; Conditionals\n[\n  \"if\"\n  \"then\"\n  \"else\"\n] @keyword.control.conditional\n"
  },
  {
    "path": "runtime/queries/dhall/injections.scm",
    "content": "([(block_comment) (line_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/dhall/textobjects.scm",
    "content": "(lambda_expression\n  (label) @parameter.inside\n  (expression) @function.inside\n) @function.around\n\n(forall_expression\n  (label) @parameter.inside\n  (expression) @function.inside\n) @function.around\n\n(assert_expression\n  (expression) @test.inside\n) @test.around\n\n[\n  (block_comment_content)\n  (line_comment_content)\n] @comment.inside\n\n[\n  (block_comment)\n  (line_comment)\n] @comment.around\n"
  },
  {
    "path": "runtime/queries/diff/highlights.scm",
    "content": "[(addition) (new_file)] @diff.plus\n[(deletion) (old_file)] @diff.minus\n\n(commit) @constant\n(location) @attribute\n(command) @markup.bold\n"
  },
  {
    "path": "runtime/queries/djot/highlights.scm",
    "content": "(heading) @markup.heading\n\n((heading\n  (marker) @markup.heading.marker) @markup.heading.1\n  (#eq? @markup.heading.marker \"# \"))\n\n((heading\n  (marker) @markup.heading.marker) @markup.heading.2\n  (#eq? @markup.heading.marker \"## \"))\n\n((heading\n  (marker) @markup.heading.marker) @markup.heading.3\n  (#eq? @markup.heading.marker \"### \"))\n\n((heading\n  (marker) @markup.heading.marker) @markup.heading.4\n  (#eq? @markup.heading.marker \"##### \"))\n\n((heading\n  (marker) @markup.heading.marker) @markup.heading.5\n  (#eq? @markup.heading.marker \"###### \"))\n\n((heading\n  (marker) @markup.heading.marker) @markup.heading.6\n  (#eq? @markup.heading.marker \"####### \"))\n\n(thematic_break) @special\n\n[\n  (div_marker_begin)\n  (div_marker_end)\n] @tag\n\n[\n  (code_block)\n  (raw_block)\n  (frontmatter)\n] @markup.raw.block\n\n[\n  (code_block_marker_begin)\n  (code_block_marker_end)\n  (raw_block_marker_begin)\n  (raw_block_marker_end)\n] @punctuation.bracket\n\n(language) @type.enum.variant\n\n(inline_attribute _ @attribute)\n\n(language_marker) @punctuation.delimiter\n\n[\n  (block_quote)\n  (block_quote_marker)\n] @markup.quote\n\n(table_header) @markup.heading\n\n(table_header \"|\" @punctuation.special)\n\n(table_row \"|\" @punctuation.special)\n\n(table_separator) @punctuation.special\n\n(table_caption (marker) @punctuation.special)\n\n(table_caption) @label\n\n[\n  (list_marker_dash)\n  (list_marker_plus)\n  (list_marker_star)\n  (list_marker_definition)\n] @markup.list.unnumbered\n\n[\n  (list_marker_decimal_period)\n  (list_marker_decimal_paren)\n  (list_marker_decimal_parens)\n  (list_marker_lower_alpha_period)\n  (list_marker_lower_alpha_paren)\n  (list_marker_lower_alpha_parens)\n  (list_marker_upper_alpha_period)\n  (list_marker_upper_alpha_paren)\n  (list_marker_upper_alpha_parens)\n  (list_marker_lower_roman_period)\n  (list_marker_lower_roman_paren)\n  (list_marker_lower_roman_parens)\n  (list_marker_upper_roman_period)\n  (list_marker_upper_roman_paren)\n  (list_marker_upper_roman_parens)\n] @markup.list.numbered\n\n(list_marker_task\n  (unchecked)) @markup.list.unchecked\n\n(list_marker_task\n  (checked)) @markup.list.checked\n\n(checked\n  [\n    \"x\"\n    \"X\"\n  ] @constant.builtin.boolean) @markup.list.checked\n\n[\n  (ellipsis)\n  (en_dash)\n  (em_dash)\n  (quotation_marks)\n] @punctuation.special\n\n(list_item (term) @constructor)\n\n(quotation_marks) @markup.quote\n\n((quotation_marks) @constant.character.escape\n  (#any-of? @constant.character.escape \"\\\\\\\"\" \"\\\\'\"))\n\n[\n  (hard_line_break)\n  (backslash_escape)\n] @constant.character.escape\n\n(emphasis) @markup.italic\n\n(strong) @markup.bold\n\n(symbol) @string.special.symbol\n\n(delete) @markup.strikethrough\n\n(insert) @markup.italic\n\n(highlighted) @markup.bold\n\n(superscript) @string.special.superscript\n\n(subscript) @string.special.subscript\n\n[\n  (emphasis_begin)\n  (emphasis_end)\n  (strong_begin)\n  (strong_end)\n  (superscript_begin)\n  (superscript_end)\n  (subscript_begin)\n  (subscript_end)\n  (highlighted_begin)\n  (highlighted_end)\n  (insert_begin)\n  (insert_end)\n  (delete_begin)\n  (delete_end)\n  (verbatim_marker_begin)\n  (verbatim_marker_end)\n  (math_marker)\n  (math_marker_begin)\n  (math_marker_end)\n  (raw_inline_attribute)\n  (raw_inline_marker_begin)\n  (raw_inline_marker_end)\n] @punctuation.bracket\n\n(math) @markup.raw\n\n(verbatim) @markup.raw\n\n(raw_inline) @markup.raw\n\n(comment) @comment.block\n\n(inline_comment) @comment.line\n\n(span\n  [\n    \"[\"\n    \"]\"\n  ] @punctuation.bracket)\n\n(inline_attribute\n  [\n    \"{\"\n    \"}\"\n  ] @punctuation.bracket)\n\n(block_attribute\n  [\n    \"{\"\n    \"}\"\n  ] @punctuation.bracket)\n\n[\n  (class)\n  (class_name)\n] @type\n\n; NOTE: Not perfectly semantically accurate, but a fair approximation.\n(identifier) @string.special.symbol\n\n(key_value \"=\" @operator)\n\n(key_value (key) @attribute)\n\n(key_value (value) @string)\n\n(link_text\n  [\n    \"[\"\n    \"]\"\n  ] @punctuation.bracket)\n\n(autolink\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n(inline_link (inline_link_destination) @markup.link.url)\n\n(link_reference_definition \":\" @punctuation.delimiter)\n\n(full_reference_link (link_text) @markup.link.text)\n\n(full_reference_link (link_label) @markup.link.label)\n\n(collapsed_reference_link \"[]\" @punctuation.bracket)\n\n(full_reference_link\n  [\n    \"[\"\n    \"]\"\n  ] @punctuation.bracket)\n\n(collapsed_reference_link (link_text) @markup.link.text)\n\n(inline_link (link_text) @markup.link.text)\n\n(full_reference_image (link_label) @markup.link.label)\n\n(full_reference_image\n  [\n    \"[\"\n    \"]\"\n  ] @punctuation.bracket)\n\n(collapsed_reference_image \"[]\" @punctuation.bracket)\n\n(image_description\n  [\n    \"![\"\n    \"]\"\n  ] @punctuation.bracket)\n\n(image_description) @label\n\n(link_reference_definition\n  [\n    \"[\"\n    \"]\"\n  ] @punctuation.bracket)\n\n(link_reference_definition (link_label) @markup.link.label)\n\n(inline_link_destination\n  [\n    \"(\"\n    \")\"\n  ] @punctuation.bracket)\n\n[\n  (autolink)\n  (inline_link_destination)\n  (link_destination)\n] @markup.link.url\n\n(footnote (reference_label) @markup.link.label)\n\n(footnote_reference (reference_label) @markup.link.label)\n\n[\n  (footnote_marker_begin)\n  (footnote_marker_end)\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/djot/injections.scm",
    "content": "(comment (content) @injection.content\n  (#set! injection.language \"comment\"))\n\n(math (content) @injection.content\n  (#set! injection.language \"latex\") (#set! injection.include-unnamed-children))\n\n(code_block\n  (language) @injection.language\n  (code) @injection.content (#set! injection.include-unnamed-children))\n\n(raw_block\n  (raw_block_info\n    (language) @injection.language)\n  (content) @injection.content (#set! injection.include-unnamed-children))\n\n(raw_inline\n  (content) @injection.content (#set! injection.include-unnamed-children)\n  (raw_inline_attribute\n    (language) @injection.language))\n"
  },
  {
    "path": "runtime/queries/docker-bake/folds.scm",
    "content": "; inherits: hcl\n"
  },
  {
    "path": "runtime/queries/docker-bake/highlights.scm",
    "content": "; inherits: hcl\n"
  },
  {
    "path": "runtime/queries/docker-bake/indents.scm",
    "content": "; inherits: hcl\n"
  },
  {
    "path": "runtime/queries/docker-bake/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n\n; https://docs.docker.com/build/bake/reference/#targetdockerfile-inline\n(block\n  (identifier) @_target (#eq? @_target \"target\")\n  (body\n    (attribute\n      (identifier) @_attr (#eq? @_attr \"dockerfile-inline\")\n      (expression\n        (template_expr\n          (heredoc_template\n            (template_literal) @injection.content)))))\n  (#set! injection.language \"dockerfile\"))\n\n(function_call\n  (identifier) @_name (#eq? @_name \"regex\")\n  (function_arguments\n    (expression\n      (literal_value\n        (string_lit\n          (template_literal) @injection.content))))\n  (#set! injection.language \"regex\"))\n"
  },
  {
    "path": "runtime/queries/docker-bake/rainbows.scm",
    "content": "; inherits: hcl\n"
  },
  {
    "path": "runtime/queries/docker-bake/tags.scm",
    "content": "; group\n; target\n; function\n; variable\n\n\n(block\n  (identifier) @_block (#eq? @_block \"group\")\n  (string_lit\n    (template_literal) @name)) @definition.module\n\n(block\n  (identifier) @_block (#eq? @_block \"target\")\n  (string_lit\n    (template_literal) @name)) @definition.struct\n\n(block\n  (identifier) @_block (#eq? @_block \"function\")\n  (string_lit\n    (template_literal) @name)) @definition.function\n\n(block\n  (identifier) @_block (#eq? @_block \"variable\")\n  (string_lit\n    (template_literal) @name)) @definition.constant\n\n\n; (config_file\n;   (body\n;   (block\n;     (identifier) @_block (#eq? @_block \"function\")\n;     (string_lit\n;       (template_literal) @name)) @definition.function))\n"
  },
  {
    "path": "runtime/queries/docker-bake/textobjects.scm",
    "content": "; inherits: hcl\n"
  },
  {
    "path": "runtime/queries/docker-compose/highlights.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/docker-compose/indents.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/docker-compose/injections.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/docker-compose/textobjects.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/dockerfile/highlights.scm",
    "content": "[\n\t\"FROM\"\n\t\"AS\"\n\t\"RUN\"\n\t\"CMD\"\n\t\"LABEL\"\n\t\"EXPOSE\"\n\t\"ENV\"\n\t\"ADD\"\n\t\"COPY\"\n\t\"ENTRYPOINT\"\n\t\"VOLUME\"\n\t\"USER\"\n\t\"WORKDIR\"\n\t\"ARG\"\n\t\"ONBUILD\"\n\t\"STOPSIGNAL\"\n\t\"HEALTHCHECK\"\n\t\"SHELL\"\n\t\"MAINTAINER\"\n\t\"CROSS_BUILD\"\n\t(heredoc_marker)\n\t(heredoc_end)\n] @keyword\n\n[\n\t\":\"\n\t\"@\"\n] @operator\n\n(comment) @comment\n\n\n(image_spec\n\t(image_tag\n\t\t\":\" @punctuation.special)\n\t(image_digest\n\t\t\"@\" @punctuation.special))\n\n[\n\t(double_quoted_string)\n\t(single_quoted_string)\n\t(json_string)\n\t(heredoc_line)\n] @string\n\n[\n  (heredoc_marker)\n  (heredoc_end)\n] @label\n\n((heredoc_block\n  (heredoc_line) @string))\n\n(expansion\n  [\n\t\"$\"\n\t\"{\"\n\t\"}\"\n  ] @punctuation.special\n) @none\n\n((variable) @constant\n (#match? @constant \"^[A-Z][A-Z_0-9]*$\"))\n\n[\n\t(param)\n\t(mount_param)\n] @constant\n\n(expose_instruction\n  (expose_port) @constant.numeric.integer)\n"
  },
  {
    "path": "runtime/queries/dockerfile/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((shell_command (shell_fragment) @injection.content)\n (#set! injection.language \"bash\")\n (#set! injection.combined))\n\n((run_instruction\n (heredoc_block (heredoc_line) @injection.content . \"\\n\" @injection.content))\n (#set! injection.language \"bash\")\n (#set! injection.combined))\n\n((copy_instruction\n (path (heredoc_marker)) . (path) @injection.filename\n (heredoc_block (heredoc_line) @injection.content . \"\\n\" @injection.content))\n (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/dockerfile/textobjects.scm",
    "content": "(comment) @comment.inside\n\n(comment)+ @comment.around\n\n"
  },
  {
    "path": "runtime/queries/dot/highlights.scm",
    "content": "(identifier) @variable\n\n(keyword) @keyword\n(string_literal) @string\n(number_literal) @constant.numeric\n\n[\n  (edgeop)\n  (operator)\n] @operator\n\n[\n  \",\"\n  \";\"\n] @punctuation.delimiter\n\n[\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"<\"\n  \">\"\n] @punctuation.bracket\n\n(subgraph\n  id: (id\n    (identifier) @namespace)\n)\n\n(attribute\n  name: (id\n    (identifier) @type)\n  value: (id\n    (identifier) @constant)\n)\n\n(comment) @comment\n\n(preproc) @keyword.directive\n"
  },
  {
    "path": "runtime/queries/dot/injections.scm",
    "content": "((html_internal) @injection.content\n  (#set! injection.language \"html\"))\n"
  },
  {
    "path": "runtime/queries/doxyfile/highlights.scm",
    "content": "(comment) @comment.line\n\n(identifier) @variable\n\n(boolean) @constant.builtin.boolean\n(number) @constant.numeric.integer\n[\n  (unquoted_string)\n  (quoted_string)\n] @string\n\n[\n  \"\\\\\"\n] @punctuation.delimiter\n\n[\n  \"=\"\n  \"+=\"\n] @operator\n"
  },
  {
    "path": "runtime/queries/doxyfile/indents.scm",
    "content": "(option\n  value: (_) @anchor\n  (#set! \"scope\" \"tail\")) @align\n"
  },
  {
    "path": "runtime/queries/doxyfile/injections.scm",
    "content": "((comment\n  body: (_) @injection.content)\n    (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/doxyfile/tags.scm",
    "content": "(option\n  key: (_) @definition.constant)\n"
  },
  {
    "path": "runtime/queries/doxyfile/textobjects.scm",
    "content": "(option\n  value: (_) @entry.inside) @entry.around\n\n(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/dtd/highlights.scm",
    "content": "; highlights.scm\n\n(comment) @comment\n\n[\n    \"ELEMENT\"\n    \"ATTLIST\"\n] @keyword\n\n[\n    \"#REQUIRED\"\n    \"#IMPLIED\"\n    \"#FIXED\"\n    \"#PCDATA\"\n] @keyword.directive\n\n[\n    \"EMPTY\"\n    \"ANY\"\n    \"SYSTEM\"\n    \"PUBLIC\"\n] @constant\n\n(element_name) @module\n\n\n(attribute_name) @attribute\n\n(system_literal) @string\n(pubid_literal) @string\n(attribute_value) @string\n\n[\n    \">\"\n    \"</\"\n    \"<?\"\n    \"?>\"\n    \"<!\"\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/dtd/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/dune/highlights.scm",
    "content": "; inherits: scheme\n"
  },
  {
    "path": "runtime/queries/dunstrc/highlights.scm",
    "content": "(assign\n  (key) @attribute)\n\n(comment) @comment.line\n\n[\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n\"=\" @operator\n\n(section\n  (name) @namespace)\n"
  },
  {
    "path": "runtime/queries/earthfile/highlights.scm",
    "content": "(string_array \",\" @punctuation.delimiter)\n(string_array [\"[\" \"]\"] @punctuation.bracket)\n\n[\n    \"ARG\"\n    \"AS LOCAL\"\n    \"BUILD\"\n    \"CACHE\"\n    \"CMD\"\n    \"COPY\"\n    \"DO\"\n    \"ENTRYPOINT\"\n    \"ENV\"\n    \"EXPOSE\"\n    \"FROM DOCKERFILE\"\n    \"FROM\"\n    \"FUNCTION\"\n    \"GIT CLONE\"\n    \"HOST\"\n    \"IMPORT\"\n    \"LABEL\"\n    \"LET\"\n    \"PROJECT\"\n    \"RUN\"\n    \"SAVE ARTIFACT\"\n    \"SAVE IMAGE\"\n    \"SET\"\n    \"USER\"\n    \"VERSION\"\n    \"VOLUME\"\n    \"WORKDIR\"\n] @keyword\n\n(for_command [\"FOR\" \"IN\" \"END\"] @keyword.control.repeat)\n\n(if_command [\"IF\" \"END\"] @keyword.control.conditional)\n(elif_block [\"ELSE IF\"] @keyword.control.conditional)\n(else_block [\"ELSE\"] @keyword.control.conditional)\n\n(import_command [\"IMPORT\" \"AS\"] @keyword.control.import)\n\n(try_command [\"TRY\" \"FINALLY\" \"END\"] @keyword.control.exception)\n\n(wait_command [\"WAIT\" \"END\"] @keyword.control)\n(with_docker_command [\"WITH DOCKER\" \"END\"] @keyword.control)\n\n[\n    (comment)\n    (line_continuation_comment)\n] @comment\n\n(line_continuation) @operator\n\n[\n    (target_ref)\n    (target_artifact)\n    (function_ref)\n] @function\n\n(target (identifier) @function)\n\n[\n    (double_quoted_string)\n    (single_quoted_string)\n] @string\n(unquoted_string) @string.special\n(escape_sequence) @constant.character.escape\n\n(variable) @variable\n(expansion [\"$\" \"{\" \"}\" \"(\" \")\"] @punctuation.special)\n(build_arg) @variable\n(options (_) @variable.parameter)\n\n\"=\" @operator\n"
  },
  {
    "path": "runtime/queries/earthfile/indents.scm",
    "content": "(target) @indent\n"
  },
  {
    "path": "runtime/queries/earthfile/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n\n((line_continuation_comment) @injection.content\n  (#set! injection.language \"comment\"))\n\n((shell_fragment) @injection.content\n  (#set! injection.language \"bash\")\n  (#set! injection.include-children))\n"
  },
  {
    "path": "runtime/queries/earthfile/textobjects.scm",
    "content": "(target (block) @function.inside) @function.around\n"
  },
  {
    "path": "runtime/queries/ecma/README.md",
    "content": "# Inheritance model for ecma-based languages\n\nEcma-based languages share many traits. Because of this we want to share as many queries as possible while avoiding nested inheritance that can make query behaviour unpredictable due to unexpected precedence.\n\nTo achieve that, there are \"public\" and \"private\" versions for javascript, jsx, and typescript query files, that share the same name, but the \"private\" version name starts with an underscore (with the exception of ecma, that already exists as a sort of base \"private\" language). This allows the \"private\" versions to host the specific queries of the language excluding any `; inherits` statement, in order to make them safe to be inherited by the \"public\" version of the same language and other languages as well. The tsx language doesn't have a \"private\" version given that currently it doesn't need to be inherited by other languages.\n\n| Language   | Inherits from           |\n| ---------- | ----------------------- |\n| javascript | _javascript, ecma       |\n| jsx        | _jsx, _javascript, ecma |\n| typescript | _typescript, ecma       |\n| tsx        | _jsx, _typescript, ecma |\n\nIf you intend to add queries to any of the ecma-based languages above, make sure you add them to the correct private language they belong to, so that other languages down the line can benefit from them.\n"
  },
  {
    "path": "runtime/queries/ecma/highlights.scm",
    "content": "; Tokens\n;-------\n\n[\n  \";\"\n  (optional_chain) ; ?.\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"-\"\n  \"--\"\n  \"-=\"\n  \"+\"\n  \"++\"\n  \"+=\"\n  \"*\"\n  \"*=\"\n  \"**\"\n  \"**=\"\n  \"/\"\n  \"/=\"\n  \"%\"\n  \"%=\"\n  \"<\"\n  \"<=\"\n  \"<<\"\n  \"<<=\"\n  \"=\"\n  \"==\"\n  \"===\"\n  \"!\"\n  \"!=\"\n  \"!==\"\n  \"=>\"\n  \">\"\n  \">=\"\n  \">>\"\n  \">>=\"\n  \">>>\"\n  \">>>=\"\n  \"~\"\n  \"^\"\n  \"&\"\n  \"|\"\n  \"^=\"\n  \"&=\"\n  \"|=\"\n  \"&&\"\n  \"||\"\n  \"??\"\n  \"&&=\"\n  \"||=\"\n  \"??=\"\n  \"...\"\n] @operator\n\n(ternary_expression [\"?\" \":\"] @operator)\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n]  @punctuation.bracket\n\n(template_substitution\n  \"${\" @punctuation.special\n  \"}\" @punctuation.special) @embedded\n\n[\n  \"async\"\n  \"debugger\"\n  \"extends\"\n  \"from\"\n  \"get\"\n  \"new\"\n  \"set\"\n  \"target\"\n  \"with\"\n] @keyword\n\n[\n  \"of\"\n  \"as\"\n  \"in\"\n  \"delete\"\n  \"typeof\"\n  \"instanceof\"\n  \"void\"\n] @keyword.operator\n\n[\n  \"function\"\n] @keyword.function\n\n[\n  \"class\"\n  \"let\"\n  \"var\"\n] @keyword.storage.type\n\n[\n  \"const\"\n  \"static\"\n] @keyword.storage.modifier\n\n[\n  \"default\"\n  \"yield\"\n  \"finally\"\n  \"do\"\n  \"await\"\n] @keyword.control\n\n[\n  \"if\"\n  \"else\"\n  \"switch\"\n  \"case\"\n] @keyword.control.conditional\n\n[\n  \"while\"\n  \"for\"\n] @keyword.control.repeat\n\n[\n  \"import\"\n  \"export\"\n] @keyword.control.import\n\n[\n  \"return\"\n  \"break\"\n  \"continue\"\n] @keyword.control.return\n\n[\n  \"throw\"\n  \"try\"\n  \"catch\"\n] @keyword.control.exception\n\n; Variables\n;----------\n\n(identifier) @variable\n\n; Properties\n;-----------\n\n(property_identifier) @variable.other.member\n(private_property_identifier) @variable.other.member.private\n(shorthand_property_identifier) @variable.other.member\n(shorthand_property_identifier_pattern) @variable.other.member\n\n; Function and method definitions\n;--------------------------------\n\n(function_expression\n  name: (identifier) @function)\n(function_declaration\n  name: (identifier) @function)\n(method_definition\n  name: (property_identifier) @function.method)\n(method_definition\n  name: (private_property_identifier) @function.method.private)\n\n(pair\n  key: (property_identifier) @function.method\n  value: [(function_expression) (arrow_function)])\n(pair\n  key: (private_property_identifier) @function.method.private\n  value: [(function_expression) (arrow_function)])\n\n(assignment_expression\n  left: (member_expression\n    property: (property_identifier) @function.method)\n  right: [(function_expression) (arrow_function)])\n(assignment_expression\n  left: (member_expression\n    property: (private_property_identifier) @function.method.private)\n  right: [(function_expression) (arrow_function)])\n\n(variable_declarator\n  name: (identifier) @function\n  value: [(function_expression) (arrow_function)])\n\n(assignment_expression\n  left: (identifier) @function\n  right: [(function_expression) (arrow_function)])\n\n; Function and method parameters\n;-------------------------------\n\n; Arrow function parameters in the form `p => ...` are supported by both\n; javascript and typescript grammars without conflicts.\n(arrow_function\n  parameter: (identifier) @variable.parameter)\n\n; Function and method calls\n;--------------------------\n\n(call_expression\n  function: (identifier) @function)\n\n(call_expression\n  function: (member_expression\n    property: (property_identifier) @function.method))\n(call_expression\n  function: (member_expression\n    property: (private_property_identifier) @function.method.private))\n\n; Literals\n;---------\n\n(this) @variable.builtin\n(super) @variable.builtin\n\n[\n  (null)\n  (undefined)\n] @constant.builtin\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(comment) @comment\n\n[\n  (string)\n  (template_string)\n] @string\n\n(escape_sequence) @constant.character.escape\n\n(regex) @string.regexp\n(number) @constant.numeric.integer\n\n; Special identifiers\n;--------------------\n\n((identifier) @constructor\n (#match? @constructor \"^[A-Z]\"))\n\n([\n    (identifier)\n    (shorthand_property_identifier)\n    (shorthand_property_identifier_pattern)\n ] @constant\n (#match? @constant \"^[A-Z_][A-Z\\\\d_]+$\"))\n\n((identifier) @variable.builtin\n (#match? @variable.builtin \"^(arguments|module|console|window|document)$\")\n (#is-not? local))\n\n(call_expression\n (identifier) @function.builtin\n (#any-of? @function.builtin\n  \"eval\"\n  \"fetch\"\n  \"isFinite\"\n  \"isNaN\"\n  \"parseFloat\"\n  \"parseInt\"\n  \"decodeURI\"\n  \"decodeURIComponent\"\n  \"encodeURI\"\n  \"encodeURIComponent\"\n  \"require\"\n  \"alert\"\n  \"prompt\"\n  \"btoa\"\n  \"atob\"\n  \"confirm\"\n  \"structuredClone\"\n  \"setTimeout\"\n  \"clearTimeout\"\n  \"setInterval\"\n  \"clearInterval\"\n  \"queueMicrotask\")\n (#is-not? local))\n"
  },
  {
    "path": "runtime/queries/ecma/indents.scm",
    "content": "[\n  (array)\n  (object)\n  (arguments)\n  (formal_parameters)\n\n  (statement_block)\n  (switch_statement)\n  (object_pattern)\n  (class_body)\n  (named_imports)\n\n  (binary_expression)\n  (return_statement)\n  (template_substitution)\n  (export_clause)\n] @indent\n\n[\n  (switch_case)\n  (switch_default)\n] @indent @extend\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/ecma/injections.scm",
    "content": "; Parse the contents of tagged template literals using\n; a language inferred from the tag.\n\n(call_expression\n  function: [\n    (identifier) @injection.language\n    (member_expression\n      property: (property_identifier) @injection.language)\n  ]\n  arguments: (template_string) @injection.content\n  (#any-of? @injection.language \"html\" \"css\" \"json\" \"sql\" \"js\" \"ts\" \"bash\"))\n\n; Parse the contents of $ template literals as shell commands\n\n(call_expression\n  function: [\n    (identifier) @_template_function_name\n    (member_expression\n      property: (property_identifier) @_template_function_name)\n  ]\n  arguments: (template_string) @injection.content\n (#eq? @_template_function_name \"$\")\n (#set! injection.language \"bash\"))\n\n; GraphQL detection generally matches the rules provided by the 'GraphQL: Syntax Highlighting'\n; VSCode extension: https://github.com/graphql/graphiql/blob/8f25b38f4ab14dc99c046109f255fb283bccde52/packages/vscode-graphql-syntax/grammars/graphql.js.json\n\n; Parse the contents of 'gql' and 'graphql' template literals and function calls\n(\n  (call_expression\n    function: (identifier) @_template_function_name\n    arguments: [\n      ; Tagged template literal: NAME``\n      (template_string (string_fragment) @injection.content)\n      (\n        arguments . [\n          ; Function call containing a string literal: NAME('')\n          (string (string_fragment) @injection.content)\n          ; Function call containing a template literal: NAME(``)\n          (template_string (string_fragment) @injection.content)\n        ]\n      )\n    ]\n  )\n  (#any-of? @_template_function_name \"gql\" \"graphql\")\n  (#set! injection.language \"graphql\")\n)\n\n; Parse the contents of strings and tagged template literals that begin with a GraphQL comment '#graphql'\n(\n  [\n    (string (string_fragment) @injection.content)\n    (template_string (string_fragment) @injection.content)\n  ]\n  (#match? @injection.content \"^\\\\s*#graphql\")\n  (#set! injection.language \"graphql\")\n)\n\n; Parse the contents of strings and tagged template literals with leading ECMAScript comments '/* GraphQL */'\n(\n  ((comment) @_ecma_comment [\n    (string (string_fragment) @injection.content)\n    (template_string (string_fragment) @injection.content)\n  ])\n  (#eq? @_ecma_comment \"/* GraphQL */\")\n  (#set! injection.language \"graphql\")\n)\n\n; Parse regex syntax within regex literals\n\n((regex_pattern) @injection.content\n (#set! injection.language \"regex\"))\n\n; Parse JSDoc annotations in multiline comments\n\n((comment) @injection.content\n (#set! injection.language \"jsdoc\")\n (#match? @injection.content \"^/\\\\*+\"))\n\n; Parse general tags in single line comments\n\n((comment) @injection.content\n (#set! injection.language \"comment\")\n (#match? @injection.content \"^//\"))\n\n; Match string literals passed to standard browser API methods that expects a\n; css selector as argument.\n; - https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector\n; - https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll\n; - https://developer.mozilla.org/en-US/docs/Web/API/Element/closest\n; - https://developer.mozilla.org/en-US/docs/Web/API/Element/matches\n; e.g.\n; `const el = document.querySelector(\"div.user-panel.main input[name='login']\");`\n(call_expression\n  function: (member_expression\n    object: (identifier) @_object\n    property: (property_identifier) @_property (#any-of? @_property \"querySelector\" \"querySelectorAll\" \"closest\" \"matches\"))\n  arguments: (arguments\n               (string (string_fragment) @injection.content))\n  (#set! injection.language \"css\"))\n"
  },
  {
    "path": "runtime/queries/ecma/locals.scm",
    "content": "; Scopes\n;-------\n\n[\n  (statement_block)\n  (arrow_function)\n  (function_expression)\n  (function_declaration)\n  (method_definition)\n  (for_statement)\n  (for_in_statement)\n  (catch_clause)\n  (finally_clause)\n] @local.scope\n\n; Definitions\n;------------\n\n; i => ...\n(arrow_function\n  parameter: (identifier) @local.definition.variable.parameter)\n\n; References\n;------------\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/ecma/rainbows.scm",
    "content": "[\n  (export_clause)\n  (named_imports)\n  (statement_block)\n  (for_statement)\n  (for_in_statement)\n  (switch_body)\n  (catch_clause \"(\" \")\")\n  (parenthesized_expression)\n  (object)\n  (object_pattern)\n  (array)\n  (array_pattern)\n  (subscript_expression)\n  (template_substitution)\n  (arguments)\n  (class_body)\n  (formal_parameters)\n  (computed_property_name)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"${\" \"{\" \"}\"\n  \"[\" \"]\"\n] @rainbow.bracket\n\n(regex \"/\" @rainbow.bracket) @rainbow.scope\n"
  },
  {
    "path": "runtime/queries/ecma/textobjects.scm",
    "content": "(function_declaration\n  body: (_) @function.inside) @function.around\n\n(function_expression\n  body: (_) @function.inside) @function.around\n\n(arrow_function\n  body: (_) @function.inside) @function.around\n\n(method_definition\n  body: (_) @function.inside) @function.around\n\n(generator_function_declaration\n  body: (_) @function.inside) @function.around\n\n(class_declaration\n  body: (class_body) @class.inside) @class.around\n\n(class\n  (class_body) @class.inside) @class.around\n\n(export_statement\n  declaration: [\n    (function_declaration) @function.around\n    (class_declaration) @class.around \n  ])\n\n(formal_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(array \n  (_) @entry.around)\n\n(pair\n  (_) @entry.inside) @entry.around\n\n(pair_pattern\n  (_) @entry.inside) @entry.around\n"
  },
  {
    "path": "runtime/queries/edoc/highlights.scm",
    "content": "((section\n   (section_marker) @markup.heading.marker\n   (section_content) @markup.heading.1\n   (section_marker) @markup.heading.marker)\n (#eq? @markup.heading.marker \"==\"))\n\n((section\n   (section_marker) @markup.heading.marker\n   (section_content) @markup.heading.2\n   (section_marker) @markup.heading.marker)\n (#eq? @markup.heading.marker \"===\"))\n\n((section\n   (section_marker) @markup.heading.marker\n   (section_content) @markup.heading.3\n   (section_marker) @markup.heading.marker)\n (#eq? @markup.heading.marker \"====\"))\n\n(tag) @keyword\n(macro (tag) @function.macro)\n(macro_escape) @constant.character.escape\n(inline_quote) @markup.raw.inline\n(email_address) @markup.link.url\n\n(em_xhtml_tag\n  (open_xhtml_tag) @tag\n  (xhtml_tag_content) @markup.italic\n  (close_xhtml_tag) @tag)\n\n(strong_xhtml_tag\n  (open_xhtml_tag) @tag\n  (xhtml_tag_content) @markup.bold\n  (close_xhtml_tag) @tag)\n\n(module) @namespace\n(function) @function\n(type) @type\n\n; could be @constant.numeric.integer but this looks similar to a capture\n(arity) @operator\n\n(expression [\":\" \"/\"] @operator)\n(expression [\"(\" \")\"] @punctuation.delimiter)\n(macro [\"{\" \"}\"] @function.macro)\n\n[\n  (quote_marker)\n  (language_identifier)\n  (quote_content)\n] @markup.raw.block\n\n(parameter) @variable.parameter\n"
  },
  {
    "path": "runtime/queries/edoc/injections.scm",
    "content": "((xhtml_tag) @injection.content\n (#set! injection.combined)\n (#set! injection.include-children)\n (#set! injection.language \"html\"))\n\n((block_quote\n   !language\n   (quote_content) @injection.content)\n  (#set! injection.language \"erlang\"))\n\n(block_quote\n  language: (language_identifier) @injection.language\n  (quote_content) @injection.content)\n\n((macro\n   (tag) @_tag\n   (argument) @injection.content)\n (#eq? @_tag \"@type\")\n (#set! injection.language \"erlang\")\n (#set! injection.include-children))\n"
  },
  {
    "path": "runtime/queries/eex/highlights.scm",
    "content": "; https://github.com/connorlay/tree-sitter-eex/blob/f742f2fe327463335e8671a87c0b9b396905d1d1/queries/highlights.scm\n\n; wrapping in (directive .. ) prevents us from highlighting '%>' in a comment as a keyword\n(directive [\"<%\" \"<%=\" \"<%%\" \"<%%=\" \"%>\"] @keyword)\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/eex/injections.scm",
    "content": "; https://github.com/connorlay/tree-sitter-eex/blob/f742f2fe327463335e8671a87c0b9b396905d1d1/queries/injections.scm\n\n((directive (expression) @injection.content)\n (#set! injection.language \"elixir\"))\n\n((partial_expression) @injection.content\n (#set! injection.language \"elixir\")\n (#set! injection.include-children)\n (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/eiffel/highlights.scm",
    "content": "[\n \"alias\"\n \"convert\"\n \"inherit\"\n \"redefine\"\n \"undefine\"\n \"rename\"\n \"select\"\n \"note\"\n \"create\"\n] @keyword.control.import\n\n[\"export\"] @keyword.control.export\n\n[\n \"do\"\n \"end\"\n \"once\"\n \"attribute\"\n] @keyword.control\n\n[\n \"class\"\n \"local\"\n] @keyword.storage.type\n\n[\n \"feature\"\n \"agent\"\n] @keyword.function\n\n[\n \"frozen\"\n \"deferred\"\n \"detachable\"\n \"expanded\"\n \"attached\"\n \"old\"\n \"like\"\n] @keyword.storage.modifier\n\n(conditional [\"if\" \"elseif\" \"end\"] @keyword.control.conditional)\n(else_part [\"else\"] @keyword.control.conditional)\n(then_part [\"then\"] @keyword.control.conditional)\n\n(conditional_expression [\"if\" \"else\" \"elseif\" \"end\"] @keyword.control.conditional)\n(else_part_expression [\"else\"] @keyword.control.conditional)\n(then_part_expression [\"then\"] @keyword.control.conditional)\n\n(multi_branch \"inspect\" @keyword.control.conditional)\n(when_part [\"when\" \"then\"] @keyword.control.conditional)\n\n(multi_branch_expression \"inspect\" @keyword.control.conditional)\n(when_part_expression [\"when\" \"then\"] @keyword.control.conditional)\n\n(quantifier_loop [\"∀\" \"∃\" \":\" \"¦\"] @keyword.control.repeat)\n(quantifier_loop_body [\"all\" \"some\"] @keyword.control.repeat)\n(iteration [\"across\" \"as\"] @keyword.control.repeat)\n(initialization \"from\" @keyword.control.repeat)\n(exit_condition \"until\" @keyword.control.repeat)\n(loop_body \"loop\" @keyword.control.repeat)\n(variant \"variant\" @keyword.control.repeat)\n(loop (invariant \"invariant\" @keyword.control.repeat))\n(loop [\"⟳\" \":\" \"¦\" \"⟲\"]@keyword.control.repeat)\n(loop \"end\" @keyword.control.repeat)\n\n[\n \"require\"\n \"ensure\"\n \"invariant\"\n \"check\"\n] @keyword.control.exception\n\n[\"(\" \")\" \"[\" \"]\" \"<<\" \">>\"] @punctuation.bracket\n[\",\" \":\" \";\"] @punctuation.delimiter\n\n[\n (unary)\n \":=\"\n (binary_caret)\n (binary_mul_div)\n (binary_plus_minus)\n (binary_comparison)\n (binary_and)\n (binary_or)\n (binary_implies)\n (comparison)\n (unary_not)\n] @operator\n\n(result) @variable.builtin\n(anchored (call (_) @variable))\n[(verbatim_string) (basic_manifest_string)] @string\n[(integer_constant) (real_constant)] @constant.numeric\n(boolean_constant) @constant.builtin.boolean\n(void) @constant.builtin\n(current) @variable.builtin\n(extended_feature_name (identifier) @function.method)\n\n(iteration (identifier) @variable)\n(quantifier_loop (identifier) @variable)\n(entity_declaration_group (identifier) @variable)\n\n(class_name) @type\n(formal_generic) @type.parameter\n\n(comment) @comment.line\n(header_comment) @comment.line.documentation\n"
  },
  {
    "path": "runtime/queries/eiffel/indents.scm",
    "content": "[\n  (notes)\n  (class_declaration)\n  (inheritance)\n  (feature_adaptation)\n  (creation_clause)\n  (converters)\n\n  (feature_declaration)\n\n  (attribute_or_routine)\n\n  (precondition)\n  (local_declarations)\n  (feature_body)\n\n  (check)\n  (multi_branch)\n  (multi_branch_expression)\n  (conditional)\n  (conditional_expression)\n  (loop)\n  (quantifier_loop)\n  (iteration)\n\n  (postcondition)\n  (rescue)\n\n  (invariant)\n] @indent\n"
  },
  {
    "path": "runtime/queries/eiffel/textobjects.scm",
    "content": "[\n  (comment)+\n  (header_comment)+\n] @comment.around\n[\n  (comment)\n  (header_comment)\n] @comment.inside\n(formal_arguments) @parameter.around\n(entity_declaration_group) @parameter.inside\n(attribute_or_routine) @function.around\n(feature_body) @function.inside\n(class_declaration) @class.around\n(feature_clause) @class.inside\n\n"
  },
  {
    "path": "runtime/queries/ejs/highlights.scm",
    "content": "(comment_directive) @comment\n\n[\n  \"<%#\"\n  \"<%\"\n  \"<%=\"\n  \"<%_\"\n  \"<%-\"\n  \"%>\"\n  \"-%>\"\n  \"_%>\"\n] @keyword\n"
  },
  {
    "path": "runtime/queries/ejs/injections.scm",
    "content": "((content) @injection.content\n (#set! injection.language \"html\")\n (#set! injection.combined))\n\n((code) @injection.content\n (#set! injection.language \"javascript\")\n (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/elisp/highlights.scm",
    "content": ";; Special forms\n[\n  \"and\"\n  \"catch\"\n  \"cond\"\n  \"condition-case\"\n  \"defconst\"\n  \"defvar\"\n  \"function\"\n  \"if\"\n  \"interactive\"\n  \"lambda\"\n  \"let\"\n  \"let*\"\n  \"or\"\n  \"prog1\"\n  \"prog2\"\n  \"progn\"\n  \"quote\"\n  \"save-current-buffer\"\n  \"save-excursion\"\n  \"save-restriction\"\n  \"setq\"\n  \"setq-default\"\n  \"unwind-protect\"\n  \"while\"\n] @keyword\n\n(string) @string\n\n;; Function definitions\n[\n \"defun\"\n \"defsubst\"\n ] @keyword\n(function_definition name: (symbol) @function)\n(function_definition parameters: (list (symbol) @variable.parameter))\n(function_definition docstring: (string) @comment)\n\n;; Highlight macro definitions the same way as function definitions.\n\"defmacro\" @keyword\n(macro_definition name: (symbol) @function)\n(macro_definition parameters: (list (symbol) @variable.parameter))\n(macro_definition docstring: (string) @comment)\n\n(comment) @comment\n\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(char) @constant.character\n\n[\n  \"(\"\n  \")\"\n  \"#[\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n[\n  \"`\"\n  \"#'\"\n  \"'\"\n  \",\"\n  \",@\"\n] @operator\n\n;; Highlight nil and t as constants, unlike other symbols\n[\n  \"nil\"\n  \"t\"\n] @constant.builtin\n"
  },
  {
    "path": "runtime/queries/elisp/tags.scm",
    "content": ";; defun/defsubst\n(function_definition name: (symbol) @name) @definition.function\n\n;; Treat macros as function definitions for the sake of TAGS.\n(macro_definition name: (symbol) @name) @definition.function\n"
  },
  {
    "path": "runtime/queries/elixir/highlights.scm",
    "content": "; The following code originates mostly from\n; https://github.com/elixir-lang/tree-sitter-elixir, with minor edits to\n; align the captures with helix. The following should be considered\n; Copyright 2021 The Elixir Team\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;    https://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; Punctuation\n\n[\n \"%\"\n] @punctuation\n\n[\n \",\"\n \";\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"<<\"\n  \">>\"\n] @punctuation.bracket\n\n; Literals\n\n(boolean) @constant.builtin.boolean\n(nil) @constant.builtin\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(char) @constant.character\n\n; Identifiers\n\n; * regular\n(identifier) @variable\n\n; * unused\n(\n  (identifier) @comment.unused\n  (#match? @comment.unused \"^_\")\n)\n\n; * special\n(\n  (identifier) @constant.builtin\n  (#any-of? @constant.builtin \"__MODULE__\" \"__DIR__\" \"__ENV__\" \"__CALLER__\" \"__STACKTRACE__\")\n)\n\n; Comment\n\n(comment) @comment\n\n; Quoted content\n\n(interpolation \"#{\" @punctuation.special \"}\" @punctuation.special) @embedded\n\n(escape_sequence) @constant.character.escape\n\n[\n  (string)\n  (charlist)\n] @string\n\n[\n  (atom)\n  (quoted_atom)\n  (keyword)\n  (quoted_keyword)\n] @string.special.symbol\n\n; Note that we explicitly target sigil quoted start/end, so they are not overridden by delimiters\n\n(sigil\n  (sigil_name) @__name__\n  quoted_start: _ @string.special\n  quoted_end: _ @string.special) @string.special\n\n(sigil\n  (sigil_name) @__name__\n  quoted_start: _ @string\n  quoted_end: _ @string\n  (#match? @__name__ \"^[sS]$\")) @string\n\n(sigil\n  (sigil_name) @__name__\n  quoted_start: _ @string.regex\n  quoted_end: _ @string.regex\n  (#match? @__name__ \"^[rR]$\")) @string.regex\n\n; Calls\n\n; * local function call\n(call\n  target: (identifier) @function)\n\n; * remote function call\n(call\n  target: (dot\n    right: (identifier) @function))\n\n; * field without parentheses or block\n(call\n  target: (dot\n    right: (identifier) @variable.other.member)\n  .)\n\n; * remote call without parentheses or block (overrides above)\n(call\n  target: (dot\n    left: [\n      (alias)\n      (atom)\n    ]\n    right: (identifier) @function)\n  .)\n\n; * definition keyword\n(call\n  target: (identifier) @keyword\n  (#any-of? @keyword \"def\" \"defdelegate\" \"defexception\" \"defguard\" \"defguardp\" \"defimpl\" \"defmacro\" \"defmacrop\" \"defmodule\" \"defn\" \"defnp\" \"defoverridable\" \"defp\" \"defprotocol\" \"defstruct\"))\n\n; * kernel or special forms keyword\n(call\n  target: (identifier) @keyword\n  (#any-of? @keyword \"alias\" \"case\" \"cond\" \"for\" \"if\" \"import\" \"quote\" \"raise\" \"receive\" \"require\" \"reraise\" \"super\" \"throw\" \"try\" \"unless\" \"unquote\" \"unquote_splicing\" \"use\" \"with\"))\n\n; * just identifier in function definition\n(call\n  target: (identifier) @keyword\n  (arguments\n    [\n      (identifier) @function\n      (binary_operator\n        left: (identifier) @function\n        operator: \"when\")\n    ])\n  (#any-of? @keyword \"def\" \"defdelegate\" \"defguard\" \"defguardp\" \"defmacro\" \"defmacrop\" \"defn\" \"defnp\" \"defp\"))\n\n; * pipe into identifier (function call)\n(binary_operator\n  operator: \"|>\"\n  right: (identifier) @function)\n\n; * pipe into identifier (definition)\n(call\n  target: (identifier) @keyword\n  (arguments\n    (binary_operator\n      operator: \"|>\"\n      right: (identifier) @variable))\n  (#any-of? @keyword \"def\" \"defdelegate\" \"defguard\" \"defguardp\" \"defmacro\" \"defmacrop\" \"defn\" \"defnp\" \"defp\"))\n\n; * pipe into field without parentheses (function call)\n(binary_operator\n  operator: \"|>\"\n  right: (call\n    target: (dot\n      right: (identifier) @function)))\n\n; Operators\n\n; * capture operand\n(unary_operator\n  operator: \"&\"\n  operand: [\n    (integer) @operator\n    (binary_operator\n      left: [\n        (call target: (dot left: (_) right: (identifier) @function))\n        (identifier) @function\n      ] operator: \"/\" right: (integer) @operator)\n  ])\n\n(operator_identifier) @operator\n\n(unary_operator\n  operator: _ @operator)\n\n(binary_operator\n  operator: _ @operator)\n\n(dot\n  operator: _ @operator)\n\n(stab_clause\n  operator: _ @operator)\n\n; * module attribute\n(unary_operator\n  operator: \"@\" @variable.other.member\n  operand: [\n    (identifier) @variable.other.member\n    (call\n      target: (identifier) @variable.other.member)\n    (boolean) @variable.other.member\n    (nil) @variable.other.member\n  ])\n\n; * doc string\n(unary_operator\n  operator: \"@\" @comment.block.documentation\n  operand: (call\n    target: (identifier) @comment.block.documentation.__attribute__\n    (arguments\n      [\n        (string) @comment.block.documentation\n        (charlist) @comment.block.documentation\n        (sigil\n          quoted_start: _ @comment.block.documentation\n          quoted_end: _ @comment.block.documentation) @comment.block.documentation\n        (boolean) @comment.block.documentation\n      ]))\n  (#any-of? @comment.block.documentation.__attribute__ \"moduledoc\" \"typedoc\" \"doc\"))\n\n; Module\n\n(alias) @namespace\n\n(call\n  target: (dot\n    left: (atom) @namespace))\n\n; Reserved keywords\n\n[\"when\" \"and\" \"or\" \"not\" \"in\" \"not in\" \"fn\" \"do\" \"end\" \"catch\" \"rescue\" \"after\" \"else\"] @keyword\n"
  },
  {
    "path": "runtime/queries/elixir/indents.scm",
    "content": "[\n  (after_block)\n  (anonymous_function)\n  (catch_block)\n  (do_block)\n  (else_block)\n  (rescue_block)\n  (stab_clause)\n] @indent\n\n[\n  \"end\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/elixir/injections.scm",
    "content": "; Elixir Code Comments\n((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; Elixir Regular Expressions\n((sigil\n  (sigil_name) @_sigil_name\n  (quoted_content) @injection.content)\n (#match? @_sigil_name \"^(R|r)$\")\n (#set! injection.language \"regex\")\n (#set! injection.combined))\n\n; Elixir Markdown Documentation\n(unary_operator\n  operator: \"@\"\n  operand: (call\n  target: ((identifier) @_identifier (#match? @_identifier \"^(module|type|short)?doc$\"))\n    (arguments [\n      (string (quoted_content) @injection.content)\n      (sigil (quoted_content) @injection.content)\n  ])) (#set! injection.language \"markdown\"))\n\n; Zigler Sigils\n((sigil\n  (sigil_name) @_sigil_name\n  (quoted_content) @injection.content)\n (#match? @_sigil_name \"^(Z|z)$\")\n (#set! injection.language \"zig\")\n (#set! injection.combined))\n\n; Jason Sigils\n((sigil\n  (sigil_name) @_sigil_name\n  (quoted_content) @injection.content)\n (#match? @_sigil_name \"^(J|j)$\")\n (#set! injection.language \"json\")\n (#set! injection.combined))\n\n; Phoenix Live View HEEx Sigils\n((sigil\n  (sigil_name) @_sigil_name\n  (quoted_content) @injection.content)\n (#eq? @_sigil_name \"H\")\n (#set! injection.language \"heex\")\n (#set! injection.combined))\n\n; Phoenix Live View Component Macros\n(call \n  (identifier) @_identifier\n  (arguments\n    (atom)+\n    (keywords (pair \n      ((keyword) @_keyword (#eq? @_keyword \"doc: \"))\n      [\n        (string (quoted_content) @injection.content)\n        (sigil (quoted_content) @injection.content)\n      ]))\n  (#match? @_identifier \"^(attr|slot)$\")\n  (#set! injection.language \"markdown\")))\n"
  },
  {
    "path": "runtime/queries/elixir/rainbows.scm",
    "content": "[\n  (block)\n  (interpolation)\n  (list)\n  (tuple)\n  (bitstring)\n  (map)\n  ; short-hand function captures like &(&1 + &2)\n  (unary_operator\n    operator: \"&\")\n  (arguments \"(\" \")\")\n  (access_call)\n  (sigil)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"%\"\n  \"{\" \"}\"\n  \"[\" \"]\"\n  \"<<\" \">>\"\n  \"#{\"\n  \"|\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/elixir/tags.scm",
    "content": "; Definitions\n\n; * modules and protocols\n(call\n  target: (identifier) @ignore\n  (arguments (alias) @name)\n  (#any-of? @ignore \"defmodule\" \"defprotocol\")) @definition.module\n\n; * functions/macros\n(call\n  target: (identifier) @ignore\n  (arguments\n    [\n      ; zero-arity functions with no parentheses\n      (identifier) @name\n      ; regular function clause\n      (call target: (identifier) @name)\n      ; function clause with a guard clause\n      (binary_operator\n        left: (call target: (identifier) @name)\n        operator: \"when\")\n    ])\n  (#any-of? @ignore \"def\" \"defp\" \"defdelegate\" \"defguard\" \"defguardp\" \"defmacro\" \"defmacrop\" \"defn\" \"defnp\")) @definition.function\n\n; References\n\n; ignore calls to kernel/special-forms keywords\n(call\n  target: (identifier) @ignore\n  (#any-of? @ignore \"def\" \"defp\" \"defdelegate\" \"defguard\" \"defguardp\" \"defmacro\" \"defmacrop\" \"defn\" \"defnp\" \"defmodule\" \"defprotocol\" \"defimpl\" \"defstruct\" \"defexception\" \"defoverridable\" \"alias\" \"case\" \"cond\" \"else\" \"for\" \"if\" \"import\" \"quote\" \"raise\" \"receive\" \"require\" \"reraise\" \"super\" \"throw\" \"try\" \"unless\" \"unquote\" \"unquote_splicing\" \"use\" \"with\"))\n\n; ignore module attributes\n(unary_operator\n  operator: \"@\"\n  operand: (call\n    target: (identifier) @ignore))\n\n; * function call\n(call\n  target: [\n   ; local\n   (identifier) @name\n   ; remote\n   (dot\n     right: (identifier) @name)\n  ]) @reference.call\n\n; * pipe into function call\n(binary_operator\n  operator: \"|>\"\n  right: (identifier) @name) @reference.call\n\n; * modules\n(alias) @name @reference.module\n"
  },
  {
    "path": "runtime/queries/elixir/textobjects.scm",
    "content": "; Function heads and guards have no body at all, so `keywords` and `do_block` nodes are both optional\n((call\n   target: (identifier) @_keyword\n   (arguments\n     [\n       (call\n         (arguments (_)? @parameter.inside))\n       ; function has a guard\n       (binary_operator\n         left:\n           (call\n             (arguments (_)? @parameter.inside)))\n     ]\n     ; body is \"do: body\" instead of a do-block\n     (keywords\n       (pair\n         value: (_) @function.inside))?)?\n   (do_block (_)* @function.inside)?)\n (#match? @_keyword \"^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$\")) @function.around\n\n(anonymous_function\n  (stab_clause right: (body) @function.inside)) @function.around\n\n((call\n   target: (identifier) @_keyword\n   (do_block (_)* @class.inside))\n (#match? @_keyword \"^(defmodule|defprotocol|defimpl)$\")) @class.around\n\n((call\n  target: (identifier) @_keyword\n  (arguments ((string) . (_)?))\n  (do_block (_)* @test.inside)?)\n (#match? @_keyword \"^(test|describe)$\")) @test.around\n\n(comment)+ @comment.around @comment.inside\n"
  },
  {
    "path": "runtime/queries/elm/highlights.scm",
    "content": "; Keywords\n[\n    \"if\"\n    \"then\"\n    \"else\"\n    \"let\"\n    \"in\"\n ] @keyword.control\n(case) @keyword.control\n(of) @keyword.control\n\n(colon) @keyword.operator\n(backslash) @keyword\n(as) @keyword\n(port) @keyword\n(exposing) @keyword\n(alias) @keyword\n(infix) @keyword\n\n(arrow) @keyword.operator\n(dot) @keyword.operator\n\n(port) @keyword\n\n(type_annotation(lower_case_identifier) @function)\n(port_annotation(lower_case_identifier) @function)\n(file (value_declaration (function_declaration_left(lower_case_identifier) @function)))\n\n(field name: (lower_case_identifier) @attribute)\n(field_access_expr(lower_case_identifier) @attribute)\n\n(operator_identifier) @keyword.operator\n(eq) @keyword.operator.assignment\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n\"|\" @keyword\n\",\" @punctuation.delimiter\n\n[\n  \"|>\"\n] @keyword\n\n\n(import) @keyword.control.import\n(module) @keyword.other\n\n(number_constant_expr) @constant.numeric\n\n(type) @type\n\n(type_declaration(upper_case_identifier) @type)\n(type_ref) @type\n(type_alias_declaration name: (upper_case_identifier) @type)\n\n(union_pattern constructor: (upper_case_qid (upper_case_identifier) @label (dot) (upper_case_identifier) @variable.other.member)) \n(union_pattern constructor: (upper_case_qid (upper_case_identifier) @variable.other.member)) \n\n(union_variant(upper_case_identifier) @variable.other.member)\n(value_expr name: (value_qid (upper_case_identifier) @label))\n(value_expr (upper_case_qid (upper_case_identifier) @label (dot) (upper_case_identifier) @variable.other.member))\n(value_expr(upper_case_qid(upper_case_identifier)) @variable.other.member)\n\n; comments\n(line_comment) @comment\n(block_comment) @comment\n\n; strings\n(string_escape) @constant.character.escape\n\n(open_quote) @string\n(close_quote) @string\n(regular_string_part) @string\n\n(open_char) @constant.character\n(close_char) @constant.character\n"
  },
  {
    "path": "runtime/queries/elm/injections.scm",
    "content": "; Parse glsl where defined\n\n((glsl_content) @injection.content\n (#set! injection.language \"glsl\"))\n"
  },
  {
    "path": "runtime/queries/elm/locals.scm",
    "content": "(value_declaration) @local.scope\n(type_alias_declaration) @local.scope\n(type_declaration) @local.scope\n(type_annotation) @local.scope\n(port_annotation) @local.scope\n(infix_declaration) @local.scope\n(let_in_expr) @local.scope\n\n(function_declaration_left (lower_pattern (lower_case_identifier)) @local.definition.function)\n(function_declaration_left (lower_case_identifier) @local.definition.function)\n\n(value_expr(value_qid(upper_case_identifier)) @local.reference)\n(value_expr(value_qid(lower_case_identifier)) @local.reference)\n(type_ref (upper_case_qid) @local.reference)\n"
  },
  {
    "path": "runtime/queries/elm/tags.scm",
    "content": "(value_declaration (function_declaration_left (lower_case_identifier) @name)) @definition.function\n\n(function_call_expr (value_expr (value_qid) @name)) @reference.function\n(exposed_value (lower_case_identifier) @name) @reference.function\n(type_annotation ((lower_case_identifier) @name) (colon)) @reference.function\n\n(type_declaration ((upper_case_identifier) @name) ) @definition.type\n\n(type_ref (upper_case_qid (upper_case_identifier) @name)) @reference.type\n(exposed_type (upper_case_identifier) @name) @reference.type\n\n(type_declaration (union_variant (upper_case_identifier) @name)) @definition.union\n\n(value_expr (upper_case_qid (upper_case_identifier) @name)) @reference.union\n\n\n(module_declaration \n    (upper_case_qid (upper_case_identifier)) @name\n) @definition.module\n"
  },
  {
    "path": "runtime/queries/elm/textobjects.scm",
    "content": "(line_comment) @comment.inside\n(line_comment)+ @comment.around\n(block_comment) @comment.inside\n(block_comment)+ @comment.around\n\n((type_annotation)?\n  (value_declaration\n    (function_declaration_left (lower_case_identifier))\n    (eq)\n    (_) @function.inside\n  )\n) @function.around\n\n(parenthesized_expr\n  (anonymous_function_expr\n    (\n      (arrow)\n      (_) @function.inside\n    )\n  )\n) @function.around\n\n(value_declaration\n  (function_declaration_left\n    (lower_pattern\n      (lower_case_identifier) @parameter.inside @parameter.around\n    )\n  )\n)\n\n(value_declaration\n  (function_declaration_left\n    (pattern) @parameter.inside @parameter.around\n  )\n)\n\n(value_declaration\n  (function_declaration_left\n    (tuple_pattern\n      (pattern) @parameter.inside\n    ) @parameter.around\n  )\n)\n\n(value_declaration\n  (function_declaration_left\n    (record_pattern\n      (lower_pattern\n        (lower_case_identifier) @parameter.inside\n      )\n    ) @parameter.around\n  )\n)\n\n(parenthesized_expr\n  (anonymous_function_expr\n    (\n      (backslash)\n      (pattern) @parameter.inside\n      (arrow)\n    )\n  )\n)\n"
  },
  {
    "path": "runtime/queries/elvish/highlights.scm",
    "content": ";; SPDX-License-Identifier: 0BSD\n;; SPDX-FileCopyrightText: 2022 Tobias Frilling\n\n(comment) @comment\n\n(if \"if\" @keyword.control.conditional)\n(if (elif \"elif\" @keyword.control.conditional))\n(if (else \"else\" @keyword.control.conditional))\n\n(while \"while\" @keyword.control.repeat)\n(while (else \"else\" @keyword.control.repeat))\n(for \"for\" @keyword.control.repeat)\n(for (else \"else\" @keyword.control.repeat))\n\n(try \"try\" @keyword.control.exception)\n(try (catch \"catch\" @keyword.control.exception))\n(try (else \"else\" @keyword.control.exception))\n(try (finally \"finally\" @keyword.control.exception))\n\n(import \"use\" @keyword.control.import)\n(import (bareword) @string.special)\n\n(wildcard [\"*\" \"**\" \"?\"] @string.special)\n\n(command argument: (bareword) @variable.parameter)\n(command head: (identifier) @function)\n((command head: (identifier) @keyword.control.return)\n (#eq? @keyword.control.return \"return\"))\n((command (identifier) @keyword.operator)\n (#match? @keyword.operator \"(and|or|coalesce)\"))\n((command head: _ @function)\n (#match? @function \"([+]|[-]|[*]|[/]|[%]|[<]|[<][=]|[=][=]|[!][=]|[>]|[>][=]|[<][s]|[<][=][s]|[=][=][s]|[!][=][s]|[>][s]|[>][=][s])\"))\n\n(pipeline \"|\" @operator)\n(redirection [\">\" \"<\" \">>\" \"<>\"] @operator)\n\n(io_port) @constant.numeric\n\n(function_definition\n  \"fn\" @keyword.function\n  (identifier) @function)\n\n(parameter_list) @variable.parameter\n(parameter_list \"|\" @punctuation.bracket)\n\n(variable_declaration\n  \"var\" @keyword\n  (lhs (identifier) @variable))\n\n(variable_assignment\n  \"set\" @keyword\n  (lhs (identifier) @variable))\n\n(temporary_assignment\n  \"tmp\" @keyword\n  (lhs (identifier) @variable))\n\n(variable_deletion\n  \"del\" @keyword\n  (identifier) @variable)\n\n\n(number) @constant.numeric\n(string) @string\n\n(variable (identifier) @variable)\n((variable (identifier) @function)\n  (#match? @function \".+\\\\~$\"))\n((variable (identifier) @constant.builtin.boolean)\n (#match? @constant.builtin.boolean \"(true|false)\"))\n((variable (identifier) @constant.builtin)\n (#match? @constant.builtin \"(_|after-chdir|args|before-chdir|buildinfo|nil|notify-bg-job-success|num-bg-jobs|ok|paths|pid|pwd|value-out-indicator|version)\"))\n\n[\"$\" \"@\"] @punctuation.special\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n\";\" @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/elvish/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/embedded-perl/highlights.scm",
    "content": "; Comments\n([\n  (comment_tag)\n  (line_comment)\n] @comment)\n\n; Tag and line directive delimiters\n(code_tag \"<%\" @keyword.directive)\n(expression_tag \"<%=\" @keyword.directive)\n(raw_expression_tag \"<%==\" @keyword.directive)\n(comment_tag \"<%#\" @keyword.directive)\n\n(line_code \"%\" @keyword.directive)\n(line_expression \"%=\" @keyword.directive)\n(line_raw_expression \"%==\" @keyword.directive)\n(line_comment \"%#\" @keyword.directive)\n(line_escaped_percent \"%%\" @constant.character.escape)\n\n(escaped_open_tag) @constant.character.escape\n\n(tag_close \"%>\" @keyword.directive)\n(tag_close \"=\" @keyword.directive \"%>\" @keyword.directive)\n"
  },
  {
    "path": "runtime/queries/embedded-perl/injections.scm",
    "content": "((code_tag (tag_content) @injection.content)\n (#set! injection.language \"perl\"))\n\n((expression_tag (tag_content) @injection.content)\n (#set! injection.language \"perl\"))\n\n((raw_expression_tag (tag_content) @injection.content)\n (#set! injection.language \"perl\"))\n\n((line_code (line_content) @injection.content)\n (#set! injection.language \"perl\"))\n\n((line_expression (line_content) @injection.content)\n (#set! injection.language \"perl\"))\n\n((line_raw_expression (line_content) @injection.content)\n (#set! injection.language \"perl\"))\n\n((non_directive_text) @injection.content\n (#set! injection.language \"html\")\n (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/env/highlights.scm",
    "content": "; inherits: bash"
  },
  {
    "path": "runtime/queries/env/textobjects.scm",
    "content": "(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(variable_assignment\n  (_) @entry.inside) @entry.around\n"
  },
  {
    "path": "runtime/queries/erb/highlights.scm",
    "content": "; inherits: ejs\n"
  },
  {
    "path": "runtime/queries/erb/injections.scm",
    "content": "((content) @injection.content\n (#set! injection.language \"html\")\n (#set! injection.combined))\n\n((code) @injection.content\n (#set! injection.language \"ruby\")\n (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/erlang/highlights.scm",
    "content": "; Comments\n(tripledot) @comment.unused\n\n[(comment) (line_comment) (shebang)] @comment\n\n; Basic types\n(variable) @variable\n(atom) @string.special.symbol\n((atom) @constant.builtin.boolean\n (#match? @constant.builtin.boolean \"^(true|false)$\"))\n[(string) (sigil)] @string\n(character) @constant.character\n(escape_sequence) @constant.character.escape\n\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n\n; Punctuation\n[\",\" \".\" \"-\" \";\"] @punctuation.delimiter\n[\"(\" \")\" \"#\" \"{\" \"}\" \"[\" \"]\" \"<<\" \">>\"] @punctuation.bracket\n\n; Operators\n(binary_operator operator: _ @operator)\n(unary_operator operator: _ @operator)\n[\"/\" \":\" \"->\"] @operator\n\n(binary_operator\n  left: (atom) @function\n  operator: \"/\"\n  right: (integer) @constant.numeric.integer)\n\n((binary_operator operator: _ @keyword.operator)\n (#match? @keyword.operator \"^\\\\w+$\"))\n((unary_operator operator: _ @keyword.operator)\n (#match? @keyword.operator \"^\\\\w+$\"))\n\n; Functions\n(function_clause name: (atom) @function)\n(call module: (atom) @namespace)\n(call function: (atom) @function)\n(stab_clause name: (atom) @function)\n(function_capture module: (atom) @namespace)\n(function_capture function: (atom) @function)\n\n; Keywords\n(attribute name: (atom) @keyword)\n\n[\"case\" \"fun\" \"if\" \"of\" \"when\" \"end\" \"receive\" \"try\" \"catch\" \"after\" \"begin\" \"maybe\"] @keyword\n\n; Attributes\n; module declaration\n(attribute\n  name: (atom) @keyword\n  (arguments (atom) @namespace)\n (#any-of? @keyword \"module\" \"behaviour\" \"behavior\"))\n\n(attribute\n  name: (atom) @keyword\n  (arguments\n    .\n    (atom) @namespace)\n (#eq? @keyword \"import\"))\n\n(attribute\n  name: (atom) @keyword\n  (arguments\n    .\n    [(atom) @type (macro)]\n    [\n      (tuple (atom)? @variable.other.member)\n      (tuple\n        (binary_operator\n          left: (atom) @variable.other.member\n          operator: [\"=\" \"::\"]))\n      (tuple\n        (binary_operator\n          left:\n            (binary_operator\n              left: (atom) @variable.other.member\n              operator: \"=\")\n          operator: \"::\"))\n      ])\n (#eq? @keyword \"record\"))\n\n(attribute\n  name: (atom) @keyword\n  (arguments\n    .\n    [\n      (atom) @constant\n      (variable) @constant\n      (call\n        function:\n          [(variable) (atom)] @keyword.directive)\n    ])\n (#eq? @keyword \"define\"))\n\n(attribute\n  name: (atom) @keyword\n  (arguments\n    (_) @keyword.directive)\n (#any-of? @keyword \"ifndef\" \"ifdef\"))\n\n(attribute\n  name: (atom) @keyword\n  module: (atom) @namespace\n (#any-of? @keyword \"spec\" \"callback\"))\n\n(attribute\n  name: (atom) @keyword\n  (arguments [\n    (string)\n    (sigil)\n  ] @comment.block.documentation)\n (#any-of? @keyword \"doc\" \"moduledoc\"))\n\n; Parameters\n; specs\n((attribute\n   name: (atom) @keyword\n   (stab_clause\n     pattern: (arguments (variable)? @variable.parameter)\n     body: (variable)? @variable.parameter))\n (#match? @keyword \"(spec|callback)\"))\n; functions\n(function_clause pattern: (arguments (variable) @variable.parameter))\n; anonymous functions\n(stab_clause pattern: (arguments (variable) @variable.parameter))\n; parametric types\n((attribute\n    name: (atom) @keyword\n    (arguments\n      (binary_operator\n        left: (call (arguments (variable) @variable.parameter))\n        operator: \"::\")))\n (#match? @keyword \"(type|opaque)\"))\n; macros\n((attribute\n   name: (atom) @keyword\n   (arguments\n     (call (arguments (variable) @variable.parameter))))\n (#eq? @keyword \"define\"))\n\n; Records\n(record_content\n  (binary_operator\n    left: (atom) @variable.other.member\n    operator: \"=\"))\n\n(record field: (atom) @variable.other.member)\n(record name: (atom) @type)\n\n; Ignored variables\n((variable) @comment.unused\n (#match? @comment.unused \"^_\"))\n\n; Macros\n(macro\n  \"?\"+ @keyword.directive\n  name: (_) @keyword.directive)\n\n(macro\n  \"?\"+ @constant\n  name: (_) @constant\n  !arguments)\n"
  },
  {
    "path": "runtime/queries/erlang/injections.scm",
    "content": "((line_comment (comment_content) @injection.content)\n (#set! injection.language \"edoc\")\n (#set! injection.include-children)\n (#set! injection.combined))\n\n((comment (comment_content) @injection.content)\n (#set! injection.language \"comment\"))\n\n; EEP-59 doc attributes use markdown by default.\n(attribute\n  name: (atom) @_attribute\n  (arguments [\n    (string (quoted_content) @injection.content)\n    (sigil (quoted_content) @injection.content)\n  ])\n (#set! injection.language \"markdown\")\n (#any-of? @_attribute \"doc\" \"moduledoc\"))\n"
  },
  {
    "path": "runtime/queries/erlang/locals.scm",
    "content": "; Specs and Callbacks\n(attribute\n  (stab_clause\n    pattern: (arguments (variable)? @local.definition.variable.parameter)\n    ; If a spec uses a variable as the return type (and later a `when` clause to type it):\n    body: (variable)? @local.definition.variable.parameter)) @local.scope\n\n; parametric `-type`s\n((attribute\n    name: (atom) @_type\n    (arguments\n      (binary_operator\n        left: (call (arguments (variable) @local.definition.variable.parameter))\n        operator: \"::\") @local.scope))\n (#match? @_type \"(type|opaque)\"))\n\n; `fun`s\n(anonymous_function (stab_clause pattern: (arguments (variable) @local.definition.variable.parameter))) @local.scope\n\n; Ordinary functions\n((function_clause\n   pattern: (arguments (variable) @local.definition.variable.parameter)) @local.scope\n (#not-match? @local.definition.variable.parameter \"^_\"))\n\n(variable) @local.reference\n"
  },
  {
    "path": "runtime/queries/erlang/rainbows.scm",
    "content": "[\n  ; ()\n  (arguments \"(\" \")\")\n  (parenthesized_expression)\n  (function_type)\n  ; #{}\n  (record)\n  (map)\n  ; {}\n  (map_update)\n  (tuple)\n  ; <<>>\n  (bitstring)\n  ; []\n  (list)\n] @rainbow.scope\n\n[\n  \"#\"\n  \"{\" \"}\"\n  \"(\" \")\"\n  \"[\" \"]\"\n  \"<<\" \">>\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/erlang/tags.scm",
    "content": "; Modules\n(attribute\n  name: (atom) @_attr\n  (arguments (atom) @definition.module)\n (#eq? @_attr \"module\"))\n\n; Constants\n((attribute\n    name: (atom) @_attr\n    (arguments\n      .\n      [\n        (atom) @definition.constant\n        (call function: [(variable) (atom)] @definition.macro)\n      ]))\n (#eq? @_attr \"define\"))\n\n; Record definitions\n((attribute\n   name: (atom) @_attr\n   (arguments\n     .\n     (atom) @definition.struct))\n (#eq? @_attr \"record\"))\n\n; Function specs\n((attribute\n    name: (atom) @_attr\n    (stab_clause name: (atom) @definition.interface))\n (#eq? @_attr \"spec\"))\n\n; Types\n((attribute\n    name: (atom) @_attr\n    (arguments\n      (binary_operator\n        left: [\n          (atom) @definition.type\n          (call function: (atom) @definition.type)\n        ]\n        operator: \"::\")))\n (#any-of? @_attr \"type\" \"opaque\"))\n\n; Functions\n(function_clause name: (atom) @definition.function)\n"
  },
  {
    "path": "runtime/queries/erlang/textobjects.scm",
    "content": "(function_clause\n  pattern: (arguments (_)? @parameter.inside)\n  body: (_) @function.inside) @function.around\n\n(anonymous_function\n  (stab_clause body: (_) @function.inside)) @function.around\n\n(comment (comment_content) @comment.inside) @comment.around\n\n; EUnit test names.\n; (CommonTest cases are not recognizable by syntax alone.)\n((function_clause\n   name: (atom) @_name\n   pattern: (arguments (_)? @parameter.inside)\n   body: (_) @test.inside) @test.around\n (#match? @_name \"_test$\"))\n"
  },
  {
    "path": "runtime/queries/esdl/highlights.scm",
    "content": "; Keywords\n[\n  \"module\"\n  \"using\"\n  \"single\"\n  \"multi\"\n  \"link\"\n  \"property\"\n  \"constraint\"\n  \"tuple\"\n  \"annotation\"\n  \"abstract\"\n  \"scalar\"\n  \"type\"\n  \"required\"\n  \"optional\"\n  \"extension\"\n  \"function\"\n] @keyword\n\n(identifier) @variable\n\n(modifier) @keyword\n(extending) @keyword\n\n(module name: (identifier) @namespace)\n(object_type) @type\n\n(comment) @comment\n\n; Properties (includes both property and link declarations, since link keyword is optional)\n(property) @variable.other.member\n\n(string) @string\n(edgeql_fragment) @string\n\n; Builtins\n(type) @type\n[\n  \"str\"\n  \"bool\"\n  \"int16\"\n  \"int32\"\n  \"int64\"\n  \"float32\"\n  \"float64\"\n  \"bigint\"\n  \"decimal\"\n  \"json\"\n  \"uuid\"\n  \"bytes\"\n  \"datetime\"\n  \"duration\"\n  \"sequence\"\n  \"anytype\"\n] @type.builtin\n\n(true) @constant.builtin.boolean\n(false) @constant.builtin.boolean\n(null) @constant.builtin\n\n; Delimiters\n[\n  \";\"\n  \",\"\n] @punctuation.delimiter\n\n; Operators\n[\n  \"->\"\n  \":=\"\n] @operator\n"
  },
  {
    "path": "runtime/queries/fennel/highlights.scm",
    "content": "; Most primitive nodes\n(shebang) @keyword.directive\n\n[\n  (symbol)\n  (symbol_binding)\n] @variable\n\n(comment) @comment\n\n(fn_form\n  name: [\n    (symbol) @function\n    (multi_symbol\n      member: (symbol_fragment) @function .)\n  ])\n\n(lambda_form\n  name: [\n    (symbol) @function\n    (multi_symbol\n      member: (symbol_fragment) @function .)\n  ])\n\n((symbol) @operator\n  (#any-of? @operator\n    ; arithmetic\n    \"+\" \"-\" \"*\" \"/\" \"//\" \"%\" \"^\"\n    ; comparison\n    \">\" \"<\" \">=\" \"<=\" \"=\" \"~=\"\n    ; other\n    \"#\" \".\" \"?.\" \"..\"))\n\n((symbol) @keyword.operator\n  (#any-of? @keyword.operator\n    ; comparison\n    \"not=\"\n    ; boolean\n    \"and\" \"or\" \"not\"\n    ; bitwise\n    \"lshift\" \"rshift\" \"band\" \"bor\" \"bxor\" \"bnot\"\n    ; other\n    \"length\"))\n\n(case_guard\n  call: (_) @keyword.control.conditional)\n\n(case_guard_or_special\n  call: (_) @keyword.control.conditional)\n\n(case_catch\n  call: (symbol) @keyword)\n\n(import_macros_form\n  imports: (table_binding\n    (table_binding_pair\n      value: (symbol_binding) @function.macro)))\n\n\n((symbol) @keyword.function\n  (#any-of? @keyword.function \"fn\" \"lambda\" \"λ\" \"hashfn\"))\n\n((symbol) @keyword.control.repeat\n  (#any-of? @keyword.control.repeat \"for\" \"each\" \"while\"))\n\n((symbol) @keyword.control.conditional\n  (#any-of? @keyword.control.conditional \"if\" \"when\" \"match\" \"case\" \"match-try\" \"case-try\"))\n\n((symbol) @keyword\n  (#any-of? @keyword\n    \"global\" \"local\" \"let\" \"set\" \"var\" \"comment\" \"do\" \"doc\" \"eval-compiler\" \"lua\" \"macros\" \"unquote\"\n    \"quote\" \"tset\" \"values\" \"tail!\"))\n\n((symbol) @keyword.control.import\n  (#any-of? @keyword.control.import \"require\" \"require-macros\" \"import-macros\" \"include\"))\n\n((symbol) @function.macro\n  (#any-of? @function.macro\n    \"collect\" \"icollect\" \"fcollect\" \"accumulate\" \"faccumulate\" \"->\" \"->>\" \"-?>\" \"-?>>\" \"?.\" \"doto\"\n    \"macro\" \"macrodebug\" \"partial\" \"pick-args\" \"pick-values\" \"with-open\"))\n\n((symbol) @variable.builtin\n  (#eq? @variable.builtin \"...\"))\n\n((symbol) @constant.builtin\n  (#eq? @constant.builtin \"_VERSION\"))\n\n((symbol) @function.builtin\n  (#any-of? @function.builtin\n    \"assert\" \"collectgarbage\" \"dofile\" \"error\" \"getmetatable\" \"ipairs\" \"load\" \"loadfile\" \"next\"\n    \"pairs\" \"pcall\" \"print\" \"rawequal\" \"rawget\" \"rawlen\" \"rawset\" \"require\" \"select\" \"setmetatable\"\n    \"tonumber\" \"tostring\" \"type\" \"warn\" \"xpcall\" \"module\" \"setfenv\" \"loadstring\" \"unpack\"))\n\n; TODO: Highlight builtin methods (`table.unpack`, etc) as @function.builtin\n([\n  (symbol) @variable.builtin\n  (multi_symbol\n    base: (symbol_fragment) @variable.builtin)\n]\n  (#any-of? @variable.builtin\n    \"vim\" \"_G\" \"_ENV\" \"debug\" \"io\" \"jit\" \"math\" \"os\" \"package\" \"string\" \"table\" \"utf8\"))\n\n([\n  (symbol) @variable.builtin\n  (multi_symbol\n    .\n    (symbol_fragment) @variable.builtin)\n]\n  (#eq? @variable.builtin \"arg\"))\n(symbol_option) @keyword.directive\n\n(escape_sequence) @constant.character.escape\n\n(multi_symbol\n  \".\" @punctuation.delimiter\n  member: (symbol_fragment) @variable.other.member)\n\n(list\n  call: (symbol) @function)\n\n(list\n  call: (multi_symbol\n    member: (symbol_fragment) @function .))\n\n(multi_symbol_method\n  \":\" @punctuation.delimiter\n  method: (symbol_fragment) @function.method)\n\n(quasi_quote_reader_macro\n  macro: _ @punctuation.special)\n\n(quote_reader_macro\n  macro: _ @punctuation.special)\n\n(unquote_reader_macro\n  macro: _ @punctuation.special)\n\n(hashfn_reader_macro\n  macro: _ @keyword.function)\n\n(docstring) @comment.block.documentation\n\n; NOTE: The macro name is highlighted as @variable because it\n; gives a nicer contrast instead of everything being the same\n; color. Rust queries use this workaround too for `macro_rules!`.\n(macro_form\n  name: [\n    (symbol) @variable\n    (multi_symbol\n      member: (symbol_fragment) @variable .)\n  ])\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n(sequence_arguments\n  (symbol_binding) @variable.parameter)\n\n(sequence_arguments\n  (rest_binding\n    rhs: (symbol_binding) @variable.parameter))\n\n((symbol) @variable.parameter\n  (#any-of? @variable.parameter \"$\" \"$...\"))\n\n((symbol) @variable.parameter\n  (#any-of? @variable.parameter \"$1\" \"$2\" \"$3\" \"$4\" \"$5\" \"$6\" \"$7\" \"$8\" \"$9\"))\n\n[\n  (nil)\n  (nil_binding)\n] @constant.builtin\n\n[\n  (boolean)\n  (boolean_binding)\n] @constant.builtin.boolean\n\n[\n  (number)\n  (number_binding)\n] @constant.numeric\n\n[\n  (string)\n  (string_binding)\n] @string\n"
  },
  {
    "path": "runtime/queries/fennel/rainbows.scm",
    "content": "[ \"(\" \")\" \"[\" \"]\" \"{\" \"}\" ] @rainbow.bracket\n[\n  ; quote & unquote\n  (quote_form)\n  (unquote_form)\n\n  ; bindings + variables\n  (local_form)\n  (var_form)\n  (set_form)\n  (global_form)\n\n  ; let\n  (let_form)\n  (let_vars)\n\n  ; functions\n  (fn_form)\n  (lambda_form)\n  (hashfn_form)\n\n  ; case & match\n  (case_form)\n  (case_catch)\n  (case_guard)\n  (case_guard_or_special)\n  (match_form)\n\n  ; case-try & match-try\n  (case_try_form)\n  (match_try_form)\n\n  ; each\n  (each_form)\n  (iter_body)\n\n  ; if\n  (if_form)\n\n  ; import-macros\n  (import_macros_form)\n\n  ; macro\n  (macro_form)\n\n  ; other\n  (list)\n  (list_binding)\n  (sequence)\n  (sequence_binding)\n  (sequence_arguments)\n  (table)\n  (table_binding)\n  (table_metadata)\n] @rainbow.scope\n"
  },
  {
    "path": "runtime/queries/fga/highlights.scm",
    "content": "(condition_declaration\n  name: (identifier) @function)\n\n(condition_declaration\n  (param\n    name: (identifier) @variable.parameter))\n\n(conditional\n  condition: (identifier) @function)\n\n(type_declaration\n  name: (extended_identifier) @type)\n\n(definition\n  relation: (extended_identifier) @variable)\n\n(indirect_relation\n  relation: (extended_identifier) @variable.other.member\n  tupleset: (extended_identifier) @variable)\n\n(relation_ref) @type\n(all) @type\n\n((simple_type_identifier) @type.builtin)\n\n((container_type_identifier) @type.builtin)\n\n(version) @constant.numeric\n(int) @constant.numeric.integer\n(uint) @constant.numeric.integer\n(float) @constant.numeric.float\n\n(string) @string\n(bytes) @string.special\n\n(boolean) @constant.builtin.boolean\n(null) @constant.builtin\n\n(condition_body\n  (identifier) @variable)\n\n(parenthesized_condition\n  (identifier) @variable)\n\n(bracket_condition\n  (identifier) @variable)\n\n(braced_condition\n  (identifier) @variable)\n\n(operator) @operator\n(condition_operator) @operator\n\n(condition_body [\"{\" \"}\"] @punctuation.bracket)\n(parenthesized_condition [\"(\" \")\"] @punctuation.bracket)\n(bracket_condition [\"[\" \"]\"] @punctuation.bracket)\n(braced_condition [\"{\" \"}\"] @punctuation.bracket)\n\n(model) @keyword\n(module \"module\" @keyword)\n(schema \"schema\" @keyword)\n(contents \"contents\" @keyword)\n(relations \"relations\" @keyword)\n(type_declaration \"extend\" @keyword)\n(type_declaration \"type\" @keyword)\n(definition \"define\" @keyword)\n\n(indirect_relation \"from\" @keyword.operator)\n(conditional \"with\" @keyword.operator)\n(condition_declaration \"condition\" @keyword.function)\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/fga/indents.scm",
    "content": "[\n  (source_file)\n  (contents)\n  (type_declaration)\n  (relations)\n  (condition_declaration)\n] @indent\n\n\"}\" @outdent\n"
  },
  {
    "path": "runtime/queries/fga/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/fga/locals.scm",
    "content": "(condition_declaration) @local.scope\n\n(param\n  name: (identifier) @local.definition.variable.parameter)\n\n(condition_body\n  (identifier) @local.reference)\n\n(parenthesized_condition\n  (identifier) @local.reference)\n\n(bracket_condition\n  (identifier) @local.reference)\n\n(braced_condition\n  (identifier) @local.reference)\n"
  },
  {
    "path": "runtime/queries/fga/textobjects.scm",
    "content": "(type_declaration\n  (relations) @class.inside) @class.around\n\n(condition_declaration\n  body: (_) @function.inside) @function.around\n\n(relations\n  (definition) @entry.inside) @entry.around\n\n(param \n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/fidl/folds.scm",
    "content": "[\n  (layout_declaration)\n  (protocol_declaration)\n  (resource_declaration)\n  (service_declaration)\n] @fold\n"
  },
  {
    "path": "runtime/queries/fidl/highlights.scm",
    "content": "[\n  \"ajar\"\n  \"alias\"\n  \"as\"\n  \"bits\"\n  \"closed\"\n  \"compose\"\n  \"const\"\n  \"enum\"\n  \"error\"\n  \"flexible\"\n  \"library\"\n  \"open\"\n  ; \"optional\" we did not specify a node for optional yet\n  \"overlay\"\n  \"protocol\"\n  \"reserved\"\n  \"resource\"\n  \"service\"\n  \"strict\"\n  \"struct\"\n  \"table\"\n  \"type\"\n  \"union\"\n  \"using\"\n] @keyword\n\n(primitives_type) @type.builtin\n\n(builtin_complex_type) @type.builtin\n\n(const_declaration\n  (identifier) @constant)\n\n[\n  \"=\"\n  \"|\"\n  \"&\"\n  \"->\"\n] @operator\n\n(attribute\n  \"@\" @attribute\n  (identifier) @attribute)\n\n(string_literal) @string\n\n(numeric_literal) @constant.numeric\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(comment) @comment\n\n[\n  \"(\"\n  \")\"\n  \"<\"\n  \">\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/fidl/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/fish/highlights.scm",
    "content": ";; Operators\n\n[\n \"&&\"\n \"||\"\n \"|\"\n \"&|\"\n \"2>|\"\n \"&\"\n \"..\"\n \"!\"\n (direction)\n (stream_redirect)\n] @operator\n\n[\n \"not\"\n \"and\"\n \"or\"\n] @keyword.operator\n\n;; Conditionals\n\n(if_statement\n[\n \"if\"\n \"end\"\n] @keyword.control.conditional)\n\n(switch_statement\n[\n \"switch\"\n \"end\"\n] @keyword.control.conditional)\n\n(case_clause\n[\n \"case\"\n] @keyword.control.conditional)\n\n(else_clause\n[\n \"else\"\n] @keyword.control.conditional)\n\n(else_if_clause\n[\n \"else\"\n \"if\"\n] @keyword.control.conditional)\n\n;; Loops/Blocks\n\n(while_statement\n[\n \"while\"\n \"end\"\n] @keyword.control.repeat)\n\n(for_statement\n[\n \"for\"\n \"end\"\n] @keyword.control.repeat)\n\n(begin_statement\n[\n \"begin\"\n \"end\"\n] @keyword.control.repeat)\n\n;; Keywords\n\n[\n \"in\"\n (break)\n (continue)\n] @keyword\n\n\"return\" @keyword.control.return\n\n;; Punctuation\n\n[\n \"[\"\n \"]\"\n \"{\"\n \"}\"\n \"(\"\n \")\"\n] @punctuation.bracket\n\n\",\" @punctuation.delimiter\n\n;; Commands\n\n(command name: (word) @function)\n\n(command\n  name: (word) @function.builtin (#match? @function.builtin \"^test$\")\n  argument: (word) @operator (#match? @operator \"^(!?=|-[a-zA-Z]+)$\"))\n\n(command\n  name: (word) @punctuation.bracket (#match? @punctuation.bracket \"^\\\\[$\")\n  argument: (word) @operator (#match? @operator \"^(!?=|-[a-zA-Z]+)$\"))\n\n(command\n  argument: [\n             (word) @variable.parameter (#match? @variable.parameter \"^-\")\n            ]\n)\n\n; derived from builtin -n (fish 3.7.1)\n(command\n  name: [\n    (word) @function.builtin\n    (#any-of? @function.builtin \"abbr\" \"alias\" \"and\" \"argparse\" \"begin\" \"bg\" \"bind\" \"block\" \"break\" \"breakpoint\" \"builtin\" \"case\" \"cd\" \"command\" \"commandline\" \"complete\" \"contains\" \"continue\" \"count\" \"disown\" \"echo\" \"else\" \"emit\" \"end\" \"eval\" \"exec\" \"exit\" \"false\" \"fg\" \"for\" \"function\" \"functions\" \"history\" \"if\" \"isatty\" \"jobs\" \"math\" \"not\" \"or\" \"path\" \"printf\" \"pwd\" \"random\" \"read\" \"realpath\" \"return\" \"set\" \"set_color\" \"source\" \"status\" \"string\" \"switch\" \"test\" \"time\" \"true\" \"type\" \"ulimit\" \"wait\" \"while\")\n  ]\n)\n\n;; Functions\n\n(function_definition [\"function\" \"end\"] @keyword.function)\n\n(function_definition\n  name: [\n        (word) (concatenation)\n        ]\n@function)\n\n(function_definition\n  option: [\n          (word)\n          (concatenation (word))\n          ] @variable.parameter (#match? @variable.parameter \"^-\")\n)\n\n;; Strings\n\n[(double_quote_string) (single_quote_string)] @string\n(escape_sequence) @constant.character.escape\n\n;; Variables\n\n(variable_name) @variable\n(variable_expansion) @constant\n\n;; Nodes\n\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(comment) @comment\n\n((word) @constant.builtin.boolean\n(#match? @constant.builtin.boolean \"^(true|false)$\"))\n"
  },
  {
    "path": "runtime/queries/fish/indents.scm",
    "content": "[\n  (function_definition)\n  (while_statement)\n  (for_statement)\n  (if_statement)\n  (begin_statement)\n  (switch_statement)\n] @indent\n\n[\n  \"end\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/fish/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n(command\n  name: (word) @_command (#any-of? @_command \"jq\" \"jaq\")\n  argument: [(double_quote_string) (single_quote_string)] @injection.content\n  (#set! injection.language \"jq\"))\n\n(command\n  name: (word) @_command (#eq? @_command \"nu\")\n  argument: (word) @_flag (#match? @_flag \"^-.*c$\")\n  argument: [(single_quote_string) (double_quote_string)] @injection.content\n  (#set! injection.language \"nu\")\n)\n"
  },
  {
    "path": "runtime/queries/fish/textobjects.scm",
    "content": "(function_definition) @function.around\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/flatbuffers/highlights.scm",
    "content": "[\n    \"namespace\"\n    \"attribute\"\n    \"table\"\n    \"struct\"\n    \"union\"\n    \"enum\"\n    \"root_type\"\n    \"rpc_service\"\n    \"file_extension\"\n    \"file_identifier\"\n] @keyword\n\n\"include\" @keyword.control.import\n\n[\n  \";\"\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n(type) @type.builtin\n(string_constant) @string\n\n[\n    (true)\n    (false)\n] @constant.builtin.boolean\n\n[\n    (inf_token)\n    (nan_token)\n] @constant.builtin\n\n[\n    (int_lit)\n    (int_constant)\n] @constant.numeric.integer\n\n[\n    (float_lit)\n    (float_constant)\n] @constant.numeric.float\n\n\n(comment) @comment\n(documentation) @comment.line.documentation\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n]  @punctuation.bracket\n\n[\n    (metadata)\n] @attribute\n\n(attribute_decl\n  attribute_name: (identifier) @string)\n\n(namespace_decl\n    namespace_ident: (full_ident) @namespace)\n\n(type_decl\n    table_or_struct_name: (identifier) @type)\n\n(enum_decl\n    enum_name: (identifier) @type)\n\n(enum_val_decl\n    enum_key: (identifier) @type)\n\n(union_decl\n    union_name: (identifier) @type)\n\n(root_decl\n    root_type_ident: (identifier) @type)\n\n(rpc_decl\n    rpc_name: (identifier) @type)\n\n(rpc_method\n    rpc_method_name: (identifier) @function\n    rpc_parameter: (identifier) @variable.parameter\n    rpc_return_type: (identifier) @type)\n"
  },
  {
    "path": "runtime/queries/forth/highlights.scm",
    "content": "; Definition keywords\n[\n  (start_definition)\n  (end_definition)\n] @keyword\n\n; Control flow - highlighted as keywords for prominence\n(control_flow) @keyword.control\n\n; I/O operations\n(io) @function.builtin\n\n; Operators - arithmetic, logic, stack manipulation\n(operator) @operator\n\n; Core builtins - defining words, memory, etc.\n(core) @type\n\n; Numbers - all subtypes\n(character_literal) @constant.character\n(hex_number) @constant.numeric\n(binary_number) @constant.numeric\n(octal_number) @constant.numeric\n(float_number) @constant.numeric\n(double_cell_number) @constant.numeric\n(decimal_number) @constant.numeric\n\n; Strings\n(string) @string\n\n; Comments - different types\n(line_comment) @comment.line\n(block_comment) @comment.block\n(stack_effect) @comment.block.documentation\n\n; User-defined words\n(word) @function\n"
  },
  {
    "path": "runtime/queries/forth/injections.scm",
    "content": "([(line_comment) (block_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/fortran/folds.scm",
    "content": ";; by @oponkork\n[\n (if_statement)\n (where_statement)\n (enum_statement)\n (do_loop)\n (derived_type_definition)\n (function)\n (subroutine)\n (module_procedure)\n (interface)\n] @fold\n"
  },
  {
    "path": "runtime/queries/fortran/highlights.scm",
    "content": "(identifier) @variable\n(string_literal) @string\n(number_literal) @constant.numeric\n(boolean_literal) @constant.builtin.boolean\n(comment) @comment\n\n[\n (intrinsic_type)\n \"allocatable\"\n \"attributes\"\n \"device\"\n \"dimension\"\n \"endtype\"\n \"global\"\n \"grid_global\"\n \"host\"\n \"import\"\n \"in\"\n \"inout\"\n \"intent\"\n \"optional\"\n \"out\"\n \"pointer\"\n \"type\"\n \"value\"\n ] @keyword.storage.modifier\n\n[\n \"contains\"\n \"private\"\n \"public\"\n ] @keyword.directive\n\n[\n (none)\n \"implicit\"\n ] @attribute\n\n[\n \"endfunction\"\n \"endprogram\"\n \"endsubroutine\"\n \"function\"\n \"procedure\"\n \"subroutine\"\n ] @keyword.function\n\n[\n (default)\n (procedure_qualifier)\n \"abstract\"\n \"bind\"\n \"call\"\n \"class\"\n \"continue\"\n \"cycle\"\n \"end\"\n \"endenum\"\n \"endinterface\"\n \"endmodule\"\n \"endprocedure\"\n \"endprogram\"\n \"endsubmodule\"\n \"enum\"\n \"enumerator\"\n \"equivalence\"\n \"exit\"\n \"extends\"\n \"format\"\n \"goto\"\n \"include\"\n \"interface\"\n \"intrinsic\"\n \"non_intrinsic\"\n \"module\"\n \"namelist\"\n \"only\"\n \"parameter\"\n \"print\"\n \"procedure\"\n \"program\"\n \"read\"\n \"stop\"\n \"submodule\"\n \"use\"\n \"write\"\n ] @keyword\n\n\"return\" @keyword.control.return\n\n[\n \"else\"\n \"elseif\"\n \"elsewhere\"\n \"endif\"\n \"endwhere\"\n \"if\"\n \"then\"\n \"where\"\n ] @keyword.control.conditional\n\n[\n \"do\"\n \"enddo\"\n \"forall\"\n \"while\"\n ] @keyword.control.repeat\n\n[\n \"*\"\n \"+\"\n \"-\"\n \"/\"\n \"=\"\n \"<\"\n \">\"\n \"<=\"\n \">=\"\n \"==\"\n \"/=\"\n ] @operator\n\n[\n \"\\\\.and\\\\.\"\n \"\\\\.or\\\\.\"\n \"\\\\.lt\\\\.\"\n \"\\\\.gt\\\\.\"\n \"\\\\.ge\\\\.\"\n \"\\\\.le\\\\.\"\n \"\\\\.eq\\\\.\"\n \"\\\\.eqv\\\\.\"\n \"\\\\.neqv\\\\.\"\n ] @keyword.operator\n\n;; Brackets\n[\n \"(\"\n \")\"\n \"[\"\n \"]\"\n \"<<<\"\n \">>>\"\n ] @punctuation.bracket\n\n;; Delimiter\n[\n \"::\"\n \",\"\n \"%\"\n ] @punctuation.delimiter\n\n[\n  \"defined\"\n  \"#define\"\n  \"#elif\"\n  \"#else\"\n  \"#endif\"\n  \"#if\"\n  \"#ifdef\"\n  \"#ifndef\"\n  \"#include\"\n (preproc_directive)\n] @keyword.directive\n\n(parameters\n  (identifier) @variable.parameter)\n\n(program_statement\n  (name) @namespace)\n\n(module_statement\n  (name) @namespace)\n\n(submodule_statement\n  (module_name) (name) @namespace)\n\n(function_statement\n  (name) @function)\n\n(subroutine_statement\n  (name) @function)\n\n(module_procedure_statement\n  (name) @function)\n\n(end_program_statement\n  (name) @namespace)\n\n(end_module_statement\n  (name) @namespace)\n\n(end_submodule_statement\n  (name) @namespace)\n\n(end_function_statement\n  (name) @function)\n\n(end_subroutine_statement\n  (name) @function)\n\n(end_module_procedure_statement\n  (name) @function)\n\n(subroutine_call\n  (identifier) @function)\n\n(keyword_argument\n  name: (identifier) @keyword)\n\n(derived_type_member_expression\n  (type_member) @variable.other.member)\n\n(call_expression\n  (identifier) @function)\n"
  },
  {
    "path": "runtime/queries/fortran/indents.scm",
    "content": "[\n  (module)\n  (submodule)\n  (program)\n  (subroutine)\n  (module_procedure)\n  (function)\n  ; (interface)\n  (if_statement)\n  (do_loop)\n  (where_statement)\n  (derived_type_definition)\n  (enum)\n] @indent\n\n[\n  (end_module_statement)\n  (end_submodule_statement)\n  (end_program_statement)\n  (end_subroutine_statement)\n  (end_module_procedure_statement)\n  (end_function_statement)\n  ; (end_interface_statement)\n  (end_if_statement)\n  (end_do_loop_statement)\n  (else_clause)\n  (elseif_clause)\n  (end_type_statement)\n  (end_enum_statement)\n  (end_where_statement)\n] @outdent\n"
  },
  {
    "path": "runtime/queries/fortran/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/freebasic/highlights.scm",
    "content": "; Keywords\n[\n  \"DIM\"\n  \"IF\"\n  \"THEN\"\n  \"ELSE\"\n  \"END IF\"\n  \"WHILE\"\n  \"WEND\"\n  \"FOR\"\n  \"TO\"\n  \"STEP\"\n  \"NEXT\"\n  \"DO\"\n  \"LOOP\"\n  \"UNTIL\"\n  \"SUB\"\n  \"END SUB\"\n  \"FUNCTION\"\n  \"END FUNCTION\"\n  \"RETURN\"\n  \"PRINT\"\n  \"INPUT\"\n  \"SLEEP\"\n  \"AS\"\n] @keyword\n\n; Logical operators\n[\n  \"AND\"\n  \"OR\"\n  \"NOT\"\n  \"MOD\"\n] @keyword.operator\n\n; Types\n[\n  \"INTEGER\"\n  \"LONG\"\n  \"SINGLE\"\n  \"DOUBLE\"\n  \"STRING\"\n  \"BYTE\"\n] @type\n\n(type_identifier) @type\n\n; Function and sub declarations\n(sub_declaration\n  name: (identifier) @function)\n(function_declaration\n  name: (identifier) @function)\n\n; Function calls\n(call_expression\n  function: (identifier) @function.call)\n\n; Built-in functions\n((identifier) @function.builtin\n  (#match? @function.builtin \"^(?i)(ABS|SIN|COS|TAN|SQR|LEN|VAL|ASC|CHR|LEFT|RIGHT|MID|STR|INT|RND|INSTR|UCASE|LCASE|LTRIM|RTRIM|SPACE|TIME|DATE|TIMER)$\"))\n\n; Literals\n(number_literal) @constant.numeric\n(string_literal) @string\n\n; Comments\n(comment) @comment\n\n; Operators\n[\n  \"=\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"^\"\n  \"<>\"\n  \"<\"\n  \">\"\n  \"<=\"\n  \">=\"\n] @operator\n\n; Punctuation\n[\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \";\"\n] @punctuation.delimiter\n\n; Variables\n(identifier) @variable\n"
  },
  {
    "path": "runtime/queries/freebasic/indents.scm",
    "content": "[\n  (for_statement)\n  (if_statement)\n  (while_statement)\n  (do_statement)\n  (function_declaration)\n  (sub_declaration)\n] @indent\n\n[\n  \"NEXT\"\n  \"END IF\"\n  \"WEND\"\n  \"LOOP\"\n  \"END FUNCTION\"\n  \"END SUB\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/freebasic/tags.scm",
    "content": "(sub_declaration name: (identifier) @definition.function)\n\n(function_declaration name: (identifier) @definition.function)\n"
  },
  {
    "path": "runtime/queries/freebasic/textobjects.scm",
    "content": "(function_declaration) @function.around\n\n(sub_declaration) @function.around\n\n(for_statement) @function.around\n\n(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/fsharp/highlights.scm",
    "content": ";; ----------------------------------------------------------------------------\n;; Literals and comments\n\n(line_comment) @comment.line\n\n(block_comment) @comment.block\n\n(xml_doc) @comment.block.documentation\n\n(const\n  [\n   (_) @constant\n   (unit) @constant.builtin\n  ])\n\n(primary_constr_args (_) @variable.parameter)\n\n((identifier_pattern (long_identifier (identifier) @special))\n (#match? @special \"^\\_.*\"))\n\n((long_identifier\n  (identifier)+\n  .\n  (identifier) @variable.other.member))\n\n;; ----------------------------------------------------------------------------\n;; Punctuation\n\n(wildcard_pattern) @string.special\n\n(type_name type_name: (_) @type)\n\n[\n (type)\n (atomic_type)\n] @type\n\n(member_signature\n  .\n  (identifier) @function.method\n  (curried_spec\n    (arguments_spec\n      \"*\"* @operator\n      (argument_spec\n        (argument_name_spec\n          \"?\"? @special\n          name: (_) @variable.parameter)))))\n\n(union_type_case) @constant\n\n(rules\n  (rule\n    pattern: (_) @constant\n    block: (_)))\n\n(identifier_pattern\n  .\n  (_) @constant\n  .\n  (_) @variable)\n\n(fsi_directive_decl . (string) @namespace)\n\n(import_decl . (_) @namespace)\n(named_module\n  name: (_) @namespace)\n(namespace\n  name: (_) @namespace)\n(module_defn\n  .\n  (_) @namespace)\n\n(ce_expression\n  .\n  (_) @function.macro)\n\n(field_initializer\n  field: (_) @variable.other.member)\n\n(record_fields\n  (record_field\n    .\n    (identifier) @variable.other.member))\n\n(dot_expression\n  base: (_) @namespace\n  field: (_) @variable.other.member)\n\n(value_declaration_left . (_) @variable)\n\n(function_declaration_left\n  . (_) @function\n  [\n    (argument_patterns)\n    (argument_patterns (long_identifier (identifier)))\n  ] @variable.parameter)\n\n(member_defn\n  (method_or_prop_defn\n    [\n      (property_or_ident) @function\n      (property_or_ident\n        instance: (identifier) @variable.builtin\n        method: (identifier) @function.method)\n    ]\n    args: (_)* @variable.parameter))\n\n(application_expression\n  .\n  [\n    (long_identifier_or_op [\n      (long_identifier (identifier)* (identifier) @function)\n      (identifier) @function\n    ])\n    (typed_expression . (long_identifier_or_op (long_identifier (identifier)* . (identifier) @function.call)))\n    (dot_expression base: (_) @variable.other.member field: (_) @function)\n  ] @function)\n\n((infix_expression\n  .\n  (_)\n  .\n  (infix_op) @operator\n  .\n  (_) @function\n  )\n (#eq? @operator \"|>\")\n )\n\n((infix_expression\n  .\n  (_) @function\n  .\n  (infix_op) @operator\n  .\n  (_)\n  )\n (#eq? @operator \"<|\")\n )\n\n[\n  (xint)\n  (int)\n  (int16)\n  (uint16)\n  (int32)\n  (uint32)\n  (int64)\n  (uint64)\n  (nativeint)\n  (unativeint)\n] @constant.numeric.integer\n\n[\n  (ieee32)\n  (ieee64)\n  (float)\n  (decimal)\n] @constant.numeric.float\n\n(bool) @constant.builtin.boolean\n\n([\n  (string)\n  (triple_quoted_string)\n  (verbatim_string)\n  (char)\n] @string)\n\n(compiler_directive_decl) @keyword.directive\n\n(attribute) @attribute\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"[|\"\n  \"|]\"\n  \"{|\"\n  \"|}\"\n  \"[<\"\n  \">]\"\n] @punctuation.bracket\n\n(format_string_eval\n  [\n    \"{\"\n    \"}\"\n  ] @punctuation.special)\n\n[\n  \",\"\n  \";\"\n] @punctuation.delimiter\n\n[\n  \"|\"\n  \"=\"\n  \">\"\n  \"<\"\n  \"-\"\n  \"~\"\n  \"->\"\n  \"<-\"\n  \"&&\"\n  \"||\"\n  \":>\"\n  \":?>\"\n  (infix_op)\n  (prefix_op)\n] @operator\n\n[\n  \"if\"\n  \"then\"\n  \"else\"\n  \"elif\"\n  \"when\"\n  \"match\"\n  \"match!\"\n] @keyword.control.conditional\n\n[\n  \"and\"\n  \"or\"\n  \"not\"\n  \"upcast\"\n  \"downcast\"\n] @keyword.operator\n\n[\n  \"return\"\n  \"return!\"\n  \"yield\"\n  \"yield!\"\n] @keyword.control.return\n\n[\n  \"for\"\n  \"while\"\n  \"downto\"\n  \"to\"\n] @keyword.control.repeat\n\n\n[\n  \"open\"\n  \"#r\"\n  \"#load\"\n] @keyword.control.import\n\n[\n  \"abstract\"\n  \"delegate\"\n  \"static\"\n  \"inline\"\n  \"mutable\"\n  \"override\"\n  \"rec\"\n  \"global\"\n  (access_modifier)\n] @keyword.storage.modifier\n\n[\n  \"let\"\n  \"let!\"\n  \"use\"\n  \"use!\"\n  \"member\"\n] @keyword.function\n\n[\n  \"enum\"\n  \"type\"\n  \"inherit\"\n  \"interface\"\n] @keyword.storage.type\n\n(try_expression\n  [\n    \"try\"\n    \"with\"\n    \"finally\"\n  ] @keyword.control.exception)\n\n((identifier) @keyword.control.exception\n (#any-of? @keyword.control.exception \"failwith\" \"failwithf\" \"raise\" \"reraise\"))\n\n[\n  \"as\"\n  \"assert\"\n  \"begin\"\n  \"end\"\n  \"done\"\n  \"default\"\n  \"in\"\n  \"do\"\n  \"do!\"\n  \"event\"\n  \"field\"\n  \"fun\"\n  \"function\"\n  \"get\"\n  \"set\"\n  \"lazy\"\n  \"new\"\n  \"of\"\n  \"param\"\n  \"property\"\n  \"struct\"\n  \"val\"\n  \"module\"\n  \"namespace\"\n  \"with\"\n] @keyword\n\n[\n  \"null\"\n] @constant.builtin\n\n(match_expression \"with\" @keyword.control.conditional)\n\n((type\n  (long_identifier (identifier) @type.builtin))\n (#any-of? @type.builtin \"bool\" \"byte\" \"sbyte\" \"int16\" \"uint16\" \"int\" \"uint\" \"int64\" \"uint64\" \"nativeint\" \"unativeint\" \"decimal\" \"float\" \"double\" \"float32\" \"single\" \"char\" \"string\" \"unit\"))\n\n(preproc_if\n  [\n    \"#if\" @keyword.directive\n    \"#endif\" @keyword.directive\n  ]\n  condition: (_)? @keyword.directive)\n\n(preproc_else\n  \"#else\" @keyword.directive)\n\n((long_identifier\n  (identifier)+ @namespace\n  .\n  (identifier)))\n\n(long_identifier_or_op\n  (op_identifier) @operator)\n\n((identifier) @namespace\n (#any-of? @namespace \"Array\" \"Async\" \"Directory\" \"File\" \"List\" \"Option\" \"Path\" \"Map\" \"Set\" \"Lazy\" \"Seq\" \"Task\" \"String\" \"Result\" ))\n"
  },
  {
    "path": "runtime/queries/fsharp/injections.scm",
    "content": "([\n (line_comment)\n (block_comment_content)\n] @injection.content\n  (#set! injection.language \"comment\"))\n\n((xml_doc (xml_doc_content) @injection.content)\n (#set! injection.language \"xml\"))\n"
  },
  {
    "path": "runtime/queries/fsharp/locals.scm",
    "content": "(identifier) @local.reference\n\n[\n  (namespace)\n  (named_module)\n  (function_or_value_defn)\n] @local.scope\n\n(function_declaration_left\n  .\n  ((_) @local.definition.function)\n  ((argument_patterns\n    [\n     (_ (identifier) @local.definition.variable.parameter)\n     (_ (_ (identifier) @local.definition.variable.parameter))\n     (_ (_ (_ (identifier) @local.definition.variable.parameter)))\n     (_ (_ (_ (_ (identifier) @local.definition.variable.parameter))))\n     (_ (_ (_ (_ (_ (identifier) @local.definition.variable.parameter)))))\n     (_ (_ (_ (_ (_ (_ (identifier) @local.definition.variable.parameter))))))\n    ])\n  ))\n"
  },
  {
    "path": "runtime/queries/gas/highlights.scm",
    "content": "(comment) @comment\n(number) @constant.numeric\n(directive_name) @keyword.directive\n(symbol) @variable\n(label) @function\n(label)\n(instruction_prefix) @keyword\n(instruction_name) @function.special\n(register) @constant.builtin\n(string) @string\n(char) @constant.character\n(type) @type\n(constant \"$\" @constant)\n(operand_modifier) @attribute\n\n(expression\n  [\"-\" \"+\" \"*\" \"/\" \"=\"] @operator)\n\n[\"(\" \")\"] @punctuation.bracket\n\n[\",\" \":\"] @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/gas/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/gas/textobjects.scm",
    "content": "(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/gdscript/highlights.scm",
    "content": "; Identifier naming conventions\n\n(\n  (identifier) @constant \n  (#match? @constant \"^[A-Z][A-Z\\\\d_]+$\"))\n\n; class\n(class_name_statement (name) @type)\n(class_definition (name) @type)\n\n\n; Function calls\n\n(attribute_call (identifier) @function)\n(base_call (identifier) @function)\n(call (identifier) @function)\n(lambda (name) @function)\n\n; Function definitions\n\n(function_definition \n  name: (name) @function\n  parameters: (parameters) @variable.parameter )\n(constructor_definition \"_init\" @function)\n(lambda (parameters) @variable.parameter)\n\n\n;; Literals\n(comment) @comment\n(string) @string\n\n(type) @type\n(expression_statement (array (identifier) @type))\n(binary_operator (identifier) @type)\n(enum_definition (name) @type.enum)\n(enumerator (identifier) @type.enum.variant)\n(underscore) @type.builtin\n\n\n(variable_statement (identifier) @variable)\n(attribute \n  (identifier) \n  (identifier) @variable.other.member)\n(attribute \n  (identifier) @type.builtin\n  (#match? @type.builtin \"^(AABB|Array|Basis|bool|Callable|Color|Dictionary|float|int|NodePath|Object|Packed(Byte|Color|String)Array|PackedFloat(32|64)Array|PackedInt(32|64)Array|PackedVector(2|3)Array|Plane|Projection|Quaternion|Rect2([i]{0,1})|RID|Signal|String|StringName|Transform(2|3)D|Variant|Vector(2|3|4)([i]{0,1}))$\"))\n\n[\n  (string_name)\n  (node_path)\n  (get_node)\n] @label\n(signal_statement (name) @label)\n\n(const_statement (name) @constant)\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(escape_sequence) @constant.character.escape\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n(null) @constant.builtin\n\n[\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"==\"\n  \"!=\"\n  \">\"\n  \"<\"\n  \">=\"\n  \"<=\"\n  \"=\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"&\"\n  \"|\"\n  \"^\"\n  \"~\"\n  \"<<\"\n  \">>\"\n  \":=\"\n  \":\"\n] @operator\n\n(annotation (identifier) @keyword.storage.modifier)\n\n[\n  \"if\"\n  \"else\"\n  \"elif\"\n  \"match\"\n  \"when\"\n] @keyword.control.conditional\n\n[\n  \"while\"\n  \"for\"\n] @keyword.control.repeat\n\n[\n  \"return\"\n  \"pass\"\n  \"break\"\n  \"continue\"\n] @keyword.control.return\n\n[\n  \"func\"\n] @keyword.control.function\n\n[\n  \"export\"\n] @keyword.control.import\n\n[\n  \"in\"\n  \"is\"\n  \"as\"\n  \"and\"\n  \"or\"\n  \"not\"\n] @keyword.operator\n\n[\n  \"var\"\n  \"class\"\n  \"class_name\"\n  \"enum\"\n] @keyword.storage.type\n\n\n[\n  (remote_keyword)\n  (static_keyword)\n  \"const\"\n  \"signal\"\n  \"@\"\n] @keyword.storage.modifier\n\n[\n  \"setget\"\n  \"onready\"\n  \"extends\"\n  \"set\"\n  \"get\"\n  \"await\"\n] @keyword\n\n"
  },
  {
    "path": "runtime/queries/gdscript/indents.scm",
    "content": "[\n  (if_statement)\n  (for_statement)\n  (while_statement)\n  (match_statement)\n  (pattern_section)\n\n  (function_definition)\n  (lambda)\n  (constructor_definition)\n  (class_definition)\n  (enum_definition)\n\n  (dictionary (_))\n  (array (_))\n  (setget)\n] @indent\n\n[\n  (if_statement)\n  (for_statement)\n  (while_statement)\n  (match_statement)\n  (pattern_section)\n\n  (function_definition)\n  (class_definition)\n] @extend\n\n[\n  (return_statement)\n  (break_statement)\n  (continue_statement)\n  (pass_statement)\n] @extend.prevent-once\n\n"
  },
  {
    "path": "runtime/queries/gdscript/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/gdscript/rainbows.scm",
    "content": "[\n  (parameters)\n  (arguments)\n  (dictionary)\n  (array)\n  (subscript)\n] @rainbow.scope\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/gdscript/tags.scm",
    "content": "(class_definition (name) @name) @definition.class\n\n(function_definition (name) @name) @definition.function\n\n(call (identifier) @name) @reference.call\n"
  },
  {
    "path": "runtime/queries/gdscript/textobjects.scm",
    "content": "\n(class_definition\n  (body) @class.inside) @class.around\n\n(function_definition\n  (body) @function.inside) @function.around\n\n(lambda (body) @function.inside) @function.around\n\n(parameters \n  [\n    (identifier)\n    (typed_parameter)\n    (default_parameter)    \n    (typed_default_parameter)  \n  ] @parameter.inside @parameter.around)\n\n(arguments (_expression) @parameter.inside @parameter.around)\n\n[\n  (const_statement)\n  (variable_statement)\n  (pair)\n  (enumerator)\n] @entry.around\n\n(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/gemini/highlights.scm",
    "content": "(link) @punctuation.bracket\n(link \n  label: (text) @markup.link.label)\n(link\n  uri: (uri) @markup.link.url)\n\n[\n  (start_pre)\n  (pre)\n  (end_pre)\n] @markup.raw.block\n(start_pre\n  alt: (text) @label)\n\n(heading1\n  (text) @markup.heading.1) @markup.heading.marker\n(heading2\n  (text) @markup.heading.2) @markup.heading.marker\n(heading3\n  (text) @markup.heading.3) @markup.heading.marker\n\n(ulist\n  (indicator) @markup.list.unnumbered) \n(quote\n  (indicator) @markup.quote\n  (text) @markup.italic)\n"
  },
  {
    "path": "runtime/queries/gherkin/highlights.scm",
    "content": "[\n  (feature_keyword)\n  (rule_keyword)\n  (background_keyword)\n  (scenario_keyword)\n  (given_keyword)\n  (when_keyword)\n  (then_keyword)\n  (and_keyword)\n  (but_keyword)\n  (asterisk_keyword)\n] @keyword\n\n(tag) @function\n(doc_string) @string\n(data_table) @special\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/ghostty/highlights.scm",
    "content": "; Comments\n(comment) @comment\n\n; Keys\n(property) @variable\n\n; Values\n(boolean) @constant.builtin.boolean\n\n\n[\n (number)\n (adjustment)\n] @constant.numeric\n\n[\n \"+\"\n \"=\"\n (keybind_trigger \">\")\n] @operator\n\n(\":\") @punctuation.delimiter\n\n[\n (string)\n (color)\n] @string\n\n; (color) are hex values\n(color \"#\" @punctuation.special\n (#eq? @punctuation.special \"#\"))\n\n(path_value \"?\" @keyword.control.conditional\n    (#eq? @keyword.control.conditional \"?\"))\n\n; `palette`\n(palette_index) @variable.other.member\n\n; `path_directive`\n(path_directive (property) @keyword.import)\n(path_directive (path_value (string) @string.special.path ))\n\n\n(action_name) @function.builtin\n(action_argument (string) @variable.parameter ) \n\n; (tuple)\n(tuple \",\" @punctuation.delimiter.special\n       (#eq? @punctuation.delimiter.special \",\"))\n\n; `keybind`\n(keybind_value) @string.special\n\n; clear is a special keyword that clear all existing keybind up to that point\n((keybind_value) @keyword \n (#eq? @keyword \"clear\"))\n\n; NOTE: The order here matters!\n[\n (key_qualifier)\n (keybind_modifier)\n] @attribute\n\n[\n (modifier_key)\n (key)\n] @constant.builtin\n"
  },
  {
    "path": "runtime/queries/ghostty/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/git-attributes/highlights.scm",
    "content": "; inherits: git-ignore\n\n(attribute) @variable\n(value) @string\n\n(quoted_pattern [\"\\\"\"] @string)\n\n(attribute_unset) @operator\n(attribute_set_to) @operator\n\n; Highlight builtin diff configuration\n; The list of languages is taken from here https://git-scm.com/docs/gitattributes#_defining_a_custom_hunk_header\n(attribute_set_to\n  (attribute) @operator (#eq? @operator \"diff\")\n  (value) @variable.builtin (#any-of? @variable.builtin\n    \"ada\"\n    \"bash\"\n    \"bibtex\"\n    \"cpp\"\n    \"csharp\"\n    \"css\"\n    \"dts\"\n    \"elixir\"\n    \"fortran\"\n    \"fountain\"\n    \"golang\"\n    \"html\"\n    \"java\"\n    \"kotlin\"\n    \"markdown\"\n    \"matlab\"\n    \"objc\"\n    \"pascal\"\n    \"perl\"\n    \"php\"\n    \"python\"\n    \"ruby\"\n    \"rust\"\n    \"scheme\"\n    \"tex\"\n  ))\n"
  },
  {
    "path": "runtime/queries/git-cliff-config/highlights.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/git-cliff-config/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; https://git-cliff.org/docs/configuration/changelog\n(table\n  (bare_key) @_table (#eq? @_table \"changelog\")\n  (pair\n    (bare_key) @_key (#any-of? @_key \"header\" \"body\" \"footer\")\n    (string) @injection.content\n  (#set! injection.language \"tera\")))\n\n; https://git-cliff.org/docs/configuration/git#commit_preprocessors\n; https://git-cliff.org/docs/configuration/git/#link_parsers\n; https://git-cliff.org/docs/configuration/changelog#postprocessors\n; https://git-cliff.org/docs/configuration/git/#tag_pattern\n; https://git-cliff.org/docs/configuration/git/#skip_tags\n; https://git-cliff.org/docs/configuration/git/#ignore_tags\n; https://git-cliff.org/docs/configuration/git/#count_tags\n; https://git-cliff.org/docs/configuration/bump/#custom_major_increment_regex--custom_minor_increment_regex\n(pair\n  (bare_key) @_key (#any-of? @_key\n    \"pattern\"\n    \"tag_pattern\"\n    \"skip_tags\"\n    \"ignore_tags\"\n    \"count_tags\"\n    \"custom_major_increment_regex\"\n    \"custom_minor_increment_regex\"\n  )\n  (string) @injection.content\n  (#set! injection.language \"regex\"))\n\n; https://git-cliff.org/docs/configuration/git/#commit_preprocessors\n; [[git.commit_preprocessors]]\n; replace_command = \"\"\n(pair\n  (bare_key) @_key (#eq? @_key \"replace_command\")\n  (string) @injection.content\n  (#set! injection.language \"bash\"))\n\n; https://git-cliff.org/docs/configuration/git/#commit_parsers\n; [[git.commit_parsers]]\n; message = \"...\"\n(table\n  (bare_key) @_table (#eq? @_table \"git\")\n  (pair\n    (bare_key) @_key (#eq? @_key \"commit_parsers\")\n    (array\n      (inline_table\n        (pair\n          (bare_key) @_message (#any-of? @_message \"message\" \"body\")\n          (string) @injection.content))))\n  (#set! injection.language \"regex\"))\n"
  },
  {
    "path": "runtime/queries/git-cliff-config/rainbows.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/git-cliff-config/textobjects.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/git-commit/highlights.scm",
    "content": "[(comment) (generated_comment) (scissor)] @comment\n(subject) @markup.heading\n(branch) @string.special.symbol\n(filepath) @string.special.path\n(arrow) @punctuation.delimiter\n(subject (subject_prefix) @function)\n(prefix (type) @keyword)\n(prefix (scope) @variable.parameter)\n(prefix [ \"(\" \")\" \":\" ] @punctuation.delimiter)\n(prefix \"!\" @punctuation.special)\n(trailer (token) @variable.other.member)\n(trailer (value) @string)\n(breaking_change (token) @special)\n\n(change kind: (new)) @diff.plus\n(change kind: (deleted)) @diff.minus\n(change kind: (modified)) @diff.delta\n(change kind: [(renamed) (typechange)]) @diff.delta.moved\n"
  },
  {
    "path": "runtime/queries/git-commit/injections.scm",
    "content": "((diff) @injection.content\n (#set! injection.language \"diff\"))\n\n((rebase_command) @injection.content\n (#set! injection.include-children)\n (#set! injection.language \"git-rebase\"))\n"
  },
  {
    "path": "runtime/queries/git-commit/textobjects.scm",
    "content": "(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/git-config/highlights.scm",
    "content": "(section_name) @markup.heading\n\n((section_name) @keyword.directive\n (#eq? @keyword.directive \"include\"))\n\n((section_header\n   (section_name) @keyword.directive\n   (subsection_name))\n (#eq? @keyword.directive \"includeIf\"))\n\n(variable (name) @variable.other.member)\n[(true) (false)] @constant.builtin.boolean\n(integer) @constant.numeric.integer\n\n[(string) (subsection_name)] @string\n\n((string) @string.special.path\n (#match? @string.special.path \"^(~|./|/)\"))\n\n[\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n[\"=\" \"\\\\\"] @punctuation.delimiter\n\n(escape_sequence) @constant.character.escape\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/git-config/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; https://git-scm.com/docs/gitattributes#_defining_a_custom_hunk_header\n; https://git-scm.com/docs/gitattributes#_customizing_word_diff\n; e.g.\n; ```\n; [diff \"tex\"]\n; \txfuncname = \"^(\\\\\\\\(sub)*section\\\\{.*)$\"\n; \twordRegex = \"\\\\\\\\[a-zA-Z]+|[{}]|\\\\\\\\.|[^\\\\{}[:space:]]+\"\n; ```\n(variable\n (name) @_var (#any-of? @_var \"xfuncname\" \"wordRegex\")\n value: (string) @injection.content\n (#set! injection.language \"regex\"))\n"
  },
  {
    "path": "runtime/queries/git-config/tags.scm",
    "content": "(section_header\n  (section_name) @name) @definition.section\n"
  },
  {
    "path": "runtime/queries/git-config/textobjects.scm",
    "content": "(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(variable\n  (_) @entry.inside) @entry.around\n"
  },
  {
    "path": "runtime/queries/git-ignore/highlights.scm",
    "content": "(pattern_char) @string\n(pattern_char_escaped) @constant.character.escape\n\n(directory_separator) @string\n(directory_separator_escaped) @constant.character.escape\n\n(negation) @operator\n\n(wildcard_char_single) @operator\n(wildcard_chars) @operator\n(wildcard_chars_allow_slash) @operator\n\n(bracket_char) @string\n(bracket_char_escaped) @constant.character.escape\n\n(bracket_negation) @operator\n(bracket_range) @operator\n(bracket_char_class) @keyword\n\n[\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/git-ignore/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/git-notes/highlights.scm",
    "content": "(comment) @comment\n"
  },
  {
    "path": "runtime/queries/git-rebase/highlights.scm",
    "content": "; a rough translation:\n; * constant.builtin - git hash\n; * constant - a git label\n; * keyword - command that acts on commits commits\n; * function - command that acts only on labels\n; * comment - discarded commentary on a command, has no effect on the rebase\n; * string - text used in the rebase operation\n; * operator - a 'switch' (used in fixup and merge), either -c or -C at time of writing\n\n(((command) @keyword\n  (label) @constant.builtin\n  (message)? @comment)\n (#match? @keyword \"^(p|pick|r|reword|e|edit|s|squash|d|drop)$\"))\n\n(((command) @function\n  (label) @constant\n  (message)? @comment)\n (#match? @function \"^(l|label|t|reset|u|update-ref)$\"))\n\n((command) @keyword\n (#match? @keyword \"^(x|exec|b|break)$\"))\n\n(((command) @attribute\n  (label) @constant.builtin\n  (message)? @comment)\n (#match? @attribute \"^(f|fixup)$\"))\n\n(((command) @keyword\n  (label) @constant.builtin\n  (label) @constant\n  (message) @string)\n (#match? @keyword \"^(m|merge)$\"))\n\n(option) @operator\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/git-rebase/injections.scm",
    "content": "(((command) @attribute\n  (message)? @injection.content)\n (#match? @attribute \"^(x|exec)$\")\n (#set! injection.language \"bash\")\n)\n"
  },
  {
    "path": "runtime/queries/github-action/highlights.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/github-action/indents.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/github-action/injections.scm",
    "content": "; inherits: yaml\n\n; JavaScript for workflow scripting (inline)\n(block_mapping\n  (block_mapping_pair\n    key: (flow_node) @_uses (#eq? @_uses \"uses\")\n    value: (flow_node) @_actions_ghs (#match? @_actions_ghs \"^actions/github-script\"))\n  (block_mapping_pair\n    key: (flow_node) @_with (#eq? @_with \"with\")\n    value: (block_node\n             (block_mapping\n               (block_mapping_pair\n                 key: (flow_node) @_run (#eq? @_run \"script\")\n                 value: (flow_node\n                          (plain_scalar\n                            (string_scalar) @injection.content\n                            (#set! injection.language \"javascript\"))))))))\n\n; JavaScript for workflow scripting (block)\n(block_mapping\n  (block_mapping_pair\n    key: (flow_node) @_uses (#eq? @_uses \"uses\")\n    value: (flow_node) @_actions_ghs (#match? @_actions_ghs \"^actions/github-script\"))\n  (block_mapping_pair\n    key: (flow_node) @_with (#any-of? @_with \"with\")\n    value: (block_node\n             (block_mapping\n               (block_mapping_pair\n                 key: (flow_node) @_run (#any-of? @_run \"script\")\n                 value: (block_node\n                          (block_scalar) @injection.content\n                          (#set! injection.language \"javascript\")))))))\n"
  },
  {
    "path": "runtime/queries/github-action/rainbows.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/github-action/textobjects.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/gitlab-ci/highlights.scm",
    "content": "(boolean_scalar) @constant.builtin.boolean\n(null_scalar) @constant.builtin\n(double_quote_scalar) @string\n(single_quote_scalar) @string\n(block_scalar) @string\n(string_scalar) @string\n(escape_sequence) @constant.character.escape\n(integer_scalar) @constant.numeric.integer\n(float_scalar) @constant.numeric.float\n(comment) @comment\n(anchor_name) @type\n(alias_name) @type\n(tag) @type\n(yaml_directive) @keyword\n\n(block_mapping_pair\n  key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member))\n(block_mapping_pair\n  key: (flow_node (plain_scalar (string_scalar) @variable.other.member)))\n\n(flow_mapping\n  (_ key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member)))\n(flow_mapping\n  (_ key: (flow_node (plain_scalar (string_scalar) @variable.other.member))))\n\n[\n\",\"\n\"-\"\n\":\"\n\">\"\n\"?\"\n\"|\"\n] @punctuation.delimiter\n\n[\n\"[\"\n\"]\"\n\"{\"\n\"}\"\n] @punctuation.bracket\n\n[\"*\" \"&\" \"---\" \"...\"] @punctuation.special\n\n\n; Highlight the toplevel keys differently as keywords\n(block_mapping_pair\n  key: (flow_node (plain_scalar (string_scalar) @keyword (#any-of? @keyword \"variables\" \"stages\" \"default\" \"include\" \"workflow\"))) )\n\n; Highlight the builtin stages differently\n; <https://docs.gitlab.com/ci/yaml/#stages>\n(block_mapping_pair\n  key: (flow_node\n         (plain_scalar\n           (string_scalar) @variable.other.member (#eq? @variable.other.member \"stage\")))\n  value: (flow_node\n           (plain_scalar\n             (string_scalar) @constant.builtin (#any-of? @constant.builtin \".pre\" \"build\" \"test\" \"deploy\" \".post\"))))\n; e.g.\n; ```\n; stages:\n;   - build\n;   - test\n; ```\n(block_mapping_pair\n  key: (flow_node\n         (plain_scalar\n           (string_scalar) @keyword (#eq? @keyword \"stages\")))\n  value: (block_node\n           (block_sequence\n             (block_sequence_item\n               (flow_node\n                 (plain_scalar\n                   (string_scalar) @constant.builtin (#any-of? @constant.builtin \".pre\" \"build\" \"test\" \"deploy\" \".post\")))))))\n\n\n; Highlight defined variable names as @variable\n; Matches on:\n; ```\n; variables:\n;   <variable>: ...\n; ```\n(block_mapping_pair\n  key: (flow_node\n         (plain_scalar\n           (string_scalar) @keyword (#eq? @keyword \"variables\")))\n  value: (block_node\n           (block_mapping\n             (block_mapping_pair\n               key: (flow_node) @variable)+)))\n"
  },
  {
    "path": "runtime/queries/gitlab-ci/indents.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/gitlab-ci/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n(block_mapping_pair\n  key: (flow_node) @_run (#any-of? @_run \"script\" \"before_script\" \"after_script\" \"pre_get_sources_script\" \"command\" \"entrypoint\")\n  value: (flow_node\n           (plain_scalar\n             (string_scalar) @injection.content)\n           (#set! injection.language \"bash\")))\n\n(block_mapping_pair\n  key: (flow_node) @_run (#any-of? @_run \"script\" \"before_script\" \"after_script\" \"pre_get_sources_script\" \"command\" \"entrypoint\")\n  value: (block_node\n           (block_scalar) @injection.content\n           (#set! injection.language \"bash\")))\n\n(block_mapping_pair\n  key: (flow_node) @_run (#any-of? @_run \"script\" \"before_script\" \"after_script\" \"pre_get_sources_script\" \"command\" \"entrypoint\")\n  value: (block_node\n           (block_sequence\n             (block_sequence_item\n                (flow_node\n                  (plain_scalar\n                    (string_scalar) @injection.content))\n                (#set! injection.language \"bash\")))))\n\n(block_mapping_pair\n  key: (flow_node) @_run (#any-of? @_run \"script\" \"before_script\" \"after_script\" \"pre_get_sources_script\" \"command\" \"entrypoint\")\n  value: (block_node\n           (block_sequence\n             (block_sequence_item\n               (block_node\n                  (block_scalar) @injection.content\n                  (#set! injection.language \"bash\"))))))\n\n; e.g.\n; ```\n; job1:\n;   services:\n;     entrypoint: [\"/usr/local/bin/docker-entrypoint.sh\", \"-c\", 'max_connections=100']\n; ```\n(block_mapping_pair\n  key: (flow_node) @_run (#any-of? @_run \"command\" \"entrypoint\")\n  value: (flow_node\n           (flow_sequence\n             (flow_node\n               [\n                 (double_quote_scalar)\n                 (single_quote_scalar)\n               ] @injection.content)))\n  (#set! injection.language \"bash\"))\n\n\n; https://docs.gitlab.com/ci/yaml/#specinputsregex\n; ```\n; spec:\n;   inputs:\n;     <input>:\n;       regex: <regex>\n; ---\n; <job>:\n;   coverage: <regex>\n; ```\n(block_mapping_pair\n  key: (flow_node) @_key (#any-of? @_key \"regex\" \"coverage\")\n  value: (flow_node\n           [\n             (single_quote_scalar) @injection.content\n             (double_quote_scalar) @injection.content\n             (plain_scalar (string_scalar) @injection.content)\n           ])\n  (#set! injection.language \"regex\"))\n"
  },
  {
    "path": "runtime/queries/gitlab-ci/rainbows.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/gitlab-ci/tags.scm",
    "content": "; select jobs\n(block_mapping\n  (block_mapping_pair\n    value: (block_node\n             (block_mapping\n               (block_mapping_pair\n                 key: (flow_node) @_key (#eq? @_key \"stage\"))))) @definition.struct)\n\n; select defined variables under `variables:`\n(block_mapping\n  (block_mapping_pair\n    key: (flow_node) @_key (#eq? @_key \"variables\")\n    value: (block_node\n             (block_mapping\n               (block_mapping_pair\n                 key: (flow_node) @name\n                 value: (_) @definition.constant)))))\n"
  },
  {
    "path": "runtime/queries/gitlab-ci/textobjects.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/gjs/highlights.scm",
    "content": "; inherits: ecma,_javascript,_gjs\n"
  },
  {
    "path": "runtime/queries/gjs/indents.scm",
    "content": "; inherits: _gjs,_javascript,ecma\n"
  },
  {
    "path": "runtime/queries/gjs/injections.scm",
    "content": "; inherits: _gjs,_javascript,ecma\n"
  },
  {
    "path": "runtime/queries/gjs/locals.scm",
    "content": "; inherits: _gjs,_javascript,ecma\n"
  },
  {
    "path": "runtime/queries/gjs/tags.scm",
    "content": "; inherits: _gjs,_javascript,ecma\n"
  },
  {
    "path": "runtime/queries/gjs/textobjects.scm",
    "content": "; inherits: _gjs,_javascript,ecma\n"
  },
  {
    "path": "runtime/queries/gleam/highlights.scm",
    "content": "; Variables\n(identifier) @variable\n(discard) @comment.unused ; `_` pattern\n(hole) @comment.unused ; `_`, `_foo` unused variable\n\n; Comments\n(module_comment) @comment.line.documentation\n(statement_comment) @comment.line.documentation\n(comment) @comment.line\n\n; Constants\n(constant\n  name: (identifier) @constant)\n\n; Modules\n(module) @namespace\n(import alias: (identifier) @namespace)\n(remote_type_identifier\n  module: (identifier) @namespace)\n(remote_constructor_name\n  module: (identifier) @namespace)\n((field_access\n  record: (identifier) @namespace\n  field: (label) @function)\n (#is-not? local))\n\n; =========\n; Functions\n; =========\n\n(unqualified_import (identifier) @function)\n(unqualified_import \"type\" (type_identifier) @type)\n(unqualified_import (type_identifier) @constructor)\n(function\n  name: (identifier) @function)\n(external_function\n  name: (identifier) @function)\n(function_parameter\n  name: (identifier) @variable.parameter)\n((function_call\n   function: (identifier) @function)\n (#is-not? local))\n; highlights `a` in `|> a` as function\n((binary_expression\n   operator: \"|>\"\n   right: (identifier) @function)\n (#is-not? local))\n\n; =========\n; Misc\n; =========\n\n; \"Properties\"\n; Assumed to be intended to refer to a name for a field; something that comes\n; before \":\" or after \".\"\n; e.g. record field names, tuple indices, names for named arguments, etc\n(label) @variable.other.member\n(tuple_access\n  index: (integer) @variable.other.member)\n\n; Attributes\n(attribute\n  \"@\" @attribute\n  name: (identifier) @attribute)\n\n(attribute_value (identifier) @constant)\n\n; =========\n; Types\n; =========\n\n(type_hole) @comment.unused\n\n; Type names\n(remote_type_identifier) @type\n(type_identifier) @type\n\n; Generic types\n[\n  ; in `pub type Dict(key, value)` this is `key` and `value`\n  (type_parameter)\n  ; in `pub fn size(dict: Dict(key, value)) -> Int` this is `key` and `value`\n  (type_var)\n] @type\n\n; Data constructors\n(constructor_name) @constructor\n\n; built-ins\n((constructor_name) @constant.builtin\n  (#any-of? @constant.builtin \"False\" \"True\"))\n((constructor_name) @constant.builtin\n  (#any-of? @constant.builtin \"Nil\"))\n((constructor_name) @type.enum.variant.builtin\n  (#any-of? @type.enum.variant.builtin \"Ok\" \"Error\" \"Some\" \"None\"))\n\n; =========\n; Literals\n; =========\n\n(string) @string\n(escape_sequence) @constant.character.escape\n((escape_sequence) @warning\n (#eq? @warning \"\\\\e\")) ; deprecated escape sequence\n(bit_string_segment_option) @function.builtin\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n\n; Reserved identifiers\n((identifier) @error\n (#any-of? @error \"auto\" \"delegate\" \"derive\" \"else\" \"implement\" \"macro\" \"test\"))\n\n; =========\n; Keywords\n; =========\n\n[\n  (visibility_modifier) ; \"pub\"\n  (opacity_modifier) ; \"opaque\"\n  \"as\"\n  \"assert\"\n  \"case\"\n  \"const\"\n  ; DEPRECATED: 'external' was removed in v0.30.\n  \"external\"\n  \"fn\"\n  \"if\"\n  \"import\"\n  \"let\"\n  \"panic\"\n  \"todo\"\n  \"type\"\n  \"use\"\n  \"echo\"\n] @keyword\n\n; =========\n; Operators\n; =========\n\n(binary_expression\n  operator: _ @operator)\n(boolean_negation \"!\" @operator)\n(integer_negation \"-\" @operator)\n\n[\n  \"->\"\n  \"-\"\n  \"=\"\n  \"..\"\n  \"<-\"\n  ; OR clause in patterns\n  \"|\"\n] @operator\n\n; ==========\n; Punctuation\n; ==========\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"<<\"\n  \">>\"\n] @punctuation.bracket\n\n(tuple_type \"#\" @punctuation.bracket)\n(tuple \"#\" @punctuation.bracket)\n(tuple_pattern \"#\" @punctuation.bracket)\n\n[\n  \",\"\n  \":\"\n] @punctuation.delimiter\n\n; the `/` in `import gleam/list`\n(import (module \"/\" @punctuation.delimiter))\n\n[\n  \".\"\n] @punctuation\n\n; affects e.g. `replace` in `string.replace(\"+\", \"-\")`\n; without this, it would be highlighted as a field instead of function\n(function_call (field_access (label) @function))\n\n; highlights `floor` in `|> float.floor` as function\n(binary_expression\n  left: (_) \"|>\"\n  right: (field_access\n    record: (identifier) \".\"\n    field: (label) @function))\n"
  },
  {
    "path": "runtime/queries/gleam/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; Inject markdown into documentation comments\n((doc_comment_content) @injection.content\n (#set! injection.language \"markdown\")\n (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/gleam/locals.scm",
    "content": "; Scopes\n(function) @local.scope\n\n(case_clause) @local.scope\n\n; Definitions\n(function_parameter name: (identifier) @local.definition.variable.parameter)\n\n; References\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/gleam/rainbows.scm",
    "content": "[\n  (target_group)\n  (unqualified_imports)\n  (tuple)\n  (list)\n  (function)\n  (function_parameters)\n  (todo)\n  (tuple)\n  (list)\n  (anonymous_function)\n  (block)\n  (case)\n  (record_update)\n  (arguments)\n  (record_pattern_arguments)\n  (tuple_pattern)\n  (list_pattern)\n  (type_definition)\n  (data_constructor_arguments)\n  (tuple_type)\n  (function_parameter_types)\n  (type_arguments)\n  (type_parameters)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"[\" \"]\"\n  \"{\" \"}\"\n  \"#\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/gleam/textobjects.scm",
    "content": "(function\n  parameters: (function_parameters (function_parameter)? @parameter.inside)\n  body: (block) @function.inside) @function.around\n\n(anonymous_function\n  body: (block) @function.inside) @function.around\n\n((function\n   name: (identifier) @_name\n   body: (block) @test.inside) @test.around\n (#match? @_name \"_test$\"))\n"
  },
  {
    "path": "runtime/queries/glimmer/highlights.scm",
    "content": "; === Tag Names ===\n\n; Tags that start with a lower case letter are HTML tags\n; We'll also use this highlighting for named blocks (which start with `:`)\n((tag_name) @tag\n  (#match? @tag \"^(:)?[a-z]\"))\n; Tags that start with a capital letter are Glimmer components\n((tag_name) @constructor\n  (#match? @constructor \"^[A-Z]\"))\n\n(attribute_name) @attribute\n\n(string_literal) @string\n(number_literal) @constant.numeric.integer\n(boolean_literal) @constant.builtin.boolean\n\n(concat_statement) @string\n\n; === Block Statements ===\n\n; Highlight the brackets\n(block_statement_start) @punctuation.delimiter\n(block_statement_end) @punctuation.delimiter\n\n; Highlight `if`/`each`/`let`\n(block_statement_start path: (identifier) @keyword.control.conditional)\n(block_statement_end path: (identifier) @keyword.control.conditional)\n((mustache_statement (identifier) @keyword.control.conditional)\n (#eq? @keyword.control.conditional \"else\"))\n\n; == Mustache Statements ===\n\n; Highlight the whole statement, to color brackets and separators\n(mustache_statement) @punctuation.delimiter\n\n; An identifier in a mustache expression is a variable\n((mustache_statement [\n  (path_expression (identifier) @variable)\n  (identifier) @variable\n  ])\n  (#not-any-of? @variable \"yield\" \"outlet\" \"this\" \"else\"))\n; As are arguments in a block statement\n((block_statement_start argument: [\n  (path_expression (identifier) @variable)\n  (identifier) @variable\n  ])\n (#not-eq? @variable \"this\"))\n; As is an identifier in a block param\n(block_params (identifier) @variable)\n; As are helper arguments\n((helper_invocation argument: [\n  (path_expression (identifier) @variable)\n  (identifier) @variable\n  ])\n  (#not-eq? @variable \"this\"))\n; `this` should be highlighted as a built-in variable\n((identifier) @variable.builtin\n  (#eq? @variable.builtin \"this\"))\n\n; If the identifier is just \"yield\" or \"outlet\", it's a keyword\n((mustache_statement (identifier) @keyword.control.return)\n  (#any-of? @keyword.control.return \"yield\" \"outlet\"))\n\n; Helpers are functions\n((helper_invocation helper: [\n  (path_expression (identifier) @function)\n  (identifier) @function\n  ])\n  (#not-any-of? @function \"if\" \"yield\"))\n\n((helper_invocation helper: (identifier) @keyword.control.conditional)\n  (#any-of? @keyword.control.conditional \"if\" \"yield\"))\n\n(hash_pair key: (identifier) @variable)\n(hash_pair value: (identifier) @variable)\n(hash_pair [\n  (path_expression (identifier) @variable)\n  (identifier) @variable\n  ])\n\n(comment_statement) @comment\n\n(attribute_node \"=\" @operator)\n\n(block_params \"as\" @keyword.control)\n(block_params \"|\" @operator)\n\n[\n  \"<\"\n  \">\"\n  \"</\"\n  \"/>\"\n] @punctuation.delimiter\n\n"
  },
  {
    "path": "runtime/queries/glimmer/injections.scm",
    "content": "((comment_statement) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/glsl/folds.scm",
    "content": "; inherits: c\n"
  },
  {
    "path": "runtime/queries/glsl/highlights.scm",
    "content": "; inherits: c\n\n[\n  \"in\"\n  \"out\"\n  \"inout\"\n  \"uniform\"\n  \"shared\"\n  \"layout\"\n  \"attribute\"\n  \"varying\"\n  \"buffer\"\n  \"coherent\"\n  \"readonly\"\n  \"writeonly\"\n  \"precision\"\n  \"highp\"\n  \"mediump\"\n  \"lowp\"\n  \"centroid\"\n  \"sample\"\n  \"patch\"\n  \"smooth\"\n  \"flat\"\n  \"noperspective\"\n  \"invariant\"\n  \"precise\"\n  \"require\"\n  \"enable\"\n  \"warn\"\n  \"disable\"\n] @keyword\n\n\"subroutine\" @keyword.function\n\n(extension_storage_class) @attribute\n\n(\n  (identifier) @variable.builtin\n  (#match? @variable.builtin \"^gl_\")\n)\n"
  },
  {
    "path": "runtime/queries/glsl/indents.scm",
    "content": "; inherits: c\n"
  },
  {
    "path": "runtime/queries/glsl/injections.scm",
    "content": "; inherits: c\n\n((preproc_arg) @injection.content\n (#set! injection.language \"glsl\"))\n"
  },
  {
    "path": "runtime/queries/glsl/locals.scm",
    "content": "; inherits: c\n"
  },
  {
    "path": "runtime/queries/glsl/rainbows.scm",
    "content": "; inherits: c\n\n(layout_qualifiers) @rainbow.scope\n"
  },
  {
    "path": "runtime/queries/glsl/tags.scm",
    "content": "; inherits: c\n"
  },
  {
    "path": "runtime/queries/glsl/textobjects.scm",
    "content": "; inherits: c\n"
  },
  {
    "path": "runtime/queries/gn/highlights.scm",
    "content": "; Copyright (C) 2021 Will Cassella (github@willcassella.com)\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(identifier) @variable.builtin\n\n(scope_access field: (_) @variable.other.member)\n\n(call target: (_) @function)\n\n[ \"if\" \"else\" ] @keyword.control.conditional\n\n[\n    (assign_op)\n    (arithmetic_binary_op)\n    (comparison_binary_op)\n    (equivalence_binary_op)\n    (logical_and_binary_op)\n    (logical_or_binary_op)\n    (negation_unary_op)\n] @operator\n\n[ \"(\" \")\" \"[\" \"]\" \"{\" \"}\" ] @punctuation.bracket\n[ \".\" \",\" ] @punctuation.delimiter\n\n(string) @string\n(string_escape) @constant.character.escape\n(string_expansion [ \"$\" \"${\" \"}\" ] @constant.character.escape)\n[ (integer) (hex) ] @constant.numeric\n(boolean) @constant.builtin.boolean\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/gn/injections.scm",
    "content": "; Copyright (C) 2021 Will Cassella (github@willcassella.com)\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((comment) @injection.content (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/gnuplot/highlights.scm",
    "content": ";; Keywords (commands)\n;; Core commands\n\"plot\" @keyword.control\n\"splot\" @keyword.control\n\"fit\" @keyword.control\n\"set\" @keyword.control\n\"unset\" @keyword.control\n\"load\" @keyword.control\n\"pause\" @keyword.control\n(reset_command) @keyword.control\n\"do\" @keyword.control.repeat\n\"for\" @keyword.control.repeat\n\n;; array definition\n\"array\" @type\n\n;; Plot / fit modifiers\n\"using\" @keyword.operator\n\"with\" @keyword.operator\n\"title\" @keyword.operator\n\"notitle\" @keyword.operator\n\"via\" @keyword.operator\n\n;; Identifiers (variables)\n(identifier) @variable\n\n;; Function calls\n(function_call\n  (expression_list\n    (expression\n      (identifier) @variable.parameter)))\n\n(function_call\n  name: (_) @function)\n\n(builtin_function) @function.builtin\n\n;; Function definitions\n(function_definition\n  name: (identifier) @function)\n\n(function_definition\n  (parameter_list\n    (_) @variable.parameter))\n\n;; Numbers (distinct integer/float if desired):\n(number) @constant.numeric.float\n\n;; Strings\n(string) @string\n\n;; Comments\n(comment) @comment\n\n;; Operators\n(operator) @keyword.operator\n\n;; Range literal\n(range) @constant\n\n;; Punctuation\n[\"(\" \")\" \"[\" \"]\" \",\" \":\" \"=\"] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/go/highlights.scm",
    "content": "\n; Identifiers\n\n(field_identifier) @variable.other.member\n\n(identifier) @variable\n\n(package_identifier) @namespace\n\n(const_spec\n  name: (identifier) @constant)\n\n(type_spec\n  name: (type_identifier) @constructor)\n\n(keyed_element . (literal_element (identifier) @variable.other.member))\n(field_declaration\n  name: (field_identifier) @variable.other.member)\n\n(parameter_declaration (identifier) @variable.parameter)\n(variadic_parameter_declaration (identifier) @variable.parameter)\n\n(label_name) @label\n\n(const_spec\n  name: (identifier) @constant)\n\n; Function calls\n\n(call_expression\n  function: (identifier) @function)\n\n(call_expression\n  function: (selector_expression\n    field: (field_identifier) @function.method))\n\n(call_expression\n  function: (identifier) @function.builtin\n  (#match? @function.builtin \"^(append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover|min|max|clear)$\"))\n\n; Types\n\n(type_identifier) @type\n\n(type_parameter_list\n  (type_parameter_declaration\n    name: (identifier) @type.parameter))\n\n((type_identifier) @type.builtin\n  (#match? @type.builtin \"^(any|bool|byte|comparable|complex128|complex64|error|float32|float64|int|int16|int32|int64|int8|rune|string|uint|uint16|uint32|uint64|uint8|uintptr)$\"))\n\n; Function definitions\n\n(function_declaration\n  name: (identifier) @function)\n\n(method_declaration\n  name: (field_identifier) @function.method)\n\n(method_elem\n  name: (field_identifier) @function.method)\n\n; Operators\n\n[\n  \"--\"\n  \"-\"\n  \"-=\"\n  \":=\"\n  \"!\"\n  \"!=\"\n  \"...\"\n  \"*\"\n  \"*\"\n  \"*=\"\n  \"/\"\n  \"/=\"\n  \"&\"\n  \"&&\"\n  \"&=\"\n  \"%\"\n  \"%=\"\n  \"^\"\n  \"^=\"\n  \"+\"\n  \"++\"\n  \"+=\"\n  \"<-\"\n  \"<\"\n  \"<<\"\n  \"<<=\"\n  \"<=\"\n  \"=\"\n  \"==\"\n  \">\"\n  \">=\"\n  \">>\"\n  \">>=\"\n  \"|\"\n  \"|=\"\n  \"||\"\n  \"&^\"\n  \"&^=\"\n  \"~\"\n] @operator\n\n; Keywords\n\n[\n  \"default\"\n  \"type\"\n] @keyword\n\n[\n  \"defer\"\n  \"go\"\n  \"goto\"\n] @keyword.control\n\n[\n  \"if\"\n  \"else\"\n  \"switch\"\n  \"select\"\n  \"case\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n  \"range\"\n] @keyword.control.repeat\n\n[\n  \"import\"\n  \"package\"\n] @keyword.control.import\n\n[\n  \"return\"\n  \"continue\"\n  \"break\"\n  \"fallthrough\"\n] @keyword.control.return\n\n[\n  \"func\"\n] @keyword.function\n\n[\n  \"var\"\n  \"chan\"\n  \"interface\"\n  \"map\"\n  \"struct\"\n] @keyword.storage.type\n\n[\n  \"const\"\n] @keyword.storage.modifier\n\n; Delimiters\n\n[\n  \":\"\n  \".\"\n  \",\"\n  \";\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n; Literals\n\n[\n  (interpreted_string_literal)\n  (raw_string_literal)\n] @string\n\n(rune_literal) @constant.character\n\n(escape_sequence) @constant.character.escape\n\n[\n  (int_literal)\n] @constant.numeric.integer\n\n[\n  (float_literal)\n  (imaginary_literal)\n] @constant.numeric.float\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n[\n  (nil)\n  (iota)\n] @constant.builtin\n\n; Comments\n(comment) @comment\n\n; Doc Comments\n(source_file\n  (comment) @comment.block.documentation . (comment)* . [\n    (package_clause) ; `package`\n    (type_declaration) ; `type`\n    (function_declaration) ; `func`\n    (method_declaration) ; `func`\n    (var_declaration) ; `var`\n    (const_declaration) ; `const`\n    ; var (\n    ; \tA = 1\n    ; \tB = 2\n    ; )\n    (var_spec)\n    ; const (\n    ; \tA = 1\n    ; \tB = 2\n    ; )\n    (const_spec)\n  ])\n"
  },
  {
    "path": "runtime/queries/go/indents.scm",
    "content": "[\n  (import_declaration)\n  (const_declaration)\n  (type_declaration)\n  (type_spec)\n  (func_literal)\n  (literal_value)\n  (literal_element)\n  (keyed_element)\n  (expression_case)\n  (default_case)\n  (type_case)\n  (communication_case)\n  (argument_list)\n  (field_declaration_list)\n  (block)\n  (var_declaration)\n] @indent\n\n[\n  \"]\"\n  \")\"\n] @outdent\n\n; Switches and selects aren't indented, only their case bodies are.\n; Outdent all closing braces except those closing switches or selects.\n(\n    (_ \"}\" @outdent) @outer\n    (#not-kind-eq? @outer \"select_statement\")\n    (#not-kind-eq? @outer \"type_switch_statement\")\n    (#not-kind-eq? @outer \"expression_switch_statement\")\n)\n\n; Starting a line after a new case should indent.\n[\n  (communication_case)\n  (expression_case)\n  (default_case)\n  (type_case)\n] @extend\n"
  },
  {
    "path": "runtime/queries/go/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; Inject markdown into documentation comments\n;\n; Go's comments are documentation comments when they are directly followed\n; by one of Go's statements (e.g. `type`, `func`, `const`)\n;\n; This is only a partial implementation, which covers only\n; block comments. For line comments (which are more common),\n; upstream changes to the grammar are required.\n(source_file\n  (comment) @injection.content . (comment)* . [\n    (package_clause) ; `package`\n    (type_declaration) ; `type`\n    (function_declaration) ; `func`\n    (method_declaration) ; `func`\n    (var_declaration) ; `var`\n    (const_declaration) ; `const`\n    ; var (\n    ; \tA = 1\n    ; \tB = 2\n    ; )\n    (var_spec)\n    ; const (\n    ; \tA = 1\n    ; \tB = 2\n    ; )\n    (const_spec)\n  ]\n  (#set! injection.language \"markdown\"))\n\n((comment) @injection.content\n (#match? @injection.content \"^//go:generate\")\n (#set! injection.language \"bash\"))\n\n(call_expression\n  (selector_expression) @_function\n  (#any-of? @_function \"regexp.Match\" \"regexp.MatchReader\" \"regexp.MatchString\" \"regexp.Compile\" \"regexp.CompilePOSIX\" \"regexp.MustCompile\" \"regexp.MustCompilePOSIX\")\n  (argument_list\n    .\n    [\n      (raw_string_literal)\n      (interpreted_string_literal)\n    ] @injection.content\n    (#set! injection.language \"regex\")))\n\n; https://pkg.go.dev/fmt#Printf\n; https://pkg.go.dev/fmt#Sprintf\n; https://pkg.go.dev/fmt#Scanf\n; https://pkg.go.dev/fmt#Errorf\n((call_expression\n  function: (selector_expression\n    operand: (identifier) @_module\n    field: (field_identifier) @_func)\n  arguments: (argument_list\n    . (interpreted_string_literal) @injection.content))\n  (#eq? @_module \"fmt\")\n  (#any-of? @_func \"Printf\" \"Sprintf\" \"Scanf\" \"Errorf\")\n  (#set! injection.language \"go-format-string\"))\n\n; https://pkg.go.dev/fmt#Fprintf\n; https://pkg.go.dev/fmt#Fscanf\n; https://pkg.go.dev/fmt#Sscanf\n((call_expression\n  function: (selector_expression\n    operand: (identifier) @_module\n    field: (field_identifier) @_func)\n  arguments: (argument_list\n    ; [(identifier) (interpreted_string_literal)]\n    (_)\n    ; (identifier)\n    .\n    (interpreted_string_literal) @injection.content))\n  (#eq? @_module \"fmt\")\n  (#any-of? @_func \"Fprintf\" \"Fscanf\" \"Sscanf\")\n  (#set! injection.language \"go-format-string\"))\n\n; https://pkg.go.dev/log#Printf\n; https://pkg.go.dev/log#Fatalf\n; https://pkg.go.dev/log#Panicf\n; https://pkg.go.dev/log#Logger.Printf\n; https://pkg.go.dev/log#Logger.Fatalf\n; https://pkg.go.dev/log#Logger.Panicf\n((call_expression\n  function: (selector_expression\n    operand: (identifier)\n    field: (field_identifier) @_func)\n  arguments: (argument_list\n    . (interpreted_string_literal) @injection.content))\n  (#any-of? @_func \"Printf\" \"Fatalf\" \"Panicf\")\n  (#set! injection.language \"go-format-string\"))\n"
  },
  {
    "path": "runtime/queries/go/locals.scm",
    "content": "; Scopes\n\n[\n  (function_declaration)\n  (method_declaration)\n  (type_declaration)\n  (block)\n] @local.scope\n\n; Definitions\n\n(parameter_declaration (identifier) @local.definition.variable.parameter)\n(variadic_parameter_declaration (identifier) @local.definition.variable.parameter)\n\n(const_declaration\n (const_spec\n  name: (identifier) @local.definition.constant))\n\n; References\n\n(identifier) @local.reference\n\n; Field names in struct literals are identifier rather than field_identifier,\n; these cannot be locals.\n(keyed_element . (literal_element (identifier) @variable.other.member))\n"
  },
  {
    "path": "runtime/queries/go/rainbows.scm",
    "content": "[\n  (import_spec_list)\n  (const_declaration)\n  (var_declaration)\n  (type_parameter_list)\n  (parameter_list)\n  (type_declaration)\n  (parenthesized_type)\n  (type_arguments)\n  (array_type)\n  (implicit_length_array_type)\n  (slice_type)\n  (field_declaration_list)\n  (interface_type)\n  (map_type)\n  (block)\n  (expression_switch_statement)\n  (type_switch_statement)\n  (select_statement)\n  (parenthesized_expression)\n  (argument_list)\n  (index_expression)\n  (slice_expression)\n  (type_assertion_expression)\n  (type_conversion_expression)\n  (literal_value)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"[\" \"]\"\n  \"{\" \"}\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/go/tags.scm",
    "content": "(\n  (comment)* @doc\n  .\n  (function_declaration\n    name: (identifier) @name) @definition.function\n  (#strip! @doc \"^//\\\\s*\")\n  (#select-adjacent! @doc @definition.function)\n)\n\n(\n  (comment)* @doc\n  .\n  (method_declaration\n    name: (field_identifier) @name) @definition.method\n  (#strip! @doc \"^//\\\\s*\")\n  (#select-adjacent! @doc @definition.method)\n)\n\n(call_expression\n  function: [\n    (identifier) @name\n    (parenthesized_expression (identifier) @name)\n    (selector_expression field: (field_identifier) @name)\n    (parenthesized_expression (selector_expression field: (field_identifier) @name))\n  ]) @reference.call\n\n(const_spec\n  name: (identifier) @name) @definition.constant\n\n(type_spec\n  name: (type_identifier) @name) @definition.type\n\n(type_alias\n  name: (type_identifier) @name) @definition.type\n\n(type_identifier) @name @reference.type\n"
  },
  {
    "path": "runtime/queries/go/textobjects.scm",
    "content": "(function_declaration\n  body: (block)? @function.inside) @function.around\n\n(func_literal\n  (_)? @function.inside) @function.around\n\n(method_declaration\n  body: (block)? @function.inside) @function.around\n\n;; struct and interface declaration as class textobject?\n(type_declaration\n  (type_spec (type_identifier) (struct_type (field_declaration_list (_)?) @class.inside))) @class.around\n\n(type_declaration\n  (type_spec (type_identifier) (interface_type (method_elem)+ @class.inside))) @class.around\n\n(type_parameter_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(parameter_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(argument_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n\n((function_declaration\n   name: (identifier) @_name\n   body: (block)? @test.inside) @test.around\n (#match? @_name \"^Test\"))\n"
  },
  {
    "path": "runtime/queries/go-format-string/highlights.scm",
    "content": "(escaped_percent_sign) @constant.character.escape\n\n\".\" @punctuation.delimiter\n\"%\" @punctuation.special\n\n[\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n(explicit_argument_index) @constant.numeric\n\n(flag) @constant.builtin\n\n(width) @constant.numeric.integer\n(precision) @constant.numeric.float\n(asterisk) @string.special.symbol\n\n(verb) @type\n\n(text) @string\n"
  },
  {
    "path": "runtime/queries/go-format-string/rainbows.scm",
    "content": "(explicit_argument_index_expr) @rainbow.scope\n\n[\n  \"[\" \"]\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/godot-resource/highlights.scm",
    "content": "(section (identifier) @type.builtin)\n\n(attribute (identifier) @attribute)\n(property (path) @variable.other.member)\n(constructor (identifier) @constructor)\n\n(string) @string\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n\n(true) @constant.builtin.boolean\n(false) @constant.builtin.boolean\n\n[\n  \"[\"\n  \"]\"\n] @tag\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n\"=\" @operator\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/godot-resource/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; ((section) @injection.content\n;  (#set! injection.language \"comment\"))\n\n((section \n  (attribute \n    (identifier) @_type\n    (string) @_is_shader)\n  (property \n    (path) @_is_code\n    (string) @injection.content))\n  (#eq? @_type \"type\")\n  (#match? @_is_shader \"Shader\")\n  (#eq? @_is_code \"code\")\n  (#set! injection.language \"glsl\")\n)\n\n((section \n  (identifier) @_is_resource\n  (property \n    (path) @_is_code\n    (string) @injection.content))\n  (#eq? @_is_resource \"resource\")\n  (#eq? @_is_code \"code\")\n  (#set! injection.language \"glsl\")\n)\n\n((section \n  (identifier) @_id\n  (property \n    (path) @_is_expression\n    (string) @injection.content))\n  (#eq? @_id \"sub_resource\")\n  (#eq? @_is_expression \"expression\")\n  (#set! injection.language \"glsl\")\n)\n\n((section \n  (attribute \n    (identifier) @_type\n    (string) @_is_shader)\n  (property \n    (path) @_is_code\n    (string) @injection.content))\n  (#eq? @_type \"type\")\n  (#match? @_is_shader \"GDScript\")\n  (#eq? @_is_code \"script/source\")\n  (#set! injection.language \"gdscript\")\n)\n"
  },
  {
    "path": "runtime/queries/godot-resource/tags.scm",
    "content": "(section\n  (identifier) @_type\n  (attribute\n    (identifier) @_attr_type\n    (string) @definition.struct)\n  (#eq? @_type \"node\")\n  (#eq? @_attr_type \"name\"))\n\n(section\n  (identifier) @definition.struct\n  (#not-eq? @definition.struct \"node\"))\n"
  },
  {
    "path": "runtime/queries/godot-resource/textobjects.scm",
    "content": "(section \n  (identifier) \n  (_)\n  (property) @class.inside\n) @class.around\n\n(attribute \n  (identifier)\n  (_) @parameter.inside) @parameter.around\n\n(property \n  (path)\n  (_) @entry.inside) @entry.around\n\n(pair \n  (_) @entry.inside) @entry.around\n\n(array\n  (_) @entry.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/gomod/highlights.scm",
    "content": "[\n  \"require\"\n  \"replace\"\n  \"go\"\n  \"toolchain\"\n  \"tool\"\n  \"exclude\"\n  \"retract\"\n  \"module\"\n] @keyword\n\n\"=>\" @operator\n\n(comment) @comment\n\n[\n(version)\n(go_version)\n] @string\n"
  },
  {
    "path": "runtime/queries/gomod/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/gotmpl/highlights.scm",
    "content": "; Identifiers\n\n[\n  (field)\n  (field_identifier)\n] @variable.other.member\n\n(variable) @variable\n\n; Function calls\n\n(function_call\n  function: (identifier) @function)\n\n(method_call\n  method: (selector_expression\n    field: (field_identifier) @function))\n\n; Operators\n\n\"|\" @operator\n\"=\" @operator\n\":=\" @operator\n\n; Builtin functions\n\n((identifier) @function.builtin\n (#match? @function.builtin \"^(and|call|html|index|slice|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|ge|gt|ge)$\"))\n\n; Delimiters\n\n\".\" @punctuation.delimiter\n\",\" @punctuation.delimiter\n\n\"{{\" @punctuation.bracket\n\"}}\" @punctuation.bracket\n\"{{-\" @punctuation.bracket\n\"-}}\" @punctuation.bracket\n\")\" @punctuation.bracket\n\"(\" @punctuation.bracket\n\n; Actions\n\n(if_action\n  [\n    \"if\"\n    \"else\"\n    \"end\"\n  ] @keyword.control.conditional)\n\n(range_action\n  [\n    \"range\"\n    \"else\"\n    \"end\"\n  ] @keyword.control.conditional)\n\n(template_action\n  \"template\" @function.builtin)\n\n(block_action\n  [\n    \"block\"\n    \"end\"\n  ] @keyword.directive)\n\n(define_action\n  [\n    \"define\"\n    \"end\"\n  ] @keyword.directive)\n\n(with_action\n  [\n    \"with\"\n    \"else\"\n    \"end\"\n  ] @keyword.control.conditional)\n\n; Literals\n\n[\n  (interpreted_string_literal)\n  (raw_string_literal)\n  (rune_literal)\n] @string\n\n(escape_sequence) @string.special\n\n[\n  (int_literal)\n  (imaginary_literal)\n] @constant.numeric.integer\n\n(float_literal) @constant.numeric.float\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(nil) @constant.builtin\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/gotmpl/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n((text) @injection.content\n (#set! injection.language \"html\")\n (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/gotmpl/locals.scm",
    "content": "[\n  (if_action)\n  (range_action)\n  (block_action)\n  (with_action)\n  (define_action)\n] @local.scope\n\n(variable_definition\n  variable: (variable) @local.definition.variable)\n\n(variable) @local.reference\n"
  },
  {
    "path": "runtime/queries/gowork/highlights.scm",
    "content": "[\n  \"replace\"\n  \"go\"\n  \"use\"\n] @keyword\n\n\"=>\" @operator\n\n(comment) @comment\n\n[\n(version)\n(go_version)\n] @string\n"
  },
  {
    "path": "runtime/queries/gowork/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/gpr/highlights.scm",
    "content": "[ \"abstract\" \"all\" \"at\"\n  \"case\"\n  \"end\" \"extends\" \"external\" \"external_as_list\"\n  \"for\"\n  \"is\"\n  \"limited\"\n  \"null\"\n  \"others\"\n  \"package\"\n  ;; \"project\"\n  \"renames\"\n  \"type\"\n  \"use\"\n  \"when\"\n  \"with\"\n  ] @keyword\n\n;; Avoid highlighting Project in Project'Project_Dir\n(project_declaration \"project\" @keyword)\n\n;; highlight qualifiers as keywords (not all qualifiers are actual keywords)\n(project_qualifier _ @keyword)\n\n[\":=\" \"&\" \"|\" \"=>\"] @operator\n\n(comment) @comment\n(string_literal) @string\n(numeric_literal) @constant.numeric\n\n;; Type\n(typed_string_declaration name: (identifier) @type)\n(variable_declaration type: (name (identifier) @type .))\n\n;; Variable\n(variable_declaration name: (identifier) @variable)\n(variable_reference (name (identifier) @variable .) .)\n\n;; Function\n(builtin_function_call name: _ @function.builtin)\n\n;; Attribute\n(attribute_declaration name: (identifier) @attribute)\n(attribute_reference (identifier) @attribute)\n\n;; Package\n(variable_reference (name (identifier) @function .) \"'\")\n(package_declaration\n [ name: (identifier) @function\n   endname: (identifier) @function\n   origname: (name (identifier) @function .)\n   basename: (name (identifier) @function .)])\n"
  },
  {
    "path": "runtime/queries/graphql/highlights.scm",
    "content": "; Types\n;------\n\n(scalar_type_definition\n  (name) @type)\n\n(object_type_definition\n  (name) @type)\n\n(interface_type_definition\n  (name) @type)\n\n(union_type_definition\n  (name) @type)\n\n(enum_type_definition\n  (name) @type)\n\n(input_object_type_definition\n  (name) @type)\n\n(directive_definition\n  (name) @type)\n\n(directive_definition\n  \"@\" @type)\n\n(scalar_type_extension\n  (name) @type)\n\n(object_type_extension\n  (name) @type)\n\n(interface_type_extension\n  (name) @type)\n\n(union_type_extension\n  (name) @type)\n\n(enum_type_extension\n  (name) @type)\n\n(input_object_type_extension\n  (name) @type)\n\n(named_type\n  (name) @type)\n\n(directive) @type\n\n; Properties\n;-----------\n\n(field\n  (name) @variable.other.member)\n\n(field\n  (alias\n    (name) @variable.other.member))\n\n(field_definition\n  (name) @variable.other.member)\n\n(object_value\n  (object_field\n    (name) @variable.other.member))\n\n(enum_value\n  (name) @variable.other.member)\n\n; Variable Definitions and Arguments \n;-----------------------------------\n\n(operation_definition\n  (name) @variable)\n\n(fragment_name\n  (name) @variable)\n\n(input_fields_definition\n  (input_value_definition\n    (name) @variable.parameter))\n\n(argument\n  (name) @variable.parameter)\n\n(arguments_definition\n  (input_value_definition\n    (name) @variable.parameter))\n\n(variable_definition\n  (variable) @variable.parameter)\n\n(argument\n  (value\n    (variable) @variable))\n\n; Constants\n;----------\n\n(string_value) @string\n\n(int_value) @constants.numeric.integer\n\n(float_value) @constants.numeric.float\n\n(boolean_value) @constants.builtin.boolean\n\n; Literals\n;---------\n\n(description) @comment\n\n(comment) @comment\n\n(directive_location\n  (executable_directive_location) @type.builtin)\n\n(directive_location\n  (type_system_directive_location) @type.builtin)\n\n; Keywords\n;----------\n\n[\n  \"query\"\n  \"mutation\"\n  \"subscription\"\n  \"fragment\"\n  \"scalar\"\n  \"type\"\n  \"interface\"\n  \"union\"\n  \"enum\"\n  \"input\"\n  \"extend\"\n  \"directive\"\n  \"schema\"\n  \"on\"\n  \"repeatable\"\n  \"implements\"\n] @keyword\n\n; Punctuation\n;------------\n\n[\n \"(\"\n \")\"\n \"[\"\n \"]\"\n \"{\"\n \"}\"\n] @punctuation.bracket\n\n\"=\" @operator\n\n\"|\" @punctuation.delimiter\n\"&\" @punctuation.delimiter\n\":\" @punctuation.delimiter\n\n\"...\" @punctuation.special\n\"!\" @punctuation.special\n"
  },
  {
    "path": "runtime/queries/graphql/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/graphql/textobjects.scm",
    "content": "(type_definition) @class.around\n\n(executable_definition) @function.around\n\n(arguments_definition\n  (input_value_definition) @parameter.inside @parameter.movement)\n\n(arguments\n  (argument) @parameter.inside @parameter.movement)\n\n(selection\n  [(field) (fragment_spread)] @entry.around)\n\n(selection\n  (field (selection_set) @entry.inside))\n\n(field_definition\n  (_) @entry.inside) @entry.around\n\n(input_fields_definition\n  (input_value_definition ) @entry.around)\n\n(enum_value) @entry.around\n"
  },
  {
    "path": "runtime/queries/gren/highlights.scm",
    "content": "[\n  (module)\n  (as)\n  (exposing)\n  (backslash)\n] @keyword\n\n(import) @keyword.control.import\n\n[\n  \"if\"\n  \"then\"\n  \"else\"\n  (when)\n  (is)\n] @keyword.control.conditional\n\n[\n  (type)\n  (alias)\n  (infix)\n  (port)\n  \"let\"\n  \"in\"\n] @keyword.storage.type\n\n(dot) @operator\n\n[\n  (colon)\n  (arrow)\n  (eq)\n  (operator_identifier)\n  \"|\"\n] @keyword.operator\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n\",\" @punctuation.delimiter\n\n; modules\n\n(module_declaration(upper_case_qid) @namespace)\n(import_clause(upper_case_qid) @namespace)\n(import_clause(as_clause(upper_case_identifier) @namespace))\n(exposing_list(exposed_type(upper_case_identifier) @type))\n(exposing_list(exposed_value) @variable)\n\n; functions\n\n(type_annotation(lower_case_identifier) @function)\n(port_annotation(lower_case_identifier) @function)\n(file (value_declaration (function_declaration_left(lower_case_identifier) @function)))\n\n; types\n\n(field name: (lower_case_identifier) @variable.other.member)\n(field_type name: (lower_case_identifier) @variable.other.member)\n(field_access_expr(lower_case_identifier) @variable)\n\n(type_declaration(upper_case_identifier) @type)\n(type_declaration typeName: (lower_type_name) @type.parameter)\n\n(type_alias_declaration name: (upper_case_identifier) @type)\n(type_alias_declaration typeVariable: (lower_type_name) @type.parameter)\n\n(type_ref(upper_case_qid) @type)\n(type_ref(upper_case_qid(upper_case_identifier) @namespace (dot) (upper_case_identifier) @type))\n\n(type_variable(lower_case_identifier) @type.parameter)\n\n; variables\n\n(union_pattern constructor: (upper_case_qid (upper_case_identifier) @namespace (dot) (upper_case_identifier) @constructor)) \n(union_pattern constructor: (upper_case_qid (upper_case_identifier) @constructor)) \n\n(union_variant(upper_case_identifier) @constructor)\n\n(value_expr name: (value_qid (upper_case_identifier) @namespace))\n(value_expr(upper_case_qid(upper_case_identifier) @namespace (dot) (upper_case_identifier) @constructor))\n(value_expr(upper_case_qid(upper_case_identifier)) @constructor)\n\n(value_expr(value_qid(upper_case_identifier) @namespace (dot) (lower_case_identifier) @variable))\n(value_expr(value_qid(lower_case_identifier) @variable))\n\n(let_in_expr(value_declaration(function_declaration_left(lower_case_identifier) @variable)))\n\n(function_declaration_left(lower_pattern(lower_case_identifier) @variable.parameter))\n\n; comments\n\n(line_comment) @comment\n(block_comment) @comment\n\n; numbers\n\n(number_constant_expr) @constant.numeric\n\n; strings\n\n(string_escape) @constant.character.escape\n\n(string_constant_expr) @string\n(char_constant_expr) @constant.character\n"
  },
  {
    "path": "runtime/queries/gren/locals.scm",
    "content": "(value_declaration) @local.scope\n(type_alias_declaration) @local.scope\n(type_declaration) @local.scope\n(type_annotation) @local.scope\n(port_annotation) @local.scope\n(infix_declaration) @local.scope\n(let_in_expr) @local.scope\n\n(function_declaration_left (lower_pattern (lower_case_identifier)) @local.definition.function)\n(function_declaration_left (lower_case_identifier) @local.definition.function)\n\n(value_expr(value_qid(upper_case_identifier)) @local.reference)\n(value_expr(value_qid(lower_case_identifier)) @local.reference)\n(type_ref (upper_case_qid) @local.reference)\n"
  },
  {
    "path": "runtime/queries/gren/textobjects.scm",
    "content": "\n(line_comment) @comment.inside\n(line_comment)+ @comment.around\n(block_comment) @comment.inside\n(block_comment)+ @comment.around\n\n((type_annotation)?\n  (value_declaration\n    (function_declaration_left (lower_case_identifier))\n    (eq)\n    (_) @function.inside\n  )\n) @function.around\n\n(parenthesized_expr\n  (anonymous_function_expr\n    (\n      (arrow)\n      (_) @function.inside\n    )\n  )\n) @function.around\n\n(value_declaration\n  (function_declaration_left\n    (lower_pattern\n      (lower_case_identifier) @parameter.inside @parameter.around\n    )\n  )\n)\n\n(value_declaration\n  (function_declaration_left\n    (pattern) @parameter.inside @parameter.around\n  )\n)\n\n(value_declaration\n  (function_declaration_left\n    (record_pattern\n      (lower_pattern\n        (lower_case_identifier) @parameter.inside\n      )\n    ) @parameter.around\n  )\n)\n\n(parenthesized_expr\n  (anonymous_function_expr\n    (\n      (backslash)\n      (pattern) @parameter.inside\n      (arrow)\n    )\n  )\n)\n"
  },
  {
    "path": "runtime/queries/groovy/folds.scm",
    "content": "[\n  (argument_list)\n  (closure)\n  (list)\n  (map)\n] @fold\n"
  },
  {
    "path": "runtime/queries/groovy/highlights.scm",
    "content": "[\n  \"!instanceof\"\n  \"assert\"\n  \"class\"\n  \"extends\"\n  \"instanceof\"\n  \"package\"\n] @keyword\n\n[\n  \"!in\"\n  \"as\"\n  \"in\"\n] @keyword.operator\n\n[\n  \"case\"\n  \"default\"\n  \"else\"\n  \"if\"\n  \"switch\"\n] @keyword.control.conditional\n\n[\n  \"catch\"\n  \"finally\"\n  \"try\"\n] @keyword.control.exception\n\n\"def\" @keyword.function\n\n\"import\" @keyword.control.import\n\n[\n  \"for\"\n  \"while\"\n  (break)\n  (continue)\n] @keyword.control.repeat\n\n\"return\" @keyword.control.return\n\n[\n  \"true\"\n  \"false\"\n] @constant.builtin.boolean\n\n(null) @constant.builtin\n\n\"this\" @variable.builtin\n\n[\n  \"int\"\n  \"char\"\n  \"short\"\n  \"long\"\n  \"boolean\"\n  \"float\"\n  \"double\"\n  \"void\"\n] @type.builtin\n\n[\n  \"final\"\n  \"private\"\n  \"protected\"\n  \"public\"\n  \"static\"\n  \"synchronized\"\n] @keyword.storage.modifier\n\n(comment) @comment\n\n(shebang) @keyword.directive\n\n(string) @string\n\n(string\n  (escape_sequence) @constant.character.escape)\n\n(string\n  (interpolation\n    \"$\" @punctuation.special))\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \":\"\n  \",\"\n  \".\"\n] @punctuation.delimiter\n\n(number_literal) @constant.numeric\n\n(identifier) @variable\n\n((identifier) @constant\n  (#match? @constant \"^[A-Z][A-Z_]+\"))\n\n[\n  \"%\"\n  \"*\"\n  \"/\"\n  \"+\"\n  \"-\"\n  \"<<\"\n  \">>\"\n  \">>>\"\n  \"..\"\n  \"..<\"\n  \"<..<\"\n  \"<..\"\n  \"<\"\n  \"<=\"\n  \">\"\n  \">=\"\n  \"==\"\n  \"!=\"\n  \"<=>\"\n  \"===\"\n  \"!==\"\n  \"=~\"\n  \"==~\"\n  \"&\"\n  \"^\"\n  \"|\"\n  \"&&\"\n  \"||\"\n  \"?:\"\n  \"+\"\n  \"*\"\n  \".&\"\n  \".@\"\n  \"?.\"\n  \"*.\"\n  \"*\"\n  \"*:\"\n  \"++\"\n  \"--\"\n  \"!\"\n] @operator\n\n(string\n  \"/\" @string)\n\n(ternary_op\n  ([\n    \"?\"\n    \":\"\n  ]) @keyword.operator)\n\n(map\n  (map_item\n    key: (identifier) @variable.parameter))\n\n(parameter\n  type: (identifier) @type\n  name: (identifier) @variable.parameter)\n\n(generic_param\n  name: (identifier) @variable.parameter)\n\n(declaration\n  type: (identifier) @type)\n\n(function_definition\n  type: (identifier) @type)\n\n(function_declaration\n  type: (identifier) @type)\n\n(class_definition\n  name: (identifier) @type)\n\n(class_definition\n  superclass: (identifier) @type)\n\n(generic_param\n  superclass: (identifier) @type)\n\n(type_with_generics\n  (identifier) @type)\n\n(type_with_generics\n  (generics\n    (identifier) @type))\n\n(generics\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n(generic_parameters\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n; TODO: Class literals with PascalCase\n(declaration\n  \"=\" @operator)\n\n(assignment\n  \"=\" @operator)\n\n(function_call\n  function: (identifier) @function)\n\n(function_call\n  function:\n    (dotted_identifier\n      (identifier) @function .))\n\n(function_call\n  (argument_list\n    (map_item\n      key: (identifier) @variable.parameter)))\n\n(juxt_function_call\n  function: (identifier) @function)\n\n(juxt_function_call\n  function:\n    (dotted_identifier\n      (identifier) @function .))\n\n(juxt_function_call\n  (argument_list\n    (map_item\n      key: (identifier) @variable.parameter)))\n\n(function_definition\n  function: (identifier) @function)\n\n(function_declaration\n  function: (identifier) @function)\n\n(annotation) @function.macro\n\n(annotation\n  (identifier) @function.macro)\n\n\"@interface\" @function.macro\n\n(groovy_doc) @comment.block.documentation\n\n(groovy_doc\n  [\n    (groovy_doc_param)\n    (groovy_doc_throws)\n    (groovy_doc_tag)\n  ] @string.special)\n\n(groovy_doc\n  (groovy_doc_param\n    (identifier) @variable.parameter))\n\n(groovy_doc\n  (groovy_doc_throws\n    (identifier) @type))\n"
  },
  {
    "path": "runtime/queries/groovy/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n\n((groovy_doc) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/groovy/locals.scm",
    "content": "(function_definition) @local.scope\n\n(parameter\n  name: (identifier) @local.definition.variable.parameter)\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/gts/highlights.scm",
    "content": "; inherits: ecma,_typescript,_gjs\n"
  },
  {
    "path": "runtime/queries/gts/indents.scm",
    "content": "; inherits: _gjs,_typescript,ecma\n"
  },
  {
    "path": "runtime/queries/gts/injections.scm",
    "content": "; inherits: _gjs,_typescript,ecma\n"
  },
  {
    "path": "runtime/queries/gts/locals.scm",
    "content": "; inherits: _gjs,_typescript,ecma\n"
  },
  {
    "path": "runtime/queries/gts/tags.scm",
    "content": "; inherits: _gjs,_typescript,ecma\n"
  },
  {
    "path": "runtime/queries/gts/textobjects.scm",
    "content": "; inherits: _gjs,_typescript,ecma\n"
  },
  {
    "path": "runtime/queries/hare/highlights.scm",
    "content": "(type) @type\n(type \"const\" @type)\n\n[\n  \"else\"\n  \"if\"\n  \"match\"\n  \"switch\"\n] @keyword.control.conditional\n\n[\n  \"export\"\n  \"use\"\n] @keyword.control.import\n\n[\n  \"continue\"\n  \"for\"\n  \"break\"\n] @keyword.control.repeat\n\n\"return\" @keyword.control.return\n\n[\n  \"abort\"\n  \"assert\"\n] @keyword.control.exception\n\n\"fn\" @keyword.function\n\n[\n  \"alloc\"\n  \"append\"\n  \"as\"\n  \"bool\"\n  \"case\"\n  \"const\"\n  \"def\"\n  \"defer\"\n  \"delete\"\n  \"enum\"\n  \"free\"\n  \"is\"\n  \"len\"\n  \"let\"\n  \"match\"\n  \"nullable\"\n  \"offset\"\n  \"struct\"\n  \"type\"\n  \"union\"\n  \"yield\"\n] @keyword\n\n\"static\" @keyword.storage.modifier\n\n[\n  \".\"  \n  \"!\"  \n  \"~\"  \n  \"?\"  \n  \"*\"  \n  \"/\"\n  \"%\"  \n  \"+\"  \n  \"-\" \n  \"<<\" \n  \">>\"\n  \"::\" \n  \"<\"  \n  \"<=\" \n  \">\"  \n  \">=\"\n  \"==\" \n  \"!=\" \n  \"&\"  \n  \"|\"  \n  \"^\"  \n  \"&&\" \n  \"||\"\n  \"=\"     \n  \"+=\"    \n  \"-=\"   \n  \"*=\"   \n  \"/=\"   \n  \"%=\"    \n  \"&=\"    \n  \"|=\"   \n  \"<<=\"   \n  \">>=\" \n  \"^=\"\n  \"=>\"\n] @operator\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \")\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \":\"\n  \";\"\n] @punctuation.delimiter\n\n\"...\" @special \n\n(comment) @comment\n\n[\n  \"false\"\n  \"null\"\n  \"true\"\n] @constant.builtin\n(literal \"void\") @constant.builtin\n\n(identifier) @variable\n\n(string_literal) @string\n(escape_sequence) @constant.character.escape\n(rune_literal) @string\n(integer_literal) @constant.numeric.integer\n(floating_literal) @constant.numeric.float\n\n(call_expression\n  (postfix_expression) @function)\n(size_expression \"size\" @function.builtin)\n\n(function_declaration\n  name: (identifier) @function)\n\n(parameter (name) @variable.parameter)\n\n(field_access_expression\n  selector: (name) @variable.other.member)\n(decl_attr) @special\n(fndec_attrs) @special\n\n(struct_union_field (name)) @variable\n"
  },
  {
    "path": "runtime/queries/hare/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/hare/locals.scm",
    "content": "(sub_unit) @local.scope\n\n(function_declaration) @local.scope\n(compound_expression) @local.scope\n\n(function_declaration\n  (identifier) @local.definition.function)\n(function_declaration\n  (parameter (name) @local.definition.variable.parameter))\n\n(identifier) @local.reference\n\n"
  },
  {
    "path": "runtime/queries/haskell/highlights.scm",
    "content": ";----------------------------------------------------------------------------\n; Parameters and variables\n; NOTE: These are at the top, so that they have low priority,\n; and don't override destructured parameters\n(variable) @variable\n\n(pattern/wildcard) @variable\n\n(decl/function\n  patterns: (patterns\n    (_) @variable.parameter))\n\n(expression/lambda\n  (_)+ @variable.parameter\n  \"->\")\n\n(decl/function\n  (infix\n    (pattern) @variable.parameter))\n\n; ----------------------------------------------------------------------------\n; Literals and comments\n(integer) @constant.numeric.integer\n\n(negation) @constant.numeric\n\n(expression/literal\n  (float)) @constant.numeric.float\n\n(char) @constant.character\n\n(string) @string\n\n(unit) @string.special.symbol ; unit, as in ()\n\n(comment) @comment\n\n((haddock) @comment.documentation)\n\n; ----------------------------------------------------------------------------\n; Punctuation\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \";\"\n] @punctuation.delimiter\n\n; ----------------------------------------------------------------------------\n; Keywords, operators, includes\n[\n  \"forall\"\n  ; \"∀\" ; utf-8 is not cross-platform safe\n] @keyword.repeat\n\n(pragma) @keyword.directive\n\n[\n  \"if\"\n  \"then\"\n  \"else\"\n  \"case\"\n  \"of\"\n] @keyword.conditional\n\n[\n  \"import\"\n  \"qualified\"\n  \"module\"\n] @keyword.import\n\n[\n  (operator)\n  (constructor_operator)\n  (all_names)\n  (wildcard)\n  \".\"\n  \"..\"\n  \"=\"\n  \"|\"\n  \"::\"\n  \"=>\"\n  \"->\"\n  \"<-\"\n  \"\\\\\"\n  \"`\"\n  \"@\"\n] @operator\n\n; TODO broken, also huh?\n; ((qualified_module\n;   (module) @constructor)\n;   .\n;   (module))\n\n(module\n  (module_id) @namespace)\n\n[\n  \"where\"\n  \"let\"\n  \"in\"\n  \"class\"\n  \"instance\"\n  \"pattern\"\n  \"data\"\n  \"newtype\"\n  \"family\"\n  \"type\"\n  \"as\"\n  \"hiding\"\n  \"deriving\"\n  \"via\"\n  \"stock\"\n  \"anyclass\"\n  \"do\"\n  \"mdo\"\n  \"rec\"\n  \"infix\"\n  \"infixl\"\n  \"infixr\"\n] @keyword\n\n; ----------------------------------------------------------------------------\n; Functions and variables\n(decl\n  [\n   name: (variable) @function\n   names: (binding_list (variable) @function)\n  ])\n\n(decl/bind\n  name: (variable) @variable)\n\n; Consider signatures (and accompanying functions)\n; with only one value on the rhs as variables\n(decl/signature\n  name: (variable) @variable\n  type: (type))\n\n((decl/signature\n  name: (variable) @variable.name\n  type: (type))\n  .\n  (decl\n    name: (variable) @variable)\n    match: (_)\n  (#eq? @variable.name @variable))\n\n; but consider a type that involves 'IO' a decl/function\n(decl/signature\n  name: (variable) @function\n  type: (type/apply\n    constructor: (name) @type)\n  (#eq? @type \"IO\"))\n\n((decl/signature\n  name: (variable) @function.name\n  type: (type/apply\n    constructor: (name) @type)\n  (#eq? @type \"IO\"))\n  .\n  (decl\n    name: (variable) @function)\n    match: (_)\n  (#eq? @function.name @function))\n\n((decl/signature) @function\n  .\n  (decl/function\n    name: (variable) @function))\n\n(decl/bind\n  name: (variable) @function\n  (match\n    expression: (expression/lambda)))\n\n; view patterns\n(view_pattern\n  [\n    (expression/variable) @function.call\n    (expression/qualified\n      (variable) @function.call)\n  ])\n\n; consider infix functions as operators\n(infix_id\n  [\n    (variable) @operator\n    (qualified\n      (variable) @operator)\n  ])\n\n; decl/function calls with an infix operator\n; e.g. func <$> a <*> b\n(infix\n  [\n    (variable) @function.call\n    (qualified\n      ((module) @namespace\n        (variable) @function.call))\n  ]\n  .\n  (operator))\n\n; infix operators applied to variables\n((expression/variable) @variable\n  .\n  (operator))\n\n((operator)\n  .\n  [\n    (expression/variable) @variable\n    (expression/qualified\n      (variable) @variable)\n  ])\n\n; decl/function calls with infix operators\n([\n    (expression/variable) @function.call\n    (expression/qualified\n      (variable) @function.call)\n  ]\n  .\n  (operator) @operator\n  (#any-of? @operator \"$\" \"<$>\" \">>=\" \"=<<\"))\n\n; right hand side of infix operator\n((infix\n  [\n    (operator)\n    (infix_id (variable))\n  ] ; infix or `func`\n  .\n  [\n    (variable) @function.call\n    (qualified\n      (variable) @function.call)\n  ])\n  .\n  (operator) @operator\n  (#any-of? @operator \"$\" \"<$>\" \"=<<\"))\n\n; decl/function composition, arrows, monadic composition (lhs)\n(\n  [\n    (expression/variable) @function\n    (expression/qualified\n      (variable) @function)\n  ]\n  .\n  (operator) @operator\n  (#any-of? @operator \".\" \">>>\" \"***\" \">=>\" \"<=<\"))\n\n; right hand side of infix operator\n((infix\n  [\n    (operator)\n    (infix_id (variable))\n  ] ; infix or `func`\n  .\n  [\n    (variable) @function\n    (qualified\n      (variable) @function)\n  ])\n  .\n  (operator) @operator\n  (#any-of? @operator \".\" \">>>\" \"***\" \">=>\" \"<=<\"))\n\n; function composition, arrows, monadic composition (rhs)\n((operator) @operator\n  .\n  [\n    (expression/variable) @function\n    (expression/qualified\n      (variable) @function)\n  ]\n  (#any-of? @operator \".\" \">>>\" \"***\" \">=>\" \"<=<\"))\n\n; function defined in terms of a function composition\n(decl/function\n  name: (variable) @function\n  (match\n    expression: (infix\n      operator: (operator) @operator\n      (#any-of? @operator \".\" \">>>\" \"***\" \">=>\" \"<=<\"))))\n\n(apply\n  [\n    (expression/variable) @function.call\n    (expression/qualified\n      (variable) @function.call)\n  ])\n\n; function compositions, in parentheses, applied\n; lhs\n(apply\n  .\n  (expression/parens\n    (infix\n      [\n        (variable) @function.call\n        (qualified\n          (variable) @function.call)\n      ]\n      .\n      (operator))))\n\n; rhs\n(apply\n  .\n  (expression/parens\n    (infix\n      (operator)\n      .\n      [\n        (variable) @function.call\n        (qualified\n          (variable) @function.call)\n      ])))\n\n; variables being passed to a function call\n(apply\n  (_)\n  .\n  [\n    (expression/variable) @variable\n    (expression/qualified\n      (variable) @variable)\n  ])\n\n; main is always a function\n; (this prevents `main = undefined` from being highlighted as a variable)\n(decl/bind\n  name: (variable) @function\n  (#eq? @function \"main\"))\n\n; scoped function types (func :: a -> b)\n(signature\n  pattern: (pattern/variable) @function\n  type: (quantified_type))\n\n; signatures that have a function type\n; + binds that follow them\n(decl/signature\n  name: (variable) @function\n  type: (quantified_type))\n\n((decl/signature\n  name: (variable) @function.name\n  type: (quantified_type))\n  .\n  (decl/bind\n    (variable) @function)\n  (#eq? @function @function.name))\n\n; ----------------------------------------------------------------------------\n; Types\n(name) @type\n\n(type/star) @type\n\n; (variable) @type\n\n(constructor) @constructor\n\n; True or False\n((constructor) @constant.builtin.boolean\n  (#any-of? @constant.builtin.boolean \"True\" \"False\"))\n\n; otherwise (= True)\n((variable) @constant.builtin.boolean\n  (#eq? @constant.builtin.boolean \"otherwise\"))\n\n; ----------------------------------------------------------------------------\n; Quasi-quotes\n(quoter) @function.call\n\n(quasiquote\n  [\n    (quoter) @_name\n    (_\n      (variable) @_name)\n  ]\n  (#eq? @_name \"qq\")\n  (quasiquote_body) @string)\n\n(quasiquote\n  (_\n    (variable) @_name)\n  (#eq? @_name \"qq\")\n  (quasiquote_body) @string)\n\n; namespaced quasi-quoter\n(quasiquote\n  (_\n    (module) @namespace\n    .\n    (variable) @function.call))\n\n; Highlighting of quasiquote_body for other languages is handled by injections.scm\n; ----------------------------------------------------------------------------\n; Exceptions/error handling\n((variable) @keyword.exception\n  (#any-of? @keyword.exception\n    \"error\" \"undefined\" \"try\" \"tryJust\" \"tryAny\" \"catch\" \"catches\" \"catchJust\" \"handle\" \"handleJust\"\n    \"throw\" \"throwIO\" \"throwTo\" \"throwError\" \"ioError\" \"mask\" \"mask_\" \"uninterruptibleMask\"\n    \"uninterruptibleMask_\" \"bracket\" \"bracket_\" \"bracketOnErrorSource\" \"finally\" \"fail\"\n    \"onException\" \"expectationFailure\"))\n\n; ----------------------------------------------------------------------------\n; Debugging\n((variable) @keyword.debug\n  (#any-of? @keyword.debug\n    \"trace\" \"traceId\" \"traceShow\" \"traceShowId\" \"traceWith\" \"traceShowWith\" \"traceStack\" \"traceIO\"\n    \"traceM\" \"traceShowM\" \"traceEvent\" \"traceEventWith\" \"traceEventIO\" \"flushEventLog\" \"traceMarker\"\n    \"traceMarkerIO\"))\n\n; ----------------------------------------------------------------------------\n; Fields\n\n(field_name\n  (variable) @variable.member)\n\n(import_name\n  (name)\n  .\n  (children\n    (variable) @variable.member))\n"
  },
  {
    "path": "runtime/queries/haskell/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n(quasiquote\n (quoter) @_quoter\n ((quasiquote_body) @injection.content\n  (#match? @_quoter \"(persistWith|persistLowerCase|persistUpperCase)\")\n  (#set! injection.language \"haskell-persistent\")\n )\n)\n\n(quasiquote\n (quoter) @injection.language\n (quasiquote_body) @injection.content)\n"
  },
  {
    "path": "runtime/queries/haskell/locals.scm",
    "content": "(signature name: (variable) @local.definition.function)\n(function name: (variable) @local.definition.function)\n(pattern/variable) @local.definition.variable.parameter\n(expression/variable) @local.reference\n"
  },
  {
    "path": "runtime/queries/haskell/textobjects.scm",
    "content": "(comment) @comment.inside\n(comment)+ @comment.around\n\n(newtype\n\t(newtype_constructor\n\t\t(_) @class.inside)) @class.around\n(data_type\n\tconstructors: (_) @class.inside) @class.around\n(decl/function\n\t(match expression:(_) @function.inside)) @function.around\n(lambda\n\texpression:(_) @function.inside) @function.around\n\n(decl/function\n\tpatterns: (patterns\n\t\t(_) @parameter.inside))\n\n(expression/lambda\n\tpatterns: (patterns\n\t(_) @parameter.inside))\n\n(decl/function\n\t(infix\n\t\t(pattern) @parameter.inside))\n"
  },
  {
    "path": "runtime/queries/haskell-literate/highlights.scm",
    "content": "; Bird track marker\n(bird_line \">\" @punctuation.special)\n\n; LaTeX delimiters\n(latex_begin) @keyword.directive\n(latex_end) @keyword.directive\n\n; Highlight LaTeX comments like comments\n(latex_comment) @comment\n\n; Markdown delimiters\n(markdown_begin) @keyword.directive\n(markdown_end) @keyword.directive\n\n; Normal prose is not highlighted. Haskell code will be\n; highlighted by the injected Haskell grammar\n"
  },
  {
    "path": "runtime/queries/haskell-literate/injections.scm",
    "content": "; Inject Haskell parser into bird-style code lines\n((bird_line\n  (haskell_code) @injection.content)\n (#set! injection.language \"haskell\"))\n\n; Inject Haskell parser into LaTeX code blocks\n((latex_code_line\n  (haskell_code) @injection.content)\n (#set! injection.language \"haskell\"))\n\n; Inject Haskell parser into Markdown code blocks\n((markdown_code_line\n  (haskell_code) @injection.content)\n (#set! injection.language \"haskell\"))\n"
  },
  {
    "path": "runtime/queries/haskell-persistent/folds.scm",
    "content": "[\n (entity_definition)\n] @fold\n"
  },
  {
    "path": "runtime/queries/haskell-persistent/highlights.scm",
    "content": ";; ----------------------------------------------------------------------------\n;; Literals and comments\n\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(char) @constant.character\n(string) @string\n(attribute_name) @attribute\n(attribute_exclamation_mark) @attribute\n\n(con_unit) @constant.builtin ; unit, as in ()\n\n(comment) @comment\n\n;; ----------------------------------------------------------------------------\n;; Keywords, operators, includes\n\n[\n  \"Id\"\n  \"Primary\"\n  \"Foreign\"\n  \"deriving\"\n] @keyword\n\n\"=\" @operator\n\n;; ----------------------------------------------------------------------------\n;; Functions and variables\n\n(variable) @variable\n\n;; ----------------------------------------------------------------------------\n;; Types\n\n(type) @type\n\n(constructor) @constructor\n"
  },
  {
    "path": "runtime/queries/haxe/folds.scm",
    "content": "[\n  (block)\n  (array)\n] @fold\n"
  },
  {
    "path": "runtime/queries/haxe/highlights.scm",
    "content": "(identifier) @variable\n(comment) @comment\n\n; Preprocessor Statement\n; --------\n(preprocessor_statement) @tag\n; (metadata name: (identifier) @type) @tag\n\n; MetaData\n; --------\n(metadata) @tag\n(metadata name: (identifier) @type) @tag\n\n; Generic/Type Params\n; --------------\n(type_params\n  \"<\" @punctuation.bracket\n  \">\" @punctuation.bracket\n)\n\n; Declarations\n; ------------\n\n(class_declaration name: (identifier) @type.definition)\n(interface_declaration name: (identifier) @type.definition)\n(typedef_declaration name: (identifier) @type.definition)\n\n(function_declaration name: (identifier) @function)\n(function_arg name: (identifier) @variable.parameter)\n\n; Expressions\n; -----------\n; (call_expression name: (identifier) @variable.parameter)\n\n; TODO: Figure out how to determined when \"nested member call\" is last ident.\n; apparently this is a known issue https://github.com/tree-sitter/tree-sitter/issues/880\n(call_expression object: [\n  (_) @function\n  (_ (identifier) @function .)\n;   (_(_ (identifier) @function .))\n;   (_(_(_ (identifier) @function .)))\n;   (_(_(_(_ (identifier) @function .))))\n;   (_(_(_(_(_ (identifier) @function .)))))\n])\n\n; Literals\n; --------\n; [(keyword) (null)] @keyword\n; (type) @type\n(type_name) @type\n(package_name) @namespace\n(type (identifier) !built_in) @type\n(type built_in: (identifier)) @type.builtin\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(string) @string\n(bool) @constant.builtin.boolean\n(operator) @operator\n(escape_sequence) @punctuation\n(null) @constant.builtin\n(access_identifiers \"null\" @keyword)\n\n; Keywords\n; --------\n[\n  \"abstract\"\n  \"as\"\n  \"break\"\n  \"case\"\n  \"cast\"\n  \"catch\"\n  \"class\"\n  \"continue\"\n  \"default\"\n  \"do\"\n  \"dynamic\"\n  \"else\"\n  \"enum\"\n  \"extends\"\n  \"extern\"\n  \"final\"\n  \"for\"\n  \"function\"\n  \"if\"\n  \"implements\"\n  \"import\"\n  \"in\"\n  \"inline\"\n  \"interface\"\n  \"macro\"\n  \"operator\"\n  \"overload\"\n  \"override\"\n  \"package\"\n  \"private\"\n  \"public\"\n  \"return\"\n  \"static\"\n  \"switch\"\n  \"this\"\n  \"throw\"\n  \"try\"\n  \"typedef\"\n  \"untyped\"\n  \"using\"\n  \"var\"\n  \"while\"\n] @keyword\n\n(function_declaration name: \"new\" @constructor)\n(call_expression\n  \"new\" @keyword\n  constructor: (type_name) @constructor\n)\n\n; Tokens\n; ------\n\n(\":\") @punctuation.special\n(pair [\":\" \"=>\"] @punctuation.special)\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n]  @punctuation.bracket\n;\n[\n;   \";\"\n;   \"?.\"\n;   \".\"\n  \",\"\n] @punctuation.delimiter\n\n\n; Interpolation\n; -------------\n(interpolation \"$\" @punctuation.special)\n(interpolation\n  \"${\" @punctuation.special\n  \"}\" @punctuation.special\n) @embedded\n\n"
  },
  {
    "path": "runtime/queries/haxe/injections.scm",
    "content": "((interpolation) @injection.content\n (#set! injection.language \"haxe\"))\n((comment) @injection.content\n (#set! injection.language \"jsdoc\"))\n; ((comment) @injection.content\n;  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/haxe/locals.scm",
    "content": "; Scopes\n[\n (block)\n (function_declaration)\n] @local.scope\n\n; Definitions\n(function_arg name: (identifier) @local.definition.variable.parameter)\n(variable_declaration name: (identifier) @local.definition.variable)\n\n; References\n(block (identifier)) @local.reference\n"
  },
  {
    "path": "runtime/queries/haxe/tags.scm",
    "content": ""
  },
  {
    "path": "runtime/queries/hcl/folds.scm",
    "content": "[\n (comment)\n (block)\n (heredoc_template)\n (object)\n] @fold\n"
  },
  {
    "path": "runtime/queries/hcl/highlights.scm",
    "content": "[ \n  \"if\"\n  \"else\"\n  \"endif\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n  \"endfor\"\n  \"in\"\n] @keyword.control.repeat\n\n[\n  \":\"\n  \"=\"\n] @none\n\n[\n  (ellipsis)\n  \"\\?\"\n  \"=>\"\n] @punctuation.special\n\n[\n  \".\"\n  \".*\"\n  \",\"\n  \"[*]\"\n] @punctuation.delimiter\n\n[\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n[\n  \"!\"\n  \"\\*\"\n  \"/\"\n  \"%\"\n  \"\\+\"\n  \"-\"\n  \">\"\n  \">=\"\n  \"<\"\n  \"<=\"\n  \"==\"\n  \"!=\"\n  \"&&\"\n  \"||\"\n] @operator\n\n(identifier) @variable\n\n; { key: val }\n\n(object_elem val: (expression\n  (variable_expr\n      (identifier) @type.builtin (#match? @type.builtin \"^(bool|string|number|object|tuple|list|map|set|any)$\"))))\n\n(get_attr (identifier) @variable.builtin (#match? @variable.builtin  \"^(root|cwd|module)$\"))\n(variable_expr (identifier) @variable.builtin (#match? @variable.builtin \"^(var|local|path)$\"))\n((identifier) @type.builtin (#match? @type.builtin \"^(bool|string|number|object|tuple|list|map|set|any)$\"))\n((identifier) @keyword (#match? @keyword \"^(module|root|cwd|resource|variable|data|locals|terraform|provider|output)$\"))\n\n; highlight identifier keys as though they were block attributes\n(object_elem key: (expression (variable_expr (identifier) @variable.other.member)))\n\n(attribute (identifier) @variable.other.member)\n(function_call (identifier) @function.method)\n(block (identifier) @type.builtin)\n\n(comment) @comment\n(null_lit) @constant.builtin\n(numeric_lit) @constant.numeric\n(bool_lit) @constant.builtin.boolean\n\n[\n  (template_interpolation_start) ; ${\n  (template_interpolation_end) ; }\n  (template_directive_start) ; %{\n  (template_directive_end) ; }\n  (strip_marker) ; ~\n] @punctuation.special\n\n[\n  (heredoc_identifier) ; <<END\n  (heredoc_start) ; END\n] @punctuation.delimiter\n\n[\n  (quoted_template_start) ; \"\n  (quoted_template_end); \"\n  (template_literal) ; non-interpolation/directive content\n] @string\n"
  },
  {
    "path": "runtime/queries/hcl/indents.scm",
    "content": "[\n  (object)\n  (block)\n  (tuple)\n  (for_tuple_expr)\n  (for_object_expr)\n] @indent\n\n[\n  (object_end)\n  (block_end)\n  (tuple_end)\n] @outdent\n"
  },
  {
    "path": "runtime/queries/hcl/injections.scm",
    "content": "((comment) @injection.content\n\t(#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/hcl/textobjects.scm",
    "content": "(comment) @comment.inside\n(comment)+ @comment.around\n\n(function_arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(attribute\n  (_) @entry.inside) @entry.around\n\n(tuple\n  (_) @entry.around)\n"
  },
  {
    "path": "runtime/queries/hdl/highlights.scm",
    "content": ";; Keywords\n[\n  \"CHIP\"\n  \"IN\"\n  \"OUT\"\n  \"PARTS\"\n  \"BUILTIN\"\n  \"CLOCKED\"\n] @keyword\n\n(identifier) @variable\n\n(chip_definition\n  name: (identifier) @function)\n\n(in_section\n  input_pin_name: (identifier) @variable.parameter)\n\n(out_section\n  output_pin_name: (identifier) @variable.parameter)\n\n(builtin_body\n  chip_name: (identifier) @function)\n\n(clocked_body\n  (identifier) @variable.parameter)\n\n(part\n  chip_name: (identifier) @function)\n\n(connection\n  part_pin: (identifier) @variable.other.member\n  chip_pin: [\n    (identifier) @variable.parameter\n    (bus_identifier\n      (identifier) @variable.parameter\n      (number) @constant.numeric)\n  ])\n\n(bus_identifier\n  (number) @constant.numeric)\n\n;; Comments\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/heex/highlights.scm",
    "content": "; https://github.com/connorlay/tree-sitter-heex/blob/592e22292a367312c35e13de7fdb888f029981d6/queries/highlights.scm\n; HEEx delimiters\n[\n  \"<!\"\n  \"<\"\n  \"<%#\"\n  \">\"\n  \"</\"\n  \"/>\"\n  ; These could be `@keyword`s but the closing `>` wouldn't be highlighted\n  ; as `@keyword`\n  \"<:\"\n  \"</:\"\n] @punctuation.bracket\n\n; Non-comment or tag delimiters\n[\n  \"{\"\n  \"}\"\n  \"<%\"\n  \"<%=\"\n  \"<%%=\"\n  \"%>\"\n] @keyword\n\n; HEEx operators are highlighted as such\n\"=\" @operator\n\n; HEEx inherits the DOCTYPE tag from HTML\n(doctype) @constant\n\n; HEEx comments are highlighted as such\n[\n  \"<!--\"\n  \"-->\"\n  \"<%!--\"\n  \"--%>\"\n  (comment)\n] @comment\n\n; HEEx tags are highlighted as HTML\n(tag_name) @tag\n\n; HEEx slots are highlighted as atoms (symbols)\n(slot_name) @string.special.symbol\n\n; HEEx attributes are highlighted as HTML attributes\n(attribute_name) @attribute\n[\n  (attribute_value)\n  (quoted_attribute_value)\n] @string\n\n; HEEx special attributes are keywords\n(special_attribute_name) @keyword\n\n; HEEx components are highlighted as Elixir modules and functions\n(component_name\n  [\n    (module) @namespace\n    (function) @function\n    \".\" @punctuation.delimiter\n  ])\n"
  },
  {
    "path": "runtime/queries/heex/injections.scm",
    "content": "; https://github.com/connorlay/tree-sitter-heex/blob/592e22292a367312c35e13de7fdb888f029981d6/queries/injections.scm\n; directives are standalone tags like '<%= @x %>'\n;\n; partial_expression_values are elixir code that is part of an expression that\n; spans multiple directive nodes, so they must be combined. For example:\n;     <%= if true do %>\n;       <p>hello, tree-sitter!</p>\n;     <% end %>\n((directive\n    [\n      (partial_expression_value)\n      (ending_expression_value)\n    ] @injection.content)\n (#set! injection.language \"elixir\")\n (#set! injection.include-children)\n (#set! injection.combined))\n\n; Regular expression_values do not need to be combined\n((directive (expression_value) @injection.content)\n (#set! injection.language \"elixir\"))\n\n; expressions live within HTML tags, and do not need to be combined\n;     <link href={ Routes.static_path(..) } />\n((expression (expression_value) @injection.content)\n (#set! injection.language \"elixir\"))\n\n((comment) @injection.content \n (#set! injection.language \"comment\"))"
  },
  {
    "path": "runtime/queries/heex/textobjects.scm",
    "content": "(comment) @comment.around @comment.inside\n"
  },
  {
    "path": "runtime/queries/helm/highlights.scm",
    "content": "; inherits: gotmpl\n"
  },
  {
    "path": "runtime/queries/helm/injections.scm",
    "content": "; inherits: gotmpl\n\n((text) @injection.content\n (#set! injection.language \"yaml\")\n (#set! injection.combined))"
  },
  {
    "path": "runtime/queries/hocon/highlights.scm",
    "content": "(comment) @comment\n\n(null) @constant.builtin\n[(true) (false)] @constant.builtin.boolean\n(number) @constant.numeric\n(string) @string\n(multiline_string) @string\n(string (escape_sequence) @constant.character.escape)\n(unquoted_string) @string\n\n(value [\":\" \"=\" \"+=\" ] @operator)\n\n[ \"(\" \")\" \"[\" \"]\" \"{\" \"}\" ]  @punctuation.bracket\n\n(substitution (_) @string)\n(substitution [\"${\" \"${?\" \"}\"] @punctuation.special)\n\n[ \n  \"url\"\n  \"file\"\n  \"classpath\"\n  \"required\"\n] @function.builtin\n\n(include) @keyword.directive\n\n(unit) @keyword\n(path (_) @keyword)\n(unquoted_path \".\" @punctuation.delimiter)\n[ \",\" ] @punctuation.delimiter\n\n"
  },
  {
    "path": "runtime/queries/hocon/indents.scm",
    "content": "[\n  (object)\n  (array)\n] @indent\n\n[\n  \"]\"\n  \"}\"\n] @outdent\n\n"
  },
  {
    "path": "runtime/queries/hocon/textobjects.scm",
    "content": "(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(pair \n  (_) @entry.inside) @entry.around\n\n(array\n  (_) @entry.around)\n\n"
  },
  {
    "path": "runtime/queries/hoon/highlights.scm",
    "content": "(number) @constant.numeric\n\n(string) @string\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n]  @punctuation.bracket\n\n[\n  (coreTerminator)\n  (seriesTerminator)\n] @punctuation.delimiter\n\n\n(rune) @keyword\n\n(term) @constant\n\n(aura) @constant.builtin\n\n(Gap) @comment\n\n(boolean) @constant.builtin\n\n(date) @constant.builtin\n(mold) @constant.builtin\n(specialIndex) @constant.builtin\n(lark) @operator\n(fullContext) @constant.builtin\n"
  },
  {
    "path": "runtime/queries/hosts/highlights.scm",
    "content": "(comment) @comment\n(ip) @namespace\n(host) @string\n"
  },
  {
    "path": "runtime/queries/html/highlights.scm",
    "content": "(tag_name) @tag\n(erroneous_end_tag_name) @error\n(doctype) @constant\n(attribute_name) @attribute\n(entity) @string.special.symbol\n(comment) @comment\n\n((attribute\n  (attribute_name) @attribute\n  (quoted_attribute_value (attribute_value) @markup.link.url))\n (#any-of? @attribute \"href\" \"src\"))\n\n((element\n  (start_tag\n    (tag_name) @tag)\n  (text) @markup.link.label)\n  (#eq? @tag \"a\"))\n\n(attribute [(attribute_value) (quoted_attribute_value)] @string)\n\n((element\n  (start_tag\n    (tag_name) @tag)\n  (text) @markup.bold)\n  (#any-of? @tag \"strong\" \"b\"))\n\n((element\n  (start_tag\n    (tag_name) @tag)\n  (text) @markup.italic)\n  (#any-of? @tag \"em\" \"i\"))\n\n((element\n  (start_tag\n    (tag_name) @tag)\n  (text) @markup.strikethrough)\n  (#any-of? @tag \"s\" \"del\"))\n\n[\n  \"<\"\n  \">\"\n  \"</\"\n  \"/>\"\n  \"<!\"\n] @punctuation.bracket\n\n\"=\" @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/html/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((script_element\n  (raw_text) @injection.content)\n (#set! injection.language \"javascript\"))\n\n((style_element\n  (raw_text) @injection.content)\n (#set! injection.language \"css\"))\n"
  },
  {
    "path": "runtime/queries/html/rainbows.scm",
    "content": "[\n  (doctype)\n  (erroneous_end_tag)\n] @rainbow.scope\n\n([\n   (element)\n   (script_element)\n   (style_element)\n ] @rainbow.scope\n (#set! rainbow.include-children))\n\n[\"<\" \">\" \"<!\" \"</\" \"/>\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/html/textobjects.scm",
    "content": "(script_element (start_tag) (_) @xml-element.inside (end_tag))  @xml-element.around\n\n(style_element (start_tag) (_) @xml-element.inside (end_tag)) @xml-element.around\n\n(element (start_tag) (_)* @xml-element.inside (end_tag))\n\n(element) @xml-element.around\n\n(comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/htmldjango/highlights.scm",
    "content": "[\n  (unpaired_comment)\n  (paired_comment)\n] @comment\n\n[\n  \"{{\"\n  \"}}\"\n  \"{%\"\n  \"%}\"\n  (end_paired_statement)\n] @punctuation.bracket\n\n[\n (tag_name) \n] @function\n\n(variable_name) @variable\n(filter_name) @function\n(filter_argument) @variable.parameter\n(keyword) @keyword\n(operator) @operator\n(keyword_operator) @keyword.operator\n(number) @constant.numeric\n(boolean) @constant.builtin.boolean\n(string) @string\n"
  },
  {
    "path": "runtime/queries/htmldjango/injections.scm",
    "content": "((content) @injection.content\n (#set! injection.language \"html\")\n (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/hurl/highlights.scm",
    "content": "[\n  \"[QueryStringParams]\"\n  \"[Query]\"\n  \"[FormParams]\"\n  \"[Form]\"\n  \"[MultipartFormData]\"\n  \"[Multipart]\"\n  \"[Cookies]\"\n  \"[Captures]\"\n  \"[Asserts]\"\n  \"[Options]\"\n  \"[BasicAuth]\"\n] @attribute\n\n(comment) @comment\n\n[\n  (key_string)\n  (json_key_string)\n] @variable.other.member\n \n(value_string) @string\n(quoted_string) @string\n(json_string) @string\n(file_value) @string.special.path\n(regex) @string.regex\n\n[\n  \"\\\\\"\n  (regex_escaped_char)\n  (quoted_string_escaped_char)\n  (key_string_escaped_char)\n  (value_string_escaped_char)\n  (oneline_string_escaped_char)\n  (multiline_string_escaped_char)\n  (filename_escaped_char)\n  (json_string_escaped_char)\n] @constant.character.escape\n\n(method) @type.builtin\n(multiline_string_type) @type\n\n[\n  \"status\"\n  \"url\"\n  \"header\"\n  \"cookie\"\n  \"body\"\n  \"xpath\"\n  \"jsonpath\"\n  \"regex\"\n  \"variable\"\n  \"duration\"\n  \"sha256\"\n  \"md5\"\n  \"bytes\"\n  \"daysAfterNow\"\n  \"daysBeforeNow\"\n  \"htmlEscape\"\n  \"htmlUnescape\"\n  \"decode\"\n  \"format\"\n  \"nth\"\n  \"replace\"\n  \"split\"\n  \"toDate\"\n  \"toInt\"\n  \"urlEncode\"\n  \"urlDecode\"\n  \"count\"\n] @function.builtin\n\n(filter) @attribute\n\n(version) @string.special\n[\n  \"null\"\n  \"cacert\"\n  \"compressed\"\n  \"location\"\n  \"insecure\"\n  \"path-as-is\"\n  \"proxy\"\n  \"max-redirs\"\n  \"retry\"\n  \"retry-interval\"\n  \"retry-max-count\"\n  (variable_option \"variable\")\n  \"verbose\"\n  \"very-verbose\"\n] @constant.builtin\n\n(boolean) @constant.builtin.boolean\n\n(variable_name) @variable\n\n[\n  \"not\"\n  \"equals\"\n  \"==\"\n  \"notEquals\"\n  \"!=\"\n  \"greaterThan\"\n  \">\"\n  \"greaterThanOrEquals\"\n  \">=\"\n  \"lessThan\"\n  \"<\"\n  \"lessThanOrEquals\"\n  \"<=\"\n  \"startsWith\"\n  \"endsWith\"\n  \"contains\"\n  \"matches\"\n  \"exists\"\n  \"includes\"\n  \"isInteger\"\n  \"isFloat\"\n  \"isBoolean\"\n  \"isString\"\n  \"isCollection\"\n  \"isNumber\"\n  \"isIsoDate\"\n  \"isEmpty\"\n] @keyword.operator\n\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(status) @constant.numeric\n(json_number) @constant.numeric.float\n\n[\n  \":\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"{{\"\n  \"}}\"\n] @punctuation.special\n\n[\n  \"base64,\"\n  \"file,\"\n  \"hex,\"\n] @string.special\n"
  },
  {
    "path": "runtime/queries/hurl/indents.scm",
    "content": "[\n  (json_object)\n  (json_array)\n  (xml_tag)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  (xml_close_tag)\n] @outdent\n"
  },
  {
    "path": "runtime/queries/hurl/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((json_value) @injection.content\n  (#set! injection.language \"json\"))\n\n((xml) @injection.content\n  (#set! injection.language \"xml\"))\n\n((multiline_string\n  (multiline_string_type) @injection.language\n  (multiline_string_content) @injection.content)\n  (#set! injection.include-children)\n  (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/hurl/textobjects.scm",
    "content": "(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(entry (_) @function.inside) @function.around\n"
  },
  {
    "path": "runtime/queries/hy/highlights.scm",
    "content": "; inherits: scheme\n"
  },
  {
    "path": "runtime/queries/hyprlang/highlights.scm",
    "content": "(comment) @comment\n\n[\n  \"source\"\n  \"exec\"\n  \"exec-once\"\n] @function.builtin\n\n(keyword\n  (name) @keyword)\n\n(assignment\n  (name) @variable.other.member)\n\n(section\n  (name) @namespace)\n\n(section\n  device: (device_name) @type)\n\n(variable) @variable\n\n\"$\" @punctuation.special\n\n(boolean) @constant.builtin.boolean\n\n(string) @string\n\n(mod) @constant\n\n[\n  \"rgb\"\n  \"rgba\"\n] @function.builtin\n\n[\n  (number)\n  (legacy_hex)\n  (angle)\n  (hex)\n] @constant.numeric\n\n\"deg\" @type\n\n\",\" @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \"=\"\n  \"-\"\n  \"+\"\n] @operator\n"
  },
  {
    "path": "runtime/queries/hyprlang/indents.scm",
    "content": "(section) @indent\n\n(section\n  \"}\" @outdent)\n\n\"}\" @extend\n"
  },
  {
    "path": "runtime/queries/hyprlang/injections.scm",
    "content": "(exec\n  (string) @injection.content\n  (#set! injection.language \"bash\"))\n"
  },
  {
    "path": "runtime/queries/hyprlang/tags.scm",
    "content": "(section\n  (name) @name) @definition.section\n"
  },
  {
    "path": "runtime/queries/iex/highlights.scm",
    "content": "(prompt) @comment\n"
  },
  {
    "path": "runtime/queries/iex/injections.scm",
    "content": "((evaluation_block (prompt_line (expression) @injection.content))\n (#set! injection.language \"elixir\")\n (#set! injection.combined))\n\n((result) @injection.content\n (#set! injection.language \"elixir\"))\n"
  },
  {
    "path": "runtime/queries/ini/highlights.scm",
    "content": "(section_name\n  (text) @type)\n\n(comment) @comment\n\n[\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n\"=\" @operator\n\n(setting\n  (setting_name) @variable.other.member\n  ((setting_value) @string)?)\n"
  },
  {
    "path": "runtime/queries/ini/injections.scm",
    "content": "((comment (text) @injection.content)\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/ini/tags.scm",
    "content": "(section_name\n  (text) @name) @definition.section\n"
  },
  {
    "path": "runtime/queries/ink/highlights.scm",
    "content": "; tags and labels\n(label) @label\n(tag (identifier) @commment)\n(tag) @comment\n\n; values\n(identifier) @function\n(string) @string\n(boolean) @constant\n(number) @constant.numeric\n\n; headers\n(knot_header) @keyword\n(stitch_header) @keyword\n(function_header) @keyword\n\n; marks (ink)\n(option_mark) @keyword.directive\n(gather_mark) @type.builtin\n(glue) @type.builtin\n\n; calls\n(divert_or_thread) @function\n\n; operators\n(assignment) @operator\n\n; special marks/operators (ink)\n(arrow) @special\n(double_arrow) @special\n(back_arrow) @constant\n(dot) @special\n(mark_start) @special\n(mark_end) @special\n(hide_start) @special\n(hide_end) @special\n\n; declarations\n(var_line) @attribute\n(const_line) @constant\n(list_line) @type\n\n; comments\n(line_comment) @comment\n(block_comment) @comment\n\n; unparsed code\n(inline_block) @keyword\n(condition_block) @keyword\n(code_text) @keyword\n\n; support injection\n(program) @ui.text\n"
  },
  {
    "path": "runtime/queries/inko/highlights.scm",
    "content": "; Brackets and operators\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \".\"\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"!=\"\n  \"%\"\n  \"%=\"\n  \"&\"\n  \"&=\"\n  \"*\"\n  \"**\"\n  \"**=\"\n  \"*=\"\n  \"+\"\n  \"+=\"\n  \"-\"\n  \"-=\"\n  \"/\"\n  \"/=\"\n  \"<\"\n  \"<<\"\n  \"<<=\"\n  \"<=\"\n  \"<=\"\n  \"==\"\n  \">\"\n  \">=\"\n  \">=\"\n  \">>\"\n  \">>=\"\n  \">>>\"\n  \">>>=\"\n  \"^\"\n  \"^=\"\n  \"|\"\n  \"|=\"\n] @operator\n\n; Identifiers/variable references\n(identifier) @variable\n\n((identifier) @function\n  (#is-not? local))\n\n; Keywords\n[\n  \"as\"\n  \"for\"\n  \"impl\"\n  \"let\"\n  \"mut\"\n  \"ref\"\n  \"uni\"\n  \"move\"\n  \"recover\"\n] @keyword\n\n\"fn\" @keyword.function\n\n\"import\" @keyword.control.import\n\n[\n  \"and\"\n  \"or\"\n] @keyword.operator\n\n[\n  \"type\"\n  \"trait\"\n] @keyword.storage.type\n\n[\n  \"extern\"\n  (modifier)\n  (visibility)\n] @keyword.storage.modifier\n\n[\n  \"loop\"\n  \"while\"\n  (break)\n  (next)\n] @keyword.control.repeat\n\n\"return\" @keyword.control.return\n\n[\n  \"throw\"\n  \"try\"\n] @keyword.control.exception\n\n[\n  \"case\"\n  \"else\"\n  \"if\"\n  \"match\"\n] @keyword.control.conditional\n\n; Comments\n(line_comment) @comment.line\n\n; Literals\n(self) @variable.builtin\n\n(nil) @constant.builtin\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(integer) @constant.numeric.integer\n\n(float) @constant.numeric.float\n\n(string) @string\n\n(escape_sequence) @constant.character.escape\n\n(interpolation\n  \"${\" @punctuation.special\n  \"}\" @punctuation.special)\n\n(constant) @constant\n\n; Patterns\n(integer_pattern) @constant.numeric.integer\n\n(string_pattern) @string\n\n(constant_pattern) @constant\n\n; Types\n(generic_type\n  name: _ @type)\n\n(type) @type\n\n; Imports\n(extern_import\n  path: _ @string)\n\n; Classes\n(class\n  name: _ @type)\n\n(define_field\n  name: _ @variable.other.member)\n\n; Traits\n(trait\n  name: _ @type)\n\n; Implementations\n(implement_trait\n  class: _ @type)\n\n(reopen_class\n  name: _ @type)\n\n(bound\n  name: _ @type)\n\n; Methods\n(method\n  name: _ @function)\n\n(external_function\n  name: _ @function)\n\n(argument\n  name: _ @variable.parameter)\n\n(named_argument\n  name: _ @variable.parameter)\n\n(call\n  name: _ @function)\n\n(field) @variable.other.member\n"
  },
  {
    "path": "runtime/queries/inko/indents.scm",
    "content": "[\n  (arguments)\n  (array)\n  (assign_field)\n  (assign_local)\n  (assign_receiver_field)\n  (binary)\n  (block)\n  (bounds)\n  (cast)\n  (class)\n  (class_pattern)\n  (compound_assign_field)\n  (compound_assign_local)\n  (compound_assign_receiver_field)\n  (define_constant)\n  (define_variable)\n  (grouped_expression)\n  (implement_trait)\n  (match)\n  (or_pattern)\n  (reopen_class)\n  (replace_field)\n  (replace_local)\n  (symbols)\n  (trait)\n  (tuple)\n  (tuple_pattern)\n  (type_arguments)\n] @indent\n\n[\n  \")\"\n  \"]\"\n  \"}\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/inko/injections.scm",
    "content": "((line_comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/inko/locals.scm",
    "content": "[\n  (method)\n  (block)\n] @local.scope\n\n(argument name: _ @local.definition.variable.parameter)\n(named_argument name: _ @local.definition.variable.parameter)\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/inko/tags.scm",
    "content": "(class\n  name: _ @definition.struct)\n\n(trait\n  name: _ @definition.interface)\n\n(external_function\n  name: _ @definition.function)\n\n(method\n  name: _ @definition.function)\n\n(define_constant\n  name: _ @definition.constant)\n"
  },
  {
    "path": "runtime/queries/inko/textobjects.scm",
    "content": "(class\n  body: (_) @class.inside) @class.around\n\n(trait\n  body: (_) @class.inside) @class.around\n\n(method\n  body: (_) @function.inside) @function.around\n\n(reopen_class\n  body: (_) @class.inside) @class.around\n\n(implement_trait\n  body: (_) @class.inside) @class.around\n\n(external_function\n  body: (_) @function.inside) @function.around\n\n(closure\n  body: (_) @function.inside) @function.around\n\n(arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(line_comment) @comment.inside\n\n(line_comment)+ @comment.around\n\n(array (_) @entry.around)\n\n(tuple (_) @entry.around)\n\n(tuple_pattern (_) @entry.around)\n\n(define_field (_) @entry.inside) @entry.around\n"
  },
  {
    "path": "runtime/queries/janet/highlights.scm",
    "content": "(kwd_lit) @string.special.symbol\n\n(str_lit) @string\n\n(long_str_lit) @string\n\n(buf_lit) @string\n\n(long_buf_lit) @string\n\n(num_lit) @constant.numeric\n\n(bool_lit) @constant.builtin.boolean\n(nil_lit) @constant.builtin \n\n(comment) @comment\n\n(sym_lit) @variable\n\n((sym_lit) @variable.builtin\n (#match? @variable.builtin \"^\\\\*.+\\\\*$\"))\n\n(short_fn_lit\n .\n (sym_lit) @function)\n\n;; other calls\n(par_tup_lit\n .\n (sym_lit) @function)\n\n;; special forms\n(par_tup_lit\n .\n (sym_lit) @function.macro\n (#match? @function.macro\n  \"^(break|def|do|fn|if|quasiquote|quote|set|splice|unquote|upscope|var|while)$\"))\n\n;; for macros\n;;\n;; (each name (all-bindings)\n;;   (when-let [info (dyn (symbol name))]\n;;     (when (info :macro)\n;;       (print name))))\n(par_tup_lit\n .\n (sym_lit) @function.macro\n (#match? @function.macro\n  \"^(%=|\\\\*=|\\\\+\\\\+|\\\\+=|\\\\-\\\\-|\\\\-=|\\\\->|\\\\->>|\\\\-\\\\?>|\\\\-\\\\?>>|/=|and|as\\\\->|as\\\\-macro|as\\\\?\\\\->|assert|case|catseq|chr|comment|compif|comptime|compwhen|cond|coro|def\\\\-|default|defdyn|defer|defmacro|defmacro\\\\-|defn|defn\\\\-|delay|doc|each|eachk|eachp|edefer|ev/do\\\\-thread|ev/gather|ev/spawn|ev/spawn\\\\-thread|ev/with\\\\-deadline|ffi/defbind|fiber\\\\-fn|for|forever|forv|generate|if\\\\-let|if\\\\-not|if\\\\-with|import|juxt|label|let|loop|match|or|prompt|protect|repeat|seq|short\\\\-fn|tabseq|toggle|tracev|try|unless|use|var\\\\-|varfn|when|when\\\\-let|when\\\\-with|with|with\\\\-dyns|with\\\\-syms|with\\\\-vars)$\"))\n\n;; builtin functions\n;;\n;; (each name (all-bindings)\n;;   (when-let [info (dyn (symbol name))]\n;;     (when (and (nil? (info :macro))\n;;                (or (function? (info :value))\n;;                    (cfunction? (info :value))))\n;;       (print name))))\n((sym_lit) @function.builtin\n (#match? @function.builtin\n  \"^(%|\\\\*|\\\\+|\\\\-|/|<|<=|=|>|>=|\\\\.break|\\\\.breakall|\\\\.bytecode|\\\\.clear|\\\\.clearall|\\\\.disasm|\\\\.fiber|\\\\.fn|\\\\.frame|\\\\.locals|\\\\.next|\\\\.nextc|\\\\.ppasm|\\\\.signal|\\\\.slot|\\\\.slots|\\\\.source|\\\\.stack|\\\\.step|abstract\\\\?|accumulate|accumulate2|all|all\\\\-bindings|all\\\\-dynamics|any\\\\?|apply|array|array/clear|array/concat|array/ensure|array/fill|array/insert|array/new|array/new\\\\-filled|array/peek|array/pop|array/push|array/remove|array/slice|array/trim|array/weak|array\\\\?|asm|bad\\\\-compile|bad\\\\-parse|band|blshift|bnot|boolean\\\\?|bor|brshift|brushift|buffer|buffer/bit|buffer/bit\\\\-clear|buffer/bit\\\\-set|buffer/bit\\\\-toggle|buffer/blit|buffer/clear|buffer/fill|buffer/format|buffer/from\\\\-bytes|buffer/new|buffer/new\\\\-filled|buffer/popn|buffer/push|buffer/push\\\\-at|buffer/push\\\\-byte|buffer/push\\\\-string|buffer/push\\\\-word|buffer/slice|buffer/trim|buffer\\\\?|bxor|bytes\\\\?|cancel|cfunction\\\\?|cli\\\\-main|cmp|comp|compare|compare<|compare<=|compare=|compare>|compare>=|compile|complement|count|curenv|debug|debug/arg\\\\-stack|debug/break|debug/fbreak|debug/lineage|debug/stack|debug/stacktrace|debug/step|debug/unbreak|debug/unfbreak|debugger|debugger\\\\-on\\\\-status|dec|deep\\\\-not=|deep=|defglobal|describe|dictionary\\\\?|disasm|distinct|div|doc\\\\*|doc\\\\-format|doc\\\\-of|dofile|drop|drop\\\\-until|drop\\\\-while|dyn|eflush|empty\\\\?|env\\\\-lookup|eprin|eprinf|eprint|eprintf|error|errorf|ev/acquire\\\\-lock|ev/acquire\\\\-rlock|ev/acquire\\\\-wlock|ev/all\\\\-tasks|ev/call|ev/cancel|ev/capacity|ev/chan|ev/chan\\\\-close|ev/chunk|ev/close|ev/count|ev/deadline|ev/full|ev/give|ev/give\\\\-supervisor|ev/go|ev/lock|ev/read|ev/release\\\\-lock|ev/release\\\\-rlock|ev/release\\\\-wlock|ev/rselect|ev/rwlock|ev/select|ev/sleep|ev/take|ev/thread|ev/thread\\\\-chan|ev/write|eval|eval\\\\-string|even\\\\?|every\\\\?|extreme|false\\\\?|ffi/align|ffi/call|ffi/calling\\\\-conventions|ffi/close|ffi/context|ffi/free|ffi/jitfn|ffi/lookup|ffi/malloc|ffi/native|ffi/pointer\\\\-buffer|ffi/pointer\\\\-cfunction|ffi/read|ffi/signature|ffi/size|ffi/struct|ffi/trampoline|ffi/write|fiber/can\\\\-resume\\\\?|fiber/current|fiber/getenv|fiber/last\\\\-value|fiber/maxstack|fiber/new|fiber/root|fiber/setenv|fiber/setmaxstack|fiber/status|fiber\\\\?|file/close|file/flush|file/lines|file/open|file/read|file/seek|file/tell|file/temp|file/write|filter|find|find\\\\-index|first|flatten|flatten\\\\-into|flush|flycheck|freeze|frequencies|from\\\\-pairs|function\\\\?|gccollect|gcinterval|gcsetinterval|gensym|get|get\\\\-in|getline|getproto|group\\\\-by|has\\\\-key\\\\?|has\\\\-value\\\\?|hash|idempotent\\\\?|identity|import\\\\*|in|inc|index\\\\-of|indexed\\\\?|int/s64|int/to\\\\-bytes|int/to\\\\-number|int/u64|int\\\\?|interleave|interpose|invert|juxt\\\\*|keep|keep\\\\-syntax|keep\\\\-syntax!|keys|keyword|keyword/slice|keyword\\\\?|kvs|last|length|lengthable\\\\?|load\\\\-image|macex|macex1|maclintf|make\\\\-env|make\\\\-image|map|mapcat|marshal|math/abs|math/acos|math/acosh|math/asin|math/asinh|math/atan|math/atan2|math/atanh|math/cbrt|math/ceil|math/cos|math/cosh|math/erf|math/erfc|math/exp|math/exp2|math/expm1|math/floor|math/gamma|math/gcd|math/hypot|math/lcm|math/log|math/log\\\\-gamma|math/log10|math/log1p|math/log2|math/next|math/pow|math/random|math/rng|math/rng\\\\-buffer|math/rng\\\\-int|math/rng\\\\-uniform|math/round|math/seedrandom|math/sin|math/sinh|math/sqrt|math/tan|math/tanh|math/trunc|max|max\\\\-of|mean|memcmp|merge|merge\\\\-into|merge\\\\-module|min|min\\\\-of|mod|module/add\\\\-paths|module/expand\\\\-path|module/find|module/value|nan\\\\?|nat\\\\?|native|neg\\\\?|net/accept|net/accept\\\\-loop|net/address|net/address\\\\-unpack|net/chunk|net/close|net/connect|net/flush|net/listen|net/localname|net/peername|net/read|net/recv\\\\-from|net/send\\\\-to|net/server|net/setsockopt|net/shutdown|net/write|next|nil\\\\?|not|not=|number\\\\?|odd\\\\?|one\\\\?|os/arch|os/cd|os/chmod|os/clock|os/compiler|os/cpu\\\\-count|os/cryptorand|os/cwd|os/date|os/dir|os/environ|os/execute|os/exit|os/getenv|os/isatty|os/link|os/lstat|os/mkdir|os/mktime|os/open|os/perm\\\\-int|os/perm\\\\-string|os/pipe|os/posix\\\\-exec|os/posix\\\\-fork|os/proc\\\\-close|os/proc\\\\-kill|os/proc\\\\-wait|os/readlink|os/realpath|os/rename|os/rm|os/rmdir|os/setenv|os/shell|os/sigaction|os/sleep|os/spawn|os/stat|os/strftime|os/symlink|os/time|os/touch|os/umask|os/which|pairs|parse|parse\\\\-all|parser/byte|parser/clone|parser/consume|parser/eof|parser/error|parser/flush|parser/has\\\\-more|parser/insert|parser/new|parser/produce|parser/state|parser/status|parser/where|partial|partition|partition\\\\-by|peg/compile|peg/find|peg/find\\\\-all|peg/match|peg/replace|peg/replace\\\\-all|pos\\\\?|postwalk|pp|prewalk|prin|prinf|print|printf|product|propagate|put|put\\\\-in|quit|range|reduce|reduce2|repl|require|resume|return|reverse|reverse!|run\\\\-context|sandbox|scan\\\\-number|setdyn|signal|slice|slurp|some|sort|sort\\\\-by|sorted|sorted\\\\-by|spit|string|string/ascii\\\\-lower|string/ascii\\\\-upper|string/bytes|string/check\\\\-set|string/find|string/find\\\\-all|string/format|string/from\\\\-bytes|string/has\\\\-prefix\\\\?|string/has\\\\-suffix\\\\?|string/join|string/repeat|string/replace|string/replace\\\\-all|string/reverse|string/slice|string/split|string/trim|string/triml|string/trimr|string\\\\?|struct|struct/getproto|struct/proto\\\\-flatten|struct/to\\\\-table|struct/with\\\\-proto|struct\\\\?|sum|symbol|symbol/slice|symbol\\\\?|table|table/clear|table/clone|table/getproto|table/new|table/proto\\\\-flatten|table/rawget|table/setproto|table/to\\\\-struct|table/weak|table/weak\\\\-keys|table/weak\\\\-values|table\\\\?|take|take\\\\-until|take\\\\-while|tarray/buffer|tarray/copy\\\\-bytes|tarray/length|tarray/new|tarray/properties|tarray/slice|tarray/swap\\\\-bytes|thread/close|thread/current|thread/exit|thread/new|thread/receive|thread/send|thaw|trace|true\\\\?|truthy\\\\?|tuple|tuple/brackets|tuple/setmap|tuple/slice|tuple/sourcemap|tuple/type|tuple\\\\?|type|unmarshal|untrace|update|update\\\\-in|values|varglobal|walk|warn\\\\-compile|xprin|xprinf|xprint|xprintf|yield|zero\\\\?|zipcoll)$\"))\n\n\n[\"{\" \"@{\" \"}\"\n \"[\" \"@[\" \"]\"\n \"(\" \"@(\" \")\"] @punctuation.bracket\n\n[\"~\" \"'\" \"|\" \";\" \",\"] @operator\n"
  },
  {
    "path": "runtime/queries/janet/indents.scm",
    "content": "; aligns forms to the second position if there's two in a line:\n; (-> 10\n;     (* 2)\n;     (print))\n(par_tup_lit . (sym_lit) @first . (_) @anchor\n  (#set! \"scope\" \"tail\")\n  (#same-line? @first @anchor)\n  ; anything that doesn't match should be indented normally\n  ; from https://github.com/janet-lang/spork/blob/5601dc883535473bca28351cc6df04ed6c656c65/spork/fmt.janet#L87C12-L93C38\n  (#not-match? @first \"^(fn|match|with|with-dyns|def|def-|var|var-|defn|defn-|varfn|defmacro|defmacro-|defer|edefer|loop|seq|tabseq|catseq|generate|coro|for|each|eachp|eachk|case|cond|do|defglobal|varglobal|if|when|when-let|when-with|while|with-syms|with-vars|if-let|if-not|if-with|let|short-fn|try|unless|default|forever|upscope|repeat|forv|compwhen|compif|ev/spawn|ev/do-thread|ev/spawn-thread|ev/with-deadline|label|prompt|forever)$\")) @align\n\n; everything else should be indented normally:\n;\n; (let [foo 10]\n;   (print foo))\n;\n; (foo\n;   bar)\n(par_tup_lit . (sym_lit)) @indent\n\n; for `{}` and `[]`:\n; {:foo 10\n;  :bar 20}\n(struct_lit . (_) @anchor) @align\n\n; [foo\n;  bar]\n(sqr_tup_lit . (_) @anchor) @align\n"
  },
  {
    "path": "runtime/queries/janet/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/janet/rainbows.scm",
    "content": "[\n  (par_arr_lit)\n  (par_tup_lit)\n  (sqr_arr_lit)\n  (sqr_tup_lit)\n  (tbl_lit)\n  (struct_lit)\n  (short_fn_lit)\n] @rainbow.scope\n\n[\n  \"(\" \"@(\" \")\"\n  \"[\" \"@[\" \"]\"\n  \"{\" \"@{\" \"}\"\n  \"|\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/java/highlights.scm",
    "content": "(identifier) @variable\n\n; Methods\n\n(method_declaration\n  name: (identifier) @function.method)\n(method_invocation\n  name: (identifier) @function.method)\n(super) @function.builtin\n\n; Annotations\n\n(annotation\n  name: (identifier) @attribute)\n(marker_annotation\n  name: (identifier) @attribute)\n\n; Types\n\n(interface_declaration\n  name: (identifier) @type)\n(class_declaration\n  name: (identifier) @type)\n(record_declaration\n  name: (identifier) @type)\n(enum_declaration\n  name: (identifier) @type)\n\n((field_access\n  object: (identifier) @type)\n (#match? @type \"^[A-Z]\"))\n((scoped_identifier\n  scope: (identifier) @type)\n (#match? @type \"^[A-Z]\"))\n\n(constructor_declaration\n  name: (identifier) @type)\n(compact_constructor_declaration\n  name: (identifier) @type)\n\n(type_identifier) @type\n\n[\n  (boolean_type)\n  (integral_type)\n  (floating_point_type)\n  (floating_point_type)\n  (void_type)\n] @type.builtin\n\n(type_arguments\n  (wildcard \"?\" @type.builtin))\n\n; Variables\n\n((identifier) @constant\n (#match? @constant \"^_*[A-Z][A-Z\\\\d_]+$\"))\n\n(this) @variable.builtin\n\n; Literals\n\n[\n  (hex_integer_literal)\n  (decimal_integer_literal)\n  (octal_integer_literal)\n  (binary_integer_literal)\n] @constant.numeric.integer\n\n[\n  (decimal_floating_point_literal)\n  (hex_floating_point_literal)\n] @constant.numeric.float\n\n(character_literal) @constant.character\n\n[\n  (string_literal)\n  (text_block)\n] @string\n\n[\n  (true)\n  (false)\n  (null_literal)\n] @constant.builtin\n\n(line_comment) @comment\n(block_comment) @comment\n\n; Punctuation\n\n[\n  \"::\"\n  \".\"\n  \";\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"@\"\n  \"...\"\n] @punctuation.special\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n(type_arguments\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n(type_parameters\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n; Operators\n\n[\n  \"=\"\n  \">\"\n  \"<\"\n  \"!\"\n  \"~\"\n  \"?\"\n  \":\"\n  \"->\"\n  \"==\"\n  \">=\"\n  \"<=\"\n  \"!=\"\n  \"&&\"\n  \"||\"\n  \"++\"\n  \"--\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"&\"\n  \"|\"\n  \"^\"\n  \"%\"\n  \"<<\"\n  \">>\"\n  \">>>\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"&=\"\n  \"|=\"\n  \"^=\"\n  \"%=\"\n  \"<<=\"\n  \">>=\"\n  \">>>=\"\n] @operator\n\n; Keywords\n\n[\n  \"abstract\"\n  \"assert\"\n  \"break\"\n  \"case\"\n  \"catch\"\n  \"class\"\n  \"continue\"\n  \"default\"\n  \"do\"\n  \"else\"\n  \"enum\"\n  \"exports\"\n  \"extends\"\n  \"final\"\n  \"finally\"\n  \"if\"\n  \"implements\"\n  \"import\"\n  \"instanceof\"\n  \"interface\"\n  \"module\"\n  \"native\"\n  \"new\"\n  \"non-sealed\"\n  \"open\"\n  \"opens\"\n  \"package\"\n  \"permits\"\n  \"private\"\n  \"protected\"\n  \"provides\"\n  \"public\"\n  \"requires\"\n  \"record\"\n  \"return\"\n  \"sealed\"\n  \"static\"\n  \"strictfp\"\n  \"switch\"\n  \"synchronized\"\n  \"throw\"\n  \"throws\"\n  \"to\"\n  \"transient\"\n  \"transitive\"\n  \"try\"\n  \"uses\"\n  \"volatile\"\n  \"with\"\n  \"yield\"\n] @keyword\n\n[\n  \"while\"\n  \"for\"\n] @keyword.control.repeat\n"
  },
  {
    "path": "runtime/queries/java/indents.scm",
    "content": "[\n  (class_body)\n  (enum_body)\n  (interface_body)\n  (constructor_body)\n  (annotation_type_body)\n  (module_body)\n  (block)\n  (switch_block)\n  (array_initializer)\n  (argument_list)\n  (formal_parameters)\n  (annotation_argument_list)\n  (element_value_array_initializer)\n] @indent\n\n[\n  \"}\"\n  \")\"\n  \"]\"\n] @outdent\n\n; Single statement after if/while/for without brackets\n(if_statement\n  consequence: (_) @indent\n  (#not-kind-eq? @indent \"block\")\n  (#set! \"scope\" \"all\"))\n(while_statement\n  body: (_) @indent\n  (#not-kind-eq? @indent \"block\")\n  (#set! \"scope\" \"all\"))\n(for_statement\n  (_) @indent\n  (#not-kind-eq? @indent \"block\")\n  (#set! \"scope\" \"all\"))\n"
  },
  {
    "path": "runtime/queries/java/injections.scm",
    "content": "([(line_comment) (block_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/java/rainbows.scm",
    "content": "[\n  (cast_expression)\n  (inferred_parameters)\n  (dimensions_expr)\n  (parenthesized_expression)\n  (array_access)\n  (argument_list)\n  (type_arguments)\n  (dimensions)\n  (block)\n  (switch_block)\n  (catch_clause)\n  (resource_specification)\n  (for_statement)\n  (enhanced_for_statement)\n  (annotation_argument_list)\n  (element_value_array_initializer)\n  (module_body)\n  (enum_body)\n  (type_parameters)\n  (class_body)\n  (constructor_body)\n  (annotation_type_body)\n  (annotation_type_element_declaration)\n  (interface_body)\n  (array_initializer)\n  (formal_parameters)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"{\" \"}\"\n  \"[\" \"]\"\n  \"<\" \">\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/java/tags.scm",
    "content": "(class_declaration\n  name: (identifier) @definition.class)\n\n(interface_declaration\n  name: (identifier) @definition.interface)\n\n(record_declaration\n  name: (identifier) @definition.class)\n\n(enum_declaration\n  name: (identifier) @defintion.class)\n\n(method_declaration\n  name: (identifier) @definition.function)\n\n(constructor_declaration\n  name: (identifier) @definition.function)\n\n(compact_constructor_declaration\n  name: (identifier) @definition.function)\n\n(field_declaration\n  declarator: (variable_declarator\n    name: (identifier) @definition.constant))\n\n(enum_constant\n  name: (identifier) @definition.constant)\n"
  },
  {
    "path": "runtime/queries/java/textobjects.scm",
    "content": "(method_declaration\n  body: (_)? @function.inside) @function.around\n\n(constructor_declaration\n  body: (_) @function.inside) @function.around\n\n(interface_declaration\n  body: (_) @class.inside) @class.around\n\n(class_declaration\n  body: (_) @class.inside) @class.around\n\n(record_declaration\n  body: (_) @class.inside) @class.around\n\n(enum_declaration\n  body: (_) @class.inside) @class.around\n\n(formal_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(argument_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n[\n  (line_comment)\n  (block_comment)\n] @comment.inside\n\n(line_comment)+ @comment.around\n\n(block_comment) @comment.around\n\n(array_initializer\n  (_) @entry.around)\n\n(enum_body\n  (enum_constant) @entry.around)\n"
  },
  {
    "path": "runtime/queries/javascript/highlights.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: ecma,_javascript\n"
  },
  {
    "path": "runtime/queries/javascript/indents.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _javascript,ecma\n"
  },
  {
    "path": "runtime/queries/javascript/injections.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _javascript,ecma\n"
  },
  {
    "path": "runtime/queries/javascript/locals.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _javascript,ecma\n"
  },
  {
    "path": "runtime/queries/javascript/rainbows.scm",
    "content": "; inherits: ecma\n"
  },
  {
    "path": "runtime/queries/javascript/tags.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _javascript,ecma\n"
  },
  {
    "path": "runtime/queries/javascript/textobjects.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _javascript,ecma\n"
  },
  {
    "path": "runtime/queries/jinja/highlights.scm",
    "content": "(expression) @string\n(statement) @variable.builtin\n(keyword) @keyword\n(comment) @comment\n(identifier) @variable.parameter\n(operator) @operator\n(string) @string"
  },
  {
    "path": "runtime/queries/jinja/injections.scm",
    "content": "((source_file) @injection.content\n (#set! injection.combined)\n (#set! injection.include-children)\n (#set! injection.language \"html\"))"
  },
  {
    "path": "runtime/queries/jjconfig/highlights.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/jjconfig/indents.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/jjconfig/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n(table\n (bare_key) @table-name (#any-of? @table-name \"templates\" \"template-aliases\")\n [(pair (_) ((string) @injection.content (#set! injection.language \"jjtemplate\"))) (comment)])\n\n(table\n (bare_key) @table-name (#any-of? @table-name \"revsets\" \"revset-aliases\")\n [(pair (_) ((string) @injection.content (#set! injection.language \"jjrevset\"))) (comment)])\n\n; Injections for aliases that contain inline scripts. (see `jj util exec --help`)\n; This pattern currently relies on the language having the same name as its\n; interpreter, which is often the case (sh, bash, python, fish, nu...)\n; It also assumes the interpreter accepts the inline script with the \"-c\" flag.\n(table\n (bare_key) @table-name (#eq? @table-name \"aliases\")\n (pair (_) (array .\n  (string) @util (#eq? @util \"\\\"util\\\"\") . (string) @exec (#eq? @exec \"\\\"exec\\\"\") . (string) @dd (#eq? @dd \"\\\"--\\\"\") .\n  (string) @injection.language .\n  ; There are many possibilities to combine \"-c\" with other short flags, but by\n  ; far the most common one should be the \"-e\" flag, which makes the script\n  ; return early when an error occurs.\n  (string) @dc (#any-of? @dc \"\\\"-c\\\"\" \"\\\"-ce\\\"\" \"\\\"-ec\\\"\") .\n  (string) @injection.content)))\n"
  },
  {
    "path": "runtime/queries/jjconfig/textobjects.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/jjdescription/highlights.scm",
    "content": "(text) @string\n(filepath) @string.special.path\n\n(change type: \"A\" @diff.plus)\n(change type: \"D\" @diff.minus)\n(change type: \"M\" @diff.delta)\n(change type: \"C\" @diff.plus)\n(change type: \"R\" @diff.delta)\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/jjdescription/injections.scm",
    "content": "(((scissors_inner) @injection.content)\n (#set! injection.include-children)\n (#set! injection.language \"diff\"))\n"
  },
  {
    "path": "runtime/queries/jjrevset/highlights.scm",
    "content": "(at_op) @variable.builtin\n\n[\n  \"::\" \"..\"\n  (negate_op)\n  (union_op) (intersection_op) (difference_op)\n] @operator\n\n[\"(\" \")\"] @punctuation.bracket\n\",\" @punctuation.delimiter\n[(raw_string_literal) (string_literal)] @string\n\n(function ((strict_identifier) @function))\n(function (function_arguments (keyword_argument (strict_identifier) @variable.parameter)))\n\n(primary ((identifier) @variable))\n\n(string_pattern (strict_identifier) @keyword)\n"
  },
  {
    "path": "runtime/queries/jjtemplate/highlights.scm",
    "content": "(function ((identifier) @function))\n; method calls\n(term (_) (\".\" @punctuation) ((function ((identifier) @function.method))))\n\n[\"(\" \")\"] @punctuation.bracket\n\",\" @punctuation.delimiter\n\n((identifier) @keyword.control.conditional (#eq? @keyword.control.conditional \"if\"))\n((identifier) @keyword.control.repeat (#eq? @keyword.control.repeat \"for\"))\n\n(term ((identifier) @variable))\n\n[(infix_ops) \"++\"] @operator\n[(string_literal) (raw_string_literal)] @string\n\n(integer_literal) @constant.numeric.integer\n"
  },
  {
    "path": "runtime/queries/jq/highlights.scm",
    "content": ";; From nvim-treesitter, contributed by @ObserverOfTime et al.\n\n; Variables\n(variable) @variable\n\n((variable) @constant.builtin\n  (#eq? @constant.builtin \"$ENV\"))\n\n((variable) @constant.builtin\n  (#eq? @constant.builtin \"$__loc__\"))\n\n; Properties\n(index\n  (identifier) @variable.other.member)\n\n; Labels\n(query\n  label: (variable) @label)\n\n(query\n  break_statement: (variable) @label)\n\n; Literals\n(number) @constant.numeric\n\n(string) @string\n\n[\n  \"true\"\n  \"false\"\n] @constant.builtin.boolean\n\n\"null\" @type.builtin\n\n; Interpolation\n[\n  \"\\\\(\"\n  \")\"\n] @special\n\n; Format\n(format) @attribute\n\n; Functions\n(funcdef\n  (identifier) @function)\n\n(funcdefargs\n  (identifier) @variable.parameter)\n\n[\n  \"reduce\"\n  \"foreach\"\n] @function.builtin\n\n((funcname) @function\n  .\n  \"(\")\n\n; jq -n 'builtins | map(split(\"/\")[0]) | unique | .[]'\n((funcname) @function.builtin\n  (#any-of? @function.builtin\n    \"IN\" \"INDEX\" \"JOIN\" \"abs\" \"acos\" \"acosh\" \"add\" \"all\" \"any\" \"arrays\" \"ascii_downcase\"\n    \"ascii_upcase\" \"asin\" \"asinh\" \"atan\" \"atan2\" \"atanh\" \"booleans\" \"bsearch\" \"builtins\" \"capture\"\n    \"cbrt\" \"ceil\" \"combinations\" \"contains\" \"copysign\" \"cos\" \"cosh\" \"debug\" \"del\" \"delpaths\" \"drem\"\n    \"empty\" \"endswith\" \"env\" \"erf\" \"erfc\" \"error\" \"exp\" \"exp10\" \"exp2\" \"explode\" \"expm1\" \"fabs\"\n    \"fdim\" \"finites\" \"first\" \"flatten\" \"floor\" \"fma\" \"fmax\" \"fmin\" \"fmod\" \"format\" \"frexp\"\n    \"from_entries\" \"fromdate\" \"fromdateiso8601\" \"fromjson\" \"fromstream\" \"gamma\" \"get_jq_origin\"\n    \"get_prog_origin\" \"get_search_list\" \"getpath\" \"gmtime\" \"group_by\" \"gsub\" \"halt\" \"halt_error\"\n    \"has\" \"hypot\" \"implode\" \"in\" \"index\" \"indices\" \"infinite\" \"input\" \"input_filename\"\n    \"input_line_number\" \"inputs\" \"inside\" \"isempty\" \"isfinite\" \"isinfinite\" \"isnan\" \"isnormal\"\n    \"iterables\" \"j0\" \"j1\" \"jn\" \"join\" \"keys\" \"keys_unsorted\" \"last\" \"ldexp\" \"length\" \"lgamma\"\n    \"lgamma_r\" \"limit\" \"localtime\" \"log\" \"log10\" \"log1p\" \"log2\" \"logb\" \"ltrimstr\" \"map\" \"map_values\"\n    \"match\" \"max\" \"max_by\" \"min\" \"min_by\" \"mktime\" \"modf\" \"modulemeta\" \"nan\" \"nearbyint\" \"nextafter\"\n    \"nexttoward\" \"normals\" \"not\" \"now\" \"nth\" \"nulls\" \"numbers\" \"objects\" \"path\" \"paths\" \"pick\" \"pow\"\n    \"pow10\" \"range\" \"recurse\" \"remainder\" \"repeat\" \"reverse\" \"rindex\" \"rint\" \"round\" \"rtrimstr\"\n    \"scalars\" \"scalb\" \"scalbln\" \"scan\" \"select\" \"setpath\" \"significand\" \"sin\" \"sinh\" \"sort\"\n    \"sort_by\" \"split\" \"splits\" \"sqrt\" \"startswith\" \"stderr\" \"strflocaltime\" \"strftime\" \"strings\"\n    \"strptime\" \"sub\" \"tan\" \"tanh\" \"test\" \"tgamma\" \"to_entries\" \"todate\" \"todateiso8601\" \"tojson\"\n    \"tonumber\" \"tostream\" \"tostring\" \"transpose\" \"trunc\" \"truncate_stream\" \"type\" \"unique\"\n    \"unique_by\" \"until\" \"utf8bytelength\" \"values\" \"walk\" \"while\" \"with_entries\" \"y0\" \"y1\" \"yn\"))\n\n; Keywords\n[\n  \"def\"\n  \"as\"\n  \"label\"\n  \"module\"\n  \"break\"\n] @keyword\n\n[\n  \"import\"\n  \"include\"\n] @keyword.control.import\n\n[\n  \"if\"\n  \"then\"\n  \"elif\"\n  \"else\"\n  \"end\"\n] @keyword.control.conditional\n\n[\n  \"try\"\n  \"catch\"\n] @keyword.control.exception\n\n[\n  \"or\"\n  \"and\"\n] @keyword.operator\n\n; Operators\n[\n  \".\"\n  \"==\"\n  \"!=\"\n  \">\"\n  \">=\"\n  \"<=\"\n  \"<\"\n  \"=\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"//=\"\n  \"|\"\n  \"?\"\n  \"//\"\n  \"?//\"\n  (recurse) ; \"..\"\n] @operator\n\n; Punctuation\n[\n  \";\"\n  \",\"\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n; Comments\n(comment) @comment.line\n"
  },
  {
    "path": "runtime/queries/jq/injections.scm",
    "content": ";; From nvim-treesitter, contributed by @ObserverOfTime et al.\n\n((comment) @injection.content\n  (#set! injection.language \"comment\"))\n\n; test(val)\n(query\n  ((funcname) @_function\n    (#any-of? @_function \"test\" \"match\" \"capture\" \"scan\" \"split\" \"splits\" \"sub\" \"gsub\"))\n  (args\n    .\n    (query\n      (string) @injection.content\n      (#set! injection.language \"regex\"))))\n\n; test(regex; flags)\n(query\n  ((funcname) @_function\n    (#any-of? @_function \"test\" \"match\" \"capture\" \"scan\" \"split\" \"splits\" \"sub\" \"gsub\"))\n  (args\n    .\n    (args\n      (query\n        (string) @injection.content\n        (#set! injection.language \"regex\")))))\n"
  },
  {
    "path": "runtime/queries/jq/locals.scm",
    "content": ";; From nvim-treesitter, contributed by @ObserverOfTime et al.\n\n(funcdef\n  (identifier) @local.definition.function)\n\n(funcdefargs\n  (identifier) @local.definition.variable.parameter)\n\n(funcname) @local.reference\n\n(index\n  (identifier) @local.reference)\n"
  },
  {
    "path": "runtime/queries/jq/textobjects.scm",
    "content": "(comment) @comment.inside\n(comment)+ @comment.around\n\n(funcdef\n  (query) @function.inside) @function.around\n\n(objectkeyval\n  (_) @entry.inside) @entry.around\n"
  },
  {
    "path": "runtime/queries/jsdoc/highlights.scm",
    "content": "(tag_name) @keyword\n(type) @type\n"
  },
  {
    "path": "runtime/queries/jsdoc/injections.scm",
    "content": "; Parse general comment tags\n\n((document) @injection.content\n (#set! injection.include-children)\n (#set! injection.language \"comment\"))"
  },
  {
    "path": "runtime/queries/json/highlights.scm",
    "content": "[\n  (true)\n  (false)\n] @constant.builtin.boolean\n(null) @constant.builtin\n(number) @constant.numeric\n\n(string) @string\n(escape_sequence) @constant.character.escape\n\n(pair\n  key: (_) @variable.other.member)\n\n(comment) @comment\n\n[\",\" \":\"] @punctuation.delimiter\n[\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/json/indents.scm",
    "content": "[\n  (object)\n  (array)\n] @indent\n\n[\n  \"]\"\n  \"}\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/json/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/json/rainbows.scm",
    "content": "[\n  (object)\n  (array)\n] @rainbow.scope\n\n[\n  \"[\" \"]\"\n  \"{\" \"}\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/json/textobjects.scm",
    "content": "(pair \n  (_) @entry.inside) @entry.around\n\n(array\n  (_) @entry.around)\n\n(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/json-ld/highlights.scm",
    "content": "; inherits: json\n\n; https://www.w3.org/TR/json-ld/#syntax-tokens-and-keywords\n((string (string_content) @keyword)\n (#any-of? @keyword\n   \"@base\"\n   \"@container\"\n   \"@context\"\n   \"@direction\"\n   \"@graph\"\n   \"@id\"\n   \"@import\"\n   \"@included\"\n   \"@index\"\n   \"@json\"\n   \"@language\"\n   \"@list\"\n   \"@nest\"\n   \"@none\"\n   \"@prefix\"\n   \"@propagate\"\n   \"@protected\"\n   \"@reverse\"\n   \"@set\"\n   \"@type\"\n   \"@value\"\n   \"@version\"\n   \"@vocab\"))\n\n((pair\n  value: (string (string_content) @string.special.url))\n (#match? @string.special.url \"^https?://\"))\n\n((array\n  (string (string_content) @string.special.url))\n  (#match? @string.special.url \"^https?://\"))\n\n; https://www.w3.org/TR/json-ld/#dfn-base-direction\n((pair\n  key: (string (string_content) @keyword)\n  value: (string (string_content) @type.enum.variant))\n (#eq? @keyword \"@direction\")\n (#any-of? @type.enum.variant \"ltr\" \"rtl\"))\n"
  },
  {
    "path": "runtime/queries/json-ld/indents.scm",
    "content": "; inherits: json\n"
  },
  {
    "path": "runtime/queries/json-ld/injections.scm",
    "content": "; inherits: json\n"
  },
  {
    "path": "runtime/queries/json-ld/rainbows.scm",
    "content": "; inherits: json\n"
  },
  {
    "path": "runtime/queries/json-ld/textobjects.scm",
    "content": "; inherits: json\n"
  },
  {
    "path": "runtime/queries/json5/highlights.scm",
    "content": "[\n  (true)\n  (false)\n] @constant.builtin.boolean\n(null) @constant.builtin\n(number) @constant.numeric\n\n(string) @string\n(comment) @comment\n\n(member\n  name: (_) @variable.other.member)\n\n[\",\" \":\"] @punctuation.delimiter\n[\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/json5/indents.scm",
    "content": "[\n  (object)\n  (array)\n] @indent\n\n[\n  \"]\"\n  \"}\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/json5/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/json5/rainbows.scm",
    "content": "[\n  (object)\n  (array)\n] @rainbow.scope\n\n[\n  \"[\" \"]\"\n  \"{\" \"}\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/json5/textobjects.scm",
    "content": "(member\n  (_) @entry.inside) @entry.around\n\n(array\n  (_) @entry.around)\n\n(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/jsonc/highlights.scm",
    "content": "; inherits: json\n"
  },
  {
    "path": "runtime/queries/jsonc/indents.scm",
    "content": "; inherits: json\n"
  },
  {
    "path": "runtime/queries/jsonc/injections.scm",
    "content": "; inherits: json\n"
  },
  {
    "path": "runtime/queries/jsonc/rainbows.scm",
    "content": "; inherits: json\n"
  },
  {
    "path": "runtime/queries/jsonc/textobjects.scm",
    "content": "; inherits: json\n"
  },
  {
    "path": "runtime/queries/jsonnet/highlights.scm",
    "content": "[\"if\" \"then\" \"else\"] @keyword.control.conditional\n[\n  (local)\n  \"function\"\n] @keyword\n(comment) @comment\n\n(string) @string\n(number) @constant.numeric\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(binaryop) @operator\n(unaryop) @operator\n\n(id) @variable\n(param identifier: (id) @variable.parameter)\n(bind function: (id) @function)\n(fieldname (id) @variable.other.member)\n[\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\"for\" @keyword.control.repeat\n\"in\" @keyword.operator\n[(self) (dollar)] @variable.builtin\n\"assert\" @keyword\n(null) @constant.builtin\n[\n  \":\"\n  \"::\"\n  \";\"\n  \"=\"\n] @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/jsonnet/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/jsx/highlights.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: ecma,_javascript,_jsx\n"
  },
  {
    "path": "runtime/queries/jsx/indents.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _jsx,_javascript,ecma\n"
  },
  {
    "path": "runtime/queries/jsx/injections.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _jsx,_javascript,ecma\n"
  },
  {
    "path": "runtime/queries/jsx/locals.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _jsx,_javascript,ecma\n"
  },
  {
    "path": "runtime/queries/jsx/rainbows.scm",
    "content": "; inherits: ecma\n\n[\n  (jsx_expression)\n] @rainbow.scope\n\n(jsx_opening_element [\"<\" \">\"] @rainbow.bracket) @rainbow.scope\n(jsx_closing_element [\"</\" \">\"] @rainbow.bracket) @rainbow.scope\n(jsx_self_closing_element [\"<\" \"/>\"] @rainbow.bracket) @rainbow.scope\n"
  },
  {
    "path": "runtime/queries/jsx/tags.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _jsx,_javascript,ecma\n"
  },
  {
    "path": "runtime/queries/jsx/textobjects.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _jsx,_javascript,ecma\n"
  },
  {
    "path": "runtime/queries/julia/folds.scm",
    "content": "[\n  (module_definition)\n  (struct_definition)\n  (macro_definition)\n  (function_definition)\n  (if_statement)\n  (try_statement)\n  (for_statement)\n  (while_statement)\n  (let_statement)\n  (quote_statement)\n  (do_clause)\n  (compound_statement) ; begin block\n] @fold\n"
  },
  {
    "path": "runtime/queries/julia/highlights.scm",
    "content": "; ------------\n; Variables identifiers\n; ------------\n\n(identifier) @variable\n\n; Remaining identifiers that start with capital letters should be types (PascalCase)\n(\n  (identifier) @type\n  (#match? @type \"^[A-Z]\"))\n\n; SCREAMING_SNAKE_CASE\n(\n  (identifier) @constant\n  (#match? @constant \"^[A-Z][A-Z0-9_]*$\"))\n\n(const_statement\n  (assignment\n    . (identifier) @constant))\n\n; Field expressions are either module content or struct fields.\n; Module types and constants should already be captured, so this\n; assumes the remaining identifiers to be struct fields.\n(field_expression\n  (_)\n  (identifier) @variable.other.member)\n\n(quote_expression\n  \":\" @string.special.symbol\n  [\n    (identifier)\n    (operator)\n  ] @string.special.symbol)\n\n; ------\n; Macros\n; ------\n\n(macro_definition\n  name: (identifier) @function.macro)\n\n(macro_identifier\n  \"@\" @function.macro\n  (identifier) @function.macro)\n\n; -------------------\n; Modules and Imports\n; -------------------\n\n(module_definition\n  name: (identifier) @namespace)\n  \n(import_statement\n  (identifier) @namespace)\n  \n(selected_import\n  . (identifier) @namespace)\n\n(scoped_identifier\n  (identifier) @namespace)\n\n; -------------------\n; Function definition\n; -------------------\n\n(\n  (function_definition\n    name: [\n      (identifier) @function\n      (scoped_identifier\n        (identifier) @namespace\n        (identifier) @function)\n    ])\n  ; prevent constructors (PascalCase) to be highlighted as functions\n  (#match? @function \"^[^A-Z]\"))\n\n(\n  (short_function_definition\n    name: [\n      (identifier) @function\n      (scoped_identifier\n        (identifier) @namespace\n        (identifier) @function)\n    ])\n  ; prevent constructors (PascalCase) to be highlighted as functions\n  (#match? @function \"^[^A-Z]\"))\n\n; ---------------\n; Functions calls\n; ---------------\n\n(\n  (call_expression\n    (identifier) @function)\n  ; prevent constructors (PascalCase) to be highlighted as functions\n  (#match? @function \"^[^A-Z]\"))\n\n(\n  (call_expression\n    (field_expression (identifier) @function .))\n  (#match? @function \"^[^A-Z]\"))\n\n(\n  (broadcast_call_expression\n    (identifier) @function)\n  (#match? @function \"^[^A-Z]\"))\n\n(\n  (broadcast_call_expression\n    (field_expression (identifier) @function .))\n  (#match? @function \"^[^A-Z]\"))\n\n\n; -------------------\n; Functions builtins\n; -------------------\n\n((identifier) @function.builtin\n  (#any-of? @function.builtin\n    \"_abstracttype\" \"_apply_iterate\" \"_apply_pure\" \"_call_in_world\" \"_call_in_world_total\"\n    \"_call_latest\" \"_equiv_typedef\" \"_expr\" \"_primitivetype\" \"_setsuper!\" \"_structtype\" \"_typebody!\"\n    \"_typevar\" \"applicable\" \"apply_type\" \"arrayref\" \"arrayset\" \"arraysize\" \"const_arrayref\"\n    \"donotdelete\" \"fieldtype\" \"get_binding_type\" \"getfield\" \"ifelse\" \"invoke\" \"isa\" \"isdefined\"\n    \"modifyfield!\" \"nfields\" \"replacefield!\" \"set_binding_type!\" \"setfield!\" \"sizeof\" \"svec\"\n    \"swapfield!\" \"throw\" \"tuple\" \"typeassert\" \"typeof\"))\n\n; -----------\n; Parameters\n; -----------\n\n(parameter_list\n  (identifier) @variable.parameter)\n\n(optional_parameter\n  . (identifier) @variable.parameter)\n\n(slurp_parameter\n  (identifier) @variable.parameter)\n\n(typed_parameter\n  parameter: (identifier)? @variable.parameter\n  type: (_) @type)\n\n(function_expression\n  . (identifier) @variable.parameter) ; Single parameter arrow functions\n\n; -----\n; Types\n; -----\n\n; Definitions\n(abstract_definition\n  name: (identifier) @type.definition) @keyword\n\n(primitive_definition\n  name: (identifier) @type.definition) @keyword\n\n(struct_definition\n  name: (identifier) @type)\n\n(struct_definition\n  . (_)\n    (identifier) @variable.other.member)\n\n(struct_definition\n  . (_)\n  (typed_expression\n    . (identifier) @variable.other.member))\n\n(type_clause\n  [\n    (identifier) @type\n    (field_expression\n      (identifier) @type .)\n  ])\n\n; Annotations\n(parametrized_type_expression\n  (_) @type\n  (curly_expression\n    (_) @type))\n\n(type_parameter_list\n  (identifier) @type)\n\n(typed_expression\n  (identifier) @type . )\n\n(function_definition\n  return_type: (identifier) @type)\n\n(short_function_definition\n  return_type: (identifier) @type)\n\n(where_clause\n  (identifier) @type)\n\n(where_clause\n  (curly_expression\n    (_) @type))\n\n; ---------\n; Builtins\n; ---------\n\n; This list was generated with:\n;\n;  istype(x) = typeof(x) === DataType || typeof(x) === UnionAll\n;  get_types(m) = filter(x -> istype(Base.eval(m, x)), names(m))\n;  type_names = sort(union(get_types(Core), get_types(Base)))\n;\n((identifier) @type.builtin\n  (#any-of? @type.builtin\n    \"AbstractArray\" \"AbstractChannel\" \"AbstractChar\" \"AbstractDict\" \"AbstractDisplay\"\n    \"AbstractFloat\" \"AbstractIrrational\" \"AbstractLock\" \"AbstractMatch\" \"AbstractMatrix\"\n    \"AbstractPattern\" \"AbstractRange\" \"AbstractSet\" \"AbstractSlices\" \"AbstractString\"\n    \"AbstractUnitRange\" \"AbstractVecOrMat\" \"AbstractVector\" \"Any\" \"ArgumentError\" \"Array\"\n    \"AssertionError\" \"Atomic\" \"BigFloat\" \"BigInt\" \"BitArray\" \"BitMatrix\" \"BitSet\" \"BitVector\" \"Bool\"\n    \"BoundsError\" \"By\" \"CanonicalIndexError\" \"CapturedException\" \"CartesianIndex\" \"CartesianIndices\"\n    \"Cchar\" \"Cdouble\" \"Cfloat\" \"Channel\" \"Char\" \"Cint\" \"Cintmax_t\" \"Clong\" \"Clonglong\" \"Cmd\" \"Colon\"\n    \"ColumnSlices\" \"Complex\" \"ComplexF16\" \"ComplexF32\" \"ComplexF64\" \"ComposedFunction\"\n    \"CompositeException\" \"ConcurrencyViolationError\" \"Condition\" \"Cptrdiff_t\" \"Cshort\" \"Csize_t\"\n    \"Cssize_t\" \"Cstring\" \"Cuchar\" \"Cuint\" \"Cuintmax_t\" \"Culong\" \"Culonglong\" \"Cushort\" \"Cvoid\"\n    \"Cwchar_t\" \"Cwstring\" \"DataType\" \"DenseArray\" \"DenseMatrix\" \"DenseVecOrMat\" \"DenseVector\" \"Dict\"\n    \"DimensionMismatch\" \"Dims\" \"DivideError\" \"DomainError\" \"EOFError\" \"Enum\" \"ErrorException\"\n    \"Exception\" \"ExponentialBackOff\" \"Expr\" \"Float16\" \"Float32\" \"Float64\" \"Function\" \"GlobalRef\"\n    \"HTML\" \"IO\" \"IOBuffer\" \"IOContext\" \"IOStream\" \"IdDict\" \"IndexCartesian\" \"IndexLinear\"\n    \"IndexStyle\" \"InexactError\" \"InitError\" \"Int\" \"Int128\" \"Int16\" \"Int32\" \"Int64\" \"Int8\" \"Integer\"\n    \"InterruptException\" \"InvalidStateException\" \"Irrational\" \"KeyError\" \"LazyString\" \"LinRange\"\n    \"LineNumberNode\" \"LinearIndices\" \"LoadError\" \"Lt\" \"MIME\" \"Matrix\" \"Method\" \"MethodError\"\n    \"Missing\" \"MissingException\" \"Module\" \"NTuple\" \"NamedTuple\" \"Nothing\" \"Number\" \"Ordering\"\n    \"OrdinalRange\" \"OutOfMemoryError\" \"OverflowError\" \"Pair\" \"ParseError\" \"PartialQuickSort\" \"Perm\"\n    \"PermutedDimsArray\" \"Pipe\" \"ProcessFailedException\" \"Ptr\" \"QuoteNode\" \"Rational\" \"RawFD\"\n    \"ReadOnlyMemoryError\" \"Real\" \"ReentrantLock\" \"Ref\" \"Regex\" \"RegexMatch\" \"Returns\"\n    \"ReverseOrdering\" \"RoundingMode\" \"RowSlices\" \"SegmentationFault\" \"Set\" \"Signed\" \"Slices\" \"Some\"\n    \"SpinLock\" \"StackFrame\" \"StackOverflowError\" \"StackTrace\" \"Stateful\" \"StepRange\" \"StepRangeLen\"\n    \"StridedArray\" \"StridedMatrix\" \"StridedVecOrMat\" \"StridedVector\" \"String\" \"StringIndexError\"\n    \"SubArray\" \"SubString\" \"SubstitutionString\" \"Symbol\" \"SystemError\" \"Task\" \"TaskFailedException\"\n    \"Text\" \"TextDisplay\" \"Timer\" \"Tmstruct\" \"Tuple\" \"Type\" \"TypeError\" \"TypeVar\" \"UInt\" \"UInt128\"\n    \"UInt16\" \"UInt32\" \"UInt64\" \"UInt8\" \"UndefInitializer\" \"UndefKeywordError\" \"UndefRefError\"\n    \"UndefVarError\" \"Union\" \"UnionAll\" \"UnitRange\" \"Unsigned\" \"Val\" \"VecElement\" \"VecOrMat\" \"Vector\"\n    \"VersionNumber\" \"WeakKeyDict\" \"WeakRef\"))\n\n((identifier) @variable.builtin\n  (#any-of? @variable.builtin \"begin\" \"end\"))\n\n((identifier) @variable.builtin\n  (#any-of? @variable.builtin \"begin\" \"end\"))\n\n\n; --------\n; Keywords\n; --------\n\n[\n  \"global\"\n  \"local\"\n] @keyword\n\n(compound_statement\n  [\n    \"begin\"\n    \"end\"\n  ] @keyword)\n\n(quote_statement\n  [\n    \"quote\"\n    \"end\"\n  ] @keyword)\n\n(let_statement\n  [\n    \"let\"\n    \"end\"\n  ] @keyword)\n\n(if_statement\n  [\n    \"if\"\n    \"end\"\n  ] @keyword.control.conditional)\n\n(elseif_clause\n  \"elseif\" @keyword.control.conditional)\n\n(else_clause\n  \"else\" @keyword.control.conditional)\n\n(if_clause\n  \"if\" @keyword.control.conditional) ; `if` clause in comprehensions\n\n(ternary_expression\n  [\n    \"?\"\n    \":\"\n  ] @keyword.control.conditional)\n\n(try_statement\n  [\n    \"try\"\n    \"end\"\n  ] @keyword.control.exception)\n\n(finally_clause\n  \"finally\" @keyword.control.exception)\n\n(catch_clause\n  \"catch\" @keyword.control.exception)\n\n(for_statement\n  [\n    \"for\"\n    \"end\"\n  ] @keyword.control.repeat)\n\n(while_statement\n  [\n    \"while\"\n    \"end\"\n  ] @keyword.control.repeat)\n\n(for_clause\n  \"for\" @keyword.control.repeat)\n\n[\n  (break_statement)\n  (continue_statement)\n] @keyword.control.repeat\n\n(module_definition\n  [\n    \"module\"\n    \"baremodule\"\n    \"end\"\n  ] @keyword.control.import)\n\n(import_statement\n  [\n    \"import\"\n    \"using\"\n  ] @keyword.control.import)\n\n(import_alias\n  \"as\" @keyword.control.import)\n\n(export_statement\n  \"export\" @keyword.control.import)\n\n(selected_import\n  \":\" @punctuation.delimiter)\n\n(struct_definition\n  [\n    \"struct\"\n    \"end\"\n  ] @keyword)\n\n(macro_definition\n  [\n    \"macro\"\n    \"end\"\n  ] @keyword)\n\n(function_definition\n  [\n    \"function\"\n    \"end\"\n  ] @keyword.function)\n\n(do_clause\n  [\n    \"do\"\n    \"end\"\n  ] @keyword.function)\n\n(return_statement\n  \"return\" @keyword.control.return)\n\n[\n  \"const\"\n  \"mutable\"\n] @keyword.storage.modifier\n\n; ---------\n; Operators\n; ---------\n\n[\n  (operator)\n  \"=\"\n  \"∈\"\n] @operator\n\n(adjoint_expression\n  \"'\" @operator)\n\n(range_expression\n  \":\" @operator)\n\n((operator) @keyword.operator\n  (#any-of? @keyword.operator \"in\" \"isa\"))\n\n(for_binding\n  \"in\" @keyword.operator)\n\n(where_clause\n  \"where\" @keyword.operator)\n\n(where_expression\n  \"where\" @keyword.operator)\n\n(binary_expression\n  (_)\n  (operator) @operator\n  (identifier) @function\n  (#any-of? @operator \"|>\" \".|>\"))\n\n; ------------\n; Punctuations\n; ------------\n\n[\n  \".\"\n  \",\" \n  \";\"\n  \"::\"\n  \"->\"\n] @punctuation.delimiter\n\n\"...\" @punctuation.special\n\n[\n  \"(\"\n  \")\" \n  \"[\"\n  \"]\"\n  \"{\" \n  \"}\"\n] @punctuation.bracket\n\n; ---------\n; Literals\n; ---------\n\n(boolean_literal) @constant.builtin.boolean\n\n(integer_literal) @constant.numeric.integer\n\n(float_literal) @constant.numeric.float\n\n(\n  ((identifier) @constant.numeric.float)\n  (#match? @constant.numeric.float \"^((Inf|NaN)(16|32|64)?)$\"))\n\n(\n  ((identifier) @constant.builtin)\n  (#match? @constant.builtin \"^(nothing|missing|undef)$\"))\n\n(character_literal) @constant.character\n\n(escape_sequence) @constant.character.escape\n\n(string_literal) @string\n\n(prefixed_string_literal\n  prefix: (identifier) @function.macro) @string\n\n(command_literal) @string\n\n(prefixed_command_literal\n  prefix: (identifier) @function.macro) @string\n\n; ---------\n; Comments\n; ---------\n\n[\n  (line_comment)\n  (block_comment)\n] @comment\n"
  },
  {
    "path": "runtime/queries/julia/indents.scm",
    "content": "[\n  (struct_definition)\n  (macro_definition)\n  (function_definition)\n  (compound_statement)\n  (if_statement)\n  (try_statement)\n  (for_statement)\n  (while_statement)\n  (let_statement)\n  (quote_statement)\n  (do_clause)\n  (assignment)\n  (for_binding)\n  (call_expression)\n  (parenthesized_expression)\n  (tuple_expression)\n  (comprehension_expression)\n  (matrix_expression)\n  (vector_expression)\n] @indent\n\n[\n  \"end\"\n  \")\"\n  \"]\"\n  \"}\"\n] @outdent\n\n(argument_list\n  . (_) @anchor\n  (#set! \"scope\" \"tail\")) @align\n\n(parameter_list\n  . (_) @anchor\n  (#set! \"scope\" \"tail\")) @align\n\n(curly_expression\n  . (_) @anchor\n  (#set! \"scope\" \"tail\")) @align\n"
  },
  {
    "path": "runtime/queries/julia/injections.scm",
    "content": "(\n  (source_file\n    (string_literal) @injection.content\n    .\n    [\n      (module_definition)\n      (function_definition)\n      (macro_definition)\n      (primitive_definition)\n      (abstract_definition)\n      (struct_definition)\n      (short_function_definition)\n      (assignment)\n      (const_statement)\n    ])\n  (#set! injection.language \"markdown\"))\n\n(\n  [\n    (line_comment) \n    (block_comment)\n  ] @injection.content\n  (#set! injection.language \"comment\"))\n\n(\n  [\n    (command_literal)\n    (prefixed_command_literal)\n  ] @injection.content\n  (#set! injection.language \"sh\"))\n\n(\n  (prefixed_string_literal\n    prefix: (identifier) @function.macro) @injection.content\n  (#eq? @function.macro \"r\")\n  (#set! injection.language \"regex\"))\n\n(\n  (prefixed_string_literal\n    prefix: (identifier) @function.macro) @injection.content\n  (#eq? @function.macro \"md\")\n  (#set! injection.language \"markdown\"))\n"
  },
  {
    "path": "runtime/queries/julia/locals.scm",
    "content": "; -----------\n; Definitions\n; -----------\n\n; Constants\n(const_statement\n  (assignment\n    . (identifier) @local.definition.constant))\n\n; Parameters\n(parameter_list\n  (identifier) @local.definition.variable.parameter)\n\n(optional_parameter\n  .\n  (identifier) @local.definition.variable.parameter)\n\n(slurp_parameter\n  (identifier) @local.definition.variable.parameter)\n\n(typed_parameter\n  parameter: (identifier) @local.definition.variable.parameter\n  (_))\n\n; Single parameter arrow function\n(function_expression\n  .\n  (identifier) @local.definition.variable.parameter)\n\n; ----------\n; References\n; ----------\n\n(identifier) @local.reference\n \n; ------\n; Scopes\n; ------\n\n[\n  (for_statement)\n  (while_statement)\n  (try_statement)\n  (catch_clause)\n  (finally_clause)\n  (let_statement)\n  (quote_statement)\n  (do_clause)\n  (function_definition)\n  (short_function_definition)\n  (macro_definition)\n] @local.scope \n\n"
  },
  {
    "path": "runtime/queries/julia/textobjects.scm",
    "content": "(function_definition (_)? @function.inside) @function.around\n\n(short_function_definition (_)? @function.inside) @function.around\n\n(macro_definition (_)? @function.inside) @function.around\n\n(struct_definition (_)? @class.inside) @class.around\n\n(abstract_definition (_)? @class.inside) @class.around\n\n(primitive_definition (_)? @class.inside) @class.around\n\n(parameter_list\n  ; Match all children of parameter_list *except* keyword_parameters\n  ([(identifier)\n    (slurp_parameter)\n    (optional_parameter)\n    (typed_parameter)\n    (tuple_expression)\n    (interpolation_expression)\n    (call_expression)]\n  @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(keyword_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(argument_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_parameter_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(line_comment) @comment.inside\n\n(line_comment)+ @comment.around\n\n(block_comment) @comment.inside\n\n(block_comment)+ @comment.around\n\n(_expression (macro_identifier\n    (identifier) @_name\n    (#match? @_name \"^(test|test_throws|test_logs|inferred|test_deprecated|test_warn|test_nowarn|test_broken|test_skip)$\")\n  )\n  .\n  (macro_argument_list) @test.inside) @test.around\n"
  },
  {
    "path": "runtime/queries/just/folds.scm",
    "content": "; Define collapse points\n\n([\n  (recipe)\n  (string)\n  (external_command)\n] @fold\n  (#trim! @fold))\n"
  },
  {
    "path": "runtime/queries/just/highlights.scm",
    "content": "; This file specifies how matched syntax patterns should be highlighted\n\n[\n  \"export\"\n  \"import\"\n  \"unexport\"\n] @keyword.control.import\n\n\"mod\" @keyword.directive\n\n[\n  \"alias\"\n  \"set\"\n  \"shell\"\n] @keyword\n\n[\n  \"if\"\n  \"else\"\n] @keyword.control.conditional\n\n[\n  \"&&\"\n  \"||\"\n] @operator\n\n; Variables\n\n(value\n  (identifier) @variable)\n\n(alias\n  alias_name: (identifier) @variable)\n\n(assignment\n  name: (identifier) @variable)\n\n(shell_variable_name) @variable\n\n(unexport\n  name: (identifier) @variable)\n\n; Functions\n\n(recipe\n  name: (identifier) @function)\n\n(recipe_dependency\n  name: (identifier) @function.call)\n\n(function_call\n  name: (identifier) @function.builtin)\n\n; Parameters\n\n(recipe_parameter\n  name: (identifier) @variable.parameter)\n\n; Namespaces\n\n(mod\n  name: (identifier) @namespace)\n\n(module_path\n  name: (identifier) @namespace)\n\n; Paths\n\n(mod\n  (path) @string.special.path)\n\n(import\n  (path) @string.special.path)\n\n; Shebangs\n\n(shebang_line) @keyword.directive\n(shebang_line\n  (shebang_shell) @string.special)\n\n\n(shell_expanded_string\n  [\n    (expansion_short_start)\n    (expansion_long_start)\n    (expansion_long_middle)\n    (expansion_long_end)\n  ] @punctuation.special)\n\n; Operators\n\n[\n  \":=\"\n  \"?\"\n  \"==\"\n  \"!=\"\n  \"=~\"\n  \"!~\"\n  \"@\"\n  \"=\"\n  \"$\"\n  \"*\"\n  \"+\"\n  \"&&\"\n  \"@-\"\n  \"-@\"\n  \"-\"\n  \"/\"\n  \":\"\n] @operator\n\n; Punctuation\n\n\",\" @punctuation.delimiter\n\n[\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"(\"\n  \")\"\n  \"{{\"\n  \"}}\"\n] @punctuation.bracket\n\n[ \"`\" \"```\" ] @punctuation.special\n\n; Literals\n\n; Booleans are not allowed anywhere except in settings\n(setting\n  (boolean) @constant.builtin.boolean)\n\n[\n  (string)\n  (external_command)\n] @string\n\n[\n  (escape_sequence)\n  (escape_variable_end)\n] @constant.character.escape\n\n; Comments\n\n(comment) @comment.line\n\n; highlight known settings\n(setting\n  name: (_) @keyword.function)\n\n; highlight known attributes\n(attribute\n  name: (identifier) @attribute)\n\n; Numbers are part of the syntax tree, even if disallowed\n(numeric_error) @error\n"
  },
  {
    "path": "runtime/queries/just/indents.scm",
    "content": "; This query specifies how to auto-indent logical blocks.\n;\n; Better documentation with diagrams is in https://docs.helix-editor.com/guides/indent.html\n\n[\n  (recipe)\n  (string)\n  (external_command)\n] @indent @extend\n"
  },
  {
    "path": "runtime/queries/just/injections.scm",
    "content": "; Specify nested languages that live within a `justfile`\n\n; ================ Always applicable ================\n\n((comment) @injection.content\n  (#set! injection.language \"comment\"))\n\n; Highlight the RHS of `=~` as regex\n((regex\n  (_) @injection.content)\n  (#set! injection.language \"regex\"))\n\n; ================ Global defaults ================\n\n; Default recipe lines to be bash, but exclude interpolation nodes\n; This prevents bash's rainbow brackets from interfering with just's {{ }} markers\n; Use injection.combined to combine all recipe lines so bash can parse multi-line constructs\n(recipe_body\n  !shebang\n  (recipe_line) @injection.content\n  (#set! injection.language \"bash\")\n  (#set! injection.combined))\n\n(external_command\n  (content) @injection.content\n  (#set! injection.language \"bash\"))\n\n; ================ Global language specified ================\n; Global language is set with something like one of the following:\n;\n;    set shell := [\"bash\", \"-c\", ...]\n;    set shell := [\"pwsh.exe\"]\n;\n; We can extract the first item of the array, but we can't extract the language\n; name from the string with something like regex. So instead we special case\n; two things: powershell, which is likely to come with a `.exe` attachment that\n; we need to strip, and everything else which hopefully has no extension. We\n; separate this with a `#match?`.\n;\n; Unfortunately, there also isn't a way to allow arbitrary nesting or\n; alternatively set \"global\" capture variables. So we can set this for item-\n; level external commands, but not for e.g. external commands within an\n; expression without getting _really_ annoying. Should at least look fine since\n; they default to bash. Limitations...\n; See https://github.com/tree-sitter/tree-sitter/issues/880 for more on that.\n\n(file\n  (setting \"shell\" \":=\" \"[\" (string) @_langstr\n    (#match? @_langstr \".*(powershell|pwsh|cmd).*\")\n    (#set! injection.language \"powershell\"))\n  [\n    (recipe\n      (recipe_body\n        !shebang\n        (recipe_line) @injection.content\n        (#set! injection.combined)))\n\n    (assignment\n      (expression\n        (value\n          (external_command\n            (content) @injection.content))))\n  ])\n\n(file\n  (setting \"shell\" \":=\" \"[\" (string) @injection.language\n    (#not-match? @injection.language \".*(powershell|pwsh|cmd).*\"))\n  [\n    (recipe\n      (recipe_body\n        !shebang\n        (recipe_line) @injection.content\n        (#set! injection.combined)))\n\n    (assignment\n      (expression\n        (value\n          (external_command\n            (content) @injection.content))))\n  ])\n\n; ================ Recipe language specified - Helix only ================\n\n; Set highlighting for recipes that specify a language using builtin shebang matching\n(recipe_body\n  (shebang_line) @injection.shebang\n  (recipe_line) @injection.content\n  (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/just/locals.scm",
    "content": "; This file tells us about the scope of variables so e.g. local\n; variables override global functions with the same name\n\n; Scope\n\n(recipe) @local.scope\n\n; Definitions\n\n(alias\n  alias_name: (identifier) @local.definition.variable)\n\n(assignment\n  name: (identifier) @local.definition.variable)\n\n(mod\n  name: (identifier) @local.definition.namespace)\n\n(recipe_parameter\n  name: (identifier) @local.definition.variable.parameter)\n\n(recipe\n  name: (identifier) @local.definition.function)\n\n; References\n\n(alias\n  name: (identifier) @local.reference)\n\n(function_call\n  name: (identifier) @local.reference)\n\n(module_path\n  name: (identifier) @local.reference)\n\n(recipe_dependency\n  name: (identifier) @local.reference)\n\n(value\n  (identifier) @local.reference)\n"
  },
  {
    "path": "runtime/queries/just/tags.scm",
    "content": "; Symbols that can be considered definitions in a Just file.\n\n(alias\n  alias_name: (identifier) @definition.function)\n\n(assignment\n  name: (identifier) @definition.constant)\n\n(import\n  (path) @definition.module)\n\n(mod\n  name: (identifier) @definition.module)\n\n(recipe\n  name: (identifier) @definition.function)\n\n(unexport\n  name: (identifier) @definition.constant)\n"
  },
  {
    "path": "runtime/queries/just/textobjects.scm",
    "content": "; Specify how to navigate around logical blocks in code\n\n(assert_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around)) @parameter.around\n\n(recipe\n  (recipe_body) @function.inside) @function.around\n\n(recipe_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around)) @parameter.around\n\n(recipe_dependency\n  (_) @parameter.inside) @parameter.around\n\n(function_call\n  (function_parameters\n    ((_) @parameter.inside . \",\"? @parameter.around)) @parameter.around) @function.around\n\n(comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/kcl/highlights.scm",
    "content": ";; Maps AST nodes (left) to highlighting classes (right)\n;; See https://docs.helix-editor.com/themes.html#scopes\n;; for the supported scopes.\n;; Don't forget to run the command `hx --grammar fetch` to fetch the grammars,\n;; and `hx --grammar build` to build any out-of-date grammars.\n\n\"fn\" @keyword.function\n\"return\" @keyword.control.return\n\"import\" @keyword.control.import\n\"export\" @keyword.control.import\n[\n \"if\"\n \"else\"\n ] @keyword.control.conditional\n(identifier) @variable\n\n;; highlight type names\n(type_name\n  (identifier) @type\n) @type\n\n(fn_call\n  callee: (identifier) @function\n  (labeledArg\n    label: (identifier) @variable.parameter\n  )\n)\n\n\n;; operators\n(binary_operator) @operator\n(prefix_operator) @operator\n\n;; punctuation\n\n; \"..\" @punctuation.special\n\n\"(\" @punctuation.bracket\n\")\" @punctuation.bracket\n\"[\" @punctuation.bracket\n\"]\" @punctuation.bracket\n\"{\" @punctuation.bracket\n\"}\" @punctuation.bracket\n\n; \".\" @punctuation.delimiter\n\",\" @punctuation.delimiter\n; \":\" @punctuation.delimiter\n; \";\" @punctuation.delimiter\n\n;; literals\n(boolean) @constant.builtin.boolean\n(string) @string\n(number) @constant.numeric\n\n;; comments\n(shebang) @keyword.directive\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/kconfig/folds.scm",
    "content": "[\n  (config)\n  (menuconfig)\n  (choice)\n  (comment_entry)\n  (menu)\n  (if)\n  (help_text)\n] @fold\n"
  },
  {
    "path": "runtime/queries/kconfig/highlights.scm",
    "content": "[\n  \"source\"\n  \"osource\"\n  \"rsource\"\n  \"orsource\"\n] @keyword.control.import\n\n[\n  \"mainmenu\"\n  \"config\"\n  \"configdefault\"\n  \"menuconfig\"\n  \"choice\"\n  \"endchoice\"\n  \"comment\"\n  \"menu\"\n  \"endmenu\"\n  \"prompt\"\n  \"default\"\n  \"range\"\n  \"help\"\n  (optional)\n  (modules)\n] @keyword\n\n[\n  \"if\"\n  \"endif\"\n  \"depends on\"\n  \"select\"\n  \"imply\"\n  \"visible if\"\n] @keyword.control.conditional\n\n[\n  \"def_bool\"\n  \"def_tristate\"\n] @keyword.function\n\n[\n  \"||\"\n  \"&&\"\n  \"=\"\n  \"!=\"\n  \"<\"\n  \">\"\n  \"<=\"\n  \">=\"\n  \"!\"\n] @operator\n\n[\n  \"bool\"\n  \"tristate\"\n  \"int\"\n  \"hex\"\n  \"string\"\n] @type.builtin\n\n[ \"(\" \")\" ] @punctuation.bracket\n\n(macro_variable [\"$(\" \")\"] @punctuation.special)\n\n(symbol) @variable\n\n[\n  (string)\n  (macro_content)\n  (text)\n] @string\n\n(config name: (name (symbol) @constant))\n(configdefault name: (name (symbol) @constant))\n(menuconfig name: (name (symbol) @constant))\n(choice name: (name (symbol) @constant))\n\n((symbol) @constant\n  (#match? @constant \"[A-Z0-9]+\"))\n\n(mainmenu name: (string) @markup.heading)\n(comment_entry name: (string) @markup.heading)\n(menu name: (string) @markup.heading)\n\n(source (string) @string.special.url @string.special)\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/kconfig/indents.scm",
    "content": "(help_text (text) @align)\n\n[\n  (config)\n  (menuconfig)\n  (choice)\n  (comment_entry)\n  (menu)\n  (if)\n  (help_text)\n] @indent\n"
  },
  {
    "path": "runtime/queries/kconfig/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/kconfig/locals.scm",
    "content": "[\n  (symbol)\n  (string)\n] @local.reference\n\n[\n  (config)\n  (menuconfig)\n  (choice)\n  (comment_entry)\n  (menu)\n  (if)\n] @local.scope\n\n(type_definition (string) @local.definition.type)\n(type_definition (input_prompt (string) @local.definition.type))\n(type_definition_default (expression (string) @local.definition.type))\n"
  },
  {
    "path": "runtime/queries/kdl/highlights.scm",
    "content": "[\n    (single_line_comment)\n    (multi_line_comment)\n\n    (node_comment)\n    (node_field_comment)\n\n    ; these do not show up as comments in Helix as they are also highlighted as\n    ; normal nodes\n    (node . (node_comment))\n    (node_field . (node_field_comment))\n] @comment\n\n(node\n    (identifier) @variable)\n\n(prop (identifier) @attribute)\n\n(type (_) @type) @punctuation.bracket\n\n(keyword) @keyword\n\n(string) @string\n(number) @constant.numeric\n(boolean) @constant.builtin.boolean\n\n\".\" @punctuation.delimiter\n\n\"=\" @operator\n\n\"{\" @punctuation.bracket\n\"}\" @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/kdl/indents.scm",
    "content": "(node_children) @indent\n\n \"}\" @outdent\n"
  },
  {
    "path": "runtime/queries/kdl/injections.scm",
    "content": "; match/exclude regex with regular string\n(node\n  (identifier) @_section_name\n  (#any-of? @_section_name \"window-rule\" \"layer-rule\")\n  children: (node_children\n    (node\n      (identifier) @_node_name\n      (#any-of? @_node_name \"match\" \"exclude\")\n      (node_field\n        (prop\n          (identifier) @_prop_name\n          (#any-of? @_prop_name \"app-id\" \"title\" \"namespace\")\n          (value\n            (string\n              (string_fragment) @injection.content\n              (#set! injection.language \"regex\")\n            )\n          )\n        )\n      )\n    )\n  )\n)\n\n(node\n  (identifier) @_section\n  (#eq? @_section \"binds\")\n  children: (node_children\n    (node\n      (identifier)\n      children: (node_children\n        (node\n          (identifier) @_action_name\n          (#eq? @_action_name \"spawn\")\n          (node_field\n            (value\n              (string\n                (string_fragment) @_executable\n                (#eq? @_executable \"fish\")\n              )\n            )\n          )\n          (node_field\n            (value\n              (string\n                (string_fragment) @_flag\n                (#eq? @_flag \"-c\")\n              )\n            )\n          )\n          (node_field\n            (value\n              (string\n                (string_fragment) @injection.content\n                (#set! injection.language \"fish\")\n              )\n            )\n          )\n        )\n      )\n    )\n  )\n)\n\n([\n  (single_line_comment)\n  (multi_line_comment)\n] @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/kdl/rainbows.scm",
    "content": "(node_children) @rainbow.scope\n\n[\"{\" \"}\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/kdl/tags.scm",
    "content": "(node (identifier) @definition.struct\n  children: _\n)\n"
  },
  {
    "path": "runtime/queries/kdl/textobjects.scm",
    "content": "(type (_) @test.inside) @test.around\n\n(node\n\tchildren: (node_children)? @class.inside) @class.around\n\n(node\n\tchildren: (node_children)? @function.inside) @function.around\n\n(node (identifier) @function.movement)\n\n[\n\t(single_line_comment)\n\t(multi_line_comment)\n] @comment.inside\n\n[\n\t(single_line_comment)+\n\t(multi_line_comment)+\n] @comment.around\n\n[\n\t(prop)\n\t(value)\n] @parameter.inside\n\n(value (type) ? (_) @parameter.inside @parameter.movement . ) @parameter.around\n\n"
  },
  {
    "path": "runtime/queries/klog/highlights.scm",
    "content": "(date) @markup.heading\n(summary) @comment\n(negative_duration) @diff.minus\n(positive_duration) @diff.plus\n(range) @diff.delta\n(tag) @constant\n"
  },
  {
    "path": "runtime/queries/koka/highlights.scm",
    "content": "; Comment\n\n[\n  (linecomment)\n  (blockcomment)\n] @comment\n\n; Literals\n\n(string) @string\n(char) @constant.character\n\n(escape) @constant.character.escape\n\n(float) @constant.numeric.float\n(int) @constant.numeric.integer\n\n; Delimiters\n\n(matchrule \"|\" @punctuation.delimiter)\n\n(tatomic \"|\" @punctuation.delimiter)\n\n[\n  \",\"\n  \"->\"\n  \".\"\n  \":\"\n  \"::\"\n  \"<-\"\n  \";\"\n] @punctuation.delimiter\n\n[\n  \"<\"\n  \">\"\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n; Keywords\n\n[\n  \"as\"\n  (externtarget)\n  \"forall\"\n  \"handle\"\n  \"handler\"\n  \"in\"\n  \"infix\"\n  \"infixl\"\n  \"infixr\"\n  \"mask\"\n  (behindmod)\n  (pub)\n  \"some\"\n] @keyword\n\n; Lazy constructor\n(constructor\n  \"lazy\" @keyword)\n\n; Lazy match\n(matchexpr\n  \"lazy\" @keyword)\n\n[\n  (con)\n  \"ctl\"\n  \"fn\"\n  \"fun\"\n] @keyword.function\n\n\"with\" @keyword.control\n\n[\n  \"elif\"\n  \"else\"\n  \"if\"\n  \"match\"\n  \"then\"\n] @keyword.control.conditional\n\n[\n  \"import\"\n  ;\"include\"\n  \"module\"\n] @keyword.control.import\n\n[\n  \"alias\"\n  \"effect\"\n  \"struct\"\n  \"type\"\n  \"val\"\n  \"var\"\n] @keyword.storage.type\n\n[\n  \"abstract\"\n  \"extern\"\n  \"final\"\n  (inlinemod)\n  (externinline)\n  (typemod)\n  (structmod)\n  (effectmod)\n  \"named\"\n  (override)\n  (controlmod)\n  ;\"scoped\" ; scoped is actually an effect modifier, but it is not in the current parser.\n  (tailmod)\n] @keyword.storage.modifier\n\n(fipmod\n  [\"fip\" \"fbip\"] @keyword.storage.modifier)\n\n\"return\" @keyword.control.return\n\n; Operators\n\n[\n  \"!\"\n  \"~\"\n  \"=\"\n  \":=\"\n  (idop)\n  (op)\n  (qidop)\n] @operator\n\n(modulepath) @namespace\n\n; Variables\n\n(pattern\n  (identifier\n    (varid) @variable))\n\n(paramid\n  (identifier\n    (varid) @variable.parameter))\n\n(pparameter\n  (pattern\n    (identifier\n      (varid) @variable.parameter)))\n\n(pparameter\n  (qimplicit) @variable.parameter)\n\n(puredecl\n  (binder\n    (qidentifier) @constant))\n\n; Named arguments\n(argument\n  [(identifier) (qimplicit)] @variable.parameter\n  \"=\"\n  (expr))\n\n; Types\n\n(typecon\n  [(varid) (qvarid)] @type)\n\n(tbinder\n  (varid) @type)\n\n(typeid\n  (varid) @type)\n\n(typedecl\n  \"effect\"\n  (varid) @type)\n\n; Function definitions\n\n(fundecl\n  (identifier) @function)\n\n(puredecl\n  (qidentifier) @function)\n\n(externdecl\n  (qidentifier) @function)\n\n; Effect definitions/usages\n\n(opclause\n  (qidentifier) @function)\n\n(operation\n  (identifier) @function)\n  \n\n; Function calls\n\n(opexpr\n  (atom\n    (name) @function)\n  .\n  [\n    call: \"(\" (arguments)? \")\"\n    trailing_lambda: [(block) (fnexpr)]\n  ])\n\n(opexpr\n  (atom)\n  (name) @function)\n\n(ntlexpr\n  (atom\n    (name) @function)\n  .\n  (\"(\" (arguments)? \")\"))\n\n(ntlexpr\n  (atom)\n  (name) @function)\n\n[(conid) (qconid)] @constructor\n\n[\n  \"initially\"\n  \"finally\"\n] @function.builtin\n"
  },
  {
    "path": "runtime/queries/koka/indents.scm",
    "content": "[\n  (opexpr [index: (arguments) call: (arguments)]) ; Applications.\n  (atom [\"[\" \"(\"]) ; Lists and tuples.\n  (funbody)\n  (block)\n  (constructor)\n  (handlerexpr)\n  (opclausex)\n] @indent\n\n[\n  (typedecl\n    [(typeid) (opdecls)]) ; Avoid matching single-operation effects.\n  (externdecl)\n  (matchexpr)\n  (matchrule)\n\n  ; For ifexprs, branches (once they exist) will contain blocks if they're\n  ; indented so we just need to make sure the initial indent happens when we're\n  ; creating them.\n  \"then\"\n  \"else\"\n] @indent @extend\n\n(matchrule \"->\" @indent @extend)\n\n; Handling for error recovery.\n(ERROR \"fun\") @indent @extend\n(ERROR \"match\") @indent @extend\n(ERROR \"->\" @indent.always @extend)\n\n; Don't outdent on function parameter declarations.\n(atom \")\" @outdent @extend.prevent-once)\n\n[\n  \"]\"\n  \"}\"\n] @outdent @extend.prevent-once\n"
  },
  {
    "path": "runtime/queries/koka/injections.scm",
    "content": "([(linecomment) (blockcomment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/kotlin/folds.scm",
    "content": "[\n\t(import_list)\n\n\t(when_expression)\n\t(control_structure_body)\n\n\t(lambda_literal)\n\t(function_body)\n\t(primary_constructor)\n\t(secondary_constructor)\n\t(anonymous_initializer)\n\n\t(class_body)\n\t(enum_class_body)\n\n\t(interpolated_expression)\n] @fold\n"
  },
  {
    "path": "runtime/queries/kotlin/highlights.scm",
    "content": ";;; Identifiers\n(simple_identifier) @variable\n\n; `field` keyword inside property getter/setter\n; FIXME: This will highlight the keyword outside of getters and setters\n;        since tree-sitter does not allow us to check for arbitrary nestation\n((simple_identifier) @variable.builtin\n(#eq? @variable.builtin \"field\"))\n\n; `it` keyword inside lambdas\n; FIXME: This will highlight the keyword outside of lambdas since tree-sitter\n;        does not allow us to check for arbitrary nestation\n((simple_identifier) @variable.builtin\n(#eq? @variable.builtin \"it\"))\n\n\n;;; Operators & Punctuation\n\n[\n\t\".\"\n\t\",\"\n\t\";\"\n\t\":\"\n\t\"::\"\n] @punctuation.delimiter\n\n[\n\t\"(\" \")\"\n\t\"[\" \"]\"\n\t\"{\" \"}\"\n] @punctuation.bracket\n\n[\n\t\"!\"\n\t\"!=\"\n\t\"!==\"\n\t\"=\"\n\t\"==\"\n\t\"===\"\n\t\">\"\n\t\">=\"\n\t\"<\"\n\t\"<=\"\n\t\"||\"\n\t\"&&\"\n\t\"+\"\n\t\"++\"\n\t\"+=\"\n\t\"-\"\n\t\"--\"\n\t\"-=\"\n\t\"*\"\n\t\"*=\"\n\t\"/\"\n\t\"/=\"\n\t\"%\"\n\t\"%=\"\n\t\"?.\"\n\t\"?:\"\n\t\"!!\"\n\t\"is\"\n\t\"!is\"\n\t\"in\"\n\t\"!in\"\n\t\"as\"\n\t\"as?\"\n\t\"..\"\n\t\"->\"\n] @operator\n\n;;; String interpolation\n\n(string_literal\n\t\"$\" @punctuation.special\n  (interpolated_identifier) @variable)\n(string_literal\n\t\"${\" @punctuation.special\n\t(interpolated_expression) @none\n\t\"}\" @punctuation.special)\n\n; `it` and `this` inside string interpolation\n((interpolated_identifier) @variable.builtin\n(#eq? @variable.builtin \"it\"))\n((interpolated_identifier) @variable.builtin\n(#eq? @variable.builtin \"this\"))\n\n;;; Keywords\n\n(type_alias \"typealias\" @keyword)\n[\n\t(class_modifier)\n\t(member_modifier)\n\t(function_modifier)\n\t(property_modifier)\n\t(platform_modifier)\n\t(variance_modifier)\n\t(parameter_modifier)\n\t(visibility_modifier)\n\t(reification_modifier)\n\t(inheritance_modifier)\n]@keyword\n\n[\n\t\"val\"\n\t\"var\"\n\t\"enum\"\n\t\"class\"\n\t\"object\"\n\t\"interface\"\n\t\"companion\"\n;\t\"typeof\" ; NOTE: It is reserved for future use\n] @keyword\n\n(\"fun\") @keyword.function\n\n(jump_expression) @keyword.control.return\n\n[\n\t\"if\"\n\t\"else\"\n\t\"when\"\n] @keyword.control.conditional\n\n[\n\t\"for\"\n\t\"do\"\n\t\"while\"\n] @keyword.control.repeat\n\n[\n\t\"try\"\n\t\"catch\"\n\t\"throw\"\n\t\"finally\"\n] @keyword.control.exception\n\n(annotation\n\t\"@\" @attribute (use_site_target)? @attribute)\n(annotation\n\t(user_type\n\t\t(type_identifier) @attribute))\n(annotation\n\t(constructor_invocation\n\t\t(user_type\n\t\t\t(type_identifier) @attribute)))\n\n(file_annotation\n\t\"@\" @attribute \"file\" @attribute \":\" @attribute)\n(file_annotation\n\t(user_type\n\t\t(type_identifier) @attribute))\n(file_annotation\n\t(constructor_invocation\n\t\t(user_type\n\t\t\t(type_identifier) @attribute)))\n\n;;; Literals\n; NOTE: Escapes not allowed in multi-line strings\n(character_literal (character_escape_seq) @constant.character.escape)\n\n(string_literal) @string\n\n(character_literal) @constant.character\n\n(boolean_literal) @constant.builtin.boolean\n(null_literal) @constant.builtin\n\n(real_literal) @constant.numeric.float\n[\n\t(integer_literal)\n\t(long_literal)\n\t(hex_literal)\n\t(bin_literal)\n\t(unsigned_literal)\n] @constant.numeric.integer\n\n[\n\t(line_comment)\n\t(multiline_comment)\n\t(shebang_line)\n] @comment\n\n;;; Constants\n\n(enum_entry\n\t(simple_identifier) @constant)\n\n; SCREAMING CASE identifiers are assumed to be constants\n((simple_identifier) @constant\n(#match? @constant \"^[A-Z][A-Z0-9_]*$\"))\n\n;;; Navigation, Members & Function calls\n\n; generic property navigation (e.g. obj.property)\n(_\n\t(navigation_suffix\n\t\t(simple_identifier) @variable.other.member))\n\n; generic function call (e.g. foo())\n(call_expression\n\t. (simple_identifier) @function)\n\n; method call via navigation (e.g. obj.method())\n(call_expression\n\t(navigation_expression\n\t\t(navigation_suffix\n\t\t\t(simple_identifier) @function) . ))\n\n; infix function call (e.g. 1 to 2)\n(infix_expression\n  . (_) .\n\t(simple_identifier) @function)\n\n; builtin function calls\n(call_expression\n\t. (simple_identifier) @function.builtin\n    (#match? @function.builtin \"^(arrayOf|arrayOfNulls|byteArrayOf|shortArrayOf|intArrayOf|longArrayOf|ubyteArrayOf|ushortArrayOf|uintArrayOf|ulongArrayOf|floatArrayOf|doubleArrayOf|booleanArrayOf|charArrayOf|emptyArray|mapOf|setOf|listOf|emptyMap|emptySet|emptyList|mutableMapOf|mutableSetOf|mutableListOf|print|println|error|TODO|run|runCatching|repeat|lazy|lazyOf|enumValues|enumValueOf|assert|check|checkNotNull|require|requireNotNull|with|suspend|synchronized)$\"))\n\n; constant access via navigation (e.g. Foo.CONSTANT)\n(_\n\t(navigation_suffix\n\t\t(simple_identifier) @constant\n\t\t(#match? @constant \"^[A-Z][A-Z0-9_]*$\")))\n\n; object or class reference (e.g. TextObjects.TEXT)\n((navigation_expression\n  . (simple_identifier) @type)\n  (#match? @type \"^[A-Z]\"))\n\n;;; Function definitions\n\n; lambda parameters\n(lambda_literal\n\t(lambda_parameters\n\t\t(variable_declaration\n\t\t\t(simple_identifier) @variable.parameter)))\n\t\t\t\n(parameter_with_optional_type\n\t(simple_identifier) @variable.parameter)\n\t\t\t\n(parameter\n\t(simple_identifier) @variable.parameter)\n\n; named arguments\n(value_argument\n  . (simple_identifier) @variable.parameter)\n\n(anonymous_initializer\n\t(\"init\") @constructor)\n\n(constructor_invocation\n\t(user_type\n\t\t(type_identifier) @constructor))\n\t\t\t\n(secondary_constructor\n\t(\"constructor\") @constructor)\n(primary_constructor) @constructor\n\t\t\t\n(getter\n\t(\"get\") @function.builtin)\n(setter\n\t(\"set\") @function.builtin)\n\n; normal function\n(function_declaration\n\t(modifiers)?\n\t(type_parameters)?\n\t(simple_identifier) @function)\n\n; extension function\n(function_declaration\n\treceiver: (receiver_type)\n\t(simple_identifier) @function)\n\n; TODO: Separate labeled returns/breaks/continue/super/this\n;       Must be implemented in the parser first\n(label) @label\n\n(import_header\n\t(identifier\n\t\t(simple_identifier) @function @_import .)\n\t(import_alias\n\t\t(type_identifier) @function)?\n\t\t(#match? @_import \"^[a-z]\"))\n\n; The last `simple_identifier` in a `import_header` will always either be a function\n; or a type. Classes can appear anywhere in the import path, unlike functions\n(import_header\n\t(identifier\n\t\t(simple_identifier) @type @_import)\n\t(import_alias\n\t\t(type_identifier) @type)?\n\t\t(#match? @_import \"^[A-Z]\"))\n\n(import_header\n\t\"import\" @keyword.control.import)\n\n(package_header\n\t. (identifier)) @namespace\n\n(type_identifier) @type\n\n((type_identifier) @type.builtin\n\t(#match? @type.builtin \"^(Byte|Short|Int|Long|UByte|UShort|UInt|ULong|Float|Double|Boolean|Char|String|Array|ByteArray|ShortArray|IntArray|LongArray|UByteArray|UShortArray|UIntArray|ULongArray|FloatArray|DoubleArray|BooleanArray|CharArray|Map|Set|List|EmptyMap|EmptySet|EmptyList|MutableMap|MutableSet|MutableList)$\"))\n\n(type_parameter\n  (type_identifier) @type.parameter)\n\n((class_body\n\t(property_declaration\n\t\t(variable_declaration\n\t\t\t(simple_identifier) @variable.other.member)))\n  (#not-match? @variable.other.member \"^[A-Z][A-Z0-9_]*$\"))\n\n; Extension property\n(property_declaration\n  receiver: (receiver_type)\n  (variable_declaration\n    (simple_identifier) @variable.other.member))\n\n(class_parameter\n\t(simple_identifier) @variable.other.member)\n\n; `super` keyword inside classes\n(super_expression) @variable.builtin\n\n; `this` this keyword inside classes\n(this_expression) @variable.builtin\n"
  },
  {
    "path": "runtime/queries/kotlin/indents.scm",
    "content": "[\n  (class_body)\n  (enum_class_body)\n  (lambda_literal)\n\n  ; _block is hidden in the grammar, so list all public wrappers explicitly.\n  (function_body)\n  (anonymous_initializer)\n  (control_structure_body)\n  (secondary_constructor)\n  (try_expression)\n  (catch_block)\n  (finally_block)\n\n  (property_declaration)\n  (assignment)\n\n  (when_expression)\n  (call_expression)\n  (if_expression)\n\n  ; Binary expressions\n  (multiplicative_expression)\n  (additive_expression)\n  (range_expression)\n  (infix_expression)\n  (elvis_expression)\n  (check_expression)\n  (comparison_expression)\n  (equality_expression)\n  (comparison_expression)\n  (equality_expression)\n  (conjunction_expression)\n  (disjunction_expression)\n\n  (call_suffix)\n  (function_value_parameters)\n] @indent\n\n[\n  \"}\"\n  \")\"\n  \"]\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/kotlin/injections.scm",
    "content": "([\n  (line_comment)\n  (multiline_comment)\n ] @injection.content\n\t(#set! injection.language \"comment\"))\n\n; There are 3 ways to define a regex\n;    - \"[abc]?\".toRegex()\n((call_expression\n\t(navigation_expression\n\t\t(string_literal\n\t\t   (string_content) @injection.content)\n\t\t(navigation_suffix\n\t\t\t((simple_identifier) @_function\n\t\t\t(#eq? @_function \"toRegex\")))))\n\t(#set! injection.language \"regex\"))\n\n;    - Regex(\"[abc]?\")\n((call_expression\n\t((simple_identifier) @_function\n\t(#eq? @_function \"Regex\"))\n\t(call_suffix\n\t\t(value_arguments\n\t\t\t(value_argument\n\t\t\t\t(string_literal\n\t\t\t\t\t(string_content) @injection.content)))))\n\t(#set! injection.language \"regex\"))\n\n;    - Regex.fromLiteral(\"[abc]?\")\n((call_expression\n\t(navigation_expression\n\t\t((simple_identifier) @_class\n\t\t(#eq? @_class \"Regex\"))\n\t\t(navigation_suffix\n\t\t\t((simple_identifier) @_function\n\t\t\t(#eq? @_function \"fromLiteral\"))))\n\t(call_suffix\n\t\t(value_arguments\n\t\t\t(value_argument\n\t\t\t\t(string_literal\n\t\t\t\t\t(string_content) @injection.content)))))\n\t(#set! injection.language \"regex\"))\n"
  },
  {
    "path": "runtime/queries/kotlin/locals.scm",
    "content": "; Scopes\n[\n  (class_declaration)\n  (function_declaration)\n  (lambda_literal)\n] @local.scope\n\n; Definitions\n(type_parameter\n  (type_identifier) @local.definition.type.parameter)\n\n(parameter\n  (simple_identifier) @local.definition.variable.parameter)\n\n(lambda_literal\n  (lambda_parameters\n    (variable_declaration\n      (simple_identifier) @local.definition.variable.parameter)))\n\n; References\n(simple_identifier) @local.reference\n(type_identifier) @local.reference\n(interpolated_identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/kotlin/tags.scm",
    "content": "(class_declaration\n  (type_identifier) @definition.class)\n\n(object_declaration\n  \"object\" (type_identifier) @definition.class)\n\n(function_declaration\n  (simple_identifier) @definition.function)\n\n(property_declaration\n  (variable_declaration\n    (simple_identifier) @definition.constant))\n"
  },
  {
    "path": "runtime/queries/kotlin/textobjects.scm",
    "content": "(function_declaration\n  (function_body)? @function.inside) @function.around\n\n; Unlike function_body above, the constructor body is does not have its own\n; symbol in the current grammar.\n(secondary_constructor) @function.around\n\n(class_declaration\n  (class_body)? @class.inside) @class.around\n\n(class_declaration\n  (enum_class_body) @class.inside) @class.around\n\n[\n  (line_comment)\n  (multiline_comment)\n] @comment.inside\n\n(line_comment)+ @comment.around\n\n(multiline_comment) @comment.around\n\n(enum_entry) @entry.around\n(lambda_literal) @entry.around\n(property_declaration) @entry.around\n(object_declaration) @entry.around\n(assignment) @entry.around\n\n; TODO: This doesn't work with annotations yet, but fixing it without breaking\n; the case of multiple parameters is non-trivial.\n(function_value_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n; secondary constructor uses function_value_parameters above\n(primary_constructor\n  ((_)@parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(function_type_parameters\n  ((_)@parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(value_arguments\n  ((_)@parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(lambda_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n"
  },
  {
    "path": "runtime/queries/koto/folds.scm",
    "content": "[\n  (assign)\n  (comment)\n  (function)\n  (list)\n  (map)\n  (tuple)\n  (string)\n] @fold\n"
  },
  {
    "path": "runtime/queries/koto/highlights.scm",
    "content": "[\n  \"=\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"^\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"^=\"\n  \"==\"\n  \"!=\"\n  \"<\"\n  \">\"\n  \"<=\"\n  \">=\"\n  \"..\"\n  \"..=\"\n  \"->\"\n  (null_check)\n] @operator\n\n[\n  \"let\"\n] @keyword\n\n[\n  \"and\"\n  \"not\"\n  \"or\"\n] @keyword.operator\n\n[\n  \"return\"\n  \"yield\"\n] @keyword.control.return\n\n[\n  \"if\"\n  \"then\"\n  \"else\"\n  \"else if\"\n  \"match\"\n  \"switch\"\n] @keyword.control.conditional\n\n[\n  (break)\n  (continue)\n  \"for\"\n  \"in\"\n  \"loop\"\n  \"until\"\n  \"while\"\n] @keyword.control.repeat\n\n[\n  \"throw\"\n  \"try\"\n  \"catch\"\n  \"finally\"\n] @keyword.control.exception\n\n[\n  \"export\"\n  \"from\"\n  \"import\"\n  \"as\"\n] @keyword.control.import\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"|\"\n] @punctuation.bracket\n\n(string (interpolation [\"{\" \"}\"] @punctuation.special))\n\n[\n  \";\"\n  \":\"\n  \",\"\n] @punctuation.delimiter\n\n(identifier) @variable\n\n(import_module\n  (identifier) @namespace)\n\n(import_item\n  (identifier) @namespace)\n\n(export\n  (identifier) @namespace)\n\n(chain\n  start: (identifier) @function)\n\n(chain\n  (lookup (identifier)) @variable.other.member)\n\n(call\n  function: (identifier)) @function\n\n(call_arg\n  (identifier) @variable.other.member)\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(comment) @comment\n\n(debug) @keyword\n\n(string) @string\n\n(fill_char) @punctuation.delimiter\n\n(alignment) @operator\n\n(escape) @constant.character.escape\n\n(null) @constant.builtin\n\n(number) @constant.numeric\n\n(meta) @keyword.directive\n\n(meta\n  name: (identifier) @variable.other.member)\n\n(entry_inline\n  key: (identifier) @variable.other.member)\n\n(entry_block\n  key: (identifier) @variable.other.member)\n\n(self) @variable.builtin\n\n(type\n  _ @type)\n\n(arg\n  (_ (identifier) @variable.parameter))\n\n(ellipsis) @variable.parameter\n"
  },
  {
    "path": "runtime/queries/koto/indents.scm",
    "content": "[\n  (list)\n  (map)\n  (tuple)\n] @indent\n\n[\n  (for)\n  (else_if)\n  (else)\n  (match)\n  (switch)\n  (until)\n  (while)\n] @indent @extend\n\n(assign\n  \"=\" @indent @extend\n  !rhs\n)\n(assign\n  \"=\" @indent @extend\n  rhs: (_) @anchor\n  (#not-same-line? @indent @anchor)\n)\n\n(if\n  condition: (_) @indent @extend\n  !then\n)\n(if\n  condition: (_) @indent @extend\n  then: (_) @anchor\n  (#not-same-line? @indent @anchor)\n)\n\n(function\n  (args) @indent @extend\n  !body\n)\n(function\n  (args) @indent @extend\n  body: (_) @anchor\n  (#not-same-line? @indent @anchor)\n)\n\n(match_arm\n  \"then\" @indent @extend\n  !then\n)\n(match_arm\n  \"then\" @indent @extend\n  then: (_) @anchor\n  (#not-same-line? @indent @anchor)\n)\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/koto/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/koto/locals.scm",
    "content": "; Scopes\n(module (_) @local.scope)\n\n(function\n  body: (_) @local.scope)\n\n; Definitions\n(arg\n  (identifier) @local.definition.variable.parameter)\n\n(arg\n  (variable (identifier)) @local.definition.parameter)\n\n(import_item\n  (identifier) @local.definition.namespace)\n\n(entry_block\n  (identifier) @local.definition.variable.other.member)\n\n(entry_inline\n  (identifier) @local.definition.variable.other.member)\n\n; References\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/koto/rainbows.scm",
    "content": "[\n  (args)\n  (call_args)\n  (index)\n  (list)\n  (map)\n  (parenthesized)\n  (tuple)\n] @rainbow.scope\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/koto/textobjects.scm",
    "content": "(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(function\n  body: (_) @function.inside) @function.around\n\n(args\n  ((arg) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(call_args\n  ((call_arg) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(map\n  ((entry_inline) @entry.inside . \",\"? @entry.around) @entry.around)\n\n(map_block\n  ((entry_block) @entry.inside) @entry.around)\n\n(list\n  ((element) @entry.inside . \",\"? @entry.around) @entry.around)\n\n(tuple\n  (_) @entry.around)\n\n(assign\n  (meta (test))\n  (function body: (_) @test.inside)\n) @test.around\n\n(entry_block\n  key: (meta (test))\n  value: (function body: (_) @test.inside)\n) @test.around\n"
  },
  {
    "path": "runtime/queries/latex/folds.scm",
    "content": "[\n  (chapter)\n  (part)\n  (section)\n  (subsection)\n  (subsubsection)\n  (paragraph)\n  (subparagraph)\n\n  (environment)\n  (displayed_equation)\n] @fold\n"
  },
  {
    "path": "runtime/queries/latex/highlights.scm",
    "content": ";; General syntax\n(command_name) @function\n(caption\n  command: _ @function)\n\n(key_value_pair\n  key: (_) @variable.parameter\n  value: (_))\n\n[\n  (comment)\n  (line_comment)\n  (block_comment)\n  (comment_environment)\n] @comment\n\n[\n  (brack_group)\n  (brack_group_argc)\n] @variable.parameter\n\n[(operator) \"=\"] @operator\n\n\"\\\\item\" @punctuation.special\n\n((word) @punctuation.delimiter\n  (#eq? @punctuation.delimiter \"&\"))\n\n[\"[\" \"]\" \"{\" \"}\"] @punctuation.bracket ; \"(\" \")\" has no syntactical meaning in LaTeX\n(math_delimiter\n  left_command: _ @punctuation.delimiter\n  left_delimiter: _ @punctuation.delimiter\n  right_command: _ @punctuation.delimiter\n  right_delimiter: _ @punctuation.delimiter\n)\n\n;; General environments\n(begin\n  command: _ @function.builtin\n  name: (curly_group_text (text) @function.macro))\n\n(end\n  command: _ @function.builtin\n  name: (curly_group_text (text) @function.macro))\n\n;; Definitions and references\n(new_command_definition\n  command: _ @function.macro\n  declaration: (curly_group_command_name (_) @function))\n(old_command_definition\n  command: _ @function.macro\n  declaration: (_) @function)\n(let_command_definition\n  command: _ @function.macro\n  declaration: (_) @function)\n\n(environment_definition\n  command: _ @function.macro\n  name: (curly_group_text (_) @constant))\n\n(theorem_definition\n  command: _ @function.macro\n  name: (curly_group_text (_) @constant))\n\n(paired_delimiter_definition\n  command: _ @function.macro\n  declaration: (curly_group_command_name (_) @function))\n\n(label_definition\n  command: _ @function.macro\n  name: (curly_group_text (_) @label))\n(label_reference_range\n  command: _ @function.macro\n  from: (curly_group_text (_) @label)\n  to: (curly_group_text (_) @label))\n(label_reference\n  command: _ @function.macro\n  names: (curly_group_text_list (_) @label))\n(label_number\n  command: _ @function.macro\n  name: (curly_group_text (_) @label)\n  number: (_) @markup.link.label)\n\n(citation\n  command: _ @function.macro\n  keys: (curly_group_text_list) @string)\n\n(glossary_entry_definition\n  command: _ @function.macro\n  name: (curly_group_text (_) @string))\n(glossary_entry_reference\n  command: _ @function.macro\n  name: (curly_group_text (_) @string))\n\n(acronym_definition\n  command: _ @function.macro\n  name: (curly_group_text (_) @string))\n(acronym_reference\n  command: _ @function.macro\n  name: (curly_group_text (_) @string))\n\n(color_definition\n  command: _ @function.macro\n  name: (curly_group_text (_) @string))\n(color_reference\n  command: _ @function.macro\n  name: (curly_group_text (_) @string))\n\n;; Math\n\n(displayed_equation) @markup.raw.block\n(inline_formula) @markup.raw.inline\n\n(math_environment\n  (begin\n    command: _ @function.builtin\n    name: (curly_group_text (text) @markup.raw)))\n\n(math_environment\n  (text) @markup.raw)\n\n(math_environment\n  (end\n    command: _ @function.builtin\n    name: (curly_group_text (text) @markup.raw)))\n\n;; Sectioning\n(title_declaration\n  command: _ @namespace\n  options: (brack_group (_) @markup.heading)?\n  text: (curly_group (_) @markup.heading))\n\n(author_declaration\n  command: _ @namespace\n  authors: (curly_group_author_list\n             ((author)+ @markup.heading)))\n\n(chapter\n  command: _ @namespace\n  toc: (brack_group (_) @markup.heading)?\n  text: (curly_group (_) @markup.heading))\n\n(part\n  command: _ @namespace\n  toc: (brack_group (_) @markup.heading)?\n  text: (curly_group (_) @markup.heading))\n\n(section\n  command: _ @namespace\n  toc: (brack_group (_) @markup.heading)?\n  text: (curly_group (_) @markup.heading))\n\n(subsection\n  command: _ @namespace\n  toc: (brack_group (_) @markup.heading)?\n  text: (curly_group (_) @markup.heading))\n\n(subsubsection\n  command: _ @namespace\n  toc: (brack_group (_) @markup.heading)?\n  text: (curly_group (_) @markup.heading))\n\n(paragraph\n  command: _ @namespace\n  toc: (brack_group (_) @markup.heading)?\n  text: (curly_group (_) @markup.heading))\n\n(subparagraph\n  command: _ @namespace\n  toc: (brack_group (_) @markup.heading)?\n  text: (curly_group (_) @markup.heading))\n\n;; Beamer frames\n(generic_environment\n  (begin\n    name: (curly_group_text\n            (text) @markup.heading)\n    (#any-of? @markup.heading \"frame\"))\n  .\n  (curly_group (_) @markup.heading))\n\n((generic_command\n  command: (command_name) @_name\n  arg: (curly_group\n          (text) @markup.heading))\n  (#eq? @_name \"\\\\frametitle\"))\n\n;; Formatting\n((generic_command\n  command: (command_name) @_name\n  arg: (curly_group (_) @markup.italic))\n  (#eq? @_name \"\\\\emph\"))\n\n((generic_command\n  command: (command_name) @_name\n  arg: (curly_group (_) @markup.italic))\n  (#match? @_name \"^(\\\\\\\\textit|\\\\\\\\mathit)$\"))\n\n((generic_command\n  command: (command_name) @_name\n  arg: (curly_group (_) @markup.bold))\n  (#match? @_name \"^(\\\\\\\\textbf|\\\\\\\\mathbf)$\"))\n\n((generic_command\n  command: (command_name) @_name\n  .\n  arg: (curly_group (_) @markup.link.uri))\n  (#match? @_name \"^(\\\\\\\\url|\\\\\\\\href)$\"))\n\n;; File inclusion commands\n(class_include\n  command: _ @keyword.storage.type\n  path: (curly_group_path) @string)\n\n(package_include\n  command: _ @keyword.storage.type\n  paths: (curly_group_path_list) @string)\n\n(latex_include\n  command: _ @keyword.control.import\n  path: (curly_group_path) @string)\n(import_include\n  command: _ @keyword.control.import\n  directory: (curly_group_path) @string\n  file: (curly_group_path) @string)\n\n(bibtex_include\n  command: _ @keyword.control.import\n  path: (curly_group_path) @string)\n(biblatex_include\n  \"\\\\addbibresource\" @include\n  glob: (curly_group_glob_pattern) @string.regex)\n\n(graphics_include\n  command: _ @keyword.control.import\n  path: (curly_group_path) @string)\n(tikz_library_import\n  command: _ @keyword.control.import\n  paths: (curly_group_path_list) @string)\n"
  },
  {
    "path": "runtime/queries/latex/injections.scm",
    "content": "([\n   (comment)\n   (line_comment)\n   (block_comment)\n   (comment_environment)\n ] @injection.content (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/latex/textobjects.scm",
    "content": "[\n  (generic_command)\n] @function.around\n\n[\n  (chapter)\n  (part)\n  (section)\n  (subsection)\n  (subsubsection)\n  (paragraph)\n  (subparagraph)\n] @class.around\n"
  },
  {
    "path": "runtime/queries/ld/highlights.scm",
    "content": "; Identifiers\n\n[(NAME) (SYMBOLNAME)] @variable\n\n(section\n  .\n  (NAME) @namespace)\n\n; Operators\n\n[\n  \"=\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"<<=\"\n  \">>=\"\n  \"&=\"\n  \"|=\"\n  \"^=\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"+\"\n  \"-\"\n  \"<<\"\n  \">>\"\n  \"==\"\n  \"!=\"\n  \"<=\"\n  \">=\"\n  \"<\"\n  \">\"\n  \"&\"\n  \"^\"\n  \"|\"\n  \"&&\"\n  \"||\"\n  \"?\"\n] @operator\n\n; Keywords\n\n[\n  \"ABSOLUTE\"\n  \"ADDR\"\n  \"ALIGNOF\"\n  \"ASSERT\"\n  \"BYTE\"\n  \"CONSTANT\"\n  \"DATA_SEGMENT_ALIGN\"\n  \"DATA_SEGMENT_END\"\n  \"DATA_SEGMENT_RELRO_END\"\n  \"DEFINED\"\n  \"LOADADDR\"\n  \"LOG2CEIL\"\n  \"LONG\"\n  \"MAX\"\n  \"MIN\"\n  \"NEXT\"\n  \"QUAD\"\n  \"SHORT\"\n  \"SIZEOF\"\n  \"SQUAD\"\n  \"FILL\"\n  \"SEGMENT_START\"\n] @function.builtin\n\n[\n  \"CONSTRUCTORS\"\n  \"CREATE_OBJECT_SYMBOLS\"\n  \"LINKER_VERSION\"\n  \"SIZEOF_HEADERS\"\n] @constant.builtin\n\n[\n  \"AFTER\"\n  \"ALIGN\"\n  \"ALIGN_WITH_INPUT\"\n  \"ASCIZ\"\n  \"AS_NEEDED\"\n  \"AT\"\n  \"BEFORE\"\n  \"BIND\"\n  \"BLOCK\"\n  \"COPY\"\n  \"DSECT\"\n  \"ENTRY\"\n  \"EXCLUDE_FILE\"\n  \"EXTERN\"\n  \"extern\"\n  \"FLOAT\"\n  \"FORCE_COMMON_ALLOCATION\"\n  \"FORCE_GROUP_ALLOCATION\"\n  \"global\"\n  \"GROUP\"\n  \"HIDDEN\"\n  \"HLL\"\n  \"INCLUDE\"\n  \"INFO\"\n  \"INHIBIT_COMMON_ALLOCATION\"\n  \"INPUT\"\n  \"INPUT_SECTION_FLAGS\"\n  \"KEEP\"\n  \"l\"\n  \"LD_FEATURE\"\n  \"len\"\n  \"LENGTH\"\n  \"local\"\n  \"MAP\"\n  \"MEMORY\"\n  \"NOCROSSREFS\"\n  \"NOCROSSREFS_TO\"\n  \"NOFLOAT\"\n  \"NOLOAD\"\n  \"o\"\n  \"ONLY_IF_RO\"\n  \"ONLY_IF_RW\"\n  \"org\"\n  \"ORIGIN\"\n  \"OUTPUT\"\n  \"OUTPUT_ARCH\"\n  \"OUTPUT_FORMAT\"\n  \"OVERLAY\"\n  \"PHDRS\"\n  \"PROVIDE\"\n  \"PROVIDE_HIDDEN\"\n  \"READONLY\"\n  \"REGION_ALIAS\"\n  \"REVERSE\"\n  \"SEARCH_DIR\"\n  \"SECTIONS\"\n  \"SORT\"\n  \"SORT_BY_ALIGNMENT\"\n  \"SORT_BY_INIT_PRIORITY\"\n  \"SORT_BY_NAME\"\n  \"SORT_NONE\"\n  \"SPECIAL\"\n  \"STARTUP\"\n  \"SUBALIGN\"\n  \"SYSLIB\"\n  \"TARGET\"\n  \"TYPE\"\n  \"VERSION\"\n] @keyword\n\n; Delimiters\n\n[\n  \",\"\n  \";\"\n  \"&\"\n  \":\"\n  \">\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n; Literals\n\n(INT) @constant.numeric.integer\n\n; Comment\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/ld/indents.scm",
    "content": "[\n  (sections)\n  (memory)\n  (section)\n  (phdrs)\n  (overlay_section)\n  (version)\n  (vers_node)\n  (vers_defns)\n] @indent\n\n\"}\" @outdent @extend.prevent-once\n"
  },
  {
    "path": "runtime/queries/ld/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/ldif/highlights.scm",
    "content": "(comment) @comment\n\n(attributeType) @type.parameter\n\n((distinguishedName\n  (name\n    (name_componet\n      (attributeTypeAndValue\n        (attributeType) @comment\n        (string) @type.parameter\n          )))) @comment)\n\n\n(dn_spec) @constant\n(changerecord) @constant\n(mod_spec) @constant\n\n(change_modify) @string\n\n(value_spec) @keyword\n"
  },
  {
    "path": "runtime/queries/lean/folds.scm",
    "content": "[\n  (namespace)\n  (section)\n\n  (instance)\n  (def)\n  (theorem)\n  (example)\n\n  (product)\n  (array)\n  (list)\n\n  (string)\n] @fold\n"
  },
  {
    "path": "runtime/queries/lean/highlights.scm",
    "content": "; Variables\n(identifier) @variable\n\n; Namespaces\n\n(open\n  namespace: (identifier) @namespace)\n(namespace\n  name: (identifier) @namespace)\n(section\n  name: (identifier) @namespace)\n\n;; Identifier naming conventions\n((identifier) @type\n (#match? @type \"^[A-Z]\"))\n\n(arrow) @type\n(product) @type\n\n;; Declarations\n\n[\n  \"abbrev\"\n  \"def\"\n  \"theorem\"\n  \"constant\"\n  \"instance\"\n  \"axiom\"\n  \"example\"\n  \"inductive\"\n  \"structure\"\n  \"class\"\n\n  \"deriving\"\n\n  \"section\"\n  \"namespace\"\n] @keyword\n\n(attributes\n  (identifier) @function)\n\n(abbrev\n  name: (identifier) @type)\n(def\n  name: (identifier) @function)\n(theorem\n  name: (identifier) @function)\n(constant\n  name: (identifier) @type)\n(instance\n  name: (identifier) @function)\n(instance\n  type: (identifier) @type)\n(axiom\n  name: (identifier) @function)\n(structure\n  name: (identifier) @type)\n(structure\n  extends: (identifier) @type)\n\n(where_decl\n  type: (identifier) @type)\n\n(proj\n  name: (identifier) @field)\n\n(binders\n  type: (identifier) @type)\n\n[\"if\" \"then\" \"else\"] @keyword.control.conditional\n\n[\"for\" \"in\" \"do\"] @keyword.control.repeat\n\n(import) @include\n\n; Tokens\n\n[\n  \"!\"\n  \"$\"\n  \"%\"\n  \"&&\"\n  \"*\"\n  \"*>\"\n  \"+\"\n  \"++\"\n  \"-\"\n  \"/\"\n  \"::\"\n  \":=\"\n  \"<\"\n  \"<$>\"\n  \"<*\"\n  \"<*>\"\n  \"<=\"\n  \"<|\"\n  \"<|>\"\n  \"=\"\n  \"==\"\n  \"=>\"\n  \">\"\n  \">\"\n  \">=\"\n  \">>\"\n  \">>=\"\n  \"@\"\n  \"^\"\n  \"|>\"\n  \"|>.\"\n  \"||\"\n  \"←\"\n  \"→\"\n  \"↔\"\n  \"∘\"\n  \"∧\"\n  \"∨\"\n  \"≠\"\n  \"≤\"\n  \"≥\"\n] @operator\n\n[\n  \"@&\"\n] @operator\n\n[\n  \"attribute\"\n  \"by\"\n  \"end\"\n  \"export\"\n  \"extends\"\n  \"fun\"\n  \"let\"\n  \"have\"\n  \"match\"\n  \"open\"\n  \"return\"\n  \"universe\"\n  \"variable\"\n  \"where\"\n  \"with\"\n  \"λ\"\n  (hash_command)\n  (prelude)\n  (sorry)\n] @keyword\n\n[\n  \"prefix\"\n  \"infix\"\n  \"infixl\"\n  \"infixr\"\n  \"postfix\"\n  \"notation\"\n  \"macro_rules\"\n  \"syntax\"\n  \"elab\"\n  \"builtin_initialize\"\n] @keyword\n\n[\n  \"noncomputable\"\n  \"partial\"\n  \"private\"\n  \"protected\"\n  \"unsafe\"\n] @keyword\n\n[\n  \"apply\"\n  \"exact\"\n  \"rewrite\"\n  \"rw\"\n  \"simp\"\n  (trivial)\n] @keyword\n\n[\n  \"catch\"\n  \"finally\"\n  \"try\"\n] @exception\n\n((apply\n  name: (identifier) @exception)\n (#match? @exception \"throw\"))\n\n[\n  \"unless\"\n  \"mut\"\n] @keyword\n\n[(true) (false)] @boolean\n\n(number) @constant.numeric.integer\n(float) @constant.numeric.float\n\n(comment) @comment\n(char) @character\n(string) @string\n(interpolated_string) @string\n; (escape_sequence) @string.escape\n\n; Reset highlighting in string interpolation\n(interpolation) @none\n\n(interpolation\n  \"{\" @punctuation.special\n  \"}\" @punctuation.special)\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\" \"⟨\" \"⟩\"] @punctuation.bracket\n\n[\"|\" \",\" \".\" \":\" \";\"] @punctuation.delimiter\n\n(sorry) @error\n"
  },
  {
    "path": "runtime/queries/lean/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"markdown\"))\n"
  },
  {
    "path": "runtime/queries/lean/locals.scm",
    "content": "[\n  (module)\n  (namespace)\n  (section)\n] @local.scope\n"
  },
  {
    "path": "runtime/queries/ledger/highlights.scm",
    "content": "[\n    (comment)\n    (note)\n] @comment\n\n[\n    (date)\n    (interval)\n    (quantity)\n] @constant.numeric.integer\n\n((account) @variable.other.member)\n((commodity) @text.literal)\n\n\"include\" @keyword.local.import\n\n[\n    \"account\"\n    \"alias\"\n    \"assert\"\n    \"check\"\n    \"commodity\"\n    \"def\"\n    \"default\"\n    \"end\"\n    \"eval\"\n    \"format\"\n    \"nomarket\"\n    \"note\"\n    \"payee\"\n    \"check\"\n    \"A\"\n    \"Y\"\n    \"N\"\n    \"D\"\n    \"C\"\n    \"P\"\n] @keyword\n"
  },
  {
    "path": "runtime/queries/ledger/injections.scm",
    "content": "([(comment) (note)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/less/highlights.scm",
    "content": "; inherits: css\n\n[\n  \"@import\"\n  \"@namespace\"\n  \"@charset\"\n] @keyword\n\n(js_comment) @comment\n\n(function_name) @function\n\n[\n  \">=\"\n  \"<=\"\n] @operator\n\n(plain_value) @string\n\n(keyword_query) @function\n\n(identifier) @variable\n\n(variable) @variable\n\n(arguments\n  (variable) @variable.parameter)\n\n[\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n(import_statement\n  (identifier) @function)\n"
  },
  {
    "path": "runtime/queries/less/indents.scm",
    "content": "[\n  (block)\n] @indent\n\n[\n \"}\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/less/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/less/rainbows.scm",
    "content": "[\n  (keyframe_block_list)\n  (block)\n  (attribute_selector)\n  (feature_query)\n  (parenthesized_query)\n  (selector_query)\n  (parenthesized_value)\n  (arguments)\n] @rainbow.scope\n\n[\n  \"{\" \"}\"\n  \"(\" \")\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/llvm/highlights.scm",
    "content": "(type) @type\n(type_keyword) @type.builtin\n\n(type [\n    (local_var)\n    (global_var)\n  ] @type)\n\n(argument) @variable.parameter\n\n(_ inst_name: _ @keyword.operator)\n\n[\n  \"catch\"\n  \"filter\"\n] @keyword.operator\n\n[\n  \"to\"\n  \"nneg\"\n  \"nuw\"\n  \"nsw\"\n  \"exact\"\n  \"disjoint\"\n  \"unwind\"\n  \"from\"\n  \"cleanup\"\n  \"swifterror\"\n  \"volatile\"\n  \"inbounds\"\n  \"inrange\"\n  (icmp_cond)\n  (fcmp_cond)\n  (fast_math)\n] @keyword.control\n\n(_ callee: _ @function)\n(function_header name: _ @function)\n\n[\n  \"declare\"\n  \"define\"\n  (calling_conv)\n] @keyword.function\n\n[\n  \"target\"\n  \"triple\"\n  \"datalayout\"\n  \"source_filename\"\n  \"addrspace\"\n  \"blockaddress\"\n  \"align\"\n  \"syncscope\"\n  \"within\"\n  \"uselistorder\"\n  \"uselistorder_bb\"\n  \"module\"\n  \"asm\"\n  \"sideeffect\"\n  \"alignstack\"\n  \"inteldialect\"\n  \"unwind\"\n  \"type\"\n  \"global\"\n  \"constant\"\n  \"externally_initialized\"\n  \"alias\"\n  \"ifunc\"\n  \"section\"\n  \"comdat\"\n  \"thread_local\"\n  \"localdynamic\"\n  \"initialexec\"\n  \"localexec\"\n  \"any\"\n  \"exactmatch\"\n  \"largest\"\n  \"nodeduplicate\"\n  \"samesize\"\n  \"distinct\"\n  \"attributes\"\n  \"vscale\"\n  \"no_cfi\"\n  (linkage_aux)\n  (dso_local)\n  (visibility)\n  (dll_storage_class)\n  (unnamed_addr)\n  (attribute_name)\n] @keyword\n\n\n(function_header [\n    (linkage)\n    (calling_conv)\n    (unnamed_addr)\n  ] @keyword.function)\n\n[\n  (string)\n  (cstring)\n] @string\n\n(number) @constant.numeric.integer\n(comment) @comment\n(label) @label\n(_ inst_name: \"ret\" @keyword.control.return)\n(float) @constant.numeric.float\n\n[\n  (local_var)\n  (global_var)\n] @variable\n\n[\n  (struct_value)\n  (array_value)\n  (vector_value)\n] @constructor\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"<\"\n  \">\"\n  \"<{\"\n  \"}>\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"=\"\n  \"|\"\n  \"x\"\n  \"...\"\n] @operator\n\n[\n  \"true\"\n  \"false\"\n] @constant.builtin.boolean\n\n[\n  \"undef\"\n  \"poison\"\n  \"null\"\n  \"none\"\n  \"zeroinitializer\"\n] @constant.builtin\n"
  },
  {
    "path": "runtime/queries/llvm/indents.scm",
    "content": "[\n  (function_body)\n  (instruction)\n] @indent\n\n\"}\" @outdent\n"
  },
  {
    "path": "runtime/queries/llvm/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/llvm/locals.scm",
    "content": "; Scopes\n\n(function_body) @local.scope\n\n; Definitions\n\n(argument\n  (value (var (local_var) @local.definition.variable.parameter)))\n\n; References\n(local_var) @local.reference\n"
  },
  {
    "path": "runtime/queries/llvm/textobjects.scm",
    "content": "(define\n  body: (_) @function.inside) @function.around\n\n(struct_type\n  (struct_body) @class.inside) @class.around\n\n(packed_struct_type\n  (struct_body) @class.inside) @class.around\n\n(array_type\n  (array_vector_body) @class.inside) @class.around\n\n(vector_type\n  (array_vector_body) @class.inside) @class.around\n\n(argument) @parameter.inside\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/llvm-mir/highlights.scm",
    "content": "[\n  (label)\n  (bb_ref)\n] @label\n\n[\n  (comment)\n  (multiline_comment)\n] @comment\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"<\"\n  \">\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \":\"\n  \"|\"\n  \"*\"\n] @punctuation.delimiter\n\n[\n  \"=\"\n  \"x\"\n] @operator\n\n[\n  \"true\"\n  \"false\"\n] @constant.builtin.boolean\n\n[\n  \"null\"\n  \"_\"\n  \"unknown-address\"\n] @constant.builtin\n\n[\n  (stack_object)\n  (constant_pool_index)\n  (jump_table_index)\n  (var)\n  (physical_register)\n  (ir_block)\n  (external_symbol)\n  (global_var)\n  (ir_local_var)\n  (metadata_ref)\n  (mnemonic)\n] @variable\n\n(low_level_type) @type\n\n[\n  (immediate_type)\n  (primitive_type)\n] @type.builtin\n\n(number) @constant.numeric.integer\n(float) @constant.numeric.float\n(string) @string\n\n(instruction name: _ @keyword.operator)\n\n[\n  \"successors\"\n  \"liveins\"\n  \"pre-instr-symbol\"\n  \"post-instr-symbol\"\n  \"heap-alloc-marker\"\n  \"pcsections\"\n  \"mmra\"\n  \"cfi-type\"\n  \"debug-instr-number\"\n  \"debug-location\"\n  \"dbg-instr-ref\"\n  \"mcsymbol\"\n  \"tied-def\"\n  \"target-flags\"\n  \"vscale\"\n  \"CustomRegMask\"\n  \"same_value\"\n  \"def_cfa_register\"\n  \"restore\"\n  \"undefined\"\n  \"offset\"\n  \"rel_offset\"\n  \"def_cfa\"\n  \"llvm_def_aspace_cfa\"\n  \"register\"\n  \"escape\"\n  \"remember_state\"\n  \"restore_state\"\n  \"window_save\"\n  \"negate_ra_sign_state\"\n  \"intpred\"\n  \"floatpred\"\n  \"shufflemask\"\n  \"liveout\"\n  \"target-index\"\n  \"blockaddress\"\n  \"intrinsic\"\n  \"load\"\n  \"store\"\n  \"unknown-size\"\n  \"on\"\n  \"from\"\n  \"into\"\n  \"align\"\n  \"basealign\"\n  \"addrspace\"\n  \"call-entry\"\n  \"custom\"\n  \"constant-pool\"\n  \"stack\"\n  \"got\"\n  \"jump-table\"\n  \"syncscope\"\n  \"machine-block-address-taken\"\n  \"ir-block-address-taken\"\n  \"landing-pad\"\n  \"inlineasm-br-indirect-target\"\n  \"ehfunclet-entry\"\n  \"bb_id\"\n  \"call-frame-size\"\n  \"bbsections\"\n  \"Exception\"\n  \"Cold\"\n\n  (intpred)\n  (floatpred)\n  (memory_operand_flag)\n  (atomic_ordering)\n  (register_flag)\n  (instruction_flag)\n  (float_keyword)\n] @keyword\n"
  },
  {
    "path": "runtime/queries/llvm-mir/indents.scm",
    "content": "(basic_block) @indent\n\n(label) @outdent\n"
  },
  {
    "path": "runtime/queries/llvm-mir/injections.scm",
    "content": "([ (comment) (multiline_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/llvm-mir/textobjects.scm",
    "content": "(basic_block) @function.around\n\n(argument) @parameter.inside\n\n[\n  (comment)\n  (multiline_comment)\n] @comment.inside\n\n(comment)+ @comment.around\n\n(multiline_comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/llvm-mir-yaml/highlights.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/llvm-mir-yaml/indents.scm",
    "content": "(block_mapping_pair) @indent\n\n"
  },
  {
    "path": "runtime/queries/llvm-mir-yaml/injections.scm",
    "content": "; inherits: yaml\n\n((document (block_node (block_scalar) @injection.content))\n (#set! injection.language \"llvm\"))\n\n((document (block_node (block_mapping (block_mapping_pair\n  key: (flow_node (plain_scalar (string_scalar))) ; \"body\"\n  value: (block_node (block_scalar) @injection.content)))))\n  (#set! injection.language \"mir\"))\n"
  },
  {
    "path": "runtime/queries/log/highlights.scm",
    "content": "(trace) @comment\n(debug) @hint\n(info) @info\n(warn) @warning\n(error) @error\n(year_month_day) @keyword\n(time) @constant\n(string_literal) @string\n(number) @constant.numeric\n(constant) @constant.builtin\n"
  },
  {
    "path": "runtime/queries/lpf/highlights.scm",
    "content": "[\n  \"SYSCONFIG\"\n  \"BLOCK\"\n  \"LOCATE\"\n  \"COMP\"\n  \"FREQUENCY\"\n  \"PORT\"\n  \"IOBUF\"\n] @keyword\n\n[\"SITE\"] @keyword.storage\n\n[\"=\"] @operator\n\n((number) @constant.numeric)\n\n((string) @string)\n((line_comment) @comment)\n\n"
  },
  {
    "path": "runtime/queries/lua/folds.scm",
    "content": "[\n (do_statement)\n (while_statement)\n (repeat_statement)\n (if_statement)\n (for_statement)\n (function_declaration)\n (function_definition)\n (table_constructor)\n] @fold\n"
  },
  {
    "path": "runtime/queries/lua/highlights.scm",
    "content": ";;; Highlighting for lua\n\n;; Keywords\n\n(if_statement\n[\n  \"if\"\n  \"then\"\n  \"end\"\n] @keyword.control.conditional)\n\n(elseif_statement\n[\n  \"elseif\"\n  \"then\"\n  \"end\"\n] @keyword.control.conditional)\n\n(else_statement\n[\n  \"else\"\n  \"end\"\n] @keyword.control.conditional)\n\n(for_statement\n[\n  \"for\"\n  \"do\"\n  \"end\"\n] @keyword.control.repeat)\n\n(while_statement\n[\n  \"while\"\n  \"do\"\n  \"end\"\n] @keyword.control.repeat)\n\n(repeat_statement\n[\n  \"repeat\"\n  \"until\"\n] @keyword.control.repeat)\n\n(do_statement\n[\n  \"do\"\n  \"end\"\n] @keyword)\n\n\"return\" @keyword.control.return\n\n[\n \"in\"\n \"local\"\n \"global\"\n (break_statement)\n \"goto\"\n] @keyword\n\n(function_declaration\n[\n  \"function\"\n  \"end\"\n] @keyword.function)\n\n(function_definition\n[\n  \"function\"\n  \"end\"\n] @keyword.function)\n\n;; Operators\n\n[\n \"not\"\n \"and\"\n \"or\"\n] @keyword.operator\n\n[\n\"=\"\n\"~=\"\n\"==\"\n\"<=\"\n\">=\"\n\"<\"\n\">\"\n\"+\"\n\"-\"\n\"%\"\n\"/\"\n\"//\"\n\"*\"\n\"^\"\n\"&\"\n\"~\"\n\"|\"\n\">>\"\n\"<<\"\n\"..\"\n\"#\"\n ] @operator\n\n;; Punctuation\n[\",\" \".\" \":\" \";\"] @punctuation.delimiter\n\n;; Brackets\n\n[\n \"(\"\n \")\"\n \"[\"\n \"]\"\n \"{\"\n \"}\"\n] @punctuation.bracket\n\n;; Variables\n(identifier) @variable\n\n((identifier) @variable.builtin\n (#eq? @variable.builtin \"self\"))\n\n(variable_list\n  (attribute\n    \"<\" @punctuation.bracket\n    (identifier) @attribute\n    \">\" @punctuation.bracket))\n\n; ;; Constants\n[\n(false)\n(true)\n] @constant.builtin.boolean\n(nil) @constant.builtin\n(vararg_expression) @constant\n\n((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z_0-9]*$\"))\n\n;; Tables\n\n(field name: (identifier) @variable.other.member)\n\n(dot_index_expression field: (identifier) @variable.other.member)\n\n(table_constructor\n[\n  \"{\"\n  \"}\"\n] @constructor)\n\n;; Functions\n\n(parameters (identifier) @variable.parameter)\n\n(function_call\n  (identifier) @function.builtin\n  (#any-of? @function.builtin\n    ;; built-in functions in Lua 5.1\n    \"assert\" \"collectgarbage\" \"dofile\" \"error\" \"getfenv\" \"getmetatable\" \"ipairs\"\n    \"load\" \"loadfile\" \"loadstring\" \"module\" \"next\" \"pairs\" \"pcall\" \"print\"\n    \"rawequal\" \"rawget\" \"rawset\" \"require\" \"select\" \"setfenv\" \"setmetatable\"\n    \"tonumber\" \"tostring\" \"type\" \"unpack\" \"xpcall\"))\n\n(function_declaration\n  name: [\n    (identifier) @function\n    (dot_index_expression\n      field: (identifier) @function)\n  ])\n\n(function_declaration\n  name: (method_index_expression\n    method: (identifier) @function.method))\n\n(assignment_statement\n  (variable_list .\n    name: [\n      (identifier) @function\n      (dot_index_expression\n        field: (identifier) @function)\n    ])\n  (expression_list .\n    value: (function_definition)))\n\n(table_constructor\n  (field\n    name: (identifier) @function\n    value: (function_definition)))\n\n;; Property\n(dot_index_expression field: (identifier) @variable.other.member)\n\n(function_call\n  name: [\n    (identifier) @function.call\n    (dot_index_expression\n      field: (identifier) @function.call)\n    (method_index_expression\n      method: (identifier) @function.method.call)\n  ])\n\n; TODO: incorrectly highlights variable N in `N, nop = 42, function() end`\n(assignment_statement\n    (variable_list\n      name: (identifier) @function)\n    (expression_list\n      value: (function_definition)))\n\n(method_index_expression method: (identifier) @function.method)\n\n;; Nodes\n(comment) @comment\n(string) @string\n(escape_sequence) @constant.character.escape\n(number) @constant.numeric.integer\n(label_statement) @label\n; A bit of a tricky one, this will only match field names\n(field . (identifier) @variable.other.member (_))\n(hash_bang_line) @comment\n"
  },
  {
    "path": "runtime/queries/lua/indents.scm",
    "content": "[\n  (function_definition)\n  (function_declaration)\n  (method_index_expression)\n  (field)\n  (if_statement)\n  (for_statement)\n  (repeat_statement)\n  (while_statement)\n  (table_constructor)\n  (arguments)\n  (do_statement)\n] @indent\n\n[\n  \"end\"\n  \"until\"\n  \"}\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/lua/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\")\n (#set! injection.include-children))\n\n; string.match(\"123\", \"%d+\")\n(function_call\n  (dot_index_expression\n    field: (identifier) @_method\n    (#any-of? @_method \"find\" \"match\" \"gmatch\" \"gsub\"))\n  arguments: (arguments\n    .\n    (_)\n    .\n    (string\n      content: (string_content) @injection.content\n      (#set! injection.language \"luap\")\n      (#set! injection.include-children))))\n\n; (\"123\"):match(\"%d+\")\n(function_call\n  (method_index_expression\n    method: (identifier) @_method\n    (#any-of? @_method \"find\" \"match\" \"gmatch\" \"gsub\"))\n  arguments: (arguments\n    .\n    (string\n      content: (string_content) @injection.content\n      (#set! injection.language \"luap\")\n      (#set! injection.include-children))))\n\n; string.format(\"format string\", ...)\n((function_call\n  name: (dot_index_expression\n    table: (identifier) @_table\n    field: (identifier) @_function)\n  arguments: (arguments\n    .\n    (string\n      content: (string_content) @injection.content)))\n  (#eq? @_table \"string\")\n  (#eq? @_function \"format\")\n  (#set! injection.language \"lua-format-string\"))\n\n; (\"format\"):format(...)\n((function_call\n  name: (method_index_expression\n    table: (parenthesized_expression\n      (string\n        content: (string_content) @injection.content))\n    method: (identifier) @_function))\n  (#eq? @_function \"format\")\n  (#set! injection.language \"lua-format-string\"))\n"
  },
  {
    "path": "runtime/queries/lua/rainbows.scm",
    "content": "[\n  (table_constructor)\n  (bracket_index_expression)\n  (parameters)\n  (arguments)\n  (field)\n] @rainbow.scope\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/lua/textobjects.scm",
    "content": "(function_definition\n  body: (_) @function.inside) @function.around\n\n(function_declaration\n  body: (_) @function.inside) @function.around\n\n(parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(table_constructor\n  (field (_) @entry.inside) @entry.around)\n"
  },
  {
    "path": "runtime/queries/lua-format-string/highlights.scm",
    "content": "(escaped_percent_sign) @constant.character.escape\n\n(flag) @constant.builtin\n\n(text) @string\n\n(width) @constant.numeric.integer\n(precision) @constant.numeric.float\n\n(conversion_specifier) @type\n\n\".\" @punctuation.delimiter\n\"%\" @punctuation.special\n"
  },
  {
    "path": "runtime/queries/luap/highlights.scm",
    "content": "[\n  (anchor_begin)\n  (anchor_end)\n] @punctuation.delimiter\n\n(pattern\n  (character\n    \".\" @variable.builtin))\n\n[\n  \"[\"\n  \"]\"\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n[\n  (zero_or_more)\n  (shortest_zero_or_more)\n  (one_or_more)\n  (zero_or_one)\n] @operator\n\n(range\n  from: (character) @constant\n  \"-\" @operator\n  to: (character) @constant)\n\n(set\n  (character) @constant)\n\n(negated_set\n  (character) @constant)\n\n(class) @constant.character.escape\n\n(class\n  \"%\" @string.regexp\n  (escape_char) @string.regexp)\n\n(negated_set\n  \"^\" @operator)\n\n(balanced_match\n  (character) @variable.parameter)\n"
  },
  {
    "path": "runtime/queries/luau/highlights.scm",
    "content": "\"return\" @keyword.control.return\n\n\"local\" @keyword.storage.modifier\n\n\"type\" @keyword.storage.type\n\n\"function\" @keyword.function\n\n(break_stmt) @keyword.control\n(continue_stmt) @keyword.control\n(readwrite) @keyword.storage.modifier\n\n[\n  \"do\"\n  \"end\"\n] @keyword\n\n[\n  \"while\"\n  \"repeat\"\n  \"until\"\n  \"for\"\n] @keyword.control.repeat\n\n[\n  \"if\"\n  \"elseif\"\n  \"else\"\n  \"then\"\n] @keyword.control.conditional\n\n[\n  \"in\"\n  \"and\"\n  \"or\"\n  \"not\"\n] @keyword.operator\n\n(ifexp\n[\n  \"if\"\n  \"then\"\n  \"elseif\"\n  \"else\"\n] @keyword.operator)\n\n(type_stmt \"export\" @keyword.control.import) \n\n(_\n  operator: [\n    \"+\" \"-\" \"*\"  \"/\"  \"//\" \"%\"\n    \"^\" \"#\" \"==\" \"~=\" \"<=\" \">=\"\n    \"<\" \">\" \"&\"  \"|\"  \"->\" \"::\"\n    \"..\"\n  ] @operator\n)\n\n(_\n  assign_symbol: [\n    \"=\"  \"+=\" \"-=\" \"*=\" \"/=\" \"//=\"\n    \"%=\" \"^=\" \"..=\"\n  ] @operator\n)\n\n[\n  \";\"\n  \":\"\n  \",\"\n  \".\"\n] @punctuation.delimiter\n\n(string) @string\n\n(_\n  variable_name: (name) @variable\n)\n\n(_\n  parameter_name: (name) @variable.parameter\n)\n\n(_\n  method_name: (name) @function.method\n)\n\n(_\n  function_name: (name) @function\n)\n\n(_\n  table_name: (name) @namespace\n)\n\n(_\n  field_name: (name) @variable.other.member\n)\n\n(table\n[\n  \"{\"\n  \"}\"\n] @constructor)\n\n; special comment directives\n(chunk\n  .\n  (comment)*\n  .\n  (comment) @keyword.directive\n  (#match? @keyword.directive \"^--!(strict|native)[\\r]?$\")\n)\n\n(comment) @comment\n\n(number) @constant.numeric\n\n(unicode_escape\n  \"{\" @punctuation.special\n  \"codepoint\" @constant.numeric.integer\n  \"}\" @punctuation.special\n)\n(unicode_escape) @constant.character.escape\n(dec_byte_escape) @constant.character.escape\n(hex_byte_escape) @constant.character.escape\n(simple_escape) @constant.character.escape\n\n(interp_start) @punctuation.special\n(interp_content) @string\n(interp_brace_open) @punctuation.special\n(interp_brace_close) @punctuation.special\n(interp_end) @punctuation.special\n\n[\n \"(\"\n \")\"\n \"[\"\n \"]\"\n \"{\"\n \"}\"\n \"<\"\n \">\"\n] @punctuation.bracket\n\n(_\n  type_name: (name) @type\n)\n\n(type_stmt\n  left: (name) @type\n)\n\n(_\n  attribute_name: (name) @attribute\n)\n\n(exp\n  (vararg) @constant\n)\n\n(nil) @constant.builtin\n\n(boolean) @constant.builtin.boolean\n\n(_\n  generic_type_name: (name) @type.parameter\n)\n\n(_\n  generic_typepack_name: (name) @type.parameter\n)\n\n(dyntype\n  \"typeof\" @keyword.directive\n)\n\n(_\n  module_namespace: (name) @namespace\n)\n\n; if the value of the field is a function, then\n; color the name of a field assignment as a method\n(field\n  field_name: (name) @function.method\n  value: (anon_fn)\n)\n\n; if a call statement is an invocation on a variable,\n; color the last name in a name sequence as a function\n(call_stmt\n  invoked: (var\n    variable_name: (name) @function\n  )\n)\n\n(call_stmt\n  invoked: (var\n    table_name: (name) @namespace\n    (key\n      field_name: (name) @function\n    )\n    .\n  )\n)\n\n(call_stmt\n  invoked: (_\n    (key\n      field_name: (name) @function\n    )\n    .\n  )\n)\n\n(fn_stmt\n  (key\n    field_name: (name) @function.method\n  )\n  .\n  (paramlist)?\n)\n\n(_\n  type_name: (name) @type.builtin\n  (#any-of? @type.builtin\n    \"number\" \"string\" \"any\"\n    \"never\"                             \"unknown\"                          \"boolean\"\n    \"thread\"                            \"userdata\"                         \"Accessory\"\n    \"Accoutrement\"                      \"Actor\"                            \"AdGui\"\n    \"AdPortal\"                          \"AdService\"                        \"AdvancedDragger\"\n    \"AirController\"                     \"AlignOrientation\"                 \"AlignPosition\"\n    \"AnalysticsSettings\"                \"AnalyticsService\"                 \"AngularVelocity\"\n    \"Animation\"                         \"AnimationClip\"                    \"AnimationClipProvider\"\n    \"AnimationController\"               \"AnimationFromVideoCreatorService\" \"AnimationFromVideoCreatorStudioService\"\n    \"AnimationRigData\"                  \"AnimationStreamTrack\"             \"AnimationTrack\"\n    \"Animator\"                          \"AppStorageService\"                \"AppUpdateService\"\n    \"ArcHandles\"                        \"AssetCounterService\"              \"AssetDeliveryProxy\"\n    \"AssetImportService\"                \"AssetImportSession\"               \"AssetManagerService\"\n    \"AssetService\"                      \"AssetSoundEffect\"                 \"Atmosphere\"\n    \"Attachment\"                        \"AvatarEditorService\"              \"AvatarImportService\"\n    \"Axes\"                              \"Backpack\"                         \"BackpackItem\"\n    \"BadgeService\"                      \"BallSocketConstraint\"             \"BasePart\"\n    \"BasePlayerGui\"                     \"BaseScript\"                       \"BaseWrap\"\n    \"Beam\"                              \"BillboardGui\"                     \"BinaryStringValue\"\n    \"BindableEvent\"                     \"BindableFunction\"                 \"BloomEffect\"\n    \"BlurEffect\"                        \"BodyAngularVelocity\"              \"BodyColors\"\n    \"BodyForce\"                         \"BodyGyro\"                         \"BodyMover\"\n    \"BodyPosition\"                      \"BodyThrust\"                       \"BodyVelocity\"\n    \"Bone\"                              \"BoolValue\"                        \"BoxHandleAdornment\"\n    \"Breakpoint\"                        \"BrickColor\"                       \"BrickColorValue\"\n    \"BrowserService\"                    \"BubbleChatConfiguration\"          \"BulkImportService\"\n    \"CFrame\"                            \"CFrameValue\"                      \"CSGDictionaryService\"\n    \"CacheableContentProvider\"          \"CalloutService\"                   \"Camera\"\n    \"CanvasGroup\"                       \"CatalogPages\"                     \"CatalogSearchParams\"\n    \"ChangeHistoryService\"              \"ChannelSelectorSoundEffect\"       \"CharacterAppearance\"\n    \"CharacterMesh\"                     \"Chat\"                             \"ChatInputBarConfiguration\"\n    \"ChatWindowConfiguration\"           \"ChorusSoundEffect\"                \"ClickDetector\"\n    \"ClientReplicator\"                  \"ClimbController\"                  \"Clothing\"\n    \"CloudLocalizationTable\"            \"Clouds\"                           \"ClusterPacketCache\"\n    \"CollectionService\"                 \"Color3\"                           \"ColorCorrectionEffect\"\n    \"ColorSequence\"                     \"ColorSequenceKeypoint\"            \"CommandInstance\"\n    \"CommandService\"                    \"CompressorSoundEffect\"            \"ConeHandleAdornment\"\n    \"Configuration\"                     \"ConfigureServerService\"           \"Constraint\"\n    \"Content\"                           \"ContentProvider\"                  \"ContextActionService\"\n    \"Controller\"                        \"ControllerBase\"                   \"ControllerManager\"\n    \"ControllerService\"                 \"CookiesService\"                   \"CoreGui\"\n    \"CorePackages\"                      \"CoreScript\"                       \"CoreScriptSyncService\"\n    \"CornerWedgePart\"                   \"CrossDMScriptChangeListener\"      \"CurveAnimation\"\n    \"CustomSoundEffect\"                 \"CylinderHandleAdornment\"          \"CylindricalConstraint\"\n    \"DataModel\"                         \"DataModelMesh\"                    \"DataModelPatchService\"\n    \"DataModelSession\"                  \"DataStore\"                        \"DataStoreIncrementOptions\"\n    \"DataStoreInfo\"                     \"DataStoreKey\"                     \"DataStoreKeyInfo\"\n    \"DataStoreKeyPages\"                 \"DataStoreListingPages\"            \"DataStoreObjectVersionInfo\"\n    \"DataStoreOptions\"                  \"DataStorePages\"                   \"DataStoreService\"\n    \"DataStoreSetOptions\"               \"DataStoreVersionPages\"            \"DateTime\"\n    \"Debris\"                            \"DebugSettings\"                    \"DebuggablePluginWatcher\"\n    \"DebuggerBreakpoint\"                \"DebuggerConnection\"               \"DebuggerConnectionManager\"\n    \"DebuggerLuaResponse\"               \"DebuggerManager\"                  \"DebuggerUIService\"\n    \"DebuggerVariable\"                  \"DebuggerWatch\"                    \"Decal\"\n    \"DepthOfFieldEffect\"                \"DeviceIdService\"                  \"Dialog\"\n    \"DialogChoice\"                      \"DistortionSoundEffect\"            \"DockWidgetPluginGui\"\n    \"DockWidgetPluginGuiInfo\"           \"DraftsService\"                    \"Dragger\"\n    \"DraggerService\"                    \"DynamicRotate\"                    \"EchoSoundEffect\"\n    \"EditableImage\"                     \"EditableMesh\"                     \"EmotesPages\"\n    \"Enum\"                              \"EnumItem\"                         \"Enums\"\n    \"EqualizerSoundEffect\"              \"EulerRotationCurve\"               \"EventIngestService\"\n    \"ExperienceInviteOptions\"           \"Explosion\"                        \"FaceAnimatorService\"\n    \"FaceControls\"                      \"FaceInstance\"                     \"Faces\"\n    \"FacialAnimationRecordingService\"   \"FacialAnimationStreamingService\"  \"Feature\"\n    \"File\"                              \"FileMesh\"                         \"Fire\"\n    \"FlagStandService\"                  \"FlangeSoundEffect\"                \"FloatCurve\"\n    \"FlyweightService\"                  \"Folder\"                           \"Font\"\n    \"ForceField\"                        \"FormFactorPart\"                   \"Frame\"\n    \"FriendPages\"                       \"FriendService\"                    \"GamePassService\"\n    \"GameSettings\"                      \"GamepadService\"                   \"GenericSettings\"\n    \"Geometry\"                          \"GetTextBoundsParams\"              \"GlobalDataStore\"\n    \"GlobalSettings\"                    \"GoogleAnalyticsConfiguration\"     \"GroundController\"\n    \"GroupService\"                      \"GuiBase\"                          \"GuiButton\"\n    \"GuiLabel\"                          \"GuiObject\"                        \"GuiService\"\n    \"GuidRegistryService\"               \"HSRDataContentProvider\"           \"HandleAdornment\"\n    \"Handles\"                           \"HandlesBase\"                      \"HapticService\"\n    \"HeightmapImporterService\"          \"HiddenSurfaceRemovalAsset\"        \"Highlight\"\n    \"HingeConstraint\"                   \"HttpRbxApiService\"                \"HttpRequest\"\n    \"HttpService\"                       \"Humanoid\"                         \"HumanoidController\"\n    \"HumanoidDescription\"               \"IKControl\"                        \"ILegacyStudioBridge\"\n    \"IXPService\"                        \"ImageButton\"                      \"ImageHandleAdornment\"\n    \"ImageLabel\"                        \"ImporterAnimationSettings\"        \"ImporterBaseSettings\"\n    \"ImporterFacsSettings\"              \"ImporterGroupSettings\"            \"ImporterJointSettings\"\n    \"ImporterMaterialSettings\"          \"ImporterMeshSettings\"             \"ImporterRootSettings\"\n    \"IncrementalPatchBuilder\"           \"InputObject\"                      \"InsertService\"\n    \"Instance\"                          \"InstanceAdornment\"                \"IntValue\"\n    \"InventoryPages\"                    \"JointInstance\"                    \"KeyboardService\"\n    \"Keyframe\"                          \"KeyframeMarker\"                   \"KeyframeSequence\"\n    \"KeyframeSequenceProvider\"          \"LSPFileSyncService\"               \"LanguageService\"\n    \"LayerCollector\"                    \"LegacyStudioBridge\"               \"Light\"\n    \"Lighting\"                          \"LineForce\"                        \"LineHandleAdornment\"\n    \"LinearVelocity\"                    \"LocalDebuggerConnection\"          \"LocalScript\"\n    \"LocalStorageService\"               \"LocalizationService\"              \"LocalizationTable\"\n    \"LodDataEntity\"                     \"LodDataService\"                   \"LogService\"\n    \"LoginService\"                      \"LuaSettings\"                      \"LuaSourceContainer\"\n    \"LuaWebService\"                     \"LuauScriptAnalyzerService\"        \"MarkerCurve\"\n    \"MarketplaceService\"                \"MaterialService\"                  \"MaterialVariant\"\n    \"MemStorageConnection\"              \"MemStorageService\"                \"MemoryStoreQueue\"\n    \"MemoryStoreService\"                \"MemoryStoreSortedMap\"             \"MeshContentProvider\"\n    \"MeshPart\"                          \"MessageBusConnection\"             \"MessageBusService\"\n    \"MessagingService\"                  \"MetaBreakpoint\"                   \"MetaBreakpointContext\"\n    \"MetaBreakpointManager\"             \"Model\"                            \"ModuleScript\"\n    \"Motor\"                             \"Mouse\"                            \"MouseService\"\n    \"MultipleDocumentInterfaceInstance\" \"NegateOperation\"                  \"NetworkClient\"\n    \"NetworkMarker\"                     \"NetworkPeer\"                      \"NetworkReplicator\"\n    \"NetworkServer\"                     \"NetworkSettings\"                  \"NoCollisionConstraint\"\n    \"NonReplicatedCSGDictionaryService\" \"NotificationService\"              \"NumberPose\"\n    \"NumberRange\"                       \"NumberSequence\"                   \"NumberSequenceKeypoint\"\n    \"NumberValue\"                       \"Object\"                           \"ObjectValue\"\n    \"OrderedDataStore\"                  \"OutfitPages\"                      \"OverlapParams\"\n    \"PVAdornment\"                       \"PVInstance\"                       \"PackageLink\"\n    \"PackageService\"                    \"PackageUIService\"                 \"Pages\"\n    \"Pants\"                             \"ParabolaAdornment\"                \"Part\"\n    \"PartAdornment\"                     \"PartOperation\"                    \"PartOperationAsset\"\n    \"ParticleEmitter\"                   \"PatchMapping\"                     \"Path\"\n    \"PathWaypoint\"                      \"PathfindingLink\"                  \"PathfindingModifier\"\n    \"PathfindingService\"                \"PausedState\"                      \"PausedStateBreakpoint\"\n    \"PausedStateException\"              \"PermissionsService\"               \"PhysicalProperties\"\n    \"PhysicsService\"                    \"PhysicsSettings\"                  \"PitchShiftSoundEffect\"\n    \"PlaneConstraint\"                   \"Platform\"                         \"Player\"\n    \"PlayerEmulatorService\"             \"PlayerGui\"                        \"PlayerMouse\"\n    \"PlayerScripts\"                     \"Players\"                          \"Plugin\"\n    \"PluginAction\"                      \"PluginDebugService\"               \"PluginDragEvent\"\n    \"PluginGui\"                         \"PluginGuiService\"                 \"PluginManagementService\"\n    \"PluginManager\"                     \"PluginManagerInterface\"           \"PluginMenu\"\n    \"PluginMouse\"                       \"PluginPolicyService\"              \"PluginToolbar\"\n    \"PluginToolbarButton\"               \"PointLight\"                       \"PolicyService\"\n    \"Pose\"                              \"PoseBase\"                         \"PostEffect\"\n    \"PrismaticConstraint\"               \"ProcessInstancePhysicsService\"    \"ProximityPrompt\"\n    \"ProximityPromptService\"            \"PublishService\"                   \"QWidgetPluginGui\"\n    \"RBXScriptConnection\"               \"Random\"                           \"Ray\"\n    \"RayValue\"                          \"RaycastParams\"                    \"RaycastResult\"\n    \"RbxAnalyticsService\"               \"Rect\"                             \"ReflectionMetadata\"\n    \"ReflectionMetadataCallbacks\"       \"ReflectionMetadataClass\"          \"ReflectionMetadataClasses\"\n    \"ReflectionMetadataEnum\"            \"ReflectionMetadataEnumItem\"       \"ReflectionMetadataEnums\"\n    \"ReflectionMetadataEvents\"          \"ReflectionMetadataFunctions\"      \"ReflectionMetadataItem\"\n    \"ReflectionMetadataMember\"          \"ReflectionMetadataProperties\"     \"ReflectionMetadataYieldFunctions\"\n    \"Region3\"                           \"Region3int16\"                     \"RemoteDebuggerServer\"\n    \"RemoteEvent\"                       \"RemoteFunction\"                   \"RenderSettings\"\n    \"RenderingTest\"                     \"ReplicatedFirst\"                  \"ReplicatedStorage\"\n    \"ReverbSoundEffect\"                 \"RigidConstraint\"                  \"RobloxPluginGuiService\"\n    \"RobloxReplicatedStorage\"           \"RodConstraint\"                    \"RopeConstraint\"\n    \"RotationCurve\"                     \"RtMessagingService\"               \"RunService\"\n    \"RunningAverageItemDouble\"          \"RunningAverageItemInt\"            \"RunningAverageTimeIntervalItem\"\n    \"RuntimeScriptService\"              \"ScreenGui\"                        \"ScreenshotHud\"\n    \"Script\"                            \"ScriptChangeService\"              \"ScriptCloneWatcher\"\n    \"ScriptCloneWatcherHelper\"          \"ScriptContext\"                    \"ScriptDebugger\"\n    \"ScriptDocument\"                    \"ScriptEditorService\"              \"ScriptRegistrationService\"\n    \"ScriptService\"                     \"ScrollingFrame\"                   \"Seat\"\n    \"Selection\"                         \"SelectionBox\"                     \"SelectionLasso\"\n    \"SelectionSphere\"                   \"ServerReplicator\"                 \"ServerScriptService\"\n    \"ServerStorage\"                     \"ServiceProvider\"                  \"SessionService\"\n    \"Shirt\"                             \"ShirtGraphic\"                     \"SkateboardController\"\n    \"Sky\"                               \"SlidingBallConstraint\"            \"Smoke\"\n    \"SnippetService\"                    \"SocialService\"                    \"SolidModelContentProvider\"\n    \"Sound\"                             \"SoundEffect\"                      \"SoundGroup\"\n    \"SoundService\"                      \"Sparkles\"                         \"SpawnLocation\"\n    \"SpawnerService\"                    \"SpecialMesh\"                      \"SphereHandleAdornment\"\n    \"SpotLight\"                         \"SpringConstraint\"                 \"StackFrame\"\n    \"StandalonePluginScripts\"           \"StandardPages\"                    \"StarterCharacterScripts\"\n    \"StarterGear\"                       \"StarterGui\"                       \"StarterPack\"\n    \"StarterPlayer\"                     \"StarterPlayerScripts\"             \"Stats\"\n    \"StatsItem\"                         \"StopWatchReporter\"                \"StringValue\"\n    \"Studio\"                            \"StudioAssetService\"               \"StudioData\"\n    \"StudioDeviceEmulatorService\"       \"StudioHighDpiService\"             \"StudioPublishService\"\n    \"StudioScriptDebugEventListener\"    \"StudioService\"                    \"StudioTheme\"\n    \"SunRaysEffect\"                     \"SurfaceAppearance\"                \"SurfaceGui\"\n    \"SurfaceGuiBase\"                    \"SurfaceLight\"                     \"SurfaceSelection\"\n    \"SwimController\"                    \"TaskScheduler\"                    \"Team\"\n    \"TeamCreateService\"                 \"Teams\"                            \"TeleportAsyncResult\"\n    \"TeleportOptions\"                   \"TeleportService\"                  \"TemporaryCageMeshProvider\"\n    \"TemporaryScriptService\"            \"Terrain\"                          \"TerrainDetail\"\n    \"TerrainRegion\"                     \"TestService\"                      \"TextBox\"\n    \"TextBoxService\"                    \"TextButton\"                       \"TextChannel\"\n    \"TextChatCommand\"                   \"TextChatConfigurations\"           \"TextChatMessage\"\n    \"TextChatMessageProperties\"         \"TextChatService\"                  \"TextFilterResult\"\n    \"TextLabel\"                         \"TextService\"                      \"TextSource\"\n    \"Texture\"                           \"ThirdPartyUserService\"            \"ThreadState\"\n    \"TimerService\"                      \"ToastNotificationService\"         \"Tool\"\n    \"Torque\"                            \"TorsionSpringConstraint\"          \"TotalCountTimeIntervalItem\"\n    \"TouchInputService\"                 \"TouchTransmitter\"                 \"TracerService\"\n    \"TrackerLodController\"              \"TrackerStreamAnimation\"           \"Trail\"\n    \"Translator\"                        \"TremoloSoundEffect\"               \"TriangleMeshPart\"\n    \"TrussPart\"                         \"Tween\"                            \"TweenBase\"\n    \"TweenInfo\"                         \"TweenService\"                     \"UDim\"\n    \"UGCValidationService\"              \"UIAspectRatioConstraint\"          \"UIBase\"\n    \"UIComponent\"                       \"UIConstraint\"                     \"UICorner\"\n    \"UIGradient\"                        \"UIGridLayout\"                     \"UIGridStyleLayout\"\n    \"UILayout\"                          \"UIListLayout\"                     \"UIPadding\"\n    \"UIPageLayout\"                      \"UIScale\"                          \"UISizeConstraint\"\n    \"UIStroke\"                          \"UITableLayout\"                    \"UITextSizeConstraint\"\n    \"UnionOperation\"                    \"UniversalConstraint\"              \"UnreliableRemoteEvent\"\n    \"UnvalidatedAssetService\"           \"UserGameSettings\"                 \"UserInputService\"\n    \"UserService\"                       \"UserSettings\"                     \"UserStorageService\"\n    \"VRService\"                         \"ValueBase\"                        \"Vector2\"\n    \"Vector2int16\"                      \"Vector3\"                          \"Vector3int16\"\n    \"VectorForce\"                       \"VehicleController\"                \"VehicleSeat\"\n    \"VelocityMotor\"                     \"VersionControlService\"            \"VideoCaptureService\"\n    \"VideoFrame\"                        \"ViewportFrame\"                    \"VirtualInputManager\"\n    \"VirtualUser\"                       \"VisibilityService\"                \"Visit\"\n    \"VoiceChannel\"                      \"VoiceChatInternal\"                \"VoiceChatService\"\n    \"WedgePart\"                         \"Weld\"                             \"WeldConstraint\"\n    \"WireframeHandleAdornment\"          \"Workspace\"                        \"WorldModel\"\n    \"WorldRoot\"                         \"WrapLayer\"                        \"WrapTarget\"\n  )\n)\n\n(var\n  variable_name: (name) @function.builtin\n  (#any-of? @function.builtin\n    \"assert\"        \"collectgarbage\" \"elapsedTime\"\n    \"error\"         \"gcinfo\"         \"getfenv\"\n    \"getmetatable\"  \"ipairs\"         \"loadstring\"\n    \"next\"          \"newproxy\"       \"pairs\"\n    \"pcall\"         \"PluginManager\"  \"print\"\n    \"printidentity\" \"rawequal\"       \"rawget\"\n    \"rawlen\"        \"rawset\"         \"require\"\n    \"select\"        \"setfenv\"        \"setmetatable\"\n    \"spawn\"         \"tick\"           \"time\"\n    \"tonumber\"      \"tostring\"       \"type\"\n    \"typeof\"        \"unpack\"         \"UserSettings\"\n    \"version\"       \"warn\"           \"workspace\"\n    \"xpcall\")\n)\n\n(var\n  .\n  (name) @variable.builtin\n  (#any-of? @variable.builtin\n    \"_G\"        \"_VERSION\" \"bit32\"\n    \"coroutine\" \"debug\"    \"game\"\n    \"math\"      \"os\"       \"plugin\"\n    \"script\"    \"string\"   \"table\"\n    \"task\"      \"utf8\"     \"workspace\"\n  )\n)\n\n(_ \n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"bit32\")\n  .\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin \n      \"arshift\" \"lrotate\" \"lshift\" \"replace\" \n      \"rrotate\" \"rshift\" \"btest\" \"bxor\" \n      \"band\" \"bnot\" \"bor\" \"countlz\" \n      \"countrz\" \"extract\" \"byteswap\"\n    )\n  )?\n)\n\n(_ table_name:\n  (name) @variable.builtin\n  (#eq? @variable.builtin \"coroutine\")\n  .\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin\n      \"close\"  \"create\"  \"isyieldable\"\n      \"resume\" \"running\" \"status\"\n      \"wrap\"   \"yield\"\n    )\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"debug\")\n  .\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin\n      \"info\"       \"traceback\"           \"profilebegin\"\n      \"profileend\" \"resetmemorycategory\" \"setmemorycategory\"\n      \"dumpcodesize\"\n    )\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"math\")\n  .\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin\n      \"abs\"        \"acos\"  \"asin\"\n      \"atan\"       \"atan2\" \"ceil\"\n      \"clamp\"      \"cos\"   \"cosh\"\n      \"deg\"        \"exp\"   \"floor\"\n      \"fmod\"       \"frexp\" \"ldexp\"\n      \"log\"        \"log10\" \"max\"\n      \"min\"        \"modf\"  \"noise\"\n      \"pow\"        \"rad\"   \"random\"\n      \"randomseed\" \"round\" \"sign\"\n      \"sin\"        \"sinh\"  \"sqrt\"\n      \"tan\"        \"tanh\"\n    )\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"math\")\n  .\n  (key\n    field_name: (name) @constant.builtin\n    ; (#match? @constant.builtin \"^(huge|pi)$\")\n    (#any-of? @constant.builtin \"huge\" \"pi\")\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"os\")\n  .\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin\n      \"clock\" \"date\" \"difftime\"\n      \"time\")\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"string\")\n  .\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin\n      \"byte\"    \"char\"     \"find\"\n      \"format\"  \"gmatch\"   \"gsub\"\n      \"len\"     \"lower\"    \"match\"\n      \"pack\"    \"packsize\" \"rep\"\n      \"reverse\" \"split\"    \"sub\"\n      \"unpack\"  \"upper\")\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"table\")\n  .\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin \n      \"create\" \"clear\"    \"clone\" \n      \"concat\" \"foreach\"  \"foreachi\" \n      \"find\"   \"freeze\"   \"getn\" \n      \"insert\" \"isfrozen\" \"maxn\" \n      \"move\"   \"pack\"     \"remove\"\n      \"sort\"   \"unpack\")\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"task\")\n  .\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin \n      \"cancel\"      \"defer\"         \"delay\" \n      \"synchronize\" \"desynchronize\" \"spawn\" \n      \"wait\")\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"utf8\")\n  .\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin \n      \"char\"         \"codepoint\"    \"codes\"\n      \"graphemes\"    \"len\"          \"offset\"\n      \"nfcnormalize\" \"nfdnormalize\")\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"utf8\")\n  .\n  (key\n    field_name: (name) @constant.builtin\n    (#eq? @constant.builtin \"charpattern\")\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"buffer\")\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin\n      \"create\"   \"fromstring\" \"tostring\"\n      \"len\"      \"copy\"       \"fill\"\n      \"readi8\"   \"readu8\"     \"readi16\"\n      \"readu16\"  \"readi32\"    \"readu32\"\n      \"readf32\"  \"readf64\"    \"writei8\"\n      \"writeu8\"  \"writei16\"   \"writeu16\"\n      \"writei32\" \"writeu32\"   \"writef32\"\n      \"writef64\" \"readstring\" \"writestring\")\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"vector\")\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin\n      \"create\" \"magnitude\" \"normalize\"\n      \"cross\"  \"dot\"       \"angle\"\n      \"floor\"  \"ceil\"      \"abs\"\n      \"sign\"   \"clamp\"     \"max\"\n      \"min\"\n    )\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"vector\")\n  (key\n    field_name: (name) @constant.builtin\n    (#any-of? @constant.builtin\n      \"zero\" \"one\"\n    )\n  )?\n)\n\n(_\n  table_name: (name) @variable.builtin\n  (#eq? @variable.builtin \"Content\")\n  (key\n    field_name: (name) @function.builtin\n    (#any-of? @function.builtin\n      \"fromUri\" \"fromAssetId\" \"fromObject\"\n    )\n  )?\n)\n\n(type_fn_stmt\n  body: (_\n    [\n      (_\n        variable_name: (name) @variable.builtin\n        (#eq? @variable.builtin \"types\")\n      )\n      (_\n        table_name: (name) @variable.builtin\n        (#eq? @variable.builtin \"types\")\n        (key\n          field_name: (name) @function.builtin\n          (#any-of? @function.builtin\n            \"\"\n          )\n        )\n      )\n    ]\n  )\n)\n\n(call_stmt\n  method_table: (var\n    (name) @variable.builtin\n    (#eq? @variable.builtin \"game\")\n  )\n  method_name: (name) @function.builtin\n  (#eq? @function.builtin \"GetService\")\n  (arglist\n    .\n    (string)? @string.special\n    (#any-of? @string.special\n      \"\\\"AccountService\\\"\"                         \"\\\"AchievementService\\\"\"                \"\\\"AdService\\\"\"\n      \"\\\"AnalyticsService\\\"\"                       \"\\\"AnimationClipProvider\\\"\"             \"\\\"AnimationFromVideoCreatorService\\\"\"\n      \"\\\"AnimationFromVideoCreatorStudioService\\\"\" \"\\\"AnnotationsService\\\"\"                \"\\\"AppLifecycleObserverService\\\"\"\n      \"\\\"AppUpdateService\\\"\"                       \"\\\"AssetCounterService\\\"\"               \"\\\"AssetDeliveryProxy\\\"\"\n      \"\\\"AssetImportService\\\"\"                     \"\\\"AssetManagerService\\\"\"               \"\\\"AssetService\\\"\"\n      \"\\\"AudioFocusService\\\"\"                      \"\\\"AvatarChatService\\\"\"                 \"\\\"AvatarCreationService\\\"\"\n      \"\\\"AvatarEditorService\\\"\"                    \"\\\"AvatarImportService\\\"\"               \"\\\"BadgeService\\\"\"\n      \"\\\"CoreGui\\\"\"                                \"\\\"StarterGui\\\"\"                        \"\\\"BrowserService\\\"\"\n      \"\\\"BulkImportService\\\"\"                      \"\\\"CacheableContentProvider\\\"\"          \"\\\"HSRDataContentProvider\\\"\"\n      \"\\\"MeshContentProvider\\\"\"                    \"\\\"SolidModelContentProvider\\\"\"         \"\\\"CalloutService\\\"\"\n      \"\\\"CaptureService\\\"\"                         \"\\\"ChangeHistoryService\\\"\"              \"\\\"Chat\\\"\"\n      \"\\\"ChatbotUIService\\\"\"                       \"\\\"CloudCRUDService\\\"\"                  \"\\\"ClusterPacketCache\\\"\"\n      \"\\\"CollaboratorsService\\\"\"                   \"\\\"CollectionService\\\"\"                 \"\\\"CommandService\\\"\"\n      \"\\\"CommerceService\\\"\"                        \"\\\"ConfigureServerService\\\"\"            \"\\\"ConnectivityService\\\"\"\n      \"\\\"ContentProvider\\\"\"                        \"\\\"ContextActionService\\\"\"              \"\\\"ControllerService\\\"\"\n      \"\\\"ConversationalAIAcceptanceService\\\"\"      \"\\\"CookiesService\\\"\"                    \"\\\"CorePackages\\\"\"\n      \"\\\"CoreScriptDebuggingManagerHelper\\\"\"       \"\\\"CoreScriptSyncService\\\"\"             \"\\\"CreationDBService\\\"\"\n      \"\\\"CreatorStoreService\\\"\"                    \"\\\"CrossDMScriptChangeListener\\\"\"       \"\\\"DataModelPatchService\\\"\"\n      \"\\\"DataStoreService\\\"\"                       \"\\\"Debris\\\"\"                            \"\\\"DebuggablePluginWatcher\\\"\"\n      \"\\\"DebuggerConnectionManager\\\"\"              \"\\\"DebuggerManager\\\"\"                   \"\\\"DebuggerUIService\\\"\"\n      \"\\\"DeviceIdService\\\"\"                        \"\\\"DraftsService\\\"\"                     \"\\\"DraggerService\\\"\"\n      \"\\\"EditableService\\\"\"                        \"\\\"EventIngestService\\\"\"                \"\\\"ExampleService\\\"\"\n      \"\\\"ExperienceAuthService\\\"\"                  \"\\\"ExperienceNotificationService\\\"\"     \"\\\"ExperienceService\\\"\"\n      \"\\\"ExperienceStateCaptureService\\\"\"          \"\\\"FaceAnimatorService\\\"\"               \"\\\"FacialAnimationRecordingService\\\"\"\n      \"\\\"FacialAnimationStreamingServiceV2\\\"\"      \"\\\"FlagStandService\\\"\"                  \"\\\"FlyweightService\\\"\"\n      \"\\\"CSGDictionaryService\\\"\"                   \"\\\"NonReplicatedCSGDictionaryService\\\"\" \"\\\"FriendService\\\"\"\n      \"\\\"GamePassService\\\"\"                        \"\\\"GamepadService\\\"\"                    \"\\\"GenericChallengeService\\\"\"\n      \"\\\"Geometry\\\"\"                               \"\\\"GeometryService\\\"\"                   \"\\\"GoogleAnalyticsConfiguration\\\"\"\n      \"\\\"GroupService\\\"\"                           \"\\\"GuiService\\\"\"                        \"\\\"GuidRegistryService\\\"\"\n      \"\\\"HapticService\\\"\"                          \"\\\"HeatmapService\\\"\"                    \"\\\"HeightmapImporterService\\\"\"\n      \"\\\"Hopper\\\"\"                                 \"\\\"HttpRbxApiService\\\"\"                 \"\\\"HttpService\\\"\"\n      \"\\\"ILegacyStudioBridge\\\"\"                    \"\\\"LegacyStudioBridge\\\"\"                \"\\\"IXPService\\\"\"\n      \"\\\"IncrementalPatchBuilder\\\"\"                \"\\\"InsertService\\\"\"                     \"\\\"InternalSyncService\\\"\"\n      \"\\\"JointsService\\\"\"                          \"\\\"KeyboardService\\\"\"                   \"\\\"KeyframeSequenceProvider\\\"\"\n      \"\\\"LSPFileSyncService\\\"\"                     \"\\\"LanguageService\\\"\"                   \"\\\"Lighting\\\"\"\n      \"\\\"LinkingService\\\"\"                         \"\\\"LiveScriptingService\\\"\"              \"\\\"LocalStorageService\\\"\"\n      \"\\\"AppStorageService\\\"\"                      \"\\\"UserStorageService\\\"\"                \"\\\"LocalizationService\\\"\"\n      \"\\\"LodDataService\\\"\"                         \"\\\"LogReporterService\\\"\"                \"\\\"LogService\\\"\"\n      \"\\\"LoginService\\\"\"                           \"\\\"LuaWebService\\\"\"                     \"\\\"LuauScriptAnalyzerService\\\"\"\n      \"\\\"MarketplaceService\\\"\"                     \"\\\"MaterialGenerationService\\\"\"         \"\\\"MaterialService\\\"\"\n      \"\\\"MemStorageService\\\"\"                      \"\\\"MemoryStoreService\\\"\"                \"\\\"MessageBusService\\\"\"\n      \"\\\"MessagingService\\\"\"                       \"\\\"MetaBreakpointManager\\\"\"             \"\\\"MouseService\\\"\"\n      \"\\\"NetworkClient\\\"\"                          \"\\\"NetworkServer\\\"\"                     \"\\\"NetworkSettings\\\"\"\n      \"\\\"NotificationService\\\"\"                    \"\\\"OmniRecommendationsService\\\"\"        \"\\\"OpenCloudService\\\"\"\n      \"\\\"Workspace\\\"\"                              \"\\\"PackageService\\\"\"                    \"\\\"PackageUIService\\\"\"\n      \"\\\"PatchBundlerFileWatch\\\"\"                  \"\\\"PathfindingService\\\"\"                \"\\\"PermissionsService\\\"\"\n      \"\\\"PhysicsService\\\"\"                         \"\\\"PlaceStatsService\\\"\"                 \"\\\"PlacesService\\\"\"\n      \"\\\"PlatformCloudStorageService\\\"\"            \"\\\"PlatformFriendsService\\\"\"            \"\\\"PlayerEmulatorService\\\"\"\n      \"\\\"PlayerHydrationService\\\"\"                 \"\\\"PlayerViewService\\\"\"                 \"\\\"Players\\\"\"\n      \"\\\"PluginDebugService\\\"\"                     \"\\\"PluginGuiService\\\"\"                  \"\\\"PluginManagementService\\\"\"\n      \"\\\"PluginPolicyService\\\"\"                    \"\\\"PointsService\\\"\"                     \"\\\"PolicyService\\\"\"\n      \"\\\"ProcessInstancePhysicsService\\\"\"          \"\\\"ProximityPromptService\\\"\"            \"\\\"PublishService\\\"\"\n      \"\\\"RbxAnalyticsService\\\"\"                    \"\\\"ReflectionService\\\"\"                 \"\\\"RemoteCursorService\\\"\"\n      \"\\\"RemoteDebuggerServer\\\"\"                   \"\\\"RenderSettings\\\"\"                    \"\\\"ReplicatedFirst\\\"\"\n      \"\\\"ReplicatedStorage\\\"\"                      \"\\\"RibbonNotificationService\\\"\"         \"\\\"RobloxPluginGuiService\\\"\"\n      \"\\\"RobloxReplicatedStorage\\\"\"                \"\\\"RobloxServerStorage\\\"\"               \"\\\"RomarkRbxAnalyticsService\\\"\"\n      \"\\\"RomarkService\\\"\"                          \"\\\"RtMessagingService\\\"\"                \"\\\"RunService\\\"\"\n      \"\\\"RuntimeScriptService\\\"\"                   \"\\\"SafetyService\\\"\"                     \"\\\"ScriptChangeService\\\"\"\n      \"\\\"ScriptCloneWatcher\\\"\"                     \"\\\"ScriptCloneWatcherHelper\\\"\"          \"\\\"ScriptCommitService\\\"\"\n      \"\\\"ScriptContext\\\"\"                          \"\\\"ScriptEditorService\\\"\"               \"\\\"ScriptProfilerService\\\"\"\n      \"\\\"ScriptRegistrationService\\\"\"              \"\\\"ScriptService\\\"\"                     \"\\\"Selection\\\"\"\n      \"\\\"SelectionHighlightManager\\\"\"              \"\\\"ServerScriptService\\\"\"               \"\\\"ServerStorage\\\"\"\n      \"\\\"ServiceVisibilityService\\\"\"               \"\\\"SessionService\\\"\"                    \"\\\"SharedTableRegistry\\\"\"\n      \"\\\"ShorelineUpgraderService\\\"\"               \"\\\"SmoothVoxelsUpgraderService\\\"\"       \"\\\"SnippetService\\\"\"\n      \"\\\"SocialService\\\"\"                          \"\\\"SoundService\\\"\"                      \"\\\"SpawnerService\\\"\"\n      \"\\\"StartPageService\\\"\"                       \"\\\"StarterPack\\\"\"                       \"\\\"StarterPlayer\\\"\"\n      \"\\\"StartupMessageService\\\"\"                  \"\\\"Stats\\\"\"                             \"\\\"StopWatchReporter\\\"\"\n      \"\\\"StreamingService\\\"\"                       \"\\\"Studio\\\"\"                            \"\\\"StudioAssetService\\\"\"\n      \"\\\"StudioData\\\"\"                             \"\\\"StudioDeviceEmulatorService\\\"\"       \"\\\"StudioPublishService\\\"\"\n      \"\\\"StudioScriptDebugEventListener\\\"\"         \"\\\"StudioSdkService\\\"\"                  \"\\\"StudioService\\\"\"\n      \"\\\"StudioUserService\\\"\"                      \"\\\"StudioWidgetsService\\\"\"              \"\\\"StylingService\\\"\"\n      \"\\\"TaskScheduler\\\"\"                          \"\\\"TeamCreateData\\\"\"                    \"\\\"TeamCreatePublishService\\\"\"\n      \"\\\"TeamCreateService\\\"\"                      \"\\\"Teams\\\"\"                             \"\\\"TeleportService\\\"\"\n      \"\\\"TemporaryCageMeshProvider\\\"\"              \"\\\"TemporaryScriptService\\\"\"            \"\\\"TestService\\\"\"\n      \"\\\"TextBoxService\\\"\"                         \"\\\"TextChatService\\\"\"                   \"\\\"TextService\\\"\"\n      \"\\\"TextureGenerationService\\\"\"               \"\\\"ThirdPartyUserService\\\"\"             \"\\\"TimerService\\\"\"\n      \"\\\"ToastNotificationService\\\"\"               \"\\\"TouchInputService\\\"\"                 \"\\\"TracerService\\\"\"\n      \"\\\"TutorialService\\\"\"                        \"\\\"TweenService\\\"\"                      \"\\\"UGCAvatarService\\\"\"\n      \"\\\"UGCValidationService\\\"\"                   \"\\\"UIDragDetectorService\\\"\"             \"\\\"UnvalidatedAssetService\\\"\"\n      \"\\\"UserInputService\\\"\"                       \"\\\"UserService\\\"\"                       \"\\\"VRService\\\"\"\n      \"\\\"VRStatusService\\\"\"                        \"\\\"VersionControlService\\\"\"             \"\\\"VideoCaptureService\\\"\"\n      \"\\\"VideoService\\\"\"                           \"\\\"VirtualInputManager\\\"\"               \"\\\"VirtualUser\\\"\"\n      \"\\\"VisibilityCheckDispatcher\\\"\"              \"\\\"Visit\\\"\"                             \"\\\"VisualizationModeService\\\"\"\n      \"\\\"VoiceChatInternal\\\"\"                      \"\\\"VoiceChatService\\\"\"                  \"\\\"WebViewService\\\"\"\n    )\n    .\n  )\n)\n\n"
  },
  {
    "path": "runtime/queries/luau/indents.scm",
    "content": "[\n  (repeat_stmt)\n  (for_in_stmt)\n  (for_range_stmt)\n  (do_stmt)\n  (while_stmt)\n  (if_stmt)\n  ; (else_clause)\n  ; (elseif_clause)\n  (fn_stmt)\n  (local_fn_stmt)\n  (anon_fn)\n  (bindinglist)\n  (varlist)\n  (paramlist)\n  (paramtypelist)\n  (table)\n  (cast)\n  (tbtype)\n  (dyntype)\n  (bintype)\n  (wraptype)\n  (typepack)\n  (attribute)\n  (parattr)\n  (littable)\n] @indent\n\n(\n  [\n    (arglist)\n  ] @indent\n  (#set! \"scope\" \"all\")\n)\n\n(\n  [\n    (explist)\n    (interp_exp)\n  ] @indent.always\n  (#set! \"scope\" \"all\")\n)\n\n[\n  \"until\"\n  \"end\"\n  \")\"\n  \"}\"\n  \"]\"\n] @outdent\n\n[\n  (interp_brace_close)\n] @outdent.always\n\n(ret_stmt\n  \"return\" @expr-start\n  .\n  (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n\n(field\n  \"[\" @expr-start\n  .\n  field_indexer: (_) @indent\n  (#not-same-line? @expr-start @indent)\n  (#set! \"scope\" \"all\")\n)\n\n(_\n  (_) @expr-start\n  .\n  assign_symbol: _ @indent\n  .\n  (_) @expr-end\n  (#not-same-line? @indent @expr-start)\n  (#same-line? @expr-end @indent)\n  (#set! \"scope\" \"all\")\n)\n\n(_\n  (_) @expr-start\n  .\n  assign_symbol: _ @assign-sym\n  .\n  (_) @indent\n  (#same-line? @expr-start @assign-sym)\n  (#not-same-line? @assign-sym @indent)\n  (#set! \"scope\" \"all\")\n)\n\n(ifexp\n  [\n    \"if\"\n    \"then\"\n    \"elseif\"\n    \"else\"\n  ] @expr-start\n  .\n  (_) @indent.always\n  (#set! \"scope\" \"all\")\n  (#not-same-line? @indent.always @expr-start)\n)\n\n(fntype\n  (paramtypelist) @expr-start\n  return_type: (_) @indent\n  (#not-same-line? @expr-start @indent)\n  (#set! \"scope\" \"all\")\n)\n\n(exp_wrap\n  (_) @expr-content\n  (#not-same-line? @indent @expr-content)\n  (#not-kind-eq? @expr-content \"ifexp\")\n) @indent\n\n(else_clause\n  \"else\" @outdent\n)\n\n(elseif_clause\n  \"elseif\" @outdent\n)\n"
  },
  {
    "path": "runtime/queries/luau/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; string.match(\"123\", \"%d+\")\n(call_stmt\n  invoked: (var\n    table_name: (name)\n    (key\n      field_name: (name) @_method))\n  (arglist\n    .\n    (_)\n    .\n    (string) @injection.content)\n  (#any-of? @_method \"find\" \"format\" \"match\" \"gmatch\" \"gsub\")\n  (#set! injection.language \"luap\"))\n\n; (\"123\"):match(\"%d+\")\n(call_stmt\n  method_table: (_)\n  method_name: (name) @_method\n  (arglist\n    .\n    (string) @injection.content)\n  (#any-of? @_method \"find\" \"format\" \"match\" \"gmatch\" \"gsub\")\n  (#set! injection.language \"luap\"))\n\n; string.format(\"format string\", ...)\n((call_stmt\n  invoked: (var\n    table_name: (name) @_table\n    (key\n      field_name: (name) @_function))\n  (arglist\n    . (string) @injection.content))\n  (#eq? @_table \"string\")\n  (#eq? @_function \"format\")\n  (#set! injection.language \"lua-format-string\"))\n\n; (\"format\"):format(...)\n((call_stmt\n  method_table: (exp_wrap (string) @injection.content)\n  method_name: (name) @_function)\n  (#eq? @_function \"format\")\n  (#set! injection.language \"lua-format-string\"))\n"
  },
  {
    "path": "runtime/queries/luau/locals.scm",
    "content": "[\n  (block)\n  (fn_stmt)\n  (local_fn_stmt)\n  (anon_fn)\n  (for_range_stmt)\n  (for_in_stmt)\n] @local.scope\n\n(_\n  parameter_name: (name) @local.definition.variable.parameter\n)\n\n(binding\n  variable_name: (name) @local.definition.variable\n)\n\n(var \n  variable_name: (name) @local.reference\n)\n\n; (call_stmt\n;   .\n;   method_table: (name) @local.reference\n; )\n"
  },
  {
    "path": "runtime/queries/luau/textobjects.scm",
    "content": "(fn_stmt\n  body: (_)? @function.inside) @function.around\n\n(local_fn_stmt\n  body: (_)? @function.inside) @function.around\n\n(anon_fn\n  body: (_)? @function.inside) @function.around\n\n(param\n  ((name) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(arglist\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/mail/highlights.scm",
    "content": "; header fields\n[\n  (header_field_email)\n  (header_field_subject)\n  (header_field)\n] @keyword\n\n; delimited punctuation\n(header_separator) @punctuation.delimiter\n(email_delimiter) @punctuation.delimiter\n\n; email subject contents\n(header_subject\n  (subject) @markup.bold)\n; extra metadata headers\n(header_other\n  (header_unstructured) @comment)\n\n; Addressee Name (Firstname, Lastname, etc.)\n(atom) @variable\n\n; Email Address\n(email) @string\n\n; Quoted Reply\n(quote_marker) @punctuation.special\n(quote_contents) @markup.quote\n\n"
  },
  {
    "path": "runtime/queries/mail/rainbows.scm",
    "content": "[\n  (quoted_block)\n] @rainbow.scope\n\n[\n  (quote_marker)\n  (quote_contents)\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/mail/textobjects.scm",
    "content": "(atom_block\n  (atom) @entry.inside) @entry.around\n\n(email_address) @entry.around\n(header_other\n  (header_unstructured) @entry.around)\n\n(quoted_block)+ @comment.around\n\n(body_block)+ @function.around\n\n(header_subject\n  (subject) @function.around)\n"
  },
  {
    "path": "runtime/queries/make/highlights.scm",
    "content": "[\n \"(\"\n \")\"\n \"{\"\n \"}\"\n] @punctuation.bracket\n\n[\n \":\"\n \"&:\"\n \"::\"\n \"|\"\n \";\"\n \"\\\"\"\n \"'\"\n \",\"\n] @punctuation.delimiter\n\n[\n \"$\"\n \"$$\"\n] @punctuation.special\n\n(automatic_variable\n [ \"@\" \"%\" \"<\" \"?\" \"^\" \"+\" \"/\" \"*\" \"D\" \"F\"] @punctuation.special)\n\n(automatic_variable\n \"/\" @error . [\"D\" \"F\"])\n\n[\n \"=\"\n \":=\"\n \"::=\"\n \"?=\"\n \"+=\"\n \"!=\"\n \"@\"\n \"-\"\n \"+\"\n] @operator\n\n[\n (text)\n (string)\n (raw_text)\n] @string\n\n(variable_assignment (word) @variable)\n(shell_text\n  [(variable_reference (word) @variable.parameter)])\n\n[\n \"ifeq\"\n \"ifneq\"\n \"ifdef\"\n \"ifndef\"\n \"else\"\n \"endif\"\n \"if\"\n \"or\"  ; boolean functions are conditional in make grammar\n \"and\"\n] @keyword.control.conditional\n\n\"foreach\" @keyword.control.repeat\n\n[\n \"define\"\n \"endef\"\n \"vpath\"\n \"undefine\"\n \"export\"\n \"unexport\"\n \"override\"\n \"private\"\n; \"load\"\n] @keyword\n\n[\n \"include\"\n \"sinclude\"\n \"-include\"\n] @keyword.control.import\n\n[\n \"subst\"\n \"patsubst\"\n \"strip\"\n \"findstring\"\n \"filter\"\n \"filter-out\"\n \"sort\"\n \"word\"\n \"words\"\n \"wordlist\"\n \"firstword\"\n \"lastword\"\n \"dir\"\n \"notdir\"\n \"suffix\"\n \"basename\"\n \"addsuffix\"\n \"addprefix\"\n \"join\"\n \"wildcard\"\n \"realpath\"\n \"abspath\"\n \"call\"\n \"eval\"\n \"file\"\n \"value\"\n \"shell\"\n] @keyword.function\n\n[\n \"error\"\n \"warning\"\n \"info\"\n] @keyword.control.exception\n\n;; Variable\n(variable_assignment\n  name: (word) @variable)\n\n(variable_reference\n  (word) @variable)\n\n(comment) @comment\n\n((word) @clean @string.regexp\n (#match? @clean \"[%\\*\\?]\"))\n\n(function_call\n  function: \"error\"\n  (arguments (text) @error))\n\n(function_call\n  function: \"warning\"\n  (arguments (text) @warning))\n\n(function_call\n  function: \"info\"\n  (arguments (text) @info))\n\n\n;; Install Command Categories\n;; Others special variables\n;; Variables Used by Implicit Rules\n[\n \"VPATH\"\n \".RECIPEPREFIX\"\n] @constant.builtin\n\n(variable_assignment\n  name: (word) @clean @constant.builtin\n        (#match? @clean \"^(AR|AS|CC|CXX|CPP|FC|M2C|PC|CO|GET|LEX|YACC|LINT|MAKEINFO|TEX|TEXI2DVI|WEAVE|CWEAVE|TANGLE|CTANGLE|RM|ARFLAGS|ASFLAGS|CFLAGS|CXXFLAGS|COFLAGS|CPPFLAGS|FFLAGS|GFLAGS|LDFLAGS|LDLIBS|LFLAGS|YFLAGS|PFLAGS|RFLAGS|LINTFLAGS|PRE_INSTALL|POST_INSTALL|NORMAL_INSTALL|PRE_UNINSTALL|POST_UNINSTALL|NORMAL_UNINSTALL|MAKEFILE_LIST|MAKE_RESTARTS|MAKE_TERMOUT|MAKE_TERMERR|\\.DEFAULT_GOAL|\\.RECIPEPREFIX|\\.EXTRA_PREREQS)$\"))\n\n(variable_reference\n  (word) @clean @constant.builtin\n  (#match? @clean \"^(AR|AS|CC|CXX|CPP|FC|M2C|PC|CO|GET|LEX|YACC|LINT|MAKEINFO|TEX|TEXI2DVI|WEAVE|CWEAVE|TANGLE|CTANGLE|RM|ARFLAGS|ASFLAGS|CFLAGS|CXXFLAGS|COFLAGS|CPPFLAGS|FFLAGS|GFLAGS|LDFLAGS|LDLIBS|LFLAGS|YFLAGS|PFLAGS|RFLAGS|LINTFLAGS|PRE_INSTALL|POST_INSTALL|NORMAL_INSTALL|PRE_UNINSTALL|POST_UNINSTALL|NORMAL_UNINSTALL|MAKEFILE_LIST|MAKE_RESTARTS|MAKE_TERMOUT|MAKE_TERMERR|\\.DEFAULT_GOAL|\\.RECIPEPREFIX|\\.EXTRA_PREREQS\\.VARIABLES|\\.FEATURES|\\.INCLUDE_DIRS|\\.LOADED)$\"))\n\n;; Standard targets\n(targets\n  (word) @constant.macro\n  (#match? @constant.macro \"^(all|install|install-html|install-dvi|install-pdf|install-ps|uninstall|install-strip|clean|distclean|mostlyclean|maintainer-clean|TAGS|info|dvi|html|pdf|ps|dist|check|installcheck|installdirs)$\"))\n\n(targets\n  (word) @constant.macro\n  (#match? @constant.macro \"^(all|install|install-html|install-dvi|install-pdf|install-ps|uninstall|install-strip|clean|distclean|mostlyclean|maintainer-clean|TAGS|info|dvi|html|pdf|ps|dist|check|installcheck|installdirs)$\"))\n\n;; Builtin targets\n(targets\n  (word) @constant.macro\n  (#match? @constant.macro \"^\\.(PHONY|SUFFIXES|DEFAULT|PRECIOUS|INTERMEDIATE|SECONDARY|SECONDEXPANSION|DELETE_ON_ERROR|IGNORE|LOW_RESOLUTION_TIME|SILENT|EXPORT_ALL_VARIABLES|NOTPARALLEL|ONESHELL|POSIX)$\"))\n\n(targets (word) @constant)\n"
  },
  {
    "path": "runtime/queries/make/indents.scm",
    "content": "[\n  (define_directive)\n  (rule)\n] @indent\n\n[\n  \"endef\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/make/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((shell_text) @injection.content\n (#set! injection.language \"bash\"))\n"
  },
  {
    "path": "runtime/queries/markdoc/highlights.scm",
    "content": "tag_name: (identifier) @tag\n(tag_self_closing \"/\" @tag)\n(tag_close \"/\" @tag)\n([(tag_start) (tag_end) \"=\"] @tag)\n(attribute [key : (identifier)] @attribute)\n(attribute [shorthand : (identifier)]  @attribute)\n(variable [variable : (identifier) (variable_sigil)] @variable)\n(variable_tail property : (identifier) @variable.other.member)\n(function function_name : (identifier) @function)\n(function_parameter_named parameter : (identifier) @variable.parameter)\n\n(hash_key key: (identifier) @variable.other.member)\n(string) @string\n(number) @constant.numeric\n(boolean) @constant.builtin.boolean\n(null) @constant.builtin\n"
  },
  {
    "path": "runtime/queries/markdoc/injections.scm",
    "content": "((markdown) @injection.content\n (#set! injection.language \"markdown\"))\n"
  },
  {
    "path": "runtime/queries/markdown/highlights.scm",
    "content": "\n(setext_heading (paragraph) @markup.heading.1 (setext_h1_underline) @markup.heading.marker)\n(setext_heading (paragraph) @markup.heading.2 (setext_h2_underline) @markup.heading.marker)\n\n(atx_heading (atx_h1_marker) @markup.heading.marker) @markup.heading.1\n(atx_heading (atx_h2_marker) @markup.heading.marker) @markup.heading.2\n(atx_heading (atx_h3_marker) @markup.heading.marker) @markup.heading.3\n(atx_heading (atx_h4_marker) @markup.heading.marker) @markup.heading.4\n(atx_heading (atx_h5_marker) @markup.heading.marker) @markup.heading.5\n(atx_heading (atx_h6_marker) @markup.heading.marker) @markup.heading.6\n\n[\n  (indented_code_block)\n  (fenced_code_block)\n] @markup.raw.block\n\n(info_string) @label\n\n[\n  (fenced_code_block_delimiter)\n] @punctuation.bracket\n\n[\n  (link_destination)\n] @markup.link.url\n\n[\n  (link_label)\n] @markup.link.label\n\n[\n  (list_marker_plus)\n  (list_marker_minus)\n  (list_marker_star)\n] @markup.list.unnumbered\n\n[\n  (list_marker_dot)\n  (list_marker_parenthesis)\n] @markup.list.numbered\n\n(task_list_marker_checked) @markup.list.checked\n(task_list_marker_unchecked) @markup.list.unchecked\n\n(thematic_break) @punctuation.special\n\n[\n  (block_continuation)\n  (block_quote_marker)\n] @punctuation.special\n\n[\n  (backslash_escape)\n] @string.escape\n\n(block_quote) @markup.quote\n\n(pipe_table_row\n  \"|\" @punctuation.special)\n(pipe_table_header\n  \"|\" @punctuation.special)\n(pipe_table_delimiter_row) @punctuation.special\n"
  },
  {
    "path": "runtime/queries/markdown/injections.scm",
    "content": "; From nvim-treesitter/nvim-treesitter\n\n(fenced_code_block\n  (code_fence_content) @injection.shebang @injection.content\n  (#set! injection.include-unnamed-children))\n\n(fenced_code_block\n  (info_string\n    (language) @injection.language)\n  (code_fence_content) @injection.content (#set! injection.include-unnamed-children))\n\n((html_block) @injection.content\n (#set! injection.language \"html\")\n (#set! injection.include-unnamed-children)\n (#set! injection.combined))\n\n((pipe_table_cell) @injection.content (#set! injection.language \"markdown.inline\") (#set! injection.include-unnamed-children))\n\n((minus_metadata) @injection.content (#set! injection.language \"yaml\") (#set! injection.include-unnamed-children))\n((plus_metadata) @injection.content (#set! injection.language \"toml\") (#set! injection.include-unnamed-children))\n\n((inline) @injection.content (#set! injection.language \"markdown.inline\") (#set! injection.include-unnamed-children))\n"
  },
  {
    "path": "runtime/queries/markdown/tags.scm",
    "content": "(atx_heading) @definition.section\n"
  },
  {
    "path": "runtime/queries/markdown-rustdoc/highlights.scm",
    "content": "; inherits: markdown\n"
  },
  {
    "path": "runtime/queries/markdown-rustdoc/injections.scm",
    "content": "; inherits: markdown\n\n; In Rust, it is common to have documentation code blocks not specify the\n; language, and it is assumed to be Rust if it is not specified.\n\n(fenced_code_block\n  (code_fence_content) @injection.content\n  (#set! injection.language \"rust\")\n  (#set! injection.include-unnamed-children))\n\n(fenced_code_block\n  (info_string\n    (language) @injection.language)\n  (code_fence_content) @injection.content (#set! injection.include-unnamed-children))\n\n(fenced_code_block\n  (info_string\n    (language) @__language)\n  (code_fence_content) @injection.content\n  ; list of attributes for Rust syntax highlighting:\n  ; https://doc.rust-lang.org/rustdoc/write-documentation/documentation-tests.html#attributes\n  (#match? @__language\n  \"(ignore|should_panic|no_run|compile_fail|standalone_crate|custom|edition*)\")\n  (#set! injection.language \"rust\")\n  (#set! injection.include-unnamed-children))\n"
  },
  {
    "path": "runtime/queries/markdown.inline/highlights.scm",
    "content": ";; From nvim-treesitter/nvim-treesitter\n[\n  (code_span)\n  (link_title)\n] @markup.raw.inline\n\n[\n  (emphasis_delimiter)\n  (code_span_delimiter)\n] @punctuation.bracket\n\n(emphasis) @markup.italic\n\n(strong_emphasis) @markup.bold\n\n(strikethrough) @markup.strikethrough\n\n[\n  (link_destination)\n  (uri_autolink)\n] @markup.link.url\n\n[\n  (link_text)\n  (image_description)\n] @markup.link.text\n\n(link_label) @markup.link.label\n\n[\n  (backslash_escape)\n  (hard_line_break)\n] @constant.character.escape\n\n(image [\"[\" \"]\" \"(\" \")\"] @punctuation.bracket)\n(image \"!\" @punctuation.special)\n(inline_link [\"[\" \"]\" \"(\" \")\"] @punctuation.bracket)\n(shortcut_link [\"[\" \"]\"] @punctuation.bracket)\n\n"
  },
  {
    "path": "runtime/queries/markdown.inline/injections.scm",
    "content": "\n((html_tag) @injection.content \n  (#set! injection.language \"html\") \n  (#set! injection.include-unnamed-children)\n  (#set! injection.combined))\n\n((latex_block) @injection.content (#set! injection.language \"latex\") (#set! injection.include-unnamed-children))\n"
  },
  {
    "path": "runtime/queries/matlab/context.scm",
    "content": "(function_definition\n  (block (_) @context.end)\n) @context\n\n(while_statement\n  (block (_) @context.end)\n) @context\n\n(for_statement\n  (block (_) @context.end)\n) @context\n\n(if_statement\n  (block (_) @context.end)\n) @context\n\n(elseif_clause\n  (block (_) @context.end)\n) @context\n\n(else_clause\n  (block (_) @context.end)\n) @context\n\n(switch_statement) @context\n\n(case_clause\n  (block (_) @context.end)\n) @context\n\n(otherwise_clause\n  (block (_) @context.end)\n) @context\n\n(try_statement\n  \"try\"\n  (block (_) @context.end) @context\n  \"end\")\n(catch_clause\n  \"catch\"\n  (block (_) @context.end) @context)\n"
  },
  {
    "path": "runtime/queries/matlab/folds.scm",
    "content": "[(if_statement)\n (for_statement)\n (while_statement)\n (switch_statement)\n (try_statement)\n (function_definition)\n (class_definition)\n (enumeration)\n (events)\n (methods)\n (properties)] @fold\n"
  },
  {
    "path": "runtime/queries/matlab/highlights.scm",
    "content": "; Constants\n\n(events (identifier) @constant)\n(attribute (identifier) @constant)\n\n\"~\" @constant.builtin\n\n; Fields/Properties\n\n(superclass \".\" (identifier) @variable.other.member)\n(property_name \".\" (identifier) @variable.other.member)\n(property name: (identifier) @variable.other.member)\n\n; Types\n\n(class_definition name: (identifier) @keyword.storage.type)\n(attributes (identifier) @constant)\n(enum . (identifier) @type.enum.variant)\n\n; Functions\n\n(function_definition\n  \"function\" @keyword.function\n  name: (identifier) @function\n  [ \"end\" \"endfunction\" ]? @keyword.function)\n\n(function_signature name: (identifier) @function)\n(function_call name: (identifier) @function)\n(handle_operator (identifier) @function)\n(validation_functions (identifier) @function)\n(command (command_name) @function.macro)\n(command_argument) @string\n(return_statement) @keyword.control.return\n\n; Assignments\n\n(assignment left: (_) @variable)\n(multioutput_variable (_) @variable)\n\n; Parameters\n\n(function_arguments (identifier) @variable.parameter)\n\n; Conditionals\n\n(if_statement [ \"if\" \"end\" ] @keyword.control.conditional)\n(elseif_clause \"elseif\" @keyword.control.conditional)\n(else_clause \"else\" @keyword.control.conditional)\n(switch_statement [ \"switch\" \"end\" ] @keyword.control.conditional)\n(case_clause \"case\" @keyword.control.conditional)\n(otherwise_clause \"otherwise\" @keyword.control.conditional)\n(break_statement) @keyword.control.conditional\n\n; Repeats\n\n(for_statement [ \"for\" \"parfor\" \"end\" ] @keyword.control.repeat)\n(while_statement [ \"while\" \"end\" ] @keyword.control.repeat)\n(continue_statement) @keyword.control.repeat\n\n; Exceptions\n\n(try_statement [ \"try\" \"end\" ] @keyword.control.exception)\n(catch_clause \"catch\" @keyword.control.exception)\n\n; Punctuation\n\n[ \";\" \",\" \".\" ] @punctuation.delimiter\n[ \"(\" \")\" \"[\" \"]\" \"{\" \"}\" ] @punctuation.bracket\n\n; Literals\n\n(escape_sequence) @constant.character.escape\n(formatting_sequence) @constant.character.escape\n(string) @string\n(number) @constant.numeric.float\n(unary_operator [\"+\" \"-\"] @constant.numeric.float)\n\n; Comments\n\n[ (comment) (line_continuation) ] @comment.line\n\n; Operators\n\n[\n  \"+\"\n  \".+\"\n  \"-\"\n  \".*\"\n  \"*\"\n  \".*\"\n  \"/\"\n  \"./\"\n  \"\\\\\"\n  \".\\\\\"\n  \"^\"\n  \".^\"\n  \"'\"\n  \".'\"\n  \"|\"\n  \"&\"\n  \"?\"\n  \"@\"\n  \"<\"\n  \"<=\"\n  \">\"\n  \">=\"\n  \"==\"\n  \"~=\"\n  \"=\"\n  \"&&\"\n  \"||\"\n  \":\"\n] @operator\n\n; Keywords\n\n\"classdef\" @keyword.storage.type\n[\n  \"arguments\"\n  \"end\"\n  \"enumeration\"\n  \"events\"\n  \"global\"\n  \"methods\"\n  \"persistent\"\n  \"properties\"\n] @keyword\n"
  },
  {
    "path": "runtime/queries/matlab/indents.scm",
    "content": "[\n  (arguments_statement)\n  (if_statement)\n  (for_statement)\n  (while_statement)\n  (switch_statement)\n  (try_statement)\n  (function_definition)\n  (class_definition)\n  (enumeration)\n  (events)\n  (methods)\n  (properties)\n] @indent\n\n[\n  (elseif_clause)\n  (else_clause)\n  (case_clause)\n  (otherwise_clause)\n  (catch_clause)\n] @indent @extend\n\n[ \"end\" ] @outdent\n"
  },
  {
    "path": "runtime/queries/matlab/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/matlab/locals.scm",
    "content": "(function_definition name: (identifier) @local.definition.function ?) @local.scope\n(function_arguments (identifier)* @local.definition.variable.parameter)\n\n(lambda (arguments (identifier) @local.definition.variable.parameter)) @local.scope\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/matlab/textobjects.scm",
    "content": "(arguments ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n(function_arguments ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(lambda expression: (_) @function.inside) @function.around\n(function_definition (block) @function.inside) @function.around\n\n(class_definition) @class.inside @class.around\n\n(comment) @comment.inside @comment.around\n"
  },
  {
    "path": "runtime/queries/mermaid/highlights.scm",
    "content": "[\n \"sequenceDiagram\"\n \"classDiagram\"\n \"classDiagram-v2\"\n \"stateDiagram\"\n \"stateDiagram-v2\"\n \"gantt\"\n \"pie\"\n \"flowchart\"\n \"erdiagram\"\n\n \"participant\"\n \"as\"\n \"activate\"\n \"deactivate\"\n \"note \"\n \"over\"\n \"link\"\n \"links\"\n ; \"left of\"\n ; \"right of\"\n \"properties\"\n \"details\"\n \"title\"\n \"loop\"\n \"rect\"\n \"opt\"\n \"alt\"\n \"else\"\n \"par\"\n \"and\"\n \"end\"\n (sequence_stmt_autonumber)\n (note_placement_left)\n (note_placement_right)\n\n \"class\"\n\n \"state \"\n\n \"dateformat\"\n \"inclusiveenddates\"\n \"topaxis\"\n \"axisformat\"\n \"includes\"\n \"excludes\"\n \"todaymarker\"\n \"title\"\n \"section\"\n\n \"direction\"\n \"subgraph\"\n\n ] @keyword\n\n[\n (comment)\n ] @comment\n\n(flow_vertex_id) @type\n(flow_arrow_text) @label\n(flow_text_literal) @string\n \n[\n \":\"\n (sequence_signal_plus_sign)\n (sequence_signal_minus_sign)\n\n (class_visibility_public)\n (class_visibility_private)\n (class_visibility_protected)\n (class_visibility_internal)\n\n (state_division)\n ] @punctuation.delimiter\n\n[\n \"(\"\n \")\"\n \"{\"\n \"}\"\n ] @punctuation.bracket\n\n[\n \"-->\"\n (solid_arrow)\n (dotted_arrow)\n (solid_open_arrow)\n (dotted_open_arrow)\n (solid_cross)\n (dotted_cross)\n (solid_point)\n (dotted_point)\n ] @operator\n\n[\n (class_reltype_aggregation)\n (class_reltype_extension)\n (class_reltype_composition)\n (class_reltype_dependency)\n (class_linetype_solid)\n (class_linetype_dotted)\n \"&\"\n ] @operator\n\n(sequence_actor) @variable\n(sequence_text) @string\n\n(class_name) @type\n(class_label) @string\n(class_method_line) @function.method\n\n(state_name) @variable\n\n(gantt_section) @markup.heading\n(gantt_task_text) @variable.builtin\n(gantt_task_data) @string\n\n[\n (class_annotation_line)\n (class_stmt_annotation)\n (class_generics)\n\n (state_annotation_fork)\n (state_annotation_join)\n (state_annotation_choice)\n ] @type\n\n(directive) @keyword.directive\n\n(pie_label) @string\n(pie_value) @constant.numeric\n\n[\n(flowchart_direction_lr)\n(flowchart_direction_rl)\n(flowchart_direction_tb)\n(flowchart_direction_bt)\n ] @constant\n\n(flow_vertex_id) @variable\n\n[\n (flow_link_arrow)\n (flow_link_arrow_start)\n ] @operator\n\n(flow_link_arrowtext \"|\" @punctuation.bracket)\n\n(flow_vertex_square        [ \"[\" \"]\" ]   @punctuation.bracket )\n(flow_vertex_circle        [\"((\" \"))\"]   @punctuation.bracket )\n(flow_vertex_ellipse       [\"(-\" \"-)\"]   @punctuation.bracket )\n(flow_vertex_stadium       [\"([\" \"])\"]   @punctuation.bracket )\n(flow_vertex_subroutine    [\"[[\" \"]]\"]   @punctuation.bracket )\n(flow_vertex_rect          [\"[|\" \"|]\"]   @punctuation.bracket )\n(flow_vertex_cylinder      [\"[(\" \")]\"]   @punctuation.bracket )\n(flow_vertex_round         [\"(\" \")\"]     @punctuation.bracket )\n(flow_vertex_diamond       [\"{\" \"}\"]     @punctuation.bracket )\n(flow_vertex_hexagon       [\"{{\" \"}}\"]   @punctuation.bracket )\n(flow_vertex_odd           [\">\" \"]\"]     @punctuation.bracket )\n(flow_vertex_trapezoid     [\"[/\" \"\\\\]\"]  @punctuation.bracket )\n(flow_vertex_inv_trapezoid [\"[\\\\\" \"/]\"]  @punctuation.bracket )\n(flow_vertex_leanright     [\"[/\" \"/]\"]   @punctuation.bracket )\n(flow_vertex_leanleft      [\"[\\\\\" \"\\\\]\"] @punctuation.bracket )\n\n(flow_stmt_subgraph [\"[\" \"]\"] @punctuation.bracket )\n\n[\n (er_cardinarity_zero_or_one)\n (er_cardinarity_zero_or_more)\n (er_cardinarity_one_or_more)\n (er_cardinarity_only_one)\n (er_reltype_non_identifying)\n (er_reltype_identifying)\n ] @operator\n\n(er_entity_name) @variable\n\n(er_attribute_type) @type\n(er_attribute_name) @variable\n\n[\n (er_attribute_key_type_pk)\n (er_attribute_key_type_fk)\n ] @keyword\n\n(er_attribute_comment) @string\n"
  },
  {
    "path": "runtime/queries/meson/highlights.scm",
    "content": "(comment) @comment\n\n(identifier) @variable\n\n[\n    (assignment_operator)\n    (additive_operator)\n    (multiplicative_operator)\n    (equality_operator)\n    \">=\"\n    \"<=\"\n    \"<\"\n    \">\"\n    \"+\"\n    \"-\"\n] @operator\n\n[\n    (and)\n    (or)\n    (not)\n    (in)\n] @keyword.operator\n\n[\n    \"(\" \")\" \"[\" \"]\" \"{\" \"}\"\n] @punctuation.bracket\n\n[\n    (if)\n    (elif)\n    (else)\n    (endif)\n] @keyword.control.conditional\n\n[\n    (foreach)\n    (endforeach)\n    (break)\n    (continue)\n] @keyword.control.repeat\n\n(boolean_literal) @constant.builtin.boolean\n(int_literal) @constant.numeric.integer\n\n(keyword_argument keyword: (identifier) @variable.parameter)\n(escape_sequence) @constant.character.escape\n(bad_escape) @warning\n\n[\n\".\"\n\",\"\n\":\"\n] @punctuation.delimiter\n\n[\n    (string_literal)\n    (fstring_literal)\n] @string\n\n; these are listed last, because they override keyword queries\n(function_expression (identifier) @function)\n"
  },
  {
    "path": "runtime/queries/meson/indents.scm",
    "content": "; Indentation queries for helix\n[\n  (function_expression)\n  (array_literal)\n  (dictionary_literal)\n  (selection_statement)\n  (iteration_statement)\n] @indent\n\n; question - what about else, elif\n[\n  \")\"\n  \"]\"\n  \"}\"\n  (endif)\n  (endforeach)\n] @outdent\n"
  },
  {
    "path": "runtime/queries/meson/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/miseconfig/highlights.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/miseconfig/indents.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/miseconfig/injections.scm",
    "content": "; inherits: toml\n\n; This part covers simple tasks where only the command(s) to run\n; are specified as a string or array of strings, e.g.\n;\n;    [tasks]\n;    simple = \"simple-command arg1 arg2\"\n;    many-simple = [\n;      \"simple-command-1\",\n;      \"simple-command-2\",\n;    ]\n;\n(table\n  (bare_key) @table-name (#eq? @table-name \"tasks\")\n  (pair (_) [\n    ((string) @injection.shebang @injection.content (#set! injection.language \"bash\"))\n    ((array (string) @injection.shebang @injection.content (#set! injection.language \"bash\")))\n  ])\n)\n\n; This part covers advanced tasks which are specified as a table.\n; Only the \"run\" key is subject to injections.\n;\n;    [tasks.foo]\n;    description = \"This is regular text.\"\n;    run = \"this is bash\"\n;\n(table\n  (dotted_key (bare_key) @table-name (#eq? @table-name \"tasks\"))\n  (pair (bare_key) @key-name (#eq? @key-name \"run\") [\n    ((string) @injection.shebang @injection.content (#set! injection.language \"bash\"))\n    ((array (string) @injection.shebang @injection.content (#set! injection.language \"bash\")))\n  ])\n)\n"
  },
  {
    "path": "runtime/queries/miseconfig/textobjects.scm",
    "content": "; inherits: toml\n"
  },
  {
    "path": "runtime/queries/mojo/highlights.scm",
    "content": "; Variables\n\n(identifier) @variable\n\n(attribute attribute: (identifier) @variable.other.member)\n\n((identifier) @constant\n  (#match? @constant \"^_*[A-Z][A-Z\\\\d_]*$\"))\n\n((identifier) @type\n  (#match? @type \"^[A-Z]\"))\n\n; Literals\n(none) @constant.builtin\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(comment) @comment\n(string) @string\n(escape_sequence) @constant.character.escape\n\n; Docstrings\n\n(expression_statement (string) @comment.block.documentation)\n\n; Imports\n\n(dotted_name\n  (identifier)* @namespace)\n\n(aliased_import\n  alias: (identifier) @namespace)\n\n; Builtin functions\n\n((call\n  function: (identifier) @function.builtin)\n  (#match?\n    @function.builtin\n    \"^(abs|all|always_inline|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|constrained|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unroll|vars|zip|__mlir_attr|__mlir_op|__mlir_type|__import__)$\"))\n\n; Function calls\n\n[\n  \"def\"\n  \"lambda\"\n  \"fn\"\n] @keyword.function\n\n(call\n  function: (attribute attribute: (identifier) @constructor)\n  (#match? @constructor \"^[A-Z]\"))\n\n(call\n  function: (identifier) @constructor\n  (#match? @constructor \"^[A-Z]\"))\n\n(call\n  function: (attribute attribute: (identifier) @function.method))\n\n(call\n  function: (identifier) @function)\n\n; Function definitions\n\n(function_definition\n  name: (identifier) @constructor\n  (#match? @constructor \"^(__new__|__init__|__moveinit__|__copyinit__)$\"))\n\n(function_definition\n  name: (identifier) @function)\n\n; Decorators\n\n(decorator) @function\n(decorator (identifier) @function)\n(decorator (attribute attribute: (identifier) @function))\n(decorator (call\n  function: (attribute attribute: (identifier) @function)))\n\n; Parameters\n\n((identifier) @variable.builtin\n  (#match? @variable.builtin \"^(self|cls)$\"))\n\n(parameters (identifier) @variable.parameter)\n(parameters (typed_parameter (identifier) @variable.parameter))\n(parameters (default_parameter name: (identifier) @variable.parameter))\n(parameters (typed_default_parameter name: (identifier) @variable.parameter))\n\n(parameters\n  (list_splat_pattern ; *args\n    (identifier) @variable.parameter))\n\n(parameters\n  (dictionary_splat_pattern ; **kwargs\n    (identifier) @variable.parameter))\n\n(lambda_parameters\n  (identifier) @variable.parameter)\n\n; Types\n\n((identifier) @type.builtin\n  (#match?\n    @type.builtin\n    \"^(bool|bytes|dict|float|frozenset|int|list|set|str|tuple)$\"))\n\n; In type hints make everything types to catch non-conforming identifiers\n; (e.g., datetime.datetime) and None\n(type [(identifier) (none)] @type)\n; Handle [] . and | nesting 4 levels deep\n(type\n  (_ [(identifier) (none)]? @type\n    (_ [(identifier) (none)]? @type\n      (_ [(identifier) (none)]? @type\n        (_ [(identifier) (none)]? @type)))))\n\n(class_definition name: (identifier) @type)\n(class_definition superclasses: (argument_list (identifier) @type))\n\n[\",\" \".\" \":\" \";\" (ellipsis)] @punctuation.delimiter\n(interpolation\n  \"{\" @punctuation.special\n  \"}\" @punctuation.special) @embedded\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n\n[\n  \"-\"\n  \"-=\"\n  \"!=\"\n  \"*\"\n  \"**\"\n  \"**=\"\n  \"*=\"\n  \"/\"\n  \"//\"\n  \"//=\"\n  \"/=\"\n  \"&\"\n  \"&=\"\n  \"%\"\n  \"%=\"\n  \"^\"\n  \"^=\"\n  \"+\"\n  \"->\"\n  \"+=\"\n  \"<\"\n  \"<<\"\n  \"<<=\"\n  \"<=\"\n  \"<>\"\n  \"=\"\n  \":=\"\n  \"==\"\n  \">\"\n  \">=\"\n  \">>\"\n  \">>=\"\n  \"|\"\n  \"|=\"\n  \"~\"\n  \"@=\"\n] @operator\n\n[\n  \"as\"\n  \"assert\"\n  \"await\"\n  \"from\"\n  \"pass\"\n  \"with\"\n] @keyword.control\n\n[\n  \"if\"\n  \"elif\"\n  \"else\"\n  \"match\"\n  \"case\"\n] @keyword.control.conditional\n\n[\n  \"while\"\n  \"for\"\n  \"break\"\n  \"continue\"\n] @keyword.control.repeat\n\n[\n  \"return\"\n  \"yield\"\n] @keyword.control.return\n\n(yield \"from\" @keyword.control.return)\n\n[\n  \"raise\"\n  \"raises\"\n  \"try\"\n  \"except\"\n  \"finally\"\n] @keyword.control.exception\n\n(raise_statement \"from\" @keyword.control.exception)\n\"import\" @keyword.control.import\n\n(for_statement \"in\" @keyword.control)\n(for_in_clause \"in\" @keyword.control)\n\n[\n  \"alias\"\n  \"async\"\n  \"class\"\n  \"exec\"\n  \"global\"\n  \"nonlocal\"\n  \"print\"\n  \"struct\"\n  ; \"trait\"\n] @keyword\n\n[\n  \"and\"\n  \"or\"\n  \"not in\"\n  \"in\"\n  \"not\"\n  \"del\"\n  \"is not\"\n  \"is\"\n] @keyword.operator\n\n\"var\" @keyword.storage\n\n[\n  \"borrowed\"\n  \"inout\"\n  \"owned\"\n] @keyword.storage.modifier\n\n((identifier) @type.builtin\n  (#match? @type.builtin\n    \"^(BaseException|Exception|ArithmeticError|BufferError|LookupError|AssertionError|AttributeError|EOFError|FloatingPointError|GeneratorExit|ImportError|ModuleNotFoundError|IndexError|KeyError|KeyboardInterrupt|MemoryError|NameError|NotImplementedError|OSError|OverflowError|RecursionError|ReferenceError|RuntimeError|StopIteration|StopAsyncIteration|SyntaxError|IndentationError|TabError|SystemError|SystemExit|TypeError|UnboundLocalError|UnicodeError|UnicodeEncodeError|UnicodeDecodeError|UnicodeTranslateError|ValueError|ZeroDivisionError|EnvironmentError|IOError|WindowsError|BlockingIOError|ChildProcessError|ConnectionError|BrokenPipeError|ConnectionAbortedError|ConnectionRefusedError|ConnectionResetError|FileExistsError|FileNotFoundError|InterruptedError|IsADirectoryError|NotADirectoryError|PermissionError|ProcessLookupError|TimeoutError|Warning|UserWarning|DeprecationWarning|PendingDeprecationWarning|SyntaxWarning|RuntimeWarning|FutureWarning|ImportWarning|UnicodeWarning|BytesWarning|ResourceWarning)$\"))\n"
  },
  {
    "path": "runtime/queries/mojo/indents.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/mojo/injections.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/mojo/locals.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/mojo/textobjects.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/move/highlights.scm",
    "content": "(ability) @keyword\n\n; ---\n; Primitives\n; ---\n\n(address_literal) @constant\n(bool_literal) @constant.builtin.boolean\n(num_literal) @constant.numeric\n[\n  (hex_string_literal)\n  (byte_string_literal)\n] @string\n; TODO: vector_literal\n\n[\n  (line_comment)\n  (block_comment)\n] @comment\n\n(annotation) @function.macro\n\n(borrow_expression \"&\" @keyword.storage.modifier.ref)\n(borrow_expression \"&mut\" @keyword.storage.modifier.mut)\n\n(identifier) @variable\n\n(constant_identifier) @constant\n((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z\\\\d_]*$\"))\n\n(function_identifier) @function\n\n(primitive_type) @type.builtin\n\n(struct_identifier) @type\n(pack_expression\n  access: (module_access\n    member: (identifier) @type))\n(apply_type\n  (module_access\n    member: (identifier) @type))\n(field_identifier) @variable.other.member\n\n; -------\n; Functions\n; -------\n\n(call_expression\n  access: (module_access\n    member: (identifier) @function))\n\n(macro_call_expression\n  access: (macro_module_access\n    access: (module_access\n      member: [(identifier) @function.macro])\n    \"!\" @function.macro))\n\n; -------\n; Paths\n; -------\n\n(module_identifier) @namespace\n\n; -------\n; Operators\n; -------\n\n[\n  \"*\"\n  \"=\"\n  \"!\"\n] @operator\n(binary_operator) @operator\n\n; ---\n; Punctuation\n; ---\n\n[\n  \"::\"\n  \".\"\n  \";\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \"abort\"\n  ; \"acquires\"\n  \"as\"\n  \"break\"\n  \"const\"\n  \"continue\"\n  \"copy\"\n  \"else\"\n  \"false\"\n  \"friend\"\n  \"fun\"\n  \"has\"\n  \"if\"\n  ; \"invariant\"\n  \"let\"\n  \"loop\"\n  \"module\"\n  \"move\"\n  \"native\"\n  \"public\"\n  \"return\"\n  ; \"script\"\n  \"spec\"\n  \"struct\"\n  \"true\"\n  \"use\"\n  \"while\"  \n\n  \"entry\"\n\n  ; \"aborts_if\"\n  ; \"aborts_with\"\n  \"address\"\n  \"apply\"\n  \"assume\"\n  ; \"axiom\"\n  ; \"choose\"\n  \"decreases\"\n  ; \"emits\"\n  \"ensures\"\n  \"except\"\n  ; \"forall\"\n  \"global\"\n  \"include\"\n  \"internal\"\n  \"local\"\n  ; \"min\"\n  ; \"modifies\"\n  \"mut\"\n  \"phantom\"\n  \"post\"\n  \"pragma\"\n  ; \"requires\"\n  ; \"Self\"\n  \"schema\"\n  \"succeeds_if\"\n  \"to\"\n  ; \"update\"\n  \"where\"\n  \"with\"\n] @keyword\n\n"
  },
  {
    "path": "runtime/queries/msbuild/highlights.scm",
    "content": "; inherits: xml\n"
  },
  {
    "path": "runtime/queries/msbuild/indents.scm",
    "content": "; inherits: xml\n"
  },
  {
    "path": "runtime/queries/msbuild/injections.scm",
    "content": "; inherits: xml\n"
  },
  {
    "path": "runtime/queries/nasm/highlights.scm",
    "content": "(comment) @comment\n\n(label) @label\n\n(preproc_expression) @keyword.directive\n\n(word) @variable\n((word) @constant\n  (#match? @constant \"^[A-Z_][?A-Z_0-9]+$\"))\n((word) @constant.builtin\n  (#match? @constant.builtin \"^__\\\\?[A-Z_a-z0-9]+\\\\?__$\"))\n\n[\n  (line_here_token)\n  (section_here_token)\n] @variable.builtin\n\n(unary_expression\n  operator: _ @operator)\n(binary_expression\n  operator: _ @operator)\n(conditional_expression\n  \"?\" @operator\n  \":\" @operator)\n\n[\n  \":\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n(instruction_prefix) @keyword\n(actual_instruction\n  instruction: (word) @function)\n\n(call_syntax_expression\n  base: (word) @function)\n\n(size_hint) @type\n(struc_declaration\n  name: (word) @type)\n(struc_instance\n  name: (word) @type)\n\n(effective_address\n hint: _ @type)\n(effective_address\n segment: _ @constant.builtin)\n\n(register) @constant.builtin\n\n(number_literal) @constant.numeric.integer\n(string_literal) @string\n(float_literal) @constant.numeric.float\n(packed_bcd_literal) @constant.numeric.integer\n\n(preproc_arg) @keyword.directive\n\n[\n  (preproc_def)\n  (preproc_function_def)\n  (preproc_undef)\n  (preproc_alias)\n  (preproc_multiline_macro)\n  (preproc_multiline_unmacro)\n  (preproc_if)\n  (preproc_rotate)\n  (preproc_rep_loop)\n  (preproc_include)\n  (preproc_pathsearch)\n  (preproc_depend)\n  (preproc_use)\n  (preproc_push)\n  (preproc_pop)\n  (preproc_repl)\n  (preproc_arg)\n  (preproc_stacksize)\n  (preproc_local)\n  (preproc_reporting)\n  (preproc_pragma)\n  (preproc_line)\n  (preproc_clear)\n] @keyword.directive\n[\n  (pseudo_instruction_dx)\n  (pseudo_instruction_resx)\n  (pseudo_instruction_incbin_command)\n  (pseudo_instruction_equ_command)\n  (pseudo_instruction_times_prefix)\n  (pseudo_instruction_alignx_macro)\n] @function.special\n[\n  (assembl_directive_target)\n  (assembl_directive_defaults)\n  (assembl_directive_sections)\n  (assembl_directive_absolute)\n  (assembl_directive_symbols)\n  (assembl_directive_common)\n  (assembl_directive_symbolfixes)\n  (assembl_directive_cpu)\n  (assembl_directive_floathandling)\n  (assembl_directive_org)\n  (assembl_directive_sectalign)\n\n  (assembl_directive_primitive_target)\n  (assembl_directive_primitive_defaults)\n  (assembl_directive_primitive_sections)\n  (assembl_directive_primitive_absolute)\n  (assembl_directive_primitive_symbols)\n  (assembl_directive_primitive_common)\n  (assembl_directive_primitive_symbolfixes)\n  (assembl_directive_primitive_cpu)\n  (assembl_directive_primitive_floathandling)\n  (assembl_directive_primitive_org)\n  (assembl_directive_primitive_sectalign)\n  (assembl_directive_primitive_warning)\n  (assembl_directive_primitive_map)\n] @keyword\n"
  },
  {
    "path": "runtime/queries/nasm/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/nasm/textobjects.scm",
    "content": "(preproc_multiline_macro\n  body: (body) @function.inside) @function.around\n(struc_declaration\n  body: (struc_declaration_body) @class.inside) @class.around\n(struc_instance\n  body: (struc_instance_body) @class.inside) @class.around\n\n(preproc_function_def_parameters\n  (word) @parameter.inside)\n(call_syntax_arguments\n  (_) @parameter.inside)\n(operand) @parameter.inside\n\n(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/nearley/highlights.scm",
    "content": "\n(comment) @comment.line\n\n(string) @string\n(string \"i\" @keyword.modifier)\n\n(identifier) @variable.other\n(rule_name (identifier) @function)\n(rule (generic (identifier) @function))\n\n(directive_name) @keyword.directive\n(directive_value (identifier) @constant)\n(directive_value (string) @string)\n\n(token) @constant\n\n(generic\n  \"<\" @punctuation.bracket\n  (identifier) @type.parameter\n  \">\" @punctuation.bracket\n)\n\n(group \"(\" @punctuation.bracket \")\" @punctuation.bracket)\n\n(charset) @string.regexp\n(wildcard) @keyword\n\n(quantifier) @function.builtin\n\n(macro_name\n  \"[\" @punctuation.bracket\n  (identifier) @variable.parameter\n  \"]\" @punctuation.bracket\n)\n(macro_arg) @variable.parameter\n\n(rule \"->\" @operator)\n(rule_body \"|\" @operator)\n\n(cont_block \"@{%\" @keyword.directive \"%}\" @keyword.directive)\n(cont_inline \"{%\" @keyword.directive \"%}\" @keyword.directive)\n\n(ifdef) @keyword.directive\n"
  },
  {
    "path": "runtime/queries/nearley/injections.scm",
    "content": "((cont) @injection.content\n  (#set! injection.language \"javascript\"))\n"
  },
  {
    "path": "runtime/queries/nearley/rainbows.scm",
    "content": "((group) @rainbow.scope)\n\n[\"(\" \")\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/nestedtext/highlights.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/nestedtext/indents.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/nestedtext/injections.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/nestedtext/textobjects.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/nginx/highlights.scm",
    "content": "(comment) @comment\n\n(block_directive\n\t(directive) @type)\n\n[\n\t\"{\"\n\t\"}\"\n\t\"(\"\n\t\")\"\n\t\"[\"\n\t\"]\"\n] @punctuation.bracket\n\n(simple_directive\n\t(directive) @function)\n\n[\n\t\";\"\n] @punctuation.delimiter\n\n((generic) @keyword\n (#any-of? @keyword\n \t\"on\"\n \t\"off\"\n \t\"any\"\n \t\"auto\"))\n\n(modifier) @operator\n\n(generic) @variable\n\n(string) @string\n\n(number) @constant.numeric\n(metric) @constant.numeric\n\n(variable) @variable.parameter\n\n(regex) @string\n\n(modifier) @keyword.operator\n\n(lua_block_directive\n\t\"access_by_lua_block\" @function)\n"
  },
  {
    "path": "runtime/queries/nginx/injections.scm",
    "content": "((lua_code) @injection.content\n (#set! injection.language \"lua\")\n (#set! injection.combined))\n\n((regex) @injection.content\n (#set! injection.language \"regex\"))\n\n((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/nickel/highlights.scm",
    "content": "(types) @type\n(type_builtin) @type.builtin\n\"Array\" @type.builtin\n\n(enum_tag) @constructor\n\n\"null\" @constant.builtin\n(bool) @constant.builtin.boolean\n(str_esc_char) @constant.character.escape\n(num_literal) @constant.numeric\n\n(str_chunks) @string\n\n; NOTE: Nickel has no block comments\n(comment) @comment.line\n; Nickel doesn't use comments for documentation, ideally this would be\n; `@documentation` or something similar\n(annot_atom\n  doc: (static_string) @comment.block.documentation\n)\n\n(record_operand (atom (ident) @variable))\n(let_in_block\n  \"let\" @keyword\n  \"rec\"? @keyword\n  \"in\" @keyword\n)\n\n(let_binding\n  pat: (pattern\n    (ident) @variable\n  )\n)\n\n(fun_expr\n  \"fun\" @keyword.function\n  pats:\n    (pattern_fun (ident) @variable.parameter)+\n  \"=>\" @operator\n)\n(record_field) @variable.other.member\n\n[\n  \".\"\n] @punctuation.delimiter\n[\n  \"{\" \"}\"\n  \"(\" \")\"\n  \"[|\" \"|]\"\n  \"[\" \"]\"\n] @punctuation.bracket\n(multstr_start) @punctuation.bracket\n(multstr_end) @punctuation.bracket\n(interpolation_start) @punctuation.bracket\n(interpolation_end) @punctuation.bracket\n\n[\"forall\" \"default\" \"doc\"] @keyword\n[\"if\" \"then\" \"else\" \"match\"] @keyword.control.conditional\n\"import\" @keyword.control.import\n\n(infix_expr\n  op: (_) @operator\n)\n\n(applicative\n  t1: (applicative\n    (record_operand) @function\n  )\n)\n(builtin) @function.builtin\n"
  },
  {
    "path": "runtime/queries/nickel/indents.scm",
    "content": "[\n  (fun_expr)\n  (let_expr)\n  (match_expr)\n  (ite_expr)\n\n  (uni_record)\n  (str_chunks_multi)\n  \"[\"\n  \"[|\"\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \"|]\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/nickel/injections.scm",
    "content": "(annot_atom doc: (static_string)\n            @injection.content\n            (#set! injection.language \"markdown\"))\n"
  },
  {
    "path": "runtime/queries/nim/highlights.scm",
    "content": ";; Constants, Comments, and Literals\n\n(comment) @comment.line\n(block_comment) @comment.block\n[\n  (documentation_comment)\n  (block_documentation_comment)\n] @comment.block.documentation\n\n(nil_literal) @constant.builtin\n\n(char_literal) @constant.character\n(escape_sequence) @constant.character.escape\n(custom_numeric_literal) @constant.numeric\n(integer_literal) @constant.numeric.integer\n(float_literal) @constant.numeric.float\n; literals\n; todo: literal?\n\n[\n  (long_string_literal)\n  (raw_string_literal)\n  (generalized_string)\n  (interpreted_string_literal)\n] @string\n; (generalized_string (string_content) @none) ; todo: attempt to un-match string_content\n; [] @string.regexp\n\n[\n  \".\"\n  \",\"\n  \";\"\n  \":\"\n] @punctuation.delimiter\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"{.\"\n  \".}\"\n] @punctuation.bracket\n; todo: interpolated_str_lit?? & { }?\n\n[\n  \"and\"\n  \"or\"\n  \"xor\"\n  \"not\"\n  \"div\"\n  \"mod\"\n  \"shl\"\n  \"shr\"\n  \"from\"\n  \"as\"\n  \"of\"\n  \"in\"\n  \"notin\"\n  \"is\"\n  \"isnot\"\n] @keyword.operator\n\n[(operator) \"=\"] @operator\n(infix_expression operator: _ @operator)\n(prefix_expression operator: _ @operator)\n\n(pragma_list\n  (identifier)? @attribute\n  (colon_expression\n    (identifier) @attribute)?)\n\n;; Imports and Exports\n\n[\n  \"import\"\n  \"export\"\n  \"include\"\n  \"from\"\n] @keyword.control.import\n\n(import_statement\n  [\n    (identifier) @namespace\n    (expression_list (identifier) @namespace)\n    (except_clause\n      \"except\" @keyword.control.import\n      (expression_list (identifier) @namespace))])\n(import_from_statement\n  (identifier) @namespace\n  (expression_list (identifier) @namespace))\n(include_statement (expression_list (identifier) @namespace))\n(export_statement (expression_list (identifier) @namespace))\n\n;; Control Flow\n\n[\n  \"if\"\n  \"when\"\n  \"case\"\n  \"elif\"\n  \"else\"\n] @keyword.control.conditional\n(of_branch \"of\" @keyword.control.conditional)\n; conditional statements\n; todo: do block\n\n\"block\" @keyword.control\n(block label: (_) @label)\n\n[\n  \"for\"\n  \"while\"\n  \"continue\"\n  \"break\"\n] @keyword.control.repeat\n(for \"in\" @keyword.control.repeat)\n\n[\n  \"return\"\n  \"yield\"\n] @keyword.control.return\n; return statements\n\n[\n  \"try\"\n  \"except\"\n  \"finally\"\n  \"raise\"\n] @keyword.control.exception\n; exception handling statements\n\n[\n  \"asm\"\n  \"bind\"\n  \"mixin\"\n  \"defer\"\n  \"static\"\n] @keyword\n; miscellaneous keywords\n\n;; Types and Type Declarations\n\n[\n  \"let\"\n  \"var\"\n  \"const\"\n  \"type\"\n  \"object\"\n  \"tuple\"\n  \"enum\"\n  \"concept\"\n] @keyword.storage.type\n\n(var_type \"var\" @keyword.storage.modifier)\n(out_type \"out\" @keyword.storage.modifier)\n(distinct_type \"distinct\" @keyword.storage.modifier)\n(ref_type \"ref\" @keyword.storage.modifier)\n(pointer_type \"ptr\" @keyword.storage.modifier)\n\n(var_parameter \"var\" @keyword.storage.modifier)\n(type_parameter \"type\" @keyword.storage.modifier)\n(static_parameter \"static\" @keyword.storage.modifier)\n(ref_parameter \"ref\" @keyword.storage.modifier)\n(pointer_parameter \"ptr\" @keyword.storage.modifier)\n; (var_parameter (identifier) @variable.parameter)\n; (type_parameter (identifier) @variable.parameter)\n; (static_parameter (identifier) @variable.parameter)\n; (ref_parameter (identifier) @variable.parameter)\n; (pointer_parameter (identifier) @variable.parameter)\n; todo: when are these used??\n\n(type_section\n  (type_declaration\n    (type_symbol_declaration\n      name: (_) @type)))\n; types in type declarations\n\n(enum_field_declaration\n  (symbol_declaration\n    name: (_) @type.enum.variant))\n; types as enum variants\n\n(variant_declaration\n  alternative: (of_branch\n    values: (expression_list (_) @type.enum.variant)))\n; types as object variants\n\n(case\n  (of_branch\n    values: (expression_list (_) @constant)))\n; case values are guaranteed to be constant\n\n(type_expression\n  [\n    (identifier) @type\n    (bracket_expression\n      [\n        (identifier) @type\n        (argument_list (identifier) @type)])\n    (tuple_construction\n      [\n        (identifier) @type\n        (bracket_expression\n          [\n            (identifier) @type\n            (argument_list (identifier) @type)])])])\n; types in type expressions\n\n(call\n  function: (bracket_expression\n    right: (argument_list (identifier) @type)))\n; types as generic parameters\n\n; (dot_generic_call\n;   generic_arguments: (_) @type)\n; ???\n\n(infix_expression\n  operator:\n    [\n      \"is\"\n      \"isnot\"\n    ]\n  right: (_) @type)\n; types in \"is\" comparisons\n\n(except_branch\n  values: (expression_list\n    [\n      (identifier) @type\n      (infix_expression\n        left: (identifier) @type\n        operator: \"as\"\n        right: (_) @variable)]))\n; types in exception branches\n\n;; Functions\n\n[\n  \"proc\"\n  \"func\"\n  \"method\"\n  \"converter\"\n  \"iterator\"\n  \"template\"\n  \"macro\"\n] @keyword.function\n\n(exported_symbol \"*\" @attribute)\n(_ \"=\" @punctuation.delimiter [body: (_) value: (_)])\n\n(proc_declaration name: (_) @function)\n(func_declaration name: (_) @function)\n(iterator_declaration name: (_) @function)\n(converter_declaration name: (_) @function)\n(method_declaration name: (_) @function.method)\n(template_declaration name: (_) @function.macro)\n(macro_declaration name: (_) @function.macro)\n(symbol_declaration name: (_) @variable)\n\n(call\n  function: [\n    (identifier) @function.call\n    (dot_expression\n      right: (identifier) @function.call)\n    (bracket_expression\n      left: [\n        (identifier) @function.call\n        (dot_expression\n          right: (identifier) @function.call)])])\n(generalized_string\n  function: [\n    (identifier) @function.call\n    (dot_expression\n      right: (identifier) @function.call)\n    (bracket_expression\n      left: [\n        (identifier) @function.call\n        (dot_expression\n          right: (identifier) @function.call)])])\n(dot_generic_call function: (_) @function.call)\n\n;; Variables\n\n(parameter_declaration\n  (symbol_declaration_list\n    (symbol_declaration\n      name: (_) @variable.parameter)))\n(argument_list\n  (equal_expression\n    left: (_) @variable.parameter))\n(concept_declaration\n  parameters: (parameter_list (identifier) @variable.parameter))\n\n(field_declaration\n  (symbol_declaration_list\n    (symbol_declaration\n      name: (_) @variable.other.member)))\n(call\n  (argument_list\n    (colon_expression\n      left: (_) @variable.other.member)))\n(tuple_construction\n  (colon_expression\n    left: (_) @variable.other.member))\n(variant_declaration\n  (variant_discriminator_declaration\n    (symbol_declaration_list\n      (symbol_declaration\n        name: (_) @variable.other.member))))\n\n;; Miscellaneous Matches\n\n[\n  \"cast\"\n  \"discard\"\n  \"do\"\n] @keyword\n; also: addr end interface using\n\n(blank_identifier) @variable.builtin\n\n; Highlight left side of dot expressions (variables being accessed)\n(dot_expression\n  left: (identifier) @variable)\n\n;; ============================================================================\n;; Fallback identifier patterns (applied last, after all specific contexts)\n;; ============================================================================\n\n;; Special built-in identifiers\n((identifier) @variable.builtin\n  (#eq? @variable.builtin \"result\"))\n\n;; Built-in constants\n((identifier) @constant.builtin\n  (#match? @constant.builtin \"^(NaN|Inf|NegInf|isMainModule|appType|CompileDate|CompileTime|cpuEndian|hostOS|hostCPU|NimVersion|NimMajor|NimMinor|NimPatch|nimvm|QuitSuccess|QuitFailure)$\"))\n\n;; Built-in boolean constants\n((identifier) @constant.builtin.boolean\n  (#any-of? @constant.builtin.boolean \"true\" \"false\" \"on\" \"off\"))\n\n;; Built-in types (primitive and common types)\n((identifier) @type.builtin\n  (#match? @type.builtin \"^(int|int8|int16|int32|int64|uint|uint8|uint16|uint32|uint64|float|float32|float64|bool|char|string|cstring|pointer|ptr|ref|void|auto|any|type|typed|untyped|typedesc|range|array|openArray|openarray|varargs|seq|set|tuple|object|enum|concept|distinct|proc|iterator|cstringArray|csize|csize_t|clonglong|culonglong|clong|culong|cint|cuint|cshort|cushort|cchar|cschar|cuchar|cfloat|cdouble|clongdouble|byte|Natural|Positive|sink|lent|owned|iterable|static)$\"))\n\n;; Constants (ALL_CAPS naming convention) - fallback for unmatched identifiers\n((identifier) @constant\n  (#match? @constant \"^[A-Z][A-Z0-9_]*$\"))\n\n;; Type names (PascalCase - starts with capital, contains lowercase) - fallback\n((identifier) @type\n  (#match? @type \"^[A-Z][a-z]\"))\n"
  },
  {
    "path": "runtime/queries/nim/indents.scm",
    "content": "[\n  (if)\n  (when)\n  (elif_branch)\n  (else_branch)\n  (of_branch) ; note: not case_statement\n  (block)\n  (while)\n  (for)\n  (try)\n  (except_branch)\n  (finally_branch)\n  (defer)\n  (static_statement)\n  (proc_declaration)\n  (func_declaration)\n  (iterator_declaration)\n  (converter_declaration)\n  (method_declaration)\n  (template_declaration)\n  (macro_declaration)\n  (symbol_declaration)\n] @indent\n;; increase the indentation level\n\n[\n  (if)\n  (when)\n  (elif_branch)\n  (else_branch)\n  (of_branch) ; note: not case_statement\n  (block)\n  (while)\n  (for)\n  (try)\n  (except_branch)\n  (finally_branch)\n  (defer)\n  (static_statement)\n  (proc_declaration)\n  (func_declaration)\n  (iterator_declaration)\n  (converter_declaration)\n  (method_declaration)\n  (template_declaration)\n  (macro_declaration)\n  (symbol_declaration)\n] @extend\n;; ???\n\n[\n  (return_statement)\n  (raise_statement)\n  (yield_statement)\n  (break_statement)\n  (continue_statement)\n] @extend.prevent-once\n;; end a level of indentation while staying indented\n\n[\n  \")\" ; tuples\n  \"]\" ; arrays, seqs\n  \"}\" ; sets\n] @outdent\n;; end a level of indentation and unindent the line\n"
  },
  {
    "path": "runtime/queries/nim/injections.scm",
    "content": "([(comment (comment_content) @injection.content)\n  (block_comment (comment_content) @injection.content)]\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/nim/textobjects.scm",
    "content": "(proc_declaration\n  body: (_) @function.inside) @function.around\n(func_declaration\n  body: (_) @function.inside) @function.around\n(iterator_declaration\n  body: (_) @function.inside) @function.around\n(converter_declaration\n  body: (_) @function.inside) @function.around\n(method_declaration\n  body: (_) @function.inside) @function.around\n(template_declaration\n  body: (_) @function.inside) @function.around\n(macro_declaration\n  body: (_) @function.inside) @function.around\n\n(type_declaration (_) @class.inside) @class.around\n\n(parameter_declaration\n  (symbol_declaration_list) @parameter.inside) @parameter.around\n\n[\n  (comment)\n  (block_comment)\n  (documentation_comment)\n  (block_documentation_comment)\n] @comment.inside\n\n[\n  (comment)+\n  (block_comment)\n  (documentation_comment)+\n  (block_documentation_comment)+\n] @comment.around\n"
  },
  {
    "path": "runtime/queries/nix/highlights.scm",
    "content": "(comment) @comment\n\n[\n  \";\"\n  \".\"\n  \",\"\n  \"=\"\n  \":\"\n  (ellipses)\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n\"assert\" @keyword.control.exception\n\"or\" @keyword.operator\n\"rec\" @keyword.control.repeat\n\n[\n  \"if\" \n  \"then\"\n  \"else\"\n] @keyword.control.conditional\n\n[\n  \"let\"\n  \"inherit\"\n  \"in\"\n  \"with\" \n] @keyword\n\n(variable_expression name: (identifier) @variable)\n\n(select_expression\n  attrpath: (attrpath attr: (identifier)) @variable.other.member)\n\n(apply_expression\n  function: [\n    (variable_expression name: (identifier) @function)\n    (select_expression\n      attrpath: (attrpath\n        attr: (identifier) @function .))])\n\n((identifier) @variable.builtin\n (#match? @variable.builtin \"^(__currentSystem|__currentTime|__nixPath|__nixVersion|__storeDir|builtins)$\")\n (#is-not? local))\n\n((identifier) @function.builtin\n (#match? @function.builtin \"^(__add|__addErrorContext|__all|__any|__appendContext|__attrNames|__attrValues|__bitAnd|__bitOr|__bitXor|__catAttrs|__compareVersions|__concatLists|__concatMap|__concatStringsSep|__deepSeq|__div|__elem|__elemAt|__fetchurl|__filter|__filterSource|__findFile|__foldl'|__fromJSON|__functionArgs|__genList|__genericClosure|__getAttr|__getContext|__getEnv|__hasAttr|__hasContext|__hashFile|__hashString|__head|__intersectAttrs|__isAttrs|__isBool|__isFloat|__isFunction|__isInt|__isList|__isPath|__isString|__langVersion|__length|__lessThan|__listToAttrs|__mapAttrs|__match|__mul|__parseDrvName|__partition|__path|__pathExists|__readDir|__readFile|__replaceStrings|__seq|__sort|__split|__splitVersion|__storePath|__stringLength|__sub|__substring|__tail|__toFile|__toJSON|__toPath|__toXML|__trace|__tryEval|__typeOf|__unsafeDiscardOutputDependency|__unsafeDiscardStringContext|__unsafeGetAttrPos|__valueSize|abort|baseNameOf|derivation|derivationStrict|dirOf|fetchGit|fetchMercurial|fetchTarball|fromTOML|import|isNull|map|placeholder|removeAttrs|scopedImport|throw|toString)$\")\n (#is-not? local))\n\n[\n  (string_expression)\n  (indented_string_expression)\n] @string\n\n[\n  (path_expression)\n  (hpath_expression)\n  (spath_expression)\n] @string.special.path\n\n(uri_expression) @string.special.uri\n\n; boolean\n((identifier) @constant.builtin.boolean (#match? @constant.builtin.boolean \"^(true|false)$\")) @constant.builtin.boolean\n; null\n((identifier) @constant.builtin (#eq? @constant.builtin \"null\")) @constant.builtin\n\n(integer_expression) @constant.numeric.integer\n(float_expression) @constant.numeric.float\n\n(escape_sequence) @constant.character.escape\n(dollar_escape) @constant.character.escape\n\n(function_expression\n  \"@\"? @punctuation.delimiter\n  universal: (identifier) @variable.parameter\n  \"@\"? @punctuation.delimiter\n)\n\n(formal\n  name: (identifier) @variable.parameter\n  \"?\"? @punctuation.delimiter)\n\n(interpolation\n  \"${\" @punctuation.special\n  \"}\" @punctuation.special) @embedded\n\n(unary_expression\n  operator: _ @operator)\n\n(binary_expression\n  operator: _ @operator)\n\n(binding\n  attrpath: (attrpath attr: (identifier)) @variable.other.member)\n\n(inherit_from attrs: (inherited_attrs attr: (identifier) @variable.other.member))\n(inherited_attrs attr: (identifier) @variable)\n\n(has_attr_expression\n  expression: (_)\n  \"?\" @operator\n  attrpath: (attrpath\n    attr: (identifier) @variable.other.member))\n"
  },
  {
    "path": "runtime/queries/nix/indents.scm",
    "content": "[\n  (indented_string_expression)\n  (string_expression)\n\n  ; these are all direct parents of (binding_set)\n  (attrset_expression)\n  (let_attrset_expression)\n  (rec_attrset_expression)\n  (let_expression)\n\n  (list_expression)\n  (parenthesized_expression)\n] @indent\n\n\n(if_expression [ \"if\" \"then\" \"else\" ] @align)\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/nix/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; mark arbitrary languages with a comment\n((((comment) @injection.language) .\n  (indented_string_expression (string_fragment) @injection.content))\n  (#set! injection.combined))\n((binding\n    (comment) @injection.language\n    expression: (indented_string_expression (string_fragment) @injection.content))\n  (#set! injection.combined))\n\n; Common attribute keys corresponding to Python scripts,\n; such as those for NixOS VM tests in nixpkgs/nixos/tests.\n((binding\n   attrpath: (attrpath (identifier) @_path)\n   expression: (indented_string_expression\n     (string_fragment) @injection.content))\n (#match? @_path \"(^|\\\\.)testScript$\")\n (#set! injection.language \"python\")\n (#set! injection.combined))\n\n; Common attribute keys corresponding to scripts,\n; such as those of stdenv.mkDerivation.\n((binding\n   attrpath: (attrpath (identifier) @_path)\n   expression: [\n     (indented_string_expression (string_fragment) @injection.content)\n     (binary_expression (indented_string_expression (string_fragment) @injection.content))\n   ])\n (#match? @_path \"(^\\\\w*Phase|command|(pre|post)\\\\w*|(.*\\\\.)?\\\\w*([sS]cript|[hH]ook)|(.*\\\\.)?startup)$\")\n (#set! injection.language \"bash\")\n (#set! injection.combined))\n\n; builtins.{match,split} regex str\n; Example: nix/tests/lang/eval-okay-regex-{match,split}.nix\n((apply_expression\n   function: (_) @_func\n   argument: (indented_string_expression (string_fragment) @injection.content))\n (#match? @_func \"(^|\\\\.)match|split$\")\n (#set! injection.language \"regex\")\n (#set! injection.combined))\n\n; builtins.fromJSON json\n; Example: nix/tests/lang/eval-okay-fromjson.nix\n((apply_expression\n   function: (_) @_func\n   argument: (indented_string_expression (string_fragment) @injection.content))\n (#match? @_func \"(^|\\\\.)fromJSON$\")\n (#set! injection.language \"json\")\n (#set! injection.combined))\n\n; builtins.fromTOML toml\n; Example: https://github.com/NixOS/nix/blob/3e8cd2ffe6c2c6ed8aae7853ddcfcc6d2a49b0ce/tests/functional/lang/eval-okay-fromTOML.nix\n((apply_expression\n   function: (_) @_func\n   argument: (indented_string_expression (string_fragment) @injection.content))\n (#match? @_func \"(^|\\\\.)fromTOML$\")\n (#set! injection.language \"toml\")\n (#set! injection.combined))\n\n; trivial-builders.nix pkgs.writeShellScript[Bin] name content\n((apply_expression\n   function: (apply_expression function: (_) @_func)\n   argument: (indented_string_expression (string_fragment) @injection.content))\n (#match? @_func \"(^|\\\\.)writeShellScript(Bin)?$\")\n (#set! injection.language \"bash\")\n (#set! injection.combined))\n\n; trivial-builders.nix, aliases.nix\n; pkgs.runCommand[[No]CC][Local] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)runCommand(((No)?(CC))?(Local)?)?$\")\n  (#set! injection.language \"bash\")\n  (#set! injection.combined))\n\n; trivial-builders.nix pkgs.writeShellApplication { text = content; }\n(apply_expression\n  function: ((_) @_func)\n  argument: (_ (_)* (_ (_)* (binding\n    attrpath: (attrpath (identifier) @_path)\n     expression: (indented_string_expression\n       (string_fragment) @injection.content))))\n  (#match? @_func \"(^|\\\\.)writeShellApplication$\")\n  (#match? @_path \"^text$\")\n  (#set! injection.language \"bash\")\n  (#set! injection.combined))\n\n; trivial-builders.nix pkgs.writeCBin name content\n((apply_expression\n   function: (apply_expression function: (_) @_func)\n   argument: (indented_string_expression (string_fragment) @injection.content))\n (#match? @_func \"(^|\\\\.)writeC(Bin)?$\")\n (#set! injection.language \"c\")\n (#set! injection.combined))\n\n; pkgs.writers.* usage examples: nixpkgs/pkgs/build-support/writers/test.nix\n\n; pkgs.writers.write{Bash,Dash}[Bin] name content\n((apply_expression\n   function: (apply_expression function: (_) @_func)\n   argument: (indented_string_expression (string_fragment) @injection.content))\n (#match? @_func \"(^|\\\\.)write[BD]ash(Bin)?$\")\n (#set! injection.language \"bash\")\n (#set! injection.combined))\n\n; pkgs.writers.writeFish[Bin] name content\n((apply_expression\n   function: (apply_expression function: (_) @_func)\n   argument: (indented_string_expression (string_fragment) @injection.content))\n (#match? @_func \"(^|\\\\.)writeFish(Bin)?$\")\n (#set! injection.language \"fish\")\n (#set! injection.combined))\n\n; pkgs.writers.writeRust[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writeRust(Bin)?$\")\n  (#set! injection.language \"rust\")\n  (#set! injection.combined))\n\n; pkgs.writers.writeHaskell[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writeHaskell(Bin)?$\")\n  (#set! injection.language \"haskell\")\n  (#set! injection.combined))\n\n; pkgs.writers.writeNim[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writeNim(Bin)?$\")\n  (#set! injection.language \"nim\")\n  (#set! injection.combined))\n\n; pkgs.writers.writeJS[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writeJS(Bin)?$\")\n  (#set! injection.language \"javascript\")\n  (#set! injection.combined))\n\n; pkgs.writers.writePerl[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writePerl(Bin)?$\")\n  (#set! injection.language \"perl\")\n  (#set! injection.combined))\n\n; pkgs.writers.write{Python,PyPy}{2,3}[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)write(Python|PyPy)[23](Bin)?$\")\n  (#set! injection.language \"python\")\n  (#set! injection.combined))\n\n; pkgs.writers.writeNu[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writeNu(Bin)?$\")\n  (#set! injection.language \"nu\")\n  (#set! injection.combined))\n\n; pkgs.writers.writeRuby[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writeRuby(Bin)?$\")\n  (#set! injection.language \"ruby\")\n  (#set! injection.combined))\n\n; pkgs.writers.writeLua[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writeLua(Bin)?$\")\n  (#set! injection.language \"lua\")\n  (#set! injection.combined))\n\n; pkgs.writers.writeNginxConfig name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writeNginxConfig$\")\n  (#set! injection.language \"nginx\")\n  (#set! injection.combined))\n\n; pkgs.writers.writeGuile[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writeGuile(Bin)?$\")\n  (#set! injection.language \"scheme\") ; Guile is a GNU specific implementation of scheme\n  (#set! injection.combined))\n\n\n; pkgs.writers.writeBabashka[Bin] name attrs content\n(apply_expression\n  (apply_expression\n    function: (apply_expression\n      function: ((_) @_func)))\n    argument: (indented_string_expression (string_fragment) @injection.content)\n  (#match? @_func \"(^|\\\\.)writeBabashka(Bin)?$\")\n  (#set! injection.language \"clojure\")\n  (#set! injection.combined))\n\n; pkgs.writers.writeFSharp[Bin] name content\n; No query available for f-sharp as of the time of writing\n; See: https://github.com/helix-editor/helix/issues/4943\n; ((apply_expression\n;    function: (apply_expression function: (_) @_func)\n;    argument: (indented_string_expression (string_fragment) @injection.content))\n;  (#match? @_func \"(^|\\\\.)writeFSharp(Bin)?$\")\n;  (#set! injection.language \"f-sharp\")\n;  (#set! injection.combined))\n\n((apply_expression\n   function: (apply_expression function: (_) @_func\n     argument: (string_expression (string_fragment) @injection.filename))\n   argument: (indented_string_expression (string_fragment) @injection.content))\n (#match? @_func \"(^|\\\\.)write(Text|Script(Bin)?)$\")\n (#set! injection.combined))\n\n((indented_string_expression (string_fragment) @injection.shebang @injection.content)\n  (#set! injection.combined))\n\n; string contents of lib.literalExpression is nix code\n((apply_expression\n    function: [\n      (select_expression) ; `lib.literalExpression`\n      (variable_expression) ; `literalExpression` this is the case when the symbol is brougth into scope e.g. `let inherit (lib) literalExpression; in`\n    ] @_func\n    argument: [\n      (indented_string_expression (string_fragment) @injection.content)  ; lib.literalExpression ''...''\n      (string_expression (string_fragment) @injection.content) ; lib.literalExpression \"...\"\n    ])\n  (#any-of? @_func \"lib.literalExpression\" \"literalExpression\")\n  (#set! injection.language \"nix\")\n  (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/nix/rainbows.scm",
    "content": "[\n  (formals)\n  (parenthesized_expression)\n  (attrset_expression)\n  (let_attrset_expression)\n  (rec_attrset_expression)\n  (inherit_from)\n  (interpolation)\n  (list_expression)\n] @rainbow.scope\n\n[\n  \"${\"\n  \"{\" \"}\"\n  \"(\" \")\"\n  \"[\" \"]\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/nix/textobjects.scm",
    "content": "(comment) @comment.inside\n(comment)+ @comment.around\n\n(formals\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(function_expression\n  body: (_) @function.inside) @function.around\n\n(binding\n  (_) @entry.inside) @entry.around\n\n"
  },
  {
    "path": "runtime/queries/nu/folds.scm",
    "content": "[\n  (attribute_list)\n  (block)\n  (command_list)\n  (parameter_bracks)\n  (record_body)\n  (val_list)\n  (val_table)\n  (val_closure)\n] @fold\n"
  },
  {
    "path": "runtime/queries/nu/highlights.scm",
    "content": "; ---\n; keywords\n[\n  \"let\"\n  \"mut\"\n  \"const\"\n] @keyword\n\n[\n  \"if\"\n  \"else\"\n  \"match\"\n] @keyword.control.conditional\n\n[\n  \"loop\"\n  \"while\"\n] @keyword.control.repeat\n\n\"def\" @keyword.function\n\n[\n  \"try\"\n  \"catch\"\n  \"error\"\n] @keyword.control.exception\n\n[\n  \"module\"\n  \"use\"\n] @keyword.control.import\n\n[\n  \"alias\"\n  \"export-env\"\n  \"export\"\n  \"extern\"\n] @keyword.storage.modifier\n\n(decl_use\n  \"use\" @keyword.control.import)\n\n(ctrl_for\n  \"for\" @keyword.control.repeat\n  \"in\" @keyword.control.repeat)\n\n; ---\n; literals\n(val_number) @constant.numeric\n\n(val_duration\n  unit: _ @variable.parameter)\n\n(val_filesize\n  unit: _ @variable.parameter)\n\n(val_binary\n  [\n    \"0b\"\n    \"0o\"\n    \"0x\"\n  ] @constant.numeric\n  \"[\" @punctuation.bracket\n  digit: [\n    \",\" @punctuation.delimiter\n    (hex_digit) @constant.numeric\n  ]\n  \"]\" @punctuation.bracket) @constant.numeric\n\n(val_bool) @constant.builtin.boolean\n\n(val_nothing) @constant.builtin\n\n(val_string) @string\n\narg_str: (val_string) @variable.parameter\n\nfile_path: (val_string) @variable.parameter\n\n(val_date) @constant.numeric\n\n(inter_escape_sequence) @constant.character.escape\n\n(escape_sequence) @constant.character.escape\n\n(val_interpolated\n  [\n    \"$\\\"\"\n    \"$\\'\"\n    \"\\\"\"\n    \"\\'\"\n  ] @string)\n\n(unescaped_interpolated_content) @string\n\n(escaped_interpolated_content) @string\n\n(expr_interpolated\n  [\n    \"(\"\n    \")\"\n  ] @variable.parameter)\n\n(raw_string_begin) @punctuation.special\n\n(raw_string_end) @punctuation.special\n\n; ---\n; operators\n(expr_binary\n  opr: _ @operator)\n\n(where_predicate\n  opr: _ @operator)\n\n(assignment\n  [\n    \"=\"\n    \"+=\"\n    \"-=\"\n    \"*=\"\n    \"/=\"\n    \"++=\"\n  ] @operator)\n\n(expr_unary\n  [\n    \"not\"\n    \"-\"\n  ] @operator)\n\n(val_range\n  [\n    \"..\"\n    \"..=\"\n    \"..<\"\n  ] @operator)\n\n[\n  \"=>\"\n  \"=\"\n  \"|\"\n] @operator\n\n[\n  \"o>\"\n  \"out>\"\n  \"e>\"\n  \"err>\"\n  \"e+o>\"\n  \"err+out>\"\n  \"o+e>\"\n  \"out+err>\"\n  \"o>>\"\n  \"out>>\"\n  \"e>>\"\n  \"err>>\"\n  \"e+o>>\"\n  \"err+out>>\"\n  \"o+e>>\"\n  \"out+err>>\"\n  \"e>|\"\n  \"err>|\"\n  \"e+o>|\"\n  \"err+out>|\"\n  \"o+e>|\"\n  \"out+err>|\"\n] @operator\n\n; ---\n; punctuation\n[\n  \",\"\n  \";\"\n] @punctuation.special\n\n(param_long_flag\n  \"--\" @punctuation.delimiter)\n\n(long_flag\n  \"--\" @punctuation.delimiter)\n\n(short_flag\n  \"-\" @punctuation.delimiter)\n\n(long_flag\n  \"=\" @punctuation.special)\n\n(short_flag\n  \"=\" @punctuation.special)\n\n(param_short_flag\n  \"-\" @punctuation.delimiter)\n\n(param_rest\n  \"...\" @punctuation.delimiter)\n\n(param_type\n  \":\" @punctuation.special)\n\n(param_value\n  \"=\" @punctuation.special)\n\n(param_cmd\n  \"@\" @punctuation.special)\n\n(attribute\n  \"@\" @punctuation.special)\n\n(param_opt\n  \"?\" @punctuation.special)\n\n(returns\n  \"->\" @punctuation.special)\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"...[\"\n  \"...(\"\n  \"...{\"\n] @punctuation.bracket\n\n(val_record\n  (record_entry\n    \":\" @punctuation.delimiter))\n\nkey: (identifier) @property\n\n; ---\n; identifiers\n(param_rest\n  name: (_) @variable.parameter)\n\n(param_opt\n  name: (_) @variable.parameter)\n\n(parameter\n  param_name: (_) @variable.parameter)\n\n(param_cmd\n  (cmd_identifier) @string)\n\n(param_long_flag\n  (long_flag_identifier) @attribute)\n\n(param_short_flag\n  (param_short_flag_identifier) @attribute)\n\n(attribute\n  (attribute_identifier) @attribute)\n\n(short_flag\n  (short_flag_identifier) @attribute)\n\n(long_flag_identifier) @attribute\n\n(scope_pattern\n  (wild_card) @function)\n\n(cmd_identifier) @function\n\n(decl_def . \"def\"\n  (val_string\n    (string_content) @function\n  )\n)\n\n; generated with Nu 0.107.0\n; help commands\n; | where $it.command_type == built-in and $it.category != core\n; | each {$'\"($in.name | split row \" \" | $in.0)\"'}\n; | uniq\n; | str join ' '\n(command\n  head: (cmd_identifier) @function.builtin\n  (#any-of? @function.builtin\n    \"all\" \"ansi\" \"any\" \"append\" \"ast\" \"bits\" \"bytes\" \"cal\" \"cd\" \"char\" \"chunk-by\" \"chunks\" \"clear\" \"collect\" \"columns\" \"compact\" \"complete\" \"config\" \"cp\" \"date\" \"debug\" \"decode\" \"default\" \"detect\" \"drop\" \"du\" \"each\" \"encode\" \"enumerate\" \"every\" \"exec\" \"exit\" \"explain\" \"explore\" \"fill\" \"filter\" \"find\" \"first\" \"flatten\" \"format\" \"from\" \"generate\" \"get\" \"glob\" \"grid\" \"group-by\" \"hash\" \"headers\" \"histogram\" \"history\" \"http\" \"input\" \"insert\" \"inspect\" \"interleave\" \"into\" \"is-empty\" \"is-not-empty\" \"is-terminal\" \"items\" \"job\" \"join\" \"keybindings\" \"kill\" \"last\" \"length\" \"let-env\" \"lines\" \"load-env\" \"ls\" \"math\" \"merge\" \"metadata\" \"mkdir\" \"mktemp\" \"move\" \"mv\" \"nu-check\" \"nu-highlight\" \"open\" \"panic\" \"par-each\" \"parse\" \"path\" \"plugin\" \"port\" \"prepend\" \"print\" \"ps\" \"query\" \"random\" \"reduce\" \"reject\" \"rename\" \"reverse\" \"rm\" \"roll\" \"rotate\" \"run-external\" \"save\" \"schema\" \"select\" \"seq\" \"shuffle\" \"skip\" \"sleep\" \"slice\" \"sort\" \"sort-by\" \"split\" \"start\" \"stor\" \"str\" \"sys\" \"table\" \"take\" \"tee\" \"term\" \"timeit\" \"to\" \"touch\" \"transpose\" \"tutor\" \"ulimit\" \"uname\" \"uniq\" \"uniq-by\" \"update\" \"upsert\" \"url\" \"values\" \"version\" \"view\" \"watch\" \"which\" \"whoami\" \"window\" \"with-env\" \"wrap\" \"zip\"))\n\n(command\n  head: (cmd_identifier) @keyword.control.repeat\n  (#any-of? @keyword.control.repeat \"break\" \"continue\" \"return\"))\n\n(command\n  head: (cmd_identifier) @keyword\n  (#any-of? @keyword \"do\" \"source\" \"source-env\" \"hide\" \"hide-env\"))\n\n(command\n  head: (cmd_identifier) @keyword\n  .\n  arg_str: (val_string) @keyword.control.import\n  (#any-of? @keyword \"overlay\" \"error\"))\n\n(command\n  head: (cmd_identifier) @cmd\n  arg_str: (val_string) @keyword\n  (#eq? @cmd \"overlay\")\n  (#eq? @keyword \"as\"))\n\n(command\n  \"^\" @punctuation.delimiter\n  head: (_) @function)\n\n\"where\" @function.builtin\n\n(where_predicate\n  [\n    \"?\"\n    \"!\"\n  ] @punctuation.delimiter)\n\n(path\n  [\n    \".\"\n    \"?\"\n    \"!\"\n  ]? @punctuation.delimiter) @variable.parameter\n\n(stmt_let\n  (identifier) @variable)\n\n(val_variable\n  \"$\"? @punctuation.special\n  \"...$\"? @punctuation.special\n  [\n    (identifier) @variable\n    \"in\" @special\n    \"nu\" @namespace\n    \"env\" @constant\n  ]) @none\n\n(val_cellpath\n  \"$\" @punctuation.special)\n\n(record_entry\n  \":\" @punctuation.special)\n\n; ---\n; types\n(flat_type) @type\n\n(list_type\n  \"list\" @type.enum\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n(collection_type\n  [\n    \"record\"\n    \"table\"\n  ] @type.enum\n  \"<\" @punctuation.bracket\n  key: (_) @variable.parameter\n  [\n    \",\"\n    \":\"\n  ] @punctuation.special\n  \">\" @punctuation.bracket)\n\n(composite_type\n  \"oneof\" @type.enum\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n[(comment) (shebang)] @comment\n\n((comment)+ @comment.documentation\n  .\n  (decl_def))\n\n(parameter\n  (comment) @comment.documentation)\n\n(command\n  head: ((cmd_identifier) @function.builtin\n    (#match? @function.builtin \"^\\\\s*(find|parse|split|str)$\"))\n  flag: (_\n    name: (_) @attribute\n    (#any-of? @attribute \"r\" \"regex\"))\n  .\n  arg: (_\n    (string_content) @string.regexp))\n\n(_\n  opr: [\n    \"=~\"\n    \"!~\"\n    \"like\"\n    \"not-like\"\n  ]\n  rhs: (_\n    (string_content) @string.regexp))\n\n(command\n  head: ((_) @function\n    (#any-of? @function \"nu\" \"$nu.current-exe\"))\n  flag: (_\n    name: (_) @attribute\n    (#any-of? @attribute \"c\" \"e\" \"commands\" \"execute\"))\n  .\n  arg: (_\n    (string_content) @string.code))\n"
  },
  {
    "path": "runtime/queries/nu/indents.scm",
    "content": "[\n  (expr_parenthesized)\n  (parameter_bracks)\n  (ctrl_match)\n\n  (val_record)\n  (val_list)\n  (val_closure)\n  (val_table)\n\n  (block)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/nu/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n\n(command\n  head: ((cmd_identifier) @_cmd\n    (#match? @_cmd \"^\\\\s*(find|parse|split|str)$\"))\n  flag: (_\n    name: (_) @_flag\n    (#any-of? @_flag \"r\" \"regex\"))\n  .\n  arg: (_\n    (string_content) @injection.content\n    (#set! injection.language \"regex\")))\n\n(_\n  opr: [\n    \"=~\"\n    \"!~\"\n    \"like\"\n    \"not-like\"\n  ]\n  rhs: (_\n    (string_content) @injection.content\n    (#set! injection.language \"regex\")))\n\n(command\n  head: (_) @_cmd\n  (#any-of? @_cmd \"nu\" \"$nu.current-exe\")\n  flag: (_\n    name: (_) @_flag\n    (#any-of? @_flag \"c\" \"e\" \"commands\" \"execute\"))\n  .\n  arg: (_\n    (string_content) @injection.content\n    (#set! injection.language \"nu\")))\n\n(command\n  head: (cmd_identifier) @_command (#any-of? @_command \"jq\" \"jaq\")\n  .\n  arg: (_ (string_content) @injection.content)\n  (#set! injection.language \"jq\")\n)\n\n(command\n  head: (cmd_identifier) @_command (#eq? @_command \"fish\")\n  flag: (short_flag \"-\") @_flag (#match? @_flag \"^-.*c$\")\n  .\n  arg: (_ (string_content) @injection.content)\n  (#set! injection.language \"fish\")\n)\n"
  },
  {
    "path": "runtime/queries/nu/textobjects.scm",
    "content": "; (stmt_let) @assignment.outer\n\n; (stmt_mut) @assignment.outer\n\n; (stmt_const) @assignment.outer\n\n; (stmt_let\n;   value: (_) @assignment.inner)\n\n; (stmt_mut\n;   value: (_) @assignment.inner)\n\n; (stmt_const\n;   value: (_) @assignment.inner)\n\n; (block) @block.outer\n\n(comment) @comment.around\n\n; (pipeline) @pipeline.outer\n\n; (pipe_element) @pipeline.inner\n\n(decl_def) @function.around\n\n(decl_def\n  body: (_) @function.inside)\n\n; (ctrl_for) @loop.outer\n\n; (ctrl_loop) @loop.outer\n\n; (ctrl_while) @loop.outer\n\n; (ctrl_for\n;   body: (_) @loop.inner)\n\n; (ctrl_loop\n;   body: (_) @loop.inner)\n\n; (ctrl_while\n;   body: (_) @loop.inner)\n\n; Conditional inner counts the last one, rather than the current one.\n; (ctrl_if\n;   then_branch: (_) @conditional.inner\n;   else_block: (_)? @conditional.inner) @conditional.outer\n\n(parameter) @parameter.around\n\n; (command\n;   head: (_) @call.inner) @call.outer\n\n; (where_command\n;   predicate: (_) @call.inner) @call.outer\n\n; define pipeline first, because it should only match as a fallback\n; e.g., `let a = date now` should match the whole assignment.\n; But a standalone `date now` should also match a statement\n; (pipeline) @statement.outer\n\n; (stmt_let) @statement.outer\n\n; (stmt_mut) @statement.outer\n\n; (stmt_const) @statement.outer\n\n; (ctrl_if) @statement.outer\n\n; (ctrl_try) @statement.outer\n\n; (ctrl_match) @statement.outer\n\n; (ctrl_while) @statement.outer\n\n; (ctrl_loop) @statement.outer\n\n; (val_number) @number.inner\n"
  },
  {
    "path": "runtime/queries/nunjucks/highlights.scm",
    "content": "; inherits: jinja"
  },
  {
    "path": "runtime/queries/nunjucks/injections.scm",
    "content": "; inherits: jinja"
  },
  {
    "path": "runtime/queries/ocaml/highlights.scm",
    "content": "; Punctuation\n;------------\n\n\"%\" @punctuation.special\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\" \"[|\" \"|]\" \"[<\" \"[>\"] @punctuation.bracket\n\n[\n  \",\" \".\" \";\" \":\" \"=\" \"|\" \"~\" \"?\" \"+\" \"-\" \"!\" \">\" \"&\"\n  \"->\" \";;\" \":>\" \"+=\" \":=\" \"..\"\n] @punctuation.delimiter\n\n(object_type [\"<\" \">\"] @punctuation.bracket)\n\n(attribute [\"[@\" \"]\"] @punctuation.special)\n(item_attribute [\"[@@\" \"]\"] @punctuation.special)\n(floating_attribute [\"[@@@\" \"]\"] @punctuation.special)\n(extension [\"[%\" \"]\"] @punctuation.special)\n(item_extension [\"[%%\" \"]\"] @punctuation.special)\n(quoted_extension [\"{%\" \"}\"] @punctuation.special)\n(quoted_item_extension [\"{%%\" \"}\"] @punctuation.special)\n\n; Modules\n;--------\n\n[(module_name) (module_type_name)] @namespace\n\n; Types\n;------\n\n(\n  (type_constructor) @type.builtin\n  (#match? @type.builtin \"^(int|char|bytes|string|float|bool|unit|exn|array|list|option|int32|int64|nativeint|format6|lazy_t)$\")\n)\n\n[(class_name) (class_type_name) (type_constructor)] @type\n\n[(constructor_name) (tag)] @constructor\n\n; Variables\n;----------\n\n[(value_name) (type_variable)] @variable\n\n(value_pattern) @variable.parameter\n\n; Functions\n;----------\n\n(let_binding\n  pattern: (value_name) @function\n  (parameter))\n\n(let_binding\n  pattern: (value_name) @function\n  body: [(fun_expression) (function_expression)])\n\n(value_specification (value_name) @function)\n\n(external (value_name) @function)\n\n(method_name) @function.method\n\n; Application\n;------------\n\n(\n  (value_name) @function.builtin\n  (#match? @function.builtin \"^(raise(_notrace)?|failwith|invalid_arg)$\")\n)\n\n(infix_expression\n  left: (value_path (value_name) @function)\n  operator: (concat_operator) @operator\n  (#eq? @operator \"@@\"))\n\n(infix_expression\n  operator: (rel_operator) @operator\n  right: (value_path (value_name) @function)\n  (#eq? @operator \"|>\"))\n\n(application_expression\n  function: (value_path (value_name) @function))\n\n; Properties\n;-----------\n\n[(label_name) (field_name) (instance_variable_name)] @variable.other.member\n\n; Constants\n;----------\n\n(boolean) @constant.builtin.boolean\n\n[(number) (signed_number)] @constant.numeric\n\n[(string) (character)] @string\n\n(quoted_string \"{\" @string \"}\" @string) @string\n\n(escape_sequence) @constant.character.escape\n\n(conversion_specification) @string.special\n\n; Operators\n;----------\n\n[\"*\" \"#\" \"::\" \"<-\"] @operator\n\n[\n  (prefix_operator)\n  (sign_operator)\n  (pow_operator)\n  (mult_operator)\n  (add_operator)\n  (concat_operator)\n  (rel_operator)\n  (and_operator)\n  (or_operator)\n  (assign_operator)\n  (hash_operator)\n  (indexing_operator)\n  (let_operator)\n  (let_and_operator)\n  (match_operator)\n] @operator\n\n(match_expression (match_operator) @keyword)\n\n(value_definition [(let_operator) (let_and_operator)] @keyword)\n\n; Keywords\n;---------\n\n[\n  \"and\" \"as\" \"assert\" \"begin\" \"class\" \"constraint\" \"do\" \"done\" \"downto\" \"else\"\n  \"end\" \"exception\" \"external\" \"for\" \"fun\" \"function\" \"functor\" \"if\" \"in\"\n  \"include\" \"inherit\" \"initializer\" \"lazy\" \"let\" \"match\" \"method\" \"module\"\n  \"mutable\" \"new\" \"nonrec\" \"object\" \"of\" \"open\" \"private\" \"rec\" \"sig\" \"struct\"\n  \"then\" \"to\" \"try\" \"type\" \"val\" \"virtual\" \"when\" \"while\" \"with\"\n] @keyword\n\n; Attributes\n;-----------\n\n(attribute_id) @tag\n\n; Comments\n;---------\n\n[(comment) (line_number_directive) (directive) (shebang)] @comment\n"
  },
  {
    "path": "runtime/queries/ocaml/indents.scm",
    "content": "[\n  (let_binding)\n  (type_binding)\n  (structure)\n  (signature)\n  (record_declaration)\n  (function_expression)\n  (match_case)\n] @indent\n\n\"}\" @outdent\n\n"
  },
  {
    "path": "runtime/queries/ocaml/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/ocaml/locals.scm",
    "content": "; Scopes\n;-------\n\n[\n  (let_binding)\n  (class_binding)\n  (class_function)\n  (method_definition)\n  (fun_expression)\n  (object_expression)\n  (for_expression)\n  (match_case)\n  (attribute_payload)\n] @local.scope\n\n; Definitions\n;------------\n\n(value_pattern) @local.definition.variable.parameter\n\n; References\n;-----------\n\n(value_path . (value_name) @local.reference)\n"
  },
  {
    "path": "runtime/queries/ocaml-interface/highlights.scm",
    "content": "; inherits: ocaml\n"
  },
  {
    "path": "runtime/queries/ocaml-interface/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/odin/highlights.scm",
    "content": "\n; Variables\n\n(identifier) @variable\n\n[\n  (calling_convention)\n  (tag)\n] @keyword.directive\n\n[\n  \"import\" \n] @keyword.control.import\n\n[\n  \"package\"\n  \"foreign\"\n  \"using\"\n  \"cast\"\n  \"transmute\"\n  \"auto_cast\"\n] @keyword\n\n[\n  \"defer\"\n] @keyword.control\n\n[\n  \"struct\"\n  \"enum\"\n  \"union\"\n  \"map\"\n  \"bit_set\"\n  \"matrix\"\n  \"bit_field\"\n] @keyword.storage.type\n\n[\n  \"proc\"\n] @keyword.function\n\n[\n  \"return\"\n  \"or_return\"\n] @keyword.control.return\n\n[\n  \"distinct\"\n  \"dynamic\"\n] @keyword.storage.modifier\n\n[\n  \"if\"\n  \"else\"\n  \"when\"\n  \"switch\"\n  \"case\"\n  \"where\"\n  \"break\"\n  \"or_break\"\n  (fallthrough_statement)\n] @keyword.control.conditional\n\n((ternary_expression\n  [\n    \"?\"\n    \":\"\n    \"if\"\n    \"else\"\n    \"when\"\n  ] @keyword.control.conditional))\n\n[\n  \"for\"\n  \"do\"\n  \"continue\"\n  \"or_continue\"\n] @keyword.control.repeat\n\n[\n  \":=\"\n  \"=\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"%%\"\n  \">\"\n  \">=\"\n  \"<\"\n  \"<=\"\n  \"==\"\n  \"!=\"\n  \"~=\"\n  \"|\"\n  \"~\"\n  \"&\"\n  \"&~\"\n  \"<<\"\n  \">>\"\n  \"||\"\n  \"&&\"\n  \"!\"\n  \"^\"\n  \"..\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"&=\"\n  \"|=\"\n  \"^=\"\n  \"<<=\"\n  \">>=\"\n  \"||=\"\n  \"&&=\"\n  \"&~=\"\n  \"..=\"\n  \"..<\"\n  \"?\"\n] @operator\n\n[\n  \"or_else\"\n  \"in\"\n  \"not_in\"\n] @keyword.operator\n\n[ \"{\" \"}\" ] @punctuation.bracket\n\n[ \"(\" \")\" ] @punctuation.bracket\n\n[ \"[\" \"]\" ] @punctuation.bracket\n\n[\n  \"::\"\n  \"->\"\n  \".\"\n  \",\"\n  \":\"\n  \";\"\n] @punctuation.delimiter\n\n[\n  \"@\"\n  \"$\"\n] @punctuation.special\n\n(number) @constant.numeric\n\n(float) @constant.numeric.float\n\n(string) @string\n\n(character) @string\n\n(escape_sequence) @constant.character.escape\n\n(boolean) @constant.builtin.boolean\n\n[\n  (uninitialized)\n  (nil)\n] @constant.builtin\n\n((identifier) @variable.builtin\n  (#any-of? @variable.builtin \"context\" \"self\"))\n\n(((identifier) @type.builtin)\n  (#any-of? @type.builtin\n    \"bool\" \"byte\" \"b8\" \"b16\" \"b32\" \"b64\"\n    \"int\" \"i8\" \"i16\" \"i32\" \"i64\" \"i128\"\n    \"uint\" \"u8\" \"u16\" \"u32\" \"u64\" \"u128\" \"uintptr\"\n    \"i16le\" \"i32le\" \"i64le\" \"i128le\" \"u16le\" \"u32le\" \"u64le\" \"u128le\"\n    \"i16be\" \"i32be\" \"i64be\" \"i128be\" \"u16be\" \"u32be\" \"u64be\" \"u128be\"\n    \"float\" \"double\" \"f16\" \"f32\" \"f64\" \"f16le\" \"f32le\" \"f64le\" \"f16be\" \"f32be\" \"f64be\"\n    \"complex32\" \"complex64\" \"complex128\" \"complex_float\" \"complex_double\"\n    \"quaternion64\" \"quaternion128\" \"quaternion256\"\n    \"rune\" \"string\" \"cstring\" \"rawptr\" \"typeid\" \"any\"))\n\n\"...\" @type.builtin\n\n[\n  (comment)\n  (block_comment)\n] @comment\n\n; Functions\n\n(procedure_declaration (identifier) @function)\n\n(procedure_declaration (identifier) @function (procedure (block)))\n\n(procedure_declaration (identifier) @function (procedure (uninitialized)))\n\n(overloaded_procedure_declaration (identifier) @function)\n\n(call_expression function: (identifier) @function)\n\n(call_expression\n  function: (identifier) @function.builtin\n  (#any-of? @function.builtin\n    \"abs\" \"align_of\" \"append\" \"append_elem\" \"append_elem_string\" \n    \"append_elems\" \"append_nothing\" \"append_soa\" \"append_soa_elem\" \n    \"append_soa_elems\" \"append_string\" \"assert\" \"assert_contextless\" \n    \"assign_at\" \"assign_at_elem\" \"assign_at_elem_string\" \"assign_at_elems\" \n    \"cap\" \"card\" \"clamp\" \"clear\" \"clear_dynamic_array\" \"clear_map\" \"clear_soa\" \n    \"complex\" \"conj\" \"container_of\" \"copy\" \"copy_from_string\" \"copy_slice\" \n    \"delete\" \"delete_cstring\" \"delete_dynamic_array\" \"delete_key\" \n    \"delete_map\" \"delete_slice\" \"delete_soa\" \"delete_string\" \n    \"expand_values\" \"free\" \"free_all\" \"imag\" \"init_global_temporary_allocator\" \n    \"inject_at\" \"inject_at_elem\" \"inject_at_elem_string\" \"inject_at_elems\" \n    \"jmag\" \"kmag\" \"len\" \"make\" \"make_dynamic_array\" \"make_dynamic_array_len\" \n    \"make_dynamic_array_len_cap\" \"make_map\" \"make_multi_pointer\" \"make_slice\" \n    \"make_soa\" \"make_soa_aligned\" \"make_soa_dynamic_array\" \n    \"make_soa_dynamic_array_len\" \"make_soa_dynamic_array_len_cap\" \n    \"make_soa_slice\" \"map_insert\" \"map_upsert\" \"max\" \"min\" \n    \"new_clone\" \"non_zero_append\" \"non_zero_append_elem\" \n    \"non_zero_append_elem_string\" \"non_zero_append_elems\" \n    \"non_zero_append_soa_elem\" \"non_zero_append_soa_elems\" \n    \"non_zero_resize\" \"non_zero_resize_dynamic_array\" \"non_zero_resize_soa\" \n    \"non_zero_reserve\" \"non_zero_reserve_dynamic_array\" \"non_zero_reserve_soa\" \n    \"offset_of\" \"offset_of_by_string\" \"offset_of_member\" \"offset_of_selector\" \n    \"ordered_remove\" \"panic\" \"panic_contextless\" \"pop\" \"pop_front\" \n    \"pop_front_safe\" \"pop_safe\" \"raw_data\" \"raw_soa_footer_dynamic_array\" \n    \"raw_soa_footer_slice\" \"real\" \"remove_range\" \"reserve\" \n    \"reserve_dynamic_array\" \"reserve_map\" \"reserve_soa\" \"resize\" \n    \"resize_dynamic_array\" \"resize_soa\" \"shrink\" \"shrink_map\" \n    \"size_of\" \"soa_unzip\" \"soa_zip\" \"swizzle\" \"type_info_of\" \"type_of\" \n    \"typeid_of\" \"unordered_remove\" \"unordered_remove_soa\" \n    \"unimplemented\" \"unimplemented_contextless\"))\n\n; Types\n\n(struct_declaration (identifier) @type \"::\")\n\n(enum_declaration (identifier) @type \"::\")\n\n(union_declaration (identifier) @type \"::\")\n\n(bit_field_declaration (identifier) @type \"::\")\n\n(const_declaration (identifier) @type \"::\" [(array_type) (distinct_type) (bit_set_type) (pointer_type)])\n\n(struct . (identifier) @type)\n\n(field_type . (identifier) @keyword.storage.type \".\" (identifier) @type)\n\n(bit_set_type (identifier) @type \";\")\n\n(polymorphic_parameters (identifier) @type)\n\n((identifier) @type\n  (#match? @type \"^[A-Z][a-z0-9_]+\"))\n\n(type (identifier) @type)\n\n; Constants\n\n(member_expression . \".\" (identifier) @constant)\n\n(enum_declaration \"{\" (identifier) @constant)\n\n((identifier) @constant\n  (#match? @constant \"^[A-Z0-9_]*$\"))\n\n; Attributes\n\n(attribute (identifier) @attribute \"=\"?)\n\n; Labels\n\n(label_statement (identifier) @label \":\")\n\n; Fields\n\n(member_expression \".\" (identifier) @variable.other.member)\n(member_expression\n  (identifier) \".\"\n  (call_expression\n    function: (identifier) @function.method))\n\n(struct_type \"{\" (identifier) @variable.other.member)\n\n(struct_field (identifier) @variable.other.member \"=\"?)\n\n(bit_field_declaration (identifier) @variable.other.member)\n\n(field (identifier) @variable.other.member)\n\n; Namespaces\n\n(package_declaration (identifier) @namespace)\n\n(foreign_block (identifier) @namespace)\n\n(using_statement (identifier) @namespace)\n\n(import_declaration (identifier) @namespace)\n\n; Parameters\n\n(parameter (identifier) @variable.parameter \":\" \"=\"? (identifier)? @constant)\n\n(default_parameter (identifier) @variable.parameter \":=\")\n\n(named_type (identifier) @variable.parameter)\n\n(call_expression argument: (identifier) @variable.parameter \"=\")\n\n(procedure_type (parameters (parameter (identifier) @variable.parameter)))\n"
  },
  {
    "path": "runtime/queries/odin/indents.scm",
    "content": "[\n  (block)\n  (enum_declaration)\n  (union_declaration)\n  (struct_declaration)\n  (struct)\n  (parameters)\n  (tuple_type)\n  (struct_type)\n  (call_expression)\n  (switch_case)\n] @indent\n\n[\n \")\"\n \"]\"\n] @outdent\n\n; Have to do all closing brackets separately because the one for switch statements shouldn't end.\n(block \"}\" @outdent)\n(enum_declaration \"}\" @outdent)\n(union_declaration \"}\" @outdent)\n(struct_declaration \"}\" @outdent)\n(struct \"}\" @outdent)\n(struct_type \"}\" @outdent)\n"
  },
  {
    "path": "runtime/queries/odin/injections.scm",
    "content": "([(comment) (block_comment)] @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/odin/textobjects.scm",
    "content": "(procedure_declaration (identifier) (procedure (block) @function.inside)) @function.around\n(procedure_declaration (identifier) (procedure (uninitialized) @function.inside)) @function.around\n(overloaded_procedure_declaration (identifier) @function.inside) @function.around\n\n(procedure_type (parameters (parameter (identifier) @parameter.inside) @parameter.around))\n(procedure (parameters (parameter (identifier) @parameter.inside) @parameter.around))\n\n((procedure_declaration\n  (attributes (attribute \"@\" \"(\" (identifier) @attr_name \")\"))\n  (identifier) (procedure (block) @test.inside)) @test.around\n (#match? @attr_name \"test\"))\n\n(comment) @comment.inside\n(comment)+ @comment.around\n(block_comment) @comment.inside\n(block_comment)+ @comment.around\n\n(struct_declaration (identifier) \"::\") @class.around\n(enum_declaration (identifier) \"::\") @class.around\n(union_declaration (identifier) \"::\") @class.around\n(bit_field_declaration (identifier) \"::\") @class.around\n(const_declaration (identifier) \"::\" [(array_type) (distinct_type) (bit_set_type) (pointer_type)]) @class.around\n"
  },
  {
    "path": "runtime/queries/ohm/highlights.scm",
    "content": "; See: https://docs.helix-editor.com/master/themes.html#syntax-highlighting\n\n; attribute\n; ---------\n\n(case_name) @attribute\n\n; comment.line\n; ------------\n\n[\n  (singleline_comment)\n  (rule_descr)\n] @comment.line\n\n; comment.block\n; -------------\n\n(multiline_comment) @comment.block\n\n; function.method\n; ---------------\n\n(rule\n  name: (identifier) @function.method)\n\n; function.builtin\n; ----------------\n\n; Lexical\n((identifier) @function.builtin\n  (#any-of? @function.builtin\n    \"any\"\n    \"alnum\"\n    \"end\"\n    \"digit\" \"hexDigit\"\n    \"letter\"\n    \"space\"\n    \"lower\" \"upper\" \"caseInsensitive\"\n    \"listOf\" \"nonemptyListOf\" \"emptyListOf\"\n    \"applySyntactic\")\n  (#is-not? local))\n\n; Syntactic\n((identifier) @function.builtin\n  (#any-of? @function.builtin \"ListOf\" \"NonemptyListOf\" \"EmptyListOf\")\n  (#is-not? local))\n\n; function.method (continuing)\n; ---------------\n\n(term\n  base: (identifier) @function.method)\n\n; string.special\n; --------------\n\n(escape_char) @constant.character.escape\n\n; string\n; ------\n\n[\n  (terminal_string)\n  (one_char_terminal)\n] @string\n\n; type\n; ----\n\n(super_grammar\n  name: (identifier) @type)\n\n(grammar\n  name: (identifier) @type)\n\n; operator\n; --------\n\n[\n  ; \"=\" \":=\" \"+=\"\n  (define) (override) (extend)\n\n  ; \"&\" \"~\"\n  (lookahead) (negative_lookahead)\n\n  ; \"#\"\n  (lexification)\n\n  ; \"*\" \"+\" \"?\"\n  (zero_or_more) (one_or_more) (zero_or_one)\n\n  ; \"...\"\n  (super_splice)\n\n  \"<:\" \"..\" \"|\"\n] @operator\n\n; punctuation.bracket\n; -------------------\n\n[\n  \"<\"\n  \">\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n(alt\n  \"(\" @punctuation.bracket\n  \")\" @punctuation.bracket)\n\n; punctuation.delimiter\n; ---------------------\n\n\",\" @punctuation.delimiter\n\n; variable.parameter\n; ------------------\n\n(formals\n  (identifier) @variable.parameter)\n"
  },
  {
    "path": "runtime/queries/ohm/indents.scm",
    "content": "; See: https://docs.helix-editor.com/guides/indent.html\n\n; indent\n; ------\n\n[\n  ; <..., ...>\n  (formals)\n  (params)\n\n  ; (...| ...)\n  (alt)\n] @indent\n\n; outdent\n; -------\n\n[\n  \"}\"\n  \")\"\n  \">\"\n] @outdent\n\n; align\n; -----\n\n; | ... | ...\n(rule_body\n  . (top_level_term) @anchor\n  (#set! \"scope\" \"tail\")) @align\n\n; N/A or unused:\n; --------------\n; indent.always\n; outdent.always\n; extend\n; extend.prevent-once\n"
  },
  {
    "path": "runtime/queries/ohm/injections.scm",
    "content": "; See: https://docs.helix-editor.com/guides/injection.html\n\n((singleline_comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((multiline_comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/ohm/textobjects.scm",
    "content": "; See: https://docs.helix-editor.com/guides/textobject.html\n\n; function.inside & around\n; ------------------------\n\n(rule\n  body: (_) @function.inside) @function.around\n\n; class.inside & around\n; ---------------------\n\n(grammar\n  body: (_) @class.inside) @class.around\n\n; parameter.inside & around\n; -------------------------\n\n(formals\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(rule_body\n  ((_) @parameter.inside . \"|\"? @parameter.around) @parameter.around)\n\n(params\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(alt\n  ((_) @parameter.inside . \"|\"? @parameter.around) @parameter.around)\n\n; comment.inside\n; --------------\n\n(multiline_comment)+ @comment.inside\n(singleline_comment)+ @comment.inside\n\n; comment.around\n; --------------\n\n(multiline_comment)+ @comment.around\n(singleline_comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/opencl/highlights.scm",
    "content": "[\n  \"sizeof\"\n  ; @todo why does \"uniform\" break highlighting?\n  ; \"uniform\" ; OpenCL C 3.0.13 reserves this as a keyword, but doesn't seem to use it for anything\n  (function_qualifier)\n] @keyword\n\n[\n  \"enum\"\n  \"struct\"\n  \"typedef\"\n  \"union\"\n] @keyword.storage.type\n\n[\n  \"extern\"\n  \"register\"\n  (type_qualifier)\n  (access_qualifier)\n  (storage_class_specifier)\n  (address_space_qualifier)\n] @keyword.storage.modifier\n\n[\n  \"goto\"\n  \"break\"\n  \"continue\"\n] @keyword.control\n\n[\n  \"do\"\n  \"for\"\n  \"while\"\n] @keyword.control.repeat\n\n[\n  \"if\"\n  \"else\"\n  \"switch\"\n  \"case\"\n  \"default\"\n] @keyword.control.conditional\n\n\"return\" @keyword.control.return\n\n[\n  \"defined\"\n  \"#define\"\n  \"#elif\"\n  \"#else\"\n  \"#endif\"\n  \"#if\"\n  \"#ifdef\"\n  \"#ifndef\"\n  \"#include\"\n  (preproc_directive)\n] @keyword.directive\n\n(pointer_declarator \"*\" @type.builtin)\n(abstract_pointer_declarator \"*\" @type.builtin)\n\n[\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"++\"\n  \"--\"\n  \"%\"\n  \"==\"\n  \"!=\"\n  \">\"\n  \"<\"\n  \">=\"\n  \"<=\"\n  \"&&\"\n  \"||\"\n  \"!\"\n  \"&\"\n  \"|\"\n  \"^\"\n  \"~\"\n  \"<<\"\n  \">>\"\n  \"=\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"<<=\"\n  \">>=\"\n  \"&=\"\n  \"^=\"\n  \"|=\"\n  \"?\"\n] @operator\n\n(conditional_expression \":\" @operator)\n\n\"...\" @punctuation\n\n[\",\" \".\" \":\" \";\" \"->\" \"::\"] @punctuation.delimiter\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n\n[(true) (false)] @constant.builtin.boolean\n\n(identifier) @variable\n\n((identifier) @constant\n  (#match? @constant \"^[A-Z][A-Z\\\\d_]*$\"))\n\n(enumerator name: (identifier) @type.enum.variant)\n\n(string_literal) @string\n(system_lib_string) @string\n\n(null) @constant.builtin\n(number_literal) @constant.numeric\n(char_literal) @constant.character\n\n(call_expression\n  function: (identifier) @function)\n(call_expression\n  function: (field_expression\n    field: (field_identifier) @function))\n(call_expression (argument_list (identifier) @variable))\n(function_declarator\n  declarator: [(identifier) (field_identifier)] @function)\n(parameter_declaration\n  declarator: (identifier) @variable.parameter)\n(parameter_declaration\n  (pointer_declarator\n    declarator: (identifier) @variable.parameter))\n(preproc_function_def\n  name: (identifier) @function.special)\n\n(attribute\n  name: (identifier) @attribute)\n\n(field_identifier) @variable.other.member\n(statement_identifier) @label\n(type_identifier) @type\n(scalar_type) @type.builtin\n(sized_type_specifier) @type.builtin\n(vector_type) @type.builtin\n(other_builtin_type) @type.builtin\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/opencl/indents.scm",
    "content": "; inherits: c\n"
  },
  {
    "path": "runtime/queries/opencl/injections.scm",
    "content": "; inherits: c\n"
  },
  {
    "path": "runtime/queries/opencl/textobjects.scm",
    "content": "; inherits: c\n"
  },
  {
    "path": "runtime/queries/openscad/highlights.scm",
    "content": "; Includes\n(identifier) @variable\n\n\"include\" @keyword.control.import\n\n(include_path) @string.special.path\n\n; Functions\n\n(function_item\n  (identifier) @function\n)\n(function_item\n  parameters: (parameters (parameter (assignment value: (_) @constant)))\n)\n(function_call name: (identifier) @function)\n(function_call\n  arguments: (arguments (assignment name: _ @variable.parameter))\n)\n; for the puroposes of distintion since modules are \"coloured\" impure functions, we will treat them as methods\n(module_item (identifier) @function.method)\n(module_item\n  parameters: (parameters (parameter (assignment value: (_) @constant)))\n)\n(module_call name: (identifier) @function.method)\n(module_call\n  arguments: (arguments (assignment name: _ @variable.parameter))\n)\n\n; assertion statements/expression arguments behave similar to function calls\n(assert_expression\n  arguments: (arguments (assignment name: _ @variable.parameter))\n)\n(assert_statement\n  arguments: (arguments (assignment name: _ @variable.parameter))\n)\n\n(echo_expression\n  arguments: (arguments (assignment name: _ @variable.parameter))\n)\n(echo_expression \"echo\" @function.builtin)\n\n; Variables\n(parameter\n  [_ @variable.parameter (assignment name: _ @variable.parameter)]\n)\n(special_variable) @variable.builtin\n(undef) @constant.builtin\n\n; Types/Properties/\n(dot_index_expression index: (_) @variable.other.member)\n\n; Keywords\n[\n  \"module\"\n  \"function\"\n  \"let\"\n  \"assign\"\n  \"use\"\n  \"each\"\n  (assert_statement \"assert\")\n  (assert_expression \"assert\")\n] @keyword\n\n; Operators\n[\n  \"||\"\n  \"&&\"\n  \"==\"\n  \"!=\"\n  \"<\"\n  \">\"\n  \"<=\"\n  \">=\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"^\"\n  \"!\"\n  \":\"\n  \"=\"\n] @operator\n\n; Builtin modules\n(module_call\n  name: (identifier) @function.builtin\n  (#any-of? @function.builtin\n    \"circle\"\n    \"color\"\n    \"cube\"\n    \"cylinder\"\n    \"difference\"\n    \"hull\"\n    \"intersection\"\n    \"linear_extrude\"\n    \"minkowski\"\n    \"mirror\"\n    \"multmatrix\"\n    \"offset\"\n    \"polygon\"\n    \"polyhedron\"\n    \"projection\"\n    \"resize\"\n    \"rotate\"\n    \"rotate_extrude\"\n    \"scale\"\n    \"sphere\"\n    \"square\"\n    \"surface\"\n    \"text\"\n    \"translate\"\n    \"union\"\n    \"echo\"\n  )\n)\n(\n  (identifier) @identifier\n  (#eq? @identifier \"PI\")\n) @constant.builtin\n\n; Conditionals\n[\n  \"if\"\n  \"else\"\n] @keyword.control.conditional\n(ternary_expression\n  [\"?\" \":\"] @keyword.control.conditional\n)\n\n; Repeats\n[\n  \"for\"\n  \"intersection_for\"\n] @keyword.control.repeat\n\n; Literals\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(string) @string\n(escape_sequence) @constant.character.escape\n(boolean) @constant.builtin.boolean\n\n; Misc\n(modifier\n  [\n    \"*\"\n    \"!\"\n    \"#\"\n    \"%\"\n  ] @keyword.storage.modifier\n)\n[\"{\" \"}\"] @punctuation.bracket\n[\"(\" \")\"] @punctuation.bracket\n[\"[\" \"]\"] @punctuation.bracket\n[\n  \";\"\n  \",\"\n  \".\"\n] @punctuation.delimiter\n\n; Comments\n[(line_comment) (block_comment)] @comment\n"
  },
  {
    "path": "runtime/queries/org/highlights.scm",
    "content": "(headline (stars) @markup.heading.marker (#eq? @markup.heading.marker \"*\")) @markup.heading.1\n(headline (stars) @markup.heading.marker (#eq? @markup.heading.marker \"**\")) @markup.heading.2\n(headline (stars) @markup.heading.marker (#eq? @markup.heading.marker \"***\")) @markup.heading.3\n(headline (stars) @markup.heading.marker (#eq? @markup.heading.marker \"****\")) @markup.heading.4\n(headline (stars) @markup.heading.marker (#eq? @markup.heading.marker \"*****\")) @markup.heading.5\n(headline (stars) @markup.heading.marker (#eq? @markup.heading.marker \"******\")) @markup.heading.6\n\n(block) @markup.raw.block\n(list) @markup.list.unnumbered\n(directive) @markup.label\n(property_drawer) @markup.label\n \n\n((expr) @markup.bold\n (#match? @markup.bold \"\\\\*.*\\\\*\"))\n\n((expr) @markup.italic\n (#match? @markup.italic \"/.*/\"))\n((expr) @markup.raw.inline\n (#match? @markup.raw.inline \"~.*~\"))\n\n((expr) @markup.quote\n (#match? @markup.quote \"=.*=\"))\n\n"
  },
  {
    "path": "runtime/queries/org/injections.scm",
    "content": "(block parameter: (expr) @injection.language\n  (contents) @injection.content\n  (#set! injection.include-children))\n\n"
  },
  {
    "path": "runtime/queries/pascal/highlights.scm",
    "content": "; -- Identifier type inference\n\n; VERY QUESTIONABLE: Highlighting of identifiers based on spelling\n(exprBinary ((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z0-9_]+$|^[a-z]{2,3}[A-Z].+$\")))\n(exprUnary ((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z0-9_]+$|^[a-z]{2,3}[A-Z].+$\")))\n(assignment rhs: ((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z0-9_]+$|^[a-z]{2,3}[A-Z].+$\")))\n(exprBrackets ((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z0-9_]+$|^[a-z]{2,3}[A-Z].+$\")))\n(exprParens ((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z0-9_]+$|^[a-z]{2,3}[A-Z].+$\")))\n(exprDot rhs: ((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z0-9_]+$|^[a-z]{2,3}[A-Z].+$\")))\n(exprTpl args: ((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z0-9_]+$|^[a-z]{2,3}[A-Z].+$\")))\n(exprArgs ((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z0-9_]+$|^[a-z]{2,3}[A-Z].+$\")))\n(declEnumValue ((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z0-9_]+$|^[a-z]{2,3}[A-Z].+$\")))\n(defaultValue ((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z0-9_]+$|^[a-z]{2,3}[A-Z].+$\")))\n\n; -- Break, Continue & Exit\n; (Not ideal: ideally, there would be a way to check if these special\n; identifiers are shadowed by a local variable)\n(statement ((identifier) @keyword.control.return\n (#match? @keyword.control.return \"^[eE][xX][iI][tT]$\")))\n(statement (exprCall entity: ((identifier) @keyword.control.return\n (#match? @keyword.control.return \"^[eE][xX][iI][tT]$\"))))\n(statement ((identifier) @keyword.control.repeat\n (#match? @keyword.control.repeat \"^[bB][rR][eE][aA][kK]$\")))\n(statement ((identifier) @keyword.control.repeat\n (#match? @keyword.control.repeat \"^[cC][oO][nN][tT][iI][nN][uU][eE]$\")))\n\n; -- Heuristic for procedure/function calls without parentheses\n; (If a statement consists only of an identifier, assume it's a procedure)\n; (This will still not match all procedure calls, and also may produce false\n; positives in rare cases, but only for nonsensical code)\n\n(statement (exprDot rhs: (exprTpl entity: (identifier) @function)))\n(statement (exprTpl entity: (identifier) @function))\n(statement (exprDot rhs: (identifier) @function))\n(statement (identifier) @function)\n\n; -- Procedure name in calls with parentheses\n; (Pascal doesn't require parentheses for procedure calls, so this will not\n; detect all calls)\n\n(inherited) @function\n\n; foo.bar<t>\n(exprCall entity: (exprDot rhs: (exprTpl entity: (identifier) @function)))\n; foo.bar\n(exprCall entity: (exprDot rhs: (identifier) @function))\n; foobar<t>\n(exprCall entity: (exprTpl entity: (identifier) @function))\n; foobar\n(exprCall entity: (identifier) @function)\n\n; -- Fields\n\n(declSection (declVars (declVar   name:(identifier) @variable.other.member)))\n(declSection (declField name:(identifier) @variable.other.member))\n(declClass   (declField name:(identifier) @variable.other.member))\n(exprDot rhs: (exprDot)    @variable.other.member)\n(exprDot rhs: (identifier) @variable.other.member)\n\n(recInitializerField name:(identifier) @variable.other.member)\n\n; -- Variable & constant declarations\n; (This is only questionable because we cannot detect types of identifiers\n; declared in other units, so the results will be inconsistent)\n\n(declVar name: (identifier) @variable)\n(declConst name: (identifier) @constant)\n(declEnumValue name: (identifier) @constant)\n\n; -- Constant usage\n\n[\n\t(caseLabel)\n\t(label)\n] @constant\n\n(procAttribute (identifier) @constant)\n(procExternal (identifier) @constant)\n\n; -- Type usage\n\n(typeref) @type\n\n; -- Exception parameters\n\n(exceptionHandler variable: (identifier) @variable.parameter)\n\n; -- Template parameters\n\n(genericArg\ttype: (typeref) @type)\n(genericArg\tname: (identifier) @variable.parameter)\n\n(declProc name: (genericDot lhs: (identifier) @type))\n(declType (genericDot (identifier) @type))\n\n(genericDot (genericTpl (identifier) @type))\n(genericDot (genericDot (identifier) @type))\n\n(genericTpl entity: (genericDot (identifier) @type))\n(genericTpl entity: (identifier) @type)\n\n; -- Function parameters\n\n(declArg name: (identifier) @variable.parameter)\n\n; Treat property declarations like functions\n\n(declProp name: (identifier) @function)\n(declProp getter: (identifier) @variable.other.member)\n(declProp setter: (identifier) @variable.other.member)\n\n; -- Procedure & function declarations\n\n; foo.bar<t>\n(declProc name: (genericDot rhs: (genericTpl entity: (identifier) @function)))\n; foo.bar\n(declProc name: (genericDot rhs: (identifier) @function))\n; foobar<t>\n(declProc name: (genericTpl entity: (identifier) @function))\n; foobar\n(declProc name: (identifier) @function)\n\n; -- Type declaration\n\n(declType name: (genericTpl entity: (identifier) @type))\n(declType name: (identifier) @type)\n\n; -- Comments\n\n(comment)         @comment\n(pp)              @function.macro\n\n; -- Variables\n\n(exprBinary (identifier) @variable)\n(exprUnary (identifier) @variable)\n(assignment (identifier) @variable)\n(exprBrackets (identifier) @variable)\n(exprParens (identifier) @variable)\n(exprDot (identifier) @variable)\n(exprTpl (identifier) @variable)\n(exprArgs (identifier) @variable)\n(defaultValue (identifier) @variable)\n\n; -- Literals\n\n(literalNumber)   @constant.builtin.numeric\n(literalString)   @string\n\n; -- Builtin constants\n\n[\n\t(kTrue)\n\t(kFalse)\n] @constant.builtin.boolean\n\n[\n\t(kNil)\n] @constant.builtin\n\n; -- Punctuation & operators\n\n[\n\t(kOr)\n\t(kXor)\n\t(kDiv)\n\t(kMod)\n\t(kAnd)\n\t(kShl)\n\t(kShr)\n\t(kNot)\n\t(kIs)\n\t(kAs)\n\t(kIn)\n] @keyword.operator\n\n[\n\t(kDot)\n\t(kAdd)\n\t(kSub)\n\t(kMul)\n\t(kFdiv)\n\t(kAssign)\n\t(kAssignAdd)\n\t(kAssignSub)\n\t(kAssignMul)\n\t(kAssignDiv)\n\t(kEq)\n\t(kLt)\n\t(kLte)\n\t(kGt)\n\t(kGte)\n\t(kNeq)\n\t(kAt)\n\t(kHat)\n] @operator\n\n[\n\t\"..\"\n] @punctuation.special\n\n[\n\t\";\"\n\t\",\"\n\t\":\"\n\t(kEndDot)\n] @punctuation.delimiter\n\n[\n\t\"(\"\n\t\")\"\n\t\"[\"\n\t\"]\"\n] @punctuation.bracket\n\n; -- Attributes\n\n(procAttribute (kPublic) @attribute)\n\n[\n\t(kDefault)\n\t(kIndex)\n\t(kNodefault)\n\t(kStored)\n\n\t(kStatic)\n\t(kVirtual)\n\t(kAbstract)\n\t(kSealed)\n\t(kDynamic)\n\t(kOverride)\n\t(kOverload)\n\t(kReintroduce)\n\t(kInline)\n\n\t(kForward)\n\n\t(kStdcall)\n\t(kCdecl)\n\t(kCppdecl)\n\t(kPascal)\n\t(kRegister)\n\t(kMwpascal)\n\t(kExternal)\n\t(kName)\n\t(kMessage)\n\t(kDeprecated)\n\t(kExperimental)\n\t(kPlatform)\n\t(kUnimplemented)\n\t(kCvar)\n\t(kExport)\n\t(kFar)\n\t(kNear)\n\t(kSafecall)\n\t(kAssembler)\n\t(kNostackframe)\n\t(kInterrupt)\n\t(kNoreturn)\n\t(kIocheck)\n\t(kLocal)\n\t(kHardfloat)\n\t(kSoftfloat)\n\t(kMs_abi_default)\n\t(kMs_abi_cdecl)\n\t(kSaveregisters)\n\t(kSysv_abi_default)\n\t(kSysv_abi_cdecl)\n\t(kVectorcall)\n\t(kVarargs)\n\t(kWinapi)\n\t(kAlias)\n\t(kDelayed)\n\n\t(rttiAttributes)\n\t(procAttribute)\n\n] @attribute\n\n; -- Keywords\n[\n\t(kProgram)\n\t(kLibrary)\n\t(kUnit)\n\t(kUses)\n\n\t(kBegin)\n\t(kEnd)\n\t(kAsm)\n\n\t(kVar)\n\t(kThreadvar)\n\t(kConst)\n\t(kResourcestring)\n\t(kConstref)\n\t(kOut)\n\t(kType)\n\t(kLabel)\n\t(kExports)\n\n\t(kAbsolute)\n\n\t(kProperty)\n\t(kRead)\n\t(kWrite)\n\t(kImplements)\n\n\t(kClass)\n\t(kInterface)\n\t(kObject)\n\t(kRecord)\n\t(kObjcclass)\n\t(kObjccategory)\n\t(kObjcprotocol)\n\t(kArray)\n\t(kFile)\n\t(kString)\n\t(kSet)\n\t(kOf)\n\t(kHelper)\n\t(kPacked)\n\n\t(kInherited)\n\n\t(kGeneric)\n\t(kSpecialize)\n\n\t(kFunction)\n\t(kProcedure)\n\t(kConstructor)\n\t(kDestructor)\n\t(kOperator)\n\t(kReference)\n\n\t(kInterface)\n\t(kImplementation)\n\t(kInitialization)\n\t(kFinalization)\n\n\t(kPublished)\n\t(kPublic)\n\t(kProtected)\n\t(kPrivate)\n\t(kStrict)\n\t(kRequired)\n\t(kOptional)\n\n\t(kTry)\n\t(kExcept)\n\t(kFinally)\n\t(kRaise)\n\t(kOn)\n\t(kCase)\n\t(kWith)\n\t(kGoto)\n] @keyword\n\n[\n\t(kFor)\n\t(kTo)\n\t(kDownto)\n\t(kDo)\n\t(kWhile)\n\t(kRepeat)\n\t(kUntil)\n] @keyword.control.repeat\n\n[\n\t(kIf)\n\t(kThen)\n\t(kElse)\n] @keyword.control.conditional\n"
  },
  {
    "path": "runtime/queries/pascal/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/pascal/textobjects.scm",
    "content": "\n(declType (declClass (declSection) @class.inside)) @class.around\n\n(defProc body: (_) @function.inside) @function.around\n\n(declArgs (_) @parameter.inside) @parameter.around\n(exprArgs (_) @parameter.inside) @parameter.around\n\n(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/passwd/highlights.scm",
    "content": "(user) @namespace\n(auth) @keyword\n(uid) @constant\n(gid) @constant\n(gecos) @string\n(home) @variable\n(shell) @attribute\n"
  },
  {
    "path": "runtime/queries/pem/highlights.scm",
    "content": "(label) @constant\n\n(preeb) @keyword\n(posteb) @keyword\n\n(base64pad) @string.special.symbol\n(laxbase64text) @string\n"
  },
  {
    "path": "runtime/queries/penrose/folds.scm",
    "content": "(block) @fold\n(comment) @fold\n"
  },
  {
    "path": "runtime/queries/penrose/highlights.scm",
    "content": "; Comments\n(comment) @comment\n\n; Literals\n(number) @constant.numeric\n(string) @string\n(latex) @string.special\n(boolean) @constant.builtin.boolean\n\n; Identifiers\n((identifier) @keyword\n  (#match? @keyword \"^(encourage|ensure|constraint|layer|Layer|in|In|canvas|global|colors)$\"))\n((identifier) @function\n  (#match? @function \"^norm$\"))\n((identifier) @variable\n  (#not-match? @variable \"^(encourage|ensure|constraint|layer|Layer|in|In|norm|canvas|global|colors)$\"))\n(escaped_identifier) @variable.special\n\n; Domain keywords\n(type_decl \"type\" @keyword)\n(subtype_decl \"type\" @keyword)\n(subtype_decl \"<:\" @operator)\n(constructor_decl \"constructor\" @keyword)\n(function_decl \"function\" @keyword)\n(predicate_decl \"predicate\" @keyword)\n(notation_stmt \"notation\" @keyword)\n(value_decl \"value\" @keyword)\n\n(type_decl names: (identifier_list (identifier) @type))\n(type_decl names: (identifier_list (escaped_identifier) @type))\n(subtype_decl subtype: (identifier) @type)\n(subtype_decl subtype: (escaped_identifier) @type)\n(subtype_decl supertype: (identifier) @type)\n(subtype_decl supertype: (escaped_identifier) @type)\n(constructor_decl name: (identifier) @function)\n(constructor_decl name: (escaped_identifier) @function)\n(constructor_decl parameters: (parameter_list (parameter type: (identifier) @type)))\n(constructor_decl parameters: (parameter_list (parameter type: (escaped_identifier) @type)))\n(constructor_decl result_type: (identifier) @type)\n(constructor_decl result_type: (escaped_identifier) @type)\n(function_decl name: (identifier) @function)\n(function_decl name: (escaped_identifier) @function)\n(function_decl parameters: (parameter_list (parameter type: (identifier) @type)))\n(function_decl parameters: (parameter_list (parameter type: (escaped_identifier) @type)))\n(function_decl result_type: (identifier) @type)\n(function_decl result_type: (escaped_identifier) @type)\n(predicate_decl name: (identifier) @function)\n(predicate_decl name: (escaped_identifier) @function)\n(predicate_decl parameters: (parameter_list (parameter type: (identifier) @type)))\n(predicate_decl parameters: (parameter_list (parameter type: (escaped_identifier) @type)))\n(value_decl name: (identifier) @variable)\n(value_decl name: (escaped_identifier) @variable)\n(value_decl type: (identifier) @type)\n(value_decl type: (escaped_identifier) @type)\n\n(predicate_modifier) @keyword.modifier\n(arrow) @operator\n(tilde) @operator\n\n; Substance keywords\n(substance_type_decl (identifier_list) @variable)\n(substance_type_decl type: (identifier) @type)\n(substance_type_decl type: (escaped_identifier) @type)\n(assignment_stmt \":=\" @operator)\n(predicate_stmt (argument_list) @punctuation.bracket)\n(label_stmt \"Label\" @keyword)\n(autolabel_stmt \"AutoLabel\" @keyword)\n(nolabel_stmt \"NoLabel\" @keyword)\n(let_stmt \"Let\" @keyword)\n(indexed_statement \"for\" @keyword)\n(indexing_clause \"in\" @keyword)\n(index_where_clause \"where\" @keyword)\n\n(typed_assignment_stmt type: (identifier) @type)\n(typed_assignment_stmt type: (escaped_identifier) @type)\n(typed_assignment_stmt name: (identifier) @variable)\n(typed_assignment_stmt name: (escaped_identifier) @variable)\n\n(predicate_stmt name: (identifier) @function)\n(predicate_stmt name: (escaped_identifier) @function)\n\n; Style keywords\n(forall_block \"forall\" @keyword)\n(where_clause \"where\" @keyword)\n(has_condition \"has\" @keyword)\n(with_clause \"with\" @keyword)\n(collect_block \"collect\" @keyword)\n(collect_block \"into\" @keyword)\n(foreach_clause \"foreach\" @keyword)\n(foreach_clause \"foreach\" @keyword)\n(with_clause \"with\" @keyword)\n((named_block (identifier) @attribute)\n  (#match? @attribute \"^(canvas|global|colors)$\"))\n((named_block (identifier) @namespace)\n  (#not-match? @namespace \"^(canvas|global|colors)$\"))\n\n(typed_binding type: (identifier) @type)\n(typed_binding type: (escaped_identifier) @type)\n(typed_binding names: (identifier_list (identifier) @variable))\n(typed_binding names: (identifier_list (escaped_identifier) @variable))\n(binding_modifier) @keyword.modifier\n(single_binding type: (identifier) @type)\n(single_binding type: (escaped_identifier) @type)\n(single_binding name: (identifier) @variable)\n(single_binding name: (escaped_identifier) @variable)\n\n(style_typed_assignment type: (identifier) @type)\n(style_typed_assignment type: (escaped_identifier) @type)\n(shape_literal name: (identifier) @type)\n(shape_literal name: (escaped_identifier) @type)\n(style_typed_assignment target: (property (identifier) @attribute))\n(style_typed_assignment target: (property (escaped_identifier) @attribute))\n(style_assignment target: (property (identifier) @attribute))\n(style_assignment target: (property (escaped_identifier) @attribute))\n(style_assignment target: (property (path (identifier) @attribute)))\n(style_assignment target: (property (path (escaped_identifier) @attribute)))\n(override_stmt target: (property (identifier) @attribute))\n(override_stmt target: (property (escaped_identifier) @attribute))\n(delete_stmt target: (property (identifier) @attribute))\n(delete_stmt target: (property (escaped_identifier) @attribute))\n(constraint_stmt target: (property (identifier) @attribute))\n(constraint_stmt target: (property (escaped_identifier) @attribute))\n(layer_stmt first: (property (identifier) @attribute))\n(layer_stmt first: (property (escaped_identifier) @attribute))\n(layer_stmt second: (property (identifier) @attribute))\n(layer_stmt second: (property (escaped_identifier) @attribute))\n(stack_stmt first: (property (identifier) @attribute))\n(stack_stmt first: (property (escaped_identifier) @attribute))\n(stack_stmt second: (property (identifier) @attribute))\n(stack_stmt second: (property (escaped_identifier) @attribute))\n\n(override_stmt \"override\" @keyword)\n(delete_stmt \"delete\" @keyword)\n(ensure_stmt \"ensure\" @keyword)\n(encourage_stmt \"encourage\" @keyword)\n(constraint_stmt \"constraint\" @keyword)\n(layer_stmt \"layer\" @keyword)\n(layer_stmt \"above\" @keyword.operator)\n(layer_stmt \"below\" @keyword.operator)\n(stack_stmt \"above\" @keyword.operator)\n(stack_stmt \"below\" @keyword.operator)\n(ensure_stmt \"in\" @keyword)\n(encourage_stmt \"in\" @keyword)\n(style_assignment \":\" @operator)\n(style_typed_assignment \":\" @operator)\n\n; Operators and punctuation\n(wildcard \"?\" @operator)\n(binary_expression (\"+\" @operator))\n(binary_expression (\"-\" @operator))\n(binary_expression (\"*\" @operator))\n(binary_expression (\"/\" @operator))\n(binary_expression (\"%\" @operator))\n(binary_expression (\"mod\" @operator))\n(binary_expression (\"^\" @operator))\n(binary_expression (\".*\" @operator))\n(binary_expression (\"./\" @operator))\n(binary_expression (\"then\" @keyword.operator))\n(binary_expression (\"==\" @operator))\n(binary_expression (\"!=\" @operator))\n(binary_expression (\"<\" @operator))\n(binary_expression (\">\" @operator))\n(binary_expression (\"<=\" @operator))\n(binary_expression (\">=\" @operator))\n(binary_expression (\"&&\" @operator))\n(binary_expression (\"||\" @operator))\n(unary_expression (\"-\" @operator))\n(unary_expression (\"+\" @operator))\n(unary_expression (\"not\" @keyword.operator))\n(unary_expression (\"!\" @keyword.operator))\n(transpose_expression (\"'\" @operator))\n\n(argument_list \"(\" @punctuation.bracket)\n(argument_list \")\" @punctuation.bracket)\n(parameter_list \"(\" @punctuation.bracket)\n(parameter_list \")\" @punctuation.bracket)\n(list \"[\" @punctuation.bracket)\n(list \"]\" @punctuation.bracket)\n(vector \"(\" @punctuation.bracket)\n(vector \")\" @punctuation.bracket)\n(tuple \"{\" @punctuation.bracket)\n(tuple \"}\" @punctuation.bracket)\n(block \"{\" @punctuation.bracket)\n(block \"}\" @punctuation.bracket)\n\n; Paths and properties\n(path (identifier) @variable.other.member)\n(path (escaped_identifier) @variable.other.member)\n\n; Functions and calls\n(call_expression (identifier) @function)\n(call_expression (path) @function)\n(numberof_expression \"numberof\" @function)\n(listof_expression \"listof\" @function)\n(nameof_expression \"nameof\" @function)\n"
  },
  {
    "path": "runtime/queries/penrose/injections.scm",
    "content": "; TeX/LaTeX in Substance/Style labels\n((latex) @injection.content\n (#set! injection.language \"latex\"))\n\n; String-based labels are often TeX as well\n((label_stmt (string) @injection.content)\n (#set! injection.language \"latex\"))\n"
  },
  {
    "path": "runtime/queries/penrose/textobjects.scm",
    "content": "; Functions/constructors/predicates in Domain\n(constructor_decl) @function.around\n\n(function_decl) @function.around\n\n(predicate_decl) @function.around\n\n; Parameters\n(parameter_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n; Arguments\n(argument_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n; Comments\n(comment) @comment.inside\n(comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/perl/fold.scm",
    "content": "(comment) @fold\n(pod) @fold\n\n; fold the block-typed package statements only\n(package_statement (block)) @fold\n\n[(subroutine_declaration_statement)\n (conditional_statement)\n (loop_statement)\n (for_statement)\n (cstyle_for_statement)\n (block_statement)\n (phaser_statement)] @fold\n\n(anonymous_subroutine_expression) @fold\n\n; perhaps folks want to fold these too?\n[(anonymous_array_expression)\n (anonymous_hash_expression)] @fold\n"
  },
  {
    "path": "runtime/queries/perl/highlights.scm",
    "content": "[\n  \"use\" \"no\" \"require\" \"package\" \"class\" \"role\"\n] @keyword.control.import\n\n[\n  \"sub\" \"method\" \"async\" \"extended\"\n] @keyword.function\n\n[\n  \"if\" \"elsif\" \"else\" \"unless\"\n] @keyword.control.conditional\n\n[\n  \"while\" \"until\"\n  \"for\" \"foreach\"\n  \"do\"\n] @keyword.control.repeat\n\n[\n  \"my\" \"our\" \"local\" \"state\"\n] @keyword.storage.modifier\n\n[\n  \"last\" \"next\" \"redo\" \"goto\" \"return\"\n] @keyword.control.return\n\n[\n  \"undef\"\n] @constant.builtin\n\n(phaser_statement phase: _ @keyword.directive)\n(class_phaser_statement phase: _ @keyword.directive)\n\n[\n  \"or\" \"xor\" \"and\"\n  \"eq\" \"ne\" \"cmp\" \"lt\" \"le\" \"ge\" \"gt\"\n  \"isa\"\n] @keyword.operator\n\n(comment) @comment\n\n(function) @function\n\n(eof_marker) @keyword.directive\n(data_section) @comment\n\n(number) @constant.numeric\n(version) @constant\n\n(string_literal) @string\n(interpolated_string_literal) @string\n(quoted_word_list) @string\n(command_string) @string\n[(heredoc_token) (command_heredoc_token)] @string.special\n(heredoc_content) @string\n(heredoc_end) @string.special\n[(escape_sequence) (escaped_delimiter)] @constant.character.escape\n\n[(quoted_regexp) (match_regexp)] @string.regexp\n\n(autoquoted_bareword) @string.special\n\n[(scalar) (arraylen)] @variable\n(scalar_deref_expression [\"->\" \"$\" \"*\"] @variable)\n(array) @variable\n(array_deref_expression [\"->\" \"@\" \"*\"] @variable)\n(hash) @variable\n(hash_deref_expression [\"->\" \"%\" \"*\"] @variable)\n\n(array_element_expression [array:(_) \"->\" \"[\" \"]\"] @variable)\n(slice_expression [array:(_) \"->\" \"[\" \"]\"] @variable)\n(keyval_expression [array:(_) \"->\" \"[\" \"]\"] @variable)\n\n(hash_element_expression [hash:(_) \"->\" \"{\" \"}\"] @variable)\n(slice_expression [hash:(_) \"->\" \"[\" \"]\"] @variable)\n(keyval_expression [hash:(_) \"->\" \"[\" \"]\"] @variable)\n\n(hash_element_expression key: (bareword) @string.special)\n\n(use_statement (package) @type)\n(package_statement (package) @type)\n(require_expression (bareword) @type)\n\n(subroutine_declaration_statement name: (_) @function)\n(attrlist (attribute) @attribute)\n\n(goto_expression (label) @label)\n(loopex_expression (label) @label)\n\n(statement_label label: _ @label)\n\n(relational_expression operator: \"isa\" right: (bareword) @type)\n\n(function_call_expression (function) @function)\n(method_call_expression (method) @function.method)\n(method_call_expression invocant: (bareword) @type)\n\n(func0op_call_expression function: _ @function.builtin)\n(func1op_call_expression function: _ @function.builtin)\n"
  },
  {
    "path": "runtime/queries/perl/indents.scm",
    "content": "[\n  (block)\n  (conditional_statement)\n  (loop_statement)\n  (cstyle_for_statement)\n  (for_statement)\n  (elsif)\n  (array_element_expression)\n  (hash_element_expression)\n  (coderef_call_expression)\n  (anonymous_slice_expression)\n  (slice_expression)\n  (keyval_expression)\n  (anonymous_array_expression)\n  (anonymous_hash_expression)\n  (stub_expression)\n  (func0op_call_expression)\n  (func1op_call_expression)\n  (map_grep_expression)\n  (function_call_expression)\n  (method_call_expression)\n  (attribute)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/perl/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n((pod) @injection.content\n (#set! injection.language \"pod\"))\n"
  },
  {
    "path": "runtime/queries/perl/textobjects.scm",
    "content": "(subroutine_declaration_statement\n  body: (_) @function.inside) @function.around\n(anonymous_subroutine_expression\n  body: (_) @function.inside) @function.around\n\n(package_statement) @class.around\n(package_statement\n  (block) @class.inside)\n\n(list_expression\n  (_) @parameter.inside)\n\n(comment) @comment.around\n(pod) @comment.around\n"
  },
  {
    "path": "runtime/queries/pest/highlights.scm",
    "content": "(line_comment) @comment\n(block_comment) @comment\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n((identifier) @variable)\n((builtin) @type.builtin)\n((const) @constant)\n\n[\n  (string)\n  (character)\n] @string\n\n[\n  \"_\"\n  \"@\"\n  \"$\"\n]@keyword.storage.modifier\n\n[\n  \"~\"\n  \"|\"\n  \"=\"\n  \"+\"\n  \"*\"\n  \"&\"\n  \"^\"\n  \"!\"\n  \"?\"\n  \"..\"\n] @operator\n\n[\n  \"ANY\"\n  \"DROP\"\n  \"EOI\"\n  \"NEWLINE\"\n  \"PEEK\"\n  \"PEEK_ALL\"\n  \"POP\"\n  \"POP_ALL\"\n  \"PUSH\"\n  \"SOI\"\n] @keyword\n"
  },
  {
    "path": "runtime/queries/pest/indents.scm",
    "content": "[\n  (expression)\n] @indent\n\n[\n  \"]\"\n  \"}\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/pest/injections.scm",
    "content": "((line_comment) @injection.content\n (#set! injection.language \"comment\")\n (#set! injection.include-children))\n\n((block_comment) @injection.content\n (#set! injection.language \"comment\")\n (#set! injection.include-children))\n"
  },
  {
    "path": "runtime/queries/pest/textobjects.scm",
    "content": "(grammar_rule (_) @class.inside) @class.around\n(term (_) @entry.inside) @entry.around\n\n(line_comment) @comment.inside\n(line_comment)+ @comment.around\n\n(block_comment) @comment.inside\n(block_comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/php/highlights.scm",
    "content": "(php_tag) @tag\n\"?>\" @tag\n\n; Variables\n\n(relative_scope) @variable.builtin\n\n(variable_name) @variable\n\n((name) @constant\n (#match? @constant \"^_?[A-Z][A-Z\\\\d_]+$\"))\n\n((name) @constructor\n (#match? @constructor \"^[A-Z]\"))\n\n((name) @variable.builtin\n (#eq? @variable.builtin \"this\"))\n\n; Types\n[\n  (primitive_type)\n  (cast_type)\n] @type.builtin\n\n(named_type\n  [ (name) @type\n    (qualified_name (name) @type)])\n\n(base_clause\n  [ (name) @type\n    (qualified_name (name) @type)])\n\n(enum_declaration\n  name: (name) @type.enum)\n\n(interface_declaration\n  name: (name) @constructor)\n\n(class_declaration\n  name: (name) @constructor)\n\n(trait_declaration\n  name:(name) @constructor)\n\n(namespace_definition\n  name: (namespace_name (name) @namespace))\n\n(namespace_name_as_prefix \n  (namespace_name (name) @namespace))\n\n(namespace_use_clause\n  [ (name) @namespace\n    (qualified_name (name) @type) ])\n\n(namespace_aliasing_clause (name) @namespace)\n\n(class_interface_clause\n  [(name) @type\n   (qualified_name (name) @type)])\n\n(scoped_call_expression\n  scope: [(name) @type\n          (qualified_name (name) @type)])\n\n(class_constant_access_expression\n  . [(name) @constructor\n     (qualified_name (name) @constructor)]\n  (name) @constant)\n\n(use_declaration (name) @type)\n\n(binary_expression\n  operator: \"instanceof\"\n  right: [(name) @type\n          (qualified_name (name) @type)])\n\n; Superglobals\n(subscript_expression\n  (variable_name(name) @constant.builtin\n    (#match? @constant.builtin \"^_?[A-Z][A-Z\\\\d_]+$\")))\n\n; Functions\n\n(array_creation_expression \"array\" @function.builtin)\n(list_literal \"list\" @function.builtin)\n\n(method_declaration\n  name: (name) @function.method)\n\n(function_call_expression\n  function: (_) @function)\n\n(scoped_call_expression\n  name: (name) @function)\n\n(member_call_expression\n  name: (name) @function.method)\n\n(function_definition\n  name: (name) @function)\n\n(nullsafe_member_call_expression\n    name: (name) @function.method)\n\n(object_creation_expression\n  [(name) @constructor\n   (qualified_name (name) @constructor)])\n\n; Parameters\n[\n  (simple_parameter)\n  (variadic_parameter)\n] @variable.parameter\n\n(argument\n    (name) @variable.parameter)\n\n; Member\n\n(property_element\n  (variable_name) @variable.other.member)\n\n(member_access_expression\n  name: (variable_name (name)) @variable.other.member)\n(member_access_expression\n  name: (name) @variable.other.member)\n\n; Attributes\n(attribute_list) @attribute\n\n; Basic tokens\n\n[\n  (string)\n  (encapsed_string)\n  (heredoc_body)\n  (nowdoc_body)\n  (shell_command_expression) \n] @string\n(escape_sequence) @constant.character.escape\n\n(boolean) @constant.builtin.boolean\n(null) @constant.builtin\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(comment) @comment\n\n(goto_statement (name) @label)\n(named_label_statement (name) @label)\n\n; Keywords\n\n[\n  \"default\" \n  \"echo\" \n  \"enum\" \n  \"extends\" \n  \"final\" \n  \"goto\"\n  \"global\" \n  \"implements\" \n  \"insteadof\" \n  \"new\" \n  \"private\" \n  \"protected\" \n  \"public\" \n  \"clone\"\n  \"unset\"\n] @keyword\n\n[\n  \"if\" \n  \"else\" \n  \"elseif\" \n  \"endif\" \n  \"switch\" \n  \"endswitch\" \n  \"case\" \n  \"match\" \n  \"declare\" \n  \"enddeclare\" \n  \"??\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n  \"endfor\"\n  \"foreach\" \n  \"endforeach\" \n  \"while\" \n  \"endwhile\" \n  \"do\"\n] @keyword.control.repeat\n\n[\n  \n  \"include_once\" \n  \"include\" \n  \"require_once\" \n  \"require\" \n  \"use\"\n] @keyword.control.import\n\n[\n  \"return\" \n  \"break\" \n  \"continue\" \n  \"yield\"\n] @keyword.control.return\n\n[\n  \"throw\" \n  \"try\" \n  \"catch\" \n  \"finally\"\n] @keyword.control.exception\n\n[\n  \"as\" \n  \"or\"\n  \"xor\"\n  \"and\"\n  \"instanceof\"\n] @keyword.operator\n\n[\n  \"fn\" \n  \"function\" \n] @keyword.function\n\n[\n  \"namespace\" \n  \"class\" \n  \"interface\" \n  \"trait\" \n  \"abstract\" \n] @keyword.storage.type\n\n[\n  \"static\"\n  \"const\"\n  \"readonly\"\n] @keyword.storage.modifier\n\n[\n  \",\"\n  \";\"\n  \":\"\n  \"\\\\\"\n ] @punctuation.delimiter\n\n[\n  (php_tag)\n  \"?>\"\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"#[\"\n] @punctuation.bracket\n\n[\n  \"=\"\n\n  \".\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"+\"\n  \"%\"\n  \"**\"\n\n  \"~\"\n  \"|\"\n  \"^\"\n  \"&\"\n  \"<<\"\n  \">>\"\n\n  \"->\"\n  \"?->\"\n\n  \"=>\"\n\n  \"<\"\n  \"<=\"\n  \">=\"\n  \">\"\n  \"<>\"\n  \"==\"\n  \"!=\"\n  \"===\"\n  \"!==\"\n\n  \"!\"\n  \"&&\"\n  \"||\"\n\n  \".=\"\n  \"-=\"\n  \"+=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"**=\"\n  \"&=\"\n  \"|=\"\n  \"^=\"\n  \"<<=\"\n  \">>=\"\n  \"??=\"\n  \"--\"\n  \"++\"\n\n  \"@\"\n  \"::\"\n] @operator\n"
  },
  {
    "path": "runtime/queries/php/indents.scm",
    "content": "[\n  (array_creation_expression)\n  (arguments)\n  (formal_parameters)\n  (compound_statement)\n  (declaration_list)\n  (binary_expression)\n  (return_statement)\n  (expression_statement)\n  (switch_block)\n  (anonymous_function_use_clause)\n] @indent\n\n[\n  \"}\"\n  \")\"\n  \"]\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/php/injections.scm",
    "content": "((text) @injection.content\n (#set! injection.language \"html\")\n (#set! injection.combined))\n\n((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((function_call_expression\n function: (name) @_function\n arguments: (arguments . (argument (_ (string_value) @injection.content))))\n (#match? @_function \"^preg_\")\n (#set! injection.language \"regex\"))\n\n((function_call_expression\n function: (name) @_function\n arguments: (arguments (_) (argument (_ (string_value) @injection.content))))\n (#match? @_function \"^mysqli_\")\n (#set! injection.language \"sql\"))\n\n((member_call_expression\n object: (_)\n name: (name) @_function\n arguments: (arguments . (argument (_ (string_value) @injection.content))))\n (#match? @_function \"^(prepare|query)$\")\n (#set! injection.language \"sql\"))\n"
  },
  {
    "path": "runtime/queries/php/rainbows.scm",
    "content": "[\n  (declaration_list)\n  (compound_statement)\n  (array_creation_expression)\n  (subscript_expression)\n  (parenthesized_expression)\n  (formal_parameters)\n  (arguments)\n  (catch_clause)\n  (foreach_statement)\n  (switch_block)\n  (anonymous_function_use_clause)\n] @rainbow.scope\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/php/tags.scm",
    "content": "(class_declaration\n  name: (name) @name) @definition.class\n\n(function_definition\n  name: (name) @name) @definition.function\n\n(method_declaration\n  name: (name) @name) @definition.function\n\n(object_creation_expression\n  [\n    (qualified_name (name) @name)\n    (variable_name (name) @name)\n  ]) @reference.class\n\n(function_call_expression\n  function: [\n    (qualified_name (name) @name)\n    (variable_name (name)) @name\n  ]) @reference.call\n\n(scoped_call_expression\n  name: (name) @name) @reference.call\n\n(member_call_expression\n  name: (name) @name) @reference.call\n"
  },
  {
    "path": "runtime/queries/php/textobjects.scm",
    "content": "(class_declaration\n  body: (_) @class.inside) @class.around\n\n(interface_declaration\n  body: (_) @class.inside) @class.around\n\n(trait_declaration\n  body: (_) @class.inside) @class.around\n\n(enum_declaration\n  body: (_) @class.inside) @class.around\n\n(function_definition\n  body: (_) @function.inside) @function.around\n\n(method_declaration\n  body: (_) @function.inside) @function.around\n\n(arrow_function \n  body: (_) @function.inside) @function.around\n  \n(anonymous_function_creation_expression\n  body: (_) @function.inside) @function.around\n\n(anonymous_function_use_clause\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(formal_parameters\n  ([\n    (simple_parameter)\n    (variadic_parameter)\n    (property_promotion_parameter)\n  ] @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(array_creation_expression\n  (array_element_initializer\n    (_) @entry.inside\n  ) @entry.around @entry.movement)\n\n(list_literal\n  (_) @entry.inside @entry.around @entry.movement)\n\n[\n  (enum_case)\n] @entry.around @entry.movement\n"
  },
  {
    "path": "runtime/queries/php-only/highlights.scm",
    "content": "(php_tag) @tag\n\"?>\" @tag\n\n; Variables\n\n(variable_name) @variable\n\n(relative_scope) @variable.builtin\n\n((name) @constant\n (#match? @constant \"^_?[A-Z][A-Z\\\\d_]+$\"))\n((name) @constant.builtin\n (#match? @constant.builtin \"^__[A-Z][A-Z\\d_]+__$\"))\n\n((name) @constructor\n (#match? @constructor \"^[A-Z]\"))\n\n((name) @variable.builtin\n (#eq? @variable.builtin \"this\"))\n\n; Types\n\n(primitive_type) @type.builtin\n(cast_type) @type.builtin\n(named_type (name) @type) @type\n(named_type (qualified_name) @type) @type\n\n; Functions\n\n(array_creation_expression \"array\" @function.builtin)\n(list_literal \"list\" @function.builtin)\n\n(method_declaration\n  name: (name) @function.method)\n\n(function_call_expression\n  function: [(qualified_name (name)) (name)] @function)\n\n(scoped_call_expression\n  name: (name) @function)\n\n(member_call_expression\n  name: (name) @function.method)\n\n(function_definition\n  name: (name) @function)\n\n; Member\n\n(property_element\n  (variable_name) @variable.other.member)\n\n(member_access_expression\n  name: (variable_name (name)) @variable.other.member)\n(member_access_expression\n  name: (name) @variable.other.member)\n\n; Basic tokens\n[\n  (string)\n  (string_value)\n  (encapsed_string)\n  (heredoc)\n  (heredoc_body)\n  (nowdoc_body)\n] @string\n(boolean) @constant.builtin.boolean\n(null) @constant.builtin\n(integer) @constant.builtin.integer\n(float) @constant.builtin.float\n(comment) @comment\n\n\"$\" @operator\n\n; Keywords\n\n\"abstract\" @keyword\n\"as\" @keyword\n\"break\" @keyword\n\"case\" @keyword\n\"catch\" @keyword\n\"class\" @keyword\n\"const\" @keyword\n\"continue\" @keyword\n\"declare\" @keyword\n\"default\" @keyword\n\"do\" @keyword\n\"echo\" @keyword\n\"else\" @keyword\n\"elseif\" @keyword\n\"enddeclare\" @keyword\n\"endforeach\" @keyword\n\"endif\" @keyword\n\"endswitch\" @keyword\n\"endwhile\" @keyword\n\"extends\" @keyword\n\"final\" @keyword\n\"finally\" @keyword\n\"for\" @keyword\n\"foreach\" @keyword\n\"function\" @keyword\n\"global\" @keyword\n\"if\" @keyword\n\"implements\" @keyword\n\"include_once\" @keyword\n\"include\" @keyword\n\"insteadof\" @keyword\n\"interface\" @keyword\n\"namespace\" @keyword\n\"new\" @keyword\n\"private\" @keyword\n\"protected\" @keyword\n\"public\" @keyword\n\"require_once\" @keyword\n\"require\" @keyword\n\"return\" @keyword\n\"static\" @keyword\n\"switch\" @keyword\n\"throw\" @keyword\n\"trait\" @keyword\n\"try\" @keyword\n\"use\" @keyword\n\"while\" @keyword\n"
  },
  {
    "path": "runtime/queries/php-only/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n\n(heredoc\n  (heredoc_body) @injection.content\n  (heredoc_end) @injection.language)\n\n(nowdoc\n  (nowdoc_body) @injection.content\n  (heredoc_end) @injection.language)\n"
  },
  {
    "path": "runtime/queries/php-only/tags.scm",
    "content": "(namespace_definition\n  name: (namespace_name) @name) @module\n\n(interface_declaration\n  name: (name) @name) @definition.interface\n\n(trait_declaration\n  name: (name) @name) @definition.interface\n\n(class_declaration\n  name: (name) @name) @definition.class\n\n(class_interface_clause [(name) (qualified_name)] @name) @impl\n\n(property_declaration\n  (property_element (variable_name (name) @name))) @definition.field\n\n(function_definition\n  name: (name) @name) @definition.function\n\n(method_declaration\n  name: (name) @name) @definition.function\n\n(object_creation_expression\n  [\n    (qualified_name (name) @name)\n    (variable_name (name) @name)\n  ]) @reference.class\n\n(function_call_expression\n  function: [\n    (qualified_name (name) @name)\n    (variable_name (name)) @name\n  ]) @reference.call\n\n(scoped_call_expression\n  name: (name) @name) @reference.call\n\n(member_call_expression\n  name: (name) @name) @reference.call\n"
  },
  {
    "path": "runtime/queries/picat/highlights.scm",
    "content": "; hightlights.scm\n\n[\n  \".\"\n  \"@\"\n  \"**\"\n  \"+\"\n  \"-\"\n  \"~\"\n  \"*\"\n  \"/\"\n  \"//\"\n  \"/<\"\n  \"/>\"\n  \"div\"\n  \"mod\"\n  \"rem\"\n  \">>\"\n  \"<<\"\n  \"/\\\\\"\n  \"^\"\n  \"\\\\/\"\n  \"..\"\n  \"++\"\n  \"=\"\n  \"!=\"\n  \":=\"\n  \"==\"\n  \"!==\"\n  \"=:=\"\n  \"<\"\n  \"=<\"\n  \"<=\"\n  \">\"\n  \">=\"\n  \"::\"\n  \"in\"\n  \"notin\"\n  \"=..\"\n  \"#=\"\n  \"#!=\"\n  \"#<\"\n  \"#=<\"\n  \"#<=\"\n  \"#>\"\n  \"#>=\"\n  \"@<\"\n  \"@=<\"\n  \"@<=\"\n  \"@>\"\n  \"@>=\"\n  \"#~\"\n  \"#/\\\\\"\n  \"#^\"\n  \"#\\\\/\"\n  \"#=>\"\n  \"#<=>\"\n  \"not\"\n  \"once\"\n  \"\\\\+\"\n  \"&&\"\n  \";\"\n  \"||\"\n] @operator\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n]  @punctuation.bracket\n\n\n[\n  \"do\"\n  \"else\"\n  \"end\"\n  \"foreach\"\n  \"if\"\n  \"import\"\n  \"in\"\n  \"index\"\n  \"module\"\n  \"private\"\n  \"table\"\n  \"then\"\n  \"while\"\n  \"throw\"\n  \"true\"\n  \"false\"\n  \"fail\"\n] @keyword\n\n(predicate_definition (predicate_rule name: (atom) @function))\n(predicate_definition (predicate_fact name: (atom) @function))\n(function_definition (function_rule name: (atom) @function))\n(function_definition (function_fact name: (atom) @function))\n(actor_definition (action_rule name: (atom) @function))\n(actor_definition (nonbacktrackable_predicate_rule name: (atom) @function))\n\n(integer) @constant.numeric.integer\n(real) @constant.numeric.float\n(string) @string\n(comment) @comment\n\n[\n  \"=>\"\n  \"->\"\n  \"$\"\n] @punctuation.special\n\n\n(parameters\n  [(variable) @variable.parameter\n   (atom) @variable.parameter\n   (array_expression [(variable) @variable.parameter (atom) @variable.parameter])\n   (list_expression [(variable) @variable.parameter (atom) @variable.parameter])\n   (as_pattern_expression left: [(variable) @variable.parameter (atom) @variable.parameter])])\n\n(function_call function: (atom) @function)\n(dot_expression right: (atom) @function)\n"
  },
  {
    "path": "runtime/queries/picat/indents.scm",
    "content": "[\n  (array_expression)\n  (list_expression)\n  (braced_goal)\n  (arguments)\n  (parameters)\n\n  (predicate_rule)\n  (predicate_fact)\n  (function_rule)\n  (function_fact)\n  (action_rule)\n  (nonbacktrackable_predicate_rule)\n\n  (if_statement)\n  (while_statement)\n  (foreach_statement)\n  (do_statement)\n] @indent\n\n[\n  \")\"\n  \"}\"\n  \"]\"\n] @outdent\n\n(if_statement \"elseif\" (_) @outdent)\n(if_statement \"else\" (_) @outdent)\n(while_statement \"do\" (_) @outdent)\n(do_statement \"while\" (_) @outdent)\n"
  },
  {
    "path": "runtime/queries/picat/locals.scm",
    "content": "; locals\n\n[\n  (predicate_definition)\n  (function_definition)\n  (actor_definition)\n  (actor_definition)\n] @local.scope\n\n(import_declaration (_) @local.definition.namespace)\n\n(module_declaration (_) @local.definition.namespace)\n\n(binary_relational_expression left: (atom) @local.definition.variable)\n\n(parameters\n  [(variable) @local.definition.variable.parameter\n   (atom) @local.definition.variable.parameter\n   (array_expression [(variable) (atom)] @local.definition.variable.parameter)\n   (list_expression [(variable) (atom)] @local.definition.variable.parameter)\n   (as_pattern_expression left: [(variable) (atom)] @local.definition.variable.parameter)])\n\n(arguments (argument [(variable) @local.reference (atom) @local.reference]))\n\n[(variable) (atom)] @local.reference\n"
  },
  {
    "path": "runtime/queries/picat/rainbows.scm",
    "content": "[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @rainbow.bracket\n\n[\n  (array_expression)\n  (list_expression)\n  (parameters)\n  (arguments)\n  (braced_goal)\n] @rainbow.scope\n"
  },
  {
    "path": "runtime/queries/picat/tags.scm",
    "content": "; tags.scm\n\n(\n  (comment)* @doc\n  .\n  [\n    (function_definition\n      [(function_rule name: (_) @name) @definition.function\n       (function_fact name: (_) @name) @definition.function])\n    (predicate_definition\n      [(predicate_rule name: (_) @name) @definition.function\n       (predicate_fact name: (_) @name) @definition.function])\n    (actor_definition\n      [(action_rule name: (_) @name) @definition.function\n       (nonbacktrackable_predicate_rule name: (_) @name) @definition.function])\n  ]\n  (#strip! @doc \"^%\\\\s*\")\n  (#select-adjacent! @doc @definition.function)\n)\n\n(function_call function: (_) @name @reference.call)\n\n(dot_expression right: (_) @reference.call)\n\n(import_declaration (_) @name) @reference.module\n\n(module_declaration (_) @name) @definition.module\n"
  },
  {
    "path": "runtime/queries/picat/textobjects.scm",
    "content": "[\n  (function_definition\n    [(function_rule) (function_fact)] @function.inside)\n  (predicate_definition\n    [(predicate_rule) (predicate_fact)] @function.inside)\n  (actor_definition\n    [(action_rule) (nonbacktrackable_predicate_rule)] @function.inside)\n] @function.around\n\n(import_declaration\n  (atom) @function.around)\n\n(parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n(comment)+ @comment.around\n\n(array_expression\n  (_) @entry.around)\n\n(list_expression\n  (_) @entry.around)\n"
  },
  {
    "path": "runtime/queries/pip-requirements/highlights.scm",
    "content": "(comment) @comment\n\n(requirement (package) @variable)\n(extras (package) @variable.parameter)\n\n; \"==\" | \">\" | \"<\" | \">=\" | \"<=\"\n(version_cmp) @operator\n\n(version) @constant.numeric\n\n(marker_var) @attribute\n\n(marker_op) @keyword.operator\n\n[\n  \"[\" \"]\"\n  \"(\" \")\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \";\"\n  \"@\"\n] @punctuation.delimiter\n\n[\n  \"${\" \"}\"\n] @punctuation.special\n\n\"=\" @operator\n\n(path) @string.special.path\n(url) @string.special.url\n\n(option) @function\n\n(env_var) @constant\n\n(quoted_string) @string\n\n(linebreak) @constant.character.escape\n"
  },
  {
    "path": "runtime/queries/pip-requirements/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/pkgbuild/highlights.scm",
    "content": "; inherits: bash\n"
  },
  {
    "path": "runtime/queries/pkgbuild/indents.scm",
    "content": "; inherits: bash\n"
  },
  {
    "path": "runtime/queries/pkgbuild/injections.scm",
    "content": "; inherits: bash\n"
  },
  {
    "path": "runtime/queries/pkgbuild/textobjects.scm",
    "content": "; inherits: bash\n"
  },
  {
    "path": "runtime/queries/pkl/highlights.scm",
    "content": "; Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.\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;     https://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; this definition is imprecise in that \n; * any qualified or unqualified call to a method named \"Regex\" is considered a regex\n; * string delimiters are considered part of the regex\n\n; Operators\n\n[\n  \"??\"\n  \"@\"\n  \"=\"\n  \"<\"\n  \">\"\n  \"!\"\n  \"==\"\n  \"!=\"\n  \"<=\"\n  \">=\"\n  \"&&\"\n  \"||\"\n  \"+\"\n  \"-\"\n  \"**\"\n  \"*\"\n  \"/\"\n  \"~/\"\n  \"%\"\n  \"|>\"\n] @keyword.operator\n\n[\n  \"?\"\n  \"|\"\n  \"->\"\n] @operator.type\n\n[\n  \",\"\n  \":\"\n  \".\"\n  \"?.\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"]\"\n  \"{\"\n  \"}\"\n  ; \"[\" @punctuation.bracket TODO: FIGURE OUT HOW TO REFER TO CUSTOM TOKENS\n] @punctuation.bracket\n\n; Keywords\n\n[\n  \"abstract\"\n  \"amends\"\n  \"as\"\n  \"class\"\n  \"extends\"\n  \"external\"\n  \"function\"\n  \"hidden\"\n  \"import\"\n  \"import*\"\n  \"in\"\n  \"let\"\n  \"local\"\n  \"module\"\n  \"new\"\n  \"open\"\n  \"out\"\n  \"typealias\"\n  \"when\"\n] @keyword\n\n[\n  \"if\"\n  \"is\"\n  \"else\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n] @keyword.control.repeat\n\n(importExpr \"import\" @keyword.control.import)\n(importGlobExpr \"import*\" @keyword.control.import)\n\n\"read\" @function.builtin\n\"read?\" @function.builtin\n\"read*\" @function.builtin\n\"throw\" @function.builtin\n\"trace\" @function.builtin\n\n(moduleExpr \"module\" @type.builtin)\n\"nothing\" @type.builtin\n\"unknown\" @type.builtin\n\n(outerExpr) @variable.builtin\n\"super\" @variable.builtin\n(thisExpr) @variable.builtin\n\n[\n  (falseLiteral)\n  (nullLiteral)\n  (trueLiteral)\n] @constant.builtin\n\n; Literals\n\n(stringConstant) @string\n(slStringLiteral) @string\n(mlStringLiteral) @string\n\n(escapeSequence) @constant.character.escape\n\n(intLiteral) @constant.numeric.integer\n(floatLiteral) @constant.numeric.float\n\n(interpolationExpr\n  \"\\\\(\" @punctuation.special\n  \")\" @punctuation.special) @embedded\n\n(interpolationExpr\n \"\\\\#(\" @punctuation.special\n \")\" @punctuation.special) @embedded\n\n(interpolationExpr\n  \"\\\\##(\" @punctuation.special\n  \")\" @punctuation.special) @embedded\n\n(lineComment) @comment\n(blockComment) @comment\n(docComment) @comment\n\n; Identifiers\n\n(identifier) @variable\n\n(classProperty (identifier) @variable.other.member)\n(objectProperty (identifier) @variable.other.member)\n\n(parameterList (typedIdentifier (identifier) @variable.parameter))\n(objectBodyParameters (typedIdentifier (identifier) @variable.parameter))\n\n; Method definitions\n\n(classMethod (methodHeader (identifier)) @function.method)\n(objectMethod (methodHeader (identifier)) @function.method)\n\n; Method calls\n\n(methodCallExpr\n  (identifier) @function.method)\n\n; Types\n\n(clazz (identifier) @type)\n(typeAlias (identifier) @type)\n((identifier) @type\n (#match? @type \"^[A-Z]\"))\n\n(typeArgumentList\n  \"<\" @punctuation.bracket\n  \">\" @punctuation.bracket)\n"
  },
  {
    "path": "runtime/queries/pkl/indents.scm",
    "content": "; Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.\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;     https://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; this definition is imprecise in that \n; * any qualified or unqualified call to a method named \"Regex\" is considered a regex\n; * string delimiters are considered part of the regex\n[\n  (objectBody)\n  (classBody)\n  (ifExpr)\n  (mlStringLiteral) ; This isn't perfect; newlines are too indented but it's better than if omitted.\n] @indent\n"
  },
  {
    "path": "runtime/queries/pkl/injections.scm",
    "content": "; Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.\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;     https://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; this definition is imprecise in that \n; * any qualified or unqualified call to a method named \"Regex\" is considered a regex\n; * string delimiters are considered part of the regex\n(\n  ((methodCallExpr (identifier) @methodName (argumentList (slStringLiteral) @injection.content))\n    (#set! injection.language \"regex\"))\n  (#eq? @methodName \"Regex\"))\n \n((lineComment) @injection.content\n (#set! injection.language \"comment\"))\n\n((blockComment) @injection.content\n (#set! injection.language \"comment\"))\n\n((docComment) @injection.content\n (#set! injection.language \"markdown\"))\n"
  },
  {
    "path": "runtime/queries/po/highlights.scm",
    "content": "[\n  (msgctxt)\n  (msgid)\n  (msgid_plural)\n  (msgstr)\n]@keyword\n\n(comment) @comment\n(comment (comment_reference (text) @string.special.path))\n(comment (comment_flag (text) @label))\n\n(number) @constant.numeric\n(string) @string\n"
  },
  {
    "path": "runtime/queries/po/textobjects.scm",
    "content": "(msgid) @parameter.inside\n\n(comment) @comment.inside\n(comment)+ @comment.around\n\n\n"
  },
  {
    "path": "runtime/queries/pod/highlights.scm",
    "content": "; A highlight file for nvim-treesitter to use\n\n[(pod_command)\n (command)\n (cut_command)] @keyword\n\n(command_paragraph\n  (command) @keyword\n  (#eq? @keyword \"=head1\")\n  (content) @markup.heading.1)\n\n(command_paragraph\n  (command) @keyword\n  (#eq? @keyword \"=head2\")\n  (content) @markup.heading.2)\n\n(command_paragraph\n  (command) @keyword\n  (#eq? @keyword \"=head3\")\n  (content) @markup.heading.3)\n\n(command_paragraph\n  (command) @keyword\n  (#eq? @keyword \"=head4\")\n  (content) @markup.heading.4)\n\n(command_paragraph\n  (command) @keyword\n  (#eq? @keyword \"=head5\")\n  (content) @markup.heading.5)\n\n(command_paragraph\n  (command) @keyword\n  (#eq? @keyword \"=head6\")\n  (content) @markup.heading.6)\n\n(command_paragraph\n  (command) @keyword\n  (#match? @keyword \"^=over\")\n  (content) @constant.numeric)\n\n(command_paragraph\n  (command) @keyword\n  (#match? @keyword \"^=item\")\n  (content) @markup)\n\n(command_paragraph\n  (command) @keyword\n  (#match? @keyword \"^=encoding\")\n  (content) @string.special)\n\n(command_paragraph\n  (command) @keyword\n  (#not-match? @keyword \"^=(head|over|item|encoding)\")\n  (content) @string)\n\n(verbatim_paragraph (content) @markup.raw)\n\n(interior_sequence\n  (sequence_letter) @constant.character\n  [\"<\" \">\"] @punctuation.delimiter\n)\n\n(interior_sequence\n  (sequence_letter) @character\n  (#eq? @character \"B\")\n  (content) @markup.bold)\n\n(interior_sequence\n  (sequence_letter) @character\n  (#eq? @character \"C\")\n  (content) @markup.literal)\n\n(interior_sequence\n  (sequence_letter) @character\n  (#eq? @character \"F\")\n  (content) @markup.underline @string.special)\n\n(interior_sequence\n  (sequence_letter) @character\n  (#eq? @character \"I\")\n  (content) @markup.bold)\n\n(interior_sequence\n  (sequence_letter) @character\n  (#eq? @character \"L\")\n  (content) @markup.link.url)\n\n(interior_sequence\n  (sequence_letter) @character\n  (#eq? @character \"X\")\n  (content) @markup.reference)\n\n(interior_sequence\n  (sequence_letter) @character\n  (#eq? @character \"E\")\n  (content) @string.special.escape)\n"
  },
  {
    "path": "runtime/queries/ponylang/highlights.scm",
    "content": "[\n  (line_comment)\n  (block_comment)\n] @comment\n\n(bool) @constant.builtin.boolean\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(character) @constant.character\n\n;; strings and docstring\n(string) @string\n(source_file docstring: (string) @string.special)\n(entity docstring: (string) @string.special)\n(method docstring: (string) @string.special) ; docstring for methods without body\n(behavior docstring: (string) @string.special) ; docstring for methods without body\n(constructor docstring: (string) @string.special) ; docstring for methods without body\n(method body: (block . (string) @string.special)) ; docstring for methods with body\n(behavior body: (block . (string) @string.special))\n(constructor body: (block . (string) @string.special))\n(field docstring: (string) @string.special)\n\n;; Punctuation\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n[\n  \";\"\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n(this) @variable.builtin\n\n(field name: (identifier) @variable.other.member)\n\n\"use\" @keyword.control.import\n[\n  \"for\"\n  \"in\"\n  \"while\"\n  \"do\"\n  \"repeat\"\n  \"until\"\n] @keyword.control.repeat\n[\n \"if\"\n \"ifdef\"\n \"iftype\"\n \"then\"\n \"elseif\"\n \"else\"\n \"match\"\n] @keyword.control.conditional\n[\n  \"break\"\n  \"continue\"\n  \"return\"\n  \"error\"\n  \"compile_error\"\n  \"compile_intrinsic\"\n] @keyword.control.return\n[\n  \"recover\"\n  \"consume\"\n  \"end\"\n  \"try\"\n  \"with\"\n] @keyword.control\n\n[\n  \"as\"\n  \"is\"\n  \"isnt\"\n  \"not\"\n  \"and\"\n  \"or\"\n  \"xor\"\n  \"digestof\"\n  \"addressof\"\n  (location)\n] @keyword.operator\n\n(entity_type) @keyword.storage.type\n\n[\n  \"var\"\n  \"let\"\n  \"embed\"\n] @keyword.storage\n\n[\n  \"fun\"\n  \"be\"\n  \"new\"\n] @keyword.function\n\n[\n  (cap)\n  (gencap)\n  \"where\"\n] @keyword\n\n[\n  (partial)\n  \"=>\"\n  \"~\"\n  \".>\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"%%\"\n  \"+~\"\n  \"-~\"\n  \"/~\"\n  \"*~\"\n  \"%~\"\n  \"%%~\"\n\n  \">>\"\n  \"<<\"\n  \">>~\"\n  \"<<~\"\n\n  \"==\"\n  \"!=\"\n  \">\"\n  \"<\"\n  \">=\"\n  \"<=\"\n] @operator\n\n;; variables\n;; references to upper case things are considered constructors\n(identifier) @variable\n(\n  (identifier) @constructor\n  (#match? @constructor \"^[A-Z]\")\n)\n\n;; Types\n(entity name: (identifier) @type)\n(nominal_type name: (identifier) @type)\n(typeparams (typeparam name: (identifier) @type))\n\n;; constructors / methods / behaviors\n(constructor name: (identifier) @constructor)\n(method name: (identifier) @function.method)\n(behavior name: (identifier) @function.method)\n\n;; method calls\n; TODO: be more specific about what is the actual function reference\n(call callee: (field_access field: (identifier) @function.method))\n(call callee: (_) @function.method)\n(ffi_call name: (_) @function)\n(partial_application function: (identifier) @function.method)\n(chain function: (identifier) @function.method)\n\n;; fields and params\n(field name: (identifier) @variable.other.member)\n(param (identifier) @variable.parameter)\n(lambdaparam (identifier) @variable.parameter)\n\n;; this.field is considered a member access\n(field_access base: (this) field: (identifier) @variable.other.member)\n\n;; annotations\n(annotations (identifier) @attribute)\n\n"
  },
  {
    "path": "runtime/queries/ponylang/indents.scm",
    "content": "; queries for helix to do automatic indentation upon hitting enter\n; TODO: needs more work, cover more cases\n[\n  (entity)\n  (method)\n  (behavior)\n  (constructor)\n  (block)\n  (tuple)\n  (grouped)\n] @indent\n(match_case body: (block) @indent)\n; ffi_call and call\n(_ arguments: (_) @indent)\n(assignment right: (_) @indent\n (#set! \"scope\" \"all\")\n)\n\n[\n  (params)\n  (object)\n  (\"if\")\n] @extend\n(lambda params: (_) @extend)\n\n[\n  \"end\"\n  \"}\"\n  \"]\"\n  \")\"\n  \"|\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/ponylang/locals.scm",
    "content": "[\n  (entity)\n  (method)\n  (behavior)\n  (constructor)\n  (\"if\")\n  (elseif)\n  (ifdef)\n  (elseifdef)\n  (iftype)\n  (elseiftype)\n  (match)\n  (match_case)\n  (\"while\")\n  (\"repeat\")\n  (\"for\")\n  (lambda)\n  (try_block)\n  (with)\n] @local.scope\n(match else_block: (block) @local.scope)\n(try_block else_block: (block) @local.scope)\n(try_block then_block: (block) @local.scope)\n(with else_block: (block) @local.scope)\n\n(param name: (identifier) @local.definition.variable.parameter)\n(lambdaparam name: (identifier) @local.definition.variable.parameter)\n\n; only lower case identifiers are references\n(\n  (identifier) @local.reference\n  (#match? @local.reference \"^[a-z_][a-zA-Z_]*\")\n)\n"
  },
  {
    "path": "runtime/queries/ponylang/textobjects.scm",
    "content": ";; Queries for helix to select textobjects: https://docs.helix-editor.com/usage.html#textobjects\n;;  function.inside\n;; function.around\n;; class.inside\n;; class.around\n;; test.inside\n;; test.around\n;; parameter.inside\n;; comment.inside\n;; comment.around\n\n;; Queries for navigating using textobjects\n\n[\n  (line_comment)\n  (block_comment)\n] @comment.inside\n\n(line_comment)+ @comment.around\n(block_comment) @comment.around\n\n(entity members: (members)? @class.inside) @class.around\n(object members: (members)? @class.inside) @class.around\n\n(method\n  body: (block)? @function.inside\n) @function.around\n(behavior\n  body: (block)? @function.inside\n) @function.around\n(constructor\n  body: (block)? @function.inside\n) @function.around\n(lambda\n  body: (block)? @function.inside\n) @function.outside\n\n(params\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around\n)\n(lambda\n  params: ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around\n)\n(typeargs\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around\n)\n(typeparams\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around\n)\n(arguments\n  positional: (positional_args\n                ((_) @parameter.inside . \",\"? @parameter.around)? @parameter.around)\n  ; TODO: get named args right\n  named: (named_args ((_) @parameter.inside . \",\"? @parameter.around)? @parameter.around)\n)\n\n(\n  (entity\n    provides: (type (nominal_type name: (identifier) @_provides))\n    members: (members) @test.inside\n  ) @test.outside\n  (#eq? @_provides \"UnitTest\")\n)\n\n"
  },
  {
    "path": "runtime/queries/powershell/highlights.scm",
    "content": "[\n  \"if\"\n  \"elseif\"\n  \"else\"\n  \"switch\"\n] @keyword.control.conditional\n\n[\n  \"foreach\"\n  \"for\"\n  \"while\"\n  \"do\"\n  \"until\"\n] @keyword.control.repeat\n\n[\n  \"break\"\n  \"continue\"\n  \"return\"\n] @keyword.control.return\n\n\"in\" @keyword.operator\n\n\"function\" @keyword.function\n\n[\n  \"class\"\n  \"enum\"\n] @keyword.storage.type\n\n[\n  \"param\"\n  \"dynamicparam\"\n  \"begin\"\n  \"process\"\n  \"end\"\n  \"filter\"\n  \"workflow\"\n  \"throw\"\n  \"exit\"\n  \"trap\"\n  \"try\"\n  \"catch\"\n  \"finally\"\n  \"data\"\n  \"inlinescript\"\n  \"parallel\"\n  \"sequence\"\n] @keyword\n\n[\n  \"-as\"\n  \"-ccontains\"\n  \"-ceq\"\n  \"-cge\"\n  \"-cgt\"\n  \"-cle\"\n  \"-clike\"\n  \"-clt\"\n  \"-cmatch\"\n  \"-cne\"\n  \"-cnotcontains\"\n  \"-cnotlike\"\n  \"-cnotmatch\"\n  \"-contains\"\n  \"-creplace\"\n  \"-csplit\"\n  \"-eq\"\n  \"-ge\"\n  \"-gt\"\n  \"-icontains\"\n  \"-ieq\"\n  \"-ige\"\n  \"-igt\"\n  \"-ile\"\n  \"-ilike\"\n  \"-ilt\"\n  \"-imatch\"\n  \"-in\"\n  \"-ine\"\n  \"-inotcontains\"\n  \"-inotlike\"\n  \"-inotmatch\"\n  \"-ireplace\"\n  \"-is\"\n  \"-isnot\"\n  \"-isplit\"\n  \"-join\"\n  \"-le\"\n  \"-like\"\n  \"-lt\"\n  \"-match\"\n  \"-ne\"\n  \"-not\"\n  \"-notcontains\"\n  \"-notin\"\n  \"-notlike\"\n  \"-notmatch\"\n  \"-replace\"\n  \"-shl\"\n  \"-shr\"\n  \"-split\"\n  \"-and\"\n  \"-or\"\n  \"-xor\"\n  \"-band\"\n  \"-bor\"\n  \"-bxor\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"++\"\n  \"--\"\n  \"!\"\n  \"\\\\\"\n  \"..\"\n  \"|\"\n] @operator\n\n(assignement_operator) @operator\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n[\n  \";\"\n  \",\"\n  \"::\"\n] @punctuation.delimiter\n\n(string_literal) @string\n\n(integer_literal) @constant.numeric\n(real_literal) @constant.numeric\n\n(command\n  command_name: (command_name) @function)\n\n(function_name) @function\n\n(invokation_expression\n  (member_name) @function)\n\n(member_access\n  (member_name) @variable.other.member)\n\n(command_invokation_operator) @operator\n\n(type_spec) @type\n\n(variable) @variable\n\n(comment) @comment\n\n(array_expression) @punctuation.bracket\n\n(assignment_expression\n  value: (pipeline) @variable)\n\n(format_operator) @operator\n\n(command_parameter) @variable.parameter\n\n(command_elements) @variable.builtin\n\n(generic_token) @variable\n"
  },
  {
    "path": "runtime/queries/powershell/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/prisma/highlights.scm",
    "content": "(string) @string\n\n(enumeral) @constant\n(number) @constant.numeric\n\n(variable) @variable\n(column_type) @type\n\n(arguments) @variable.other.member\n(model_declaration (identifier) @type)\n(view_declaration (identifier) @type)\n\n[\n \"datasource\"\n \"enum\"\n \"generator\"\n \"model\"\n \"type\"\n \"view\"\n] @keyword\n\n[\n (comment)\n (developer_comment)\n] @comment\n\n[\n (attribute)\n (block_attribute_declaration)\n (call_expression)\n] @function.builtin\n\n[\n (true)\n (false)\n] @constant.builtin.boolean\n(null) @constant.builtin\n\n[\n \"(\"\n \")\"\n \"[\"\n \"]\"\n \"{\"\n \"}\"\n] @punctuation.bracket\n\n[\n \":\" \n \",\"\n] @punctuation.delimiter\n\n[\n \"=\"\n \"@\"\n \"@@\"\n (binary_expression)\n] @operator\n"
  },
  {
    "path": "runtime/queries/prisma/textobjects.scm",
    "content": "(model_declaration\n  ((statement_block) @class.inside)) @class.around\n\n(call_expression\n  (arguments (_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(column_declaration) @entry.around\n\n(array (_) @entry.around)\n\n(assignment_expression\n  (_) @entry.inside) @entry.around\n\n(developer_comment) @comment.inside\n\n(developer_comment)+ @comment.around\n\n"
  },
  {
    "path": "runtime/queries/prolog/folds.scm",
    "content": "[\n  (directive_term)\n  (clause_term)\n  (arg_list)\n  (list_notation)\n] @fold\n"
  },
  {
    "path": "runtime/queries/prolog/highlights.scm",
    "content": "(comment) @comment\n\n(atom) @constant\n\n((atom) @constant.builtin.boolean\n  (#any-of? @constant.builtin.boolean \"true\" \"false\"))\n\n(functional_notation\n  function: (atom) @function)\n\n(integer) @constant.numeric.integer\n\n(float_number) @constant.numeric.float\n\n(directive_head) @operator\n\n(operator_notation\n  operator: _ @operator)\n\n[\n (open)\n (open_ct)\n (close)\n (open_list)\n \"|\"\n (close_list)\n (open_curly)\n (close_curly)\n] @punctuation.bracket\n\n[\n (arg_list_separator)\n (comma)\n (end)\n (list_notation_separator)\n] @punctuation.delimiter\n\n(operator_notation\n  operator: (semicolon) @punctuation.delimiter)\n\n(double_quoted_list_notation) @string\n\n(variable_term) @variable\n"
  },
  {
    "path": "runtime/queries/prolog/indents.scm",
    "content": "(functional_notation\n  (atom)\n  (open_ct) @indent\n  (close) @outdent)\n\n(list_notation\n  (open_list) @indent\n  (close_list) @outdent)\n\n(curly_bracketed_notation\n  (open_curly) @indent\n  (close_curly) @outdent)\n"
  },
  {
    "path": "runtime/queries/prolog/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/properties/highlights.scm",
    "content": "(comment) @comment\n\n(key) @attribute\n\n(value) @string\n\n(value (escape) @constant.character.escape)\n\n((index) @constant.numeric.integer\n  (#match? @constant.numeric.integer \"^[0-9]+$\"))\n\n((substitution (key) @constant)\n  (#match? @constant \"^[A-Z0-9_]+\"))\n\n((value) @constant.builtin.boolean\n  (#any-of? @constant.builtin.boolean \"true\" \"false\" \"enabled\" \"disabled\"))\n\n((value) @constant.numeric.float\n  (#match? @constant.numeric.float \"^[+-]?(([0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?)|([0-9]+[eE][+-]?[0-9]+))$\"))\n\n((value) @constant.numeric.integer\n  ; according to the Java spec, hex literals must represent a 64bit int;\n  ; overflow (too long) is considered an error.\n  ; however, since these are just strings,\n  ; a long hex-literal could represent a BigInt, so we allow it\n  (#match? @constant.numeric.integer \"^([+-]?[0-9]+)|(0[xX][0-9a-fA-F]+)$\"))\n\n((value) @string.special.path\n  (#match? @string.special.path \"^(\\.{1,2})?/\"))\n\n(substitution\n  (key) @function\n  \"::\" @punctuation.special\n  (secret) @string.special.symbol)\n\n(property [ \"=\" \":\" ] @keyword.operator)\n\n[ \"${\" \"}\" ] @punctuation.special\n\n(substitution \":\" @punctuation.special)\n\n[ \"[\" \"]\" ] @punctuation.bracket\n\n[ \".\" \"\\\\\" ] @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/properties/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/properties/locals.scm",
    "content": "(property\n  (key) @local.definition.attribute)\n\n(substitution\n  (key) @local.reference)\n"
  },
  {
    "path": "runtime/queries/properties/textobjects.scm",
    "content": "(comment) @comment.inside\n(comment)+ @comment.around\n\n(property (key) @parameter.inside) @parameter.around\n"
  },
  {
    "path": "runtime/queries/protobuf/highlights.scm",
    "content": "[\n  \"syntax\"\n  \"edition\"\n  \"package\"\n  \"option\"\n  \"import\"\n  \"service\"\n  \"rpc\"\n  \"returns\"\n  \"message\"\n  \"map\"\n  \"enum\"\n  \"oneof\"\n  \"repeated\"\n  \"optional\"\n  \"required\"\n  \"reserved\"\n  \"to\"\n  \"stream\"\n  \"extend\"\n] @keyword\n\n[\n  (key_type)\n  (type)\n  (message_or_enum_type)\n] @type.builtin\n\n[\n  (enum_name)\n  (message_name)\n  (service_name)\n  (rpc_name)\n] @type\n\n[\n  (field_name)\n  (option_name)\n] @variable.other.member\n(enum_variant_name) @type.enum.variant\n\n(full_ident) @namespace\n\n(int_lit) @constant.numeric.integer\n(float_lit) @constant.numeric.float\n(bool) @constant.builtin.boolean\n(string) @string\n\n(block_lit) @constant\n\n(comment) @comment\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n]  @punctuation.bracket\n\n\"=\" @operator\n\n\";\" @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/protobuf/indents.scm",
    "content": "[\n  (message_body)\n  (enum_body)\n  (oneof_body)\n  (service_body)\n  (rpc_body)\n  (block_lit)\n] @indent\n\n\"}\" @outdent\n\n"
  },
  {
    "path": "runtime/queries/protobuf/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/protobuf/tags.scm",
    "content": "(message_name (identifier) @definition.class)\n\n(enum_name (identifier) @definition.class)\n\n(service_name (identifier) @definition.class)\n\n(rpc_name (identifier) @definition.function)\n\n(enum_variant_name (identifier) @definition.constant)\n\n(field_name (identifier) @definition.constant)\n"
  },
  {
    "path": "runtime/queries/protobuf/textobjects.scm",
    "content": "(message (message_body) @class.inside) @class.around\n(enum (enum_body) @class.inside) @class.around\n(service (service_body) @class.inside) @class.around\n\n(rpc (message_or_enum_type) @parameter.inside) @function.inside\n(rpc (message_or_enum_type) @parameter.around) @function.around\n\n(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/proverif/highlights.scm",
    "content": ";; fallback for identifiers\n(ident) @variable\n\n;; Comments\n\n(comment) @comment\n\n; CryptoVerif-only opaque blocks\n(proof) @comment.unused\n(def) @comment.unused\n\n;; Types\n(type_def\n  name: (ident) @type)\n\n(typeid) @type\n(typeid\n  (ident) @type)\n\n(decl_table\n  name: (ident) @type)\n\n;; Function & Macro Definitions\n\n(function_def\n  name: (ident) @function)\n\n(function_macro_def\n  name: (ident) @function.macro)\n\n(decl_pred\n  name: (ident) @function)\n\n(decl_event\n  name: (ident) @function)\n\n;; Function Calls\n\n(term_function_call\n  name: (ident) @function)\n(term_function_call\n (term (ident) @variable.parameter))\n\n(pterm_function_call\n  name: (ident) @function)\n(pterm_function_call\n (pterm (ident) @variable.parameter))\n\n(decl_process_macro\n  name: (ident) @function)\n(decl_process_macro\n (typedecl (ident) @variable.parameter))\n\n(gterm_function_call\n  name: (ident) @function)\n(gterm_function_call\n (gterm (ident) @variable.parameter))\n\n(gformat_function_call\n  name: (ident) @function)\n(gformat_function_call\n (gformat (ident) @variable.parameter))\n\n(process_function_call\n  name: (ident) @function)\n(process_function_call\n (pterm (ident) @variable.parameter))\n\n(process_input \"in\" @function.builtin)\n(process_input\n (pterm (ident) @variable.parameter))\n(process_input\n (pattern (ident) @variable.parameter))\n(process_input\n (pattern (pattern (ident) @variable.parameter)))\n\n(process_output \"out\" @function.builtin)\n(process_output\n (pterm (ident) @variable.parameter))\n(process_output\n (pterm (pterm (ident) @variable.parameter)))\n\n;; Literals\n\n(nat) @constant.numeric\n(int) @constant.numeric\n(string) @string\n\n[\n  \"true\"\n  \"false\"\n] @constant.builtin.boolean\n\n\"fail\" @constant.builtin\n\n(process_final_item\n  \"0\" @constant.builtin)\n\n;; Keywords\n\n[\n  \"among\"\n  \"axiom\"\n  \"choice\"\n  \"clauses\"\n  \"const\"\n  \"def\"\n  \"elimtrue\"\n  \"else\"\n  \"equation\"\n  \"equivalence\"\n  \"event\"\n  \"expand\"\n  \"fail\"\n  \"forall\"\n  \"foreach\"\n  \"free\"\n  \"fun\"\n  \"get\"\n  \"if\"\n  \"inj-event\"\n  \"insert\"\n  \"lemma\"\n  \"let\"\n  \"letfun\"\n  \"letproba\"\n  \"new\"\n  \"noninterf\"\n  \"noselect\"\n  \"not\"\n  \"nounif\"\n  \"otherwise\"\n  \"param\"\n  \"phase\"\n  \"pred\"\n  \"proba\"\n  \"process\"\n  \"proof\"\n  \"public_vars\"\n  \"putbegin\"\n  \"query\"\n  \"reduc\"\n  \"restriction\"\n  \"secret\"\n  \"select\"\n  \"set\"\n  \"suchthat\"\n  \"sync\"\n  \"table\"\n  \"then\"\n  \"type\"\n  \"weaksecret\"\n  \"yield\"\n] @keyword\n\n(decl_channel \"channel\" @keyword) ; \"channel\" can also be used as type, hence the restriction\n(process_let \"in\" @keyword) ; \"in\" can is keyword in \"let ... in\", but builtin function otherwise\n\n;; Operators\n\n[\n  \"=\"\n  \"<>\"\n  \"<=\"\n  \">=\"\n  \"<\"\n  \">\"\n  \"+\"\n  \"-\"\n  \"==>\"\n  \"<-\"\n  \"<-R\"\n  \"->\"\n  \"<->\"\n  \"<=>\"\n  \"||\"\n  \"&&\"\n  \"|\"\n  \"!\"\n] @keyword.operator\n\n;; Punctuation\n\n[\n  \".\"\n  \",\"\n  \";\"\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n;; Options\n\n(option) @attribute\n(nounifoption) @attribute\n"
  },
  {
    "path": "runtime/queries/prql/highlights.scm",
    "content": "[\n  (keyword_from)\n  (keyword_filter)\n  (keyword_derive)\n  (keyword_group)\n  (keyword_aggregate)\n  (keyword_sort)\n  (keyword_take)\n  (keyword_window)\n  (keyword_join)\n  (keyword_select)\n  (keyword_case)\n  (keyword_append)\n  (keyword_remove)\n  (keyword_intersect)\n  (keyword_rolling)\n  (keyword_rows)\n  (keyword_expanding)\n  (keyword_let)\n  (keyword_prql)\n  (keyword_from_text)\n  (keyword_loop)\n] @keyword\n\n(literal) @string\n\n(assignment\n  alias: (field) @variable.other.member)\n\nalias: (identifier) @variable.other.member\n\n(f_string) @string.special\n(s_string) @string.special\n\n(comment) @comment\n\n(function_call\n  (identifier) @function)\n\n[\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"=\"\n  \"==\"\n  \"<\"\n  \"<=\"\n  \"!=\"\n  \">=\"\n  \">\"\n  \"&&\"\n  \"||\"\n  \"//\"\n  \"~=\"\n  (bang)\n] @operator\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \".\"\n  (pipe)\n  \"->\"\n] @punctuation.delimiter\n\n(literal\n  (integer) @constant.numeric.integer)\n\n(integer) @constant.numeric.integer\n\n(literal\n  (decimal_number) @constant.numeric.float)\n\n(decimal_number) @constant.numeric.float\n\n[\n  (keyword_min)\n  (keyword_max)\n  (keyword_count)\n  (keyword_count_distinct)\n  (keyword_average)\n  (keyword_avg)\n  (keyword_sum)\n  (keyword_stddev)\n  (keyword_count)\n  (keyword_lag)\n  (keyword_lead)\n  (keyword_first)\n  (keyword_last)\n  (keyword_rank)\n  (keyword_row_number)\n  (keyword_round)\n  (keyword_all)\n  (keyword_map)\n] @function\n\n[\n (keyword_side)\n (keyword_version)\n (keyword_target)\n (keyword_null)\n (keyword_format)\n] @attribute\n\n(target) @function.builtin\n\n [\n  (date)\n  (time)\n  (timestamp)\n] @string.special\n\n[\n  (keyword_left)\n  (keyword_inner)\n  (keyword_right)\n  (keyword_full)\n  (keyword_csv)\n  (keyword_json)\n] @function.method\n\n[\n  (keyword_true)\n  (keyword_false)\n] @constant.builtin.boolean\n\n(function_definition\n  (keyword_let)\n  name: (identifier) @function)\n\n(parameter\n  (identifier) @variable.parameter)\n\n(variable\n  (keyword_let)\n  name: (identifier) @constant)\n"
  },
  {
    "path": "runtime/queries/prql/injections.scm",
    "content": "((s_string) @injection.content\n (#set! injection.language \"sql\"))\n\n(from_text\n  (keyword_from_text)\n  (keyword_json)\n  (literal) @injection.content\n  (#set! injection.language \"json\"))\n"
  },
  {
    "path": "runtime/queries/ptx/folds.scm",
    "content": "; Folding for PTX\n[\n  (func_body)\n  (entry_declaration)\n] @fold"
  },
  {
    "path": "runtime/queries/ptx/highlights.scm",
    "content": "; highlights.scm - Syntax highlighting for PTX\n\n; Comments\n(comment) @comment\n\n; Directives\n(version_directive) @keyword\n(target_directive) @keyword\n(address_size_directive) @keyword\n(file_directive) @keyword\n(section_directive) @keyword\n(visibility_directive) @keyword\n(pragma_directive) @keyword\n\n; Keywords\n[\n  \".global\"\n  \".const\"\n  \".param\"\n  \".local\"\n  \".shared\"\n  \".tex\"\n  \".func\"\n  \".entry\"\n] @keyword\n\n; Types\n(data_type) @type\n\n; Instructions\n(opcode) @function\n\n; Identifiers\n(identifier) @variable\n\n; Registers\n(register) @variable\n\n; Numbers\n(number) @constant.numeric.integer\n(float_literal) @constant.numeric.float\n\n; Strings\n(string) @string\n\n; Labels\n(label) @label\n"
  },
  {
    "path": "runtime/queries/ptx/indents.scm",
    "content": "; Indentation for PTX\n[\n  (func_body)\n  (entry_declaration)\n] @indent\n; Do not indent on closing brace\n[\n  \"}\"\n] @outdent"
  },
  {
    "path": "runtime/queries/pug/highlights.scm",
    "content": "(comment) @comment\n\n(\n  doctype\n  ((\"doctype\") @keyword.storage.type)\n  ((doctype_name) @type.enum.variant)\n)\n\n(tag_name) @constant\n\n; Attributes\n(id) @attribute\n(class) @attribute\n(attribute_name) @attribute\n\n(quoted_attribute_value) @string\n\n; Controls\n(\n  conditional\n  ((keyword) @keyword.control.conditional)\n)\n(\n  case\n  ((keyword) @keyword.control)\n  (\n    when\n    ((keyword) @keyword.control)\n  )\n)\n(\n  each\n  ((keyword) @keyword.control.repeat)\n)\n(\n  else\n  ((keyword) @keyword.control.conditional)\n)\n(\n  while\n  ((keyword) @keyword.control.repeat)\n)\n\n; Mixins\n(\n  mixin_definition\n  ((keyword) @keyword.function)\n  ((mixin_name) @function.method)\n)\n(\n  mixin_use\n  ((\"+\") @operator)\n  ((mixin_name) @function.method)\n)\n\n; Includes\n(\n  include\n  ((keyword) @keyword.directive)\n  ((filename) @string.special.path)\n)\n\n; Inheritance\n(\n  extends\n  ((keyword) @keyword.directive)\n  ((filename) @string.special.path)\n)\n(\n  block_definition\n  ((keyword) @keyword.directive)\n  ((block_name) @function.method)\n)\n(\n  block_append\n  ((keyword) @keyword.directive)\n  ((block_name) @function.method)\n)\n(\n  block_prepend\n  ((keyword) @keyword.directive)\n  ((block_name) @function.method)\n)\n\n; Filters\n(\n  filter\n  (\":\" @function.macro)\n  ((filter_name) @function.macro)\n  ((content) @special)\n)\n\n; Inline JavaScript\n(\n  unbuffered_code\n  ((\"-\") @special)\n)\n"
  },
  {
    "path": "runtime/queries/pug/injections.scm",
    "content": "((javascript) @injection.content\n  (#set! injection.language \"javascript\")\n)\n"
  },
  {
    "path": "runtime/queries/purescript/highlights.scm",
    "content": "; ----------------------------------------------------------------------------\n; Literals and comments\n\n (integer) @constant.numeric.integer\n (exp_negation) @constant.numeric.integer\n (exp_literal (number)) @constant.numeric.float\n (char) @constant.character\n\n [\n   (string)\n   (triple_quote_string)\n ] @string\n\n (comment) @comment\n\n; ----------------------------------------------------------------------------\n; Punctuation\n\n [\n   \"(\"\n   \")\"\n   \"{\"\n   \"}\"\n   \"[\"\n   \"]\"\n ] @punctuation.bracket\n\n (comma) @punctuation.delimiter\n\n; ----------------------------------------------------------------------------\n; Types\n\n (type) @type\n\n (constructor) @constructor\n\n; ----------------------------------------------------------------------------\n; Keywords, operators, includes\n\n (module) @namespace\n\n [\n   \"if\"\n   \"then\"\n   \"else\"\n   \"case\"\n   \"of\"\n ] @keyword.control.conditional\n\n [\n   \"import\"\n   \"module\"\n ] @keyword.control.import\n\n [\n   (operator)\n   (type_operator)\n   (qualified_module)  ; grabs the `.` (dot), ex: import System.IO\n   (all_names)\n\n   ; `_` wildcards in if-then-else and case-of expressions,\n   ; as well as record updates and operator sections\n   (wildcard)\n   \"=\"\n   \"|\"\n   \"::\"\n   \"∷\"\n   \"=>\"\n   \"⇒\"\n   \"<=\"\n   \"⇐\"\n   \"->\"\n   \"→\"\n   \"<-\"\n   \"←\"\n   \"\\\\\"\n   \"`\"\n   \"@\"\n ] @operator\n\n (qualified_module (module) @constructor)\n (qualified_type (module) @namespace)\n (qualified_variable (module) @namespace)\n (import (module) @namespace)\n\n [\n   (where)\n   \"let\"\n   \"in\"\n   \"class\"\n   \"instance\"\n   \"derive\"\n   \"foreign\"\n   \"data\"\n   \"newtype\"\n   \"type\"\n   \"as\"\n   \"hiding\"\n   \"do\"\n   \"ado\"\n   \"forall\"\n   \"∀\"\n   \"infix\"\n   \"infixl\"\n   \"infixr\"\n ] @keyword\n\n ; NOTE\n ; Needs to come after the other `else` in\n ; order to be highlighted correctly\n (class_instance \"else\" @keyword)\n\n (type_role_declaration\n   \"role\" @keyword\n   role: (type_role) @keyword)\n\n (hole) @label\n\n; ----------------------------------------------------------------------------\n; Functions and variables\n\n (variable) @variable\n\n (row_field (field_name) @variable.other.member)\n (record_field (field_name) @variable.other.member)\n (record_field (field_pun) @variable.other.member)\n\n ; NOTE\n ; Record fields must come after literal strings and\n ; plain variables in order to be highlighted correctly\n (record_accessor\n    field: [ (variable)\n             (string)\n             (triple_quote_string)\n           ] @variable.other.member)\n\n (exp_record_access\n    field: [ (variable)\n             (string)\n             (triple_quote_string)\n           ] @variable.other.member)\n\n (signature name: (variable) @type)\n (function name: (variable) @function)\n (class_instance (instance_name) @function)\n (derive_declaration (instance_name) @function)\n\n ; true or false\n ((variable) @constant.builtin.boolean\n  (#match? @constant.builtin.boolean \"^(true|false)$\"))\n\n ; The former one works for `tree-sitter highlight` but not in Helix/Kakoune.\n ; The latter two work in Helix (but not Kakoune) and are a good compromise between not highlighting anything at all\n ; as an operator and leaving it to the child nodes, and highlighting everything as an operator.\n (exp_ticked (_) @operator)\n (exp_ticked (exp_name (variable) @operator))\n (exp_ticked (exp_name (qualified_variable (variable) @operator)))\n\n (patterns (pat_as \"@\" @namespace))\n\n"
  },
  {
    "path": "runtime/queries/purescript/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/purescript/locals.scm",
    "content": "(signature name: (variable) @local.definition.function)\n(function name: (variable) @local.definition.function)\n(exp_name (variable)) @local.reference\n"
  },
  {
    "path": "runtime/queries/purescript/textobjects.scm",
    "content": "(comment) @comment.inside\n\n[\n  (data)\n  (type)\n  (newtype)\n] @class.around\n\n((signature)? (function rhs:(_) @function.inside)) @function.around \n(exp_lambda) @function.around\n\n(data (type_variable) @parameter.inside)\n(patterns (_) @parameter.inside)\n"
  },
  {
    "path": "runtime/queries/python/highlights.scm",
    "content": "; -------\n; Punctuation\n; -------\n\n[\",\" \".\" \":\" \";\" (ellipsis)] @punctuation.delimiter\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n(interpolation\n  \"{\" @punctuation.special\n  \"}\" @punctuation.special)\n\n; -------\n; Operators\n; -------\n\n[\n  \"-\"\n  \"-=\"\n  \"!=\"\n  \"*\"\n  \"**\"\n  \"**=\"\n  \"*=\"\n  \"/\"\n  \"//\"\n  \"//=\"\n  \"/=\"\n  \"&\"\n  \"&=\"\n  \"%\"\n  \"%=\"\n  \"^\"\n  \"^=\"\n  \"+\"\n  \"->\"\n  \"+=\"\n  \"<\"\n  \"<<\"\n  \"<<=\"\n  \"<=\"\n  \"<>\"\n  \"=\"\n  \":=\"\n  \"==\"\n  \">\"\n  \">=\"\n  \">>\"\n  \">>=\"\n  \"|\"\n  \"|=\"\n  \"~\"\n  \"@=\"\n] @operator\n\n; -------\n; Variables\n; -------\n\n(identifier) @variable\n\n; - Member\n(attribute attribute: (identifier) @variable.other.member)\n\n; - Parameter\n(parameters (identifier) @variable.parameter)\n(parameters (typed_parameter (identifier) @variable.parameter))\n(parameters (default_parameter name: (identifier) @variable.parameter))\n(parameters (typed_default_parameter name: (identifier) @variable.parameter))\n(parameters\n  (list_splat_pattern ; *args\n    (identifier) @variable.parameter))\n(parameters\n  (dictionary_splat_pattern ; **kwargs\n    (identifier) @variable.parameter))\n\n(lambda_parameters\n  (identifier) @variable.parameter)\n\n(keyword_argument\n  name: (identifier) @variable.parameter)\n\n; - Builtin\n((identifier) @variable.builtin\n (#any-of? @variable.builtin \"self\" \"cls\"))\n\n; -------\n; Keywords\n; -------\n\n[\n  \"async\"\n  \"class\"\n  \"exec\"\n  \"global\"\n  \"nonlocal\"\n  \"print\"\n  \"type\"\n] @keyword\n\n; Operators\n[\n  \"and\"\n  \"or\"\n  \"not in\"\n  \"in\" ; Has to be before loop keywords because \"in\" is overloaded\n  \"not\"\n  \"del\"\n  \"is not\"\n  \"is\"\n] @keyword.operator\n\n; Control\n[\n  \"as\"\n  \"assert\"\n  \"await\"\n  \"from\"\n  \"pass\"\n\n  \"with\"\n] @keyword.control\n\n; Conditionals\n[\n  \"if\"\n  \"elif\"\n  \"else\"\n  \"match\"\n  \"case\"\n] @keyword.control.conditional\n\n; Exceptions\n[\n  \"raise\"\n  \"try\"\n  \"except\"\n  \"finally\"\n] @keyword.control.exception\n(raise_statement \"from\" @keyword.control.exception)\n\n; Functions\n[\n  \"def\"\n  \"lambda\"\n] @keyword.function\n\n; Import\n\"import\" @keyword.control.import\n\n; Loops\n[\n  \"while\"\n  \"for\"\n  \"break\"\n  \"continue\"\n] @keyword.control.repeat\n\n(for_statement \"in\" @keyword.control.repeat)\n(for_in_clause \"in\" @keyword.control.repeat)\n\n; Return\n[\n  \"return\"\n  \"yield\"\n] @keyword.control.return\n(yield \"from\" @keyword.control.return)\n\n; -------\n; Imports\n; -------\n \n(dotted_name\n  (identifier)* @namespace)\n\n(aliased_import\n  alias: (identifier) @namespace)\n\n; - Builtins\n(none) @constant.builtin ; Has to be before types\n\n; -------\n; Types\n; -------\n \n((identifier) @type \n (#match? @type \"^[A-Z]\")) ; Has to be before constructor due to this being a more general match \n\n; In type hints make everything types to catch non-conforming identifiers\n; (e.g., datetime.datetime) and None\n(type [(identifier) (none)] @type)\n; Handle [] . and | nesting 4 levels deep\n(type\n  (_ [(identifier) (none)]? @type\n    (_ [(identifier) (none)]? @type\n      (_ [(identifier) (none)]? @type\n        (_ [(identifier) (none)]? @type)))))\n\n; Classes\n(class_definition name: (identifier) @type)\n(class_definition superclasses: (argument_list (identifier) @type))\n\n; -------\n; Functions\n; -------\n\n(function_definition\n  name: (identifier) @function)\n\n(call\n  function: (identifier) @function)\n\n; Decorators\n(decorator) @function\n(decorator (identifier) @function)\n(decorator (attribute attribute: (identifier) @function))\n(decorator (call\n  function: (attribute attribute: (identifier) @function)))\n\n; Methods\n(call\n  function: (attribute attribute: (identifier) @function.method))\n\n; Builtin functions\n((call\n  function: (identifier) @function.builtin)\n (#any-of?\n   @function.builtin\n   \"abs\" \"all\" \"any\" \"ascii\" \"bin\" \"breakpoint\" \"bytearray\" \"callable\" \"chr\"\n   \"classmethod\" \"compile\" \"complex\" \"delattr\" \"dir\" \"divmod\" \"enumerate\"\n   \"eval\" \"exec\" \"filter\" \"format\" \"getattr\" \"globals\" \"hasattr\" \"hash\" \"help\"\n   \"hex\" \"id\" \"input\" \"isinstance\" \"issubclass\" \"iter\" \"len\" \"locals\" \"map\"\n   \"max\" \"memoryview\" \"min\" \"next\" \"object\" \"oct\" \"open\" \"ord\" \"pow\" \"print\"\n   \"property\" \"range\" \"repr\" \"reversed\" \"round\" \"setattr\" \"slice\" \"sorted\"\n   \"staticmethod\" \"sum\" \"super\" \"type\" \"vars\" \"zip\" \"__import__\"))\n\n; Constructors\n(call\n  function: (attribute attribute: (identifier) @constructor)\n  (#any-of?\n    @constructor\n    \"__new__\" \"__init__\"))\n\n((call\n  function: (identifier) @constructor)\n (#any-of?\n   @constructor\n   \"__new__\" \"__init__\"))\n\n(function_definition\n  name: (identifier) @constructor\n (#any-of? @constructor \"__new__\" \"__init__\"))\n\n(call\n  function: (attribute attribute: (identifier) @constructor)\n (#match? @constructor \"^[A-Z]\"))\n(call\n  function: (identifier) @constructor\n (#match? @constructor \"^[A-Z]\"))\n\n; Builtin types\n((identifier) @type.builtin ; Has to be after functions due to broad matching\n (#any-of?\n   @type.builtin\n   \"bool\" \"bytes\" \"dict\" \"float\" \"frozenset\" \"int\" \"list\" \"set\" \"str\" \"tuple\"))\n\n; Builtin error types\n((identifier) @type.builtin ; Has to be after constructors due to broad matching of constructor\n  (#any-of? @type.builtin\n    \"BaseException\" \"Exception\" \"ArithmeticError\" \"BufferError\" \"LookupError\"\n    \"AssertionError\" \"AttributeError\" \"EOFError\" \"FloatingPointError\" \"GeneratorExit\"\n    \"ImportError\" \"ModuleNotFoundError\" \"IndexError\" \"KeyError\" \"KeyboardInterrupt\"\n    \"MemoryError\" \"NameError\" \"NotImplementedError\" \"OSError\" \"OverflowError\"\n    \"RecursionError\" \"ReferenceError\" \"RuntimeError\" \"StopIteration\" \"StopAsyncIteration\"\n    \"SyntaxError\" \"IndentationError\" \"TabError\" \"SystemError\" \"SystemExit\" \"TypeError\"\n    \"UnboundLocalError\" \"UnicodeError\" \"UnicodeEncodeError\" \"UnicodeDecodeError\"\n    \"UnicodeTranslateError\" \"ValueError\" \"ZeroDivisionError\" \"EnvironmentError\"\n    \"IOError\" \"WindowsError\" \"BlockingIOError\" \"ChildProcessError\" \"ConnectionError\"\n    \"BrokenPipeError\" \"ConnectionAbortedError\" \"ConnectionRefusedError\"\n    \"ConnectionResetError\" \"FileExistsError\" \"FileNotFoundError\" \"InterruptedError\"\n    \"IsADirectoryError\" \"NotADirectoryError\" \"PermissionError\" \"ProcessLookupError\"\n    \"TimeoutError\" \"Warning\" \"UserWarning\" \"DeprecationWarning\" \"PendingDeprecationWarning\"\n    \"SyntaxWarning\" \"RuntimeWarning\" \"FutureWarning\" \"ImportWarning\" \"UnicodeWarning\"\n    \"BytesWarning\" \"ResourceWarning\"))\n\n; -------\n; Constants\n; -------\n\n((identifier) @constant\n (#match? @constant \"^_*[A-Z][A-Z\\\\d_]*$\"))\n\n(escape_sequence) @constant.character.escape\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n\n; - Numbers\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n\n; -------\n; Other literals\n; -------\n \n(comment) @comment\n(string) @string\n"
  },
  {
    "path": "runtime/queries/python/indents.scm",
    "content": "[\n  (list)\n  (tuple)\n  (dictionary)\n  (set)\n\n  (if_statement)\n  (for_statement)\n  (while_statement)\n  (with_statement)\n  (try_statement)\n  (match_statement)\n  (case_clause)\n  (import_from_statement)\n\n  (parenthesized_expression)\n  (generator_expression)\n  (list_comprehension)\n  (set_comprehension)\n  (dictionary_comprehension)\n\n  (tuple_pattern)\n  (list_pattern)\n  (argument_list)\n  (parameters)\n  (binary_operator)\n\n  (function_definition)\n  (class_definition)\n] @indent\n\n; Workaround for the tree-sitter grammar creating large errors when a\n; try_statement is missing the except/finally clause\n(ERROR\n  \"try\"\n  .\n  \":\" @indent @extend)\n(ERROR\n  .\n  \"def\") @indent @extend\n(ERROR\n  (block) @indent @extend\n  (#set! \"scope\" \"all\"))\n\n[\n  (if_statement)\n  (for_statement)\n  (while_statement)\n  (with_statement)\n  (try_statement)\n  (match_statement)\n  (case_clause)\n\n  (function_definition)\n  (class_definition)\n\n  (except_clause)\n  (finally_clause)\n] @extend\n\n[\n  (return_statement)\n  (break_statement)\n  (continue_statement)\n  (raise_statement)\n  (pass_statement)\n] @extend.prevent-once\n\n[\n  \")\"\n  \"]\"\n  \"}\"\n] @outdent\n(elif_clause\n  \"elif\" @outdent)\n(else_clause\n  \"else\" @outdent)\n(except_clause\n  \"except\" @outdent)\n(finally_clause\n  \"finally\" @outdent)\n\n(parameters\n  .\n  (identifier) @anchor\n  (#set! \"scope\" \"tail\")) @align\n(argument_list\n  .\n  (_) @anchor\n  (#set! \"scope\" \"tail\")) @align\n\n"
  },
  {
    "path": "runtime/queries/python/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; Match all 9 functions in the `re` module from the standard library that\n; that takes a regex pattern as first argument.\n; https://docs.python.org/3/library/re.html#functions\n(call\n  function: (attribute\n    object: (identifier) @_module (#eq? @_module \"re\")\n    attribute: (identifier) @_function (#any-of? @_function \"compile\" \"search\" \"match\" \"fullmatch\" \"sub\" \"subn\" \"findall\" \"finditer\" \"split\"))\n  arguments: (argument_list\n    . (string\n        (string_content) @injection.content))\n  (#set! injection.language \"regex\"))\n"
  },
  {
    "path": "runtime/queries/python/locals.scm",
    "content": ";; Scopes\n\n[\n  (module)\n  (function_definition)\n  (lambda)\n] @local.scope\n\n;; Definitions\n\n; Parameters\n(parameters\n  (identifier) @local.definition.variable.parameter)\n(parameters\n  (typed_parameter\n    (identifier) @local.definition.variable.parameter))\n(parameters\n  (default_parameter \n    name: (identifier) @local.definition.variable.parameter))\n(parameters \n  (typed_default_parameter \n    name: (identifier) @local.definition.variable.parameter))\n(parameters\n  (list_splat_pattern ; *args\n    (identifier) @local.definition.variable.parameter))\n(parameters\n  (dictionary_splat_pattern ; **kwargs\n    (identifier) @local.definition.variable.parameter))\n(parameters\n  (identifier) @local.definition.variable.builtin\n  (#any-of? @local.definition.variable.builtin \"self\" \"cls\")) ; label self/cls as builtin\n    \n(lambda_parameters\n  (identifier) @local.definition.variable.parameter)\n  \n; Imports\n(import_statement\n  name: (dotted_name \n    (identifier) @local.definition.namespace))\n\n(aliased_import\n  alias: (identifier) @local.definition.namespace)\n\n;; References\n\n(identifier) @local.reference\n\n; don't make the name of kwargs locals\n(keyword_argument\n  name: (identifier) @variable.parameter)\n"
  },
  {
    "path": "runtime/queries/python/rainbows.scm",
    "content": "[\n  (future_import_statement)\n  (import_from_statement)\n  (with_clause)\n  (parameters)\n  (parenthesized_list_splat)\n  (argument_list)\n  (tuple_pattern)\n  (list_pattern)\n  (subscript)\n  (list)\n  (set)\n  (tuple)\n  (dictionary)\n  (dictionary_comprehension)\n  (set_comprehension)\n  (list_comprehension)\n  (generator_expression)\n  (parenthesized_expression)\n  (interpolation)\n  (format_expression)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"{\" \"}\"\n  \"[\" \"]\"\n] @rainbow.bracket\n\n; (string [\"{{\" \"}}\"] @rainbow.bracket) @rainbow.scope\n"
  },
  {
    "path": "runtime/queries/python/tags.scm",
    "content": "(module (expression_statement (assignment left: (identifier) @name) @definition.constant))\n\n(class_definition\n  name: (identifier) @name) @definition.class\n\n(function_definition\n  name: (identifier) @name) @definition.function\n\n(call\n  function: [\n      (identifier) @name\n      (attribute\n        attribute: (identifier) @name)\n  ]) @reference.call\n"
  },
  {
    "path": "runtime/queries/python/textobjects.scm",
    "content": "(function_definition\n  body: (block)? @function.inside) @function.around\n\n(class_definition\n  body: (block)? @class.inside) @class.around\n\n(parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n  \n(lambda_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(argument_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n\n((function_definition\n   name: (identifier) @_name\n   body: (block)? @test.inside) @test.around\n (#match? @_name \"^test_\"))\n\n(list\n  (_) @entry.around)\n\n(tuple\n  (_) @entry.around)\n\n(set\n  (_) @entry.around)\n\n(pair\n  (_) @entry.inside) @entry.around\n"
  },
  {
    "path": "runtime/queries/qml/highlights.scm",
    "content": "(comment) @comment\n\n(ui_import\n  source: _ @namespace\n  version: _? @constant\n  alias: _? @namespace)\n\n(ui_pragma\n  name: (identifier) @attribute\n  value: (identifier)? @constant)\n\n(ui_annotation\n  \"@\" @punctuation\n  type_name: _ @type)\n\n;;; Declarations\n\n(enum_declaration\n  name: (identifier) @type)\n\n(enum_assignment\n  name: (identifier) @constant\n  value: _ @constant)\n\n(enum_body\n  name: (identifier) @constant)\n\n(ui_inline_component\n  name: (identifier) @type)\n\n(ui_object_definition\n  type_name: _ @type)\n\n(ui_object_definition_binding\n  type_name: _ @type\n  name: _ @variable.other.member)\n\n(ui_property\n  type: _ @type\n  name: (identifier) @variable.other.member)\n\n(ui_signal\n  name: (identifier) @function)\n\n(ui_signal_parameter\n  name: (identifier) @variable.parameter\n  type: _ @type)\n\n(ui_signal_parameter\n  type: _ @type\n  name: (identifier) @variable.parameter);;; Properties and bindings\n\n;;; Bindings\n\n(ui_binding\n  name: _ @variable.other.member)\n\n;;; Other\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n(ui_list_property_type [\n  \"<\"\n  \">\"\n] @punctuation.bracket)\n\n[\n  \",\"\n  \".\"\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"as\"\n  \"component\"\n  \"default\"\n  \"enum\"\n  \"import\"\n  \"on\"\n  \"pragma\"\n  \"property\"\n  \"readonly\"\n  \"required\"\n  \"signal\"\n] @keyword\n"
  },
  {
    "path": "runtime/queries/qml/indents.scm",
    "content": "[\n  (enum_body)\n  (ui_object_initializer)\n] @indent\n\n\"}\" @outdent\n"
  },
  {
    "path": "runtime/queries/qml/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n\n([\n    (empty_statement)\n    (expression_statement)\n    (function_declaration)\n    (generator_function_declaration)\n    (statement_block)\n    (switch_statement)\n    (try_statement)\n    (variable_declaration)\n    (with_statement)\n  ] @injection.content\n  (#set! injection.include-children)\n  (#set! injection.language \"javascript\"))\n"
  },
  {
    "path": "runtime/queries/qml/textobjects.scm",
    "content": "; (comment) is used for both // and /* ... */ comment syntax\n(comment) @comment.inside\n(comment)+ @comment.around\n\n(ui_object_definition\n  initializer: (_) @class.inside) @class.around\n\n(ui_binding\n  name: (identifier) @parameter.inside) @parameter.around\n\n(ui_property\n  (_)+ @parameter.inside \":\") @parameter.around\n\n(function_declaration\n  body: (_) @function.inside) @function.around\n\n(arrow_function\n  body: (_) @function.inside) @function.around\n\n; e.g. `onClicked: console.log(\"Button clicked!\")`\n((ui_binding\n  name: (identifier) @_name\n  value: (_) @function.around @function.inside)\n  (#match? @_name \"^on[A-Z].*\"))\n\n; e.g.\n; Component.onCompleted: {\n;    console.log(\"completed\")\n; }\n(statement_block (expression_statement)* @function.inside) @function.around\n\n; e.g.\n; states: [\n;        State { name: \"activated\" },\n;        State { name: \"deactivated\" }\n; ]\n(ui_object_array\n  ((_) @entry.inside . \",\"? @entry.around) @entry.around)\n\n; e.g. [1, 2, 3, 4]\n(array\n  ((_) @entry.inside . \",\"? @entry.around) @entry.around)\n\n; Tests in QML are written using \"Qt Quick Test\" and it's `TestCase` type\n; ref: https://doc.qt.io/qt-6/qtquicktest-index.html\n((ui_object_definition\n  type_name: (identifier) @_name\n  initializer: (_) @test.inside) @test.around\n  (#eq? @_name \"TestCase\"))\n"
  },
  {
    "path": "runtime/queries/quarto/highlights.scm",
    "content": "; inherits: markdown\n"
  },
  {
    "path": "runtime/queries/quarto/indents.scm",
    "content": "; inherits: markdown\n"
  },
  {
    "path": "runtime/queries/quarto/injections.scm",
    "content": "; inherits: markdown\n"
  },
  {
    "path": "runtime/queries/quint/highlights.scm",
    "content": "[\n  \"module\"\n  \"type\"\n  \"assume\"\n  \"const\"\n  \"var\"\n  \"val\"\n  \"nondet\"\n  \"def\"\n  \"pure\"\n  \"action\"\n  \"temporal\"\n  \"run\"\n] @keyword\n\n(match_expr \"match\" @keyword.control.conditional)\n\n(if_else_condition \n  \"if\" @keyword.control.conditional\n  \"else\" @keyword.control.conditional)\n\n(import \"import\" @keyword.control.import)\n(import \"as\" @keyword.control.import)\n(import \"from\" @keyword.control.import)\n(export \"export\" @keyword.control.import)\n(export \"as\" @keyword.control.import)\n\n[\n  \"true\"\n  \"false\"\n  \"Int\"\n  \"Nat\"\n  \"Bool\"\n] @constant.builtin\n\n[\n  \";\"\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"-\"\n  \"+\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"<\"\n  \"<=\"\n  \"=\"\n  \"==\"\n  \"!=\"\n  \"=>\"\n  \">\"\n  \">=\"\n  \"^\"\n  \"->\"\n] @operator\n\n(infix_and \"and\" @operator)\n(infix_or \"or\" @operator)\n(infix_iff \"iff\" @operator)\n(infix_implies \"implies\" @operator)\n\n(braced_and \"and\" @keyword)\n(braced_or \"or\" @keyword)\n(braced_all \"all\" @keyword)\n(braced_any \"any\" @keyword)\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n(polymorphic_type \n  (type) @type.parameter)\n\n(variant_constructor) @type.enum.variant\n\n(type) @type\n(int_literal) @constant.numeric.integer\n(comment) @comment\n(string) @string\n\n(operator_application\n  operator: (qualified_identifier) @function)\n\n(operator_definition\n  name: (qualified_identifier) @function\n  arguments: (typed_argument_list))\n"
  },
  {
    "path": "runtime/queries/quint/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/r/highlights.scm",
    "content": "; highlights.scm\n\n(identifier) @variable\n\n; Literals\n\n[\n  (integer)\n  (complex)\n] @constant.numeric.integer\n\n[\n  (float)\n  (nan)\n] @constant.numeric.float\n\n[\n  (true)\n  (false)\n] @constant.builtin.boolean\n\n[\n  (na)\n  (null)\n] @constant.builtin\n\n(string) @string\n(string (escape_sequence) @constant.character.escape)\n\n(comment) @comment\n\n(formal_parameters (identifier) @variable.parameter)\n(formal_parameters (default_parameter (identifier) @variable.parameter))\n\n; Operators\n[\n \"=\"\n \"<-\"\n \"<<-\"\n \"->>\"\n \"->\"\n] @operator\n\n(unary operator: [\n  \"-\"\n  \"+\"\n  \"!\"\n  \"~\"\n] @operator)\n\n(binary operator: [\n  \"-\"\n  \"+\"\n  \"*\"\n  \"/\"\n  \"^\"\n  \"<\"\n  \">\"\n  \"<=\"\n  \">=\"\n  \"==\"\n  \"!=\"\n  \"||\"\n  \"|\"\n  \"&&\"\n  \"&\"\n  \":\"\n  \"~\"\n] @operator)\n\n[\n  \"|>\"\n  (special)\n] @operator\n\n(lambda_function \"\\\\\" @operator)\n\n[\n \"(\"\n \")\"\n \"[\"\n \"]\"\n \"{\"\n \"}\"\n] @punctuation.bracket\n\n(dollar \"$\" @operator)\n\n(subset2\n [\n  \"[[\"\n  \"]]\"\n ] @punctuation.bracket)\n\n[\n \"in\"\n (dots)\n (break)\n (next)\n (inf)\n] @keyword\n\n[\n  \"if\"\n  \"else\"\n  \"switch\"\n] @keyword.control.conditional\n\n[\n  \"while\"\n  \"repeat\"\n  \"for\"\n] @keyword.control.repeat\n\n\"function\" @keyword.function\n\n(call function: (identifier) @function)\n(default_argument name: (identifier) @variable.parameter)\n\n\n(namespace_get namespace: (identifier) @namespace\n \"::\" @operator)\n(namespace_get_internal namespace: (identifier) @namespace\n \":::\" @operator)\n\n(namespace_get function: (identifier) @function.method)\n(namespace_get_internal function: (identifier) @function.method)\n"
  },
  {
    "path": "runtime/queries/r/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/r/locals.scm",
    "content": "; locals.scm\n\n(function_definition) @local.scope\n\n(formal_parameters (identifier) @local.definition.variable.parameter)\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/racket/highlights.scm",
    "content": "; inherits: scheme\n"
  },
  {
    "path": "runtime/queries/racket/indents.scm",
    "content": "; inherits: scheme\n"
  },
  {
    "path": "runtime/queries/racket/injections.scm",
    "content": "; inherits: scheme\n"
  },
  {
    "path": "runtime/queries/racket/rainbows.scm",
    "content": "; inherits: scheme\n"
  },
  {
    "path": "runtime/queries/regex/highlights.scm",
    "content": "; upstream: https://github.com/tree-sitter/tree-sitter-regex/blob/e1cfca3c79896ff79842f057ea13e529b66af636/queries/highlights.scm\n\n[\n  \"(\"\n  \")\"\n  \"(?\"\n  \"(?:\"\n  \"(?<\"\n  \">\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \"*\"\n  \"+\"\n  \"|\"\n  \"=\"\n  \"<=\"\n  \"!\"\n  \"<!\"\n  \"?\"\n] @operator\n\n[\n  (identity_escape)\n  (control_letter_escape)\n  (character_class_escape)\n  (control_escape)\n  (start_assertion)\n  (end_assertion)\n  (boundary_assertion)\n  (non_boundary_assertion)\n] @constant.character.escape\n\n(group_name) @label\n\n(count_quantifier\n  [\n    (decimal_digits) @constant.numeric\n    \",\" @punctuation.delimiter\n  ])\n\n(character_class\n  [\n    \"^\" @operator\n    (class_range \"-\" @operator)\n  ])\n\n(class_character) @constant.character\n"
  },
  {
    "path": "runtime/queries/regex/rainbows.scm",
    "content": "[\n  (lookahead_assertion)\n  (character_class)\n  (anonymous_capturing_group)\n  (named_capturing_group)\n  (non_capturing_group)\n  (count_quantifier)\n  (character_class_escape)\n] @rainbow.scope\n\n[\n  \"(?\" \"(?:\"\n  \"(?<\" \">\"\n  \"(\" \")\"\n  \"[\" \"]\"\n  \"{\" \"}\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/rego/highlights.scm",
    "content": "[\n  (import)\n] @keyword.control.import\n\n[\n  (package)\n] @namespace\n\n[\n  (with)\n  (as)\n  (every)\n  (some)\n  (in)\n  (default)\n  \"null\"\n] @keyword.control\n\n[\n  (not)\n  (if)\n  (contains)\n  (else)\n] @keyword.control.conditional\n\n[\n  (boolean)\n] @constant.builtin.boolean\n\n[\n  (assignment_operator)\n  (bool_operator)\n  (arith_operator)\n  (bin_operator)\n] @operator\n\n[\n  (string)\n  (raw_string)\n] @string\n\n(term (ref (var))) @variable\n\n(comment) @comment.line\n\n(number) @constant.numeric.integer\n\n(expr_call func_name: (fn_name (var) @function .))\n\n(expr_call func_arguments: (fn_args (expr) @variable.parameter))\n\n(rule_args (term) @variable.parameter)\n\n[\n  (open_paren)\n  (close_paren)\n  (open_bracket)\n  (close_bracket)\n  (open_curly)\n  (close_curly)\n] @punctuation.bracket\n\n(rule (rule_head (var) @function.method))\n\n(rule\n  (rule_head (term (ref (var) @namespace)))\n  (rule_body (query (literal (expr (expr_infix (expr (term (ref (var)) @_output)))))) (#eq? @_output @namespace))\n)\n"
  },
  {
    "path": "runtime/queries/rego/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/rescript/highlights.scm",
    "content": "(comment) @comment\n\n[\n  \".\"\n  \",\"\n  \"|\"\n] @punctuation.delimiter\n\n[\n  \"++\"\n  \"+\"\n  \"+.\"\n  \"-\"\n  \"-.\"\n  \"*\"\n  \"**\"\n  \"*.\"\n  \"/.\"\n  \"<=\"\n  \"==\"\n  \"===\"\n  \"!\"\n  \"!=\"\n  \"!==\"\n  \">=\"\n  \"&&\"\n  \"||\"\n  \"=\"\n  \":=\"\n  \"->\"\n  \"|>\"\n  \":>\"\n  \"+=\"\n  (uncurry)\n] @operator\n\n; Explicitly enclose these operators with binary_expression\n; to avoid confusion with JSX tag delimiters\n(binary_expression [\"<\" \">\" \"/\"] @operator)\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n(polyvar_type\n  [\n   \"[\"\n   \"[>\"\n   \"[<\"\n   \"]\"\n  ] @punctuation.bracket)\n\n[\n  \"~\"\n  \"?\"\n  \"=>\"\n  \"..\"\n  \"...\"\n] @punctuation.special\n\n\n; Identifiers\n;------------\n\n; Escaped identifiers like \\\"+.\"\n((value_identifier) @function.macro\n (#match? @function.macro \"^\\\\.*$\"))\n\n[\n  (type_identifier)\n  (unit_type)\n  (list)\n  (list_pattern)\n] @type\n\n[\n  (variant_identifier)\n  (polyvar_identifier)\n] @constructor\n\n(record_type_field (property_identifier) @type)\n(object_type (field (property_identifier) @type))\n(record_field (property_identifier) @variable.other.member)\n(object (field (property_identifier) @variable.other.member))\n(member_expression (property_identifier) @variable.other.member)\n(module_identifier) @namespace\n\n; Parameters\n;----------------\n\n(list_pattern (value_identifier) @variable.parameter)\n(spread_pattern (value_identifier) @variable.parameter)\n\n; String literals\n;----------------\n\n[\n  (string)\n  (template_string)\n] @string\n\n(template_substitution\n  \"${\" @punctuation.bracket\n  \"}\" @punctuation.bracket) @embedded\n\n(character) @string.special\n(escape_sequence) @string.special\n\n; Other literals\n;---------------\n\n[\n  (true)\n  (false)\n] @constant.builtin\n\n(number) @constant.numeric\n(polyvar) @constant\n(polyvar_string) @constant\n\n; Functions\n;----------\n\n; parameter(s) in parens\n[\n (parameter (value_identifier))\n (labeled_parameter (value_identifier))\n] @variable.parameter\n\n; single parameter with no parens\n(function parameter: (value_identifier) @variable.parameter)\n\n; first-level descructuring (required for nvim-tree-sitter as it only matches direct\n; children and the above patterns do not match destructuring patterns in NeoVim)\n(parameter (tuple_pattern (tuple_item_pattern (value_identifier) @variable.parameter)))\n(parameter (array_pattern (value_identifier) @variable.parameter))\n(parameter (record_pattern (value_identifier) @variable.parameter))\n\n; Meta\n;-----\n\n(decorator_identifier) @keyword.directive\n\n(extension_identifier) @keyword\n(\"%\") @keyword\n\n; Misc\n;-----\n\n(subscript_expression index: (string) @attribute)\n(polyvar_type_pattern \"#\" @constant)\n\n[\n  (\"include\")\n  (\"open\")\n] @keyword.control.import\n\n[\n  \"as\"\n  \"export\"\n  \"external\"\n  \"let\"\n  \"module\"\n  \"mutable\"\n  \"private\"\n  \"rec\"\n  \"type\"\n  \"and\"\n  \"assert\"\n  \"await\"\n  \"with\"\n  \"lazy\"\n  \"constraint\"\n] @keyword\n\n((function \"async\" @keyword.storage))\n\n(module_unpack \"unpack\" @keyword)\n\n[\n  \"if\"\n  \"else\"\n  \"switch\"\n  \"when\"\n] @keyword.control.conditional\n\n[\n  \"exception\"\n  \"try\"\n  \"catch\"\n] @keyword.control.exception\n\n(call_expression\n  function: (value_identifier) @keyword.control.exception\n  (#eq? @keyword.control.exception \"raise\"))\n\n[\n  \"for\"\n  \"in\"\n  \"to\"\n  \"downto\"\n  \"while\"\n] @keyword.control.conditional\n\n(ternary_expression [\"?\" \":\"] @operator)\n\n; JSX\n;----------\n(jsx_identifier) @tag\n(jsx_element\n  open_tag: (jsx_opening_element [\"<\" \">\"] @punctuation.special))\n(jsx_element\n  close_tag: (jsx_closing_element [\"<\" \"/\" \">\"] @punctuation.special))\n(jsx_self_closing_element [\"/\" \">\" \"<\"] @punctuation.special)\n(jsx_fragment [\">\" \"<\" \"/\"] @punctuation.special)\n(jsx_attribute (property_identifier) @attribute)\n"
  },
  {
    "path": "runtime/queries/rescript/injections.scm",
    "content": "((comment) @injection.content (#set! injection.language \"comment\"))\n\n; %re\n(extension_expression\n  (extension_identifier) @_name\n  (#eq? @_name \"re\")\n  (expression_statement (_) @injection.content (#set! injection.language \"regex\")))\n\n; %raw\n(extension_expression\n  (extension_identifier) @_name\n  (#eq? @_name \"raw\")\n  (expression_statement\n    (_ (_)  @injection.content (#set! injection.language \"javascript\"))))\n\n; %graphql\n(extension_expression\n  (extension_identifier) @_name\n  (#eq? @_name \"graphql\")\n  (expression_statement\n    (_ (_) @injection.content (#set! injection.language \"graphql\"))))\n\n; %relay\n(extension_expression\n  (extension_identifier) @_name\n  (#eq? @_name \"relay\")\n  (expression_statement\n    (_ (_) @injection.content (#set! injection.language \"graphql\") )))\n\n"
  },
  {
    "path": "runtime/queries/rescript/textobjects.scm",
    "content": "; Classes (modules)\n;------------------\n\n(module_binding definition: ((_) @class.inside)) @class.around\n\n; Blocks\n;-------\n\n(block (_) @function.inside) @function.around\n\n; Functions\n;----------\n\n(function body: (_) @function.inside) @function.around\n\n; Calls\n;------\n\n(call_expression arguments: ((_) @parameter.inside)) @parameter.around\n\n; Comments\n;---------\n\n(comment) @comment.inside\n(comment)+ @comment.around\n\n; Parameters\n;-----------\n\n(function parameter: (_) @parameter.inside @parameter.around)\n\n(formal_parameters\n  \",\"\n  . (_) @parameter.inside\n  @parameter.around)\n(formal_parameters\n  . (_) @parameter.inside\n  . \",\"?\n  @parameter.around)\n\n(arguments\n  \",\" @_arguments_start\n  . (_) @parameter.inside\n  @parameter.around)\n(arguments\n  . (_) @parameter.inside\n  . \",\"?\n  @parameter.around)\n\n(function_type_parameters\n  \",\"\n  . (_) @parameter.inside\n  @parameter.around)\n(function_type_parameters\n  . (_) @parameter.inside\n  . \",\"?\n  @parameter.around)\n\n(functor_parameters\n  \",\"\n  . (_) @parameter.inside\n  @parameter.around)\n(functor_parameters\n  . (_) @parameter.inside\n  . \",\"?\n  @parameter.around)\n\n(type_parameters\n  \",\"\n  . (_) @parameter.inside\n  @parameter.around)\n(type_parameters\n  . (_) @parameter.inside\n  . \",\"?\n  @parameter.around)\n\n(type_arguments\n  \",\"\n  . (_) @parameter.inside\n  @parameter.around)\n(type_arguments\n  . (_) @parameter.inside\n  . \",\"?\n  @parameter.around)\n\n(decorator_arguments\n  \",\"\n  . (_) @parameter.inside\n  @parameter.around)\n(decorator_arguments\n  . (_) @parameter.inside\n  . \",\"?\n  @parameter.around)\n\n(variant_parameters\n  \",\"\n  . (_) @parameter.inside\n  @parameter.around)\n(variant_parameters\n  . (_) @parameter.inside\n  . \",\"?\n  @parameter.around)\n\n(polyvar_parameters\n  \",\"\n  . (_) @parameter.inside\n  @parameter.around)\n(polyvar_parameters\n  . (_) @parameter.inside\n  . \",\"?\n  @parameter.around)\n\n"
  },
  {
    "path": "runtime/queries/ripple/folds.scm",
    "content": "; Folds for code blocks\n[\n  (statement_block)\n  (component_body)\n  (class_body)\n  (object)\n  (object_pattern)\n  (array)\n  (array_pattern)\n  (switch_body)\n] @fold\n\n; Fold multi-line JSX elements\n(jsx_element) @fold\n\n; Fold style elements\n(style_element) @fold\n\n; Fold server blocks\n(server_block) @fold\n\n; Fold comments\n(comment) @fold\n\n; Fold template strings\n(template_string) @fold\n"
  },
  {
    "path": "runtime/queries/ripple/highlights.scm",
    "content": "; Keywords\n(component_declaration \"component\" @keyword)\n(fragment_declaration \"fragment\" @keyword)\n(server_block \"#server\" @keyword)\n\n; Reserved identifiers\n[\n  \"track\"\n  \"untrack\"\n] @function.builtin\n\n; Functions\n(component_declaration\n  name: (identifier) @function)\n\n(fragment_declaration\n  name: (identifier) @function)\n\n(function_declaration\n  name: (identifier) @function)\n\n(method_definition\n  name: (property_name) @function.method)\n\n(call_expression\n  function: (identifier) @function.call)\n\n(call_expression\n  function: (member_expression\n    property: (identifier) @function.method.call))\n\n; Variables\n(identifier) @variable\n\n; Parameters\n(required_parameter\n  pattern: (identifier) @variable.parameter)\n\n(rest_parameter\n  (identifier) @variable.parameter)\n\n; Reactive constructs\n(unbox_expression \"@\" @operator.special)\n(reactive_array \"#[\" @punctuation.bracket.special)\n(reactive_object \"#{\" @punctuation.bracket.special)\n\n; JSX/Components\n(jsx_opening_element\n  \"<\" @tag.delimiter\n  name: (jsx_element_name) @tag\n  \">\" @tag.delimiter)\n\n(jsx_closing_element\n  \"</\" @tag.delimiter\n  name: (jsx_element_name) @tag\n  \">\" @tag.delimiter)\n\n(jsx_self_closing_element\n  \"<\" @tag.delimiter\n  name: (jsx_non_namespaced_element_name) @tag\n  \"/>\" @tag.delimiter)\n\n; Override identifier coloring for JSX element names\n; These must come after the general (identifier) @variable pattern to have higher priority\n\n; Regular element names (plain identifiers)\n(jsx_opening_element\n  name: (jsx_element_name (identifier) @tag))\n\n(jsx_closing_element\n  name: (jsx_element_name (identifier) @tag))\n\n(jsx_self_closing_element\n  name: (jsx_non_namespaced_element_name (identifier) @tag))\n\n; Dynamic element names (unbox expressions)\n(jsx_opening_element\n  name: (jsx_element_name\n    (unbox_expression (identifier) @tag)))\n\n(jsx_closing_element\n  name: (jsx_element_name\n    (unbox_expression (identifier) @tag)))\n\n(jsx_self_closing_element\n  name: (jsx_non_namespaced_element_name\n    (unbox_expression (identifier) @tag)))\n\n(jsx_attribute\n  name: [(identifier) (jsx_namespace_name)] @attribute)\n\n(jsx_expression\n  \"{\" @punctuation.bracket\n  \"}\" @punctuation.bracket)\n\n; Style elements\n(style_element\n  \"<style\" @tag\n  \">\" @tag.delimiter\n  \"</style>\" @tag)\n\n(style_element\n  (raw_text) @string.special)\n\n; Types\n(type_identifier) @type\n(predefined_type) @type.builtin\n(type_parameter (identifier) @type.parameter)\n\n; Type annotations (commented out - _type_annotation is hidden)\n; The colon will be captured as punctuation.delimiter via other rules\n\n; Literals\n(string) @string\n(template_string) @string\n(template_substitution\n  \"${\" @punctuation.special\n  \"}\" @punctuation.special)\n\n(number) @number\n(true) @constant.builtin.boolean\n(false) @constant.builtin.boolean\n(null) @constant.builtin\n(undefined) @constant.builtin\n\n; Regex\n(regex) @string.regexp\n(regex_pattern) @string.regexp\n(regex_flags) @string.regexp\n\n; Comments\n(comment) @comment\n\n; Operators\n(unary_expression operator: _ @operator)\n(binary_expression operator: _ @operator)\n(ternary_expression \":\" @operator)\n(update_expression operator: _ @operator)\n\n[\n  \"=\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"^=\"\n  \"&=\"\n  \"|=\"\n  \">>=\"\n  \">>>=\"\n  \"<<=\"\n  \"**=\"\n  \"&&=\"\n  \"||=\"\n  \"??=\"\n] @operator\n\n[\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"**\"\n  \"++\"\n  \"--\"\n] @operator\n\n[\n  \"&&\"\n  \"||\"\n  \"??\"\n  \"!\"\n  \"~\"\n] @operator\n\n[\n  \"==\"\n  \"===\"\n  \"!=\"\n  \"!==\"\n  \"<\"\n  \"<=\"\n  \">\"\n  \">=\"\n] @operator\n\n[\n  \"<<\"\n  \">>\"\n  \">>>\"\n  \"&\"\n  \"|\"\n  \"^\"\n] @operator\n\n; Control flow keywords\n[\n  \"if\"\n  \"else\"\n  \"switch\"\n  \"case\"\n  \"default\"\n  \"for\"\n  \"while\"\n  \"do\"\n  \"break\"\n  \"continue\"\n  \"return\"\n  \"throw\"\n  \"try\"\n  \"catch\"\n  \"finally\"\n] @keyword.control\n\n[\n  \"await\"\n  \"async\"\n] @keyword.control.flow\n\n[\n  \"import\"\n  \"export\"\n  \"from\"\n  \"as\"\n] @keyword.control.import\n\n; Other keywords\n[\n  \"function\"\n  \"class\"\n  \"extends\"\n  \"implements\"\n  \"new\"\n  \"typeof\"\n  \"instanceof\"\n  \"in\"\n  \"of\"\n  \"void\"\n  \"delete\"\n  \"yield\"\n  \"static\"\n  \"get\"\n  \"set\"\n  \"abstract\"\n  \"readonly\"\n  \"declare\"\n  \"override\"\n] @keyword\n\n[\n  \"let\"\n  \"const\"\n  \"var\"\n] @keyword.storage\n\n; Special identifiers\n[\n  (this)\n  (super)\n] @variable.builtin\n\n; Reserved identifiers used as special built-ins\n((identifier) @variable.builtin\n  (#any-of? @variable.builtin \"arguments\" \"await\" \"component\" \"fragment\" \"track\" \"untrack\"))\n\n; Properties\n(property_signature\n  name: (property_name) @variable.other.member)\n\n(pair\n  key: (property_name) @variable.other.member)\n\n(member_expression\n  property: (identifier) @variable.other.member)\n\n(shorthand_property_identifier) @variable.other.member\n(shorthand_property_identifier_pattern) @variable.other.member\n\n; Private properties\n(private_property_identifier) @variable.other.member\n\n; Punctuation\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n[\".\" \",\" \";\" \":\" \"...\"] @punctuation.delimiter\n; Note: < and > are handled separately in JSX contexts as @tag.delimiter\n\n; Special: Arrow function\n\"=>\" @operator\n\n; Hash bang\n(hash_bang_line) @comment\n"
  },
  {
    "path": "runtime/queries/ripple/injections.scm",
    "content": "; Inject CSS into style elements\n(style_element\n  (raw_text) @injection.content\n  (#set! injection.language \"css\"))\n\n; Inject JavaScript/TypeScript into server blocks\n; Note: statement is inlined, so we need to match specific statement types\n; Commenting out for now as it requires matching all concrete statement types\n\n; Template string interpolations\n(template_substitution\n  (expression) @injection.content\n  (#set! injection.language \"typescript\"))\n"
  },
  {
    "path": "runtime/queries/ripple/locals.scm",
    "content": "; Scopes\n[\n  (statement_block)\n  (function_declaration)\n  (arrow_function)\n  (function_expression)\n  (component_declaration)\n  (fragment_declaration)\n  (class_declaration)\n  (for_statement)\n  (for_of_statement)\n  (for_in_statement)\n  (while_statement)\n  (catch_clause)\n] @local.scope\n\n; Definitions\n(component_declaration\n  name: (identifier) @local.definition.function)\n\n(fragment_declaration\n  name: (identifier) @local.definition.function)\n\n(function_declaration\n  name: (identifier) @local.definition.function)\n\n(class_declaration\n  name: (identifier) @local.definition.type)\n\n(method_definition\n  name: (property_name) @local.definition.function.method)\n\n(variable_declarator\n  name: (identifier) @local.definition.variable)\n\n(required_parameter\n  pattern: (identifier) @local.definition.variable.parameter)\n\n(rest_parameter\n  (identifier) @local.definition.variable.parameter)\n\n; References\n(identifier) @local.reference\n\n; Imports\n(import_specifier\n  name: (identifier) @local.definition.namespace)\n\n(namespace_import\n  (identifier) @local.definition.namespace)\n\n; Exports\n(export_specifier\n  name: (identifier) @local.definition.namespace)\n"
  },
  {
    "path": "runtime/queries/ripple/rainbows.scm",
    "content": "; Bracket pairs for cursor navigation\n\n[\n  (for_statement)\n  (for_in_statement)\n  (for_of_statement)\n  (catch_clause)\n  (formal_parameters)\n  (parenthesized_expression)\n  (arguments)\n  (parenthesized_type)\n  (array_pattern)\n  (subscript_expression)\n  (computed_property_name)\n  (array)\n  (array_type)\n  (tuple_type)\n  (export_clause)\n  (named_imports)\n  (statement_block)\n  (switch_body)\n  (component_body)\n  (class_body)\n  (object_pattern)\n  (server_block)\n  (object)\n  (jsx_expression)\n  (object_type)\n] @rainbow.scope\n\n(jsx_opening_element [\"<\" \">\"] @rainbow.bracket) @rainbow.scope\n(jsx_closing_element [\"</\" \">\"] @rainbow.bracket) @rainbow.scope\n(jsx_self_closing_element [\"<\" \"/>\"] @rainbow.bracket) @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"[\" \"]\"\n  \"{\" \"}\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/ripple/readme.md",
    "content": "Taken from https://github.com/Ripple-TS/ripple/tree/6ccf86deaf03d48b2ca325b61bb129601628f8c6/packages/tree-sitter/queries\n"
  },
  {
    "path": "runtime/queries/ripple/tags.scm",
    "content": "; Code outline/structure for symbol navigation\n\n; Components\n(component_declaration\n  name: (identifier) @name) @definition.function\n\n; Fragments\n(fragment_declaration\n  name: (identifier) @name) @definition.function\n\n; Functions\n(function_declaration\n  name: (identifier) @name) @definition.function\n\n; Classes\n(class_declaration\n  name: (identifier) @name) @definition.class\n\n; Methods\n(method_definition\n  name: (property_name) @name) @definition.function\n"
  },
  {
    "path": "runtime/queries/rmarkdown/highlights.scm",
    "content": "; inherits: markdown\n"
  },
  {
    "path": "runtime/queries/rmarkdown/indents.scm",
    "content": "; inherits: markdown\n"
  },
  {
    "path": "runtime/queries/rmarkdown/injections.scm",
    "content": "; inherits: markdown\n"
  },
  {
    "path": "runtime/queries/robot/highlights.scm",
    "content": "[\n  (comment)\n  (extra_text)\n] @comment\n\n[\n  (section_header)\n  (setting_statement)\n  (keyword_setting)\n  (test_case_setting)\n] @keyword\n\n(variable_definition (variable_name) @variable)\n(keyword_definition (name) @function)\n(test_case_definition (name) @function)\n\n(keyword_invocation (keyword) @function)\n(ellipses) @punctuation.delimiter\n\n(text_chunk) @string\n(inline_python_expression) @string.special\n[\n  (scalar_variable)\n  (list_variable)\n  (dictionary_variable)\n] @variable\n\n; Control structures\n\n\"RETURN\" @keyword.control.return\n\n[\n  \"FOR\"\n  \"IN\"\n  \"IN RANGE\"\n  \"IN ENUMERATE\"\n  \"IN ZIP\"\n  (break_statement)\n  (continue_statement)\n] @keyword.control.repeat\n(for_statement \"END\" @keyword.control.repeat)\n\n\"WHILE\" @keyword.control.repeat\n(while_statement \"END\" @keyword.control.repeat)\n\n[\n  \"IF\"\n  \"ELSE IF\"\n] @keyword.control.conditional\n(if_statement \"END\" @keyword.control.conditional)\n(if_statement (else_statement \"ELSE\" @keyword.control.conditional))\n\n[\n  \"TRY\"\n  \"EXCEPT\"\n  \"FINALLY\"\n] @keyword.control.exception\n(try_statement \"END\" @keyword.control.exception)\n(try_statement (else_statement \"ELSE\" @keyword.control.exception))\n"
  },
  {
    "path": "runtime/queries/robots.txt/highlights.scm",
    "content": "(comment) @comment\n\n(directive) @attribute\n\n(rule (unknownDirective) @attribute) @diagnostic.error\n\n(userAgent) @namespace\n\n(value) @string\n\n((value) @string.special.path\n  (#match? @string.special.path \"^/\"))\n\n((value) @ui.text.directory\n  (#match? @ui.text.directory \"^/.+/$\"))\n\n((value) @operator\n  (#match? @operator \"\\\\*\"))\n\n(rule\n  (directive (sitemap))\n  (value) @string.special.url)\n\n(rule\n  (directive (crawlDelay))\n  (value) @constant.numeric.integer)\n\n\":\" @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/robots.txt/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/robots.txt/tags.scm",
    "content": "(rule\n  (directive\n    (userAgent))\n  (value) @definition.module)\n"
  },
  {
    "path": "runtime/queries/robots.txt/textobjects.scm",
    "content": "(comment) @comment.inside\n(comment)+ @comment.around\n\n(rule (_) @entry.inside) @entry.around\n"
  },
  {
    "path": "runtime/queries/ron/highlights.scm",
    "content": "; Structs\n;------------\n\n(enum_variant) @type.enum.variant\n(struct_entry (_) @variable.other.member \":\")\n(struct_name (identifier)) @type\n(unit_struct) @type.builtin\n\n; Literals\n;------------\n\n(string) @string\n(boolean) @constant.builtin.boolean\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(char) @constant.character\n\n; Comments\n;------------\n\n(line_comment) @comment.line\n(block_comment) @comment.block\n\n\n; Punctuation\n;------------\n\n\",\" @punctuation.delimiter\n\":\" @punctuation.delimiter\n\n\"(\" @punctuation.bracket\n\")\" @punctuation.bracket\n\"[\" @punctuation.bracket\n\"]\" @punctuation.bracket\n\"{\" @punctuation.bracket\n\"}\" @punctuation.bracket\n\n\"-\" @operator\n\n; Special\n;------------\n(escape_sequence) @constant.character.escape\n"
  },
  {
    "path": "runtime/queries/ron/indents.scm",
    "content": "[\n  (array)\n  (map)\n  (tuple)\n  (struct)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/ron/injections.scm",
    "content": "([(line_comment) (block_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/ron/rainbows.scm",
    "content": "[\n  (struct)\n  (map)\n  (tuple)\n  (array)\n] @rainbow.scope\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/ron/tags.scm",
    "content": "(struct_entry\n  (identifier) @definition.struct)\n\n(map_entry (string) @definition.struct)\n"
  },
  {
    "path": "runtime/queries/rpmspec/highlights.scm",
    "content": "; Specific parametric macro expansion rules (must come first)\n(macro_expansion_call\n  (builtin) @function.macro)\n\n(macro_expansion_call\n  (identifier) @function.macro)\n\n(macro_expansion_call\n  option: (macro_option) @variable.parameter\n  argument: [\n    (word) @variable.parameter\n    (concatenation\n      (word) @variable.parameter)\n    (macro_expansion) @function.call\n    (macro_simple_expansion) @function.call\n  ])\n\n; Highlight macro options in parametric expansions\n(macro_option) @variable.parameter\n\n; Macro expansion rules\n(macro_expansion\n  (builtin) @variable.builtin\n  argument: (_) @variable.parameter)\n\n(macro_expansion\n  (identifier) @function.call\n  argument: [\n    (word) @variable.parameter\n    (concatenation\n      (word) @variable.parameter)\n  ])\n\n; Macro definition and undefinition\n(macro_definition\n  \"%\" @punctuation.special\n  (builtin) @keyword.directive.define\n  (identifier) @keyword.macro)\n(macro_undefinition\n  (builtin) @keyword.directive.define\n  (identifier) @keyword.macro)\n\n; General punctuation for macros\n(macro_simple_expansion\n  \"%\" @punctuation.special) @none\n(macro_expansion\n  \"%{\" @punctuation.special\n  \"}\" @punctuation.special) @none\n\n; General identifier and builtin rules (must come after specific rules)\n(special_variable_name) @constant\n(builtin) @variable.builtin\n\n(setup_macro\n  argument: [\n    (setup_flag) @variable.parameter\n    (setup_source_option) @variable.parameter\n    ((setup_name_option\n      directory: (_) @string) @variable.parameter)\n  ])\n\n(patch_macro\n  [\n    (patch_flag) @variable.parameter\n    (patch_number_option) @variable.parameter\n    (patch_string_option) @variable.parameter\n    (patch_long_option) @variable.parameter\n  ])\n\n[\n  (tag)\n  (dependency_tag)\n] @type.definition\n\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(version) @constant.numeric.float\n\n(comment) @comment\n;(string) @string\n(quoted_string) @string\n\n(description\n  (section_name) @type.definition)\n(package\n  (section_name) @type.definition)\n(files\n  (section_name) @type.definition)\n(changelog\n  (section_name) @type.definition)\n\n(prep_scriptlet\n  (section_name) @function.builtin)\n(generate_buildrequires\n  (section_name) @function.builtin)\n(conf_scriptlet\n  (section_name) @function.builtin)\n(build_scriptlet\n  (section_name) @function.builtin)\n(install_scriptlet\n  (section_name) @function.builtin)\n(check_scriptlet\n  (section_name) @function.builtin)\n(clean_scriptlet\n  (section_name) @function.builtin)\n\n[\n  \"%pre\"\n  \"%post\"\n  \"%preun\"\n  \"%postun\"\n  \"%pretrans\"\n  \"%posttrans\"\n  \"%preuntrans\"\n  \"%postuntrans\"\n  \"%verify\"\n] @function.builtin\n\n[\n  \"%triggerprein\"\n  \"%triggerin\"\n  \"%triggerun\"\n  \"%triggerpostun\"\n] @function.builtin\n\n[\n  \"%filetriggerin\"\n  \"%filetriggerun\"\n  \"%filetriggerpostun\"\n  \"%transfiletriggerin\"\n  \"%transfiletriggerun\"\n  \"%transfiletriggerpostun\"\n] @function.builtin\n\n[\n  \"%artifact\"\n  \"%attr\"\n  \"%config\"\n  \"%dir\"\n  \"%doc\"\n  \"%docdir\"\n  \"%ghost\"\n  \"%license\"\n  \"%missingok\"\n  \"%readme\"\n] @keyword.type\n\n[\n  \"!=\"\n  \"<\"\n  \"<=\"\n  \"==\"\n  \">\"\n  \">=\"\n  \"and\"\n  \"&&\"\n  \"or\"\n  \"||\"\n] @operator\n\n[\n  \"with\"\n  \"without\"\n  \"defined\"\n  \"undefined\"\n] @keyword.operator\n\n[\n  \"%if\"\n  \"%ifarch\"\n  \"%ifos\"\n  \"%ifnarch\"\n  \"%ifnos\"\n  \"%elif\"\n  \"%elifarch\"\n  \"%elifos\"\n  \"%else\"\n  \"%endif\"\n] @keyword.conditional\n\n; Fallback rule for identifiers (commented out due to conflicts with parametric macros)\n; (identifier) @variable\n"
  },
  {
    "path": "runtime/queries/rshtml/highlights.scm",
    "content": "(start_symbol) @keyword\n(hash_symbol) @punctuation.special\n\n(open_paren) @punctuation.bracket\n(close_paren) @punctuation.bracket\n(open_brace) @punctuation.bracket\n(close_brace) @punctuation.bracket\n\n(fat_arrow) @operator\n(semicolon) @punctuation.delimiter\n(equals) @punctuation.delimiter\n\n(string_line) @string\n\n(comment_block) @comment.block\n(open_comment) @operator\n(close_comment) @operator\n\n(continue_) @keyword.control.conditional\n(break_) @keyword.control.conditional\n\n(\n  (start_symbol) @keyword.control.import\n  .\n  (extends_) @keyword.control.import\n)\n\n(raw_) @keyword\n\n(\n  (start_symbol) @keyword.control.import\n  .\n  (include_directive (include_) @keyword.control.import)\n)\n\n(render_) @keyword\n(render_body_) @keyword\n(child_content_) @keyword\n(section_) @keyword\n\n(section_block\n  name: (rust_identifier) @namespace)\n\n(as_) @keyword.operator\n(as_clause\n  alias: (rust_identifier) @type)\n(\n  (start_symbol) @keyword.control.import\n  .\n  (use_directive (use_) @keyword.control.import)\n)\n\n(number) @constant.numeric\n(bool) @constant.builtin.boolean\n\n(tag_open) @punctuation.bracket\n(tag_close) @punctuation.bracket\n(tag_end_open) @punctuation.bracket\n(tag_self_close) @punctuation.bracket\n\n(component_tag\n  name: (component_tag_identifier) @tag)\n\n(component_tag\n  name_close: (component_tag_identifier) @tag)\n\n(component_tag_parameter\n  name: (rust_identifier) @attribute)\n\n(\n  (start_symbol) @function.method\n  .\n  (rust_expr_simple)\n)\n\n(\n  (start_symbol) @function.method\n  .\n  (rust_expr_paren)\n)\n\n(\n  (start_symbol) @keyword.directive\n  .\n  (rust_block)\n)\n\n(\n  (start_symbol) @keyword.control.conditional\n  .\n  (if_stmt)\n)\n(\n  (start_symbol) @keyword\n  .\n  (for_stmt)\n)\n(\n  (start_symbol) @keyword.control.repeat\n  .\n  (while_stmt)\n)\n(\n  (start_symbol) @keyword.control.conditional\n  .\n  (match_stmt)\n)\n\n;this is for now extra\n(else_clause\n  head: (rust_text) @keyword.control.conditional)\n"
  },
  {
    "path": "runtime/queries/rshtml/injections.scm",
    "content": "((html_text) @injection.content\n  (#set! injection.language \"html\")\n  (#set! injection.include-children)\n  (#set! injection.combined))\n\n((rust_text) @injection.content\n   (#set! injection.language \"rust\")\n   (#set! injection.include-children)\n   (#not-match? @injection.content \"^else\"))\n\n((comment_block) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/rshtml/textobjects.scm",
    "content": "(raw_block (html_text)? @entry.inside) @entry.around\n\n(section_block body: (_)? @entry.inside) @entry.around\n\n(rust_block content: (rust_text)? @entry.inside) @entry.around\n\n\n(if_stmt body: (_)? @entry.inside) @entry.around\n\n(while_stmt body: (_)? @entry.inside) @entry.around\n\n(for_stmt body: (_)? @entry.inside) @entry.around\n\n(match_stmt (match_stmt_arm) @entry.inside) \n(match_stmt (match_stmt_arm)+ @entry.inside) @entry.around\n\n(component_tag (component_tag_parameter (rust_identifier) @parameter.inside) @parameter.around)\n(component_tag body: (component_tag_body)? @entry.inside) @entry.around\n\n(comment_block (comment_content) @comment.inside) @comment.around\n"
  },
  {
    "path": "runtime/queries/rst/highlights.scm",
    "content": "(comment) @comment\n\n[\n  (title)\n] @markup.heading.1\n\n[\n  \"adornment\"\n] @markup.heading.marker\n\n[\n  (target)\n  (reference)\n] @markup.link.url\n\n[\n  \"bullet\"\n] @markup.list.unnumbered\n\n(strong) @markup.bold\n(emphasis) @markup.italic\n(literal) @markup.raw.inline\n\n(list_item\n  (term) @markup.bold\n  (classifier)? @markup.italic)\n\n(directive\n  [\"..\" (type) \"::\"] @function\n)\n\n(field\n  [\":\" (field_name) \":\"] @variable.other.member\n)\n\n(interpreted_text) @markup.raw.inline\n\n(interpreted_text (role)) @keyword\n"
  },
  {
    "path": "runtime/queries/rst/tags.scm",
    "content": "(section (title) @definition.section)\n"
  },
  {
    "path": "runtime/queries/ruby/highlights.scm",
    "content": "; Operators\n[\n\":\"\n\"?\"\n\"~\"\n\"=>\"\n\"->\"\n\"!\"\n] @operator\n\n(assignment\n  \"=\" @operator)\n\n(operator_assignment\n  operator: [\"+=\" \"-=\" \"*=\" \"**=\" \"/=\" \"||=\" \"|=\" \"&&=\" \"&=\" \"%=\" \">>=\" \"<<=\" \"^=\"] @operator)\n\n(binary\n  operator: [\"/\" \"|\" \"==\" \"===\" \"||\" \"&&\" \">>\" \"<<\" \"<\" \">\" \"<=\" \">=\" \"&\" \"^\" \"!~\" \"=~\" \"<=>\" \"**\" \"*\" \"!=\" \"%\" \"-\" \"+\"] @operator)\n\n(range\n  operator: [\"..\" \"...\"] @operator)\n\n[\n  \",\"\n  \";\"\n  \".\"\n  \"&.\"\n] @punctuation.delimiter\n\n[\n  \"|\"\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"%w(\"\n  \"%i(\"\n] @punctuation.bracket\n\n; Literals\n\n[\n  (string)\n  (bare_string)\n  (subshell)\n  (heredoc_body)\n  (heredoc_beginning)\n] @string\n\n[\n  (simple_symbol)\n  (delimited_symbol)\n  (bare_symbol)\n] @string.special.symbol\n\n(pair key: ((_)\":\" @string.special.symbol) @string.special.symbol)\n\n(regex) @string.regexp\n(escape_sequence) @constant.character.escape\n\n[\n  (integer)\n  (float)\n] @constant.numeric.integer\n\n[\n  (nil)\n  (true)\n  (false)\n] @constant.builtin\n\n(interpolation\n  \"#{\" @punctuation.special\n  \"}\" @punctuation.special) @embedded\n\n(comment) @comment\n\n; Identifiers\n\n((identifier) @function.method\n (#is-not? local))\n\n[\n  (identifier)\n] @variable\n\n[\n  (class_variable)\n  (instance_variable)\n] @variable.other.member\n\n(constant) @constructor\n\n((identifier) @constant.builtin\n (#match? @constant.builtin \"^(__FILE__|__LINE__|__ENCODING__)$\"))\n\n((constant) @constant.builtin\n (#match? @constant.builtin \"^(ENV|ARGV|ARGF|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING)$\"))\n\n((constant) @constant\n (#match? @constant \"^[A-Z\\\\d_]+$\"))\n\n(self) @variable.builtin\n(super) @function.builtin\n\n[(forward_parameter)(forward_argument)] @variable.parameter\n(keyword_parameter name:((_)\":\" @variable.parameter) @variable.parameter)\n(optional_parameter name:((_)\"=\" @operator) @variable.parameter)\n(optional_parameter name: (identifier) @variable.parameter)\n(splat_parameter name: (identifier) @variable.parameter) @variable.parameter\n(hash_splat_parameter name: (identifier) @variable.parameter) @variable.parameter\n(method_parameters (identifier) @variable.parameter)\n(block_parameter (identifier) @variable.parameter)\n(block_parameters (identifier) @variable.parameter)\n\n; Function definitions\n\n(alias (identifier) @function.method)\n(setter (identifier) @function.method)\n(method name: [(identifier) (constant)] @function.method)\n(singleton_method name: [(identifier) (constant)] @function.method)\n\n; Function calls\n\n(call\n  method: [(identifier) (constant)] @function.method)\n\n((identifier) @function.builtin\n (#match? @function.builtin \"^(attr|attr_accessor|attr_reader|attr_writer|include|prepend|refine|private|protected|public)$\"))\n\n\"defined?\" @function.builtin\n\n; Keywords\n\n[\n  \"BEGIN\"\n  \"END\"\n  \"alias\"\n  \"begin\"\n  \"class\"\n  \"do\"\n  \"end\"\n  \"module\"\n  \"in\"\n  \"rescue\"\n  \"ensure\"\n] @keyword\n\n[\n  \"if\"\n  \"else\"\n  \"elsif\"\n  \"when\"\n  \"case\"\n  \"unless\"\n  \"then\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n  \"while\"\n  \"retry\"\n  \"until\"\n  \"redo\"\n] @keyword.control.repeat\n\n[\n  \"yield\"\n  \"return\"\n  \"next\"\n  \"break\"\n] @keyword.control.return\n\n[\n  \"def\"\n  \"undef\"\n] @keyword.function\n\n((identifier) @keyword.control.import\n (#match? @keyword.control.import \"^(require|require_relative|load|autoload)$\"))\n\n[\n  \"or\"\n  \"and\"\n  \"not\"\n] @keyword.operator\n\n((identifier) @keyword.control.exception\n (#match? @keyword.control.exception \"^(raise|fail)$\"))\n"
  },
  {
    "path": "runtime/queries/ruby/indents.scm",
    "content": "[\n  (argument_list)\n  (array)\n  (begin)\n  (block)\n  (call)\n  (class)\n  (case)\n  (elsif)\n  (if)\n  (hash)\n  (method)\n  (module)\n  (singleton_class)\n  (singleton_method)\n] @indent\n\n[\n  \")\"\n  \"}\"\n  \"]\"\n  \"end\"\n  \"when\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/ruby/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((heredoc_body \n  (heredoc_content) @injection.content\n  (heredoc_end) @name\n  (#set! injection.language \"sql\")) \n (#eq? @name \"SQL\"))\n\n((heredoc_body\n  (heredoc_content) @injection.content\n  (heredoc_end) @name\n  (#set! injection.language \"graphql\"))\n (#any-of? @name\n       \"GQL\"\n       \"GRAPHQL\"))\n\n((heredoc_body\n  (heredoc_content) @injection.content\n  (heredoc_end) @name\n  (#set! injection.language \"erb\"))\n (#eq? @name \"ERB\"))\n\n; `<command>`\n; %x{<command>}\n(subshell\n  (string_content) @injection.content\n  (#set! injection.language \"bash\"))\n\n(call\n  method: (identifier) @_method (#any-of? @_method \"system\" \"spawn\" \"exec\")\n  arguments: (argument_list\n    (string\n      (string_content) @injection.content))\n  (#set! injection.language \"bash\"))\n"
  },
  {
    "path": "runtime/queries/ruby/locals.scm",
    "content": "((method) @local.scope\n (#set! local.scope-inherits false))\n\n[\n  (lambda)\n  (block)\n  (do_block)\n] @local.scope\n\n(block_parameter (identifier) @local.definition.variable.parameter)\n(block_parameters (identifier) @local.definition.variable.parameter)\n(destructured_parameter (identifier) @local.definition.variable.parameter)\n(hash_splat_parameter (identifier) @local.definition.variable.parameter)\n(lambda_parameters (identifier) @local.definition.variable.parameter)\n(method_parameters (identifier) @local.definition.variable.parameter)\n(splat_parameter (identifier) @local.definition.variable.parameter)\n(keyword_parameter name: (identifier) @local.definition.variable.parameter)\n(optional_parameter name: (identifier) @local.definition.variable.parameter)\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/ruby/rainbows.scm",
    "content": "[\n  (begin_block)\n  (end_block)\n  (singleton_method)\n  (block_parameters)\n  (parenthesized_statements)\n  (element_reference)\n  (argument_list \"(\" \")\")\n  (block)\n  (destructured_left_assignment)\n  (interpolation)\n  (string_array)\n  (symbol_array)\n  (regex)\n  (array)\n  (hash)\n  (method_parameters)\n] @rainbow.scope\n\n[\n  \"#{\"\n  \"{\" \"}\"\n  \"(\" \")\"\n  \"%w(\" \"%i(\"\n  \"[\" \"]\"\n  \"|\"\n  \"/\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/ruby/tags.scm",
    "content": "; Method definitions\n\n(\n  (comment)* @doc\n  .\n  [\n    (method\n      name: (_) @name) @definition.method\n    (singleton_method\n      name: (_) @name) @definition.method\n  ]\n  (#strip! @doc \"^#\\\\s*\")\n  (#select-adjacent! @doc @definition.method)\n)\n\n(alias\n  name: (_) @name) @definition.method\n\n(setter\n  (identifier) @ignore)\n\n; Class definitions\n\n(\n  (comment)* @doc\n  .\n  [\n    (class\n      name: [\n        (constant) @name\n        (scope_resolution\n          name: (_) @name)\n      ]) @definition.class\n    (singleton_class\n      value: [\n        (constant) @name\n        (scope_resolution\n          name: (_) @name)\n      ]) @definition.class\n  ]\n  (#strip! @doc \"^#\\\\s*\")\n  (#select-adjacent! @doc @definition.class)\n)\n\n; Module definitions\n\n(\n  (module\n    name: [\n      (constant) @name\n      (scope_resolution\n        name: (_) @name)\n    ]) @definition.module\n)\n\n; Calls\n\n(call method: (identifier) @name) @reference.call\n\n(\n  [(identifier) (constant)] @name @reference.call\n  (#is-not? local)\n  (#not-match? @name \"^(lambda|load|require|require_relative|__FILE__|__LINE__)$\")\n)\n"
  },
  {
    "path": "runtime/queries/ruby/textobjects.scm",
    "content": "; Class and Modules\n(class\n  body: (_)? @class.inside) @class.around\n\n(singleton_class\n  value: (_)\n  (_)+ @class.inside) @class.around\n\n(call\n  receiver: (constant) @class_const\n  method: (identifier) @class_method\n  (#match? @class_const \"Class\")\n  (#match? @class_method \"new\")\n  (do_block (_)+ @class.inside)) @class.around\n  \n(module\n  body: (_)? @class.inside) @class.around\n\n; Functions and Blocks\n(singleton_method\n  body: (_)? @function.inside) @function.around\n\n(method\n  body: (_)? @function.inside) @function.around\n\n(do_block\n  body: (_)? @function.inside) @function.around\n\n(block\n  body: (_)? @function.inside) @function.around\n\n; Parameters      \n(method_parameters\n  (_) @parameter.inside) @parameter.around\n        \n(block_parameters \n  (_) @parameter.inside) @parameter.around\n        \n(lambda_parameters \n  (_) @parameter.inside) @parameter.around\n\n; Comments\n(comment) @comment.inside \n(comment)+ @comment.around\n\n(pair\n  (_) @entry.inside) @entry.around\n\n(array\n  (_) @entry.around)\n\n(string_array\n  (_) @entry.around)\n\n(symbol_array\n  (_) @entry.around)\n"
  },
  {
    "path": "runtime/queries/rust/highlights.scm",
    "content": "; -------\n; Basic identifiers\n; -------\n\n; We do not style ? as an operator on purpose as it allows styling ? differently, as many highlighters do. @operator.special might have been a better scope, but @special is already documented so the change would break themes (including the intent of the default theme)\n\"?\" @special\n\n(type_identifier) @type\n(identifier) @variable\n(field_identifier) @variable.other.member\n\n; -------\n; Operators\n; -------\n\n[\n  \"*\"\n  \"'\"\n  \"->\"\n  \"=>\"\n  \"<=\"\n  \"=\"\n  \"==\"\n  \"!\"\n  \"!=\"\n  \"%\"\n  \"%=\"\n  \"&\"\n  \"&=\"\n  \"&&\"\n  \"|\"\n  \"|=\"\n  \"||\"\n  \"^\"\n  \"^=\"\n  \"*\"\n  \"*=\"\n  \"-\"\n  \"-=\"\n  \"+\"\n  \"+=\"\n  \"/\"\n  \"/=\"\n  \">\"\n  \"<\"\n  \">=\"\n  \">>\"\n  \"<<\"\n  \">>=\"\n  \"<<=\"\n  \"@\"\n  \"..\"\n  \"..=\"\n  \"'\"\n] @operator\n\n; -------\n; Paths\n; -------\n\n(use_declaration\n  argument: (identifier) @namespace)\n(use_wildcard\n  (identifier) @namespace)\n(extern_crate_declaration\n  name: (identifier) @namespace\n  alias: (identifier)? @namespace)\n(mod_item\n  name: (identifier) @namespace)\n(scoped_use_list\n  path: (identifier)? @namespace)\n(use_list\n  (identifier) @namespace)\n(use_as_clause\n  path: (identifier)? @namespace\n  alias: (identifier) @namespace)\n\n; -------\n; Types\n; -------\n\n(type_parameter\n  name: (type_identifier) @type.parameter)\n((type_arguments (type_identifier) @constant)\n (#match? @constant \"^[A-Z_]+$\"))\n(type_arguments (type_identifier) @type)\n; `_` in `(_, _)`\n(tuple_struct_pattern \"_\" @comment.unused)\n; `_` in `Vec<_>`\n((type_arguments (type_identifier) @comment.unused)\n (#eq? @comment.unused \"_\"))\n; `_` in `Rc<[_]>`\n((array_type (type_identifier) @comment.unused)\n (#eq? @comment.unused \"_\"))\n\n; ---\n; Primitives\n; ---\n\n(escape_sequence) @constant.character.escape\n(primitive_type) @type.builtin\n(boolean_literal) @constant.builtin.boolean\n(integer_literal) @constant.numeric.integer\n(float_literal) @constant.numeric.float\n(char_literal) @constant.character\n[\n  (string_literal)\n  (raw_string_literal)\n] @string\n\n; -------\n; Comments\n; -------\n\n(shebang) @comment\n(line_comment) @comment.line\n(block_comment) @comment.block\n\n; Doc Comments\n(line_comment\n  (outer_doc_comment_marker \"/\" @comment.line.documentation)\n  (doc_comment)) @comment.line.documentation\n(line_comment\n  (inner_doc_comment_marker \"!\" @comment.line.documentation)\n  (doc_comment)) @comment.line.documentation\n\n(block_comment\n  (outer_doc_comment_marker) @comment.block.documentation\n  (doc_comment) \"*/\" @comment.block.documentation) @comment.block.documentation\n(block_comment\n  (inner_doc_comment_marker) @comment.block.documentation\n  (doc_comment) \"*/\" @comment.block.documentation) @comment.block.documentation\n\n; ---\n; Extraneous\n; ---\n\n(self) @variable.builtin\n\n(field_initializer\n  (field_identifier) @variable.other.member)\n(shorthand_field_initializer\n  (identifier) @variable.other.member)\n(shorthand_field_identifier) @variable.other.member\n\n(lifetime\n  \"'\" @label\n  (identifier) @label)\n(label\n  \"'\" @label\n  (identifier) @label)\n\n; ---\n; Punctuation\n; ---\n\n[\n  \"::\"\n  \".\"\n  \";\"\n  \",\"\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"#\"\n] @punctuation.bracket\n(type_arguments\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n(type_parameters\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n(for_lifetimes [\"<\" \">\"] @punctuation.bracket)\n(closure_parameters\n  \"|\" @punctuation.bracket)\n(bracketed_type [\"<\" \">\"] @punctuation.bracket)\n\n; ---\n; Variables\n; ---\n\n(let_declaration\n  pattern: [\n    ((identifier) @variable)\n    ((tuple_pattern\n      (identifier) @variable))\n  ])\n  \n; It needs to be anonymous to not conflict with `call_expression` further below. \n(_\n value: (field_expression\n  value: (identifier)? @variable\n  field: (field_identifier) @variable.other.member))\n\n(parameter\n\tpattern: (identifier) @variable.parameter)\n(closure_parameters\n\t(identifier) @variable.parameter)\n\n; Mutable variables\n\n(let_declaration\n  (mutable_specifier)\n  pattern: (identifier) @variable.mutable)\n(mut_pattern\n  (mutable_specifier)\n  (identifier) @variable.mutable)\n\n(parameter\n  (mutable_specifier)\n  pattern: (identifier) @variable.parameter.mutable)\n\n(self_parameter\n  (mutable_specifier)\n  (self) @variable.builtin.mutable)\n\n; -------\n; Keywords\n; -------\n\n\"in\" @keyword.control\n\n[\n  \"match\"\n  \"if\"\n  \"else\"\n  \"try\"\n] @keyword.control.conditional\n\n[\n  \"while\"\n  \"loop\"\n] @keyword.control.repeat\n\n[\n  \"break\"\n  \"continue\"\n  \"return\"\n  \"await\"\n  \"yield\"\n] @keyword.control.return\n\n\"use\" @keyword.control.import\n(mod_item \"mod\" @keyword.control.import !body)\n(use_as_clause \"as\" @keyword.control.import)\n\n(type_cast_expression \"as\" @keyword.operator)\n\n[\n  (crate)\n  (super)\n  \"as\"\n  \"pub\"\n  \"mod\"\n  \"extern\"\n\n  \"impl\"\n  \"where\"\n  \"trait\"\n  \"for\"\n\n  \"default\"\n  \"async\"\n] @keyword\n\n(for_expression\n  \"for\" @keyword.control.repeat)\n(gen_block \"gen\" @keyword.control)\n\n[\n  \"struct\"\n  \"enum\"\n  \"union\"\n  \"type\"\n] @keyword.storage.type\n\n\"let\" @keyword.storage\n\"fn\" @keyword.function\n\"unsafe\" @keyword.special\n\"macro_rules!\" @function.macro\n\n(mutable_specifier) @keyword.storage.modifier.mut\n\n(reference_type \"&\" @keyword.storage.modifier.ref)\n(self_parameter \"&\" @keyword.storage.modifier.ref)\n\n[\n  \"static\"\n  \"const\"\n  \"raw\"\n  \"ref\"\n  \"move\"\n  \"dyn\"\n] @keyword.storage.modifier\n\n; ---\n; Remaining Paths\n; ---\n\n(scoped_identifier\n  path: (identifier)? @namespace\n  name: (identifier) @namespace)\n(scoped_type_identifier\n  path: (identifier) @namespace)\n\n; -------\n; Functions\n; -------\n\n; highlight `baz` in `any_function(foo::bar::baz)` as function\n; This generically works for an unlimited number of path segments:\n;\n; - `f(foo::bar)`\n; - `f(foo::bar::baz)`\n; - `f(foo::bar::baz::quux)`\n;\n; We know that in the above examples, the last component of each path is a function\n; as the only other valid thing (following Rust naming conventions) would be a module at\n; that position, however you cannot pass modules as arguments\n(call_expression\n  function: _\n  arguments: (arguments\n    (scoped_identifier\n      path: _\n      name: (identifier) @function)))\n\n(call_expression\n  function: [\n    ((identifier) @function)\n    (scoped_identifier\n      name: (identifier) @function)\n    (field_expression\n      field: (field_identifier) @function)\n  ])\n(generic_function\n  function: [\n    ((identifier) @function)\n    (scoped_identifier\n      name: (identifier) @function)\n    (field_expression\n      field: (field_identifier) @function.method)\n  ])\n\n(function_item\n  name: (identifier) @function)\n\n(function_signature_item\n  name: (identifier) @function)\n\n; -------\n; Guess Other Types\n; -------\n; Other PascalCase identifiers are assumed to be structs.\n\n((identifier) @type\n  (#match? @type \"^[A-Z]\"))\n\n(never_type \"!\" @type)\n\n((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z\\\\d_]*$\"))\n\n; ---\n; PascalCase identifiers in call_expressions (e.g. `Ok()`)\n; are assumed to be enum constructors.\n; ---\n\n(call_expression\n  function: [\n    ((identifier) @constructor\n      (#match? @constructor \"^[A-Z]\"))\n    (scoped_identifier\n      name: ((identifier) @constructor\n        (#match? @constructor \"^[A-Z]\")))\n  ])\n\n; ---\n; PascalCase identifiers under a path which is also PascalCase\n; are assumed to be constructors if they have methods or fields.\n; ---\n\n(field_expression\n  value: (scoped_identifier\n    path: [\n      (identifier) @type\n      (scoped_identifier\n        name: (identifier) @type)\n    ]\n    name: (identifier) @constructor\n      (#match? @type \"^[A-Z]\")\n      (#match? @constructor \"^[A-Z]\")))\n\n(enum_variant (identifier) @type.enum.variant)\n\n\n; -------\n; Constructors\n; -------\n; TODO: this is largely guesswork, remove it once we get actual info from locals.scm or r-a\n\n(struct_expression\n  name: (type_identifier) @constructor)\n\n(tuple_struct_pattern\n  type: [\n    (identifier) @constructor\n    (scoped_identifier\n      name: (identifier) @constructor)\n  ])\n(struct_pattern\n  type: [\n    ((type_identifier) @constructor)\n    (scoped_type_identifier\n      name: (type_identifier) @constructor)\n  ])\n(match_pattern\n  ((identifier) @constructor) (#match? @constructor \"^[A-Z]\"))\n(or_pattern\n  ((identifier) @constructor)\n  ((identifier) @constructor)\n  (#match? @constructor \"^[A-Z]\"))\n\n; ---\n; Macros\n; ---\n\n(attribute\n  (identifier) @function.macro)\n(inner_attribute_item \"!\" @punctuation)\n(attribute\n  [\n    (identifier) @function.macro\n    (scoped_identifier\n      name: (identifier) @function.macro)\n  ]\n  (token_tree (identifier) @function.macro)?)\n\n(inner_attribute_item) @attribute\n\n(macro_definition\n  name: (identifier) @function.macro)\n(macro_invocation\n  macro: [\n    ((identifier) @function.macro)\n    (scoped_identifier\n      name: (identifier) @function.macro)\n  ]\n  \"!\" @function.macro)\n\n(metavariable) @variable.parameter\n(fragment_specifier) @type\n\n(attribute\n  (identifier) @special\n  arguments: (token_tree (identifier) @type)\n  (#eq? @special \"derive\")\n)\n\n(token_repetition_pattern) @punctuation.delimiter\n(token_repetition_pattern [\")\" \"(\" \"$\"] @punctuation.special)\n(token_repetition_pattern \"?\" @operator)\n\n; ---\n; Prelude\n; ---\n\n((identifier) @type.enum.variant.builtin\n (#any-of? @type.enum.variant.builtin \"Some\" \"None\" \"Ok\" \"Err\"))\n\n\n(call_expression\n  (identifier) @function.builtin\n  (#any-of? @function.builtin\n    \"drop\"\n    \"size_of\"\n    \"size_of_val\"\n    \"align_of\"\n    \"align_of_val\"))\n\n((type_identifier) @type.builtin\n (#any-of?\n    @type.builtin\n    \"Send\"\n    \"Sized\"\n    \"Sync\"\n    \"Unpin\"\n    \"Drop\"\n    \"Fn\"\n    \"FnMut\"\n    \"FnOnce\"\n    \"AsMut\"\n    \"AsRef\"\n    \"From\"\n    \"Into\"\n    \"DoubleEndedIterator\"\n    \"ExactSizeIterator\"\n    \"Extend\"\n    \"IntoIterator\"\n    \"Iterator\"\n    \"Option\"\n    \"Result\"\n    \"Clone\"\n    \"Copy\"\n    \"Debug\"\n    \"Default\"\n    \"Eq\"\n    \"Hash\"\n    \"Ord\"\n    \"PartialEq\"\n    \"PartialOrd\"\n    \"ToOwned\"\n    \"Box\"\n    \"String\"\n    \"ToString\"\n    \"Vec\"\n    \"FromIterator\"\n    \"TryFrom\"\n    \"TryInto\"))\n"
  },
  {
    "path": "runtime/queries/rust/indents.scm",
    "content": "[\n  (use_list)\n  (block)\n  (match_block)\n  (arguments)\n  (parameters)\n  (declaration_list)\n  (field_declaration_list)\n  (field_initializer_list)\n  (struct_pattern)\n  (tuple_pattern)\n  (unit_expression)\n  (enum_variant_list)\n  (call_expression)\n  (binary_expression)\n  (field_expression)\n  (await_expression)\n  (tuple_expression)\n  (array_expression)\n  (where_clause)\n  (type_cast_expression)\n\n  (token_tree)\n  (macro_definition)\n  (token_tree_pattern)\n  (token_repetition)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n\n; Indent the right side of assignments.\n; The #not-same-line? predicate is required to prevent an extra indent for e.g.\n; an else-clause where the previous if-clause starts on the same line as the assignment.\n(assignment_expression\n  .\n  (_) @expr-start\n  right: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(compound_assignment_expr\n  .\n  (_) @expr-start\n  right: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(let_declaration\n  \"let\" @expr-start\n  value: (_) @indent\n  alternative: (_)? @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(let_condition\n  .\n  (_) @expr-start\n  value: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(if_expression\n  .\n  (_) @expr-start\n  condition: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(static_item\n  .\n  (_) @expr-start\n  value: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(field_pattern\n  .\n  (_) @expr-start\n  pattern: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n; Indent type aliases that span multiple lines, similar to\n; regular assignment expressions\n(type_item\n  .\n  (_) @expr-start\n  type: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n\n; Some field expressions where the left part is a multiline expression are not\n; indented by cargo fmt.\n; Because this multiline expression might be nested in an arbitrary number of\n; field expressions, this can only be matched using a Regex.\n(field_expression\n  value: (_) @val\n  \".\" @outdent\n  ; Check whether the first line ends with `(`, `{` or `[` (up to whitespace).\n  (#match? @val \"(\\\\A[^\\\\n\\\\r]+(\\\\(|\\\\{|\\\\[)[\\\\t ]*(\\\\n|\\\\r))\")\n)\n; Same as above, but with an additional `call_expression`. This is required since otherwise\n; the arguments of the function call won't be outdented.\n(call_expression\n  function: (field_expression\n    value: (_) @val\n    \".\" @outdent\n    (#match? @val \"(\\\\A[^\\\\n\\\\r]+(\\\\(|\\\\{|\\\\[)[\\\\t ]*(\\\\n|\\\\r))\")\n  )\n  arguments: (_) @outdent\n)\n\n\n; Indent if guards in patterns.\n; Since the tree-sitter grammar doesn't create a node for the if expression,\n; it's not possible to do this correctly in all cases. Indenting the tail of the\n; whole pattern whenever it contains an `if` only fails if the `if` appears after\n; the second line of the pattern (which should only rarely be the case)\n(match_pattern\n  .\n  (_) @expr-start\n  \"if\" @pattern-guard\n  (#not-same-line? @expr-start @pattern-guard)\n) @indent\n\n; Align closure parameters if they span more than one line\n(closure_parameters\n  \"|\"\n  .\n  (_) @anchor\n  (_) @expr-end\n  .\n  (#not-same-line? @anchor @expr-end)\n) @align\n\n(for_expression\n  \"in\" @in\n  .\n  (_) @indent\n  (#not-same-line? @in @indent)\n  (#set! \"scope\" \"all\")\n)\n  \n"
  },
  {
    "path": "runtime/queries/rust/injections.scm",
    "content": "([(line_comment !doc) (block_comment !doc)] @injection.content\n (#set! injection.language \"comment\"))\n\n((doc_comment) @injection.content\n (#set! injection.language \"markdown-rustdoc\")\n (#set! injection.combined))\n\n((macro_invocation\n  (token_tree) @injection.content)\n (#set! injection.language \"rust\")\n (#set! injection.include-children))\n\n((macro_rule\n  (token_tree) @injection.content)\n (#set! injection.language \"rust\")\n (#set! injection.include-children))\n\n((macro_invocation\n   macro:\n     [\n       (scoped_identifier\n         name: (_) @_macro_name)\n       (identifier) @_macro_name\n     ]\n   (token_tree) @injection.content)\n (#eq? @_macro_name \"html\")\n (#set! injection.language \"html\")\n (#set! injection.include-children))\n\n((macro_invocation\n   macro:\n     [\n       (scoped_identifier\n         name: (_) @_macro_name)\n       (identifier) @_macro_name\n     ]\n   (token_tree) @injection.content)\n (#eq? @_macro_name \"slint\")\n (#set! injection.language \"slint\")\n (#set! injection.include-children))\n\n((macro_invocation\n   macro:\n     [\n       (scoped_identifier name: (_) @_macro_name)\n       (identifier) @_macro_name\n     ]\n   (token_tree\n     (token_tree . \"{\" \"}\" .) @injection.content))\n (#eq? @_macro_name \"json\")\n (#set! injection.language \"json\")\n (#set! injection.include-children))\n\n(call_expression\n  function: (scoped_identifier\n    path: (identifier) @_regex (#any-of? @_regex \"Regex\" \"RegexBuilder\")\n    name: (identifier) @_new (#eq? @_new \"new\"))\n  arguments:\n    (arguments\n      [\n        (string_literal (string_content) @injection.content)\n        (raw_string_literal (string_content) @injection.content)\n      ])\n  (#set! injection.language \"regex\"))\n\n(call_expression\n  function: (scoped_identifier\n    path: (scoped_identifier (identifier) @_regex (#any-of? @_regex \"Regex\" \"RegexBuilder\") .)\n    name: (identifier) @_new (#eq? @_new \"new\"))\n  arguments:\n    (arguments\n      [\n        (string_literal (string_content) @injection.content)\n        (raw_string_literal (string_content) @injection.content)\n      ])\n  (#set! injection.language \"regex\"))\n\n; Highlight SQL in `sqlx::query!()`, `sqlx::query_scalar!()`, and `sqlx::query_scalar_unchecked!()`\n(macro_invocation\n  macro: (scoped_identifier\n    path: (identifier) @_sqlx (#eq? @_sqlx \"sqlx\")\n    name: (identifier) @_query (#match? @_query \"^query(_scalar|_scalar_unchecked)?$\"))\n  (token_tree\n    ; Only the first argument is SQL\n    .\n    [\n      (string_literal (string_content) @injection.content)\n      (raw_string_literal (string_content) @injection.content)\n    ]\n  )\n  (#set! injection.language \"sql\"))\n\n; Highlight SQL in `sqlx::query_as!()` and `sqlx::query_as_unchecked!()`\n(macro_invocation\n  macro: (scoped_identifier\n    path: (identifier) @_sqlx (#eq? @_sqlx \"sqlx\")\n    name: (identifier) @_query_as (#match? @_query_as \"^query_as(_unchecked)?$\"))\n  (token_tree\n    ; Only the second argument is SQL\n    .\n    ; Allow anything as the first argument in case the user has lower case type\n    ; names for some reason\n    (_)\n    [\n      (string_literal (string_content) @injection.content)\n      (raw_string_literal (string_content) @injection.content)\n    ]\n  )\n  (#set! injection.language \"sql\"))\n\n; Highlight SQL in `sqlx::query*` and `sqlx::raw_sql` functions\n(call_expression\n  function: (scoped_identifier\n    path: (identifier) @_sqlx\n    (#eq? @_sqlx \"sqlx\")\n    name: (identifier) @_query_function)\n  (#match? @_query_function \"^query.*|raw_sql$\")\n  arguments: (arguments\n    .\n    [\n      (string_literal\n        (string_content) @injection.content)\n      (raw_string_literal\n        (string_content) @injection.content)\n    ])\n  (#set! injection.language \"sql\"))\n\n; Special language `tree-sitter-rust-format-args` for Rust macros,\n; which use `format_args!` under the hood and therefore have\n; the `format_args!` syntax.\n;\n; This language is injected into a hard-coded set of macros.\n(\n  (macro_invocation\n    macro:\n      [\n        (scoped_identifier\n          name: (_) @_macro_name)\n        (identifier) @_macro_name\n      ]\n    (token_tree) @injection.content\n  )\n  (#any-of? @_macro_name\n    ; 1st argument is `format_args!`\n\n    ; std\n    \"print\" \"println\" \"eprint\" \"eprintln\"\n    \"format\" \"format_args\" \"todo\" \"panic\"\n    \"unreachable\" \"unimplemented\" \"compile_error\"\n    ; log\n    \"crit\" \"trace\" \"debug\" \"info\" \"warn\" \"error\"\n    ; anyhow\n    \"anyhow\" \"bail\"\n    ; syn\n    \"format_ident\"\n    ; indoc\n    \"formatdoc\" \"printdoc\" \"eprintdoc\" \"writedoc\"\n    ; iced\n    \"text\"\n    ; ratatui\n    \"span\"\n    ; eyre\n    \"eyre\"\n    ; miette\n    \"miette\"\n\n    ; 2nd argument is `format_args!`\n\n    ; std\n    \"write\" \"writeln\" \"assert\" \"debug_assert\"\n    ; defmt\n    \"expect\" \"unwrap\"\n    ; ratatui\n    \"span\"\n\n    ; 3rd argument is `format_args!`\n\n    ; std\n    \"assert_eq\" \"debug_assert_eq\" \"assert_ne\" \"debug_assert_ne\"\n\n    ; Dioxus's rsx! macro accepts string interpolation in all\n    ; strings, across the entire token tree\n    \"rsx\"\n  )\n  (#set! injection.language \"rust-format-args-macro\")\n  (#set! injection.include-children)\n)\n\n; for some queries (e.g. when you have generic table names) you need to wrap it in `AssertSqlSafe`\n; after `format!` so it can overwrite `format!` formatting correctly.\n(call_expression\n  function: [\n    (scoped_identifier\n      path: (identifier) @_sqlx\n      (#eq? @_sqlx \"sqlx\")\n      name: (identifier) @_AssertSqlSafe)\n    (identifier) @_AssertSqlSafe\n  ]\n  (#eq? @_AssertSqlSafe \"AssertSqlSafe\")\n  arguments: (arguments\n    [\n      (string_literal\n        (string_content) @injection.content)\n      (raw_string_literal\n        (string_content) @injection.content)\n      (macro_invocation\n        macro: (identifier) @_format\n        (#eq? @_format \"format\")\n        (token_tree\n          [\n            (string_literal\n              (string_content) @injection.content)\n            (raw_string_literal\n              (string_content) @injection.content)\n          ]))\n    ])\n  (#set! injection.language \"sql\"))\n"
  },
  {
    "path": "runtime/queries/rust/locals.scm",
    "content": "; Scopes\n\n[\n  (function_item)\n  (struct_item)\n  (enum_item)\n  (union_item)\n  (type_item)\n  (trait_item)\n  (impl_item)\n  (closure_expression)\n  (block)\n] @local.scope\n\n; Definitions\n\n(function_item\n  (parameters\n    (parameter\n      pattern: (identifier) @local.definition.variable.parameter)))\n\n(closure_parameters (identifier) @local.definition.variable.parameter)\n\n; Mutable variables\n\n(let_declaration\n  (mutable_specifier)\n  pattern: (identifier) @local.definition.variable.mutable)\n(mut_pattern\n  (mutable_specifier)\n  (identifier) @local.definition.variable.mutable)\n\n(parameter\n  (mutable_specifier)\n  pattern: (identifier) @local.definition.variable.parameter.mutable)\n\n(self_parameter\n  (mutable_specifier)\n  (self) @local.definition.variable.builtin.mutable)\n\n; References\n(self) @local.reference\n(identifier) @local.reference\n; lifetimes / labels\n(lifetime (identifier) @label)\n(label (identifier) @label)\n"
  },
  {
    "path": "runtime/queries/rust/rainbows.scm",
    "content": "[\n  ; {/}\n  (declaration_list)\n  (field_declaration_list)\n  (field_initializer_list)\n  (enum_variant_list)\n  (block)\n  (match_block)\n  (use_list)\n  (struct_pattern)\n\n  ; (/)\n  (ordered_field_declaration_list)\n  (arguments)\n  (parameters)\n  (tuple_type)\n  (tuple_expression)\n  (tuple_pattern)\n  (tuple_struct_pattern)\n  (unit_type)\n  (unit_expression)\n  (visibility_modifier)\n  (parenthesized_expression)\n  (token_repetition_pattern)\n\n  ; </>\n  (type_parameters)\n  (type_arguments)\n  (bracketed_type)\n  (for_lifetimes)\n\n  ; [/]\n  (array_type)\n  (array_expression)\n  (index_expression)\n  (slice_pattern)\n\n  ; attributes #[]\n  (attribute_item)\n  (inner_attribute_item)\n\n  ; macros\n  (token_tree_pattern)\n  (macro_definition)\n\n  ; closures\n  (closure_parameters)\n] @rainbow.scope\n\n; attributes like `#[serde(rename_all = \"kebab-case\")]`\n(attribute arguments: (token_tree) @rainbow.scope)\n\n[\n  \"#\"\n  \"[\" \"]\"\n  \"(\" \")\"\n  \"{\" \"}\"\n  \"<\" \">\"\n  \"|\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/rust/tags.scm",
    "content": "(struct_item\n  name: (type_identifier) @definition.struct)\n\n(const_item\n  name: (identifier) @definition.constant)\n\n(trait_item\n  name: (type_identifier) @definition.interface)\n\n(function_item\n  name: (identifier) @definition.function)\n\n(function_signature_item\n  name: (identifier) @definition.function)\n\n(enum_item\n  name: (type_identifier) @definition.enum)\n\n(enum_variant\n  name: (identifier) @definition.struct)\n\n(type_item\n  name: (type_identifier) @definition.type)\n\n(mod_item\n  name: (identifier) @definition.module)\n\n(macro_definition\n  name: (identifier) @definition.macro)\n"
  },
  {
    "path": "runtime/queries/rust/textobjects.scm",
    "content": "(function_item\n  body: (_) @function.inside) @function.around\n\n(closure_expression\n  body: (_) @function.inside) @function.around\n\n(struct_item\n  body: (_) @class.inside) @class.around\n\n(enum_item\n  body: (_) @class.inside) @class.around\n\n(union_item\n  body: (_) @class.inside) @class.around\n\n(trait_item\n  body: (_) @class.inside) @class.around\n\n(impl_item\n  body: (_) @class.inside) @class.around\n\n(parameters \n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(closure_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(field_initializer_list  \n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n[\n  (line_comment)\n  (block_comment)\n] @comment.inside\n\n(line_comment)+ @comment.around\n\n(block_comment) @comment.around\n\n(; #[test]\n (attribute_item\n   (attribute\n     (identifier) @_test_attribute))\n ; allow other attributes like #[should_panic] and comments\n [\n   (attribute_item)\n   (line_comment)\n ]*\n ; the test function\n (function_item\n   body: (_) @test.inside) @test.around\n (#eq? @_test_attribute \"test\"))\n\n(array_expression\n  (_) @entry.around)\n\n(tuple_expression\n  (_) @entry.around)\n\n(tuple_pattern\n  (_) @entry.around)\n\n; Commonly used vec macro initializer is special cased\n(macro_invocation\n  (identifier) @_id (token_tree (_) @entry.around)\n  (#eq? @_id \"vec\"))\n\n(enum_variant) @entry.around\n\n(field_declaration\n  (_) @entry.inside) @entry.around\n\n(field_initializer\n  (_) @entry.inside) @entry.around\n\n(shorthand_field_initializer) @entry.around\n"
  },
  {
    "path": "runtime/queries/rust-format-args/highlights.scm",
    "content": "; regular escapes like `\\n` are detected using another grammar\n; Here, we only detect `{{` and `}}` as escapes for `{` and `}`\n(escaped) @constant.character.escape\n\n[\n  \"#\"\n  (type)\n] @special\n\n[\n  (sign)\n  (fill)\n  (align)\n  (width)\n] @operator\n\n(number) @constant.numeric\n\n(colon) @punctuation\n\n(identifier) @variable\n\n; SCREAMING_CASE is assumed to be constant\n((identifier) @constant\n (#match? @constant \"^[A-Z_]+$\"))\n\n[\n  \"{\"\n  \"}\"\n] @punctuation.special\n"
  },
  {
    "path": "runtime/queries/rust-format-args-macro/highlights.scm",
    "content": "; inherits: rust\n"
  },
  {
    "path": "runtime/queries/rust-format-args-macro/indents.scm",
    "content": "; inherits: rust\n"
  },
  {
    "path": "runtime/queries/rust-format-args-macro/injections.scm",
    "content": "; inherits: rust\n\n; HACK: This language is the same as Rust but all strings are injected\n; with rust-format-args. Rust injects this into known macros which use\n; the format args syntax. This can cause false-positive highlights but\n; those are expected to be rare.\n\n([\n   (string_literal (string_content) @injection.content)\n   (raw_string_literal (string_content) @injection.content)\n ]\n (#set! injection.language \"rust-format-args\")\n (#set! injection.include-children))\n"
  },
  {
    "path": "runtime/queries/rust-format-args-macro/locals.scm",
    "content": "; inherits: rust\n"
  },
  {
    "path": "runtime/queries/rust-format-args-macro/rainbows.scm",
    "content": "; inherits: rust\n"
  },
  {
    "path": "runtime/queries/rust-format-args-macro/textobjects.scm",
    "content": "; inherits: rust\n"
  },
  {
    "path": "runtime/queries/sage/highlights.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/sage/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/sage/textobjects.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/scala/highlights.scm",
    "content": "; CREDITS @stumash (stuart.mashaal@gmail.com)\n\n;; variables\n\n(identifier) @variable\n\n(operator_identifier) @operator\n\n((identifier) @variable.builtin\n (#match? @variable.builtin \"^this$\"))\n\n(interpolation) @none\n\n; Assume other uppercase names constants.\n; NOTE: In order to distinguish constants we highlight\n; all the identifiers that are uppercased. But this solution\n; is not suitable for all occurrences e.g. it will highlight\n; an uppercased method as a constant if used with no params.\n; Introducing highlighting for those specific cases, is probably\n; best way to resolve the issue.\n((identifier) @constant (#match? @constant \"^[A-Z]\"))\n\n;; types\n\n(type_identifier) @type\n\n(class_definition\n  name: (identifier) @type)\n\n(object_definition\n  name: (identifier) @type)\n\n(trait_definition\n  name: (identifier) @type)\n\n(type_definition\n  name: (type_identifier) @type)\n\n(full_enum_case\n  name: (identifier) @type)\n\n(simple_enum_case\n  name: (identifier) @type)\n\n;; val/var definitions/declarations\n\n(val_definition\n  pattern: (identifier) @variable)\n\n(var_definition\n  pattern: (identifier) @variable)\n\n(val_declaration\n  name: (identifier) @variable)\n\n(var_declaration\n  name: (identifier) @variable)\n\n; function definitions/declarations\n\n(function_declaration\n    name: (identifier) @function.method)\n\n(function_definition\n      name: (identifier) @function.method)\n\n; imports/exports\n\n(import_declaration\n  path: (identifier) @namespace)\n((stable_identifier (identifier) @namespace))\n\n((import_declaration\n  path: (identifier) @type) (#match? @type \"^[A-Z]\"))\n((stable_identifier (identifier) @type) (#match? @type \"^[A-Z]\"))\n\n(export_declaration\n  path: (identifier) @namespace)\n((stable_identifier (identifier) @namespace))\n\n((export_declaration\n  path: (identifier) @type) (#match? @type \"^[A-Z]\"))\n((stable_identifier (identifier) @type) (#match? @type \"^[A-Z]\"))\n\n((namespace_selectors (identifier) @type) (#match? @type \"^[A-Z]\"))\n\n; method invocation\n\n\n(call_expression\n  function: (identifier) @function)\n\n(call_expression\n  function: (operator_identifier) @function)\n\n(call_expression\n  function: (field_expression\n    field: (identifier) @function.method))\n\n(call_expression\n  function: (field_expression\n    field: (operator_identifier) @function.method))\n\n((call_expression\n   function: (identifier) @variable.other.member)\n (#match? @variable.other.member \"^[A-Z]\"))\n\n(generic_function\n  function: (identifier) @function)\n\n(interpolated_string_expression\n  interpolator: (identifier) @function)\n\n(\n  (identifier) @function.builtin\n  (#match? @function.builtin \"^super$\")\n)\n\n; function definitions\n\n(function_definition\n  name: (identifier) @function)\n\n(function_definition\n  name: (operator_identifier) @function)\n\n(parameter\n  name: (identifier) @variable.parameter)\n\n(binding\n  name: (identifier) @variable.parameter)\n\n; expressions\n\n\n(field_expression field: (identifier) @variable.other.member)\n(field_expression value: (identifier) @type\n (#match? @type \"^[A-Z]\"))\n\n(infix_expression operator: (identifier) @operator)\n(infix_expression operator: (operator_identifier) @operator)\n(infix_type operator: (operator_identifier) @operator)\n(infix_type operator: (operator_identifier) @operator)\n\n; literals\n(boolean_literal) @constant.builtin.boolean\n(integer_literal) @constant.numeric.integer\n(floating_point_literal) @constant.numeric.float\n\n[\n(string)\n(character_literal)\n(interpolated_string_expression)\n] @string\n\n(interpolation \"$\" @punctuation.special)\n\n; annotations\n\n(annotation) @attribute\n\n;; keywords\n\n;; storage in TextMate scope lingo means field or type\n[\n  (opaque_modifier)\n  (infix_modifier)\n  (transparent_modifier)\n  (open_modifier)\n  \"abstract\"\n  \"final\"\n  \"implicit\"\n  \"lazy\"\n  \"override\"\n  \"private\"\n  \"protected\"\n  \"sealed\"\n] @keyword.storage.modifier\n\n[\n  \"class\"\n  \"enum\"\n  \"extension\"\n  \"given\"\n  \"object\"\n  \"package\"\n  \"trait\"\n  \"type\"\n  \"val\"\n  \"var\"\n] @keyword.storage.type\n\n[\n  \"as\"\n  \"derives\"\n  \"end\"\n  \"extends\"\n;; `forSome` existential types not implemented yet\n;; `macro` not implemented yet\n;; `throws`\n  \"using\"\n  \"with\"\n] @keyword\n\n(null_literal) @constant.builtin\n(wildcard) @keyword\n\n;; special keywords\n\n\"new\" @keyword.operator\n\n[\n  \"case\"\n  \"catch\"\n  \"else\"\n  \"finally\"\n  \"if\"\n  \"match\"\n  \"then\"\n  \"throw\"\n  \"try\"\n] @keyword.control.conditional\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"do\"\n  \"for\"\n  \"while\"\n  \"yield\"\n] @keyword.control.repeat\n\n\"def\" @keyword.function\n\n[\n  \"=>\"\n  \"<-\"\n  \"@\"\n] @keyword.operator\n\n\"import\" @keyword.control.import\n\n\"export\" @keyword.control.import\n\n\"return\" @keyword.control.return\n\n[(comment) (block_comment)] @comment\n\n;; `case` is a conditional keyword in case_block\n\n(case_block\n  (case_clause (\"case\") @keyword.control.conditional))\n"
  },
  {
    "path": "runtime/queries/scala/indents.scm",
    "content": "[\n  (block)\n  (arguments)\n  (parameter)\n  (class_definition)\n  (trait_definition)\n  (object_definition)\n  (function_definition)\n  (val_definition)\n  (import_declaration)\n  (while_expression)\n  (do_while_expression)\n  (for_expression)\n  (try_expression)\n  (match_expression)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/scala/injections.scm",
    "content": "([(comment) (block_comment)] @injection.content\n (#set! injection.language \"comment\"))\n\n\n; Matches these SQL interpolators:\n;  - Doobie: 'sql', 'fr'\n;  - Quill: 'sql', 'infix'\n;  - Slick: 'sql', 'sqlu'\n(interpolated_string_expression \n  interpolator: \n    ((identifier) @interpolator \n     (#any-of? @interpolator \"fr\" \"infix\" \"sql\" \"sqlu\"))\n  (interpolated_string) @injection.content\n  (#set! injection.language \"sql\"))\n\n"
  },
  {
    "path": "runtime/queries/scala/locals.scm",
    "content": "(template_body) @local.scope\n(lambda_expression) @local.scope\n\n\n(function_declaration\n      name: (identifier) @local.definition.function) @local.scope\n\n(function_definition\n      name: (identifier) @local.definition.function)\n\n(parameter\n  name: (identifier) @local.definition.variable.parameter)\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/scala/textobjects.scm",
    "content": "; Function queries\n\n(function_definition\n  body: (_) @function.inside) @function.around ; Does not include end marker\n\n(lambda_expression\n  (_) @function.inside) @function.around\n\n; Scala 3 braceless lambda\n(colon_argument\n  (_) @function.inside) @function.around\n\n\n; Class queries\n\n(object_definition\n  body: (_)? @class.inside) @class.around\n\n(class_definition\n  body: (_)? @class.inside) @class.around\n\n(trait_definition\n  body: (_)? @class.inside) @class.around\n\n(type_definition) @class.around\n\n(enum_case_definitions) @class.around\n\n(enum_definition\n  body: (_)? @class.inside) @class.around\n\n\n; Parameter queries\n\n(parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(class_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(parameter_types\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(bindings\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n; Does not match context bounds or higher-kinded types\n(type_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n\n; Comment queries\n\n[(comment) (block_comment)] @comment.inside\n[(comment) (block_comment)] @comment.around ; Does not match consecutive block comments\n\n\n; Test queries\n; Not supported\n"
  },
  {
    "path": "runtime/queries/scfg/highlights.scm",
    "content": "[\n \"{\"\n \"}\"\n ] @punctuation.bracket\n\n\n(comment) @comment\n(directive_name) @type\n(directive_params) @parameter\n"
  },
  {
    "path": "runtime/queries/scheme/highlights.scm",
    "content": "(number) @constant.numeric\n(character) @constant.character\n(boolean) @constant.builtin.boolean\n\n(string) @string\n\n(escape_sequence) @constant.character.escape\n\n(comment) @comment.line\n(block_comment) @comment.block\n(directive) @keyword.directive\n\n; variables\n\n((symbol) @variable.builtin\n  (#eq? @variable.builtin \"...\"))\n\n((symbol) @variable.builtin\n  (#eq? @variable.builtin \".\"))\n\n(symbol) @variable\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n\n(quote \"'\") @operator\n(unquote_splicing \",@\") @operator\n(unquote \",\") @operator\n(quasiquote \"`\") @operator\n\n; procedure\n\n(list\n  .\n  (symbol) @function)\n\n(list\n  .\n  (symbol) @function.builtin\n  (#any-of? @function.builtin\n    \"caar\" \"cadr\" \"call-with-input-file\" \"call-with-output-file\" \"cdar\" \"cddr\" \"list\"\n    \"open-input-file\" \"open-output-file\" \"with-input-from-file\" \"with-output-to-file\" \"*\" \"+\" \"-\"\n    \"/\" \"<\" \"<=\" \"=\" \">\" \">=\" \"abs\" \"acos\" \"angle\" \"append\" \"apply\" \"asin\" \"assoc\" \"assq\" \"assv\"\n    \"atan\" \"boolean?\" \"caaaar\" \"caaadr\" \"caaar\" \"caadar\" \"caaddr\" \"caadr\" \"cadaar\" \"cadadr\" \"cadar\"\n    \"caddar\" \"cadddr\" \"caddr\" \"call-with-current-continuation\" \"call-with-values\" \"car\" \"cdaaar\"\n    \"cdaadr\" \"cdaar\" \"cdadar\" \"cdaddr\" \"cdadr\" \"cddaar\" \"cddadr\" \"cddar\" \"cdddar\" \"cddddr\" \"cdddr\"\n    \"cdr\" \"ceiling\" \"char->integer\" \"char-alphabetic?\" \"char-ci<=?\" \"char-ci<?\" \"char-ci=?\"\n    \"char-ci>=?\" \"char-ci>?\" \"char-downcase\" \"char-lower-case?\" \"char-numeric?\" \"char-ready?\"\n    \"char-upcase\" \"char-upper-case?\" \"char-whitespace?\" \"char<=?\" \"char<?\" \"char=?\" \"char>=?\"\n    \"char>?\" \"char?\" \"close-input-port\" \"close-output-port\" \"complex?\" \"cons\" \"cos\"\n    \"current-error-port\" \"current-input-port\" \"current-output-port\" \"denominator\" \"display\"\n    \"dynamic-wind\" \"eof-object?\" \"eq?\" \"equal?\" \"eqv?\" \"eval\" \"even?\" \"exact->inexact\" \"exact?\" \"exp\"\n    \"expt\" \"floor\" \"flush-output\" \"for-each\" \"force\" \"gcd\" \"imag-part\" \"inexact->exact\" \"inexact?\"\n    \"input-port?\" \"integer->char\" \"integer?\" \"interaction-environment\" \"lcm\" \"length\" \"list->string\"\n    \"list->vector\" \"list-ref\" \"list-tail\" \"list?\" \"load\" \"log\" \"magnitude\" \"make-polar\"\n    \"make-rectangular\" \"make-string\" \"make-vector\" \"map\" \"max\" \"member\" \"memq\" \"memv\" \"min\" \"modulo\"\n    \"negative?\" \"newline\" \"not\" \"null-environment\" \"null?\" \"number->string\" \"number?\" \"numerator\"\n    \"odd?\" \"output-port?\" \"pair?\" \"peek-char\" \"positive?\" \"procedure?\" \"quotient\" \"rational?\"\n    \"rationalize\" \"read\" \"read-char\" \"real-part\" \"real?\" \"remainder\" \"reverse\" \"round\"\n    \"scheme-report-environment\" \"set-car!\" \"set-cdr!\" \"sin\" \"sqrt\" \"string\" \"string->list\"\n    \"string->number\" \"string->symbol\" \"string-append\" \"string-ci<=?\" \"string-ci<?\" \"string-ci=?\"\n    \"string-ci>=?\" \"string-ci>?\" \"string-copy\" \"string-fill!\" \"string-length\" \"string-ref\"\n    \"string-set!\" \"string<=?\" \"string<?\" \"string=?\" \"string>=?\" \"string>?\" \"string?\" \"substring\"\n    \"symbol->string\" \"symbol?\" \"tan\" \"transcript-off\" \"transcript-on\" \"truncate\" \"values\" \"vector\"\n    \"vector->list\" \"vector-fill!\" \"vector-length\" \"vector-ref\" \"vector-set!\" \"vector?\" \"write\"\n    \"write-char\" \"zero?\"))\n\n; special forms\n\n(list\n  \"[\"\n  (symbol)+ @variable\n  \"]\")\n\n(list\n  .\n  (symbol) @_f\n  .\n  (list\n    (symbol) @variable)\n  (#any-of? @_f \"lambda\" \"λ\" \"define-values\"))\n\n(list\n  .\n  (symbol) @_f\n  (list\n    .\n    (list\n      (symbol) @variable))\n  (#eq? @_f \"case-lambda\"))\n\n(list\n  .\n  (symbol) @_f\n  .\n  (list\n    (list\n      (symbol) @variable.parameter))\n  (#any-of? @_f\n    \"let\" \"let*\" \"let-syntax\" \"let-values\" \"let*-values\" \"letrec\" \"letrec*\" \"letrec-syntax\" \"do\"))\n\n; operators\n\n((symbol) @operator\n  (#any-of? @operator \"+\" \"-\" \"*\" \"/\" \"=\" \">\" \"<\" \">=\" \"<=\"))\n\n; library\n\n(list\n  .\n  (symbol) @_lib\n  .\n  (symbol) @namespace\n\n  (#eq? @_lib \"library\"))\n\n; quote\n\n(list\n  .\n  (symbol) @_f\n  (#eq? @_f \"quote\")) @string.symbol\n\n; keywords\n\n(list\n  .\n  ((symbol) @keyword.conditional\n   (#any-of? @keyword.conditional \"if\" \"cond\" \"case\" \"when\" \"unless\")))\n\n(list\n  .\n  (symbol) @keyword\n  (#any-of? @keyword\n    \"define-syntax\" \"let*\" \"lambda\" \"λ\" \"case-lambda\" \"case\" \"=>\" \"quote-splicing\" \"unquote-splicing\"\n    \"set!\" \"let\" \"letrec\" \"letrec-syntax\" \"let-values\" \"let*-values\" \"do\" \"else\" \"define\" \"cond\"\n    \"syntax-rules\" \"unquote\" \"begin\" \"quote\" \"let-syntax\" \"and\" \"if\" \"quasiquote\" \"letrec\" \"delay\"\n    \"or\" \"when\" \"unless\" \"identifier-syntax\" \"assert\" \"library\" \"export\" \"import\" \"rename\" \"only\"\n    \"except\" \"prefix\" \"define-values\"))\n"
  },
  {
    "path": "runtime/queries/scheme/indents.scm",
    "content": "; This roughly follows the description at: https://github.com/ds26gte/scmindent#how-subforms-are-indented\n\n; Exclude literals in the first patterns, since different rules apply for them.\n; Similarly, exclude certain keywords (detected by a regular expression).\n; If a list has 2 elements on the first line, it is aligned to the second element.\n(list . (_) @first . (_) @anchor\n  (#same-line? @first @anchor)\n  (#set! \"scope\" \"tail\")\n  (#not-kind-eq? @first \"boolean\") (#not-kind-eq? @first \"character\") (#not-kind-eq? @first \"string\") (#not-kind-eq? @first \"number\")\n  (#not-match? @first \"def.*|let.*|set!\")) @align\n; If the first element in a list is also a list and on a line by itself, the outer list is aligned to it\n(list . (list) @anchor .\n  (#set! \"scope\" \"tail\")\n  (#not-kind-eq? @first \"boolean\") (#not-kind-eq? @first \"character\") (#not-kind-eq? @first \"string\") (#not-kind-eq? @first \"number\")) @align\n(list . (list) @anchor . (_) @second\n  (#not-same-line? @anchor @second)\n  (#set! \"scope\" \"tail\")\n  (#not-kind-eq? @first \"boolean\") (#not-kind-eq? @first \"character\") (#not-kind-eq? @first \"string\") (#not-kind-eq? @first \"number\")\n  (#not-match? @first \"def.*|let.*|set!\")) @align\n; If the first element in a list is not a list and on a line by itself, the outer list is aligned to\n; it plus 1 additional space. This cannot currently be modelled exactly by our indent queries,\n; but the following is equivalent, assuming that:\n; - the indent width is 2 (the default for scheme)\n; - There is no space between the opening parenthesis of the list and the first element\n(list . (_) @first .\n  (#not-kind-eq? @first \"boolean\") (#not-kind-eq? @first \"character\") (#not-kind-eq? @first \"string\") (#not-kind-eq? @first \"number\")\n  (#not-match? @first \"def.*|let.*|set!\")) @indent\n(list . (_) @first . (_) @second\n  (#not-same-line? @first @second)\n  (#not-kind-eq? @first \"boolean\") (#not-kind-eq? @first \"character\") (#not-kind-eq? @first \"string\") (#not-kind-eq? @first \"number\")\n  (#not-match? @first \"def.*|let.*|set!\")) @indent\n\n; If the first element in a list is a literal, align the list to it\n(list . [(boolean) (character) (string) (number)] @anchor\n  (#set! \"scope\" \"tail\")) @align\n\n; If the first element is among a set of predefined keywords, align the list to this element\n; plus 1 space (using the same workaround as above for now). This is a simplification since actually\n; the second line of the list should be indented by 2 spaces more in some cases. Supporting this would\n; be possible but require significantly more patterns.\n(list . (symbol) @first\n  (#match? @first \"def.*|let.*|set!\")) @indent\n\n"
  },
  {
    "path": "runtime/queries/scheme/injections.scm",
    "content": "([(comment) (block_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/scheme/rainbows.scm",
    "content": "[\n  (list)\n  (vector)\n  (byte_vector)\n] @rainbow.scope\n\n[\n  \"#(\" \"#vu8(\"\n  \"(\" \")\"\n  \"[\" \"]\"\n  \"{\" \"}\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/scheme/tags.scm",
    "content": "; function definitions\n(list\n  .\n  (symbol) @_define\n  .\n  (list\n    .\n    [\n      (symbol) @name\n      ; for curried functions\n      (list . (symbol) @name)\n      (list . (list . [(symbol) (list)] @name))\n    ])\n  (#eq? @_define \"define\")) @definition.function\n\n(list\n  .\n  (symbol) @_define\n  .\n  (symbol) @name\n  (#eq? @_define \"define\")) @definition.constant\n"
  },
  {
    "path": "runtime/queries/scheme/textobjects.scm",
    "content": "[\n  (comment)\n  (block_comment)\n] @comment.inside\n\n(comment)+ @comment.around\n(block_comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/scss/highlights.scm",
    "content": "[(comment) (single_line_comment)] @comment\n\n[\n \"~\"\n \">\"\n \"+\"\n \"-\"\n \"*\"\n \"/\"\n \"=\"\n \"^=\"\n \"|=\"\n \"~=\"\n \"$=\"\n \"*=\"\n] @operator\n\n[\n  \"in\"\n  \"and\"\n  \"or\"\n  \"not\"\n  \"only\"\n] @operator.control\n\n[\n  \"@apply\"\n  \"@at-root\"\n  \"@charset\"\n  \"@debug\"\n  \"@error\"\n  \"@extend\"\n  \"@keyframes\"\n  \"@media\"\n  \"@mixin\"\n  \"@supports\"\n  \"@warn\"\n] @constant.builtin\n\n[\n  \"@import\"\n  \"@include\"\n  \"@forward\"\n  \"@use\"\n] @keyword.control.import\n\n[\n  \"@if\"\n  \"@else\"\n] @keyword.control.conditional\n\n[\n  \"@each\"\n  \"@for\"\n  \"@while\"\n] @keyword.control.repeat\n\n\"@return\" @keyword.control.return\n\n\"@function\" @function.method\n\"@namespace\" @namespace\n\n(property_name) @variable.other.member\n\n((property_name) @variable\n (#match? @variable \"^--\"))\n((plain_value) @variable\n (#match? @variable \"^--\"))\n\n(tag_name) @tag\n(universal_selector) @tag\n(attribute_selector (plain_value) @string)\n(nesting_selector) @variable.other.member\n(pseudo_element_selector) @attribute\n(pseudo_class_selector) @attribute\n\n(identifier) @variable\n(class_name) @label\n(id_name) @label\n(namespace_name) @namespace\n\n(feature_name) @variable.other.member\n(variable) @variable\n(variable_name) @variable.other.member\n(variable_value) @variable.other.member\n(argument_name) @variable.parameter\n(selectors) @variable.other.member\n\n(attribute_name) @attribute\n\n(function_name) @function\n\n(to) @keyword\n(from) @keyword\n(important) @keyword\n\n(string_value) @string\n(color_value) @string.special\n\n(integer_value) @constant.numeric.integer\n(float_value) @constant.numeric.float\n(unit) @type\n\n\"#\" @punctuation.delimiter\n\",\" @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/scss/injections.scm",
    "content": "([(comment) (single_line_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/scss/rainbows.scm",
    "content": "; inherits: css\n\n(parameters) @rainbow.scope\n"
  },
  {
    "path": "runtime/queries/shellcheckrc/highlights.scm",
    "content": "(comment) @comment\n(string) @string\n(boolean) @constant.builtin.boolean\n(integer) @constant.numeric.integer\n\n[\n  \"disable\"\n  \"enable\"\n  \"extended-analysis\"\n  \"external-sources\"\n  \"source\"\n  \"source-path\"\n  \"shell\"\n] @keyword\n\n\"=\" @operator\n\n[\n  \",\"\n  \"-\"\n] @punctuation.delimiter\n\n\"SC\" @special\n\n(shell) @type.enum.variant\n\n(all) @variable.builtin\n\n(identifier) @label\n\n(source_directive\n  (identifier) @string.special.path)\n\n(source_path_directive\n  (identifier) @string.special.path)\n\n(source_directive\n  (identifier) @variable.builtin (#eq? @variable.builtin \"SCRIPTDIR\"))\n\n(source_path_directive\n  (identifier) @variable.builtin (#eq? @variable.builtin \"SCRIPTDIR\"))\n\n(enable_directive\n  (identifier) @diagnostic.error\n  (#not-any-of? @diagnostic.error\n    \"add-default-case\"\n    \"avoid-nullary-conditions\"\n    \"check-extra-masked-returns\"\n    \"check-set-e-suppressed\"\n    \"check-unassigned-uppercase\"\n    \"deprecate-which\"\n    \"quote-safe-variables\"\n    \"require-double-brackets\"\n    \"require-variable-braces\"\n  ))\n"
  },
  {
    "path": "runtime/queries/shellcheckrc/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/shellcheckrc/textobjects.scm",
    "content": "(comment) @comment.inside\n(comment)+ @comment.around\n\n\n[\n  (disable_directive)\n  (enable_directive)\n  (extended_analysis_directive)\n  (external_sources_directive)\n  (source_directive)\n  (source_path_directive)\n  (shell_directive)\n] @entry.around\n"
  },
  {
    "path": "runtime/queries/slang/highlights.scm",
    "content": "; inherits: c\n\n; cpp\n((identifier) @variable.other.member\n  (#match? @variable.other.member \"^m_.*$\"))\n\n(parameter_declaration\n  declarator: (reference_declarator) @variable.parameter)\n\n; function(Foo ...foo)\n(variadic_parameter_declaration\n  declarator: (variadic_declarator\n    (_) @variable.parameter))\n\n; int foo = 0\n(optional_parameter_declaration\n  declarator: (_) @variable.parameter)\n\n(field_declaration\n  (field_identifier) @variable.other.member)\n\n(field_initializer\n  (field_identifier) @variable.other.member)\n\n(function_declarator\n  declarator: (field_identifier) @function.method)\n\n(concept_definition\n  name: (identifier) @type)\n\n(alias_declaration\n  name: (type_identifier) @type)\n\n(namespace_identifier) @namespace\n\n((namespace_identifier) @type\n  (#match? @type \"^[%u]\"))\n\n(case_statement\n  value: (qualified_identifier\n    (identifier) @constant))\n\n(using_declaration\n  .\n  \"using\"\n  .\n  \"namespace\"\n  .\n  [\n    (qualified_identifier)\n    (identifier)\n  ] @namespace)\n\n(destructor_name\n  (identifier) @function.method)\n\n; functions\n(function_declarator\n  (qualified_identifier\n    (identifier) @function))\n\n(function_declarator\n  (qualified_identifier\n    (qualified_identifier\n      (identifier) @function)))\n\n(function_declarator\n  (qualified_identifier\n    (qualified_identifier\n      (qualified_identifier\n        (identifier) @function))))\n\n(function_declarator\n  (template_function\n    (identifier) @function))\n\n(operator_name) @function\n\n\"operator\" @function\n\n\"static_assert\" @function.builtin\n\n\n(call_expression\n  (qualified_identifier\n    (identifier) @function))\n\n\n(call_expression\n  (qualified_identifier\n    (qualified_identifier\n      (identifier) @function)))\n\n(call_expression\n  (qualified_identifier\n    (qualified_identifier\n      (qualified_identifier\n        (identifier) @function))))\n\n(call_expression\n  (template_function\n    (identifier) @function))\n\n(call_expression\n  (qualified_identifier\n    (template_function\n      (identifier) @function)))\n\n(call_expression\n  (qualified_identifier\n    (qualified_identifier\n      (template_function\n        (identifier) @function))))\n\n(call_expression\n  (qualified_identifier\n    (qualified_identifier\n      (qualified_identifier\n        (template_function\n          (identifier) @function)))))\n\n; methods\n(function_declarator\n  (template_method\n    (field_identifier) @function.method))\n\n(call_expression\n  (field_expression\n    (field_identifier) @function.method))\n\n; constructors\n((function_declarator\n  (qualified_identifier\n    (identifier) @constructor))\n  (#match? @constructor \"^%u\"))\n\n((call_expression\n  function: (identifier) @constructor)\n  (#match? @constructor \"^%u\"))\n\n((call_expression\n  function: (qualified_identifier\n    name: (identifier) @constructor))\n  (#match? @constructor \"^%u\"))\n\n((call_expression\n  function: (field_expression\n    field: (field_identifier) @constructor))\n  (#match? @constructor \"^%u\"))\n\n; constructing a type in an initializer list: Constructor ():  **SuperType (1)**\n((field_initializer\n  (field_identifier) @constructor\n  (argument_list))\n  (#match? @constructor \"^%u\"))\n\n; Constants\n(this) @variable.builtin\n\n(null\n  \"nullptr\" @constant.builtin)\n\n(true) @constant.builtin.boolean\n\n(false) @constant.builtin.boolean\n\n; Literals\n(raw_string_literal) @string\n\n; Keywords\n[\n  \"try\"\n  \"catch\"\n  \"noexcept\"\n  \"throw\"\n] @keyword.control.exception\n\n[\n  \"decltype\"\n  \"explicit\"\n  \"friend\"\n  \"override\"\n  \"using\"\n  \"requires\"\n  \"constexpr\"\n] @keyword\n\n[\n  \"class\"\n  \"namespace\"\n  \"template\"\n  \"typename\"\n  \"concept\"\n] @keyword.storage.type\n\n[\n  \"co_await\"\n  \"co_yield\"\n  \"co_return\"\n] @keyword\n\n[\n  \"public\"\n  \"private\"\n  \"protected\"\n  \"final\"\n  \"virtual\"\n] @keyword.storage.modifier\n\n[\n  \"new\"\n  \"delete\"\n  \"xor\"\n  \"bitand\"\n  \"bitor\"\n  \"compl\"\n  \"not\"\n  \"xor_eq\"\n  \"and_eq\"\n  \"or_eq\"\n  \"not_eq\"\n  \"and\"\n  \"or\"\n] @keyword.operator\n\n\"<=>\" @operator\n\n\"::\" @punctuation.delimiter\n\n(template_argument_list\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n(template_parameter_list\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n(literal_suffix) @operator\n\n; hlsl\n[\n  \"in\"\n  \"out\"\n  \"inout\"\n  \"uniform\"\n  \"shared\"\n  \"groupshared\"\n  \"discard\"\n  \"cbuffer\"\n  \"row_major\"\n  \"column_major\"\n  \"globallycoherent\"\n  \"centroid\"\n  \"noperspective\"\n  \"nointerpolation\"\n  \"sample\"\n  \"linear\"\n  \"snorm\"\n  \"unorm\"\n  \"point\"\n  \"line\"\n  \"triangleadj\"\n  \"lineadj\"\n  \"triangle\"\n] @keyword\n\n((identifier) @variable.builtin\n  (#match? @variable.builtin \"^SV_\"))\n; ((identifier) @variable)\n\n(hlsl_attribute) @attribute\n\n(hlsl_attribute\n  [\n    \"[\"\n    \"]\"\n  ] @attribute)\n\n\"This\" @type.builtin\n\n[\n  \"interface\"\n  \"extension\"\n  \"property\"\n  \"associatedtype\"\n  \"where\"\n\t\"var\"\n\t\"let\"\n] @keyword\n\n\"__init\" @constructor\n\n[\n  \"__subscript\"\n  \"get\"\n  \"set\"\n] @function.builtin\n\n(call_expression) @function\n\n(call_expression (identifier)) @function\n\n((call_expression\n  function: (identifier) @function.builtin)\n  (#any-of? @function.builtin\n\t\t\"frac\" \"abs\" \"acos\" \"acosh\" \"asin\" \"asinh\" \"atan\" \"atanh\" \"cos\" \"cosh\" \"exp\" \"exp2\" \"floor\" \"log\" \"log10\" \"log2\" \"round\" \"rsqrt\" \"sin\" \"sincos\" \"sinh\" \"sqrt\" \"tan\" \"tanh\" \"trunc\"\n\t\t\"AllMemoryBarrier\" \"AllMemoryBarrierWithGroupSync\" \"DeviceMemoryBarrier\" \"DeviceMemoryBarrierWithGroupSync\" \"GroupMemoryBarrier\" \"GroupMemoryBarrierWithGroupSync\"\n\t\t\"abort\" \"clip\" \"errorf\" \"printf\"\n\t\t\"all\" \"any\" \"countbits\" \"faceforward\" \"firstbithigh\" \"firstbitlow\" \"isfinite\" \"isinf\" \"isnan\" \"max\" \"min\" \"noise\" \"pow\" \"reversebits\" \"sign\"\n\t\t\"asdouble\" \"asfloat\" \"asint\" \"asuint\" \"D3DCOLORtoUBYTE4\" \"f16tof32\" \"f32tof16\"\n\t\t\"ceil\" \"clamp\" \"degrees\" \"fma\" \"fmod\" \"frac\" \"frexp\" \"ldexp\" \"lerp\" \"mad\" \"modf\" \"radiants\" \"saturate\" \"smoothstep\" \"step\"\n\t\t\"cross\" \"determinant\" \"distance\" \"dot\" \"dst\" \"length\" \"lit\" \"msad4\" \"mul\" \"normalize\" \"rcp\" \"reflect\" \"refract\" \"transpose\"\n\t\t\"ddx\" \"ddx_coarse\" \"ddx_fine\" \"ddy\" \"ddy_coarse\" \"ddy_fine\" \"fwidth\"\n\t\t\"EvaluateAttributeAtCentroid\" \"EvaluateAttributeAtSample\" \"EvaluateAttributeSnapped\"\n\t\t\"GetRenderTargetSampleCount\" \"GetRenderTargetSamplePosition\"\n\t\t\"InterlockedAdd\" \"InterlockedAnd\" \"InterlockedCompareExchange\" \"InterlockedCompareStore\" \"InterlockedExchange\" \"InterlockedMax\" \"InterlockedMin\" \"InterlockedOr\" \"InterlockedXor\"\n\t\t\"InterlockedCompareStoreFloatBitwise\" \"InterlockedCompareExchangeFloatBitwise\"\n\t\t\"Process2DQuadTessFactorsAvg\" \"Process2DQuadTessFactorsMax\" \"Process2DQuadTessFactorsMin\" \"ProcessIsolineTessFactors\"\n\t\t\"ProcessQuadTessFactorsAvg\" \"ProcessQuadTessFactorsMax\" \"ProcessQuadTessFactorsMin\" \"ProcessTriTessFactorsAvg\" \"ProcessTriTessFactorsMax\" \"ProcessTriTessFactorsMin\"\n\t\t\"tex1D\" \"tex1Dbias\" \"tex1Dgrad\" \"tex1Dlod\" \"tex1Dproj\"\n\t\t\"tex2D\" \"tex2Dbias\" \"tex2Dgrad\" \"tex2Dlod\" \"tex2Dproj\"\n\t\t\"tex3D\" \"tex3Dbias\" \"tex3Dgrad\" \"tex3Dlod\" \"tex3Dproj\"\n\t\t\"texCUBE\" \"texCUBEbias\" \"texCUBEgrad\" \"texCUBElod\" \"texCUBEproj\"\n\t\t\"WaveIsFirstLane\" \"WaveGetLaneCount\" \"WaveGetLaneIndex\"\n\t\t\"IsHelperLane\"\n\t\t\"WaveActiveAnyTrue\" \"WaveActiveAllTrue\" \"WaveActiveBallot\"\n\t\t\"WaveReadLaneFirst\" \"WaveReadLaneAt\"\n\t\t\"WaveActiveAllEqual\" \"WaveActiveAllEqualBool\" \"WaveActiveCountBits\"\n\t\t\"WaveActiveSum\" \"WaveActiveProduct\" \"WaveActiveBitAnd\" \"WaveActiveBitOr\" \"WaveActiveBitXor\" \"WaveActiveMin\" \"WaveActiveMax\"\n\t\t\"WavePrefixCountBits\" \"WavePrefixProduct\" \"WavePrefixSum\"\n\t\t\"QuadReadAcrossX\" \"QuadReadAcrossY\" \"QuadReadAcrossDiagonal\" \"QuadReadLaneAt\"\n\t\t\"QuadAny\" \"QuadAll\"\n\t\t\"WaveMatch\" \"WaveMultiPrefixSum\" \"WaveMultiPrefixProduct\" \"WaveMultiPrefixCountBits\" \"WaveMultiPrefixAnd\" \"WaveMultiPrefixOr\" \"WaveMultiPrefixXor\"\n\t\t\"NonUniformResourceIndex\"\n\t\t\"DispatchMesh\" \"SetMeshOutputCounts\"\n\t\t\"dot4add_u8packed\" \"dot4add_i8packed\" \"dot2add\"\n\t\t\"RestartStrip\"\n\t\t\"CalculateLevelOfDetail\" \"CalculateLevelOfDetailUnclamped\" \"Gather\" \"GetDimensions\" \"GetSamplePosition\" \"Load\" \"Sample\" \"SampleBias\" \"SampleCmp\" \"SampleCmpLevelZero\" \"SampleGrad\" \"SampleLevel\" \"GatherRaw\" \"SampleCmpLevel\"\n\t\t\"SampleCmpBias\" \"SampleCmpGrad\"\n\t\t\"WriteSamplerFeedback\" \"WriteSamplerFeedbackBias\" \"WriteSamplerFeedbackGrad\" \"WriteSamplerFeedbackLevel\"\n\t\t\"Append\" \"Consume\" \"DecrementCounter\" \"IncrementCounter\"\n\t\t\"Load2\" \"Load3\" \"Load4\" \"Store\" \"Store2\" \"Store3\" \"Store4\"\n\t\t\"GatherRed\" \"GatherGreen\" \"GatherBlue\" \"GatherAlpha\" \"GatherCmp\" \"GatherCmpRed\" \"GatherCmpGreen\" \"GatherCmpBlue\" \"GatherCmpAlpha\"\n\t))\n\n(interface_requirements\n  (identifier) @type)\n\n(binary_expression\n  [\n    \"is\"\n    \"as\"\n  ]\n  right: (identifier) @type)\n\n[\n  \"as\"\n  \"is\"\n] @keyword.operator\n\n[\n  \"__exported\"\n  \"import\"\n] @keyword.control.import\n\n(property_declaration\n  (identifier) @variable.other.member)\n"
  },
  {
    "path": "runtime/queries/slang/indents.scm",
    "content": "; inherits: hlsl\n\n[\n  (interface_specifier)\n  (extension_specifier)\n] @indent\n"
  },
  {
    "path": "runtime/queries/slang/injections.scm",
    "content": "((preproc_arg) @injection.content\n  (#set! injection.language \"slang\"))\n\n((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/slang/textobjects.scm",
    "content": "(function_definition\n  body: (_) @function.inside) @function.around\n\n(struct_specifier\n  body: (_) @class.inside) @class.around\n\n(interface_specifier\n  body: (_) @class.inside) @class.around\n\n(enum_specifier\n  body: (_) @class.inside) @class.around\n\n(union_specifier\n  body: (_) @class.inside) @class.around\n\n(parameter_list \n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(argument_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(enumerator\n  (_) @entry.inside) @entry.around\n\n(initializer_list\n  (_) @entry.around)\n"
  },
  {
    "path": "runtime/queries/slint/highlights.scm",
    "content": "(comment) @comment\n\n; Different types:\n(string_value) @string\n(bool_value) @constant.builtin.boolean\n\n; Constants\n\n(escape_sequence) @constant.character.escape\n\n(color_value) @constant\n\n[\n  (children_identifier)\n  (easing_kind_identifier)\n] @constant.builtin\n\n[\n  (int_value)\n  (physical_length_value)\n] @constant.numeric.integer\n\n[\n  (float_value)\n  (percent_value)\n  (length_value)\n  (duration_value)\n  (angle_value)\n  (relative_font_size_value)\n] @constant.numeric.float\n\n(purity) @keyword.storage.modifier\n\n(function_visibility) @keyword.storage.modifier\n\n(property_visibility) @keyword.storage.modifier\n\n(builtin_type_identifier) @type.builtin\n\n(reference_identifier) @variable.builtin\n\n(type\n  [\n    (type_list)\n    (user_type_identifier)\n    (anon_struct_block)\n  ]) @type\n\n(user_type_identifier) @type\n\n; Functions and callbacks\n(argument) @variable.parameter\n\n(function_call\n  name: (_) @function.call)\n\n; definitions\n(callback\n  name: (_) @function)\n\n(callback_alias\n  name: (_) @function)\n\n(callback_event\n  name: (simple_identifier) @function.call)\n\n(enum_definition\n  name: (_) @type.enum)\n\n(function_definition\n  name: (_) @function)\n\n(struct_definition\n  name: (_) @type)\n\n(typed_identifier\n  type: (_) @type)\n\n; Operators\n(binary_expression\n  op: (_) @operator)\n\n(unary_expression\n  op: (_) @operator)\n\n[\n  (comparison_operator)\n  (mult_prec_operator)\n  (add_prec_operator)\n  (unary_prec_operator)\n  (assignment_prec_operator)\n] @operator\n\n[\n  \":=\"\n  \"=>\"\n  \"->\"\n  \"<=>\"\n] @operator\n\n[\n  \";\"\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n(property\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n\n; Properties, constants and variables\n(component\n  id: (simple_identifier) @constant)\n\n(property\n  name: (simple_identifier) @variable)\n\n(binding_alias\n  name: (simple_identifier) @variable)\n\n(binding\n  name: (simple_identifier) @variable)\n\n(struct_block\n  (simple_identifier) @variable.other.member)\n\n(anon_struct_block\n  (simple_identifier) @variable.other.member)\n\n(property_assignment\n  property: (simple_identifier) @variable)\n\n(states_definition\n  name: (simple_identifier) @variable)\n\n(callback\n  name: (simple_identifier) @variable)\n\n(typed_identifier\n  name: (_) @variable)\n\n(simple_indexed_identifier\n  (simple_identifier) @variable)\n\n(expression\n  (simple_identifier) @variable)\n\n; Attributes\n[\n  (linear_gradient_identifier)\n  (radial_gradient_identifier)\n  (radial_gradient_kind)\n] @attribute\n\n(image_call\n  \"@image-url\" @attribute)\n\n(tr\n  \"@tr\" @attribute)\n\n; Keywords\n(animate_option_identifier) @keyword\n\n(export) @keyword.control.import\n\n(if_statement\n  \"if\" @keyword.control.conditional)\n\n(if_expr\n  [\n    \"if\"\n    \"else\"\n  ] @keyword.control.conditional)\n\n(ternary_expression\n  [\n    \"?\"\n    \":\"\n  ] @keyword.control.conditional)\n\n(animate_statement\n  \"animate\" @keyword)\n\n(callback\n  \"callback\" @keyword.function)\n\n(component_definition\n  [\n    \"component\"\n    \"inherits\"\n  ] @keyword.storage.type)\n\n(enum_definition\n  \"enum\" @keyword.storage.type)\n\n(for_loop\n  [\n    \"for\"\n    \"in\"\n  ] @keyword.control.repeat)\n\n(function_definition\n  \"function\" @keyword.function)\n\n(global_definition\n  \"global\" @keyword.storage.type)\n\n(imperative_block\n  \"return\" @keyword.control.return)\n\n(import_statement\n  [\n    \"import\"\n    \"from\"\n  ] @keyword.control.import)\n\n(import_type\n  \"as\" @keyword.control.import)\n\n(property\n  \"property\" @keyword.storage.type)\n\n(states_definition\n  [\n    \"states\"\n    \"when\"\n  ] @keyword)\n\n(struct_definition\n  \"struct\" @keyword.storage.type)\n\n(transitions_definition\n  [\n    \"transitions\"\n    \"in\"\n    \"out\"\n  ] @keyword)\n"
  },
  {
    "path": "runtime/queries/slint/indents.scm",
    "content": "[\n  (anon_struct_block)\n  (assignment_block)\n  (block)\n  (enum_block)\n  (global_block)\n  (imperative_block)\n  (struct_block)\n] @indent\n\n\"}\" @outdent\n"
  },
  {
    "path": "runtime/queries/slint/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/slint/locals.scm",
    "content": "[\n  (component)\n  (component_definition)\n  (function_definition)\n  (imperative_block)\n] @local.scope\n"
  },
  {
    "path": "runtime/queries/slint/textobjects.scm",
    "content": "(function_definition\n  (imperative_block) @function.inside) @function.around\n\n(callback_event\n  (imperative_block) @function.inside) @function.around\n\n(property\n  (imperative_block) @function.inside) @function.around\n\n(struct_definition\n  (struct_block) @class.inside) @class.around\n\n(enum_definition\n  (enum_block) @class.inside) @class.around\n\n(global_definition\n  (global_block) @class.inside) @class.around\n\n(component_definition\n  (block) @class.inside) @class.around\n\n(component_definition\n  (block) @class.inside) @class.around\n\n(comment) @comment.around\n\n(typed_identifier\n  name: (_) @parameter.inside) @parameter.around\n\n(callback\n  arguments: (_) @parameter.inside)\n\n(string_value\n  \"\\\"\" . (_) @text.inside . \"\\\"\") @text.around\n\n"
  },
  {
    "path": "runtime/queries/slisp/highlights.scm",
    "content": ";; Keywords\n[ \"if\" \"prog\" ] @keyword\n\n;; Let binding\n[ \"let\" ] @keyword\n\n(let_bindings name: (symbol) @variable)\n\n;; Apply\n(apply_stmt . (symbol) @function)\n\n;; Use module\n[ \"use\" ] @keyword\n\n(use_module_global (quote) . (symbol) @namespace)\n(use_module_select (quote) . (symbol) @namespace)\n\n;; Val definition\n[ \"val\" ] @keyword\n\n(val_definition name: (symbol) @constant)\n\n;; External definitions\n[ \"ext\" ] @keyword\n\n(external_definition name: (symbol) @function)\n(external_definition signature: (signature (symbol) @variable.parameter (dot) (external_type) @type.builtin))\n(external_definition docstring: (string) @comment)\n(external_definition return_type: (external_type) @type.builtin)\n\n;; Function definitions\n[ \"def\" ] @keyword\n\n(function_definition name: (symbol) @function)\n(function_definition parameters: (parameters (symbol) @variable.parameter))\n(function_definition docstring: (string) @comment)\n\n;; Macro definitions\n[ \"mac\" ] @keyword\n\n(macro_definition name: (symbol) @function)\n(macro_definition parameters: (parameters (symbol) @variable.parameter))\n(macro_definition docstring: (string) @comment)\n\n;; Lambda \n[ \"\\\\\" ] @keyword\n\n(lambda_stmt parameters: (parameters (symbol) @variable.parameter))\n\n;; Atoms\n(char) @constant.character\n(comment) @comment\n(number) @constant.numeric\n(string) @string\n\n;; Punctuation\n[ \"(\" \")\" ] @punctuation.bracket\n\n;; Operators\n(dot) @operator\n(tilde) @operator\n(backquote) @operator\n(quote) @operator\n(unquote) @operator\n(unquote_splice) @operator\n\n;; Highlight nil t as constant\n[ \"nil\" ] @constant.builtin\n\n;; Highlight as t as boolean constant\n[ \"T\" ] @constant.builtin.boolean\n\n;; Highlight variable names used in anamorphic macros.\n[ \"it\" ] @variable.builtin\n"
  },
  {
    "path": "runtime/queries/slisp/tags.scm",
    "content": ";; def\n(function_definition name: (symbol) @name) @definition.function\n\n;; ext\n(external_definition name: (symbol) @name) @definition.function\n\n;; mac\n(macro_definition name: (symbol) @name) @definition.function\n"
  },
  {
    "path": "runtime/queries/smali/folds.scm",
    "content": "[\n  (annotation_directive)\n  (array_data_directive)\n  (field_definition)\n  (method_definition)\n  (packed_switch_directive)\n  (param_directive)\n  (parameter_directive)\n  (sparse_switch_directive)\n  (subannotation_directive)\n  (list)\n] @fold\n"
  },
  {
    "path": "runtime/queries/smali/highlights.scm",
    "content": "; Types\n\n(class_identifier\n  (identifier) @type)\n\n(primitive_type) @type.builtin\n\n((class_identifier\n   . (identifier) @_first @type.builtin\n   (identifier) @type.builtin)\n  (#match? @_first \"^(android|dalvik|java|kotlinx)$\"))\n\n((class_identifier\n   . (identifier) @_first @type.builtin\n   . (identifier) @_second @type.builtin\n   (identifier) @type.builtin)\n  (#eq? @_first \"com\")\n  (#match? @_second \"^(android|google)$\"))\n\n; Methods\n\n(method_definition\n  (method_signature (method_identifier) @function.method))\n\n(expression\n  (opcode) @_invoke\n\t(body\n\t  (full_method_signature\n      (method_signature (method_identifier) @function.method)))\n  (#match? @_invoke \"^invoke\"))\n\n(expression\n  (opcode) @_field_access\n\t(body\n\t  (field_identifier) @variable.other.member)\n  (#match? @_field_access \"^[is](get|put)-\"))\n\n(method_handle\n  (full_method_signature\n\t(method_signature (method_identifier) @function.method)))\n\n(custom_invoke\n  . (identifier) @function.method\n  (method_signature (method_identifier) @function.method))\n\n(annotation_value\n  (body\n    (method_signature (method_identifier) @function.method)))\n\n(annotation_value\n  (body\n    (full_method_signature\n      (method_signature (method_identifier) @function.method))))\n\n(field_definition\n\t(body\n\t\t(method_signature (method_identifier) @function.method)))\n\n(field_definition\n\t(body\n\t  (full_method_signature\n\t\t  (method_signature (method_identifier) @function.method))))\n\n((method_identifier) @constructor\n  (#match? @constructor \"^(<init>|<clinit>)$\"))\n\n\"constructor\" @constructor\n\n; Fields\n\n[\n  (field_identifier)\n  (annotation_key)\n] @variable.other.member\n\n((field_identifier) @constant\n  (#match? @constant \"^[%u_]*$\"))\n\n; Variables\n\n(variable) @variable.builtin\n\n(local_directive\n  (identifier) @variable)\n\n; Parameters\n\n(parameter) @variable.parameter\n(param_identifier) @variable.parameter\n\n; Labels\n\n[\n  (label)\n  (jmp_label)\n] @label\n\n; Operators\n\n; (opcode) @keyword.operator\n\n((opcode) @keyword.control.return\n  (#match? @keyword.control.return \"^return\"))\n\n((opcode) @keyword.control.conditional\n  (#match? @keyword.control.conditional \"^if\"))\n\n((opcode) @keyword.control.conditional\n  (#match? @keyword.control.conditional \"^cmp\"))\n\n((opcode) @keyword.control.exception\n  (#match? @keyword.control.exception \"^throw\"))\n\n[\n  \"=\"\n  \"..\"\n] @operator\n\n; Keywords\n\n[\n  \".class\"\n  \".super\"\n  \".implements\"\n  \".field\"\n  \".end field\"\n  \".annotation\"\n  \".end annotation\"\n  \".subannotation\"\n  \".end subannotation\"\n  \".param\"\n  \".end param\"\n  \".parameter\"\n  \".end parameter\"\n  \".local\"\n  \".end local\"\n  \".restart local\"\n  \".registers\"\n  \".packed-switch\"\n  \".end packed-switch\"\n  \".sparse-switch\"\n  \".end sparse-switch\"\n  \".array-data\"\n  \".end array-data\"\n  \".enum\"\n  (prologue_directive)\n  (epilogue_directive)\n] @keyword\n\n[\n  \".source\"\n] @keyword.directive\n\n[\n  \".method\"\n  \".end method\"\n] @keyword.function\n\n[\n  \".catch\"\n  \".catchall\"\n] @keyword.control.exception\n\n; Literals\n\n(string) @string\n(source_directive (string \"\\\"\" _ @string.special.url \"\\\"\"))\n(escape_sequence) @constant.character.escape\n\n(character) @constant.character\n\n\"L\" @punctuation\n\n(line_directive (number) @comment) @comment\n(\".locals\" (number) @comment) @comment\n\n(number) @constant.numeric.integer\n\n[\n (float)\n (NaN)\n (Infinity)\n] @constant.numeric.float\n\n(boolean) @constant.builtin.boolean\n\n(null) @constant.builtin\n\n; Misc\n\n(annotation_visibility) @keyword.storage.modifier\n\n(access_modifier) @keyword.storage.type\n\n(array_type\n  \"[\" @punctuation.special)\n\n[\"{\" \"}\"] @punctuation.bracket\n\n[\"(\" \")\"] @punctuation.bracket\n\n[\n  \"->\"\n  \",\"\n  \":\"\n  \";\"\n  \"@\"\n  \"/\"\n] @punctuation.delimiter\n\n; Comments\n\n(comment) @comment\n\n(class_definition\n  (comment) @comment.block.documentation)\n"
  },
  {
    "path": "runtime/queries/smali/indents.scm",
    "content": "[\n  (annotation_directive)\n  (array_data_directive)\n  (field_definition)\n  (method_definition)\n  (packed_switch_directive)\n  (param_directive)\n  (parameter_directive)\n  (sparse_switch_directive)\n  (subannotation_directive)\n  (list)\n  \"\\{\"\n] @indent\n\n[\n  \".end annotation\"\n  \".end array-data\"\n  \".end field\"\n  \".end method\"\n  \".end packed-switch\"\n  \".end param\"\n  \".end parameter\"\n  \".end sparse-switch\"\n  \".end subannotation\"\n  \"\\}\"\n] @outdent\n\n[\n  (ERROR)\n  (comment)\n] @indent.always\n"
  },
  {
    "path": "runtime/queries/smali/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/smali/locals.scm",
    "content": "[\n  (class_directive)\n  (expression)\n  (annotation_directive)\n  (array_data_directive)\n  (method_definition)\n  (packed_switch_directive)\n  (sparse_switch_directive)\n  (subannotation_directive)\n] @local.scope\n\n[\n  (identifier)\n  (class_identifier)\n  (label)\n  (jmp_label)\n] @local.reference\n\n(method_definition\n  (method_signature (method_identifier) @local.definition.function.method))\n\n(param_identifier) @local.definition.variable.parameter\n"
  },
  {
    "path": "runtime/queries/smithy/highlights.scm",
    "content": "; Queries are taken from: https://github.com/indoorvivants/tree-sitter-smithy/blob/main/queries/highlights.scm\n; Preproc\n(control_key) @keyword.directive\n\n; Namespace\n(namespace) @namespace\n\n; Includes\n[\n  \"use\"\n] @keyword.control.import\n\n; Builtins\n(primitive) @type.builtin\n[\n  \"enum\"\n  \"intEnum\"\n  \"list\"\n  \"map\"\n  \"set\"\n] @type.builtin\n\n; Fields (Members)\n; (field) @variable.other.member\n\n(key_identifier) @variable.other.member\n(shape_member\n  (field) @variable.other.member)\n(operation_field) @variable.other.member\n(operation_error_field) @variable.other.member\n\n; Constants\n(enum_member\n  (enum_field) @type.enum)\n\n; Types\n(identifier) @type\n(structure_resource\n  (shape_id) @type)\n\n; Attributes\n(mixins\n  (shape_id) @attribute)\n(trait_statement\n  (shape_id) @attribute)\n\n; Operators\n[\n  \"@\"\n  \"-\"\n  \"=\"\n  \":=\"\n] @operator\n\n; Keywords\n[\n  \"namespace\"\n  \"service\"\n  \"structure\"\n  \"operation\"\n  \"union\"\n  \"resource\"\n  \"metadata\"\n  \"apply\"\n  \"for\"\n  \"with\"\n] @keyword\n\n; Literals\n(string) @string\n(escape_sequence) @constant.character.escape\n\n(number) @constant.numeric\n\n(float) @constant.numeric.float\n\n(boolean) @constant.builtin.boolean\n\n(null) @constant.builtin\n\n; Misc\n[\n  \"$\"\n  \"#\"\n] @punctuation.special\n\n[\"{\" \"}\"] @punctuation.bracket\n\n[\"(\" \")\"] @punctuation.bracket\n\n[\"[\" \"]\"] @punctuation.bracket\n\n[\n  \":\"\n  \".\"\n] @punctuation.delimiter\n\n; Comments\n[\n  (comment)\n  (documentation_comment)\n] @comment\n"
  },
  {
    "path": "runtime/queries/sml/highlights.scm",
    "content": "; Highlights queries from Matthew Fluet (https://github.com/MatthewFluet/tree-sitter-sml)\n;\n; MIT License\n;\n; Copyright (c) 2022 Matthew Fluet\n;\n; Permission is hereby granted, free of charge, to any person obtaining a copy\n; of this software and associated documentation files (the \"Software\"), to deal\n; in the Software without restriction, including without limitation the rights\n; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n; copies of the Software, and to permit persons to whom the Software is\n; furnished to do so, subject to the following conditions:\n;\n; The above copyright notice and this permission notice shall be included in all\n; copies or substantial portions of the Software.\n;\n; THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n; SOFTWARE.\n\n;; *******************************************************************\n;; Comments\n;; *******************************************************************\n\n[(block_comment) (line_comment)] @comment\n\n;; *******************************************************************\n;; Keywords\n;; *******************************************************************\n\n[\n ;; Reserved Words Core\n \"abstype\" \"and\" \"andalso\" \"as\" \"case\" \"datatype\" \"do\" \"else\" \"end\"\n \"exception\" \"fn\" \"fun\" \"handle\" \"if\" \"in\" \"infix\" \"infixr\" \"let\"\n \"local\" \"nonfix\" \"of\" \"op\" \"open\" \"orelse\" \"raise\" \"rec\" \"then\"\n \"type\" \"val\" \"with\" \"withtype\" \"while\"\n ;; Reserved Words Modules\n \"eqtype\" \"functor\" \"include\" \"sharing\" \"sig\" \"signature\" \"struct\"\n \"structure\" \"where\"\n] @keyword\n\n;; *******************************************************************\n;; Constants\n;; *******************************************************************\n\n(integer_scon) @constant.numeric.integer\n(real_scon) @constant.numeric.float\n(word_scon) @constant.numeric\n(string_scon) @string\n(char_scon) @constant.character\n\n;; *******************************************************************\n;; Types\n;; *******************************************************************\n\n(fn_ty \"->\" @type)\n(tuple_ty \"*\" @type)\n(paren_ty [\"(\" \")\"] @type)\n(tyvar_ty (tyvar) @type)\n(record_ty\n [\"{\" \",\" \"}\"] @type\n (tyrow [(lab) \":\"] @type)?\n (ellipsis_tyrow [\"...\" \":\"] @type)?)\n(tycon_ty\n (tyseq [\"(\" \",\" \")\"] @type)?\n (longtycon) @type)\n\n;; *******************************************************************\n;; Constructors\n;; *******************************************************************\n\n;; Assume value identifiers starting with capital letter are constructors\n((vid) @constructor\n (#match? @constructor \"^[A-Z].*\"))\n\n((vid) @constant.builtin (#eq? @constant.builtin \"nil\"))\n((vid) @constant.builtin.boolean\n (#match? @constant.builtin.boolean \"^(true|false)$\"))\n((vid) @operator (#eq? @operator \"::\"))\n((vid) @keyword.storage.modifier (#eq? @keyword.storage.modifier \"ref\"))\n\n;; *******************************************************************\n;; Punctuation\n;; *******************************************************************\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n[\".\" \",\" \":\" \";\" \"|\" \"=>\" \":>\"] @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/snakemake/LICENSE",
    "content": "Copyright (c) 2016 Max Brunsfeld\nCopyright (c) 2023 Oliver Thomas\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/queries/snakemake/folds.scm",
    "content": "; inherits: python\n\n[\n  (rule_definition)\n  (rule_inheritance)\n  (module_definition)\n  (checkpoint_definition)\n] @fold\n"
  },
  {
    "path": "runtime/queries/snakemake/highlights.scm",
    "content": "; inherits: python\n\n; Compound directives\n[\n  \"rule\"\n  \"checkpoint\"\n  \"module\"\n] @keyword\n\n; Top level directives (eg. configfile, include)\n(module\n  (directive\n    name: _ @keyword))\n\n; Subordinate directives (eg. input, output)\n((_)\n  body: (_\n    (directive\n      name: _ @label)))\n\n; rule/module/checkpoint names\n(rule_definition\n  name: (identifier) @type)\n\n(module_definition\n  name: (identifier) @type)\n\n(checkpoint_definition\n  name: (identifier) @type)\n\n; Rule imports\n(rule_import\n  \"use\" @keyword.import\n  \"rule\" @keyword.import\n  \"from\" @keyword.import\n  \"exclude\"? @keyword.import\n  \"as\"? @keyword.import\n  \"with\"? @keyword.import)\n\n; Rule inheritance\n(rule_inheritance\n  \"use\" @keyword\n  \"rule\" @keyword\n  \"with\" @keyword)\n\n; Wildcard names\n(wildcard (identifier) @variable)\n(wildcard (flag) @variable.parameter.builtin)\n\n; builtin variables\n((identifier) @variable.builtin\n  (#any-of? @variable.builtin \"checkpoints\" \"config\" \"gather\" \"rules\" \"scatter\" \"workflow\"))\n\n; References to directive labels in wildcard interpolations\n; the #any-of? queries are moved above the #has-ancestor? queries to\n; short-circuit the potentially expensive tree traversal, if possible\n; see:\n; https://github.com/nvim-treesitter/nvim-treesitter/pull/4302#issuecomment-1685789790\n; directive labels in wildcard context\n((wildcard\n  (identifier) @label)\n  (#any-of? @label \"input\" \"log\" \"output\" \"params\" \"resources\" \"threads\" \"wildcards\"))\n\n((wildcard\n  (attribute\n    object: (identifier) @label))\n  (#any-of? @label \"input\" \"log\" \"output\" \"params\" \"resources\" \"threads\" \"wildcards\"))\n\n((wildcard\n  (subscript\n    value: (identifier) @label))\n  (#any-of? @label \"input\" \"log\" \"output\" \"params\" \"resources\" \"threads\" \"wildcards\"))\n\n; directive labels in block context (eg. within 'run:')\n((identifier) @label\n  (#any-of? @label \"input\" \"log\" \"output\" \"params\" \"resources\" \"threads\" \"wildcards\"))\n"
  },
  {
    "path": "runtime/queries/snakemake/indents.scm",
    "content": "; inherits: python\n\n\n[\n  (rule_definition)\n  (checkpoint_definition)\n  (rule_inheritance)\n  (module_definition)\n] @indent\n\n[\n  (rule_definition)\n  (checkpoint_definition)\n  (rule_inheritance)\n  (module_definition)\n] @extend\n\n\n(directive) @indent\n(directive) @extend\n\n(rule_import\n  \"with\"\n  \":\") @indent\n(rule_import\n  \"with\"\n  \":\") @extend\n"
  },
  {
    "path": "runtime/queries/snakemake/injections.scm",
    "content": "; inherits: python\n\n(wildcard\n  (constraint) @injection.content\n  (#set! injection.language \"regex\"))\n"
  },
  {
    "path": "runtime/queries/snakemake/locals.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/solidity/highlights.scm",
    "content": "; identifiers\n; -----------\n(identifier) @variable\n((identifier) @variable.builtin (#any-of? @variable.builtin \"this\" \"msg\" \"block\" \"tx\"))\n(yul_identifier) @variable\n\n; Pragma\n(pragma_directive) @keyword.directive\n(solidity_version_comparison_operator _ @keyword.directive)\n\n; Literals\n; --------\n[\n (string)\n (hex_string_literal)\n (unicode_string_literal)\n (yul_string_literal)\n] @string\n(hex_string_literal \"hex\" @string.special.symbol)\n(unicode_string_literal \"unicode\" @string.special.symbol)\n[\n (number_literal)\n (yul_decimal_number)\n (yul_hex_number)\n] @constant.numeric\n[\n (true)\n (false)\n (yul_boolean)\n] @constant.builtin.boolean\n\n(comment) @comment\n\n; Definitions and references\n; -----------\n(type_name) @type\n\n[\n  (primitive_type)\n  (number_unit)\n] @type.builtin\n\n(user_defined_type (_) @type)\n(user_defined_type_definition name: (identifier) @type)\n(type_alias (identifier) @type)\n\n; Color payable in payable address conversion as type and not as keyword\n(payable_conversion_expression \"payable\" @type)\n; Ensures that delimiters in mapping( ... => .. ) are not colored like types\n(type_name \"(\" @punctuation.bracket \"=>\" @punctuation.delimiter \")\" @punctuation.bracket)\n\n; Definitions\n(struct_declaration name: (identifier) @type)\n(enum_declaration name: (identifier) @type)\n(contract_declaration name: (identifier) @type)\n(library_declaration name: (identifier) @type)\n(interface_declaration name: (identifier) @type)\n(event_definition name: (identifier) @type)\n(error_declaration name: (identifier) @type)\n(function_definition name: (identifier) @function)\n(modifier_definition name: (identifier) @function)\n(yul_evm_builtin) @function.builtin\n\n; Use constructor coloring for special functions\n(constructor_definition \"constructor\" @constructor)\n(error_declaration \"error\" @constructor)\n(fallback_receive_definition \"receive\" @constructor)\n(fallback_receive_definition \"fallback\" @constructor)\n\n(struct_member name: (identifier) @variable.other.member)\n(enum_value) @constant\n; SCREAMING_SNAKE_CASE identifier are constants\n((identifier) @constant (#match? @constant \"^[A-Z][A-Z_]+$\"))\n\n; Invocations\n(emit_statement name: (expression (identifier) @type))\n(revert_statement error: (expression (identifier) @type))\n(modifier_invocation . (_) @function)\n\n(call_expression . (_(member_expression property: (_) @function.method)))\n(call_expression . (expression (identifier) @function))\n\n; Function parameters\n(call_struct_argument name: (identifier) @field)\n(event_parameter name: (identifier) @variable.parameter)\n(parameter name: (identifier) @variable.parameter)\n\n; Yul functions\n(yul_function_call function: (_) @function)\n(yul_function_definition\n  (\"function\" (yul_identifier) @function \"(\" (\n      (yul_identifier) @variable.parameter (\",\" (yul_identifier) @variable.parameter)*\n    )\n  )\n)\n\n; Structs and members\n(member_expression property: (identifier) @variable.other.member)\n(struct_expression type: ((expression (identifier)) @type .))\n(struct_field_assignment name: (identifier) @variable.other.member)\n\n\n; Tokens\n; -------\n\n; Keywords\n(meta_type_expression \"type\" @keyword)\n[\n \"abstract\"\n \"contract\"\n \"interface\"\n \"library\"\n \"is\"\n \"struct\"\n \"enum\"\n \"event\"\n \"type\"\n \"assembly\"\n \"emit\"\n \"public\"\n \"internal\"\n \"private\"\n \"external\"\n \"pure\"\n \"view\"\n \"payable\"\n \"modifier\"\n \"var\"\n \"let\"\n (virtual)\n (override_specifier)\n (yul_leave)\n] @keyword\n\n[\n \"memory\"\n \"storage\"\n \"calldata\"\n \"constant\"\n \"transient\"\n (immutable)\n] @keyword.storage.modifier\n\n[\n \"for\"\n \"while\"\n \"do\"\n] @keyword.control.repeat\n\n[\n \"break\"\n \"continue\"\n \"if\"\n \"else\"\n \"switch\"\n \"case\"\n \"default\"\n] @keyword.control.conditional\n\n[\n \"try\"\n \"catch\"\n \"revert\"\n] @keyword.control.exception\n\n[\n \"return\"\n \"returns\"\n] @keyword.control.return\n\n\"function\" @keyword.function\n\n\"import\" @keyword.control.import\n\"using\" @keyword.control.import\n(import_directive \"as\" @keyword.control.import)\n(import_directive \"from\" @keyword.control.import)\n(event_parameter \"indexed\" @keyword)\n\n; Punctuation\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \".\"\n  \",\"\n  \":\"\n  \"->\"\n  \"=>\"\n] @punctuation.delimiter\n\n; Operators\n[\n  \"&&\"\n  \"||\"\n  \">>\"\n  \"<<\"\n  \"&\"\n  \"^\"\n  \"|\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"**\"\n  \"<\"\n  \"<=\"\n  \"==\"\n  \"!=\"\n  \">=\"\n  \">\"\n  \"!\"\n  \"~\"\n  \"-\"\n  \"+\"\n  \"++\"\n  \"--\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"^=\"\n  \"&=\"\n  \"|=\"\n  \"<<=\"\n  \">>=\"\n] @operator\n\n[\n  \"delete\"\n  \"new\"\n] @keyword.operator\n"
  },
  {
    "path": "runtime/queries/solidity/locals.scm",
    "content": "(function_definition) @local.scope\n(constructor_definition) @local.scope\n(block_statement) @local.scope\n\n(function_definition (parameter name: (identifier) @local.definition.variable.parameter))\n(constructor_definition (parameter name: (identifier) @local.definition.variable.parameter))\n\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/solidity/textobjects.scm",
    "content": "(function_definition\n  body: (_) @function.inside) @function.around\n\n(constructor_definition\n  body: (_) @function.inside) @function.around\n\n(fallback_receive_definition\n  body: (_) @function.inside) @function.around\n\n(yul_function_definition\n  (yul_block) @function.inside) @function.around\n\n(function_definition \n  ((parameter) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(constructor_definition \n  ((parameter) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(return_type_definition \n  ((parameter) @entry.inside . \",\"? @entry.around) @entry.around)\n\n(modifier_definition \n  ((parameter) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(event_definition \n  ((event_parameter) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(error_declaration \n  ((error_parameter) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(call_argument\n  ((call_struct_argument) @entry.inside . \",\"? @entry.around) @entry.around)\n\n(call_expression\n  ((call_argument) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(variable_declaration_tuple\n  ((variable_declaration) @entry.inside . \",\"? @entry.around) @entry.around)\n\n(emit_statement\n  ((call_argument) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(revert_arguments\n  ((call_argument) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(struct_declaration\n  body: (_) @class.inside) @class.around\n\n(enum_declaration\n  body: (_) @class.inside) @class.around\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n\n"
  },
  {
    "path": "runtime/queries/sourcepawn/highlights.scm",
    "content": "; Assume all-caps names are constants\n((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z\\\\d_]+$'\"))\n\n; Function definitions/declarations\n(function_definition\n  name: (identifier) @function)\n(function_declaration\n  name: (identifier) @function)\n(parameter_declaration\n  name: (identifier) @variable.parameter)\n\n; Methods / Properties\n(field_access\n  field: (identifier) @variable.other.member)\n\n; Function calls\n(call_expression\n  function: (identifier) @function)\n(call_expression\n  function: (field_access\n    field: (identifier) @function))\n\n; Types\n(builtin_type) @type.builtin\n(type (identifier) @type)\n(any_type) @type\n\n; Variables\n(variable_storage_class) @keyword.storage\n(variable_declaration\n  name: (identifier) @variable)\n(old_variable_declaration\n  name: (identifier) @variable)\n\n; Preprocessor\n(preproc_include) @keyword.control.import\n(preproc_tryinclude) @keyword.control.import\n(system_lib_string) @string\n(string_literal) @string\n\n(preproc_assert) @keyword.directive\n(preproc_pragma) @keyword.directive\n(preproc_arg) @constant\n(preproc_macro) @function.macro\n(macro_param) @variable.parameter\n(preproc_if) @keyword.directive\n(preproc_else) @keyword.directive\n(preproc_elseif) @keyword.directive\n(preproc_endif) @keyword.directive\n(preproc_endinput) @keyword.directive\n(preproc_define) @keyword.directive\n(preproc_define\n  name: (identifier) @constant)\n(preproc_undefine) @keyword.directive\n(preproc_undefine\n  name: (identifier) @constant)\n(preproc_error) @function.macro ; Wrong color?\n(preproc_warning) @function.macro ; Wrong color?\n\n; Statements\n(for_statement) @keyword.control.repeat\n(condition_statement) @keyword.control.conditional\n(while_statement) @keyword.control.repeat\n(do_while_statement) @keyword.control.repeat\n(switch_statement) @keyword.control.conditional\n(switch_case) @keyword.control.conditional\n(ternary_expression) @conditional.ternary\n\n; Expressions\n(view_as) @function.builtin\n(sizeof_expression) @function.macro\n(this) @variable.builtin\n\n; https://github.com/alliedmodders/sourcemod/blob/5c0ae11a4619e9cba93478683c7737253ea93ba6/plugins/include/handles.inc#L78\n(hardcoded_symbol) @variable.builtin\n\n; Comments\n(comment) @comment\n\n; General\n(parameter_declaration\n  defaultValue: (identifier) @constant)\n(fixed_dimension) @punctuation.bracket ; the [3] in var[3]\n(dimension) @punctuation.bracket\n(array_indexed_access) @punctuation.bracket\n(escape_sequence) @constant.character.escape\n\n; Constructors\n(new_expression\n  class: (identifier) @type\n  arguments: (call_arguments) @constructor)\n\n; Methodmaps\n(methodmap) @type.definition\n(methodmap\n  name: (identifier) @type)\n(methodmap\n  inherits: (identifier) @type)\n(methodmap_method_constructor\n  name: (identifier) @constructor)\n(methodmap_method\n  name: (identifier) @function.method)\n(methodmap_native\n  name: (identifier) @function.method)\n(methodmap_property\n  name: (identifier) @variable.other.member)\n(methodmap_property_getter) @function.method\n(methodmap_property_setter) @function.method\n\n; Enum structs\n(enum_struct) @type.enum.variant\n(enum_struct\n  name: (identifier) @type)\n(enum_struct_field\n  name: (identifier) @variable.other.member)\n(enum_struct_method\n  name: (identifier) @function.method)\n\n; Non-type Keywords\n(variable_storage_class) @keyword.storage\n(visibility) @keyword.storage\n(visibility) @keyword.storage\n(assertion) @function.builtin\n(function_declaration_kind) @keyword.function\n[\n  \"new\"\n  \"delete\"\n] @keyword.operator\n[\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n; Operators\n[\n  \"+\"\n  \"-\"\n  \"...\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"++\"\n  \"--\"\n  \"=\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"==\"\n  \"!=\"\n  \"<\"\n  \">\"\n  \">=\"\n  \"<=\"\n  \"!\"\n  \"&&\"\n  \"||\"\n  \"&\"\n  \"|\"\n  \"~\"\n  \"^\"\n  \"<<\"\n  \">>\"\n  \">>>\"\n  \"|=\"\n  \"&=\"\n  \"^=\"\n  \"~=\"\n  \"<<=\"\n  \">>=\"\n] @operator\n(ignore_argument) @operator\n(scope_access) @operator\n(rest_operator) @operator\n\n; public Plugin myinfo\n(struct_declaration\n  name: (identifier) @variable.builtin)\n\n; Typedef/Typedef\n(typeset) @type.builtin\n(typedef) @type.builtin\n(functag) @type.builtin\n(funcenum) @type.builtin\n(typedef_expression) @keyword.function ; function void(int x)\n\n; Enums\n(enum) @type.enum\n(enum\n  name: (identifier) @type)\n(enum_entry\n  name: (identifier) @constant)\n(enum_entry\n  value: (_) @constant)\n\n; Literals\n(int_literal) @constant.numeric.integer\n(char_literal) @constant.character\n(float_literal) @constant.numeric.float\n(string_literal) @string\n(array_literal) @punctuation.bracket\n[\n  (bool_literal)\n  (null)\n] @constant.builtin\n((identifier) @constant\n  (#match? @constant \"INVALID_HANDLE\"))\n\n; Comment specialisations (must be after comment)\n; These might be unnecessary and/or used incorrectly, since they're intended\n; for markup languages\n((comment) @diff.plus\n  (#match? @diff.plus \"^\\/[\\/\\*][\\t ]TODO\"))\n((comment) @diff.plus\n  (#match? @diff.plus \"^\\/[\\/\\*][\\t ]NOTE\"))\n((comment) @diff.minus\n  (#match? @diff.minus \"^\\/[\\/\\*][\\t ]WARNING\"))\n\n; Keywords\n[\n  \"__nullable__\"\n  \"break\"\n  \"case\"\n  \"const\"\n  \"continue\"\n  \"default\"\n  \"delete\"\n  \"do\"\n  \"else\"\n  \"enum\"\n  \"for\"\n  \"forward\"\n  \"funcenum\"\n  \"functag\"\n  \"get\"\n  \"if\"\n  \"methodmap\"\n  \"native\"\n  \"new\"\n  \"property\"\n  \"public\"\n  \"return\"\n  \"set\"\n  \"static\"\n  \"stock\"\n  \"struct\"\n  \"switch\"\n  \"typedef\"\n  \"typeset\"\n  \"void\"\n  \"while\"\n] @keyword\n\n(identifier) @variable\n"
  },
  {
    "path": "runtime/queries/sourcepawn/injections.scm",
    "content": "; Parse JSDoc annotations in comments\n\n((comment) @injection.content\n (#set! injection.language \"jsdoc\"))\n"
  },
  {
    "path": "runtime/queries/sourcepawn/textobjects.scm",
    "content": "(function_definition\n  body: (_) @function.inside) @function.around\n\n(alias_declaration\n  body: (_) @function.inside) @function.around\n\n(enum_struct_method\n  body: (_) @function.inside) @function.around\n\n(methodmap_method\n  body: (_) @function.inside) @function.around\n\n(methodmap_method_constructor\n  body: (_) @function.inside) @function.around\n\n(methodmap_method_destructor\n  body: (_) @function.inside) @function.around\n\n(methodmap_property_method\n  body: (_) @function.inside) @function.around\n\n(enum_struct) @class.around\n\n(methodmap) @class.around\n\n(parameter_declarations \n  ((parameter_declaration) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/spade/highlights.scm",
    "content": "(self) @variable.builtin\n\n(unit_definition (identifier) @function)\n\n(parameter (identifier) @variable.parameter)\n\n((pipeline_reg_marker) @keyword)\n\n(scoped_identifier\n  path: (identifier) @namespace)\n(scoped_identifier\n (scoped_identifier\n  name: (identifier) @namespace))\n\n((builtin_type) @type.builtin)\n\n((identifier) @type.builtin\n (#any-of?\n    @type.builtin\n    \"uint\"\n    \"Option\"\n    \"Memory\"))\n\n((identifier) @type.enum.variant.builtin\n (#any-of? @type.enum.variant.builtin \"Some\" \"None\"))\n\n((pipeline_stage_name) @label)\n((label) @label)\n((label_ref) @label)\n\n((stage_reference\n    stage: (identifier) @label))\n\n[\n    \"pipeline\"\n    \"let\"\n    \"set\"\n    \"entity\"\n    \"fn\"\n    \"reg\"\n    \"reset\"\n    \"initial\"\n    \"inst\"\n    \"assert\"\n    \"struct\"\n    \"enum\"\n    \"stage\"\n    \"impl\"\n    \"port\"\n    \"decl\"\n    \"mod\"\n    \"where\"\n    \"trait\"\n    \"for\"\n    \"pub\"\n    \"unsafe\"\n    \"type\"\n    \"as\"\n    \"initial\"\n] @keyword\n\n[\n  \"wire\"\n    \"super\"\n    \"lib\"\n] @keyword.storage\n\n[\n  \"use\"\n] @keyword.import\n\n[\n  \"gen\"\n] @keyword.directive\n\n((gen_if_expression  [\"if\" \"else\"] @keyword.directive))\n((naked_gen_if_expression  [\"if\" \"else\"] @keyword.directive))\n\n((attribute) [\"#\" \"[\" \"]\"] @punctuation.delimiter)\n\n[\n  \"else\"\n  \"if\"\n  \"match\"\n] @keyword.control.conditional\n\n(bool_literal) @constant.builtin.boolean\n(int_literal) @constant.numeric.integer\n(char_literal) @constant.character\n(string_literal) @string\n\n[\n  \"&\"\n  \"inv\"\n  \"-\"\n  \"=>\"\n  \">\"\n  \"<\"\n  \"::<\"\n  \"::$<\"\n  \"=\"\n  \"->\"\n  \"~\"\n  \"!\"\n] @operator\n\n\n((op_custom_infix) @operator)\n((op_add) @operator)\n((op_sub) @operator)\n((op_mul) @operator)\n((op_equals) @operator)\n((op_lt) @operator)\n((op_gt) @operator)\n((op_le) @operator)\n((op_ge) @operator)\n((op_lshift) @operator)\n((op_rshift) @operator)\n((op_bitwise_and) @operator)\n((op_bitwise_xor) @operator)\n((op_bitwise_or) @operator)\n((op_logical_and) @operator)\n((op_logical_or) @operator)\n\n\n[\n  (line_comment)\n  (block_comment)\n] @comment\n\n[\n  (doc_comment)\n] @comment.block.documentation\n\n\n((identifier) @type\n  (#match? @type \"[A-Z]\"))\n\n((scoped_identifier\n    name: (identifier) @type)\n (#match? @type \"^[A-Z]\"))\n\n((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z\\\\d_]*$\"))\n\n"
  },
  {
    "path": "runtime/queries/spade/indents.scm",
    "content": "\n[\n  (unit_definition)\n  (struct_definition)\n  (enum_definition)\n  (enum_member)\n  (impl)\n  (mod)\n  (argument_list)\n  (let_binding)\n  (block)\n  (tuple_literal)\n  (array_literal)\n  (paren_expression)\n  (turbofish)\n  (generic_parameters)\n  (named_unpack)\n  (positional_unpack)\n  (tuple_pattern)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n\n"
  },
  {
    "path": "runtime/queries/spade/rainbows.scm",
    "content": "[\n  (block)\n  (impl)\n  (attribute)\n  (generic_parameters)\n  (parameter_list)\n  (impl)\n  (trait)\n  (enum_body)\n  (enum_member)\n  (mod)\n  (reg_reset)\n  (reg_initial)\n  (match_block)\n  (lambda_params)\n  (paren_expression)\n  (turbofish)\n  (stage_reference)\n  (argument_list)\n  (braced_parameter_list)\n  (tuple_literal)\n  (array_type)\n  (array_literal)\n  (array_pattern)\n  (index)\n  (tuple_pattern)\n] @rainbow.scope\n\n\n[\n  \"[\" \"]\"\n  \"(\" \")\"\n  \"{\" \"}\"\n  \"<\" \">\"\n  \"$(\"\n  \"::<\"\n  \"::$<\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/spicedb/highlights.scm",
    "content": "; highlights.scm\n\n[\n  \"definition\"\n  \"caveat\"\n  \"permission\"\n  \"relation\"\n  \"nil\"\n] @keyword\n\n[\n  \",\"\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \"|\"\n  \"+\"\n  \"-\"\n  \"&\"\n  \"#\"\n  \"->\"\n  \"=\"\n] @operator\n(\"with\") @keyword.operator\n\n[\n  \"nil\"\n  \"*\"\n] @constant.builtin\n\n(comment) @comment\n(type_identifier) @type\n(cel_type_identifier) @type\n(cel_variable_identifier) @variable.parameter\n(field_identifier) @variable.other.member\n[\n  (func_identifier)\n  (method_identifier)\n] @function.method\n"
  },
  {
    "path": "runtime/queries/spicedb/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((caveat_expr) @injection.content\n (#set! injection.language \"cel\"))\n"
  },
  {
    "path": "runtime/queries/spicedb/tags.scm",
    "content": "(object_definition\n  name: (type_identifier) @name) @definition.type\n\n(type_identifier) @name @reference.type\n"
  },
  {
    "path": "runtime/queries/sql/highlights.scm",
    "content": "(invocation\n  (object_reference\n    name: (identifier) @function.method))\n\n[\n  (keyword_gist)\n  (keyword_btree)\n  (keyword_hash)\n  (keyword_spgist)\n  (keyword_gin)\n  (keyword_brin)\n  (keyword_array)\n] @function.builtin\n\n(object_reference\n  name: (identifier) @variable.other.member)\n\n(relation\n  alias: (identifier) @variable.parameter)\n\n(field\n  name: (identifier) @variable.other.member)\n\n(term\n  alias: (identifier) @variable.parameter)\n\n((term\n   value: (cast\n    name: (keyword_cast) @function.builtin\n    parameter: [(literal)]?)))\n\n(literal) @string\n(comment) @comment.line\n(marginalia) @comment.block\n\n((literal) @constant.numeric.integer\n   (#match? @constant.numeric.integer \"^[-+]?\\\\d+$\"))\n\n((literal) @constant.numeric.float\n  (#match? @constant.numeric.float \"^[-+]?\\\\d*\\\\.\\\\d*$\"))\n\n(parameter) @variable.parameter\n\n[\n (keyword_true)\n (keyword_false)\n] @constant.builtin.boolean\n\n[\n (keyword_asc)\n (keyword_desc)\n (keyword_terminated)\n (keyword_escaped)\n (keyword_unsigned)\n (keyword_nulls)\n (keyword_last)\n (keyword_delimited)\n (keyword_replication)\n (keyword_auto_increment)\n (keyword_default)\n (keyword_collate)\n (keyword_concurrently)\n (keyword_engine)\n (keyword_always)\n (keyword_generated)\n (keyword_preceding)\n (keyword_following)\n (keyword_first)\n (keyword_current_timestamp)\n (keyword_immutable)\n (keyword_atomic)\n (keyword_parallel)\n (keyword_leakproof)\n (keyword_safe)\n (keyword_cost)\n (keyword_strict)\n] @attribute\n\n[\n (keyword_materialized)\n (keyword_recursive)\n (keyword_temp)\n (keyword_temporary)\n (keyword_unlogged)\n (keyword_external)\n (keyword_parquet)\n (keyword_csv)\n (keyword_rcfile)\n (keyword_textfile)\n (keyword_orc)\n (keyword_avro)\n (keyword_jsonfile)\n (keyword_sequencefile)\n (keyword_volatile)\n] @keyword.storage.type\n\n[\n (keyword_case)\n (keyword_when)\n (keyword_then)\n (keyword_else)\n] @keyword.control.conditional\n\n[\n  (keyword_select)\n  (keyword_from)\n  (keyword_where)\n  (keyword_index)\n  (keyword_join)\n  (keyword_primary)\n  (keyword_delete)\n  (keyword_create)\n  (keyword_show)\n  (keyword_unload)\n  (keyword_insert)\n  (keyword_merge)\n  (keyword_distinct)\n  (keyword_replace)\n  (keyword_update)\n  (keyword_into)\n  (keyword_overwrite)\n  (keyword_matched)\n  (keyword_values)\n  (keyword_value)\n  (keyword_attribute)\n  (keyword_set)\n  (keyword_left)\n  (keyword_right)\n  (keyword_outer)\n  (keyword_inner)\n  (keyword_full)\n  (keyword_order)\n  (keyword_partition)\n  (keyword_group)\n  (keyword_with)\n  (keyword_without)\n  (keyword_as)\n  (keyword_having)\n  (keyword_limit)\n  (keyword_offset)\n  (keyword_table)\n  (keyword_tables)\n  (keyword_key)\n  (keyword_references)\n  (keyword_foreign)\n  (keyword_constraint)\n  (keyword_force)\n  (keyword_use)\n  (keyword_for)\n  (keyword_if)\n  (keyword_exists)\n  (keyword_column)\n  (keyword_columns)\n  (keyword_cross)\n  (keyword_lateral)\n  (keyword_natural)\n  (keyword_alter)\n  (keyword_drop)\n  (keyword_add)\n  (keyword_view)\n  (keyword_end)\n  (keyword_is)\n  (keyword_using)\n  (keyword_between)\n  (keyword_window)\n  (keyword_no)\n  (keyword_data)\n  (keyword_type)\n  (keyword_rename)\n  (keyword_to)\n  (keyword_schema)\n  (keyword_owner)\n  (keyword_authorization)\n  (keyword_all)\n  (keyword_any)\n  (keyword_some)\n  (keyword_returning)\n  (keyword_begin)\n  (keyword_commit)\n  (keyword_rollback)\n  (keyword_transaction)\n  (keyword_only)\n  (keyword_like)\n  (keyword_similar)\n  (keyword_over)\n  (keyword_change)\n  (keyword_modify)\n  (keyword_after)\n  (keyword_before)\n  (keyword_range)\n  (keyword_rows)\n  (keyword_groups)\n  (keyword_exclude)\n  (keyword_current)\n  (keyword_ties)\n  (keyword_others)\n  (keyword_zerofill)\n  (keyword_format)\n  (keyword_fields)\n  (keyword_row)\n  (keyword_sort)\n  (keyword_compute)\n  (keyword_comment)\n  (keyword_location)\n  (keyword_cached)\n  (keyword_uncached)\n  (keyword_lines)\n  (keyword_stored)\n  (keyword_virtual)\n  (keyword_partitioned)\n  (keyword_analyze)\n  (keyword_explain)\n  (keyword_verbose)\n  (keyword_truncate)\n  (keyword_rewrite)\n  (keyword_optimize)\n  (keyword_vacuum)\n  (keyword_cache)\n  (keyword_language)\n  (keyword_called)\n  (keyword_conflict)\n  (keyword_declare)\n  (keyword_filter)\n  (keyword_function)\n  (keyword_input)\n  (keyword_name)\n  (keyword_oid)\n  (keyword_oids)\n  (keyword_precision)\n  (keyword_regclass)\n  (keyword_regnamespace)\n  (keyword_regproc)\n  (keyword_regtype)\n  (keyword_restricted)\n  (keyword_return)\n  (keyword_returns)\n  (keyword_separator)\n  (keyword_setof)\n  (keyword_stable)\n  (keyword_support)\n  (keyword_tblproperties)\n  (keyword_trigger)\n  (keyword_unsafe)\n  (keyword_admin)\n  (keyword_connection)\n  (keyword_cycle)\n  (keyword_database)\n  (keyword_encrypted)\n  (keyword_increment)\n  (keyword_logged)\n  (keyword_none)\n  (keyword_owned)\n  (keyword_password)\n  (keyword_reset)\n  (keyword_role)\n  (keyword_sequence)\n  (keyword_start)\n  (keyword_restart)\n  (keyword_tablespace)\n  (keyword_until)\n  (keyword_user)\n  (keyword_valid)\n  (keyword_action)\n  (keyword_definer)\n  (keyword_invoker)\n  (keyword_security)\n  (keyword_extension)\n  (keyword_version)\n  (keyword_out)\n  (keyword_inout)\n  (keyword_variadic)\n  (keyword_ordinality)\n  (keyword_session)\n  (keyword_isolation)\n  (keyword_level)\n  (keyword_serializable)\n  (keyword_repeatable)\n  (keyword_read)\n  (keyword_write)\n  (keyword_committed)\n  (keyword_uncommitted)\n  (keyword_deferrable)\n  (keyword_names)\n  (keyword_zone)\n  (keyword_immediate)\n  (keyword_deferred)\n  (keyword_constraints)\n  (keyword_snapshot)\n  (keyword_characteristics)\n  (keyword_off)\n  (keyword_follows)\n  (keyword_precedes)\n  (keyword_each)\n  (keyword_instead)\n  (keyword_of)\n  (keyword_initially)\n  (keyword_old)\n  (keyword_new)\n  (keyword_referencing)\n  (keyword_statement)\n  (keyword_execute)\n  (keyword_procedure)\n  (keyword_copy)\n  (keyword_delimiter)\n  (keyword_encoding)\n  (keyword_escape)\n  (keyword_force_not_null)\n  (keyword_force_null)\n  (keyword_force_quote)\n  (keyword_freeze)\n  (keyword_header)\n  (keyword_match)\n  (keyword_program)\n  (keyword_quote)\n  (keyword_stdin)\n  (keyword_extended)\n  (keyword_main)\n  (keyword_plain)\n  (keyword_storage)\n  (keyword_compression)\n  (keyword_duplicate)\n] @keyword\n\n[\n (keyword_restrict)\n (keyword_unbounded)\n (keyword_unique)\n (keyword_cascade)\n (keyword_delayed)\n (keyword_high_priority)\n (keyword_low_priority)\n (keyword_ignore)\n (keyword_nothing)\n (keyword_check)\n (keyword_option)\n (keyword_local)\n (keyword_cascaded)\n (keyword_wait)\n (keyword_nowait)\n (keyword_metadata)\n (keyword_incremental)\n (keyword_bin_pack)\n (keyword_noscan)\n (keyword_stats)\n (keyword_statistics)\n (keyword_maxvalue)\n (keyword_minvalue)\n] @keyword\n\n[\n  (keyword_int)\n  (keyword_null)\n  (keyword_boolean)\n  (keyword_binary)\n  (keyword_varbinary)\n  (keyword_image)\n  (keyword_bit)\n  (keyword_inet)\n  (keyword_character)\n  (keyword_smallserial)\n  (keyword_serial)\n  (keyword_bigserial)\n  (keyword_smallint)\n  (keyword_mediumint)\n  (keyword_bigint)\n  (keyword_tinyint)\n  (keyword_decimal)\n  (keyword_float)\n  (keyword_double)\n  (keyword_numeric)\n  (keyword_real)\n  (double)\n  (keyword_money)\n  (keyword_smallmoney)\n  (keyword_char)\n  (keyword_nchar)\n  (keyword_varchar)\n  (keyword_nvarchar)\n  (keyword_varying)\n  (keyword_text)\n  (keyword_string)\n  (keyword_uuid)\n  (keyword_json)\n  (keyword_jsonb)\n  (keyword_xml)\n  (keyword_bytea)\n  (keyword_enum)\n  (keyword_date)\n  (keyword_datetime)\n  (keyword_time)\n  (keyword_datetime2)\n  (keyword_datetimeoffset)\n  (keyword_smalldatetime)\n  (keyword_timestamp)\n  (keyword_timestamptz)\n  (keyword_geometry)\n  (keyword_geography)\n  (keyword_box2d)\n  (keyword_box3d)\n  (keyword_interval)\n] @type.builtin\n\n[\n  (keyword_in)\n  (keyword_and)\n  (keyword_or)\n  (keyword_not)\n  (keyword_by)\n  (keyword_on)\n  (keyword_do)\n  (keyword_union)\n  (keyword_except)\n  (keyword_intersect)\n] @keyword.operator\n\n[\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"^\"\n  \":=\"\n  \"=\"\n  \"<\"\n  \"<=\"\n  \"!=\"\n  \">=\"\n  \">\"\n  \"<>\"\n  (op_other)\n  (op_unary_other)\n] @operator\n\n[\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n[\n  \";\"\n  \",\"\n  \".\"\n] @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/sql/textobjects.scm",
    "content": "(comment) @comment.inside\n\n(comment)+ @comment.around\n\n"
  },
  {
    "path": "runtime/queries/sshclientconfig/highlights.scm",
    "content": "(host) @namespace\n(host_value) @string\n\n(match) @namespace\n(match_value) @string\n\n(add_keys_to_agent) @keyword\n(add_keys_to_agent_value) @constant.builtin.boolean\n\n(address_family) @keyword\n(address_family_value) @constant.builtin\n\n(batch_mode) @keyword\n(batch_mode_value) @constant.builtin.boolean\n\n(bind_address) @keyword\n(bind_address_value) @string\n\n(bind_interface) @keyword\n(bind_interface_value) @string\n\n(canonical_domains) @keyword\n(canonical_domains_value) @string\n\n(canonicalize_fallback_local) @keyword\n(canonicalize_fallback_local_value) @constant.builtin.boolean\n\n(canonicalize_hostname) @keyword\n(canonicalize_hostname_value) @constant.builtin\n\n(canonicalize_max_dots) @keyword\n(canonicalize_max_dots_value) @constant.numeric.integer\n\n(canonicalize_permitted_cnames) @keyword\n(canonicalize_permitted_cnames_value) @string\n\n(ca_signature_algorithms) @keyword\n(ca_signature_algorithms_value) @string\n\n(certificate_file) @keyword\n(certificate_file_value) @string.special.path\n\n(challenge_response_authentication) @keyword\n(challenge_response_authentication_value) @constant.builtin.boolean\n\n(check_host_ip) @keyword\n(check_host_ip_value) @constant.builtin.boolean\n\n(cipher) @keyword\n(cipher_value) @string\n\n(ciphers) @keyword\n(ciphers_value) @string\n\n(clear_all_forwardings) @keyword\n(clear_all_forwardings_value) @constant.builtin.boolean\n\n(comment) @comment\n\n(compression) @keyword\n(compression_value) @constant.builtin.boolean\n\n(connect_timeout) @keyword\n(connect_timeout_value) @constant.numeric.integer\n\n(connection_attempts) @keyword\n(connection_attempts_value) @constant.numeric.integer\n\n(control_master) @keyword\n(control_master_value) @constant.builtin\n\n(control_path) @keyword\n(control_path_value) @string.special.path\n\n(control_persist) @keyword\n(control_persist_value) @constant.builtin\n\n(dynamic_forward) @keyword\n(dynamic_forward_value) @string\n\n(enable_ssh_keysign) @keyword\n(enable_ssh_keysign_value) @constant.builtin.boolean\n\n(escape_char) @keyword\n(escape_char_value) @constant.character.escape\n\n(exit_on_forward_failure) @keyword\n(exit_on_forward_failure_value) @constant.builtin.boolean\n\n(fingerprint_hash) @keyword\n(fingerprint_hash_value) @constant.builtin\n\n(fork_after_authentication) @keyword\n(fork_after_authentication_value) @constant.builtin.boolean\n\n(forward_agent) @keyword\n(forward_agent_value) @string\n\n(forward_x11) @keyword\n(forward_x11_value) @constant.builtin.boolean\n\n(forward_x11_timeout) @keyword\n(forward_x11_timeout_value) @constant.numeric.integer\n\n(forward_x11_trusted) @keyword\n(forward_x11_trusted_value) @constant.builtin.boolean\n\n(gateway_ports) @keyword\n(gateway_ports_value) @constant.builtin.boolean\n\n(global_known_hosts_file) @keyword\n(global_known_hosts_file_value) @string.special.path\n\n(gssapi_authentication) @keyword\n(gssapi_authentication_value) @constant.builtin.boolean\n\n(gssapi_client_identity) @keyword\n(gssapi_client_identity_value) @string\n\n(gssapi_delegate_credentials) @keyword\n(gssapi_delegate_credentials_value) @constant.builtin.boolean\n\n(gssapi_kex_algorithms) @keyword\n(gssapi_kex_algorithms_value) @string\n\n(gssapi_key_exchange) @keyword\n(gssapi_key_exchange_value) @constant.builtin.boolean\n\n(gssapi_renewal_forces_rekey) @keyword\n(gssapi_renewal_forces_rekey_value) @constant.builtin.boolean\n\n(gssapi_server_identity) @keyword\n(gssapi_server_identity_value) @string\n\n(gssapi_trust_dns) @keyword\n(gssapi_trust_dns_value) @constant.builtin.boolean\n\n(hash_known_hosts) @keyword\n(hash_known_hosts_value) @constant.builtin.boolean\n\n(host_key_algorithms) @keyword\n(host_key_algorithms_value) @string\n\n(host_key_alias) @keyword\n(host_key_alias_value) @string\n\n(hostbased_accepted_algorithms) @keyword\n(hostbased_accepted_algorithms_value) @string\n\n(hostbased_authentication) @keyword\n(hostbased_authentication_value) @constant.builtin.boolean\n\n(hostname) @keyword\n(hostname_value) @string\n\n(identities_only) @keyword\n(identities_only_value) @constant.builtin.boolean\n\n(identity_agent) @keyword\n(identity_agent_value) @string\n\n(identity_file) @keyword\n(identity_file_value) @string.special.path\n\n(ignore_unknown) @keyword\n(ignore_unknown_value) @string\n\n(include) @function.macro\n(include_value) @string.special.path\n\n(ip_qos) @keyword\n(ip_qos_value) @constant.builtin\n\n(kbd_interactive_authentication) @keyword\n(kbd_interactive_authentication_value) @constant.builtin.boolean\n\n(kbd_interactive_devices) @keyword\n(kbd_interactive_devices_value) @string\n\n(kex_algorithms) @keyword\n(kex_algorithms_value) @string\n\n(known_hosts_command) @keyword\n(known_hosts_command_value) @string\n\n(local_command) @keyword\n(local_command_value) @string\n\n(local_forward) @keyword\n(local_forward_value) @string\n\n(log_level) @keyword\n(log_level_value) @constant.builtin\n\n(log_verbose) @keyword\n(log_verbose_value) @string\n\n(macs) @keyword\n(macs_value) @string\n\n(no_host_authentication_for_localhost) @keyword\n(no_host_authentication_for_localhost_value) @constant.builtin.boolean\n\n(number_of_password_prompts) @keyword\n(number_of_password_prompts_value) @constant.numeric.integer\n\n(password_authentication) @keyword\n(password_authentication_value) @constant.builtin.boolean\n\n(permit_local_command) @keyword\n(permit_local_command_value) @constant.builtin.boolean\n\n(permit_remote_open) @keyword\n(permit_remote_open_value) @string\n\n(pkcs11_provider) @keyword\n(pkcs11_provider_value) @string\n\n(port) @keyword\n(port_value) @constant.numeric.integer\n\n(preferred_authentications) @keyword\n(preferred_authentications_value) @string\n\n(protocol) @keyword\n(protocol_value) @constant.numeric.integer\n\n(proxy_command) @keyword\n(proxy_command_value) @string\n\n(proxy_jump) @keyword\n(proxy_jump_value) @string\n\n(proxy_use_fdpass) @keyword\n(proxy_use_fdpass_value) @constant.builtin.boolean\n\n(pubkey_accepted_algorithms) @keyword\n(pubkey_accepted_algorithms_value) @string\n\n(pubkey_accepted_key_types) @keyword\n(pubkey_accepted_key_types_value) @string\n\n(pubkey_authentication) @keyword\n(pubkey_authentication_value) @constant.builtin\n\n(rekey_limit) @keyword\n(rekey_limit_value) @string\n\n(remote_command) @keyword\n(remote_command_value) @string\n\n(remote_forward) @keyword\n(remote_forward_value) @string\n\n(request_tty) @keyword\n(request_tty_value) @constant.builtin\n\n(revoked_host_keys) @keyword\n(revoked_host_keys_value) @string.special.path\n\n(security_key_provider) @keyword\n(security_key_provider_value) @string\n\n(send_env) @keyword\n(send_env_value) @string\n\n(server_alive_count_max) @keyword\n(server_alive_count_max_value) @constant.numeric.integer\n\n(server_alive_interval) @keyword\n(server_alive_interval_value) @constant.numeric.integer\n\n(session_type) @keyword\n(session_type_value) @constant.builtin\n\n(set_env) @keyword\n(set_env_value) @string\n\n(stdin_null) @keyword\n(stdin_null_value) @constant.builtin.boolean\n\n(stream_local_bind_mask) @keyword\n(stream_local_bind_mask_value) @string\n\n(stream_local_bind_unlink) @keyword\n(stream_local_bind_unlink_value) @constant.builtin.boolean\n\n(strict_host_key_checking) @keyword\n(strict_host_key_checking_value) @constant.builtin\n\n(syslog_facility) @keyword\n(syslog_facility_value) @constant.builtin\n\n(tcp_keep_alive) @keyword\n(tcp_keep_alive_value) @constant.builtin.boolean\n(keep_alive) @keyword\n(keep_alive_value) @constant.builtin.boolean\n\n(tunnel) @keyword\n(tunnel_value) @constant.builtin\n\n(tunnel_device) @keyword\n(tunnel_device_value) @string\n\n(update_host_keys) @keyword\n(update_host_keys_value) @constant.builtin\n\n(use_keychain) @keyword\n(use_keychain_value) @constant.builtin.boolean\n\n(user) @keyword\n(user_value) @string\n\n(user_known_hosts_file) @keyword\n(user_known_hosts_file_value) @string.special.path\n\n(verify_host_key_dns) @keyword\n(verify_host_key_dns_value) @constant.builtin\n\n(visual_host_key) @keyword\n(visual_host_key_value) @constant.builtin.boolean\n\n(xauth_location) @keyword\n(xauth_location_value) @string.special.path\n"
  },
  {
    "path": "runtime/queries/starlark/highlights.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/starlark/indents.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/starlark/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/starlark/rainbows.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/starlark/textobjects.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/strace/highlights.scm",
    "content": "(syscall) @function.builtin\n(integer) @constant.numeric\n(pointer) @constant.numeric\n(value) @label\n(string) @string\n(comment) @comment\n(errorName) @error\n(errorDescription) @error\n"
  },
  {
    "path": "runtime/queries/strictdoc/highlights.scm",
    "content": ";; Tree-sitter highlight queries for strictdoc\n\n;; —————————————————————————————————————————\n;; Keywords “blok” del documento\n;; —————————————————————————————————————————\n[\n  \"[DOCUMENT]\"\n  \"[DOCUMENT_FROM_FILE]\"\n  \"[GRAMMAR]\"\n  \"[/SECTION]\"\n  \"[SECTION]\"\n  (sdoc_node_opening)\n  (sdoc_composite_node_opening)\n  (sdoc_composite_node_closing)\n  (sdoc_composite_node_type_name)\n] @keyword\n\n[\n  \"AUTO_LEVELS\"\n  \"CLASSIFICATION\"\n  \"DATE\"\n  \"DEFAULT_VIEW\"\n  \"ELEMENTS\"\n  \"ENABLE_MID\"\n  \"FIELDS\"\n  \"FILE\"\n  \"FORMAT\"\n  \"IMPORT_FROM_FILE\"\n  \"IS_COMPOSITE\"\n  \"LAYOUT\"\n  \"LEVEL\"\n  \"MARKUP\"\n  \"METADATA\"\n  \"MID\"\n  \"NAME\"\n  \"NODE_IN_TOC\"\n  \"OBJECT_TYPE\"\n  \"OPTIONS\"\n  \"PLACEMENT\"\n  \"PREFIX\"\n  \"PROPERTIES\"\n  \"REQ_PREFIX\"\n  \"REQUIRED\"\n  \"REQUIREMENT_IN_TOC\"\n  \"REQUIREMENT_STYLE\"\n  \"ROLE\"\n  \"ROOT\"\n  \"TAG\"\n  \"TITLE\"\n  \"TYPE\"\n  \"UID\"\n  \"VALUE\"\n  \"VERSION\"\n  \"VIEW_STYLE\"\n  \"VISIBLE_FIELDS\"\n] @type.builtin\n\n;; Operators\n[\n  (multiline_opening_token)\n  (multiline_closing_token)\n] @operator\n\n;; Punctuation\n[\n  \":\" @punctuation.delimiter\n  \",\" @punctuation.delimiter\n  \"-\" @punctuation.delimiter\n]\n\n;; Boolean literals\n(boolean_choice) @constant.builtin.boolean\n\n;; Requirement types and file formats\n\n;; Config option values\n[\n  \"Child\"\n  \"Default\"\n  \"File\"\n  \"HTML\"\n  \"Inline\"\n  \"Narrative\"\n  \"Off\"\n  \"On\"\n  \"Parent\"\n  \"Plain\"\n  \"RST\"\n  \"Simple\"\n  \"Table\"\n  \"Text\"\n  \"Website\"\n  \"Zebra\"\n] @constant.builtin\n\n\n;; Strings\n(single_line_string) @string\n[ (uid_string) (req_reference_value_id) ] @string.special.symbol\n(date) @string.special\n\n;; Fields\n(document_custom_metadata_key) @type.parameter\n[ \"RELATIONS\" (field_name) ] @variable.other.member\n(choice_option) @variable.parameter\n\n;; Anchors and links\n(anchor) @label\n(inline_link) @string.special.url\n\n[\n (role_id)\n] @variable\n"
  },
  {
    "path": "runtime/queries/strictdoc/injections.scm",
    "content": "\n((text_part) @injection.content\n (#set! injection.language \"rst\")\n (#set! injection.include-children))\n\n((single_line_text_part) @injection.content\n (#set! injection.language \"rst\")\n (#set! injection.include-children))\n\n"
  },
  {
    "path": "runtime/queries/strictdoc/tags.scm",
    "content": "; == StrictDoc Code Navigation Queries ==\n\n; -- Document Configuration Definitions --\n(\n(document_config\nuid: (uid_string) @name) @definition.document.uid\n)\n(\n(document_version\nversion: (single_line_string) @name) @definition.document.version\n)\n(\n(document_date\ndate: (date) @name) @definition.document.date\n)\n(\n(document_classification\nclassification: (single_line_string) @name) @definition.document.classification\n)\n(\n(document_requirement\nrequirement_prefix: (single_line_string) @name) @definition.document.requirement_prefix\n)\n(\n(document_config\nroot: (boolean_choice) @name) @definition.document.root\n)\n(\n(document_config\noptions: (document_config_options) @name) @definition.document.options\n)\n(\n(enable_mid\n(boolean_choice) @name) @definition.document.options.enable_mid\n)\n(\n(markup\n(markup_choice) @name) @definition.document.options.markup\n)\n(\n(auto_levels\n(auto_levels_choice) @name) @definition.document.options.auto_levels\n)\n(\n(layout\n(layout_choice) @name) @definition.document.options.layout\n)\n(\n(view_style\n(style_choice) @name) @definition.document.options.view_style\n)\n(\n(in_toc_tag\n(boolean_choice) @name) @definition.document.options.in_toc_tag\n)\n(\n(default_view\n(single_line_string) @name) @definition.document.options.default_view\n)\n(\n(document_config\nmetadata: (document_custom_metadata) @name) @definition.document.metadata\n)\n\n; -- Grammar Definition -- ( (document_grammar) @definition.grammar.document_grammar )\n\n; -- Import From File Reference --\n(\n(import_from_file\nimport_path: (file_path) @name) @reference.grammar.file_path\n)\n\n; -- Grammar Elements Definitions --\n(\n(grammar_elements) @definition.grammar.elements\n)\n(\n(grammar_element) @definition.grammar.element\n)\n\n; -- Grammar Properties Definitions --\n(\n(grammar_properties) @definition.grammar.properties\n)\n(\n(grammar_property_is_composite\n(boolean_choice) @name) @definition.grammar.property.is_composite\n)\n(\n(grammar_property_prefix\n(single_line_string) @name) @definition.grammar.property.prefix\n)\n(\n(grammar_property_view_style\n(style_choice) @name) @definition.grammar.property.view_style\n)\n\n; -- Grammar Fields Definitions --\n(\n(grammar_fields) @definition.grammar.fields\n)\n(\n(grammar_field_title\ntitle: (field_name) @name) @definition.grammar.field.title\n)\n(\n(grammar_field_required\nvalue: (boolean_choice) @name) @definition.grammar.field.required\n)\n(\n(grammar_field_string) @definition.grammar.field.string\n)\n(\n(grammar_field_single_choice) @definition.grammar.field.single_choice\n)\n(\n(grammar_field_multiple_choice) @definition.grammar.field.multiple_choice\n)\n(\n(grammar_field_tag) @definition.grammar.field.tag\n)\n\n; -- Grammar Relations Definitions --\n(\n(grammar_relations) @definition.grammar.relations\n)\n(\n(grammar_relation_parent\n(single_line_string) @name) @definition.grammar.relation.parent\n)\n(\n(grammar_relation_child\n(single_line_string) @name) @definition.grammar.relation.child\n)\n(\n(grammar_relation_file\n(single_line_string) @name) @definition.grammar.relation.file\n)\n\n; -- Document Custom Metadata --\n(\n  (document_custom_metadata) @definition.document.metadata\n)\n(\n  (document_custom_metadata_key_value_pair\n    key: (document_custom_metadata_key) @name\n    value: (single_line_string) @doc) @definition.document.metadata.entry\n)\n\n; -- Document View Definitions --\n(\n(document_view) @definition.document.view\n)\n(\n(view_element\nid: (uid_string) @name) @definition.view.element.id\n)\n(\n(view_element\nname: (single_line_string) @name) @definition.view.element.name\n)\n(\n(view_element_tag\nobject_type: (single_line_string) @name) @definition.view.element.tag.object_type\n)\n(\n(view_element_field\nname: (single_line_string) @name) @definition.view.element.field.name\n)\n(\n(view_element_field\nplacement: (single_line_string) @name) @definition.view.element.field.placement\n)\n(\n(view_element_hidden_tag\nhidden_tag: (single_line_string) @name) @definition.view.element.hidden_tag\n)\n\n; -- Section & Requirement Definitions --\n\n(\n(section_or_requirement_list) @definition.section.list\n)\n(\n  (sdoc_section) @definition.section\n)\n\n(\n  (section_body\n    mid: (single_line_string) @name) @definition.section.mid\n)\n\n(\n(section_body\n  uid: (uid_string) @name) @definition.section.uid\n)\n\n(\n  (section_body\n    custom_level: (single_line_string) @name) @definition.section.level\n)\n\n(\n  (section_body\n    title: (single_line_string) @name) @definition.section.title\n)\n\n(\n  (section_body\n    requirement_prefix: (single_line_string) @name) @definition.section.requirement_prefix\n)\n; -- Document From File Reference --\n(\n(document_from_file\npath: (file_path) @name) @definition.document.from_file\n)\n\n; -- SDoc Node Definitions --\n(\n(sdoc_node) @definition.node\n)\n(\n(sdoc_composite_node) @definition.composite_node\n)\n(\n(sdoc_composite_node_opening\nnode_type_opening: (sdoc_composite_node_type_name) @name) @definition.composite_node.opening\n)\n(\n(sdoc_composite_node_type_name) @definition.composite_node.type\n)\n\n; -- SDoc Node Field Definitions --\n(\n  (sdoc_node_field_mid\n    mid: (single_line_string) @name) @definition.node.mid\n)\n\n(\n  (sdoc_node_field_uid\n    uid: (uid_string) @name) @definition.node.uid\n)\n\n(\n  (sdoc_node_field_generic\n    field_name: (field_name) @name\n  ) @definition.node.field\n)\n\n(\n  (parent_req_reference\n    ref_uid: (req_reference_value_id) @name) @reference.node.uid\n)\n\n(\n  (child_req_reference\n    ref_uid: (req_reference_value_id) @name) @reference.node.uid\n)\n"
  },
  {
    "path": "runtime/queries/styx/highlights.scm",
    "content": "(line_comment) @comment.line\n(doc_comment) @comment.line.documentation\n\n(escape_sequence) @constant.character.escape\n\n(bare_scalar) @string\n(quoted_scalar) @string\n(raw_scalar) @string\n(heredoc) @string\n\n; Heredoc language hint (metadata)\n(heredoc_lang) @label\n\n(unit) @constant.builtin\n\n; Tags - styled same as unit since @ is the tag sigil\n(tag) @constant.builtin\n\n; Attributes - key in attribute syntax\n; Use @keyword or @punctuation.special to make > stand out\n(attribute\n  key: (bare_scalar) @variable.other.member\n  \">\" @keyword)\n\n; Keys in entries - any scalar in the key position (overrides @string above)\n(entry\n  key: (expr\n    payload: (scalar (_) @variable.other.member)))\n\n; Sequence items are values, not keys (must come AFTER entry key rule to override)\n(sequence\n  (expr\n    payload: (scalar (_) @string)))\n\n[\n  \"{\"\n  \"}\"\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n\",\" @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/styx/indents.scm",
    "content": "(object \"}\" @end) @indent\n(sequence \")\" @end) @indent\n"
  },
  {
    "path": "runtime/queries/styx/injections.scm",
    "content": "([(line_comment) (doc_comment)] @injection.content\n (#set! injection.language \"comment\"))\n\n; Heredocs can specify a language: <<SQL,sql\n; The heredoc_lang node captures the language name (e.g., \"sql\")\n; The heredoc_content node contains the actual content to highlight\n(heredoc\n  (heredoc_lang) @injection.language\n  (heredoc_content) @injection.content)\n"
  },
  {
    "path": "runtime/queries/styx/rainbows.scm",
    "content": "[\n  (object)\n  (sequence)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"{\" \"}\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/styx/textobjects.scm",
    "content": "[(line_comment) (doc_comment)] @comment.inside\n\n(line_comment)+ @comment.around\n(doc_comment)+ @comment.around\n\n(entry value: (_) @entry.inside) @entry.around\n"
  },
  {
    "path": "runtime/queries/supercollider/folds.scm",
    "content": "[\n(function_call)\n(code_block)\n(function_block)\n(control_structure)\n] @fold\n\n"
  },
  {
    "path": "runtime/queries/supercollider/highlights.scm",
    "content": "(line_comment) @comment.line\n(block_comment) @comment.block\n\n(argument name: (identifier) @variable.parameter)\n\n(local_var name: (identifier) @variable)\n(environment_var name:(identifier) @variable.builtin)\n(builtin_var) @constant.builtin\n\n(function_definition name: (variable) @function)\n\n(named_argument name: (identifier) @variable.other.member)\n\n(method_call name: (method_name) @function.method)\n\n(class) @keyword.storage.type\n\n(number) @constant.numeric\n(float) @constant.numeric.float\n\n(string) @string\n(symbol) @string.special.symbol\n\n[\n\"&&\"\n\"||\"\n\"&\"\n\"|\"\n\"^\"\n\"==\"\n\"!=\"\n\"<\"\n\"<=\"\n\">\"\n\">=\"\n\"<<\"\n\">>\"\n\"+\"\n\"-\"\n\"*\"\n\"/\"\n\"%\"\n\"=\"\n\"|@|\"\n\"@@\"\n\"@|@\"\n] @operator\n\n[\n\"arg\"\n\"classvar\"\n\"const\"\n\"var\"\n] @keyword\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"|\"\n] @punctuation.bracket\n\n[\n  \";\"\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n(control_structure) @keyword.control.conditional\n\n(escape_sequence) @string.special\n\n(duplicated_statement) @keyword.control.repeat\n"
  },
  {
    "path": "runtime/queries/svelte/folds.scm",
    "content": "; inherits: html\n\n[\n  (if_statement)\n  (else_if_block)\n  (else_block)\n  (each_statement)\n  (await_statement)\n  (then_block)\n  (catch_block)\n  (key_statement)\n  (snippet_statement)\n] @fold\n"
  },
  {
    "path": "runtime/queries/svelte/highlights.scm",
    "content": "; inherits: html\n\n(raw_text) @none\n\n[\n  \"as\"\n  \"key\"\n  \"html\"\n  \"debug\"\n  \"snippet\"\n  \"render\"\n] @keyword\n\n\"const\" @keyword.storage.modifier\n\n[\n  \"if\"\n  \"else if\"\n  \"else\"\n  \"then\"\n  \"await\"\n] @keyword.control.conditional\n\n\"each\" @keyword.control.repeat\n\n\"catch\" @keyword.control.exception\n\n[\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \"#\"\n  \":\"\n  \"/\"\n  \"@\"\n] @punctuation.delimiter\n\n(snippet_name) @function\n"
  },
  {
    "path": "runtime/queries/svelte/indents.scm",
    "content": "[\n  (element)\n  (start_tag)\n  (if_statement)\n  (else_if_block)\n  (else_block)\n  (then_block)\n  (each_statement)\n  (key_statement)\n  (snippet_statement)\n  (await_statement)\n  (style_element)\n  (script_element)\n  (expression)\n] @indent\n\n[\n  (end_tag)\n  (if_end)\n  (each_end)\n  (await_end)\n  (key_end)\n  (snippet_end)\n] @outdent\n"
  },
  {
    "path": "runtime/queries/svelte/injections.scm",
    "content": "; inherits html\n((style_element\n  (start_tag\n    (attribute\n      (attribute_name) @_attr\n      (quoted_attribute_value\n        (attribute_value) @_lang)))\n  (raw_text) @injection.content)\n  (#eq? @_attr \"lang\")\n  (#any-of? @_lang \"scss\" \"postcss\" \"less\")\n  (#set! injection.language \"scss\"))\n\n((svelte_raw_text) @injection.content\n  (#set! injection.language \"typescript\"))\n\n((script_element\n  (start_tag\n    (attribute\n      (attribute_name) @_attr\n      (quoted_attribute_value\n        (attribute_value) @_lang)))\n  (raw_text) @injection.content)\n  (#eq? @_attr \"lang\")\n  (#any-of? @_lang \"ts\" \"typescript\")\n  (#set! injection.language \"typescript\"))\n\n((script_element\n  (start_tag\n    (attribute\n      (attribute_name) @_attr\n      (quoted_attribute_value\n        (attribute_value) @_lang)))\n  (raw_text) @injection.content)\n  (#eq? @_attr \"lang\")\n  (#any-of? @_lang \"js\" \"javascript\")\n  (#set! injection.language \"javascript\"))\n\n((element\n  (start_tag\n    (attribute\n      (attribute_name) @_attr\n      (quoted_attribute_value\n        (attribute_value) @injection.language)))\n  (text) @injection.content)\n  (#eq? @_attr \"lang\")\n  (#eq? @injection.language \"pug\"))\n"
  },
  {
    "path": "runtime/queries/svelte/locals.scm",
    "content": "; inherits: html\n"
  },
  {
    "path": "runtime/queries/svelte/rainbows.scm",
    "content": "; inherits: html\n\n[\n  (if_start)\n  (else_if_start)\n  (else_start)\n  (if_end)\n  (each_start)\n  (each_end)\n  (await_start)\n  (then_start)\n  (catch_start)\n  (await_end)\n  (key_start)\n  (key_end)\n  (snippet_start)\n  (snippet_end)\n  (expression)\n  (html_tag)\n  (const_tag)\n  (debug_tag)\n  (render_tag)\n] @rainbow.scope\n\n[\"{\" \"}\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/svelte/textobjects.scm",
    "content": "; inherits: html\n"
  },
  {
    "path": "runtime/queries/sway/highlights.scm",
    "content": "; -------\n; Basic identifiers\n; -------\n\n; We do not style ? as an operator on purpose as it allows styling ? differently, as many highlighters do. @operator.special might have been a better scope, but @special is already documented so the change would break themes (including the intent of the default theme)\n\"?\" @special\n\n(type_identifier) @type\n(identifier) @variable\n(field_identifier) @variable.other.member\n\n; -------\n; Operators\n; -------\n\n[\n  \"*\"\n  \"'\"\n  \"->\"\n  \"=>\"\n  \"<=\"\n  \"=\"\n  \"==\"\n  \"!\"\n  \"!=\"\n  \"%\"\n  \"%=\"\n  \"&\"\n  \"&=\"\n  \"&&\"\n  \"|\"\n  \"|=\"\n  \"||\"\n  \"^\"\n  \"^=\"\n  \"*\"\n  \"*=\"\n  \"-\"\n  \"-=\"\n  \"+\"\n  \"+=\"\n  \"/\"\n  \"/=\"\n  \">\"\n  \"<\"\n  \">=\"\n  \">>\"\n  \"<<\"\n  \">>=\"\n  \"<<=\"\n  \"@\"\n  \"..\"\n  \"..=\"\n  \"'\"\n] @operator\n\n; -------\n; Paths\n; -------\n\n(use_declaration\n  argument: (identifier) @namespace)\n(use_wildcard\n  (identifier) @namespace)\n(dep_item\n  name: (identifier) @namespace)\n(scoped_use_list\n  path: (identifier)? @namespace)\n(use_list\n  (identifier) @namespace)\n(use_as_clause\n  path: (identifier)? @namespace\n  alias: (identifier) @namespace)\n\n; ---\n; Remaining Paths\n; ---\n\n(scoped_identifier\n  path: (identifier)? @namespace\n  name: (identifier) @namespace)\n(scoped_type_identifier\n  path: (identifier) @namespace)\n\n; ---\n; Primitives\n; ---\n\n(escape_sequence) @constant.character.escape\n(primitive_type) @type.builtin\n(boolean_literal) @constant.builtin.boolean\n(integer_literal) @constant.numeric.integer\n(float_literal) @constant.numeric.float\n(char_literal) @constant.character\n[\n  (string_literal)\n  (raw_string_literal)\n] @string\n[\n  (line_comment)\n  (block_comment)\n] @comment\n\n; ---\n; Extraneous\n; ---\n\n(self) @variable.builtin\n(enum_variant (identifier) @type.enum.variant)\n\n(field_initializer\n  (field_identifier) @variable.other.member)\n(shorthand_field_initializer\n  (identifier) @variable.other.member)\n(shorthand_field_identifier) @variable.other.member\n\n(loop_label\n  \"'\" @label\n  (identifier) @label)\n\n; ---\n; Punctuation\n; ---\n\n[\n  \"::\"\n  \".\"\n  \";\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"#\"\n] @punctuation.bracket\n(type_arguments\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n(type_parameters\n  [\n    \"<\"\n    \">\"\n  ] @punctuation.bracket)\n(closure_parameters\n  \"|\" @punctuation.bracket)\n\n; ---\n; Variables\n; ---\n\n(let_declaration\n  pattern: [\n    ((identifier) @variable)\n    ((tuple_pattern\n      (identifier) @variable))\n  ])\n  \n; It needs to be anonymous to not conflict with `call_expression` further below. \n(_\n value: (field_expression\n  value: (identifier)? @variable\n  field: (field_identifier) @variable.other.member))\n\n(parameter\n\tpattern: (identifier) @variable.parameter)\n(closure_parameters\n\t(identifier) @variable.parameter)\n\n; -------\n; Keywords\n; -------\n\n(for_expression\n  \"for\" @keyword.control.repeat)\n((identifier) @keyword.control\n  (#match? @keyword.control \"^yield$\"))\n\n\"in\" @keyword.control\n\n[\n  \"match\"\n  \"if\"\n  \"else\"\n] @keyword.control.conditional\n\n[\n  \"while\"\n] @keyword.control.repeat\n\n[\n  \"break\"\n  \"continue\"\n  \"return\"\n] @keyword.control.return\n\n[\n  \"contract\"\n  \"script\"\n  \"predicate\"\n] @keyword.other\n\n\"use\" @keyword.control.import\n(dep_item \"dep\" @keyword.control.import !body)\n(use_as_clause \"as\" @keyword.control.import)\n\n(type_cast_expression \"as\" @keyword.operator)\n\n[\n  \"as\"\n  \"pub\"\n  \"dep\"\n\n  \"abi\"\n  \"impl\"\n  \"where\"\n  \"trait\"\n  \"for\"\n] @keyword\n\n[\n  \"struct\"\n  \"enum\"\n  \"storage\"\n  \"configurable\"\n] @keyword.storage.type\n\n\"let\" @keyword.storage\n\"fn\" @keyword.function\n\"abi\" @keyword.function\n\n(mutable_specifier) @keyword.storage.modifier.mut\n\n(reference_type \"&\" @keyword.storage.modifier.ref)\n(self_parameter \"&\" @keyword.storage.modifier.ref)\n\n[\n  \"const\"\n  \"ref\"\n  \"deref\"\n  \"move\"\n] @keyword.storage.modifier\n\n; TODO: variable.mut to highlight mutable identifiers via locals.scm\n\n; -------\n; Guess Other Types\n; -------\n; Other PascalCase identifiers are assumed to be structs.\n\n((identifier) @type\n  (#match? @type \"^[A-Z]\"))\n\n((identifier) @constant\n (#match? @constant \"^[A-Z][A-Z\\\\d_]*$\"))\n\n; ---\n; PascalCase identifiers in call_expressions (e.g. `Ok()`)\n; are assumed to be enum constructors.\n; ---\n\n(call_expression\n  function: [\n    ((identifier) @constructor\n      (#match? @constructor \"^[A-Z]\"))\n    (scoped_identifier\n      name: ((identifier) @constructor\n        (#match? @constructor \"^[A-Z]\")))\n  ])\n\n; ---\n; PascalCase identifiers under a path which is also PascalCase\n; are assumed to be constructors if they have methods or fields.\n; ---\n\n(field_expression\n  value: (scoped_identifier\n    path: [\n      (identifier) @type\n      (scoped_identifier\n        name: (identifier) @type)\n    ]\n    name: (identifier) @constructor\n      (#match? @type \"^[A-Z]\")\n      (#match? @constructor \"^[A-Z]\")))\n\n; -------\n; Functions\n; -------\n\n(call_expression\n  function: [\n    ((identifier) @function)\n    (scoped_identifier\n      name: (identifier) @function)\n    (field_expression\n      field: (field_identifier) @function)\n  ])\n(generic_function\n  function: [\n    ((identifier) @function)\n    (scoped_identifier\n      name: (identifier) @function)\n    (field_expression\n      field: (field_identifier) @function.method)\n  ])\n\n(function_item\n  name: (identifier) @function)\n\n(function_signature_item\n  name: (identifier) @function)\n"
  },
  {
    "path": "runtime/queries/sway/indents.scm",
    "content": "[\n  (use_list)\n  (block)\n  (match_block)\n  (arguments)\n  (parameters)\n  (declaration_list)\n  (field_declaration_list)\n  (field_initializer_list)\n  (struct_pattern)\n  (tuple_pattern)\n  (unit_expression)\n  (enum_variant_list)\n  (call_expression)\n  (binary_expression)\n  (field_expression)\n  (tuple_expression)\n  (array_expression)\n  (where_clause)\n\n  (token_tree)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n\n; Indent the right side of assignments.\n; The #not-same-line? predicate is required to prevent an extra indent for e.g.\n; an else-clause where the previous if-clause starts on the same line as the assignment.\n(assignment_expression\n  .\n  (_) @expr-start\n  right: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(compound_assignment_expr\n  .\n  (_) @expr-start\n  right: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(let_declaration\n  .\n  (_) @expr-start\n  value: (_) @indent\n  alternative: (_)? @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n(if_expression\n  .\n  (_) @expr-start\n  condition: (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n\n; Some field expressions where the left part is a multiline expression are not\n; indented by cargo fmt.\n; Because this multiline expression might be nested in an arbitrary number of\n; field expressions, this can only be matched using a Regex.\n(field_expression\n  value: (_) @val\n  \".\" @outdent\n  (#match? @val \"(\\\\A[^\\\\n\\\\r]+\\\\([\\\\t ]*(\\\\n|\\\\r).*)|(\\\\A[^\\\\n\\\\r]*\\\\{[\\\\t ]*(\\\\n|\\\\r))\")\n)\n"
  },
  {
    "path": "runtime/queries/sway/injections.scm",
    "content": "([(line_comment) (block_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/sway/locals.scm",
    "content": "; Scopes\n\n[\n  (function_item)\n  (closure_expression)\n  (block)\n] @local.scope\n\n; Definitions\n\n(parameter\n  (identifier) @local.definition.variable.parameter)\n\n(closure_parameters (identifier) @local.definition.variable.parameter)\n\n; References\n(identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/sway/textobjects.scm",
    "content": "(function_item\n  body: (_) @function.inside) @function.around(closure_expression body: (_) @function.inside) @function.around\n\n(struct_item\n  body: (_) @class.inside) @class.around\n\n(enum_item\n  body: (_) @class.inside) @class.around\n\n(trait_item\n  body: (_) @class.inside) @class.around\n\n(impl_item\n  body: (_) @class.inside) @class.around\n\n(parameters \n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(type_arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(closure_parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n[\n  (line_comment)\n  (block_comment)\n] @comment.inside\n\n(line_comment)+ @comment.around\n\n(block_comment) @comment.around\n\n(; #[test]\n (attribute_item\n   (attribute\n     (identifier) @_test_attribute))\n ; allow other attributes like #[should_panic] and comments\n [\n   (attribute_item)\n   (line_comment)\n ]*\n ; the test function\n (function_item\n   body: (_) @test.inside) @test.around\n (#eq? @_test_attribute \"test\"))\n"
  },
  {
    "path": "runtime/queries/swift/highlights.scm",
    "content": "; Upstream: https://github.com/alex-pinkus/tree-sitter-swift/blob/57c1c6d6ffa1c44b330182d41717e6fe37430704/queries/highlights.scm\n\n(line_string_literal\n  [\"\\\\(\" \")\"] @punctuation.special)\n\n[\".\" \";\" \":\" \",\" ] @punctuation.delimiter\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\" \"<\" \">\"] @punctuation.bracket\n\n; Operators\n[\n  \"!\"\n  \"?\"\n  \"+\"\n  \"-\"\n  \"\\\\\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"=\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"<\"\n  \">\"\n  \"<=\"\n  \">=\"\n  \"++\"\n  \"--\"\n  \"&\"\n  \"~\"\n  \"%=\"\n  \"!=\"\n  \"!==\"\n  \"==\"\n  \"===\"\n  \"??\"\n\n  \"->\"\n\n  \"..<\"\n  \"...\"\n  (custom_operator)\n] @operator\n\n\"?\" @type\n(type_annotation \"!\" @type)\n\n; Identifiers\n(simple_identifier) @variable\n(attribute) @variable\n(type_identifier) @type\n(self_expression) @variable.builtin\n(user_type (type_identifier) @variable.builtin (#eq? @variable.builtin \"Self\"))\n\n; Declarations\n\"func\" @keyword.function\n[\n  (visibility_modifier)\n  (member_modifier)\n  (function_modifier)\n  (property_modifier)\n  (parameter_modifier)\n  (inheritance_modifier)\n] @keyword\n\n(function_declaration (simple_identifier) @function.method)\n(protocol_function_declaration (simple_identifier) @function.method)\n(init_declaration [\"init\" @constructor])\n(deinit_declaration [\"deinit\" @constructor])\n\n(throws) @keyword\n\"async\" @keyword\n\"await\" @keyword\n(where_keyword) @keyword\n(parameter external_name: (simple_identifier) @variable.parameter)\n(parameter name: (simple_identifier) @variable.parameter)\n(type_parameter (type_identifier) @variable.parameter)\n(inheritance_constraint (identifier (simple_identifier) @variable.parameter))\n(equality_constraint (identifier (simple_identifier) @variable.parameter))\n(pattern bound_identifier: (simple_identifier)) @variable\n\n[\n  \"typealias\"\n  \"struct\"\n  \"class\"\n  \"actor\"\n  \"enum\"\n  \"protocol\"\n  \"extension\"\n  \"indirect\"\n  \"nonisolated\"\n  \"override\"\n  \"convenience\"\n  \"required\"\n  \"mutating\"\n  \"associatedtype\"\n  \"package\"\n  \"any\"\n] @keyword\n\n(opaque_type [\"some\" @keyword])\n(existential_type [\"any\" @keyword])\n\n(precedence_group_declaration\n [\"precedencegroup\" @keyword]\n (simple_identifier) @type)\n(precedence_group_attribute\n (simple_identifier) @keyword\n [(simple_identifier) @type\n  (boolean_literal) @constant.builtin.boolean])\n\n[\n  (getter_specifier)\n  (setter_specifier)\n  (modify_specifier)\n] @keyword\n\n(class_body (property_declaration (pattern (simple_identifier) @variable.other.member)))\n(protocol_property_declaration (pattern (simple_identifier) @variable.other.member))\n\n(import_declaration \"import\" @keyword.control.import)\n\n(enum_entry \"case\" @keyword)\n\n; Function calls\n(call_expression (simple_identifier) @function) ; foo()\n(call_expression ; foo.bar.baz(): highlight the baz()\n  (navigation_expression\n    (navigation_suffix (simple_identifier) @function)))\n((navigation_expression\n   (simple_identifier) @type) ; SomeType.method(): highlight SomeType as a type\n   (#match? @type \"^[A-Z]\"))\n(call_expression (simple_identifier) @keyword (#eq? @keyword \"defer\")) ; defer { ... }\n\n(navigation_suffix\n  (simple_identifier) @variable.other.member)\n\n(try_operator) @operator\n(try_operator [\"try\" @keyword])\n\n(directive) @function.macro\n(diagnostic) @function.macro\n\n; Statements\n(for_statement \"for\" @keyword.control.repeat)\n(for_statement \"in\" @keyword.control.repeat)\n(for_statement item: (simple_identifier) @variable)\n(else) @keyword\n(as_operator) @keyword\n\n[\"while\" \"repeat\" \"continue\" \"break\"] @keyword.control.repeat\n\n[\"let\" \"var\"] @keyword\n\n(guard_statement \"guard\" @keyword.control.conditional)\n(if_statement \"if\" @keyword.control.conditional)\n(switch_statement \"switch\" @keyword.control.conditional)\n(switch_entry \"case\" @keyword)\n(switch_entry \"fallthrough\" @keyword)\n(switch_entry (default_keyword) @keyword)\n\"return\" @keyword.return\n(ternary_expression\n  [\"?\" \":\"] @keyword.control.conditional)\n\n[\"do\" (throw_keyword) (catch_keyword)] @keyword\n\n(statement_label) @label\n\n; Comments\n(comment) @comment\n(multiline_comment) @comment\n\n; String literals\n(line_str_text) @string\n(str_escaped_char) @string\n(multi_line_str_text) @string\n(raw_str_part) @string\n(raw_str_end_part) @string\n(raw_str_interpolation_start) @punctuation.special\n[\"\\\"\" \"\\\"\\\"\\\"\"] @string\n\n; Lambda literals\n(lambda_literal \"in\" @keyword.operator)\n\n; Basic literals\n[\n  (hex_literal)\n  (oct_literal)\n  (bin_literal)\n] @constant.numeric\n(integer_literal) @constant.numeric.integer\n(real_literal) @constant.numeric.float\n(boolean_literal) @constant.builtin.boolean\n\"nil\" @constant.builtin\n\n(value_parameter_pack [\"each\" @keyword])\n(value_pack_expansion [\"repeat\" @keyword])\n(type_parameter_pack [\"each\" @keyword])\n(type_pack_expansion [\"repeat\" @keyword])\n"
  },
  {
    "path": "runtime/queries/swift/indents.scm",
    "content": "[\n  (protocol_body)\n  (class_body)\n  (enum_class_body)\n  (function_declaration)\n  (init_declaration)\n  (deinit_declaration)\n  (computed_property)\n  (subscript_declaration)\n  (computed_getter)\n  (computed_setter)\n  (for_statement)\n  (while_statement)\n  (repeat_while_statement)\n  (do_statement)\n  (if_statement)\n  (switch_statement)\n  (guard_statement)\n  (type_parameters)\n  (tuple_type)\n  (array_type)\n  (dictionary_type)\n  (call_expression)\n  (tuple_expression)\n  (array_literal)\n  (dictionary_literal)\n  (lambda_literal)\n  (willset_didset_block)\n  (willset_clause)\n  (didset_clause)\n  (value_arguments)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n  \">\"\n] @outdent\n\n(assignment\n  .\n  (_) @expr-start\n  (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n\n(control_transfer_statement\n  .\n  (_) @expr-start\n  (_) @indent\n  (#not-same-line? @indent @expr-start)\n  (#set! \"scope\" \"all\")\n)\n\n(if_statement\n  (if_statement) @outdent\n)\n\n(switch_entry\n  .\n  _ @indent\n  (#set! \"scope\" \"tail\")\n)\n\n(init_declaration\n  (parameter) @indent\n)\n\n(modifiers\n  (attribute) @indent\n)\n\n(type_parameters\n  \">\" @outdent\n)\n\n(tuple_expression\n  \")\" @outdent\n)\n\n(tuple_type\n  \")\" @outdent\n)\n\n(modifiers\n  (attribute\n    \")\" @outdent\n  )\n)\n\n(ERROR\n  [\n    \"<\"\n    \"{\"\n    \"(\"\n    \"[\"\n  ]\n) @indent\n"
  },
  {
    "path": "runtime/queries/swift/injections.scm",
    "content": "; Upstream: https://github.com/alex-pinkus/tree-sitter-swift/blob/57c1c6d6ffa1c44b330182d41717e6fe37430704/queries/injections.scm\n\n; Parse regex syntax within regex literals\n\n((regex_literal) @injection.content\n (#set! injection.language \"regex\"))\n\n((comment) @injection.content\n (#set! injection.language \"comment\")\n (#set! injection.include-children))\n"
  },
  {
    "path": "runtime/queries/swift/locals.scm",
    "content": "; Upstream: https://github.com/alex-pinkus/tree-sitter-swift/blob/57c1c6d6ffa1c44b330182d41717e6fe37430704/queries/locals.scm\n(import_declaration (identifier) @local.definition.namespace)\n(function_declaration name: (simple_identifier) @local.definition.function)\n\n; Scopes\n[\n (for_statement)\n (while_statement)\n (repeat_while_statement)\n (do_statement)\n (if_statement)\n (guard_statement)\n (switch_statement)\n (property_declaration)\n (function_declaration)\n (class_declaration)\n (protocol_declaration)\n (lambda_literal)\n] @local.scope\n"
  },
  {
    "path": "runtime/queries/swift/rainbows.scm",
    "content": "[\n  (array_literal)\n  (array_type)\n  (attribute)\n  (availability_condition)\n  (call_expression)\n  (call_suffix)\n  (catch_block)\n  (class_body)\n  (class_declaration)\n  (computed_getter)\n  (computed_property)\n  (computed_setter)\n  (dictionary_literal)\n  (dictionary_type)\n  (didset_clause)\n  (do_statement)\n  (enum_class_body)\n  (enum_entry)\n  (enum_type_parameters)\n  (for_statement)\n  (function_body)\n  (function_declaration)\n  (guard_statement)\n  (if_statement)\n  (init_declaration)\n  (lambda_literal)\n  (line_string_literal)\n  (modifiers)\n  (navigation_expression)\n  (optional_type)\n  (pattern)\n  (protocol_body)\n  (protocol_declaration)\n  (protocol_function_declaration)\n  (protocol_property_requirements)\n  (property_declaration)\n  (source_file)\n  (statements)\n  (subscript_declaration)\n  (switch_entry)\n  (switch_pattern)\n  (switch_statement)\n  (tuple_expression)\n  (tuple_type)\n  (tuple_type_item)\n  (type_annotation)\n  (value_arguments)\n  (visibility_modifier)\n  (while_statement)\n  (willset_didset_block)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"[\" \"]\"\n  \"{\" \"}\"\n  \"<\" \">\"\n  \"\\\\(\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/swift/textobjects.scm",
    "content": "(class_declaration\n  body: (_) @class.inside) @class.around\n\n(protocol_declaration\n  body: (_) @class.inside) @class.around\n\n(function_declaration\n  body: (_) @function.inside) @function.around\n\n(parameter\n  (_) @parameter.inside) @parameter.around\n\n(lambda_parameter\n  (_) @parameter.inside) @parameter.around\n\n[\n  (comment)\n  (multiline_comment)\n] @comment.inside\n\n(comment)+ @comment.around\n\n(multiline_comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/systemd/highlights.scm",
    "content": "; inherits: ini\n"
  },
  {
    "path": "runtime/queries/systemd/injections.scm",
    "content": "; inherits: ini\n"
  },
  {
    "path": "runtime/queries/systemd/tags.scm",
    "content": "; inherits: ini\n"
  },
  {
    "path": "runtime/queries/systemverilog/highlights.scm",
    "content": ";; Comments\n(one_line_comment) @comment\n(block_comment) @comment\n\n\n;; Strings\n(string_literal) @string\n(quoted_string) @string ; `include strings\n(system_lib_string) @string\n\n\n;; Keywords\n([\"begin\" \"end\" \"this\"]) @keyword\n([\"input\" \"output\" \"inout\" \"ref\"]) @keyword\n([\"alias\" \"and\" \"assert\" \"assign\" \"assume\" \"before\" \"bind\" \"binsof\" \"break\"\n  \"case\" \"checker\" \"class\" \"class\" \"clocking\" \"config\" \"const\" \"constraint\"\n  \"cover\" \"covergroup\" \"coverpoint\" \"cross\" \"default\" \"defparam\" \"disable\"\n  \"do\" \"else\" \"endcase\" \"endchecker\" \"endclass\" \"endclocking\" \"endconfig\"\n  \"endfunction\" \"endgenerate\" \"endgroup\" \"endinterface\" \"endmodule\"\n  \"endpackage\" \"endprogram\" \"endproperty\" \"endsequence\" \"endtask\" \"enum\"\n  \"extends\" \"extern\" \"final\" \"first_match\" \"for\" \"force\" \"foreach\" \"forever\"\n  \"fork\" \"forkjoin\" \"function\" \"generate\" \"genvar\" \"if\" \"iff\" \"illegal_bins\"\n  \"implements\" \"import\" \"initial\" \"inside\" \"interconnect\" \"interface\"\n  \"intersect\" \"join\" \"join_any\" \"join_none\" \"local\" \"localparam\" \"matches\"\n  \"modport\" \"new\" \"null\" \"option\" \"or\" \"package\" \"packed\" \"parameter\"\n  \"program\" \"property\" \"pure\" \"randcase\" \"randomize\" \"release\" \"repeat\"\n  \"return\" \"sequence\" \"showcancelled\" \"soft\" \"solve\" \"struct\" \"super\" \"tagged\"\n  \"task\" \"timeprecision\" \"timeunit\" \"type\" \"typedef\" \"union\" \"unique\"\n  \"virtual\" \"wait\" \"while\" \"with\"\n  (always_keyword)             ; always, always_comb, always_latch, always_ff\n  (bins_keyword)               ; bins, illegal_bins, ignore_bins\n  (case_keyword)               ; case, casez, casex\n  (class_item_qualifier)       ; static, protected, local\n  (edge_identifier)            ; posedge, negedge, edge\n  (lifetime)                   ; static, automatic\n  (module_keyword)             ; module, macromodule\n  (random_qualifier)           ; rand, randc\n  (unique_priority)]) @keyword ; unique, unique0, priority\n\n\n;; Preprocessor directives and macro usage\n([\"`include\" \"`define\" \"`ifdef\" \"`ifndef\" \"`timescale\" \"`default_nettype\"\n  \"`elsif\" \"`undef\" (resetall_compiler_directive) (undefineall_compiler_directive)\n  \"`endif\" \"`else\" \"`unconnected_drive\" (celldefine_compiler_directive)\n  (endcelldefine_compiler_directive) (endkeywords_directive) \"`line\"\n  \"`begin_keywords\" \"`pragma\" \"`__FILE__\" \"`__LINE__\"]) @string.special\n(text_macro_usage\n (simple_identifier) @string.special)\n\n\n;; Delimiters, operators\n([\";\" \":\" \",\" \"::\"\n  \"=\" \"?\" \"|=\" \"&=\" \"^=\"\n  \"|->\" \"|=>\" \"->\"\n  \":=\" \":/\" \"-:\" \"+:\"]) @punctuation.delimiter\n([\"(\" \")\"]) @punctuation.bracket\n([\"[\" \"]\"]) @punctuation.bracket\n([\"{\" \"}\" \"'{\"]) @punctuation.bracket\n\n([\".\"] @operator)\n([\"+\" \"-\" \"*\" \"/\" \"%\" \"**\"]) @operator\n([\"<\" \"<=\" \">\" \">=\"]) @operator\n([\"===\" \"!==\" \"==\" \"!=\"]) @operator\n([\"&&\" \"||\" \"!\"]) @operator\n([\"~\" \"&\" \"~&\" \"|\" \"~|\" \"^\" \"~^\"]) @operator\n([\"<<\" \">>\" \"<<<\" \">>>\"]) @operator\n\n([\"@\" \"#\" \"##\"]) @operator\n(assignment_operator) @operator\n(unary_operator) @operator\n(inc_or_dec_operator) @operator\n(stream_operator) @operator\n(event_trigger) @operator\n([\"->\" \"->>\"]) @operator\n\n\n;; Declarations\n;; Module/interface/program/package/class/checker\n(module_nonansi_header\n name: (simple_identifier) @function)\n(module_ansi_header\n name: (simple_identifier) @function)\n(interface_nonansi_header\n name: (simple_identifier) @function)\n(interface_ansi_header\n name: (simple_identifier) @function)\n(program_nonansi_header\n name: (simple_identifier) @function)\n(program_ansi_header\n name: (simple_identifier) @function)\n(package_declaration\n name: (simple_identifier) @function)\n(class_declaration\n name: (simple_identifier) @function)\n(interface_class_declaration\n name: (simple_identifier) @function)\n(checker_declaration\n name: (simple_identifier) @function)\n(class_declaration\n (class_type\n  (simple_identifier) @type)) ; Parent class\n;; Function/task/methods\n(function_body_declaration\n name: (simple_identifier) @function)\n(task_body_declaration\n name: (simple_identifier) @function)\n(function_prototype\n (data_type_or_void)\n name: (simple_identifier) @function)\n(task_prototype\n name: (simple_identifier) @function)\n(class_scope ; Definition of extern defined methods\n (class_type\n  (simple_identifier)) @function)\n\n\n;; Types\n[(integer_vector_type) ; bit, logic, reg\n  (integer_atom_type)   ; byte, shortint, int, longint, integer, time\n  (non_integer_type)    ; shortreal, real, realtime\n  (net_type)            ; supply0, supply1, tri, triand, trior, trireg, tri0, tri1, uwire, wire, wand, wor\n  [\"string\" \"event\" \"signed\" \"unsigned\" \"chandle\"]] @type\n(data_type_or_implicit\n (data_type\n  (simple_identifier)) @type)\n(data_type\n (class_type\n  (simple_identifier) @type\n  (parameter_value_assignment)))\n(data_type\n (class_type\n  (simple_identifier) @operator\n  (simple_identifier) @type))\n(net_port_header\n (net_port_type\n  (simple_identifier) @type))\n(variable_port_header\n (variable_port_type\n  (data_type\n   (simple_identifier) @type)))\n([\"void'\" (data_type_or_void)]) @type ; void cast of task called as a function\n(interface_port_header ; Interfaces with modports\n interface_name: (simple_identifier) @type\n modport_name: (simple_identifier) @type)\n(type_assignment\n name: (simple_identifier) @type)\n(net_declaration ; User type variable declaration\n (simple_identifier) @type)\n(enum_base_type ; Enum base type with user type\n (simple_identifier) @type)\n\n\n;; Instances\n;; Module names\n(module_instantiation\n instance_type: (simple_identifier) @namespace)\n(interface_instantiation\n instance_type: (simple_identifier) @namespace)\n(program_instantiation\n instance_type: (simple_identifier) @namespace)\n(checker_instantiation\n instance_type: (simple_identifier) @namespace)\n(udp_instantiation\n instance_type: (simple_identifier) @namespace)\n(gate_instantiation\n [(cmos_switchtype)\n  (mos_switchtype)\n  (enable_gatetype)\n  (n_input_gatetype)\n  (n_output_gatetype)\n  (pass_en_switchtype)\n  (pass_switchtype)\n  \"pulldown\" \"pullup\"]\n @namespace)\n;; Instance names\n(name_of_instance\n instance_name: (simple_identifier) @constant)\n;; Instance parameters\n(module_instantiation\n (parameter_value_assignment\n  (list_of_parameter_value_assignments\n   (named_parameter_assignment\n    (simple_identifier) @constant))))\n(module_instantiation\n (parameter_value_assignment\n  (list_of_parameter_value_assignments\n   (ordered_parameter_assignment\n    (param_expression\n     (data_type\n      (simple_identifier) @constant))))))\n;; Port names\n(named_port_connection\n port_name: (simple_identifier) @constant)\n(named_parameter_assignment\n (simple_identifier) @constant)\n(named_checker_port_connection\n port_name: (simple_identifier) @constant)\n;; Bind statements\n(bind_directive\n (bind_target_scope\n  (simple_identifier) @constant))\n\n\n;; Numbers\n(hex_number\n size: (unsigned_number) @constant.numeric\n base: (hex_base) @punctuation.delimiter)\n(decimal_number\n size: (unsigned_number) @constant.numeric\n base: (decimal_base) @punctuation.delimiter)\n(octal_number\n size: (unsigned_number) @constant.numeric\n base: (octal_base) @punctuation.delimiter)\n(binary_number\n size: (unsigned_number) @constant.numeric\n base: (binary_base) @punctuation.delimiter)\n;; Same as before but without the width (width extension)\n(hex_number\n base: (hex_base) @punctuation.delimiter)\n(decimal_number\n base: (decimal_base) @punctuation.delimiter)\n(octal_number\n base: (octal_base) @punctuation.delimiter)\n(binary_number\n base: (binary_base) @punctuation.delimiter)\n\n\n;; Arrays\n(unpacked_dimension\n [(constant_expression) (constant_range)] @constant.numeric)\n(packed_dimension\n (constant_range) @constant.numeric)\n(select\n (constant_range) @constant.numeric)\n(constant_select\n (constant_range\n  (constant_expression) @constant.numeric))\n(constant_bit_select\n (constant_expression) @constant.numeric)\n(bit_select\n (expression) @constant.numeric)\n(indexed_range\n (expression) @constant.numeric\n (constant_expression) @constant.numeric)\n(constant_indexed_range\n (constant_expression) @constant.numeric)\n(value_range ; inside {[min_range:max_range]}, place here to apply override\n (expression) @constant)\n(dynamic_array_new\n (expression) @constant)\n\n\n;; Misc\n;; Timeunit\n((time_unit) @constant.builtin)\n;; Enum labels\n(enum_name_declaration\n (simple_identifier) @constant.builtin)\n;; Case item label (not radix)\n(case_item_expression\n (expression\n  (primary\n   (hierarchical_identifier\n    (simple_identifier) @constant.builtin))))\n;; Hierarchical references, interface signals, class members, package scope\n(hierarchical_identifier\n (simple_identifier) @punctuation.delimiter\n \".\"\n (simple_identifier))\n(method_call\n (primary) @punctuation.delimiter\n ([\".\" \"::\"])\n (method_call_body))\n(package_scope\n (simple_identifier) @punctuation.delimiter)\n(method_call\n (primary\n  (select\n   (simple_identifier) @punctuation.delimiter))\n (method_call_body))\n;; Attributes\n([\"(*\" \"*)\"] @constant)\n(attribute_instance\n (attr_spec (simple_identifier) @attribute))\n;; Typedefs\n(type_declaration\n (class_type (simple_identifier) @type)\n type_name: (simple_identifier) @constant)\n(type_declaration\n type_name: (simple_identifier) @constant)\n(\"typedef\" \"class\" (simple_identifier) @constant)\n;; Coverpoint & cross labels\n(cover_point\n name: (simple_identifier) @constant)\n(cover_cross\n name: (simple_identifier) @constant)\n;; Loop variables (foreach[i])\n(loop_variables\n (simple_identifier) @constant)\n;; Bins values\n(bins_or_options\n (expression\n  (primary\n   (concatenation\n    (expression) @constant))))\n;; Bins ranges\n(covergroup_value_range\n (expression) @constant)\n;; Queue dimension\n((\"$\") @punctuation.special)\n;; Parameterized classes (e.g: uvm_config_db #(axi_stream_agent_config))\n(class_type\n (parameter_value_assignment\n  (list_of_parameter_value_assignments) @punctuation.delimiter))\n\n\n;; System-tf\n([(system_tf_identifier)               ; System task/function\n  \"$fatal\" \"$error\" \"$warning\" \"$info\" ; (severity_system_task)\n  \"$stop\" \"$finish\" \"$exit\"])          ; (simulation_control_task)\n@function.builtin\n"
  },
  {
    "path": "runtime/queries/t32/highlights.scm",
    "content": "; Operators in command and conditional HLL expressions\n(hll_comma_expression\n  \",\" @operator)\n\n(hll_conditional_expression\n  [\n   \"?\"\n   \":\"\n] @operator)\n\n\n; Keywords, punctuation and operators\n[\n  \"enum\"\n  \"struct\"\n  \"union\"\n] @keyword.storage.type\n\n\"sizeof\" @keyword.operator\n\n[\n  \"const\"\n  \"volatile\"\n] @keyword.storage.modifier\n\n[\n  \"=\"\n  \"^^\"\n  \"||\"\n  \"&&\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"|\"\n  \"^\"\n  \"==\"\n  \"!=\"\n  \">\"\n  \">=\"\n  \"<=\"\n  \"<\"\n  \"<<\"\n  \">>\"\n  \"..\"\n  \"--\"\n  \"++\"\n  \"+\"\n  \"-\"\n  \"~\"\n  \"!\"\n  \"&\"\n  \"->\"\n  \"*\"\n  \"-=\"\n  \"+=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \"|=\"\n  \"&=\"\n  \"^=\"\n  \">>=\"\n  \"<<=\"\n  \"--\"\n  \"++\"\n] @operator\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \".\"\n] @punctuation.delimiter\n\n; HLL variables\n(identifier) @variable\n(hll_field_identifier) @variable.other.member\n\n\n; Strings and others literal types\n(access_class) @constant.builtin\n\n[\n  (address)\n  (bitmask)\n  (file_handle)\n  (integer)\n  (hll_number_literal)\n] @constant.numeric.integer\n\n[\n  (float)\n  (frequency)\n  (percentage)\n  (time)\n] @constant.numeric.float\n\n[\n  (string)\n  (hll_string_literal)\n] @string\n\n(hll_escape_sequence) @constant.character.escape\n\n(path) @string.special.path\n(symbol) @string.special.symbol\n\n[\n  (character)\n  (hll_char_literal)\n] @constant.character\n\n\n; Types in HLL expressions\n[\n  (hll_type_identifier)\n  (hll_type_descriptor)\n] @type\n\n(hll_type_qualifier) @keyword.storage.modifier\n\n(hll_primitive_type) @type.builtin\n\n\n; HLL call expressions\n(hll_call_expression\n  function: (hll_field_expression\n    field: (hll_field_identifier) @function))\n\n(hll_call_expression\n  function: (identifier) @function)\n\n\n; Returns\n(\n  (command_expression\n    command: (identifier) @keyword.return)\n  (#match? @keyword.return \"^[eE][nN][dD]([dD][oO])?$\")\n)\n(\n  (command_expression\n    command: (identifier) @keyword.return)\n  (#match? @keyword.return \"^[rR][eE][tT][uU][rR][nN]$\")\n)\n\n\n; Subroutine calls\n(subroutine_call_expression\n  command: (identifier) @keyword\n  subroutine: (identifier) @function)\n\n\n; Subroutine blocks\n(subroutine_block\n  command: (identifier) @keyword\n  subroutine: (identifier) @function)\n\n(labeled_expression\n  label: (identifier) @function\n  (block))\n\n\n; Parameter declarations\n(parameter_declaration\n  command: (identifier) @keyword\n  (identifier)? @constant.builtin\n  macro: (macro) @variable.parameter)\n\n\n; Variables, constants and labels\n(macro) @variable.builtin\n(trace32_hll_variable) @variable.builtin\n\n(\n  (command_expression\n    command: (identifier) @keyword\n    arguments: (argument_list . (identifier) @label))\n  (#match? @keyword \"^[gG][oO][tT][oO]$\")\n)\n(labeled_expression\n  label: (identifier) @label)\n\n(option_expression\n  (identifier) @constant.builtin)\n\n(format_expression\n  (identifier) @constant.builtin)\n\n(\n  (argument_list (identifier) @constant.builtin)\n  (#match? @constant.builtin \"^[%/][a-zA-Z][a-zA-Z0-9.]*$\")\n)\n(argument_list\n  (identifier) @constant.builtin)\n\n\n; Commands\n(command_expression command: (identifier) @keyword)\n(macro_definition command: (identifier) @keyword)\n\n(call_expression\n  function: (identifier) @function.builtin)\n\n\n; Control flow\n(if_block\n  command: (identifier) @keyword.control.conditional.if)\n(else_block\n  command: (identifier) @keyword.control.control.else)\n\n(while_block\n  command: (identifier) @keyword.control.repeat.while)\n(repeat_block\n  command: (identifier) @keyword.control.loop)\n\n\n\n(comment) @comment\n"
  },
  {
    "path": "runtime/queries/t32/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/tablegen/highlights.scm",
    "content": "[\n  (comment)\n  (multiline_comment)\n] @comment\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n  \"<\"\n  \">\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \";\"\n  \".\"\n] @punctuation.delimiter\n\n[\n  \"#\"\n  \"-\"\n  \"...\"\n  \":\"\n] @operator\n\n[\n  \"=\"\n  \"!cond\"\n  (operator_keyword)\n] @function\n\n[\n  \"true\"\n  \"false\"\n] @constant.builtin.boolean\n\n[\n  \"?\"\n] @constant.builtin\n\n(var) @variable\n\n(template_arg (identifier) @variable.parameter)\n\n(_ argument: (value (identifier) @variable.parameter))\n\n(type) @type\n\n\"code\" @type.builtin\n\n(number) @constant.numeric.integer\n[\n  (string_string)\n  (code_string)\n] @string\n\n(preprocessor) @keyword.directive\n\n[\n  \"class\"\n  \"field\"\n  \"let\"\n  \"defvar\"\n  \"def\"\n  \"defset\"\n  \"defvar\"\n  \"deftype\"\n  \"assert\"\n  \"dump\"\n] @keyword\n\n[\n  \"let\"\n  \"in\"\n  \"foreach\"\n  \"if\"\n  \"then\"\n  \"else\"\n] @keyword.operator\n\n\"include\" @keyword.control.import\n\n[\n  \"multiclass\"\n  \"defm\"\n] @namespace\n"
  },
  {
    "path": "runtime/queries/tablegen/indents.scm",
    "content": "(statement) @indent\n\n\"}\" @outdent\n"
  },
  {
    "path": "runtime/queries/tablegen/injections.scm",
    "content": "([ (comment) (multiline_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/tablegen/textobjects.scm",
    "content": "(class\n  body: (_) @class.inside) @class.around\n\n(multiclass\n  body: (_) @class.inside) @class.around\n\n(_ argument: _ @parameter.inside)\n\n[\n  (comment)\n  (multiline_comment)\n] @comment.inside\n\n(comment)+ @comment.around\n\n(multiline_comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/tact/highlights.scm",
    "content": "; See: https://docs.helix-editor.com/master/themes.html#syntax-highlighting\n; -------------------------------------------------------------------------\n\n; attribute\n; ---------\n\n[\n  \"@name\"\n  \"@interface\"\n] @attribute\n\n; operator\n; --------\n\n[\n  \"-\" \"-=\"\n  \"+\" \"+=\"\n  \"*\" \"*=\"\n  \"/\" \"/=\"\n  \"%\" \"%=\"\n  \"=\" \"==\"\n  \"!\" \"!=\" \"!!\"\n  \"<\" \"<=\" \"<<\"\n  \">\" \">=\" \">>\"\n  \"&\" \"|\"\n  \"&&\" \"||\"\n] @operator\n\n; punctuation.bracket\n; -------------------\n\n[\n  \"(\" \")\"\n  \"{\" \"}\"\n] @punctuation.bracket\n\n; punctuation.delimiter\n; ---------------------\n\n[\n  \";\"\n  \",\"\n  \".\"\n  \":\"\n  \"?\"\n] @punctuation.delimiter\n\n; variable\n; --------\n\n(identifier) @variable\n\n; variable.builtin\n; ----------------\n\n(self) @variable.builtin\n\n; variable.parameter\n; ------------------\n\n(parameter\n  name: (identifier) @variable.parameter)\n\n; variable.other.member\n; ---------------------\n\n(field\n  name: (identifier) @variable.other.member)\n\n(contract_body\n  (constant\n    name: (identifier) @variable.other.member))\n\n(trait_body\n  (constant\n    name: (identifier) @variable.other.member))\n\n(field_access_expression\n  name: (identifier) @variable.other.member)\n\n(lvalue (_) (_) @variable.other.member)\n\n(instance_argument\n  name: (identifier) @variable.other.member)\n\n; comment.block\n; -------------\n\n(comment) @comment.block\n\n; comment.line\n; ------------\n\n((comment) @comment.line\n  (#match? @comment.line \"^//\"))\n\n; function\n; --------\n\n(func_identifier) @function\n\n(native_function\n  name: (identifier) @function)\n\n(static_function\n  name: (identifier) @function)\n\n(static_call_expression\n  name: (identifier) @function)\n\n(init_function\n  \"init\" @function.method)\n\n(receive_function\n  \"receive\" @function.method)\n\n(bounced_function\n  \"bounced\" @function.method)\n\n(external_function\n  \"external\" @function.method)\n\n(function\n  name: (identifier) @function.method)\n\n; function.method\n; ---------------\n\n(method_call_expression\n  name: (identifier) @function.method)\n\n; function.builtin\n; ----------------\n\n((identifier) @function.builtin\n  (#any-of? @function.builtin\n    \"send\" \"sender\" \"require\" \"now\"\n    \"myBalance\" \"myAddress\" \"newAddress\"\n    \"contractAddress\" \"contractAddressExt\"\n    \"emit\" \"cell\" \"ton\"\n    \"beginString\" \"beginComment\" \"beginTailString\" \"beginStringFromBuilder\" \"beginCell\" \"emptyCell\"\n    \"randomInt\" \"random\"\n    \"checkSignature\" \"checkDataSignature\" \"sha256\"\n    \"min\" \"max\" \"abs\" \"pow\"\n    \"throw\" \"dump\" \"getConfigParam\"\n    \"nativeThrowWhen\" \"nativeThrowUnless\" \"nativeReserve\"\n    \"nativeRandomize\" \"nativeRandomizeLt\" \"nativePrepareRandom\" \"nativeRandom\" \"nativeRandomInterval\")\n  (#is-not? local))\n\n; keyword.control.conditional\n; ---------------------------\n\n[\n  \"if\" \"else\"\n] @keyword.control.conditional\n\n; keyword.control.repeat\n; ----------------------\n\n[\n  \"while\" \"repeat\" \"do\" \"until\"\n] @keyword.control.repeat\n\n; keyword.control.import\n; ----------------------\n\n\"import\" @keyword.control.import\n\n; keyword.control.return\n; ----------------------\n\n\"return\" @keyword.control.return\n\n; keyword.operator\n; ----------------\n\n\"initOf\" @keyword.operator\n\n; keyword.directive\n; -----------------\n\n\"primitive\" @keyword.directive\n\n; keyword.function\n; ----------------\n\n[\n  \"fun\"\n  \"native\"\n] @keyword.function\n\n; keyword.storage.type\n; --------------------\n\n[\n  \"contract\" \"trait\" \"struct\" \"message\" \"with\"\n  \"const\" \"let\"\n] @keyword.storage.type\n\n; keyword.storage.modifier\n; ------------------------\n\n[\n  \"get\" \"mutates\" \"extends\" \"virtual\" \"override\" \"inline\" \"abstract\"\n] @keyword.storage.modifier\n\n; keyword\n; -------\n\n[\n  \"with\"\n  ; \"public\" ; -- not used, but declared in grammar.ohm\n  ; \"extend\" ; -- not used, but declared in grammar.ohm\n] @keyword\n\n; constant.builtin.boolean\n; ------------------------\n\n(boolean) @constant.builtin.boolean\n\n; constant.builtin\n; ----------------\n\n((identifier) @constant.builtin\n  (#any-of? @constant.builtin\n    \"SendPayGasSeparately\"\n    \"SendIgnoreErrors\"\n    \"SendDestroyIfZero\"\n    \"SendRemainingValue\"\n    \"SendRemainingBalance\")\n  (#is-not? local))\n\n(null) @constant.builtin\n\n; constant.numeric.integer\n; ------------------------\n\n(integer) @constant.numeric.integer\n\n; constant\n; --------\n\n(constant\n  name: (identifier) @constant)\n\n; string\n; ------\n\n(string) @string\n\n; string.special.path\n; -------------------\n\n(import_statement\n  library: (string) @string.special.path)\n\n; type\n; ----\n\n(type_identifier) @type\n\n; type.builtin\n; ------------\n\n(tlb_serialization\n  \"as\" @keyword\n  type: (identifier) @type.builtin\n  (#any-of? @type.builtin\n    \"int8\" \"int16\" \"int32\" \"int64\" \"int128\" \"int256\" \"int257\"\n    \"uint8\" \"uint16\" \"uint32\" \"uint64\" \"uint128\" \"uint256\"\n    \"coins\" \"remaining\" \"bytes32\" \"bytes64\"))\n\n((type_identifier) @type.builtin\n  (#any-of? @type.builtin\n    \"Address\" \"Bool\" \"Builder\" \"Cell\" \"Int\" \"Slice\" \"String\" \"StringBuilder\"))\n\n(map_type\n  \"map\" @type.builtin\n  \"<\" @punctuation.bracket\n  \">\" @punctuation.bracket)\n\n(bounced_type\n  \"bounced\" @type.builtin\n  \"<\" @punctuation.bracket\n  \">\" @punctuation.bracket)\n\n((identifier) @type.builtin\n  (#eq? @type.builtin \"SendParameters\")\n  (#is-not? local))\n\n; constructor\n; -----------\n\n(instance_expression\n  name: (identifier) @constructor)\n\n(initOf\n  name: (identifier) @constructor)\n"
  },
  {
    "path": "runtime/queries/tact/indents.scm",
    "content": "; indent\n; ------\n\n[\n  ; (..., ...)\n  (parameter_list)\n  (argument_list)\n\n  ; {..., ...}\n  (instance_argument_list)\n\n  ; {...; ...}\n  (message_body)\n  (struct_body)\n  (contract_body)\n  (trait_body)\n  (function_body)\n  (block_statement)\n\n  ; misc.\n  (binary_expression)\n  (return_statement)\n] @indent\n\n; outdent\n; -------\n\n[\n  \"}\"\n  \")\"\n  \">\"\n] @outdent\n\n; indent.always\n; outdent.always\n; align\n; extend\n; extend.prevent-once"
  },
  {
    "path": "runtime/queries/tact/injections.scm",
    "content": "; See: https://docs.helix-editor.com/guides/injection.html\n\n((comment) @injection.content\n (#set! injection.language \"comment\")\n (#match? @injection.content \"^//\"))"
  },
  {
    "path": "runtime/queries/tact/locals.scm",
    "content": "; Scopes       @local.scope\n; -------------------------\n\n[\n  (static_function)\n  (init_function)\n  (bounced_function)\n  (receive_function)\n  (external_function)\n  (function)\n  (block_statement)\n] @local.scope\n\n; Definitions  @local.definition\n; ------------------------------\n\n(parameter\n  name: (identifier) @local.definition.variable.parameter)\n\n(constant\n  name: (identifier) @local.definition.constant)\n\n; References   @local.reference\n; -----------------------------\n\n(self) @local.reference\n\n(value_expression (identifier) @local.reference)\n\n(lvalue (identifier) @local.reference)\n"
  },
  {
    "path": "runtime/queries/tact/textobjects.scm",
    "content": "; function.inside & around\n; ------------------------\n\n(static_function\n  body: (_) @function.inside) @function.around\n\n(init_function\n  body: (_) @function.inside) @function.around\n\n(bounced_function\n  body: (_) @function.inside) @function.around\n\n(receive_function\n  body: (_) @function.inside) @function.around\n\n(external_function\n  body: (_) @function.inside) @function.around\n\n(function\n  body: (_) @function.inside) @function.around\n\n; class.inside & around\n; ---------------------\n\n(struct\n  body: (_) @class.inside) @class.around\n\n(message\n  body: (_) @class.inside) @class.around\n\n(contract\n  body: (_) @class.inside) @class.around\n\n; NOTE: Marked as @definition.interface in tags, as it's semantically correct\n(trait\n  body: (_) @class.inside) @class.around\n\n; parameter.inside & around\n; -------------------------\n\n(parameter_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(argument_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(instance_argument_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n; comment.inside\n; --------------\n\n(comment) @comment.inside\n\n; comment.around\n; --------------\n\n(comment)+ @comment.around"
  },
  {
    "path": "runtime/queries/task/highlights.scm",
    "content": "(comment) @comment\n(datetime) @type\n(identifier) @variable\n(keyword) @keyword\n"
  },
  {
    "path": "runtime/queries/task/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/tcl/folds.scm",
    "content": "(braced_word) @fold\n"
  },
  {
    "path": "runtime/queries/tcl/highlights.scm",
    "content": "\n(comment) @comment\n\n(command name: (simple_word) @function)\n\n\"proc\" @keyword.function\n\n(procedure\n  name: (_) @variable\n)\n\n(set (simple_word) @variable)\n\n(argument\n  name: (_) @variable.parameter\n)\n\n((simple_word) @variable.builtin\n               (#any-of? @variable.builtin\n                \"argc\"\n                \"argv\"\n                \"argv0\"\n                \"auto_path\"\n                \"env\"\n                \"errorCode\"\n                \"errorInfo\"\n                \"tcl_interactive\"\n                \"tcl_library\"\n                \"tcl_nonwordchars\"\n                \"tcl_patchLevel\"\n                \"tcl_pkgPath\"\n                \"tcl_platform\"\n                \"tcl_precision\"\n                \"tcl_rcFileName\"\n                \"tcl_traceCompile\"\n                \"tcl_traceExec\"\n                \"tcl_wordchars\"\n                \"tcl_version\"))\n\n\n\"expr\" @function.builtin\n\n(command\n  name: (simple_word) @function.builtin\n  (#any-of? @function.builtin\n   \"cd\"\n   \"exec\"\n   \"exit\"\n   \"incr\"\n   \"info\"\n   \"join\"\n   \"puts\"\n   \"regexp\"\n   \"regsub\"\n   \"split\"\n   \"subst\"\n   \"trace\"\n   \"source\"))\n\n(command name: (simple_word) @keyword\n         (#any-of? @keyword\n          \"append\"\n          \"break\"\n          \"catch\"\n          \"continue\"\n          \"default\"\n          \"dict\"\n          \"error\"\n          \"eval\"\n          \"global\"\n          \"lappend\"\n          \"lassign\"\n          \"lindex\"\n          \"linsert\"\n          \"list\"\n          \"llength\"\n          \"lmap\"\n          \"lrange\"\n          \"lrepeat\"\n          \"lreplace\"\n          \"lreverse\"\n          \"lsearch\"\n          \"lset\"\n          \"lsort\"\n          \"package\"\n          \"return\"\n          \"switch\"\n          \"throw\"\n          \"unset\"\n          \"variable\"))\n\n[\n \"error\"\n \"namespace\"\n \"on\"\n \"set\"\n \"try\"\n ] @keyword\n\n(unpack) @operator\n\n[\n \"while\"\n \"foreach\"\n ; \"for\"\n ] @keyword.control.repeat\n\n[\n \"if\"\n \"else\"\n \"elseif\"\n ] @keyword.control.conditional\n\n[\n \"**\"\n \"/\" \"*\" \"%\" \"+\" \"-\"\n \"<<\" \">>\"\n \">\" \"<\" \">=\" \"<=\"\n \"==\" \"!=\"\n \"eq\" \"ne\"\n \"in\" \"ni\"\n \"&\"\n \"^\"\n \"|\"\n \"&&\"\n \"||\"\n ] @operator\n\n(variable_substitution) @variable\n(quoted_word) @string\n(escaped_character) @constant.character.escape\n\n[\n \"{\" \"}\"\n \"[\" \"]\"\n \";\"\n ] @punctuation.delimiter\n\n((simple_word) @constant.numeric\n               (#match? @constant.numeric \"^[0-9]+$\"))\n\n((simple_word) @constant.builtin.boolean\n               (#any-of? @constant.builtin.boolean \"true\" \"false\"))\n\n; after apply array auto_execok auto_import auto_load auto_mkindex auto_qualify\n; auto_reset bgerror binary chan clock close coroutine dde encoding eof fblocked\n; fconfigure fcopy file fileevent filename flush format gets glob history http\n; interp load mathfunc mathop memory msgcat my next nextto open parray pid\n; pkg::create pkg_mkIndex platform platform::shell pwd re_syntax read refchan\n; registry rename safe scan seek self socket source string tailcall tcl::prefix\n; tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord\n; tcl_wordBreakAfter tcl_wordBreakBefore tcltest tell time timerate tm\n; transchan unknown unload update uplevel upvar vwait yield yieldto zlib\n"
  },
  {
    "path": "runtime/queries/tcl/indents.scm",
    "content": "[\n (braced_word_simple)\n (namespace)\n (command)\n (conditional)\n (foreach)\n (while)\n (try)\n (procedure)\n (command_substitution)\n ] @indent\n\n[ \"}\" \"]\" ] @outdent\n"
  },
  {
    "path": "runtime/queries/teal/folds.scm",
    "content": "[\n(do_statement)\n(numeric_for_statement)\n(generic_for_statement)\n(while_statement)\n(repeat_statement)\n(if_statement)\n(function_statement)\n(record_declaration)\n(interface_declaration)\n(enum_declaration)\n(anon_function)\n(table_constructor)\n] @fold\n\n"
  },
  {
    "path": "runtime/queries/teal/highlights.scm",
    "content": "\n;; Primitives\n(boolean) @constant.builtin.boolean\n(comment) @comment\n(shebang_comment) @comment\n(identifier) @variable\n((identifier) @variable.builtin\n  (#eq? @variable.builtin \"self\"))\n(nil) @constant.builtin\n(number) @constant.numeric\n(string) @string\n(table_constructor [\"{\" \"}\"] @constructor)\n(varargs \"...\" @constant.builtin)\n[ \",\" \".\" \":\" \";\" ] @punctuation.delimiter\n\n(escape_sequence) @constant.character.escape\n(format_specifier) @constant.character.escape\n\n;; Basic statements/Keywords\n[ \"if\" \"then\" \"elseif\" \"else\" ] @keyword.control.conditional\n[ \"for\" \"while\" \"repeat\" \"until\" \"do\" ] @keyword.control.repeat\n[ \"end\" ] @keyword\n[ \"in\" ] @keyword.operator\n[ \"local\" ] @keyword.storage.type\n[ (break) (goto) ] @keyword.control\n[ \"return\" ] @keyword.control.return\n(label) @label\n\n;; Global isn't a real keyword, but it gets special treatment in these places\n(var_declaration \"global\" @keyword.storage.type)\n(type_declaration \"global\" @keyword.storage.type)\n(function_statement \"global\" @keyword.storage.type)\n(record_declaration \"global\" @keyword.storage.type)\n(interface_declaration \"global\" @keyword.storage.type)\n(enum_declaration \"global\" @keyword.storage.type)\n\n(macroexp_statement \"macroexp\" @keyword)\n\n;; Ops\n(bin_op (op) @operator)\n(unary_op (op) @operator)\n[ \"=\" \"as\" ] @operator\n\n;; Functions\n(function_statement\n  \"function\" @keyword.function\n  . name: (_) @function)\n(anon_function\n  \"function\" @keyword.function)\n(function_body \"end\" @keyword.function)\n\n(arg name: (identifier) @variable.parameter)\n\n(function_signature\n  (arguments\n    . (arg name: (identifier) @variable.builtin))\n  (#eq? @variable.builtin \"self\"))\n\n(typeargs\n  \"<\" @punctuation.bracket\n  . (_) @type.parameter\n  . (\",\" . (_) @type.parameter)*\n  . \">\" @punctuation.bracket)\n\n(function_call\n  (identifier) @function . (arguments))\n(function_call\n  (index (_) key: (identifier) @function) . (arguments))\n(function_call\n  (method_index (_) key: (identifier) @function) . (arguments))\n\n;; Types\n\n; Contextual keywords in record bodies\n(record_declaration\n  . [ \"record\" ] @keyword.storage.type\n  name: (identifier) @type)\n(anon_record . \"record\" @keyword.storage.type)\n(record_body\n  (record_declaration\n    . [ \"record\" ] @keyword.storage.type\n    . name: (identifier) @type))\n(record_body\n  (enum_declaration\n    . [ \"enum\" ] @keyword.storage.type\n    . name: (identifier) @type.enum))\n(record_body\n  (interface_declaration\n    . [ \"interface\" ] @keyword.storage.type\n    . name: (identifier) @type))\n(record_body\n  (typedef\n    . \"type\" @keyword.storage.type\n    . name: (identifier) @type . \"=\"))\n(record_body\n  (macroexp_declaration\n    . [ \"macroexp\" ] @keyword.storage.type))\n(record_body (metamethod \"metamethod\" @keyword.storage.modifier))\n(record_body (userdata) @keyword.storage.modifier)\n\n; Contextual keywords in interface bodies\n(interface_declaration\n  . [ \"interface\" ] @keyword.storage.type\n  name: (identifier) @type)\n(anon_interface . \"interface\" @keyword.storage.type)\n(interface_body\n  (record_declaration\n    . [ \"record\" ] @keyword.storage.type\n    . name: (identifier) @type))\n(interface_body\n  (enum_declaration\n    . [ \"enum\" ] @keyword.storage.type\n    . name: (identifier) @type.enum))\n(interface_body\n  (interface_declaration\n    . [ \"interface\" ] @keyword.storage.type\n    . name: (identifier) @type))\n(interface_body\n  (typedef\n    . \"type\" @keyword.storage.type\n    . name: (identifier) @type . \"=\"))\n(interface_body\n  (macroexp_declaration\n    . [ \"macroexp\" ] @keyword.storage.type))\n(interface_body (metamethod \"metamethod\" @keyword.storage.modifier))\n(interface_body (userdata) @keyword.storage.modifier)\n\n(enum_declaration\n  \"enum\" @keyword.storage.type\n  name: (identifier) @type.enum)\n\n(type_declaration \"type\" @keyword.storage.type)\n(type_declaration (identifier) @type)\n(simple_type) @type\n(type_index) @type\n(type_union \"|\" @operator)\n(function_type \"function\" @type)\n\n;; The rest of it\n(var_declaration\n  declarators: (var_declarators\n      (var name: (identifier) @variable)))\n(var_declaration\n  declarators: (var_declarators\n    (var\n      \"<\" @punctuation.bracket\n      . attribute: (attribute) @attribute\n      . \">\" @punctuation.bracket)))\n[ \"(\" \")\" \"[\" \"]\" \"{\" \"}\" ] @punctuation.bracket\n\n;; Only highlight format specifiers in calls to string.format\n;; string.format('...')\n;(function_call\n;  called_object: (index\n;    (identifier) @base\n;    key: (identifier) @entry)\n;  arguments: (arguments .\n;    (string (format_specifier) @string.escape))\n;\n;  (#eq? @base \"string\")\n;  (#eq? @entry \"format\"))\n\n;; ('...'):format()\n;(function_call\n;  called_object: (method_index\n;    (string (format_specifier) @string.escape)\n;    key: (identifier) @func-name)\n;    (#eq? @func-name \"format\"))\n\n\n"
  },
  {
    "path": "runtime/queries/teal/locals.scm",
    "content": "\n(var_declaration\n  declarators: (var_declarators\n  (var (identifier)) @local.definition.variable))\n\n(var_assignment\n  variables: (assignment_variables\n    (var (identifier) @local.definition.variable)))\n\n(arg name: (identifier) @local.definition.variable.parameter)\n\n(anon_function) @local.scope\n((function_statement\n  (function_name) @local.definition.function) @local.scope)\n\n(program) @local.scope\n(if_statement) @local.scope\n(generic_for_statement (for_body) @local.scope)\n(numeric_for_statement (for_body) @local.scope)\n(repeat_statement) @local.scope\n(while_statement (while_body) @local.scope)\n(do_statement) @local.scope\n\n(identifier) @local.reference\n\n"
  },
  {
    "path": "runtime/queries/templ/highlights.scm",
    "content": "; inherits: go\n\n(css_declaration\n  name: (css_identifier) @function)\n(script_declaration\n  name: (script_identifier) @function)\n\n(component_declaration\n  name: (component_identifier) @function)\n\n(tag_start) @tag\n(tag_end) @tag\n(self_closing_tag) @tag\n(style_element) @tag\n\n(attribute\n  name: (attribute_name) @attribute)\n(attribute\n  value: (quoted_attribute_value) @string)\n\n(element_text) @string.special\n(style_element_text) @string.special\n\n(css_property\n  name: (css_property_name) @attribute)\n(css_property\n  value: (css_property_value) @constant)\n\n(expression) @function.method\n(dynamic_class_attribute_value) @function.method\n\n(component_import\n  name: (component_identifier) @function)\n\n(component_render) @function\n\n[\n  \"@\"\n] @operator\n\n[\n  \"templ\"\n  \"css\"\n  \"type\"\n  \"script\"\n] @keyword.storage.type\n\n[\n  (interpreted_string_literal)\n  (raw_string_literal)\n  (rune_literal)\n] @string\n\n; Comments\n\n(comment) @comment\n\n(element_comment) @comment\n"
  },
  {
    "path": "runtime/queries/templ/injections.scm",
    "content": "((script_block_text) @injection.content (#set! injection.language \"javascript\"))\n((script_element_text) @injection.content (#set! injection.language \"javascript\"))\n\n((style_element_text) @injection.content (#set! injection.language \"css\"))\n"
  },
  {
    "path": "runtime/queries/tera/highlights.scm",
    "content": "; Variables\n;----------\n\n(identifier) @variable\n\n((identifier) @variable.builtin\n  (#any-of? @variable.builtin\n    \"loop\"\n    \"__tera_context\"))\n\n; Properties\n;-----------\n\n(member_expression\n  property: (identifier)? @variable.other.member)\n\n; Literals\n;-----------\n\n(string) @string\n\n(bool) @constant.builtin\n\n(number) @constant.numeric\n\n; Tokens\n;-----------\n\n[\n  \".\"\n  \",\"\n] @punctuation.delimiter\n\n[\n  \"*\"\n  \"/\"\n  \"%\"\n  \"|\"\n  \"+\"\n  \"-\"\n  \"~\"\n  \"=\"\n  \"==\"\n  \"!=\"\n  \"<\"\n  \">\"\n  \"<=\"\n  \">=\"\n] @operator\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"{%\"\n  \"%}\"\n  \"-%}\"\n  \"{%-\"\n  \"}}\"\n  \"{{\"\n  \"-}}\"\n  \"{{-\"\n  \"::\"\n] @punctuation.bracket\n\n; Tags\n;-----------\n\n(comment_tag) @comment\n\n; Keywords\n;-----------\n\n[\n  \"if\"\n  \"elif\"\n  \"else\"\n  \"endif\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n  \"endfor\"\n] @keyword.control.repeat\n\n[\n  \"include\"\n  \"import\"\n  \"extends\"\n] @keyword.control.import\n\n[\n  \"in\"\n  \"and\"\n  \"or\"\n  \"not\"\n  \"is\"\n] @keyword.operator\n\n[\n  \"break\"\n  \"continue\"\n] @keyword.control.return\n\n[\n  \"set\"\n  \"set_global\"\n  \"filter\"\n  \"endfilter\"\n  \"block\"\n  \"endblock\"\n  \"macro\"\n  \"endmacro\"\n  \"raw\"\n  \"endraw\"\n  \"as\"\n] @keyword\n\n; Functions\n;-----------\n\n(macro_statement\n  name: (identifier) @function\n  (parameter_list\n    parameter: (identifier) @variable.parameter\n    (optional_parameter\n      name: (identifier) @variable.parameter)))\n\n(call_expression\n  scope: (identifier)? @namespace\n  name: (identifier) @function)\n\n(call_expression\n  name: (identifier) @function.builtin\n  (#any-of? @function.builtin\n    ; Functions - https://keats.github.io/tera/docs/#built-in-functions\n    \"range\"\n    \"now\"\n    \"throw\"\n    \"get_random\"\n    \"get_env\"))\n\n(test_expression\n  test: (identifier) @function)\n\n(test_expression\n  test: (identifier) @function.builtin\n  (#any-of? @function.builtin\n    ; Tests - https://keats.github.io/tera/docs/#built-in-tests\n    \"defined\"\n    \"undefined\"\n    \"odd\"\n    \"even\"\n    \"string\"\n    \"number\"\n    \"divisibleby\"\n    \"iterable\"\n    \"object\"\n    \"starting_with\"\n    \"ending_with\"\n    \"containing\"\n    \"matching\"))\n\n(filter_expression\n  filter: (identifier) @function.method)\n\n(filter_expression\n  filter: (identifier) @function.builtin\n  (#any-of? @function.builtin\n    ; Filters - https://keats.github.io/tera/docs/#built-in-filters\n    \"lower\"\n    \"upper\"\n    \"wordcount\"\n    \"capitalize\"\n    \"replace\"\n    \"addslashes\"\n    \"slugify\"\n    \"title\"\n    \"trim\"\n    \"trim_start\"\n    \"trim_end\"\n    \"trim_start_matches\"\n    \"trim_end_matches\"\n    \"truncate\"\n    \"linebreaksbr\"\n    \"spaceless\"\n    \"indent\"\n    \"striptags\"\n    \"first\"\n    \"last\"\n    \"nth\"\n    \"join\"\n    \"length\"\n    \"reverse\"\n    \"sort\"\n    \"unique\"\n    \"slice\"\n    \"group_by\"\n    \"filter\"\n    \"map\"\n    \"concat\"\n    \"urlencode\"\n    \"urlencode_strict\"\n    \"abs\"\n    \"pluralize\"\n    \"round\"\n    \"filesizeformat\"\n    \"date\"\n    \"escape\"\n    \"escape_xml\"\n    \"safe\"\n    \"get\"\n    \"split\"\n    \"int\"\n    \"float\"\n    \"json_encode\"\n    \"as_str\"\n    \"default\"))\n\n; Namespaces\n;-----------\n\n(import_statement\n  scope: (identifier) @namespace)\n"
  },
  {
    "path": "runtime/queries/tera/injections.scm",
    "content": "(frontmatter (content) @injection.content\n  (#set! injection.language \"yaml\")\n  (#set! injection.combined)\n)\n"
  },
  {
    "path": "runtime/queries/tera/locals.scm",
    "content": "(identifier) @local.reference\n(assignment_expression\n   left: (identifier) @local.definition.variable)\n(macro_statement\n  (parameter_list\n    (identifier) @local.definition.variable.parameter))\n(macro_statement) @local.scope\n"
  },
  {
    "path": "runtime/queries/textproto/highlights.scm",
    "content": "(string) @string\n\n(field_name) @variable.other.member\n\n(comment) @comment\n\n(number) @constant.numeric\n; covers e.g. booleans and \"inf\"\n(scalar_value (identifier)) @constant\n; Covers \"-inf\"\n(scalar_value (signed_identifier)) @constant.numeric\n\n[\n  (open_squiggly)\n  (close_squiggly)\n  (open_square)\n  (close_square)\n  (open_arrow)\n  (close_arrow)\n] @punctuation.bracket\n\n\",\" @punctuation.delimiter\n"
  },
  {
    "path": "runtime/queries/textproto/indents.scm",
    "content": "[\n  (message_value)\n  (message_list)\n  (scalar_list)\n] @indent\n\n[\n  (close_arrow)\n  (close_square)\n  (close_squiggly)\n] @outdent\n"
  },
  {
    "path": "runtime/queries/textproto/textobjects.scm",
    "content": "(message_field \n  (_) @entry.inside) @entry.around\n\n(scalar_field \n  (_) @entry.inside) @entry.around\n\n(message_list\n  (_) @entry.around)\n\n(scalar_list\n  (_) @entry.around)\n\n"
  },
  {
    "path": "runtime/queries/tfvars/folds.scm",
    "content": "; inherits: hcl\n"
  },
  {
    "path": "runtime/queries/tfvars/highlights.scm",
    "content": "; inherits: hcl\n"
  },
  {
    "path": "runtime/queries/tfvars/indents.scm",
    "content": "; inherits: hcl\n"
  },
  {
    "path": "runtime/queries/tfvars/injections.scm",
    "content": "; inherits: hcl\n"
  },
  {
    "path": "runtime/queries/thrift/folds.scm",
    "content": "[\n  (annotation_definition)\n  (enum_definition)\n  (exception_definition)\n  (function_definition)\n  (senum_definition)\n  (service_definition)\n  (struct_definition)\n  (union_definition)\n\n  (comment)\n] @fold\n"
  },
  {
    "path": "runtime/queries/thrift/highlights.scm",
    "content": "; Variables\n\n((identifier) @variable)\n\n; Includes\n\n[\n  \"include\"\n  \"cpp_include\"\n] @keyword\n\n; Function\n\n(function_definition\n  (identifier) @function)\n\n; Fields\n\n(field (identifier) @variable.other.member)\n\n; Parameters\n\n(function_definition\n  (parameters\n    (parameter (identifier) @variable.parameter)))\n\n(throws\n  (parameters\n    (parameter (identifier) @keyword.control.exception)))\n\n; Types\n\n(typedef_identifier) @type\n(struct_definition\n  \"struct\" (identifier) @type)\n\n(union_definition\n  \"union\" (identifier) @type)\n\n(exception_definition\n  \"exception\" (identifier) @type)\n\n(service_definition\n  \"service\" (identifier) @type)\n\n(interaction_definition\n  \"interaction\" (identifier) @type)\n\n(type\n  type: (identifier) @type)\n\n(definition_type\n  type: (identifier) @type)\n\n; Constants\n\n(const_definition (identifier) @constant)\n\n(enum_definition \"enum\"\n  . (identifier) @type\n  \"{\" (identifier) @constant \"}\")\n\n; Builtin Types\n\n(primitive) @type.builtin\n\n[\n  \"list\"\n  \"map\"\n  \"set\"\n  \"sink\"\n  \"stream\"\n  \"void\"\n] @type.builtin\n\n; Namespace\n\n(namespace_declaration\n  (namespace_scope) @tag\n  [(namespace) @namespace (_ (identifier) @namespace)])\n\n; Attributes\n\n(annotation_definition\n  (annotation_identifier (identifier) @attribute))\n(fb_annotation_definition\n  \"@\" @attribute (annotation_identifier (identifier) @attribute)\n  (identifier)? @attribute)\n(namespace_uri (string) @attribute)\n\n; Operators\n\n[\n  \"=\"\n  \"&\"\n] @operator\n\n; Exceptions\n\n[\n  \"throws\"\n] @keyword.control.exception\n\n; Keywords\n\n[\n  \"enum\"\n  \"exception\"\n  \"extends\"\n  \"interaction\"\n  \"namespace\"\n  \"senum\"\n  \"service\"\n  \"struct\"\n  \"typedef\"\n  \"union\"\n  \"uri\"\n] @keyword\n\n; Deprecated Keywords\n\n[\n  \"cocoa_prefix\"\n  \"cpp_namespace\"\n  \"csharp_namespace\"\n  \"delphi_namespace\"\n  \"java_package\"\n  \"perl_package\"\n  \"php_namespace\"\n  \"py_module\"\n  \"ruby_namespace\"\n  \"smalltalk_category\"\n  \"smalltalk_prefix\"\n  \"xsd_all\"\n  \"xsd_attrs\"\n  \"xsd_namespace\"\n  \"xsd_nillable\"\n  \"xsd_optional\"\n] @keyword\n\n; Extended Keywords\n[\n  \"package\"\n  \"performs\"\n] @keyword\n\n[\n  \"async\"\n  \"oneway\"\n] @keyword\n\n; Qualifiers\n\n[\n  \"client\"\n  \"const\"\n  \"idempotent\"\n  \"optional\"\n  \"permanent\"\n  \"readonly\"\n  \"required\"\n  \"safe\"\n  \"server\"\n  \"stateful\"\n  \"transient\"\n] @type.directive\n\n; Literals\n\n(string) @string\n\n(escape_sequence) @constant.character.escape\n\n(namespace_uri\n  (string) @string.special)\n\n(number) @constant.numeric.integer\n\n(double) @constant.numeric.float\n\n(boolean) @constant.builtin.boolean\n\n; Typedefs\n\n(typedef_identifier) @type.definition\n\n; Punctuation\n\n[\n  \"*\"\n] @punctuation.special\n\n[\"{\" \"}\"] @punctuation.bracket\n\n[\"(\" \")\"] @punctuation.bracket\n\n[\"[\" \"]\"] @punctuation.bracket\n\n[\"<\" \">\"] @punctuation.bracket\n\n[\n  \".\"\n  \",\"\n  \";\"\n  \":\"\n] @punctuation.delimiter\n\n; Comments\n\n(comment) @comment\n\n"
  },
  {
    "path": "runtime/queries/thrift/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/thrift/locals.scm",
    "content": "; Scopes\n\n[\n  (document)\n  (definition)\n] @local.scope\n\n; References\n\n(identifier) @local.reference\n\n; Definitions\n\n(annotation_identifier) @local.definition.attribute\n"
  },
  {
    "path": "runtime/queries/tilt/highlights.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/tilt/indents.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/tilt/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; https://docs.tilt.dev/api.html#api.local\n; https://docs.tilt.dev/api.html#api.run\n; e.g. `local(\"git rev-parse --show-toplevel\")`\n(call\n  function: (identifier) @_function (#any-of? @_function \"local\" \"run\")\n  arguments: (argument_list . (string (string_content) @injection.content))\n  (#set! injection.language \"bash\"))\n\n; https://docs.tilt.dev/api.html#api.local_resource\n; https://docs.tilt.dev/api.html#api.custom_build\n; e.g.\n; ```\n; custom_build(\n;   'gcr.io/my-project/frontend-server',\n;   'docker build -t $EXPECTED_REF .',\n;   ['.'],\n; )\n; ```\n(call\n  function: (identifier) @_function (#any-of? @_function \"custom_build\" \"local_resource\")\n  arguments: (argument_list . (string) (string (string_content) @injection.content))\n  (#set! injection.language \"bash\"))\n\n; https://docs.tilt.dev/api.html#api.k8s_custom_deploy\n; e.g.\n; ```\n; local_resource(\n;   'local-myserver',\n;   cmd='go build ./cmd/myserver',\n;   serve_cmd='./myserver --port=8001',\n;   deps=['cmd/myserver']\n; )\n; ```\n(call\n  arguments: (argument_list\n    (keyword_argument\n      name: (identifier) @_keyword_arg (#any-of? @_keyword_arg\n        \"cmd\"\n        \"serve_cmd\"\n        \"apply_cmd\"\n        \"delete_cmd\"\n        \"cmd_bat\"\n        \"apply_cmd_bat\"\n        \"serve_cmd_bat\"\n        \"delete_cmd_bat\"\n        \"command\"\n        \"command_bat\"\n        \"entrypoint\")\n      value: (string (string_content) @injection.content)))\n  (#set! injection.language \"bash\"))\n"
  },
  {
    "path": "runtime/queries/tilt/rainbows.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/tilt/textobjects.scm",
    "content": "; inherits: python\n"
  },
  {
    "path": "runtime/queries/tlaplus/highlights.scm",
    "content": "; ; Intended for consumption by GitHub and the tree-sitter highlight command\n; ; Default capture names found here:\n; ; https://github.com/tree-sitter/tree-sitter/blob/f5d1c0b8609f8697861eab352ead44916c068c74/cli/src/highlight.rs#L150-L171\n; ; In this file, captures defined earlier take precedence over captures defined later.\n\n; TLA⁺ Keywords\n[\n  \"ACTION\"\n  \"ASSUME\"\n  \"ASSUMPTION\"\n  \"AXIOM\"\n  \"BY\"\n  \"CASE\"\n  \"CHOOSE\"\n  \"CONSTANT\"\n  \"CONSTANTS\"\n  \"COROLLARY\"\n  \"DEF\"\n  \"DEFINE\"\n  \"DEFS\"\n  \"ELSE\"\n  \"EXCEPT\"\n  \"EXTENDS\"\n  \"HAVE\"\n  \"HIDE\"\n  \"IF\"\n  \"IN\"\n  \"INSTANCE\"\n  \"LAMBDA\"\n  \"LEMMA\"\n  \"LET\"\n  \"LOCAL\"\n  \"MODULE\"\n  \"NEW\"\n  \"OBVIOUS\"\n  \"OMITTED\"\n  \"ONLY\"\n  \"OTHER\"\n  \"PICK\"\n  \"PROOF\"\n  \"PROPOSITION\"\n  \"PROVE\"\n  \"QED\"\n  \"RECURSIVE\"\n  \"SF_\"\n  \"STATE\"\n  \"SUFFICES\"\n  \"TAKE\"\n  \"TEMPORAL\"\n  \"THEN\"\n  \"THEOREM\"\n  \"USE\"\n  \"VARIABLE\"\n  \"VARIABLES\"\n  \"WF_\"\n  \"WITH\"\n  \"WITNESS\"\n  (address)\n  (all_map_to)\n  (assign)\n  (case_arrow)\n  (case_box)\n  (def_eq)\n  (exists)\n  (forall)\n  (gets)\n  (label_as)\n  (maps_to)\n  (set_in)\n  (temporal_exists)\n  (temporal_forall)\n] @keyword\n\n;  PlusCal keywords\n[\n  \"algorithm\"\n  \"assert\"\n  \"await\"\n  \"begin\"\n  \"call\"\n  \"define\"\n  \"either\"\n  \"else\"\n  \"elsif\"\n  \"end\"\n  \"fair\"\n  \"goto\"\n  \"if\"\n  \"macro\"\n  \"or\"\n  \"print\"\n  \"procedure\"\n  \"process\"\n  \"variable\"\n  \"variables\"\n  \"when\"\n  \"with\"\n  \"then\"\n  (pcal_algorithm_start)\n  (pcal_end_either)\n  (pcal_end_if)\n  (pcal_return)\n  (pcal_skip)\n  (pcal_process (\"=\"))\n  (pcal_with (\"=\"))\n] @keyword\n\n; Literals\n(binary_number (format) @keyword)\n(binary_number (value) @constant.numeric)\n(boolean) @constant.builtin.boolean\n(boolean_set) @type\n(hex_number (format) @keyword)\n(hex_number (value) @constant.numeric)\n(int_number_set) @type\n(nat_number) @constant.numeric.integer\n(nat_number_set) @type\n(octal_number (format) @keyword)\n(octal_number (value) @constant.numeric)\n(real_number) @constant.numeric.integer\n(real_number_set) @type\n(string) @string\n(escape_char) @string.special.symbol\n(string_set) @type\n\n; Namespaces and includes\n(extends (identifier_ref) @namespace)\n(instance (identifier_ref) @namespace)\n(module name: (_) @namespace)\n(pcal_algorithm name: (identifier) @namespace)\n\n; Constants and variables\n(constant_declaration (identifier) @constant)\n(constant_declaration (operator_declaration name: (_) @constant))\n(pcal_var_decl (identifier) @variable.builtin)\n(pcal_with (identifier) @variable.parameter)\n((\".\") . (identifier) @attribute)\n(record_literal (identifier) @attribute)\n(set_of_records (identifier) @attribute)\n(variable_declaration (identifier) @variable.builtin)\n\n; Parameters\n(choose (identifier) @variable.parameter)\n(choose (tuple_of_identifiers (identifier) @variable.parameter))\n(lambda (identifier) @variable.parameter)\n(module_definition (operator_declaration name: (_) @variable.parameter))\n(module_definition parameter: (identifier) @variable.parameter)\n(operator_definition (operator_declaration name: (_) @variable.parameter))\n(operator_definition parameter: (identifier) @variable.parameter)\n(pcal_macro_decl parameter: (identifier) @variable.parameter)\n(pcal_proc_var_decl (identifier) @variable.parameter)\n(quantifier_bound (identifier) @variable.parameter)\n(quantifier_bound (tuple_of_identifiers (identifier) @variable.parameter))\n(unbounded_quantification (identifier) @variable.parameter)\n\n; Operators, functions, and macros\n(function_definition name: (identifier) @function)\n(module_definition name: (_) @namespace)\n(operator_definition name: (_) @operator)\n(pcal_macro_decl name: (identifier) @function)\n(pcal_macro_call name: (identifier) @function)\n(pcal_proc_decl name: (identifier) @function)\n(pcal_process name: (identifier) @function)\n(recursive_declaration (identifier) @operator)\n(recursive_declaration (operator_declaration name: (_) @operator))\n\n; Delimiters\n[\n  (langle_bracket)\n  (rangle_bracket)\n  (rangle_bracket_sub)\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"]_\"\n  \"(\"\n  \")\"\n] @punctuation.bracket\n[\n  \",\"\n  \":\"\n  \".\"\n  \"!\"\n  \";\"\n  (bullet_conj)\n  (bullet_disj)\n  (prev_func_val)\n  (placeholder)\n] @punctuation.delimiter\n\n; Proofs\n(assume_prove (new (identifier) @variable.parameter))\n(assume_prove (new (operator_declaration name: (_) @variable.parameter)))\n(assumption name: (identifier) @constant)\n(pick_proof_step (identifier) @variable.parameter)\n(proof_step_id \"<\" @punctuation.bracket)\n(proof_step_id (level) @tag)\n(proof_step_id (name) @tag)\n(proof_step_id \">\" @punctuation.bracket)\n(proof_step_ref \"<\" @punctuation.bracket)\n(proof_step_ref (level) @tag)\n(proof_step_ref (name) @tag)\n(proof_step_ref \">\" @punctuation.bracket)\n(take_proof_step (identifier) @variable.parameter)\n(theorem name: (identifier) @constant)\n\n; Comments and tags\n(block_comment \"(*\" @comment.block)\n(block_comment \"*)\" @comment.block)\n(block_comment_text) @comment.block\n(comment) @comment\n(single_line) @comment\n(_ label: (identifier) @tag)\n(label name: (_) @tag)\n(pcal_goto statement: (identifier) @tag)\n\n; Put these last so they are overridden by everything else\n(bound_infix_op symbol: (_) @function.builtin)\n(bound_nonfix_op symbol: (_) @function.builtin)\n(bound_postfix_op symbol: (_) @function.builtin)\n(bound_prefix_op symbol: (_) @function.builtin)\n((prefix_op_symbol) @function.builtin)\n((infix_op_symbol) @function.builtin)\n((postfix_op_symbol) @function.builtin)\n"
  },
  {
    "path": "runtime/queries/tlaplus/locals.scm",
    "content": "; TLA⁺ scopes and definitions\n[\n  (bounded_quantification)\n  (choose)\n  (function_definition) \n  (function_literal)\n  (lambda) \n  (let_in)\n  (module) \n  (module_definition)\n  (operator_definition)\n  (set_filter)\n  (set_map)\n  (unbounded_quantification)\n] @local.scope\n\n; Definitions\n(choose (identifier) @local.definition.variable.parameter)\n(choose (tuple_of_identifiers (identifier) @local.definition.variable.parameter))\n(constant_declaration (identifier) @local.definition.constant)\n(constant_declaration (operator_declaration name: (_) @local.definition.constant))\n(function_definition name: (identifier) @local.definition.function)\n(lambda (identifier) @local.definition.function)\n(module_definition name: (_) @local.definition.namespace)\n(module_definition parameter: (identifier) @local.definition.variable.parameter)\n(module_definition parameter: (operator_declaration name: (_) @local.definition.variable.parameter))\n(operator_definition name: (_) @local.definition.operator)\n(operator_definition parameter: (identifier) @local.definition.variable.parameter)\n(operator_definition parameter: (operator_declaration name: (_) @local.definition.variable.parameter))\n(quantifier_bound (identifier) @local.definition.variable.parameter)\n(quantifier_bound (tuple_of_identifiers (identifier) @local.definition.variable.parameter))\n(unbounded_quantification (identifier) @local.definition.variable.parameter)\n(variable_declaration (identifier) @local.definition.variable.builtin)\n\n; Proof scopes and definitions\n[\n  (non_terminal_proof)\n  (suffices_proof_step)\n  (theorem)\n] @local.scope\n\n(assume_prove (new (identifier) @local.definition.variable.parameter))\n(assume_prove (new (operator_declaration name: (_) @local.definition.variable.parameter)))\n(assumption name: (identifier) @local.definition.constant)\n(pick_proof_step (identifier) @local.definition.variable.parameter)\n(take_proof_step (identifier) @local.definition.variable.parameter)\n(theorem name: (identifier) @local.definition.constant)\n\n;PlusCal scopes and definitions\n[\n  (pcal_algorithm)\n  (pcal_macro)\n  (pcal_procedure)\n  (pcal_with)\n] @local.scope\n\n(pcal_macro_decl parameter: (identifier) @local.definition.variable.parameter)\n(pcal_proc_var_decl (identifier) @local.definition.variable.parameter)\n(pcal_var_decl (identifier) @local.definition.variable.parameter)\n(pcal_with (identifier) @local.definition.variable.parameter)\n\n; References\n(identifier_ref) @local.reference\n((prefix_op_symbol) @local.reference)\n(bound_prefix_op symbol: (_) @local.reference)\n((infix_op_symbol) @local.reference)\n(bound_infix_op symbol: (_) @local.reference)\n((postfix_op_symbol) @local.reference)\n(bound_postfix_op symbol: (_) @local.reference)\n(bound_nonfix_op symbol: (_) @local.reference)\n"
  },
  {
    "path": "runtime/queries/todotxt/highlights.scm",
    "content": "(done_task) @comment\n(task (priority) @keyword)\n(task (date) @comment)\n(task (kv) @comment)\n(task (project) @string)\n(task (context) @type)\n"
  },
  {
    "path": "runtime/queries/toml/highlights.scm",
    "content": "; Properties\n;-----------\n\n(table [\n  (bare_key)\n  (dotted_key)\n  (quoted_key)\n] @type)\n\n(table_array_element [\n  (bare_key)\n  (dotted_key)\n  (quoted_key)\n] @type)\n\n(pair [\n  (bare_key)\n  (dotted_key)\n  (quoted_key)\n] @variable.other.member)\n\n; Literals\n;---------\n\n(boolean) @constant.builtin.boolean\n(comment) @comment\n(string) @string\n(integer) @constant.numeric.integer\n(float) @constant.numeric.float\n(offset_date_time) @string.special\n(local_date_time) @string.special\n(local_date) @string.special\n(local_time) @string.special\n\n; Punctuation\n;------------\n\n\".\" @punctuation.delimiter\n\",\" @punctuation.delimiter\n\n\"=\" @operator\n\n\"[\" @punctuation.bracket\n\"]\" @punctuation.bracket\n\"[[\" @punctuation.bracket\n\"]]\" @punctuation.bracket\n\"{\" @punctuation.bracket\n\"}\" @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/toml/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/toml/rainbows.scm",
    "content": "[\n  (table_array_element)\n  (table)\n  (array)\n  (inline_table)\n] @rainbow.scope\n\n[\n  \"[[\" \"]]\"\n  \"[\" \"]\"\n  \"{\" \"}\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/toml/tags.scm",
    "content": "(table \"[\" (bare_key) @definition.section \"]\")\n(table \"[\" (dotted_key) @definition.section \"]\")\n"
  },
  {
    "path": "runtime/queries/toml/textobjects.scm",
    "content": "(pair \n  (_) @entry.inside) @entry.around\n\n(array\n  (_) @entry.around)\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/tql/highlights.scm",
    "content": ";; Upstream: https://github.com/tenzir/tree-sitter-tql/blob/main/queries/tql/highlights.scm\n\n\"move\" @keyword\n\n[\n  \"let\"\n] @keyword.storage\n\n[\n  \"and\"\n  \"or\"\n  \"not\"\n  \"in\"\n] @keyword.operator\n\n[\n  \"if\"\n  \"else\"\n  \"match\"\n] @keyword.control.conditional\n\n\"this\" @variable.builtin\n\n[\n  \".\"\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"[\"\n  \"]\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \"?\"\n  \"...\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"=\"\n  \"=>\"\n  \"|\"\n  \"::\"\n  \"==\"\n  \"!=\"\n  \">\"\n  \">=\"\n  \"<\"\n  \"<=\"\n] @operator\n\n[\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n[\n  \",\"\n] @punctuation.delimiter\n\n\"_\" @variable.builtin\n\n\"null\" @constant.builtin\n\n[\n  \"true\"\n  \"false\"\n] @constant.builtin.boolean\n\n(dollar_var) @variable\n(meta_selector) @attribute\n(number) @constant.numeric\n(string) @string\n(format_expr) @string\n(ip) @constant\n(subnet) @constant\n(time) @number\n(duration) @constant.numeric\n(frontmatter_open) @comment\n(frontmatter_close) @comment\n(comment) @comment\n\n(invocation\n  operator: (entity) @function.call)\n(call_expression\n  (entity) @function.call)\n(call_expression\n  method: (entity) @function.method)\n(identifier) @variable\n"
  },
  {
    "path": "runtime/queries/tql/indents.scm",
    "content": ";; Upstream: https://github.com/tenzir/tree-sitter-tql/blob/main/queries/tql/indents.scm\n\n[\n  (then_block)\n  (else_block)\n  (pipeline_block)\n  (match_statement)\n  (match_arm)\n  (list)\n  (record)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/tsq/folds.scm",
    "content": "[\n  (named_node)\n  (predicate)\n  (grouping)\n  (list)\n] @fold\n"
  },
  {
    "path": "runtime/queries/tsq/highlights.scm",
    "content": "((program\n  .\n  (comment)*\n  .\n  (comment) @keyword.import)\n  (#match? @keyword.import \"^;+ *inherits *:\"))\n\n((parameters\n  (identifier) @constant.numeric)\n  (#match? @constant.numeric \"^[-+]?[0-9]+(.[0-9]+)?$\"))\n\n\"_\" @constant\n\n\":\" @punctuation.delimiter\n\n[\n  \"[\"\n  \"]\"\n  \"(\"\n  \")\"\n] @punctuation.bracket\n\n\".\" @operator\n\n(quantifier) @operator\n\n(comment) @comment\n\n(negated_field\n  \"!\" @operator\n  (identifier) @variable.other.member)\n\n(field_definition\n  name: (identifier) @variable.other.member)\n\n(named_node\n  name: (identifier) @tag)\n\n(predicate name: (identifier) @error)\n((predicate\n   \"#\" @function.builtin\n   name: (identifier) @function.builtin @_name\n   type: (predicate_type) @function.builtin)\n (#any-of? @_name \"eq\" \"not-eq\" \"match\" \"not-match\" \"any-of\" \"not-any-of\" \"is\" \"is-not\" \"not-same-line\" \"not-kind-eq\" \"set\" \"select-adjacent\" \"strip\"))\n\n(capture) @label\n\n(escape_sequence) @constant.character.escape\n\n(string) @string\n"
  },
  {
    "path": "runtime/queries/tsq/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n\n((predicate\n  name: (identifier) @_name\n  parameters:\n    (parameters\n      (string (string_content) @injection.content)))\n  (#any-of? @_name \"match\" \"not-match\")\n  (#set! injection.language \"regex\"))\n"
  },
  {
    "path": "runtime/queries/tsq/rainbows.scm",
    "content": "[\n  (list)\n  (predicate)\n  (grouping)\n  (named_node)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"[\" \"]\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/tsx/highlights.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: ecma,_typescript,_jsx\n"
  },
  {
    "path": "runtime/queries/tsx/indents.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _jsx,_typescript,ecma\n"
  },
  {
    "path": "runtime/queries/tsx/injections.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _jsx,_typescript,ecma\n"
  },
  {
    "path": "runtime/queries/tsx/locals.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _jsx,_typescript,ecma\n"
  },
  {
    "path": "runtime/queries/tsx/rainbows.scm",
    "content": "; inherits: typescript\n; inherits: jsx\n"
  },
  {
    "path": "runtime/queries/tsx/tags.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _jsx,_typescript,ecma\n"
  },
  {
    "path": "runtime/queries/tsx/textobjects.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _jsx,_typescript,ecma\n"
  },
  {
    "path": "runtime/queries/twig/highlights.scm",
    "content": "(comment) @comment\n\n(filter_identifier) @function.method\n(function_identifier) @function.method\n(test) @function.builtin\n(variable) @variable\n(string) @string\n(interpolated_string) @string\n(operator) @operator\n(number) @constant.numeric.integer\n(boolean) @constant.builtin.boolean\n(null) @constant.builtin\n(keyword) @keyword\n(attribute) @attribute\n(tag) @tag\n(conditional) @keyword.control.conditional\n(repeat) @keyword.control.repeat\n(method) @function.method\n(parameter) @variable.parameter\n\n[\n    \"{{\"\n    \"}}\"\n    \"{{-\"\n    \"-}}\"\n    \"{{~\"\n    \"~}}\"\n    \"{%\"\n    \"%}\"\n    \"{%-\"\n    \"-%}\"\n    \"{%~\"\n    \"~%}\"\n] @keyword\n\n[\n    \",\"\n    \".\"\n    \"?\"\n    \":\"\n    \"=\"\n] @punctuation.delimiter\n\n[\n    \"(\"\n    \")\"\n    \"[\"\n    \"]\"\n    \"{\"\n] @punctuation.bracket\n\n(hash [\n    \"}\"\n] @punctuation.bracket)\n\n(interpolated_string [\n    \"#{\"\n    \"}\"\n] @punctuation.delimiter)\n\n"
  },
  {
    "path": "runtime/queries/twig/injections.scm",
    "content": "((content) @injection.content\n (#set! injection.language \"html\")\n (#set! injection.combined))\n"
  },
  {
    "path": "runtime/queries/typescript/highlights.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: ecma,_typescript\n"
  },
  {
    "path": "runtime/queries/typescript/indents.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _typescript,ecma\n"
  },
  {
    "path": "runtime/queries/typescript/injections.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _typescript,ecma\n"
  },
  {
    "path": "runtime/queries/typescript/locals.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _typescript,ecma\n"
  },
  {
    "path": "runtime/queries/typescript/rainbows.scm",
    "content": "; inherits: ecma\n\n[\n  (import_require_clause)\n  (enum_body)\n  (lookup_type)\n  (parenthesized_type)\n  (object_type)\n  (type_parameters)\n  (index_signature)\n  (array_type)\n  (tuple_type)\n] @rainbow.scope\n\n(type_arguments [\"<\" \">\"] @rainbow.bracket) @rainbow.scope\n\n[\n  \"{|\" \"|}\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/typescript/tags.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _typescript,ecma\n"
  },
  {
    "path": "runtime/queries/typescript/textobjects.scm",
    "content": "; See runtime/queries/ecma/README.md for more info.\n\n; inherits: _typescript,ecma\n"
  },
  {
    "path": "runtime/queries/typespec/highlights.scm",
    "content": "; Keywords\n\n[\n  \"is\"\n  \"extends\"\n  \"valueof\"\n] @keyword.operator\n\n[\n  \"namespace\"\n  \"scalar\"\n  \"interface\"\n  \"alias\"\n] @keyword\n\n[\n  \"model\"\n  \"enum\"\n  \"union\"\n] @keyword.storage.type\n\n[\n  \"op\"\n  \"fn\"\n  \"dec\"\n] @keyword.function\n\n\"extern\" @keyword.storage.modifier\n\n[\n  \"import\"\n  \"using\"\n] @keyword.control.import\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"<\"\n  \">\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n[\n  \",\"\n  \";\"\n  \".\"\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"|\"\n  \"&\"\n  \"=\"\n  \"...\"\n] @operator\n\n\"?\" @punctuation.special\n\n; Identifiers\n\n(identifier_or_member_expression) @type\n\n; Imports\n\n(import_statement\n  (quoted_string_literal) @string.special.path)\n\n; Namespaces\n\n(using_statement\n  module: (identifier_or_member_expression) @namespace)\n\n(namespace_statement\n  name: (identifier_or_member_expression) @namespace)\n\n; Comments\n\n[\n  (single_line_comment)\n] @comment.line\n\n[\n  (multi_line_comment)\n] @comment.block\n\n; Decorators\n\n(decorator\n  \"@\" @attribute\n  name: (identifier_or_member_expression) @attribute)\n\n(augment_decorator_statement\n  name: (identifier_or_member_expression) @attribute)\n\n(decorator\n  (decorator_arguments) @variable.parameter)\n\n; Scalars\n\n(scalar_statement\n  name: (identifier) @type)\n\n; Models\n\n(model_statement\n  name: (identifier) @type)\n\n(model_property\n  name: (identifier) @variable.other.member)\n\n; Operations\n\n(operation_statement\n  name: (identifier) @function.method)\n\n(operation_arguments\n  (model_property\n    name: (identifier) @variable.parameter))\n\n(template_parameter\n  name: (identifier) @type.parameter)\n\n(function_parameter\n  name: (identifier) @variable.parameter)\n\n; Interfaces\n\n(interface_statement\n  name: (identifier) @type)\n\n(interface_statement\n  (interface_body\n    (interface_member\n      (identifier) @function.method)))\n\n; Enums\n\n(enum_statement\n  name: (identifier) @type.enum)\n\n(enum_member\n  name: (identifier) @constant)\n\n; Unions\n\n(union_statement\n  name: (identifier) @type)\n\n(union_variant\n  name: (identifier) @type.enum.variant)\n\n; Aliases\n\n(alias_statement\n  name: (identifier) @type)\n\n; Built-in types\n\n[\n  (quoted_string_literal)\n  (triple_quoted_string_literal)\n] @string\n\n(escape_sequence) @constant.character.escape\n\n(boolean_literal) @constant.builtin.boolean\n\n[\n  (decimal_literal)\n  (hex_integer_literal)\n  (binary_integer_literal)\n] @constant.numeric.integer\n\n(builtin_type) @type.builtin\n"
  },
  {
    "path": "runtime/queries/typespec/indents.scm",
    "content": "[\n  (model_expression)\n  (tuple_expression)\n  (namespace_body)\n  (interface_body)\n  (union_body)\n  (enum_body)\n  (template_arguments)\n  (template_parameters)\n  (operation_arguments)\n] @indent.begin\n\n[\n  \"}\"\n  \")\"\n  \">\"\n  \"]\"\n] @indent.end\n"
  },
  {
    "path": "runtime/queries/typespec/injections.scm",
    "content": "([\n  (single_line_comment)\n  (multi_line_comment)\n] @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/typespec/textobjects.scm",
    "content": "; Classes\n\n(enum_statement\n  (enum_body) @class.inside) @class.around\n\n(model_statement\n  (model_expression) @class.inside) @class.around\n\n(union_statement\n  (union_body) @class.inside) @class.around\n\n; Interfaces\n\n(interface_statement\n  (interface_body\n    (interface_member) @function.around) @class.inside) @class.around\n\n; Comments\n\n[\n  (single_line_comment)\n  (multi_line_comment)\n] @comment.inside\n\n[\n  (single_line_comment)\n  (multi_line_comment)\n]+ @comment.around\n\n; Functions\n\n[\n  (decorator)\n  (decorator_declaration_statement)\n  (function_declaration_statement)\n  (operation_statement)\n] @function.around\n\n(function_parameter_list\n  (function_parameter)? @parameter.inside)* @function.inside\n\n(decorator_arguments\n  (expression_list\n    (_) @parameter.inside)*) @function.inside\n\n(operation_arguments\n  (model_property)? @parameter.inside)* @function.inside\n\n(template_parameters\n  (template_parameter_list\n    (template_parameter) @parameter.inside)) @function.inside\n"
  },
  {
    "path": "runtime/queries/typst/highlights.scm",
    "content": "; CONTROL\n(let \"let\" @keyword.storage.type)\n(branch [\"if\" \"else\"] @keyword.control.conditional)\n(while \"while\" @keyword.control.repeat)\n(for [\"for\" \"in\"] @keyword.control.repeat)\n(import \"import\" @keyword.control.import)\n(as \"as\" @keyword.operator)\n(include \"include\" @keyword.control.import)\n(show \"show\" @keyword.control)\n(set \"set\" @keyword.control)\n(return \"return\" @keyword.control)\n(flow [\"break\" \"continue\"] @keyword.control)\n\n; OPERATOR\n(let \"=\" @operator)\n(lambda \"=>\" @operator)\n(in [\"in\" \"not\"] @keyword.operator)\n(context \"context\" @keyword.control)\n(and \"and\" @keyword.operator)\n(or \"or\" @keyword.operator)\n(not \"not\" @keyword.operator)\n(sign [\"+\" \"-\"] @operator)\n(add \"+\" @operator)\n(sub \"-\" @operator)\n(mul \"*\" @operator)\n(div \"/\" @operator)\n(cmp [\"==\" \"<=\" \">=\" \"!=\" \"<\" \">\"] @operator)\n(fraction \"/\" @operator)\n(fac \"!\" @operator)\n(attach [\"^\" \"_\"] @operator)\n(wildcard) @operator\n\n; VALUE\n(raw_blck \"```\" @operator) @markup.raw.block\n(raw_span \"`\" @operator) @markup.raw.block\n(raw_blck lang: (ident) @tag)\n(label) @tag\n(ref) @tag\n(number) @constant.numeric\n(string) @string\n(content [\"[\" \"]\"] @operator)\n(bool) @constant.builtin.boolean\n(none) @constant.builtin\n(auto) @constant.builtin\n(ident) @variable\n\n; FUNCTIONS\n(call\n  item: (ident) @function)\n(call\n  item: (field field: (ident) @function.method))\n(tagged field: (ident) @tag)\n(field field: (ident) @tag)\n(comment) @comment\n\n; MARKUP\n(item \"-\" @markup.list)\n(term [\"/\" \":\"] @markup.list)\n(heading \"=\" @markup.heading.marker) @markup.heading.1\n(heading \"==\" @markup.heading.marker) @markup.heading.2\n(heading \"===\" @markup.heading.marker) @markup.heading.3\n(heading \"====\" @markup.heading.marker) @markup.heading.4\n(heading \"=====\" @markup.heading.marker) @markup.heading.5\n(heading \"======\" @markup.heading.marker) @markup.heading.6\n(url) @tag\n(emph) @markup.italic\n(strong) @markup.bold\n(symbol) @constant.character\n(shorthand) @constant.builtin\n(quote) @markup.quote\n(align) @operator\n(letter) @constant.character\n(linebreak) @constant.builtin\n\n(math \"$\" @operator)\n\"#\" @operator\n\"end\" @operator\n\n(escape) @constant.character.escape\n[\"(\" \")\" \"{\" \"}\"] @punctuation.bracket\n[\",\" \";\" \"..\" \":\" \"sep\"] @punctuation.delimiter\n\"assign\" @punctuation\n(field \".\" @punctuation)\n"
  },
  {
    "path": "runtime/queries/typst/injections.scm",
    "content": "(raw_blck\n  (blob) @injection.shebang @injection.content)\n\n(raw_blck\n\tlang: (ident) @injection.language\n  (blob) @injection.content)\n\n((comment)\n\t@injection.content\n\t(#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/typst/tags.scm",
    "content": "; should be a heading\n(heading (text) @definition.section)\n\n; should be a label/reference/tag\n(heading (label) @definition.function)\n(content (label) @definition.function)\n"
  },
  {
    "path": "runtime/queries/typst/textobjects.scm",
    "content": "(let\n  pattern: (call)\n  value: (_) @function.inside) @function.around\n\n(call\n  (group\n    ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around))\n\n(lambda\n  pattern: \n    (group\n      ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n  value: (_) @function.inside) @function.around\n\n(group\n  [\n    (tagged (_) @entry.inside)\n    (_)\n  ] @entry.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/ungrammar/highlights.scm",
    "content": "(line_comment) @comment\n\n(identifier) @function\n\n(labeled_rule\n  (identifier) @type)\n\n(node_rule\n  (identifier) @variable.parameter)\n\n(token) @string\n\n[\n  \"=\"\n  \"|\"\n  \":\"\n  \"(\"\n  \")\"\n  \"?\"\n  \"*\"\n] @operator\n"
  },
  {
    "path": "runtime/queries/unison/highlights.scm",
    "content": ";; Primitives\n(comment) @comment\n(nat) @constant.numeric\n(unit) @constant.builtin\n(literal_char) @constant.character\n(literal_text) @string\n(literal_boolean) @constant.builtin.boolean\n\n;; Keywords\n[\n  (kw_forall)\n  (kw_equals)\n  (do)\n  (kw_let)\n  (ability)\n  (where)\n] @keyword\n\n(kw_let) @keyword.function\n(type_kw) @keyword.storage.modifier\n(structural) @keyword.storage.modifier\n(\"use\") @keyword.control.import\n(unique) @keyword.storage.modifier\n\n[\n  (operator)\n  (pipe)\n  (arrow_symbol)\n  (or)\n  (and)\n] @operator\n\n[\n  \"if\"\n  \"else\"\n  \"then\"\n  (match)\n  (with)\n  (cases)\n] @keyword.control.conditional\n\n(blank_pattern) @variable.builtin\n\n(pattern) @variable\n\n(use_clause) @keyword.import\n\n;; Types\n(record_field\n  (field_name) @variable.other.member\n  type: (regular_identifier) @type)\n\n(type_name) @type\n\n(type_declaration\n  (regular_identifier) @type.enum.variant)\n\n(ability_name\n  (path)? @namespace\n  (regular_identifier) @type)\n\n(ability_declaration\n  (ability_name) @type\n  (type_argument) @variable.parameter)\n\n(type_constructor) @constructor\n\n(constructor\n  (constructor_name) @constructor)\n\n(constructor\n  type: (regular_identifier) @type)\n\n(effect\n  (regular_identifier) @special) ; NOTE: an effect is a special type\n\n; Namespaces\n(path) @namespace\n\n(namespace) @namespace\n\n; Terms\n(type_signature\n  term_name: (path) @namespace\n  term_name: (regular_identifier) @variable)\n\n(type_signature\n  term_name: (regular_identifier) @variable)\n\n(term_type) @type\n\n(term_definition\n  name: (path) @namespace)\n\n(term_definition\n  name: (regular_identifier) @variable)\n\n(term_definition\n  param: (regular_identifier) @variable.parameter)\n\n;; Punctuation\n[\n  (type_signature_colon)\n  \":\"\n] @punctuation.delimiter\n\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n] @punctuation.bracket\n\n(watch_expression) @keyword.directive\n\n(test_watch_expression) @keyword.directive\n"
  },
  {
    "path": "runtime/queries/unison/indents.scm",
    "content": "[\n  (term_definition)\n  (pattern)\n  (exp_if)\n  (constructor)\n  (delay_block)\n  (type_signature)\n] @indent\n\n[(kw_then) (kw_else) (cases)] @indent.always @extend\n"
  },
  {
    "path": "runtime/queries/unison/injections.scm",
    "content": "((doc_block) @injection.content (#set! injection.language \"markdown\"))\n"
  },
  {
    "path": "runtime/queries/unison/rainbows.scm",
    "content": "[\n  (literal_list)\n  (parenthesized_or_tuple_pattern)\n] @rainbow.scope\n\n[\n  \"(\" \")\"\n  \"{\" \"}\"\n  \"[\" \"]\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/unison/tags.scm",
    "content": "(term_definition\n  name: (regular_identifier) @name) @definition.function\n\n(type_declaration\n  (type_kw)\n  (type_constructor\n    ((type_name (regular_identifier) @name)) @definition.type))\n\n(ability_declaration\n  (ability_name) @type _) @definition.type\n"
  },
  {
    "path": "runtime/queries/unison/textobjects.scm",
    "content": "(term_declaration) @function.around\n\n(type_declaration) @class.inside\n(record) @class.inside\n\n(comment) @comment.inside\n(comment)+ @comment.around\n\n(doc_block) @comment.around\n\n(literal_list) @entry.around\n\n(parenthesized_or_tuple_pattern) @entry.around\n\n(pattern) @entry.around\n"
  },
  {
    "path": "runtime/queries/uxntal/highlights.scm",
    "content": "; highlights.scm\n\n(identifier) @keyword\n(number) @constant.numeric\n(comment) @comment\n(raw_character) @constant.character\n(literal_hex) @constant.numeric.integer\n(macro_definition) @function\n(label_definition) @label\n(sub_label_definition) @label\n(relative_pad) @constant\n(label) @label\n(sub_label) @label\n[\"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/v/highlights.scm",
    "content": "[(line_comment) (block_comment)] @comment\n\n(module_clause\n (identifier) @namespace)\n\n(import_path\n (import_name) @namespace)\n\n(import_alias\n (import_name) @namespace)\n\n(enum_fetch\n (reference_expression) @constant)\n\n(enum_field_definition\n (identifier) @constant)\n\n(global_var_definition\n (identifier) @constant)\n\n(compile_time_if_expression\n condition: (reference_expression) @constant)\n\n(compile_time_if_expression\n condition: (binary_expression\n              left: (reference_expression) @constant\n              right: (reference_expression) @constant))\n\n(compile_time_if_expression\n condition: (binary_expression\n              left: (reference_expression) @constant\n              right: (unary_expression (reference_expression) @constant)))\n\n(label_reference) @label\n\n(parameter_declaration\n name: (identifier) @variable.parameter)\n(receiver\n name: (identifier) @variable.parameter)\n(function_declaration\n name: (identifier) @function)\n(function_declaration\n receiver: (receiver)\n name: (identifier) @function.method)\n(interface_method_definition\n name: (identifier) @function.method)\n\n(call_expression\n name: (selector_expression\n  field: (reference_expression) @function.method))\n\n(call_expression\n name: (reference_expression) @function)\n\n(struct_declaration\n name: (identifier) @type)\n\n(enum_declaration\n name: (identifier) @type)\n\n(interface_declaration\n name: (identifier) @type)\n\n(type_declaration\n name: (identifier) @type)\n\n(struct_field_declaration\n name: (identifier) @variable.other.member)\n\n(field_name) @variable.other.member\n\n(selector_expression\n field: (reference_expression) @variable.other.member)\n\n(int_literal) @constant.numeric.integer\n(escape_sequence) @constant.character.escape\n\n[\n (c_string_literal)\n (raw_string_literal)\n (interpreted_string_literal)\n (string_interpolation)\n (rune_literal)\n] @string\n\n(string_interpolation\n (interpolation_opening) @punctuation.bracket\n (interpolation_expression) @embedded\n (interpolation_closing) @punctuation.bracket)\n\n(attribute) @attribute\n\n[\n (type_reference_expression)\n ] @type\n\n[\n (true)\n (false)\n] @constant.builtin.boolean\n(nil) @constant.builtin\n\n[\n  \"pub\"\n  \"assert\"\n  \"asm\"\n  \"defer\"\n  \"unsafe\"\n  \"sql\"\n  (none)\n] @keyword\n\n[\n  \"interface\"\n  \"enum\"\n  \"type\"\n  \"union\"\n  \"struct\"\n  \"module\"\n] @keyword.storage.type\n\n[\n  \"static\"\n  \"const\"\n  \"__global\"\n] @keyword.storage.modifier\n\n[\n  \"mut\"\n] @keyword.storage.modifier.mut\n\n[\n  \"shared\"\n  \"lock\"\n  \"rlock\"\n  \"spawn\"\n  \"break\"\n  \"continue\"\n  \"go\"\n] @keyword.control\n\n[\n  \"if\"\n  \"$if\"\n  \"select\"\n  \"else\"\n  \"$else\"\n  \"match\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n] @keyword.control.repeat\n\n[\n  \"goto\"\n  \"return\"\n] @keyword.control.return\n\n[\n  \"fn\"\n] @keyword.control.function\n\n\n[\n  \"import\"\n] @keyword.control.import\n\n[\n  \"as\"\n  \"in\"\n  \"is\"\n  \"or\"\n] @keyword.operator\n\n[\n \".\"\n \",\"\n \":\"\n \";\"\n] @punctuation.delimiter\n\n[\n \"(\"\n \")\"\n \"{\"\n \"}\"\n \"[\"\n \"]\"\n] @punctuation.bracket\n\n(array_creation) @punctuation.bracket\n\n[\n \"++\"\n \"--\"\n\n \"+\"\n \"-\"\n \"*\"\n \"/\"\n \"%\"\n\n \"~\"\n \"&\"\n \"|\"\n \"^\"\n\n \"!\"\n \"&&\"\n \"||\"\n \"!=\"\n\n \"<<\"\n \">>\"\n\n \"<\"\n \">\"\n \"<=\"\n \">=\"\n\n \"+=\"\n \"-=\"\n \"*=\"\n \"/=\"\n \"&=\"\n \"|=\"\n \"^=\"\n \"<<=\"\n \">>=\"\n\n \"=\"\n \":=\"\n \"==\"\n\n \"?\"\n \"<-\"\n \"$\"\n \"..\"\n \"...\"\n] @operator\n"
  },
  {
    "path": "runtime/queries/v/indents.scm",
    "content": "[\n  (struct_declaration)\n  (function_declaration)\n  (if_expression)\n  (match_expression)\n  (for_statement)\n  (unsafe_expression)\n  (var_declaration)\n  (const_declaration)\n] @indent\n\n[\n  \"]\"\n  \")\"\n  \"}\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/v/injections.scm",
    "content": "([(line_comment) (block_comment)] @injection.content\n (#set! injection.language \"comment\"))\n\n((sql_expression) @injection.content\n (#set! injection.language \"sql\"))\n\n"
  },
  {
    "path": "runtime/queries/v/textobjects.scm",
    "content": "(function_declaration\n  body: (block)? @function.inside) @function.around\n\n((function_declaration\n   name: (identifier) @_name\n   body: (block)? @test.inside) @test.around\n (#match? @_name \"^test\"))\n\n(function_literal\n  body: (block)? @function.inside) @function.around\n\n(parameter_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(call_expression\n  (argument_list\n    ((_) @parameter.inside) @parameter.around))\n\n(struct_declaration\n    (struct_field_declaration) @class.inside) @class.around\n\n(struct_field_declaration\n  ((_) @parameter.inside) @parameter.around)\n\n[(line_comment) (block_comment)] @comment.inside\n[(line_comment)+ (block_comment)+] @comment.around\n\n"
  },
  {
    "path": "runtime/queries/vala/highlights.scm",
    "content": "; highlights.scm\n\n; highlight constants\n(\n  (member_access_expression (identifier) @constant)\n  (#match? @constant \"^[A-Z][A-Z_0-9]*$\")\n)\n\n(\n  (member_access_expression (member_access_expression) @namespace (identifier) @constant)\n  (#match? @constant \"^[A-Z][A-Z_0-9]*$\")\n)\n\n(comment) @comment\n\n(type (symbol (_)? @namespace (identifier) @type))\n\n; highlight creation methods in object creation expressions\n(\n  (object_creation_expression (type (symbol (symbol (symbol)? @namespace (identifier) @type) (identifier) @constructor)))\n  (#match? @constructor \"^[a-z][a-z_0-9]*$\")\n)\n\n(unqualified_type (symbol . (identifier) @type))\n(unqualified_type (symbol (symbol) @namespace (identifier) @type))\n\n(identifier) @variable\n(attribute) @variable.other.member\n(method_declaration (symbol (symbol) @type (identifier) @function))\n(method_declaration (symbol (identifier) @function))\n(local_function_declaration (identifier) @function)\n(destructor_declaration (identifier) @function)\n(creation_method_declaration (symbol (symbol (identifier) @type) (identifier) @constructor))\n(creation_method_declaration (symbol (identifier) @constructor))\n(enum_declaration (symbol) @type)\n(enum_value (identifier) @constant)\n(errordomain_declaration (symbol) @type)\n(errorcode (identifier) @constant)\n(constant_declaration (identifier) @constant)\n(method_call_expression (member_access_expression (identifier) @function))\n(lambda_expression (identifier) @variable.parameter)\n(parameter (identifier) @variable.parameter)\n(property_declaration (symbol (identifier) @variable.other.member))\n(field_declaration (identifier) @variable)\n[\n (this_access)\n (base_access)\n (value_access)\n] @variable.builtin\n(boolean) @constant.builtin.boolean\n(character) @constant.character\n(integer) @constant.numeric.integer\n(null) @constant.builtin\n(real) @constant.numeric.float\n(regex) @string.regexp\n(string) @string\n[\n (escape_sequence)\n (string_formatter)\n] @string.special\n(template_string) @string\n(template_string_expression) @string.special\n(verbatim_string) @string\n[\n \"var\"\n \"void\"\n] @type.builtin\n\n[\n \"abstract\"\n \"async\"\n \"break\"\n \"case\"\n \"catch\"\n \"class\"\n \"const\"\n \"construct\"\n \"continue\"\n \"default\"\n \"delegate\"\n \"do\"\n \"dynamic\"\n \"else\"\n \"enum\"\n \"errordomain\"\n \"extern\"\n \"finally\"\n \"for\"\n \"foreach\"\n \"get\"\n \"if\"\n \"inline\"\n \"interface\"\n \"internal\"\n \"lock\"\n \"namespace\"\n \"new\"\n \"out\"\n \"override\"\n \"owned\"\n \"partial\"\n \"private\"\n \"protected\"\n \"public\"\n \"ref\"\n \"set\"\n \"signal\"\n \"static\"\n \"struct\"\n \"switch\"\n \"throw\"\n \"throws\"\n \"try\"\n \"unowned\"\n \"virtual\"\n \"weak\"\n \"while\"\n \"with\"\n] @keyword\n\n[\n  \"and\"\n  \"as\"\n  \"delete\"\n  \"in\"\n  \"is\"\n  \"not\"\n  \"or\"\n  \"sizeof\"\n  \"typeof\"\n] @keyword.operator\n\n\"using\" @namespace\n\n(symbol \"global::\" @namespace)\n\n(array_creation_expression \"new\" @keyword.operator)\n(object_creation_expression \"new\" @keyword.operator)\n(argument \"out\" @keyword.operator)\n(argument \"ref\" @keyword.operator)\n\n[\n  \"continue\"\n  \"do\"\n  \"for\"\n  \"foreach\"\n  \"while\"\n] @keyword.control.repeat\n\n[\n  \"catch\"\n  \"finally\"\n  \"throw\"\n  \"throws\"\n  \"try\"\n] @keyword.control.exception\n\n[\n  \"return\"\n  \"yield\"\n] @keyword.control.return\n\n[\n \"=\"\n \"==\"\n \"+\"\n \"+=\"\n \"-\"\n \"-=\"\n \"++\"\n \"--\"\n \"|\"\n \"|=\"\n \"&\"\n \"&=\"\n \"^\"\n \"^=\"\n \"/\"\n \"/=\"\n \"*\"\n \"*=\"\n \"%\"\n \"%=\"\n \"<<\"\n \"<<=\"\n \">>\"\n \">>=\"\n \".\"\n \"?.\"\n \"->\"\n \"!\"\n \"!=\"\n \"~\"\n \"??\"\n \"?\"\n \":\"\n \"<\"\n \"<=\"\n \">\"\n \">=\"\n \"||\"\n \"&&\"\n \"=>\"\n] @operator\n\n[\n \",\"\n \";\"\n] @punctuation.delimiter\n\n[\n \"(\"\n \")\"\n \"{\"\n \"}\"\n \"[\"\n \"]\"\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/vala/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/vala/textobjects.scm",
    "content": "(method_declaration\n  (block) @function.inside) @function.around\n\n(creation_method_declaration\n  (block) @function.inside) @function.around\n\n(method_declaration\n  ((parameter) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n[\n  (class_declaration)\n  (struct_declaration)\n  (interface_declaration)\n] @class.around\n\n(type_arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(creation_method_declaration\n  ((parameter) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(method_call_expression\n  ((argument) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/vento/highlights.scm",
    "content": "(comment) @comment\n\n(keyword) @keyword\n\n(tag\n  [\n    \"{{\"\n    \"{{-\"\n    \"}}\"\n    \"-}}\"\n  ] @punctuation.bracket)\n\n\"|>\" @operator\n"
  },
  {
    "path": "runtime/queries/vento/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n((content) @injection.content\n  (#set! injection.language \"html\")\n  (#set! injection.combined))\n\n((code) @injection.content\n  (#set! injection.language \"javascript\"))\n"
  },
  {
    "path": "runtime/queries/verilog/highlights.scm",
    "content": "; Keywords\n\n[\n  ; block delimiters\n  (module_keyword)\n  \"endmodule\"\n  \"program\"\n  \"endprogram\"\n  \"class\"\n  \"endclass\"\n  \"interface\"\n  \"endinterface\"\n  \"package\"\n  \"endpackage\"\n  \"checker\"\n  \"endchecker\"\n  \"config\"\n  \"endconfig\"\n\n  \"pure\"\n  \"virtual\"\n  \"extends\"\n  \"implements\"\n  \"super\"\n  (class_item_qualifier)\n\n  \"parameter\"\n  \"localparam\"\n  \"defparam\"\n  \"assign\"\n  \"typedef\"\n  \"modport\"\n  \"fork\"\n  \"join\"\n  \"join_none\"\n  \"join_any\"\n  \"default\"\n  \"break\"\n  \"assert\"\n  (unique_priority)\n  \"tagged\"\n  \"extern\"\n] @keyword\n\n[\n  \"function\"\n  \"endfunction\"\n\n  \"task\"\n  \"endtask\"\n] @keyword.function\n\n\"return\" @keyword.control.return\n\n[\n  \"begin\"\n  \"end\"\n] @label\n\n[\n  (always_keyword)\n  \"generate\"\n  \"for\"\n  \"foreach\"\n  \"repeat\"\n  \"forever\"\n  \"initial\"\n  \"while\"\n] @keyword.control\n\n[\n  \"if\"\n  \"else\"\n  (case_keyword)\n  \"endcase\"\n] @keyword.control.conditional\n\n(comment) @comment\n\n(include_compiler_directive) @keyword.directive\n(package_import_declaration\n \"import\" @keyword.control.import)\n\n(package_import_declaration\n (package_import_item\n  (package_identifier\n   (simple_identifier) @constant)))\n\n(text_macro_identifier\n (simple_identifier) @keyword.directive)\n\n(package_scope\n (package_identifier\n  (simple_identifier) @constant))\n\n(package_declaration\n (package_identifier\n  (simple_identifier) @constant))\n\n(parameter_port_list\n \"#\" @constructor)\n\n[\n  \"=\"\n  \"-\"\n  \"+\"\n  \"/\"\n  \"*\"\n  \"**\"\n  \"^\"\n  \"&\"\n  \"|\"\n  \"&&\"\n  \"||\"\n  \":\"\n  (unary_operator)\n  \"{\"\n  \"}\"\n  \"'{\"\n  \"<=\"\n  \"@\"\n  \"==\"\n  \"!=\"\n  \"===\"\n  \"!==\"\n  \"-:\"\n  \"<\"\n  \">\"\n  \">=\"\n  \"%\"\n  \">>\"\n  \"<<\"\n  \">>>\"\n  \"<<<\"\n  \"|=\"\n  (inc_or_dec_operator)\n  \"?\"\n] @operator\n[\n  \"or\"\n  \"and\"\n] @keyword.operator\n\n(cast\n [\"'\" \"(\" \")\"] @keyword.operator)\n\n(edge_identifier) @constant\n\n(port_direction) @label\n(port_identifier\n (simple_identifier) @variable)\n\n(variable_port_header (\"var\") @type.builtin)\n(data_declaration (\"var\") @type.builtin)\n(tf_port_item1 (\"var\") @type.builtin)\n[\n  (net_type)\n  (integer_vector_type)\n  (integer_atom_type)\n] @type.builtin\n\n[\n  \"signed\"\n  \"unsigned\"\n] @label\n\n(data_type\n (simple_identifier) @type)\n\n(method_call_body\n  (method_identifier) @variable.other.member)\n\n(interface_identifier\n (simple_identifier) @type)\n\n(modport_identifier\n (modport_identifier\n  (simple_identifier) @variable.other.member))\n\n(net_port_type1\n (simple_identifier) @type)\n\n[\n  (double_quoted_string)\n  (string_literal)\n] @string\n\n[\n  (include_compiler_directive)\n  (default_nettype_compiler_directive)\n  (timescale_compiler_directive)\n] @keyword.directive\n\n; begin/end label\n(seq_block\n (simple_identifier) @comment)\n\n[\n \";\"\n \"::\"\n \",\"\n \".\"\n] @punctuation.delimiter\n\n\n(default_nettype_compiler_directive\n (default_nettype_value) @string)\n\n(text_macro_identifier\n (simple_identifier) @function.macro)\n\n(module_declaration\n (module_header\n  (simple_identifier) @constructor))\n\n(class_constructor_declaration\n \"new\" @constructor)\n\n(parameter_identifier\n (simple_identifier) @variable.parameter)\n\n[\n  (integral_number)\n  (unsigned_number)\n  (unbased_unsized_literal)\n] @constant.numeric\n\n(time_unit) @constant\n\n(checker_instantiation\n (checker_identifier\n  (simple_identifier) @constructor))\n\n(module_instantiation\n (simple_identifier) @constructor)\n\n(name_of_instance\n (instance_identifier\n  (simple_identifier) @variable))\n\n(interface_port_declaration\n (interface_identifier\n  (simple_identifier) @type))\n\n(net_declaration\n (simple_identifier) @type)\n\n(lifetime) @label\n\n(function_identifier \n (function_identifier \n  (simple_identifier) @function))\n\n(function_subroutine_call \n (subroutine_call\n  (tf_call\n   (simple_identifier) @function)))\n\n(function_subroutine_call \n (subroutine_call\n  (system_tf_call\n   (system_tf_identifier) @function.builtin)))\n\n(task_identifier\n (task_identifier\n  (simple_identifier) @function.method))\n\n;;TODO: fixme\n;(assignment_pattern_expression\n ;(assignment_pattern\n  ;(parameter_identifier) @variable.other.member))\n\n(type_declaration\n  (data_type [\"packed\"] @label))\n\n(struct_union) @type\n\n[\n  \"enum\"\n] @type\n\n(enum_name_declaration\n (enum_identifier\n  (simple_identifier) @constant))\n\n(type_declaration\n (simple_identifier) @type)\n\n[\n  (integer_atom_type)\n  (non_integer_type)\n  \"genvar\"\n] @type.builtin\n\n(struct_union_member\n (list_of_variable_decl_assignments\n  (variable_decl_assignment\n   (simple_identifier) @variable.other.member)))\n\n(member_identifier\n (simple_identifier) @variable.other.member)\n\n(struct_union_member\n (data_type_or_void\n  (data_type\n   (simple_identifier) @type)))\n\n(type_declaration\n (simple_identifier) @type)\n\n(generate_block_identifier) @comment\n\n[\n  \"[\"\n  \"]\"\n  \"(\"\n  \")\"\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/verilog/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))"
  },
  {
    "path": "runtime/queries/verilog/locals.scm",
    "content": "[\n  (loop_generate_construct)\n  (loop_statement)\n  (conditional_statement)\n  (case_item)\n  (function_declaration)\n  (always_construct)\n  (module_declaration)\n] @scope\n\n(parameter_declaration\n (list_of_param_assignments\n  (param_assignment\n   (parameter_identifier\n    (simple_identifier) @local.definition.variable.parameter))))\n\n(local_parameter_declaration\n (list_of_param_assignments\n  (param_assignment\n   (parameter_identifier\n    (simple_identifier) @local.definition.variable.parameter))))\n\n;; TODO: fixme\n;(function_declaration\n ;(function_identifier\n  ;(simple_identifier) @local.definition.function))\n\n(function_declaration\n (function_body_declaration\n  (function_identifier\n   (function_identifier\n    (simple_identifier) @local.definition.function))))\n\n(tf_port_item1\n (port_identifier\n  (simple_identifier) @local.definition.variable.parameter))\n\n; too broad, now includes types etc\n(simple_identifier) @local.reference\n"
  },
  {
    "path": "runtime/queries/verilog/textobjects.scm",
    "content": "\n(function_declaration\n (function_body_declaration\n  (function_identifier\n     (function_identifier\n        (simple_identifier) @function.inside)))) @function.around\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/vhdl/highlights.scm",
    "content": "(line_comment) @comment.line\n\n(block_comment) @comment.block\n\n(identifier) @variable\n\n[\n  \"access\"\n  \"after\"\n  \"alias\"\n  \"architecture\"\n  \"array\"\n  \"attribute\"\n  \"block\"\n  \"body\"\n  \"component\"\n  \"configuration\"\n  \"context\"\n  \"disconnect\"\n  \"entity\"\n  \"file\"\n  \"force\"\n  \"generate\"\n  \"generic\"\n  \"group\"\n  \"label\"\n  \"literal\"\n  \"map\"\n  \"new\"\n  \"package\"\n  \"parameter\"\n  \"port\"\n  \"property\"\n  \"range\"\n  \"reject\"\n  \"release\"\n  \"sequence\"\n  \"transport\"\n  \"unaffected\"\n  \"view\"\n  \"vunit\"\n] @keyword\n\n[\n  (ALL)\n  (OTHERS)\n  \"<>\"\n  (DEFAULT)\n  (OPEN)\n] @constant.builtin\n\n[\n  \"is\"\n  \"begin\"\n  \"end\"\n] @keyword\n\n(parameter_specification\n  \"in\" @keyword)\n\n[\n  \"process\"\n  \"wait\"\n  \"on\"\n  \"until\"\n] @keyword\n\n(timeout_clause\n  \"for\" @keyword)\n\n[\n  \"function\"\n  \"procedure\"\n] @keyword.function\n\n[\n  \"to\"\n  \"downto\"\n  \"of\"\n] @keyword.operator\n\n[\n  \"library\"\n  \"use\"\n] @keyword.control.import\n\n[\n  \"subtype\"\n  \"type\"\n  \"record\"\n  \"units\"\n  \"constant\"\n  \"signal\"\n  \"variable\"\n] @keyword.storage.type\n\n[\n  \"protected\"\n  \"private\"\n  \"pure\"\n  \"impure\"\n  \"inertial\"\n  \"postponed\"\n  \"guarded\"\n  \"out\"\n  \"inout\"\n  \"linkage\"\n  \"buffer\"\n  \"register\"\n  \"bus\"\n  \"shared\"\n] @keyword.storage.modifier\n\n(mode\n  \"in\" @keyword.storage.modifier)\n\n(force_mode\n  \"in\" @keyword.storage.modifier)\n\n[\n  \"while\"\n  \"loop\"\n  \"next\"\n  \"exit\"\n] @keyword.control.repeat\n\n(for_loop\n  \"for\" @keyword.control.repeat)\n\n(block_configuration\n  \"for\" @keyword)\n\n(configuration_specification\n  \"for\" @keyword)\n\n(component_configuration\n  \"for\" @keyword)\n\n(end_for\n  \"for\" @keyword)\n\n\"return\" @keyword.control.return\n\n[\n  \"assert\"\n  \"report\"\n  \"severity\"\n] @keyword\n\n[\n  \"if\"\n  \"then\"\n  \"elsif\"\n  \"case\"\n] @keyword.control.conditional\n\n(when_element\n  \"when\" @keyword.control.conditional)\n\n(case_generate_alternative\n  \"when\" @keyword.control.conditional)\n\n(else_statement\n  \"else\" @keyword.control.conditional)\n\n(else_generate\n  \"else\" @keyword.control.conditional)\n\n[\n  \"with\"\n  \"select\"\n] @keyword.control.conditional\n\n(when_expression\n  \"when\" @keyword.control.conditional)\n\n(else_expression\n  \"else\" @keyword.control.conditional)\n\n(else_waveform\n  \"else\" @keyword.control.conditional)\n\n(else_expression_or_unaffected\n  \"else\" @keyword.control.conditional)\n\n\"null\" @constant.builtin\n\n(user_directive) @keyword.directive\n\n(protect_directive) @keyword.directive\n\n(warning_directive) @keyword.directive\n\n(error_directive) @keyword.directive\n\n(if_conditional_analysis\n  \"if\" @keyword.directive)\n\n(if_conditional_analysis\n  \"then\" @keyword.directive)\n\n(elsif_conditional_analysis\n  \"elsif\" @keyword.directive)\n\n(else_conditional_analysis\n  \"else\" @keyword.directive)\n\n(end_conditional_analysis\n  \"end\" @keyword.directive)\n\n(end_conditional_analysis\n  \"if\" @keyword.directive)\n\n(directive_body) @keyword.directive\n\n(directive_constant_builtin) @constant.builtin\n\n(directive_error) @keyword.directive\n\n(directive_protect) @keyword.directive\n\n(directive_warning) @keyword.directive\n\n[\n  (condition_conversion)\n  (relational_operator)\n  (sign)\n  (adding_operator)\n  (exponentiate)\n  (variable_assignment)\n  (signal_assignment)\n  \"*\"\n  \"/\"\n  \":\"\n  \"=>\"\n] @operator\n\n[\n  (unary_operator)\n  (logical_operator)\n  (shift_operator)\n  \"mod\"\n  \"not\"\n  \"rem\"\n] @keyword.operator\n\n[\n  \"'\"\n  \",\"\n  \".\"\n  \";\"\n] @punctuation.delimiters\n\n[\n  \"(\"\n  \")\"\n  \"[\"\n  \"]\"\n  \"<<\"\n  \">>\"\n] @punctuation.bracket\n\n\"@\" @punctuation.special\n\n[\n  (decimal_integer)\n  (string_literal_std_logic)\n] @constant.numeric.integer\n\n(decimal_float) @constant.numeric.float\n\n(bit_string_length) @type.parameter\n\n(bit_string_base) @type.builtin\n\n(bit_string_value) @constant.numeric.integer\n\n(based_literal\n  (based_base) @type.builtin\n  (based_integer) @constant.numeric.integer)\n\n(based_literal\n  (based_base) @type.builtin\n  (based_float) @constant.numeric.float)\n\n(string_literal) @string\n\n(character_literal) @constant.character\n\n(library_constant_std_logic) @constant.builtin\n\n(library_constant) @constant.builtin\n\n(library_function) @function.builtin\n\n(library_constant_boolean) @constant.builtin.boolean\n\n(library_constant_character) @constant.character\n\n(unit) @keyword.storage.modifier\n\n(library_constant_unit) @keyword.storage.modifier\n\n(label) @label\n\n(generic_map_aspect\n  \"generic\" @constructor\n  \"map\" @constructor)\n\n(port_map_aspect\n  \"port\" @constructor\n  \"map\" @constructor)\n\n(selection\n  (identifier) @variable.other.member)\n\n(_\n  view: (_) @type)\n\n(_\n  type: (_) @type)\n\n(_\n  library: (_) @namespace)\n\n(_\n  package: (_) @namespace)\n\n(_\n  entity: (_) @namespace)\n\n(_\n  component: (_) @namespace)\n\n(_\n  configuration: (_) @type.parameter)\n\n(_\n  architecture: (_) @type.parameter)\n\n(_\n  function: (_) @function)\n\n(_\n  procedure: (_) @function.method)\n\n(_\n  attribute: (_) @attribute)\n\n(_\n  constant: (_) @constant)\n\n(_\n  generic: (_) @variable.parameter)\n\n(_\n  view: (name\n    (_)) @type)\n\n(_\n  type: (name\n    (_)) @type)\n\n(_\n  entity: (name\n    (_)) @namespace)\n\n(_\n  component: (name\n    (_)) @namespace)\n\n(_\n  configuration: (name\n    (_)) @namespace)\n\n(library_type) @type.builtin\n\n"
  },
  {
    "path": "runtime/queries/vhs/highlights.scm",
    "content": "[\n  \"Output\"\n  \"Backspace\"\n  \"Down\"\n  \"Enter\"\n  \"Escape\"\n  \"Left\"\n  \"Right\"\n  \"Space\"\n  \"Tab\"\n  \"Up\"\n  \"Set\"\n  \"Type\"\n  \"Sleep\"\n  \"Hide\"\n  \"Show\" ] @keyword\n\n[ \"Shell\"\n  \"FontFamily\"\n  \"FontSize\"\n  \"Framerate\"\n  \"PlaybackSpeed\"\n  \"Height\"\n  \"LetterSpacing\"\n  \"TypingSpeed\"\n  \"LineHeight\"\n  \"Padding\"\n  \"Theme\"\n  \"LoopOffset\"\n  \"Width\"\n  \"BorderRadius\"\n  \"Margin\"\n  \"MarginFill\"\n  \"WindowBar\"\n  \"WindowBarSize\"\n  \"CursorBlink\" ] @type\n\n[ \"@\" ] @operator\n(control) @function.macro\n(float) @constant.numeric.float\n(integer) @constant.numeric.integer\n(comment) @comment\n[(string) (json)] @string.special.path\n(path) @string.special.path\n(time) @string.special.symbol\n(boolean) @constant.builtin.boolean\n"
  },
  {
    "path": "runtime/queries/vim/folds.scm",
    "content": "[\n  (if_statement)\n  (function_definition)\n] @fold\n"
  },
  {
    "path": "runtime/queries/vim/highlights.scm",
    "content": "(identifier) @variable\n\n((identifier) @constant\n  (#match? @constant \"^[A-Z][A-Z_0-9]*$\"))\n\n; Keywords\n[\n  \"if\"\n  \"else\"\n  \"elseif\"\n  \"endif\"\n] @keyword.control.conditional\n\n[\n  \"try\"\n  \"catch\"\n  \"finally\"\n  \"endtry\"\n  \"throw\"\n] @keyword.control.except\n\n[\n  \"for\"\n  \"endfor\"\n  \"in\"\n  \"while\"\n  \"endwhile\"\n  \"break\"\n  \"continue\"\n] @keyword.control.repeat\n\n[\n  \"function\"\n  \"endfunction\"\n] @keyword.function\n\n; Function related\n(function_declaration\n  name: (_) @function)\n\n(call_expression\n  function: (identifier) @function)\n\n(call_expression\n  function:\n    (scoped_identifier\n      (identifier) @function))\n\n(parameters\n  (identifier) @variable.parameter)\n\n(default_parameter\n  (identifier) @variable.parameter)\n\n[\n  (bang)\n  (spread)\n] @punctuation.special\n\n[\n  (no_option)\n  (inv_option)\n  (default_option)\n  (option_name)\n] @variable.builtin\n\n[\n  (scope)\n  \"a:\"\n  \"$\"\n] @namespace\n\n; Commands and user defined commands\n[\n  \"let\"\n  \"unlet\"\n  \"const\"\n  \"call\"\n  \"execute\"\n  \"normal\"\n  \"set\"\n  \"setfiletype\"\n  \"setlocal\"\n  \"silent\"\n  \"echo\"\n  \"echon\"\n  \"echohl\"\n  \"echomsg\"\n  \"echoerr\"\n  \"autocmd\"\n  \"augroup\"\n  \"return\"\n  \"syntax\"\n  \"filetype\"\n  \"source\"\n  \"lua\"\n  \"ruby\"\n  \"perl\"\n  \"python\"\n  \"highlight\"\n  \"command\"\n  \"delcommand\"\n  \"comclear\"\n  \"colorscheme\"\n  \"scriptencoding\"\n  \"startinsert\"\n  \"stopinsert\"\n  \"global\"\n  \"runtime\"\n  \"wincmd\"\n  \"cnext\"\n  \"cprevious\"\n  \"cNext\"\n  \"vertical\"\n  \"leftabove\"\n  \"aboveleft\"\n  \"rightbelow\"\n  \"belowright\"\n  \"topleft\"\n  \"botright\"\n  (unknown_command_name)\n  \"edit\"\n  \"enew\"\n  \"find\"\n  \"ex\"\n  \"visual\"\n  \"view\"\n  \"eval\"\n  \"sign\"\n] @keyword\n\n(map_statement\n  cmd: _ @keyword)\n\n(keycode) @constant.character.escape\n\n(command_name) @function.macro\n\n; Filetype command\n(filetype_statement\n  [\n    \"detect\"\n    \"plugin\"\n    \"indent\"\n    \"on\"\n    \"off\"\n  ] @keyword)\n\n; Syntax command\n(syntax_statement\n  (keyword) @string)\n\n(syntax_statement\n  [\n    \"enable\"\n    \"on\"\n    \"off\"\n    \"reset\"\n    \"case\"\n    \"spell\"\n    \"foldlevel\"\n    \"iskeyword\"\n    \"keyword\"\n    \"match\"\n    \"cluster\"\n    \"region\"\n    \"clear\"\n    \"include\"\n  ] @keyword)\n\n(syntax_argument\n  name: _ @keyword)\n\n[\n  \"<buffer>\"\n  \"<nowait>\"\n  \"<silent>\"\n  \"<script>\"\n  \"<expr>\"\n  \"<unique>\"\n] @constant.builtin\n\n(augroup_name) @namespace\n\n(au_event) @constant\n\n(normal_statement\n  (commands) @constant)\n\n; Highlight command\n(hl_attribute\n  key: _ @variable.parameter\n  val: _ @constant)\n\n(hl_group) @type\n\n(highlight_statement\n  [\n    \"default\"\n    \"link\"\n    \"clear\"\n  ] @keyword)\n\n; Command command\n(command) @string\n\n(command_attribute\n  name: _ @variable.parameter)\n\n(command_attribute\n  val: (behavior\n         _ @constant))\n\n; Edit command\n(plus_plus_opt\n  val: _? @constant) @variable.parameter\n\n(plus_cmd\n  \"+\" @variable.parameter) @variable.parameter\n\n; Runtime command\n(runtime_statement\n  (where) @keyword.operator)\n\n; Colorscheme command\n(colorscheme_statement\n  (name) @string)\n\n; Scriptencoding command\n(scriptencoding_statement\n  (encoding) @string.special)\n\n; Literals\n(string_literal) @string\n\n(integer_literal) @constant.numeric.integer\n\n(float_literal) @constant.numeric.float\n\n(comment) @comment\n\n(line_continuation_comment) @comment\n\n(pattern) @string.special\n\n(pattern_multi) @string.regexp\n\n(filename) @string.special.path\n\n(heredoc\n  (body) @string)\n\n(heredoc\n  (parameter) @keyword)\n\n[\n  (marker_definition)\n  (endmarker)\n] @label\n\n(literal_dictionary\n  (literal_key) @variable.parameter)\n\n((scoped_identifier\n  (scope) @_scope\n  .\n  (identifier) @constant.builtin.boolean)\n  (#eq? @_scope \"v:\")\n  (#any-of? @constant.builtin.boolean \"true\" \"false\"))\n\n; Operators\n[\n  \"||\"\n  \"&&\"\n  \"&\"\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"..\"\n  \"is\"\n  \"isnot\"\n  \"==\"\n  \"!=\"\n  \">\"\n  \">=\"\n  \"<\"\n  \"<=\"\n  \"=~\"\n  \"!~\"\n  \"=\"\n  \"+=\"\n  \"-=\"\n  \"*=\"\n  \"/=\"\n  \"%=\"\n  \".=\"\n  \"..=\"\n  \"<<\"\n  \"=<<\"\n  (match_case)\n] @operator\n\n; Some characters have different meanings based on the context\n(unary_operation\n  \"!\" @operator)\n\n(binary_operation\n  \".\" @operator)\n\n; Punctuation\n[\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"#{\"\n] @punctuation.bracket\n\n(field_expression\n  \".\" @punctuation.delimiter)\n\n[\n  \",\"\n  \":\"\n] @punctuation.delimiter\n\n(ternary_expression\n  [\n    \"?\"\n    \":\"\n  ] @keyword.operator)\n\n; Options\n((set_value) @constant.numeric\n  (#match? @constant.numeric \"^[0-9]+([.][0-9]+)?$\"))\n\n(inv_option\n  \"!\" @operator)\n\n(set_item\n  \"?\" @operator)\n\n((set_item\n  option: (option_name) @_option\n  value: (set_value) @function)\n  (#any-of? @_option \"tagfunc\" \"tfu\" \"completefunc\" \"cfu\" \"omnifunc\" \"ofu\" \"operatorfunc\" \"opfunc\"))\n"
  },
  {
    "path": "runtime/queries/vim/injections.scm",
    "content": "(lua_statement\n  (script\n    (body) @injection.content\n    (#set! injection.language \"lua\")))\n\n(lua_statement\n  (chunk) @injection.content\n  (#set! injection.language \"lua\"))\n\n(ruby_statement\n  (script\n    (body) @injection.content\n    (#set! injection.language \"ruby\")))\n\n(ruby_statement\n  (chunk) @injection.content\n  (#set! injection.language \"ruby\"))\n\n(python_statement\n  (script\n    (body) @injection.content\n    (#set! injection.language \"python\")))\n\n(python_statement\n  (chunk) @injection.content\n  (#set! injection.language \"python\"))\n\n; If we support perl at some point...\n; (perl_statement (script (body) @perl))\n; (perl_statement (chunk) @perl)\n(autocmd_statement\n  (pattern) @injection.content\n  (#set! injection.language \"regex\"))\n\n((set_item\n  option: (option_name) @_option\n  value: (set_value) @injection.content)\n  (#any-of? @_option\n    \"includeexpr\" \"inex\" \"printexpr\" \"pexpr\" \"formatexpr\" \"fex\" \"indentexpr\" \"inde\" \"foldtext\" \"fdt\"\n    \"foldexpr\" \"fde\" \"diffexpr\" \"dex\" \"patchexpr\" \"pex\" \"charconvert\" \"ccv\")\n  (#set! injection.language \"vim\"))\n\n((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/vue/highlights.scm",
    "content": "(tag_name) @tag\n(end_tag) @tag\n\n(directive_name) @keyword\n(directive_argument) @constant\n\n(attribute\n  (attribute_name) @attribute\n  [(attribute_value) (quoted_attribute_value)]? @string)\n \n(directive_attribute\n  (directive_name) @attribute\n  (directive_argument)? @attribute\n  (directive_modifiers)? @attribute\n  [(attribute_value) (quoted_attribute_value)]? @string) \n\n(comment) @comment\n\n[\n  \"<\"\n  \">\"\n  \"</\"\n  \"{{\"\n  \"}}\"\n  \"/>\" \n] @punctuation.bracket\n\"=\" @punctuation.delimiter\n\n"
  },
  {
    "path": "runtime/queries/vue/injections.scm",
    "content": "(directive_attribute\n  (directive_name) @keyword\n  (quoted_attribute_value\n    (attribute_value) @injection.content)\n (#set! injection.language \"javascript\"))\n\n((interpolation\n  (raw_text) @injection.content)\n (#set! injection.language \"javascript\"))\n\n; <script>\n((script_element\n    (start_tag) @_no_lang\n    (raw_text) @injection.content)\n  (#not-match? @_no_lang \"lang=\")\n  (#set! injection.language \"javascript\"))\n\n; <script lang=\"...\">\n((script_element\n  (start_tag\n    (attribute\n    (attribute_name) @_attr_name\n    (quoted_attribute_value (attribute_value) @injection.language)))\n  (raw_text) @injection.content)\n  (#eq? @_attr_name \"lang\"))\n\n; <style>\n((style_element\n    (start_tag) @_no_lang\n    (raw_text) @injection.content)\n  (#not-match? @_no_lang \"lang=\")\n  (#set! injection.language \"css\"))\n\n; <style lang=\"...\">\n((style_element\n  (start_tag\n    (attribute\n      (attribute_name) @_attr_name\n      (quoted_attribute_value (attribute_value) @injection.language)))\n   (raw_text) @injection.content)\n (#eq? @_attr_name \"lang\"))\n\n; <template>\n((template_element\n    (start_tag) @_no_lang\n    (text) @injection.content)\n  (#not-match? @_no_lang \"lang=\")\n  (#set! injection.language \"html\"))\n\n; <template lang=\"...\">\n((template_element\n    (start_tag\n      (attribute\n      (attribute_name) @_attr_name\n      (quoted_attribute_value (attribute_value) @injection.language)))\n  (text) @injection.content)\n  (#eq? @_attr_name \"lang\"))\n\n((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/wast/highlights.scm",
    "content": "; inherits: wat\n\n[\n  \"assert_return\"\n  \"assert_trap\"\n  \"assert_exhaustion\"\n  \"assert_malformed\"\n  \"assert_invalid\"\n  \"assert_unlinkable\"\n  \"assert_trap\"\n\n  \"invoke\"\n  \"get\"\n\n  \"script\"\n  \"input\"\n  \"output\"\n\n  \"binary\"\n  \"quote\"\n] @keyword\n"
  },
  {
    "path": "runtime/queries/wat/highlights.scm",
    "content": "[\n  \"module\" \"func\" \"param\" \"result\" \"type\" \"memory\" \"elem\" \"data\" \"table\" \"global\"\n  \"if\" \"then\" \"else\" \"block\" \"loop\" \"end\" \"mut\"\n] @keyword\n\n[\"import\" \"export\"] @keyword.control.import\n\n[\"local\"] @keyword.storage.type\n\n[(name) (string)] @string\n\n(identifier) @function\n\n[(comment_block) (comment_line)] @comment\n\n[(nat) (float) (align_offset_value)] @constant.numeric.integer\n\n(value_type) @type\n\n[\"(\" \")\"] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/webc/highlights.scm",
    "content": "; inherits: html"
  },
  {
    "path": "runtime/queries/webc/injections.scm",
    "content": "; inherits: html"
  },
  {
    "path": "runtime/queries/werk/highlights.scm",
    "content": "(buildBlock . (\"build\") @keyword.function)\n(taskBlock . (\"task\") @keyword.function )\n(run . (\"run\") @keyword.function )\n(taskBlock name: (identifier) @function )\n\n(comment) @comment\n(string) @string\n(number) @constant.numeric\n(identifier) @identifier\n\n(include) @keyword.control.import\n(let) @keyword.storage\n(default) @keyword.storage\n(config) @keyword.storage\n\n(interpolation [\"{\" \"}\" \"<\" \">\" ] @punctuation.special)\n[\"{\" \"}\" \"<\" \">\" \"(\" \")\" \"[\" \"]\"] @punctuation.bracket\n[\"=>\" \"|\"] @punctuation\n\n; Statements\n(build \"build\") @function\n(config \"config\") @function\n(copy \"copy\") @function\n(default \"default\") @function\n(delete \"delete\") @function\n(depfile \"depfile\") @function\n(envRemove \"env-remove\") @function\n(from \"from\") @function\n(info \"info\") @function\n(let \"let\") @function\n(setEnv \"env\") @function\n(shell \"shell\") @function\n(write \"write\") @function\n\n; Expressions\n(error \"error\" @function.builtin)\n(getEnv \"env\" @function.builtin)\n(glob \"glob\" @function.builtin)\n(include \"include\" @function.builtin)\n(info \"info\" @function.builtin)\n(read \"read\" @function.builtin)\n(warn \"warn\" @function.builtin)\n(which \"which\" @function.builtin)\n\n; Operations\n(op (string)  @operator) \n(\"dedup\" @operator)\n(\"first\" @operator)\n(\"flatten\" @operator)\n(\"last\" @operator)\n(\"len\" @operator)\n(\"lines\" @operator)\n(\"tail\" @operator)\n(assertEq \"assert-eq\" @operator)\n(discard \"discard\" @operator)\n(filter \"filter\" @operator)\n(filterMatch \"filter-match\" @operator)\n(join \"join\" @operator)\n(map \"map\" @operator)\n(match \"match\" @operator)\n(split \"split\" @operator)\n\n"
  },
  {
    "path": "runtime/queries/wesl/highlights.scm",
    "content": "; reserved: must not be used in source code. https://www.w3.org/TR/WGSL/#reserved-words\n\n; ((identifier) @special\n;   (#any-of? @special\n;   \"NULL\" \"Self\" \"abstract\" \"active\" \"alignas\" \"alignof\" \"as\" \"asm\"\n; \"asm_fragment\" \"async\" \"attribute\" \"auto\" \"await\" \"become\" \"binding_array\"\n; \"cast\" \"catch\" \"class\" \"co_await\" \"co_return\" \"co_yield\" \"coherent\"\n; \"column_major\" \"common\" \"compile\" \"compile_fragment\" \"concept\" \"const_cast\"\n; \"consteval\" \"constexpr\" \"constinit\" \"crate\" \"debugger\" \"decltype\" \"delete\"\n; \"demote\" \"demote_to_helper\" \"do\" \"dynamic_cast\" \"enum\" \"explicit\" \"export\"\n; \"extends\" \"extern\" \"external\" \"fallthrough\" \"filter\" \"final\" \"finally\" \"friend\"\n; \"from\" \"fxgroup\" \"get\" \"goto\" \"groupshared\" \"highp\" \"impl\" \"implements\" \"import\"\n; \"inline\" \"instanceof\" \"interface\" \"layout\" \"lowp\" \"macro\" \"macro_rules\" \"match\"\n; \"mediump\" \"meta\" \"mod\" \"module\" \"move\" \"mut\" \"mutable\" \"namespace\" \"new\"\n; \"nil\" \"noexcept\" \"noinline\" \"nointerpolation\" \"non_coherent\" \"noncoherent\"\n; \"noperspective\" \"null\" \"nullptr\" \"of\" \"operator\" \"package\" \"packoffset\"\n; \"partition\" \"pass\" \"patch\" \"pixelfragment\" \"precise\" \"precision\" \"premerge\"\n; \"priv\" \"protected\" \"pub\" \"public\" \"readonly\" \"ref\" \"regardless\" \"register\"\n; \"reinterpret_cast\" \"require\" \"resource\" \"restrict\" \"self\" \"set\" \"shared\"\n; \"sizeof\" \"smooth\" \"snorm\" \"static\" \"static_assert\" \"static_cast\" \"std\"\n; \"subroutine\" \"super\" \"target\" \"template\" \"this\" \"thread_local\" \"throw\" \"trait\"\n; \"try\" \"type\" \"typedef\" \"typeid\" \"typename\" \"typeof\" \"union\" \"unless\" \"unorm\"\n; \"unsafe\" \"unsized\" \"use\" \"using\" \"varying\" \"virtual\" \"volatile\" \"wgsl\" \"where\"\n; \"with\" \"writeonly\" \"yield\"))\n\n; comments\n\n(line_comment) @comment.line\n(block_comment) @comment.block\n\n; imports (WESL extension)\n\n(import_item (identifier) @type\n  (#match? @type \"^[A-Z]\"))\n\n(import_item (identifier) @constant\n  (#match? @constant \"^[A-Z0-9_]+$\"))\n\n(import_item (identifier) @namespace)\n\n(import_path (identifier) @namespace)\n\n(ident_path (identifier) @namespace)\n\n; types\n\n((identifier) @constant\n  (#match? @constant \"^[A-Z0-9_]+$\"))\n\n((identifier) @type\n  (#match? @type \"^[A-Z]\"))\n\n(type_specifier\n    (identifier) @type)\n\n; functions\n\n(function_decl \n  (function_header\n    (identifier) @function))\n\n(call_expression\n  (identifier) @function)\n\n; templates\n\n(template_list) @punctuation\n\n(variable_decl ; this is var<storage> et.al\n  (template_list\n    (identifier) @keyword.storage.modifier))\n\n(type_specifier\n  (template_list\n    (identifier) @type))\n\n(template_list\n  (template_list\n    (identifier) @type))\n\n; attributes\n\n(attribute\n  (identifier) @attribute) @attribute\n\n(attribute\n  (identifier) @attr-name\n  (argument_list\n    (identifier) @variable.builtin)\n  (#eq? @attr-name \"builtin\"))\n\n; variables, names\n\n(param\n  (identifier) @variable.parameter)\n(variable_decl\n  (identifier) @variable)\n(const_assert_statement) @variable\n\n(struct_decl\n  (identifier) @type)\n\n(struct_member\n  name: (_) @variable.other.member)\n\n(named_component_expression\n  component: (_) @variable.other.member)\n\n(identifier) @variable\n\n; literals\n\n(bool_literal) @constant.builtin.boolean\n(int_literal) @constant.numeric.integer\n(float_literal) @constant.numeric.float\n\n\n; keywords\n\n[\n  \"if\"\n  \"else\"\n] @keyword.control.conditional\n[\n  \"loop\"\n  \"for\"\n  \"while\"\n  \"break\"\n  \"continue\"\n] @keyword.control.repeat\n[\n  \"return\"\n] @keyword.control.return\n[\n  \"switch\"\n  \"case\"\n  \"default\"\n  \"discard\"\n] @keyword.control\n[ ; WESL import extension\n  \"import\"\n  \"as\"\n] @keyword.control.import\n[\n  \"fn\"\n] @keyword.function\n[\n  \"var\"\n  \"let\"\n  \"const\"\n  \"struct\"\n] @keyword.storage.type\n[\n  \"alias\"\n  \"virtual\" ; Bevy / naga_oil extension\n  \"override\" ; Bevy / naga_oil extension\n] @keyword\n\n; expressions\n\n[\n  \"-\" \"!\" \"~\" \"*\" \"&\" ; unary\n  \"^\" \"|\" \"/\" \"%\" \"+\" (shift_left) (shift_right) ; binary\n  (less_than) (greater_than) (less_than_equal) (greater_than_equal) \"==\" \"!=\" ; relational\n  \"+=\" \"-=\" \"*=\" \"/=\" \"%=\" \"|=\" \"^=\" \"++\" \"--\" \"=\" ; assign\n  \"->\" ; return\n] @operator\n\n; punctuation\n\n[ \"(\" \")\" \"[\" \"]\" \"{\" \"}\" ] @punctuation.bracket\n[ \",\" \".\" \":\" \";\" ] @punctuation.delimiter\n\n; preprocessor\n\n[ (preproc_directive) \"#import\" ] @keyword.directive\n"
  },
  {
    "path": "runtime/queries/wesl/injections.scm",
    "content": "([(line_comment) (block_comment)] @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/wesl/locals.scm",
    "content": "; Scopes\n\n[\n  (global_decl)\n  (switch_body)\n  (compound_statement)\n] @local.scope\n\n; Definitions\n\n(param\n  (identifier) @local.definition.variable.parameter)\n\n; References\n\n(identifier) @local.reference\n; (type_specifier) @local.reference\n\n"
  },
  {
    "path": "runtime/queries/wesl/textobjects.scm",
    "content": "(function_decl\n  body: (_) @function.inside) @function.around\n\n(struct_decl\n  body: (_) @class.inside) @class.around\n\n(param_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(argument_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(template_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n[\n  (line_comment)\n  (block_comment)\n] @comment.inside\n  \n(line_comment)+ @comment.around\n\n(block_comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/wgsl/highlights.scm",
    "content": "(int_literal) @constant.numeric.integer\n(float_literal) @constant.numeric.float\n(bool_literal) @constant.builtin.boolean\n\n[\n  \"bitcast\"\n  \"discard\"\n  \"enable\"\n  \"fallthrough\"\n] @keyword\n\n[\n  \"let\"\n  \"override\"\n  \"struct\"\n  \"type\"\n  \"var\"\n  (texel_format)\n] @keyword.storage.type\n\n[\n  (access_mode)\n  (address_space)\n] @keyword.storage.modifier\n\n\"fn\" @keyword.function\n\n\"return\" @keyword.control.return\n\n[\",\" \".\" \":\" \";\"] @punctuation.delimiter\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\"] @punctuation.bracket\n\n[\n  \"break\"\n  \"continue\"\n  \"continuing\"\n] @keyword.control\n\n[\n  \"loop\"\n  \"for\"\n  \"while\"\n] @keyword.control.repeat\n\n[\n  \"if\"\n  \"else\"\n  \"switch\"\n  \"case\"\n  \"default\"\n] @keyword.control.conditional\n\n[\n  \"!\"\n  \"!=\"\n  \"%\"\n  \"%=\"\n  \"&\"\n  \"&&\"\n  \"&=\"\n  \"*\"\n  \"*=\"\n  \"+\"\n  \"++\"\n  \"+=\"\n  \"-\"\n  \"--\"\n  \"-=\"\n  \"->\"\n  \"/\"\n  \"/=\"\n  \"<\"\n  \"<<\"\n  \"<=\"\n  \"=\"\n  \"==\"\n  \">\"\n  \">=\"\n  \">>\"\n  \"@\"\n  \"^\"\n  \"^=\"\n  \"|\"\n  \"|=\"\n  \"||\"\n  \"~\"\n] @operator\n\n(identifier) @variable\n\n(function_declaration\n  (identifier) @function)\n\n(parameter\n  (variable_identifier_declaration\n    (identifier) @variable.parameter))\n\n(struct_declaration\n  (identifier) @type)\n\n(struct_declaration\n  (struct_member\n    (variable_identifier_declaration\n      (identifier) @variable.other.member)))\n\n(type_constructor_or_function_call_expression\n  (type_declaration (identifier) @function))\n\n(type_declaration _ @type)\n\n(attribute\n  (identifier) @attribute)\n\n(comment) @comment\n\n; built-in wgsl functions: https://webgpufundamentals.org/webgpu/lessons/webgpu-wgsl-function-reference.html\n(\n  (identifier) @function.builtin\n  (#any-of? @function.builtin \n    \"abs\"\n    \"abs\"\n    \"acos\"\n    \"acosh\"\n    \"all\"\n    \"any\"\n    \"arrayLength\"\n    \"asin\"\n    \"asinh\"\n    \"atan\"\n    \"atan2\"\n    \"atanh\"\n    \"atomicAdd\"\n    \"atomicLoad\"\n    \"atomicStore\"\n    \"bitcast\"\n    \"ceil\"\n    \"clamp\"\n    \"cos\"\n    \"cosh\"\n    \"countLeadingZeros\"\n    \"countOneBits\"\n    \"countTrailingZeros\"\n    \"cross\"\n    \"degrees\"\n    \"determinant\"\n    \"distance\"\n    \"dot\"\n    \"dpdx\"\n    \"dpdxCoarse\"\n    \"dpdxFine\"\n    \"dpdy\"\n    \"dpdyCoarse\"\n    \"dpdyFine\"\n    \"exp\"\n    \"exp2\"\n    \"extractBits\"\n    \"faceForward\"\n    \"firstLeadingBit\"\n    \"firstTrailingBit\"\n    \"floor\"\n    \"fma\"\n    \"fract\"\n    \"frexp\"\n    \"fwidth\"\n    \"fwidthCoarse\"\n    \"fwidthFine\"\n    \"gather_depth_compare\"\n    \"gather_x_components\"\n    \"insertBits\"\n    \"inverseSqrt\"\n    \"ldexp\"\n    \"length\"\n    \"log\"\n    \"log2\"\n    \"max\"\n    \"min\"\n    \"mix\"\n    \"modf\"\n    \"normalize\"\n    \"pack2x16float\"\n    \"pack2x16snorm\"\n    \"pack2x16unorm\"\n    \"pack4x8snorm\"\n    \"pack4x8unorm\"\n    \"pow\"\n    \"quantizeToF16\"\n    \"radians\"\n    \"reflect\"\n    \"refract\"\n    \"reverseBits\"\n    \"round\"\n    \"saturate\"\n    \"select\"\n    \"sign\"\n    \"sin\"\n    \"sinh\"\n    \"smoothstep\"\n    \"sqrt\"\n    \"step\"\n    \"storageBarrier\"\n    \"tan\"\n    \"tanh\"\n    \"textureDimensions\"\n    \"textureGather\"\n    \"textureGatherCompare\"\n    \"textureLoad\"\n    \"textureNumLayers\"\n    \"textureNumLevels\"\n    \"textureNumSamples\"\n    \"textureSample\"\n    \"textureSampleBaseClampToEdge\"\n    \"textureSampleBias\"\n    \"textureSampleCompare\"\n    \"textureSampleCompareLevel\"\n    \"textureSampleGrad\"\n    \"textureSampleLevel\"\n    \"textureStore\"\n    \"transpose\"\n    \"trunc\"\n    \"unpack2x16float\"\n    \"unpack2x16snorm\"\n    \"unpack2x16unorm\"\n    \"unpack4x8snorm\"\n    \"unpack4x8unorm\"\n    \"workgroupBarrier\"\n    \"workgroupUniformLoad\"\n  )\n)\n\n(type_declaration [\"<\" \">\"] @punctuation.bracket)\n(variable_qualifier [\"<\" \">\"] @punctuation.bracket)\n"
  },
  {
    "path": "runtime/queries/wgsl/indents.scm",
    "content": "[\n  (struct_declaration)\n  (compound_statement)\n] @indent\n\n\"}\" @outdent\n"
  },
  {
    "path": "runtime/queries/wgsl/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/wgsl/rainbows.scm",
    "content": "[\n  (struct_declaration)\n  (function_declaration)\n  (attribute)\n  (type_declaration)\n  (compound_statement)\n  (argument_list_expression)\n  (postfix_expression)\n  (variable_qualifier)\n  (subscript_expression)\n  (parenthesized_expression)\n] @rainbow.scope\n\n[\"(\" \")\" \"[\" \"]\" \"{\" \"}\" \"<\" \">\"] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/wgsl/tags.scm",
    "content": "(struct_declaration\n  name: (identifier) @definition.struct)\n\n(function_declaration\n  name: (identifier) @definition.function)\n\n(global_variable_declaration\n  (variable_declaration\n    (variable_identifier_declaration\n      name: (identifier) @definition.constant)))\n"
  },
  {
    "path": "runtime/queries/wgsl/textobjects.scm",
    "content": "(function_declaration\n  body: (_) @function.inside) @function.around\n\n(struct_declaration) @class.around\n\n[\n  (struct_member)\n  (parameter)\n  (variable_declaration)\n] @parameter.around\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/wikitext/folds.scm",
    "content": "(section) @fold\n\n"
  },
  {
    "path": "runtime/queries/wikitext/highlights.scm",
    "content": "(heading1\n  (heading_marker) @markup.heading.marker\n  (text) @markup.heading.1\n  (heading_marker) @markup.heading.marker\n)\n(heading2\n  (heading_marker) @markup.heading.marker\n  (text) @markup.heading.2\n  (heading_marker) @markup.heading.marker\n)\n(heading3\n  (heading_marker) @markup.heading.marker\n  (text) @markup.heading.3\n  (heading_marker) @markup.heading.marker\n)\n(heading4\n  (heading_marker) @markup.heading.marker\n  (text) @markup.heading.4\n  (heading_marker) @markup.heading.marker\n)\n(heading5\n  (heading_marker) @markup.heading.marker\n  (text) @markup.heading.5\n  (heading_marker) @markup.heading.marker\n)\n(heading6\n  (heading_marker) @markup.heading.marker\n  (text) @markup.heading.6\n  (heading_marker) @markup.heading.marker\n)\n\n(wikilink\n  (wikilink_page) @markup.link.url\n  (page_name_segment)? @markup.link.label\n)\n(external_link\n  (url) @markup.link.url\n  (page_name_segment)? @markup.link.label\n)\n\n(template\n  (template_name) @function\n  (template_argument\n  (template_param_name)? @attribute\n  (template_param_value)? @string\n  )\n)\n\n(comment) @comment\n\n[\n  \"[[\"\n  \"]]\"\n  \"{{\"\n  \"}}\"\n  \"{|\"\n  \"|}\"\n  \"[\"\n  \"]\"\n  \"<\"\n  \">\"\n  \"</\"\n] @punctuation.bracket\n\n[\n  \"|\"\n  \"|-\"\n  \"|+\"\n  \"!\"\n  \"!!\"\n  \"||\"\n] @punctuation.delimiter\n\n(table_header_block\n  (content) @markup.bold\n)\n(table_header_inline\n  (content) @markup.bold\n)\n\n(html_tag_name) @tag\n(html_attribute\n  (html_attribute_name) @attribute\n)\n(html_attribute\n  (html_attribute_name) @attribute\n  (html_attribute_value) @string\n)\n\n(italic) @markup.italic\n(bold) @markup.bold\n\n"
  },
  {
    "path": "runtime/queries/wit/highlights.scm",
    "content": "(line_comment) @comment.line\n(block_comment) @comment.block\n(ty (ident) @type)\n\n(item_type name: (ident) @type)\n(item_record name: (ident) @type)\n(item_variant name: (ident) @type)\n(item_flags name: (ident) @type)\n(item_enum name: (ident) @type)\n(item_union name: (ident) @type)\n(item_resource name: (ident) @type)\n\n(item_use from: (ident) @namespace)\n(use_item name: (ident) @type)\n(item_func name: (ident) @function)\n(method name: (ident) @function.method)\n(fields (named_ty name: (ident) @variable.other.member))\n(input (args (named_ty name: (ident) @variable.parameter)))\n(output (args (named_ty name: (ident) @variable.other.member)))\n(flags (ident) @constant)\n(enum_items (ident) @constant)\n(variant_item tag: (ident) @type.enum.variant)\n\n[\n  (unit)\n\n  \"u8\" \"u16\" \"u32\" \"u64\"\n  \"s8\" \"s16\" \"s32\" \"s64\"\n  \"float32\" \"float64\"\n  \"char\" \"bool\" \"string\"\n] @type.builtin\n\n[\n  \"list\"\n  \"option\"\n  \"result\"\n  \"tuple\"\n  \"future\"\n  \"stream\"\n] @function.macro\n\n[ \",\" \":\" ] @punctuation.delimiter\n[ \"(\" \")\" \"{\" \"}\" \"<\" \">\" ] @punctuation.bracket\n[ \"=\" \"->\" ] @operator\n\n[\n  \"record\"\n  \"flags\"\n  \"variant\"\n  \"enum\"\n  \"union\"\n  \"type\"\n  \"resource\"\n] @keyword.storage.type\n\n\"func\" @keyword\n\n[\n  \"static\"\n] @keyword.storage.modifier\n\n[\n  (star)\n  \"use\"\n  \"as\"\n  \"from\"\n] @keyword.control.import\n"
  },
  {
    "path": "runtime/queries/wit/indents.scm",
    "content": "[\n  (use_items)\n  (fields)\n  (variant_items)\n  (variant_payload)\n  (flags)\n  (enum_items)\n  (union_items)\n  (args)\n  (resource_items)\n] @indent\n\n[ \"}\" \")\" ] @outdent\n"
  },
  {
    "path": "runtime/queries/woodpecker-ci/highlights.scm",
    "content": "; yaml highlights from runtime/queries/yaml/highlights.scm\n(boolean_scalar) @constant.builtin.boolean\n(null_scalar) @constant.builtin\n(double_quote_scalar) @string\n(single_quote_scalar) @string\n(block_scalar) @string\n(string_scalar) @string\n(escape_sequence) @constant.character.escape\n(integer_scalar) @constant.numeric.integer\n(float_scalar) @constant.numeric.float\n(comment) @comment\n(anchor_name) @type\n(alias_name) @type\n(tag) @type\n(yaml_directive) @keyword\n\n(block_mapping_pair\n  key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member))\n(block_mapping_pair\n  key: (flow_node (plain_scalar (string_scalar) @variable.other.member)))\n\n(flow_mapping\n  (_ key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member)))\n(flow_mapping\n  (_ key: (flow_node (plain_scalar (string_scalar) @variable.other.member))))\n\n[\n\",\"\n\"-\"\n\":\"\n\">\"\n\"?\"\n\"|\"\n] @punctuation.delimiter\n\n[\n\"[\"\n\"]\"\n\"{\"\n\"}\"\n] @punctuation.bracket\n\n[\"*\" \"&\" \"---\" \"...\"] @punctuation.special\n\n; Highlight the toplevel keys differently as keywords\n; https://woodpecker-ci.org/docs/usage/workflow-syntax\n(block_mapping_pair\n  key: (flow_node (plain_scalar (string_scalar) @keyword (#any-of? @keyword \"steps\" \"workspace\" \"labels\" \"matrix\" \"services\" \"variables\" \"clone\" \"skip_clone\" \"depends_on\" \"runs_on\"))) )\n"
  },
  {
    "path": "runtime/queries/woodpecker-ci/indents.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/woodpecker-ci/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; https://woodpecker-ci.org/docs/usage/workflow-syntax#commands\n; e.g.\n; ```\n; steps:\n;   - name: backend\n;     image: golang\n;     commands:\n;       - go build\n;       - go test\n; ```\n(block_mapping_pair\n  key: (flow_node) @_key (#eq? @_key \"commands\")\n  value: (block_node\n           (block_sequence\n             (block_sequence_item\n                (flow_node\n                  (plain_scalar\n                    (string_scalar) @injection.content))\n                (#set! injection.language \"bash\")))))\n\n(block_mapping_pair\n  key: (flow_node) @_key (#any-of? @_key \"commands\")\n  value: (block_node\n           (block_sequence\n             (block_sequence_item\n               (block_node\n                  (block_scalar) @injection.content\n                  (#set! injection.language \"bash\"))))))\n\n; https://woodpecker-ci.org/docs/usage/workflow-syntax#entrypoint\n; e.g.\n; ```\n; job1:\n;   services:\n;     entrypoint: [\"/usr/local/bin/docker-entrypoint.sh\", \"-c\", 'max_connections=100']\n; ```\n(block_mapping_pair\n  key: (flow_node) @_key (#any-of? @_key \"entrypoint\")\n  value: (flow_node\n           (flow_sequence\n             (flow_node\n               [\n                 (double_quote_scalar)\n                 (single_quote_scalar)\n               ] @injection.content)))\n  (#set! injection.language \"bash\"))\n"
  },
  {
    "path": "runtime/queries/woodpecker-ci/rainbows.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/woodpecker-ci/tags.scm",
    "content": "; select steps\n; e.g.\n; ```\n; steps:\n;   - name: build-image\n;     image: docker\n;     commands:\n;       - docker build --rm -t local/project-image .\n;     volumes:\n;       - /var/run/docker.sock:/var/run/docker.sock\n; ```\n(block_mapping_pair\n  key: (_) @_key (#eq? @_key \"steps\")\n  value: (block_node\n           (block_sequence\n             (block_sequence_item\n               (block_node) @definition.struct))))\n"
  },
  {
    "path": "runtime/queries/woodpecker-ci/textobjects.scm",
    "content": "; inherits: yaml\n"
  },
  {
    "path": "runtime/queries/wren/highlights.scm",
    "content": "(comment) @comment\n(string) @string\n(raw_string) @string\n(number) @constant.numeric.integer\n(name) @variable\n(field) @variable\n(static_field) @variable\n(null) @constant.builtin\n(boolean) @constant.builtin.boolean\n\n((name) @variable.builtin\n (#match? @variable.builtin \"^(Bool|Class|Fiber|Fn|List|Map|Null|Num|Object|Range|Sequence|String|System)$\"))\n\n(call_expression\n  (name) @function)\n\n(method_definition\n  (name) @function.method)\n\n((parameter) @variable.parameter)\n\n\n(if_statement\n[\n  \"if\"\n  \"else\"\n] @keyword.control.conditional)\n\n(for_statement\n[\n  \"for\"\n  \"in\"\n] @keyword.control.repeat)\n\n(while_statement\n[\n  \"while\"\n] @keyword.control.repeat)\n\n[\n  (break_statement)\n  (continue_statement)\n  (return_statement)\n] @keyword.control.return\n\n(class_definition\n\"is\"\n@keyword)\n\n[\n  \"import\"\n  \"for\"\n  \"as\"\n] @keyword.control.import\n\n[\n  \"is\"\n] @keyword\n\n(operator) @operator\n\n[\n \"(\"\n \")\"\n \"[\"\n \"]\"\n \"{\"\n \"}\"\n] @punctuation.bracket\n\n[\",\" \".\"] @punctuation.delimiter\n\n[\n  \"class\"\n  \"var\"\n] @keyword.storage.type\n\n[\n  \"static\"\n] @keyword.storage.modifier\n\n(constructor\n  [\"construct\"] @constructor)\n"
  },
  {
    "path": "runtime/queries/wren/indents.scm",
    "content": "[\n\t(list)\n\t(map)\n\t(call_body)\n\t(parameter_list)\n\t(call_expression)\n\t(getter_definition)\n\t(setter_definition)\n\t(prefix_operator_definition)\n\t(subscript_operator_definition)\n\t(subscript_setter_definition)\n\t(infix_operator_definition)\n\t(method_definition)\n\t(constructor)\n\t(static_method_definition)\n\t(static_getter_definition)\n\t(attribute)\n\t(conditional)\n\t(class_body)\n\t(if_statement)\n\t(for_statement)\n\t(while_statement)\n] @indent\n\n[\n\t\"}\"\n\t\"]\"\n\t\")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/wren/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\")\n (#set! injection.include-children))\n"
  },
  {
    "path": "runtime/queries/wren/locals.scm",
    "content": "[\n\t(method_definition)\n] @local.scope\n\n(name) @local.reference\n(field) @local.reference\n(static_field) @local.reference\n\n(parameter) @local.definition.variable.parameter\n"
  },
  {
    "path": "runtime/queries/wren/textobjects.scm",
    "content": "(class_definition\n  (class_body) @class.inside) @class.around\n\n(call_expression\n  (call_body\n    (_) @function.inside) @function.around)\n\n(method_definition\n  body: (_) @function.inside) @function.around\n\n(parameter_list\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/queries/xit/highlights.scm",
    "content": "(headline) @markup.heading\n\n(open_checkbox) @markup.list\n(ongoing_checkbox) @keyword.control\n(checked_checkbox) @diff.plus\n(obsolete_checkbox) @comment.unused\n\n(checked_task) @comment.unused\n(obsolete_task) @comment.unused\n\n(priority) @error\n"
  },
  {
    "path": "runtime/queries/xml/highlights.scm",
    "content": "(comment) @comment\n\n[\n    \"DOCTYPE\"\n    \"ELEMENT\"\n    \"ATTLIST\"\n] @keyword\n\n[\n    \"#REQUIRED\"\n    \"#IMPLIED\"\n    \"#FIXED\"\n    \"#PCDATA\"\n] @keyword.directive\n\n[\n    \"EMPTY\"\n    \"ANY\"\n    \"SYSTEM\"\n    \"PUBLIC\"\n] @constant\n\n(doctype) @variable\n(element_name) @variable\n\n\"xml\" @tag\n(tag_name) @tag\n\n[\n    \"encoding\"\n    \"version\"\n    \"standalone\"\n] @attribute\n(attribute_name) @attribute\n\n(system_literal) @string\n(pubid_literal) @string\n(attribute_value) @string\n\n[\n    \"<\" \">\" \"</\" \"/>\" \"<?\" \"?>\" \"<!\"\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/xml/indents.scm",
    "content": "(element) @indent\n"
  },
  {
    "path": "runtime/queries/xml/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/xml/rainbows.scm",
    "content": "[\n  (processing_instructions)\n  (cdata_sect)\n  (xml_decl)\n  (doctype_decl)\n  (element_decl)\n  (element_choice)\n  (element_seq)\n  (mixed)\n  (attlist_decl)\n  (notation_type)\n  (enumeration)\n  (ge_decl)\n  (pe_decl)\n  (notation_decl)\n] @rainbow.scope\n\n((element) @rainbow.scope\n (#set! rainbow.include-children))\n\n[\n  \"<?\" \"?>\"\n  \"<\" \">\"\n  \"</\" \"/>\"\n  \"<!\"\n  \"(\" \")\"\n  \")*\"\n  \"[\" \"]\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/xml/textobjects.scm",
    "content": "(element (start_tag) (_)* @xml-element.inside (end_tag))\n\n(element) @xml-element.around\n\n(comment) @comment.around\n"
  },
  {
    "path": "runtime/queries/xtc/highlights.scm",
    "content": "(parameter) @keyword\n\n(change_port) @function.special\n\n(template) @variable\n\n[\n  (hex_argument)\n  (ipv4_argument)\n] @attribute\n\n(numeric_argument) @constant.numeric\n\n(index) @tag\n\n(string_literal_argument) @string\n\n(string_argument) @constant.character\n\n(comment) @comment\n\n(port_comment) @label\n\n[\n(\"[\") \n(\"]\")\n] @punctuation.bracket\n"
  },
  {
    "path": "runtime/queries/yaml/highlights.scm",
    "content": "(boolean_scalar) @constant.builtin.boolean\n(null_scalar) @constant.builtin\n(double_quote_scalar) @string\n(single_quote_scalar) @string\n(block_scalar) @string\n(string_scalar) @string\n(escape_sequence) @constant.character.escape\n(integer_scalar) @constant.numeric.integer\n(float_scalar) @constant.numeric.float\n(comment) @comment\n(anchor_name) @type\n(alias_name) @type\n(tag) @type\n(yaml_directive) @keyword\n\n(block_mapping_pair\n  key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member))\n(block_mapping_pair\n  key: (flow_node (plain_scalar (string_scalar) @variable.other.member)))\n\n(flow_mapping\n  (_ key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member)))\n(flow_mapping\n  (_ key: (flow_node (plain_scalar (string_scalar) @variable.other.member))))\n\n[\n\",\"\n\"-\"\n\":\"\n\">\"\n\"?\"\n\"|\"\n] @punctuation.delimiter\n\n[\n\"[\"\n\"]\"\n\"{\"\n\"}\"\n] @punctuation.bracket\n\n[\"*\" \"&\" \"---\" \"...\"] @punctuation.special\n"
  },
  {
    "path": "runtime/queries/yaml/indents.scm",
    "content": "(block_scalar) @indent @extend\n\n; indent sequence items only if they span more than one line, e.g.\n;\n; - foo:\n;     bar: baz\n; - quux:\n;     bar: baz\n;\n; but not\n;\n; - foo\n; - bar\n; - baz\n((block_sequence_item) @item @indent.always @extend\n  (#not-one-line? @item))\n\n; map pair where without a key\n;\n; foo:\n((block_mapping_pair\n    key: (_) @key\n    !value\n  ) @indent.always @extend\n)\n\n; map pair where the key and value are on different lines\n;\n; foo:\n;   bar: baz\n((block_mapping_pair\n    key: (_) @key\n    value: (_) @val\n    (#not-same-line? @key @val)\n  ) @indent.always @extend\n)"
  },
  {
    "path": "runtime/queries/yaml/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n\n; The following code in this file until the \";;; END nvim-treesitter LICENSED CODE\"\n; marker incorporates work covered by the following copyright and permission notice:\n;\n;   Copyright 2023 the nvim-treesitter 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; Modified for Helix from https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/yaml/injections.scm\n\n;; GitHub actions: run\n;; Buildkite: command, commands\n(block_mapping_pair\n  key: (flow_node) @_run (#any-of? @_run \"run\" \"command\" \"commands\")\n  value: (flow_node\n           (plain_scalar\n             (string_scalar) @injection.content)\n           (#set! injection.language \"bash\")))\n\n(block_mapping_pair\n  key: (flow_node) @_run (#any-of? @_run \"run\" \"command\" \"commands\")\n  value: (block_node\n           (block_scalar) @injection.content\n           (#set! injection.language \"bash\")))\n\n(block_mapping_pair\n  key: (flow_node) @_run (#any-of? @_run \"run\" \"command\" \"commands\")\n  value: (block_node\n           (block_sequence\n             (block_sequence_item\n                (flow_node\n                  (plain_scalar\n                    (string_scalar) @injection.content))\n                (#set! injection.language \"bash\")))))\n\n(block_mapping_pair\n  key: (flow_node) @_run (#any-of? @_run \"run\" \"command\" \"commands\")\n  value: (block_node\n           (block_sequence\n             (block_sequence_item\n               (block_node\n                  (block_scalar) @injection.content\n                  (#set! injection.language \"bash\"))))))\n\n;;; END nvim-treesitter LICENSED CODE\n"
  },
  {
    "path": "runtime/queries/yaml/rainbows.scm",
    "content": "[\n  (flow_sequence)\n  (flow_mapping)\n] @rainbow.scope\n\n[\n  \"[\" \"]\"\n  \"{\" \"}\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/yaml/textobjects.scm",
    "content": "(comment) @comment.inside\n\n(comment)+ @comment.around\n\n(block_mapping_pair\n  (_) @entry.inside) @entry.around\n\n"
  },
  {
    "path": "runtime/queries/yara/highlights.scm",
    "content": "; Comments\n(comment) @comment\n\n; Keywords\n[\n  \"global\"\n  \"import\"\n  \"private\"\n] @constant.builtin\n\n[\n  \"rule\"\n] @function\n\n[\n  \"meta\"\n  \"strings\"\n  \"condition\"\n] @attribute\n\n; Operators\n[\n  \"matches\"\n  \"contains\"\n  \"icontains\"\n  \"imatches\"\n  \"startswith\"\n  \"istartswith\"\n  \"endswith\"\n  \"iendswith\"\n  \"and\"\n  \"or\"\n  \"not\"\n  \"==\"\n  \"!=\"\n  \"<\"\n  \">\"\n  \">=\"\n  \"<=\"\n  \"of\"\n  \"for\"\n  \"all\"\n  \"any\"\n  \"none\"\n  \"in\"\n] @string.special\n\n; String modifiers\n[\n  \"wide\"\n  \"ascii\"\n  \"nocase\"\n  \"fullword\"\n  \"xor\"\n  \"base64\"\n  \"base64wide\"\n] @keyword.storage.modifier\n\n; Numbers and sizes\n(integer_literal) @constant.numeric\n(size_unit) @constant.numeric\n\n; Strings\n(double_quoted_string) @string\n(single_quoted_string) @string\n(escape_sequence) @constant.character.escape\n\n; Hex strings\n(hex_string) @string.special\n(hex_byte) @constant.numeric\n(hex_wildcard) @constant.builtin\n(hex_jump) @constant.numeric\n\n; Regular expressions\n(regex_string) @string.regexp\n(pattern) @string.regexp\n\n; Boolean literals\n[\n  \"true\"\n  \"false\"\n] @constant.builtin.boolean\n\n; Keywords and special identifiers\n[\n  \"them\"\n  \"all\"\n  \"any\"\n  \"none\"\n] @keyword.operator\n\n\n; String identifiers\n\"$\" @string.special.symbol\n(identifier) @string\n(string_identifier) @string.special.symbol\n\n; Built-ins\n[\n  (filesize_keyword)\n  (entrypoint_keyword)\n] @constant.builtin\n\n; Tags\n(tag_list\n  [(identifier) (tag)] @tag)\n\n; Punctuation and delimiters\n[\n  \"=\"\n  \":\"\n  \"{\"\n  \"}\"\n  \"[\"\n  \"]\"\n  \"(\"\n  \")\"\n  \"#\"\n  \"@\"\n  \"..\"\n  \"|\"\n  \",\"\n  \"!\"\n  \"/\"\n  \"\\\"\"\n  \"'\"\n  \"*\"\n] @string.special.symbol\n\n; Rule names\n(rule_definition\n  name: (identifier) @string.special)\n\n; Meta definitions\n(meta_definition\n  key: (identifier) @string.special)\n"
  },
  {
    "path": "runtime/queries/yara/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/yara/locals.scm",
    "content": "(rule_definition name: (identifier) @local.definition.string.special)\n(string_identifier) @local.definition.string.special.symbol\n\n(for_expression\n  (string_identifier) @local.reference)\n\n(for_of_expression\n  (string_identifier) @local.reference)\n\n(of_expression\n  (string_set\n    (string_identifier) @local.reference))\n\n(string_count\n  (string_identifier) @local.reference)\n\n(string_offset\n  (string_identifier) @local.reference)\n\n(string_length\n  (string_identifier) @local.reference)\n"
  },
  {
    "path": "runtime/queries/yuck/highlights.scm",
    "content": "(ident) @variable\n(index) @variable\n\n; Comments\n\n(comment) @comment\n\n; Operators\n\n[\n  \"+\"\n  \"-\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"||\"\n  \"&&\"\n  \"==\"\n  \"!=\"\n  \"=~\"\n  \">\"\n  \"<\"\n  \">=\"\n  \"<=\"\n  \"!\"\n  \"?.\"\n  \"?:\"\n] @operator\n\n(ternary_expression\n  [\"?\" \":\"] @operator)\n\n; Punctuation\n\n[ \":\" \".\" \",\" ] @punctuation.delimiter\n\n[ \"{\" \"}\" \"[\" \"]\" \"(\" \")\" ] @punctuation.bracket\n\n; Literals\n\n(number (float)) @constant.numeric.float\n\n(number (integer)) @constant.numeric.integer\n\n(boolean) @constant.builtin.boolean\n\n; Strings\n\n(escape_sequence) @constant.character.escape\n\n(string_interpolation\n  \"${\" @punctuation.special\n  \"}\" @punctuation.special)\n\n[ (string_fragment) \"\\\"\" \"'\" \"`\" ] @string\n\n; Attributes & Fields\n\n(keyword) @attribute\n\n; Functions\n\n(function_call\n  name: (ident) @function)\n\n; Tags\n\n; TODO apply to every symbol in list? I think it should probably only be applied to the first child of the list\n(list\n  (symbol) @tag)\n\n; Variables\n\n(ident) @variable\n\n(array\n  (symbol) @variable)\n\n; Builtin widgets\n\n(list .\n  ((symbol) @tag.builtin\n    (#match? @tag.builtin \"^(box|button|calendar|centerbox|checkbox|circular-progress|color-button|color-chooser|combo-box-text|eventbox|expander|graph|image|input|label|literal|overlay|progress|revealer|scale|scroll|transform)$\")))\n\n; Keywords\n\n; I think there's a bug in tree-sitter the anchor doesn't seem to be working, see\n; https://github.com/tree-sitter/tree-sitter/pull/2107\n(list .\n  ((symbol) @keyword\n    (#match? @keyword \"^(defwindow|defwidget|defvar|defpoll|deflisten|geometry|children|struts)$\")))\n\n(list .\n  ((symbol) @keyword.control.import\n    (#eq? @keyword.control.import \"include\")))\n\n; Loop\n\n(loop_widget . \"for\" @keyword.control.repeat . (symbol) @variable . \"in\" @keyword.operator . (symbol) @variable)\n\n(loop_widget . \"for\" @keyword.control.repeat . (symbol) @variable . \"in\" @keyword.operator)\n"
  },
  {
    "path": "runtime/queries/yuck/indents.scm",
    "content": "(list) @indent @extend\n"
  },
  {
    "path": "runtime/queries/yuck/injections.scm",
    "content": "((comment) @injection.content\n (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/yuck/rainbows.scm",
    "content": "[\n  (list)\n  (array)\n] @rainbow.scope\n\n[\n  \"[\" \"]\"\n  \"(\" \")\"\n] @rainbow.bracket\n"
  },
  {
    "path": "runtime/queries/zig/highlights.scm",
    "content": "; Variables\n\n(identifier) @variable\n\n; Parameters\n\n(parameter\n  name: (identifier) @variable.parameter)\n\n(payload\n  (identifier) @variable.parameter)\n\n; Types\n\n(parameter\n  type: (identifier) @type)\n\n((identifier) @type\n  (#match? @type \"^[A-Z_][a-zA-Z0-9_]*\"))\n\n(variable_declaration\n  (identifier) @type\n  \"=\"\n  [\n    (struct_declaration)\n    (enum_declaration)\n    (union_declaration)\n    (opaque_declaration)\n  ])\n\n[\n  (builtin_type)\n  \"anyframe\"\n] @type.builtin\n\n; Constants\n\n((identifier) @constant\n  (#match? @constant \"^[A-Z][A-Z_0-9]+$\"))\n\n[\n  \"null\"\n  \"unreachable\"\n  \"undefined\"\n] @constant.builtin\n\n(field_expression\n  .\n  member: (identifier) @constant)\n\n(enum_declaration\n  (container_field\n    type: (identifier) @constant))\n\n; Labels\n\n(block_label\n  (identifier) @label)\n\n(break_label\n  (identifier) @label)\n\n; Fields\n\n(field_initializer\n  .\n  (identifier) @variable.other.member)\n\n(field_expression\n  (_)\n  member: (identifier) @variable.other.member)\n\n(field_expression\n  (_)\n  member: (identifier) @type (#match? @type \"^[A-Z_][a-zA-Z0-9_]*\"))\n\n(field_expression\n  (_)\n  member: (identifier) @constant (#match? @constant \"^[A-Z][A-Z_0-9]+$\"))\n\n(container_field\n  name: (identifier) @variable.other.member)\n\n(initializer_list\n  (assignment_expression\n      left: (field_expression\n              .\n              member: (identifier) @variable.other.member)))\n\n; Functions\n\n(builtin_identifier) @function.builtin\n\n(call_expression\n  function: (identifier) @function)\n\n(call_expression\n  function: (field_expression\n    member: (identifier) @function.method))\n\n(function_declaration\n  name: (identifier) @function)\n\n; Modules\n\n(variable_declaration\n  (_)\n  (builtin_function\n    (builtin_identifier) @keyword.control.import\n    (#any-of? @keyword.control.import \"@import\" \"@cImport\")))\n\n(variable_declaration\n  (_)\n  (field_expression\n    object: (builtin_function\n      (builtin_identifier) @keyword.control.import\n      (#any-of? @keyword.control.import \"@import\" \"@cImport\"))))\n\n; Builtins\n\n[\n  \"c\"\n  \"...\"\n] @variable.builtin\n\n((identifier) @variable.builtin\n  (#eq? @variable.builtin \"_\"))\n\n(calling_convention\n  (identifier) @variable.builtin)\n\n; Keywords\n\n[\n  \"asm\"\n  \"test\"\n] @keyword\n\n[\n  \"error\"\n  \"const\"\n  \"var\"\n  \"struct\"\n  \"union\"\n  \"enum\"\n  \"opaque\"\n] @keyword.storage.type\n\n; todo: keyword.coroutine\n[\n  \"async\"\n  \"await\"\n  \"suspend\"\n  \"nosuspend\"\n  \"resume\"\n] @keyword\n\n\"fn\" @keyword.function\n\n[\n  \"and\"\n  \"or\"\n  \"orelse\"\n] @keyword.operator\n\n[\n  \"try\"\n  \"unreachable\"\n  \"return\"\n] @keyword.control.return\n\n[\n  \"if\"\n  \"else\"\n  \"switch\"\n  \"catch\"\n] @keyword.control.conditional\n\n[\n  \"for\"\n  \"while\"\n  \"break\"\n  \"continue\"\n] @keyword.control.repeat\n\n[\n  \"usingnamespace\"\n  \"export\"\n] @keyword.control.import\n\n[\n  \"defer\"\n  \"errdefer\"\n] @keyword.control.exception\n\n[\n  \"volatile\"\n  \"allowzero\"\n  \"noalias\"\n  \"addrspace\"\n  \"align\"\n  \"callconv\"\n  \"linksection\"\n  \"pub\"\n  \"inline\"\n  \"noinline\"\n  \"extern\"\n  \"comptime\"\n  \"packed\"\n  \"threadlocal\"\n] @keyword.storage.modifier\n\n; Operator\n\n[\n  \"=\"\n  \"*=\"\n  \"*%=\"\n  \"*|=\"\n  \"/=\"\n  \"%=\"\n  \"+=\"\n  \"+%=\"\n  \"+|=\"\n  \"-=\"\n  \"-%=\"\n  \"-|=\"\n  \"<<=\"\n  \"<<|=\"\n  \">>=\"\n  \"&=\"\n  \"^=\"\n  \"|=\"\n  \"!\"\n  \"~\"\n  \"-\"\n  \"-%\"\n  \"&\"\n  \"==\"\n  \"!=\"\n  \">\"\n  \">=\"\n  \"<=\"\n  \"<\"\n  \"&\"\n  \"^\"\n  \"|\"\n  \"<<\"\n  \">>\"\n  \"<<|\"\n  \"+\"\n  \"++\"\n  \"+%\"\n  \"-%\"\n  \"+|\"\n  \"-|\"\n  \"*\"\n  \"/\"\n  \"%\"\n  \"**\"\n  \"*%\"\n  \"*|\"\n  \"||\"\n  \".*\"\n  \".?\"\n  \"?\"\n  \"..\"\n] @operator\n\n; Literals\n\n(character) @constant.character\n\n[\n  (string)\n  (multiline_string)\n] @string\n\n(integer) @constant.numeric.integer\n\n(float) @constant.numeric.float\n\n(boolean) @constant.builtin.boolean\n\n(escape_sequence) @constant.character.escape\n\n; Punctuation\n\n[\n  \"[\"\n  \"]\"\n  \"(\"\n  \")\"\n  \"{\"\n  \"}\"\n] @punctuation.bracket\n\n[\n  \";\"\n  \".\"\n  \",\"\n  \":\"\n  \"=>\"\n  \"->\"\n] @punctuation.delimiter\n\n(payload \"|\" @punctuation.bracket)\n\n; Comments\n\n(comment) @comment.line\n\n((comment) @comment.block.documentation\n  (#match? @comment.block.documentation \"^//!\"))\n"
  },
  {
    "path": "runtime/queries/zig/indents.scm",
    "content": "[\n  (block)\n  (switch_expression)\n  (initializer_list)\n] @indent\n\n[\n  \"}\"\n  \"]\"\n  \")\"\n] @outdent\n"
  },
  {
    "path": "runtime/queries/zig/injections.scm",
    "content": "((comment) @injection.content\n  (#set! injection.language \"comment\"))\n"
  },
  {
    "path": "runtime/queries/zig/textobjects.scm",
    "content": "(function_declaration\n  body: (_) @function.inside) @function.around\n\n(test_declaration (_) (block) @test.inside) @test.around\n\n; matches all of: struct, enum, union\n; this unfortunately cannot be split up because\n; of the way struct \"container\" types are defined\n(variable_declaration (identifier) (struct_declaration\n    (_) @class.inside)) @class.around\n\n(variable_declaration (identifier) (enum_declaration\n    (_) @class.inside)) @class.around\n\n(variable_declaration (identifier) (enum_declaration\n    (_) @class.inside)) @class.around\n\n(parameters\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(arguments\n  ((_) @parameter.inside . \",\"? @parameter.around) @parameter.around)\n\n(comment) @comment.inside\n(comment)+ @comment.around\n"
  },
  {
    "path": "runtime/themes/README.md",
    "content": "# User submitted themes\n\nIf you submit a theme, please include a comment at the top with your name and email address:\n\n```toml\n# Author : Name <email@my.domain>\n```\n\nIf you are submitting a theme that is already published somewhere, then please\nadd the corresponding license file for it under `licenses/` with the following\nname `theme_name.license` and add a comment at the top of the theme file:\n\n```toml\n# License: <License specification>\n```\n\nWe have a preview page for themes on our [wiki](https://github.com/helix-editor/helix/wiki/Themes)!\n"
  },
  {
    "path": "runtime/themes/acid.toml",
    "content": "# Author: zyrafal\n\n# Syntax highlighting\n\"attribute\" = \"yellow\"\n\"type\" = \"cyan\"\n\"type.parameter\" = \"magenta\"\n\"type.enum.variant\" = \"yellow\"\n\"constructor\" = \"yellow\"\n\"constant\" = \"magenta\"\n\"constant.builtin\" = \"magenta\"\n\"constant.builtin.boolean\" = \"yellow\"\n\"constant.numeric\" = \"cyan\"\n\"constant.character\" = \"yellow\"\n\"string\" = \"green\"\n\"string.regexp\" = \"yellow\"\n\"string.special\" = \"yellow\"\n\"comment\" = { fg = \"light-gray\", modifiers = [\"italic\"] }\n\"comment.block.documentation\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"variable\" = \"white\"\n\"variable.builtin\" = \"red\"\n\"label\" = \"purple\"\n\"punctuation\" = \"white\"\n\"keyword\" = \"red\"\n\"keyword.directive\" = \"orange\"\n\"operator\" = \"white\"\n\"function\" = \"yellow\"\n\"function.macro\" = \"orange\"\n\"function.builtin\" = \"purple\"\n\"tag\" = \"magenta\"\n\"namespace\" = \"white\"\n\"namespace.mod\" = \"cyan\"\n\"namespace.mod_type\" = \"purple\"\n\"markup.heading\" = \"green\"\n\"markup.list\" = \"red\"\n\"markup.bold\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = \"cyan\"\n\"markup.link.text\" = \"yellow\"\n\"markup.link.label\" = \"magenta\"\n\"markup.raw\" = \"magenta\"\n\"markup.quote\" = \"green\"\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"yellow\"\n\n# Interface\n\"ui.background\" = { bg = \"background\" }\n\"ui.cursor\" = { fg = \"background\", bg = \"cyan\" }\n\"ui.cursor.primary\" = { fg = \"background\", bg = \"orange\" }\n\"ui.cursor.match\" = { fg = \"orange\", modifiers = [\"underlined\"] }\n\"ui.linenr\" = \"gray\"\n\"ui.linenr.selected\" = \"light-gray\"\n\"ui.statusline\" = { fg = \"white\", bg = \"highlight\" }\n\"ui.statusline.normal\" = { fg = \"highlight\", bg = \"cyan\" }\n\"ui.statusline.insert\" = { fg = \"highlight\", bg = \"yellow\" }\n\"ui.statusline.select\" = { fg = \"highlight\", bg = \"magenta\" }\n\"ui.cursorline\" = { bg = \"highlight\" }\n\"ui.popup\" = { fg = \"accent\", bg = \"highlight\" }\n\"ui.help\" = { fg = \"accent\", bg = \"highlight\" }\n\"ui.window\" = \"gray\"\n\"ui.text\" = \"white\"\n\"ui.text.focus\" = { bg = \"gray\" }\n\"ui.text.info\" = \"white\"\n\"ui.virtual.whitespace\" = \"orange\"\n\"ui.virtual.ruler\" = { bg = \"unknown\" }\n\"ui.virtual.inlay-hint\" = { fg = \"yellow\", bg = \"unknown\" }\n\"ui.menu\" = { bg = \"highlight\" }\n\"ui.menu.selected\" = { fg = \"background\", bg = \"light-gray\" }\n\"ui.selection\" = { bg = \"gray\" }\n\"warning\" = \"yellow\"\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"diagnostic.hint\"= { underline = { color = \"green\", style = \"curl\" } }\n\"diagnostic.info\"= { underline = { color = \"cyan\", style = \"curl\" } }\n\"diagnostic.warning\"= { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\"= { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"ui.bufferline\" = { fg = \"light-gray\", bg = \"background\" }\n\"ui.bufferline.active\" = { fg = \"white\", bg = \"gray\" }\n\"ui.debug\" = \"orange\"\n\"ui.highlight.frameline\" = { bg = \"unknown\" }\n\"ui.virtual.jump-label\" = { fg = \"unknown\", modifiers = [\"italic\", \"bold\"] }\n\n\"special\" = \"orange\"\n\n[palette]\nbackground = \"#161e26\"\nhighlight = \"#1e262e\"\naccent = \"#8080c0\"\ngray = \"#303840\"\nlight-gray = \"#606870\"\nwhite = \"#e0e0e0\"\n\nred = \"#ff7070\"\norange = \"#ffa060\"\nyellow = \"#ffd080\"\ngreen = \"#b0ff80\"\ncyan = \"#80d0ff\"\nmagenta = \"#f0b0ff\"\npurple = \"#b090ff\"\n\nunknown = \"#ff00ff\"\n"
  },
  {
    "path": "runtime/themes/acme.toml",
    "content": "# Author: Two-Six<twopsix@duck.com>\n\n\"ui.background\" = {bg=\"acme_bg\"}\n\"ui.text\" = \"black\"\n\"ui.linenr\" = {bg=\"acme_bg\", fg=\"black\"}\n\"ui.linenr.selected\" = {bg=\"acme_bg\", fg=\"black\"}\n\"ui.selection\" = {bg=\"selected\"}\n\"ui.cursorline\" = {bg=\"acme_bar_bg\"}\n\"ui.statusline\" = {fg=\"black\", bg=\"acme_bar_bg\"}\n\"ui.statusline.inactive\" = {fg=\"black\", bg=\"acme_bar_inactive\"}\n\"ui.virtual\" = \"indent\"\n\"ui.virtual.ruler\" = { bg = \"acme_bar_bg\" }\n\"ui.cursor.match\" = {bg=\"acme_bar_bg\"}\n\"ui.cursor\" = {bg=\"cursor\", fg=\"white\"}\n\"ui.debug\" = {fg=\"orange\"}\n\"ui.highlight.frameline\" = {bg=\"#da8581\"}\n\"string\" = \"red\"\n\"comment\" = \"green\"\n\"ui.help\" = {fg=\"black\", bg=\"acme_bg\"}\n\"ui.popup\" = {fg=\"black\", bg=\"acme_bg\"}\n\"ui.menu\" = {fg=\"black\", bg=\"acme_bg\"}\n\"ui.menu.selected\" = {bg=\"selected\"}\n\"ui.window\" = {bg=\"acme_bg\"}\n\"diagnostic.error\" = {bg=\"red\", fg=\"white\", modifiers=[\"bold\"]}\n\"diagnostic.warning\" = {bg=\"orange\", fg=\"black\", modifiers=[\"bold\"]}\n\"diagnostic.hint\" = {fg=\"gray\", modifiers=[\"bold\"]}\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"ui.bufferline\" = { fg = \"black\", bg = \"acme_bar_bg\" }\n\"ui.bufferline.active\" = { fg = \"black\", bg = \"acme_bg\" }\n\"diff.plus\" = {fg = \"green\"}\n\"diff.delta\" = {fg = \"acme_bar_bg\"}\n\"diff.minus\" = {fg = \"red\"}\n\n[palette]\nwhite = \"#ffffff\"\nacme_bg = \"#ffffea\"\nblack = \"#000000\"\nselected = \"#eeee9e\"\nacme_bar_bg = \"#aeeeee\"\nacme_bar_inactive = \"#eaffff\"\ncursor = \"#444444\"\nred = \"#a0342f\"\ngreen = \"#065905\"\nindent = \"#aaaaaa\"\norange = \"#f0ad4e\"\ngray = \"#777777\"\n"
  },
  {
    "path": "runtime/themes/adwaita-dark.toml",
    "content": "# Author: Mofiqul Islam <mofi0islam@gmail.com>\n\n\"attribute\" = \"orange_4\"\n\n\"type\" = \"teal_2\"\n\"type.builtin\" = \"teal_2\"\n\n\"constructor\" = \"blue_2\"\n\n\"constant\" = \"violet_2\"\n\"constant.builtin\" = { fg = \"violet_2\", modifiers = [\"bold\"] }\n\"constant.character\" = \"teal_3\"\n\"constant.numeric\" = { fg = \"teal_3\", modifiers = [\"bold\"] }\n\"constant.character.escape\" = \"violet_2\"\n\n\"string\" = \"teal_2\"\n\"string.regexp\" = \"purple_2\"\n\"string.special\" = \"blue_2\"\n\n\"comment\" = \"dark_2\"\n\n\"variable\" = \"light_4\"\n\"variable.parameter\" = \"light_4\"\n\"variable.builtin\" = \"orange_2\"\n\"variable.other\" = \"teal_2\"\n\"variable.other.member\" = \"teal_2\"\n\n\"label\" = \"purple_2\"\n\n\"punctuation\" = \"light_4\"\n\"punctuation.delimiter\" = \"light_4\"\n\"punctuation.bracket\" = \"light_4\"\n\"punctuation.special\" = \"red_3\"\n\n\"keyword\" = { fg = \"orange_2\", modifiers = [\"bold\"] }\n\"keyword.control\" = { fg = \"orange_2\", modifiers = [\"bold\"] }\n\"keyword.operator\" = \"purple_2\"\n\"keyword.directive\" = { fg = \"orange_2\", modifiers = [\"bold\"] }\n\"keyword.function\" = \"orange_2\"\n\"keyword.storage\" = { fg = \"orange_2\", modifiers = [\"bold\"] }\n\n\"operator\" = \"purple_2\"\n\n\"function\" = \"blue_2\"\n\"function.builtin\" = \"blue_2\"\n\"function.macro\" = { fg = \"blue_2\", modifiers = [\"bold\"] }\n\"function.special\" = { fg = \"blue_2\", modifiers = [\"bold\"] }\n\n\"tag\" = \"teal_2\"\n\n\"namespace\" = \"orange_2\"\n\n\"markup\" = \"light_4\"\n\"markup.heading\" = { fg = \"teal_2\", modifiers = [\"bold\"] }\n\"markup.list\" = { fg = \"orange_2\", modifiers = [\"bold\"] }\n\"markup.bold\" = { fg = \"light_4\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"light_4\", modifiers = [\"italic\"] }\n\"markup.link\" = { fg = \"blue_3\", modifiers = [\"underlined\"] }\n\"markup.quote\" = { fg = \"light_3\", modifiers = [\"italic\"] }\n\"diff.plus\" = \"teal_3\"\n\"diff.minus\" = \"red_1\"\n\"diff.delta\" = \"orange_3\"\n\"diff.delta.moved\" = \"orange_2\"\n\n\"ui.background\" = { fg = \"light_4\", bg = \"libadwaita_dark\" }\n\"ui.background.separator\" = { fg = \"split_and_borders\", bg = \"libadwaita_dark\" }\n\"ui.cursor\" = { fg = \"libadwaita_dark\", bg = \"light_5\" }\n\"ui.cursor.insert\" = { fg = \"libadwaita_dark\", bg = \"light_5\" }\n\"ui.cursor.select\" = { fg = \"libadwaita_dark\", bg = \"light_5\" }\n\"ui.cursor.match\" = { fg = \"libadwaita_dark\", bg = \"blue_2\" }\n\"ui.cursor.primary\" = { fg = \"libadwaita_dark\", bg = \"light_7\" }\n\"ui.cursor.primary.normal\" = { fg = \"libadwaita_dark\", bg = \"light_7\" }\n\"ui.cursor.primary.insert\" = { fg = \"libadwaita_dark\", bg = \"teal_4\" }\n\"ui.cursor.primary.select\" = { fg = \"libadwaita_dark\", bg = \"blue_4\" }\n\"ui.linenr\" = \"dark_2\"\n\"ui.linenr.selected\" = { fg = \"light_7\", modifiers = [\"bold\"] }\n\"ui.statusline\" = { fg = \"light_4\", bg = \"libadwaita_dark_alt\" }\n\"ui.statusline.inactive\" = { fg = \"light_7\", bg = \"libadwaita_dark_alt\" }\n\"ui.statusline.normal\" = { fg = \"libadwaita_dark\", bg = \"light_7\" }\n\"ui.statusline.insert\" = { fg = \"libadwaita_dark\", bg = \"teal_4\" }\n\"ui.statusline.select\" = { fg = \"libadwaita_dark\", bg = \"blue_4\" }\n\"ui.popup\" = { fg = \"light_4\", bg = \"libadwaita_popup\" }\n\"ui.window\" = \"split_and_borders\"\n\"ui.help\" = { fg = \"light_4\", bg = \"libadwaita_dark_alt\" }\n\"ui.text\" = \"light_4\"\n\"ui.virtual\" = \"dark_1\"\n\"ui.virtual.ruler\" = { bg = \"libadwaita_popup\"}\n\"ui.virtual.jump-label\" = { fg = \"libadwaita_dark\", bg = \"light_4\" }\n\"ui.menu\" = { fg = \"light_4\", bg = \"libadwaita_popup\" }\n\"ui.menu.selected\" = { fg = \"light_4\", bg = \"blue_5\" }\n\"ui.menu.scroll\" = { fg = \"light_7\", bg = \"dark_3\" }\n\"ui.selection\" = { bg = \"blue_7\" }\n\"ui.selection.primary\" = { bg = \"blue_7\" }\n\"ui.cursorline.primary\" = { bg = \"libadwaita_dark_alt\" }\n\"ui.virtual.whitespace\" = \"dark_2\"\n\n\"warning\" = \"yellow_2\"\n\"error\" = \"red_4\"\n\"info\" = \"purple_2\"\n\"hint\" = \"blue_2\"\n\n\"diagnostic.hint\" = { fg = \"blue_2\", modifiers = [\"dim\"] }\n\"diagnostic.info\" = { fg = \"purple_2\", modifiers = [\"dim\"] }\n\"diagnostic.error\" = { fg = \"red_4\", modifiers = [\"underlined\"] }\n\"diagnostic.warning\" = { fg = \"yellow_2\", modifiers = [\"underlined\"] }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"ui.bufferline\" = { fg = \"dark_2\", bg = \"libadwaita_dark\" }\n\"ui.bufferline.active\" = { fg = \"light_4\", bg = \"libadwaita_dark_alt\" }\n\n[palette]\nblue_0 = \"#d3e4f9\"\nblue_1 = \"#99C1F1\"\nblue_2 = \"#62A0EA\"\nblue_3 = \"#3584E4\"\nblue_4 = \"#1C71D8\"\nblue_5 = \"#1A5FB4\"\nblue_6 = \"#1B497E\"\nblue_7 = \"#193D66\"\nbrown_1 = \"#CDAB8F\"\nbrown_2 = \"#B5835A\"\nbrown_3 = \"#986A44\"\nbrown_4 = \"#865E3C\"\nbrown_5 = \"#63452C\"\nchameleon_3 = \"#4E9A06\"\ndark_1 = \"#77767B\"\ndark_2 = \"#5E5C64\"\ndark_3 = \"#504E55\"\ndark_4 = \"#3D3846\"\ndark_5 = \"#241F31\"\ndark_6 = \"#000000\"\ndark_7 = \"#1c1c1c\"\ngreen_1 = \"#8FF0A4\"\ngreen_2 = \"#57E389\"\ngreen_3 = \"#33D17A\"\ngreen_4 = \"#2EC27E\"\ngreen_5 = \"#26A269\"\ngreen_6 = \"#1F7F56\"\ngreen_7 = \"#1C6849\"\nlibadwaita_dark = \"#1c1c1f\"\nlibadwaita_dark_alt = \"#28282c\"\nlibadwaita_popup = \"#36363a\"\nlight_1 = \"#FFFFFF\"\nlight_2 = \"#FCFCFC\"\nlight_3 = \"#F6F5F4\"\nlight_4 = \"#DEDDDA\"\nlight_5 = \"#C0BFBC\"\nlight_6 = \"#B0AFAC\"\nlight_7 = \"#9A9996\"\norange_1 = \"#FFBE6F\"\norange_2 = \"#FFA348\"\norange_3 = \"#FF7800\"\norange_4 = \"#E66100\"\norange_5 = \"#C64600\"\npurple_1 = \"#DC8ADD\"\npurple_2 = \"#C061CB\"\npurple_3 = \"#9141AC\"\npurple_4 = \"#813D9C\"\npurple_5 = \"#613583\"\nred_1 = \"#F66151\"\nred_2 = \"#ED333B\"\nred_3 = \"#E01B24\"\nred_4 = \"#C01C28\"\nred_5 = \"#A51D2D\"\nteal_1 = \"#93DDC2\"\nteal_2 = \"#5BC8AF\"\nteal_3 = \"#33B2A4\"\nteal_4 = \"#26A1A2\"\nteal_5 = \"#218787\"\nviolet_2 = \"#7D8AC7\"\nviolet_3 = \"#6362C8\"\nviolet_4 = \"#4E57BA\"\nyellow_1 = \"#F9F06B\"\nyellow_2 = \"#F8E45C\"\nyellow_3 = \"#F6D32D\"\nyellow_4 = \"#F5C211\"\nyellow_5 = \"#E5A50A\"\nyellow_6 = \"#D38B09\"\nsplit_and_borders = \"#4F4F4F\"\n"
  },
  {
    "path": "runtime/themes/adwaita-light.toml",
    "content": "inherits=\"adwaita-dark\"\n\"attribute\" = \"orange_5\"\n\n\"type\" = \"teal_4\"\n\"type.builtin\" = \"teal_4\"\n\n\"constructor\" = \"blue_4\"\n\n\"constant\" = \"violet_4\"\n\"constant.builtin\" = { fg = \"violet_4\", modifiers = [\"bold\"] }\n\"constant.character\" = \"teal_5\"\n\"constant.numeric\" = { fg = \"teal_5\", modifiers = [\"bold\"] }\n\"constant.character.escape\" = \"violet_4\"\n\n\"string\" = \"teal_3\"\n\"string.regexp\" = \"purple_4\"\n\"string.special\" = \"blue_4\"\n\n\"comment\" = \"light_6\"\n\n\"variable\" = \"dark_5\"\n\"variable.parameter\" = \"dark_5\"\n\"variable.builtin\" = \"orange_4\"\n\"variable.other\" = \"teal_4\"\n\"variable.other.member\" = \"teal_5\"\n\n\"label\" = \"purple_4\"\n\n\"punctuation\" = \"dark_4\"\n\"punctuation.delimiter\" = \"dark_4\"\n\"punctuation.bracket\" = \"dark_4\"\n\"punctuation.special\" = \"red_5\"\n\n\"keyword\" = { fg = \"orange_4\", modifiers = [\"bold\"] }\n\"keyword.control\" = { fg = \"orange_4\", modifiers = [\"bold\"] }\n\"keyword.operator\" = \"purple_4\"\n\"keyword.directive\" = { fg = \"orange_4\", modifiers = [\"bold\"] }\n\"keyword.function\" = \"orange_4\"\n\"keyword.storage\" = { fg = \"orange_4\", modifiers = [\"bold\"] }\n\n\"operator\" = \"purple_4\"\n\n\"function\" = \"blue_4\"\n\"function.builtin\" = \"blue_4\"\n\"function.macro\" = { fg = \"blue_4\", modifiers = [\"bold\"] }\n\"function.special\" = { fg = \"blue_4\", modifiers = [\"bold\"] }\n\n\"tag\" = \"teal_4\"\n\n\"namespace\" = \"orange_4\"\n\n\"markup\" = \"dark_4\"\n\"markup.heading\" = { fg = \"teal_4\", modifiers = [\"bold\"] }\n\"markup.list\" = { fg = \"orange_4\", modifiers = [\"bold\"] }\n\"markup.bold\" = { fg = \"dark_4\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"dark_4\", modifiers = [\"italic\"] }\n\"markup.link\" = { fg = \"blue_5\", modifiers = [\"underlined\"] }\n\"markup.quote\" = { fg = \"dark_3\", modifiers = [\"italic\"] }\n\"diff.plus\" = \"teal_5\"\n\"diff.minus\" = \"red_3\"\n\"diff.delta\" = \"orange_5\"\n\"diff.delta.moved\" = \"orange_4\"\n\n\"ui.background\" = { fg = \"dark_4\", bg = \"light_1\" }\n\"ui.background.separator\" = { fg = \"split_and_borders\", bg = \"light_2\" }\n\"ui.cursor\" = { fg = \"light_2\", bg = \"dark_5\" }\n\"ui.cursor.insert\" = { fg = \"light_2\", bg = \"dark_4\" }\n\"ui.cursor.select\" = { fg = \"light_2\", bg = \"dark_5\" }\n\"ui.cursor.match\" = { fg = \"light_2\", bg = \"blue_1\" }\n\"ui.cursor.primary\" = { fg = \"light_2\", bg = \"dark_6\" }\n\"ui.cursor.primary.normal\" = { fg = \"light_2\", bg = \"dark_6\" }\n\"ui.cursor.primary.insert\" = { fg = \"light_2\", bg = \"teal_4\" }\n\"ui.cursor.primary.select\" = { fg = \"light_2\", bg = \"blue_4\" }\n\"ui.linenr\" = \"light_5\"\n\"ui.linenr.selected\" = { fg = \"dark_2\", modifiers = [\"bold\"] }\n\"ui.statusline\" = { fg = \"dark_4\", bg = \"light_4\" }\n\"ui.statusline.inactive\" = { fg = \"light_7\", bg = \"light_4\" }\n\"ui.statusline.normal\" = { fg = \"light_2\", bg = \"dark_6\" }\n\"ui.statusline.insert\" = { fg = \"light_2\", bg = \"teal_4\" }\n\"ui.statusline.select\" = { fg = \"light_2\", bg = \"blue_4\" }\n\"ui.popup\" = { fg = \"dark_4\", bg = \"light_3\" }\n\"ui.window\" = \"split_and_borders\"\n\"ui.help\" = { fg = \"dark_4\", bg = \"light_3\" }\n\"ui.text\" = \"dark_4\"\n\"ui.virtual\" = \"light_5\"\n\"ui.virtual.ruler\" = { bg = \"light_5\"}\n\"ui.virtual.jump-label\" = { fg = \"light_1\", bg = \"dark_4\" }\n\"ui.menu\" = { fg = \"dark_4\", bg = \"light_3\" }\n\"ui.menu.selected\" = { fg = \"dark_4\", bg = \"blue_1\" }\n\"ui.menu.scroll\" = { fg = \"dark_6\", bg = \"light_3\" }\n\"ui.selection\" = { bg = \"blue_0\" }\n\"ui.selection.primary\" = { bg = \"blue_0\" }\n\"ui.cursorline.primary\" = { bg = \"light_3\" }\n\"ui.virtual.whitespace\" = \"light_7\"\n\n\"warning\" = \"yellow_4\"\n\"error\" = \"red_5\"\n\"info\" = \"purple_3\"\n\"hint\" = \"blue_3\"\n\n\"diagnostic.hint\" = { fg = \"blue_4\", modifiers = [\"dim\"] }\n\"diagnostic.info\" = { fg = \"purple_4\", modifiers = [\"dim\"] }\n\"diagnostic.error\" = { fg = \"red_5\", modifiers = [\"underlined\"] }\n\"diagnostic.warning\" = { fg = \"yellow_4\", modifiers = [\"underlined\"] }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"ui.bufferline\" = { fg = \"light_7\", bg = \"light_2\" }\n\"ui.bufferline.active\" = { fg = \"dark_4\", bg = \"light_4\", modifiers = [\"bold\"]}\n"
  },
  {
    "path": "runtime/themes/akari-dawn.toml",
    "content": "# Author: Shu Kutsuzawa <cappyzawa@gmail.com>\n# License: MIT\n# Akari Dawn — A light palette inspired by Japanese alleys lit by round lanterns.\n\n# UI elements\n\"ui.background\" = { bg = \"background\" }\n\"ui.text\" = \"foreground\"\n\"ui.text.focus\" = { fg = \"selection-fg\", bg = \"selection-bg\" }\n\"ui.text.inactive\" = { fg = \"bright-black\" }\n\"ui.text.info\" = { fg = \"info\" }\n\"ui.text.directory\" = { fg = \"directory\" }\n\n\"ui.cursor\" = { fg = \"cursor-text\", bg = \"cursor\" }\n\"ui.cursor.normal\" = { fg = \"cursor-text\", bg = \"cursor\" }\n\"ui.cursor.primary\" = { fg = \"cursor-text\", bg = \"cursor\" }\n\"ui.cursor.primary.normal\" = { fg = \"cursor-text\", bg = \"cursor\" }\n\"ui.cursor.match\" = { fg = \"lantern\", bg = \"sunken\", modifiers = [\"bold\"] }\n\"ui.cursor.insert\" = { fg = \"cursor-text\", bg = \"green\" }\n\"ui.cursor.primary.insert\" = { fg = \"cursor-text\", bg = \"green\" }\n\"ui.cursor.select\" = { fg = \"cursor-text\", bg = \"magenta\" }\n\"ui.cursor.primary.select\" = { fg = \"cursor-text\", bg = \"magenta\" }\n\n\"ui.selection\" = { bg = \"selection-bg\" }\n\"ui.selection.primary\" = { bg = \"selection-bg\" }\n\n\"ui.cursorline.primary\" = { bg = \"cursorline\" }\n\"ui.cursorline.secondary\" = { bg = \"surface\" }\n\"ui.cursorcolumn.primary\" = { bg = \"surface\" }\n\"ui.cursorcolumn.secondary\" = { bg = \"surface\" }\n\n\"ui.gutter\" = { bg = \"background\" }\n\"ui.gutter.selected\" = { bg = \"cursorline\" }\n\"ui.linenr\" = { fg = \"bright-black\" }\n\"ui.linenr.selected\" = { fg = \"lantern\" }\n\n\"ui.statusline\" = { fg = \"foreground\", bg = \"surface\" }\n\"ui.statusline.inactive\" = { fg = \"comment\", bg = \"surface\" }\n\"ui.statusline.normal\" = { fg = \"background\", bg = \"green\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"background\", bg = \"lantern\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"background\", bg = \"magenta\", modifiers = [\"bold\"] }\n\"ui.statusline.separator\" = { fg = \"bright-black\", bg = \"surface\" }\n\n\"ui.popup\" = { fg = \"foreground\", bg = \"raised\" }\n\"ui.popup.info\" = { fg = \"foreground\", bg = \"raised\" }\n\"ui.window\" = { fg = \"border\" }\n\"ui.background.separator\" = { bg = \"surface\" }\n\"ui.help\" = { fg = \"foreground\", bg = \"raised\" }\n\n\"ui.menu\" = { fg = \"foreground\", bg = \"raised\" }\n\"ui.menu.selected\" = { fg = \"selection-fg\", bg = \"selection-bg\" }\n\"ui.menu.scroll\" = { fg = \"bright-black\", bg = \"raised\" }\n\n\"ui.virtual.ruler\" = { bg = \"surface\" }\n\"ui.virtual.whitespace\" = { fg = \"bright-black\" }\n\"ui.virtual.indent-guide\" = { fg = \"bright-black\" }\n\"ui.virtual.inlay-hint\" = { fg = \"comment\" }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"comment\" }\n\"ui.virtual.inlay-hint.type\" = { fg = \"comment\" }\n\"ui.virtual.wrap\" = { fg = \"bright-black\" }\n\"ui.virtual.jump-label\" = { fg = \"bright-red\", modifiers = [\"bold\"] }\n\n\"ui.debug.breakpoint\" = { fg = \"red\" }\n\"ui.debug.active\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\n\"ui.highlight\" = { bg = \"match-bg\" }\n\"ui.highlight.frameline\" = { bg = \"surface\" }\n\n\"ui.bufferline\" = { fg = \"bright-black\", bg = \"surface\" }\n\"ui.bufferline.active\" = { fg = \"foreground\", bg = \"background\" }\n\"ui.bufferline.background\" = { bg = \"surface\" }\n\n\"ui.picker.header\" = { fg = \"bright-blue\", modifiers = [\"bold\"] }\n\"ui.picker.header.column\" = { fg = \"bright-blue\", modifiers = [\"bold\"] }\n\"ui.picker.header.column.active\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\n# Diagnostics\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"warning\" = { fg = \"lantern\" }\n\"info\" = { fg = \"blue\" }\n\"hint\" = { fg = \"comment\" }\n\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"lantern\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"comment\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"tabstop\" = { underline = { color = \"lantern\", style = \"dashed\" } }\n\n# Diff\n\"diff.plus\" = \"green\"\n\"diff.plus.gutter\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.minus.gutter\" = \"red\"\n\"diff.delta\" = \"amber\"\n\"diff.delta.gutter\" = \"amber\"\n\"diff.delta.moved\" = \"diff-moved\"\n\"diff.delta.conflict\" = { fg = \"conflict\", modifiers = [\"bold\"] }\n\n# Markup\n\"markup.heading\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = { fg = \"comment\" }\n\"markup.heading.1\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"amber\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"ember\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"amber\" }\n\"markup.heading.5\" = { fg = \"comment\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"blue\" }\n\"markup.list\" = { fg = \"cyan\" }\n\"markup.list.numbered\" = { fg = \"lantern\" }\n\"markup.list.unnumbered\" = { fg = \"cyan\" }\n\"markup.list.checked\" = { fg = \"green\" }\n\"markup.list.unchecked\" = { fg = \"comment\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"link\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"cyan\" }\n\"markup.link.label\" = { fg = \"magenta\" }\n\"markup.quote\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"markup.raw\" = { fg = \"bright-green\" }\n\"markup.raw.inline\" = { fg = \"bright-green\" }\n\"markup.raw.block\" = { fg = \"bright-green\" }\n\"markup.normal.completion\" = \"foreground\"\n\"markup.normal.hover\" = \"foreground\"\n\"markup.heading.completion\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\"markup.heading.hover\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\"markup.raw.inline.completion\" = { fg = \"bright-green\" }\n\"markup.raw.inline.hover\" = { fg = \"bright-green\" }\n\n# Syntax highlighting\n\"attribute\" = { fg = \"amber\" }\n\"type\" = { fg = \"amber\" }\n\"type.builtin\" = { fg = \"yellow\" }\n\"type.enum\" = { fg = \"amber\" }\n\"type.enum.variant\" = { fg = \"amber\" }\n\"type.parameter\" = { fg = \"yellow\" }\n\n\"constructor\" = { fg = \"amber\" }\n\n\"constant\" = { fg = \"constant\" }\n\"constant.builtin\" = { fg = \"constant\" }\n\"constant.builtin.boolean\" = { fg = \"constant\" }\n\"constant.character\" = { fg = \"lantern\" }\n\"constant.character.escape\" = { fg = \"escape\" }\n\"constant.numeric\" = { fg = \"constant\" }\n\"constant.numeric.integer\" = { fg = \"constant\" }\n\"constant.numeric.float\" = { fg = \"constant\" }\n\n\"string\" = { fg = \"green\" }\n\"string.regexp\" = { fg = \"regexp\" }\n\"string.regexp.special\" = { fg = \"bright-magenta\" }\n\"string.special\" = { fg = \"green\" }\n\"string.special.path\" = { fg = \"path\" }\n\"string.special.url\" = { fg = \"link\", modifiers = [\"underlined\"] }\n\"string.special.symbol\" = { fg = \"bright-magenta\" }\n\n\"comment\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"comment.line\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"comment.line.documentation\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"comment.block\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"comment.block.documentation\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"comment.unused\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\n\"variable\" = \"foreground\"\n\"variable.builtin\" = { fg = \"bright-red\" }\n\"variable.parameter\" = \"foreground\"\n\"variable.other\" = \"foreground\"\n\"variable.other.member\" = \"foreground\"\n\"variable.other.member.private\" = \"foreground\"\n\n\"label\" = { fg = \"amber\" }\n\n\"punctuation\" = \"foreground\"\n\"punctuation.bracket\" = \"foreground\"\n\"punctuation.delimiter\" = \"foreground\"\n\"punctuation.special\" = { fg = \"amber\" }\n\n\"keyword\" = { fg = \"lantern\" }\n\"keyword.control\" = { fg = \"lantern\" }\n\"keyword.control.conditional\" = { fg = \"lantern\" }\n\"keyword.control.repeat\" = { fg = \"lantern\" }\n\"keyword.control.import\" = { fg = \"lantern\" }\n\"keyword.control.return\" = { fg = \"lantern\" }\n\"keyword.control.exception\" = { fg = \"lantern\" }\n\"keyword.operator\" = { fg = \"lantern\" }\n\"keyword.directive\" = { fg = \"macro\" }\n\"keyword.function\" = { fg = \"lantern\" }\n\"keyword.storage\" = { fg = \"lantern\" }\n\"keyword.storage.type\" = { fg = \"lantern\" }\n\"keyword.storage.modifier\" = { fg = \"lantern\" }\n\n\"operator\" = \"foreground\"\n\n\"function\" = { fg = \"magenta\" }\n\"function.builtin\" = { fg = \"bright-magenta\" }\n\"function.method\" = { fg = \"magenta\" }\n\"function.method.private\" = { fg = \"magenta\" }\n\"function.macro\" = { fg = \"macro\" }\n\"function.special\" = { fg = \"bright-magenta\" }\n\n\"tag\" = { fg = \"lantern\" }\n\"tag.builtin\" = { fg = \"blue\" }\n\n\"namespace\" = { fg = \"amber\" }\n\n\"special\" = { fg = \"bright-yellow\" }\n\n\"module\" = { fg = \"amber\" }\n\n# Palette definition (MUST be at the end of the file)\n[palette]\nbackground = \"#E4DED6\"\nforeground = \"#1A1816\"\n\ncursor = \"#8A4530\"\ncursor-text = \"#E4DED6\"\nselection-bg = \"#D7C5B1\"\nselection-fg = \"#1A1816\"\ncursorline = \"#DDD2C9\"\n\nsurface = \"#CFC4B6\"\nraised = \"#D9D1C6\"\nborder = \"#CABEAE\"\n\nblack = \"#1A1816\"\nred = \"#6A2828\"\ngreen = \"#3A5830\"\nyellow = \"#B07840\"\nblue = \"#304050\"\nmagenta = \"#806080\"\ncyan = \"#305858\"\nwhite = \"#E4DED6\"\n\nbright-black = \"#514B45\"\nbright-red = \"#3E1717\"\nbright-green = \"#20301A\"\nbright-yellow = \"#78522C\"\nbright-blue = \"#131A20\"\nbright-magenta = \"#543F54\"\nbright-cyan = \"#152727\"\nbright-white = \"#D0C5B7\"\n\nlantern = \"#8A4530\"\nember = \"#7A3828\"\namber = \"#B07840\"\nconstant = \"#447C7C\"\ncomment = \"#222D38\"\npath = \"#3A5830\"\nmacro = \"#543F54\"\nescape = \"#543F54\"\nregexp = \"#20301A\"\nlink = \"#131A20\"\ndirectory = \"#305858\"\nsunken = \"#DDD2C9\"\nmatch-bg = \"#D2BFB5\"\ninfo = \"#304050\"\ndiff-moved = \"#304050\"\nconflict = \"#6A2828\"\n"
  },
  {
    "path": "runtime/themes/akari-night.toml",
    "content": "# Author: Shu Kutsuzawa <cappyzawa@gmail.com>\n# License: MIT\n# Akari Night — A dark palette inspired by Japanese alleys lit by round lanterns.\n\n# UI elements\n\"ui.background\" = { bg = \"background\" }\n\"ui.text\" = \"foreground\"\n\"ui.text.focus\" = { fg = \"selection-fg\", bg = \"selection-bg\" }\n\"ui.text.inactive\" = { fg = \"bright-black\" }\n\"ui.text.info\" = { fg = \"info\" }\n\"ui.text.directory\" = { fg = \"directory\" }\n\n\"ui.cursor\" = { fg = \"cursor-text\", bg = \"cursor\" }\n\"ui.cursor.normal\" = { fg = \"cursor-text\", bg = \"cursor\" }\n\"ui.cursor.primary\" = { fg = \"cursor-text\", bg = \"cursor\" }\n\"ui.cursor.primary.normal\" = { fg = \"cursor-text\", bg = \"cursor\" }\n\"ui.cursor.match\" = { fg = \"lantern\", bg = \"sunken\", modifiers = [\"bold\"] }\n\"ui.cursor.insert\" = { fg = \"cursor-text\", bg = \"green\" }\n\"ui.cursor.primary.insert\" = { fg = \"cursor-text\", bg = \"green\" }\n\"ui.cursor.select\" = { fg = \"cursor-text\", bg = \"magenta\" }\n\"ui.cursor.primary.select\" = { fg = \"cursor-text\", bg = \"magenta\" }\n\n\"ui.selection\" = { bg = \"selection-bg\" }\n\"ui.selection.primary\" = { bg = \"selection-bg\" }\n\n\"ui.cursorline.primary\" = { bg = \"cursorline\" }\n\"ui.cursorline.secondary\" = { bg = \"surface\" }\n\"ui.cursorcolumn.primary\" = { bg = \"surface\" }\n\"ui.cursorcolumn.secondary\" = { bg = \"surface\" }\n\n\"ui.gutter\" = { bg = \"background\" }\n\"ui.gutter.selected\" = { bg = \"cursorline\" }\n\"ui.linenr\" = { fg = \"bright-black\" }\n\"ui.linenr.selected\" = { fg = \"lantern\" }\n\n\"ui.statusline\" = { fg = \"foreground\", bg = \"surface\" }\n\"ui.statusline.inactive\" = { fg = \"comment\", bg = \"surface\" }\n\"ui.statusline.normal\" = { fg = \"background\", bg = \"green\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"background\", bg = \"lantern\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"background\", bg = \"magenta\", modifiers = [\"bold\"] }\n\"ui.statusline.separator\" = { fg = \"bright-black\", bg = \"surface\" }\n\n\"ui.popup\" = { fg = \"foreground\", bg = \"raised\" }\n\"ui.popup.info\" = { fg = \"foreground\", bg = \"raised\" }\n\"ui.window\" = { fg = \"border\" }\n\"ui.background.separator\" = { bg = \"surface\" }\n\"ui.help\" = { fg = \"foreground\", bg = \"raised\" }\n\n\"ui.menu\" = { fg = \"foreground\", bg = \"raised\" }\n\"ui.menu.selected\" = { fg = \"selection-fg\", bg = \"selection-bg\" }\n\"ui.menu.scroll\" = { fg = \"bright-black\", bg = \"raised\" }\n\n\"ui.virtual.ruler\" = { bg = \"surface\" }\n\"ui.virtual.whitespace\" = { fg = \"bright-black\" }\n\"ui.virtual.indent-guide\" = { fg = \"bright-black\" }\n\"ui.virtual.inlay-hint\" = { fg = \"comment\" }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"comment\" }\n\"ui.virtual.inlay-hint.type\" = { fg = \"comment\" }\n\"ui.virtual.wrap\" = { fg = \"bright-black\" }\n\"ui.virtual.jump-label\" = { fg = \"bright-red\", modifiers = [\"bold\"] }\n\n\"ui.debug.breakpoint\" = { fg = \"red\" }\n\"ui.debug.active\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\n\"ui.highlight\" = { bg = \"match-bg\" }\n\"ui.highlight.frameline\" = { bg = \"surface\" }\n\n\"ui.bufferline\" = { fg = \"bright-black\", bg = \"surface\" }\n\"ui.bufferline.active\" = { fg = \"foreground\", bg = \"background\" }\n\"ui.bufferline.background\" = { bg = \"surface\" }\n\n\"ui.picker.header\" = { fg = \"bright-blue\", modifiers = [\"bold\"] }\n\"ui.picker.header.column\" = { fg = \"bright-blue\", modifiers = [\"bold\"] }\n\"ui.picker.header.column.active\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\n# Diagnostics\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"warning\" = { fg = \"lantern\" }\n\"info\" = { fg = \"blue\" }\n\"hint\" = { fg = \"comment\" }\n\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"lantern\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"comment\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"tabstop\" = { underline = { color = \"lantern\", style = \"dashed\" } }\n\n# Diff\n\"diff.plus\" = \"green\"\n\"diff.plus.gutter\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.minus.gutter\" = \"red\"\n\"diff.delta\" = \"amber\"\n\"diff.delta.gutter\" = \"amber\"\n\"diff.delta.moved\" = \"diff-moved\"\n\"diff.delta.conflict\" = { fg = \"conflict\", modifiers = [\"bold\"] }\n\n# Markup\n\"markup.heading\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = { fg = \"comment\" }\n\"markup.heading.1\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"amber\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"ember\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"amber\" }\n\"markup.heading.5\" = { fg = \"comment\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"blue\" }\n\"markup.list\" = { fg = \"cyan\" }\n\"markup.list.numbered\" = { fg = \"lantern\" }\n\"markup.list.unnumbered\" = { fg = \"cyan\" }\n\"markup.list.checked\" = { fg = \"green\" }\n\"markup.list.unchecked\" = { fg = \"comment\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"link\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"cyan\" }\n\"markup.link.label\" = { fg = \"magenta\" }\n\"markup.quote\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"markup.raw\" = { fg = \"bright-green\" }\n\"markup.raw.inline\" = { fg = \"bright-green\" }\n\"markup.raw.block\" = { fg = \"bright-green\" }\n\"markup.normal.completion\" = \"foreground\"\n\"markup.normal.hover\" = \"foreground\"\n\"markup.heading.completion\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\"markup.heading.hover\" = { fg = \"lantern\", modifiers = [\"bold\"] }\n\"markup.raw.inline.completion\" = { fg = \"bright-green\" }\n\"markup.raw.inline.hover\" = { fg = \"bright-green\" }\n\n# Syntax highlighting\n\"attribute\" = { fg = \"amber\" }\n\"type\" = { fg = \"amber\" }\n\"type.builtin\" = { fg = \"yellow\" }\n\"type.enum\" = { fg = \"amber\" }\n\"type.enum.variant\" = { fg = \"amber\" }\n\"type.parameter\" = { fg = \"yellow\" }\n\n\"constructor\" = { fg = \"amber\" }\n\n\"constant\" = { fg = \"constant\" }\n\"constant.builtin\" = { fg = \"constant\" }\n\"constant.builtin.boolean\" = { fg = \"constant\" }\n\"constant.character\" = { fg = \"lantern\" }\n\"constant.character.escape\" = { fg = \"escape\" }\n\"constant.numeric\" = { fg = \"constant\" }\n\"constant.numeric.integer\" = { fg = \"constant\" }\n\"constant.numeric.float\" = { fg = \"constant\" }\n\n\"string\" = { fg = \"green\" }\n\"string.regexp\" = { fg = \"regexp\" }\n\"string.regexp.special\" = { fg = \"bright-magenta\" }\n\"string.special\" = { fg = \"green\" }\n\"string.special.path\" = { fg = \"path\" }\n\"string.special.url\" = { fg = \"link\", modifiers = [\"underlined\"] }\n\"string.special.symbol\" = { fg = \"bright-magenta\" }\n\n\"comment\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"comment.line\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"comment.line.documentation\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"comment.block\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"comment.block.documentation\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\"comment.unused\" = { fg = \"comment\", modifiers = [\"dim\"] }\n\n\"variable\" = \"foreground\"\n\"variable.builtin\" = { fg = \"bright-red\" }\n\"variable.parameter\" = \"foreground\"\n\"variable.other\" = \"foreground\"\n\"variable.other.member\" = \"foreground\"\n\"variable.other.member.private\" = \"foreground\"\n\n\"label\" = { fg = \"amber\" }\n\n\"punctuation\" = \"foreground\"\n\"punctuation.bracket\" = \"foreground\"\n\"punctuation.delimiter\" = \"foreground\"\n\"punctuation.special\" = { fg = \"amber\" }\n\n\"keyword\" = { fg = \"lantern\" }\n\"keyword.control\" = { fg = \"lantern\" }\n\"keyword.control.conditional\" = { fg = \"lantern\" }\n\"keyword.control.repeat\" = { fg = \"lantern\" }\n\"keyword.control.import\" = { fg = \"lantern\" }\n\"keyword.control.return\" = { fg = \"lantern\" }\n\"keyword.control.exception\" = { fg = \"lantern\" }\n\"keyword.operator\" = { fg = \"lantern\" }\n\"keyword.directive\" = { fg = \"macro\" }\n\"keyword.function\" = { fg = \"lantern\" }\n\"keyword.storage\" = { fg = \"lantern\" }\n\"keyword.storage.type\" = { fg = \"lantern\" }\n\"keyword.storage.modifier\" = { fg = \"lantern\" }\n\n\"operator\" = \"foreground\"\n\n\"function\" = { fg = \"magenta\" }\n\"function.builtin\" = { fg = \"bright-magenta\" }\n\"function.method\" = { fg = \"magenta\" }\n\"function.method.private\" = { fg = \"magenta\" }\n\"function.macro\" = { fg = \"macro\" }\n\"function.special\" = { fg = \"bright-magenta\" }\n\n\"tag\" = { fg = \"lantern\" }\n\"tag.builtin\" = { fg = \"blue\" }\n\n\"namespace\" = { fg = \"amber\" }\n\n\"special\" = { fg = \"bright-yellow\" }\n\n\"module\" = { fg = \"amber\" }\n\n# Palette definition (MUST be at the end of the file)\n[palette]\nbackground = \"#25231F\"\nforeground = \"#E6DED3\"\n\ncursor = \"#E26A3B\"\ncursor-text = \"#25231F\"\nselection-bg = \"#51422E\"\nselection-fg = \"#E6DED3\"\ncursorline = \"#412E23\"\n\nsurface = \"#2D2E2E\"\nraised = \"#303233\"\nborder = \"#353A3D\"\n\nblack = \"#1E1C19\"\nred = \"#D25046\"\ngreen = \"#7FAF6A\"\nyellow = \"#D4A05A\"\nblue = \"#5A6F82\"\nmagenta = \"#8E7BA0\"\ncyan = \"#6F8F8A\"\nwhite = \"#E6DED3\"\n\nbright-black = \"#716A5F\"\nbright-red = \"#DE7F77\"\nbright-green = \"#A1C492\"\nbright-yellow = \"#E4C397\"\nbright-blue = \"#8195A8\"\nbright-magenta = \"#B4A7C0\"\nbright-cyan = \"#9AB1AD\"\nbright-white = \"#EFEAE3\"\n\nlantern = \"#E26A3B\"\nember = \"#D65A3A\"\namber = \"#D4A05A\"\nconstant = \"#8CA6A1\"\ncomment = \"#7E93A6\"\npath = \"#7FAF6A\"\nmacro = \"#B4A7C0\"\nescape = \"#B4A7C0\"\nregexp = \"#A1C492\"\nlink = \"#8195A8\"\ndirectory = \"#6F8F8A\"\nsunken = \"#412E23\"\nmatch-bg = \"#4B3125\"\ninfo = \"#5A6F82\"\ndiff-moved = \"#5A6F82\"\nconflict = \"#D25046\"\n"
  },
  {
    "path": "runtime/themes/amberwood.toml",
    "content": "\n\"attribute\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\"ui.virtual.wrap\"=\"softwrap\"\n\"keyword\" = \"keyword\"\n\"keyword.control.conditional\" = { fg = \"conditional\", modifiers = [\"italic\"] }\n\"keyword.directive\" = \"magenta\" # -- preprocessor comments (#if in C)\n\n\"namespace\" = { fg = \"namespace\", modifiers = [\"italic\"] }\n\n\"punctuation\" = \"gray06\"\n\"punctuation.delimiter\" = \"gray06\"\n\n\"operator\" = \"operator\"\n\"special\" = \"yellow\"\n\n\"variable\" = {fg=\"fg\"}\n\"variable.builtin\" = \"bright_blue\"\n\"variable.parameter\" = {fg=\"white\", modifiers=[\"italic\"]}\n\"variable.other.member\" = \"white\"\n\n\"type\" = \"bright_blue\"\n\"type.builtin\" = \"magenta\"\n\"type.enum.variant\" = \"magenta\"\n\n\"constructor\" = \"yellow\"\n\n\"function\" = {fg=\"function\", modifiers=[\"italic\"]}\n\"function.macro\" = \"bright_cyan\"\n\"function.builtin\" = \"support_function\"\n\n\"tag\" = \"tag\"\n\"comment\" = { fg = \"comment\", modifiers = [\"italic\"] }\n\n\"string\" = \"string\"\n\"string.regexp\" = \"green\"\n\"string.special\" = \"yellow\"\n\n\"constant\" = \"constant\"\n\"constant.builtin\" = \"yellow\"\n\"constant.numeric\" = \"numeric\"\n\"constant.character.escape\" = \"cyan\"\n\n# used for lifetimes\n\"label\" = \"yellow\"\n\n\"markup.heading.marker\" = { fg = \"gray06\" }\n\"markup.heading\" = { fg = \"bright_blue\", modifiers = [\"bold\"] }\n\"markup.list\" = \"gray06\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link.url\" = { fg = \"green\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\"markup.raw\" = \"yellow\"\n\n\"diff.plus\" = \"bright_green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"bright_blue\"\n\n\"ui.background\" = { bg = \"bg\" }\n\"ui.background.separator\" = { fg = \"fg\" }\n\n\"ui.linenr\" = { fg = \"gray04\" }\n\"ui.linenr.selected\" = { fg = \"fg\" }\n\n\"ui.statusline\" = { fg = \"status_line_fg\", bg = \"gray01\" }\n\"ui.statusline.inactive\" = { fg = \"fg\", bg = \"gray01\", modifiers = [\"dim\"] }\n\"ui.statusline.normal\" = { fg = \"bg\", bg = \"cyan\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"bg\", bg = \"blue\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"bg\", bg = \"magenta\", modifiers = [\"bold\"] }\n\n\"ui.popup\" = { bg = \"gray01\" }\n\"ui.window\" = { fg = \"gray02\" }\n\"ui.help\" = { bg = \"gray01\", fg = \"white\" }\n\n\"ui.text\" = { fg = \"fg\" }\n\"ui.text.focus\" = { fg = \"fg\" }\n\n\"ui.virtual\" = { fg = \"gray02\" }\n\"ui.virtual.ruler\" = {bg=\"gray02\"}\n\"ui.virtual.indent-guide\" = { fg = \"gray02\" }\n\"ui.virtual.inlay-hint\" = { fg = \"gray03\" }\n\n\n\"ui.selection\" = { bg = \"gray03\" }\n\"ui.selection.primary\" = { bg = \"gray03\" }\n\n\"ui.cursor\" = {fg=\"bg\", bg = \"cursor\" }\n\"ui.cursor.match\" = { fg = \"yellow\", modifiers = [\"bold\", \"underlined\"] }\n\"ui.cursorline.primary\" = { bg = \"gray01\" }\n\n\"ui.highlight\" = { bg = \"gray02\" }\n\n\"ui.menu\" = { fg = \"white\", bg = \"gray01\" }\n\"ui.menu.selected\" = { fg = \"bright_white\", bg = \"gray03\" }\n\"ui.menu.scroll\" = { fg = \"gray04\", bg = \"gray01\" }\n\ndiagnostic = { modifiers = [\"underlined\"] }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nwarning = \"yellow\"\nerror = \"error\"\ninfo = \"bright_blue\"\nhint = \"bright_cyan\"\n\n[palette]\nerror=\"#fca5a5\"\nbg = \"#0F1014\"\nfg = \"#c9c7cd\"\ngreen = \"#90b99f\"\nbright_green = \"#9dc6ac\"\nyellow = \"#e5c890\"\nblue = \"#aca1cf\"\nbright_blue = \"#b9aeda\"\nmagenta = \"#e29eca\"\ncyan = \"#ea83a5\"\nbright_cyan = \"#f591b2\"\nwhite = \"#c1c0d4\"\nbright_white = \"#cac9dd\"\ngray01 = \"#1b1b1d\"\ngray02 = \"#2a2a2d\"\ngray03 = \"#3e3e43\"\ngray04 = \"#57575f\"\ngray06 = \"#9998a8\"\ngray07 = \"#c1c0d4\"\ncomment=\"#808080\"\nred=\"#e78284\"\nfunction=\"#e5c890\"\nsupport_function=\"#9898a6\"\nconstant=\"#8eb6f5\"\nstring=\"#9898a6\"\ntag=\"#9898a6\"\nkeyword=\"#8eb6f5\"\nnamespace= \"#c58fff\"\nnumeric= \"#e9c46a\"\nstatus_line_fg = \"#e5c890\"\noperator=\"#8eb6f5\"\nsoftwrap=\"#808080\"\nconditional=\"#a8a29e\"\ncursor=\"#e5c890\"\n"
  },
  {
    "path": "runtime/themes/andromeda.toml",
    "content": "\n# Interface colors\n\"ui.background\" = { bg = \"background\" }\n\"ui.background.separator\" = { fg = \"muted\" }\n\"ui.cursor\" = { fg = \"background\", bg = \"cursor\" }\n\"ui.cursor.normal\" = { fg = \"background\", bg = \"cursor\" }\n\"ui.cursor.insert\" = { fg = \"background\", bg = \"accent\" }\n\"ui.cursor.select\" = { fg = \"background\", bg = \"purple\" }\n\"ui.cursor.match\" = { fg = \"background\", bg = \"yellow\" }\n\"ui.cursor.primary\" = { fg = \"background\", bg = \"cursor\" }\n\"ui.cursor.primary.normal\" = { fg = \"background\", bg = \"cursor\" }\n\"ui.cursor.primary.insert\" = { fg = \"background\", bg = \"accent\" }\n\"ui.cursor.primary.select\" = { fg = \"background\", bg = \"purple\" }\n\n\"ui.gutter\" = { bg = \"background\" }\n\"ui.gutter.selected\" = { bg = \"line_highlight\" }\n\"ui.linenr\" = { fg = \"line_numbers\" }\n\"ui.linenr.selected\" = { fg = \"accent\", modifiers = [\"bold\"] }\n\n\"ui.statusline\" = { fg = \"foreground\", bg = \"background\" }\n\"ui.statusline.inactive\" = { fg = \"muted\", bg = \"background\" }\n\"ui.statusline.normal\" = { fg = \"background\", bg = \"accent\" }\n\"ui.statusline.insert\" = { fg = \"background\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"background\", bg = \"purple\" }\n\n\"ui.popup\" = { fg = \"foreground\", bg = \"popup_bg\" }\n\"ui.popup.info\" = { fg = \"foreground\", bg = \"popup_bg\" }\n\"ui.window\" = { fg = \"muted\" }\n\"ui.help\" = { fg = \"foreground\", bg = \"popup_bg\" }\n\n\"ui.text\" = { fg = \"foreground\" }\n\"ui.text.focus\" = { fg = \"accent\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = { fg = \"muted\" }\n\"ui.text.info\" = { fg = \"foreground\" }\n\n\"ui.virtual.ruler\" = { bg = \"line_highlight\" }\n\"ui.virtual.whitespace\" = { fg = \"muted\" }\n\"ui.virtual.indent-guide\" = { fg = \"muted\" }\n\"ui.virtual.inlay-hint\" = { fg = \"hint\" }\n\"ui.virtual.jump-label\" = { fg = \"white\", bg = \"background\" }\n\n\"ui.menu\" = { fg = \"foreground\", bg = \"popup_bg\" }\n\"ui.menu.selected\" = { fg = \"background\", bg = \"accent\" }\n\"ui.menu.scroll\" = { fg = \"muted\", bg = \"background\" }\n\n\"ui.selection\" = { bg = \"selection_background\" }\n\"ui.selection.primary\" = { bg = \"selection_background\" }\n\"ui.highlight\" = { bg = \"line_highlight\" }\n\"ui.cursorline.primary\" = { bg = \"line_highlight\" }\n\"ui.cursorline.secondary\" = { bg = \"line_highlight\" }\n\n# Diagnostics\n\"warning\" = { fg = \"warning\" }\n\"error\" = { fg = \"error\" }\n\"info\" = { fg = \"info\" }\n\"hint\" = { fg = \"hint\" }\n\"diagnostic\" = { modifiers = [\"underlined\"] }\n\"diagnostic.hint\" = { fg = \"hint\", modifiers = [\"underlined\"] }\n\"diagnostic.info\" = { fg = \"info\", modifiers = [\"underlined\"] }\n\"diagnostic.warning\" = { fg = \"warning\", modifiers = [\"underlined\"] }\n\"diagnostic.error\" = { fg = \"error\", modifiers = [\"underlined\"] }\n\"diagnostic.unnecessary\" = { fg = \"muted\", modifiers = [\"dim\"] }\n\n# Syntax highlighting\n\"comment\" = { fg = \"comment\", modifiers = [\"italic\"] }\n\"constant\" = { fg = \"red\" }\n\"constant.character\" = { fg = \"green\" }\n\"constant.character.escape\" = { fg = \"yellow\" }\n\"constant.numeric\" = { fg = \"orange\" }\n\"constant.builtin\" = { fg = \"red\" }\n\n\"string\" = { fg = \"green\" }\n\"string.regexp\" = { fg = \"blue\" }\n\"string.special\" = { fg = \"yellow\" }\n\n\"type\" = { fg = \"yellow\" }\n\"type.builtin\" = { fg = \"yellow\" }\n\"type.enum\" = { fg = \"yellow\" }\n\"type.parameter\" = { fg = \"orange\" }\n\n\"constructor\" = { fg = \"red\" }\n\"function\" = { fg = \"yellow\" }\n\"function.builtin\" = { fg = \"yellow\" }\n\"function.method\" = { fg = \"yellow\" }\n\"function.macro\" = { fg = \"purple\" }\n\n\"variable\" = { fg = \"cyan\" }\n\"variable.builtin\" = { fg = \"red\" }\n\"variable.parameter\" = { fg = \"orange\" }\n\"variable.other.member\" = { fg = \"cyan\" }\n\n\"keyword\" = { fg = \"purple\" }\n\"keyword.control\" = { fg = \"purple\" }\n\"keyword.control.conditional\" = { fg = \"purple\" }\n\"keyword.control.repeat\" = { fg = \"purple\" }\n\"keyword.control.import\" = { fg = \"purple\" }\n\"keyword.control.return\" = { fg = \"purple\" }\n\"keyword.control.exception\" = { fg = \"purple\" }\n\"keyword.operator\" = { fg = \"red\" }\n\"keyword.directive\" = { fg = \"purple\" }\n\"keyword.function\" = { fg = \"purple\" }\n\"keyword.storage\" = { fg = \"purple\" }\n\"keyword.storage.type\" = { fg = \"purple\" }\n\"keyword.storage.modifier\" = { fg = \"purple\" }\n\n\"operator\" = { fg = \"red\" }\n\"punctuation\" = { fg = \"foreground\" }\n\"punctuation.delimiter\" = { fg = \"foreground\" }\n\"punctuation.bracket\" = { fg = \"foreground\" }\n\"punctuation.special\" = { fg = \"hot_pink\" }\n\n\"tag\" = { fg = \"hot_pink\" }\n\"attribute\" = { fg = \"orange\" }\n\"namespace\" = { fg = \"yellow\" }\n\"module\" = { fg = \"yellow\" }\n\"special\" = { fg = \"hot_pink\" }\n\n# Markup\n\"markup.heading\" = { fg = \"hot_pink\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = { fg = \"hot_pink\" }\n\"markup.list\" = { fg = \"yellow\" }\n\"markup.list.marker\" = { fg = \"hot_pink\" }\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"blue\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"cyan\" }\n\"markup.quote\" = { fg = \"comment\", modifiers = [\"italic\"] }\n\"markup.raw\" = { fg = \"green\" }\n\"markup.raw.block\" = { fg = \"green\" }\n\n# Diff\n\"diff.plus\" = { fg = \"diff_add\" }\n\"diff.minus\" = { fg = \"diff_delete\" }\n\"diff.delta\" = { fg = \"diff_change\" }\n\n# Color palette\n[palette]\n# Main colors\nwhite = \"#FFFFFF\"\nbackground = \"#23262E\"\nforeground = \"#D5CED9\"\ncursor = \"#FFFFFF\"\n\n# UI colors\nline_highlight = \"#2e323d\"\nselection_background = \"#3D4352\"\nline_numbers = \"#746f77\"\nmuted = \"#746f77\"\npopup_bg = \"#20232A\"\n\n# Accent colors\naccent = \"#00e8c6\"   # Cyan\ncyan = \"#00e8c6\"     # Cyan\norange = \"#f39c12\"   # Orange\nyellow = \"#FFE66D\"   # Yellow\npurple = \"#c74ded\"   # Purple\nhot_pink = \"#f92672\" # Hot Pink\nblue = \"#7cb7ff\"     # Blue\nred = \"#ee5d43\"      # Red\ngreen = \"#96E072\"    # Green\n\n# Syntax colors\ncomment = \"#A0A1A7\"\nstring = \"#96E072\"\nnumber = \"#f39c12\"\nkeyword = \"#c74ded\"\nfunction = \"#FFE66D\"\nvariable = \"#00e8c6\"\ntype = \"#FFE66D\"\nconstant = \"#ee5d43\"\noperator = \"#ee5d43\"\ntag = \"#f92672\"\nattribute = \"#f39c12\"\npunctuation = \"#D5CED9\"\n\n# Diagnostic colors\nerror = \"#FC644D\"\nwarning = \"#FF9F2E\"\ninfo = \"#00b0ff\"\nhint = \"#746f77\"\n\n# Diff colors\ndiff_add = \"#96E072\"\ndiff_delete = \"#FC644D\"\ndiff_change = \"#FFE66D\"\n"
  },
  {
    "path": "runtime/themes/ao.toml",
    "content": "# Theme: Ao\n# Author: YardQuit\n\n# SYNTAX HIGHLIGHTING\n\"attribute\" = { fg = \"yellow\" }\n\"type\" = { fg = \"white\" }\n\"type.builtin\" = { fg = \"white\" }\n\"type.parameter\" = { fg = \"white\" }\n\"type.enum\" = { fg = \"white\" }\n\"type.enum.variant\" = { fg = \"white\" }\n\"constructor\" = { fg = \"orange\" }\n\"constant\" = { fg = \"blue\" }\n\"constant.character.escape\" = { fg = \"yellow\" }\n\"string\" = { fg = \"blue\" }\n\"string.regexp\" = { fg = \"yellow\" }\n\"comment\" = { fg = \"gray\" }\n\"variable\" = { fg = \"orange\" }\n\"variable.parameter\" = { fg = \"yellow\" }\n\"variable.other\" = { fg = \"green\" }\n\"variable.other.member\" = { fg = \"green\" }\n\"label\" = { fg = \"blue\" }\n\"punctuation\" = { fg = \"white\" }\n\"punctuation.bracket\" = { fg = \"orange\" }\n\"punctuation.special\" = { fg = \"yellow\" }\n\"keyword\" = { fg = \"red\" }\n\"keyword.operator\" = { fg = \"blue\" }\n\"keyword.directive\" = { fg = \"white\" }\n\"keyword.function\" = { fg = \"red\" }\n\"keyword.storage\" = { fg = \"red\" }\n\"keyword.storage.modifier\" = { fg = \"green\" }\n\"operator\" = { fg = \"white\" }\n\"function\" = { fg = \"purple\" }\n\"function.method\" = { fg = \"green\" }\n\"function.macro\" = { fg = \"green\" }\n\"function.special\" = { fg = \"yellow\" }\n\"tag\" = { fg = \"green\" }\n\"namespace\" = { fg = \"white\" }\n\"diff\" = { fg = \"white\" }\n\"diff.minus\" = { fg = \"red\" }\n\"diff.delta\" = { fg = \"brown\" }\n\n# MARKUP, SYNTAX HIGHLIGHTING AND INTERFACE HYBRID\n\"markup.heading\" = { fg = \"blaze_orange\" }\n\"markup.heading.1\" = { fg = \"crystal_blue\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"sky_blue\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"dreamy_blue\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"crystal_blue\" }\n\"markup.heading.5\" = { fg = \"sky_blue\" }\n\"markup.heading.6\" = { fg = \"dreamy_blue\" }\n\"markup.list\" = { fg = \"blaze_orange\" }\n\"markup.bold\" = { fg = \"crystal_blue\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"crystal_blue\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { fg = \"crystal_blue\", modifiers = [\"crossed_out\"] }\n\"markup.link\" = { fg = \"crystal_blue\", underline = { color = \"light_purple\", style = \"line\" } }\n\"markup.link.url\" = { fg = \"slate_purple\", underline = { color = \"slate_purple\", style = \"line\" } }\n\"markup.link.label\" = { fg = \"crystal_blue\" }\n\"markup.link.text\" = { fg = \"crystal_blue\", modifiers = [\"bold\"] }\n\"markup.quote\" = { fg = \"winter_sky\", modifiers = [\"italic\"] }\n\"markup.raw\" = { fg = \"winter_sky\" }\n\"markup.raw.block\" = { fg = \"white\" }\n\n# USER INTERFACE \n\"ui.background\" = { bg = \"deep_abyss\"}                                                               # workspace background\n\"ui.background.separator\" = { fg = \"winter_sky\" }                                                    # picker separator below input line (space + j)\n\"ui.gutter\" = { bg = \"deep_abyss\" }                                                                  # gutter\n\"ui.gutter.selected\" = { bg = \"pitch_black\" }                                                        # gutter for the line the cursor is on\n\"ui.linenr\" = { fg = \"slate_gray\" }                                                                  # line numbers\n\"ui.linenr.selected\" = { fg = \"blaze_orange\", modifiers = [\"bold\"] }                                 # line number for the line the cursor is on\n\"ui.statusline\" = { fg = \"winter_sky\", bg = \"twilight_blue\" }                                        # statusline, fucused\n\"ui.statusline.inactive\" = { fg = \"slate_gray\", bg = \"pitch_black\" }                                 # statusline, unfocused\n\"ui.statusline.normal\" = { fg = \"deep_abyss\", bg = \"leafy_green\", modifiers = [\"bold\"] }             # statusline normal mode (if editor.color-modes is enabled)\n\"ui.statusline.insert\" = { fg = \"deep_abyss\", bg = \"blaze_orange\", modifiers = [\"bold\"] }            # statusline insert mode (if editor.color-modes is enabled)\n\"ui.statusline.select\" = { fg = \"deep_abyss\", bg = \"sky_blue\", modifiers = [\"bold\"] }                # statusline select mode (if editor.color-modes is enabled)\n\"ui.statusline.separator\" = { fg = \"winter_sky\" }                                                    # separator character is statusline\n\"ui.bufferline\" = { fg = \"slate_gray\", modifiers = [\"bold\"] }                                        # bufferline inactive tab\n\"ui.bufferline.active\" = { fg = \"winter_sky\", bg = \"twilight_blue\" }                                 # bufferline active tab\n\"ui.bufferline.background\" = { bg = \"pitch_black\" }                                                  # bufferline background\n\"ui.virtual.ruler\" = { bg = \"stormy_night\" }                                                         # ruler columns\n\"ui.virtual.whitespace\" = { fg = \"stormy_night\" }                                                    # whitespace characters\n\"ui.virtual.indent-guide\" = { fg = \"stormy_night\" }                                                  # vertical indent width guides\n\"ui.virtual.inlay-hint\" = { fg = \"slate_gray\" }                                                      # inlay hints of all kinds\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"slate_gray\" }                                            # inlay hints of kind parameter (lsps are not required to set a kind)\n\"ui.virtual.inlay-hint.type\" = { fg = \"slate_gray\" }                                                 # inlay hints of kind type (lsps are not required to set a kind)\n\"ui.virtual.wrap\" = { fg = \"slate_gray\" }                                                            # soft-wrap indicator\n\"ui.virtual.jump-label\" = { modifiers = [\"reversed\"] }                                               # virtual jump labels (g + w)\n\"ui.selection\" = { bg = \"deep_purple\" }                                                              # slave selections in the editing area\n\"ui.selection.primary\" = { bg = \"light_purple\" }                                                     # primary selection in the editing area\n\"ui.cursor\" = { modifiers = [\"reversed\"] }                                                           # only if \"ui.cursor.primary.normal\" isn't set\n\"ui.cursor.normal\" = { fg = \"winter_sky\", bg = \"twilight_blue\" }                                     # slave cursor block in normal mode\n\"ui.cursor.insert\" = { bg = \"rustic_red\" }                                                           # slave cursor block in insert mode\n\"ui.cursor.select\" = { bg = \"deep_purple\" }                                                          # slave cursor block in select mode\n\"ui.cursor.match\" = { fg = \"deep_abyss\", bg = \"blaze_orange\", modifiers = [\"bold\"] }                 # matching bracket etc\n\"ui.cursor.primary\" = { modifiers = [\"reversed\"] }                                                   # cursor with primary selection (has no effect due to \"ui.cursor.primary.normal\" is set)\n\"ui.cursor.primary.normal\" = { fg = \"deep_abyss\", bg = \"sky_blue\" }                                  # cursor block in normal mode\n\"ui.cursor.primary.insert\" = { fg = \"deep_abyss\", bg = \"ruby_glow\" }                                 # cursor block in insert mode\n\"ui.cursor.primary.select\" = { fg = \"winter_sky\", bg = \"deep_purple\" }                               # cursor block in select mode (not the selected color)\n\"ui.cursorline.primary\" = { bg = \"nightfall_blue\" }                                                  # line of the primary cursor\n\"ui.cursorline.secondary\" = { bg = \"midnight_thunder\"}                                               # lines of secondary cursors\n\"ui.cursorcolumn.primary\" = { bg = \"nightfall_blue\" }                                                # column of the primary cursor\n\"ui.cursorcolumn.secondary\" = { bg = \"midnight_thunder\" }                                            # columns of secondary cursors\n\n# USER INTERFACE - MENUS AND POPUP\n\"ui.popup\" = { fg = \"winter_sky\", bg = \"midnight_thunder\" }                                          # documentation popups (space + k)\n\"ui.popup.info\" = { fg = \"winter_sky\", bg = \"nightfall_blue\" }                                       # prompt for multiple key options, menu border (space, g, z, m, etc)\n\"ui.window\" = { fg = \"slate_gray\" }                                                                  # borderlines separating splits\n\"ui.help\" = { fg = \"winter_sky\", bg = \"nightfall_blue\" }                                             # description box for commands\n\"ui.text\" = { fg = \"white\" }                                                                         # default text style, command prompts, popup text, etc\n\"ui.text.focus\" = { fg = \"dreamy_blue\" }                                                             # the currently selected line in the picker (space j, space f, space s, etc)\n\"ui.text.inactive\" = { fg = \"slate_gray\" }                                                           # same as ui.text but when the text is inactive e.g. suggestions\n\"ui.text.info\" = { fg = \"winter_sky\", bg = \"nightfall_blue\" }                                        # the key: command in ui.popup.info boxes (space, g, z, m, etc)\n\"ui.menu\" = { fg = \"winter_sky\", bg = \"midnight_thunder\" }                                           # code and command completion menus \":\"\n\"ui.menu.selected\" = { fg = \"winter_sky\", bg = \"twilight_blue\" }                                     # selected autocomplete item\n\"ui.menu.scroll\" = { fg = \"crystal_blue\", bg = \"moonlight_ocean\" }                                   # scrollbar\n\"ui.highlight\" = { underline = { color = \"sky_blue\", style = \"line\" } }                              # highlighted lines in the picker preview\n\n# USER INTERFACE - DIAGNOSTICS\n\"warning\" = { fg = \"lemon_zest\" }                                                                    # diagnostics warning (gutter)\n\"error\" = { fg = \"ruby_glow\" }                                                                       # diagnostics error (gutter)\n\"info\" = { fg = \"sky_blue\" }                                                                         # diagnostics info (gutter)\n\"hint\" = { fg = \"walnut_brown\" }                                                                     # diagnostics hint (gutter)\n\"diagnostic\" = { modifiers = [\"reversed\"] }                                                          # diagnostics fallback style (editing area)\n\"diagnostic.hint\" = { fg = \"deep_abyss\", bg = \"walnut_brown\" }                                       # diagnostics hint (editing area)\n\"diagnostic.info\" = { fg = \"winter_sky\", bg = \"twilight_blue\" }                                      # diagnostics info (editing area)\n\"diagnostic.warning\" = { fg = \"winter_sky\", bg = \"rustic_amber\" }                                    # diagnostics warning (editing area)\n\"diagnostic.error\" = { fg = \"winter_sky\", bg = \"rustic_red\" }                                        # diagnostics error (editing area)\n\n# COLOR NAMES\n[palette] \n# PALETTE USER INTERFACE\ndeep_abyss = \"#080d15\"\nstormy_night = \"#254862\"\nnightfall_blue = \"#1f2937\"\nmidnight_thunder = \"#0d1526\"\ntwilight_blue = \"#2c5484\"\npitch_black = \"#000000\"\nwinter_sky = \"#f3f4f6\"\nslate_gray = \"#838a97\"\nblaze_orange = \"#ff9000\"\nlemon_zest = \"#ffba00\"\nleafy_green = \"#81be83\"\ndreamy_blue = \"#6eb0ff\"\ncrystal_blue = \"#99c7ff\"\nsky_blue = \"#45b1e8\"\nmoonlight_ocean = \"#0c1420\"\nrustic_red = \"#540b0c\"\nruby_glow = \"#fa7970\"\nwalnut_brown = \"#987654\"\nrustic_amber = \"#9d5800\"\nslate_purple = \"#d2a8ff\"\nlight_purple = \"#7533bd\"\ndeep_purple = \"#4c1785\"\n\n# SYNTAX HIGHLIGHTING\nblack = \"#0d1117\"\nred = \"#fa7970\"\ngreen = \"#81be83\"\nyellow = \"#ffba00\"\norange = \"#ff9000\"\nblue = \"#45b1e8\"\npurple = \"#d2a8ff\"\nbrown = \"#987654\"\ngray = \"#838a97\"\nwhite = \"#dadada\"\n\n\n"
  },
  {
    "path": "runtime/themes/ashen.toml",
    "content": "# Ashen for Helix\n# -------------------\n# Author: Daniel Fichtinger <daniel@ficd.ca>\n# License: MIT License\n# Upstream: https://sr.ht/~ficd/ashen\n# -------------------\n# Sections:\n# - Syntax highlighting\n# - User interface\n# - Palette\n\n# Syntax highlighting\n# -------------------\n\"attribute\" = \"g_4\"\n\n\"type\" = \"blue\"\n\"type.builtin\" = \"blue\"\n\"type.parameter\" = \"orange_glow\"\n\"type.enum.variant\" = \"orange_blaze\"\n\n\"constructor\" = \"g_1\"\n\n\"constant\" = \"orange_blaze\"\n\"constant.builtin\" = \"blue\"\n\"constant.character\" = { fg = \"red_glowing\", modifiers = [\"bold\"] }\n\"constant.character.escape\" = \"g_2\"\n\"constant.numeric\" = \"blue\"\n\n\"string\" = \"red_glowing\"\n\"string.regexp\" = \"orange_glow\"\n\"string.special\" = \"g_2\"\n\"string.special.url\" = { fg = \"red_glowing\", modifiers = [\"bold\"] }\n\"string.special.path\" = { fg = \"red_glowing\", modifiers = [\"bold\"] }\n\"string.special.symbol\" = \"orange_smolder\"\n\n\"comment\" = { fg = \"g_6\", modifiers = [\"italic\"] }\n\"comment.block.documentation\" = { fg = \"g_5\", modifiers = [\"italic\"] }\n\"comment.line.documentation\" = { fg = \"g_5\", modifiers = [\"italic\"] }\n\n\"variable\" = \"g_3\"\n\"variable.parameter\" = { fg = \"g_2\", modifiers = [\"italic\"] }\n\"variable.builtin\" = \"blue\"\n\"variable.other.member\" = { fg = \"g_2\" }\n\n\"label\" = \"red_ember\" # used for lifetimes\n\n\"punctuation\" = \"g_2\"\n\"punctuation.special\" = \"orange_golden\"\n\"punctuation.bracket\" = \"g_6\"\n\"punctuation.delimiter\" = \"orange_smolder\"\n\n\n\"keyword\" = \"red_ember\"\n\"keyword.operator\" = \"orange_blaze\"\n\"keyword.directive\" = { fg = \"red_ember\", modifiers = [\"italic\"] }\n\"keyword.storage.modifier\" = { fg = \"red_ember\", modifiers = [\"italic\"] }\n\n\"operator\" = \"orange_glow\"\n\n\"function\" = { fg = \"g_3\", modifiers = [\"bold\"] }\n\"function.builtin\" = { fg = \"g_3\", modifiers = [\"bold\", \"italic\"] }\n\"function.macro\" = \"red_ember\"\n\n\"tag\" = { fg = \"orange_glow\", modifiers = [\"italic\"] }\n\n\"namespace\" = { fg = \"orange_glow\", modifiers = [\"bold\"] }\n\n\"special\" = \"orange_smolder\" # fuzzy highlight\n\n\"markup.heading\" = { fg = \"red_glowing\", modifiers = [\"bold\"] }\n\"markup.list\" = \"orange_glow\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link.url\" = { fg = \"red_glowing\", modifiers = [\"italic\", \"underlined\"] }\n\"markup.link.text\" = \"red_ember\"\n\"markup.raw\" = { fg = \"g_2\", bg = \"g_10\" }\n\"markup.quote\" = { modifiers = [\"italic\"] }\n\n\"diff.plus\" = \"g_6\"\n\"diff.minus\" = \"red_ember\"\n\"diff.delta\" = \"brown\"\n\n# User Interface\n# --------------\n\"ui.background\" = { fg = \"text\", bg = \"background\" }\n\n\"ui.linenr\" = { fg = \"g_8\" }\n\"ui.linenr.selected\" = { fg = \"g_6\" }\n\n\"ui.statusline\" = { fg = \"g_3\", bg = \"g_9\" }\n\"ui.statusline.inactive\" = { fg = \"g_5\", bg = \"g_10\" }\n\"ui.statusline.normal\" = { fg = \"background\", bg = \"orange_blaze\", modifiers = [\n  \"bold\",\n] }\n\"ui.statusline.insert\" = { fg = \"g_1\", bg = \"g_7\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"background\", bg = \"orange_golden\", modifiers = [\n  \"bold\",\n] }\n\n\"ui.popup\" = { fg = \"text\", bg = \"g_10\" }\n\"ui.info\" = { fg = \"orange_blaze\", bg = \"g_10\" }\n\"ui.window\" = { fg = \"g_7\" }\n\"ui.help\" = { fg = \"text\", bg = \"g_10\", modifiers = [\"bold\"] }\n\n\"ui.bufferline\" = { fg = \"text\", bg = \"background\" }\n\"ui.bufferline.active\" = { fg = \"g_2\", bg = \"g_10\", underline = { color = \"orange_blaze\", style = \"line\" } }\n\"ui.bufferline.background\" = { bg = \"background\" }\n\n\"ui.text\" = \"text\"\n\"ui.text.focus\" = { fg = \"g_2\", bg = \"g_10\", underline = { color = \"red_ember\", style = \"line\" }, modifiers = [\n  \"bold\",\n] }\n\"ui.text.inactive\" = { fg = \"g_7\" }\n\"ui.text.directory\" = { fg = \"red_ember\" }\n\n\"ui.virtual\" = \"g_5\"\n\"ui.virtual.ruler\" = { bg = \"cursorline\" }\n\"ui.virtual.whitespace\" = \"g_7\"\n\"ui.virtual.indent-guide\" = \"g_7\"\n\"ui.virtual.wrap\" = \"g_7\"\n\"ui.virtual.inlay-hint\" = { fg = \"g_6\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"background\", bg = \"orange_blaze\", modifiers = [\n  \"bold\",\n] }\n\n\"ui.selection\" = { bg = \"brown_dark\" }\n\n\"ui.cursor.normal\" = { fg = \"background\", bg = \"orange_muted\" }\n\"ui.cursor.insert\" = { fg = \"background\", bg = \"g_7\" }\n\"ui.cursor.select\" = { fg = \"background\", bg = \"golden_muted\" }\n\"ui.cursor.primary.normal\" = { fg = \"background\", bg = \"orange_blaze\", modifiers = [\n  \"bold\",\n] }\n\"ui.cursor.primary.insert\" = { fg = \"background\", bg = \"g_3\", modifiers = [\n  \"bold\",\n] }\n\"ui.cursor.primary.select\" = { fg = \"background\", bg = \"orange_golden\", modifiers = [\n  \"bold\",\n] }\n\"ui.cursor.match\" = { fg = \"orange_smolder\", modifiers = [\"underlined\"] }\n\n\"ui.cursorline.primary\" = { bg = \"cursorline\" }\n\"ui.cursorline\" = { bg = \"g_12\" }\n\n\"ui.highlight\" = { fg = \"orange_blaze\", bg = \"cursorline\", underline = { color = \"red_ember\", style = \"line\" }, modifiers = [\n  \"bold\",\n] }\n\n\"ui.menu\" = { fg = \"g_2\", bg = \"g_10\" }\n\"ui.menu.selected\" = { fg = \"background\", bg = \"orange_blaze\", modifiers = [\n  \"bold\",\n] }\n\n\"diagnostic.error\" = { underline = { color = \"red_flame\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"orange_golden\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"g_4\", style = \"dotted\" } }\n\"diagnostic.hint\" = { underline = { color = \"g_5\", style = \"dotted\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\nerror = { fg = \"red_flame\", bg = \"g_10\" }\nwarning = { fg = \"orange_golden\", bg = \"g_10\" }\ninfo = { fg = \"g_2\", bg = \"g_10\" }\nhint = { fg = \"g_4\", bg = \"g_10\" }\n\n[palette]\ncursorline = \"#191919\"\ntext = \"#b4b4b4\"\nred_flame = \"#C53030\"\nred_glowing = \"#DF6464\"\nred_ember = \"#B14242\"\norange_glow = \"#D87C4A\"\norange_blaze = \"#C4693D\"\norange_muted = \"#6D3B22\"\norange_smolder = \"#E49A44\"\norange_golden = \"#E5A72A\"\ngolden_muted = \"#6D4D0D\"\nbrown = \"#89492a\"\nbrown_dark = \"#322119\"\nblue = \"#4A8B8B\"\nbackground = \"#121212\"\ng_1 = \"#e5e5e5\"\ng_2 = \"#d5d5d5\"\ng_3 = \"#b4b4b4\"\ng_4 = \"#a7a7a7\"\ng_5 = \"#949494\"\ng_6 = \"#737373\"\ng_7 = \"#535353\"\ng_8 = \"#323232\"\ng_9 = \"#212121\"\ng_10 = \"#1d1d1d\"\ng_11 = \"#191919\"\ng_12 = \"#151515\"\n"
  },
  {
    "path": "runtime/themes/ashokai.toml",
    "content": "# name = \"Ashokai\"\n# author = \"TeriyakiBomb\"\n# version = \"1.0.0\"\n\n# Syntax highlighting\n\"type\" = \"purple\"\n\"constant\" = \"magenta\"\n\"constant.numeric\" = \"purple\"\n\"constant.character.escape\" = \"orange\"\n\"string\" = \"orange\"\n\"string.regexp\" = \"blue\"\n\"comment\" = \"comment\"\n\"variable\" = \"fg0\"\n\"class\" = {fg =\"purple\", modifiers = [\"bold\"]}\n\"variable.builtin\" = \"blue\"\n\"variable.parameter\" = \"yellow\"\n\"variable.other.member\" = \"fg0\"\n\"label\" = \"purple\"\n\"punctuation\" = \"grey1\"\n\"punctuation.delimiter\" = \"lightblue\"\n\"punctuation.bracket\" = \"blue2\"\n\"keyword\" = \"blue\"\n\"keyword.directive\" = \"aqua\"\n\"operator\" = \"lightblue\"\n\"function\" = \"green\"\n\"function.builtin\" = \"blue\"\n\"function.macro\" = \"aqua\"\n\"function.method\" = \"magenta\"\n\"tag\" = \"magenta\"\n\"namespace\" = \"aqua\"\n\"attribute\" = \"green\"\n\"constructor\" = \"purple\"\n\"module\" = \"blue\"\n\"special\" = \"orange\"\n\"identifier\" = \"blue\"\n\n# Markup\n\"markup.heading.marker\" = \"grey1\"\n\"markup.heading.1\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"magenta\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"fg0\", modifiers = [\"bold\"] }\n\"markup.list\" = \"red\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link.url\" = { fg = \"blue\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"magenta\"\n\"markup.quote\" = \"grey1\"\n\"markup.raw\" = \"green\"\n\n# Diff\n\"diff.plus\" = \"diffgreen\"\n\"diff.delta\" = \"orange\"\n\"diff.minus\" = \"red\"\n\n# UI elements\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.background.separator\" = \"grey\"\n\n\"ui.cursor\" = { fg = \"bg0\", bg = \"cursor\" }\n\"ui.cursor.match\" = { fg = \"orange\", bg = \"selection\" }\n\"ui.cursor.insert\" = { fg = \"bg0\", bg = \"grey1\" }\n\"ui.cursor.select\" = { fg = \"bg0\", bg = \"blue\" }\n\"ui.cursor.primary\" = {fg = \"bg0\", bg =\"fg0\"}\n\"ui.cursor.primary.normal\" = {fg = \"bg0\", bg =\"fg0\"}\n\"ui.cursorline.primary\" = { bg = \"cursorline\" }\n\"ui.cursorline.secondary\" = { bg = \"cursorline\" }\n\n\"ui.selection\" = { bg = \"selection\" }\n\"ui.selection.primary\" = { bg = \"selection\" }\n\n\"ui.linenr\" = \"line_number\"\n\"ui.linenr.selected\" = \"line_number_selected\"\n\"ui.statusline\" = { fg = \"fg0\", bg = \"bg3\" }\n\"ui.statusline.inactive\" = { fg = \"grey\", bg = \"bg0\" }\n\"ui.statusline.normal\" = { fg = \"bg0\", bg = \"fg0\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"bg0\", bg = \"green\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"bg0\", bg = \"pink\", modifiers = [\"bold\"] }\n\"ui.bufferline\" = { fg = \"grey\", bg = \"bg1\" }\n\"ui.bufferline.active\" = { fg = \"fg0\", bg = \"bg3\", modifiers = [\"bold\"] }\n\"ui.popup\" = { fg = \"helptext\", bg = \"bg3\" }\n\"ui.window\" = { fg = \"grey\", bg = \"bg0\" }\n\"ui.help\" = { fg = \"helptext\", bg = \"helpbg\" }\n\"ui.text\" = \"fg0\"\n\"ui.text.focus\" = \"fg0\"\n\"ui.menu\" = { fg = \"fg0\", bg = \"bg3\" }\n\"ui.menu.selected\" = { fg = \"bg0\", bg = \"blue\", modifiers = [\"bold\"] }\n\"ui.virtual.whitespace\" = { fg = \"bg3\" }\n\"ui.virtual.indent-guide\" = { fg = \"bg3\" }\n\"ui.virtual.ruler\" = { bg = \"bg3\" }\n\n# Diagnostics\n\"hint\" = \"blue\"\n\"info\" = \"aqua\"\n\"warning\" = \"yellow\"\n\"error\" = \"red\"\n\"diagnostic\" = { underline = { style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue\", style = \"dotted\" } }\n\"diagnostic.info\" = { underline = { color = \"aqua\", style = \"dotted\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n[palette]\nbg0 = \"#191D24\"\nbg1 = \"#0F141C\"\nbg2 = \"#2C4A7A\"\nbg3 = \"#2A3A54\"\nfg0 = \"#FEFEFF\"\nhelptext = \"#8599B9\"\nhelpbg = \"#2A3A54\"\ngrey = \"#70697D\"\ngrey1 = \"#667E99\"\nred = \"#FF5D5D\"\nyellow = \"#FDC153\"\ngreen = \"#64FF85\"\nblue = \"#7AC3FF\"\nblue2 = \"#6C849D\"\nlightblue = \"#B0DDD2\"\naqua = \"#5DB1B1\"\norange = \"#FF9647\"\npurple = \"#9983D7\"\nmagenta = \"#FF1E6D\"\npink = \"#E06798\"\n\ndiffgreen = \"#5B7753\"\n\nline_number = \"#374B6B\"\nline_number_selected = \"#8397B8\"\ncomment =  \"#4E6A97\"\n\ncursor = \"#6F757F\"\ncursorline = \"#1B232E\"\nselection = \"#1B232E\"\n"
  },
  {
    "path": "runtime/themes/ashokai_brahn.toml",
    "content": "# name = \"Ashokai Brahn\"\n# author = \"TeriyakiBomb\"\n# version = \"1.0.0\"\n\ninherits = \"ashokai\"\n\n[palette]\nbg0 = \"#2A211D\"\nbg1 = \"#3A2C27\"\nbg2 = \"#49385D\"\nbg3 = \"#4F3D35\"\nfg0 = \"#EEE3DC\"\nhelptext = \"#976E5E\"\nhelpbg = \"#24150F\"\ngrey = \"#70697D\"\ngrey1 = \"#667E99\"\nred = \"#FF5D5D\"\nyellow = \"#FBC664\"\ngreen = \"#43BB71\"\nblue = \"#7AC3FF\"\nblue2 = \"#9D7D6C\"\nlightblue = \"#EEE3DC\"\naqua = \"#5DB1B1\"\norange = \"#FF9647\"\npurple = \"#B57CED\"\nmagenta = \"#F94786\"\npink = \"#EA7AD5\"\n\ndiffgreen = \"#5B7753\"\n\nline_number = \"#574941\"\nline_number_selected = \"#7B665B\"\ncomment = \"#6F5D53\"\n\ncursor = \"#5E8F81\"\ncursorline = \"#30241C\"\nselection = \"#442E21\"\n"
  },
  {
    "path": "runtime/themes/ashokai_evermoor.toml",
    "content": "# name = \"Ashokai Evermoor\"\n# author = \"TeriyakiBomb\"\n# version = \"1.0.0\"\n\ninherits = \"ashokai\"\n\n[palette]\nbg0 = \"#1D2A26\"\nbg1 = \"#14332A\"\nbg2 = \"#49385D\"\nbg3 = \"#3F6457\"\nfg0 = \"#F8FFF8\"\nhelptext = \"#5E9785\"\nhelpbg = \"#0F241E\"\ngrey = \"#70697D\"\ngrey1 = \"#667E99\"\nred = \"#FF5D5D\"\nyellow = \"#FBC664\"\ngreen = \"#7AEA92\"\nblue = \"#7AC3FF\"\nblue2 = \"#4E6A97\"\nlightblue = \"#B0DDD2\"\naqua = \"#5DB1B1\"\norange = \"#FF9647\"\npurple = \"#9983D7\"\nmagenta = \"#F94786\"\npink = \"#F9518C\"\n\ndiffgreen = \"#5B7753\"\n\nline_number = \"#32403B\"\nline_number_selected = \"#5E8F81\"\ncomment = \"#6C9286\"\n\ncursor = \"#5E8F81\"\ncursorline = \"#1E302A\"\nselection = \"#214037\"\n"
  },
  {
    "path": "runtime/themes/ashokai_urple.toml",
    "content": "# name = \"Ashokai Urple\"\n# author = \"TeriyakiBomb\"\n# version = \"1.0.0\"\n\ninherits = \"ashokai\"\n\n[palette]\nbg0 = \"#211D2A\"\nbg1 = \"#322750\"\nbg2 = \"#49385D\"\nbg3 = \"#4B3E64\"\nfg0 = \"#EFEAFF\"\nhelptext = \"#9485b9\"\nhelpbg = \"#130F1C\"\ngrey = \"#70697D\"\ngrey1 = \"#667E99\"\nred = \"#FF5D5D\"\nyellow = \"#FBC664\"\ngreen = \"#7AEA92\"\nblue = \"#7AC3FF\"\nblue2 = \"#4E6A97\"\nlightblue = \"#B0DDD2\"\naqua = \"#5DB1B1\"\norange = \"#FF9647\"\npurple = \"#9983D7\"\nmagenta = \"#F94786\"\npink = \"#E06798\"\n\ndiffgreen = \"#5B7753\"\n\nline_number = \"#5D5E72\"\nline_number_selected = \"#7262A6\"\ncomment = \"#565775\"\n\ncursor = \"#746F7F\"\ncursorline = \"#2B2437\"\nselection = \"#493A77\"\n"
  },
  {
    "path": "runtime/themes/ataraxia.toml",
    "content": "# ataraxia theme for Helix (｡•̀ᴗ-)✧☆*:・ﾟ\n\n# Author : mazrine <mazrine@protonmail.com>\n# -------------------\n# purple and violet centered with contrasting cyan and green plus some blue shades in the mix, making a mostly cold palette.\n# -------------------\n# if you wanna see my full config, check out https://github.com/Mazrine/helix-configuration it has kaomojis for modes instead of the usual normal / insert etc\n# -------------------\n\n# GENERAL ==============================\n\nwarning = \"soft-blue\"\nerror = \"electric-violet\"\ninfo = \"sky-cyan\"\nhint = \"neon-cyan\"\ndiagnostic = \"cool-sky\"\n\n \n\"diagnostic.error\" = \"electric-violet\"\n\"diagnostic.warning\" = \"soft-blue\"\n\"diagnostic.info\" = \"sky-cyan\"\n\"diagnostic.hint\" = \"neon-cyan\"\n\n \n# UI ==============================\n\n\"ui.background\" = { fg = \"orchid\", bg = \"midnight\" }\n\"ui.help\" = {fg = \"neon-cyan\", bg = \"midnight\"}\n\"ui.text\" = {fg = \"neon-cyan\", bg = \"midnight\"}\n\"ui.window\" = \"orchid\"\n\"ui.cursor\" = { fg = \"#000000\", bg = \"neon-cyan\" }\n\"ui.cursor.primary\" = { fg = \"#000000\", bg = \"electric-violet\" }\n\"ui.cursor.primary.normal\" = { fg = \"#000000\", bg = \"neon-cyan\" }\n\"ui.cursor.primary.insert\" = { fg = \"#000000\", bg = \"ufo-green\" }\n\"ui.cursor.primary.select\" = { fg = \"#000000\", bg = \"muted-violet\" }\n\"ui.cursor.match\" = \"orchid\"\n\"ui.popup\" = {fg = \"neon-cyan\", bg = \"midnight\"}\n\"ui.selection\" = { fg = \"#000000\", bg = \"muted-violet\" }\n\"ui.selection.primary\" = { fg = \"#000000\", bg = \"muted-violet\" }\n\"ui.virtual\" = \"eggplant\"\n\"ui.virtual.whitespace\" = \"deep-indigo\"\n\"ui.linenr\" = \"purple-gray\"\n\"ui.linenr.selected\" = \"neon-cyan\"\n\"ui.statusline\" = \"sky-cyan\"\n\"ui.statusline.inactive\" = \"orchid\"\n\"ui.statusline.normal\" = \"neon-cyan\"\n\"ui.statusline.insert\" = \"ufo-green\"\n\"ui.statusline.select\" = \"muted-violet\"\n\"ui.statusline.separator\" = \"neon-cyan\"\n\"ui.bufferline\" = { fg = \"orchid\", bg = \"midnight\"}\n\"ui.bufferline.active\" = { fg = \"neon-cyan\", bg = \"midnight\"}\n\"ui.menu\" = \"orchid\"\n\"ui.menu.selected\" = \"orchid\"\n\n# SYNTAX HIGHLIGHTING  ==============================\n\n\"comment\" = \"purple-gray\"\n\"comment.line\" = \"purple-gray\"\n\"comment.line.documentation\" = \"purple-gray\"\n\"comment.block\" = \"dead-green\"\n\"comment.block.documentation\" = \"dead-green\"\n\n\"constant\" = \"soft-blue\"\n\"constant.builtin\" = \"royal-blue\"\n\"constant.builtin.boolean\" = \"ufo-green\"\n\"constant.character\" = \"royal-blue\"\n\"constant.character.escape\" = \"royal-blue\"\n\"constant.numeric\"  = \"cool-sky\"\n\"constant.numeric.integer\" = \"cool-sky\"\n\"constant.numeric.float\" = \"cool-sky\"\n\n\"string\" = \"ufo-green\" \n\"string.regexp\" = \"orchid\"\n\"string.special\" = \"orchid\"\n\"string.special.path\" = \"orchid\"\n\"string.special.url\" = \"orchid\"\n\"string.special.symbol\" = \"orchid\"\n\n\"constructor\" = \"royal-blue\"\n\n\"variable\" = \"deep-grape\"\n\"variable.builtin\" = \"neon-cyan\"\n\"variable.parameter\" = \"neon-cyan\" \n\"variable.other.member\" = \"orchid\"\n\n\"function\" = \"royal-blue\"\n\"function.builtin\" = \"royal-blue\"\n\"function.method\" = \"royal-blue\"\n\"function.macro\" = \"ufo-green\"\n\"function.special\" = \"royal-blue\"\n\n\"punctuation.special\" = \"neon-cyan\"\n\"punctuation.delimiter\" = \"neon-cyan\"\n\"punctuation.bracket\" = \"neon-cyan\"\n\n\"keyword\" = \"royal-blue\"\n\"keyword.control\" = \"orchid\"\n\"keyword.control.conditional\" = \"deep-grape\"\n\"keyword.control.repeat\" = \"deep-grape\"\n\"keyword.control.import\" = \"royal-blue\"\n\"keyword.control.return\" = \"deep-grape\"\n\"keyword.control.exception\" = \"orchid\"\n\"keyword.operator\" = \"royal-blue\"\n\"keyword.directive\" = \"royal-blue\"\n\"keyword.storage\" = \"orchid\"\n\"keyword.function\" = \"orchid\"\n\n\"operator\" = \"amethyst\"\n\"type\" = \"soft-blue\"\n\"type.builtin\" = \"plum\"\n\"type.parameter\" = \"orchid\"\n\"type.enum\" = \"soft-blue\"\n\"type.enum.variant\" = \"royal-blue\"\n\"attribute\" = \"deep-grape\"\n\"namespace\" = \"muted-violet\"\n\"special\" = \"cool-sky\"\n\"tag\" = \"neon-cyan\"\n\"tag.error\" = \"bad\"\n\n# Markup  ==============================\n\n\"markup.heading.1\" = \"deep-grape\"\n\"markup.heading.2\" = \"muted-violet\"\n\"markup.heading.3\" = \"orchid\"\n\"markup.heading.4\" = \"amethyst\"\n\"markup.heading.5\" = \"soft-blue\"\n\"markup.heading.6\" = \"cool-sky\"\n\"markup.heading.marker\" = \"ufo-green\"\n\"markup.list\" = \"ufo-green\"\n\"markup.list.checked\" = \"ufo-green\"\n\"markup.list.unchecked\" = \"deep-indigo\"\n\"markup.bold\" = \"soft-blue\"\n\"markup.italic\" = \"cool-sky\"\n\"markup.strikethrough\" = \"deep-indigo\"\n\"markup.link.url\" = \"sky-cyan\"\n\"markup.link.text\" = \"orchid\"\n\"markup.quote\" = \"muted-violet\"\n\"markup.raw\" = \"eggplant\"\n\n\n# Diff ==============================\n\n\"diff.plus\" = \"ufo-green\"\n\"diff.minus\" = \"bad\"\n\"diff.delta\" = \"soft-blue\"\n \n\n[palette]\nmidnight = \"#1c0c28\"\neggplant = \"#301b4d\"\ndeep-indigo = \"#432775\"\npurple-gray = \"#5c3a9e\"\nmuted-violet = \"#7b52c7\"\nneon-cyan = \"#00D2F7\"\ncool-sky = \"#7a88ff\"\norchid = \"#8f45ff\"\nsoft-blue = \"#8AA3FE\"\nplum = \"#6d4db8\"\nufo-green = \"#00D974\"\ndead-green = \"#025c33\"\nsky-cyan = \"#00ddff\"\nroyal-blue = \"#4264d9\"\nelectric-violet = \"#A600FF\"\namethyst = \"#9963ff\"\ndeep-grape = \"#7640cc\"\nbad = \"#EB3E5E\"\n"
  },
  {
    "path": "runtime/themes/aura-dark-soft.toml",
    "content": "# aura ported by:\n# Author: elainabialkowski\n\n# aura originally by:\n# Author: Dalton Menezes\n# License: MIT\n\n\"ui.background\" = { fg = \"white\", bg = \"black\"}\n\n\"ui.linenr\" = { fg = \"accent17\"}\n\"ui.linenr.selected\" = { bg = \"accent33\", modifiers = [\"bold\"]}\n\n\"ui.statusline\" = { fg = \"accent10\", bg = \"accent24\"}\n\n\"ui.selection\" = { bg = \"purple_selection\"}\n\"ui.selection.background\" = { fg = \"purple_selection\"}\n\n\"ui.cursor\" = { fg = \"black\", bg = \"pink\" }\n\"ui.cursor.match\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\n\"ui.text\" = { fg = \"white\"}\n\"ui.text.focus\" = { fg = \"white\", bg = \"purple_selection_solid\"  }\n\"ui.text.inactive\" = { fg = \"gray\" }\n\n\"ui.virtual.indent-guide\" = \"accent13\"\n\"ui.virtual.ruler\" = { bg = \"accent13\" }\n\"ui.virtual.whitespace\" = { fg = \"accent13\" }\n\"ui.virtual.inlay-hint\" = { fg = \"accent9\", bg = \"accent33\" }\n\"ui.virtual.jump-label\" = { fg = \"pink\" , modifiers = [\"bold\"] }\n\n\"ui.highlight\" = { bg = \"accent33\", modifiers = [\"bold\"] }\n\n\"ui.menu\" = { fg = \"accent9\", bg = \"accent24\"}\n\"ui.menu.selected\" = { fg = \"purple\", bg = \"accent33\"}\n\n\"ui.popup\" = { fg = \"accent9\", bg = \"accent24\"}\n\n\"ui.window\" = { fg = \"green\" }\n\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"orange\" , style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\" , style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue\" , style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nerror = \"red\"\nwarning = \"orange\" \ninfo = \"blue\" \nhint = \"blue\" \n\nattributes = \"purple\"\ntype = \"blue\" \n\nconstructor = \"blue\" \n\nconstant = \"green\" \nstring = \"green\" \n\ncomment = {fg = \"gray\" }\n\nvariable = \"white\" # should be dimmed\n\"variable.builtin\" = \"purple\"\n\"variable.other\" = \"pink\" \n\n\"punctuation.delimeter\" = \"pink\" \n\"punctuation.special\" = \"white\"\n\nkeyword = \"purple\"\noperator = \"purple\"\n\nfunction = \"orange\"\ntag = \"purple\"\n\nmarkup = \"purple\"\n\"markup.heading\" = \"orange\" \n\"markup.quote\" = \"gray\"\n\"markup.list\" = \"purple\"\n\"markup.link.url\" = { fg = \"green\" , modifiers = [\"underlined\"]}\n\n\"diff.plus\" = \"green\" \n\"diff.delta\" = \"orange\" \n\"diff.minus\" = \"red\"\n\n[palette]\n# dark soft/dim\npurple = \"#8464c6\" # 132,100,198\taccent1\tprimary color\t\npurple_selection = \"#3d375e\" # 61,55,94\taccent20\tselections\t\npurple_selection_solid = \"#29263c\" # 41,38,60\taccent38\tselections (without alpha)\t\ngreen = \"#54c59f\" # 84,197,159\taccent2\tsecondary color\t\norange = \"#c7a06f\" # 199,160,111\taccent3\ttertiary color\t\npink = \"#c17ac8\" # 193,122,200\taccent6\tquaternary color\t\nblue = \"#6cb2c7\" # 108,178,199\taccent32\tquinary color\t\nred = \"#c55858\" # 197,88,88\taccent5\tsenary color\t\nwhite = \"#bdbdbd\" # 189,189,189\taccent7\tforegrounds\ngray = \"#6d6d6d\" # 109,109,109\taccent8\tcomments\t\nblack = \"#15141b\" # 21,20,27\taccent12\tbackgrounds\n\n\n# https://github.com/daltonmenezes/aura-theme/blob/main/src/core/colors/schemes/common.ts\n# commonColors = {\n# accent0 = \"#0f0f0f\" # black\n# ...\n# accent4 = \"#9dff65\" # bright green\n# ...\n# accent31 = \"#ffca85\" # bright orange\n# accent32 = \"#82e2ff\" # light blue!!\n# accent33 = \"#24222c\" # black\n# accent34 = \"#000000\" # fully transparent,\n# accent35 = \"#525156\" # activity bar inactive foreground,\n# # }\n\n# export const commonUI = {\naccent9 = \"#cdccce\" # black\naccent10 = \"#adacae\" # light grey\naccent13 = \"#2d2d2d\" # black\n# accent14 = \"#af8aff\" # light purple\n# accent15 = \"#4d4d4d\"\n# accent16 = \"#ffffff\"\naccent17 = \"#a394f0\" # secondary-selection\n# accent18 = \"#a394f0\" # light purple\n# accent19 = \"#3ea784\"\n# accent20 = \"#3d375e\" # primary-selection\n# accent22 = \"#4d466e\"\n# accent23 = \"#3b334b\"\n# accent25 = \"#49c29a\"\n# accent26 = \"#00d890\"\n# accent27 = \"#ff4747\"\n# accent28 = \"#121016\"\n# accent29 = \"#000000\"\n# accent30 = \"#2d2b38\"\naccent33 = \"#2e2b38\"\n# accent36 = \"#a19c77\" # debugging background\n# accent37 = \"#353424\" # breakpoint frame highlight\n# accent38 = \"#29263c\" # primary-selection without alpha\n# accent39 = \"#211D26\"\n# }c',\n# accent34 = \"#000000\" # fully transparent,\n# accent35 = \"#525156\" # activity bar inactive foreground,\n# }\n\n# https://github.com/daltonmenezes/aura-theme/tree/c607be79c8eeaa5a5d7ac66421f8b5c51d936fe8/src/core/colors/schemes\naccent24 = \"#1f1a27\" # soft dark\n\n\n"
  },
  {
    "path": "runtime/themes/aura-dark.toml",
    "content": "# aura ported by:\n# Author: elainabialkowski\n\n# aura originally by:\n# Author: Dalton Menezes\n# License: MIT\n\n\"ui.background\" = { fg = \"white\", bg = \"black\"}\n\n\"ui.linenr\" = { fg = \"accent17\"}\n\"ui.linenr.selected\" = { bg = \"accent33\", modifiers = [\"bold\"]}\n\n\"ui.statusline\" = { fg = \"accent10\", bg = \"accent24\"}\n\n\"ui.selection\" = { bg = \"purple_selection\"}\n\"ui.selection.background\" = { fg = \"purple_selection\"}\n\n\"ui.cursor\" = { fg = \"black\", bg = \"pink\" }\n\"ui.cursor.match\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\n\"ui.text\" = { fg = \"white\"}\n\"ui.text.focus\" = { fg = \"white\", bg = \"purple_selection_solid\"  }\n\"ui.text.inactive\" = { fg = \"gray\" }\n\n\"ui.virtual.indent-guide\" = \"accent13\"\n\"ui.virtual.ruler\" = { bg = \"accent13\" }\n\"ui.virtual.whitespace\" = { fg = \"accent13\" }\n\"ui.virtual.inlay-hint\" = { fg = \"accent9\", bg = \"accent33\" }\n\"ui.virtual.jump-label\" = { fg = \"pink\" , modifiers = [\"bold\"] }\n\n\"ui.highlight\" = { bg = \"accent33\", modifiers = [\"bold\"] }\n\n\"ui.menu\" = { fg = \"accent9\", bg = \"accent24\"}\n\"ui.menu.selected\" = { fg = \"purple\", bg = \"accent33\"}\n\n\"ui.popup\" = { fg = \"accent9\", bg = \"accent24\"}\n\n\"ui.window\" = { fg = \"green\" }\n\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"orange\" , style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\" , style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue\" , style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nerror = \"red\"\nwarning = \"orange\" \ninfo = \"blue\" \nhint = \"blue\" \n\nattributes = \"purple\"\ntype = \"blue\" \n\nconstructor = \"blue\" \n\nconstant = \"green\" \nstring = \"green\" \n\ncomment = {fg = \"gray\" }\n\nvariable = \"white\" # should be dimmed\n\"variable.builtin\" = \"purple\"\n\"variable.other\" = \"pink\" \n\n\"punctuation.delimeter\" = \"pink\" \n\"punctuation.special\" = \"white\"\n\nkeyword = \"purple\"\noperator = \"purple\"\n\nfunction = \"orange\"\ntag = \"purple\"\n\nmarkup = \"purple\"\n\"markup.heading\" = \"orange\" \n\"markup.quote\" = \"gray\"\n\"markup.list\" = \"purple\"\n\"markup.link.url\" = { fg = \"green\" , modifiers = [\"underlined\"]}\n\n\"diff.plus\" = \"green\" \n\"diff.delta\" = \"orange\" \n\"diff.minus\" = \"red\"\n\n[palette]\n# dark\npurple\t= \"#a277ff\" #\t162,119,255\taccent1\tPrimary color\npurple_selection = \"#3d375e\" #\t61,55,94\taccent20\tSelections\npurple_selection_solid\t= \"#29263c\" #\t41,38,60\taccent38\tSelections (without alpha)\ngreen\t= \"#61ffca\" #\t97,255,202\taccent2\tSecondary color\norange\t= \"#ffca85\" #\t255,202,133\taccent3\tTertiary color\npink\t= \"#f694ff\" #\t246,148,255\taccent6\tQuaternary color\nblue\t= \"#82e2ff\" #\t130,226,255\taccent32\tQuinary color\nred\t= \"#ff6767\"\t# 255,103,103\taccent5\tSenary color\nwhite\t= \"#edecee\" #\t237,236,238\taccent7\tForegrounds\ngray\t= \"#6d6d6d\" #\t109,109,109\taccent8\tComments\nblack\t= \"#15141b\" #\t21,20,27\taccent12\tBackgrounds\n\n\n# https://github.com/daltonmenezes/aura-theme/blob/main/src/core/colors/schemes/common.ts\n# commonColors = {\n# accent0 = \"#0f0f0f\" # black\n# ...\n# accent4 = \"#9dff65\" # bright green\n# ...\n# accent32 = \"#82e2ff\" # light blue!!\n# accent33 = \"#24222c\" # black\n# accent34 = \"#000000\" # fully transparent,\n# accent35 = \"#525156\" # activity bar inactive foreground,\n# # }\n\n# export const commonUI = {\naccent9 = \"#cdccce\" # black\naccent10 = \"#adacae\" # light grey\naccent13 = \"#2d2d2d\" # black\n# accent14 = \"#af8aff\" # light purple\n# accent15 = \"#4d4d4d\"\n# accent16 = \"#ffffff\"\naccent17 = \"#a394f0\" # secondary-selection\n# accent18 = \"#a394f0\" # light purple\n# accent19 = \"#3ea784\"\n# accent20 = \"#3d375e\" # primary-selection\n# accent22 = \"#4d466e\"\n# accent23 = \"#3b334b\"\n# accent25 = \"#49c29a\"\n# accent26 = \"#00d890\"\n# accent27 = \"#ff4747\"\n# accent28 = \"#121016\"\n# accent29 = \"#000000\"\n# accent30 = \"#2d2b38\"\naccent33 = \"#2e2b38\"\n# accent36 = \"#a19c77\" # debugging background\n# accent37 = \"#353424\" # breakpoint frame highlight\n# accent38 = \"#29263c\" # primary-selection without alpha\n# accent39 = \"#211D26\"\n# }c',\n# accent34 = \"#000000\" # fully transparent,\n# accent35 = \"#525156\" # activity bar inactive foreground,\n# }\n\n# https://github.com/daltonmenezes/aura-theme/tree/c607be79c8eeaa5a5d7ac66421f8b5c51d936fe8/src/core/colors/schemes\naccent24 = \"#1f1a27\" # soft dark\n\n"
  },
  {
    "path": "runtime/themes/aurara.toml",
    "content": "# aurara\n# a messy mix of aura (dark, soft), noctis, and liberal use of helix's text styling\n# Author : rahil/rathewolf <rahil627@berkeley.edu>\n\n# aura ported by:\n# Author: elainabialkowski\n\n# aura originally by:\n# Author: Dalton Menezes\n# License: MIT\n\n# noctis ported by:\n# Author: 0rphee\n# who used this template: https://github.com/n0s4/helix-theme-template\n\n# noctis originally by:\n# Author: Liviu Schera and contributors\n# License: MIT\n\n\n# design\n# mostly from natural convergences\n# \"soft\"/\"dim\"/low-brightness colors\n  # this should've been done on the app/terminal level.. however, since i've already used mostly low-brightness colors, perhaps there can be special cases to use brighter colors, to make certain things stand out... anyway, now can make use of both palettes: dim and bright\n# simple color scheme: purple as main text color (plain text, ui, possibly strings and/or comments), a secondary color (popups, punctuation or operators, variable.other?), tertiary color (functions)\n\n# the mains things you read should stick out, while the rest shouldn't\n# a common line:\n# modifier type-declaration variable operator type.function(\"string\")\n# most visible: variable operator function type\n# clearly visible: operator, punctuation\n# less visible: type-declaration\n# least visible: modifiers\n\n# TODO:\n# should just inherit the original aura theme\n# try purple for comments and something else for strings?\n# maybe add a fallback for every table..?\n# not happy with aura's orange, it's just too dim.. boring! is noctis's orange really that bright..?\n# still not happy about aura's blue-green used for namespace, especially for rust.. desaturating didn't quite do it..\n# can try another color/shade for atoms..? although, it's not too bad..\n# could try other colors for either operators or punctuation..\n# currently trying a dimmer shade of pink for variable.other.member, but there's too many keywords categorized in there..\n  # create a white-stone with a tinge of color for variable.other..?\n# never found out why the derive macro is a bolded bright orange color..\n# find out where the color for file picker is set, and try to dim it\n  # i tried searching the other configs in the repo to no avail, just found ui.picker.header\n# oranger-brighter used for functions is slightly too bright, get a darker shade (using orange for now..)\n# find a different color for built-in types, currently using aura's default green-sea\n\n# NOTE:\n# blinking doesn't work with italics, another reason to not italicize comments\n# see keys here:\n  # https://github.com/helix-editor/helix/blob/master/book/src/themes.md#scopes\n# can fetch syntax highlighting tests from here:\n  # https://github.com/sharkdp/bat\n\n\n## GENERAL ==============================\n\n# the diagnostic info in the gutter area\n'warning' = { fg =\"orange-bright\", modifiers = [\"bold\"] } # Editor warnings. TEMP/TEST/WARN\n'error' = { fg = \"red-error\", modifiers = [\"bold\", \"slow_blink\"] } # Editor errors, like mis-typing a command. BUG ISSUE\n  # but not ERROR..?\n'info' = { fg = \"blue-aqua\" } # Code diagnostic info in gutter (LSP). TODO/INFO\n  # def prefer noctis's blue-aqua over aura's here\n'hint' = { fg = \"green-aqua\", modifiers = [\"bold\"] } # Code diagnostics hint in gutter (LSP).\n  # ? Difference between info and hint ?\n\n# diagnostic info in the main text-editing area\n'diagnostic' = { underline = { style = \"line\" } } # Code diagnostics in editing area (LSP).\n'diagnostic.error' = { underline = { style = \"curl\", color = \"red-error\" }, modifiers = [\"bold\", \"dim\", \"slow_blink\"] }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"orange\" }, modifiers = [\"bold\", \"dim\" ] }\n'diagnostic.info' = { underline = { style = \"dashed\", color = \"blue-aqua\" }, modifiers = [\"bold\", \"dim\" ] }\n'diagnostic.hint' = { underline = { style = \"dashed\", color = \"green-aqua\" }, modifiers = [\"bold\", \"dim\" ] }\n  # TODO: TEST: diagnostics, might need a new set of colors..! can use all neon colors here!! definitely need to test all this blinking.. LOL\n  # underline styles: line, curl, dashed, dotted, double_line\n'diagnostic.unnecessary' = { modifiers = [\"dim\"] } # took this from default theme\n'diagnostic.deprecated' = { modifiers = [\"crossed_out\"] } # took this from default theme\n\n# UI ==============================\n# For styling helix itself.\n\n# 'ui' = { bg = 'bg-ui' }\n  # doesn't work.. :/\n'ui.background' = { fg = \"purple-pleasant-dimmer\", bg = \"bg\"} # Default background color., the fg seems to be used for borders..\n  # NOTE:this effects the main background of the text-editing area; it's values don't cascade down to popup/auto-complete/etc; you must override them in each key\n'ui.background.separator' = { fg = \"gray-stone\" } # below the input line in picker\n'ui.window' = { fg = \"gray-stone\" } # Window border between splits.\n  # pruple also works really well here.. maybe more needed when there are no line numbers..\n\n'ui.gutter' = { fg = \"gold\" } # Left gutter for diagnostics and breakpoints.\n  # background affects the entire background of the gutter!\n  # breakpoints are kinda hard to see, only the outline..?\n# 'ui.gutter.selected' = { bg = \"selection-ui\" }\n# 'ui.debug.breakpoint' = \"●\" # character for breakpoint? nope, that's not it..\n'ui.debug.active' = { fg = \"pink-dimmer\" } # debug execution paused, gutter?\n'ui.highlight.frameline' = { bg = \"selection-ui\" } # debug execution paused, line\n  # TODO: could use a tinted color here.. a little confusing as it uses the same background as selected text\n\n'ui.text' = { fg = \"purple-pleasant-dimmer\" } # Default text color. used in text files, pickers, ui, and more!\n'ui.text.focus' = { fg = \"pink\", bg = \"selection-ui\", modifiers = [\"bold\"] } # Selection highlight in buffer-picker or file-picker.\n'ui.text.info' = { fg = \"pink-dimmer\", bg = \"bg-ui\" } # Info popup contents (space mode menu).\n  # see ui.menu for auto-complete\n  # NOTE: pink pops out more, making it better than the comfy purple-pleasant-dimmer here\n'ui.text.inactive' = { fg = \"gray-stone-lighter\", modifiers = [\"dim\"] } # i think used in autocomplete suggestion..\n  # i might like this better than gray-purple\n\n'ui.cursor' = { fg = \"light-green-complement\", bg = \"light-green\", modifiers = [\"reversed\", \"bold\" ] } # Fallback cursor colour, non-primary cursors when there are multiple (shift-c).\n  # should be slightly darker than primary cursor..\n'ui.cursor.primary' = { fg = \"pink\", bg = \"light-green\", modifiers = [\"reversed\", \"bold\"] } # The primary cursor when there are multiple (shift-c).\n  # TODO: NOTE: this blinking at a different timing then the selection's blink is too much!! lol, but i do prefer it to blink..\n# 'ui.cursor.insert' =  { fg = \"pink\", bg = \"light-green\", modifiers = [\"reversed\", \"bold\"] } # The cursor in insert mode (i).\n# 'ui.cursor.select' = { fg = \"pink\", bg = \"light-green\", modifiers = [\"reversed\", \"bold\"] } # The cursor in select mode (v).\n'ui.cursor.match' = { fg = \"cyan\", bg = \"pink\", modifiers = [\"bold\", \"reversed\", \"slow_blink\"] } # The matching parentheses of that under the cursor.\n  # NOTE: changed from purple, which was a bit tough to see..; rapid_blink was just too annoying..; light-green was too much, trying cyan..\n\n'ui.selection' = { bg = \"selection-ui\", modifiers = [ \"bold\", \"slow_blink\" ] } # All currently selected text.\n  # TODO: decide purple-selection vs the neutral selection-ui: purple is easier to see immediately, but the neutral selection shows text more clearly / less muddy, and with the aid of blinking, it's pretty easy to see too\n  # TODO: ...wish there were a \"brighten\" modifier..\n# 'ui.selection.primary' = { bg = \"purple-selection\" } # The primary selection when there are multiple.\n# 'ui.cursorline.primary' = { bg = 'purple-selection' } #\n  # TODO: would need a very dim color, between selection-ui and background.. it could work of primary selection has a tinge of color to it (purple-selection), but without that, it would make it even harder to see the selection\n\n\n'ui.linenr' = { fg = \"purple-pleasant\", modifiers = [\"dim\"]} # Line numbers.\n'ui.linenr.selected' = { modifiers = [ \"bold\" ] } # Current line number.\n\n'ui.virtual' = { fg = \"gray-stone\" } # Namespace for additions to the editing area.\n'ui.virtual.ruler' = { bg = \"selection-ui\"} # Vertical rulers (colored columns in editing area).\n  # TODO: TEST: haven't seen these two yet..error\n# 'ui.virtual.whitespace' = { fg = \"gray-stone\"} # Whitespace markers in editing area: newline..\n# 'ui.virtual.wrap'\n# 'ui.virtual.jump-label'\n'ui.virtual.indent-guide' = { fg = \"marker13\" } # Indentation guides.\n\n'ui.virtual.inlay-hint' = { fg = \"purple-pleasant-dimmer\" } # TODO: TEST:\n# ui.virtual.inlay-hint.parameter\t\n# ui.virtual.inlay-hint.type\t\n\n# 'ui.bufferline' = { fg = \"purple-pleasant\", bg = \"bg-ui\", modifiers = [\"dim\"] }\n# 'ui.bufferline.active' = { underline = { style = \"line\" } }\n  # not so pretty.., and it extends past the text\n# 'ui.bufferline.inactive' = { fg = \"gray-purple\" } # BUG: doesn't work..\n  # or berry-desturated\n  # using ui.statusline as fallback instead:\n\n'ui.statusline' = { fg = \"purple-pleasant\", bg = \"bg-ui\", modifiers = [\"dim\"] } # Status line. and tab bar\n  # NOTE: matches line numbers\n# 'ui.statusline.separator' = '|' # not working..? don't think i'd need anyway, seems cleaner without it..\n  \n'ui.statusline.inactive' = { fg = \"gray-stone\", bg = \"bg-ui\", modifiers = [] } # Status line in unfocused windows.\n  # seems very dim.., likely inherited, but i don't know how to uninherit it.., i do prefer it to be different from the text used for comments though.. so it's not bad..\n\n\"ui.statusline.normal\" = { fg = \"purple-pleasant\" }\n\"ui.statusline.insert\" = { fg = \"pink-salmon\", modifiers = [] }\n  # matches return keyword\n\"ui.statusline.select\" = { fg = \"blue-aqua\", modifiers = [] }\n  # seems dark, even without dim.. not sure how inheritance works here..\n  # slow_blink on insert/select was too annoying..\n  # using a colored background was also too annoying\n\n'ui.help' = { fg = \"pink-dimmer\", bg = \"bg-ui\" } # `:command` descriptions above the command line.\n\n'ui.highlight' = { bg = \"selection-ui\", modifiers = [\"slow_blink\"] } # selected contents of symbol pickers (spc-s, spc-S) and current line in buffer picker (spc-b).\n  # bold doesn't seem to work here..\n\n'ui.menu' = { fg = \"purple-pleasant\", bg = \"bg-ui\", modifiers = [\"dim\"] } # Autocomplete menu.\n  # a dim color that doesn't pop up makes sense here\n  # BUG: the dim modifier conflicts with the matching gold for the first line only, maybe the parent key's dim affects the child key..?\n'ui.menu.selected' = { fg = \"gold\", bg = \"selection-ui\", modifiers = [\"bold\"] } # Selected autocomplete item.\n  # not a fan of slow_blink here..\n  # gold is fantastic for selected text and fuzzy matching\n# 'ui.menu.scroll'\n\n# 'ui.picker' = { fg = \"purple\" } # ope.. good guess..\n\"ui.picker.header\" = { modifiers = [\"bold\"] } # TODO: TEST: i found this in another config, no clue yet..\n\n'ui.popup' = { fg = \"purple-pleasant-dimmer\", bg = \"bg-ui\" } # Documentation popups (space-k).\n'ui.popup.info' = { fg = \"purple\", bg = \"bg-ui\" } # Info popups box (space mode menu). just the borders.\n  # gold is very pretty here.., but distracting.. purple creates a solid frame and feels out of the way..\n  # modifiers don't work here.. no shiny blinky stuff..; also dim doesn't work, so can't use purple-pleasant dimmed..\n# \"ui.menu.scroll\" = { }\n\n# SYNTAX HIGHLIGHTING ==============================\n# All the keys here are Treesitter scopes.\n\n'property' = { fg = \"green-aqua\" } # Regex group names.\n  # TODO: no clue.. never seen this.. just matching regex strings for now..\n'special' = { fg = \"orange-bright\", modifiers = [\"bold\"] } # Special symbols e.g `?` in Rust, `...` in Hare, also derive macro..??\n  # rust's ? is usually squashed between punctuation ()?;\n  # pink-hotter works well for punctuation. gold also works well for the derive macro. it's also nice for it to just stick out, so as to indicate a syntax highlighting problem\n'attribute' = { fg = \"purple\", modifiers = [\"italic\"] } # Class attributes, html tag attributes.\n  # italics makes sense for html tag attributes.. matching tag\n\n'type' = { fg = \"blue-aqua\" } # Variable type, like integer or string, including program defined classes, structs etc..\n  # NOTE: sometimes there's class / end, which looks odd not bolded like other control/end statements\n  # doesn't seperate declaration, parameters, instantiation (though there is constructor), so it's difficult to italicize\n'type.builtin' = { fg = \"green-sea\", modifiers = [\"italic\"] } # Primitive types of the language (string, int, float).\n'type.enum.variant' = { fg = \"green-sea\" } # A variant of an enum.\n  # vs match constant color\n  # NOTE: i think was pink in aura theme.. but i def didn't like that for the enum values TODO: maybe white is fine\n\n'constructor' = { fg = \"blue-aqua\" } # Constructor method for a class or struct. And in some cases applies to module names, as in ruby\n  # was blue-aqua in noctis, it's pink in vs-code's aura, along with static... TODO: maybe could try a new color here..\n  # ruby's class seems to use this.. maybe best to stick to using the same color as type.., but then __init__ uses this too..; also used upon constructor call! Ok(), Some() in rust\n\n'constant' = { fg = \"green-aqua\" } # Constant value\n  # originally green in aura... and it seems a pretty good use of this green, as i don't use it for strings anymore..\n  # NOTE: if this is too dark, can use cyan or light-green, as there aren't too many of these..\n# 'constant.builtin' = { fg = \"blue-aqua\" } # Special constants like `true`, `false`, `none`, etc.\n# 'constant.builtin.boolean' = { } # True or False.\n# 'constant.character' = { fg = \"blue-aqua\"} # Constant of character type.\n# 'constant.character.escape' = { fg = \"mid-green\", modifiers = [\"bold\"] } # escape codes like \\n.\n  # NOTE: matches regexp\n# 'constant.numeric'  = { fg = \"blue-green\", modifiers = [\"bold\"] } # constant integer or float value.\n# 'constant.numeric.integer' = { } # constant integer value.\n# 'constant.numeric.float' = { fg = \"green-aqua\" } # constant float value.\n\n'string' = { fg = \"purple-pleasant-dimmer\" } # String literal.\n  # changed to use main text color (purple!) TODO: can decrease alpha more if needed\n'string.regexp' = { fg = \"green-aqua\" } # Regular expression literal.\n  # NOTE: matches character escape\n'string.special' = { fg = \"purple-pleasant-dimmer\", modifiers = [\"italic\"] } # Strings containing a path, URL, etc.\n  # could use something funky 'n dark here..\n  # i hate long underlined text!, so def don't want that..\n  # TODO: TEST: italics\n# 'string.special.path' = { } # String containing a file path.\n# 'string.special.url' = { } # String containing a web URL.\n'string.special.symbol' = { fg = \"berry-desaturated\" } # Erlang/Elixir atoms, Ruby symbols, Clojure keywords.\n  # secondary text (pink) collides with punctuation :/, so now pink is used for variable.other\n  # perhaps it could be similar to the color used for constant/literals.. a kind of green..?\n\n'comment' = { fg = \"gray-stone-lighter\", modifiers = [\"dim\"] } # This is a comment.\n  # TODO: dim and italics should be optional\n  # TODO: this is beautiful when it's dim, but with a transparent background, it can be tough to see..\n  # even purple-pleasant dimmed doesn't look bad..\n# 'comment.line' = { } # Line comments, like this.\n# 'comment.block' = { } # Block comments, like /* this */ in some languages.\n'comment.block.documentation' = { fg = \"gray-stone-lighter\", modifiers = [\"dim\", \"italic\"] } # Doc comments, e.g '///' in rust.\n  # TODO: TEST: maybe okay to use italics here..\n\n'variable' = { fg = \"white-stone\" }  # Variable names.\n  # likely the most important word in the line, and therefore must be the most easily visible, yet comfortable\n'variable.builtin' = { fg = \"blue-aqua\" } # Language reserved variables: `this`, `self`, `super`, etc.\n  # NOTE: matches class color\n'variable.parameter' = { fg = \"white-stone\" } # Function parameters.\n  # TODO: this would be really useful to differentiate.. white-sea-tinged isn't too bad.. italic is too anooying\n'variable.function' = { fg = \"orange\" } # ? ruby-like everything is an object..?\n'variable.other' = { fg = \"white-stone\" } # from aura..\n  # fallback\n'variable.other.member' = { fg = \"pink-dimmer\" } # Fields of composite data types (e.g. structs, unions)., @callback in elixir, serialized data fields (like this config file..)\n# 'variable.other.member.private' # only for ECMAScript-based languages\n  # TODO: decide white-stone vs pink vs another color, and remember to turn down punctuation down a notch in hotness; would be nice to create a slightly tinged color, like noctis's white-sea-tinge\n\n'label' = { fg = \"purple\" } # Loop labels in rust.\n\n'punctuation' =  { fg = \"pink-dimmer\", modifiers = [\"bold\"] } # (){}[]:;,. \n  # NOTE: the bolded gold from noctic is really, really nice, but it collides with the orange-brighter color; also, bolded white is too much white, should save white just for variables only\n'punctuation.delimiter' = { fg = \"pink-hot\", modifiers = [\"bold\"] } # Commas and colons.\n  # pink-hotter is slightly too annoying..\n'punctuation.bracket' = { fg = \"pink-dimmer\", modifiers = [\"bold\"]  } # Parentheses, angle brackets, etc.\n'punctuation.special' = { fg = \"pink-dimmer\", modifiers = [\"bold\"] } # string interpolation\n\n'keyword' = { fg = \"purple\" } # Language reserved keywords. var, void, let\n'keyword.control' = { fg = \"purple\", modifiers = [\"bold\"] } # Control keywords.\n  # NOTE: bold makes it slightly brighter too\n'keyword.control.conditional' = { fg = \"purple\", modifiers = [\"bold\"] } # 'if', 'else', 'elif'.\n  # TODO: could use a cascading shades of purple here, between purple and purple-darker of operator, darkest on the outside, yet it's also nice to have it consistent..\n'keyword.control.repeat' = {  fg = \"purple\", modifiers = [\"bold\"] } # 'for', 'while', 'loop'.\n'keyword.control.import' = { fg = \"purple\", modifiers = [\"italic\"] } # 'import', 'export', 'use', 'mod'\n  # use crate::blah blah conflicts, crate is the same color..\n'keyword.control.return' = { fg = \"pink-salmon\", modifiers = [\"italic\"] } # 'return' in most languages.\n  # NOTE: tried red-error, but it's so ugly!!.. :/ but could use it's own color.. stole noctis's pink-salmon here.. bold is really nice too, more pink-salmony, but it eventually bugged me..; italics makes it feel like it's *pressed* in\n'keyword.control.exception' = { fg = \"pink-salmon\", modifiers = [\"italic\"] } # 'raise' in python.\n'keyword.operator' = { fg = \"purple\", modifiers = [\"bold\"] } # 'or', 'and', 'in'.\n  # TODO: doesn't look like it's working..??\n'keyword.directive' = { fg = \"purple\", modifiers = [\"italic\"] } # Preprocessor directives (#if, #include in C).\n'keyword.function' = { fg = \"purple\", modifiers = [\"bold\"] } # The keyword to define a funtion: 'def', 'fun', 'fn'.\n'keyword.storage' = { fg = \"purple\" } # let and var in rust.. these should be more visible..\n'keyword.storage.modifier' = { fg = \"purple-dimmer\", modifiers = [\"italic\"] } # function and type modifiers/accessors: public/private, mut, dyn, ref, &, internal, readonly, const, etc.\n  # these should be less visible\n  # bold makes sense here for C#, as it's usually the start of a function, but not so much for rust..\n  # currently using the same purple as operators.. which isn't too bad though, as it keeps a consistent scheme.. and it doesn't conflict with anything either. it's also good as a fallback for 'end', as that sometimes doesn't highlight properly..\n'keyword.storage.type' = { fg = \"green-sea\", modifiers = [\"italic\"] } # class, struct, enum, namespace, sometimes var? (for javascript but not rust)\n  # matches type.builtin\n\n\n'operator' = { fg = \"purple\", modifiers = [\"bold\"] } # Logical (&&, ||) and - I assume - Mathematical (+, %) operators\n\n# top three are ordered from brightest to darkest\n  # also used in markup headings\n'function' = { fg = \"orange\"}\n  # TODO: orange-brighter is too bright.. :/ but much of the beauty of the theme comes from this color... just need to get a notch lower..\n'function.method' = { fg = \"orange\" } # Class / Struct methods.\n# 'function.method.private' # just ECMAScript-based languages..\n'function.builtin' = { fg = \"orange-desaturated\" }\n'function.macro' = { fg = \"orange\", modifiers = [\"italic\"] } # Like macros in rust.\n  # italics works well here.. as does the magical gold of macros, as does orange-pumpkin\n'function.special' = { fg = \"orange\", modifiers = [\"italic\"] } # Preprocessor in C.\n\n'tag' = { fg = \"purple-darker\", modifiers = [\"italic\"] } # As in <body> for html. also @tags in comments?\n  # must be darker then the default text, and attribute\n#'tag.builtin' # ?\n\n'namespace' = { fg = \"blue-green\" } # * Namespace keyword in java, C#, etc.\n  # namespace::function, namespace::class, package main, *types.Tuple\n  # requires a seperate color\n  # TODO: this nasty blue-green accurately matches how i feel about namespace syntax..: *barf*.. pink-hotter is interesting... really changes things up!.. but i still prefer something similar to blue for logical reasoning\n  # for a long time i was using italics here, but then discovered it was part of its ugliness! now it's actually tolerable\n  \n# Colors for markup languages, like Markdown or XML.\n  # a little different from code since it's so simple, using a simple two color scheme: purple 'n gold\n\n# NOTE: it inherits the main text color from ui.text, and punctuation too\n\nmarkup = \"purple-pleasant-dimmer\" # fallback\n\n'markup.bold' = { fg = \"orange-bright\" } # Bold text.\n  # bold text isn't so easy to read.. but purple bold works pretty well alongside purple-pleasant\n  # this orange is surprisingly dim! not bad at all, and keeps a consistent two-color theme. though, orange-brighter is far more beautiful, but perhaps too bright..\n'markup.italic' = { modifiers = [\"italic\"] } # Italicised text.\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\n'markup.heading' = { fg = \"orange-bright\", modifiers = [\"bold\"] } # Markdown headings\n# NOTE: underline didn't bold, and looked wayyy too thin compared to the bold font..\n  # underline = { style = \"curl\", modifiers = [\"bold\"] }\n'markup.heading.1' = { fg = \"orange-bright\", modifiers = [\"bold\"]  }\n'markup.heading.2' = { fg = \"orange\", modifiers = [\"bold\"]  }\n'markup.heading.3' = { fg = \"orange-desaturated\", modifiers = [\"bold\"] }\n'markup.heading.4' = { fg = \"orange-bright\" }\n'markup.heading.5' = { fg = \"orange\" }\n'markup.heading.6' = { fg = \"orange-desaturated\" }\n'markup.heading.marker' = { fg = \"orange-brighter\" } # Hashtag color on Markdown headings.\n\n'markup.list' = { fg = \"orange-bright\", modifiers = [\"bold\"] }\n  # the bullet symbols are like shiny jewelry in the sea :)\n'markup.list.numbered' = { fg = \"orange-bright\" } # Numbered list.\n# 'markup.list.unnumbered' = { } # Bullet point list.\n\n'markup.link' = { fg = \"gray-stone\" }\n  # different color is annoying in comments\n  # seems to underline only when highlighted, which is great!!\n'markup.link.url' = { fg = \"gray-stone\"} # Urls pointed to by links.\n'markup.link.label' = { fg = \"gray-stone\" } # Non-URL link references.\n'markup.link.text' = { fg = \"purple-pleasant-dimmer\"} # URL and image descriptions in links.\n\n'markup.quote' = { fg = \"pink-dimmer\", modifiers = [\"italic\"] } # `> Quotes` in Markdown.\n\n# Markup - Interface ==============================\n# \"These scopes are used for theming the editor interface.\"\n\n# TODO: ??\n'markup.normal' = { }\n'markup.normal.completion' = { } # For completion doc popup ui.\n'markup.normal.raw' = { } # For hover popup ui.\n\n'markup.heading.completion' = { } # Headings for completion doc popup ui.\n'markup.heading.raw' = { } # Headings for hover popup ui.\n\n'markup.raw' = { } # Code block in Markdown.\n'markup.raw.block' = { } # Multiline (```) codeblock in Markdown.\n'markup.raw.inline' = { } # `Inline code block` in Markdown.\n'markup.raw.inline.completion' = { } # ?\n'markup.raw.inline.hover' = { } # ?\n\n# Diff ==============================\n# Version control changes.\n\n'diff.plus' = { fg = \"green-aqua\" } # Additions.\n'diff.minus' = { fg = \"pink-salmon\", modifiers = [\"slow_blink\"] } # Deletions.\n  # shows up as a little red dash, so blinking actually works well here!\n'diff.delta' = { fg = \"orange\" } # Modifications.\n'diff.delta.moved' = {fg = \"blue-aqua\" } # Renamed or moved files / changes.\n'diff.delta.conflict' = { fg = \"orange\" }\n  # could dim.. but i also quite like how clear it is.. especially without the line numbers. BUG: dim doesn't seem to work..\n  # slow_blink is fun, but epilepsy-inducing, lol.. at least they blink at the same time!\n    # TODO: TEST: blinking on deletions, is it too distracting..?\n  # not sure where you'd see diff.delta.moved..\n\n\n[palette] # Define your custom colors here.\n# NOTE: there are 16 colors in the palette by default, these will override any that have the same name. TODO: in order to make it most compatible and future-proof, should really use thsoe color names, even if it's not actually that color\n\n# noctis\n# dark-green = \"#00262a\" # backgrounds\n# mid-green = \"#073a40\" # highlights\n# autocomp-green = \"#0d6772\" # lighter than mid-green\n  # these three were used for backgrounds\nlight-green = \"#48e9a7\" # a nice sea green, bright neon when bolded, like the displays of deep sea instruments, was \"green\", re-used for text under the cursor\n\npink-salmon = \"#df769b\" # re-used for return, was \"pink\", it's perfect! :D use sparingly as i really don't like themes with lots of red in it, only returns and maybe exceptions\ngold = \"#ffd800\" # a nice, shiny bolded gold used for punctuation, was \"yellow\", ..maybe was also used for it's variable text..? unfortunately, it's very bright. used for matching fuzzy search, and other things that should really stick out, or otherwise highlighting selected text\npurple-darker = \"#6f60ea\" # this purple is slightly darker than aura's, used for cascading keywords, but seems to match vs-code's aura better??\nwhite-sea-tinged = \"#b1cace\" # has a tinge of green in it.., pleasant tho\norange-bright = \"#e4b782\" # looks fantastic in noctis, fit for the sea theme, like a clown-fish, but too bright :(\ngreen-sea-darker = \"#5b858b\" # was mainly used for comments/background text in noctis, was \"gray\", it's very readable but rather less saturated compared to the other colors.. TODO: a very good, unused reading color, not bad for atoms..\n# red = \"#e34e1b\" # an ugly red.. only good for errors.. using aura's instead, though they seem the same..\n\nblue-green = \"#19a2b7\" # TODO: quite hideous toxic aqua green... currently using for namespaces, as i don't have anymore colors.. just feels too saturated. it's closest to tokyonight's aqua, but dimmer\n# blue-green-desaturated = \"#3B94A3\" # hmmm, maybe desaturate isn't the answer.. just dims it.., but it's not a bad idea either..\n# blue-green-blue = \"#0098C2\" # slightly bluer in hue, possible replacement for type.builtin, then can use green-sea with namespace\n# blue-green-green = \"#2C98BF\" blue-green, with slightly lower hue, more greener\n# cyan-bright = \"#87efff\" # a tad too bright..\n\n\n# aura dark soft/dim\npurple = \"#8464c6\"\npurple-dimmer = \"#7B57C2\" # increased saturation??\npurple-selection = \"#3d375e\"\npurple-selection-solid = \"#29263c\"\nblue-aqua = \"#47ace8\" # currently used for types, a pretty standard blue for classes..\ngreen-aqua = \"#54c59f\" # used for constants/literals, not the prettiest, but it fits the aqua sea feelin' of the overall theme.. maybe can try bogster's green\norange = \"#c7a06f\" # used for functions, but feels too boring.. :(\norange-desaturated = \"#C7B693\"\npink = \"#c17ac8\" # great, comfy pink for pop-up-menu ui text, TODO: shuold be second main text color, but using it for punctuation t the moment..\n# pink-lighter = \"#cb90d1\" # 1/7th shade lighter (whiter)\n# white-stone-pink = \"#BEA7C1\" # somewhere between white-stone and pink; meh... pink is just more clearly visible than the colors between..\n# pink-brighter = \"#DE95E5\"\npink-dimmer = \"#B56EBC\" # slightly desaturated, used for fields/methods and elixir's @thing\n# fuschia = \"#A955B2\" # TODO: an interesting one to use..\n# pink-even-dimmer = \"#8C5C90\" # used for pop-up menus, similar to pink with dim modifier.. too dim, not even pink anymore! more like magenta.. but very comfy to read!\npink-hot = \"#cc6cd6\" # +25% saturation, nice 'n slight! for delimiters via coolers.co gradient\npink-hotter = \"#d85ee3\" # +50% saturation, for \"special\" symbols\ngreen-sea = \"#6cb2c7\" # builtin type, a bit funky but very much readable\nred-error = \"#c55858\" # error, looks great when blinking, like red flashing like underwater!\nwhite-stone = \"#bdbdbd\" # variable, has a dim tinge of dirty stone to it\n# white-stone-yellow-tinge = \"#BAB195\" # just added a little saturation, but it feels less readable :/\ngray-stone = \"#6d6d6d\" # comment, similar to white, but desaturated/grayed out, now a sort of dirty blonde; i didn't like it at first, but then became amazing once dimmed!!\n  # gray-stone-dimmed = \"#6d6d6d\" # 80 = 50%, 40 = 25%\ngray-stone-lighter = \"#7d7d7d\" # used for comments with the dim modifier; 9d9d9d dimmed seems slightly brighter than gray-stone undimmed.. 7d7d7d is out of the way, 858585 forces eyes to read it, vs 8d8d8d?\n  # TODO: alpha doesn't seem to affect these, only dim works..\n# bg = \"#121016\" # black, was accent28, slightly darker\nbg = \"#15141b\" # was \"black\", quite dark.. high-contrast\n  # TODO: have to figure out how backgrounds work: shouldn't the gui app (terminal or not) handle it?\n# bg = \"#211D26\" # a darker raisin black, was accent39, seems like a nice alternative\n# bg = \"#2d2b38\" # raisin black, was accent30. much much lighter, tougher to see on transparent backgrounds\n\npurple-pleasant = \"#a394f0\" # great comfy purp for ui, should be main color, used for text (in .txt files) and strings and ui, was accent17 (with 33 alpha) as TODO: secondary selection and accent18 (with 00 alpha)\n  # NOTE: still use this with dim modifer to make a color even dimmer than purple-pleasant-dimmer\npurple-pleasant-dimmer = \"#9889E4\" # switch to using this as main text.. along with pink-dimmer\n\n# aura colors shared between variations\n# text10 = \"#adacae\" # TODO: try it\nbg-ui = \"#1f1a27\" # soft dark, used in ui background, status line, tab bar, seems similar to purple-selection, was accent24\n\n# somewhere hidden in aura\nselection-ui = \"#2e2b38\" # no purple tinge, more closer to gray-stone, was accent33\nmarker13 = \"#2d2d2d\" # a barely visible gray\n\n# others scraped from aura\ncyan = \"#82e2ff\" # seems like noctis's cyan.. also sticks out too much.., just used for cursor match..\n# purple14 = \"#af8aff\" # light purple TODO: try it\n# purple-pleasant-opaque = \"#a394f0\" # purple-pleasant with 00 alpha (opaque?), was accent18\n  # NOTE: doesn't seem to make a difference..\n# accent4 = \"#9dff65\" # bright green\norange-brighter = \"#ffca85\" # brighter than noctis's orange, beautiful, was accent31\n# green-aqua-darker = \"#3ea784\" # was accent19\n# gray-purple = \"#4d466e\" # was accent22, english violet, too dark to read, almost charcoal.. perhaps used for grayed out text like for auto-suggestions? too dark for even inactive tabs..\n# accent25 = \"#49c29a\" # mint green, seems very close to green-aqua\n# accent26 = \"#00d890\" # emerald green, slightly brighter than the above, when without alpha\n# TODO: untested colors below..\n# accent36 = \"#a19c77\" # debugging background\n# accent37 = \"#353424\" # breakpoint frame highlight\n# accent35 = \"#525156\" # activity bar inactive foreground,\n\n# new colors\nlight-green-complement = \"#e9488a\" # initially used to create a high-contrast color for match surrounding pairs but it was too fugly to use as a cursor.. pink is better. currently using for secondary cursors as it's darker than the primary cursor's pink\n\n# from boo berry\nberry-desaturated = \"#886C9C\" # originally used for comments, but didn't quite work.. maybe because boo berry has a background color..; didn't quite work for keywords either, as it was too dim and didn't match the rest of the scheme, like dirty blood.. worth keeping! currently using for atoms, which isn't bad!..\n\n# from tokyonight\n# orange-pumpkin = \"#ff9e64\" # orange from tokyonight, too bright but really orange! looks okay with dim modifier..\n# orange-tokyonight = \"#e0af68\" # yellow from tokyonight, similar to orange from noctis\n\n# TODO: \"shades of purple\" theme has an actual orangey orange, a nice fuschia/deep purple, a good red, and a cyan that isn't too bright\n\n# TODO: try checking out noctis variants minimus and uva\n\n# try this site for buildings shades of a color..\n  # https://www.radix-ui.com/colors/custom\n  \n# this site seems fun too..\n  # coolors.co\n"
  },
  {
    "path": "runtime/themes/autumn.toml",
    "content": "# The structure is based on `base16_default_dark` by Ray Gervais.  Most of\n# the colors come from the so called Autumn theme, a color scheme inspired by\n# the colors you can find in the autumn. Originally it was designed as a\n# color scheme for the Komodo IDE and then ported to Vim by Kenneth Love\n# and Chris Jones. Later, Yorick Peterse improved their work. See:\n# <https://github.com/YorickPeterse/Autumn.vim>\n# Jens Getreu ported and optimised the color theme for the Helix editor.\n# Author: Jens Getreu <getreu at web.de>\n\n\"attribute\" = \"my_turquoise1\"\n\"comment\" = { fg = \"my_gray5\" }\n\"constant.character.escape\" = \"my_turquoise1\"\n\"constant\" = \"my_white3\"\n\"constant.numeric\" = \"my_turquoise1\"\n\"constructor\" = \"my_yellow1\"\n\"debug\" = \"my_yellow2\"\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"my_red\" } }\n\"diagnostic.hint\" = { underline = { style = \"line\", color = \"my_gray5\" }, bg = \"my_black\"}\n\"diagnostic.info\" = { underline = { style = \"line\" } }\n\"diagnostic\" = { underline = { style = \"line\", color = \"my_gray5\" }, bg = \"my_black\"}\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"my_yellow2\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"diff.delta\" = \"my_gray5\"\n\"diff.minus\" = \"my_red\"\n\"diff.plus\" = \"my_green\"\n\"error\" = \"my_red\"\n\"function\" = \"my_yellow1\"\n\"hint\" = \"my_gray6\"\n\"info\" = \"my_yellow2\"\n\"keyword\" = \"my_red\"\n\"label\" = \"my_red\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.heading\" = \"my_yellow1\"\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link.text\" = \"my_white2\"\n\"markup.link.url\" = \"my_turquoise2\"\n\"markup.list\" = \"my_white2\"\n\"markup.quote\" = \"my_brown\"\n\"markup.raw\" = \"my_green\"\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"namespace\" = \"my_white3\"\n\"operator\" = \"my_white1\"\n\"special\" = \"my_yellow1\"\n\"string\"  = \"my_green\"\n\"type\" = { fg = \"my_white3\", modifiers = [\"italic\"] }\n\"ui.background\" = { bg = \"my_gray0\" }\n\"ui.cursor\" = { bg = \"my_white4\", fg = \"my_black\" }\n\"ui.cursorline\" = { bg = \"my_gray3\" }\n\"ui.cursorline.primary\" = { bg = \"my_black\" }\n\"ui.cursorline.secondary\" = { bg = \"my_black\" }\n\"ui.cursor.match\" = { fg = \"my_white1\", modifiers = [\"bold\"], underline = { style = \"double_line\", color = \"my_white1\" }, bg = \"my_black\"}\n\"ui.cursor.primary\" = { fg = \"my_white1\", modifiers = [\"reversed\"] }\n\"ui.debug\" = { fg = \"my_yellow1\", bg = \"my_gray0\" }\n\"ui.gutter\" = { bg = \"my_gray0\" }\n\"ui.help\" = { fg = \"my_gray7\", bg = \"my_gray2\" }\n\"ui.highlight.frameline\" = { bg = \"#8b6904\" }\n\"ui.linenr\" = { fg = \"my_gray3\", bg = \"my_gray0\" }\n\"ui.linenr.selected\" = { fg = \"my_gray7\", bg = \"my_gray0\"}\n\"ui.menu\" = { fg = \"my_white1\", bg = \"my_gray2\" }\n\"ui.menu.selected\" = { fg = \"my_gray2\", bg = \"my_gray6\" }\n\"ui.popup\" = { bg = \"my_gray2\" }\n\"ui.selection\" = { bg = \"my_gray3\" }\n\"ui.statusline\" = { fg = \"my_gray7\", bg = \"my_gray2\" }\n\"ui.statusline.inactive\" = { fg = 'my_gray5', bg = 'my_gray2' }\n\"ui.statusline.insert\" = { fg = \"my_black\", bg = \"my_gray6\", modifiers = [\"bold\"] }\n\"ui.statusline.normal\" = { fg = \"my_gray7\", bg = \"my_gray2\" }\n\"ui.statusline.select\" = { fg = \"my_gray7\", bg = \"my_black\", modifiers = [\"bold\"] }\n\"ui.text.focus\" = \"my_white1\"\n\"ui.text\" = \"my_white1\"\n# Invalid modifier: \"normal\". See 'https://github.com/helix-editor/helix/issues/5709'\n\"ui.virtual.inlay-hint\" = { fg = \"my_gray4\", bg=\"my_black\" } #, modifiers = [\"normal\"] }\n# \"ui.virtual.inlay-hint.parameter\" = { fg = \"my_gray4\", modifiers = [\"normal\"] }\n\"ui.virtual.inlay-hint.parameter\" = \"my_gray4\"\n\"ui.virtual.inlay-hint.type\" = { fg = \"my_gray4\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"my_yellow2\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"my_gray1\" }\n\"ui.virtual.whitespace\" = { fg = \"my_gray6\" }\n\"ui.virtual.wrap\" = \"my_gray4\"\n\"ui.window\" = { fg = \"my_gray3\", bg = \"my_gray2\" }\n\"variable\" = \"my_white3\"\n\"variable.other.member\" = \"my_brown\"\n\"warning\" = \"my_yellow2\"\n\n[palette]\nmy_black      = \"#212121\" # Cursorline\nmy_brown      = \"#cfba8b\" # Member variables, Quotes\nmy_gray0      = \"#232323\" # Default Background\nmy_gray1      = \"#2b2b2b\" # Ruler\nmy_gray2      = \"#323232\" # Lighter Background (Used for status bars, line number and folding marks)\nmy_gray3      = \"#404040\" # Selection Background\nmy_gray4      = \"#646f69\" # Inlay-hint\nmy_gray5      = \"#646f69\" # Comments, Invisibles, Line Highlighting\nmy_gray6      = \"#a8a8a8\" # Dark Foreground (Used for status bars)\nmy_gray7      = \"#c8c8c8\" # Light Foreground\nmy_gray8      = \"#e8e8e8\" # Light Background\nmy_green      = \"#99be70\" # Strings, Inherited Class, Markup Code, Diff Inserted\nmy_red        = \"#F05E48\" # Keywords, Storage, Selector, Diff Changed\nmy_turquoise1 = \"#86c1b9\" # Support, Regular Expressions, Escape Characters\nmy_turquoise2 = \"#72a59e\" # URL\nmy_white1     = \"#F3F2CC\" # Default Foreground, Caret, Delimiters, Operators\nmy_white2     = \"#F3F2CC\" # Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted\nmy_white3     = \"#F3F2CC\" # Classes, Markup Bold, Search Text Background\nmy_white4     = \"#7e7d6a\" # Cursor match\nmy_yellow1    = \"#FAD566\" # Functions, Methods, Attribute IDs, Headings\nmy_yellow2    = \"#ffff9f\" # Debug, Info\n"
  },
  {
    "path": "runtime/themes/autumn_night.toml",
    "content": "# The structure is based on `base16_default_dark` by Ray Gervais.  Most of\n# the colors come from the so called Autumn theme, a color scheme inspired by\n# the colors you can find in the autumn. Originally it was designed as a\n# color scheme for the Komodo IDE and then ported to Vim by Kenneth Love\n# and Chris Jones. Later, Yorick Peterse improved their work. See:\n# <https://github.com/YorickPeterse/Autumn.vim>\n# Jens Getreu ported and optimised the color theme for the Helix editor.\n# Author: Jens Getreu <getreu at web.de>\n\ninherits = \"autumn\"\n\n[palette]\nmy_black      = \"#111111\" # Cursorline\nmy_brown      = \"#cfba8b\" # Member variables, Quotes\nmy_gray0      = \"#090909\" # Default Background\nmy_gray1      = \"#0e0e0e\" # Ruler\nmy_gray2      = \"#1a1a1a\" # Lighter Background (Used for status bars, line number and folding marks)\nmy_gray3      = \"#404040\" # Selection Background\nmy_gray4      = \"#626C66\" # Inlay-hint\nmy_gray5      = \"#626C66\" # Comments, Invisibles, Line Highlighting\nmy_gray6      = \"#aaaaaa\" # Dark Foreground (Used for status bars)\nmy_gray7      = \"#c4c4c4\" # Light Foreground\nmy_gray8      = \"#e8e8e8\" # Light Background\nmy_green      = \"#99be70\" # Strings, Inherited Class, Markup Code, Diff Inserted\nmy_red        = \"#F05E48\" # Keywords, Storage, Selector, Diff Changed\nmy_turquoise1 = \"#86c1b9\" # Support, Regular Expressions, Escape Characters\nmy_turquoise2 = \"#72a59e\" # URL\nmy_white1     = \"#F3F2CC\" # Default Foreground, Caret, Delimiters, Operators\nmy_white2     = \"#F3F2CC\" # Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted\nmy_white3     = \"#F3F2CC\" # Classes, Markup Bold, Search Text Background\nmy_white4     = \"#7e7d6a\" # Secondary cursors\nmy_yellow1    = \"#FAD566\" # Functions, Methods, Attribute IDs, Headings\nmy_yellow2    = \"#ffff9f\" # Debug, Info\n"
  },
  {
    "path": "runtime/themes/ayu_dark.toml",
    "content": "# Author: André Sá <enkodr@outlook.com>\n# Based on the AYU theme colors from https://github.com/dempfi/ayu\n\n# Syntax highlighting\n\"type\" = \"blue\"\n\"type.builtin\" = \"blue\"\n\"constructor\" = \"green\"\n\"constant\" = \"magenta\"\n\"string\" = \"green\"\n\"string.regexp\" = \"orange\"\n\"string.special\" = \"yellow\"\n\"comment\" = { fg = \"gray\", modifiers = [\"italic\"] }\n\"variable\" = \"foreground\"\n\"label\" = \"orange\"\n\"punctuation\" = \"foreground\"\n\"keyword\" = \"orange\"\n\"keyword.control\" = \"yellow\"\n\"keyword.directive\" = \"yellow\"\n\"operator\" = \"orange\"\n\"function\" = \"yellow\"\n\"tag\" = \"blue\"\n\"namespace\" = \"blue\"\n\"markup.heading\" = \"orange\"\n\"markup.list\" = \"yellow\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"orange\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.raw.block\" = \"orange\"\n\"markup.link.url\" = \"blue\"\n\"markup.link.text\" = \"yellow\"\n\"markup.link.label\" = \"green\"\n\"markup.quote\" = \"yellow\"\n\"diff.plus\" =  \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"yellow\"\n\n# Interface\n\"ui.background\"= { bg = \"background\" }\n\"ui.cursor\" = { fg = \"dark_gray\", bg = \"yellow\" }\n\"ui.cursor.primary\" = { fg = \"dark_gray\", bg = \"orange\" }\n\"ui.cursor.match\" = \"orange\"\n\"ui.linenr\" = \"dark_gray\"\n\"ui.linenr.selected\" = \"gray\"\n\"ui.statusline\" = { fg = \"foreground\", bg = \"black\" }\n\"ui.statusline.normal\" = { fg = \"black\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"orange\" }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"magenta\" }\n\"ui.cursorline\" = { bg = \"black\" }\n\"ui.popup\" = { fg = \"#7B91b3\", bg = \"black\" }\n\"ui.window\" = \"dark_gray\"\n\"ui.help\" = { fg = \"#7B91b3\", bg = \"black\" }\n\"ui.text\" = \"foreground\"\n\"ui.text.focus\" = { bg = \"dark_gray\", fg = \"foreground\" }\n\"ui.text.info\" = \"foreground\"\n\"ui.virtual.whitespace\" = \"dark_gray\"\n\"ui.virtual.ruler\" = { bg = \"black\" }\n\"ui.virtual.inlay-hint\" = { fg = \"#e6b450\", bg = \"#302a20\" }  # original bg #e6b45033\n\"ui.menu\" = { fg = \"foreground\", bg = \"black\" }\n\"ui.menu.selected\" = { bg = \"gray\", fg = \"background\" }\n\"ui.selection\" = { bg = \"dark_gray\" }\n\"warning\" = \"yellow\"\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"diagnostic.hint\" = { underline = { color = \"blue\", style=\"curl\"} }\n\"diagnostic.info\"= { underline = { color = \"blue\", style=\"curl\"} }\n\"diagnostic.warning\"= { underline = { color = \"yellow\", style=\"curl\"} }\n\"diagnostic.error\"= { underline = { color = \"red\", style=\"curl\"} }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"ui.bufferline\" = { fg = \"gray\", bg = \"background\" }\n\"ui.bufferline.active\" = { fg = \"foreground\", bg = \"dark_gray\" }\n\"ui.debug\" = { fg = \"orange\", bg = \"background\" }\n\"ui.highlight.frameline\" = { bg = \"#0067a3\" }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"italic\", \"bold\"] }\n\n\"special\" = \"orange\"\n\n[palette]\nbackground = \"#0f1419\"\nforeground = \"#bfbdb6\"\n\nblack = \"#131721\"\nblue = \"#59c2ff\"\ndark_gray = \"#2d3640\"\ncyan = \"#73b8ff\"\ngray = \"#5c6773\"\ngreen = \"#aad94c\"\nmagenta = \"#d2a6ff\"\norange = \"#ff8f40\"\nred = \"#f07178\"\nyellow = \"#e6b450\"\n"
  },
  {
    "path": "runtime/themes/ayu_evolve.toml",
    "content": "inherits = 'ayu_dark'\n\n\"keyword.control\" = \"orange\"\n\"keyword.storage\" = \"yellow\"\n\"keyword.storage.modifier\" = \"magenta\"\n\"variable\" = \"light_gray\"\n\"constructor\" = \"magenta\"\n\"type.builtin\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\n# Gutters and editing area\n\"error\" = \"red\"\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"warning\" = \"vibrant_orange\"\n\"diagnostic.warning\" = { underline = { color = \"vibrant_orange\", style = \"curl\" } }\n\"hint\" = \"vibrant_yellow\"\n\"diagnostic.hint\" = { underline = { color = \"vibrant_yellow\", style = \"curl\" } }\n\"info\" = \"white\"\n\"diagnostic.info\" = { underline = { color = \"white\", style = \"curl\" } }\n\n\"markup.raw.block\" = { bg = \"black\" }\n\"markup.raw.inline\" = { bg = \"black\" }\n\n\"ui.cursor\" = { fg = \"dark_gray\", bg = \"light_gray\" }\n\"ui.cursor.primary\" = { fg = \"dark_gray\", bg = \"orange\" }\n\"ui.cursor.primary.select\" = { fg = \"dark_gray\", bg = \"magenta\" }\n\"ui.cursor.primary.insert\" = { fg = \"dark_gray\", bg = \"green\" }\n\"ui.text.inactive\" = \"gray\"\n\"ui.bufferline\" = { fg = \"light_gray\", bg = \"background\" }\n\"ui.bufferline.active\" = { fg = \"light_gray\", bg = \"dark_gray\" }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"italic\", \"bold\"] }\n\n[palette]\nbackground = '#020202'\nblack = \"#0D0D0D\"\nlight_gray = \"#dedede\"\nred = \"#DD3E25\"\nvibrant_yellow = \"#CFCA0D\"\nvibrant_orange = \"#FF8732\"\n"
  },
  {
    "path": "runtime/themes/ayu_light.toml",
    "content": "# Author: André Sá <enkodr@outlook.com>\n# Based on the AYU theme colors from https://github.com/dempfi/ayu\n\n# Syntax highlighting\n\"type\" = \"blue\"\n\"type.builtin\" = \"blue\"\n\"constructor\" = \"green\"\n\"constant\" = \"magenta\"\n\"string\" = \"green\"\n\"string.regexp\" = \"orange\"\n\"string.special\" = \"yellow\"\n\"comment\" = { fg = \"gray\", modifiers = [\"italic\"] }\n\"variable\" = \"foreground\"\n\"label\" = \"orange\"\n\"punctuation\" = \"foreground\"\n\"keyword\" = \"orange\"\n\"keyword.control\" = \"yellow\"\n\"keyword.directive\" = \"yellow\"\n\"operator\" = \"orange\"\n\"function\" = \"yellow\"\n\"tag\" = \"blue\"\n\"namespace\" = \"blue\"\n\"markup.heading\" = \"orange\"\n\"markup.list\" = \"yellow\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"orange\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.raw.block\" = \"orange\"\n\"markup.link.url\" = { fg = \"blue\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"yellow\"\n\"markup.link.label\" = \"green\"\n\"markup.quote\" = \"yellow\"\n\"diff.plus\" =  \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"yellow\"\n\n# Interface\n\"ui.background\"= { bg = \"background\" }\n\"ui.cursor\" = { fg = \"dark_gray\", bg = \"yellow\" }\n\"ui.cursor.primary\" = { fg = \"dark_gray\", bg = \"orange\" }\n\"ui.cursor.match\" = \"orange\"\n\"ui.linenr\" = \"dark_gray\"\n\"ui.linenr.selected\" = \"gray\"\n\"ui.statusline\" = { fg = \"foreground\", bg = \"black\" }\n\"ui.statusline.normal\" = { fg = \"black\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"orange\" }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"magenta\" }\n\"ui.cursorline\" = { bg = \"black\" }\n\"ui.popup\" = { fg = \"#7B91b3\", bg = \"black\" }\n\"ui.window\" = \"dark_gray\"\n\"ui.help\" = { fg = \"#7B91b3\", bg = \"black\" }\n\"ui.text\" = \"foreground\"\n\"ui.text.focus\" = { bg = \"dark_gray\", fg = \"foreground\" }\n\"ui.text.info\" = \"foreground\"\n\"ui.virtual.whitespace\" = \"dark_gray\"\n\"ui.virtual.ruler\" = { bg = \"black\" }\n\"ui.virtual.inlay-hint\" = { fg = \"#f4a028\", bg = \"#fcf2e3\" }  # bg original #ffaa3333\n\"ui.menu\" = { fg = \"foreground\", bg = \"black\" }\n\"ui.menu.selected\" = { bg = \"gray\", fg = \"background\" }\n\"ui.selection\" = { bg = \"dark_gray\" }\n\"warning\" = \"yellow\"\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"diagnostic.hint\"= { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.info\"= { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.warning\"= { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\"= { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"ui.bufferline\" = { fg = \"gray\", bg = \"background\" }\n\"ui.bufferline.active\" = { fg = \"foreground\", bg = \"dark_gray\" }\n\"ui.debug\" = { fg = \"orange\", bg = \"background\" }\n\"ui.highlight.frameline\" = { bg = \"#cfe0f2\" }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"italic\", \"bold\"] }\n\n\"special\" = \"orange\"\n\n[palette]\nbackground = \"#fafafa\"\nforeground = \"#5c6166\"\n\nblack = \"#e7eaed\"\nwhite = \"#fcfcfc\"\nblue = \"#399ee6\"\nlight_blue = \"#55b4d4\"\ncyan = \"#478acc\"\ndark_gray = \"#d8d8d7\"\ngray = \"#828c9a\"\ngreen = \"#86b300\"\nmagenta = \"#a37acc\"\norange = \"#fa8d3e\"\nred = \"#f07171\"\nyellow = \"#ffaa33\"\n"
  },
  {
    "path": "runtime/themes/ayu_mirage.toml",
    "content": "# Author: André Sá <enkodr@outlook.com>\n# Based on the AYU theme colors from https://github.com/dempfi/ayu\n\n# Syntax highlighting\n\"type\" = \"blue\"\n\"type.builtin\" = \"blue\"\n\"constructor\" = \"green\"\n\"constant\" = \"magenta\"\n\"string\" = \"green\"\n\"string.regexp\" = \"orange\"\n\"string.special\" = \"yellow\"\n\"comment\" = { fg = \"gray\", modifiers = [\"italic\"] }\n\"variable\" = \"foreground\"\n\"label\" = \"orange\"\n\"punctuation\" = \"foreground\"\n\"keyword\" = \"orange\"\n\"keyword.control\" = \"yellow\"\n\"keyword.directive\" = \"yellow\"\n\"operator\" = \"orange\"\n\"function\" = \"yellow\"\n\"tag\" = \"blue\"\n\"namespace\" = \"blue\"\n\"markup.heading\" = \"orange\"\n\"markup.list\" = \"yellow\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"orange\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.raw.block\" = \"orange\"\n\"markup.link.url\" = \"blue\"\n\"markup.link.text\" = \"yellow\"\n\"markup.link.label\" = \"green\"\n\"markup.quote\" = \"yellow\"\n\"diff.plus\" =  \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"yellow\"\n\n# Interface\n\"ui.background\"= { bg = \"background\" }\n\"ui.cursor\" = { fg = \"dark_gray\", bg = \"yellow\" }\n\"ui.cursor.primary\" = { fg = \"dark_gray\", bg = \"orange\" }\n\"ui.cursor.match\" = \"orange\"\n\"ui.linenr\" = \"dark_gray\"\n\"ui.linenr.selected\" = \"gray\"\n\"ui.statusline\" = { fg = \"foreground\", bg = \"black\" }\n\"ui.statusline.normal\" = { fg = \"black\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"orange\" }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"magenta\" }\n\"ui.cursorline\" = { bg = \"black\" }\n\"ui.popup\" = { fg = \"#7B91b3\", bg = \"black\" }\n\"ui.window\" = \"dark_gray\"\n\"ui.help\" = { fg = \"#7B91b3\", bg = \"black\" }\n\"ui.text\" = \"foreground\"\n\"ui.text.focus\" = { bg = \"dark_gray\", fg = \"foreground\" }\n\"ui.text.info\" = \"foreground\"\n\"ui.virtual.whitespace\" = \"dark_gray\"\n\"ui.virtual.ruler\" = { bg = \"black\" }\n\"ui.virtual.inlay-hint\" = { fg = \"#ffcc66\", bg = \"#47433d\" }  # original bg #ffcc6633\n\"ui.menu\" = { fg = \"foreground\", bg = \"black\" }\n\"ui.menu.selected\" = { bg = \"gray\", fg = \"background\" }\n\"ui.selection\" = { bg = \"dark_gray\" }\n\"warning\" = \"yellow\"\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"diagnostic.hint\"= { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.info\"= { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.warning\"= { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\"= { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"ui.bufferline\" = { fg = \"gray\", bg = \"background\" }\n\"ui.bufferline.active\" = { fg = \"foreground\", bg = \"dark_gray\" }\n\"ui.debug\" = { fg = \"orange\", bg = \"background\" }\n\"ui.highlight.frameline\" = { bg = \"#0067a3\" }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"italic\", \"bold\"] }\n\n\"special\" = \"orange\"\n\n[palette]\nbackground = \"#1f2430\"\nforeground = \"#cccac2\"\n\nblack = \"#1a1f29\"\nblue = \"#73d0ff\"\ndark_gray = \"#323843\"\ncyan = \"#444b55\"\ngray = \"#565b66\"\ngreen = \"#d5ff80\"\nmagenta = \"#dfbfff\"\norange = \"#ffad66\"\nred = \"#f28779\"\nyellow = \"#ffcc77\"\n"
  },
  {
    "path": "runtime/themes/base16_default_dark.toml",
    "content": "# Author: RayGervais <raygervais@hotmail.ca>\n\n\"ui.background\" = { bg = \"base00\" }\n\"ui.virtual.whitespace\" = \"base03\"\n\"ui.virtual.jump-label\" = { fg = \"blue\", modifiers = [\"bold\", \"underlined\"] }\n\"ui.virtual.ruler\" = { bg = \"base01\" }\n\"ui.menu\" = { fg = \"base05\", bg = \"base01\" }\n\"ui.menu.selected\" = { fg = \"base01\", bg = \"base04\" }\n\"ui.linenr\" = { fg = \"base03\", bg = \"base01\" }\n\"ui.popup\" = { bg = \"base01\" }\n\"ui.window\" = { bg = \"base01\" }\n\"ui.linenr.selected\" = { fg = \"base04\", bg = \"base01\", modifiers = [\"bold\"] }\n\"ui.selection\" = { bg = \"base02\" }\n\"comment\" = { fg = \"base03\", modifiers = [\"italic\"] }\n\"ui.statusline\" = { fg = \"base04\", bg = \"base01\" }\n\"ui.cursor\" = { fg = \"base04\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"base05\", modifiers = [\"reversed\"] }\n\"ui.text\" = \"base05\"\n\"operator\" = \"base05\"\n\"ui.text.focus\" = \"base05\"\n\"variable\" = \"base08\"\n\"constant.numeric\" = \"base09\"\n\"constant\" = \"base09\"\n\"attribute\" = \"base09\"\n\"type\" = \"base0A\"\n\"ui.cursor.match\" = { fg = \"base0A\", modifiers = [\"underlined\"] }\n\"string\"  = \"base0B\"\n\"variable.other.member\" = \"base0B\"\n\"constant.character.escape\" = \"base0C\"\n\"function\" = \"base0D\"\n\"constructor\" = \"base0D\"\n\"special\" = \"base0D\"\n\"keyword\" = \"base0E\"\n\"label\" = \"base0E\"\n\"namespace\" = \"base0E\"\n\"ui.help\" = { fg = \"base06\", bg = \"base01\" }\n\n\"markup.heading\" = \"base0D\"\n\"markup.list\" = \"base08\"\n\"markup.bold\" = { fg = \"base0A\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"base0E\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"base09\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"base08\"\n\"markup.quote\" = \"base0C\"\n\"markup.raw\" = \"base0B\"\n\n\"diff.plus\" = \"base0B\"\n\"diff.delta\" = \"base09\"\n\"diff.minus\" = \"base08\"\n\n\"diagnostic\" = { modifiers = [\"underlined\"] }\n\"ui.gutter\" = { bg = \"base01\" }\n\"info\" = \"base0D\"\n\"hint\" = \"base03\"\n\"debug\" = \"base03\"\n\"warning\" = \"base09\"\n\"error\" = \"base08\"\n\n\"ui.bufferline\" = { fg = \"base04\", bg = \"base00\" }\n\"ui.bufferline.active\" = { fg = \"base06\", bg = \"base01\" }\n\n[palette]\nbase00 = \"#181818\" # Default Background\nbase01 = \"#282828\" # Lighter Background (Used for status bars, line number and folding marks)\nbase02 = \"#383838\" # Selection Background\nbase03 = \"#585858\" # Comments, Invisibles, Line Highlighting\nbase04 = \"#b8b8b8\" # Dark Foreground (Used for status bars)\nbase05 = \"#d8d8d8\" # Default Foreground, Caret, Delimiters, Operators\nbase06 = \"#e8e8e8\" # Light Foreground (Not often used)\nbase07 = \"#f8f8f8\" # Light Background (Not often used)\nbase08 = \"#ab4642\" # Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted\nbase09 = \"#dc9656\" # Integers, Boolean, Constants, XML Attributes, Markup Link Url\nbase0A = \"#f7ca88\" # Classes, Markup Bold, Search Text Background\nbase0B = \"#a1b56c\" # Strings, Inherited Class, Markup Code, Diff Inserted\nbase0C = \"#86c1b9\" # Support, Regular Expressions, Escape Characters, Markup Quotes\nbase0D = \"#7cafc2\" # Functions, Methods, Attribute IDs, Headings\nbase0E = \"#ba8baf\" # Keywords, Storage, Selector, Markup Italic, Diff Changed\nbase0F = \"#a16946\" # Deprecated, Opening/Closing Embedded Language Tags, e.g. <?php ?>\n"
  },
  {
    "path": "runtime/themes/base16_default_light.toml",
    "content": "# Author: NNB <nnbnh@protonmail.com>\n\n\"ui.background\" = { bg = \"base00\" }\n\"ui.menu\" = { fg = \"base05\", bg = \"base01\" }\n\"ui.menu.selected\" = { fg = \"base01\", bg = \"base04\" }\n\"ui.linenr\" = { fg = \"base03\", bg = \"base01\" }\n\"ui.popup\" = { bg = \"base01\" }\n\"ui.window\" = { bg = \"base01\" }\n\"ui.linenr.selected\" = { fg = \"base04\", bg = \"base01\", modifiers = [\"bold\"] }\n\"ui.selection\" = { bg = \"base02\" }\n\"comment\" = { fg = \"base03\", modifiers = [\"italic\"] }\n\"ui.statusline\" = { fg = \"base04\", bg = \"base01\" }\n\"ui.cursor\" = { fg = \"base04\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"base05\", modifiers = [\"reversed\"] }\n\"ui.virtual.whitespace\" = \"base03\"\n\"ui.virtual.jump-label\" = { fg = \"blue\", modifiers = [\"bold\", \"underlined\"] }\n\"ui.virtual.ruler\" = { bg = \"base01\" }\n\"ui.text\" = \"base05\"\n\"operator\" = \"base05\"\n\"ui.text.focus\" = \"base05\"\n\"variable\" = \"base08\"\n\"constant.numeric\" = \"base09\"\n\"constant\" = \"base09\"\n\"attribute\" = \"base09\"\n\"type\" = \"base0A\"\n\"ui.cursor.match\" = { fg = \"base0A\", modifiers = [\"underlined\"] }\n\"string\"  = \"base0B\"\n\"variable.other.member\" = \"base0B\"\n\"constant.character.escape\" = \"base0C\"\n\"function\" = \"base0D\"\n\"constructor\" = \"base0D\"\n\"special\" = \"base0D\"\n\"keyword\" = \"base0E\"\n\"label\" = \"base0E\"\n\"namespace\" = \"base0E\"\n\"ui.help\" = { fg = \"base06\", bg = \"base01\" }\n\n\"markup.heading\" = \"base0D\"\n\"markup.list\" = \"base08\"\n\"markup.bold\" = { fg = \"base0A\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"base0E\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"base09\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"base08\"\n\"markup.quote\" = \"base0C\"\n\"markup.raw\" = \"base0B\"\n\n\"diff.plus\" = \"base0B\"\n\"diff.delta\" = \"base09\"\n\"diff.minus\" = \"base08\"\n\n\"diagnostic\" = { modifiers = [\"underlined\"] }\n\"ui.gutter\" = { bg = \"base01\" }\n\"info\" = \"base0D\"\n\"hint\" = \"base03\"\n\"debug\" = \"base03\"\n\"warning\" = \"base09\"\n\"error\" = \"base08\"\n\n\"ui.bufferline\" = { fg = \"base04\", bg = \"base01\" }\n\"ui.bufferline.active\" = { fg = \"base07\", bg = \"base00\" }\n\n[palette]\nbase00 = \"#f8f8f8\" # Default Background\nbase01 = \"#e8e8e8\" # Lighter Background (Used for status bars, line number and folding marks)\nbase02 = \"#d8d8d8\" # Selection Background\nbase03 = \"#b8b8b8\" # Comments, Invisibles, Line Highlighting\nbase04 = \"#585858\" # Dark Foreground (Used for status bars)\nbase05 = \"#383838\" # Default Foreground, Caret, Delimiters, Operators\nbase06 = \"#282828\" # Light Foreground (Not often used)\nbase07 = \"#181818\" # Light Background (Not often used)\nbase08 = \"#ab4642\" # Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted\nbase09 = \"#dc9656\" # Integers, Boolean, Constants, XML Attributes, Markup Link Url\nbase0A = \"#f7ca88\" # Classes, Markup Bold, Search Text Background\nbase0B = \"#a1b56c\" # Strings, Inherited Class, Markup Code, Diff Inserted\nbase0C = \"#86c1b9\" # Support, Regular Expressions, Escape Characters, Markup Quotes\nbase0D = \"#7cafc2\" # Functions, Methods, Attribute IDs, Headings\nbase0E = \"#ba8baf\" # Keywords, Storage, Selector, Markup Italic, Diff Changed\nbase0F = \"#a16946\" # Deprecated, Opening/Closing Embedded Language Tags, e.g. <?php ?>\n"
  },
  {
    "path": "runtime/themes/base16_terminal.toml",
    "content": "# Author: NNB <nnbnh@protonmail.com>\n\n\"ui.menu\" = { fg = \"light-gray\", bg = \"gray\" }\n\"ui.menu.selected\" = { modifiers = [\"reversed\"] }\n\"ui.linenr\" = { fg = \"light-gray\", bg = \"black\" }\n\"ui.popup\" = { bg = \"black\" }\n\"ui.window\" = { bg = \"black\" }\n\"ui.linenr.selected\" = { fg = \"white\", bg = \"black\", modifiers = [\"bold\"] }\n\"ui.selection\" = { fg = \"gray\", modifiers = [\"reversed\"] }\n\"comment\" = { fg = \"light-gray\", modifiers = [\"italic\"] }\n\"ui.statusline\" = { fg = \"white\", bg = \"black\" }\n\"ui.statusline.inactive\" = { fg = \"gray\", bg = \"black\" }\n\"ui.help\" = { fg = \"white\", bg = \"black\" }\n\"ui.cursor\" = { fg = \"light-gray\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"light-gray\", modifiers = [\"reversed\"] }\n\"ui.virtual.whitespace\" = \"light-gray\"\n\"ui.virtual.jump-label\" = { fg = \"blue\", modifiers = [\"bold\", \"underlined\"] }\n\"ui.virtual.ruler\" = { bg = \"black\" }\n\"variable\" = \"light-red\"\n\"constant.numeric\" = \"yellow\"\n\"constant\" = \"yellow\"\n\"attribute\" = \"yellow\"\n\"type\" = \"light-yellow\"\n\"ui.cursor.match\" = { fg = \"light-yellow\", modifiers = [\"underlined\"] }\n\"string\"  = \"light-green\"\n\"variable.other.member\" = \"light-green\"\n\"constant.character.escape\" = \"light-cyan\"\n\"function\" = \"light-blue\"\n\"constructor\" = \"light-blue\"\n\"special\" = \"light-blue\"\n\"keyword\" = \"light-magenta\"\n\"label\" = \"light-magenta\"\n\"namespace\" = \"light-magenta\"\n\n\"markup.heading\" = \"light-blue\"\n\"markup.list\" = \"light-red\"\n\"markup.bold\" = { fg = \"light-yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"light-magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"light-red\"\n\"markup.quote\" = \"light-cyan\"\n\"markup.raw\" = \"light-green\"\n\n\"diff.plus\" = \"light-green\"\n\"diff.delta\" = \"yellow\"\n\"diff.minus\" = \"light-red\"\n\n\"diagnostic\" = { modifiers = [\"underlined\"] }\n\"ui.gutter\" = { bg = \"black\" }\n\"info\" = \"light-blue\"\n\"hint\" = \"gray\"\n\"debug\" = \"gray\"\n\"warning\" = \"yellow\"\n\"error\" = \"light-red\"\n"
  },
  {
    "path": "runtime/themes/base16_transparent.toml",
    "content": "# Author: GreasySlug <9619abgoni@gmail.com>\n# This theme is base on base16_theme(Author: NNB <nnbnh@protonmail.com>)\n\n\"ui.background\" = { fg = \"white\"}\n\"ui.background.separator\" = { fg = \"gray\" }\n\"ui.text\" = { fg = \"light-gray\" }\n\"ui.text.focus\" = { fg = \"white\" }\n\"ui.menu\" = { fg = \"white\" }\n\"ui.menu.selected\" = { modifiers = [\"reversed\"] }\n\"ui.menu.scroll\" = { fg = \"light-gray\" }\n\"ui.linenr\" = { modifiers = [\"dim\"] }\n\"ui.linenr.selected\" = { fg = \"white\",  modifiers = [\"bold\"] }\n\"ui.popup\" = { fg = \"white\" }\n\"ui.window\" = { fg = \"gray\" }\n\"ui.selection\" = { bg = \"gray\" }\n\"comment\" = \"light-gray\"\n\"ui.statusline\" = { fg = \"white\" }\n\"ui.statusline.inactive\" = { fg = \"gray\" }\n\"ui.statusline.normal\" = { fg = \"black\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"magenta\" }\n\"ui.help\" = { fg = \"light-gray\" }\n\"ui.cursor\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"light-yellow\", underline = { color = \"light-yellow\", style = \"line\" } }\n\"ui.cursor.primary\" = { modifiers = [\"reversed\", \"slow_blink\"] }\n\"ui.cursor.secondary\" = { modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { underline = { color = \"light-gray\", style = \"line\" } }\n\"ui.cursorline.secondary\" = { underline = { color = \"light-gray\", style = \"line\" } }\n\"ui.cursorcolumn.primary\" = { bg = \"gray\" }\n\"ui.cursorcolumn.secondary\" = { bg = \"gray\" }\n\"ui.virtual.ruler\" = { bg = \"gray\" }\n\"ui.virtual.whitespace\" = \"gray\"\n\"ui.virtual.indent-guide\" = \"gray\"\n\"ui.virtual.inlay-hint\" = { fg = \"white\", bg = \"gray\" }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"white\", bg = \"gray\"}\n\"ui.virtual.inlay-hint.type\" = { fg = \"white\", bg = \"gray\"}\n\"ui.virtual.wrap\" = \"gray\"\n\"ui.virtual.jump-label\" = { fg = \"blue\", modifiers = [\"bold\", \"underlined\"] }\n\n\"variable\" = \"light-red\"\n\"constant.numeric\" = \"yellow\"\n\"constant\" = \"yellow\"\n\"attribute\" = \"yellow\"\n\"type\" = \"light-yellow\"\n\"string\"  = \"light-green\"\n\"variable.other.member\" = \"green\"\n\"constant.character.escape\" = \"light-cyan\"\n\"function\" = \"light-blue\"\n\"constructor\" = \"light-blue\"\n\"special\" = \"light-blue\"\n\"keyword\" = \"light-magenta\"\n\"label\" = \"light-magenta\"\n\"namespace\" = \"light-magenta\"\n\n\"markup.heading\" = \"light-blue\"\n\"markup.list\" = \"light-red\"\n\"markup.bold\" = { fg = \"light-yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"light-magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"yellow\", underline = { color = \"yellow\", style = \"line\"} }\n\"markup.link.text\" = \"light-red\"\n\"markup.quote\" = \"light-cyan\"\n\"markup.raw\" = \"green\"\n\"markup.normal\" = { fg = \"blue\" }\n\"markup.insert\" = { fg = \"green\" }\n\"markup.select\" = { fg = \"magenta\" }\n\n\"diff.plus\" = \"light-green\"\n\"diff.delta\" = \"light-blue\"\n\"diff.delta.moved\" = \"blue\"\n\"diff.minus\" = \"light-red\"\n\n\"ui.gutter\" = \"gray\"\n\"info\" = \"light-blue\"\n\"hint\" = \"light-gray\"\n\"debug\" = \"light-gray\"\n\"warning\" = \"light-yellow\"\n\"error\" = \"light-red\"\n\n\"diagnostic.info\" = { underline = { color = \"light-blue\", style = \"dotted\" } }\n\"diagnostic.hint\" = { underline = { color = \"light-gray\", style = \"double_line\" } }\n\"diagnostic.debug\" = { underline ={ color =\"light-gray\", style = \"dashed\" } }\n\"diagnostic.warning\" = { underline = { color = \"light-yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color =\"light-red\", style = \"curl\" } }\n"
  },
  {
    "path": "runtime/themes/beans.toml",
    "content": "# Beans\n# A slightly modified Jellybeans with better support for multi-cursor and multiple selections\n#\n# Original repository: nanotech/jellybeans.vim\n# Contributors:\n# @cemalokten\n# @gnur\n\n\n\"attribute\" = \"green\"\n\"type\" = \"light_blue\"\n\"type.enum.variant\" = \"purple\"\n\"constructor\" = \"yellow\"\n\"constant\" = \"dark_orange\"\n\n\"constant.builtin.boolean\" = \"yellow\"\n\"constant.character\" = \"yellow\"\n\"constant.character.escape\" = \"red_error\"\n\"constant.numeric\" = \"dark_orange\"\n\"string\" = \"dark_green\"\n\"string.regexp\" = \"light_purple\"\n\"string.special\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"comment\" = \"light_gray\"\n\n\"variable\" = \"light_yellow\"\n\"variable.builtin\" = { fg = \"dark_green\", modifiers = [\"underlined\"] }\n\"variable.parameter\" = \"yellow\"\n\"variable.other.member\" = \"light_purple\"\n\"label\" = \"yellow\"\n\"punctuation\" = \"mid_blue\"\n\"keyword\" = \"mid_blue\"\n\"keyword.control.exception\" = \"purple\"\n\"operator\" = \"light_purple\"\n\"function\" = \"yellow\"\n\"function.macro\" = \"green\"\n\"function.builtin\" = \"green\"\n\"function.special\" = \"green\"\n\"function.method\" = \"yellow\"\n\"tag\" = \"light_blue\"\n\"special\" = \"green\"\n\"namespace\" = \"light_purple\"\n\n\"markup.bold\" = { fg = \"white\", modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.heading\" = { fg = \"mid_blue\", modifiers = [\"bold\"] }\n\"markup.list\" = \"dark_green\"\n\"markup.list.numbered\" = \"mid_blue\"\n\"markup.list.unnumbered\" = \"mid_blue\"\n\"markup.link.url\" = { fg = \"dark_green\", modifiers = ['italic', 'underlined'] }\n\"markup.link.text\" = \"mid_blue\"\n\"markup.link.label\" = \"purple\"\n\"markup.quote\" = \"dark_green\"\n\"markup.raw\" = \"dark_green\"\n\"markup.raw.inline\" = \"mid_blue\"\n\"markup.raw.block\" = \"dark_green\"\n\n\"diff.plus\" = \"diff_plus\"\n\"diff.minus\" = \"red_accent\"\n\"diff.delta\" = \"blue_accent\"\n\n# ui specific\n\"ui.background\" = { bg = \"background\" }\n\"ui.cursor\" = { bg = \"purple\", fg = \"selectionfg\" }\n\"ui.cursor.primary\" = { bg = \"dark_blue\", fg = \"white\" }\n\"ui.cursor.normal\" = { bg = \"purple\", fg = \"selectionfg\" }\n\"ui.cursor.insert\" = { bg = \"light_yellow\", fg = \"background\" }\n\"ui.cursor.match\" = { fg = \"background\", bg = \"dark_orange\" }\n\"ui.cursorline\" = { bg = \"darker\" }\n\"ui.linenr\" = \"dark_gray\"\n\"ui.linenr.selected\" = { fg = \"light_yellow\", bg = \"darker\" }\n\"ui.statusline\" = { fg = \"light_yellow\", bg = \"darker\" }\n\"ui.statusline.inactive\" = { fg = \"dark\", bg = \"darker\" }\n\"ui.statusline.normal\" = { fg = \"light_yellow\", bg = \"darker\" }\n\"ui.statusline.insert\" = { fg = \"darker\", bg = \"purple\" }\n\"ui.statusline.select\" = { fg = \"selectionfg\", bg = \"selection\" }\n\"ui.popup\" = { fg = \"light_yellow\", bg = \"darkest\" }\n\"ui.window\" = { fg = \"dark\", bg = \"darkest\" }\n\"ui.help\" = { fg = \"light_yellow\", bg = \"darkest\" }\n\"ui.text\" = \"light_yellow\"\n\"ui.text.focus\" = { fg = \"white\", bg = \"dark_blue\" }\n\"ui.virtual\" = \"dark\"\n\"ui.virtual.ruler\" = { bg = \"darker\" }\n\"ui.virtual.jump-label\" = { bg = \"light_blue\", fg = \"darkest\", modifiers = [\"bold\"] }\n\"ui.menu\" = { fg = \"light_purple\", bg = \"darkest\" }\n\"ui.menu.selected\" = { fg = \"white\", bg = \"dark_blue\" }\n\"ui.selection.primary\" = { bg = \"light_purple\", fg = \"darkest\" }\n\"ui.selection\" = { bg = \"light_blue\", fg = \"darkest\" }\n\"hint\" = \"blue\"\n\"info\" = \"yellow_accent\"\n\"warning\" = \"orange_accent\"\n\"error\" = \"red_error\"\n\"diagnostic\" = { modifiers = [] }\n\"diagnostic.hint\" = { underline = { color = \"white\", style = \"line\" } }\n\"diagnostic.info\" = { underline = { color = \"blue_accent\", style = \"line\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow_accent\", style = \"line\" } }\n\"diagnostic.error\" = { underline = { color = \"red_error\", style = \"line\" } }\n\n[palette]\nbackground = \"#111111\"\ndarkest = \"#1c1c1c\"\ndarker = \"#292929\"\ndark = \"#898989\"\nwhite = \"#ffffff\"\ndark_gray = \"#535353\"\nlight_gray = \"#6d6d6d\"\n\npurple = \"#833c9f\"\nlight_purple = \"#be67e1\"\n\nblue = \"#048ac7\"\nlight_blue = \"#48c6ff\"\nmid_blue = \"#8197bf\"\ndark_blue = \"#0ac1cd\"\nblue_accent = \"#63e7f0\"\n\ngreen = \"#ccff00\"\ndark_green = \"#cee318\"\n\nred = \"#cc7c8a\"\nred_error = \"#902020\"\nred_accent = \"#f44747\"\n\norange = \"#ff9f00\"\ndark_orange = \"#ff005b\"\norange_accent = \"#ee7f25\"\n\nyellow = \"#fad07a\"\nlight_yellow = \"#ebebd8\"\nyellow_accent = \"#dea407\"\n\ndiff_plus = \"#5a9f81\"\nselection = \"#37232d\"\nselectionfg = \"#e5e5e5\"\n"
  },
  {
    "path": "runtime/themes/bogster.toml",
    "content": "# Author : Wojciech Kępka <wojciech@wkepka.dev>\n\n\"attribute\" = \"bogster-orange\"\n\"keyword\" = { fg = \"bogster-yellow\", modifiers = [\"bold\"] }\n\"keyword.directive\" = \"bogster-yellow\"\n\"namespace\" = \"bogster-red\"\n\"punctuation\" = \"bogster-orange\"\n\"punctuation.delimiter\" = \"bogster-orange\"\n\"operator\" = { fg = \"bogster-orange\", modifiers = [\"bold\"] }\n\"special\" = \"bogster-lgreen\"\n\"variable.other.member\" = \"bogster-fg0\"\n\"variable\" = \"bogster-fg0\"\n\"variable.parameter\" = \"bogster-fg0\"\n\"type\" = \"bogster-lred\"\n\"type.builtin\" = { fg = \"bogster-red\", modifiers = [\"bold\"] }\n\"constructor\" = \"bogster-lred\"\n\"function\" = \"bogster-lblue\"\n\"function.macro\" = { fg = \"bogster-orange\", modifiers = [\"bold\"] }\n\"function.builtin\" = { fg = \"bogster-lblue\", modifiers = [\"bold\"] }\n\"comment\" = \"bogster-base5\"\n\"variable.builtin\" = \"bogster-fg0\"\n\"constant\" = \"bogster-teal\"\n\"constant.builtin\" = \"bogster-teal\"\n\"string\" = \"bogster-teal\"\n\"constant.numeric\" = \"bogster-blue\"\n\"constant.character.escape\" = { fg = \"bogster-lgreen\", modifiers = [\"bold\"] }\n\"label\" = \"bogster-blue\"\n\"module\" = \"bogster-red\"\n\n\"markup.heading\" = \"bogster-blue\"\n\"markup.list\" = \"bogster-red\"\n\"markup.bold\" = { fg = \"bogster-yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"bogster-purp\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"bogster-yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"bogster-red\"\n\"markup.quote\" = \"bogster-teal\"\n\"markup.raw\" = \"bogster-lgreen\"\n\n\"diff.plus\" = \"bogster-teal\"\n\"diff.delta\" = \"bogster-orange\"\n\"diff.minus\" = \"bogster-lred\"\n\n\"ui.background\" = { bg = \"bogster-base1\" }\n\"ui.linenr\" = { fg = \"bogster-base4\" }\n\"ui.linenr.selected\" = { fg = \"bogster-fg1\" }\n\"ui.cursorline\" = { bg = \"bogster-base0\" }\n\"ui.statusline\" = { fg = \"bogster-fg1\", bg = \"bogster-base2\" }\n\"ui.statusline.inactive\" = { fg = \"bogster-fg0\", bg = \"bogster-base2\" }\n\"ui.popup\" = { bg = \"bogster-base2\" }\n\"ui.window\" = { bg = \"bogster-base2\" }\n\"ui.help\" = { bg = \"bogster-base2\", fg = \"bogster-fg1\" }\n\n\"ui.statusline.normal\" = { fg = \"bogster-base1\", bg = \"bogster-blue\", modifiers = [ \"bold\" ]}\n\"ui.statusline.insert\" = { fg = \"bogster-base1\", bg = \"bogster-lgreen\", modifiers = [ \"bold\" ]}\n\"ui.statusline.select\" = { fg = \"bogster-base1\", bg = \"bogster-red\", modifiers = [ \"bold\" ] }\n\n\"ui.text\" = { fg = \"bogster-fg1\" }\n\"ui.text.focus\" = { fg = \"bogster-fg1\", modifiers= [\"bold\"] }\n\"ui.virtual.whitespace\" = \"bogster-base5\"\n\"ui.virtual.ruler\" = { bg = \"bogster-base0\" }\n\"ui.virtual.jump-label\" = { fg = \"bogster-base0\", bg = \"bogster-yellow\", modifiers = [ \"bold\" ] }\n\n\"ui.selection\" = { bg = \"bogster-base2\" }\n\"ui.selection.primary\" = { bg = \"bogster-base3\" }\n\"ui.cursor.match\" = { fg = \"bogster-base3\", bg = \"bogster-orange\" }\n\"ui.cursor\" = { fg = \"bogster-base5\", modifiers = [\"reversed\"] }\n\n\"ui.menu\" = { fg = \"bogster-fg1\", bg = \"bogster-base2\" }\n\"ui.menu.selected\" = { bg = \"bogster-base3\" }\n\n\"warning\" = \"bogster-orange\"\n\"error\" = \"bogster-lred\"\n\"info\" = \"bogster-teal\"\n\"hint\" = \"bogster-blue\"\n\n# make diagnostic underlined, to distinguish with selection text.\n\"diagnostic.warning\" = { underline = { color = \"bogster-orange\", style = \"curl\"} }\n\"diagnostic.error\" = { underline = { color = \"bogster-lred\", style = \"curl\"} }\n\"diagnostic.info\" = { underline = { color = \"bogster-teal\", style = \"curl\"} }\n\"diagnostic.hint\" = { underline = { color = \"bogster-blue\", style = \"curl\"} }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nbogster-yellow = \"#dcb659\"\nbogster-lblue = \"#59dcd8\"\nbogster-teal = \"#59dcb7\"\nbogster-blue = \"#36b2d4\"\nbogster-orange = \"#dc7759\"\nbogster-red = \"#d32c5d\"\nbogster-lgreen = \"#7fdc59\"\nbogster-lred = \"#dc597f\"\nbogster-purp = \"#b759dc\"\n\nbogster-base0 = \"#13181e\"\nbogster-base1 = \"#161c23\" \nbogster-base2 = \"#232d38\"\nbogster-base3 = \"#313f4e\" \nbogster-base4 = \"#415367\" \nbogster-base5 = \"#abb2bf\"\n\nbogster-fg0 = \"#c6b8ad\"\nbogster-fg1 = \"#e5ded6\"\n"
  },
  {
    "path": "runtime/themes/bogster_light.toml",
    "content": "# Author : Wojciech Kępka <wojciech@wkepka.dev>\n\n\"attribute\" = \"bogster-orange\"\n\"keyword\" = { fg = \"bogster-yellow\", modifiers = [\"bold\"] }\n\"keyword.directive\" = \"bogster-yellow\"\n\"namespace\" = \"bogster-red\"\n\"punctuation\" = \"bogster-orange\"\n\"punctuation.delimiter\" = \"bogster-orange\"\n\"operator\" = { fg = \"bogster-orange\", modifiers = [\"bold\"] }\n\"special\" = \"bogster-lgreen\"\n\"variable.other.member\" = \"bogster-fg0\"\n\"variable\" = \"bogster-fg0\"\n\"variable.parameter\" = \"bogster-fg0\"\n\"type\" = \"bogster-lred\"\n\"type.builtin\" = { fg = \"bogster-red\", modifiers = [\"bold\"] }\n\"constructor\" = \"bogster-lred\"\n\"function\" = \"bogster-lblue\"\n\"function.macro\" = { fg = \"bogster-orange\", modifiers = [\"bold\"] }\n\"function.builtin\" = { fg = \"bogster-lblue\", modifiers = [\"bold\"] }\n\"comment\" = \"bogster-base5\"\n\"variable.builtin\" = \"bogster-fg0\"\n\"constant\" = \"bogster-teal\"\n\"constant.builtin\" = \"bogster-teal\"\n\"string\" = \"bogster-teal\"\n\"constant.numeric\" = \"bogster-blue\"\n\"constant.character.escape\" = { fg = \"bogster-lgreen\", modifiers = [\"bold\"] }\n\"label\" = \"bogster-blue\"\n\"module\" = \"bogster-red\"\n\n\"markup.heading\" = \"bogster-blue\"\n\"markup.list\" = \"bogster-red\"\n\"markup.bold\" = { fg = \"bogster-yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"bogster-yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"bogster-red\"\n\"markup.quote\" = \"bogster-lblue\"\n\"markup.raw\" = \"bogster-teal\"\n\n\"diff.plus\" = \"bogster-teal\"\n\"diff.delta\" = \"bogster-orange\"\n\"diff.minus\" = \"bogster-lred\"\n\n\"ui.background\" = { bg = \"bogster-base0\" }\n\"ui.linenr\" = { fg = \"bogster-base3\" }\n\"ui.linenr.selected\" = { fg = \"bogster-fg1\" }\n\"ui.cursorline\" = { bg = \"bogster-base00\" }\n\"ui.statusline\" = { fg = \"bogster-fg1\", bg = \"bogster-base1\" }\n\"ui.statusline.inactive\" = { fg = \"bogster-fg0\", bg = \"bogster-base1\" }\n\"ui.popup\" = { bg = \"bogster-base1\" }\n\"ui.window\" = { bg = \"bogster-base1\" }\n\"ui.help\" = { bg = \"bogster-base1\", fg = \"bogster-fg1\" }\n\n\"ui.statusline.normal\" = { fg = \"bogster-base0\", bg = \"bogster-blue\", modifiers = [ \"bold\" ]}\n\"ui.statusline.insert\" = { fg = \"bogster-base0\", bg = \"bogster-lgreen\", modifiers = [ \"bold\" ]}\n\"ui.statusline.select\" = { fg = \"bogster-base0\", bg = \"bogster-red\", modifiers = [ \"bold\" ] }\n\n\"ui.text\" = { fg = \"bogster-fg1\" }\n\"ui.text.focus\" = { fg = \"bogster-fg1\", modifiers= [\"bold\"] }\n\"ui.virtual.whitespace\" = \"bogster-base5\"\n\"ui.virtual.ruler\" = { bg = \"bogster-base00\" }\n\n\"ui.selection\" = { bg = \"bogster-base1\" }\n\"ui.cursor.match\" = { fg = \"bogster-base2\", bg = \"bogster-orange\" }\n\"ui.cursor\" = { fg = \"bogster-gray\", modifiers = [\"reversed\"] }\n\n\"ui.menu\" = { fg = \"bogster-fg1\", bg = \"bogster-base1\" }\n\"ui.menu.selected\" = { bg = \"bogster-base2\" }\n\n\"warning\" = \"bogster-orange\"\n\"error\" = \"bogster-lred\"\n\"info\" = \"bogster-teal\"\n\"hint\" = \"bogster-blue\"\n\n# make diagnostic underlined, to distinguish with selection text.\n\"diagnostic.warning\" = { underline = { color = \"bogster-orange\", style = \"curl\"} }\n\"diagnostic.error\" = { underline = { color = \"bogster-lred\", style = \"curl\"} }\n\"diagnostic.info\" = { underline = { color = \"bogster-teal\", style = \"curl\"} }\n\"diagnostic.hint\" = { underline = { color = \"bogster-blue\", style = \"curl\"} }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nbogster-orange = \"#dc7759\"\nbogster-yellow = \"#a58023\"\nbogster-red = \"#d32c5d\"\nbogster-blue = \"#59c0dc\"\nbogster-gray = \"#abb2bf\"\nbogster-lgreen = \"#7fdc59\"\nbogster-lred = \"#dc597f\"\nbogster-lblue = \"#289cbc\"\nbogster-teal = \"#23a580\"\n\nbogster-fg1 = \"#161c23\" \nbogster-fg0 = \"#232d38\"\n\nbogster-base00 = \"#d7dbbb\"\nbogster-base0 = \"#f6fbd6\"\nbogster-base1 = \"#c7c7ba\"\nbogster-base2 = \"#aaaa97\" \nbogster-base3 = \"#415367\" \nbogster-base5 = \"#627d9d\"\n\n"
  },
  {
    "path": "runtime/themes/boo_berry.toml",
    "content": "# made by bootra\n\n\"comment\" = { fg = \"berry_desaturated\" }\n\"constant\" = { fg = \"gold\" }\n\"function\" = { fg = \"mint\" }\n\"function.macro\" = { fg = \"bubblegum\" }\n\"keyword\" = { fg = \"bubblegum\" }\n\"operator\" = { fg = \"bubblegum\" }\n\"punctuation\" = { fg = \"lilac\" }\n\"string\" = { fg = \"gold\" }\n\"type\" = { fg = \"violet\" }\n\"variable\" = { fg = \"lilac\" }\n\"variable.builtin\" = { fg = \"violet\" }\n\"tag\" = { fg = \"gold\" }\n\"label\" = { fg = \"gold\" }\n\"attribute\" = { fg = \"lilac\" }\n\"namespace\" = { fg = \"lilac\" }\n\"module\" = { fg = \"lilac\" }\n\n\"markup.heading\" = { fg = \"gold\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = { fg = \"berry_desaturated\" }\n\"markup.list\" = { fg = \"bubblegum\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"violet\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"violet\" }\n\"markup.quote\" = { fg = \"berry_desaturated\" }\n\"markup.raw\" = { fg = \"mint\" }\n\n\"ui.background\" = { bg = \"berry\" }\n\"ui.cursor\" =  { fg = \"berry\", bg = \"lilac\" }\n\"ui.cursor.match\" = { fg = \"berry\", bg = \"berry_desaturated\" }\n\"ui.cursor.select\" = { fg = \"berry\", bg = \"violet\" }\n\"ui.cursor.insert\" = { fg = \"berry\", bg = \"mint\" }\n\"ui.linenr\" = { fg = \"berry_desaturated\" }\n\"ui.linenr.selected\" = { fg = \"lilac\" }\n\"ui.cursorline\" = { fg = \"lilac\", bg = \"berry_dim\" }\n\"ui.statusline\" = { fg = \"lilac\", bg = \"berry_saturated\" }\n\"ui.statusline.inactive\" = { fg = \"berry_desaturated\", bg = \"berry_saturated\" }\n\"ui.statusline.normal\" = { fg = \"berry_saturated\", bg = \"lilac\" }\n\"ui.statusline.insert\" = { fg = \"berry_saturated\", bg = \"mint\" }\n\"ui.statusline.select\" = { fg = \"berry_saturated\", bg = \"violet\" }\n\"ui.popup\" = { fg = \"lilac\", bg = \"berry_saturated\" }\n\"ui.window\" = { fg = \"berry_desaturated\", bg = \"berry\" }\n\"ui.help\" = { fg = \"lilac\", bg = \"berry_saturated\" }\n\"ui.text\" = { fg = \"lilac\" }\n\"ui.text.focus\" = { fg = \"mint\" }\n\"ui.menu\" = { fg = \"lilac\", bg = \"berry_saturated\" }\n\"ui.menu.selected\" = { fg = \"mint\", bg = \"berry_saturated\" }\n\"ui.selection\" = { bg = \"berry_saturated\" }\n\"ui.virtual.whitespace\" = { fg = \"berry_desaturated\" }\n\"ui.virtual.ruler\" = { bg = \"berry_dim\" }\n\"ui.virtual.indent-guide\" = { fg = \"berry_fade\" }\n\"ui.virtual.inlay-hint\" = { fg = \"berry_desaturated\" }\n\n\"diff.plus\" = { fg = \"mint\" }\n\"diff.delta\" = { fg = \"gold\" }\n\"diff.minus\" = { fg = \"bubblegum\" }\n\n\"error\" = { fg = \"bubblegum\" }\n\"warning\" = { fg = \"gold\" }\n\"info\" = { fg = \"lilac\" }\n\"hint\" = { fg = \"lilac\" }\n\n\"diagnostic.warning\" = { underline = { color = \"bubblegum\", style = \"curl\"} }\n\"diagnostic.error\" = { underline = { color = \"gold\", style = \"curl\"} }\n\"diagnostic.info\" = { underline = { color = \"lilac\", style = \"curl\"} }\n\"diagnostic.hint\" = { underline = { color = \"lilac\", style = \"curl\"} }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nberry = \"#3A2A4D\"\nberry_fade = \"#5A3D6E\"\nberry_dim = \"#47345E\"\nberry_saturated = \"#2B1C3D\"\nberry_desaturated = \"#886C9C\"\nbubblegum = \"#D678B5\"\ngold = \"#E3C0A8\"\nlilac = \"#C7B8E0\"\nmint = \"#7FC9AB\"\nviolet = \"#C78DFC\"\n"
  },
  {
    "path": "runtime/themes/carbon.toml",
    "content": "# Syntax highlighting\n\n\"attribute\" = { fg = \"blue60\", modifiers = [\"italic\"] }\n\n\"type\" = { fg = \"cyan30\", modifiers = [\"italic\"] }\n\"type.builtin\" = { fg = \"cyan30\", modifiers = [\"bold\"] }\n\"type.enum.variant\" = \"magenta40\"\n\n\"constructor\" = { fg = \"purple40\", modifiers = [\"bold\"] }\n\n\"constant\" = \"teal40\"\n\"constant.builtin\" = { fg = \"teal40\", modifiers = [\"bold\"] }\n\"constant.character\" = \"green40\"\n\"constant.character.escape\" = \"purple40\"\n\"constant.numeric\" = \"teal30\"\n\n\"string\" = \"green50\"\n\"string.regexp\" = \"purple40\"\n\"string.special\" = \"blue40\"\n\"string.special.symbol\" = \"cyan30\"\n\"string.special.url\" = { fg = \"blue30\", modifiers = [\"underlined\"] }\n\n\"comment\" = { fg = \"gray40\", modifiers = [\"italic\"] }\n\"comment.block.documentation\" = { fg = \"gray40\", modifiers = [\"italic\"] }\n\"comment.line.documentation\" = { fg = \"gray40\", modifiers = [\"italic\"] }\n\n\"variable\" = \"gray70\"\n\"variable.builtin\" = { fg = \"cyan30\", modifiers = [\"bold\"] }\n\"variable.parameter\" = { fg = \"magenta40\", modifiers = [\"italic\"] }\n\"variable.other.member\" = { fg = \"magenta30\", modifiers = [\"italic\"] }\n\n\"label\" = { fg = \"blue40\", modifiers = [\"italic\"] }\n\n\"punctuation\" = \"gray70\"\n\"punctuation.special\" = \"blue50\"\n\"punctuation.bracket\" = \"gray60\"\n\"punctuation.delimiter\" = \"gray60\"\n\n\"keyword\" = { fg = \"blue50\", modifiers = [\"bold\"] }\n\"keyword.control\" = { fg = \"blue50\", modifiers = [\"bold\"] }\n\"keyword.control.conditional\" = { fg = \"blue50\", modifiers = [\"bold\"] }\n\"keyword.control.repeat\" = { fg = \"blue50\", modifiers = [\"bold\"] }\n\"keyword.control.import\" = { fg = \"purple40\", modifiers = [\"bold\"] }\n\"keyword.control.return\" = { fg = \"red50\", modifiers = [\"bold\"] }\n\"keyword.control.exception\" = { fg = \"red40\", modifiers = [\"bold\"] }\n\"keyword.operator\" = \"blue40\"\n\"keyword.function\" = { fg = \"teal40\", modifiers = [\"bold\", \"italic\"] }\n\"keyword.storage\" = { fg = \"purple50\", modifiers = [\"bold\"] }\n\"keyword.storage.modifier\" = { fg = \"purple40\", modifiers = [\"italic\"] }\n\n\"operator\" = \"blue50\"\n\n\"function\" = { fg = \"blue40\", modifiers = [\"bold\"] }\n\"function.builtin\" = { fg = \"blue50\", modifiers = [\"bold\"] }\n\"function.method\" = { fg = \"blue40\", modifiers = [\"bold\"] }\n# \"function.macro\" = { fg = \"purple30\", modifiers = [\"bold\", \"italic\"] }\n\n\"tag\" = \"cyan40\"\n\"tag.builtin\" = { fg = \"cyan40\", modifiers = [\"bold\"] }\n\n\"namespace\" = { fg = \"teal40\", modifiers = [\"italic\"] }\n\n\"special\" = \"purple40\"\n\n# Markup\n\"markup.heading\" = { fg = \"blue50\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = { fg = \"gray60\", modifiers = [\"bold\"] }\n\"markup.heading.1\" = { fg = \"blue40\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"cyan40\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"teal40\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"green40\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"purple40\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"magenta40\", modifiers = [\"bold\"] }\n\"markup.list\" = \"blue30\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link.url\" = { fg = \"blue30\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"cyan30\"\n\"markup.quote\" = { fg = \"green30\", modifiers = [\"italic\"] }\n\"markup.raw\" = \"teal30\"\n\n# Diff\n\"diff.plus\" = \"green40\"\n\"diff.minus\" = \"red40\"\n\"diff.delta\" = \"blue40\"\n\"diff.delta.moved\" = \"purple40\"\n\n# UI Elements\n\"ui.background\" = { fg = \"gray70\", bg = \"gray10\" }\n\"ui.background.separator\" = { fg = \"gray30\" }\n\n\"ui.cursor\" = { fg = \"gray10\", bg = \"blue50\" }\n\"ui.cursor.normal\" = { fg = \"gray10\", bg = \"blue50\" }\n\"ui.cursor.insert\" = { fg = \"gray10\", bg = \"green50\" }\n\"ui.cursor.select\" = { fg = \"gray10\", bg = \"purple50\" }\n\"ui.cursor.match\" = { fg = \"gray10\", bg = \"cyan40\" }\n\n\"ui.cursor.primary\" = { fg = \"gray10\", bg = \"blue60\" }\n\"ui.cursor.primary.normal\" = { fg = \"gray10\", bg = \"blue60\" }\n\"ui.cursor.primary.insert\" = { fg = \"gray10\", bg = \"green60\" }\n\"ui.cursor.primary.select\" = { fg = \"gray10\", bg = \"purple60\" }\n\n\"ui.linenr\" = { fg = \"gray40\" }\n\"ui.linenr.selected\" = { fg = \"gray70\" }\n\n\"ui.statusline\" = { fg = \"gray70\", bg = \"gray20\" }\n\"ui.statusline.inactive\" = { fg = \"gray50\", bg = \"gray20\" }\n\"ui.statusline.normal\" = { fg = \"gray10\", bg = \"blue50\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"gray10\", bg = \"green50\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"gray10\", bg = \"purple50\", modifiers = [\"bold\"] }\n\n\"ui.popup\" = { fg = \"gray70\", bg = \"gray20\" }\n\"ui.popup.info\" = { fg = \"blue40\", bg = \"gray20\" }\n\"ui.window\" = { fg = \"gray30\" }\n\"ui.help\" = { fg = \"gray70\", bg = \"gray20\" }\n\n\"ui.text\" = \"gray70\"\n\"ui.text.focus\" = { fg = \"gray70\", bg = \"gray30\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = { fg = \"gray50\" }\n\"ui.text.info\" = { fg = \"blue40\" }\n\n\"ui.virtual.ruler\" = { bg = \"gray20\" }\n\"ui.virtual.whitespace\" = \"gray30\"\n\"ui.virtual.indent-guide\" = \"gray30\"\n\"ui.virtual.inlay-hint\" = { fg = \"gray50\", bg = \"gray10\" }\n\"ui.virtual.jump-label\" = { fg = \"yellow50\", bg = \"gray10\" }\n\n\"ui.selection\" = { bg = \"gray30\" }\n\"ui.selection.primary\" = { bg = \"gray40\" }\n\"ui.cursorline.primary\" = { bg = \"gray20\" }\n\n\"ui.highlight\" = { bg = \"gray30\", modifiers = [\"bold\"] }\n\"ui.highlight.frameline\" = { bg = \"blue20\" }\n\n\"ui.menu\" = { fg = \"gray70\", bg = \"gray20\" }\n\"ui.menu.selected\" = { fg = \"gray70\", bg = \"gray30\", modifiers = [\"bold\"] }\n\"ui.menu.scroll\" = { fg = \"blue40\", bg = \"gray30\" }\n\n# Diagnostics\n\"diagnostic\" = { fg = \"gray60\" }\n\"diagnostic.error\" = { underline = { color = \"magenta30\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow30\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue40\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"cyan40\", style = \"curl\" } }\n\n\"error\" = \"magenta30\"\n\"warning\" = \"yellow30\"\n\"info\" = \"blue40\"\n\"hint\" = \"cyan40\"\n\n[palette]\n# Softer, more aesthetic color palette inspired by IBM Carbon\ngray10 = \"#161616\"\ngray20 = \"#262626\"\ngray30 = \"#393939\"\ngray40 = \"#525252\"\ngray50 = \"#6F6F6F\"\ngray60 = \"#8D8D8D\"\ngray70 = \"#a8a8a8\"\ngray80 = \"#c8ccd4\"\n\n# Softer blues\nblue20 = \"#0043ce\"\nblue30 = \"#4589ff\"\nblue40 = \"#78a9ff\"\nblue50 = \"#82cfff\"\nblue60 = \"#bae6ff\"\n\n# Softer cyans\ncyan30 = \"#08bdba\"\ncyan40 = \"#3ddbd9\"\ncyan50 = \"#9ef0f0\"\n\n# Softer, more muted greens\ngreen30 = \"#42be65\"  # Softened\ngreen40 = \"#6fdc8c\"  # More pastel\ngreen50 = \"#a7f0ba\"  # Even softer\ngreen60 = \"#defbe6\"  # Very soft\n\n# Pinks and magentas (more prominent as per your preference)\nmagenta30 = \"#ff7eb6\"  # Your original pink\nmagenta40 = \"#ff9ec7\"  # Lighter pink\nmagenta50 = \"#ffd6e8\"  # Very soft pink\n\n# Softer purples\npurple30 = \"#a56eff\"\npurple40 = \"#be95ff\"\npurple50 = \"#d4bbff\"\npurple60 = \"#e8daff\"\n\n# Softer reds with pink undertones\nred30 = \"#ff8389\"    # Softer red\nred40 = \"#ffa4a9\"    # Pink-red\nred50 = \"#ffd7d9\"    # Very soft\n\n# Softer teals\nteal30 = \"#08bdba\"\nteal40 = \"#3ddbd9\"\nteal50 = \"#9ef0f0\"\n\n# Warmer, softer yellows\nyellow30 = \"#f1c21b\"\nyellow40 = \"#fddc69\"\nyellow50 = \"#fff1d2\"\n"
  },
  {
    "path": "runtime/themes/carbonfox.toml",
    "content": "# Author: github.com/ETCaton\n# License: MIT License\n# Carbonfox\n#\n# Based on Helix's Nightfox port with changes to align it to Nightfox's Carbonfox theme\n# Any 'custom' colors are replicating the result of the linear color blending done in the original\n# Neovim theme.\n# https://github.com/EdenEast/nightfox.nvim/blob/d3e8b1acc095baf57af81bb5e89fe7c4359eb619/lua/nightfox/lib/color.lua#L236-L247\n\ninherits = 'nightfox'\n\n# DIAGNOSTICS\n# For brevity: All blends here are a blend between bg1 and the fg value with factor of 0.15\n\"warning\"  = { fg = \"magenta\", bg = \"#2f2939\" }\n\"error.bg\" = \"#361f29\"\n\"info.bg\"  = \"#252c39\"\n\"hint\"     = { fg = \"orange\", bg = \"#1c3433\" }\n\n[palette]\nblack          = \"#282828\"\nred            = \"#ee5396\"\nred-dim        = \"#ca4780\"\ngreen          = \"#25be6a\"\ngreen-dim      = \"#1fa25a\"\nyellow         = \"#08bdba\"\nyellow-bright  = \"#2dc7c4\"\nblue           = \"#78a9ff\"\nblue-bright    = \"#8cb6ff\"\nblue-dim       = \"#6690d9\"\nmagenta        = \"#be95ff\"\nmagenta-bright = \"#c8a5ff\"\ncyan           = \"#33b1ff\"\ncyan-bright    = \"#52bdff\"\ncyan-dim       = \"#2b96d9\"\norange         = \"#3ddbd9\"\norange-bright  = \"#5ae0df\"\npink           = \"#ff7eb6\"\npink-bright    = \"#ff91c1\"\n# spec\nbg0            = \"#0c0c0c\"\nbg1            = \"#161616\"\nbg2            = \"#252525\"\nbg3            = \"#353535\"\nbg4            = \"#535353\"\nfg0            = \"#f9fbff\"\nfg1            = \"#f2f4f8\"\nfg2            = \"#b6b8bb\"\nfg3            = \"#7b7c7e\"\nsel0           = \"#2a2a2a\"\nsel1           = \"#525253\"\n"
  },
  {
    "path": "runtime/themes/catppuccin_frappe.toml",
    "content": "inherits = \"catppuccin_mocha\"\n\n[palette]\nrosewater = \"#f2d5cf\"\nflamingo = \"#eebebe\"\npink = \"#f4b8e4\"\nmauve = \"#ca9ee6\"\nred = \"#e78284\"\nmaroon = \"#ea999c\"\npeach = \"#ef9f76\"\nyellow = \"#e5c890\"\ngreen = \"#a6d189\"\nteal = \"#81c8be\"\nsky = \"#99d1db\"\nsapphire = \"#85c1dc\"\nblue = \"#8caaee\"\nlavender = \"#babbf1\"\ntext = \"#c6d0f5\"\nsubtext1 = \"#b5bfe2\"\nsubtext0 = \"#a5adce\"\noverlay2 = \"#949cbb\"\noverlay1 = \"#838ba7\"\noverlay0 = \"#737994\"\nsurface2 = \"#626880\"\nsurface1 = \"#51576d\"\nsurface0 = \"#414559\"\nbase = \"#303446\"\nmantle = \"#292c3c\"\ncrust = \"#232634\"\n\ncursorline = \"#3b3f52\"\nsecondary_cursor = \"#b8a5a6\"\nsecondary_cursor_normal = \"#9192be\"\nsecondary_cursor_insert = \"#83a275\"\n"
  },
  {
    "path": "runtime/themes/catppuccin_latte.toml",
    "content": "inherits = \"catppuccin_mocha\"\n\n[palette]\nrosewater = \"#dc8a78\"\nflamingo = \"#dd7878\"\npink = \"#ea76cb\"\nmauve = \"#8839ef\"\nred = \"#d20f39\"\nmaroon = \"#e64553\"\npeach = \"#fe640b\"\nyellow = \"#df8e1d\"\ngreen = \"#40a02b\"\nteal = \"#179299\"\nsky = \"#04a5e5\"\nsapphire = \"#209fb5\"\nblue = \"#1e66f5\"\nlavender = \"#7287fd\"\ntext = \"#4c4f69\"\nsubtext1 = \"#5c5f77\"\nsubtext0 = \"#6c6f85\"\noverlay2 = \"#7c7f93\"\noverlay1 = \"#8c8fa1\"\noverlay0 = \"#9ca0b0\"\nsurface2 = \"#acb0be\"\nsurface1 = \"#bcc0cc\"\nsurface0 = \"#ccd0da\"\nbase = \"#eff1f5\"\nmantle = \"#e6e9ef\"\ncrust = \"#dce0e8\"\n\ncursorline = \"#e8ecf1\"\nsecondary_cursor = \"#e1a99d\"\nsecondary_cursor_normal = \"#97a7fb\"\nsecondary_cursor_insert = \"#74b867\"\n"
  },
  {
    "path": "runtime/themes/catppuccin_macchiato.toml",
    "content": "inherits = \"catppuccin_mocha\"\n\n[palette]\nrosewater = \"#f4dbd6\"\nflamingo = \"#f0c6c6\"\npink = \"#f5bde6\"\nmauve = \"#c6a0f6\"\nred = \"#ed8796\"\nmaroon = \"#ee99a0\"\npeach = \"#f5a97f\"\nyellow = \"#eed49f\"\ngreen = \"#a6da95\"\nteal = \"#8bd5ca\"\nsky = \"#91d7e3\"\nsapphire = \"#7dc4e4\"\nblue = \"#8aadf4\"\nlavender = \"#b7bdf8\"\ntext = \"#cad3f5\"\nsubtext1 = \"#b8c0e0\"\nsubtext0 = \"#a5adcb\"\noverlay2 = \"#939ab7\"\noverlay1 = \"#8087a2\"\noverlay0 = \"#6e738d\"\nsurface2 = \"#5b6078\"\nsurface1 = \"#494d64\"\nsurface0 = \"#363a4f\"\nbase = \"#24273a\"\nmantle = \"#1e2030\"\ncrust = \"#181926\"\n\ncursorline = \"#303347\"\nsecondary_cursor = \"#b6a6a7\"\nsecondary_cursor_normal = \"#8b91bf\"\nsecondary_cursor_insert = \"#80a57a\"\n"
  },
  {
    "path": "runtime/themes/catppuccin_mocha.toml",
    "content": "# NOTE: For contributors looking to modify the theme, please submit a pull request at https://github.com/catppuccin/helix instead of updating this file. Changes are frequently synchronized from the catppuccin/helix theme repository.\n# Syntax highlighting\n# -------------------\n\"attribute\" = \"yellow\"\n\n\"type\" = \"yellow\"\n\"type.enum.variant\" = \"teal\"\n\n\"constructor\" = \"sapphire\"\n\n\"constant\" = \"peach\"\n\"constant.character\" = \"teal\"\n\"constant.character.escape\" = \"pink\"\n\n\"string\" = \"green\"\n\"string.regexp\" = \"pink\"\n\"string.special\" = \"blue\"\n\"string.special.symbol\" = \"red\"\n\n\"comment\" = { fg = \"overlay2\", modifiers = [\"italic\"] }\n\n\"variable\" = \"text\"\n\"variable.parameter\" = { fg = \"maroon\", modifiers = [\"italic\"] }\n\"variable.builtin\" = \"red\"\n\"variable.other.member\" = \"blue\"\n\n\"label\" = \"sapphire\" # used for lifetimes\n\n\"punctuation\" = \"overlay2\"\n\"punctuation.special\" = \"sky\"\n\n\"keyword\" = \"mauve\"\n\"keyword.control.conditional\" = { fg = \"mauve\", modifiers = [\"italic\"] }\n\n\"operator\" = \"sky\"\n\n\"function\" = \"blue\"\n\"function.macro\" = \"mauve\"\n\n\"tag\" = \"blue\"\n\n\"namespace\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\n\"special\" = \"blue\" # fuzzy highlight\n\n\"markup.heading.1\" = \"red\"\n\"markup.heading.2\" = \"peach\"\n\"markup.heading.3\" = \"yellow\"\n\"markup.heading.4\" = \"green\"\n\"markup.heading.5\" = \"sapphire\"\n\"markup.heading.6\" = \"lavender\"\n\"markup.list\" = \"teal\"\n\"markup.list.unchecked\" = \"overlay2\"\n\"markup.list.checked\" = \"green\"\n\"markup.bold\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"red\", modifiers = [\"italic\"] }\n\"markup.link.url\" = { fg = \"blue\", modifiers = [\"italic\", \"underlined\"] }\n\"markup.link.text\" = \"lavender\"\n\"markup.link.label\" = \"sapphire\"\n\"markup.raw\" = \"green\"\n\"markup.quote\" = \"pink\"\n\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"blue\"\n\n# User Interface\n# --------------\n\"ui.background\" = { fg = \"text\", bg = \"base\" }\n\n\"ui.linenr\" = { fg = \"surface1\" }\n\"ui.linenr.selected\" = { fg = \"lavender\" }\n\n\"ui.statusline\" = { fg = \"subtext1\", bg = \"mantle\" }\n\"ui.statusline.inactive\" = { fg = \"surface2\", bg = \"mantle\" }\n\"ui.statusline.normal\" = { fg = \"base\", bg = \"rosewater\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"base\", bg = \"green\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"base\", bg = \"lavender\", modifiers = [\"bold\"] }\n\n\"ui.popup\" = { fg = \"text\", bg = \"surface0\" }\n\"ui.window\" = { fg = \"crust\" }\n\"ui.help\" = { fg = \"overlay2\", bg = \"surface0\" }\n\n\"ui.bufferline\" = { fg = \"subtext0\", bg = \"mantle\" }\n\"ui.bufferline.active\" = { fg = \"mauve\", bg = \"base\", underline = { color = \"mauve\", style = \"line\" } }\n\"ui.bufferline.background\" = { bg = \"crust\" }\n\n\"ui.text\" = \"text\"\n\"ui.text.focus\" = { fg = \"text\", bg = \"surface0\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = { fg = \"overlay1\" }\n\"ui.text.directory\" = { fg = \"blue\" }\n\n\"ui.virtual\" = \"overlay0\"\n\"ui.virtual.ruler\" = { bg = \"surface0\" }\n\"ui.virtual.indent-guide\" = \"surface0\"\n\"ui.virtual.inlay-hint\" = { fg = \"surface1\", bg = \"mantle\" }\n\"ui.virtual.jump-label\" = { fg = \"rosewater\", modifiers = [\"bold\"] }\n\n\"ui.selection\" = { bg = \"surface1\" }\n\n\"ui.cursor\" = { fg = \"base\", bg = \"secondary_cursor\" }\n\"ui.cursor.primary\" = { fg = \"base\", bg = \"rosewater\" }\n\"ui.cursor.match\" = { fg = \"peach\", modifiers = [\"bold\"] }\n\n\"ui.cursor.primary.normal\" = { fg = \"base\", bg = \"rosewater\" }\n\"ui.cursor.primary.insert\" = { fg = \"base\", bg = \"green\" }\n\"ui.cursor.primary.select\" = { fg = \"base\", bg = \"lavender\" }\n\n\"ui.cursor.normal\" = { fg = \"base\", bg = \"secondary_cursor_normal\" }\n\"ui.cursor.insert\" = { fg = \"base\", bg = \"secondary_cursor_insert\" }\n\"ui.cursor.select\" = { fg = \"base\", bg = \"secondary_cursor_select\" }\n\n\"ui.cursorline.primary\" = { bg = \"cursorline\" }\n\n\"ui.highlight\" = { bg = \"surface1\", modifiers = [\"bold\"] }\n\n\"ui.menu\" = { fg = \"overlay2\", bg = \"surface0\" }\n\"ui.menu.selected\" = { fg = \"text\", bg = \"surface1\", modifiers = [\"bold\"] }\n\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"sky\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"teal\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\nerror = \"red\"\nwarning = \"yellow\"\ninfo = \"sky\"\nhint = \"teal\"\n\nrainbow = [\"red\", \"peach\", \"yellow\", \"green\", \"sapphire\", \"lavender\"]\n\n[palette]\nrosewater = \"#f5e0dc\"\nflamingo = \"#f2cdcd\"\npink = \"#f5c2e7\"\nmauve = \"#cba6f7\"\nred = \"#f38ba8\"\nmaroon = \"#eba0ac\"\npeach = \"#fab387\"\nyellow = \"#f9e2af\"\ngreen = \"#a6e3a1\"\nteal = \"#94e2d5\"\nsky = \"#89dceb\"\nsapphire = \"#74c7ec\"\nblue = \"#89b4fa\"\nlavender = \"#b4befe\"\ntext = \"#cdd6f4\"\nsubtext1 = \"#bac2de\"\nsubtext0 = \"#a6adc8\"\noverlay2 = \"#9399b2\"\noverlay1 = \"#7f849c\"\noverlay0 = \"#6c7086\"\nsurface2 = \"#585b70\"\nsurface1 = \"#45475a\"\nsurface0 = \"#313244\"\nbase = \"#1e1e2e\"\nmantle = \"#181825\"\ncrust = \"#11111b\"\n\ncursorline = \"#2a2b3c\"\nsecondary_cursor = \"#b5a6a8\"\nsecondary_cursor_select = \"#878ec0\"\nsecondary_cursor_normal = \"#b5a6a8\"\nsecondary_cursor_insert = \"#7ea87f\"\n"
  },
  {
    "path": "runtime/themes/curzon.toml",
    "content": "attribute_color = \"attribute_color\"\nkeyword = \"keyword_foreground_color\"\n\"keyword.directive\" = \"light_blue\" \nnamespace = \"light_blue\"\npunctuation = \"punctuation_color\"\n\"punctuation.delimiter\" = \"punctuation_color\"\noperator = \"operator_color\"\nspecial = \"label\"\n\"variable.other.member\" = \"white\"\nvariable = \"variable\"\n\"variable.parameter\" = { fg = \"variable\" }\n\"variable.builtin\" = {fg = \"built_in\", modifiers=[\"bold\",\"italic\"]}\ntype = \"white\"\n\"type.builtin\" = \"white\" \nconstructor = \"light_blue\"\nfunction = \"white\"\n\"function.macro\" = {fg =\"light_blue\" }\n\"function.builtin\" = \"white\"\ntag = \"tag\"\ncomment = { fg = \"comment_color\", modifiers = [\"italic\"] }\nconstant = {fg =\"white\"}\n\"constant.builtin\" = \"white\"\nstring = {fg=\"string\", modifiers=[\"italic\"]}\n\"constant.numeric\" = \"constant_numeric_foreground_color\"\n\"constant.character.escape\" = \"label\"\n# used for lifetimes\nlabel = \"label\"\n\n\"markup.heading\" = \"light_blue\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"link_url_foreground_color\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"markup_link_foreground_color\"\n\"markup.raw\" = \"markup_raw_foreground_color\"\n\n\"diff.plus\" = \"#35bf86\"\n\"diff.minus\" = \"#f22c86\"\n\"diff.delta\" = \"info\"\n\n\"ui.background\" = { bg = \"black\" }\n\"ui.background.separator\" = { fg = \"window_color\" }\n\"ui.linenr\" = { fg = \"window_color\" }\n\"ui.linenr.selected\" = { fg = \"light_blue\" }\n\"ui.statusline\" = { fg = \"statusline_foreground_color\", bg = \"black\" }\n\"ui.statusline.inactive\" = { fg = \"statusline_inactive_foreground_color\", bg = \"black\" }\n\"ui.virtual.ruler\" = { bg = \"dark\"}\n\n\"ui.popup\" = {  fg = \"menu_normal_text_color\", bg = \"menu_background_color\"  }\n\"ui.window\" = { fg = \"dark\"}\n\"ui.help\" = {  fg = \"menu_normal_text_color\", bg = \"menu_background_color\"  }\n\n\"ui.text\" = { fg = \"text\" }\n\"ui.text.focus\" = { fg = \"white\" }\n\"ui.text.inactive\" = \"comment_color\"\n\"ui.virtual\" = { fg = \"#008DFF\" }\n\n\"ui.virtual.indent-guide\" = { fg = \"window_color\" }\n\n\"ui.selection\" = { bg = \"#4f46e5\" }\n\"ui.selection.primary\" = { bg = \"#4f46e5\" }\n\"ui.cursor.select\" = { bg = \"cursor_normal_bg_color\" }\n\"ui.cursor.primary.insert\" = { bg = \"#f43f5e\", fg = \"white\" }\n\"ui.cursor.match\" = { fg = \"#212121\", bg = \"#6C6999\" }\n\"ui.cursorline.primary\" = { bg = \"dark\"}\n\"ui.highlight\" = { bg = \"dark\" }\n\"ui.highlight.frameline\" = { bg = \"#634450\" }\n\"ui.debug\" = { fg = \"#634450\" }\n\"ui.debug.breakpoint\" = { fg = \"debug_breakpoint\" }\n\"ui.menu\" = { fg = \"menu_normal_text_color\", bg = \"menu_background_color\" }\n\"ui.menu.selected\" = { fg = \"menu_background_color\", bg = \"white\" }\n\"ui.menu.scroll\" = { fg = \"menu_scroll\", bg = \"window_color\" }\n\n\"diagnostic.hint\" = { underline = { color = \"hint\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"info\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"warning\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"error\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nwarning = \"warning\"\nerror = \"#f43f5e\"\ninfo = \"info\"\nhint = \"#38bdf8\"\n\n[palette]\nlabel = \"#efba5d\"\nconstant_numeric_foreground_color = \"#E8DCA0\"\ntag = \"#eccdba\"\nmarkup_link_foreground_color = \"#eccdba\"\nmarkup_raw_foreground_color = \"#eccdba\"\nkeyword_foreground_color=\"#eccdba\" # alternative color \"#ecc1ba\"\ncomment_color = \"#697C81\"\nlink_url_foreground_color=\"#b8b8b8\"\ndebug_breakpoint = \"#f47868\"\nwindow_color = \"#484a4d\"\nlight_blue = \"#bee0ec\" #change name \ntext=\"#bfdbfe\"\nblack = \"#000000\"\nwhite = \"#ffffff\"\ndark= \"#111111\"\npunctuation_color = \"#a4a0e8\"\nstring=\"#6ee7b7\"\nattribute_color=\"#dbbfef\"\noperator_color=\"#bee0ec\"\nmenu_background_color=\"#1e3a8a\"\nmenu_normal_text_color=\"#93c5fd\"\nstatusline_active_background_color=\"#111111\"\nstatusline_inactive_background_color=\"#0e0e0e\"\nstatusline_inactive_foreground_color=\"#b8b8b8\"\npopup_background_color=\"#1e3a8a\"\ncursor_normal_bg_color=\"#6366f1\"\nwarning=\"#ffcd1c\"\nerror = \"#f43f5e\"\nhint = \"#38bdf8\"\ninfo = \"#6366f1\"\nvariable=\"#c7d2fe\"\nmenu_scroll=\"#93c5fd\"\nbuilt_in=\"#10b981\"\nstatusline_foreground_color=\"#6366f1\"\n"
  },
  {
    "path": "runtime/themes/cyan_light.toml",
    "content": "# Deprecation notice\n#\n# This theme has moved to jetbrains_cyan_light, make sure to update your configuration accordingly.\n\ninherits = \"jetbrains_cyan_light\"\n"
  },
  {
    "path": "runtime/themes/darcula-solid.toml",
    "content": "# Original source and more info: https://github.com/jesusmgg/darcula-solid-helix\n\ninherits = \"darcula\"\n\n\"ui.background.separator\" = { bg = \"grey01\" }\n\"ui.menu.scroll\" = { fg = \"grey02\", bg = \"grey00\" }\n\"ui.popup\" = { fg = \"grey05\", bg = \"grey00\" }\n\"ui.window\" = { bg = \"grey00\" }\n\"ui.cursorline.secondary\" = { bg = \"grey03\" }\n\n[palette]\ngrey00 = \"#101010\"\ngrey01 = \"#1f1f1f\"\ngrey02 = \"#323232\"\ngrey03 = \"#555555\"\ngrey04 = \"#a8a8a8\"\n"
  },
  {
    "path": "runtime/themes/darcula.toml",
    "content": "# Author : Nick Ogden <nick@nickogden.org>\n\n\"ui.background\" = { bg = \"grey01\" }\n\"ui.menu\" = { fg = \"grey05\", bg = \"grey00\" }\n\"ui.menu.selected\" = { fg = \"grey01\", bg = \"grey04\" }\n\"ui.linenr\" = { fg = \"grey03\", bg = \"grey01\" }\n\"ui.linenr.selected\" = { fg = \"grey04\", bg = \"grey01\", modifiers = [\"bold\"] }\n\"ui.gutter\" = { bg = \"grey01\" }\n\"ui.popup\" = { fg = \"grey05\", bg = \"grey00\" }\n\"ui.window\" = { bg = \"grey01\" }\n\"ui.selection\" = { bg = \"grey02\" }\n\"ui.selection.primary\" = { bg = \"blue\" }\n\"ui.statusline\" = { fg = \"grey04\", bg = \"grey02\" }\n\"ui.statusline.insert\" = { bg = \"white\", fg = \"grey01\" }\n\"ui.statusline.select\" = { bg = \"orange\", fg = \"grey01\" }\n\"ui.help\" = { fg = \"grey04\", bg = \"grey01\" }\n\"ui.cursor\" = { fg = \"grey04\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"grey02\", bg = \"grey05\" }\n\"ui.cursor.match\" = { fg = \"white\", modifiers = [\"underlined\"] }\n\"ui.cursorline.primary\" = { bg = \"grey02\" }\n\"ui.cursorline.secondary\" = { bg = \"grey02\" }\n\"ui.text\" = \"white\"\n\"ui.text.focus\" = \"grey05\"\n\"ui.virtual.ruler\" = { bg = \"grey02\" }\n\"ui.virtual.indent-guide\" = \"grey02\"\n\"ui.virtual.whitespace\" = \"grey03\"\n\"ui.virtual.inlay-hint\" = { fg = \"grey03\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"lightblue\", modifiers = [\"italic\", \"bold\"] }\n\"ui.bufferline\" = { fg = \"grey04\", bg = \"grey00\" }\n\"ui.bufferline.active\" = { fg = \"grey07\", bg = \"grey02\" }\n\"ui.picker.header.column\" = { fg = \"grey05\", modifiers = [\"italic\", \"bold\"] }\n\"ui.picker.header.column.active\" = { fg = \"grey05\", bg = \"grey03\", modifiers = [\"italic\", \"bold\"] }\n\n\"operator\" = \"grey05\"\n\"variable\" = \"white\"\n\"variable.other.member\" = \"yellow\"\n\"constant\" = \"lightblue\"\n\"constant.numeric\" = \"lightblue\"\n\"constant.character.escape\" = \"white\"\n\"attribute\" = \"yellow\"\n\"type\" = \"white\"\n\"type.builtin\" = \"orange\"\n\"type.parameter\" = { fg = \"white\", modifiers = [\"bold\"] }\n\"type.enum\" = \"white\"\n\"type.enum.variant\" = \"orange\"\n\"string\"  = \"darkgreen\"\n\"function\" = \"yellow\"\n\"function.macro\" = \"green\"\n\"constructor\" = \"yellow\"\n\"special\" = \"green\"\n\"keyword\" = \"orange\"\n\"comment\" = { fg = \"grey\", modifiers = [\"italic\"] }\n\"label\" = \"purple\"\n\"namespace\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\n# HTML\n\"tag\" = \"orange\"\n\n\"markup.heading.1\" = \"orange\"\n\"markup.heading.2\" = \"yellow\"\n\"markup.heading.3\" = \"darkred\"\n\"markup.heading.4\" = \"grey\"\n\"markup.heading.5\" = \"purple\"\n\"markup.heading.6\" = \"darkgreen\"\n\"markup.list\" = \"white\"\n\"markup.bold\" = { fg = \"white\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"white\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { fg = \"white\", modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"lightblue\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"white\"\n\"markup.quote\" = \"darkgreen\"\n\"markup.raw\" = \"purple\"\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"grey\"\n\"diff.minus\" = \"red\"\n\n\"diagnostic.warning\" = { underline = { color = \"orange\", style = \"curl\"} }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\"} }\n\"diagnostic.info\" = { underline = { color = \"grey05\", style = \"curl\"} }\n\"diagnostic.hint\" = { underline = { color = \"grey05\", style = \"curl\"} }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"info\" = \"grey05\"\n\"hint\" = \"grey05\"\n\"debug\" = \"grey05\"\n\"warning\" = \"orange\"\n\"error\" = \"red\"\n\nrainbow = [\"rainbow_gold\", \"rainbow_blue\", \"rainbow_orange\", \"rainbow_purple\", \"rainbow_khaki\", \"rainbow_turquoise\"]\n\n[palette]\ngrey00 = \"#181818\" # Default Background\ngrey01 = \"#282828\" # Lighter Background (Used for status bars, line number and folding marks)\ngrey02 = \"#383838\" # Selection Background\ngrey03 = \"#585858\" # Comments, Invisibles, Line Highlighting\ngrey04 = \"#b8b8b8\" # Dark Foreground (Used for status bars)\ngrey05 = \"#d8d8d8\" # Default Foreground, Caret, Delimiters, Operators\ngrey06 = \"#e8e8e8\" # Light Foreground (Not often used)\ngrey07 = \"#f8f8f8\" # Light Background (Not often used)\n\nwhite = \"#d0d0d0\"\nyellow = \"#eedd82\"\norange = \"#cc7832\"\ndarkred = \"#a34a27\"\npurple = \"#9876aa\"\ngreen = \"#32cd32\"\ngrey = \"#808080\"\ndarkgreen = \"#629755\"\nlightblue = \"#6897bb\"\nblue = \"#104158\"\n\n# Rainbow bracket colors\nrainbow_gold = \"#FFD700\"\nrainbow_blue = \"#1E90FF\"\nrainbow_orange = \"#FF8C00\"\nrainbow_purple = \"#9370DB\"\nrainbow_khaki = \"#F0E68C\"\nrainbow_turquoise = \"#00CED1\" \n"
  },
  {
    "path": "runtime/themes/dark-synthwave.toml",
    "content": "# Dark Synthwave\n# Based on Dark SynthWave '84 for VS Code (https://github.com/brainomite/dark-synthwave-vscode/tree/main)\n# \n# Author : Peter Retzlaff <pe.retzlaff@gmail.com>\n# License: MIT License\n\n# UI Colors\n\"ui.background\" = { bg = \"black\", fg = \"blood-red\" }\n\"ui.cursor\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { bg = \"selection-blue\" }\n\"ui.text\" = \"white\"\n\"ui.text.focus\" = { fg = \"dark-grey\", bg = \"synth-red\" }\n\"ui.text.inactive\" = \"grey\"\n\"ui.linenr\" = \"grey\"\n\"ui.linenr.selected\" = \"white\"\n\"ui.statusline\" = { fg = \"white\", bg = \"black\" }\n\"ui.statusline.inactive\" = { fg = \"grey\", bg = \"black\"}\n\"ui.statusline.separator\" = \"synth-red\"\n\"ui.popup\" = { fg = \"#f8f8f0\", bg = \"#1E1E1E\" }\n\"ui.popup.info\" = { fg = \"synth-red\", bg = \"black\" }\n\"ui.window\" = \"synth-red\"\n\"ui.help\" = { fg = \"#f8f8f0\", bg = \"#1E1E1E\" }\n\"ui.virtual.jump-label\" = {fg = \"synth-red\", modifiers = [\"bold\"]}\n\"ui.selection\" = { bg = \"selection-blue\" }\n\"ui.selection.primary\" = { bg = \"selection-blue\" }\n\"ui.menu\" = { fg = \"white\", bg = \"black\" }\n\"ui.menu.selected\" = { fg = \"dark-grey\", bg = \"synth-red\" }\n\"ui.picker\" = { fg = \"neon-yellow\" }\n\"ui.picker.header.column.active\" = { modifiers = [\"bold\"] }\n\"ui.background.separator\" = \"synth-red\"\n\n# Diagnostic colors\n\"warning\" = \"warning\"\n\"error\" = \"error\"\n\"info\" = \"info\"\n\"hint\" = \"info\"\n\"diagnostic.warning\" = { underline = { color = \"warning\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"error\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"info\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"info\", style = \"curl\" } }\n\n# Syntax highlighting\n\"comment\" = { fg = \"mauve\", modifiers = [\"italic\"] }\n\"constant\" = \"salmon\"\n\"constant.numeric\" = \"salmon\"\n\"constant.character.escape\" = \"beaming-blue\"\n\"constant.builtin\" = \"synthetic-green\"\n\"constant.builtin.boolean\" = \"synthetic-green\"\n\"string\" = \"orange\"\n\"string.regexp\" = \"salmon\"\n\"variable\" = \"pelati-red\"\n\"variable.builtin\" = { fg = \"blood-red\", modifiers = [\"bold\"] }\n\"variable.parameter\" = { fg = \"jess-green\", modifiers = [\"italic\"] }\n\"type\" = \"blood-red\"\n\"constructor\" = \"blood-red\"\n\"function\" = \"beaming-blue\"\n\"keyword\" = \"neon-yellow\"\n\"keyword.control\" = \"neon-yellow\"\n\"keyword.control.import\" = \"jade\"\n\"keyword.operator\" = \"neon-yellow\"\n\"keyword.directive\" = \"jade\"\n\"keyword.storage.type\" = \"neon-yellow\"\n\"keyword.storage.modifier\" = \"neon-yellow\"\n\n# \"label\" = \"neon-yellow\"\n\"namespace\" = \"blood-red\"\n\"operator\" = \"neon-yellow\"\n# \"special\" = \"beaming-blue\"\n\n\"punctuation.bracket\" = \"neon-yellow\"\n\"tag\" = \"jade\"\n\"attribute\" = { fg = \"neon-yellow\", modifiers = [\"italic\"] }\n\n\"markup.heading\" = { fg = \"#ff7edb\", modifiers = [\"bold\"] }\n\"markup.bold\" = { fg = \"#2ee2fa\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"#2ee2fa\", modifiers = [\"italic\"] }\n\"markup.link.url\" = { fg = \"jade\", modifiers = [\"italic\"] }\n\"markup.link.text\" = \"neon-yellow\"\n\"markup.quote\" = { fg = \"jade\", modifiers = [\"italic\"] }\n\"markup.raw\" = \"pelati-red\"\n\"markup.raw.inline\" = \"pelati-red\"\n\"markup.raw.block\" = \"pelati-red\"\n\n# Git gutter\n\"diff.plus.gutter\" = \"#47ffa0\"\n\"diff.minus.gutter\" = \"error\"\n\"diff.delta.gutter\" = \"info\"\n\n# bufferline\n\"ui.bufferline\" = { fg = \"grey\", bg = \"#000000\"}\n\"ui.bufferline.active\" = { fg = \"dark-grey\", bg = \"synth-red\" }\n\n[palette]\nblack = \"#000000\"\nwhite = \"#ffffff\"\nneon-yellow = \"#fede5d\"\nblood-red = \"#fe4450\"\npelati-red = \"#f73232\"\nsynth-red = \"#ff3366\"\nsalmon = \"#f97e72\"\nbeaming-blue = \"#36f9f6\"\nselection-blue = \"#001069\"\nsynthetic-green = \"#1afc65\"\njess-green = \"#28b881\"\norange = \"#ff8b39\"\njade = \"#72f1b8\"\nmauve = \"#848bbd\"\ngrey = \"#808080\"\ndark-grey = \"#141414\"\nerror = \"#ff5252\"\nwarning = \"#ffab40\"\ninfo = \"#40c4ff\"\n\n"
  },
  {
    "path": "runtime/themes/dark_high_contrast.toml",
    "content": "# GreasySlug : dark high contrast <9619abgoni@gmail.com>\n\n# Interface\n\"ui.background\" = { bg = \"black\" }\n\"ui.window\" = { fg = \"aqua\" }\n\"special\" = \"orange\"                           # file picker fuzzy match\n\"ui.background.separator\" = { fg = \"white\" }\n\"ui.text\" = \"white\"\n\"ui.text.focus\" = { modifiers = [\"reversed\"] } # file picker selected\n\n\"ui.virtual.jump-label\" = { fg = \"deep_red\", modifiers = [\n    \"bold\",\n], underline = { color = \"deep_red\", style = \"line\" } }\n\"ui.virtual\" = \"gray\"\n\"ui.virtual.whitespace\" = \"gray\"\n\"ui.virtual.ruler\" = { fg = \"white\", bg = \"gray\" }\n\"ui.virtual.indent-guide\" = \"white\"\n\"ui.virtual.inlay-hint\" = { fg = \"black\", bg = \"orange\" }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"black\", bg = \"orange\" }\n\"ui.virtual.inlay-hint.type\" = { fg = \"black\", bg = \"orange\" }\n\"ui.virtual.wrap\" = \"gray\"\n\n\"ui.statusline\" = { fg = \"white\", bg = \"deep_blue\" }\n\"ui.statusline.inactive\" = { fg = \"gray\", bg = \"deep_blue\" }\n\"ui.statusline.normal\" = { fg = \"black\", bg = \"aqua\" }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"orange\" }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"purple\" }\n\"ui.statusline.separator\" = { fg = \"aqua\", bg = \"white\" }\n\n\"ui.cursor\" = { fg = \"black\", bg = \"white\" }\n\"ui.cursor.insert\" = { fg = \"black\", bg = \"white\" }\n\"ui.cursor.select\" = { fg = \"black\", bg = \"white\" }\n\"ui.cursor.match\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"black\", bg = \"white\", modifiers = [\"slow_blink\"] }\n\"ui.cursor.secondary\" = \"white\"\n\"ui.cursorline.primary\" = { bg = \"deep_blue\", underline = { color = \"orange\", style = \"double_line\" } }\n\"ui.cursorline.secondary\" = { bg = \"dark_blue\", underline = { color = \"white\", style = \"line\" } }\n\"ui.selection\" = { fg = \"dark_blue\", bg = \"white\" }\n\"ui.selection.primary\" = { fg = \"deep_blue\", bg = \"white\" }\n\n\"ui.menu\" = { fg = \"white\", bg = \"deep_blue\" }\n\"ui.menu.selected\" = { fg = \"orange\", underline = { style = \"line\" } }\n\"ui.menu.scroll\" = { fg = \"aqua\", bg = \"black\" }\n\"ui.help\" = { fg = \"white\", bg = \"deep_blue\" }\n\n\"ui.popup\" = { bg = \"deep_blue\" }\n\"ui.popup.info\" = { fg = \"white\", bg = \"deep_blue\" }\n\n\"ui.gutter\" = { bg = \"black\" }\n\"ui.gutter.selected\" = { bg = \"black\" }\n\"ui.linenr\" = { fg = \"white\", bg = \"black\" }\n\"ui.linenr.selected\" = { fg = \"orange\", bg = \"black\", modifiers = [\"bold\"] }\n\n# Diagnostic\n\"diagnostic\" = { fg = \"white\" }\n\"diagnostic.info\" = { underline = { color = \"white\", style = \"dotted\" } }\n\"diagnostic.hint\" = { underline = { color = \"yellow\", style = \"dashed\" } }\n\"diagnostic.warning\" = { underline = { color = \"orange\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"info\" = \"white\"\n\"hint\" = \"yellow\"\n\"warning\" = \"orange\"\n\"error\" = \"red\"\n\"debug\" = \"red\"\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"blue\"\n\"diff.minus\" = \"pink\"\n\n# Syntax high light\n\"type\" = \"emerald_green\"\n\"type.buildin\" = \"emerald_green\"\n\"comment\" = \"white\"\n\"operator\" = \"white\"\n\"variable\" = \"aqua\"\n\"variable.other.member\" = \"brown\"\n\"constant\" = \"aqua\"\n\"constant.numeric\" = \"emerald_green\"\n\"attributes\" = \"blue\"\n\"namespace\" = \"blue\"\n\"string\" = \"brown\"\n\"string.special.url\" = \"brown\"\n\"constant.character.escape\" = \"yellow\"\n\"constructor\" = \"aqua\"\n\"keyword\" = \"blue\"\n\"keyword.control\" = \"purple\"\n\"function\" = \"yellow\"\n\"label\" = \"blue\"\n\"tag\" = \"aqua\"\n\"attribute\" = \"blue\"\n\n# Markup \n\"markup.heading\" = { fg = \"yellow\", modifiers = [\n    \"bold\",\n], underline = { color = \"yellow\", style = \"double_line\" } }\n\"markup.list\" = \"pink\"\n\"markup.bold\" = { fg = \"emerald_green\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"blue\", underline = { color = \"blue\", style = \"line\" } }\n\"markup.link.text\" = \"pink\"\n\"markup.quote\" = \"yellow\"\n\"markup.raw\" = \"brown\"\n\n[palette]\nblack = \"#000000\"\ngray = \"#585858\"\nwhite = \"#ffffff\"\nblue = \"#66a4ff\"\ndeep_blue = \"#142743\"\ndark_blue = \"#0d1a2d\"\naqua = \"#6fc3df\"\npurple = \"#c586c0\"\nred = \"#b65f5f\"\ndeep_red = \"#fd0004\"\npink = \"#ff5c8d\"\norange = \"#f38518\"\nbrown = \"#ce9178\"\nyellow = \"#cedc84\"\ngreen = \"#427a2d\"\nemerald_green = \"#4ec9b0\"\n"
  },
  {
    "path": "runtime/themes/dark_plus.toml",
    "content": "# Author: David Else <12832280+David-Else@users.noreply.github.com>\n\n# SYNTAX\n\"attribute\"                 = \"variable\"\n\"comment\"                   = \"dark_green\"\n\"constant\"                  = \"constant\"\n\"constant.builtin\"          = \"blue2\"\n\"constant.character\"        = \"orange\"\n\"constant.character.escape\" = \"gold\"\n\"constant.numeric\"          = \"pale_green\"\n\"constructor\"               = \"type\"\n\"diff.delta\"                = \"blue4\"\n\"diff.minus\"                = \"orange_red\"\n\"diff.plus\"                 = \"dark_green2\"\n\"function\"                  = \"fn_declaration\"\n\"function.builtin\"          = \"fn_declaration\"\n\"function.macro\"            = \"blue2\"\n\"keyword\"                   = \"blue2\"\n\"keyword.control\"           = \"special\"\n\"keyword.directive\"         = \"special\"\n\"label\"                     = \"blue2\"\n\"module\"                    = \"type\"\n\"namespace\"                 = \"type\"\n\"operator\"                  = \"text\"\n\"punctuation\"               = \"text\"\n\"punctuation.delimiter\"     = \"text\"\n\"special\"                   = \"light_blue\"\n\"string\"                    = \"orange\"\n\"string.regexp\"             = \"gold\"\n\"tag\"                       = \"blue2\"\n\"type\"                      = \"type\"\n\"type.builtin\"              = \"type\"\n\"type.enum.variant\"         = \"constant\"\n\"variable\"                  = \"variable\"\n\"variable.builtin\"          = \"blue2\"\n\"variable.other.member\"     = \"variable\"\n\"variable.parameter\"        = \"variable\"\n\n# MARKUP\n\"markup.heading\"       = { fg = \"blue2\", modifiers = [\"bold\"] }\n\"markup.list\"          = \"blue3\"\n\"markup.bold\"          = { modifiers = [\"bold\"] }\n\"markup.italic\"        = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\"      = { underline.style= \"line\" }\n\"markup.link.text\"     = \"orange\"\n\"markup.quote\"         = \"dark_green\"\n\"markup.raw\"           = \"orange\"\n\n# UI\n\"ui.background\"              = { fg = \"light_gray\", bg = \"dark_gray2\" }\n\"ui.window\"                  = { bg = \"widget\" }\n\"ui.popup\"                   = { fg = \"text\", bg = \"widget\" }\n\"ui.help\"                    = { fg = \"text\", bg = \"widget\" }\n\"ui.menu\"                    = { fg = \"text\", bg = \"widget\" }\n\"ui.menu.selected\"           = { bg = \"dark_blue2\" }\n# TODO: Alternate bg colour for `ui.cursor.match` and `ui.selection`.\n\"ui.cursor\"                  = { fg = \"cursor\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\"          = { fg = \"cursor\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\"            = { bg = \"#3a3d41\", underline.style = \"line\" }\n\"ui.selection\"               = { bg = \"#3a3d41\" }\n\"ui.selection.primary\"       = { bg = \"dark_blue\" }\n\"ui.linenr\"                  = { fg = \"dark_gray\" }\n\"ui.linenr.selected\"         = { fg = \"light_gray2\" }\n\"ui.cursorline.primary\"      = { bg = \"dark_gray3\" }\n\"ui.statusline\"              = { fg = \"white\", bg = \"blue\" }\n\"ui.statusline.inactive\"     = { fg = \"white\", bg = \"widget\" }\n\"ui.statusline.insert\"       = { fg = \"white\", bg = \"yellow\" }\n\"ui.statusline.select\"       = { fg = \"white\", bg = \"magenta\" }\n\"ui.bufferline\"              = { fg = \"text\", bg = \"widget\" }\n\"ui.bufferline.active\"       = { fg = \"white\", bg = \"blue\" }\n\"ui.bufferline.background\"   = { bg = \"background\" }\n\"ui.text\"                    = { fg = \"text\" }\n\"ui.text.focus\"              = { fg = \"white\" }\n\"ui.text.directory\"          = { fg = \"blue2\" }\n\"ui.text.inactive\"           = { fg = \"dark_gray\" }\n\"ui.virtual.whitespace\"      = { fg = \"#3e3e3d\" }\n\"ui.virtual.wrap\"            = { fg = \"#3e3e3d\" }\n\"ui.virtual.ruler\"           = { bg = \"borders\" }\n\"ui.virtual.indent-guide\"    = { fg = \"dark_gray4\" }\n\"ui.virtual.inlay-hint\"      = { fg = \"dark_gray5\"}\n\"ui.virtual.jump-label\"      = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"ui.highlight.frameline\"     = { bg = \"#4b4b18\" }\n\"ui.debug.active\"            = { fg = \"#ffcc00\" }\n\"ui.debug.breakpoint\"        = { fg = \"#e51400\" }\n\"ui.picker.header.column\"    = { underline.style = \"line\" }\n\"ui.picker.header.column.active\" = { fg =\"white\", underline.style = \"line\" }\n\"warning\"                    = { fg = \"gold2\" }\n\"error\"                      = { fg = \"red\" }\n\"info\"                       = { fg = \"light_blue\" }\n\"hint\"                       = { fg = \"light_gray3\" }\n\"diagnostic.error\".underline = { color = \"red\", style = \"curl\" }\n\"diagnostic\".underline       = { color = \"gold\", style = \"curl\" }\n\"diagnostic.unnecessary\"     = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\"      = { modifiers = [\"crossed_out\"] }\n\nrainbow = [\"#FFD700\", \"#DA70D6\", \"#179FFF\"]\n\n[palette]\nwhite = \"#ffffff\"\norange = \"#ce9178\"\ngold = \"#d7ba7d\"\ngold2 = \"#cca700\"\npale_green = \"#b5cea8\"\ndark_green = \"#6A9955\"\ndark_green2 = \"#487e02\"\nlight_gray = \"#d4d4d4\"\nlight_gray2 = \"#c6c6c6\"\nlight_gray3 = \"#eeeeee\"\ndark_gray = \"#858585\"\ndark_gray2 = \"#1e1e1e\"\ndark_gray3 = \"#282828\"\ndark_gray4 = \"#404040\"\ndark_gray5 = \"#8b949e\"\nblue = \"#007acc\"\nblue2 = \"#569CD6\"\nblue3 = \"#6796E6\"\nblue4 = \"#1b81a8\"\nlight_blue = \"#75beff\"\ndark_blue = \"#264f78\"\ndark_blue2 = \"#094771\"\nred = \"#ff1212\"\norange_red = \"#f14c4c\"\n\ntype = \"#4EC9B0\"\nspecial = \"#C586C0\"\nvariable = \"#9CDCFE\"\nfn_declaration = \"#DCDCAA\"\nconstant = \"#4FC1FF\"\n\nbackground = \"#1e1e1e\"\ntext = \"#d4d4d4\"\ncursor = \"#a6a6a6\"\nwidget = \"#252526\"\nborders = \"#323232\"\n"
  },
  {
    "path": "runtime/themes/doom-one.toml",
    "content": "# Author: spentbliss <zyhkekrz.hatbox475@passinbox.com>\n# License: MIT (originally by NTBBloodbath)\n\n\"ui.background\" = { bg = \"bg\", fg = \"fg\" } \n\"ui.text\" = \"fg\"\n\"ui.text.focus\" = { bg = \"bg_highlight\", fg = \"cyan\" }\n\"ui.cursor\" = { bg = \"cyan\", fg = \"bg\" }\n\"ui.linenr\" = \"grey\"\n\"ui.linenr.selected\" = \"yellow\"\n\"ui.statusline\" = { fg = \"blue\" }\n\"ui.selection\" = { bg = \"bg_highlight\" } \n\"ui.selection.primary\" = { bg = \"bg_highlight\" }  \n\"ui.virtual.ruler\" = { bg = \"bg_highlight\" }\n\"ui.virtual.jump-label\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\n# Markdown Highlighting\n\"markup.raw\" = { fg = \"blue\", bg = \"bg\" } \n\"markup.raw.inline\" = { fg = \"orange\" } \n\"markup.heading.1\" = { fg = \"#E99BEA\", bg = \"#4F4258\"}\n\"markup.heading.2\" = { fg = \"#51AFEF\", bg = \"#2F4456\" }\n\"markup.heading.3\" = { fg = \"#A9A1E1\", bg = \"#3F4153\" }\n\"markup.heading.4\" = { fg = \"#98BE65\", bg = \"#3C453D\" }\n\"markup.heading.5\" = { fg = \"#ECBE7B\", bg = \"#4B4641\" }\n\"markup.heading.6\" = { fg = \"#DA8549\", bg = \"#483C39\" }\n\"markup.list\" = { fg = \"magenta\" }\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"orange\" }\n\"markup.strikethrough\" = { fg = \"red\", modifiers = [\"crossed_out\"] }\n\"markup.link\" = { fg = \"cyan\" }\n\"markup.quote\" = { fg = \"fg\" }\n\n# Syntax Highlighting for Code\n\"comment\" = { fg = \"grey\" }\n\"comment.line\" = { fg = \"grey\" }\n\"comment.block\" = { fg = \"grey\" }\n\"comment.documentation\" = { fg = \"blue\" }\n\n\"keyword\" = \"blue\"\n\"keyword.control\" = \"blue\"\n\"keyword.operator\" = \"fg\"\n\"keyword.function\" = \"blue\"\n\"keyword.directive\" = \"green\"\n\"keyword.storage\" = \"blue\"\n\n\"type\" = \"yellow\"\n\"type.builtin\" = \"yellow\" \n\"type.enum.variant\" = \"purple\"\n\n\"function\" = \"magenta\"\n\"function.builtin\" = \"fg\"\n\"function.method\" = \"fg\"\n\"function.macro\" = \"purple\"\n\n\"variable\" = \"fg\"\n\"variable.builtin\" = \"red\"\n\"variable.parameter\" = \"fg\" \n\n\"string\" = \"green\"\n\"string.special\" = \"green\"\n\n\"constant\" = \"orange\"\n\"constant.builtin\" = \"orange\"\n\"constant.numeric\" = \"orange\"\n\"constant.character\" = \"orange\"\n\"constant.boolean\" = \"orange\"\n\n\"attribute\" = \"magenta\"\n\"operator\" = \"blue\"\n\"tag\" = { fg = \"magenta\", modifiers = [\"bold\"] }\n\"tag.special\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"namespace\" = \"blue\"\n\"macro\" = \"orange\"\n\"label\" = \"red\"\n\n# Interface specific\n\"ui.cursorline.primary\" = { bg = \"bg_highlight\" }\n\"ui.cursorline.secondary\" = { bg = \"bg_alt\" }\n\"ui.cursorcolumn.primary\" = { bg = \"bg_highlight\" }\n\"ui.cursorcolumn.secondary\" = { bg = \"bg_alt\" }\n\"ui.statusline.normal\" = { fg = \"bg\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"bg\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"bg\", bg = \"purple\" }\n\n# Git changes indicator\n\"diff.plus\" = \"green\"\n\"diff.plus.gutter\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.minus.gutter\" = \"red\"\n\"diff.delta\" = \"green\"\n\"diff.delta.gutter\" = \"green\"\n\"diff.delta.moved\" = \"orange\"\n\"diff.delta.conflict\" = \"purple\"\n\n# Diagnostic styles\n\"warning\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"diagnostic.error\" = { fg = \"red\" }\n\"diagnostic.warning\" = { fg = \"yellow\" }\n\"diagnostic.info\" = { fg = \"cyan\" }\n\"diagnostic.hint\" = { fg = \"blue\" }\n\n# Popups for documentation or file picker\n\"ui.popup\" = { fg = \"fg\", bg = \"bg\" } \n\"ui.popup.info\" = { fg = \"fg\", bg = \"bg_alt\" } \n\"ui.menu\" = { fg = \"fg\", bg = \"bg\" } \n\"ui.menu.selected\" = { fg = \"cyan\", bg = \"bg_highlight\" }\n\n# Additional overrides\n\"ui.virtual.whitespace\" = \"grey\"\n\"ui.virtual.indent-guide\" = { fg = \"grey\" }\n\n[palette]\nbg = \"#282C34\"\nfg = \"#BBC2CF\" \ngrey = \"#5B6268\"\nblue = \"#51AFEF\"\ngreen = \"#98BE65\"\ncyan = \"#46D9FF\" \nred = \"#FF6C6B\"\nyellow = \"#ECBE7B\"\npurple = \"#A8A1E1\"\nmagenta = \"#C678DD\"\norange = \"#DA8548\" \nbg_alt = \"#21242B\"\nbg_highlight = \"#3C4048\"\n"
  },
  {
    "path": "runtime/themes/doom_acario_dark.toml",
    "content": "# Author : Luna <rinnray@gliroid.com>\n#\n# This was made based on\n# https://github.com/doomemacs/themes/blob/master/themes/doom-acario-dark-theme.el\n# I've done my best to make it look like the Emacs theme, there are still things that looks different from the original.\n# But I've decided to keep it like that as I found it to be easier to read when there's a lot going on i.e lots of variables, strings and functions close to each other.\n\n'attribute' = { fg = 'blue' }\n'comment' = { fg = 'gray', modifiers = ['italic'] }\n'comment.block' = { fg = 'green', modifiers = ['italic'] }\n'comment.block.documentation' = { fg = 'green', modifiers = ['italic'] }\n'comment.line.documentation' = { fg = 'green', modifiers = ['italic'] }\n'constant' = { fg = 'magenta' }\n'constant.numeric' = { fg = 'orange' }\n'constructor' = { fg = 'red' }\n'function' = { fg = 'yellow' }\n'function.builtin' = { fg = 'blue' }\n'function.method' = { fg = 'white' }\n'keyword' = { fg = 'red' }\n'label' = { fg = 'green' }\n'namespace' = { fg = 'white' }\n'operator' = { fg = 'blue' }\n'punctuation.bracket' = { fg = 'blue' }\n'punctuation.delimiter' = { fg = 'white', modifiers = ['bold'] }\n'string' = { fg = 'green' }\n'tag' = { fg = 'cyan' }\n'type' = { fg = 'blue' }\n'variable' = { fg = 'cyan' }\n'variable.parameter' = { fg = 'white' }\n\n'markup.bold' = { fg = 'orange', modifiers = ['bold'] }\n'markup.italic' = { fg = 'magenta', modifiers = ['italic'] }\n'markup.strikethrough' = { modifiers = ['crossed_out'] }\n'markup.heading' = { fg = 'red' }\n'markup.link' = { fg = 'orange' }\n'markup.link.url' = { fg = 'magenta' }\n'markup.link.text' = { fg = 'orange' }\n'markup.link.label' = { fg = 'green' }\n'markup.list' = { fg = 'red' }\n'markup.quote' = { fg = 'green', modifiers = ['italic'] }\n'markup.raw.block' = { fg = 'green', bg = 'base4' }\n'markup.raw.inline' = { fg = 'green', bg = 'base4' }\n\n'diff.plus' = { fg = 'green' }\n'diff.minus' = { fg = 'red' }\n'diff.delta' = { fg = 'blue' }\n\n'ui.background'= { bg = 'bg' }\n'ui.cursor' = { bg = 'orange', fg = 'bg-alt' }\n'ui.cursor.match' = { fg = 'red', modifiers = ['bold'] }\n'ui.cursorline' = { bg = 'bg-alt' }\n'ui.linenr' = { fg = 'base4' }\n'ui.linenr.selected' = { fg = 'orange', bg = 'bg-alt', modifiers = ['bold'] }\n'ui.statusline' = { fg = 'fg', bg = 'base3' }\n'ui.statusline.normal' = { bg = 'base3' }\n'ui.statusline.insert' = { bg = 'base3' }\n'ui.statusline.select' = { bg = 'base3' }\n'ui.bufferline' = { fg = 'gray', bg = 'base2' }\n'ui.bufferline.active' = { fg = 'white', bg = 'base4' }\n'ui.bufferline.background' = { bg = 'bg' }\n'ui.popup' = { bg = 'bg-alt' }\n'ui.window' = { fg = 'gray' }\n'ui.help' = { fg = 'fg', bg = 'base2' }\n'ui.text' = { fg = 'fg' }\n'ui.text.focus' = { bg = 'bg-alt', fg = 'fg' }\n'ui.text.info' = { fg = 'fg' }\n'ui.virtual.whitespace' = { fg = 'base2' }\n'ui.virtual.ruler' = { bg = 'black' }\n'ui.menu' = { fg = 'fg', bg = 'bg-alt' }\n'ui.menu.selected' = { bg = 'base3', fg = 'fg' }\n'ui.selection' = { bg = 'base2' }\n\n'warning' = { fg = 'orange' }\n'error' = { fg = 'red', modifiers = ['bold'] }\n'info' = { fg = 'blue', modifiers = ['bold'] }\n'hint' = { fg = 'blue', modifiers = ['bold'] }\n\n'diagnostic.hint'= { underline = { color = 'red', style = \"curl\"} }\n'diagnostic.error'= { underline = { color = 'red', style = \"curl\"} }\n'diagnostic.info'= { underline = { color = 'blue', style = \"curl\"} }\n'diagnostic.warning'= { underline = { color = 'yellow', style = \"curl\"} }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n'special' = { fg = 'orange' }\n\n[palette]\nwhite = '#ffffff'\nblack = '#000000'\nred = '#D83441'\ngreen = '#79D836'\nblue = '#3679D8'\nyellow = '#D8B941'\nmagenta = '#8041D8'\ncyan = '#36D8BD'\ngray = '#767676'\norange = '#D85F00'\n\n# Custom to doom\nbg = '#0D0E16'\nbg-alt = '#040408'\nfg = '#C3DBE5'\nbase2 = '#1E1E33'\nbase3 = '#464A56'\nbase4 = '#585C6C'\n"
  },
  {
    "path": "runtime/themes/dracula.toml",
    "content": "# Author : Sebastian Zivota <loewenheim@mailbox.org>\n# Author : Chirikumbrah\n\n\"annotation\"                      = { fg = \"foreground\"                                                     }\n\n\"attribute\"                       = { fg = \"green\",              modifiers = [\"italic\"]                     }\n\n\"comment\"                         = { fg = \"comment\"                                                        }\n\"comment.block\"                   = { fg = \"comment\"                                                        }\n\"comment.block.documentation\"     = { fg = \"comment\"                                                        }\n\"comment.line\"                    = { fg = \"comment\"                                                        }\n\"comment.line.documentation\"      = { fg = \"comment\"                                                        }\n\n\"constant\"                        = { fg = \"purple\"                                                         }\n\"constant.builtin\"                = { fg = \"purple\"                                                         }\n\"constant.builtin.boolean\"        = { fg = \"purple\"                                                         }\n\"constant.character\"              = { fg = \"cyan\"                                                           }\n\"constant.character.escape\"       = { fg = \"pink\"                                                           }\n\"constant.macro\"                  = { fg = \"purple\"                                                         }\n\"constant.numeric\"                = { fg = \"purple\"                                                         }\n\"constructor\"                     = { fg = \"purple\"                                                         }\n\n\"definition\"                      = { underline = { color = \"cyan\"                                        } }\n\n\"diagnostic\"                      = { underline = { color = \"orange\",          style = \"curl\"             } }\n\"diagnostic.hint\"                 = { underline = { color = \"purple\",          style = \"curl\"             } }\n\"diagnostic.warning\"              = { underline = { color = \"yellow\",          style = \"curl\"             } }\n\"diagnostic.error\"                = { underline = { color = \"red\",             style = \"curl\"             } }\n\"diagnostic.info\"                 = { underline = { color = \"cyan\",            style = \"curl\"             } }\n\"diagnostic.unnecessary\"          = { modifiers = [\"dim\"]                                                   }\n\"diagnostic.deprecated\"           = { modifiers = [\"crossed_out\"]                                           }\n\n\"error\"                           = { fg    = \"red\"                                                         }\n\"hint\"                            = { fg    = \"purple\"                                                      }\n\"info\"                            = { fg    = \"cyan\"                                                        }\n\"warning\"                         = { fg    = \"yellow\"                                                      }\n\n\"diff.delta\"                      = { fg    = \"orange\"                                                      }\n\"diff.minus\"                      = { fg    = \"red\"                                                         }\n\"diff.plus\"                       = { fg    = \"green\"                                                       }\n\n# d\n\"function\"                        = { fg = \"green\"                                                          }\n\"function.builtin\"                = { fg = \"green\"                                                          }\n\"function.call\"                   = { fg = \"green\"                                                          }\n\"function.macro\"                  = { fg = \"purple\"                                                         }\n\"function.method\"                 = { fg = \"green\"                                                          }\n\n\"keyword\"                         = { fg = \"pink\"                                                           }\n\"keyword.control.conditional\"     = { fg = \"pink\"                                                           }\n\"keyword.control.exception\"       = { fg = \"purple\"                                                         }\n\"keyword.control.import\"          = { fg = \"pink\"                                                           }\n\"keyword.control.repeat\"          = { fg = \"pink\"                                                           }\n\"keyword.directive\"               = { fg = \"green\"                                                          }\n\"keyword.function\"                = { fg = \"pink\"                                                           }\n\"keyword.operator\"                = { fg = \"pink\"                                                           }\n\"keyword.return\"                  = { fg = \"pink\"                                                           }\n\"keyword.storage\"                 = { fg = \"pink\"                                                           }\n\"keyword.storage.modifier\"        = { fg = \"pink\"                                                           }\n\"keyword.storage.type\"            = { fg = \"cyan\",               modifiers = [\"italic\"]                     }\n\n\"label\"                           = { fg = \"cyan\"                                                           }\n\n\"markup.bold\"                     = { fg    = \"orange\",          modifiers = [\"bold\"]                       }\n\"markup.heading\"                  = { fg    = \"purple\",          modifiers = [\"bold\"]                       }\n\"markup.italic\"                   = { fg    = \"yellow\",          modifiers = [\"italic\"]                     }\n\"markup.link.text\"                = { fg    = \"pink\"                                                        }\n\"markup.link.url\"                 = { fg    = \"cyan\"                                                        }\n\"markup.list\"                     = { fg    = \"cyan\"                                                        }\n\"markup.quote\"                    = { fg    = \"yellow\",          modifiers = [\"italic\"]                     }\n\"markup.raw\"                      = { fg    = \"foreground\"                                                  }\n\"markup.strikethrough\"            = {                            modifiers = [\"crossed_out\"]                }\n\n\"punctuation\"                     = { fg = \"foreground\"                                                     }\n\"punctuation.bracket\"             = { fg = \"foreground\"                                                     }\n\"punctuation.delimiter\"           = { fg = \"foreground\"                                                     }\n\"punctuation.special\"             = { fg = \"pink\"                                                           }\n\n\"special\"                         = { fg = \"pink\"                                                           }\n\n\"string\"                          = { fg = \"yellow\"                                                         }\n\"string.regexp\"                   = { fg = \"red\"                                                            }\n\"string.special\"                  = { fg = \"orange\"                                                         }\n\"string.symbol\"                   = { fg = \"yellow\"                                                         }\n\n\"tag\"                             = { fg = \"pink\"                                                           }\n\"tag.attribute\"                   = { fg = \"purple\"                                                         }\n\"tag.delimiter\"                   = { fg = \"foreground\"                                                     }\n\n\"type\"                            = { fg = \"cyan\",               modifiers = [\"italic\"]                     }\n\"type.builtin\"                    = { fg = \"cyan\"                                                           }\n\"type.enum.variant\"               = { fg = \"foreground\",         modifiers = [\"italic\"]                     }\n\n\"ui.background\"                   = { fg    = \"foreground\",      bg = \"background\"                          }\n\"ui.cursor\"                       = { fg    = \"background\",      bg = \"purple\",        modifiers = [\"dim\"]  }\n\"ui.cursor.insert\"                = { fg    = \"background\",      bg = \"green\",         modifiers = [\"dim\"]  }\t\n\"ui.cursor.match\"                 = { fg    = \"foreground\",      bg = \"grey\"                                }\n\"ui.cursor.normal\"                = { fg    = \"background\",      bg = \"purple\",        modifiers = [\"dim\"]  }\t\n\"ui.cursor.primary.insert\"        = { fg    = \"background\",      bg = \"green\"                               }\t\n\"ui.cursor.primary.normal\"        = { fg    = \"background\",      bg = \"purple\"                              }\t\n\"ui.cursor.primary.select\"        = { fg    = \"background\",      bg = \"cyan\"                                }\n\"ui.cursor.select\"                = { fg    = \"background\",      bg = \"cyan\",          modifiers = [\"dim\"]  }\n\"ui.cursorline.primary\"           = {                            bg = \"cursorline\"                          }\n\"ui.debug\"                        = { fg    = \"red\"                                                         }\n\"ui.help\"                         = { fg    = \"foreground\",      bg = \"black\"                               }\n\"ui.highlight.frameline\"          = { fg    = \"background\",      bg = \"red\"                                 }\n\"ui.linenr\"                       = { fg    = \"comment\"                                                     }\n\"ui.linenr.selected\"              = { fg    = \"foreground\"                                                  }\n\"ui.menu\"                         = { fg    = \"foreground\",      bg = \"current_line\"                        }\n\"ui.menu.scroll\"                  = { fg    = \"foreground\",      bg = \"current_line\"                        }\n\"ui.menu.selected\"                = { fg    = \"current_line\",    bg = \"purple\",        modifiers = [\"dim\"]  }\n\"ui.popup\"                        = { fg    = \"foreground\",      bg = \"black\"                               }\n\"ui.selection\"                    = {                            bg = \"selection\"                           }\n\"ui.selection.primary\"            = {                            bg = \"current_line\"                        }\n\"ui.statusline\"                   = { fg    = \"foreground\",      bg = \"darker\"                              }\n\"ui.statusline.inactive\"          = { fg    = \"comment\",         bg = \"darker\"                              }\n\"ui.statusline.insert\"            = { fg    = \"black\",           bg = \"green\",         modifiers = [\"bold\"] }\n\"ui.statusline.normal\"            = { fg    = \"black\",           bg = \"purple\",        modifiers = [\"bold\"] }\n\"ui.statusline.select\"            = { fg    = \"black\",           bg = \"cyan\",          modifiers = [\"bold\"] }\n\"ui.text\"                         = { fg    = \"foreground\"                                                  }\n\"ui.text.focus\"                   = { fg    = \"cyan\"                                                        }\n\"ui.text.directory\"               = { fg    = \"cyan\"                                                        }\n\"ui.virtual.indent-guide\"         = { fg    = \"indent\"                                                      }\n\"ui.virtual.inlay-hint\"           = { fg    = \"cyan\"                                                        }\n\"ui.virtual.inlay-hint.parameter\" = { fg    = \"cyan\",            modifiers = [\"italic\", \"dim\"]              }\n\"ui.virtual.inlay-hint.type\"      = { fg    = \"cyan\",            modifiers = [\"italic\", \"dim\"]              }\n\"ui.virtual.jump-label\"           = { fg    = \"pink\",            modifiers = [\"bold\"]                       }\n\"ui.virtual.ruler\"                = { bg    = \"black\"                                                       }\n\"ui.virtual.whitespace\"           = { fg    = \"whitespace\"                                                  }\n\"ui.virtual.wrap\"                 = { fg    = \"current_line\"                                                }\n\"ui.window\"                       = { fg    = \"foreground\"                                                  }\n\n\"variable\"                        = { fg = \"foreground\"                                                     }\n\"variable.builtin\"                = { fg = \"purple\",             modifiers = [\"italic\"]                     }\n\"variable.other\"                  = { fg = \"foreground\"                                                     }\n\"variable.other.member\"           = { fg = \"foreground\"                                                     }\n\"variable.parameter\"              = { fg = \"orange\",             modifiers = [\"italic\"]                     }\n\n\n[palette]\nbackground        = \"#282A36\"\nblack             = \"#191A21\"\ncomment           = \"#6272A4\"\ncurrent_line      = \"#44475a\"\ncursorline        = \"#2d303e\"\ncyan              = \"#8be9fd\"\ndarker            = \"#222430\"\nforeground        = \"#f8f8f2\"\ngreen             = \"#50fa7b\" \ngrey              = \"#666771\"\nindent            = \"#56596a\"\norange            = \"#ffb86c\" \npink              = \"#ff79c6\"\npurple            = \"#BD93F9\" \nred               = \"#ff5555\"\nselection         = \"#363848\"\nwhitespace        = \"#586693\"\nyellow            = \"#f1fa8c\" \n\n"
  },
  {
    "path": "runtime/themes/dracula_at_night.toml",
    "content": "# Author : Sam Sartor <me@samsartor.com>\n# A port of https://github.com/bceskavich/dracula-at-night\n\"comment\" = { fg = \"comment\" }\n\"constant\" = { fg = \"purple\" }\n\"constant.character.escape\" = { fg = \"pink\" }\n\"function\" = { fg = \"green\" }\n\"keyword\" = { fg = \"pink\" }\n\"operator\" = { fg = \"pink\" }\n\"punctuation\" = { fg = \"foreground\" }\n\"string\" = { fg = \"yellow\" }\n\"string.regexp\" = { fg = \"red\" }\n\"tag\" = { fg = \"pink\" }\n\"type\" = { fg = \"cyan\", modifiers = [\"italic\"] }\n\"type.enum.variant\" = { fg = \"foreground\", modifiers = [\"italic\"] }\n\"variable\" = { fg = \"foreground\" }\n\"variable.builtin\" = { fg = \"cyan\", modifiers = [\"italic\"] }\n\"variable.parameter\" = { fg =\"orange\", modifiers = [\"italic\"] }\n\n\"diff.plus\" = { fg = \"green\" }\n\"diff.delta\" = { fg = \"orange\" }\n\"diff.minus\" = { fg = \"red\" }\n\n\"ui.background\" = { fg = \"foreground\", bg = \"background\" }\n\"ui.cursor\" =  { fg = \"background\", bg = \"orange\", modifiers = [\"dim\"] }\n\"ui.cursor.match\" = { fg = \"green\", modifiers = [\"underlined\"] }\n\"ui.cursor.primary\" = { fg = \"background\", bg = \"cyan\", modifiers = [\"dim\"] }\n\"ui.help\" = { fg = \"foreground\", bg = \"background_dark\" }\n\"ui.debug\" = { fg = \"red\" }\n\"ui.highlight.frameline\" = { fg = \"black\", bg = \"red\" }\n\"ui.linenr\" = { fg = \"comment\" }\n\"ui.linenr.selected\" = { fg = \"foreground\" }\n\"ui.menu\" = { fg = \"foreground\", bg = \"background_dark\" }\n\"ui.menu.selected\" = { fg = \"cyan\", bg = \"background_dark\" }\n\"ui.popup\" = { fg = \"foreground\", bg = \"background_dark\" }\n\"ui.selection\" = { fg = \"background\", bg = \"purple\", modifiers = [\"dim\"] }\n\"ui.selection.primary\" = { fg = \"background\", bg = \"pink\" }\n\"ui.cursorline\" = { bg = \"background_dark\" }\n\"ui.statusline\" = { fg = \"foreground\", bg = \"background_dark\" }\n\"ui.statusline.inactive\" = { fg = \"comment\", bg = \"background_dark\" }\n\"ui.statusline.normal\" = { fg = \"background_dark\", bg = \"cyan\" }\n\"ui.statusline.insert\" = { fg = \"background_dark\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"background_dark\", bg = \"purple\" }\n\"ui.text\" = { fg = \"foreground\" }\n\"ui.text.focus\" = { fg = \"cyan\" }\n\"ui.text.directory\" = { fg = \"cyan\" }\n\"ui.window\" = { fg = \"foreground\" }\n\"ui.virtual.jump-label\" = { fg = \"pink\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"background_dark\" }\n\n\"error\" = { fg = \"red\" }\n\"warning\" = { fg = \"cyan\" }\n\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"markup.heading\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\"markup.list\" = \"cyan\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = \"cyan\"\n\"markup.link.text\" = \"pink\"\n\"markup.quote\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.raw\" = { fg = \"foreground\" }\n\n[palette]\nbackground = \"#0e1419\"\nbackground_dark = \"#21222c\"\nforeground = \"#f8f8f2\"\ncomment = \"#6272a4\"\nred = \"#ff5555\"\norange = \"#ffb86c\"\nyellow = \"#f1fa8c\"\ngreen = \"#50fa7b\"\npurple = \"#bd93f9\"\ncyan = \"#8be9fd\"\npink = \"#ff79c6\"\n"
  },
  {
    "path": "runtime/themes/earl_grey.toml",
    "content": "# Author : Steven Vancoillie <steven.vancoillie@gmail.com>\n#\n# Migraine-friendly, minimal color scheme focused only on structural elements\n# like types, functions, and keywords.\n\n\"comment\" = { modifiers = [\"dim\"] }\n\"diagnostic.error\" = { underline = { color = \"blush\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"sky\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"grey\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"maple\", style = \"curl\" } }\n\"diff.delta\" = \"silver\"\n\"diff.minus\" = \"blush\"\n\"diff.plus\" = \"jade\"\n\"error\" = \"blush\"\n\"function\" = { modifiers = [\"bold\"] }\n\"hint\" = \"sky\"\n\"info\" = \"grey\"\n\"keyword\" = \"earl\"\n\"type\" = \"maple\"\n\"ui.background\" = { bg = \"chaotica\" }\n\"ui.background.separator\" = { fg = \"snow\" }\n\"ui.cursor\" = { fg = \"black\", bg = \"earl\" }\n\"ui.cursorline.primary\" = { bg = \"deepspace\" }\n\"ui.help\" = { bg = \"deepspace\", fg = \"snow\" }\n\"ui.highlight\" = { bg = \"space\" }\n\"ui.linenr\" = { fg = \"grey\" }\n\"ui.linenr.selected\" = { fg = \"earl\" }\n\"ui.menu\" = { fg = \"snow\", bg = \"deepspace\" }\n\"ui.menu.scroll\" = { fg = \"grey\", bg = \"deepspace\" }\n\"ui.menu.selected\" = { fg = \"snow\", bg = \"lacquer\" }\n\"ui.popup\" = { bg = \"deepspace\" }\n\"ui.selection\" = { bg = \"lacquer\" }\n\"ui.statusline\" = { fg = \"earl\", bg = \"deepspace\" }\n\"ui.statusline.inactive\" = { fg = \"snow\", bg = \"deepspace\", modifiers = [\"dim\"] }\n\"ui.statusline.insert\" = { fg = \"chaotica\", bg = \"earl\", modifiers = [\"bold\"] }\n\"ui.statusline.normal\" = { fg = \"chaotica\", bg = \"sky\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"chaotica\", bg = \"myrtle\", modifiers = [\"bold\"] }\n\"ui.text\" = { fg = \"silver\" }\n\"ui.text.focus\" = { fg = \"snow\" }\n\"ui.virtual\" = { fg = \"space\" }\n\"ui.virtual.indent-guide\" = { fg = \"space\" }\n\"ui.virtual.inlay-hint\" = { fg = \"lacquer\" }\n\"ui.virtual.jump-label\" = { fg = \"myrtle\" }\n\"ui.virtual.ruler\" = { bg = \"space\" }\n\"ui.window\" = { fg = \"space\" }\n\"warning\" = \"maple\"\n\n[palette]\nblack = \"#000000\"\nchaotica = \"#101010\"\ndeepspace = \"#1b1b1b\"\nspace = \"#2a2a2d\"\nlacquer = \"#3e3e3e\"\ndarkgrey = \"#505050\"\ngrey = \"#808080\"\nsilver = \"#a6a6a6\"\nsnow = \"#f0f0f0\"\nwhite = \"#ffffff\"\nblush = \"#e78284\"\njade = \"#90b99f\"\nearl = \"#b59efc\"\nsky = \"#99bbe0\"\nmyrtle = \"#e29eca\"\nmaple = \"#e5c890\"\n"
  },
  {
    "path": "runtime/themes/eiffel.toml",
    "content": "## Author: mesmere <95945959+mesmere@users.noreply.github.com>\n## Original design by Ian Joyner\n\n\"attribute\" = { fg = \"markup\", modifiers = [\"italic\"] }\n\"comment\" = \"comments\"\n\"comment.block\" = \"comments\"\n\"comment.block.documentation\" = \"comments\"\n\"comment.line\" = \"comments\"\n\"comment.line.documentation\" = \"comments\"\n#\"constant\" = \"\"\n\"constant.builtin\" = { fg = \"builtins\", modifiers = [\"italic\"] }\n\"constant.character\" = \"strings\"\n\"constant.character.escape\" = \"symbols\"\n\"constant.numeric\" = { fg = \"constants_numeric\", modifiers = [\"italic\"] }\n\"constructor\" = { modifiers = [\"italic\"] }\n\"function\" = { fg = \"members\" }\n\"function.builtin\" = \"builtins\"\n\"function.macro\" = \"preprocessor\"\n\"function.method\" = { fg = \"members\", modifiers = [\"italic\"] }\n#\"function.method.private\" = \"\"\n\"function.special\" = \"preprocessor\"\n\"keyword\" = { fg = \"ui_text\" }\n\"keyword.control\" = { fg = \"keywords\", modifiers = [\"bold\"] }\n\"keyword.directive\" = { fg = \"preprocessor\", modifiers = [\"bold\"] }\n#\"keyword.function\" = \"\"\n\"keyword.operator\" = { fg = \"operators\", modifiers = [\"italic\"] }\n#\"keyword.storage\" = \"\"\n#\"label\" = \"\"\n#\"namespace\" = \"\"\n\"operator\" = { fg = \"operators\", modifiers = [\"bold\"] }\n#\"punctuation\" = \"\"\n#\"punctuation.bracket\" = \"\"\n#\"punctuation.delimiter\" = \"\"\n\"punctuation.special\" = \"strings\"\n#\"special\" = \"\"\n\"string\" = \"strings\"\n\"string.regexp\" = \"symbols\"\n\"string.special\" = \"symbols\"\n\"tag\" = \"markup\"\n\"type\" = { modifiers = [\"italic\"] }\n#\"type.builtin\" = \"\"\n#\"type.enum\" = \"\"\n#\"type.parameter\" = \"\"\n#\"variable\" = \"\"\n\"variable.builtin\" = \"builtins\"\n\"variable.other.member\" = { fg = \"members\", modifiers = [\"italic\"] }\n#\"variable.other.member.private\" = \"\"\n#\"variable.parameter\" = \"\"\n\"markup\" = \"markup\"\n\"markup.heading\" = { fg = \"markup_headings\", modifiers = [\"bold\"] }\n#\"markup.heading.marker\" = \"\"\n\"markup.list\" = \"markup_lists\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"strings\", underline.style = \"line\" } # Match HTML href/src attributes.\n#\"markup.link.label\" = \"\"\n\"markup.link.text\" = \"ui_text\"\n\"markup.quote\" = { fg = \"black\", modifiers = [\"italic\"] }\n\"markup.raw\" = \"strings\"\n#\"markup.raw.inline\" = \"\"\n#\"markup.raw.block\" = \"\"\n\n\"diff.delta\" = \"diff_delta\"\n\"diff.minus\" = \"diff_minus\"\n\"diff.plus\" = \"diff_plus\"\n\n\"ui.background\" = { bg = \"ui_background\" }\n#\"ui.background.separator\" = \"\"\n\"ui.bufferline\" = { fg = \"ui_text_dim\", bg = \"ui_background_accent\" }\n\"ui.bufferline.active\" = { fg = \"ui_text\", bg = \"ui_background_accent\" }\n\"ui.bufferline.background\" = { bg = \"ui_background_accent\" }\n#\"ui.cursor\" = { modifiers = ['reversed'] }\n\"ui.cursor.insert\" = { bg = \"ui_mode_insert_accent\" }\n\"ui.cursor.match\" = { modifiers = ['reversed'] }\n\"ui.cursor.normal\" = { bg = \"ui_mode_normal_accent\" }\n\"ui.cursor.select\" = { bg = \"ui_mode_select_accent\" }\n#\"ui.cursor.primary\" = \"\"\n\"ui.cursor.primary.insert\" = { bg = \"ui_mode_insert\" }\n#\"ui.cursor.primary.match\" = \"\"\n\"ui.cursor.primary.normal\" = { bg = \"ui_mode_normal\" }\n\"ui.cursor.primary.select\" = { bg = \"ui_mode_select\" }\n\"ui.cursorcolumn.primary\" = { bg = \"ui_background_accent\" }\n#\"ui.cursorcolumn.secondary\" = \"\"\n\"ui.cursorline.primary\" = { bg = \"ui_background_accent\" }\n#\"ui.cursorline.secondary\" = \"\"\n\"ui.debug.active\" = { fg = \"ui_debug_breakpoint\" }\n\"ui.debug.breakpoint\" = { fg = \"ui_debug_breakpoint\" }\n\"ui.gutter\" = { bg = \"ui_background\" }\n\"ui.gutter.selected\" = { bg = \"ui_background_accent\" }\n\"ui.help\" = { fg = \"ui_text\", bg = \"ui_menu\" }\n\"ui.highlight\" = { fg = \"ui_highlight_line_text\", bg = \"ui_highlight_line\" } # fg is not respected https://github.com/helix-editor/helix/issues/11141 \n\"ui.highlight.frameline\" = { fg = \"ui_highlight_line_text\", bg = \"ui_highlight_line\" }\n\"ui.linenr\" = \"ui_text_dim\"\n\"ui.linenr.selected\" = { fg = \"ui_text_dim\", bg = \"ui_background_accent\" }\n\"ui.menu\" = { fg = \"ui_menu_text\", bg = \"ui_menu\" }\n\"ui.menu.scroll\" = { fg = \"ui_menu_handle\", bg = \"ui_menu_selected\" }\n\"ui.menu.selected\" = { fg = \"ui_text\", bg = \"ui_menu_selected\" }\n#\"ui.picker\" = { fg = \"ui_text\", bg = \"ui_menu\" } # Styling the picker is currently unsupported.\n\"ui.picker.header\" = { bg = \"ui_background_accent\" }\n\"ui.picker.header.column\" = \"ui_text\"\n\"ui.picker.header.column.active\" = { fg = \"ui_text\", modifiers = [\"bold\"], underline = { style = \"line\" } }\n\"ui.popup\" = { fg = \"ui_text\", bg = \"ui_background_accent\" }\n\"ui.popup.info\" = { fg = \"ui_text\", bg = \"ui_menu\" }\n\"ui.selection\" = { bg = \"ui_selection\" }\n#\"ui.selection.primary\" = { bg = \"ui_selection\", underline.style = \"line\" }\n\"ui.statusline\" = { fg = \"ui_text\", bg = \"ui_background_accent\" }\n#\"ui.statusline.inactive\" = { fg = \"\", bg = \"\" }\n\"ui.statusline.insert\" = { fg = \"ui_mode_insert_text\", bg = \"ui_mode_insert\", modifiers = [\"bold\"] } \n\"ui.statusline.normal\" = { fg = \"ui_mode_normal_text\", bg = \"ui_mode_normal\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"ui_mode_select_text\", bg = \"ui_mode_select\", modifiers = [\"bold\"] }\n\"ui.text\" = \"ui_text\"\n\"ui.text.focus\" = { fg = \"ui_text\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = \"ui_text_dim\"\n#\"ui.text.info\" = \"\"\n\"ui.virtual.indent-guide\" = \"ui_text_dim\"\n\"ui.virtual.inlay-hint\" = \"ui_text_dim\"\n#\"ui.virtual.inlay-hint.parameter\" = \"\"\n#\"ui.virtual.inlay-hint.type\" = \"\"\n\"ui.virtual.jump-label\" = { fg = \"white\", bg = \"ui_jumplabel\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"ui_background_accent\" }\n\"ui.virtual.whitespace\" = \"ui_text_dim\"\n\"ui.virtual.wrap\" = \"ui_text_dim\"\n\"ui.window\" = \"ui_split_line\"\n\ninfo = { fg = 'ui_diagnostic_info' }\nhint = { fg = 'ui_diagnostic_hint', modifiers = ['bold'] }\nwarning = { fg = 'ui_diagnostic_warning', modifiers = ['bold'] }\nerror = { fg = 'ui_diagnostic_error', modifiers = ['bold'] }\n\n\"diagnostic.info\" = { fg = \"ui_diagnostic_info\", underline = { style = \"curl\", color = \"ui_diagnostic_info\" } }\n\"diagnostic.hint\" = { fg = \"ui_diagnostic_hint\", underline = { style = \"curl\", color = \"ui_diagnostic_hint\" } }\n\"diagnostic.warning\" = { fg = \"ui_diagnostic_warning\", underline = { style = \"curl\", color = \"ui_diagnostic_warning\" } }\n\"diagnostic.error\" = { fg = \"ui_diagnostic_error\", underline = { style = \"curl\", color = \"ui_diagnostic_error\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nbuiltins = \"#585cf6\"\ncomments = \"#00b418\"\nconstants_numeric = \"#cd0000\"\ndiff_delta = \"#0000a2\"\ndiff_minus = \"#990000\"\ndiff_plus = \"#00b418\"\nkeywords = \"#0100b6\"\nmarkup = \"#1c02ff\"\nmarkup_headings = \"#0c07ff\"\nmarkup_lists = \"#b90690\"\nmembers = \"#0206ff\"\noperators = \"#0100b6\"\npreprocessor = \"#0c450d\"\nstrings = \"#d80800\"\nsymbols = \"#26b31a\"\nui_background = \"#ffffff\"\nui_background_accent = \"#ededed\"\nui_highlight_line = \"#0100b6\"\nui_highlight_line_text = \"#ffffff\"\nui_debug_breakpoint = \"#990000\"\nui_diagnostic_error = \"#990000\"\nui_diagnostic_hint = \"#06960e\"\nui_diagnostic_info = \"#808080\"\nui_diagnostic_warning = \"#fafa28\"\nui_jumplabel = \"#990000\"\nui_menu = \"#c3dcff\"\nui_menu_selected = \"#a3bcdf\"\nui_menu_handle = \"#839cbf\"\nui_menu_text = \"#000000\"\nui_mode_insert = \"#009608\"\nui_mode_insert_accent = \"#73e678\"\nui_mode_insert_text = \"#ffffff\"\nui_mode_normal = \"#444444\" \nui_mode_normal_accent = \"#cccccc\"\nui_mode_normal_text = \"#ffffff\"\nui_mode_select = \"#000096\" \nui_mode_select_accent = \"#7373e6\"\nui_mode_select_text = \"#ffffff\"\nui_selection = \"#c3dcff\"\nui_split_line = \"#000000\"\nui_statusline = \"#000000\"\nui_text = \"#000000\"\nui_text_dim = \"#808080\"\n"
  },
  {
    "path": "runtime/themes/eldritch.toml",
    "content": "# Author : tangowithfoxtrot\n# Author : neonvoidx\n# Eldritch - a theme for the Ancient Ones\n\n\"annotation\"                      = { fg = \"foreground\"                                                     }\n\"attribute\"                       = { fg = \"green\",              modifiers = [\"italic\"]                     }\n\"comment\"                         = { fg = \"comment\"                                                        }\n\"comment.block.documentation\"     = { fg = \"comment\"                                                        }\n\"comment.block\"                   = { fg = \"comment\"                                                        }\n\"comment.line\"                    = { fg = \"comment\"                                                        }\n\"constant\"                        = { fg = \"purple\"                                                         }\n\"constant.numeric\"                = { fg = \"purple\"                                                         }\n\"constant.builtin\"                = { fg = \"purple\"                                                         }\n\"constant.builtin.boolean\"        = { fg = \"purple\"                                                         }\n\"constant.character\"              = { fg = \"cyan\"                                                           }\n\"constant.character.escape\"       = { fg = \"pink\"                                                           }\n\"constant.macro\"                  = { fg = \"purple\"                                                         }\n\"constructor\"                     = { fg = \"purple\"                                                         }\n\"function\"                        = { fg = \"green\"                                                          }\n\"function.builtin\"                = { fg = \"green\"                                                          }\n\"function.method\"                 = { fg = \"green\"                                                          }\n\"function.macro\"                  = { fg = \"purple\"                                                         }\n\"function.call\"                   = { fg = \"green\"                                                          }\n\"keyword\"                         = { fg = \"pink\"                                                           }\n\"keyword.operator\"                = { fg = \"pink\"                                                           }\n\"keyword.function\"                = { fg = \"pink\"                                                           }\n\"keyword.return\"                  = { fg = \"pink\"                                                           }\n\"keyword.control.import\"          = { fg = \"pink\"                                                           }\n\"keyword.directive\"               = { fg = \"green\"                                                          }\n\"keyword.control.repeat\"          = { fg = \"pink\"                                                           }\n\"keyword.control.conditional\"     = { fg = \"pink\"                                                           }\n\"keyword.control.exception\"       = { fg = \"purple\"                                                         }\n\"keyword.storage\"                 = { fg = \"pink\"                                                           }\n\"keyword.storage.type\"            = { fg = \"cyan\",               modifiers = [\"italic\"]                     }\n\"keyword.storage.modifier\"        = { fg = \"pink\"                                                           }\n\"tag\"                             = { fg = \"pink\"                                                           }\n\"tag.attribute\"                   = { fg = \"purple\"                                                         }\n\"tag.delimiter\"                   = { fg = \"foreground\"                                                     }\n\"label\"                           = { fg = \"cyan\"                                                           }\n\"punctuation\"                     = { fg = \"foreground\"                                                     }\n\"punctuation.bracket\"             = { fg = \"foreground\"                                                     }\n\"punctuation.delimiter\"           = { fg = \"foreground\"                                                     }\n\"punctuation.special\"             = { fg = \"pink\"                                                           }\n\"special\"                         = { fg = \"pink\"                                                           }\n\"string\"                          = { fg = \"yellow\"                                                         }\n\"string.special\"                  = { fg = \"orange\"                                                         }\n\"string.symbol\"                   = { fg = \"yellow\"                                                         }\n\"string.regexp\"                   = { fg = \"red\"                                                            }\n\"type.builtin\"                    = { fg = \"cyan\"                                                           }\n\"type\"                            = { fg = \"cyan\",               modifiers = [\"italic\"]                     }\n\"type.enum.variant\"               = { fg = \"foreground\",         modifiers = [\"italic\"]                     }\n\"variable\"                        = { fg = \"foreground\"                                                     }\n\"variable.builtin\"                = { fg = \"purple\",             modifiers = [\"italic\"]                     }\n\"variable.parameter\"              = { fg = \"orange\",             modifiers = [\"italic\"]                     }\n\"variable.other\"                  = { fg = \"foreground\"                                                     }\n\"variable.other.member\"           = { fg = \"foreground\"                                                     }\n\"diff.plus\"                       = { fg = \"green\"                                                          }\n\"diff.delta\"                      = { fg = \"orange\"                                                         }\n\"diff.minus\"                      = { fg = \"red\"                                                            }\n\"ui.background\"                   = { fg = \"foreground\",         bg = \"background\"                          }\n\"ui.cursor.match\"                 = { fg = \"foreground\",         bg = \"grey\",          modifiers = [\"bold\"] }\n\"ui.cursor\"                       = { fg = \"background\",         bg = \"purple\",        modifiers = [\"dim\"]  }\n\"ui.cursor.normal\"                = { fg = \"background\",         bg = \"cyan\",          modifiers = [\"dim\"]  }\t\n\"ui.cursor.insert\"                = { fg = \"background\",         bg = \"green\",         modifiers = [\"dim\"]  }\t\n\"ui.cursor.select\"                = { fg = \"background\",         bg = \"yellow\",        modifiers = [\"dim\"]  }\n\"ui.cursor.primary.normal\"        = { fg = \"background\",         bg = \"cyan\"                                }\t\n\"ui.cursor.primary.insert\"        = { fg = \"background\",         bg = \"green\"                               }\t\n\"ui.cursor.primary.select\"        = { fg = \"background\",         bg = \"yellow\"                              }\n\"ui.cursorline.primary\"           = {                            bg = \"cursorline\"                          }\n\"ui.help\"                         = { fg = \"foreground\",         bg = \"background\"                          }\n\"ui.debug\"                        = { fg = \"red\"                                                            }\n\"ui.highlight.frameline\"          = { fg = \"background\",         bg = \"red\"                                 }\n\"ui.linenr\"                       = { fg = \"comment\"                                                        }\n\"ui.linenr.selected\"              = { fg = \"foreground\"                                                     }\n\"ui.menu\"                         = { fg = \"foreground\",         bg = \"current_line\"                        }\n\"ui.menu.selected\"                = { fg = \"current_line\",       bg = \"purple\",        modifiers = [\"dim\"]  }\n\"ui.menu.scroll\"                  = { fg = \"foreground\",         bg = \"current_line\"                        }\n\"ui.popup\"                        = { fg = \"foreground\",         bg = \"background_dark\"                     }\n\"ui.selection.primary\"            = {                            bg = \"current_line\"                        }\n\"ui.selection\"                    = {                            bg = \"selection\"                           }\n\"ui.statusline\"                   = { fg = \"foreground\",         bg = \"darker\"                              }\n\"ui.statusline.inactive\"          = { fg = \"comment\",            bg = \"darker\"                              }\n\"ui.statusline.normal\"            = { fg = \"black\",              bg = \"cyan\",          modifiers = [\"bold\"] }\n\"ui.statusline.insert\"            = { fg = \"black\",              bg = \"green\",         modifiers = [\"bold\"] }\n\"ui.statusline.select\"            = { fg = \"black\",              bg = \"yellow\",        modifiers = [\"bold\"] }\n\"ui.text\"                         = { fg = \"foreground\"                                                     }\n\"ui.text.directory\"               = { fg = \"blue\"                                                           }\n\"ui.text.focus\"                   = { fg = \"cyan\"                                                           }\n\"ui.window\"                       = { fg = \"foreground\"                                                     }\n\"ui.virtual.whitespace\"           = { fg = \"current_line\"                                                   }\n\"ui.virtual.wrap\"                 = { fg = \"current_line\"                                                   }\n\"ui.virtual.ruler\"                = {                            bg = \"black\"                               }\n\"ui.virtual.indent-guide\"         = { fg = \"indent\"                                                         }\n\"ui.virtual.inlay-hint\"           = { fg = \"cyan\"                                                           }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"cyan\",               modifiers = [\"italic\", \"dim\"]              }\n\"ui.virtual.inlay-hint.type\"      = { fg = \"cyan\",               modifiers = [\"italic\", \"dim\"]              }\n\"hint\"                            = { fg = \"purple\",             bg = \"darker\"                              }\n\"error\"                           = { fg = \"red\",                bg = \"darker\"                              }\n\"warning\"                         = { fg = \"yellow\",             bg = \"darker\"                              }\n\"info\"                            = { fg = \"cyan\",               bg = \"darker\"                              }\n\"markup.heading\"                  = { fg = \"purple\",             modifiers = [\"bold\"]                       }\n\"markup.list\"                     = { fg = \"cyan\"                                                           }\n\"markup.bold\"                     = { fg = \"orange\",             modifiers = [\"bold\"]                       }\n\"markup.italic\"                   = { fg = \"yellow\",             modifiers = [\"italic\"]                     }\n\"markup.strikethrough\"            = {                            modifiers = [\"crossed_out\"]                }\n\"markup.link.url\"                 = { fg = \"cyan\"                                                           }\n\"markup.link.text\"                = { fg = \"pink\"                                                           }\n\"markup.quote\"                    = { fg = \"yellow\",             modifiers = [\"italic\"]                     }\n\"markup.raw\"                      = { fg = \"foreground\"                                                     }\n\n\"diagnostic\"                      = { underline = { color = \"orange\", style = \"curl\" } }\n\"diagnostic.hint\"                 = { underline = { color = \"purple\", style = \"curl\" } }\n\"diagnostic.warning\"              = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\"                = { underline = { color = \"red\",    style = \"curl\" } }\n\"diagnostic.info\"                 = { underline = { color = \"cyan\",   style = \"curl\" } }\n\"definition\"                      = { underline = { color = \"cyan\"                   } }\n\n[palette]\nbackground      = \"#323449\"\nbackground_dark = \"#212337\"\nforeground      = \"#ebfafa\"\ncomment         = \"#7081d0\"\ncursorline      = \"#323449\"\ncurrent_line    = \"#3b4261\"\nindent          = \"#6ce9ff\"\nselection       = \"#323449\"\ndarker          = \"#212337\"\nblack           = \"#171928\"\ngrey            = \"#7081d0\"\nred             = \"#f16c75\"\norange          = \"#ffb86c\"\nyellow          = \"#f7c67f\"\ngreen           = \"#37f499\"\npurple          = \"#a48cf2\"\ncyan            = \"#04d1f9\"\npink            = \"#f265b5\"\n"
  },
  {
    "path": "runtime/themes/eldritch_transparent.toml",
    "content": "# Author : tangowithfoxtrot\n# Eldritch theme with a transparent background\n\ninherits = \"eldritch\"\n\n\"ui.background\" = { }\n\"ui.popup\"      = { modifiers = [\"italic\"] }\n"
  },
  {
    "path": "runtime/themes/emacs.toml",
    "content": "# Ported by Yevgnen.\n\n\"comment\" = { fg = \"firebrick\" }\n\"constant\" = { fg = \"dark_cyan\" }\n\"constant.builtin\" = { fg = \"dark_slate_blue\" }\n\"function\" = { fg = \"blue1\" }\n\"function.call\" = { fg = \"blue1\" }\n\"function.macro\" = { fg = \"dark_slate_blue\" }\n\"function.builtin\" = { fg = \"dark_slate_blue\" }\n\"function.special\" = { fg = \"dark_slate_blue\" }\n\"keyword\" = { fg = \"purple\" }\n\"operator\" = { fg = \"purple\" }\n\"punctuation\" = { fg = \"black\" }\n\"string\" = { fg = \"violetred4\" }\n\"string.special\" = { fg = \"violetred4\", modifiers = [\"bold\"] }\n\"type\" = { fg = \"forest_green\" }\n\"type.builtin\" = { fg = \"dark_slate_blue\" }\n\"constructor\" = { fg = \"forest_green\" }\n\"variable\" = { fg = \"sienna\" }\n\"variable.builtin\" = { fg = \"dark_slate_blue\" }\n\"variable.parameter\" = { fg = \"sienna\" }\n\"tag\" = { fg = \"blue1\" }\n\"label\" = { fg = \"dark_slate_blue\" }\n\"attribute\" = { fg = \"dark_slate_blue\" }\n\"namespace\" = { fg = \"dark_cyan\" }\n\"module\" = { fg = \"dark_cyan\" }\n\"special\" = { fg = \"blue1\" }\n\n\"markup.heading\" = { fg = \"gold\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = { fg = \"gray60\" }\n\"markup.heading.1\" = { fg = \"blue1\" }\n\"markup.heading.2\" = { fg = \"sienna\" }\n\"markup.heading.3\" = { fg = \"purple\" }\n\"markup.heading.4\" = { fg = \"firebrick\" }\n\"markup.heading.5\" = { fg = \"forest_green\" }\n\"markup.heading.6\" = { fg = \"dark_cyan\" }\n\"markup.list\" = { fg = \"black\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"royalblue3\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"royalblue3\" }\n\"markup.quote\" = { fg = \"gray60\" }\n\"markup.raw.inline\" = { fg = \"dark_cyan\" }\n\"markup.raw.block\" = { fg = \"dark_cyan\" }\n\n\"ui.background\" = { fg = \"black\", bg = \"white\" }\n\"ui.background.separator\" = { fg = \"black\", bg = \"white\" }\n\"ui.cursor\" = { fg = \"white\", bg = \"gray70\" }\n\"ui.cursor.primary\" = { fg = \"white\", bg = \"black\" }\n\"ui.cursor.match\" = { fg = \"black\", bg = \"turquoise\" }\n\"ui.cursor.select\" = { fg = \"white\", bg = \"black\" }\n\"ui.cursor.insert\" = { fg = \"red\", bg = \"black\" }\n\"ui.linenr\" = { fg = \"gray60\" }\n\"ui.linenr.selected\" = { fg = \"gray80\" }\n\"ui.statusline\" = { fg = \"black\", bg = \"gray75\" }\n\"ui.statusline.inactive\" = { fg = \"gray20\", bg = \"gray90\" }\n\"ui.bufferline\" = { fg = \"gray36\", bg = \"gray90\", modifiers = [\"underlined\"] }\n\"ui.bufferline.active\" = { fg = \"gray0\", bg = \"gray99\" }\n\"ui.bufferline.background\" = { bg = \"gray75\" }\n\"ui.popup\" = { fg = \"black\", bg = \"gray97\" }\n\"ui.popup.info\" = { fg = \"black\", bg = \"gray97\" }\n\"ui.window\" = { fg = \"black\" }\n\"ui.help\" = { fg = \"dark_red\", bg = \"cornsilk\" }\n\"ui.text\" = { fg = \"black\" }\n\"ui.text.focus\" = { fg = \"black\", bg = \"darkseagreen2\" }\n\"ui.menu\" = { fg = \"black\", bg = \"cornsilk\" }\n\"ui.menu.selected\" = { fg = \"dark_red\", bg = \"light_blue\" }\n\"ui.selection\" = { bg = \"lightgoldenrod1\" }\n\"ui.selection.primary\" = { bg = \"lightgoldenrod2\" }\n# Malformed ANSI: highlight. See 'https://github.com/helix-editor/helix/issues/5709'\n# \"ui.virtual.whitespace\" = \"highlight\"\n\"ui.virtual.ruler\" = { bg = \"gray95\" }\n\"ui.virtual.inlay-hint\" = { fg = \"gray75\" }\n\"ui.cursorline.primary\" = { bg = \"darkseagreen2\" }\n\"ui.cursorline.secondary\" = { bg = \"darkseagreen2\" }\n\n\"diff.plus\" = { fg = \"green3\" }\n\"diff.delta\" = { fg = \"orange2\" }\n\"diff.minus\" = { fg = \"red2\" }\n\n\"error\" = { fg = \"red1\" }\n\"warning\" = { fg = \"dark_orange\" }\n\"info\" = { fg = \"forest_green\" }\n\"hint\" = { fg = \"dark_cyan\" }\n\n\"diagnostic.error\" = { underline = { color = \"red1\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"dark_orange\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"forest_green\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"dark_cyan\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nblack = \"#000000\"\ndim_gray = \"#696969\"\ndark_gray = \"#a9a9a9\"\ngray = \"#bebebe\"\nlight_gray = \"#d3d3d3\"\ngainsboro = \"#dcdcdc\"\nwhite_smoke = \"#f5f5f5\"\nwhite = \"#ffffff\"\nred = \"#ff0000\"\norange_red = \"#ff4500\"\ndark_orange = \"#ff8c00\"\norange = \"#ffa500\"\ngold = \"#ffd700\"\nyellow = \"#ffff00\"\nchartreuse = \"#7fff00\"\nlawn_green = \"#7cfc00\"\ngreen = \"#00ff00\"\nspring_green = \"#00ff7f\"\nmedium_spring_green = \"#00fa9a\"\ncyan = \"#00ffff\"\ndeep_sky_blue = \"#00bfff\"\nblue = \"#0000ff\"\nmedium_blue = \"#0000cd\"\ndark_violet = \"#9400d3\"\ndark_magenta = \"#8b008b\"\nmagenta = \"#ff00ff\"\ndark_red = \"#8b0000\"\nbrown = \"#a52a2a\"\nfirebrick = \"#b22222\"\nindian_red = \"#cd5c5c\"\nlight_coral = \"#f08080\"\nsalmon = \"#fa8072\"\nlight_salmon = \"#ffa07a\"\ntomato = \"#ff6347\"\ncoral = \"#ff7f50\"\ndark_salmon = \"#e9967a\"\nrosy_brown = \"#bc8f8f\"\nsienna = \"#a0522d\"\nsaddle_brown = \"#8b4513\"\nchocolate = \"#d2691e\"\nperu = \"#cd853f\"\nsandy_brown = \"#f4a460\"\nburlywood = \"#deb887\"\ntan = \"#d2b48c\"\nnavajo_white = \"#ffdead\"\nwheat = \"#f5deb3\"\ndark_goldenrod = \"#b8860b\"\ngoldenrod = \"#daa520\"\nlight_goldenrod = \"#eedd82\"\npale_goldenrod = \"#eee8aa\"\ncornsilk = \"#fff8dc\"\ndark_khaki = \"#bdb76b\"\nkhaki = \"#f0e68c\"\nlemon_chiffon = \"#fffacd\"\ndark_olive_green = \"#556b2f\"\nolive_drab = \"#6b8e23\"\nyellow_green = \"#9acd32\"\ngreen_yellow = \"#adff2f\"\nlight_green = \"#90ee90\"\nforest_green = \"#228b22\"\ndark_green = \"#006400\"\nlime_green = \"#32cd32\"\npale_green = \"#98fb98\"\ndark_sea_green = \"#8fbc8f\"\nsea_green = \"#2e8b57\"\nmedium_sea_green = \"#3cb371\"\nlight_sea_green = \"#20b2aa\"\nmedium_aquamarine = \"#66cdaa\"\naquamarine = \"#7fffd4\"\ndark_cyan = \"#008b8b\"\ndark_turquoise = \"#00ced1\"\nmedium_turquoise = \"#48d1cc\"\nturquoise = \"#40e0d0\"\npale_turquoise = \"#afeeee\"\npowder_blue = \"#b0e0e6\"\nlight_blue = \"#add8e6\"\nsky_blue = \"#87ceeb\"\nlight_sky_blue = \"#87cefa\"\ncadet_blue = \"#5f9ea0\"\nsteel_blue = \"#4682b4\"\ndark_slate_gray = \"#2f4f4f\"\nslate_gray = \"#708090\"\nlight_slate_gray = \"#778899\"\nroyal_blue = \"#4169e1\"\ndodger_blue = \"#1e90ff\"\ncornflower_blue = \"#6495ed\"\nlight_steel_blue = \"#b0c4de\"\ndark_blue = \"#00008b\"\nnavy = \"#000080\"\nmidnight_blue = \"#191970\"\ndark_slate_blue = \"#483d8b\"\nslate_blue = \"#6a5acd\"\nmedium_slate_blue = \"#7b68ee\"\nlight_slate_blue = \"#8470ff\"\nmedium_purple = \"#9370db\"\nblue_violet = \"#8a2be2\"\npurple = \"#a020f0\"\ndark_orchid = \"#9932cc\"\nmedium_orchid = \"#ba55d3\"\norchid = \"#da70d6\"\nthistle = \"#d8bfd8\"\nplum = \"#dda0dd\"\nviolet = \"#ee82ee\"\nmedium_violet_red = \"#c71585\"\nviolet_red = \"#d02090\"\npale_violet_red = \"#db7093\"\nmaroon = \"#b03060\"\ndeep_pink = \"#ff1493\"\nhot_pink = \"#ff69b4\"\npink = \"#ffc0cb\"\nlight_pink = \"#ffb6c1\"\nsnow = \"#fffafa\"\nmisty_rose = \"#ffe4e1\"\nseashell = \"#fff5ee\"\npeach_puff = \"#ffdab9\"\nlinen = \"#faf0e6\"\nantique_white = \"#faebd7\"\nbisque = \"#ffe4c4\"\npapaya_whip = \"#ffefd5\"\nmoccasin = \"#ffe4b5\"\nblanched_almond = \"#ffebcd\"\nold_lace = \"#fdf5e6\"\nfloral_white = \"#fffaf0\"\nbeige = \"#f5f5dc\"\nlight_yellow = \"#ffffe0\"\nlight_goldenrod_yellow = \"#fafad2\"\nivory = \"#fffff0\"\nhoneydew = \"#f0fff0\"\nmint_cream = \"#f5fffa\"\nlight_cyan = \"#e0ffff\"\nazure = \"#f0ffff\"\nalice_blue = \"#f0f8ff\"\nlavender = \"#e6e6fa\"\nghost_white = \"#f8f8ff\"\nlavender_blush = \"#fff0f5\"\nred4 = \"#8b0000\"\nred3 = \"#cd0000\"\nred2 = \"#ee0000\"\nred1 = \"#ff0000\"\norangered4 = \"#8b2500\"\norangered3 = \"#cd3700\"\norangered2 = \"#ee4000\"\norangered1 = \"#ff4500\"\ndarkorange4 = \"#8b4500\"\ndarkorange3 = \"#cd6600\"\ndarkorange2 = \"#ee7600\"\ndarkorange1 = \"#ff7f00\"\norange4 = \"#8b5a00\"\norange3 = \"#cd8500\"\norange2 = \"#ee9a00\"\norange1 = \"#ffa500\"\ngold4 = \"#8b7500\"\ngold3 = \"#cdad00\"\ngold2 = \"#eec900\"\ngold1 = \"#ffd700\"\nyellow4 = \"#8b8b00\"\nyellow3 = \"#cdcd00\"\nyellow2 = \"#eeee00\"\nyellow1 = \"#ffff00\"\nchartreuse4 = \"#458b00\"\nchartreuse3 = \"#66cd00\"\nchartreuse2 = \"#76ee00\"\nchartreuse1 = \"#7fff00\"\ngreen4 = \"#008b00\"\ngreen3 = \"#00cd00\"\ngreen2 = \"#00ee00\"\ngreen1 = \"#00ff00\"\nspringgreen4 = \"#008b45\"\nspringgreen3 = \"#00cd66\"\nspringgreen2 = \"#00ee76\"\nspringgreen1 = \"#00ff7f\"\ncyan4 = \"#008b8b\"\ncyan3 = \"#00cdcd\"\ncyan2 = \"#00eeee\"\ncyan1 = \"#00ffff\"\nturquoise4 = \"#00868b\"\nturquoise3 = \"#00c5cd\"\nturquoise2 = \"#00e5ee\"\nturquoise1 = \"#00f5ff\"\ndeepskyblue4 = \"#00688b\"\ndeepskyblue3 = \"#009acd\"\ndeepskyblue2 = \"#00b2ee\"\ndeepskyblue1 = \"#00bfff\"\nblue4 = \"#00008b\"\nblue3 = \"#0000cd\"\nblue2 = \"#0000ee\"\nblue1 = \"#0000ff\"\nmagenta4 = \"#8b008b\"\nmagenta3 = \"#cd00cd\"\nmagenta2 = \"#ee00ee\"\nmagenta1 = \"#ff00ff\"\nbrown4 = \"#8b2323\"\nbrown3 = \"#cd3333\"\nbrown2 = \"#ee3b3b\"\nbrown1 = \"#ff4040\"\nfirebrick4 = \"#8b1a1a\"\nfirebrick3 = \"#cd2626\"\nfirebrick2 = \"#ee2c2c\"\nfirebrick1 = \"#ff3030\"\nindianred4 = \"#8b3a3a\"\nindianred3 = \"#cd5555\"\nindianred2 = \"#ee6363\"\nindianred1 = \"#ff6a6a\"\nrosybrown4 = \"#8b6969\"\nrosybrown3 = \"#cd9b9b\"\nrosybrown2 = \"#eeb4b4\"\nrosybrown1 = \"#ffc1c1\"\nsnow4 = \"#8b8989\"\nsnow3 = \"#cdc9c9\"\nsnow2 = \"#eee9e9\"\nsnow1 = \"#fffafa\"\nmistyrose4 = \"#8b7d7b\"\nmistyrose3 = \"#cdb7b5\"\nmistyrose2 = \"#eed5d2\"\nmistyrose1 = \"#ffe4e1\"\ntomato4 = \"#8b3626\"\ntomato3 = \"#cd4f39\"\ntomato2 = \"#ee5c42\"\ntomato1 = \"#ff6347\"\ncoral4 = \"#8b3e2f\"\ncoral3 = \"#cd5b45\"\ncoral2 = \"#ee6a50\"\ncoral1 = \"#ff7256\"\nsalmon4 = \"#8b4c39\"\nsalmon3 = \"#cd7054\"\nsalmon2 = \"#ee8262\"\nsalmon1 = \"#ff8c69\"\nlightsalmon4 = \"#8b5742\"\nlightsalmon3 = \"#cd8162\"\nlightsalmon2 = \"#ee9572\"\nlightsalmon1 = \"#ffa07a\"\nsienna4 = \"#8b4726\"\nsienna3 = \"#cd6839\"\nsienna2 = \"#ee7942\"\nsienna1 = \"#ff8247\"\nchocolate4 = \"#8b4513\"\nchocolate3 = \"#cd661d\"\nchocolate2 = \"#ee7621\"\nchocolate1 = \"#ff7f24\"\nseashell4 = \"#8b8682\"\nseashell3 = \"#cdc5bf\"\nseashell2 = \"#eee5de\"\nseashell1 = \"#fff5ee\"\npeachpuff4 = \"#8b7765\"\npeachpuff3 = \"#cdaf95\"\npeachpuff2 = \"#eecbad\"\npeachpuff1 = \"#ffdab9\"\ntan4 = \"#8b5a2b\"\ntan3 = \"#cd853f\"\ntan2 = \"#ee9a49\"\ntan1 = \"#ffa54f\"\nbisque4 = \"#8b7d6b\"\nbisque3 = \"#cdb79e\"\nbisque2 = \"#eed5b7\"\nbisque1 = \"#ffe4c4\"\nantiquewhite4 = \"#8b8378\"\nantiquewhite3 = \"#cdc0b0\"\nantiquewhite2 = \"#eedfcc\"\nantiquewhite1 = \"#ffefdb\"\nburlywood4 = \"#8b7355\"\nburlywood3 = \"#cdaa7d\"\nburlywood2 = \"#eec591\"\nburlywood1 = \"#ffd39b\"\nnavajowhite4 = \"#8b795e\"\nnavajowhite3 = \"#cdb38b\"\nnavajowhite2 = \"#eecfa1\"\nnavajowhite1 = \"#ffdead\"\nwheat4 = \"#8b7e66\"\nwheat3 = \"#cdba96\"\nwheat2 = \"#eed8ae\"\nwheat1 = \"#ffe7ba\"\ndarkgoldenrod4 = \"#8b6508\"\ndarkgoldenrod3 = \"#cd950c\"\ndarkgoldenrod2 = \"#eead0e\"\ndarkgoldenrod1 = \"#ffb90f\"\ngoldenrod4 = \"#8b6914\"\ngoldenrod3 = \"#cd9b1d\"\ngoldenrod2 = \"#eeb422\"\ngoldenrod1 = \"#ffc125\"\ncornsilk4 = \"#8b8878\"\ncornsilk3 = \"#cdc8b1\"\ncornsilk2 = \"#eee8cd\"\ncornsilk1 = \"#fff8dc\"\nlightgoldenrod4 = \"#8b814c\"\nlightgoldenrod3 = \"#cdbe70\"\nlightgoldenrod2 = \"#eedc82\"\nlightgoldenrod1 = \"#ffec8b\"\nlemonchiffon4 = \"#8b8970\"\nlemonchiffon3 = \"#cdc9a5\"\nlemonchiffon2 = \"#eee9bf\"\nlemonchiffon1 = \"#fffacd\"\nkhaki4 = \"#8b864e\"\nkhaki3 = \"#cdc673\"\nkhaki2 = \"#eee685\"\nkhaki1 = \"#fff68f\"\nlightyellow4 = \"#8b8b7a\"\nlightyellow3 = \"#cdcdb4\"\nlightyellow2 = \"#eeeed1\"\nlightyellow1 = \"#ffffe0\"\nivory4 = \"#8b8b83\"\nivory3 = \"#cdcdc1\"\nivory2 = \"#eeeee0\"\nivory1 = \"#fffff0\"\nolivedrab4 = \"#698b22\"\nolivedrab3 = \"#9acd32\"\nolivedrab2 = \"#b3ee3a\"\nolivedrab1 = \"#c0ff3e\"\ndarkolivegreen4 = \"#6e8b3d\"\ndarkolivegreen3 = \"#a2cd5a\"\ndarkolivegreen2 = \"#bcee68\"\ndarkolivegreen1 = \"#caff70\"\npalegreen4 = \"#548b54\"\npalegreen3 = \"#7ccd7c\"\npalegreen2 = \"#90ee90\"\npalegreen1 = \"#9aff9a\"\ndarkseagreen4 = \"#698b69\"\ndarkseagreen3 = \"#9bcd9b\"\ndarkseagreen2 = \"#b4eeb4\"\ndarkseagreen1 = \"#c1ffc1\"\nhoneydew4 = \"#838b83\"\nhoneydew3 = \"#c1cdc1\"\nhoneydew2 = \"#e0eee0\"\nhoneydew1 = \"#f0fff0\"\nseagreen4 = \"#2e8b57\"\nseagreen3 = \"#43cd80\"\nseagreen2 = \"#4eee94\"\nseagreen1 = \"#54ff9f\"\naquamarine4 = \"#458b74\"\naquamarine3 = \"#66cdaa\"\naquamarine2 = \"#76eec6\"\naquamarine1 = \"#7fffd4\"\ndarkslategray4 = \"#528b8b\"\ndarkslategray3 = \"#79cdcd\"\ndarkslategray2 = \"#8deeee\"\ndarkslategray1 = \"#97ffff\"\npaleturquoise4 = \"#668b8b\"\npaleturquoise3 = \"#96cdcd\"\npaleturquoise2 = \"#aeeeee\"\npaleturquoise1 = \"#bbffff\"\nlightcyan4 = \"#7a8b8b\"\nlightcyan3 = \"#b4cdcd\"\nlightcyan2 = \"#d1eeee\"\nlightcyan1 = \"#e0ffff\"\nazure4 = \"#838b8b\"\nazure3 = \"#c1cdcd\"\nazure2 = \"#e0eeee\"\nazure1 = \"#f0ffff\"\ncadetblue4 = \"#53868b\"\ncadetblue3 = \"#7ac5cd\"\ncadetblue2 = \"#8ee5ee\"\ncadetblue1 = \"#98f5ff\"\nlightblue4 = \"#68838b\"\nlightblue3 = \"#9ac0cd\"\nlightblue2 = \"#b2dfee\"\nlightblue1 = \"#bfefff\"\nlightskyblue4 = \"#607b8b\"\nlightskyblue3 = \"#8db6cd\"\nlightskyblue2 = \"#a4d3ee\"\nlightskyblue1 = \"#b0e2ff\"\nskyblue4 = \"#4a708b\"\nskyblue3 = \"#6ca6cd\"\nskyblue2 = \"#7ec0ee\"\nskyblue1 = \"#87ceff\"\nsteelblue4 = \"#36648b\"\nsteelblue3 = \"#4f94cd\"\nsteelblue2 = \"#5cacee\"\nsteelblue1 = \"#63b8ff\"\ndodgerblue4 = \"#104e8b\"\ndodgerblue3 = \"#1874cd\"\ndodgerblue2 = \"#1c86ee\"\ndodgerblue1 = \"#1e90ff\"\nslategray4 = \"#6c7b8b\"\nslategray3 = \"#9fb6cd\"\nslategray2 = \"#b9d3ee\"\nslategray1 = \"#c6e2ff\"\nlightsteelblue4 = \"#6e7b8b\"\nlightsteelblue3 = \"#a2b5cd\"\nlightsteelblue2 = \"#bcd2ee\"\nlightsteelblue1 = \"#cae1ff\"\nroyalblue4 = \"#27408b\"\nroyalblue3 = \"#3a5fcd\"\nroyalblue2 = \"#436eee\"\nroyalblue1 = \"#4876ff\"\nslateblue4 = \"#473c8b\"\nslateblue3 = \"#6959cd\"\nslateblue2 = \"#7a67ee\"\nslateblue1 = \"#836fff\"\nmediumpurple4 = \"#5d478b\"\nmediumpurple3 = \"#8968cd\"\nmediumpurple2 = \"#9f79ee\"\nmediumpurple1 = \"#ab82ff\"\npurple4 = \"#551a8b\"\npurple3 = \"#7d26cd\"\npurple2 = \"#912cee\"\npurple1 = \"#9b30ff\"\ndarkorchid4 = \"#68228b\"\ndarkorchid3 = \"#9a32cd\"\ndarkorchid2 = \"#b23aee\"\ndarkorchid1 = \"#bf3eff\"\nmediumorchid4 = \"#7a378b\"\nmediumorchid3 = \"#b452cd\"\nmediumorchid2 = \"#d15fee\"\nmediumorchid1 = \"#e066ff\"\nthistle4 = \"#8b7b8b\"\nthistle3 = \"#cdb5cd\"\nthistle2 = \"#eed2ee\"\nthistle1 = \"#ffe1ff\"\nplum4 = \"#8b668b\"\nplum3 = \"#cd96cd\"\nplum2 = \"#eeaeee\"\nplum1 = \"#ffbbff\"\norchid4 = \"#8b4789\"\norchid3 = \"#cd69c9\"\norchid2 = \"#ee7ae9\"\norchid1 = \"#ff83fa\"\nmaroon4 = \"#8b1c62\"\nmaroon3 = \"#cd2990\"\nmaroon2 = \"#ee30a7\"\nmaroon1 = \"#ff34b3\"\ndeeppink4 = \"#8b0a50\"\ndeeppink3 = \"#cd1076\"\ndeeppink2 = \"#ee1289\"\ndeeppink1 = \"#ff1493\"\nhotpink4 = \"#8b3a62\"\nhotpink3 = \"#cd6090\"\nhotpink2 = \"#ee6aa7\"\nhotpink1 = \"#ff6eb4\"\nvioletred4 = \"#8b2252\"\nvioletred3 = \"#cd3278\"\nvioletred2 = \"#ee3a8c\"\nvioletred1 = \"#ff3e96\"\nlavenderblush4 = \"#8b8386\"\nlavenderblush3 = \"#cdc1c5\"\nlavenderblush2 = \"#eee0e5\"\nlavenderblush1 = \"#fff0f5\"\npalevioletred4 = \"#8b475d\"\npalevioletred3 = \"#cd6889\"\npalevioletred2 = \"#ee799f\"\npalevioletred1 = \"#ff82ab\"\npink4 = \"#8b636c\"\npink3 = \"#cd919e\"\npink2 = \"#eea9b8\"\npink1 = \"#ffb5c5\"\nlightpink4 = \"#8b5f65\"\nlightpink3 = \"#cd8c95\"\nlightpink2 = \"#eea2ad\"\nlightpink1 = \"#ffaeb9\"\ngray0 = \"#000000\"\ngray1 = \"#030303\"\ngray2 = \"#050505\"\ngray3 = \"#080808\"\ngray4 = \"#0a0a0a\"\ngray5 = \"#0d0d0d\"\ngray6 = \"#0f0f0f\"\ngray7 = \"#121212\"\ngray8 = \"#141414\"\ngray9 = \"#171717\"\ngray10 = \"#1a1a1a\"\ngray11 = \"#1c1c1c\"\ngray12 = \"#1f1f1f\"\ngray13 = \"#212121\"\ngray14 = \"#242424\"\ngray15 = \"#262626\"\ngray16 = \"#292929\"\ngray17 = \"#2b2b2b\"\ngray18 = \"#2e2e2e\"\ngray19 = \"#303030\"\ngray20 = \"#333333\"\ngray21 = \"#363636\"\ngray22 = \"#383838\"\ngray23 = \"#3b3b3b\"\ngray24 = \"#3d3d3d\"\ngray25 = \"#404040\"\ngray26 = \"#424242\"\ngray27 = \"#454545\"\ngray28 = \"#474747\"\ngray29 = \"#4a4a4a\"\ngray30 = \"#4d4d4d\"\ngray31 = \"#4f4f4f\"\ngray32 = \"#525252\"\ngray33 = \"#545454\"\ngray34 = \"#575757\"\ngray35 = \"#595959\"\ngray36 = \"#5c5c5c\"\ngray37 = \"#5e5e5e\"\ngray38 = \"#616161\"\ngray39 = \"#636363\"\ngray40 = \"#666666\"\ngray41 = \"#696969\"\ngray42 = \"#6b6b6b\"\ngray43 = \"#6e6e6e\"\ngray44 = \"#707070\"\ngray45 = \"#737373\"\ngray46 = \"#757575\"\ngray47 = \"#787878\"\ngray48 = \"#7a7a7a\"\ngray49 = \"#7d7d7d\"\ngray50 = \"#7f7f7f\"\ngray51 = \"#828282\"\ngray52 = \"#858585\"\ngray53 = \"#878787\"\ngray54 = \"#8a8a8a\"\ngray55 = \"#8c8c8c\"\ngray56 = \"#8f8f8f\"\ngray57 = \"#919191\"\ngray58 = \"#949494\"\ngray59 = \"#969696\"\ngray60 = \"#999999\"\ngray61 = \"#9c9c9c\"\ngray62 = \"#9e9e9e\"\ngray63 = \"#a1a1a1\"\ngray64 = \"#a3a3a3\"\ngray65 = \"#a6a6a6\"\ngray66 = \"#a8a8a8\"\ngray67 = \"#ababab\"\ngray68 = \"#adadad\"\ngray69 = \"#b0b0b0\"\ngray70 = \"#b3b3b3\"\ngray71 = \"#b5b5b5\"\ngray72 = \"#b8b8b8\"\ngray73 = \"#bababa\"\ngray74 = \"#bdbdbd\"\ngray75 = \"#bfbfbf\"\ngray76 = \"#c2c2c2\"\ngray77 = \"#c4c4c4\"\ngray78 = \"#c7c7c7\"\ngray79 = \"#c9c9c9\"\ngray80 = \"#cccccc\"\ngray81 = \"#cfcfcf\"\ngray82 = \"#d1d1d1\"\ngray83 = \"#d4d4d4\"\ngray84 = \"#d6d6d6\"\ngray85 = \"#d9d9d9\"\ngray86 = \"#dbdbdb\"\ngray87 = \"#dedede\"\ngray88 = \"#e0e0e0\"\ngray89 = \"#e3e3e3\"\ngray90 = \"#e5e5e5\"\ngray91 = \"#e8e8e8\"\ngray92 = \"#ebebeb\"\ngray93 = \"#ededed\"\ngray94 = \"#f0f0f0\"\ngray95 = \"#f2f2f2\"\ngray96 = \"#f5f5f5\"\ngray97 = \"#f7f7f7\"\ngray98 = \"#fafafa\"\ngray99 = \"#fcfcfc\"\ngray100 = \"#ffffff\"\n"
  },
  {
    "path": "runtime/themes/everblush.toml",
    "content": "# Author: Isotoxal <isotoxal@proton.me>\n\n\"attribute\" = { fg = \"blue\" }\n\"comment\" = { fg = \"comment\", modifiers = [\"italic\"] }\n\"constant\" = { fg = \"cyan\" }\n\"constant.builtin.boolean\" = { fg = \"cyan\" }\n\"constant.character\" = { fg = \"blue\" }\n\"constant.numeric.float\" = { fg = \"black-light\" }\n\"constant.builtin\" = { fg = \"blue\" }\n\"constant.numeric\" = { fg = \"yellow\" }\n\"constructor\" = { fg = \"blue\" }\n\"function\" = { fg = \"red\" }\n\"function.builtin\" = { fg = \"cyan-light\" }\n\"function.macro\" = { fg = \"green\" }\n\"function.method\" = { fg = \"blue-light\" }\n\"keyword\" = { fg = \"blue\" }\n\"keyword.function\" = { fg = \"blue\" }\n\"keyword.operator\" = { fg = \"blue-light\" }\n\"keyword.control.conditional\" = { fg = \"red\" }\n\"keyword.control.import\" = { fg = \"red-light\" }\n\"keyword.control.return\" = { fg = \"blue\" }\n\"keyword.control.repeat\" = { fg = \"yellow-light\" }\n\"keyword.control.exception\" = { fg = \"black-light\" }\n\"label\" = { fg = \"blue\" }\n\"namespace\" = { fg = \"red-light\" }\n\"operator\" = { fg = \"white\" }\n#\"parameter.reference\" = { fg = \"red-light\" }\n#\"property\" = { fg = \"red\" }\n\"punctuation.bracket\" = { fg = \"white\" }\n\"punctuation.delimiter\" = { fg = \"white\" }\n\"punctuation.special\" = { fg = \"white\" }\n\"string\" = { fg = \"green\" }\n\"string.escape\" = { fg = \"blue\" }\n\"string.regex\" = { fg = \"green\" }\n\"string.special\" = { fg = \"blue\" }\n\"string.special.symbol\" = { fg = \"red\" }\n\"tag\" = { fg = \"blue\" }\n\"type\" = { fg = \"yellow\" }\n\"type.builtin\" = { fg = \"yellow\" }\n\"variable\" = { fg = \"white\" }\n\"variable.builtin\" = { fg = \"blue\" }\n\"variable.parameter\" = { fg = \"red\" }\n\"variable.other.member\" = { fg = \"red\" }\n\n\"diff.plus\" = { fg = \"blue\" }\n\"diff.delta\" = { fg = \"magenta\" }\n\"diff.minus\" = { fg = \"red\" }\n\n\"ui.background\" = { fg = \"foreground\", bg = \"background\" }\n\"ui.cursor\" = { modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { bg = \"cursorline\" }\n\"ui.help\" = { fg = \"foreground\", bg = \"contrast\" }\n\"ui.linenr\" = { fg = \"comment\" }\n\"ui.linenr.selected\" = { fg = \"foreground\" }\n\"ui.menu\" = { fg = \"foreground\", bg = \"contrast\" }\n\"ui.menu.selected\" = { bg = \"black\" }\n\"ui.popup\" = { fg = \"foreground\", bg = \"contrast\" }\n\"ui.selection\" = { bg = \"black\" }\n\"ui.selection.primary\" = { bg = \"black\" }\n\"ui.statusline\" = { fg = \"foreground\", bg = \"background\" }\n\"ui.statusline.inactive\" = { fg = \"foreground\", bg = \"background\" }\n\"ui.statusline.normal\" = { fg = \"white\", bg = \"background\" }\n\"ui.statusline.insert\" = { fg = \"blue\", bg = \"background\" }\n\"ui.statusline.select\" = { fg = \"magenta\", bg = \"background\" }\n\"ui.text\" = { fg = \"foreground\" }\n\"ui.text.focus\" = { fg = \"blue\" }\n\"ui.virtual.ruler\" = { bg = \"cursorline\" }\n\"ui.virtual.whitespace\" = { fg = \"comment\" }\n\"ui.virtual.wrap\" = { fg = \"comment\" }\n\"ui.virtual.indent-guide\" = { fg = \"comment\" }\n\"ui.virtual.inlay-hint\" = { fg = \"comment\" }\n\"ui.window\" = { fg = \"black\" }\n\n\"error\" = { fg = \"red\" }\n\"hint\" = { fg = \"green\" }\n\"warning\" = { fg = \"yellow\" }\n\"info\" = { fg = \"blue\" }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"red\" } }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"yellow\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"blue\" } }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"green\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"special\" = { fg = \"red-light\" }\n\n\"markup.heading\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.list\" = { fg = \"cyan\" }\n\"markup.bold\" = { fg = \"magenta\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"green\" }\n\"markup.link.text\" = { fg = \"black-light\" }\n\"markup.quote\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.raw\" = { fg = \"cyan\" }\n\n[palette]\nblack = \"#232a2d\"\nred = \"#e57474\"\ngreen = \"#8ccf7e\"\nyellow = \"#e5c76b\"\nblue = \"#67b0e8\"\nmagenta = \"#c47fd5\"\ncyan = \"#6cbfbf\"\nwhite = \"#b3b9b8\"\nblack-light = \"#2d3437\"\nred-light = \"#ef7e7e\"\ngreen-light = \"#96d988\"\nyellow-light = \"#f4d67a\"\nblue-light = \"#71baf2\"\nmagenta-light = \"#ce89df\"\ncyan-light = \"#67cbe7\"\nwhite-light = \"#bdc3c2\"\ncomment = \"#404749\"\ncontrast = \"#161d1f\"\nbackground = \"#141b1e\"\nforeground = \"#dadada\"\ncursorline = \"#2c3333\"\n"
  },
  {
    "path": "runtime/themes/everforest_dark.toml",
    "content": "# Everforest (Dark Medium)\n# Authors: CptPotato, basbebe\n\n# Original Author:\n# URL: https://github.com/sainnhe/everforest\n# Filename: colors/everforest.vim\n# Author: sainnhe\n# Email: sainnhe@gmail.com\n# License: MIT License\n\n\"type\" = \"yellow\"\n\"constant\" = \"fg\"\n\"constant.builtin\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"constant.builtin.boolean\" = \"purple\"\n\"constant.numeric\" = \"purple\"\n\"constant.character.escape\" = \"green\"\n\"string\" = \"aqua\"\n\"string.regexp\" = \"green\"\n\"string.special\" = \"yellow\"\n\"comment\" = { fg = \"grey1\", modifiers = [\"italic\"] }\n\"variable\" = \"fg\"\n\"variable.builtin\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"variable.parameter\" = \"fg\"\n\"variable.other.member\" = \"blue\"\n\"label\" = \"orange\"\n\"punctuation\" = \"grey2\"\n\"punctuation.delimiter\" = \"grey1\"\n\"punctuation.bracket\" = \"fg\"\n\"punctuation.special\" = \"blue\"\n\"keyword\" = \"red\"\n\"keyword.operator\" = \"orange\"\n\"keyword.directive\" = \"purple\"\n\"keyword.storage\" = \"red\"\n\"operator\" = \"orange\"\n\"function\" = \"green\"\n\"function.macro\" = \"green\"\n\"tag\" = \"orange\"\n\"namespace\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"attribute\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"constructor\" = \"green\"\n\"module\" = \"yellow\"\n\"special\" = \"blue\"\n\"ui.virtual.jump-label\" = { fg = \"#00dfff\", modifiers = [\"bold\"] }\n\n\"markup.heading.marker\" = \"grey1\"\n\"markup.heading.1\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\"markup.list\" = \"red\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"blue\", underline = { style = \"line\" } }\n\"markup.link.label\" = \"orange\"\n\"markup.link.text\" = \"purple\"\n\"markup.quote\" = \"grey1\"\n\"markup.raw.inline\" = \"green\"\n\"markup.raw.block\" = \"aqua\"\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"blue\"\n\"diff.minus\" = \"red\"\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.background.separator\" = \"grey0\"\n\"ui.cursor\" = { fg = \"bg1\", bg = \"grey2\" }\n\"ui.cursor.insert\" = { fg = \"bg0\", bg = \"grey1\" }\n\"ui.cursor.select\" = { fg = \"bg0\", bg = \"blue\" }\n\"ui.cursor.match\" = { fg = \"orange\", bg = \"bg_yellow\" }\n\"ui.cursor.primary\" = { fg = \"bg0\", bg = \"fg\" }\n\"ui.cursorline.primary\" = { bg = \"bg1\" }\n\"ui.cursorline.secondary\" = { bg = \"bg2\" }\n\"ui.selection\" = { bg = \"bg3\" }\n\"ui.linenr\" = \"grey0\"\n\"ui.linenr.selected\" = \"grey2\"\n\"ui.statusline\" = { fg = \"grey2\", bg = \"bg3\" }\n\"ui.statusline.inactive\" = { fg = \"grey0\", bg = \"bg1\" }\n\"ui.statusline.normal\" = { fg = \"bg0\", bg = \"statusline1\", modifiers = [\n  \"bold\",\n] }\n\"ui.statusline.insert\" = { fg = \"bg0\", bg = \"statusline2\", modifiers = [\n  \"bold\",\n] }\n\"ui.statusline.select\" = { fg = \"bg0\", bg = \"blue\", modifiers = [\"bold\"] }\n\"ui.bufferline\" = { fg = \"grey2\", bg = \"bg3\" }\n\"ui.bufferline.active\" = { fg = \"bg0\", bg = \"statusline1\", modifiers = [\n  \"bold\",\n] }\n\"ui.popup\" = { fg = \"grey2\", bg = \"bg2\" }\n\"ui.picker.header\" = { modifiers = [\"bold\", \"underlined\"] }\n\"ui.window\" = { fg = \"bg4\", bg = \"bg_dim\" }\n\"ui.help\" = { fg = \"fg\", bg = \"bg2\" }\n\"ui.text\" = \"fg\"\n\"ui.text.directory\" = { fg = \"green\" }\n\"ui.text.focus\" = \"fg\"\n\"ui.menu\" = { fg = \"fg\", bg = \"bg3\" }\n\"ui.menu.selected\" = { fg = \"bg0\", bg = \"green\" }\n\"ui.virtual.ruler\" = { bg = \"bg3\" }\n\"ui.virtual.whitespace\" = { fg = \"bg4\" }\n\"ui.virtual.indent-guide\" = { fg = \"bg4\" }\n\"ui.virtual.inlay-hint\" = { fg = \"grey0\" }\n\"ui.virtual.wrap\" = { fg = \"grey0\" }\n\n\"hint\" = \"green\"\n\"info\" = \"blue\"\n\"warning\" = \"yellow\"\n\"error\" = \"red\"\n\n\"diagnostic.hint\" = { underline = { color = \"green\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\n\nbg_dim = \"#232a2e\"\nbg0 = \"#2d353b\"\nbg1 = \"#343f44\"\nbg2 = \"#3d484d\"\nbg3 = \"#475258\"\nbg4 = \"#4f585e\"\nbg5 = \"#56635f\"\nbg_visual = \"#543a48\"\nbg_red = \"#514045\"\nbg_green = \"#425047\"\nbg_blue = \"#3a515d\"\nbg_yellow = \"#4d4c43\"\n\nfg = \"#d3c6aa\"\nred = \"#e67e80\"\norange = \"#e69875\"\nyellow = \"#dbbc7f\"\ngreen = \"#a7c080\"\naqua = \"#83c092\"\nblue = \"#7fbbb3\"\npurple = \"#d699b6\"\n\ngrey0 = \"#7a8478\"\ngrey1 = \"#859289\"\ngrey2 = \"#9da9a0\"\n\nstatusline1 = \"#a7c080\"\nstatusline2 = \"#d3c6aa\"\nstatusline3 = \"#e67e80\"\n"
  },
  {
    "path": "runtime/themes/everforest_light.toml",
    "content": "# Everforest (Light Medium)\n# Authors: CptPotato, WindSoilder, basbebe\n\n# Original Author:\n# URL: https://github.com/sainnhe/everforest\n# Filename: colors/everforest.vim\n# Author: sainnhe\n# Email: sainnhe@gmail.com\n# License: MIT License\n\n\"type\" = \"yellow\"\n\"constant\" = \"fg\"\n\"constant.builtin\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"constant.builtin.boolean\" = \"purple\"\n\"constant.numeric\" = \"purple\"\n\"constant.character.escape\" = \"green\"\n\"string\" = \"aqua\"\n\"string.regexp\" = \"green\"\n\"string.special\" = \"yellow\"\n\"comment\" = { fg = \"grey1\", modifiers = [\"italic\"] }\n\"variable\" = \"fg\"\n\"variable.builtin\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"variable.parameter\" = \"fg\"\n\"variable.other.member\" = \"blue\"\n\"label\" = \"orange\"\n\"punctuation\" = \"grey2\"\n\"punctuation.delimiter\" = \"grey1\"\n\"punctuation.bracket\" = \"fg\"\n\"punctuation.special\" = \"blue\"\n\"keyword\" = \"red\"\n\"keyword.operator\" = \"orange\"\n\"keyword.directive\" = \"purple\"\n\"keyword.storage\" = \"red\"\n\"operator\" = \"orange\"\n\"function\" = \"green\"\n\"function.macro\" = \"green\"\n\"tag\" = \"orange\"\n\"namespace\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"attribute\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"constructor\" = \"green\"\n\"module\" = \"yellow\"\n\"special\" = \"blue\"\n\n\"markup.heading.marker\" = \"grey1\"\n\"markup.heading.1\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\"markup.list\" = \"red\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"blue\", underline = { style = \"line\" } }\n\"markup.link.label\" = \"orange\"\n\"markup.link.text\" = \"purple\"\n\"markup.quote\" = \"grey1\"\n\"markup.raw.inline\" = \"green\"\n\"markup.raw.block\" = \"aqua\"\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"blue\"\n\"diff.minus\" = \"red\"\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.background.separator\" = \"grey0\"\n\"ui.cursor\" = { fg = \"bg1\", bg = \"grey2\" }\n\"ui.cursor.insert\" = { fg = \"bg0\", bg = \"grey1\" }\n\"ui.cursor.select\" = { fg = \"bg0\", bg = \"blue\" }\n\"ui.cursor.match\" = { bg = \"bg4\", modifiers = [\"bold\"] }\n\"ui.cursor.primary\" = { fg = \"bg0\", bg = \"fg\" }\n\"ui.cursorline.primary\" = { bg = \"bg1\" }\n\"ui.cursorline.secondary\" = { bg = \"bg2\" }\n\"ui.selection\" = { bg = \"bg3\" }\n\"ui.linenr\" = \"grey0\"\n\"ui.linenr.selected\" = \"grey2\"\n\"ui.statusline\" = { fg = \"grey2\", bg = \"bg3\" }\n\"ui.statusline.inactive\" = { fg = \"grey0\", bg = \"bg1\" }\n\"ui.statusline.normal\" = { fg = \"bg0\", bg = \"statusline1\", modifiers = [\n  \"bold\",\n] }\n\"ui.statusline.insert\" = { fg = \"bg0\", bg = \"statusline2\", modifiers = [\n  \"bold\",\n] }\n\"ui.statusline.select\" = { fg = \"bg0\", bg = \"blue\", modifiers = [\"bold\"] }\n\"ui.bufferline\" = { fg = \"grey2\", bg = \"bg3\" }\n\"ui.bufferline.active\" = { fg = \"bg0\", bg = \"statusline1\", modifiers = [\n  \"bold\",\n] }\n\"ui.popup\" = { fg = \"grey2\", bg = \"bg2\" }\n\"ui.picker.header\" = { modifiers = [\"bold\", \"underlined\"] }\n\"ui.window\" = { fg = \"bg4\", bg = \"bg_dim\" }\n\"ui.help\" = { fg = \"fg\", bg = \"bg2\" }\n\"ui.text\" = \"fg\"\n\"ui.text.directory\" = { fg = \"green\" }\n\"ui.text.focus\" = \"fg\"\n\"ui.menu\" = { fg = \"fg\", bg = \"bg3\" }\n\"ui.menu.selected\" = { fg = \"bg0\", bg = \"green\" }\n\"ui.virtual.ruler\" = { bg = \"bg3\" }\n\"ui.virtual.whitespace\" = { fg = \"bg4\" }\n\"ui.virtual.indent-guide\" = { fg = \"bg4\" }\n\"ui.virtual.inlay-hint\" = { fg = \"grey0\" }\n\"ui.virtual.wrap\" = { fg = \"grey0\" }\n\"ui.virtual.jump-label\" = { fg = \"red\", bg = \"bg0\", modifiers = [\n  \"bold\",\n] }\n\n\"hint\" = \"green\"\n\"info\" = \"blue\"\n\"warning\" = \"yellow\"\n\"error\" = \"red\"\n\n\"diagnostic.hint\" = { underline = { color = \"green\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\n\nbg_dim = \"#efebd4\"\nbg0 = \"#fdf6e3\"\nbg1 = \"#f4f0d9\"\nbg2 = \"#efebd4\"\nbg3 = \"#e6e2cc\"\nbg4 = \"#e0dcc7\"\nbg5 = \"#bdc3af\"\nbg_red = \"#fbe3da\"\nbg_visual = \"#eaedc8\"\nbg_yellow = \"#faedcd\"\nbg_green = \"#f0f1d2\"\nbg_blue = \"#e9f0e9\"\n\nfg = \"#5c6a72\"\nred = \"#f85552\"\norange = \"#f57d26\"\nyellow = \"#dfa000\"\ngreen = \"#8da101\"\nblue = \"#3a94c5\"\naqua = \"#35a77c\"\npurple = \"#df69ba\"\n\ngrey0 = \"#a6b0a0\"\ngrey1 = \"#939f91\"\ngrey2 = \"#829181\"\nstatusline1 = \"#93b259\"\nstatusline2 = \"#708089\"\nstatusline3 = \"#e66868\"\n"
  },
  {
    "path": "runtime/themes/faded-prism.toml",
    "content": "# Author: Ryan Brue <ryanbrue.dev@gmail.com>\n# Ref: https://github.com/ryanabx/faded-prism-color-theme\n\n# Syntax\n\n\"variable\" = \"white\"\n\"namespace\" = \"white\"\n\"punctuation\" = \"off_white\"\n\"operator\" = \"off_white\"\n\"comment\" = \"light_gray\"\n\n\"keyword\" = \"red\"\n\"special\" = \"red\"\n\"label\" = \"red\"\n\"tag\" = \"red\"\n\"string\" = \"yellow\"\n\"attribute\" = \"green\"\n\"constructor\" = \"green\"\n\"function\" = \"green\"\n\"type\" = \"blue\"\n\"type.enum.variant\" = \"light_blue\"\n\"constant\" = \"light_blue\"\n\"constant.numeric\" = \"purple\"\n\n\"markup.heading.1\" = \"vibrant_yellow\"\n\"markup.heading.2\" = \"vibrant_green\"\n\"markup.heading.3\" = \"vibrant_blue\"\n\"markup.heading.4\" = \"vibrant_purple\"\n\"markup.heading.5\" = \"vibrant_red\"\n\"markup.heading.6\" = \"vibrant_orange\"\n\n# UI\n\n\"ui.background\" = { fg = \"white\", bg = \"dark_gray\" }\n\n\"ui.linenr\" = { fg = \"off_white\" }\n\"ui.linenr.selected\" = { fg = \"white\" }\n\n\"ui.statusline\" = { fg = \"white\", bg = \"black\" }\n\"ui.statusline.inactive\" = { fg = \"gray\", bg = \"black\" }\n\"ui.statusline.normal\" = { fg = \"white\", bg = \"vibrant_red\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"white\", bg = \"vibrant_blue\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"white\", bg = \"vibrant_orange\", modifiers = [\"bold\"] }\n\n\"ui.popup\" = { fg = \"white\", bg = \"black\" }\n\"ui.window\" = { fg = \"white\" }\n\"ui.help\" = { fg = \"white\", bg = \"black\" }\n\n\"ui.bufferline\" = { fg = \"white\", bg = \"gray\" }\n# \"ui.bufferline.active\" = { fg = \"yellow\", bg = \"black\", underline = { color = \"red\", style = \"line\" } }\n# \"ui.bufferline.background\" = { bg = \"gray\" }\n\n\"ui.text\" = \"white\"\n\"ui.text.focus\" = { fg = \"white\", bg = \"gray\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = { fg = \"off_white\" }\n\"ui.text.directory\" = { fg = \"blue\" }\n\n\"ui.virtual\" = \"gray\"\n\"ui.virtual.ruler\" = { bg = \"gray\" }\n\"ui.virtual.indent-guide\" = \"gray\"\n\"ui.virtual.inlay-hint\" = { fg = \"white\", bg = \"gray\" }\n\"ui.virtual.jump-label\" = { fg = \"white\", modifiers = [\"bold\"] }\n\n\"ui.selection\" = { bg = \"gray\" }\n\n\"ui.cursor\" = { fg = \"black\", bg = \"white\" }\n\n\"ui.highlight\" = { bg = \"gray\", modifiers = [\"bold\"] }\n\n\"ui.menu\" = { fg = \"white\", bg = \"black\" }\n\"ui.menu.selected\" = { fg = \"white\", bg = \"gray\", modifiers = [\"bold\"] }\n\n\"diagnostic.error\" = { underline = { color = \"error_red\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"warning_yellow\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"suggestion_blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"suggestion_blue\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\nerror = \"error_red\"\nwarning = \"warning_yellow\"\ninfo = \"suggestion_blue\"\nhint = \"suggestion_blue\"\n\n\"diff.plus\" = \"diff_green\"\n\"diff.minus\" = \"diff_red\"\n\"diff.delta\" = \"diff_yellow\"\n\nrainbow = [\"vibrant_yellow\", \"vibrant_green\", \"vibrant_blue\", \"vibrant_purple\", \"vibrant_red\", \"vibrant_orange\"]\n\n[palette]\n# Grayscale\nwhite = \"#d8d8d8\"\noff_white = \"#909090\"\nlight_gray = \"#6c6c6c\"\ngray = \"#4d4d4d\"\ndark_gray = \"#252525\"\nblack = \"#181818\"\n# Diffs and diagnostics\ndiff_red = \"#ff3e3e\"\ndiff_yellow = \"#ffea8a\"\ndiff_green = \"#6eff69\"\nerror_red = \"#ff3e3e\"\nwarning_yellow = \"#ffd932\"\nsuggestion_blue = \"#4fd6ff\"\n# Pastel colors\nlight_red = \"#f7afaf\"\nred = \"#ff8d74\"\nyellow = \"#fffa9f\"\ngreen = \"#abff8d\"\nblue = \"#7bbdff\"\nlight_blue = \"#b8e3ff\"\npurple = \"#f5c8ff\"\n# Vibrant colors, used exclusively for bracket rainbows\nvibrant_yellow = \"#fffd78\"\nvibrant_green = \"#6cffa4\"\nvibrant_blue = \"#628cff\"\nvibrant_purple = \"#e552ff\"\nvibrant_red = \"#ff4b90\"\nvibrant_orange = \"#ff915a\""
  },
  {
    "path": "runtime/themes/ferra.toml",
    "content": "# Author : Casper Rogild Storm <casper@asynkron.xyz>\n\n\"comment\" = { fg = \"ferra_bark\", modifiers = [\"italic\"] }\n\"constant\" = { fg = \"ferra_sage\" }\n\"function\" = { fg = \"ferra_coral\" }\n\"function.macro\" = { fg = \"ferra_mist\" }\n\"keyword\" = { fg = \"ferra_mist\" }\n\"operator\" = { fg = \"ferra_mist\" }\n\"punctuation\" = { fg = \"ferra_blush\" }\n\"string\" = { fg = \"ferra_sage\" }\n\"type\" = { fg = \"ferra_rose\" }\n\"variable\" = { fg = \"ferra_blush\" }\n\"variable.builtin\" = { fg = \"ferra_rose\" }\n\"tag\" = { fg = \"ferra_sage\" }\n\"label\" = { fg = \"ferra_sage\" }\n\"attribute\" = { fg = \"ferra_blush\" }\n\"namespace\" = { fg = \"ferra_blush\" }\n\"module\" = { fg = \"ferra_blush\" }\n\n\"markup.heading\" = { fg = \"ferra_sage\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = { fg = \"ferra_bark\" }\n\"markup.list\" = { fg = \"ferra_mist\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"ferra_rose\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"ferra_rose\" }\n\"markup.quote\" = { fg = \"ferra_bark\" }\n\"markup.raw\" = { fg = \"ferra_coral\" }\n\n\"ui.background\" = { bg = \"ferra_night\" }\n\"ui.cursor\" = { fg = \"ferra_night\", bg = \"ferra_blush\" }\n\"ui.cursor.match\" = { fg = \"ferra_night\", bg = \"ferra_bark\" }\n\"ui.cursor.select\" = { fg = \"ferra_night\", bg = \"ferra_rose\" }\n\"ui.cursor.insert\" = { fg = \"ferra_night\", bg = \"ferra_coral\" }\n\"ui.linenr\" = { fg = \"ferra_bark\" }\n\"ui.linenr.selected\" = { fg = \"ferra_blush\" }\n\"ui.cursorline\" = { fg = \"ferra_blush\", bg = \"ferra_ash\" }\n\"ui.statusline\" = { fg = \"ferra_blush\", bg = \"ferra_ash\" }\n\"ui.statusline.inactive\" = { fg = \"ferra_bark\", bg = \"ferra_ash\" }\n\"ui.statusline.normal\" = { fg = \"ferra_ash\", bg = \"ferra_blush\" }\n\"ui.statusline.insert\" = { fg = \"ferra_ash\", bg = \"ferra_coral\" }\n\"ui.statusline.select\" = { fg = \"ferra_ash\", bg = \"ferra_rose\" }\n\"ui.popup\" = { fg = \"ferra_blush\", bg = \"ferra_ash\" }\n\"ui.window\" = { fg = \"ferra_bark\", bg = \"ferra_night\" }\n\"ui.help\" = { fg = \"ferra_blush\", bg = \"ferra_ash\" }\n\"ui.text\" = { fg = \"ferra_blush\" }\n\"ui.text.focus\" = { fg = \"ferra_coral\" }\n\"ui.menu\" = { fg = \"ferra_blush\", bg = \"ferra_ash\" }\n\"ui.menu.selected\" = { fg = \"ferra_coral\", bg = \"ferra_ash\" }\n\"ui.selection\" = { bg = \"ferra_umber\" }\n\"ui.virtual\" = { fg = \"ferra_bark\" }\n\"ui.virtual.whitespace\" = { fg = \"ferra_bark\" }\n\"ui.virtual.ruler\" = { bg = \"ferra_ash\" }\n\"ui.virtual.indent-guide\" = { fg = \"ferra_ash\" }\n\"ui.virtual.inlay-hint\" = { fg = \"ferra_bark\" }\n\n\"diff.plus\" = { fg = \"ferra_sage\" }\n\"diff.delta\" = { fg = \"ferra_blush\" }\n\"diff.minus\" = { fg = \"ferra_ember\" }\n\n\"error\" = { fg = \"ferra_ember\" }\n\"warning\" = { fg = \"ferra_honey\" }\n\"info\" = { fg = \"ferra_blush\" }\n\"hint\" = { fg = \"ferra_blush\" }\n\n\"diagnostic.warning\" = { underline = { color = \"ferra_honey\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"ferra_ember\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"ferra_blush\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"ferra_blush\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nferra_night = \"#2b292d\"\nferra_ash = \"#383539\"\nferra_umber = \"#4d424b\"\nferra_bark = \"#6F5D63\"\nferra_mist = \"#D1D1E0\"\nferra_sage = \"#B1B695\"\nferra_blush = \"#fecdb2\"\nferra_coral = \"#ffa07a\"\nferra_rose = \"#F6B6C9\"\nferra_ember = \"#e06b75\"\nferra_honey = \"#F5D76E\"\n"
  },
  {
    "path": "runtime/themes/flatwhite.toml",
    "content": "# Author: Alexander Brevig <alexanderbrevig@gmail.com>, krfl <kr.fl@outlook.com>\n# Adopted from https://github.com/biletskyy/flatwhite-syntax\n\n\"attribute\" = { fg = \"blue_text\", bg = \"blue_bg\" }\n\"comment\" = { fg = \"base2\", bg = \"base6\" }\n\"comment.line\" = { fg = \"base2\", bg = \"base6\" }\n\"comment.block\" = { fg = \"base2\", bg = \"base6\" }\n\"comment.block.documentation\" = { fg = \"base2\", bg = \"base6\" }\n\"constant\" = { fg = \"blue_text\", bg = \"blue_bg\" }\n\"constructor\" = { fg = \"base1\" }\n\"function\" = { fg = \"base1\", modifiers = [\"bold\"] }\n\"keyword\" = { fg = \"purple_text\", bg = \"purple_bg\" }\n\"label\" = { modifiers = [\"bold\"] }\n\"namespace\" = { fg = \"teal_text\", bg = \"teal_bg\" }\n\"operator\" = { fg = \"base1\" }\n\"punctuation.bracket\" = { modifiers = [\"bold\"] }\n\"special\" = { fg = \"blue_text\", bg = \"blue_bg\" }\n\"string\" = { fg = \"green_text\", bg = \"green_bg\" }\n\"type\" = { fg = \"base1\" }\n\"variable\" = { fg = \"base1\" }\n\"variable.parameter\" = { fg = \"blue_text\", bg = \"blue_bg\" }\n\n\"diagnostic\" = { modifiers = [\"underlined\"] }\n\n\"diagnostic.info\" = { underline = { color = \"orange_text\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"orange_text\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"diff_delete\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"info\" = { fg = \"orange_text\", bg = \"orange_bg\" }\n\"hint\" = { modifiers = [\"bold\"] }\n\"warning\" = { fg = \"orange_text\", bg = \"orange_bg\" }\n\"error\" = { fg = \"diff_delete\" }\n\n\"markup.heading\" = { fg = \"purple_text\", bg = \"purple_bg\", modifiers = [\n  \"bold\",\n] }\n\"markup.raw\" = { fg = \"orange_text\", bg = \"orange_bg\" }\n\"markup.raw.inline\" = { fg = \"orange_text\", bg = \"orange_bg\" }\n\"markup.raw.block\" = { fg = \"orange_text\", bg = \"orange_bg\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"blue_text\", bg = \"blue_bg\", modifiers = [\n  \"underlined\",\n] }\n\"markup.link.label\" = { fg = \"blue_text\", bg = \"blue_bg\" }\n\"markup.link.text\" = { fg = \"blue_text\", bg = \"blue_bg\" }\n\"markup.quote\" = { fg = \"teal_text\", bg = \"teal_bg\" }\n\"markup.list\" = { fg = \"purple_text\", bg = \"purple_bg\" }\n\n\"ui.background\" = { fg = \"base1\", bg = \"base7\" }\n\"ui.cursorline\" = { bg = \"base6\" }\n\"ui.cursor\" = { fg = \"base1\", bg = \"base7\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"base1\", bg = \"base7\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"base5\", bg = \"base3\", modifiers = [\"reversed\"] }\n\"ui.selection\" = { bg = \"base4\" }\n\"ui.selection.primary\" = { fg = \"base6\", bg = \"base2\" }\n\n\"ui.virtual\" = { fg = \"base5\", bg = \"base6\" }\n\"ui.virtual.whitespace\" = { fg = \"base5\" }\n\"ui.virtual.ruler\" = { bg = \"base6\" }\n\"ui.virtual.inlay-hint\" = \"base4\"\n\"ui.virtual.inlay-hint.parameter\" = \"base3\"\n\"ui.virtual.inlay-hint.type\" = { fg = \"base3\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { bg = \"orange_bg\", modifiers = [\"bold\"] }\n\n\"ui.linenr\" = { bg = \"base6\" }\n\"ui.linenr.selected\" = { bg = \"base6\", modifiers = [\"reversed\"] }\n\n\"ui.statusline\" = { fg = \"base7\", bg = \"base1\", modifiers = [\"bold\"] }\n\"ui.statusline.inactive\" = { fg = \"base7\", bg = \"base3\" }\n\"ui.statusline.normal\" = { fg = \"base7\", bg = \"base1\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"purple_text\", bg = \"purple_bg\", modifiers = [\n  \"bold\",\n] }\n\"ui.statusline.select\" = { fg = \"teal_text\", bg = \"teal_bg\", modifiers = [\n  \"bold\",\n] }\n\n\"ui.text\" = { fg = \"base1\" }\n\"ui.text.focus\" = { fg = \"base1\", modifiers = [\"bold\"] }\n\n\"ui.menu\" = { fg = \"base1\", bg = \"base6\" }\n\"ui.menu.selected\" = { fg = \"base1\", bg = \"base6\", modifiers = [\"reversed\"] }\n\"ui.menu.scroll\" = { fg = \"base1\", bg = \"base6\" }\n\"ui.help\" = { fg = \"base1\", bg = \"base6\" }\n\"ui.popup\" = { fg = \"base1\", bg = \"base6\" }\n\"ui.window\" = { fg = \"base1\", bg = \"base6\" }\n\n\"diff.plus\" = { fg = \"diff_add\" }\n\"diff.delta\" = { fg = \"diff_change\" }\n\"diff.minus\" = { fg = \"diff_delete\" }\n\n[palette]\nbase1 = \"#605a52\"\nbase2 = \"#93836c\"\nbase3 = \"#b9a992\"\nbase4 = \"#dcd3c6\"\nbase5 = \"#e4ddd2\"\nbase6 = \"#f1ece4\"\nbase7 = \"#f7f3ee\"\naccent = \"#6a4cff\"\norange_text = \"#5b5143\"\norange_text_sec = \"#957f5f\"\norange_bg = \"#f7e0c3\"\ngreen_text = \"#525643\"\ngreen_text_sec = \"#81895d\"\ngreen_bg = \"#e2e9c1\"\nteal_text = \"#465953\"\nteal_text_sec = \"#5f8c7d\"\nteal_bg = \"#d2ebe3\"\nblue_text = \"#4c5361\"\nblue_text_sec = \"#7382a0\"\nblue_bg = \"#dde4f2\"\npurple_text = \"#614c61\"\npurple_text_sec = \"#9c739c\"\npurple_bg = \"#f1ddf1\"\ndiff_add = \"#2db448\"\ndiff_change = \"#f2a60d\"\ndiff_change_dark = \"#795306\"\ndiff_delete = \"#ff1414\"\ndiff_renamed = \"#52aeff\"\nwhite = \"#ffffff\"\n"
  },
  {
    "path": "runtime/themes/fleet_dark.toml",
    "content": "# Fleet Dark\n# A take on the JetBrains Fleet theme. Feel free to contribute\n\n# Original author: @krfl\n# Contributors:\n# @matoous\n# @kirawi\n\n\"attribute\" = \"Lime\"\n\n\"type\" = \"Blue\"\n\"type.return\" = \"Blue Light\"\n\"type.parameter\" = \"Blue Light\"\n\"constructor\" = \"Yellow\"\n\n\"constant\" = \"Violet\"\n# \"constant.builtin\" = {} # .boolean\n\"constant.builtin.boolean\" = \"Cyan\"\n\"constant.character\" = \"Yellow\"\n\"constant.character.escape\" = \"Cyan\"\n\"constant.numeric\" = \"Yellow\"\n\"string\" = \"Pink\"\n\"string.regexp\" = \"Cyan\"\n\"string.special\" = { fg = \"Yellow\", modifiers = [\"underlined\"] } #.path / .url / .symbol\n\n\"comment\" = \"Gray 90\" # .line\n# \"comment.block\" = {} # .documentation\n\"variable\" = \"Gray 120\" # .builtin\n\"variable.builtin\" = { fg = \"Coral\" }\n# \"variable.other\" = {} # .member\n\"variable.other.member\" = \"Violet\"\n\"label\" = \"Yellow\"\n\"keyword\" = \"Cyan\" # .operator / .directive / .function\n\"function\" = \"Yellow\"\n\"function.declaration\" = \"#EFEFEF\"\n\"function.macro\" = \"Lime\"\n\"function.builtin\" = \"Lime\"\n\"function.special\" = \"Lime\"\n#\"function.declaration.method\" = { fg = \"lightest\", modifiers = [\"bold\"] } #depends on #4892\n\"tag\" = \"Blue\"\n\"special\" = \"Lime\"\n\"namespace\" = \"Blue\"\n\n# used in theming\n# \"markup\" = {} # .normal / .quote / .raw\n# \"markup.normal\" = {} # .completion / .hover\n\"markup.bold\" = {  modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.heading\" = { fg = \"Cyan\", modifiers = [\"bold\"] } # .marker / .1 / .2 / .3 / .4 / .5 / .6\n\"markup.list\" = \"Pink\" # .unnumbered / .numbered\n\"markup.list.numbered\" = \"Cyan\"\n\"markup.list.unnumbered\" = \"Cyan\"\n# \"markup.link\" = \"green\"\n\"markup.link.url\" = { fg = \"Pink\", modifiers = ['italic', 'underlined'] }\n\"markup.link.text\" = \"Cyan\"\n\"markup.link.label\" = \"Purple 20\"\n\"markup.quote\" = \"Pink\"\n\"markup.raw\" = \"Pink\"\n\"markup.raw.inline\" = \"Cyan\" # .completion / .hover\n\"markup.raw.block\" = \"#EB83E2\"\n\n\"diff.plus\" = \"Green 50\"\n\"diff.minus\" = \"Red 50\"\n\"diff.delta\" = \"Blue 80\"\n\n# ui specific\n\"ui.background\" = { bg = \"Gray 10\" } # .separator\n\"ui.statusline\" = { fg = \"Gray 120\", bg = \"Gray 20\" } # .inactive / .normal / .insert / .select\n\"ui.statusline.normal\" = { fg = \"Gray 120\", bg = \"Gray 20\" }\n\"ui.statusline.inactive\" = { fg = \"Gray 90\"}\n\"ui.statusline.insert\" = { fg = \"Gray 20\", bg = \"Blue 90\" }\n\"ui.statusline.select\" = { fg = \"Gray 20\", bg = \"Yellow 60\" }\n\n\"ui.cursor\" = { modifiers = [\"reversed\"] } # .insert / .select / .match / .primary\n\"ui.cursor.match\" = { bg = \"Blue 30\" } # .insert / .select / .match / .primary\n\"ui.selection\" = { bg = \"Gray 50\" } # .primary\n\"ui.selection.primary\" = { bg = \"Blue 40\" }\n\n\"ui.cursorline\" = { bg = \"Gray 15\" }\n\"ui.linenr\" = \"Gray 70\"\n\"ui.linenr.selected\" = \"Gray 110\"\n\n\"ui.popup\" = { fg = \"Gray 120\", bg = \"Gray 20\" } # .info\n\"ui.window\" = { fg = \"Gray 50\" }\n\"ui.help\" = { fg = \"Gray 120\", bg = \"Gray 20\" }\n\"ui.menu\" = { fg = \"Gray 120\", bg = \"Gray 20\" } # .selected\n\"ui.menu.selected\" = { fg = \"White\", bg = \"Blue 40\" } # .selected\n# Calculated as #ffffff with 30% opacity\n\"ui.menu.scroll\" = { fg = \"#dfdfdf\" }\n\n\"ui.text\" = \"Gray 120\" # .focus / .info\n\"ui.text.focus\" = { fg = \"White\", bg = \"Blue 40\" }\n\n\"ui.virtual\" = \"Gray 90\" # .whitespace\n\"ui.virtual.inlay-hint\" = { fg = \"Gray 70\" }\n\"ui.virtual.ruler\" = { bg = \"Gray 20\" }\n\n\"hint\" = \"Gray 80\"\n\"info\" = \"#A366C4\"\n\"warning\" = \"#FACb66\"\n\"error\" = \"#FF5269\"\n\n\"diagnostic.hint\" = { underline = { color = \"Gray 80\", style = \"line\" } }\n\"diagnostic.info\" = { underline = { color = \"#A366C4\", style = \"line\" } }\n\"diagnostic.warning\" = { underline = { color = \"#FACB66\", style = \"line\" } }\n\"diagnostic.error\" = { underline = { color = \"#FF5269\", style = \"line\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\n\"White\" = \"#ffffff\"\n\"Gray 120\" = \"#d1d1d1\"\n\"Gray 110\" = \"#c2c2c2\"\n\"Gray 100\" = \"#a0a0a0\"\n\"Gray 90\" = \"#898989\"\n\"Gray 80\" = \"#767676\"\n\"Gray 70\" = \"#5d5d5d\"\n\"Gray 60\" = \"#484848\"\n\"Gray 50\" = \"#383838\"\n\"Gray 40\" = \"#333333\"\n\"Gray 30\" = \"#2d2d2d\"\n\"Gray 20\" = \"#292929\"\n\"Gray 15\" = \"#1F1F1F\"\n\"Gray 10\" = \"#181818\"\n\"Black\" = \"#000000\"\n\"Blue 110\" = \"#6daaf7\"\n\"Blue 100\" = \"#4d9bf8\"\n\"Blue 90\" = \"#3691f9\"\n\"Blue 80\" = \"#1a85f6\"\n\"Blue 70\" = \"#0273eb\"\n\"Blue 60\" = \"#0c6ddd\"\n\"Blue 50\" = \"#195eb5\"\n\"Blue 40\" = \"#194176\"\n\"Blue 30\" = \"#163764\"\n\"Blue 20\" = \"#132c4f\"\n\"Blue 10\" = \"#0b1b32\"\n\"Red 80\" = \"#ec7388\"\n\"Red 70\" = \"#ea4b67\"\n\"Red 60\" = \"#d93953\"\n\"Red 50\" = \"#ce364d\"\n\"Red 40\" = \"#c03248\"\n\"Red 30\" = \"#a72a3f\"\n\"Red 20\" = \"#761b2d\"\n\"Red 10\" = \"#390813\"\n\"Green 50\" = \"#4ca988\"\n\"Green 40\" = \"#3ea17f\"\n\"Green 30\" = \"#028764\"\n\"Green 20\" = \"#134939\"\n\"Green 10\" = \"#081f19\"\n\"Yellow 60\" = \"#f8ab17\"\n\"Yellow 50\" = \"#e1971b\"\n\"Yellow 40\" = \"#b5791f\"\n\"Yellow 30\" = \"#7c511a\"\n\"Yellow 20\" = \"#5a3a14\"\n\"Yellow 10\" = \"#281806\"\n\"Purple 20\" = \"#c07bf3\"\n\"Purple 10\" = \"#b35def\"\n\n\"Blue\" = \"#87C3FF\"\n\"Blue Light\" = \"#ADD1DE\"\n\"Coral\" = \"#CC7C8A\"\n\"Cyan\" = \"#82D2CE\"\n\"Cyan Dark\" = \"#779E9E\"\n\"Lime\" = \"#A8CC7C\"\n\"Orange\" = \"#E09B70\"\n\"Pink\" = \"#E394DC\"\n\"Violet\" = \"#AF9CFF\"\n\"Yellow\" = \"#EBC88D\"\n"
  },
  {
    "path": "runtime/themes/flexoki_dark.toml",
    "content": "inherits = \"flexoki_light\"\n\n[palette]\ntx = \"#CECDC3\"\ntx-2 = \"#878580\"\ntx-3 = \"#575653\"\nui-3 = \"#403E3C\"\nui-2 = \"#343331\"\nui = \"#282726\"\nbg-2 = \"#1C1B1A\"\nbg = \"#100F0F\"\n\nre = \"#D14D41\"\nor = \"#DA702C\"\nye = \"#D0A215\"\ngr = \"#879A39\"\ncy = \"#3AA99F\"\nbl = \"#4385BE\"\npu = \"#8B7EC8\"\nma = \"#CE5D97\"\n"
  },
  {
    "path": "runtime/themes/flexoki_light.toml",
    "content": "# Based on Flexoki: https://stephango.com/flexoki\n\n\"ui.background\" = { bg = \"bg\" }\n\"ui.cursor\" = { fg = \"tx\", bg = \"tx-3\" }\n\"ui.cursor.primary\" = { fg = \"bg\", bg = \"tx\" }\n\"ui.cursor.match\" = { modifiers = [\"bold\"] }\n\"ui.linenr\" = \"tx-3\"\n\"ui.linenr.selected\" = \"tx\"\n\"ui.selection\" = { bg = \"ui-2\" }\n\"ui.statusline\" = { fg = \"tx\", bg = \"bg-2\" }\n\"ui.statusline.normal\" = { fg = \"bg\", bg = \"bl\" }\n\"ui.statusline.insert\" = { fg = \"bg\", bg = \"or\" }\n\"ui.statusline.select\" = { fg = \"bg\", bg = \"ma\" }\n\"ui.cursorline\" = { bg = \"bg-2\" }\n\"ui.popup\" = { fg = \"tx\", bg = \"bg-2\" }\n\"ui.window\" = \"tx\"\n\"ui.help\" = { fg = \"tx\", bg = \"bg\" }\n\"ui.text\" = \"tx\"\n\"ui.text.focus\" = { bg = \"bg-2\", fg = \"tx\" }\n\"ui.text.info\" = \"tx\"\n\"ui.virtual.whitespace\" = \"bg-2\"\n\"ui.virtual.ruler\" = { bg = \"bg-2\" }\n\"ui.virtual.inlay-hint\" = { fg = \"tx-3\", bg = \"bg\" }\n\"ui.virtual.jump-label\" = { bg = \"bg-2\", modifiers = [\"bold\"]}\n\"ui.menu\" = { fg = \"tx\", bg = \"bg\" }\n\"ui.menu.selected\" = { bg = \"ui\", fg = \"tx\" }\n\"ui.debug\" = { fg = \"or\", bg = \"bg\" }\n\"ui.highlight.frameline\" = { bg = \"ye\" }\n\"ui.bufferline\" = { fg = \"tx-2\", bg = \"bg-2\"}                      \n\"ui.bufferline.active\" = { fg = \"ye\", bg = \"bg-2\" }                          \n\"diagnostic.hint\" = { underline = { color = \"bl\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"bl\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"ye\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"re\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"hint\" = { fg = \"bl\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"ye\", modifiers = [\"bold\"] }\n\"warning\" = { fg = \"or\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"re\", modifiers = [\"bold\"] }\n\"attribute\" = \"ye\"\n\"type\" = \"ye\"\n\"constructor\" = \"gr\"\n\"constant\" = \"pu\"\n\"constant.builtin\" = \"ye\"\n\"string\" = \"cy\"\n\"string.regexp\" = \"or\"\n\"string.special\" = \"ye\"\n\"comment\" = \"tx-3\"\n\"variable\" = \"tx\"\n\"variable.builtin\" = \"ma\"\n\"variable.other\" = \"bl\"\n\"punctuation\" = \"tx-2\"\n\"keyword\" = \"gr\"\n\"keyword.control\" = \"re\"\n\"keyword.control.conditional\" = \"gr\"\n\"keyword.control.import\" = \"ye\"\n\"keyword.control.return\" = \"gr\"\n\"keyword.function\" = \"gr\"\n\"keyword.storage.type\" = \"bl\"\n\"keyword.storage.modifier\" = \"bl\"\n\"operator\" = \"tx-2\"\n\"function\" = \"or\"\n\"tag\" = \"bl\"\n\"namespace\" = \"re\"\n\"markup.heading\" = \"or\"\n\"markup.list\" = \"ye\"\n\"markup.bold\" = { fg = \"or\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"or\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.raw.block\" = \"or\"\n\"markup.link.url\" = \"bl\"\n\"markup.link.text\" = \"ye\"\n\"markup.link.label\" = \"gr\"\n\"markup.quote\" = \"ye\"\n\"markup.raw\" = \"bl\"\n\"diff.plus\" = \"gr\"\n\"diff.minus\" = \"re\"\n\"diff.delta\" = \"ye\"\n\n[palette]\ntx = \"#100F0F\"\ntx-2 = \"#6F6E69\"\ntx-3 = \"#B7B5AC\"\nui-3 = \"#CECDC3\"\nui-2 = \"#DAD8CE\"\nui = \"#E6E4D9\"\nbg-2 = \"#F2F0E5\"\nbg = \"#FFFCF0\"\n\n\nre = \"#AF3029\"\nor = \"#BC5215\"\nye = \"#AD8301\"\ngr = \"#66800B\"\ncy = \"#24837B\"\nbl = \"#205EA6\"\npu = \"#5E409D\"\nma = \"#A02F6F\"\n"
  },
  {
    "path": "runtime/themes/focus_nova.toml",
    "content": "# Author: Ahmir Postell <postell.ahmir@gmail.com>\n\n\"annotation\" = { fg = \"fg1\" }\n\n\"attribute\" = { fg = \"aqua1\", modifiers = [\"italic\"] }\n\n\"comment\" = { fg = \"gray\", modifiers = [\"italic\"] }\n\n\"constant\" = { fg = \"purple1\" }\n\"constant.character\" = { fg = \"aqua1\" }\n\"constant.character.escape\" = { fg = \"orange1\" }\n\"constant.macro\" = { fg = \"aqua1\" }\n\"constructor\" = { fg = \"purple1\" }\n\n\"definition\" = { underline = { color = \"aqua1\" } }\n\n\"diagnostic\" = { underline = { color = \"orange1\", style = \"curl\" } }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"diagnostic.error\" = { fg = \"red1\", underline = { color = \"red1\", style = \"curl\" } }\n\"diagnostic.warning\" = { fg = \"yellow1\", underline = { color = \"yellow1\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue1\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"aqua1\", style = \"curl\" } }\n# \"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }  # do not remove this for future resolving\n\n\"error\" = { fg = \"red1\" }\n\"hint\" = { fg = \"blue1\" }\n\"info\" = { fg = \"aqua1\" }\n\"warning\" = { fg = \"yellow1\" }\n\n\"diff.plus\" = { fg = \"green1\", bg = \"bg2\" }\n\"diff.minus\" = { fg = \"red1\", bg = \"bg2\" }\n\"diff.delta\" = { fg = \"yellow1\", bg = \"bg2\" }\n\n\"function\" = { fg = \"green1\" }\n\"function.builtin\" = { fg = \"yellow1\" }\n\"function.macro\" = { fg = \"blue1\" }\n\n\"keyword\" = { fg = \"red1\" }\n\"keyword.control.import\" = { fg = \"aqua1\" }\n\n\"label\" = { fg = \"red1\" }\n\n\"markup.bold\"          = { fg = \"blue1\", modifiers = [\"bold\"] }\n\"markup.heading\"       = { fg = \"purple1\", modifiers = [\"bold\"] }\n\"markup.italic\"        = { fg = \"yellow1\", modifiers = [\"italic\"] }\n\"markup.link.label\"    = { fg = \"blue1\", modifiers = [\"italic\"] }\n\"markup.link.text\"     = \"purple0\"\n\"markup.link.url\"      = \"aqua1\"\n\"markup.list\"          = \"aqua1\"\n\"markup.quote\"         = { fg = \"yellow1\", modifiers = [\"italic\"] }\n\"markup.raw\"           = { fg = \"fg1\" }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\n\"module\" = { fg = \"aqua1\" }\n\n\"namespace\" = { fg = \"fg1\" }\n\n\"operator\" = { fg = \"purple1\" }\n\n\"punctuation\" = { fg = \"orange1\" }\n\n\"special\" = { fg = \"purple0\" }\n\n\"string\" = { fg = \"green1\" }\n\"string.regexp\" = { fg = \"orange1\" }\n\"string.special\" = { fg = \"orange1\" }\n\"string.symbol\" = { fg = \"yellow1\" }\n\n\"tag\" = { fg = \"aqua1\" }\n\n\"type\" = { fg = \"yellow1\" }\n\"type.enum.variant\" = { modifiers = [\"italic\"] }\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.bufferline\" = { fg = \"fg1\", bg = \"bg1\" }\n\"ui.bufferline.active\" = { fg = \"bg0\", bg = \"yellow0\" }\n\"ui.bufferline.background\" = { bg = \"bg2\" }\n\n\"ui.cursor\" = { fg = \"bg1\", bg = \"bg2\" }\n\"ui.cursor.insert\" = { fg = \"bg1\", bg = \"blue0\" }\n\"ui.cursor.normal\" = { fg = \"bg1\", bg = \"gray\" }\n\"ui.cursor.select\" = { fg = \"bg1\", bg = \"orange0\" }\n\"ui.cursor.match\" = { fg = \"fg1\", bg = \"bg2\", modifiers = [\"bold\"] }\n\n\"ui.cursor.primary\" = { bg = \"fg3\", fg = \"bg1\" }\n\"ui.cursor.primary.insert\" = { fg = \"bg1\", bg = \"blue1\" }\n\"ui.cursor.primary.normal\" = { fg = \"bg1\", bg = \"fg3\" }\n\"ui.cursor.primary.select\" = { fg = \"bg1\", bg = \"orange1\" }\n\n\"ui.cursorline\" = { bg = \"bg0_s\" }\n\"ui.cursorline.primary\" = { bg = \"bg1\" }\n\n\"ui.help\" = { bg = \"bg1\", fg = \"fg1\" }\n\"ui.linenr\" = { fg = \"bg3\" }\n\"ui.linenr.selected\" = { fg = \"yellow1\" }\n\"ui.menu\" = { fg = \"fg1\", bg = \"bg2\" }\n\"ui.menu.selected\" = { fg = \"bg1\", bg = \"blue1\", modifiers = [\"bold\"] }\n\"ui.popup\" = { bg = \"bg1\" }\n\"ui.picker.header.column\" = { underline.style = \"line\" }\n\"ui.picker.header.column.active\" = { modifiers = [\"bold\"], underline.style = \"line\" }\n\"ui.selection\" = { bg = \"bg3\" }\n\"ui.selection.primary\" = { bg = \"bg4\" }\n\n\"ui.statusline\" = { fg = \"fg1\", bg = \"bg2\" }\n\"ui.statusline.inactive\" = { fg = \"fg4\", bg = \"bg2\" }\n\"ui.statusline.insert\" = { fg = \"bg1\", bg = \"blue1\", modifiers = [\"bold\", \"italic\"] }\n\"ui.statusline.normal\" = { fg = \"bg1\", bg = \"fg3\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"bg1\", bg = \"orange1\", modifiers = [\"bold\"] }\n\n\"ui.text\" = { fg = \"fg1\" }\n\"ui.text.directory\" = { fg = \"blue1\" }\n\"ui.virtual.inlay-hint\" = { fg = \"gray\" }\n\"ui.virtual.jump-label\" = { fg = \"purple0\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"bg1\" }\n\"ui.virtual.whitespace\" = \"bg2\"\n\"ui.virtual.wrap\" = { fg = \"bg2\" }\n\"ui.window\" = { bg = \"bg1\" }\n\n\"variable\" = { fg = \"fg1\" }\n\"variable.builtin\" = { fg = \"orange1\", modifiers = [\"italic\"] }\n\"variable.other.member\" = { fg = \"blue1\" }\n\"variable.parameter\" = { fg = \"blue1\", modifiers = [\"italic\", \"bold\"] }\n\n[palette]\nbg0     = \"#1e1e2e\"   # main workspace background\nbg0_s   = \"#1c1c2a\"   # slightly darker for smooth layering\nbg1     = \"#2e2e3e\"   # active panel\nbg2     = \"#3b3b4d\"   # status bar / line numbers\nbg3     = \"#4b4b5e\"   # popup/menu bg\nbg4     = \"#5a5a72\"   # gutters/secondary borders\n\nfg0     = \"#f4f4f5\"   # high-contrast text\nfg1     = \"#dcdcdc\"   # main foreground\nfg2     = \"#c0c0c0\"   # soft text\nfg3     = \"#a8a8a8\"   # lighter text\nfg4     = \"#909090\"   # faint hints\n\ngray    = \"#7a7a89\"   # modern neutral gray, no brown tint\n\nred0    = \"#f7768e\"   # rose red\nred1    = \"#ff6e7f\"   # coral pop\ngreen0  = \"#9ece6a\"   # tea green\ngreen1  = \"#c0fca0\"   # brighter success green (tweaked)\n\nyellow0 = \"#e0af68\"   # burnt honey gold\nyellow1 = \"#f9e2af\"   # pastel gold\n\nblue0   = \"#7aa2f7\"   # cobalt sky blue\nblue1   = \"#89b4fa\"   # light sky blue\n\npurple0 = \"#bb9af7\"   # lavender violet\npurple1 = \"#cba6f7\"   # soft purple haze\n\naqua0   = \"#7dcfff\"   # icy aqua\naqua1   = \"#94e2d5\"   # mint aqua\n\norange0 = \"#fab387\"   # peachy orange\norange1 = \"#fca86f\"   # vibrant tangerine\n"
  },
  {
    "path": "runtime/themes/github_dark.toml",
    "content": "# Author : OwOSwordsman <owoswordsman@gmail.com>\n# An unofficial GitHub theme, generated using colors from: https://primer.style/primitives/colors\n# Credit goes to the original VSCode theme: https://github.com/primer/github-vscode-theme\n# Only the Light and Dark variants were specifically tested\n\nattribute = \"fg.default\"\nkeyword = \"scale.red.3\"\n\"keyword.directive\" = \"scale.red.3\"          # -- preprocessor comments (#if in C)\nnamespace = \"scale.orange.2\"\npunctuation = \"fg.default\"\n\"punctuation.delimiter\" = \"fg.default\"\noperator = \"scale.blue.1\"\nspecial = \"scale.blue.1\"\n\"variable.other.member\" = \"scale.blue.1\"\nvariable = \"fg.default\"\n\"variable.parameter\" = \"scale.orange.2\"\n\"variable.builtin\" = \"scale.red.3\"\ntype = \"scale.orange.2\"\n\"type.builtin\" = \"scale.blue.2\"\nconstructor = \"scale.purple.2\"\nfunction = \"scale.purple.2\"\n\"function.macro\" = \"scale.purple.2\"\ntag = \"scale.green.1\"\ncomment = \"fg.muted\"\nconstant = \"scale.blue.2\"\n\"constant.builtin\" = \"scale.blue.2\"\nstring = \"scale.blue.1\"\n\"constant.numeric\" = \"scale.blue.2\"\n\"constant.character.escape\" = \"scale.blue.2\"\n# used for lifetimes\nlabel = \"scale.red.3\"\n\n\"markup.heading\" = \"scale.blue.2\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"scale.blue.1\", modifiers = [\"underlined\"] }\n\"markup.raw\" = \"scale.blue.2\"\n\n\"diff.plus\" = \"open.fg\"\n\"diff.minus\" = \"closed.fg\"\n\"diff.delta\" = \"attention.fg\"\n\n\"ui.background\" = { bg = \"canvas.default\" }\n\"ui.background.separator\" = { fg = \"fg.subtle\" }\n\"ui.linenr\" = { fg = \"fg.subtle\" }\n\"ui.linenr.selected\" = { fg = \"fg.default\" }\n\"ui.statusline\" = { fg = \"fg.muted\", bg = \"scale.gray.7\" }\n\"ui.statusline.active\" = { fg = \"fg.default\", bg = \"canvas.default\", underline = { color = \"scale.coral.3\", style = \"line\" } }\n\"ui.statusline.normal\" = { fg = \"fg.default\", bg = \"accent.muted\" }\n\"ui.statusline.insert\" = { fg = \"fg.default\", bg = \"attention.muted\" }\n\"ui.statusline.select\" = { fg = \"fg.default\", bg = \"sponsors.muted\" }\n\"ui.popup\" = { bg = \"scale.gray.8\" }\n\"ui.popup.info\" = { fg = \"fg.default\", bg = \"canvas.overlay\" }\n\"ui.window\" = { fg = \"border.default\" }\n\"ui.help\" = { fg = \"fg.default\", bg = \"canvas.overlay\" }\n\n\"ui.text\" = { fg = \"fg.muted\" }\n\"ui.text.focus\" = { fg = \"fg.default\" }\n\"ui.text.inactive\" = \"fg.subtle\"\n\"ui.text.directory\" = { fg = \"scale.blue.2\" }\n\"ui.virtual\" = { fg = \"scale.gray.6\" }\n\"ui.virtual.ruler\" = { bg = \"canvas.subtle\" }\n\"ui.virtual.jump-label\" = { fg = \"scale.red.2\", modifiers = [\"bold\"] }\n\n\"ui.selection\" = { bg = \"scale.blue.8\" }\n\"ui.selection.primary\" = { bg = \"scale.blue.7\" }\n\"ui.cursor.match\" = { fg = \"attention.fg\", modifiers = [\n    \"bold\",\n], underline = { style = \"line\" } }\n\"ui.cursor\" = { modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { bg = \"canvas.subtle\" }\n\n\"ui.menu\" = { fg = \"fg.default\", bg = \"canvas.overlay\" }\n\"ui.menu.selected\" = { bg = \"scale.gray.4\" }\n\"ui.menu.scroll\" = { fg = \"scale.gray.5\", bg = \"canvas.overlay\" }\n\n\"diagnostic.hint\" = { underline = { color = \"success.fg\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"accent.fg\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"attention.fg\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"danger.fg\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nhint = \"success.fg\"\ninfo = \"accent.fg\"\nwarning = \"attention.fg\"\nerror = \"danger.fg\"\n\n[palette]\n\"accent.emphasis\" = \"#1f6feb\"\n\"accent.fg\" = \"#58a6ff\"\n\"accent.muted\" = \"#388bfd\"\n\"accent.subtle\" = \"#388bfd\"\n\"attention.emphasis\" = \"#9e6a03\"\n\"attention.fg\" = \"#d29922\"\n\"attention.muted\" = \"#bb8009\"\n\"attention.subtle\" = \"#bb8009\"\n\"border.default\" = \"#30363d\"\n\"border.muted\" = \"#21262d\"\n\"border.subtle\" = \"#f0f6fc\"\n\"canvas.default\" = \"#0d1117\"\n\"canvas.inset\" = \"#010409\"\n\"canvas.overlay\" = \"#161b22\"\n\"canvas.subtle\" = \"#161b22\"\n\"closed.emphasis\" = \"#da3633\"\n\"closed.fg\" = \"#f85149\"\n\"closed.muted\" = \"#f85149\"\n\"closed.subtle\" = \"#f85149\"\n\"danger.emphasis\" = \"#da3633\"\n\"danger.fg\" = \"#f85149\"\n\"danger.muted\" = \"#f85149\"\n\"danger.subtle\" = \"#f85149\"\n\"done.emphasis\" = \"#8957e5\"\n\"done.fg\" = \"#a371f7\"\n\"done.muted\" = \"#a371f7\"\n\"done.subtle\" = \"#a371f7\"\n\"fg.default\" = \"#c9d1d9\"\n\"fg.muted\" = \"#8b949e\"\n\"fg.onEmphasis\" = \"#ffffff\"\n\"fg.subtle\" = \"#6e7681\"\n\"neutral.emphasis\" = \"#6e7681\"\n\"neutral.emphasisPlus\" = \"#6e7681\"\n\"neutral.muted\" = \"#6e7681\"\n\"neutral.subtle\" = \"#6e7681\"\n\"open.emphasis\" = \"#238636\"\n\"open.fg\" = \"#3fb950\"\n\"open.muted\" = \"#2ea043\"\n\"open.subtle\" = \"#2ea043\"\n\"scale.black\" = \"#010409\"\n\"scale.blue.0\" = \"#cae8ff\"\n\"scale.blue.1\" = \"#a5d6ff\"\n\"scale.blue.2\" = \"#79c0ff\"\n\"scale.blue.3\" = \"#58a6ff\"\n\"scale.blue.4\" = \"#388bfd\"\n\"scale.blue.5\" = \"#1f6feb\"\n\"scale.blue.6\" = \"#1158c7\"\n\"scale.blue.7\" = \"#0d419d\"\n\"scale.blue.8\" = \"#0c2d6b\"\n\"scale.blue.9\" = \"#051d4d\"\n\"scale.coral.0\" = \"#ffddd2\"\n\"scale.coral.1\" = \"#ffc2b2\"\n\"scale.coral.2\" = \"#ffa28b\"\n\"scale.coral.3\" = \"#f78166\"\n\"scale.coral.4\" = \"#ea6045\"\n\"scale.coral.5\" = \"#cf462d\"\n\"scale.coral.6\" = \"#ac3220\"\n\"scale.coral.7\" = \"#872012\"\n\"scale.coral.8\" = \"#640d04\"\n\"scale.coral.9\" = \"#460701\"\n\"scale.gray.0\" = \"#f0f6fc\"\n\"scale.gray.1\" = \"#c9d1d9\"\n\"scale.gray.2\" = \"#b1bac4\"\n\"scale.gray.3\" = \"#8b949e\"\n\"scale.gray.4\" = \"#6e7681\"\n\"scale.gray.5\" = \"#484f58\"\n\"scale.gray.6\" = \"#30363d\"\n\"scale.gray.7\" = \"#21262d\"\n\"scale.gray.8\" = \"#161b22\"\n\"scale.gray.9\" = \"#0d1117\"\n\"scale.green.0\" = \"#aff5b4\"\n\"scale.green.1\" = \"#7ee787\"\n\"scale.green.2\" = \"#56d364\"\n\"scale.green.3\" = \"#3fb950\"\n\"scale.green.4\" = \"#2ea043\"\n\"scale.green.5\" = \"#238636\"\n\"scale.green.6\" = \"#196c2e\"\n\"scale.green.7\" = \"#0f5323\"\n\"scale.green.8\" = \"#033a16\"\n\"scale.green.9\" = \"#04260f\"\n\"scale.orange.0\" = \"#ffdfb6\"\n\"scale.orange.1\" = \"#ffc680\"\n\"scale.orange.2\" = \"#ffa657\"\n\"scale.orange.3\" = \"#f0883e\"\n\"scale.orange.4\" = \"#db6d28\"\n\"scale.orange.5\" = \"#bd561d\"\n\"scale.orange.6\" = \"#9b4215\"\n\"scale.orange.7\" = \"#762d0a\"\n\"scale.orange.8\" = \"#5a1e02\"\n\"scale.orange.9\" = \"#3d1300\"\n\"scale.pink.0\" = \"#ffdaec\"\n\"scale.pink.1\" = \"#ffbedd\"\n\"scale.pink.2\" = \"#ff9bce\"\n\"scale.pink.3\" = \"#f778ba\"\n\"scale.pink.4\" = \"#db61a2\"\n\"scale.pink.5\" = \"#bf4b8a\"\n\"scale.pink.6\" = \"#9e3670\"\n\"scale.pink.7\" = \"#7d2457\"\n\"scale.pink.8\" = \"#5e103e\"\n\"scale.pink.9\" = \"#42062a\"\n\"scale.purple.0\" = \"#eddeff\"\n\"scale.purple.1\" = \"#e2c5ff\"\n\"scale.purple.2\" = \"#d2a8ff\"\n\"scale.purple.3\" = \"#bc8cff\"\n\"scale.purple.4\" = \"#a371f7\"\n\"scale.purple.5\" = \"#8957e5\"\n\"scale.purple.6\" = \"#6e40c9\"\n\"scale.purple.7\" = \"#553098\"\n\"scale.purple.8\" = \"#3c1e70\"\n\"scale.purple.9\" = \"#271052\"\n\"scale.red.0\" = \"#ffdcd7\"\n\"scale.red.1\" = \"#ffc1ba\"\n\"scale.red.2\" = \"#ffa198\"\n\"scale.red.3\" = \"#ff7b72\"\n\"scale.red.4\" = \"#f85149\"\n\"scale.red.5\" = \"#da3633\"\n\"scale.red.6\" = \"#b62324\"\n\"scale.red.7\" = \"#8e1519\"\n\"scale.red.8\" = \"#67060c\"\n\"scale.red.9\" = \"#490202\"\n\"scale.white\" = \"#ffffff\"\n\"scale.yellow.0\" = \"#f8e3a1\"\n\"scale.yellow.1\" = \"#f2cc60\"\n\"scale.yellow.2\" = \"#e3b341\"\n\"scale.yellow.3\" = \"#d29922\"\n\"scale.yellow.4\" = \"#bb8009\"\n\"scale.yellow.5\" = \"#9e6a03\"\n\"scale.yellow.6\" = \"#845306\"\n\"scale.yellow.7\" = \"#693e00\"\n\"scale.yellow.8\" = \"#4b2900\"\n\"scale.yellow.9\" = \"#341a00\"\n\"severe.emphasis\" = \"#bd561d\"\n\"severe.fg\" = \"#db6d28\"\n\"severe.muted\" = \"#db6d28\"\n\"severe.subtle\" = \"#db6d28\"\n\"sponsors.emphasis\" = \"#bf4b8a\"\n\"sponsors.fg\" = \"#db61a2\"\n\"sponsors.muted\" = \"#db61a2\"\n\"sponsors.subtle\" = \"#db61a2\"\n\"success.emphasis\" = \"#238636\"\n\"success.fg\" = \"#3fb950\"\n\"success.muted\" = \"#2ea043\"\n\"success.subtle\" = \"#2ea043\"\n"
  },
  {
    "path": "runtime/themes/github_dark_colorblind.toml",
    "content": "# Author : OwOSwordsman <owoswordsman@gmail.com>\n# An unofficial GitHub theme, generated using colors from: https://primer.style/primitives/colors\n# Credit goes to the original VSCode theme: https://github.com/primer/github-vscode-theme\n# Only the Light and Dark variants were specifically tested\n\ninherits = \"github_dark\"\n\n[palette]\n\"accent.emphasis\" = \"#1f6feb\"\n\"accent.fg\" = \"#58a6ff\"\n\"accent.muted\" = \"#388bfd\"\n\"accent.subtle\" = \"#388bfd\"\n\"attention.emphasis\" = \"#9e6a03\"\n\"attention.fg\" = \"#d29922\"\n\"attention.muted\" = \"#bb8009\"\n\"attention.subtle\" = \"#bb8009\"\n\"border.default\" = \"#30363d\"\n\"border.muted\" = \"#21262d\"\n\"border.subtle\" = \"#f0f6fc\"\n\"canvas.default\" = \"#0d1117\"\n\"canvas.inset\" = \"#010409\"\n\"canvas.overlay\" = \"#161b22\"\n\"canvas.subtle\" = \"#161b22\"\n\"closed.emphasis\" = \"#6e7681\"\n\"closed.fg\" = \"#8b949e\"\n\"closed.muted\" = \"#6e7681\"\n\"closed.subtle\" = \"#6e7681\"\n\"danger.emphasis\" = \"#b76100\"\n\"danger.fg\" = \"#d47616\"\n\"danger.muted\" = \"#d47616\"\n\"danger.subtle\" = \"#d47616\"\n\"done.emphasis\" = \"#8957e5\"\n\"done.fg\" = \"#a371f7\"\n\"done.muted\" = \"#a371f7\"\n\"done.subtle\" = \"#a371f7\"\n\"fg.default\" = \"#c9d1d9\"\n\"fg.muted\" = \"#8b949e\"\n\"fg.onEmphasis\" = \"#ffffff\"\n\"fg.subtle\" = \"#6e7681\"\n\"neutral.emphasis\" = \"#6e7681\"\n\"neutral.emphasisPlus\" = \"#6e7681\"\n\"neutral.muted\" = \"#6e7681\"\n\"neutral.subtle\" = \"#6e7681\"\n\"open.emphasis\" = \"#b76100\"\n\"open.fg\" = \"#ec8e2c\"\n\"open.muted\" = \"#d47616\"\n\"open.subtle\" = \"#d47616\"\n\"scale.black\" = \"#010409\"\n\"scale.blue.0\" = \"#cae8ff\"\n\"scale.blue.1\" = \"#a5d6ff\"\n\"scale.blue.2\" = \"#79c0ff\"\n\"scale.blue.3\" = \"#58a6ff\"\n\"scale.blue.4\" = \"#388bfd\"\n\"scale.blue.5\" = \"#1f6feb\"\n\"scale.blue.6\" = \"#1158c7\"\n\"scale.blue.7\" = \"#0d419d\"\n\"scale.blue.8\" = \"#0c2d6b\"\n\"scale.blue.9\" = \"#051d4d\"\n\"scale.coral.0\" = \"#ffddd2\"\n\"scale.coral.1\" = \"#ffc2b2\"\n\"scale.coral.2\" = \"#ffa28b\"\n\"scale.coral.3\" = \"#f78166\"\n\"scale.coral.4\" = \"#ea6045\"\n\"scale.coral.5\" = \"#cf462d\"\n\"scale.coral.6\" = \"#ac3220\"\n\"scale.coral.7\" = \"#872012\"\n\"scale.coral.8\" = \"#640d04\"\n\"scale.coral.9\" = \"#460701\"\n\"scale.gray.0\" = \"#f0f6fc\"\n\"scale.gray.1\" = \"#c9d1d9\"\n\"scale.gray.2\" = \"#b1bac4\"\n\"scale.gray.3\" = \"#8b949e\"\n\"scale.gray.4\" = \"#6e7681\"\n\"scale.gray.5\" = \"#484f58\"\n\"scale.gray.6\" = \"#30363d\"\n\"scale.gray.7\" = \"#21262d\"\n\"scale.gray.8\" = \"#161b22\"\n\"scale.gray.9\" = \"#0d1117\"\n\"scale.green.0\" = \"#cae8ff\"\n\"scale.green.1\" = \"#a5d6ff\"\n\"scale.green.2\" = \"#79c0ff\"\n\"scale.green.3\" = \"#58a6ff\"\n\"scale.green.4\" = \"#388bfd\"\n\"scale.green.5\" = \"#1f6feb\"\n\"scale.green.6\" = \"#1158c7\"\n\"scale.green.7\" = \"#0d419d\"\n\"scale.green.8\" = \"#0c2d6b\"\n\"scale.green.9\" = \"#051d4d\"\n\"scale.orange.0\" = \"#ffe2bb\"\n\"scale.orange.1\" = \"#ffc981\"\n\"scale.orange.2\" = \"#fdac54\"\n\"scale.orange.3\" = \"#ec8e2c\"\n\"scale.orange.4\" = \"#d47616\"\n\"scale.orange.5\" = \"#b76100\"\n\"scale.orange.6\" = \"#914d04\"\n\"scale.orange.7\" = \"#6c3906\"\n\"scale.orange.8\" = \"#4e2906\"\n\"scale.orange.9\" = \"#331c04\"\n\"scale.pink.0\" = \"#ffdaec\"\n\"scale.pink.1\" = \"#ffbedd\"\n\"scale.pink.2\" = \"#ff9bce\"\n\"scale.pink.3\" = \"#f778ba\"\n\"scale.pink.4\" = \"#db61a2\"\n\"scale.pink.5\" = \"#bf4b8a\"\n\"scale.pink.6\" = \"#9e3670\"\n\"scale.pink.7\" = \"#7d2457\"\n\"scale.pink.8\" = \"#5e103e\"\n\"scale.pink.9\" = \"#42062a\"\n\"scale.purple.0\" = \"#eddeff\"\n\"scale.purple.1\" = \"#e2c5ff\"\n\"scale.purple.2\" = \"#d2a8ff\"\n\"scale.purple.3\" = \"#bc8cff\"\n\"scale.purple.4\" = \"#a371f7\"\n\"scale.purple.5\" = \"#8957e5\"\n\"scale.purple.6\" = \"#6e40c9\"\n\"scale.purple.7\" = \"#553098\"\n\"scale.purple.8\" = \"#3c1e70\"\n\"scale.purple.9\" = \"#271052\"\n\"scale.red.0\" = \"#ffe2bb\"\n\"scale.red.1\" = \"#ffc981\"\n\"scale.red.2\" = \"#fdac54\"\n\"scale.red.3\" = \"#ec8e2c\"\n\"scale.red.4\" = \"#d47616\"\n\"scale.red.5\" = \"#b76100\"\n\"scale.red.6\" = \"#914d04\"\n\"scale.red.7\" = \"#6c3906\"\n\"scale.red.8\" = \"#4e2906\"\n\"scale.red.9\" = \"#331c04\"\n\"scale.white\" = \"#ffffff\"\n\"scale.yellow.0\" = \"#f8e3a1\"\n\"scale.yellow.1\" = \"#f2cc60\"\n\"scale.yellow.2\" = \"#e3b341\"\n\"scale.yellow.3\" = \"#d29922\"\n\"scale.yellow.4\" = \"#bb8009\"\n\"scale.yellow.5\" = \"#9e6a03\"\n\"scale.yellow.6\" = \"#845306\"\n\"scale.yellow.7\" = \"#693e00\"\n\"scale.yellow.8\" = \"#4b2900\"\n\"scale.yellow.9\" = \"#341a00\"\n\"severe.emphasis\" = \"#b76100\"\n\"severe.fg\" = \"#d47616\"\n\"severe.muted\" = \"#d47616\"\n\"severe.subtle\" = \"#d47616\"\n\"sponsors.emphasis\" = \"#bf4b8a\"\n\"sponsors.fg\" = \"#db61a2\"\n\"sponsors.muted\" = \"#db61a2\"\n\"sponsors.subtle\" = \"#db61a2\"\n\"success.emphasis\" = \"#1f6feb\"\n\"success.fg\" = \"#58a6ff\"\n\"success.muted\" = \"#388bfd\"\n\"success.subtle\" = \"#388bfd\"\n"
  },
  {
    "path": "runtime/themes/github_dark_dimmed.toml",
    "content": "# Author : OwOSwordsman <owoswordsman@gmail.com>\n# An unofficial GitHub theme, generated using colors from: https://primer.style/primitives/colors\n# Credit goes to the original VSCode theme: https://github.com/primer/github-vscode-theme\n# Only the Light and Dark variants were specifically tested\n\ninherits = \"github_dark\"\n\n[palette]\n\"accent.emphasis\" = \"#316dca\"\n\"accent.fg\" = \"#539bf5\"\n\"accent.muted\" = \"#4184e4\"\n\"accent.subtle\" = \"#4184e4\"\n\"attention.emphasis\" = \"#966600\"\n\"attention.fg\" = \"#c69026\"\n\"attention.muted\" = \"#ae7c14\"\n\"attention.subtle\" = \"#ae7c14\"\n\"border.default\" = \"#444c56\"\n\"border.muted\" = \"#373e47\"\n\"border.subtle\" = \"#cdd9e5\"\n\"canvas.default\" = \"#22272e\"\n\"canvas.inset\" = \"#1c2128\"\n\"canvas.overlay\" = \"#2d333b\"\n\"canvas.subtle\" = \"#2d333b\"\n\"closed.emphasis\" = \"#c93c37\"\n\"closed.fg\" = \"#e5534b\"\n\"closed.muted\" = \"#e5534b\"\n\"closed.subtle\" = \"#e5534b\"\n\"danger.emphasis\" = \"#c93c37\"\n\"danger.fg\" = \"#e5534b\"\n\"danger.muted\" = \"#e5534b\"\n\"danger.subtle\" = \"#e5534b\"\n\"done.emphasis\" = \"#8256d0\"\n\"done.fg\" = \"#986ee2\"\n\"done.muted\" = \"#986ee2\"\n\"done.subtle\" = \"#986ee2\"\n\"fg.default\" = \"#adbac7\"\n\"fg.muted\" = \"#768390\"\n\"fg.onEmphasis\" = \"#cdd9e5\"\n\"fg.subtle\" = \"#636e7b\"\n\"neutral.emphasis\" = \"#636e7b\"\n\"neutral.emphasisPlus\" = \"#636e7b\"\n\"neutral.muted\" = \"#636e7b\"\n\"neutral.subtle\" = \"#636e7b\"\n\"open.emphasis\" = \"#347d39\"\n\"open.fg\" = \"#57ab5a\"\n\"open.muted\" = \"#46954a\"\n\"open.subtle\" = \"#46954a\"\n\"scale.black\" = \"#1c2128\"\n\"scale.blue.0\" = \"#c6e6ff\"\n\"scale.blue.1\" = \"#96d0ff\"\n\"scale.blue.2\" = \"#6cb6ff\"\n\"scale.blue.3\" = \"#539bf5\"\n\"scale.blue.4\" = \"#4184e4\"\n\"scale.blue.5\" = \"#316dca\"\n\"scale.blue.6\" = \"#255ab2\"\n\"scale.blue.7\" = \"#1b4b91\"\n\"scale.blue.8\" = \"#143d79\"\n\"scale.blue.9\" = \"#0f2d5c\"\n\"scale.coral.0\" = \"#ffdacf\"\n\"scale.coral.1\" = \"#ffb9a5\"\n\"scale.coral.2\" = \"#f79981\"\n\"scale.coral.3\" = \"#ec775c\"\n\"scale.coral.4\" = \"#de5b41\"\n\"scale.coral.5\" = \"#c2442d\"\n\"scale.coral.6\" = \"#a93524\"\n\"scale.coral.7\" = \"#8d291b\"\n\"scale.coral.8\" = \"#771d13\"\n\"scale.coral.9\" = \"#5d1008\"\n\"scale.gray.0\" = \"#cdd9e5\"\n\"scale.gray.1\" = \"#adbac7\"\n\"scale.gray.2\" = \"#909dab\"\n\"scale.gray.3\" = \"#768390\"\n\"scale.gray.4\" = \"#636e7b\"\n\"scale.gray.5\" = \"#545d68\"\n\"scale.gray.6\" = \"#444c56\"\n\"scale.gray.7\" = \"#373e47\"\n\"scale.gray.8\" = \"#2d333b\"\n\"scale.gray.9\" = \"#22272e\"\n\"scale.green.0\" = \"#b4f1b4\"\n\"scale.green.1\" = \"#8ddb8c\"\n\"scale.green.2\" = \"#6bc46d\"\n\"scale.green.3\" = \"#57ab5a\"\n\"scale.green.4\" = \"#46954a\"\n\"scale.green.5\" = \"#347d39\"\n\"scale.green.6\" = \"#2b6a30\"\n\"scale.green.7\" = \"#245829\"\n\"scale.green.8\" = \"#1b4721\"\n\"scale.green.9\" = \"#113417\"\n\"scale.orange.0\" = \"#ffddb0\"\n\"scale.orange.1\" = \"#ffbc6f\"\n\"scale.orange.2\" = \"#f69d50\"\n\"scale.orange.3\" = \"#e0823d\"\n\"scale.orange.4\" = \"#cc6b2c\"\n\"scale.orange.5\" = \"#ae5622\"\n\"scale.orange.6\" = \"#94471b\"\n\"scale.orange.7\" = \"#7f3913\"\n\"scale.orange.8\" = \"#682d0f\"\n\"scale.orange.9\" = \"#4d210c\"\n\"scale.pink.0\" = \"#ffd7eb\"\n\"scale.pink.1\" = \"#ffb3d8\"\n\"scale.pink.2\" = \"#fc8dc7\"\n\"scale.pink.3\" = \"#e275ad\"\n\"scale.pink.4\" = \"#c96198\"\n\"scale.pink.5\" = \"#ae4c82\"\n\"scale.pink.6\" = \"#983b6e\"\n\"scale.pink.7\" = \"#7e325a\"\n\"scale.pink.8\" = \"#69264a\"\n\"scale.pink.9\" = \"#551639\"\n\"scale.purple.0\" = \"#eedcff\"\n\"scale.purple.1\" = \"#dcbdfb\"\n\"scale.purple.2\" = \"#dcbdfb\"\n\"scale.purple.3\" = \"#b083f0\"\n\"scale.purple.4\" = \"#986ee2\"\n\"scale.purple.5\" = \"#8256d0\"\n\"scale.purple.6\" = \"#6b44bc\"\n\"scale.purple.7\" = \"#5936a2\"\n\"scale.purple.8\" = \"#472c82\"\n\"scale.purple.9\" = \"#352160\"\n\"scale.red.0\" = \"#ffd8d3\"\n\"scale.red.1\" = \"#ffb8b0\"\n\"scale.red.2\" = \"#ff938a\"\n\"scale.red.3\" = \"#f47067\"\n\"scale.red.4\" = \"#e5534b\"\n\"scale.red.5\" = \"#c93c37\"\n\"scale.red.6\" = \"#ad2e2c\"\n\"scale.red.7\" = \"#922323\"\n\"scale.red.8\" = \"#78191b\"\n\"scale.red.9\" = \"#5d0f12\"\n\"scale.white\" = \"#cdd9e5\"\n\"scale.yellow.0\" = \"#fbe090\"\n\"scale.yellow.1\" = \"#eac55f\"\n\"scale.yellow.2\" = \"#daaa3f\"\n\"scale.yellow.3\" = \"#c69026\"\n\"scale.yellow.4\" = \"#ae7c14\"\n\"scale.yellow.5\" = \"#966600\"\n\"scale.yellow.6\" = \"#805400\"\n\"scale.yellow.7\" = \"#6c4400\"\n\"scale.yellow.8\" = \"#593600\"\n\"scale.yellow.9\" = \"#452700\"\n\"severe.emphasis\" = \"#ae5622\"\n\"severe.fg\" = \"#cc6b2c\"\n\"severe.muted\" = \"#cc6b2c\"\n\"severe.subtle\" = \"#cc6b2c\"\n\"sponsors.emphasis\" = \"#ae4c82\"\n\"sponsors.fg\" = \"#c96198\"\n\"sponsors.muted\" = \"#c96198\"\n\"sponsors.subtle\" = \"#c96198\"\n\"success.emphasis\" = \"#347d39\"\n\"success.fg\" = \"#57ab5a\"\n\"success.muted\" = \"#46954a\"\n\"success.subtle\" = \"#46954a\"\n"
  },
  {
    "path": "runtime/themes/github_dark_high_contrast.toml",
    "content": "# Author : OwOSwordsman <owoswordsman@gmail.com>\n# An unofficial GitHub theme, generated using colors from: https://primer.style/primitives/colors\n# Credit goes to the original VSCode theme: https://github.com/primer/github-vscode-theme\n# Only the Light and Dark variants were specifically tested\n\ninherits = \"github_dark\"\n\n[palette]\n\"accent.emphasis\" = \"#409eff\"\n\"accent.fg\" = \"#71b7ff\"\n\"accent.muted\" = \"#409eff\"\n\"accent.subtle\" = \"#409eff\"\n\"attention.emphasis\" = \"#e09b13\"\n\"attention.fg\" = \"#f0b72f\"\n\"attention.muted\" = \"#e09b13\"\n\"attention.subtle\" = \"#e09b13\"\n\"border.default\" = \"#7a828e\"\n\"border.muted\" = \"#7a828e\"\n\"border.subtle\" = \"#7a828e\"\n\"canvas.default\" = \"#0a0c10\"\n\"canvas.inset\" = \"#010409\"\n\"canvas.overlay\" = \"#272b33\"\n\"canvas.subtle\" = \"#272b33\"\n\"closed.emphasis\" = \"#ff6a69\"\n\"closed.fg\" = \"#ff6a69\"\n\"closed.muted\" = \"#ff6a69\"\n\"closed.subtle\" = \"#ff6a69\"\n\"danger.emphasis\" = \"#ff6a69\"\n\"danger.fg\" = \"#ff6a69\"\n\"danger.muted\" = \"#ff6a69\"\n\"danger.subtle\" = \"#ff6a69\"\n\"done.emphasis\" = \"#b87fff\"\n\"done.fg\" = \"#b780ff\"\n\"done.muted\" = \"#b780ff\"\n\"done.subtle\" = \"#b780ff\"\n\"fg.default\" = \"#f0f3f6\"\n\"fg.muted\" = \"#f0f3f6\"\n\"fg.onEmphasis\" = \"#0a0c10\"\n\"fg.subtle\" = \"#9ea7b3\"\n\"neutral.emphasis\" = \"#9ea7b3\"\n\"neutral.emphasisPlus\" = \"#ffffff\"\n\"neutral.muted\" = \"#9ea7b3\"\n\"neutral.subtle\" = \"#9ea7b3\"\n\"open.emphasis\" = \"#09b43a\"\n\"open.fg\" = \"#26cd4d\"\n\"open.muted\" = \"#09b43a\"\n\"open.subtle\" = \"#09b43a\"\n\"scale.black\" = \"#010409\"\n\"scale.blue.0\" = \"#caeaff\"\n\"scale.blue.1\" = \"#addcff\"\n\"scale.blue.2\" = \"#91cbff\"\n\"scale.blue.3\" = \"#71b7ff\"\n\"scale.blue.4\" = \"#409eff\"\n\"scale.blue.5\" = \"#409eff\"\n\"scale.blue.6\" = \"#318bf8\"\n\"scale.blue.7\" = \"#2672f3\"\n\"scale.blue.8\" = \"#1e60d5\"\n\"scale.blue.9\" = \"#194fb1\"\n\"scale.coral.0\" = \"#ffded4\"\n\"scale.coral.1\" = \"#ffcbb9\"\n\"scale.coral.2\" = \"#ffb39b\"\n\"scale.coral.3\" = \"#ff967d\"\n\"scale.coral.4\" = \"#fc704f\"\n\"scale.coral.5\" = \"#fc704f\"\n\"scale.coral.6\" = \"#f75133\"\n\"scale.coral.7\" = \"#e03b21\"\n\"scale.coral.8\" = \"#c62612\"\n\"scale.coral.9\" = \"#a91500\"\n\"scale.gray.0\" = \"#ffffff\"\n\"scale.gray.1\" = \"#f0f3f6\"\n\"scale.gray.2\" = \"#d9dee3\"\n\"scale.gray.3\" = \"#bdc4cc\"\n\"scale.gray.4\" = \"#9ea7b3\"\n\"scale.gray.5\" = \"#7a828e\"\n\"scale.gray.6\" = \"#525964\"\n\"scale.gray.7\" = \"#272b33\"\n\"scale.gray.8\" = \"#272b33\"\n\"scale.gray.9\" = \"#0a0c10\"\n\"scale.green.0\" = \"#acf7b6\"\n\"scale.green.1\" = \"#72f088\"\n\"scale.green.2\" = \"#4ae168\"\n\"scale.green.3\" = \"#26cd4d\"\n\"scale.green.4\" = \"#09b43a\"\n\"scale.green.5\" = \"#09b43a\"\n\"scale.green.6\" = \"#02a232\"\n\"scale.green.7\" = \"#008c2c\"\n\"scale.green.8\" = \"#007728\"\n\"scale.green.9\" = \"#006222\"\n\"scale.orange.0\" = \"#ffe1b4\"\n\"scale.orange.1\" = \"#ffcf86\"\n\"scale.orange.2\" = \"#ffb757\"\n\"scale.orange.3\" = \"#fe9a2d\"\n\"scale.orange.4\" = \"#e7811d\"\n\"scale.orange.5\" = \"#e7811d\"\n\"scale.orange.6\" = \"#d57014\"\n\"scale.orange.7\" = \"#bf5e0a\"\n\"scale.orange.8\" = \"#a74c00\"\n\"scale.orange.9\" = \"#8f3c00\"\n\"scale.pink.0\" = \"#ffdceb\"\n\"scale.pink.1\" = \"#ffc7e1\"\n\"scale.pink.2\" = \"#ffadd4\"\n\"scale.pink.3\" = \"#ff8dc7\"\n\"scale.pink.4\" = \"#ef6eb1\"\n\"scale.pink.5\" = \"#ef6eb1\"\n\"scale.pink.6\" = \"#e456a3\"\n\"scale.pink.7\" = \"#d23d91\"\n\"scale.pink.8\" = \"#b72c7d\"\n\"scale.pink.9\" = \"#9c1d6a\"\n\"scale.purple.0\" = \"#f0dfff\"\n\"scale.purple.1\" = \"#e6ccff\"\n\"scale.purple.2\" = \"#dbb7ff\"\n\"scale.purple.3\" = \"#cb9eff\"\n\"scale.purple.4\" = \"#b780ff\"\n\"scale.purple.5\" = \"#b87fff\"\n\"scale.purple.6\" = \"#a66bff\"\n\"scale.purple.7\" = \"#954ffd\"\n\"scale.purple.8\" = \"#8031f7\"\n\"scale.purple.9\" = \"#6921d7\"\n\"scale.red.0\" = \"#ffdedb\"\n\"scale.red.1\" = \"#ffc9c7\"\n\"scale.red.2\" = \"#ffb1af\"\n\"scale.red.3\" = \"#ff9492\"\n\"scale.red.4\" = \"#ff6a69\"\n\"scale.red.5\" = \"#ff6a69\"\n\"scale.red.6\" = \"#ff4445\"\n\"scale.red.7\" = \"#e82a2f\"\n\"scale.red.8\" = \"#cc1421\"\n\"scale.red.9\" = \"#ad0116\"\n\"scale.white\" = \"#ffffff\"\n\"scale.yellow.0\" = \"#fbe59e\"\n\"scale.yellow.1\" = \"#fbd669\"\n\"scale.yellow.2\" = \"#f7c843\"\n\"scale.yellow.3\" = \"#f0b72f\"\n\"scale.yellow.4\" = \"#e09b13\"\n\"scale.yellow.5\" = \"#e09b13\"\n\"scale.yellow.6\" = \"#c88508\"\n\"scale.yellow.7\" = \"#ae7104\"\n\"scale.yellow.8\" = \"#945d02\"\n\"scale.yellow.9\" = \"#7b4900\"\n\"severe.emphasis\" = \"#e7811d\"\n\"severe.fg\" = \"#e7811d\"\n\"severe.muted\" = \"#e7811d\"\n\"severe.subtle\" = \"#e7811d\"\n\"sponsors.emphasis\" = \"#ef6eb1\"\n\"sponsors.fg\" = \"#ef6eb1\"\n\"sponsors.muted\" = \"#ef6eb1\"\n\"sponsors.subtle\" = \"#ef6eb1\"\n\"success.emphasis\" = \"#09b43a\"\n\"success.fg\" = \"#26cd4d\"\n\"success.muted\" = \"#09b43a\"\n\"success.subtle\" = \"#09b43a\"\n"
  },
  {
    "path": "runtime/themes/github_dark_tritanopia.toml",
    "content": "# Author : OwOSwordsman <owoswordsman@gmail.com>\n# An unofficial GitHub theme, generated using colors from: https://primer.style/primitives/colors\n# Credit goes to the original VSCode theme: https://github.com/primer/github-vscode-theme\n# Only the Light and Dark variants were specifically tested\n\ninherits = \"github_dark\"\n\n[palette]\n\"accent.emphasis\" = \"#1f6feb\"\n\"accent.fg\" = \"#58a6ff\"\n\"accent.muted\" = \"#388bfd\"\n\"accent.subtle\" = \"#388bfd\"\n\"attention.emphasis\" = \"#9e6a03\"\n\"attention.fg\" = \"#d29922\"\n\"attention.muted\" = \"#bb8009\"\n\"attention.subtle\" = \"#bb8009\"\n\"border.default\" = \"#30363d\"\n\"border.muted\" = \"#21262d\"\n\"border.subtle\" = \"#f0f6fc\"\n\"canvas.default\" = \"#0d1117\"\n\"canvas.inset\" = \"#010409\"\n\"canvas.overlay\" = \"#161b22\"\n\"canvas.subtle\" = \"#161b22\"\n\"closed.emphasis\" = \"#6e7681\"\n\"closed.fg\" = \"#8b949e\"\n\"closed.muted\" = \"#6e7681\"\n\"closed.subtle\" = \"#6e7681\"\n\"danger.emphasis\" = \"#da3633\"\n\"danger.fg\" = \"#f85149\"\n\"danger.muted\" = \"#f85149\"\n\"danger.subtle\" = \"#f85149\"\n\"done.emphasis\" = \"#8957e5\"\n\"done.fg\" = \"#a371f7\"\n\"done.muted\" = \"#a371f7\"\n\"done.subtle\" = \"#a371f7\"\n\"fg.default\" = \"#c9d1d9\"\n\"fg.muted\" = \"#8b949e\"\n\"fg.onEmphasis\" = \"#ffffff\"\n\"fg.subtle\" = \"#6e7681\"\n\"neutral.emphasis\" = \"#6e7681\"\n\"neutral.emphasisPlus\" = \"#6e7681\"\n\"neutral.muted\" = \"#6e7681\"\n\"neutral.subtle\" = \"#6e7681\"\n\"open.emphasis\" = \"#da3633\"\n\"open.fg\" = \"#ff7b72\"\n\"open.muted\" = \"#f85149\"\n\"open.subtle\" = \"#f85149\"\n\"scale.black\" = \"#010409\"\n\"scale.blue.0\" = \"#cae8ff\"\n\"scale.blue.1\" = \"#a5d6ff\"\n\"scale.blue.2\" = \"#79c0ff\"\n\"scale.blue.3\" = \"#58a6ff\"\n\"scale.blue.4\" = \"#388bfd\"\n\"scale.blue.5\" = \"#1f6feb\"\n\"scale.blue.6\" = \"#1158c7\"\n\"scale.blue.7\" = \"#0d419d\"\n\"scale.blue.8\" = \"#0c2d6b\"\n\"scale.blue.9\" = \"#051d4d\"\n\"scale.coral.0\" = \"#ffddd2\"\n\"scale.coral.1\" = \"#ffc2b2\"\n\"scale.coral.2\" = \"#ffa28b\"\n\"scale.coral.3\" = \"#f78166\"\n\"scale.coral.4\" = \"#ea6045\"\n\"scale.coral.5\" = \"#cf462d\"\n\"scale.coral.6\" = \"#ac3220\"\n\"scale.coral.7\" = \"#872012\"\n\"scale.coral.8\" = \"#640d04\"\n\"scale.coral.9\" = \"#460701\"\n\"scale.gray.0\" = \"#f0f6fc\"\n\"scale.gray.1\" = \"#c9d1d9\"\n\"scale.gray.2\" = \"#b1bac4\"\n\"scale.gray.3\" = \"#8b949e\"\n\"scale.gray.4\" = \"#6e7681\"\n\"scale.gray.5\" = \"#484f58\"\n\"scale.gray.6\" = \"#30363d\"\n\"scale.gray.7\" = \"#21262d\"\n\"scale.gray.8\" = \"#161b22\"\n\"scale.gray.9\" = \"#0d1117\"\n\"scale.green.0\" = \"#cae8ff\"\n\"scale.green.1\" = \"#a5d6ff\"\n\"scale.green.2\" = \"#79c0ff\"\n\"scale.green.3\" = \"#58a6ff\"\n\"scale.green.4\" = \"#388bfd\"\n\"scale.green.5\" = \"#1f6feb\"\n\"scale.green.6\" = \"#1158c7\"\n\"scale.green.7\" = \"#0d419d\"\n\"scale.green.8\" = \"#0c2d6b\"\n\"scale.green.9\" = \"#051d4d\"\n\"scale.orange.0\" = \"#ffdcd7\"\n\"scale.orange.1\" = \"#ffc1ba\"\n\"scale.orange.2\" = \"#ffa198\"\n\"scale.orange.3\" = \"#ff7b72\"\n\"scale.orange.4\" = \"#f85149\"\n\"scale.orange.5\" = \"#da3633\"\n\"scale.orange.6\" = \"#b62324\"\n\"scale.orange.7\" = \"#8e1519\"\n\"scale.orange.8\" = \"#67060c\"\n\"scale.orange.9\" = \"#490202\"\n\"scale.pink.0\" = \"#ffdaec\"\n\"scale.pink.1\" = \"#ffbedd\"\n\"scale.pink.2\" = \"#ff9bce\"\n\"scale.pink.3\" = \"#f778ba\"\n\"scale.pink.4\" = \"#db61a2\"\n\"scale.pink.5\" = \"#bf4b8a\"\n\"scale.pink.6\" = \"#9e3670\"\n\"scale.pink.7\" = \"#7d2457\"\n\"scale.pink.8\" = \"#5e103e\"\n\"scale.pink.9\" = \"#42062a\"\n\"scale.purple.0\" = \"#eddeff\"\n\"scale.purple.1\" = \"#e2c5ff\"\n\"scale.purple.2\" = \"#d2a8ff\"\n\"scale.purple.3\" = \"#bc8cff\"\n\"scale.purple.4\" = \"#a371f7\"\n\"scale.purple.5\" = \"#8957e5\"\n\"scale.purple.6\" = \"#6e40c9\"\n\"scale.purple.7\" = \"#553098\"\n\"scale.purple.8\" = \"#3c1e70\"\n\"scale.purple.9\" = \"#271052\"\n\"scale.red.0\" = \"#ffdcd7\"\n\"scale.red.1\" = \"#ffc1ba\"\n\"scale.red.2\" = \"#ffa198\"\n\"scale.red.3\" = \"#ff7b72\"\n\"scale.red.4\" = \"#f85149\"\n\"scale.red.5\" = \"#da3633\"\n\"scale.red.6\" = \"#b62324\"\n\"scale.red.7\" = \"#8e1519\"\n\"scale.red.8\" = \"#67060c\"\n\"scale.red.9\" = \"#490202\"\n\"scale.white\" = \"#ffffff\"\n\"scale.yellow.0\" = \"#f8e3a1\"\n\"scale.yellow.1\" = \"#f2cc60\"\n\"scale.yellow.2\" = \"#e3b341\"\n\"scale.yellow.3\" = \"#d29922\"\n\"scale.yellow.4\" = \"#bb8009\"\n\"scale.yellow.5\" = \"#9e6a03\"\n\"scale.yellow.6\" = \"#845306\"\n\"scale.yellow.7\" = \"#693e00\"\n\"scale.yellow.8\" = \"#4b2900\"\n\"scale.yellow.9\" = \"#341a00\"\n\"severe.emphasis\" = \"#da3633\"\n\"severe.fg\" = \"#f85149\"\n\"severe.muted\" = \"#f85149\"\n\"severe.subtle\" = \"#f85149\"\n\"sponsors.emphasis\" = \"#bf4b8a\"\n\"sponsors.fg\" = \"#db61a2\"\n\"sponsors.muted\" = \"#db61a2\"\n\"sponsors.subtle\" = \"#db61a2\"\n\"success.emphasis\" = \"#1f6feb\"\n\"success.fg\" = \"#58a6ff\"\n\"success.muted\" = \"#388bfd\"\n\"success.subtle\" = \"#388bfd\"\n"
  },
  {
    "path": "runtime/themes/github_light.toml",
    "content": "# Author : OwOSwordsman <owoswordsman@gmail.com>\n# An unofficial GitHub theme, generated using colors from: https://primer.style/primitives/colors\n# Credit goes to the original VSCode theme: https://github.com/primer/github-vscode-theme\n# Only the Light and Dark variants were specifically tested\n\nattribute = \"fg.default\"\nkeyword = \"scale.red.5\"\n\"keyword.directive\" = \"scale.red.5\"          # -- preprocessor comments (#if in C)\nnamespace = \"scale.orange.6\"\npunctuation = \"fg.default\"\n\"punctuation.delimiter\" = \"fg.default\"\noperator = \"scale.blue.8\"\nspecial = \"scale.blue.8\"\n\"variable.other.member\" = \"scale.blue.8\"\nvariable = \"fg.default\"\n\"variable.parameter\" = \"scale.orange.6\"\n\"variable.builtin\" = \"scale.red.5\"\ntype = \"scale.orange.6\"\n\"type.builtin\" = \"scale.blue.6\"\nconstructor = \"done.fg\"\nfunction = \"done.fg\"\n\"function.macro\" = \"done.fg\"\ntag = \"scale.green.6\"\ncomment = \"fg.muted\"\nconstant = \"scale.blue.6\"\n\"constant.builtin\" = \"scale.blue.6\"\nstring = \"scale.blue.8\"\n\"constant.numeric\" = \"scale.blue.6\"\n\"constant.character.escape\" = \"scale.blue.6\"\n# used for lifetimes\nlabel = \"scale.red.5\"\n\n\"markup.heading\" = \"scale.blue.6\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"scale.blue.8\", modifiers = [\"underlined\"] }\n\"markup.raw\" = \"scale.blue.6\"\n\n\"diff.plus\" = \"open.fg\"\n\"diff.minus\" = \"closed.fg\"\n\"diff.delta\" = \"attention.fg\"\n\n\"ui.background\" = { bg = \"canvas.default\" }\n\"ui.background.separator\" = { fg = \"fg.subtle\" }\n\"ui.linenr\" = { fg = \"fg.subtle\" }\n\"ui.linenr.selected\" = { fg = \"fg.default\" }\n\"ui.statusline\" = { fg = \"fg.muted\", bg = \"neutral.subtle\" }\n\"ui.statusline.active\" = { fg = \"fg.default\", bg = \"canvas.default\", underline = { color = \"scale.coral.3\", style = \"line\" } }\n\"ui.statusline.normal\" = { fg = \"fg.default\", bg = \"accent.muted\" }\n\"ui.statusline.insert\" = { fg = \"fg.default\", bg = \"attention.muted\" }\n\"ui.statusline.select\" = { fg = \"fg.default\", bg = \"sponsors.muted\" }\n\"ui.popup\" = { bg = \"scale.gray.0\" }\n\"ui.popup.info\" = { fg = \"fg.default\", bg = \"scale.gray.0\" }\n\"ui.window\" = { fg = \"border.default\" }\n\"ui.help\" = { fg = \"fg.default\", bg = \"scale.gray.0\" }\n\n\"ui.text\" = { fg = \"fg.muted\" }\n\"ui.text.focus\" = { fg = \"fg.default\" }\n\"ui.text.inactive\" = \"fg.subtle\"\n\"ui.text.directory\" = { fg = \"scale.blue.4\" }\n\"ui.virtual\" = { fg = \"scale.gray.2\" }\n\"ui.virtual.ruler\" = { bg = \"canvas.subtle\" }\n\"ui.virtual.jump-label\" = { modifiers = [\"reversed\"] }\n\n\"ui.selection\" = { bg = \"scale.blue.0\" }\n\"ui.selection.primary\" = { bg = \"scale.blue.1\" }\n\"ui.cursor.match\" = { fg = \"attention.fg\", modifiers = [\n    \"bold\",\n], underline = { style = \"line\" } }\n\"ui.cursor\" = { modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { bg = \"canvas.subtle\" }\n\n\"ui.menu\" = { fg = \"fg.default\", bg = \"scale.gray.0\" }\n\"ui.menu.selected\" = { bg = \"scale.gray.1\" }\n\"ui.menu.scroll\" = { fg = \"scale.gray.2\", bg = \"scale.gray.0\" }\n\n\"diagnostic.hint\" = { underline = { color = \"success.fg\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"accent.fg\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"attention.fg\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"danger.fg\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nhint = \"success.fg\"\ninfo = \"accent.fg\"\nwarning = \"attention.fg\"\nerror = \"danger.fg\"\n\n[palette]\n\"accent.emphasis\" = \"#0969da\"\n\"accent.fg\" = \"#0969da\"\n\"accent.muted\" = \"#54aeff\"\n\"accent.subtle\" = \"#ddf4ff\"\n\"attention.emphasis\" = \"#bf8700\"\n\"attention.fg\" = \"#9a6700\"\n\"attention.muted\" = \"#d4a72c\"\n\"attention.subtle\" = \"#fff8c5\"\n\"border.default\" = \"#d0d7de\"\n\"border.muted\" = \"#d8dee4\"\n\"border.subtle\" = \"#1b1f24\"\n\"canvas.default\" = \"#ffffff\"\n\"canvas.inset\" = \"#f6f8fa\"\n\"canvas.overlay\" = \"#ffffff\"\n\"canvas.subtle\" = \"#f6f8fa\"\n\"closed.emphasis\" = \"#cf222e\"\n\"closed.fg\" = \"#cf222e\"\n\"closed.muted\" = \"#ff8182\"\n\"closed.subtle\" = \"#ffebe9\"\n\"danger.emphasis\" = \"#cf222e\"\n\"danger.fg\" = \"#cf222e\"\n\"danger.muted\" = \"#ff8182\"\n\"danger.subtle\" = \"#ffebe9\"\n\"done.emphasis\" = \"#8250df\"\n\"done.fg\" = \"#8250df\"\n\"done.muted\" = \"#c297ff\"\n\"done.subtle\" = \"#fbefff\"\n\"fg.default\" = \"#24292f\"\n\"fg.muted\" = \"#57606a\"\n\"fg.onEmphasis\" = \"#ffffff\"\n\"fg.subtle\" = \"#6e7781\"\n\"neutral.emphasis\" = \"#6e7781\"\n\"neutral.emphasisPlus\" = \"#24292f\"\n\"neutral.muted\" = \"#afb8c1\"\n\"neutral.subtle\" = \"#eaeef2\"\n\"open.emphasis\" = \"#2da44e\"\n\"open.fg\" = \"#1a7f37\"\n\"open.muted\" = \"#4ac26b\"\n\"open.subtle\" = \"#dafbe1\"\n\"scale.black\" = \"#1b1f24\"\n\"scale.blue.0\" = \"#ddf4ff\"\n\"scale.blue.1\" = \"#b6e3ff\"\n\"scale.blue.2\" = \"#80ccff\"\n\"scale.blue.3\" = \"#54aeff\"\n\"scale.blue.4\" = \"#218bff\"\n\"scale.blue.5\" = \"#0969da\"\n\"scale.blue.6\" = \"#0550ae\"\n\"scale.blue.7\" = \"#033d8b\"\n\"scale.blue.8\" = \"#0a3069\"\n\"scale.blue.9\" = \"#002155\"\n\"scale.coral.0\" = \"#fff0eb\"\n\"scale.coral.1\" = \"#ffd6cc\"\n\"scale.coral.2\" = \"#ffb4a1\"\n\"scale.coral.3\" = \"#fd8c73\"\n\"scale.coral.4\" = \"#ec6547\"\n\"scale.coral.5\" = \"#c4432b\"\n\"scale.coral.6\" = \"#9e2f1c\"\n\"scale.coral.7\" = \"#801f0f\"\n\"scale.coral.8\" = \"#691105\"\n\"scale.coral.9\" = \"#510901\"\n\"scale.gray.0\" = \"#f6f8fa\"\n\"scale.gray.1\" = \"#eaeef2\"\n\"scale.gray.2\" = \"#d0d7de\"\n\"scale.gray.3\" = \"#afb8c1\"\n\"scale.gray.4\" = \"#8c959f\"\n\"scale.gray.5\" = \"#6e7781\"\n\"scale.gray.6\" = \"#57606a\"\n\"scale.gray.7\" = \"#424a53\"\n\"scale.gray.8\" = \"#32383f\"\n\"scale.gray.9\" = \"#24292f\"\n\"scale.green.0\" = \"#dafbe1\"\n\"scale.green.1\" = \"#aceebb\"\n\"scale.green.2\" = \"#6fdd8b\"\n\"scale.green.3\" = \"#4ac26b\"\n\"scale.green.4\" = \"#2da44e\"\n\"scale.green.5\" = \"#1a7f37\"\n\"scale.green.6\" = \"#116329\"\n\"scale.green.7\" = \"#044f1e\"\n\"scale.green.8\" = \"#003d16\"\n\"scale.green.9\" = \"#002d11\"\n\"scale.orange.0\" = \"#fff1e5\"\n\"scale.orange.1\" = \"#ffd8b5\"\n\"scale.orange.2\" = \"#ffb77c\"\n\"scale.orange.3\" = \"#fb8f44\"\n\"scale.orange.4\" = \"#e16f24\"\n\"scale.orange.5\" = \"#bc4c00\"\n\"scale.orange.6\" = \"#953800\"\n\"scale.orange.7\" = \"#762c00\"\n\"scale.orange.8\" = \"#5c2200\"\n\"scale.orange.9\" = \"#471700\"\n\"scale.pink.0\" = \"#ffeff7\"\n\"scale.pink.1\" = \"#ffd3eb\"\n\"scale.pink.2\" = \"#ffadda\"\n\"scale.pink.3\" = \"#ff80c8\"\n\"scale.pink.4\" = \"#e85aad\"\n\"scale.pink.5\" = \"#bf3989\"\n\"scale.pink.6\" = \"#99286e\"\n\"scale.pink.7\" = \"#772057\"\n\"scale.pink.8\" = \"#611347\"\n\"scale.pink.9\" = \"#4d0336\"\n\"scale.purple.0\" = \"#fbefff\"\n\"scale.purple.1\" = \"#ecd8ff\"\n\"scale.purple.2\" = \"#d8b9ff\"\n\"scale.purple.3\" = \"#c297ff\"\n\"scale.purple.4\" = \"#a475f9\"\n\"scale.purple.5\" = \"#8250df\"\n\"scale.purple.6\" = \"#6639ba\"\n\"scale.purple.7\" = \"#512a97\"\n\"scale.purple.8\" = \"#3e1f79\"\n\"scale.purple.9\" = \"#2e1461\"\n\"scale.red.0\" = \"#ffebe9\"\n\"scale.red.1\" = \"#ffcecb\"\n\"scale.red.2\" = \"#ffaba8\"\n\"scale.red.3\" = \"#ff8182\"\n\"scale.red.4\" = \"#fa4549\"\n\"scale.red.5\" = \"#cf222e\"\n\"scale.red.6\" = \"#a40e26\"\n\"scale.red.7\" = \"#82071e\"\n\"scale.red.8\" = \"#660018\"\n\"scale.red.9\" = \"#4c0014\"\n\"scale.white\" = \"#ffffff\"\n\"scale.yellow.0\" = \"#fff8c5\"\n\"scale.yellow.1\" = \"#fae17d\"\n\"scale.yellow.2\" = \"#eac54f\"\n\"scale.yellow.3\" = \"#d4a72c\"\n\"scale.yellow.4\" = \"#bf8700\"\n\"scale.yellow.5\" = \"#9a6700\"\n\"scale.yellow.6\" = \"#7d4e00\"\n\"scale.yellow.7\" = \"#633c01\"\n\"scale.yellow.8\" = \"#4d2d00\"\n\"scale.yellow.9\" = \"#3b2300\"\n\"severe.emphasis\" = \"#bc4c00\"\n\"severe.fg\" = \"#bc4c00\"\n\"severe.muted\" = \"#fb8f44\"\n\"severe.subtle\" = \"#fff1e5\"\n\"sponsors.emphasis\" = \"#bf3989\"\n\"sponsors.fg\" = \"#bf3989\"\n\"sponsors.muted\" = \"#ff80c8\"\n\"sponsors.subtle\" = \"#ffeff7\"\n\"success.emphasis\" = \"#2da44e\"\n\"success.fg\" = \"#1a7f37\"\n\"success.muted\" = \"#4ac26b\"\n\"success.subtle\" = \"#dafbe1\"\n"
  },
  {
    "path": "runtime/themes/github_light_colorblind.toml",
    "content": "# Author : OwOSwordsman <owoswordsman@gmail.com>\n# An unofficial GitHub theme, generated using colors from: https://primer.style/primitives/colors\n# Credit goes to the original VSCode theme: https://github.com/primer/github-vscode-theme\n# Only the Light and Dark variants were specifically tested\n\ninherits = \"github_light\"\n\n[palette]\n\"accent.emphasis\" = \"#0969da\"\n\"accent.fg\" = \"#0969da\"\n\"accent.muted\" = \"#54aeff\"\n\"accent.subtle\" = \"#ddf4ff\"\n\"attention.emphasis\" = \"#bf8700\"\n\"attention.fg\" = \"#9a6700\"\n\"attention.muted\" = \"#d4a72c\"\n\"attention.subtle\" = \"#fff8c5\"\n\"border.default\" = \"#d0d7de\"\n\"border.muted\" = \"#d8dee4\"\n\"border.subtle\" = \"#1b1f24\"\n\"canvas.default\" = \"#ffffff\"\n\"canvas.inset\" = \"#f6f8fa\"\n\"canvas.overlay\" = \"#ffffff\"\n\"canvas.subtle\" = \"#f6f8fa\"\n\"closed.emphasis\" = \"#6e7781\"\n\"closed.fg\" = \"#6e7781\"\n\"closed.muted\" = \"#afb8c1\"\n\"closed.subtle\" = \"#f6f8fa\"\n\"danger.emphasis\" = \"#b35900\"\n\"danger.fg\" = \"#b35900\"\n\"danger.muted\" = \"#f79939\"\n\"danger.subtle\" = \"#fff5e8\"\n\"done.emphasis\" = \"#8250df\"\n\"done.fg\" = \"#8250df\"\n\"done.muted\" = \"#c297ff\"\n\"done.subtle\" = \"#fbefff\"\n\"fg.default\" = \"#24292f\"\n\"fg.muted\" = \"#57606a\"\n\"fg.onEmphasis\" = \"#ffffff\"\n\"fg.subtle\" = \"#6e7781\"\n\"neutral.emphasis\" = \"#6e7781\"\n\"neutral.emphasisPlus\" = \"#24292f\"\n\"neutral.muted\" = \"#afb8c1\"\n\"neutral.subtle\" = \"#eaeef2\"\n\"open.emphasis\" = \"#dd7815\"\n\"open.fg\" = \"#b35900\"\n\"open.muted\" = \"#f79939\"\n\"open.subtle\" = \"#fff5e8\"\n\"scale.black\" = \"#1b1f24\"\n\"scale.blue.0\" = \"#ddf4ff\"\n\"scale.blue.1\" = \"#b6e3ff\"\n\"scale.blue.2\" = \"#80ccff\"\n\"scale.blue.3\" = \"#54aeff\"\n\"scale.blue.4\" = \"#218bff\"\n\"scale.blue.5\" = \"#0969da\"\n\"scale.blue.6\" = \"#0550ae\"\n\"scale.blue.7\" = \"#033d8b\"\n\"scale.blue.8\" = \"#0a3069\"\n\"scale.blue.9\" = \"#002155\"\n\"scale.coral.0\" = \"#fff0eb\"\n\"scale.coral.1\" = \"#ffd6cc\"\n\"scale.coral.2\" = \"#ffb4a1\"\n\"scale.coral.3\" = \"#fd8c73\"\n\"scale.coral.4\" = \"#ec6547\"\n\"scale.coral.5\" = \"#c4432b\"\n\"scale.coral.6\" = \"#9e2f1c\"\n\"scale.coral.7\" = \"#801f0f\"\n\"scale.coral.8\" = \"#691105\"\n\"scale.coral.9\" = \"#510901\"\n\"scale.gray.0\" = \"#f6f8fa\"\n\"scale.gray.1\" = \"#eaeef2\"\n\"scale.gray.2\" = \"#d0d7de\"\n\"scale.gray.3\" = \"#afb8c1\"\n\"scale.gray.4\" = \"#8c959f\"\n\"scale.gray.5\" = \"#6e7781\"\n\"scale.gray.6\" = \"#57606a\"\n\"scale.gray.7\" = \"#424a53\"\n\"scale.gray.8\" = \"#32383f\"\n\"scale.gray.9\" = \"#24292f\"\n\"scale.green.0\" = \"#ddf4ff\"\n\"scale.green.1\" = \"#b6e3ff\"\n\"scale.green.2\" = \"#80ccff\"\n\"scale.green.3\" = \"#54aeff\"\n\"scale.green.4\" = \"#218bff\"\n\"scale.green.5\" = \"#0969da\"\n\"scale.green.6\" = \"#0550ae\"\n\"scale.green.7\" = \"#033d8b\"\n\"scale.green.8\" = \"#0a3069\"\n\"scale.green.9\" = \"#002155\"\n\"scale.orange.0\" = \"#fff5e8\"\n\"scale.orange.1\" = \"#ffddb0\"\n\"scale.orange.2\" = \"#ffbc6d\"\n\"scale.orange.3\" = \"#f79939\"\n\"scale.orange.4\" = \"#dd7815\"\n\"scale.orange.5\" = \"#b35900\"\n\"scale.orange.6\" = \"#8a4600\"\n\"scale.orange.7\" = \"#6f3800\"\n\"scale.orange.8\" = \"#572c00\"\n\"scale.orange.9\" = \"#412000\"\n\"scale.pink.0\" = \"#ffeff7\"\n\"scale.pink.1\" = \"#ffd3eb\"\n\"scale.pink.2\" = \"#ffadda\"\n\"scale.pink.3\" = \"#ff80c8\"\n\"scale.pink.4\" = \"#e85aad\"\n\"scale.pink.5\" = \"#bf3989\"\n\"scale.pink.6\" = \"#99286e\"\n\"scale.pink.7\" = \"#772057\"\n\"scale.pink.8\" = \"#611347\"\n\"scale.pink.9\" = \"#4d0336\"\n\"scale.purple.0\" = \"#fbefff\"\n\"scale.purple.1\" = \"#ecd8ff\"\n\"scale.purple.2\" = \"#d8b9ff\"\n\"scale.purple.3\" = \"#c297ff\"\n\"scale.purple.4\" = \"#a475f9\"\n\"scale.purple.5\" = \"#8250df\"\n\"scale.purple.6\" = \"#6639ba\"\n\"scale.purple.7\" = \"#512a97\"\n\"scale.purple.8\" = \"#3e1f79\"\n\"scale.purple.9\" = \"#2e1461\"\n\"scale.red.0\" = \"#fff5e8\"\n\"scale.red.1\" = \"#ffddb0\"\n\"scale.red.2\" = \"#ffbc6d\"\n\"scale.red.3\" = \"#f79939\"\n\"scale.red.4\" = \"#dd7815\"\n\"scale.red.5\" = \"#b35900\"\n\"scale.red.6\" = \"#8a4600\"\n\"scale.red.7\" = \"#6f3800\"\n\"scale.red.8\" = \"#572c00\"\n\"scale.red.9\" = \"#412000\"\n\"scale.white\" = \"#ffffff\"\n\"scale.yellow.0\" = \"#fff8c5\"\n\"scale.yellow.1\" = \"#fae17d\"\n\"scale.yellow.2\" = \"#eac54f\"\n\"scale.yellow.3\" = \"#d4a72c\"\n\"scale.yellow.4\" = \"#bf8700\"\n\"scale.yellow.5\" = \"#9a6700\"\n\"scale.yellow.6\" = \"#7d4e00\"\n\"scale.yellow.7\" = \"#633c01\"\n\"scale.yellow.8\" = \"#4d2d00\"\n\"scale.yellow.9\" = \"#3b2300\"\n\"severe.emphasis\" = \"#b35900\"\n\"severe.fg\" = \"#b35900\"\n\"severe.muted\" = \"#f79939\"\n\"severe.subtle\" = \"#fff5e8\"\n\"sponsors.emphasis\" = \"#bf3989\"\n\"sponsors.fg\" = \"#bf3989\"\n\"sponsors.muted\" = \"#ff80c8\"\n\"sponsors.subtle\" = \"#ffeff7\"\n\"success.emphasis\" = \"#218bff\"\n\"success.fg\" = \"#0969da\"\n\"success.muted\" = \"#54aeff\"\n\"success.subtle\" = \"#ddf4ff\"\n"
  },
  {
    "path": "runtime/themes/github_light_high_contrast.toml",
    "content": "# Author : OwOSwordsman <owoswordsman@gmail.com>\n# An unofficial GitHub theme, generated using colors from: https://primer.style/primitives/colors\n# Credit goes to the original VSCode theme: https://github.com/primer/github-vscode-theme\n# Only the Light and Dark variants were specifically tested\n\ninherits = \"github_light\"\n\n[palette]\n\"accent.emphasis\" = \"#0349b4\"\n\"accent.fg\" = \"#0349b4\"\n\"accent.muted\" = \"#368cf9\"\n\"accent.subtle\" = \"#dff7ff\"\n\"attention.emphasis\" = \"#744500\"\n\"attention.fg\" = \"#744500\"\n\"attention.muted\" = \"#b58407\"\n\"attention.subtle\" = \"#fcf7be\"\n\"border.default\" = \"#20252c\"\n\"border.muted\" = \"#88929d\"\n\"border.subtle\" = \"#010409\"\n\"canvas.default\" = \"#ffffff\"\n\"canvas.inset\" = \"#ffffff\"\n\"canvas.overlay\" = \"#ffffff\"\n\"canvas.subtle\" = \"#e7ecf0\"\n\"closed.emphasis\" = \"#a0111f\"\n\"closed.fg\" = \"#a0111f\"\n\"closed.muted\" = \"#ee5a5d\"\n\"closed.subtle\" = \"#fff0ee\"\n\"danger.emphasis\" = \"#a0111f\"\n\"danger.fg\" = \"#a0111f\"\n\"danger.muted\" = \"#ee5a5d\"\n\"danger.subtle\" = \"#fff0ee\"\n\"done.emphasis\" = \"#622cbc\"\n\"done.fg\" = \"#622cbc\"\n\"done.muted\" = \"#a371f7\"\n\"done.subtle\" = \"#faf0fe\"\n\"fg.default\" = \"#0e1116\"\n\"fg.muted\" = \"#0e1116\"\n\"fg.onEmphasis\" = \"#ffffff\"\n\"fg.subtle\" = \"#66707b\"\n\"neutral.emphasis\" = \"#66707b\"\n\"neutral.emphasisPlus\" = \"#0e1116\"\n\"neutral.muted\" = \"#acb6c0\"\n\"neutral.subtle\" = \"#e7ecf0\"\n\"open.emphasis\" = \"#117f32\"\n\"open.fg\" = \"#055d20\"\n\"open.muted\" = \"#26a148\"\n\"open.subtle\" = \"#d2fedb\"\n\"scale.black\" = \"#010409\"\n\"scale.blue.0\" = \"#dff7ff\"\n\"scale.blue.1\" = \"#9cd7ff\"\n\"scale.blue.2\" = \"#67b3fd\"\n\"scale.blue.3\" = \"#368cf9\"\n\"scale.blue.4\" = \"#1168e3\"\n\"scale.blue.5\" = \"#0349b4\"\n\"scale.blue.6\" = \"#023b95\"\n\"scale.blue.7\" = \"#022f7a\"\n\"scale.blue.8\" = \"#032563\"\n\"scale.blue.9\" = \"#021a4a\"\n\"scale.coral.0\" = \"#fff0ed\"\n\"scale.coral.1\" = \"#ffc2b6\"\n\"scale.coral.2\" = \"#ff8f7e\"\n\"scale.coral.3\" = \"#ef5b48\"\n\"scale.coral.4\" = \"#cd3425\"\n\"scale.coral.5\" = \"#9f1710\"\n\"scale.coral.6\" = \"#870706\"\n\"scale.coral.7\" = \"#6f0107\"\n\"scale.coral.8\" = \"#5b0002\"\n\"scale.coral.9\" = \"#430200\"\n\"scale.gray.0\" = \"#ffffff\"\n\"scale.gray.1\" = \"#e7ecf0\"\n\"scale.gray.2\" = \"#ced5dc\"\n\"scale.gray.3\" = \"#acb6c0\"\n\"scale.gray.4\" = \"#88929d\"\n\"scale.gray.5\" = \"#66707b\"\n\"scale.gray.6\" = \"#4b535d\"\n\"scale.gray.7\" = \"#343b43\"\n\"scale.gray.8\" = \"#20252c\"\n\"scale.gray.9\" = \"#0e1116\"\n\"scale.green.0\" = \"#d2fedb\"\n\"scale.green.1\" = \"#82e596\"\n\"scale.green.2\" = \"#43c663\"\n\"scale.green.3\" = \"#26a148\"\n\"scale.green.4\" = \"#117f32\"\n\"scale.green.5\" = \"#055d20\"\n\"scale.green.6\" = \"#024c1a\"\n\"scale.green.7\" = \"#013d14\"\n\"scale.green.8\" = \"#003110\"\n\"scale.green.9\" = \"#00230b\"\n\"scale.orange.0\" = \"#fff2d5\"\n\"scale.orange.1\" = \"#ffc67b\"\n\"scale.orange.2\" = \"#f99636\"\n\"scale.orange.3\" = \"#dc6d1a\"\n\"scale.orange.4\" = \"#b45105\"\n\"scale.orange.5\" = \"#873800\"\n\"scale.orange.6\" = \"#702c00\"\n\"scale.orange.7\" = \"#5b2300\"\n\"scale.orange.8\" = \"#491b00\"\n\"scale.orange.9\" = \"#361200\"\n\"scale.pink.0\" = \"#feeff7\"\n\"scale.pink.1\" = \"#ffbde0\"\n\"scale.pink.2\" = \"#fc87ca\"\n\"scale.pink.3\" = \"#ed4baf\"\n\"scale.pink.4\" = \"#c9248e\"\n\"scale.pink.5\" = \"#971368\"\n\"scale.pink.6\" = \"#7d0c57\"\n\"scale.pink.7\" = \"#660847\"\n\"scale.pink.8\" = \"#53043a\"\n\"scale.pink.9\" = \"#3e022b\"\n\"scale.purple.0\" = \"#faf0fe\"\n\"scale.purple.1\" = \"#e0c5ff\"\n\"scale.purple.2\" = \"#c49bff\"\n\"scale.purple.3\" = \"#a371f7\"\n\"scale.purple.4\" = \"#844ae7\"\n\"scale.purple.5\" = \"#622cbc\"\n\"scale.purple.6\" = \"#512598\"\n\"scale.purple.7\" = \"#411d7b\"\n\"scale.purple.8\" = \"#341763\"\n\"scale.purple.9\" = \"#260f49\"\n\"scale.red.0\" = \"#fff0ee\"\n\"scale.red.1\" = \"#ffc1bc\"\n\"scale.red.2\" = \"#ff8e8a\"\n\"scale.red.3\" = \"#ee5a5d\"\n\"scale.red.4\" = \"#d5232c\"\n\"scale.red.5\" = \"#a0111f\"\n\"scale.red.6\" = \"#86061d\"\n\"scale.red.7\" = \"#6e011a\"\n\"scale.red.8\" = \"#5a0016\"\n\"scale.red.9\" = \"#430011\"\n\"scale.white\" = \"#ffffff\"\n\"scale.yellow.0\" = \"#fcf7be\"\n\"scale.yellow.1\" = \"#f0ce53\"\n\"scale.yellow.2\" = \"#d5a824\"\n\"scale.yellow.3\" = \"#b58407\"\n\"scale.yellow.4\" = \"#956400\"\n\"scale.yellow.5\" = \"#744500\"\n\"scale.yellow.6\" = \"#603700\"\n\"scale.yellow.7\" = \"#4e2c00\"\n\"scale.yellow.8\" = \"#3f2200\"\n\"scale.yellow.9\" = \"#2e1800\"\n\"severe.emphasis\" = \"#873800\"\n\"severe.fg\" = \"#873800\"\n\"severe.muted\" = \"#dc6d1a\"\n\"severe.subtle\" = \"#fff2d5\"\n\"sponsors.emphasis\" = \"#971368\"\n\"sponsors.fg\" = \"#971368\"\n\"sponsors.muted\" = \"#ed4baf\"\n\"sponsors.subtle\" = \"#feeff7\"\n\"success.emphasis\" = \"#055d20\"\n\"success.fg\" = \"#055d20\"\n\"success.muted\" = \"#26a148\"\n\"success.subtle\" = \"#d2fedb\"\n"
  },
  {
    "path": "runtime/themes/github_light_tritanopia.toml",
    "content": "# Author : OwOSwordsman <owoswordsman@gmail.com>\n# An unofficial GitHub theme, generated using colors from: https://primer.style/primitives/colors\n# Credit goes to the original VSCode theme: https://github.com/primer/github-vscode-theme\n# Only the Light and Dark variants were specifically tested\n\ninherits = \"github_light\"\n\n[palette]\n\"accent.emphasis\" = \"#0969da\"\n\"accent.fg\" = \"#0969da\"\n\"accent.muted\" = \"#54aeff\"\n\"accent.subtle\" = \"#ddf4ff\"\n\"attention.emphasis\" = \"#bf8700\"\n\"attention.fg\" = \"#9a6700\"\n\"attention.muted\" = \"#d4a72c\"\n\"attention.subtle\" = \"#fff8c5\"\n\"border.default\" = \"#d0d7de\"\n\"border.muted\" = \"#d8dee4\"\n\"border.subtle\" = \"#1b1f24\"\n\"canvas.default\" = \"#ffffff\"\n\"canvas.inset\" = \"#f6f8fa\"\n\"canvas.overlay\" = \"#ffffff\"\n\"canvas.subtle\" = \"#f6f8fa\"\n\"closed.emphasis\" = \"#6e7781\"\n\"closed.fg\" = \"#6e7781\"\n\"closed.muted\" = \"#afb8c1\"\n\"closed.subtle\" = \"#f6f8fa\"\n\"danger.emphasis\" = \"#cf222e\"\n\"danger.fg\" = \"#cf222e\"\n\"danger.muted\" = \"#ff8182\"\n\"danger.subtle\" = \"#ffebe9\"\n\"done.emphasis\" = \"#8250df\"\n\"done.fg\" = \"#8250df\"\n\"done.muted\" = \"#c297ff\"\n\"done.subtle\" = \"#fbefff\"\n\"fg.default\" = \"#24292f\"\n\"fg.muted\" = \"#57606a\"\n\"fg.onEmphasis\" = \"#ffffff\"\n\"fg.subtle\" = \"#6e7781\"\n\"neutral.emphasis\" = \"#6e7781\"\n\"neutral.emphasisPlus\" = \"#24292f\"\n\"neutral.muted\" = \"#afb8c1\"\n\"neutral.subtle\" = \"#eaeef2\"\n\"open.emphasis\" = \"#fa4549\"\n\"open.fg\" = \"#cf222e\"\n\"open.muted\" = \"#ff8182\"\n\"open.subtle\" = \"#ffebe9\"\n\"scale.black\" = \"#1b1f24\"\n\"scale.blue.0\" = \"#ddf4ff\"\n\"scale.blue.1\" = \"#b6e3ff\"\n\"scale.blue.2\" = \"#80ccff\"\n\"scale.blue.3\" = \"#54aeff\"\n\"scale.blue.4\" = \"#218bff\"\n\"scale.blue.5\" = \"#0969da\"\n\"scale.blue.6\" = \"#0550ae\"\n\"scale.blue.7\" = \"#033d8b\"\n\"scale.blue.8\" = \"#0a3069\"\n\"scale.blue.9\" = \"#002155\"\n\"scale.coral.0\" = \"#fff0eb\"\n\"scale.coral.1\" = \"#ffd6cc\"\n\"scale.coral.2\" = \"#ffb4a1\"\n\"scale.coral.3\" = \"#fd8c73\"\n\"scale.coral.4\" = \"#ec6547\"\n\"scale.coral.5\" = \"#c4432b\"\n\"scale.coral.6\" = \"#9e2f1c\"\n\"scale.coral.7\" = \"#801f0f\"\n\"scale.coral.8\" = \"#691105\"\n\"scale.coral.9\" = \"#510901\"\n\"scale.gray.0\" = \"#f6f8fa\"\n\"scale.gray.1\" = \"#eaeef2\"\n\"scale.gray.2\" = \"#d0d7de\"\n\"scale.gray.3\" = \"#afb8c1\"\n\"scale.gray.4\" = \"#8c959f\"\n\"scale.gray.5\" = \"#6e7781\"\n\"scale.gray.6\" = \"#57606a\"\n\"scale.gray.7\" = \"#424a53\"\n\"scale.gray.8\" = \"#32383f\"\n\"scale.gray.9\" = \"#24292f\"\n\"scale.green.0\" = \"#ddf4ff\"\n\"scale.green.1\" = \"#b6e3ff\"\n\"scale.green.2\" = \"#80ccff\"\n\"scale.green.3\" = \"#54aeff\"\n\"scale.green.4\" = \"#218bff\"\n\"scale.green.5\" = \"#0969da\"\n\"scale.green.6\" = \"#0550ae\"\n\"scale.green.7\" = \"#033d8b\"\n\"scale.green.8\" = \"#0a3069\"\n\"scale.green.9\" = \"#002155\"\n\"scale.orange.0\" = \"#ffebe9\"\n\"scale.orange.1\" = \"#ffcecb\"\n\"scale.orange.2\" = \"#ffaba8\"\n\"scale.orange.3\" = \"#ff8182\"\n\"scale.orange.4\" = \"#fa4549\"\n\"scale.orange.5\" = \"#cf222e\"\n\"scale.orange.6\" = \"#a40e26\"\n\"scale.orange.7\" = \"#82071e\"\n\"scale.orange.8\" = \"#660018\"\n\"scale.orange.9\" = \"#4c0014\"\n\"scale.pink.0\" = \"#ffeff7\"\n\"scale.pink.1\" = \"#ffd3eb\"\n\"scale.pink.2\" = \"#ffadda\"\n\"scale.pink.3\" = \"#ff80c8\"\n\"scale.pink.4\" = \"#e85aad\"\n\"scale.pink.5\" = \"#bf3989\"\n\"scale.pink.6\" = \"#99286e\"\n\"scale.pink.7\" = \"#772057\"\n\"scale.pink.8\" = \"#611347\"\n\"scale.pink.9\" = \"#4d0336\"\n\"scale.purple.0\" = \"#fbefff\"\n\"scale.purple.1\" = \"#ecd8ff\"\n\"scale.purple.2\" = \"#d8b9ff\"\n\"scale.purple.3\" = \"#c297ff\"\n\"scale.purple.4\" = \"#a475f9\"\n\"scale.purple.5\" = \"#8250df\"\n\"scale.purple.6\" = \"#6639ba\"\n\"scale.purple.7\" = \"#512a97\"\n\"scale.purple.8\" = \"#3e1f79\"\n\"scale.purple.9\" = \"#2e1461\"\n\"scale.red.0\" = \"#ffebe9\"\n\"scale.red.1\" = \"#ffcecb\"\n\"scale.red.2\" = \"#ffaba8\"\n\"scale.red.3\" = \"#ff8182\"\n\"scale.red.4\" = \"#fa4549\"\n\"scale.red.5\" = \"#cf222e\"\n\"scale.red.6\" = \"#a40e26\"\n\"scale.red.7\" = \"#82071e\"\n\"scale.red.8\" = \"#660018\"\n\"scale.red.9\" = \"#4c0014\"\n\"scale.white\" = \"#ffffff\"\n\"scale.yellow.0\" = \"#fff8c5\"\n\"scale.yellow.1\" = \"#fae17d\"\n\"scale.yellow.2\" = \"#eac54f\"\n\"scale.yellow.3\" = \"#d4a72c\"\n\"scale.yellow.4\" = \"#bf8700\"\n\"scale.yellow.5\" = \"#9a6700\"\n\"scale.yellow.6\" = \"#7d4e00\"\n\"scale.yellow.7\" = \"#633c01\"\n\"scale.yellow.8\" = \"#4d2d00\"\n\"scale.yellow.9\" = \"#3b2300\"\n\"severe.emphasis\" = \"#cf222e\"\n\"severe.fg\" = \"#cf222e\"\n\"severe.muted\" = \"#ff8182\"\n\"severe.subtle\" = \"#ffebe9\"\n\"sponsors.emphasis\" = \"#bf3989\"\n\"sponsors.fg\" = \"#bf3989\"\n\"sponsors.muted\" = \"#ff80c8\"\n\"sponsors.subtle\" = \"#ffeff7\"\n\"success.emphasis\" = \"#218bff\"\n\"success.fg\" = \"#0969da\"\n\"success.muted\" = \"#54aeff\"\n\"success.subtle\" = \"#ddf4ff\"\n"
  },
  {
    "path": "runtime/themes/gruber-darker.toml",
    "content": "# Author : Mehedi Hasan <mehedi.r137@gmail.com>\n# Based on : https://github.com/rexim/gruber-darker-theme\n\n\"attribute\" = \"fg0\"\n\"keyword\" = { fg = \"yellow0\", modifiers = [\"bold\"] }\n\"keyword.directive\" = \"quartz\"\n\"namespace\" = \"quartz\"\n\"punctuation\" = \"fg0\"\n\"punctuation.delimiter\" = \"fg0\"\n\"operator\" = \"fg0\"\n\"special\" = { fg = \"yellow0\", modifiers = [\"bold\"] }\n\"variable\" = \"fg0\"\n\"variable.builtin\" = {  fg = \"yellow0\", modifiers = [\"bold\"] }\n\"variable.parameter\" = \"fg0\"\n\"type\" = \"quartz\"\n\"type.builtin\" = \"yellow0\"\n\"constructor\" = { fg = \"quartz\" }\n\"function\" = \"niagara0\"\n\"function.builtin\" = \"yellow0\"\n\"tag\" = \"niagara0\"\n\"comment\" = { fg = \"brown0\" }\n\"constant.character\" = { fg = \"green0\" }\n\"constant.character.escape\" = { fg = \"yellow0\" }\n\"constant.builtin\" = { fg = \"yellow0\", modifiers = [\"bold\"] }\n\"string\" = \"green0\"\n\"constant.numeric\" = \"wisteria\"\n\"label\" = \"fg0\"\n\"module\" = \"aqua1\"\n\n\"diff.plus\" = \"green1\"\n\"diff.delta\" = \"orange1\"\n\"diff.minus\" = \"red0\"\n\n\"warning\" = { fg = \"orange1\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"red0\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"aqua1\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"blue0\", modifiers = [\"bold\"] }\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.linenr\" = { fg = \"bg4\" }\n\"ui.linenr.selected\" = { fg = \"yellow0\" }\n\"ui.cursorline\" = { bg = \"bg1\" }\n\n\"ui.statusline\" = { fg = \"fg0\", bg = \"bg1\" }\n\"ui.statusline.normal\" = { fg = \"bg1\", bg = \"yellow0\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"bg1\", bg = \"blue0\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"bg1\", bg = \"wisteria\", modifiers = [\"bold\"] }\n\"ui.statusline.inactive\" = { fg = \"fg3\", bg = \"bg1\" }\n\n\"ui.bufferline\" = { fg = \"fg3\", bg = \"bg6\" }\n\"ui.bufferline.active\" = { fg = \"fg0\", bg = \"bg7\" }\n\n\"ui.popup\" = { bg = \"bg6\" }\n\"ui.window\" = { fg = \"bg1\" }\n\"ui.help\" = { bg = \"bg1\", fg = \"fg0\" }\n\"ui.text\" = { fg = \"fg0\" }\n\"ui.text.directory\" = { fg = \"niagara0\", modifiers = [\"bold\"] }\n\"ui.text.focus\" = { bg = \"bg5\", modifiers = [\"bold\"] }\n\"ui.selection\" = { bg = \"bg2\" }\n\"ui.selection.primary\" = { bg = \"bg5\" }\n\"ui.cursor.primary\" = { bg = \"fg0\", fg = \"niagara1\" }\n\"ui.cursor.match\" = { bg = \"yellow1\" }\n\"ui.menu\" = { fg = \"fg0\", bg = \"bg6\" }\n\"ui.menu.selected\" = { fg = \"fg0\", bg = \"bg5\", modifiers = [\"bold\"] }\n\n\"ui.virtual.whitespace\" = \"bg8\"\n\"ui.virtual.indent-guide\" = \"bg8\"\n\"ui.virtual.ruler\" = { bg = \"bg1\" }\n\"ui.virtual.inlay-hint\" = { fg = \"bg7\" }\n\"ui.virtual.wrap\" = { fg = \"bg2\" }\n\"ui.virtual.jump-label\" = { fg = \"red3\", modifiers = [\"bold\"] }\n\n\"diagnostic.warning\" = { underline = { color = \"orange1\", style = \"dashed\" } }\n\"diagnostic.error\" = { underline = { color = \"red3\", style = \"dashed\" } }\n\"diagnostic.info\" = { underline = { color = \"aqua1\", style = \"dashed\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue0\", style = \"dashed\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"markup.heading\" = { fg = \"aqua1\", modifiers = [\"bold\"] }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"green1\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"red3\"\n\"markup.raw\" = { fg = \"fg0\", bg = \"bg8\", modifiers = [\"bold\"] }\n\n[palette]\nfg0 =      \"#e4e4ef\"\nfg1 =      \"#f4f4ff\"\nfg2 =      \"#f5f5f5\"\nfg3 =      \"#a89984\" \nbg0 =      \"#181818\"\nbg1 =      \"#282828\"\nbg2 =      \"#453d41\"\nbg4 =      \"#52494e\"\nbg5 =      \"#404040\"\nbg6 =      \"#232323\"\nbg7 =      \"#3f3f3f\"\nbg8 =      \"#2c2c2c\"\nred0 =     \"#f43841\"\nred1 =     \"#ff4f58\"\nred2 =     \"#2B0A0B\"\nred3 =     \"#fb4934\"\ngreen0 =   \"#73c936\"\ngreen1 =   \"#b8bb26\"\nyellow0 =  \"#ffdd33\"\nyellow1 =  \"#655814\"\nblue0 =    \"#5292c8\"\norange0 =  \"#d65d0e\"\norange1 =  \"#fe8019\"\nbrown0 =   \"#cc8c3c\"\nquartz =   \"#95a99f\"\nniagara0 = \"#96a6c8\"\nniagara1 = \"#303540\"\nwisteria = \"#9e95c7\"\naqua1 =    \"#8ec07c\"\n\n"
  },
  {
    "path": "runtime/themes/gruvbox-material.toml",
    "content": "# Gruvbox Material for Helix\n# Original Author: @sainnhe (https://github.com/sainnhe/gruvbox-material)\n# Ported by: @satoqz\n# License: MIT\n\ninherits = \"gruvbox_material_dark_medium\"\n"
  },
  {
    "path": "runtime/themes/gruvbox.toml",
    "content": "# Author : Jakub Bartodziej <kubabartodziej@gmail.com>\n# The theme uses the gruvbox dark palette with standard contrast: github.com/morhetz/gruvbox\n\n\"annotation\" = { fg = \"fg1\" }\n\n\"attribute\" = { fg = \"aqua1\", modifiers = [\"italic\"] }\n\n\"comment\" = { fg = \"gray\", modifiers = [\"italic\"] }\n\n\"constant\" = { fg = \"purple1\" }\n\"constant.character\" = { fg = \"aqua1\" }\n\"constant.character.escape\" = { fg = \"orange1\" }\n\"constant.macro\" = { fg = \"aqua1\" }\n\"constructor\" = { fg = \"purple1\" }\n\n\"definition\" = { underline = { color = \"aqua1\" } }\n\n\"diagnostic\" = { underline = { color = \"orange1\", style = \"curl\" } }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"diagnostic.error\" = { underline = { color = \"red1\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue1\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"aqua1\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow1\", style = \"curl\" } }\n# \"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }  # do not remove this for future resolving\n\n\"error\" = { fg = \"red1\" }\n\"hint\" = { fg = \"blue1\" }\n\"info\" = { fg = \"aqua1\" }\n\"warning\" = { fg = \"yellow1\" }\n\n\"diff.delta\" = { fg = \"yellow1\" }\n\"diff.minus\" = { fg = \"red1\" }\n\"diff.plus\" = { fg = \"green1\" }\n\n\"function\" = { fg = \"green1\" }\n\"function.builtin\" = { fg = \"yellow1\" }\n\"function.macro\" = { fg = \"blue1\" }\n\n\"keyword\" = { fg = \"red1\" }\n\"keyword.control.import\" = { fg = \"aqua1\" }\n\n\"label\" = { fg = \"red1\" }\n\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.heading\" = \"aqua1\"\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link.text\" = \"red1\"\n\"markup.link.url\" = { fg = \"green1\", modifiers = [\"underlined\"] }\n\"markup.raw\" = \"red1\"\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\n\"module\" = { fg = \"aqua1\" }\n\n\"namespace\" = { fg = \"fg1\" }\n\n\"operator\" = { fg = \"purple1\" }\n\n\"punctuation\" = { fg = \"orange1\" }\n\n\"special\" = { fg = \"purple0\" }\n\n\"string\" = { fg = \"green1\" }\n\"string.regexp\" = { fg = \"orange1\" }\n\"string.special\" = { fg = \"orange1\" }\n\"string.symbol\" = { fg = \"yellow1\" }\n\n\"tag\" = { fg = \"aqua1\" }\n\n\"type\" = { fg = \"yellow1\" }\n\"type.enum.variant\" = { modifiers = [\"italic\"] }\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.bufferline\" = { fg = \"fg1\", bg = \"bg1\" }\n\"ui.bufferline.active\" = { fg = \"bg0\", bg = \"yellow0\" }\n\"ui.bufferline.background\" = { bg = \"bg2\" }\n\n\"ui.cursor\" = { fg = \"bg1\", bg = \"bg2\" }\n\"ui.cursor.insert\" = { fg = \"bg1\", bg = \"blue0\" }\n\"ui.cursor.normal\" = { fg = \"bg1\", bg = \"gray\" }\n\"ui.cursor.select\" = { fg = \"bg1\", bg = \"orange0\" }\n\"ui.cursor.match\" = { fg = \"fg3\", bg = \"bg3\" }\n\n\"ui.cursor.primary\" = { bg = \"fg3\", fg = \"bg1\" }\n\"ui.cursor.primary.insert\" = { fg = \"bg1\", bg = \"blue1\" }\n\"ui.cursor.primary.normal\" = { fg = \"bg1\", bg = \"fg3\" }\n\"ui.cursor.primary.select\" = { fg = \"bg1\", bg = \"orange1\" }\n\n\"ui.cursorline\" = { bg = \"bg0_s\" }\n\"ui.cursorline.primary\" = { bg = \"bg1\" }\n\n\"ui.help\" = { bg = \"bg1\", fg = \"fg1\" }\n\"ui.linenr\" = { fg = \"bg3\" }\n\"ui.linenr.selected\" = { fg = \"yellow1\" }\n\"ui.menu\" = { fg = \"fg1\", bg = \"bg2\" }\n\"ui.menu.selected\" = { fg = \"green1\", bg = \"bg1\", modifiers = [\"bold\"] }\n\"ui.popup\" = { bg = \"bg1\" }\n\"ui.picker.header.column\" = { underline.style = \"line\" }\n\"ui.picker.header.column.active\" = { modifiers = [\"bold\"], underline.style = \"line\" }\n\"ui.selection\" = { bg = \"bg2\" }\n\"ui.selection.primary\" = { bg = \"bg3\" }\n\n\"ui.statusline\" = { fg = \"fg1\", bg = \"bg2\" }\n\"ui.statusline.inactive\" = { fg = \"fg4\", bg = \"bg2\" }\n\"ui.statusline.insert\" = { fg = \"bg1\", bg = \"blue1\", modifiers = [\"bold\"] }\n\"ui.statusline.normal\" = { fg = \"bg1\", bg = \"fg3\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"bg1\", bg = \"orange1\", modifiers = [\"bold\"] }\n\n\"ui.text\" = { fg = \"fg1\" }\n\"ui.text.focus\" = { fg = \"green1\", bg=\"bg1\" }\n\"ui.text.directory\" = { fg = \"blue1\" }\n\"ui.virtual.inlay-hint\" = { fg = \"gray\" }\n\"ui.virtual.jump-label\" = { fg = \"purple0\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"bg1\" }\n\"ui.virtual.whitespace\" = \"bg2\"\n\"ui.virtual.wrap\" = { fg = \"bg2\" }\n\"ui.window\" = { bg = \"bg1\" }\n\n\"variable\" = { fg = \"fg1\" }\n\"variable.builtin\" = { fg = \"orange1\", modifiers = [\"italic\"] }\n\"variable.other.member\" = { fg = \"blue1\" }\n\"variable.parameter\" = { fg = \"blue1\", modifiers = [\"italic\"] }\n\n\n[palette]\nbg0 = \"#282828\"   # main background\nbg0_s = \"#32302f\"\nbg1 = \"#3c3836\"\nbg2 = \"#504945\"\nbg3 = \"#665c54\"\nbg4 = \"#7c6f64\"\n\nfg0 = \"#fbf1c7\"\nfg1 = \"#ebdbb2\" # main foreground\nfg2 = \"#d5c4a1\"\nfg3 = \"#bdae93\"\nfg4 = \"#a89984\"\n\ngray = \"#928374\"\n\nred0 = \"#cc241d\"    # neutral\nred1 = \"#fb4934\"    # bright\ngreen0 = \"#98971a\"\ngreen1 = \"#b8bb26\"\nyellow0 = \"#d79921\"\nyellow1 = \"#fabd2f\"\nblue0 = \"#458588\"\nblue1 = \"#83a598\"\npurple0 = \"#b16286\"\npurple1 = \"#d3869b\"\naqua0 = \"#689d6a\"\naqua1 = \"#8ec07c\"\norange0 = \"#d65d0e\"\norange1 = \"#fe8019\"\n"
  },
  {
    "path": "runtime/themes/gruvbox_dark_hard.toml",
    "content": "# Author : Sven-Hendrik Haase <svenstaro@gmail.com>\n# Author : Jakub Bartodziej <kubabartodziej@gmail.com>\n# The theme uses the gruvbox dark palette with hard contrast: github.com/morhetz/gruvbox\n\ninherits = \"gruvbox\"\n\n\"ui.cursor.primary\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { bg = \"bg2\" }\n\n\"diagnostic.error\" = { underline = { color = \"red0\", style = \"curl\"} }\n\n[palette]\nbg0 = \"#1d2021\" # main background\n"
  },
  {
    "path": "runtime/themes/gruvbox_dark_soft.toml",
    "content": "# Author : broke <broke@in-fucking.space>\n# The theme uses the gruvbox dark palette with soft contrast: github.com/morhetz/gruvbox\n\ninherits = \"gruvbox\"\n\n[palette]\nbg0 = \"#32302f\" # main background\n"
  },
  {
    "path": "runtime/themes/gruvbox_light.toml",
    "content": "# Author : Rohan Jain <crodjer@pm.me> \n# Author : Jakub Bartodziej <kubabartodziej@gmail.com>\n# The theme uses the gruvbox light palette with standard contrast: github.com/morhetz/gruvbox\n\ninherits = \"gruvbox\"\n\n\"ui.cursor.primary\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { bg = \"bg2\" }\n\"ui.cursorline\" = { bg = \"bg1\" }\n\n[palette]\nbg0 = \"#fbf1c7\" # main background\nbg1 = \"#ebdbb2\"\nbg2 = \"#d5c4a1\"\nbg3 = \"#bdae93\"\nbg4 = \"#a89984\"\n\nfg0 = \"#282828\" # main foreground\nfg1 = \"#3c3836\"\nfg2 = \"#504945\"\nfg3 = \"#665c54\"\nfg4 = \"#7c6f64\" # gray0\n\ngray0 = \"#7c6f64\"\n\nred1 = \"#9d0006\" # bright\ngreen1 = \"#79740e\"\nyellow1 = \"#b57614\"\nblue1 = \"#076678\"\npurple1 = \"#8f3f71\"\naqua1 = \"#427b58\"\norange1 = \"#af3a03\"\n"
  },
  {
    "path": "runtime/themes/gruvbox_light_hard.toml",
    "content": "# Author : Twinkle <saintwinkle@gmail.com>\n# The theme uses the gruvbox light palette with hard contrast: github.com/morhetz/gruvbox\n\ninherits = \"gruvbox_light\"\n\n[palette]\nbg0 = \"#f9f5d7\" # main background\n"
  },
  {
    "path": "runtime/themes/gruvbox_light_soft.toml",
    "content": "# Author : Twinkle <saintwinkle@gmail.com>\n# The theme uses the gruvbox light palette with soft contrast: github.com/morhetz/gruvbox\n\ninherits = \"gruvbox_light\"\n\n[palette]\nbg0 = \"#f2e5bc\" # main background\n"
  },
  {
    "path": "runtime/themes/gruvbox_material_dark_hard.toml",
    "content": "# Gruvbox Material Dark Hard for Helix\n# Original Author: @sainnhe (https://github.com/sainnhe/gruvbox-material)\n# Base theme ported by: @satoqz\n# Palette ported by: @ivan-shymkiv\n# License: MIT\n\ninherits = \"gruvbox_material_dark_medium\"\n\n[palette]\nbg0 = \"#1d2021\"\nbg1 = \"#282828\"\nbg2 = \"#3c3836\"\nbg3 = \"#504945\"\n"
  },
  {
    "path": "runtime/themes/gruvbox_material_dark_medium.toml",
    "content": "# Gruvbox Material Dark Medium for Helix\n# Original Author: @sainnhe (https://github.com/sainnhe/gruvbox-material)\n# Ported by: @satoqz\n# License: MIT\n\n\"attribute\" = \"green\"\n\"comment\" = { fg = \"grey1\", modifiers = [\"italic\"] }\n\"constant\" = \"fg0\"\n\"constant.builtin\" = \"purple\"\n\"constant.character.escape\" = \"green\"\n\"constant.numeric\" = \"purple\"\n\"constructor\" = \"green\"\n\"function\" = \"green\"\n\"keyword\" = \"red\"\n\"keyword.directive\" = \"purple\"\n\"keyword.operator\" = \"orange\"\n\"label\" = \"red\"\n\"namespace\" = \"yellow\"\n\"operator\" = \"orange\"\n\"punctuation\" = \"grey1\"\n\"punctuation.bracket\" = \"fg0\"\n\"punctuation.delimiter\" = \"grey1\"\n\"punctuation.special\" = \"blue\"\n\"special\" = \"green\"\n\"string\" = \"aqua\"\n\"string.regexp\" = \"green\"\n\"string.special.path\" = \"yellow\"\n\"string.special.symbol\" = \"fg0\"\n\"string.special.url\" = { fg = \"fg0\", modifiers = [\"underlined\"] }\n\"tag\" = \"orange\"\n\"type\" = \"yellow\"\n\"type.enum.variant\" = \"purple\"\n\"variable\" = \"fg0\"\n\"variable.builtin\" = \"purple\"\n\"variable.other.member\" = \"blue\"\n\"variable.parameter\" = \"fg0\"\n\n\"markup.heading.1\" = \"red\"\n\"markup.heading.2\" = \"orange\"\n\"markup.heading.3\" = \"yellow\"\n\"markup.heading.4\" = \"green\"\n\"markup.heading.5\" = \"blue\"\n\"markup.heading.6\" = \"purple\"\n\n\"markup.bold\" = { fg = \"fg0\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"fg0\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { fg = \"fg0\", modifiers = [\"crossed_out\"] }\n\n\"markup.link.label\" = \"blue\"\n\"markup.link.text\" = \"yellow\"\n\"markup.link.url\" = { fg = \"blue\", modifiers = [\"underlined\"] }\n\"markup.list\" = \"blue\"\n\"markup.list.checked\" = \"green\"\n\"markup.list.unchecked\" = \"grey1\"\n\"markup.quote\" = \"grey1\"\n\"markup.raw\" = \"green\"\n\n\"diff.delta\" = \"blue\"\n\"diff.minus\" = \"red\"\n\"diff.plus\" = \"green\"\n\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"green\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\nerror = \"red\"\nhint = \"green\"\ninfo = \"blue\"\nwarning = \"yellow\"\n\n\"ui.background\" = { fg = \"fg0\", bg = \"bg0\" }\n\"ui.bufferline\" = { fg = \"fg1\", bg = \"bg4\" }\n\"ui.bufferline.active\" = { fg = \"bg0\", bg = \"grey2\" }\n\"ui.bufferline.background\" = { bg = \"bg1\" }\n\"ui.cursor\" = { fg = \"bg0\", bg = \"grey1\" }\n\"ui.cursor.primary\" = { fg = \"bg0\", bg = \"fg0\" }\n\"ui.cursor.match\" = { bg = \"bg2\" }\n\"ui.cursorline.primary\" = { bg = \"bg1\" }\n\"ui.help\" = { fg = \"grey1\", bg = \"bg0\" }\n\"ui.highlight\" = { bg = \"bg2\" }\n\"ui.linenr\" = \"bg3\"\n\"ui.linenr.selected\" = \"grey1\"\n\"ui.menu\" = { fg = \"fg1\", bg = \"bg2\" }\n\"ui.menu.scroll\" = { fg = \"grey0\", bg = \"bg1\" }\n\"ui.menu.selected\" = { fg = \"bg2\", bg = \"grey2\" }\n\"ui.popup\" = { fg = \"fg1\", bg = \"bg2\" }\n\"ui.popup.info\" = { \"fg\" = \"grey1\", bg = \"bg0\" }\n\"ui.selection\" = { bg = \"bg2\" }\n\"ui.statusline\" = { fg = \"fg1\", bg = \"bg1\" }\n\"ui.statusline.inactive\" = { fg = \"grey1\", bg = \"bg1\" }\n\"ui.statusline.insert\" = { fg = \"bg0\", bg = \"green\" }\n\"ui.statusline.normal\" = { fg = \"bg0\", bg = \"grey2\" }\n\"ui.statusline.select\" = { fg = \"bg0\", bg = \"red\" }\n\"ui.text\" = \"fg0\"\n\"ui.text.directory\" = { fg = \"blue\" }\n\"ui.text.focus\" = { bg = \"bg2\" }\n\"ui.text.inactive\" = { fg = \"grey1\" }\n\"ui.text.info\" = \"grey1\"\n\"ui.virtual\" = \"grey0\"\n\"ui.virtual.indent-guide\" = \"bg3\"\n\"ui.virtual.inlay-hint\" = \"grey0\"\n\"ui.virtual.jump-label\" = \"grey2\"\n\"ui.virtual.ruler\" = { bg = \"bg1\" }\n\"ui.window\" = { fg = \"bg3\" }\n\n[palette]\nfg0 = \"#d4be98\"\nfg1 = \"#ddc7a1\"\n\nbg0 = \"#282828\"\nbg1 = \"#32302f\"\nbg2 = \"#45403d\"\nbg3 = \"#5a524c\"\nbg4 = \"#504945\"\n\ngrey0 = \"#7c6f64\"\ngrey1 = \"#928374\"\ngrey2 = \"#a89984\"\n\naqua = \"#89b482\"\nblue = \"#7daea3\"\ngreen = \"#a9b665\"\norange = \"#e78a4e\"\npurple = \"#d3869b\"\nred = \"#ea6962\"\nyellow = \"#d8a657\"\n"
  },
  {
    "path": "runtime/themes/gruvbox_material_dark_soft.toml",
    "content": "# Gruvbox Material Dark Soft for Helix\n# Original Author: @sainnhe (https://github.com/sainnhe/gruvbox-material)\n# Base theme ported by: @satoqz\n# Palette ported by: @ivan-shymkiv\n# License: MIT\n\ninherits = \"gruvbox_material_dark_medium\"\n\n[palette]\nbg0 = \"#32302f\"\nbg1 = \"#3c3836\"\nbg2 = \"#504945\"\nbg3 = \"#665c54\"\nbg4 = \"#5b534d\"\n"
  },
  {
    "path": "runtime/themes/gruvbox_material_light_hard.toml",
    "content": "# Gruvbox Material Light Hard for Helix\n# Original Author: @sainnhe (https://github.com/sainnhe/gruvbox-material)\n# Base theme ported by: @satoqz\n# Palette ported by: @ivan-shymkiv\n# License: MIT\n\ninherits = \"gruvbox_material_light_medium\"\n\n[palette]\nbg0 = \"#f9f5d7\"\nbg1 = \"#f5edca\"\nbg2 = \"#f2e5bc\"\nbg3 = \"#ebdbb2\"\nbg4 = \"#eee0b7\"\n"
  },
  {
    "path": "runtime/themes/gruvbox_material_light_medium.toml",
    "content": "# Gruvbox Material Light Medium for Helix\n# Original Author: @sainnhe (https://github.com/sainnhe/gruvbox-material)\n# Base theme ported by: @satoqz\n# Palette ported by: @ivan-shymkiv\n# License: MIT\n\n\"attribute\" = \"green\"\n\"comment\" = { fg = \"grey1\", modifiers = [\"italic\"] }\n\"constant\" = \"fg0\"\n\"constant.builtin\" = \"purple\"\n\"constant.character.escape\" = \"green\"\n\"constant.numeric\" = \"purple\"\n\"constructor\" = \"green\"\n\"function\" = \"green\"\n\"keyword\" = \"red\"\n\"keyword.directive\" = \"purple\"\n\"keyword.operator\" = \"orange\"\n\"label\" = \"red\"\n\"namespace\" = \"yellow\"\n\"operator\" = \"orange\"\n\"punctuation\" = \"grey1\"\n\"punctuation.bracket\" = \"fg0\"\n\"punctuation.delimiter\" = \"grey1\"\n\"punctuation.special\" = \"blue\"\n\"special\" = \"green\"\n\"string\" = \"aqua\"\n\"string.regexp\" = \"green\"\n\"string.special.path\" = \"yellow\"\n\"string.special.symbol\" = \"fg0\"\n\"string.special.url\" = { fg = \"fg0\", modifiers = [\"underlined\"] }\n\"tag\" = \"orange\"\n\"type\" = \"yellow\"\n\"type.enum.variant\" = \"purple\"\n\"variable\" = \"fg0\"\n\"variable.builtin\" = \"purple\"\n\"variable.other.member\" = \"blue\"\n\"variable.parameter\" = \"fg0\"\n\n\"markup.heading.1\" = \"red\"\n\"markup.heading.2\" = \"orange\"\n\"markup.heading.3\" = \"yellow\"\n\"markup.heading.4\" = \"green\"\n\"markup.heading.5\" = \"blue\"\n\"markup.heading.6\" = \"purple\"\n\n\"markup.bold\" = { fg = \"fg0\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"fg0\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { fg = \"fg0\", modifiers = [\"crossed_out\"] }\n\n\"markup.link.label\" = \"blue\"\n\"markup.link.text\" = \"yellow\"\n\"markup.link.url\" = { fg = \"blue\", modifiers = [\"underlined\"] }\n\"markup.list\" = \"blue\"\n\"markup.list.checked\" = \"green\"\n\"markup.list.unchecked\" = \"grey1\"\n\"markup.quote\" = \"grey1\"\n\"markup.raw\" = \"green\"\n\n\"diff.delta\" = \"blue\"\n\"diff.minus\" = \"red\"\n\"diff.plus\" = \"green\"\n\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"green\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\nerror = \"red\"\nhint = \"green\"\ninfo = \"blue\"\nwarning = \"yellow\"\n\n\"ui.background\" = { fg = \"fg0\", bg = \"bg0\" }\n\"ui.bufferline\" = { fg = \"fg1\", bg = \"bg4\" }\n\"ui.bufferline.active\" = { fg = \"bg0\", bg = \"grey2\" }\n\"ui.bufferline.background\" = { bg = \"bg1\" }\n\"ui.cursor\" = { fg = \"bg0\", bg = \"grey1\" }\n\"ui.cursor.primary\" = { fg = \"bg0\", bg = \"fg0\" }\n\"ui.cursor.match\" = { bg = \"bg2\" }\n\"ui.cursorline.primary\" = { bg = \"bg1\" }\n\"ui.help\" = { fg = \"grey1\", bg = \"bg0\" }\n\"ui.highlight\" = { bg = \"bg2\" }\n\"ui.linenr\" = \"bg3\"\n\"ui.linenr.selected\" = \"grey1\"\n\"ui.menu\" = { fg = \"fg1\", bg = \"bg2\" }\n\"ui.menu.scroll\" = { fg = \"grey0\", bg = \"bg1\" }\n\"ui.menu.selected\" = { fg = \"bg2\", bg = \"grey2\" }\n\"ui.popup\" = { fg = \"fg1\", bg = \"bg2\" }\n\"ui.popup.info\" = { \"fg\" = \"grey1\", bg = \"bg0\" }\n\"ui.selection\" = { bg = \"bg2\" }\n\"ui.statusline\" = { fg = \"fg1\", bg = \"bg1\" }\n\"ui.statusline.inactive\" = { fg = \"grey1\", bg = \"bg1\" }\n\"ui.statusline.insert\" = { fg = \"bg0\", bg = \"green\" }\n\"ui.statusline.normal\" = { fg = \"bg0\", bg = \"grey2\" }\n\"ui.statusline.select\" = { fg = \"bg0\", bg = \"red\" }\n\"ui.text\" = \"fg0\"\n\"ui.text.directory\" = { fg = \"blue\" }\n\"ui.text.focus\" = { bg = \"bg2\" }\n\"ui.text.inactive\" = { fg = \"grey1\" }\n\"ui.text.info\" = \"grey1\"\n\"ui.virtual\" = \"grey0\"\n\"ui.virtual.indent-guide\" = \"bg3\"\n\"ui.virtual.inlay-hint\" = \"grey0\"\n\"ui.virtual.jump-label\" = \"grey2\"\n\"ui.virtual.ruler\" = { bg = \"bg1\" }\n\"ui.window\" = { fg = \"bg3\" }\n\n[palette]\nfg0 = \"#654735\"\nfg1 = \"#4f3829\"\n\nbg0 = \"#fbf1c7\"\nbg1 = \"#f4e8be\"\nbg2 = \"#eee0b7\"\nbg3 = \"#ddccab\"\nbg4 = \"#e5d5ad\"\n\ngrey0 = \"#a89984\"\ngrey1 = \"#928374\"\ngrey2 = \"#7c6f64\"\n\naqua = \"#4c7a5d\"\nblue = \"#45707a\"\ngreen = \"#6c782e\"\norange = \"#c35e0a\"\npurple = \"#945e80\"\nred = \"#c14a4a\"\nyellow = \"#b47109\"\n"
  },
  {
    "path": "runtime/themes/gruvbox_material_light_soft.toml",
    "content": "# Gruvbox Material Light Soft for Helix\n# Original Author: @sainnhe (https://github.com/sainnhe/gruvbox-material)\n# Base theme ported by: @satoqz\n# Palette ported by: @ivan-shymkiv\n# License: MIT\n\ninherits = \"gruvbox_material_light_medium\"\n\n[palette]\nbg0 = \"#f2e5bc\"\nbg1 = \"#eddeb5\"\nbg2 = \"#e6d5ae\"\nbg3 = \"#d5c4a1\"\nbg4 = \"#dac9a5\"\n"
  },
  {
    "path": "runtime/themes/hazyland.toml",
    "content": "# Hazyland theme for Helix editor.\n# Heavily inspired by Neovim's default dark color scheme created by echasnovski: https://github.com/neovim/neovim/pull/26334 and\n# Kim Nørgaard's Neovim dark (accented) theme for Zed: https://github.com/KimNorgaard/zed-neovim-default\n\nattribute = \"text\"\nkeyword = { fg = \"text\", modifiers = [\"bold\"] }\n\"keyword.directive\" = { fg = \"text\", modifiers = [\"bold\"] }\nnamespace = \"text\"\npunctuation = \"text2\"\n\"punctuation.delimiter\" = \"text2\"\noperator = \"text\"\nspecial = \"primary\"\n\"variable.other.member\" = \"third\"\nvariable = \"text\"\n\"variable.parameter\" = { fg = \"text\" }\n\"variable.builtin\" = \"primary\"\ntype = \"text\"\n\"type.builtin\" = \"primary\"\nconstructor = \"fourth\"\nfunction = \"primary\"\n\"function.macro\" = \"text\"\n\"function.builtin\" = \"primary\"\ntag = \"primary\"\ncomment = \"comment\"\nconstant = \"text\"\n\"constant.builtin\" = \"text\"\nstring = \"second\"\n\"constant.numeric\" = \"text\"\n\"constant.character.escape\" = \"primary\"\nlabel = { fg = \"text\", modifiers = [\"bold\"] }\ntabstop = { modifiers = [\"italic\"], bg = \"panel\"}\n\n\"markup.heading\" = \"text\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"primary\", modifiers = [\"italic\"] }\n\"markup.link.text\" = \"primary\"\n\"markup.raw\" = \"primary\"\n\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"yellow\"\n\n\"ui.background\" = { bg = \"background\" }\n\"ui.background.separator\" = { fg = \"panel\" }\n\"ui.linenr\" = { fg = \"frame\" }\n\"ui.linenr.selected\" = { fg = \"text\" }\n\n\"ui.statusline\" = { fg = \"text\", bg = \"panel\" }\n\"ui.statusline.inactive\" = { fg = \"frame\", bg = \"panel\" }\n\"ui.statusline.normal\" = { bg = \"primary\", fg = \"panel\" }\n\"ui.statusline.insert\" = { bg = \"second\", fg = \"panel\" }\n\"ui.statusline.select\" = { bg = \"third\", fg = \"panel\" }\n\n\"ui.popup\" = { bg = \"panel\" }\n\"ui.window\" = { fg = \"panel\" }\n\"ui.help\" = { bg = \"panel\", fg = \"text\" }\n\"ui.text\" = { fg = \"text\" }\n\"ui.text.focus\" = { fg = \"text\" }\n\"ui.text.inactive\" = \"comment\"\n\"ui.text.directory\" = { fg = \"third\" }\n\"ui.virtual\" = { fg = \"frame\" }\n\"ui.virtual.ruler\" = { bg = \"panel\" }\n\"ui.virtual.jump-label\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\n\"ui.virtual.indent-guide\" = { fg = \"frame\" }\n\n\"ui.selection\" = { bg = \"selection\" }\n\"ui.selection.primary\" = { bg = \"selection\" }\n\"ui.cursor.select\" = { bg = \"primary\" }\n\"ui.cursor.insert\" = { bg = \"text\" }\n\"ui.cursor.primary.select\" = { bg = \"primary\" }\n\"ui.cursor.primary.insert\" = { bg = \"text\" }\n\"ui.cursor.match\" = { fg = \"background\", bg = \"frame\" }\n\"ui.cursor\" = { modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { bg = \"panel\" }\n\"ui.highlight\" = { bg = \"panel\" }\n\"ui.highlight.frameline\" = { bg = \"frame\" }\n\"ui.debug\" = { fg = \"frame\" }\n\"ui.debug.breakpoint\" = { fg = \"yellow\" }\n\"ui.menu\" = { fg = \"text\", bg = \"panel\" }\n\"ui.menu.selected\" = { fg = \"background\", bg = \"text\" }\n\"ui.menu.scroll\" = { fg = \"text\", bg = \"panel\" }\n\n\"diagnostic.hint\" = { underline = { color = \"comment\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nwarning = \"yellow\"\nerror = \"red\"\ninfo = \"blue\"\nhint = \"comment\"\n\n[palette]\nbackground = \"#171219\"\nprimary   = \"#ff8fc4\"\nsecond   = \"#f9bbff\"\nthird    = \"#b4b7f2\"\nfourth = \"#96ccff\"\nfifth = \"#b2ffe3\"\nselection = \"#0D2847\"\n\ntext   = \"#eee4ff\"\ntext2 = \"#cbbcd3\"\ncomment = \"#5d4869\"\npanel = \"#26202c\"\nframe = \"#6a5f78\"\n\ngreen = \"#8cfba2\"\nyellow    = \"#fbe88c\"\nred = \"#fb9b8c\"\nblue = \"#8cc9fb\"\n"
  },
  {
    "path": "runtime/themes/heisenberg.toml",
    "content": "# Author: IrishMaestro <github.com/irishmaestro>\n\n# Syntax highlighting\n\"type\" = { fg = \"crystal_blue\" }\n\"type.builtin\" = { fg = \"crystal_blue\" }\n\"constructor\" = { fg = \"barium_green\" }\n\"constant\" = { fg = \"hazmat_yellow\" }\n\"string\" = { fg = \"crystal_blue\" }\n\"string.regexp\" = { fg = \"orange\" }\n\"string.special\" = { fg = \"vapor_yellow\" }\n\"comment\" = { fg = \"teddy_bear_pink\", modifiers = [\"slow_blink\", \"italic\"] }\n\"variable\" = { fg = \"element_green\" }\n\"variable.parameter\" = { fg = \"hazmat_yellow\" }\n\"label\" = { fg = \"vapor_yellow\" }\n\"punctuation\" = { fg = \"barium_green\" }\n\"keyword\" = { fg = \"barium_green\" }\n\"keyword.control\" = { fg = \"barium_green\" }\n\"keyword.directive\" = { fg = \"teddy_bear_pink\" }\n\"operator\" = { fg = \"hazmat_yellow\" }\n\"function\" = { fg = \"cash_green\", modifiers = [\"bold\"] }\n\"tag\" = { fg = \"crystal_blue\" }\n\"namespace\" = { fg = \"hazmat_yellow\" }\n\"markup.heading\" = { fg = \"hazmat_yellow\" }\n\"markup.list\" = { fg = \"vapor_yellow\" }\n\"markup.raw.block\" = { bg = \"background\", fg = \"orange\" }\n\"markup.link.url\" = { fg = \"crystal_blue\" }\n\"markup.link.text\" = { fg = \"vapor_yellow\" }\n\"markup.link.label\" = { fg = \"barium_green\" }\n\"markup.quote\" = { fg = \"vapor_yellow\" }\n\"diff.plus\" = { fg = \"cash_green\" }\n\"diff.minus\" = { fg = \"chili_powder_red\" }\n\"diff.delta\" = { fg = \"orange\" }\n\n# Interface\n\"ui.background\" = { bg = \"background\" }\n\"ui.cursor\" = { bg = \"crystal_blue\", fg = \"background\" }\n\"ui.cursor.match\" = { fg = \"hazmat_yellow\" }\n\"ui.linenr\" = { fg = \"crystal_blue\" }\n\"ui.linenr.selected\" = { fg = \"barium_green\" }\n\"ui.statusline\" = { fg = \"crystal_blue\", bg = \"black\" }\n\"ui.statusline.normal\" = { fg = \"crystal_blue\", bg = \"black\" }\n\"ui.statusline.insert\" = { fg = \"barium_green\", bg = \"black\"} \n\"ui.statusline.select\" = { fg = \"hazmat_yellow\", bg = \"black\" }\n\"ui.cursorline.primary\" = { bg = \"#041B0E\" }\n\"ui.popup\" = { fg = \"crystal_blue\", bg = \"background\" }\n\"ui.window\" = { fg = \"barium_green\" }\n\"ui.help\" = { fg = \"crystal_blue\", bg = \"background\"}\n\"ui.text\" = { fg = \"crystal_blue\" }\n\"ui.text.focus\" = { bg = \"background\", fg = \"barium_green\" }\n\"ui.text.info\" = { fg = \"crystal_blue\" }\n\"ui.virtual.whitespace\" = { fg = \"#08341B\" }\n\"ui.virtual.ruler\" = { bg = \"#041B0E\" }\n\"ui.virtual.indent-guide\" = { fg = \"#08341B\" }\n\"ui.menu\" = { fg = \"crystal_blue\", bg = \"background\" }\n\"ui.menu.selected\" = { bg = \"hazmat_yellow\", fg = \"background\" }\n\"ui.selection\" = { bg = \"#1B0334\" }\n\"ui.selection.primary\" = { bg = \"desert_maroon\" }\n\"warning\" = { fg = \"vapor_yellow\" }\n\"error\" = { fg = \"chili_powder_red\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"crystal_blue\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"crystal_blue\", modifiers = [\"bold\"] }\n\"diagnostic.hint\" = { underline = {color = \"chili_powder_red\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = {color = \"crystal_blue\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = {color = \"vapor_yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = {color = \"chili_powder_red\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"ui.bufferline\" = { fg = \"gray\", bg = \"background\" }\n\"ui.bufferline.active\" = { fg = \"foreground\", bg = \"dark_gray\" }\n\n\"special\" = { fg = \"cash_green\" }\n\n[palette]\nbackground = \"#000000\"   \nforeground = \"#cccccc\"\nblack = \"#121212\"\ndark_gray = \"#2d3640\"\ngray = \"#5c6773\"\norange = \"#ff8f40\"\nbarium_green = \"#009669\"\nhazmat_yellow = \"#f7b90c\"\nvapor_yellow = \"#cecd19\"\nteddy_bear_pink = \"#bd5173\"\ncrystal_blue = \"#32c9fa\"\ncash_green = \"#00ff80\"\nelement_green = \"#186800\"\ndesert_maroon = \"#2B0C02\"\nchili_powder_red = \"#c32101\"\n"
  },
  {
    "path": "runtime/themes/hex_lavender.toml",
    "content": "# Author : portalsurfer <https://github.com/PORTALSURFER>\n\ninherits = \"hex_steel\"\n\n[palette]\nt1 = \"#0e0e0d\"\nt2 = \"#181a17\"\nt3 = \"#2b3444\"\nt4 = \"#61586f\"\nt5 = \"#686e73\"\nt6 = \"#878480\"\nt7 = \"#8e80de\"\nt8 = \"#7b89a3\"\nt9 = \"#bcb6ba\"\nt10 = \"#9db2b8\"\nt11 = \"#a0c7cf\"\n\nhighlight = \"#ff2e5f\"\nhighlight_two = \"#0affa9\"\nhighlight_three = \"#29bbff\"\n\nblack = \"#000000\"\n\nselection = \"#290019\"\nselection_fg = \"#958e9a\"\n\ncomment = \"#404768\"\ncomment_doc = \"#0affa9\"\n\nerror = \"#ff0900\"\nwarning = \"#ffbf00\"\ndisplay = \"#57ff89\"\ninfo = \"#dad7d5\"\n\nhints = \"#44273f\"\nruler  = \"#1c1f1b\"\n\ndiff_minus = \"#ff4000\"\ndiff_delta = \"#0078bd\"\ndiff_plus = \"#c9d400\"\ndiff_delta_moved = \"#0048bd\""
  },
  {
    "path": "runtime/themes/hex_poison.toml",
    "content": "# Author : portalsurfer <https://github.com/PORTALSURFER>\n\ninherits = \"hex_steel\"\n\n[palette]\nt1 = \"#121211\"\nt2 = \"#1e1f1b\"\nt3 = \"#4c513a\"\nt4 = \"#5a6052\"\nt5 = \"#6f6d6f\"\nt8 = \"#7e808a\"\nt7 = \"#b1b354\"\nt10 = \"#6fa197\"\nt9 = \"#3f4a4e\"\nt6 = \"#98acaa\"\nt11 = \"#6fd7a8\"\n\nhighlight = \"#ff2e5f\"\nhighlight_two = \"#0affa9\"\nhighlight_three = \"#d7ff52\"\n\nblack = \"#000000\"\n\nselection = \"#290019\"\nselection_fg = \"#c8e732\"\n\ncomment = \"#396884\"\ncomment_doc = \"#234048\"\n\nerror = \"#c73500\"\nwarning = \"#dcbb00\"\ndisplay = \"#57ff89\"\ninfo = \"#dad7d5\"\n\nhints = \"#313d3c\"\nruler  = \"#21221e\"\n\ndiff_minus = \"#ff4000\"\ndiff_delta = \"#16a7c7\"\ndiff_plus = \"#c9d400\"\ndiff_delta_moved = \"#0048bd\""
  },
  {
    "path": "runtime/themes/hex_steel.toml",
    "content": "# Author : portalsurfer <https://github.com/PORTALSURFER>\n\n\"comment\" = { fg = \"comment\" }\n\"comment.block.documentation\" = { bg = \"comment_doc\", modifiers = [\"italic\"] }\n\"comment.line.documentation\" = { bg = \"comment_doc\", modifiers = [\"italic\"] }\n\n\"constant\" = { fg = \"t11\" }\n\"function\" = { fg = \"t10\" }\n\"function.method\" = { fg = \"t7\" }\n\"function.macro\" = { fg = \"t7\" }\n\"keyword.storage.modifier\" = { fg = \"t7\" }\n\"keyword.control.import\" = { fg = \"t8\" }\n\"keyword.control\" = { fg = \"t8\" }\n\"keyword.function\" = { fg = \"t11\" }\n\"keyword\" = { fg = \"t6\" }\n\"operator\" = { fg = \"t8\" }\n\"punctuation\" = { fg = \"t9\" }\n\"string\" = { fg = \"t6\", modifiers = [\"italic\"] }\n\"string.regexp\" = { fg = \"t6\" }\n\"tag\" = { fg = \"t4\" }\n\"type\" = { fg = \"t8\", modifiers = [\"bold\"] }\n\"namespace\" = { fg = \"t6\", modifiers = [\"bold\"] }\n\"variable\" = { fg = \"t4\" }\n\"variable.parameter\" = { fg = \"t6\" } \n\"variable.other.member\" = { fg = \"t3\" } \n\"label\" = { fg = \"t4\" }\n\n\"diff.plus\" = { fg = \"diff_plus\" }\n\"diff.delta\" = { fg = \"diff_delta\" }\n\"diff.delta.moved\" = { fg = \"diff_delta_moved\" }\n\"diff.minus\" = { fg = \"diff_minus\" }\n\n\"ui.cursor.primary.insert\" = { fg = \"t2\", bg = \"highlight\" }\n\"ui.cursor.primary.select\" = { fg = \"t2\", bg = \"highlight_two\" }\n\"ui.cursor.primary\" = { fg = \"t1\", bg = \"highlight_three\" }\n\"ui.cursor.match\" = { fg = \"highlight\", bg = \"t1\", modifiers = [\"bold\"] }\n\"ui.cursorline.primary\" = { bg = \"ruler\" }\n\"ui.cursorline.secondary\" = { bg = \"ruler\" }\n\n\"ui.linenr\" = { fg = \"t3\", bg = \"t2\" }\n\"ui.linenr.selected\" = { fg = \"highlight_three\", bg = \"t2\" }\n\"ui.gutter\" = { bg = \"t2\" }\n\n\"ui.background\" = { fg = \"t4\", bg = \"t2\" }\n\"ui.background.separator\" = { fg = \"t3\" }\n\"ui.help\" = { fg = \"t4\", bg = \"t1\" }\n\"ui.menu\" = { fg = \"t4\", bg = \"t1\" }\n\"ui.menu.selected\" = { fg = \"highlight_three\", bg = \"t1\" }\n\"ui.popup\" = { fg = \"t4\", bg = \"t1\" }\n\"ui.window\" = { fg = \"t4\" }\n\n\"ui.selection\" = { fg = \"selection_fg\", bg = \"selection\" }\n\n\"ui.statusline\" = { fg = \"t4\", bg = \"t1\" }\n\"ui.statusline.inactive\" = { fg = \"t4\", bg = \"t1\" }\n\"ui.statusline.normal\" = { fg = \"t3\", bg = \"t1\" }\n\"ui.statusline.insert\" = { fg = \"t3\", bg = \"t1\" }\n\"ui.statusline.select\" = { fg = \"highlight\", bg = \"t4\" }\n\n\"ui.text\" = { fg = \"t4\" }\n\"ui.text.focus\" = { fg = \"highlight_three\", modifiers = [\"bold\"] }\n\n\"ui.virtual.ruler\" = { bg = \"ruler\" }\n\"ui.virtual.indent-guide\" = { fg = \"t3\" }\n\"ui.virtual.whitespace\" = { fg = \"t3\" }\n\"ui.virtual.jump-label\" = { fg = \"t11\", modifiers = [\"bold\"] }\n\"ui.virtual.inlay-hint\" = { fg = \"hints\", modifiers = [\"bold\"] }\n\n\"ui.bufferline\" = { fg = \"t3\", bg = \"t1\" }\n\"ui.bufferline.active\" = { fg = \"t7\", bg = \"t2\" }\n\n\"diagnostic.error\" = { underline = { color = \"error\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"warning\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"info\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"display\", style = \"curl\" } }\n\n\"error\" = { fg = \"error\", modifiers = [\"bold\"] }\n\"warning\" = { fg = \"warning\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"info\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"display\", modifiers = [\"bold\"] }\n\"special\" = { fg = \"t7\", modifiers = [\"bold\"] }\n\n\"markup.heading\" = { fg = \"t7\" }\n\"markup.list\" = { fg = \"t7\" }\n\"markup.bold\" = { fg = \"t4\" }\n\"markup.italic\" = { fg = \"t4\" }\n\"markup.strikethrough\" = { fg = \"t4\", modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"t11\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"t11\" }\n\"markup.quote\" = { fg = \"t5\" }\n\"markup.raw\" = { fg = \"t4\" }\n\n[palette]\nt1 = \"#0e0e0d\"\nt2 = \"#1d1e1b\"\nt3 = \"#5b5555\"\nt4 = \"#656869\"\nt5 = \"#727b7c\"\nt6 = \"#6e8789\"\nt7 = \"#d85c60\"\nt8 = \"#9bc1bb\"\nt9 = \"#b5c5c5\"\nt10 = \"#c3c3bd\"\nt11 = \"#f78c5e\"\n\nhighlight = \"#f23672\"\nhighlight_two = \"#f69c3c\"\nhighlight_three = \"#d4d987\"\n\nselection = \"#4a9aa6\"\nselection_fg = \"#080a0b\"\n\nblack = \"#000000\"\ncomment = \"#654642\"\ncomment_doc = \"#234048\"\nhints = \"#31353c\"\nruler  = \"#222320\"\n\nerror = \"#ff4000\"\nwarning = \"#ffbf00\"\ndisplay = \"#42baff\"\ninfo = \"#dad7d5\"\n\ndiff_minus = \"#ff4000\"\ndiff_delta = \"#0078bd\"\ndiff_plus = \"#c9d400\"\ndiff_delta_moved = \"#0048bd\"\n"
  },
  {
    "path": "runtime/themes/hex_toxic.toml",
    "content": "# Author : portalsurfer <https://github.com/PORTALSURFER>\n\ninherits = \"hex_steel\"\n\n[palette]\nt1 = \"#101719\"\nt2 = \"#1b2a32\"\nt3 = \"#4b5968\"\nt4 = \"#8792ab\"\nt5 = \"#6f91bc\"\nt6 = \"#8bb2b9\"\nt7 = \"#eeac90\"\nt8 = \"#b0bd9f\"\nt9 = \"#b3ccd0\"\nt10 = \"#b0d4d8\"\nt11 = \"#ffbf52\"\n\nhighlight = \"#ff0a50\"\nhighlight_two = \"#0affa9\"\nhighlight_three = \"#f8ed8b\"\n\nblack = \"#000000\"\n\nselection = \"#b10656\"\nselection_fg = \"#101719\"\n\ncomment = \"#417e8c\"\ncomment_doc = \"#234048\"\n\nerror = \"#ff0900\"\nwarning = \"#ffbf00\"\ndisplay = \"#57ff89\"\ninfo = \"#dad7d5\"\n\nhints = \"#39515c\"\nruler  = \"#1e3039\"\n\ndiff_minus = \"#ff4000\"\ndiff_delta = \"#0078bd\"\ndiff_plus = \"#c9d400\"\ndiff_delta_moved = \"#0048bd\""
  },
  {
    "path": "runtime/themes/horizon-dark.toml",
    "content": "# Syntax\nstring = \"orange\"\nconstant = \"purple\"\n\"constant.numeric\" = \"orange\"\n\"constant.builtin\" = \"orange\"\nvariable = \"red\"\nattribute = \"brown\"\ncomment = \"light-gray\"\nspecial = \"purple\"\n\"punctuation\" = \"red\"\n\"punctuation.bracket\" = \"purple\"\n\"punctuation.delimiter\" = \"white\"\nkeyword = \"purple\"\nfunction = \"blue\"\nlabel = \"orange\"\ntype = \"orange\"\nconstructor = \"orange\"\nnamespace = \"orange\"\ntag = \"red\"\n\n# User Interface\n\"ui.background\" = { bg = \"bg\", fg = \"gray\" }\n\"ui.background.separator\" = \"light-gray\"\n\"ui.linenr\" = { fg = \"light-gray\" }\n\"ui.linenr.selected\" = { fg = \"white\" }\n\"ui.text\" = \"white\"\n\"ui.text.focus\" = \"green\"\n\"ui.text.inactive\" = \"selection\"\n\"ui.text.info\" = \"orange\"\n\"ui.cursor\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { bg = \"selection\" }\n\"ui.gutter\" = \"gray\"\n\"ui.gutter.selected\" = \"light-gray\"\n\"ui.selection\" = { bg = \"selection\" }\n\"ui.virtual.indent-guide\" = { fg = \"gray\" }\n\"ui.virtual.whitespace\" = { fg = \"light-gray\" }\n\"ui.virtual.ruler\" = { bg = \"dark-bg\" }\n\"ui.statusline\" = { bg = \"dark-bg\", fg = \"light-gray\" }\n\"ui.popup\" = { bg = \"dark-bg\", fg = \"orange\" }\n\"ui.help\" = { bg = \"dark-bg\", fg = \"orange\" }\n\"ui.menu\" = { bg = \"dark-bg\", fg = \"light-gray\" }\n\"ui.menu.selected\" = { bg = \"selection\", fg = \"orange\" }\n\"ui.window\" = \"selection\"\n\"ui.bufferline\" = { bg = \"dark-bg\", fg = \"light-gray\" }\n\"ui.bufferline.active\" = { bg = \"dark-bg\", fg = \"orange\" }\n\"ui.virtual.jump-label\" = { fg = \"pink\", modifiers = [\"bold\"] }\n\"ui.picker.header.column\" = { fg = \"orange\", underline.style = \"line\" }\n\"ui.picker.header.column.active\" = { fg = \"purple\", modifiers = [\n  \"bold\",\n], underline.style = \"line\" }\n\n# Diagnostics\n\"diagnostic\" = { underline = { style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"green\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostics.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostics.warning\" = { underline = { color = \"orange\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nwarning = { fg = \"orange\", modifiers = [\"bold\"] }\nerror = { fg = \"red\", modifiers = [\"bold\"] }\ninfo = { fg = \"blue\", modifiers = [\"bold\"] }\nhint = { fg = \"green\", modifiers = [\"bold\"] }\n\n# Markup\n\"markup.heading\" = \"pink\"\n\"markup.list\" = \"light-gray\"\n\"markup.list.checked\" = \"green\"\n\"markup.list.unchecked\" = \"light-gray\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link\" = \"blue\"\n\"markup.quote\" = \"orange\"\n\"markup.raw\" = \"orange\"\n\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"orange\"\n\nrainbow = [\"yellow\", \"pink\", \"blue\"]\n\n[palette]\nwhite = \"#D5D8DA\"\ngray = \"#2E303E\"\nlight-gray = \"#6C6F93\"\nbg = \"#1C1E26\"\ndark-bg = \"#16161C\"\npink = \"#EE64AE\"\nselection = \"#353747\"\ngreen = \"#27D796\"\norange = \"#FAB795\"\nbrown = \"#F09383\"\npurple = \"#B877DB\"\nred = \"#E95678\"\nblue = \"#25B2BC\"\nyellow = \"#EFB41B\"\n"
  },
  {
    "path": "runtime/themes/iceberg-dark.toml",
    "content": "# Author : Chromo-residuum-opec <development.0extl@simplelogin.com>\n\n\"attribute\" = { fg = \"green\" }\n\"boolean\" = { fg = \"purple\" }\n\"character\" = { fg = \"purple\" }\n\"comment\" = { fg = \"comment_fg\" }\n\"conditional\" = { fg = \"blue\" }\n\"constant\" = { fg = \"purple\" }\n\"constructor\" = { fg = \"blue\" }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"red\" } }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"comment_fg\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"cyan\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"orange\" } }\n\"diff.delta\" = { fg = \"blue\" }\n\"diff.delta.gutter\" = { fg = \"cyan\", bg = \"linenr_bg\" }\n\"diff.minus\" = { fg = \"red\" }\n\"diff.minus.gutter\" = { fg = \"red\", bg = \"linenr_bg\" }\n\"diff.plus\" = { fg = \"green\" }\n\"diff.plus.gutter\" = { fg = \"green\", bg = \"linenr_bg\" }\n\"error\" = { fg = \"red\" }\n\"exception\" = { fg = \"blue\" }\n\"field\" = { fg = \"background_fg\" }\n\"float\" = { fg = \"purple\" }\n\"function\" = { fg = \"pale\" }\n\"function.macro\" = { fg = \"green\" }\n\"hint\" = { fg = \"comment_fg\" }\n\"identifier\" = { fg = \"blue\" }\n\"info\" = { fg = \"cyan\" }\n\"keyword\" = { fg = \"blue\" }\n\"keyword.directive\" = { fg = \"green\" }\n\"keyword.import\" = { fg = \"pale\" }\n\"label\" = { fg = \"green\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.heading\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link\" = { fg = \"blue\", underline = { style = \"line\" } }\n\"markup.link.label\" = { fg = \"cyan\" }\n\"markup.link.text\" = { fg = \"cyan\" }\n\"markup.link.url\" = { underline = { style = \"line\" } }\n\"markup.list\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.raw\" = { fg = \"cyan\" }\n\"markup.raw.inline\" = { bg = \"black\", fg = \"blue\" }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"method\" = { fg = \"pale\" }\n\"namespace\" = { fg = \"blue\" }\n\"number\" = { fg = \"purple\" }\n\"operator\" = { fg = \"blue\" }\n\"parameter\" = { fg = \"background_fg\" }\n\"property\" = { fg = \"background_fg\" }\n\"punctuation.bracket\" = { fg = \"background_fg\" }\n\"punctuation.delimiter\" = { fg = \"background_fg\" }\n\"punctuation.special\" = { fg = \"green\" }\n\"repeat\" = { fg = \"blue\" }\n\"special\" = { fg = \"green\" }\n\"string\" = { fg = \"cyan\" }\n\"string.escape\" = { fg = \"green\" }\n\"string.special\" = { fg = \"green\" }\n\"tag\" = { fg = \"blue\" }\n\"tag.attribute\" = { fg = \"purple\" }\n\"text\" = { fg = \"background_fg\" }\n\"type\" = { fg = \"blue\" }\n\"ui.background\" = { fg = \"background_fg\", bg = \"background_bg\" }\n\"ui.background.separator\" = { fg = \"comment_fg\" }\n\"ui.bufferline.active\" = { fg = \"pale\" }\n\"ui.cursor.match\" = { fg = \"background_fg\", bg = \"matchparen_bg\" }\n\"ui.cursor.normal\" = { bg = \"gray\" }\n\"ui.cursor.primary\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.select\" = { bg = \"gray\" }\n\"ui.cursorline.primary\" = { bg = \"linenr_bg\" }\n\"ui.gutter\" = { fg = \"linenr_fg\", bg = \"linenr_bg\" }\n\"ui.help\" = { fg = \"background_fg\", bg = \"cursorlinenr_bg\" }\n\"ui.linenr\" = { fg = \"linenr_fg\", bg = \"linenr_bg\" }\n\"ui.menu\" = { fg = \"background_fg\", bg = \"cursorlinenr_bg\" }\n\"ui.menu.border\" = { fg = \"comment_fg\" }\n\"ui.menu.selected\" = { fg = \"menusel_fg\", bg = \"menusel_bg\" }\n\"ui.popup\" = { fg = \"background_fg\", bg = \"cursorlinenr_bg\" }\n\"ui.popup.info\" = { fg = \"blue\" }\n\"ui.selection\" = { bg = \"sel_bg\" }\n\"ui.statusline\" = { bg = \"statusline_bg\", fg = \"statusline_fg\" }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"blue\" }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"green\" }\n\"ui.text.focus\" = { fg = \"orange\" }\n\"ui.virtual\" = { fg = \"linenr_fg\" }\n\"ui.virtual.indent-guide\" = { fg = \"linenr_fg\" }\n\"ui.virtual.jump-label\" = {  fg = \"orange\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"linenr_bg\" }\n\"ui.virtual.whitespace\" = { fg = \"sel_bg\" }\n\"ui.window\" = { fg = \"comment_fg\", modifiers = [\"bold\"] }\n\"variable\" = { fg = \"background_fg\" }\n\"variable.builtin\" = { fg = \"blue\" }\n\"warning\" = { fg = \"orange\" }\n\n[palette]\n\norange = \"#e2a578\"\npale = \"#a4aecc\"\npurple = \"#a093c8\"\n\nblack = \"#1e2132\"\ngray = \"#6b7089\"\nred = \"#e27878\"\nlight-red = \"#e98989\"\ngreen = \"#b5bf82\"\nlight-green = \"#c0ca8e\"\nyellow = \"#e2a478\"\nlight-yellow = \"#e9b189\"\nblue = \"#85a0c7\"\nlight-blue = \"#91acd1\"\nmagenta = \"#a093c7\"\nlight-magenta = \"#ada0d3\"\ncyan = \"#89b9c2\"\nlight-cyan = \"#95c4ce\"\nwhite = \"#c6c8d1\"\nlight-gray = \"#d2d4de\"\n\nbackground_bg = \"#161822\"\nbackground_fg = \"#c7c9d1\"\ncomment_fg = \"#6c7189\"\ncursorlinenr_bg = \"#3d425c\"\nlinenr_bg = \"#1f2233\"\nlinenr_fg = \"#454d73\"\nmatchparen_bg = \"#3f455f\"\nmenusel_bg = \"#5c638a\"\nmenusel_fg = \"#f0f1f5\"\nsel_bg = \"#282d43\"\nstatusline_bg = \"#0f1117\"\nstatusline_fg = \"#828597\"\n"
  },
  {
    "path": "runtime/themes/iceberg-light.toml",
    "content": "# Author : Chromo-residuum-opec <development.0extl@simplelogin.com>\n\ninherits = \"iceberg-dark\"\n\"ui.menu.selected\" = { fg = \"background_fg\", bg = \"menusel_bg\" }\n\n[palette]\n\norange = \"#c67439\"\npale = \"#505695\"\npurple = \"#785ab5\"\n\nblack = \"#dcdfe7\"\ngray = \"#8389a3\"\nred = \"#cd517a\"\nlight-red = \"#cc3768\"\ngreen = \"#668f3d\"\nlight-green = \"#598030\"\nyellow = \"#c57339\"\nlight-yellow = \"#b6662d\"\nblue = \"#2e539e\"\nlight-blue = \"#22478e\"\nmagenta = \"#7759b4\"\nlight-magenta = \"#6845ad\"\ncyan = \"#3f84a6\"\nlight-cyan = \"#327698\"\nwhite = \"#33374c\"\nlight-gray = \"#262a3f\"\n\nbackground_bg = \"#e9e9ed\"\nbackground_fg = \"#33374d\"\ncomment_fg = \"#8489a4\"\ncursorlinenr_bg = \"#cccfe0\"\nlinenr_bg = \"#dddfe9\"\nlinenr_fg = \"#a0a5c0\"\nmatchparen_bg = \"#bec0ca\"\nmenusel_bg = \"#a9afd1\"\nsel_bg = \"#cacdd8\"\nstatusline_bg = \"#cad0de\"\nstatusline_fg = \"#757da3\"\n"
  },
  {
    "path": "runtime/themes/ingrid.toml",
    "content": "# Author : Ingrid Rebecca Abraham <git@ingrids.email>\n\n\"attribute\" = \"#839A53\"\n\"keyword\" = { fg = \"#D74E50\", modifiers = [\"bold\"] }\n\"keyword.directive\" = \"#6F873E\"\n\"namespace\" = \"#839A53\"\n\"punctuation\" = \"#C97270\"\n\"punctuation.delimiter\" = \"#C97270\"\n\"operator\" = { fg = \"#D74E50\", modifiers = [\"bold\"] }\n\"special\" = \"#D68482\"\n\"variable.other.member\" = \"#89BEB7\"\n\"variable\" = \"#A6B6CE\"\n\"variable.parameter\" = \"#89BEB7\"\n\"type\" = { fg = \"#A6B6CE\", modifiers = [\"bold\"] }\n\"type.builtin\" = \"#839A53\"\n\"constructor\" = { fg = \"#839A53\", modifiers = [\"bold\"] }\n\"function\" = { fg = \"#89BEB7\", modifiers = [\"bold\"] }\n\"function.macro\" = { fg = \"#D4A520\", modifiers = [\"bold\"] }\n\"function.builtin\" = \"#89BEB7\"\n\"comment\" = \"#A6B6CE\"\n\"variable.builtin\" = \"#D4A520\"\n\"constant\" = \"#D4A520\"\n\"constant.builtin\" = \"#D4A520\"\n\"string\" = \"#D74E50\"\n\"constant.numeric\" = \"#D74E50\"\n\"constant.character.escape\" = { fg = \"#D74E50\", modifiers = [\"bold\"] }\n\"label\" = \"#D68482\"\n\n\"module\" = \"#839A53\"\n\n# TODO\n\"markup.heading\" = \"blue\"\n\"markup.list\" = \"red\"\n\"markup.bold\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"red\"\n\"markup.quote\" = \"cyan\"\n\"markup.raw\" = \"green\"\n\n\"diff.plus\" = \"#839A53\"\n\"diff.delta\" = \"#D4A520\"\n\"diff.minus\" = \"#D74E50\"\n\n\"ui.background\" = { bg = \"#FFFCFD\" }\n\"ui.linenr\" = { fg = \"#bbbbbb\" }\n\"ui.linenr.selected\" = { fg = \"#ED5466\", modifiers = [\"bold\"] }\n\"ui.cursorline\" = { bg = \"#F3EAE9\" }\n\"ui.statusline\" = { fg = \"#250E07\", bg = \"#F3EAE9\" }\n\"ui.statusline.inactive\" = { fg = \"#7b91b3\", bg = \"#F3EAE9\" }\n\"ui.popup\" = { fg = \"#7B91b3\", bg = \"#F3E8E9\" }\n\"ui.window\" = { bg = \"#D8B8B3\" }\n\"ui.help\" = { bg = \"#D8B8B3\", fg = \"#250E07\" }\n\n\"ui.text\" = { fg = \"#7B91B3\" }\n\"ui.text.focus\" = { fg = \"#250E07\", modifiers= [\"bold\"] }\n\"ui.virtual.whitespace\" = \"#A6B6CE\"\n\"ui.virtual.ruler\" = { bg = \"#F3EAE9\" }\n\n\"ui.selection\" = { bg = \"#F3EAE9\" }\n\"ui.cursor.primary\" = { bg = \"#ED5466\", fg = \"#FFFCFD\", modifiers = [\"bold\"] }\n\"ui.cursor.match\" = { bg = \"#F3EAE9\", fg = \"#ED5466\", modifiers = [\"bold\"] }\n\"ui.menu\" = { fg = \"#7B91B3\", bg = \"#F3EAE9\" }\n\"ui.menu.selected\" = { fg = \"#D74E50\", bg = \"#F3EAE9\" }\n\n\"warning\" = \"#D4A520\"\n\"error\" = \"#D74E50\"\n\"info\" = \"#839A53\"\n\"hint\" = \"#A6B6CE\"\n\n\"diagnostic.warning\" = { underline = { color = \"#D4A520\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"#D74E50\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"#839A53\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"#A6B6CE\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n"
  },
  {
    "path": "runtime/themes/iroaseta.toml",
    "content": "# Theme: Iroaseta\n# Author: YardQuit\n\n# SYNTAX HIGHLIGHTING\n\"attribute\" = { fg = \"yellow\" }\n\"type\" = { fg = \"white\" }\n\"type.builtin\" = { fg = \"white\" }\n\"type.parameter\" = { fg = \"white\" }\n\"type.enum\" = { fg = \"white\" }\n\"type.enum.variant\" = { fg = \"white\" }\n\"constructor\" = { fg = \"orange\" }\n\"constant\" = { fg = \"blue\" }\n\"constant.character.escape\" = { fg = \"yellow\" }\n\"string\" = { fg = \"blue\" }\n\"string.regexp\" = { fg = \"yellow\" }\n\"comment\" = { fg = \"gray\" }\n\"variable\" = { fg = \"orange\" }\n\"variable.parameter\" = { fg = \"yellow\" }\n\"variable.other\" = { fg = \"green\" }\n\"variable.other.member\" = { fg = \"green\" }\n\"label\" = { fg = \"blue\" }\n\"punctuation\" = { fg = \"white\" }\n\"punctuation.bracket\" = { fg = \"orange\" }\n\"punctuation.special\" = { fg = \"yellow\" }\n\"keyword\" = { fg = \"red\" }\n\"keyword.operator\" = { fg = \"blue\" }\n\"keyword.directive\" = { fg = \"white\" }\n\"keyword.function\" = { fg = \"red\" }\n\"keyword.storage\" = { fg = \"red\" }\n\"keyword.storage.modifier\" = { fg = \"green\" }\n\"operator\" = { fg = \"white\" }\n\"function\" = { fg = \"purple\" }\n\"function.method\" = { fg = \"green\" }\n\"function.macro\" = { fg = \"green\" }\n\"function.special\" = { fg = \"yellow\" }\n\"tag\" = { fg = \"green\" }\n\"namespace\" = { fg = \"white\" }\n\"diff\" = { fg = \"white\" }\n\"diff.minus\" = { fg = \"red\" }\n\"diff.delta\" = { fg = \"brown\" }\n\n# MARKUP, SYNTAX HIGHLIGHTING AND INTERFACE HYBRID\n\"markup.heading\" = { fg = \"blaze_orange\" }\n\"markup.heading.1\" = { fg = \"crystal_blue\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"sky_blue\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"dreamy_blue\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"crystal_blue\" }\n\"markup.heading.5\" = { fg = \"sky_blue\" }\n\"markup.heading.6\" = { fg = \"dreamy_blue\" }\n\"markup.list\" = { fg = \"blaze_orange\" }\n\"markup.bold\" = { fg = \"crystal_blue\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"crystal_blue\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { fg = \"crystal_blue\", modifiers = [\"crossed_out\"] }\n\"markup.link\" = { fg = \"crystal_blue\", underline = { color = \"light_purple\", style = \"line\" } }\n\"markup.link.url\" = { fg = \"slate_purple\", underline = { color = \"slate_purple\", style = \"line\" } }\n\"markup.link.label\" = { fg = \"crystal_blue\" }\n\"markup.link.text\" = { fg = \"crystal_blue\", modifiers = [\"bold\"] }\n\"markup.quote\" = { fg = \"misty_white\", modifiers = [\"italic\"] }\n\"markup.raw\" = { fg = \"misty_white\" }\n\"markup.raw.block\" = { fg = \"white\" }\n\n# USER INTERFACE \n\"ui.background\" = { bg = \"amber_shadow\"}                                                             # workspace background\n\"ui.background.separator\" = { fg = \"misty_white\" }                                                   # picker separator below input line (space + j)\n\"ui.gutter\" = { bg = \"amber_shadow\" }                                                                # gutter\n\"ui.gutter.selected\" = { bg = \"pitch_black\" }                                                        # gutter for the line the cursor is on\n\"ui.linenr\" = { fg = \"slate_gray\" }                                                                  # line numbers\n\"ui.linenr.selected\" = { fg = \"blaze_orange\", modifiers = [\"bold\"] }                                 # line number for the line the cursor is on\n\"ui.statusline\" = { fg = \"misty_white\", bg = \"pitch_black\" }                                         # statusline, fucused\n\"ui.statusline.inactive\" = { fg = \"slate_gray\", bg = \"dark_steel\" }                                  # statusline, unfocused\n\"ui.statusline.normal\" = { fg = \"amber_shadow\", bg = \"leafy_green\", modifiers = [\"bold\"] }           # statusline normal mode (if editor.color-modes is enabled)\n\"ui.statusline.insert\" = { fg = \"amber_shadow\", bg = \"blaze_orange\", modifiers = [\"bold\"] }          # statusline insert mode (if editor.color-modes is enabled)\n\"ui.statusline.select\" = { fg = \"amber_shadow\", bg = \"sky_blue\", modifiers = [\"bold\"] }              # statusline select mode (if editor.color-modes is enabled)\n\"ui.statusline.separator\" = { fg = \"misty_white\" }                                                   # separator character is statusline\n\"ui.bufferline\" = { fg = \"slate_gray\", modifiers = [\"bold\"] }                                        # bufferline inactive tab\n\"ui.bufferline.active\" = { fg = \"misty_white\", bg = \"rustic_red\" }                                   # bufferline active tab\n\"ui.bufferline.background\" = { bg = \"pitch_black\" }                                                  # bufferline background\n\"ui.virtual.ruler\" = { bg = \"rustic_red\" }                                                           # ruler columns\n\"ui.virtual.whitespace\" = { fg = \"brown\" }                                                           # whitespace characters\n\"ui.virtual.indent-guide\" = { fg = \"brown\" }                                                         # vertical indent width guides\n\"ui.virtual.inlay-hint\" = { fg = \"slate_gray\" }                                                      # inlay hints of all kinds\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"slate_gray\" }                                            # inlay hints of kind parameter (lsps are not required to set a kind)\n\"ui.virtual.inlay-hint.type\" = { fg = \"slate_gray\" }                                                 # inlay hints of kind type (lsps are not required to set a kind)\n\"ui.virtual.wrap\" = { fg = \"slate_gray\" }                                                            # soft-wrap indicator\n\"ui.virtual.jump-label\" = { modifiers = [\"reversed\"] }                                               # virtual jump labels (g + w)\n\"ui.selection\" = { bg = \"deep_purple\" }                                                              # slave selections in the editing area\n\"ui.selection.primary\" = { bg = \"light_purple\" }                                                     # primary selection in the editing area\n\"ui.cursor\" = { modifiers = [\"reversed\"] }                                                           # only if \"ui.cursor.primary.normal\" isn't set\n\"ui.cursor.normal\" = { modifiers = [\"reversed\"] }                                                    # slave cursor block in normal mode\n\"ui.cursor.insert\" = { bg = \"rustic_red\" }                                                           # slave cursor block in insert mode\n\"ui.cursor.select\" = { bg = \"deep_purple\" }                                                          # slave cursor block in select mode\n\"ui.cursor.match\" = { fg = \"amber_shadow\", bg = \"blaze_orange\", modifiers = [\"bold\"] }               # matching bracket etc\n\"ui.cursor.primary\" = { modifiers = [\"reversed\"] }                                                   # cursor with primary selection (has no effect due to \"ui.cursor.primary.normal\" is set)\n\"ui.cursor.primary.normal\" = { modifiers = [\"reversed\"] }                                            # cursor block in normal mode\n\"ui.cursor.primary.insert\" = { fg = \"amber_shadow\", bg = \"ruby_glow\" }                               # cursor block in insert mode    \n\"ui.cursor.primary.select\" = { fg = \"misty_white\", bg = \"deep_purple\" }                              # cursor block in select mode (not the selected color)\n\"ui.cursorline.primary\" = { bg = \"dark_steel\" }                                                      # line of the primary cursor\n\"ui.cursorline.secondary\" = { bg = \"midnight_black\"}                                                 # lines of secondary cursors\n\"ui.cursorcolumn.primary\" = { bg = \"dark_steel\" }                                                    # column of the primary cursor\n\"ui.cursorcolumn.secondary\" = { bg = \"midnight_black\" }                                              # columns of secondary cursors\n\n# USER INTERFACE - MENUS AND POPUP\n\"ui.popup\" = { fg = \"misty_white\", bg = \"midnight_black\" }                                           # documentation popups (space + k)\n\"ui.popup.info\" = { fg = \"misty_white\", bg = \"midnight_black\" }                                      # prompt for multiple key options, menu border (space, g, z, m, etc)\n\"ui.window\" = { fg = \"pitch_black\" }                                                                 # borderlines separating splits\n\"ui.help\" = { fg = \"misty_white\", bg = \"midnight_black\" }                                            # description box for commands\n\"ui.text\" = { fg = \"white\" }                                                                         # default text style, command prompts, popup text, etc\n\"ui.text.focus\" = { fg = \"leafy_green\" }                                                             # the currently selected line in the picker (space j, space f, space s, etc)\n\"ui.text.inactive\" = { fg = \"slate_gray\" }                                                           # same as ui.text but when the text is inactive e.g. suggestions\n\"ui.text.info\" = { fg = \"misty_white\", bg = \"midnight_black\" }                                       # the key: command in ui.popup.info boxes (space, g, z, m, etc)\n\"ui.menu\" = { fg = \"ethereal_gray\", bg = \"pitch_black\" }                                             # code and command completion menus \":\"\n\"ui.menu.selected\" = { fg = \"misty_white\", bg = \"dark_steel\" }                                       # selected autocomplete item\n\"ui.menu.scroll\" = { fg = \"slate_gray\", bg = \"midnight_black\" }                                      # scrollbar\n\"ui.highlight\" = { underline = { color = \"blaze_orange\", style = \"line\" } }                          # highlighted lines in the picker preview\n\n# User Interface - Diagnostics\n\"warning\" = { fg = \"lemon_zest\" }                                                                    # diagnostics warning (gutter)\n\"error\" = { fg = \"ruby_glow\" }                                                                       # diagnostics error (gutter)\n\"info\" = { fg = \"sky_blue\" }                                                                         # diagnostics info (gutter)\n\"hint\" = { fg = \"walnut_brown\" }                                                                     # diagnostics hint (gutter)\n\"diagnostic\" = { modifiers = [\"reversed\"] }                                                          # diagnostics fallback style (editing area)\n\"diagnostic.hint\" = { fg = \"amber_shadow\", bg = \"walnut_brown\" }                                     # diagnostics hint (editing area)\n\"diagnostic.info\" = { fg = \"misty_white\", bg = \"twilight_slate\" }                                    # diagnostics info (editing area)\n\"diagnostic.warning\" = { fg = \"misty_white\", bg = \"rustic_amber\" }                                   # diagnostics warning (editing area)\n\"diagnostic.error\" = { fg = \"misty_white\", bg = \"rustic_red\" }                                       # diagnostics error (editing area)\n\n# COLOR NAMES\n[palette] \n# PALETTE USER INTERFACE\namber_shadow = \"#0d1117\"\nmidnight_black = \"#010409\"\ndark_steel = \"#161b22\"\npitch_black = \"#000000\"\nmisty_white = \"#f2f0eb\"\nslate_gray = \"#838a97\"\nethereal_gray = \"#91a3b0\"\nblaze_orange = \"#ff9000\"\nlemon_zest = \"#ffba00\"\nleafy_green = \"#81be83\"\ndreamy_blue = \"#6eb0ff\"\ncrystal_blue = \"#99c7ff\"\ntwilight_slate = \"#263c57\"\nsky_blue = \"#45b1e8\"\nrustic_red = \"#540b0c\"\nruby_glow = \"#fa7970\"\nwalnut_brown = \"#987654\"\nrustic_amber = \"#9d5800\"\nslate_purple = \"#d2a8ff\"\nlight_purple = \"#7533bd\"\ndeep_purple = \"#4c1785\"\n\n# PALETTE SYNTAX HIGHLIGHTING\nblack = \"#0d1117\"\nred = \"#fa7970\"\ngreen = \"#81be83\"\nyellow = \"#ffba00\"\norange = \"#ff9000\"\nblue = \"#45b1e8\"\npurple = \"#d2a8ff\"\nbrown = \"#987654\"\ngray = \"#838a97\"\nwhite = \"#dadada\"\n"
  },
  {
    "path": "runtime/themes/jellybeans.toml",
    "content": "#\n#    __       _ _       _                           \n#    \\ \\  ___| | |_   _| |__   ___  __ _ _ __  ___  \n#     \\ \\/ _ \\ | | | | |  _ \\ / _ \\/ _  |  _ \\/ __| \n#  /\\_/ /  __/ | | |_| | |_| |  __/ |_| | | | \\__ \\ \n#  \\___/ \\___|_|_|\\__  |____/ \\___|\\____|_| |_|___/ \n#                 \\___/                             \n#\n# Jellybeans\n# A take on the Jellybeans theme, please feel free to contribute! \n#\n# Original author: @nanotech\n# Original repository: nanotech/jellybeans.vim\n# Contributors:\n# @cemalokten\n\n\"attribute\" = \"green\"\n\"type\" = \"light_blue\"\n\"type.enum.variant\" = \"purple\"\n\"constructor\" = \"yellow\"\n\"constant\" = \"dark_orange\"\n\n\"constant.builtin.boolean\" = \"yellow\"\n\"constant.character\" = \"yellow\"\n\"constant.character.escape\" = \"red_error\"\n\"constant.numeric\" = \"dark_orange\"\n\"string\" = \"dark_green\"\n\"string.regexp\" = \"light_purple\"\n\"string.special\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"comment\" = \"light_gray\"\n\n\"variable\" = \"light_yellow\"\n\"variable.builtin\" = { fg = \"dark_green\", modifiers = [\"underlined\"] }\n\"variable.parameter\" = \"yellow\"\n\"variable.other.member\" = \"light_purple\"\n\"label\" = \"yellow\"\n\"punctuation\" = \"mid_blue\"\n\"keyword\" = \"mid_blue\"\n\"keyword.control.exception\" = \"purple\"\n\"operator\" = \"light_purple\"\n\"function\" = \"yellow\"\n\"function.macro\" = \"green\"\n\"function.builtin\" = \"green\"\n\"function.special\" = \"green\"\n\"function.method\" = \"yellow\"\n\"tag\" = \"light_blue\"\n\"special\" = \"green\"\n\"namespace\" = \"light_purple\"\n\n\"markup.bold\" = { fg = \"white\", modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.heading\" = { fg = \"mid_blue\", modifiers = [\"bold\"] }\n\"markup.list\" = \"dark_green\"\n\"markup.list.numbered\" = \"mid_blue\"\n\"markup.list.unnumbered\" = \"mid_blue\"\n\"markup.link.url\" = { fg = \"dark_green\", modifiers = ['italic', 'underlined'] }\n\"markup.link.text\" = \"mid_blue\"\n\"markup.link.label\" = \"purple\"\n\"markup.quote\" = \"dark_green\"\n\"markup.raw\" = \"dark_green\"\n\"markup.raw.inline\" = \"mid_blue\"\n\"markup.raw.block\" = \"dark_green\"\n\n\"diff.plus\" = \"diff_plus\"\n\"diff.minus\" = \"red_accent\"\n\"diff.delta\" = \"blue_accent\"\n\n# ui specific\n\"ui.background\" = { bg = \"background\" }                                            # .separator\n\"ui.cursor\" = { bg = \"background\", modifiers = [\"reversed\"] }\n\"ui.cursor.insert\" = { bg = \"light_yellow\", fg = \"background\" }\n\"ui.cursor.match\" = { fg = \"background\", bg = \"dark_orange\" }\n\"ui.cursorline\" = { bg = \"darker\" }\n\"ui.linenr\" = \"dark_gray\"\n\"ui.linenr.selected\" = { fg = \"light_yellow\", bg = \"darker\" }\n\"ui.statusline\" = { fg = \"light_yellow\", bg = \"darker\" }\n\"ui.statusline.inactive\" = { fg = \"dark\", bg = \"darker\" }\n\"ui.statusline.normal\" = { fg = \"light_yellow\", bg = \"darker\" }\n\"ui.statusline.insert\" = { fg = \"darker\", bg = \"purple\" }\n\"ui.statusline.select\" = { fg = \"selectionFG\", bg = \"selection\" }\n\"ui.popup\" = { fg = \"light_yellow\", bg = \"darkest\" }\n\"ui.window\" = { fg = \"dark\", bg = \"darkest\" }\n\"ui.help\" = { fg = \"light_yellow\", bg = \"darkest\" }\n\"ui.text\" = \"light_yellow\"\n\"ui.text.focus\" = { fg = \"white\", bg = \"dark_blue\" }\n\"ui.virtual\" = \"dark\"\n\"ui.virtual.ruler\" = { bg = \"darker\" }\n\"ui.menu\" = { fg = \"light_purple\", bg = \"darkest\" }\n\"ui.menu.selected\" = { fg = \"white\", bg = \"dark_blue\" }\n\"ui.selection\" = { bg = \"darker\" }\n\"ui.selection.primary\" = { bg = \"selection\", fg = \"selectionFG\" }\n\"hint\" = \"blue\"\n\"info\" = \"yellow_accent\"\n\"warning\" = \"orange_accent\"\n\"error\" = \"red_error\"\n\"diagnostic\" = { modifiers = [] }\n\"diagnostic.hint\" = { underline = { color = \"light_purple\", style = \"line\" } }\n\"diagnostic.info\" = { underline = { color = \"blue_accent\", style = \"line\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow_accent\", style = \"line\" } }\n\"diagnostic.error\" = { underline = { color = \"red_error\", style = \"line\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nbackground = \"#151515\"\ndarkest = \"#1e1e1e\"\ndarker = \"#292929\"\ndark = \"#898989\"\nwhite = \"#ffffff\"\ndark_gray = \"#535353\"\nlight_gray = \"#6d6d6d\"\n\npurple = \"#a390f0\"\nlight_purple = \"#CDBEF0\"\n\nblue = \"#52a7f6\"\nlight_blue = \"#8fbfdc\"\nmid_blue = \"#8197bf\"\ndark_blue = \"#204474\"\nblue_accent = \"#2197F3\"\n\ngreen = \"#99ad6a\"\ndark_green = \"#84A775\"\n\nred = \"#CC7C8A\"\nred_error = \"#902020\"\nred_accent = \"#F44747\"\n\norange = \"#efb080\"\ndark_orange = \"#cf6a4c\"\norange_accent = \"#EE7F25\"\n\nyellow = \"#fad07a\"\nlight_yellow = \"#EBEBD8\"\nyellow_accent = \"#DEA407\"\n\ndiff_plus = \"#5A9F81\"\nselection = \"#37232D\"\nselectionFG = \"#F2AAC7\"\n"
  },
  {
    "path": "runtime/themes/jetbrains_cyan_light.toml",
    "content": "# Jetbrains Cyan Light\n# Adapted from JetBrains' Cyan Light Theme https://plugins.jetbrains.com/plugin/12102-cyan-light-theme \n# Author: Abderrahmane Tahri Jouti <tj.abderrahmane@gmail.com>\n\n# Original Author : Olga Berdnikova\n# LICENSE : MIT\n# Source: https://github.com/OlyaB/CyanTheme\n\n\"attribute\" = \"blue\"\n\"type\" = \"shade07\"\n\"type.enum.variant\" = \"purple\"\n\"constructor\" = \"shade07\"\n\n\"constant\" = \"darker_blue\"\n\"constant.builtin.boolean\" = \"blue\"\n\"constant.character\" = \"blue\"\n\"constant.character.escape\" = \"dark_red\"\n\"constant.numeric\" = \"blue\"\n\n\"string\" = \"green\"\n\"string.regexp\" = \"blue\"\n\"string.special\" = { fg = \"dark_red\", modifiers = [\"underlined\"] }\n\n\"comment\" = \"comment_gray\"\n\n\"variable\" = \"green_blue\"\n\"variable.builtin\" = { fg = \"darker_blue\" }\n\"variable.parameter\" = \"purple\"\n\"variable.other.member\" = \"purple\"\n\n\"label\" = { fg = \"darker_blue\", modifiers = [\"underlined\"] }\n\"punctuation\" = \"shade06\"\n\n\"keyword\" = \"darker_blue\"\n\"keyword.control.exception\" = \"darker_blue\"\n\n\"operator\" = \"shade06\"\n\n\"function\" = \"shade07\"\n\"function.macro\" = \"yellow\"\n\"function.builtin\" = { fg = \"shade07\", modifiers = [\"italic\"] }\n\"function.special\" = \"dark_red\"\n\"function.method\" = \"dark_yellow\"\n\n\"tag\" = \"darker_blue\"\n\"special\" = \"shade06\"\n\"namespace\" = \"darker_blue\"\n\n\"markup.bold\" = { fg = \"shade06\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"shade06\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { fg = \"shade06\", modifiers = [\"crossed_out\"] }\n\"markup.heading\" = { fg = \"purple\" }\n\"markup.list\" = \"darker_blue\"\n\"markup.list.numbered\" = \"darker_blue\"\n\"markup.list.unnumbered\" = \"darker_blue\"\n\"markup.link.url\" = \"shade06\"\n\"markup.link.text\" = { fg = \"dark_blue\", modifiers = ['underlined'] }\n\"markup.link.label\" = \"dark_blue\"\n\"markup.quote\" = \"green\"\n\"markup.raw\" = \"green\"\n\"markup.raw.inline\" = \"green\"\n\"markup.raw.block\" = \"green\"\n\n\"diff.plus\" = \"green\"\n\"diff.plus.gutter\" = \"gutter_green\"\n\"diff.minus\" = \"red\"\n\"diff.minus.gutter\" = \"gutter_red\"\n\"diff.delta\" = \"blue\"\n\"diff.delta.gutter\" = \"gutter_blue\"\n\n# ui specific\n\"ui.background\" = { bg = \"shade00\" }\n\"ui.cursor\" = { bg = \"shade02\" }\n\"ui.cursor.primary\" = { bg = \"cursor_blue\" }\n\"ui.cursor.match\" = { fg = \"shade00\", bg = \"shade04\" }\n\"ui.cursor.primary.select\" = { bg = \"light_purple\" }\n\"ui.cursor.primary.insert\" = { bg = \"light_green\" }\n\n\"ui.selection\" = { bg = \"lighter_blue\" }\n\"ui.selection.primary\" = { bg = \"lighter_blue\" }\n\n\"ui.highlight\" = { bg = \"faint_blue\" }\n\"ui.cursorline.primary\" = { bg = \"faint_blue\" }\n\n\"ui.linenr\" = { fg = \"shade03\" }\n\"ui.linenr.selected\" = { fg = \"shade04\", bg = \"faint_blue\", modifiers = [\n    \"bold\",\n] }\n\n\"ui.statusline\" = { fg = \"shade06\", bg = \"shade01\" }\n\"ui.statusline.inactive\" = { fg = \"shade03_darker\", bg = \"shade01_lighter\" }\n\"ui.statusline.normal\" = { fg = \"shade00\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"shade00\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"shade00\", bg = \"purple\" }\n\n\"ui.popup\" = { fg = \"shade04\", bg = \"shade01_lighter\" }\n\"ui.window\" = { fg = \"shade03_darker\", bg = \"shade01_lighter\" }\n\"ui.help\" = { fg = \"shade06\", bg = \"shade00\" }\n\"ui.text\" = \"shade05\"\n\"ui.text.focus\" = { fg = \"shade07\", bg = \"light_blue\" }\n\"ui.text.directory\" = \"blue\"\n\n\"ui.virtual\" = \"shade03\"\n\"ui.virtual.ruler\" = { bg = \"shade01\" }\n\"ui.virtual.inlay-hint\" = { fg = \"shade03_darker\" }\n\"ui.virtual.jump-label\" = { fg = \"shade07\", bg = \"shade01\", modifiers = [\"bold\" ] }\n\n\"ui.menu\" = { fg = \"shade05\", bg = \"shade01_lighter\" }\n\"ui.menu.selected\" = { fg = \"shade07\", bg = \"light_blue\" }\n\n\"hint\" = \"shade04\"\n\"info\" = \"light_blue\"\n\"warning\" = \"orange\"\n\"error\" = \"red\"\n\n\"diagnostic\" = { modifiers = [] }\n\"diagnostic.hint\" = { underline = { color = \"shade04\", style = \"line\" } }\n\"diagnostic.info\" = { underline = { color = \"light_blue\", style = \"line\" } }\n\"diagnostic.warning\" = { underline = { color = \"orange\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nshade00 = \"#f2f3f7\"\nshade01 = \"#dadde8\"\nshade02 = \"#c1c6d9\"\nshade03 = \"#a9b0ca\"\nshade04 = \"#525c85\"\nshade05 = \"#434b6c\"\nshade06 = \"#343a54\"\nshade07 = \"#25293c\"\n\nshade01_lighter = \"#e6e8f0\"\nshade03_darker = \"#9199bb\"\nshade04_lighter = \"#616d9d\"\n\nbackground = \"#f2f3f7\"\nforeground = \"#25293c\"\n\ncomment_gray = \"#808080\"\n\ngutter_blue = \"#C3D6E8\"\nfaint_blue = \"#E8Eef1\"\nlighter_blue = \"#d0eaff\"\nlight_blue = \"#99ccff\"\ncursor_blue = \"#80bfff\"\nblue = \"#0073E6\"\ndark_blue = \"#185b93\"\ndarker_blue = \"#000080\"\n\npurple = \"#660E7A\"\nlight_purple = \"#ED9CFF\"\n\ngutter_green = \"#C9DEC1\"\ngreen = \"#00733B\"\nlight_green = \"#5DCE87\"\ngreen_blue = \"#458383\"\n\nyellow = \"#808000\"\ndark_yellow = \"#7A7A43\"\n\nlight_orange = \"#f9c881\"\norange = \"#F49810\"\n\ngutter_red = \"#EBBCBC\"\nred = \"#d90016\"\ndark_red = \"#7F0000\"\n"
  },
  {
    "path": "runtime/themes/jetbrains_dark.toml",
    "content": "\"type.builtin\" = \"red207\"\n\"type.enum\" = \"red199\"\n\"constant.builtin\" = \"red207\"\n\"constant.numeric\" = \"blue184\"\nstring = \"green171\"\ncomment = \"blue133\"\n\"comment.block.documentation\" = \"green130\"\n\"comment.line.documentation\" = \"green130\"\n\"variable.builtin\" = \"red207\"\n\"variable.other.member\" = \"red199\"\nlabel = \"red199\"\nkeyword = \"red207\"\nfunction = \"blue245\"\n\"function.macro\" = \"red179\"\ntag = \"red213\"\n\n\"markup.heading\" = { fg = \"red199\", modifiers = [\"italic\"] }\n\"markup.heading.marker\" = \"red207\"\n\"markup.list\" = \"red207\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link\" = { fg = \"blue247\", underline = { style = \"line\" } }\n\"markup.raw\" = { bg = \"blue64\" }\n\n\"diff.plus\" = \"green145\"\n\"diff.minus\" = \"blue145\"\n\"diff.delta\" = \"blue173\"\n\n\"ui.background\" = { fg = \"blue196\", bg = \"blue34\" }\n\"ui.gutter\" = \"blue56\"\n\"ui.gutter.selected\" = { fg =\"blue56\", bg = \"blue46\" }\n\"ui.linenr\" = \"blue89\"\n\"ui.linenr.selected\" = \"blue171\"\n\"ui.statusline\" = { bg = \"blue48\" }\n\"ui.statusline.inactive\" = \"blue89\"\n\"ui.statusline.normal\" = { fg = \"blue48\", bg = \"green156\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"blue48\", bg = \"blue247\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"blue48\", bg = \"red194\", modifiers = [\"bold\"] }\n\"ui.popup\" = { bg = \"blue48\" }\n\"ui.text.focus\" = \"blue247\"\n\"ui.virtual\" = \"blue122\"\n\"ui.virtual.ruler\" = { bg = \"blue64\" }\n\"ui.virtual.whitespace\" = \"blue122\"\n\"ui.virtual.indent-guide\" = \"blue56\"\n\"ui.virtual.inlay-hint\" = { fg = \"blue145\", bg = \"blue50\" }\n\"ui.menu\" = { bg = \"blue48\" }\n\"ui.menu.selected\" = { bg = \"blue110\" }\n\"ui.menu.scroll\" = { fg = \"blue81\", bg = \"blue48\" }\n\"ui.selection\" = { fg = \"black\", bg = \"blue214\" }\n\"ui.selection.primary\" = { bg = \"blue131\" }\n\"ui.cursorline.primary\" = { bg = \"blue46\" }\n\"ui.cursorline.secondary\" = { bg = \"blue46\" }\n\"ui.cursorcolumn.primary\" = { bg = \"blue46\" }\n\"ui.cursorcolumn.secondary\" = { bg = \"blue46\" }\n\nwarning = \"red194\"\nerror = \"red214\"\ninfo = \"blue247\"\nhint = \"green156\"\n\n\"diagnostic\" = { underline = { style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"green156\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue247\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"red194\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red214\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nred179 = \"#b3ae60\"\nred194 = \"#c29e4a\"\nred199 = \"#c77dbb\"\nred207 = \"#cf8e6d\"\nred213 = \"#d5b778\"\nred214 = \"#d64d5b\"\n\ngreen130 = \"#5f826b\"\ngreen145 = \"#549159\"\ngreen156 = \"#499c54\"\ngreen171 = \"#6aab73\"\n\nblue34 = \"#1e1f22\"\nblue46 = \"#26282e\"\nblue48 = \"#2b2d30\"\nblue50 = \"#2d2e32\"\nblue56 = \"#313438\"\nblue64 = \"#293c40\"\nblue81 = \"#4d4e51\"\nblue89 = \"#4b5059\"\nblue110 = \"#2e436e\"\nblue122 = \"#6f737a\"\nblue131 = \"#214283\"\nblue133 = \"#7a7e85\"\nblue145 = \"#868a91\"\nblue171 = \"#A1A3AB\"\nblue173 = \"#375fad\"\nblue184 = \"#2aacb8\"\nblue196 = \"#bcbec4\"\nblue214 = \"#ced0d6\"\nblue245 = \"#56a8f5\"\nblue247 = \"#57aaf7\"\n"
  },
  {
    "path": "runtime/themes/kanagawa-dragon.toml",
    "content": "# Kanagawa Dragon\n# Author: EricHenry\n\n# Adaptation of https://github.com/rebelot/kanagawa.nvim\n# Original author: rebelot\n# All credits to the original author, the palette is taken from the README\n# because of some theming differences, it's not an exact copy of the original.\n\ninherits = \"kanagawa\"\n\n## User interface\n\"ui.selection\" = { bg = \"waveBlue2\" }\n\"ui.selection.primary\" = { bg = \"waveBlue1\" }\n\"ui.background\" = { fg = \"dragonWhite\", bg = \"dragonBlack3\" }\n\"ui.gutter\" = { fg = \"dragonBlack6\", bg = \"dragonBlack4\" }\n\n\"ui.linenr\" = { fg = \"dragonBlack6\", bg = \"dragonBlack4\" }\n\"ui.linenr.selected\" = { fg = \"roninYellow\", modifiers = [\"bold\"] }\n\n\"ui.virtual\" = \"dragonBlack4\"\n\"ui.virtual.ruler\" = { bg = \"dragonBlack5\" }\n\"ui.virtual.inlay-hint\" = \"dragonGray2\"\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"dragonYellow\", modifiers = [\"dim\"] }\n\"ui.virtual.inlay-hint.type\" = { fg = \"dragonAqua\", modifiers = [\"dim\"] }\n\"ui.virtual.jump-label\" = { fg = \"dragonRed\", modifiers = [\"bold\"] }\n\n\"ui.statusline\" = { fg = \"oldWhite\", bg = \"dragonBlack0\" }\n\n\"ui.bufferline\" = { fg = \"oldWhite\", bg = \"dragonBlack0\" }\n\"ui.bufferline.active\" = { fg = \"oldWhite\", bg = \"dragonBlack0\" }\n\"ui.bufferline.background\" = { bg = \"sumiInk0\" }\n\n\"ui.popup\" = { fg = \"oldWhite\", bg = \"dragonBlack0\" }\n\"ui.window\" = { fg = \"sumiInk0\" }\n\"ui.help\" = { fg = \"fujiWhite\", bg = \"sumiInk0\" }\n\"ui.text\" = \"dragonWhite\"\n\"ui.text.focus\" = { fg = \"dragonWhite\", bg = \"waveBlue1\", modifiers = [\"bold\"] }\n\n\"ui.cursor\" = { fg = \"waveBlue1\", bg = \"waveAqua2\" }\n\"ui.cursor.primary\" = { fg = \"waveBlue1\", bg = \"fujiWhite\" }\n\"ui.cursor.match\" = { fg = \"roninYellow\", modifiers = [\"bold\"] }\n\"ui.highlight\" = { fg = \"fujiWhite\", bg = \"waveBlue2\" }\n\n\"ui.cursorline.primary\" = { bg = \"dragonBlack5\" }\n\"ui.cursorcolumn.primary\" = { bg = \"dragonBlack5\" }\n\n\"diagnostic.info\" = { underline = { color = \"dragonBlue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"waveAqua1\", style = \"curl\" } }\n\"diagnostic.deprecated\" = { fg= \"katanaGray\", modifiers = [\"crossed_out\"] }\n\n## Syntax highlighting\n\"attribute\" = \"waveRed\"\n\"type\" = \"dragonAqua\"\n\"type.enum.variant\" = \"dragonOrange\"\n\"constructor\" = \"dragonTeal\"\n\"constant\" = \"dragonOrange\"\n\"constant.numeric\" = \"dragonPink\"\n\"constant.character.escape\" = \"dragonBlue2\"\n\"string\" = \"dragonGreen2\"\n\"string.regexp\" = \"dragonRed\"\n\"string.special.url\" = \"dragonTeal\"\n\"string.special.symbol\" = \"dragonTeal\"\n\"comment\" = \"dragonAsh\"\n\"variable\" = \"dragonWhite\"\n\"variable.builtin\" = \"dragonRed\"\n\"variable.parameter\" = \"dragonGray\"\n\"variable.other.member\" = \"dragonYellow\"\n\"label\" = \"dragonRed\"\n\"punctuation\" = \"dragonWhite\"\n\"keyword\" = \"dragonViolet\"\n\"keyword.control.return\" = \"dragonRed\"\n\"keyword.control.exception\" = \"dragonRed\"\n\"keyword.directive\" = \"dragonRed\"\n\"operator\" = \"dragonRed\"\n\"function\" = \"dragonBlue2\"\n\"function.builtin\" = \"dragonBlue2\"\n\"function.macro\" = \"dragonRed\"\n\"tag\" = \"dragonYellow\"\n\"namespace\" = \"dragonWhite\"\n\"special\" = \"dragonYellow\"\n\n## Markup modifiers\n\"markup.heading.marker\" = \"dragonViolet\"\n\"markup.heading.1\" = { fg = \"dragonOrange\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"dragonYellow\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"dragonBlue2\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"dragonWhite\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"dragonRed\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"dragonPink\", modifiers = [\"bold\"] }\n\"markup.list.numbered\" = \"dragonPink\"\n\"markup.list.unnumbered\" = \"dragonRed\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.text\" = \"dragonTeal\"\n\"markup.link.url\" = { fg = \"dragonPink\", underline.style = \"line\" }\n\"markup.link.label\" = \"dragonBlue2\"\n\"markup.quote\" = \"springViolet1\"\n\"markup.raw\" = \"dragonGreen2\"\n\n[palette]\ndragonBlack0 = \"#0d0c0c\"\ndragonBlack1 = \"#12120f\"\ndragonBlack2 = \"#1D1C19\"\ndragonBlack3 = \"#181616\"\ndragonBlack4 = \"#282727\"\ndragonBlack5 = \"#393836\"\ndragonBlack6 = \"#625e5a\"\n\ndragonWhite = \"#c5c9c5\"\ndragonGreen = \"#87a987\"\ndragonGreen2 = \"#8a9a7b\"\ndragonPink = \"#a292a3\"\ndragonOrange = \"#b6927b\"\ndragonOrange2 = \"#b98d7b\"\ndragonGray = \"#a6a69c\"\ndragonGray2 = \"#9e9b93\"\ndragonGray3 = \"#7a8382\"\ndragonBlue2 = \"#8ba4b0\"\ndragonViolet= \"#8992a7\"\ndragonRed = \"#c4746e\"\ndragonAqua = \"#8ea4a2\"\ndragonAsh = \"#737c73\"\ndragonTeal = \"#949fb5\"\ndragonYellow = \"#c4b28a\"\n"
  },
  {
    "path": "runtime/themes/kanagawa-lotus.toml",
    "content": "# Kanagawa-lotus\n# Author: vmanolop\n\n# A light variant of the Kanagawa theme, based on the original dark Kanagawa theme\n# and inspired by the lotus variant of https://github.com/rebelot/kanagawa.nvim\n\n## User interface\n\"ui.selection\" = { bg = \"lotusBlue1\" }\n\"ui.selection.primary\" = { bg = \"lotusBlue1\" }\n\"ui.background\" = { fg = \"lotusInk0\", bg = \"lotusWhite0\" }\n\n\"ui.linenr\" = { fg = \"lotusInk1\" }\n\"ui.linenr.selected\" = { fg = \"lotusBrightOrange\", modifiers = [\"bold\"] }\n\"ui.gutter\" = { fg = \"lotusInk1\", bg = \"lotusWhite1\" }\n\n\"ui.virtual\" = \"lotusInk1\"\n\"ui.virtual.ruler\" = { bg = \"lotusWhite1\" }\n\"ui.virtual.inlay-hint\" = \"lotusInk2\"\n\"ui.virtual.jump-label\" = { fg = \"lotusRed\", modifiers = [\"bold\"] }\n\"ui.virtual.whitespace\" = { fg = \"lotusWhite2\" }\n\n\"ui.statusline\" = { fg = \"lotusInk0\", bg = \"lotusWhite2\" }\n\"ui.statusline.inactive\" = { fg = \"lotusInk1\", bg = \"lotusWhite2\" }\n\"ui.statusline.normal\" = { fg = \"lotusWhite2\", bg = \"lotusBlue1\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"lotusWhite2\", bg = \"lotusBrightGreen\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"lotusWhite2\", bg = \"lotusBrightViolet\", modifiers = [\"bold\"] }\n\n\"ui.bufferline\" = { fg = \"lotusInk1\", bg = \"lotusWhite2\" }\n\"ui.bufferline.active\" = { fg = \"lotusInk0\", bg = \"lotusWhite2\" }\n\"ui.bufferline.background\" = { bg = \"lotusWhite2\" }\n\n\"ui.popup\" = { fg = \"lotusInk0\", bg = \"lotusWhite2\" }\n\"ui.window\" = { fg = \"lotusWhite2\" }\n\"ui.help\" = { fg = \"lotusInk0\", bg = \"lotusWhite2\" }\n\"ui.text\" = \"lotusInk0\"\n\"ui.text.focus\" = { fg = \"lotusInk0\", bg = \"lotusBlue1\", modifiers = [\"bold\"] }\n\n\"ui.cursor\" = { fg = \"lotusSuperBlue\", bg = \"lotusInk3\" }\n\"ui.cursor.primary\" = { fg = \"lotusSuperBlue\", bg = \"lotusPink\" }\n\"ui.cursor.match\" = { fg = \"lotusRed\", modifiers = [\"bold\"] }\n\"ui.highlight\" = { fg = \"lotusInk0\", bg = \"lotusBlue1\" }\n\"ui.menu\" = { fg = \"lotusInk0\", bg = \"lotusBlue1\" }\n\"ui.menu.selected\" = { fg = \"lotusWhite0\", bg = \"lotusBlue3\", modifiers = [\"bold\"] }\n\"ui.menu.scroll\" = { fg = \"lotusInk0\", bg = \"lotusBlue1\" }\n\n\"ui.cursorline.primary\" = { bg = \"lotusWhite1\" }\n\"ui.cursorcolumn.primary\" = { bg = \"lotusWhite1\" }\n\n\"ui.debug.breakpoint\" = \"lotusBlue3\"\n\"ui.debug.active\" = \"lotusRed\"\n\n\"diagnostic.error\" = { underline = { color = \"lotusRed\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"lotusBrightOrange\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"lotusBlue3\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"lotusGreen\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nerror = \"lotusRed\"\nwarning = \"lotusBrightOrange\"\ninfo = \"lotusBlue3\"\nhint = \"lotusGreen\"\n\n## Diff\n\"diff.plus\" = \"lotusBrightGreen\"\n\"diff.minus\" = \"lotusRed\"\n\"diff.delta\" = \"lotusBrightOrange\"\n\n## Syntax highlighting\n\"attribute\" = \"lotusAutumnRed\"\n\"type\" = { fg = \"lotusSuperAqua\" }\n\"type.builtin\" = { fg = \"lotusBlue3\" }\n\"constructor\" = { fg = \"lotusBlue3\" }\n\"constant\" = { fg = \"lotusSuperOrange\" }\n\"constant.numeric\" = { fg = \"lotusSuperPink\" }\n\"constant.character.escape\" = { fg = \"lotusYellow2\" }\n\"string\" = { fg = \"lotusSuperBlue\" }\n\"string.regexp\" = { fg = \"lotusYellow2\" }\n\"string.special.url\" = { fg = \"lotusSuperGreen\" }\n\"string.special.symbol\" = { fg = \"lotusSuperViolet\" }\n\"comment\" = { fg = \"lotusInk1\", modifiers = [\"italic\"] }\n\"variable\" = { fg = \"lotusInk0\" }\n\"variable.builtin\" = { fg = \"lotusAutumnRed\" }\n\"variable.parameter\" = { fg = \"lotusSuperViolet\" }\n\"variable.other.member\" = { fg = \"lotusSuperOrange\" }\n\"label\" = { fg = \"lotusBlue3\" }\n\"punctuation\" = { fg = \"lotusPunctuation\" }\n\"keyword\" = { fg = \"lotusSuperViolet\", modifiers = [\"italic\"] }\n\"keyword.control.return\" = { fg = \"lotusSuperPink\" }\n\"keyword.control.exception\" = { fg = \"lotusSuperPink\" }\n\"keyword.directive\" = { fg = \"lotusAutumnRed\" }\n\"operator\" = { fg = \"lotusBrightPink\", modifiers = [\"bold\"] }\n\"function\" = { fg = \"lotusBlue2\" }\n\"function.builtin\" = { fg = \"lotusCyan\" }\n\"function.macro\" = { fg = \"lotusAutumnRed\" }\n\"tag\" = { fg = \"lotusSuperAqua\" }\n\"namespace\" = { fg = \"lotusSuperOrange\" }\n\"special\" = { fg = \"lotusSuperPink\" }\n\n## Markup modifiers\n\"markup.heading\" = { fg = \"lotusBlue3\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = \"lotusBlue3\"\n\"markup.heading.1\" = { fg = \"lotusYellow\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"lotusBlue3\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"lotusSuperAqua\", modifiers = [\"bold\"] }\n\"markup.list\" = { fg = \"lotusSuperPink\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.text\" = { fg = \"lotusBlue3\" }\n\"markup.link.url\" = { fg = \"lotusCyan\" }\n\"markup.link.label\" = { fg = \"lotusSuperOrange\" }\n\"markup.quote\" = { fg = \"lotusViolet\", modifiers = [\"italic\"] }\n\"markup.raw\" = { fg = \"lotusSuperGreen\" }\n\n[palette]\nlotusWhite0       = \"#FDFCFB\"\nlotusWhite1       = \"#F7ECE1\"\nlotusWhite2       = \"#EAE3D7\"\n\nlotusInk0         = \"#181825\"\nlotusInk1         = \"#8F909C\"\nlotusInk2         = \"#8AA6B8\"\nlotusInk3         = \"#65869C\"\n\nlotusBlue1        = \"#B7C5D8\"\nlotusBlue2        = \"#086187\"\nlotusBlue3        = \"#223249\"\n\nlotusGreen        = \"#76946A\"\nlotusBrightGreen  = \"#2E8B57\"\n\nlotusViolet       = \"#957FB8\"\nlotusBrightViolet = \"#7C3AED\"\n\nlotusAutumnRed    = \"#C34043\"\nlotusRed          = \"#E82424\"\nlotusPink         = \"#D27E99\"\nlotusBrightPink   = \"#FF5D62\"\n\nlotusYellow       = \"#DCA561\"\nlotusYellow2      = \"#AD8700\"\nlotusBrightOrange = \"#FF8800\"\n\nlotusCyan         = \"#0081A7\"\n\nlotusPunctuation  = \"#473428\"\n\n# Max contrast accent colors\nlotusSuperGreen   = \"#00612D\"\nlotusSuperAqua    = \"#006A6A\"\nlotusSuperViolet  = \"#43098A\"\nlotusSuperOrange  = \"#A34100\"\nlotusSuperPink    = \"#861657\"\nlotusSuperBlue    = \"#0D267D\"\n\n"
  },
  {
    "path": "runtime/themes/kanagawa.toml",
    "content": "# Kanagawa\n# Author: zetashift\n\n# Adaptation of https://github.com/rebelot/kanagawa.nvim\n# Original author: rebelot\n# All credits to the original author, the palette is taken from the README\n# because of some theming differences, it's not an exact copy of the original.\n\n## User interface\n\"ui.selection\" = { bg = \"waveBlue2\" }\n\"ui.selection.primary\" = { bg = \"waveBlue2\" }\n\"ui.background\" = { fg = \"fujiWhite\", bg = \"sumiInk3\" }\n\n\"ui.linenr\" = { fg = \"sumiInk6\" }\n\"ui.linenr.selected\" = { fg = \"roninYellow\", modifiers = [\"bold\"] }\n\"ui.gutter\" = { fg = \"sumiInk6\", bg = \"sumiInk4\" }\n\n\"ui.virtual\" = \"sumiInk6\"\n\"ui.virtual.ruler\" = { bg = \"sumiInk4\" }\n\"ui.virtual.inlay-hint\" = \"sumiInk6\"\n\"ui.virtual.jump-label\" = { fg = \"peachRed\", modifiers = [\"bold\"] }\n\n\"ui.statusline\" = { fg = \"oldWhite\", bg = \"sumiInk0\" }\n\"ui.statusline.inactive\" = { fg = \"fujiGray\", bg = \"sumiInk0\" }\n\"ui.statusline.normal\" = { fg = \"sumiInk0\", bg = \"crystalBlue\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"sumiInk0\", bg = \"autumnGreen\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"sumiInk0\", bg = \"oniViolet\", modifiers = [\"bold\"] }\n\n\"ui.bufferline\" = { fg = \"fujiGray\", bg = \"sumiInk0\" }\n\"ui.bufferline.active\" = { fg = \"oldWhite\", bg = \"sumiInk0\" }\n\"ui.bufferline.background\" = { bg = \"sumiInk0\" }\n\n\"ui.popup\" = { fg = \"fujiWhite\", bg = \"sumiInk0\" }\n\"ui.window\" = { fg = \"sumiInk0\" }\n\"ui.help\" = { fg = \"fujiWhite\", bg = \"sumiInk0\" }\n\"ui.text\" = \"fujiWhite\"\n\"ui.text.focus\" = { fg = \"fujiWhite\", bg = \"waveBlue2\", modifiers = [\"bold\"] }\n\n\"ui.cursor\" = { fg = \"waveBlue1\", bg = \"waveAqua2\" }\n\"ui.cursor.primary\" = { fg = \"waveBlue1\", bg = \"fujiWhite\" }\n\"ui.cursor.match\" = { fg = \"waveRed\", modifiers = [\"bold\"] }\n\"ui.highlight\" = { fg = \"fujiWhite\", bg = \"waveBlue2\" }\n\"ui.menu\" = { fg = \"fujiWhite\", bg = \"waveBlue1\" }\n\"ui.menu.selected\" = { fg = \"fujiWhite\", bg = \"waveBlue2\", modifiers = [\"bold\"] }\n\"ui.menu.scroll\" = { fg = \"oldWhite\", bg = \"waveBlue1\" }\n\n\"ui.cursorline.primary\" = { bg = \"sumiInk5\" }\n\"ui.cursorcolumn.primary\" = { bg = \"sumiInk5\" }\n\n\"ui.debug.breakpoint\" = \"springBlue\"\n\"ui.debug.active\" = \"winterRed\"\n\n\"diagnostic.error\" = { underline = { color = \"samuraiRed\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"roninYellow\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"dragonBlue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"waveAqua1\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nerror = \"samuraiRed\"\nwarning = \"roninYellow\"\ninfo = \"dragonBlue\"\nhint = \"waveAqua1\"\n\n## Diff\n\"diff.plus\" = \"autumnGreen\"\n\"diff.minus\" = \"autumnRed\"\n\"diff.delta\" = \"autumnYellow\"\n\n## Syntax highlighting\n\"attribute\" = \"waveRed\"\n\"type\" = \"waveAqua2\"\n\"type.builtin\" = \"springBlue\"\n\"constructor\" = \"springBlue\"\n\"constant\" = \"surimiOrange\"\n\"constant.numeric\" = \"sakuraPink\"\n\"constant.character.escape\" = { fg = \"boatYellow2\", modifiers = [\"bold\"] }\n\"string\" = \"springGreen\"\n\"string.regexp\" = \"boatYellow2\"\n\"string.special.url\" = \"springBlue\"\n\"string.special.symbol\" = \"oniViolet\"\n\"comment\" = \"fujiGray\"\n\"variable\" = \"fujiWhite\"\n\"variable.builtin\" = \"waveRed\"\n\"variable.parameter\" = \"oniViolet2\"\n\"variable.other.member\" = \"carpYellow\"\n\"label\" = \"springBlue\"\n\"punctuation\" = \"springViolet2\"\n\"keyword\" = { fg = \"oniViolet\", modifiers = [\"italic\"] }\n\"keyword.control.return\" = \"peachRed\"\n\"keyword.control.exception\" = \"peachRed\"\n\"keyword.directive\" = \"waveRed\"\n\"operator\" = \"boatYellow2\"\n\"function\" = \"crystalBlue\"\n\"function.builtin\" = \"springBlue\"\n\"function.macro\" = \"waveRed\"\n\"tag\" = \"waveAqua2\"\n\"namespace\" = \"surimiOrange\"\n\"special\" = \"peachRed\"\n\n## Markup modifiers\n\"markup.heading\" = { fg = \"springViolet2\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = \"springViolet2\"\n\"markup.heading.1\" = { fg = \"carpYellow\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"crystalBlue\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"waveAqua2\", modifiers = [\"bold\"] }\n\"markup.list\" = \"sakuraPink\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.text\" = { fg = \"springBlue\" }\n\"markup.link.url\" = { fg = \"lightBlue\" }\n\"markup.link.label\" = \"surimiOrange\"\n\"markup.quote\" = \"oniViolet2\"\n\"markup.raw\" = \"springGreen\"\n\n[palette]\noldWhite = \"#C8C093\"       # dark foreground, e.g. statuslines\nfujiWhite = \"#DCD7BA\"      # default foreground\nfujiGray = \"#727169\"       # comments\nsumiInk0 = \"#16161D\"       # dark background, e.g. statuslines, floating windows\nsumiInk1 = \"#181820\"       # unused\nsumiInk2 = \"#1A1A22\"       # unused\nsumiInk3 = \"#1F1F28\"       # default background\nsumiInk4 = \"#2A2A37\"       # lighter background, e.g. colorcolumns, folds\nsumiInk5 = \"#363646\"       # lighter background, e.g. cursorline\nsumiInk6 = \"#54546D\"       # inlay hints\nwaveBlue1 = \"#223249\"      # popup background, visual selection background\nwaveBlue2 = \"#2D4F67\"      # popup selection background, search background\nwinterGreen = \"#2B3328\"    # diff add background\nwinterYellow = \"#49443C\"   # diff change background\nwinterRed = \"#43242B\"      # diff delete background\nwinterBlue = \"#252535\"     # diff line background\nautumnGreen = \"#76946A\"    # git add\nautumnRed = \"#C34043\"      # git delete\nautumnYellow = \"#DCA561\"   # git change\nsamuraiRed = \"#E82424\"     # diagnostic error\nroninYellow = \"#FF9E3B\"    # diagnostic warning\nwaveAqua1 = \"#6A9589\"      # diagnostic info\ndragonBlue = \"#658594\"     # diagnostic hint\noniViolet = \"#957FB8\"      # statements and keywords\noniViolet2 = \"#B8B4D0\"     # parameters\ncrystalBlue = \"#7E9CD8\"    # functions and titles\nspringViolet1 = \"#938AA9\"  # unused\nspringViolet2 = \"#9CABCA\"  # brackets and punctuation\nspringBlue = \"#7FB4CA\"     # specials and builtins\nlightBlue = \"#A3D4D5\"      # URLs\nwaveAqua2 = \"#7AA89F\"      # types\nwaveAqua3  = \"#68AD99\"     # unused\nwaveAqua4  = \"#7AA880\"     # unused\nwaveAqua5  = \"#6CAF95\"     # unused\nspringGreen = \"#98BB6C\"    # strings\nboatYellow1 = \"#938056\"    # unused\nboatYellow2 = \"#C0A36E\"    # operators, regex\ncarpYellow = \"#E6C384\"     # identifiers\nsakuraPink = \"#D27E99\"     # numbers\nwaveRed = \"#E46876\"        # standout specials 1, e.g. builtin variables\npeachRed = \"#FF5D62\"       # standout specials 2, e.g. exception handling, returns\nsurimiOrange = \"#FFA066\"   # constants, imports, booleans\nkatanaGray = \"#717C7C\"     # unused\n"
  },
  {
    "path": "runtime/themes/kaolin-dark.toml",
    "content": "# Author : thlsrms <thlsrmsdev@gmail.com>\n\n# Original author: kaolin-dark by Ogden Webb: github.com/ogdenwebb/emacs-kaolin-themes\n# Kaolin Dark Theme - A dark jade theme inspired by Sierra.vim : github.com/AlessandroYorba/Sierra\n\n\"attribute\" = \"constant\"\n\"keyword\" = { fg = \"hint\" }\n\"keyword.directive\" = \"info\"\n\"namespace\" = \"constant\"\n\"punctuation\" = \"fg0\"\n\"punctuation.delimiter\" = \"fg0\"\n\"operator\" = \"fg0\"\n\"special\" = \"constant\"\n\"variable.other.member\" = { fg = \"violet7\", modifiers = [\"italic\"] }\n\"variable\" = \"ultramarine4_dark\"\n\"variable.builtin\" = \"hint\"\n\"variable.parameter\" = \"ultramarine4_dark\"\n\"type\" = \"type\"\n\"type.builtin\" = \"info\"\n\"constructor\" = { fg = \"type\" }\n\"function\" = { fg = \"info\" }\n\"function.macro\" = \"constant\"\n\"function.builtin\" = \"selection0\"\n\"tag\" = \"#7aaaa5\"\n\"comment\" = { fg = \"gray0\", modifiers = [\"italic\"] }\n\"constant\" = { fg = \"constant\" }\n\"constant.builtin\" = { fg = \"info\" }\n\"string\" = \"hint\"\n\"constant.numeric\" = \"info\"\n\"constant.character.escape\" = { fg = \"hint\", modifiers = [\"bold\"] }\n\"label\" = \"constant\"\n\"module\" = \"info\"\n\n\"diff.plus\" = \"green0\"\n\"diff.delta\" = \"warn\"\n\"diff.minus\" = \"error\"\n\n\"warning\" = \"warn\"\n\"error\" = \"error\"\n\"info\" = \"info\"\n\"hint\" = \"hint\"\n\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"error\" } }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"warn\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"info\" } }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"hint\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.linenr\" = { fg = \"gray0\" }\n\"ui.linenr.selected\" = { fg = \"gray1\", modifiers = [\"bold\"] }\n\"ui.cursorline\" = { bg = \"bg1\" }\n\"ui.cursorline.secondary\" = { bg = \"bg2\" }\n\"ui.cursorcolumn.primary\" = { bg = \"bg1\" }\n\"ui.cursorcolumn.secondary\" = { bg = \"bg2\" }\n\"ui.statusline\" = { fg = \"info\", bg = \"bg1\" }\n\"ui.statusline.normal\" = { fg = \"hint\", bg = \"bg1\", modifiers = [\"reversed\", \"bold\"] }\n\"ui.statusline.insert\" = { fg = \"green0\", bg = \"bg1\", modifiers = [\"reversed\", \"bold\"] }\n\"ui.statusline.select\" = { fg = \"ultramarine4_dark\", bg = \"bg1\", modifiers = [\"reversed\", \"bold\"] }\n\"ui.statusline.inactive\" = { fg = \"gray0\", bg = \"bg1\" }\n\"ui.popup\" = { bg = \"bg1\" }\n\"ui.window\" = { fg= \"bg1\", bg = \"bg0\" }\n\"ui.help\" = { bg = \"bg1\", fg = \"fg0\" }\n\"ui.text\" = { fg = \"fg1\" }\n\"ui.text.focus\" = { fg = \"selection0\" }\n\"ui.selection\" = { bg = \"selection1\" }\n\"ui.selection.primary\" = { bg = \"selection1\" }\n\"ui.cursor.primary\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"bg1\", bg = \"ultramarine4_dark\" }\n\"ui.menu\" = { fg = \"fg0\", bg = \"bg1\" }\n\"ui.menu.selected\" = { fg = \"selection0\", bg = \"bg2\", modifiers = [\"bold\"] }\n\"ui.virtual.wrap\" = \"bg2\"\n\"ui.virtual.whitespace\" = \"fg1\"\n\"ui.virtual.indent-guide\" = \"bg2\"\n\"ui.virtual.ruler\" = { bg = \"bg1\" }\n\"ui.virtual.inlay-hint\" = \"gray1\"\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"gray1\", modifiers = [\"dim\"] }\n\"ui.virtual.inlay-hint.type\" = { fg = \"gray1\", modifiers = [\"dim\"] }\n\"ui.debug.breakpoint\" = \"error\"\n\"ui.debug.active\" = \"warn\"\n\n\"markup.heading\" = \"info\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"warn\", underline = { style = \"line\" } }\n\"markup.link.text\" = \"selection0\"\n\"markup.raw\" = \"selection0\"\n\n[palette]\n# kaolin-dark palette\nbg0 = \"#18181b\" # black1\nbg1 = \"#222225\" # black2\nbg2 = \"#303035\" # black4\nfg0 = \"#e6e6e8\" # white1\nfg1 = \"#adadb9\" # whiet4\ngray0 = \"#545c5e\" # gray3\ngray1 = \"#919a9c\" # gray9\ngreen0 = \"#6fb593\" # spring-green3\nselection0 = \"#68f3ca\" # aquamarine3\nselection1 = \"#2e403b\" # aquamarine6\ntype = \"#cd9575\" # vermilion4\nhint = \"#4d9391\" # teal1\ninfo = \"#80bcb6\" # teal4\nwarn = \"#dbac66\" # orange1\nerror = \"#cd5c60\" # red1\nconstant = \"#ab98b5\" # purple4\nultramarine4_dark = \"#968cc7\"\nviolet7 = \"#766884\"\n"
  },
  {
    "path": "runtime/themes/kaolin-light.toml",
    "content": "# Author : thlsrms <thlsrmsdev@gmail.com>\n\n# Original author: kaolin-dark by Ogden Webb: github.com/ogdenwebb/emacs-kaolin-themes\n# Kaolin Light Theme - Light variant of the original Kaolin Dark Theme\n\ninherits = \"kaolin-dark\"\n\n\"keyword.directive\" = \"selection0\"\n\"special\" = \"ultramarine1\"\n\"variable.other.member\" = { fg = \"constant\", modifiers = [\"italic\"] }\n\"variable\" = \"ultramarine1\"\n\"variable.parameter\" = \"constant\"\n\"type.builtin\" = \"selection0\"\n\"function\" = { fg = \"selection0\" }\n\"function.builtin\" = \"ultramarine1\"\n\"tag\" = { fg = \"hint\", modifiers = [\"italic\"] }\n\"constant.builtin\" = { fg = \"selection0\" }\n\"string\" = \"green0\"\n\"constant.numeric\" = \"selection0\"\n\"module\" = \"selection0\"\n\n\"ui.linenr.selected\" = { fg = \"green1\", modifiers = [\"bold\"] }\n\"ui.statusline\" = { fg = \"selection0\", bg = \"bg1\" }\n\"ui.statusline.normal\" = { fg = \"hint\", bg = \"bg1\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"warn\", bg = \"bg1\", modifiers = [\"reversed\", \"bold\"] }\n\"ui.statusline.select\" = { fg = \"constant\", bg = \"bg1\", modifiers = [\"reversed\", \"bold\"] }\n\"ui.text\" = { fg = \"fg0\" }\n\"ui.text.focus\" = { fg = \"green1\", modifiers = [\"bold\"] }\n\"ui.cursor.match\" = { fg = \"fg1\", bg = \"gray0\" }\n\"ui.menu.selected\" = { fg = \"green1\", bg = \"bg2\", modifiers = [\"bold\"] }\n\"ui.virtual.wrap\" = \"fg1\"\n\"ui.virtual.indent-guide\" = \"fg1\"\n\"ui.virtual.inlay-hint\" = \"gray0\"\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"gray0\", modifiers = [\"italic\"] }\n\"ui.virtual.inlay-hint.type\" = { fg = \"gray0\", modifiers = [\"italic\"] }\n\n\"markup.heading\" = { fg = \"ultramarine1\", modifiers = [\"bold\"] }\n\"markup.link.url\" = { fg = \"info\", underline = { style = \"line\" } }\n\"markup.link.text\" = \"info\"\n\"markup.raw\" = \"constant\"\n\n[palette]\n# kaolin-light palette\nbg0  = \"#edeeeb\" # kaolin-light-bg1\nbg1  = \"#dfe1dc\" # kaolin-light-bg2\nbg2  = \"#d1d4cd\" # kaolin-light-bg3\nfg0 = \"#383e3f\" # gray1\nfg1 = \"#bebec4\" # white4\ngray0 = \"#7c878a\" # gray7\ngreen0 = \"#39854c\" # erin2\ngreen1 = \"#18a318\" # green2\nselection0 = \"#4c7a90\" # azure4\nselection1 = \"#d3e4f0\" # azure9\ntype = \"#e36b3f\" # vermilion3\nhint = \"#13665f\" # teal2\ninfo = \"#3b84cc\" # azure1\nwarn = \"#dbac66\" # orange1\nerror = \"#e84c58\" # red3\nconstant = \"#845A84\" # magenta4\nultramarine1 = \"#6d46e3\" # ultramarine1\n"
  },
  {
    "path": "runtime/themes/kaolin-valley-dark.toml",
    "content": "# Author : thlsrms <thlsrmsdev@gmail.com>\n\n# Original author: kaolin-valley-dark by Ogden Webb: github.com/ogdenwebb/emacs-kaolin-themes\n# Kaolin Valley Dark Theme - Colorful Kaolin theme with brown background\n\ninherits = \"kaolin-dark\"\n\n\"attribute\" = \"fg1\"\n\"keyword\" = { fg = \"teal3\" }\n\"keyword.directive\" = \"green0\"\n\"operator\" = \"teal3\"\n\"special\" = \"ultramarine3\"\n\"variable.other.member\" = { fg = \"selection0\", modifiers = [\"italic\"] }\n\"variable\" = \"constant\"\n\"variable.builtin\" = \"teal3\"\n\"variable.parameter\" = \"constant\"\n\"type.builtin\" = \"aquamarine3\"\n\"function\" = { fg = \"valley-dark-fn\" }\n\"function.macro\" = \"valley-dark-fn\"\n\"function.builtin\" = \"aquamarine3\"\n\"tag\" = \"green0\"\n\"constant.builtin\" = { fg = \"aquamarine3\" }\n\"string\" = \"fg1\"\n\"constant.numeric\" = \"aquamarine3\"\n\"constant.character.escape\" = \"fg1\"\n\"label\" = \"ultramarine3\"\n\"module\" = \"green0\"\n\n\"diff.delta\" = \"type\"\n\n\"ui.linenr.selected\" = { fg = \"warn\", modifiers = [\"bold\"] }\n\"ui.statusline\" = { fg = \"fg0\", bg = \"bg1\" }\n\"ui.statusline.normal\" = { fg = \"warn\", bg = \"bg1\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"hint\", bg = \"bg1\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"constant\", bg = \"bg1\", modifiers = [\"bold\"] }\n\"ui.text.focus\" = { fg = \"selection0\", bg = \"bg1\" }\n\"ui.cursor.match\" = { fg = \"bg0\", bg = \"selection0\" }\n\"ui.menu\" = { fg = \"fg1\", bg = \"bg1\" }\n\"ui.menu.selected\" = { fg = \"selection0\", bg = \"bg1\", modifiers = [\"bold\"] }\n\"ui.virtual.wrap\" = \"gray1\"\n\"ui.virtual.whitespace\" = \"gray1\"\n\"ui.virtual.indent-guide\" = \"gray1\"\n\"ui.virtual.ruler\" = { bg = \"bg2\" }\n\"ui.virtual.inlay-hint\" = \"gray0\"\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"gray0\", modifiers = [\"italic\"] }\n\"ui.virtual.inlay-hint.type\" = { fg = \"gray0\", modifiers = [\"italic\"] }\n\n\"markup.heading\" = \"type\"\n\"markup.link.url\" = { fg = \"constant\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"valley-dark-fn\"\n\n[palette]\n# kaolin-valley-dark palette\nbg0 = \"#262221\" # valley-dark-bg1\nbg1 = \"#2e2a29\" # valley-dark-bg2\nbg2 = \"#383030\" # valley-dark-bg4\nfg0 = \"#eee6d3\" # amber9\nfg1 = \"#cea2ca\" # magenta3\ngray0 = \"#635c4a\" # valley-dark-comment\ngray1 = \"#52413f\" # brown2\ngreen0 = \"#91f368\" # harlequin3\nselection0 = \"#ee7042\" # vermilion3\nselection1 = \"#402e2e\" # red6\ntype = \"#eed891\" # amber3\nhint = \"#6bd9db\" # cyan3\ninfo = \"#41b0f3\" # capri3\nwarn = \"#cfb05f\" # amber1\nerror = \"#e84c58\" # red3\nconstant = \"#ef6787\" # crimson3\nvalley-dark-fn = \"#7ed7e6\"\nteal3 = \"#49bdb0\"\naquamarine3 = \"#53e6b5\"\nultramarine3 = \"#9587dd\"\n"
  },
  {
    "path": "runtime/themes/kinda_nvim.toml",
    "content": "# Theme  : kinda_nvim (dark)\n# \n# Author : Strash familev.imen.otchestvovich@gmail.com\n# License: MIT\n# \n# GitHub : https://github.com/strash/kinda_nvim.hx\n\n\"ui.background\" = { bg =\"bg\", fg = \"fg_4\" }\n\"ui.background.separator\" = { bg = \"bg\", fg = \"fg_4\" }\n\n\"ui.cursor.normal\" = { bg = \"fg_2\", fg = \"bg\", modifiers = [ \"slow_blink\" ] }\n\"ui.cursor.insert\" = { bg = \"fg_secondary\", fg = \"bg\" }\n\"ui.cursor.select\" = { bg = \"fg_tertiary\", fg = \"bg\" }\n\"ui.cursor.match\" = { bg = \"bg_3\" }\n\"ui.cursor.primary.normal\" = { bg = \"fg\", fg = \"bg\", modifiers = [ \"slow_blink\" ] }\n\"ui.cursor.primary.insert\" = { bg = \"fg_secondary\", fg = \"bg\" }\n\"ui.cursor.primary.select\" = { bg = \"fg_tertiary\", fg = \"bg\" }\n\n\"ui.debug.breakpoint\" = { fg = \"fg_hint\" }\n\n\"ui.gutter\" = { bg = \"bg\", fg = \"fg_4\" }\n\"ui.linenr\" = { bg = \"bg\", fg = \"fg_4\" }\n\"ui.gutter.selected\" = { bg = \"bg\", fg = \"fg_1\" }\n\"ui.linenr.selected\" = { bg = \"bg\", fg = \"fg_1\", modifiers = [ \"bold\" ] }\n\n\"ui.statusline\" = { bg = \"bg\", fg = \"fg\" }\n\"ui.statusline.inactive\" = { bg = \"bg\", fg = \"fg\", modifiers = [ \"dim\" ] }\n\"ui.statusline.normal\" = { fg = \"fg_primary\"}\n\"ui.statusline.insert\" = { fg = \"fg_secondary\"}\n\"ui.statusline.select\" = { fg = \"fg_tertiary\"}\n\n\"ui.bufferline.active\" = { bg = \"bg\", fg = \"fg\" }\n\"ui.bufferline\" = { bg = \"bg\", fg = \"fg\", modifiers = [ \"dim\" ] }\n\n\"ui.popup\" = { bg = \"bg_2\", fg = \"fg_3\" }\n\"ui.popup.info\" = { bg = \"bg_2\", fg = \"fg_3\" }\n\n\"ui.picker.header\" = { fg = \"fg_3\", modifiers = [ \"bold\" ] }\n\"ui.picker.header.column.active\" = { fg = \"fg\", modifiers = [ \"bold\" ] }\n\n\"ui.window\" = { fg = \"fg_4\" }\n\n\"ui.help\" = { bg = \"bg_2\", fg = \"fg_3\" }\n\n\"ui.text\" = { fg = \"fg\" }\n\"ui.text.focus\" = { fg = \"fg\", modifiers = [ \"bold\" ] }\n\"ui.text.inactive\" = { fg = \"fg_2\" }\n\"ui.text.info\" = { fg = \"fg_2\" }\n\"ui.text.directory\" = { fg = \"fg_secondary\" }\n\n\"ui.virtual\" = { fg = \"fg_4\" }\n\"ui.virtual.ruler\" = { bg = \"bg_1\" }\n\"ui.virtual.indent-guide\" = { fg = \"bg_4\" }\n\"ui.virtual.inlay-hint\" = { fg = \"fg_2\", modifiers = [ \"dim\" ] }\n\"ui.virtual.wrap\" = { fg = \"fg_4\" }\n\"ui.virtual.jump-label\" = { fg = \"fg_4\" }\n\n\"ui.menu\" = { bg = \"bg_2\", fg = \"fg_2\" }\n\"ui.menu.selected\" = { bg = \"bg_3\", fg = \"fg\" }\n\"ui.menu.scroll\" = { bg = \"bg_1\", fg = \"bg_4\" }\n\n\"ui.selection\" = { bg = \"bg_3\", modifiers = [ \"dim\" ] }\n\"ui.selection.primary\" = { bg = \"bg_4\" }\n\n\"ui.highlight\" = { bg = \"bg_1\" }\n\"ui.highlight.frameline\" = { bg = \"bg_warn\" }\n\n\"ui.cursorline.primary\" = { bg = \"bg_1\" }\n\"ui.cursorline.secondary\" = { bg = \"bg_1\" }\n\"ui.cursorcolumn.primary\" = { bg = \"bg_1\" }\n\"ui.cursorcolumn.secondary\" = { bg = \"bg_1\" }\n\n\"error\" = { fg = \"fg_err\" }\n\"warning\" = { fg = \"fg_warn\" }\n\"info\" = { fg = \"fg_info\" }\n\"hint\" = { fg = \"fg_hint\" }\n\n\"diagnostic.error\" = { bg = \"bg_err\", fg = \"fg_err\" }\n\"diagnostic.warning\" = { bg = \"bg_warn\", fg = \"fg_warn\" }\n\"diagnostic.info\" = { bg = \"bg_info\", fg = \"fg_info\" }\n\"diagnostic.hint\" = { bg = \"bg_hint\", fg = \"fg_hint\" }\n\"diagnostic.unnecessary\" = { bg = \"bg_info\", fg = \"fg_info\" }\n\"diagnostic.deprecated\" = { bg = \"bg_err\", fg = \"fg_err\", modifiers = [ \"crossed_out\" ] }\n\n\"tabstop\" = { modifiers = [ \"italic\" ] }\n\n\"markup\" = { bg = \"bg_2\", fg = \"fg_2\" }\n\n\"attribute\" = { fg = \"fg_warn\" }\n\n\"type\" = { fg = \"fg_primary\" }\n\"type.builtin\" = { fg = \"fg_primary_variant\" }\n\"type.parameter\" = { fg = \"fg_primary_variant\" }\n\"type.enum\" = { fg = \"fg_primary\" }\n\"type.enum.variant\" = { fg = \"fg_primary_variant\" }\n\n\"constructor\" = { fg = \"fg_primary\", modifiers = [ \"bold\" ] }\n\n\"constant\" = { fg = \"fg\", modifiers = [ \"bold\" ] }\n\"constant.builtin\" = { fg = \"fg_primary_variant\", modifiers = [ \"bold\" ] }\n\"constant.character\" = { fg = \"fg_tertiary_variant\", modifiers = [ \"bold\" ] }\n\"constant.numeric\" = { fg = \"fg_err\" }\n\n\"string\" = { fg = \"fg_2\" }\n\"string.regexp\" = { fg = \"fg_tertiary_variant\" }\n\"string.special.url\" = { fg = \"fg_2\", modifiers = [ \"underlined\" ] }\n\n\"comment\" = { fg = \"fg_secondary_variant\", modifiers = [ \"italic\" ] }\n\n\"variable\" = { fg = \"fg_hint\" }\n\"variable.builtin\" = { fg = \"fg_tertiary\" }\n\"variable.parameter\" = { fg = \"fg_hint\" }\n\"variable.other\" = { fg = \"fg_tertiary\" }\n\"variable.other.member\" = { fg = \"fg_secondary\" }\n\n\"label\" = { fg = \"fg_1\" }\n\n\"punctuation.delimiter\" = { fg = \"fg_1\" }\n\"punctuation.bracket\" = { fg = \"fg_3\" }\n\"punctuation.special\" = { fg = \"fg_tertiary_variant\" }\n\n\"keyword\" = { fg = \"fg_tertiary\" }\n\"keyword.directive\" = { fg = \"fg_secondary\", modifiers = [ \"bold\" ] }\n\"keyword.control.import\" = { fg = \"fg_tertiary\" }\n\"keyword.control.return\" = { fg = \"fg_tertiary\" }\n\"keyword.control.exception\" = { fg = \"fg_tertiary\" }\n\"keyword.function\" = { fg = \"fg_tertiary\", modifiers = [ \"bold\" ] }\n\"keyword.storage\" = { fg = \"fg_tertiary\", modifiers = [ \"bold\" ] }\n\n\"operator\" = { fg = \"fg_2\" }\n\n\"function\" = { fg = \"fg_secondary\" }\n\n\"tag\" = { fg = \"fg_hint\" }\n\n\"namespace\" = { fg = \"fg_primary\" }\n\n\"special\" = { fg = \"fg_tertiary_variant\" }\n\n\"markup.heading\" = { fg = \"fg_primary\" }\n\"markup.bold\" = { modifiers = [ \"bold\" ] }\n\"markup.italic\" = { modifiers = [ \"italic\" ] }\n\"markup.strikethrough\" = { modifiers = [ \"crossed_out\" ] }\n\"markup.lint\" = { modifiers = [ \"underlined\" ] }\n\"markup.raw\" = { fg = \"fg_primary\" }\n\n\"diff.plus\" = { fg = \"fg_primary\", bg = \"bg_hint\" }\n\"diff.delta\" = { fg = \"fg_2\", bg = \"bg_3\" }\n\"diff.minus\" = { fg = \"fg_err\", bg = \"bg_err\" }\n\"diff.plus.gutter\" = { fg = \"fg_primary\" }\n\"diff.delta.gutter\" = { fg = \"fg_2\" }\n\"diff.minus.gutter\" = { fg = \"fg_err\" }\n\n\n[palette]\nfg = \"#B6BFBC\"\nfg_1 = \"#A0A8A5\"\nfg_2 = \"#969E9B\"\nfg_3 = \"#838A87\"\nfg_4 = \"#4C5955\"\nfg_err = \"#C27280\"\nfg_warn = \"#B8A26C\"\nfg_info = \"#6C94B8\"\nfg_hint = \"#32878F\"\nfg_primary = \"#12B27D\"\nfg_secondary = \"#6797C2\"\nfg_tertiary = \"#9C59B2\"\nfg_primary_variant = \"#0F996B\"\nfg_secondary_variant = \"#526B82\"\nfg_tertiary_variant = \"#945EA6\"\n\nbg = \"#00120C\"\nbg_1 = \"#001F14\"\nbg_2 = \"#001C13\"\nbg_3 = \"#002E1F\"\nbg_4 = \"#003624\"\nbg_err = \"#382125\"\nbg_warn = \"#383221\"\nbg_info = \"#212D38\"\nbg_hint = \"#213638\"\n\n"
  },
  {
    "path": "runtime/themes/kinda_nvim_light.toml",
    "content": "# Theme  : kinda_nvim_light (light)\n# \n# Author : Strash familev.imen.otchestvovich@gmail.com\n# License: MIT\n# \n# GitHub : https://github.com/strash/kinda_nvim.hx\n\ninherits = \"kinda_nvim\"\n\n[palette]\nfg = \"#414D49\"\nfg_1 = \"#62736D\"\nfg_2 = \"#738780\"\nfg_3 = \"#8FA8A0\"\nfg_4 = \"#BECFC9\"\nfg_err = \"#BF0020\"\nfg_warn = \"#B58200\"\nfg_info = \"#005BAB\"\nfg_hint = \"#119CA8\"\nfg_primary = \"#008C5D\"\nfg_secondary = \"#2470B2\"\nfg_tertiary = \"#9847B2\"\nfg_primary_variant = \"#2F9C77\"\nfg_secondary_variant = \"#759ABA\"\nfg_tertiary_variant = \"#A860BF\"\n\nbg = \"#F2F5F4\"\nbg_1 = \"#EDF0EF\"\nbg_2 = \"#FCFFFE\"\nbg_3 = \"#F7FAF9\"\nbg_4 = \"#E6E8E7\"\nbg_err = \"#E8D8DB\"\nbg_warn = \"#E8E3D8\"\nbg_info = \"#D3DCE3\"\nbg_hint = \"#D3E2E3\"\n\n"
  },
  {
    "path": "runtime/themes/lapis_aquamarine.toml",
    "content": "# Author: spentbliss <zyhkekrz.hatbox475@passinbox.com>\n# License: MIT (originally by Alex Barnett)\n\n\"ui.background\" = { fg = \"fg\", bg = \"bg\" } # file picker border color\n\"ui.text\" = \"fg\"\n\"ui.text.focus\" = { fg = \"bg\", bg = \"fg\" } # file picker selection\n\"ui.cursor\" = { bg = \"blue\", fg = \"bg\" }\n\"ui.linenr\" = \"grey\"\n\"ui.statusline\" = { fg = \"fg\" }\n\"ui.selection\" = \"green\"\n\"ui.selection.primary\" = { bg = \"bg_highlight\" } \n\"ui.virtual.ruler\" = { bg = \"bg_highlight\" }\n\n# Syntax Highlighting for Markdown \n\"markup.raw\" = { fg = \"purple\", bg = \"bg\" } \n\"markup.raw.inline\" = {fg = \"fg\" }\n\"markup.heading.1\" = { fg = \"#46D9FF\", bg = \"#11313B\" }   # cyan\n\"markup.heading.2\" = { fg = \"#C678DD\", bg = \"#2D2233\" }   # magenta\n\"markup.heading.3\" = { fg = \"#98BE65\", bg = \"#253027\" }   # green\n\"markup.heading.4\" = { fg = \"#A8A1E1\", bg = \"#2A2738\" }   # purple\n\"markup.heading.5\" = { fg = \"#ECBE7B\", bg = \"#3A3223\" }   # yellow\n\"markup.heading.6\" = { fg = \"#46D9FF\", bg = \"#1E2A30\" }   # cyan again\n\"markup.list\" = { fg = \"purple\" }\n\"markup.bold\" = { fg = \"fg\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"fg\" }\n\"markup.strikethrough\" = { fg = \"red\", modifiers = [\"crossed_out\"] }\n\"markup.link\" = { fg = \"cyan\" }\n\"markup.quote\" = { fg = \"fg\" }\n\n# Syntax Highlighting for Code\n\"comment\" = { fg = \"grey\", modifiers = [\"italic\"] }\n\"comment.line\" = { fg = \"grey\", modifiers = [\"italic\"] }\n\"comment.block\" = { fg = \"grey\", modifiers = [\"italic\"] }\n\"comment.documentation\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\n\"keyword\" = \"blue\"\n\"keyword.storage\" = \"blue\" # let keyword in rust \n\"keyword.storage.type\" = \"blue\" # keywords describing how things are stored, class, var, let, etc\n\"keyword.storage.modifier\" = \"fg\" # mut keyword\n\"keyword.control.import\" = \"blue\" # use keyword in rust\n\"keyword.control.export\" = \"blue\" \n\"keyword.control.conditional\" = \"blue\" # if, else\n\"keyword.directive\" = \"blue\"\n\"keyword.control.repeat\" = \"blue\" # for, while, loop\n\"keyword.operator\" = \"blue\" # or, in keywords\n\"keyword.function\" = \"blue\" # function keyword color\n\n\"type\" = \"green\" \n\"type.builtin\" = \"green\" # primitive types int, usize\n\"type.parameter\" = \"green\"\n\"type.enum\" = \"cyan\"\n\n\"function\" = \"purple\" # color for function NAME not the keyword fn or func\n\"function.builtin\" = \"purple\"\n\"function.method\" = \"blue\"\n\n\"variable\" = \"fg\"\n\"variable.builtin\" = \"fg\"\n\"variable.parameter\" = \"cyan\"\n\n\"string\" = \"green\"\n\"string.special\" = \"green\"\n\n\"constant\" = \"cyan\"\n\"constant.builtin\" = \"blue\" # true, false, nil\n\"constant.numeric\" = \"cyan\" # int & float\n\"constant.character\" = \"yellow\" # escape character\n\n\"operator\" = \"fg\"\n\n# html tags\n\"tag\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\"attribute\" = \"blue\"\n\n\"namespace\" = \"fg\"\n\"macro\" = \"orange\"\n\"label\" = \"red\"\n\n# Interface specific\n\"ui.cursorline.primary\" = { bg = \"bg_highlight\" }\n\"ui.cursorline.secondary\" = { bg = \"bg_alt\" }\n\"ui.cursorcolumn.primary\" = { bg = \"bg_highlight\" }\n\"ui.cursorcolumn.secondary\" = { bg = \"bg_alt\" }\n\"ui.statusline.normal\" = { fg = \"bg\", bg = \"cyan\" }\n\"ui.statusline.insert\" = { fg = \"bg\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"bg\", bg = \"purple\" }\n\n# Diagnostic styles\n\"warning\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"diagnostic.error\" = { fg = \"grey\" }\n\"diagnostic.warning\" = { fg = \"grey\" }\n\"diagnostic.info\" = { fg = \"grey\" }\n\"diagnostic.hint\" = { fg = \"grey\" }\n\n# Git changes indicator\n\"diff.plus\" = \"green\"\n\"diff.plus.gutter\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.minus.gutter\" = \"red\"\n\"diff.delta\" = \"fg\"\n\"diff.delta.gutter\" = \"fg\"\n\"diff.delta.moved\" = \"orange\"\n\"diff.delta.conflict\" = \"purple\"\n\n# Popups and Menus\n\"ui.popup\" = { fg = \"fg\", bg = \"bg\" }\n\"ui.popup.info\" = { fg = \"fg\", bg = \"bg\" }\n\"ui.menu\" = { fg = \"fg\", bg = \"bg\" }\n\"ui.menu.selected\" = { fg = \"bg\", bg = \"fg\" }\n\n# Additional overrides\n\"ui.virtual.whitespace\" = \"grey\"\n\"ui.virtual.indent-guide\" = { fg = \"indent_color\", underline.style = \"dotted\" }\n\n[palette]\nbg = \"#1B1F27\"\nfg = \"#D6E2FF\" \ngrey = \"#7183A9\"\nblue = \"#83ABFC\" \ngreen = \"#ABFC83\"\ncyan = \"#84FCD4\"\nred = \"#FC83AB\" \nyellow = \"#FCD583\"\npink = \"#FC83D6\"\norange = \"#FCAB83\"\npurple = \"#D483FC\"\nbg_alt = \"#14181D\"\nbg_highlight = \"#43537A\"\nindent_color = \"#2E3953\"\n"
  },
  {
    "path": "runtime/themes/licenses/akari.license",
    "content": "MIT License\n\nCopyright (c) 2026 Shu Kutsuzawa\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/ashen.license",
    "content": "MIT License\n\nCopyright (c) 2025 Daniel Fichtinger\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "runtime/themes/licenses/aura.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 - * Dalton Menezes\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/carbonfox.license",
    "content": "MIT License\n\nCopyright (c) 2021 James Simpson\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "runtime/themes/licenses/dark-synthwave.license",
    "content": "MIT License\n\nCopyright (c) 2021 Aaron Young\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/doom-one.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2025 NTBBloodbath\n\nThis theme has been ported by spentbliss <zyhkekrz.hatbox475@passinbox.com>.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/everforest.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 sainnhe\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/faded-prism.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023-2025 Ryan Brue\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/jetbrains_cyan_light.LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 CloudCannon\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/kinda_nvim.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2025 Strash\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/lapis_aquamarine.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2025 Alex Barnett\n\nThis theme has been ported by spentbliss <zyhkekrz.hatbox475@passinbox.com>.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/modus_vivendi.LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    modus-themes\n    Copyright (C) 2019-2023  Free Software Foundation, Inc.\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    modus-themes  Copyright (C) 2019-2023  Free Software Foundation, Inc.\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "runtime/themes/licenses/modus_vivendi_deuteranopia.LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    modus-themes\n    Copyright (C) 2019-2023  Free Software Foundation, Inc.\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    modus-themes  Copyright (C) 2019-2023  Free Software Foundation, Inc.\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "runtime/themes/licenses/modus_vivendi_tinted.LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    modus-themes\n    Copyright (C) 2019-2023  Free Software Foundation, Inc.\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    modus-themes  Copyright (C) 2019-2023  Free Software Foundation, Inc.\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "runtime/themes/licenses/modus_vivendi_tritanopia.LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    modus-themes\n    Copyright (C) 2019-2023  Free Software Foundation, Inc.\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    modus-themes  Copyright (C) 2019-2023  Free Software Foundation, Inc.\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "runtime/themes/licenses/noctis.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 Liviu Schera\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/poimandres.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 drcmda\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/serika-syntax.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 arturoalviar\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/sonokai.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 sainnhe\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/starlight.LICENSE",
    "content": "This is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, compile, sell, or\ndistribute this software, either in source code form or as a compiled\nbinary, for any purpose, commercial or non-commercial, and by any\nmeans.\n\nIn jurisdictions that recognize copyright laws, the author or authors\nof this software dedicate any and all copyright interest in the\nsoftware to the public domain. We make this dedication for the benefit\nof the public at large and to the detriment of our heirs and\nsuccessors. We intend this dedication to be an overt act of\nrelinquishment in perpetuity of all present and future rights to this\nsoftware under copyright law.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\nOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n\nFor more information, please refer to <https://unlicense.org>\n"
  },
  {
    "path": "runtime/themes/licenses/vesper.LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 Rauno Freiberg\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "runtime/themes/licenses/zenburn.license",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "runtime/themes/material_darker.toml",
    "content": "# Material Theme <https://material-theme.com/> for Helix Editor\n\ninherits = \"material_deep_ocean\"\n\n[palette]\nbg = \"#212121\"\ntext = \"#b0bec5\"\n\ngray = \"#616161\"\nerror = \"#ff5370\"\n\ndisabled = \"#474747\"\n\naccent = \"#ff9800\"\n\nactive = \"#323232\"\nhighlight = \"#3f3f3f\"\n\ncomment = \"#616161\"\n\nselection = \"#404040\"\n"
  },
  {
    "path": "runtime/themes/material_deep_ocean.toml",
    "content": "# Material Theme <https://material-theme.com/> for Helix Editor\n\n# Syntax Highlighting\n\n\"type\" = \"purple\"\n\n\"constructor\" = \"blue\"\n\n\"constant\" = \"yellow\"\n\n\"string\" = \"green\"\n\"string.regexp\" = \"yellow\"\n\"string.special\" = \"blue\"\n\n\"comment\" = { fg = \"comment\" }\n\n\"variable\" = \"text\"\n\"variable.parameter\" = { fg = \"orange\" }\n\"variable.builtin\" = \"yellow\"\n\n\"label\" = \"orange\"\n\n\"punctuation\" = \"cyan\"\n\n\"keyword\" = \"purple\"\n\"keyword.storage\" = \"cyan\"\n\n\"operator\" = \"cyan\"\n\n\"function\" = \"blue\"\n\"function.macro\" = \"cyan\"\n\n\"tag\" = \"red\"\n\"attribute\" = \"purple\"\n\n\"namespace\" = { fg = \"yellow\" }\n\n\"special\" = \"cyan\"\n\n\"markup.heading.marker\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\"markup.heading.1\" = \"cyan\"\n\"markup.heading.2\" = \"red\"\n\"markup.heading.3\" = \"green\"\n\"markup.heading.4\" = \"yellow\"\n\"markup.heading.5\" = \"blue\"\n\"markup.heading.6\" = \"orange\"\n\"markup.list\" = \"purple\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"green\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"blue\"\n\"markup.raw\" = \"text\"\n\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"blue\"\n\n# User Interface\n\n\"ui.background\" = { bg = \"bg\", fg = \"text\" }\n\"ui.text\" = { fg = \"text\" }\n\"ui.text.directory\" = { fg = \"blue\" }\n\n\"ui.statusline\" = { bg = \"bg\", fg = \"text\" }\n\"ui.statusline.inactive\" = { bg = \"bg\", fg = \"disabled\" }\n\"ui.statusline.normal\" = { bg = \"blue\", fg = \"bg\" }\n\"ui.statusline.insert\" = { bg = \"green\", fg = \"bg\" }\n\"ui.statusline.select\" = { bg = \"purple\", fg = \"bg\" }\n\n\n\"ui.selection\" = { bg = \"selection\" }\n\n\"ui.linenr\" = { fg = \"line-number\" }\n\"ui.linenr.selected\" = { fg = \"accent\" }\n\n\"ui.cursor\" = { bg = \"highlight\", fg = \"white\" }\n\n\"ui.cursor.primary\" = { bg = \"white\", fg = \"gray\" }\n\"ui.cursorline.primary\" = { bg = \"active\" }\n\n\"ui.virtual\" = { fg = \"gray\" }\n\"ui.virtual.ruler\" = { bg = \"highlight\" }\n\"ui.virtual.indent-guide\" = { fg = \"gray\" }\n\n\"ui.highlight\" = { bg = \"highlight\" }\n\n\"ui.menu\" = { bg = \"highlight\", fg = \"text\" }\n\"ui.menu.selected\" = { bg = \"blue\", fg = \"bg\" }\n\n\"ui.help\" = { bg = \"highlight\", fg = \"text\" }\n\n\"ui.popup\" = { bg = \"highlight\", fg = \"text\" }\n\n\"ui.virtual.jump-label\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\nwarning = \"yellow\"\nerror = \"error\"\ninfo = \"blue\"\nhint = \"purple\"\n\n\"diagnostic\" = { underline = { color = \"error\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"purple\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"error\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"]}\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"]}\n\n\n[palette]\nbg = \"#0f111a\"\ntext = \"#a6accd\"\n\nwhite = \"#eeffff\"\ngreen = \"#c3e88d\"\nyellow = \"#ffcb6b\"\nblue = \"#82aaff\"\nred = \"#f07178\"\npurple = \"#c792ea\"\norange = \"#f78c6c\"\ncyan = \"#89ddff\"\ngray = \"#717cb4\"\nerror = \"#ff5370\"\n\ndisabled = \"#464b5d\"\n\naccent = \"#84ffff\"\n\nactive = \"#1a1c25\"\nhighlight = \"#1f2233\"\n\ncomment = \"#464b5d\"\n\nselection = \"#1f2233\"\n\nline-number = \"#3b3f51\"\n"
  },
  {
    "path": "runtime/themes/material_oceanic.toml",
    "content": "# Material Theme <https://material-theme.com/> for Helix Editor\n\ninherits = \"material_deep_ocean\"\n\n[palette]\nbg = \"#25363b\"\ntext = \"#b0bec5\"\n\ngray = \"#546e7a\"\n\ndisabled = \"#415967\"\n\naccent = \"#009688\"\n\nactive = \"#314549\"\nhighlight = \"#425b67\"\n\ncomment = \"#546e7a\"\n\nselection = \"#395b65\"\n\nline-number = \"#355058\"\n"
  },
  {
    "path": "runtime/themes/material_palenight.toml",
    "content": "# Material Theme <https://material-theme.com/> for Helix Editor\n\ninherits = \"material_deep_ocean\"\n\n[palette]\nbg = \"#292d3e\"\ntext = \"#a6accd\"\n\ndisabled = \"#515772\"\n\naccent = \"#ab47bc\"\n\nactive = \"#414863\"\nhighlight = \"#444267\"\n\ncomment = \"#676e95\"\n\nselection = \"#444267\"\n\nline-number = \"#3a3f58\"\n"
  },
  {
    "path": "runtime/themes/meliora.toml",
    "content": "# Author: Ramojus Lapinskas <ramojus.lap@gmail.com>\n\n\"comment\" = { fg = \"comment\" }\n\"constant\" = { fg = \"magenta\" }\n\"function\" = { fg = \"blue\" }\n\"keyword.control.import\" = { fg = \"orange\" }\n\"keyword.control\" = { fg = \"red\" }\n\"keyword.function\" = { fg = \"red\" }\n\"keyword\" = { fg = \"orange\" }\n\"operator\" = { fg = \"secondary_white\" }\n\"punctuation\" = { fg = \"secondary_white\" }\n\"string\" = { fg = \"yellow\" }\n\"string.regexp\" = { fg = \"orange\" }\n\"tag\" = { fg = \"red\" }\n\"type\" = { fg = \"secondary_white\" }\n\"namespace\" = { fg = \"blue\" }\n\"variable\" = { fg = \"white\" }\n\"label\" = { fg = \"orange\" }\n\n\"diff.plus\" = { fg = \"blue\" }\n\"diff.delta\" = { fg = \"magenta\" }\n\"diff.minus\" = { fg = \"red\" }\n\n\"ui.cursor\" = { bg = \"light_grey\", fg = \"black\"}\n\"ui.cursor.match\" = { bg = \"dark_grey\" } \n\"ui.cursor.primary\" = { bg = \"secondary_white\", fg = \"black\" }\n\n\"ui.linenr\" = { fg = \"grey\", bg = \"dark_black\"}\n\"ui.linenr.selected\" = { fg = \"dark_white\", bg = \"dark_light_black\"}\n\"ui.gutter\" = { bg = \"dark_black\" }\n\n\"ui.background\" = { fg = \"light_grey\", bg = \"black\" }\n\"ui.background.separator\" = { fg = \"dark_grey\" }\n\"ui.help\" = { fg = \"white\", bg = \"light_black3\" }\n\"ui.menu\" = { fg = \"dark_white\", bg = \"light_black\" }\n\"ui.menu.selected\" = { bg = \"orange\" , fg = \"black\" }\n\"ui.popup\" = { fg = \"dark_white\", bg = \"light_black\" }\n\"ui.window\" = { fg = \"light_black3\" }\n\n\"ui.selection\" = { bg = \"light_black3\" }\n\"ui.selection.primary\" = { bg = \"light_black3\", modifiers = [\"bold\"] }\n\"ui.cursorline.primary\" = { bg = \"light_black\" }\n\n\"ui.statusline\" = { fg = \"dark_white\", bg = \"light_black3\" }\n\"ui.statusline.inactive\" = { fg = \"dark_white2\", bg = \"light_black\" }\n\"ui.statusline.normal\" = { bg  = \"dark_white2\", fg = \"black\" }\n\"ui.statusline.insert\" = { bg  = \"blue\", fg = \"black\" }\n\"ui.statusline.select\" = { bg  = \"orange\", fg = \"black\" }\n\n\"ui.text\" = { fg = \"white\" }\n\"ui.text.focus\" = { fg = \"orange\" }\n\n\"ui.virtual.ruler\" = { bg = \"light_black2\" }\n\"ui.virtual.indent-guide\" = { fg = \"dark_grey2\" }\n\"ui.virtual.whitespace\" = { fg = \"grey\" }\n \n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"orange\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"magenta\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"error\" = { fg = \"red\" }\n\"warning\" = { fg = \"orange\" }\n\"info\" = { fg = \"blue\" }\n\"hint\" = { fg = \"magenta\" }\n\"special\" = { fg = \"yellow\" }\n\n\"markup.heading\" = { fg = \"orange\" }\n\"markup.list\" = { fg = \"blue\" }\n\"markup.bold\" = { fg = \"magenta\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"comment\" , modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"comment\" }\n\"markup.quote\" = { fg = \"yellow\" }\n\"markup.raw\" = { fg = \"blue\" }\n\n[palette]\nred = \"#d29595\"\norange = \"#cbab8a\"\nyellow = \"#c9b58e\"\nblue = \"#a49db9\"\nmagenta = \"#b494af\"\n\ncomment = \"#707035\"\n\nlight_black = \"#252220\"\nlight_black2 = \"#292725\"\nlight_black3 = \"#302D2B\"\nblack = \"#1c1917\"\ndark_black = \"#191514\"\ndark_light_black = \"#211d1c\"\n\nwhite = \"#dad7d5\"\ndark_white = \"#aaa7a6\"\ndark_white2 = \"#949290\"\nlight_grey = \"#6a6867\"\ngrey = \"#605e5d\"\ndark_grey = \"#4c4b49\"\ndark_grey2 = \"#383735\"\nsecondary_white = \"#c2b4a8\"\n"
  },
  {
    "path": "runtime/themes/mellow.toml",
    "content": "# Author : Rohit K Viswanath <kvrohit@gmail.com>\n# Theme: Mellow\n\n\"attribute\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\n\"keyword\" = \"blue\"\n\"keyword.control.conditional\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\"keyword.directive\" = \"magenta\" # -- preprocessor comments (#if in C)\n\n\"namespace\" = { fg = \"cyan\", modifiers = [\"italic\"] }\n\n\"punctuation\" = \"gray06\"\n\"punctuation.delimiter\" = \"gray06\"\n\n\"operator\" = \"yellow\"\n\"special\" = \"yellow\"\n\n\"variable\" = \"fg\"\n\"variable.builtin\" = \"bright_blue\"\n\"variable.parameter\" = \"cyan\"\n\"variable.other.member\" = \"white\"\n\n\"type\" = \"bright_blue\"\n\"type.builtin\" = \"magenta\"\n\"type.enum.variant\" = \"magenta\"\n\n\"constructor\" = \"yellow\"\n\n\"function\" = \"white\"\n\"function.macro\" = \"bright_cyan\"\n\"function.builtin\" = \"bright_blue\"\n\n\"tag\" = \"cyan\"\n\"comment\" = { fg = \"gray05\", modifiers = [\"italic\"] }\n\n\"string\" = \"green\"\n\"string.regexp\" = \"green\"\n\"string.special\" = \"yellow\"\n\n\"constant\" = \"cyan\"\n\"constant.builtin\" = \"yellow\"\n\"constant.numeric\" = \"magenta\"\n\"constant.character.escape\" = \"cyan\"\n\n# used for lifetimes\n\"label\" = \"yellow\"\n\n\"markup.heading.marker\" = { fg = \"gray06\" }\n\"markup.heading\" = { fg = \"bright_blue\", modifiers = [\"bold\"] }\n\"markup.list\" = \"gray06\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"green\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\"markup.raw\" = \"yellow\"\n\n\"diff.plus\" = \"bright_green\"\n\"diff.minus\" = \"bright_red\"\n\"diff.delta\" = \"bright_blue\"\n\n\"ui.background\" = { bg = \"bg\" }\n\"ui.background.separator\" = { fg = \"fg\" }\n\n\"ui.linenr\" = { fg = \"gray04\" }\n\"ui.linenr.selected\" = { fg = \"fg\" }\n\n\"ui.statusline\" = { fg = \"fg\", bg = \"gray01\" }\n\"ui.statusline.inactive\" = { fg = \"fg\", bg = \"gray01\", modifiers = [\"dim\"] }\n\"ui.statusline.normal\" = { fg = \"bg\", bg = \"cyan\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"bg\", bg = \"blue\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"bg\", bg = \"magenta\", modifiers = [\"bold\"] }\n\n\"ui.popup\" = { bg = \"gray01\" }\n\"ui.window\" = { fg = \"gray02\" }\n\"ui.help\" = { bg = \"gray01\", fg = \"white\" }\n\n\"ui.text\" = { fg = \"fg\" }\n\"ui.text.focus\" = { fg = \"fg\" }\n\n\"ui.virtual\" = { fg = \"gray02\" }\n\"ui.virtual.ruler\" = { bg =\"gray02\" }\n\"ui.virtual.indent-guide\" = { fg = \"gray02\" }\n\"ui.virtual.inlay-hint\" = { fg = \"gray04\" }\n\n\"ui.selection\" = { bg = \"gray03\" }\n\"ui.selection.primary\" = { bg = \"gray03\" }\n\n\"ui.cursor\" = { bg = \"gray04\" }\n\"ui.cursor.match\" = { fg = \"yellow\", modifiers = [\"bold\", \"underlined\"] }\n\"ui.cursorline.primary\" = { bg = \"gray01\" }\n\n\"ui.highlight\" = { bg = \"gray02\" }\n\n\"ui.menu\" = { fg = \"white\", bg = \"gray01\" }\n\"ui.menu.selected\" = { fg = \"bright_white\", bg = \"gray03\" }\n\"ui.menu.scroll\" = { fg = \"gray04\", bg = \"gray01\" }\n\n\"diagnostic.warning\" = { underline = { color = \"bright_yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"bright_red\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"bright_blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"bright_cyan\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nwarning = \"bright_yellow\"\nerror = \"bright_red\"\ninfo = \"bright_blue\"\nhint = \"bright_cyan\"\n\n[palette]\nbg = \"#161617\"\nfg = \"#c9c7cd\"\nbg_dark = \"#131314\"\n\nblack = \"#27272a\"\nbright_black = \"#353539\"\n\nred = \"#f5a191\"\nbright_red = \"#ffae9f\"\n\ngreen = \"#90b99f\"\nbright_green = \"#9dc6ac\"\n\nyellow = \"#e6b99d\"\nbright_yellow = \"#f0c5a9\"\n\nblue = \"#aca1cf\"\nbright_blue = \"#b9aeda\"\n\nmagenta = \"#e29eca\"\nbright_magenta = \"#ecaad6\"\n\ncyan = \"#ea83a5\"\nbright_cyan = \"#f591b2\"\n\nwhite = \"#c1c0d4\"\nbright_white = \"#cac9dd\"\n\ngray01 = \"#1b1b1d\"\ngray02 = \"#2a2a2d\"\ngray03 = \"#3e3e43\"\ngray04 = \"#57575f\"\ngray05 = \"#757581\"\ngray06 = \"#9998a8\"\ngray07 = \"#c1c0d4\"\n"
  },
  {
    "path": "runtime/themes/merionette.toml",
    "content": "\"attribute\" = \"blue0\"\n\"comment\" = { fg = \"pink1\", modifiers = [\"italic\"]  }\n\"constant\" = { fg = \"orange0\" }\n\"constant.builtin\" = { fg = \"orange0\", modifiers = [\"bold\"] }\n\"constant.character.escape\" = { fg = \"orange0\", modifiers = [\"bold\"] }\n\"constant.numeric\" = \"orange0\"\n\"constructor\" = { fg = \"blue0\", modifiers = [\"bold\"] }\n\"function\" = { fg = \"green0\", modifiers = [\"bold\"] }\n\"function.builtin\" = \"green0\"\n\"function.macro\" = \"green0\"\n\"keyword\" = { fg = \"orange1\" }\n\"label\" = \"blue0\"\n\"module\" = \"blue0\"\n\"namespace\" = \"pink2\"\n\"operator\" = \"orange1\"\n\"punctuation\" = \"orange1\"\n\"special\" = \"pink2\"\n\"string\" = \"violet0\"\n\"tag\" = \"green0\"\n\"type\" = \"blue0\"\n\"type.builtin\" = \"orange0\"\n\"variable\" = \"white0\"\n\"variable.builtin\" = \"blue0\"\n\"variable.other.member\" = \"blue0\"\n\"variable.parameter\" = \"green1\"\n\n\"diff.delta\" = \"violet0\"\n\"diff.minus\" = \"pink2\"\n\"diff.plus\" = \"green1\"\n\n\"error\" = \"orange1\"\n\"hint\" = \"white0\"\n\"info\" = \"blue0\"\n\"warning\" = \"green1\"\n\n\"ui.background\" = { bg = \"dark_red0\" }\n\"ui.cursor.match\" = { bg = \"pink0\", fg = \"pink4\" }\n\"ui.cursor.primary\" = { bg = \"pink3\", fg = \"dark_red0\" }\n\"ui.cursorline\" = { bg = \"dark_red2\" }\n\"ui.help\" = { bg = \"dark_red2\", fg = \"white0\" }\n\"ui.linenr\" = { fg = \"white0\" }\n\"ui.linenr.selected\" = { fg = \"pink4\" }\n\"ui.menu\" = { fg = \"white0\", bg = \"dark_red3\" }\n\"ui.menu.selected\" = { fg = \"orange1\", bg = \"dark_red1\", modifiers = [\"bold\"] }\n\"ui.popup\" = { bg = \"dark_red2\" }\n\"ui.selection\" = { bg = \"dark_red4\" }\n\"ui.selection.primary\" = { bg = \"dark_red3\" }\n\"ui.statusline\" = { fg = \"dark_red0\", bg = \"pink1\" }\n\"ui.statusline.inactive\" = { fg = \"dark_red0\", bg = \"pink0\" }\n\"ui.statusline.insert\" = { fg = \"dark_red0\", bg = \"green0\" }\n\"ui.statusline.normal\" = { fg = \"dark_red0\", bg = \"pink1\" }\n\"ui.statusline.select\" = { fg = \"dark_red0\", bg = \"blue0\" }\n\"ui.text\" = { fg = \"white0\" }\n\"ui.text.focus\" = { fg = \"orange1\" }\n\"ui.virtual\" = { fg = \"pink1\" }\n\"ui.virtual.indent-guide\" = { fg = \"dark_red4\" }\n\"ui.virtual.inlay-hint\" = { fg = \"blue0\" }\n\"ui.virtual.ruler\" = { bg = \"dark_red2\" }\n\"ui.virtual.whitespace\" = \"dark_red4\"\n\"ui.window\" = { bg = \"dark_red2\" }\n\n\"diagnostic.error\" = { underline = { color = \"orange1\", style = \"double_line\" } }\n\"diagnostic.hint\" = { underline = { color = \"white0\", style = \"double_line\" } }\n\"diagnostic.info\" = { underline = { color = \"blue0\", style = \"double_line\" } }\n\"diagnostic.warning\" = { underline = { color = \"green1\", style = \"double_line\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.heading\" = { fg = \"orange1\", modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link.text\" = \"green1\"\n\"markup.link.url\" = { fg = \"blue0\", modifiers = [\"underlined\"] }\n\"markup.raw\" = \"pink2\"\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nblue0     = \"#65aba3\"\n\ndark_red0 = \"#190f0f\"\ndark_red1 = \"#331c1e\"\ndark_red2 = \"#2c1617\"\ndark_red3 = \"#442022\"\ndark_red4 = \"#704144\"\n\ngreen0    = \"#8ea84d\"\ngreen1    = \"#6db269\"\n\norange0   = \"#ff7550\"\norange1   = \"#eb842b\"\n\npink0     = \"#622b30\"\npink1     = \"#d2505f\"\npink2     = \"#d95362\"\npink3     = \"#c79295\"\npink4     = \"#e97e8a\"\n\nviolet0   = \"#ce8b9f\"\n\nwhite0    = \"#cebabf\"\n"
  },
  {
    "path": "runtime/themes/modus_operandi.toml",
    "content": "# Author: Alexis Mousset <contact@amousset.me>\n# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou\n# Version 4.6.0\n#\n\n# Syntax highlighting\n# -------------------\n\"type\" = \"cyan-cooler\"\n\"constructor\" = \"cyan-cooler\"\n\n\"constant\" = \"blue-cooler\"\n\"constant.character.escape\" = \"magenta\"\n\n\"string\" = \"blue-warmer\"\n\"string.regexp\" = \"magenta-faint\"\n\"string.special\" = \"blue-faint\" # used for colors in CSS\n\n\"comment\" = \"fg-dim\"\n\n\"variable.parameter\" = \"cyan\"\n\"variable.builtin\" = \"magenta-warmer\"\n\"label\" = \"fg-dim\" # used for language in markdown code blocks\n\"keyword\" = \"magenta-cooler\"\n\"keyword.directive\" = \"red-cooler\"\n\"function\" = \"magenta\"\n\"function.macro\" = \"red-cooler\"\n\npunctuation = \"fg-dim\"\n\"tag\" = \"magenta-cooler\"\n\"attribute\" = \"cyan\"\n\"namespace\" = \"cyan\"\n\"special\" = \"red-cooler\"\n\n\"markup.heading.marker\" = \"fg-dim\"\n\"markup.heading.1\" = { fg = \"fg-main\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"yellow-faint\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"fg-alt\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"magenta\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"green-faint\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"red-faint\", modifiers = [\"bold\"] }\n\"markup.list\" = \"fg-dim\"\n\"markup.list.checked\" = { fg = \"yellow-warmer\" }\n\"markup.list.unchecked\" = { fg = \"yellow-warmer\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"cyan\" }\n\"markup.link.text\" = { fg = \"blue-warmer\", modifiers = [\"underlined\"] }\n\"markup.raw.block\" = { bg = \"bg-dim\" }\n\"markup.raw.inline\" = { fg = \"green-cooler\" }\n\n\"diff.plus\" = { fg = \"fg-added\", bg = \"bg-added\" }\n\"diff.plus.gutter\" = \"green-intense\"\n\"diff.minus\" = { fg = \"fg-removed\", bg = \"bg-removed\" }\n\"diff.minus.gutter\" = \"red-intense\"\n\"diff.delta\" = { fg = \"fg-changed\", bg = \"bg-changed\" }\n\"diff.delta.gutter\" = \"yellow-intense\"\n\n# User Interface\n# --------------\n\n\"ui.background\" = { bg = \"bg-main\" }\n\"ui.background.separator\" = { fg = \"fg-dim\" }\n\n\"ui.linenr\" = { fg = \"fg-dim\", bg = \"bg-dim\" }\n\"ui.linenr.selected\" = { fg = \"fg-main\", bg = \"bg-active\" }\n\n\"ui.statusline\" = { fg = \"fg-mode-line-active\", bg = \"bg-mode-line-active\" }\n\"ui.statusline.inactive\" = { fg = \"fg-mode-line-inactive\", bg = \"bg-mode-line-inactive\" }\n\"ui.statusline.normal\" = { fg = \"blue-warmer\" }\n\"ui.statusline.insert\" = { fg = \"green-warmer\" }\n\"ui.statusline.select\" = { fg = \"magenta-warmer\" }\n\"ui.statusline.separator\" = { fg = \"border-mode-line-active\" }\n\n\"ui.bufferline\" = { bg = \"bg-tab-bar\" }\n\"ui.bufferline.active\" = { bg = \"bg-tab-current\", fg = \"fg-mode-line-active\" }\n\"ui.bufferline.background\" = { bg = \"bg-tab-bar\" }\n\n\"ui.popup\" = { fg = \"fg-main\", bg = \"bg-dim\" }\n\"ui.popup.info\" = { fg = \"fg-main\", bg = \"bg-active\" }\n\"ui.picker.header\" = { fg = \"fg-main\", bg = \"bg-active\", modifiers = [\"bold\"] }\n\"ui.picker.header.column\" = { fg = \"fg-dim\", bg = \"bg-active\" }\n\"ui.picker.header.column.active\" = { fg = \"fg-main\", bg = \"bg-active\", modifiers = [\"bold\"] }\n\"ui.window\" = { fg = \"fg-dim\" }\n\"ui.help\" = { fg = \"fg-main\", bg = \"bg-active\" }\n\"ui.gutter\" = { bg = \"bg-dim\" }\n\"ui.debug.breakpoint\" = { fg = \"red-intense\" }\n\"ui.debug.active\" = { fg = \"yellow-intense\" }\n\"ui.debug\" = { fg = \"yellow-intense\" }\n\"ui.gutter.selected\" = { bg = \"bg-active\" }\n\"ui.text\" = \"fg-main\"\n\"ui.text.directory\" = \"blue\"\n\"ui.text.focus\" = { fg = \"fg-main\", bg = \"bg-completion\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = { fg = \"fg-dim\" }\n\"ui.text.info\" = { fg = \"blue-warmer\" }\n\"ui.virtual\" = \"bg-active\"\n\"ui.virtual.ruler\" = { bg = \"bg-dim\" }\n\"ui.virtual.inlay-hint\" = { fg = \"fg-dim\", modifiers = [\"italic\"] }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"fg-dim\", modifiers = [\"italic\"] }\n\"ui.virtual.inlay-hint.type\" = { fg = \"fg-dim\", modifiers = [\"italic\"] }\n\"ui.virtual.indent-guide\" = { fg = \"fg-dim\" }\n\"ui.virtual.whitespace\" = { fg = \"fg-dim\" }\n\"ui.virtual.wrap\" = { fg = \"fg-dim\" }\n\"ui.virtual.jump-label\" = { fg = \"yellow-cooler\", modifiers = [\"bold\"] }\n\n\"ui.selection\" = { bg = \"bg-inactive\" }\n\"ui.selection.primary\" = { bg = \"bg-active\" }\n\n\"ui.cursor\" = { fg = \"bg-main\", bg = \"fg-main\" }\n\"ui.cursor.normal\" = { fg = \"bg-main\", bg = \"fg-main\" }\n\"ui.cursor.insert\" = { fg = \"bg-main\", bg = \"fg-main\" }\n\"ui.cursor.select\" = { fg = \"bg-main\", bg = \"fg-main\" }\n\"ui.cursor.primary\" = { fg = \"bg-main\", bg = \"fg-dim\" }\n\"ui.cursor.primary.normal\" = { fg = \"bg-main\", bg = \"fg-dim\" }\n\"ui.cursor.primary.insert\" = { fg = \"bg-main\", bg = \"fg-dim\" }\n\"ui.cursor.primary.select\" = { fg = \"bg-main\", bg = \"fg-dim\" }\n\"ui.cursor.match\" = { fg = \"fg-main\", bg = \"bg-paren-match\" }\n\"ui.cursorline.primary\" = { bg = \"bg-hl-line\" }\n\n\"ui.highlight\" = { bg = \"bg-hl-line\" }\n\"ui.highlight.frameline\" = { bg = \"bg-paren-match\" }\n\n\"ui.menu\" = { fg = \"fg-main\", bg = \"bg-dim\" }\n\"ui.menu.selected\" = { fg = \"fg-main\", bg = \"bg-completion\", modifiers = [\"bold\"] }\n\"ui.menu.scroll\" = { fg = \"fg-dim\", bg = \"bg-cyan-intense\" }\n\n\"diagnostic.error\" = { underline = { color = \"red-intense\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow-intense\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"cyan-intense\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue-intense\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nerror = \"red\"\nwarning = \"yellow-warmer\"\ninfo = \"cyan-cooler\"\nhint = \"blue-cooler\"\n\n[palette]\n# Basic values\nbg-main = \"#ffffff\"\nbg-dim = \"#f2f2f2\"\nfg-main = \"#000000\"\nfg-dim = \"#595959\"\nfg-alt = \"#193668\"\nbg-active = \"#c4c4c4\"\nbg-inactive = \"#e0e0e0\"\n\n# Common accent foregrounds\nred = \"#a60000\"\nred-warmer = \"#972500\"\nred-cooler = \"#a0132f\"\nred-faint = \"#7f0000\"\nred-intense = \"#d00000\"\ngreen = \"#006800\"\ngreen-warmer = \"#316500\"\ngreen-cooler = \"#00663f\"\ngreen-faint = \"#2a5045\"\ngreen-intense = \"#008900\"\nyellow = \"#6f5500\"\nyellow-warmer = \"#884900\"\nyellow-cooler = \"#7a4f2f\"\nyellow-faint = \"#624416\"\nyellow-intense = \"#808000\"\nblue = \"#0031a9\"\nblue-warmer = \"#3548cf\"\nblue-cooler = \"#0000b0\"\nblue-faint = \"#003497\"\nblue-intense = \"#0000ff\"\nmagenta = \"#721045\"\nmagenta-warmer = \"#8f0075\"\nmagenta-cooler = \"#531ab6\"\nmagenta-faint = \"#7c318f\"\nmagenta-intense = \"#dd22dd\"\ncyan = \"#005e8b\"\ncyan-warmer = \"#3f578f\"\ncyan-cooler = \"#005f5f\"\ncyan-faint = \"#005077\"\ncyan-intense = \"#008899\"\n\n# Common accent backgrounds\nbg-red-intense = \"#ff8f88\"\nbg-green-intense = \"#8adf80\"\nbg-yellow-intense = \"#f3d000\"\nbg-blue-intense = \"#bfc9ff\"\nbg-magenta-intense = \"#dfa0f0\"\nbg-cyan-intense = \"#a4d5f9\"\n\nbg-red-subtle = \"#ffcfbf\"\nbg-green-subtle = \"#b3fabf\"\nbg-yellow-subtle = \"#fff576\"\nbg-blue-subtle = \"#ccdfff\"\nbg-magenta-subtle = \"#ffddff\"\nbg-cyan-subtle = \"#bfefff\"\n\nbg-red-nuanced = \"#ffe8e8\"\nbg-green-nuanced = \"#e0f6e0\"\nbg-yellow-nuanced = \"#f8f0d0\"\nbg-blue-nuanced = \"#ecedff\"\nbg-magenta-nuanced = \"#f8e6f5\"\nbg-cyan-nuanced = \"#e0f2fa\"\n\n# Special purpose\nbg-completion = \"#c0deff\"\nbg-hl-line = \"#dae5ec\"\n\nbg-mode-line-active = \"#c8c8c8\"\nfg-mode-line-active = \"#000000\"\nborder-mode-line-active = \"#5a5a5a\"\nbg-mode-line-inactive = \"#e6e6e6\"\nfg-mode-line-inactive = \"#585858\"\n\nmodeline-err = \"#7f0000\"\nmodeline-warning = \"#5f0070\"\nmodeline-info = \"#002580\"\n\nbg-tab-bar = \"#dfdfdf\"\nbg-tab-current = \"#ffffff\"\nbg-tab-other = \"#c2c2c2\"\n\n# Diffs\nbg-added = \"#c1f2d1\"\nfg-added = \"#005000\"\nbg-changed = \"#ffdfa9\"\nfg-changed = \"#553d00\"\nbg-removed = \"#ffd8d5\"\nfg-removed = \"#8f1313\"\n\n# Paren match\nbg-paren-match = \"#5fcfff\"\n"
  },
  {
    "path": "runtime/themes/modus_operandi_deuteranopia.toml",
    "content": "# Author: Alexis Mousset <contact@amousset.me>\n# modus_operandi.toml variant\n#\n# This variant is optimized for users with red-green color deficiency (deuteranopia)\n# Version 4.6.0\n\ninherits = \"modus_operandi\"\n\n\"constant.character.escape\" = \"magenta\"\n\"comment\" = \"yellow-cooler\"\n\"function\" = \"yellow-warmer\"\n\"tag\" = \"blue-cooler\"\n\n\"ui.cursor\" = { fg = \"bg-main\", bg = \"blue-intense\" }\n\"ui.cursor.primary.normal\" = { fg = \"bg-main\", bg = \"blue-intense\" }\n\n\"diagnostic.error\" = { underline = { color = \"yellow-intense\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"magenta-faint\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"cyan\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue\", style = \"curl\" } }\n\nerror = \"yellow-intense\"\nwarning = \"magenta-faint\"\ninfo = \"cyan\"\nhint = \"blue\"\n\n[palette]\n\nyellow = \"#695500\"\nyellow-warmer = \"#973300\"\nyellow-cooler = \"#77492f\"\n\nbg-mode-line-active = \"#d0d6ff\"\nfg-mode-line-active = \"#0f0f0f\"\nborder-mode-line-active = \"#4f4f74\"\n\nmodeline-err = \"#603a00\"\nmodeline-warning = \"#454500\"\nmodeline-info = \"#023d92\"\n\n# Diffs\nbg-added = \"#d5d7ff\"\nfg-added = \"#303099\"\nbg-changed = \"#eecfdf\"\nfg-changed = \"#6f1343\"\nbg-removed = \"#f4f099\"\nfg-removed = \"#553d00\"\n"
  },
  {
    "path": "runtime/themes/modus_operandi_tinted.toml",
    "content": "# Author: Alexis Mousset <contact@amousset.me>\n# modus_operandi.toml variant\n# Version 4.6.0\n\ninherits = \"modus_operandi\"\n\n\"comment\" = \"red-faint\"\n\n\"ui.cursor.primary\" = { fg = \"bg-main\", bg = \"red-intense\" }\n\n[palette]\n# Basic values\nbg-main = \"#fbf7f0\"\nbg-dim = \"#efe9dd\"\nbg-active = \"#c9b9b0\"\nbg-inactive = \"#dfd5cf\"\nborder = \"#9f9690\"\n\n# Common accent backgrounds\nbg-red-nuanced = \"#ffe8e8\"\nbg-green-nuanced = \"#e0f6e0\"\nbg-yellow-nuanced = \"#f8f0d0\"\nbg-blue-nuanced = \"#ecedff\"\nbg-magenta-nuanced = \"#f8e6f5\"\nbg-cyan-nuanced = \"#e0f2fa\"\n\n# Special purpose\nbg-completion = \"#f0c1cf\"\nbg-hl-line = \"#f1d5d0\"\nbg-region = \"#c2bcb5\"\n\nbg-mode-line-active = \"#cab9b2\"\nborder-mode-line-active = \"#545454\"\nbg-mode-line-inactive = \"#dfd9cf\"\nborder-mode-line-inactive = \"#a59a94\"\n\nbg-tab-bar = \"#e0d4ce\"\nbg-tab-current = \"#fbf7f0\"\nbg-tab-other = \"#c8b8b2\"\n\n# Diffs\nbg-added = \"#c3ebc1\"\nbg-removed = \"#f4d0cf\"\n\n# Paren match\nbg-paren-match = \"#7fdfcf\"\n"
  },
  {
    "path": "runtime/themes/modus_operandi_tritanopia.toml",
    "content": "# Author: Alexis Mousset <contact@amousset.me>\n# modus_operandi.toml variant\n#\n# This variant is optimized for users with blue-yellow color deficiency (tritanopia)\n# Version 4.6.0\n\ninherits = \"modus_operandi\"\n\n\"type\" = \"blue-warmer\"\n\"constructor\" = \"blue-warmer\"\n\"constant\" = \"green-cooler\"\n\"constant.character.escape\" = \"red-cooler\"\n\"string\" = \"cyan\"\n\"comment\" = \"red-faint\"\n\"variable.parameter\" = \"cyan-cooler\"\n\"keyword\" = \"red-cooler\"\n\"keyword.directive\" = \"red-warmer\"\n\"function\" = \"cyan-warmer\"\n\"function.macro\" = \"red-warmer\"\n\"tag\" = \"red-cooler\"\n\n\"markup.heading.2\" = { fg = \"red-faint\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"cyan-faint\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"magenta-faint\", modifiers = [\"bold\"] }\n\"markup.link.url\" = { fg = \"cyan-cooler\" }\n\"markup.link.text\" = { fg = \"cyan\", modifiers = [\"underlined\"] }\n\n\"ui.cursor\" = { fg = \"bg-main\", bg = \"red-intense\" }\n\"ui.cursor.primary.normal\" = { fg = \"bg-main\", bg = \"red-intense\" }\n\n\"diagnostic.error\" = { underline = { color = \"red-warmer\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"magenta\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"cyan\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue\", style = \"curl\" } }\n\nerror = \"red-warmer\"\nwarning = \"magenta\"\ninfo = \"cyan\"\nhint = \"blue\"\n\n[palette]\n\n# Common accent foregrounds\nred-warmer = \"#b21100\"\nred-faint = \"#702000\"\nyellow = \"#695500\"\nyellow-warmer = \"#973300\"\nyellow-cooler = \"#77492f\"\nmagenta-intense = \"#cd22bd\"\ncyan-faint = \"#004f5f\"\n\n# Special purpose\nbg-completion = \"#afdfef\"\nbg-hover = \"#ffafbc\"\nbg-hover-secondary = \"#abdfdd\"\nbg-hl-line = \"#dfeaec\"\n\nbg-char-0 = \"#ff908f\"\nbg-char-1 = \"#bfbfff\"\nbg-char-2 = \"#5fcfdf\"\n\nbg-mode-line-active = \"#afe0f2\"\nfg-mode-line-active = \"#0f0f0f\"\nborder-mode-line-active = \"#2f4f44\"\n\nmodeline-err = \"#8f0000\"\nmodeline-warning = \"#6f306f\"\nmodeline-info = \"#00445f\"\n\n# Diffs\nbg-added = \"#b5e7ff\"\nfg-added = \"#005079\"\nbg-changed = \"#eecfdf\"\nfg-changed = \"#6f1343\"\n"
  },
  {
    "path": "runtime/themes/modus_vivendi.toml",
    "content": "# Author: Matous Dzivjak <matousdzivjak@gmail.com>\n# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou\n# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-theme.el\n# Version 4.6.0\n\n# Syntax highlighting\n# -------------------\n\"type\" = \"cyan-cooler\"\n\"constructor\" = \"cyan-cooler\"\n\n\"constant\" = \"blue-cooler\"\n\"constant.character.escape\" = \"magenta\"\n\n\"string\" = \"blue-warmer\"\n\"string.regexp\" = \"magenta-faint\"\n\"string.special\" = \"blue-faint\" # used for colors in CSS\n\n\"comment\" = \"fg-dim\"\n\n\"variable.parameter\" = \"cyan\"\n\"variable.builtin\" = \"magenta-warmer\"\n\"label\" = \"fg-dim\" # used for language in markdown code blocks\n\"keyword\" = \"magenta-cooler\"\n\"keyword.directive\" = \"red-cooler\"\n\"function\" = \"magenta\"\n\"function.macro\" = \"red-cooler\"\n\npunctuation = \"fg-dim\"\n\"tag\" = \"magenta-cooler\"\n\"attribute\" = \"cyan\"\n\"namespace\" = \"cyan\"\n\"special\" = \"red-cooler\"\n\n\"markup.heading.marker\" = \"fg-dim\"\n\"markup.heading.1\" = { fg = \"fg-main\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"yellow-faint\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"fg-alt\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"magenta\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"green-faint\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"red-faint\", modifiers = [\"bold\"] }\n\"markup.list\" = \"fg-dim\"\n\"markup.list.checked\" = { fg = \"yellow-warmer\" }\n\"markup.list.unchecked\" = { fg = \"yellow-warmer\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"cyan\" }\n\"markup.link.text\" = { fg = \"blue-warmer\", modifiers = [\"underlined\"] }\n\"markup.raw.block\" = { bg = \"bg-dim\" }\n\"markup.raw.inline\" = { fg = \"green-cooler\" }\n\n\"diff.plus\" = { fg = \"fg-added\", bg = \"bg-added\" }\n\"diff.plus.gutter\" = \"green-intense\"\n\"diff.minus\" = { fg = \"fg-removed\", bg = \"bg-removed\" }\n\"diff.minus.gutter\" = \"red-intense\"\n\"diff.delta\" = { fg = \"fg-changed\", bg = \"bg-changed\" }\n\"diff.delta.gutter\" = \"yellow-intense\"\n\n# User Interface\n# --------------\n\n\"ui.background\" = { bg = \"bg-main\" }\n\"ui.background.separator\" = { fg = \"fg-dim\" }\n\n\"ui.linenr\" = { fg = \"fg-dim\", bg = \"bg-dim\" }\n\"ui.linenr.selected\" = { fg = \"fg-main\", bg = \"bg-active\" }\n\n\"ui.statusline\" = { fg = \"fg-mode-line-active\", bg = \"bg-mode-line-active\" }\n\"ui.statusline.inactive\" = { fg = \"fg-mode-line-inactive\", bg = \"bg-mode-line-inactive\" }\n\"ui.statusline.normal\" = { fg = \"blue-warmer\" }\n\"ui.statusline.insert\" = { fg = \"green-warmer\" }\n\"ui.statusline.select\" = { fg = \"magenta-warmer\" }\n\"ui.statusline.separator\" = { fg = \"border-mode-line-active\" }\n\n\"ui.bufferline\" = { bg = \"bg-tab-bar\" }\n\"ui.bufferline.active\" = { bg = \"bg-tab-current\", fg = \"fg-mode-line-active\" }\n\"ui.bufferline.background\" = { bg = \"bg-tab-bar\" }\n\n\"ui.popup\" = { fg = \"fg-main\", bg = \"bg-dim\" }\n\"ui.popup.info\" = { fg = \"fg-main\", bg = \"bg-active\" }\n\"ui.picker.header\" = { fg = \"fg-main\", bg = \"bg-active\", modifiers = [\"bold\"] }\n\"ui.picker.header.column\" = { fg = \"fg-dim\", bg = \"bg-active\" }\n\"ui.picker.header.column.active\" = { fg = \"fg-main\", bg = \"bg-active\", modifiers = [\"bold\"] }\n\"ui.window\" = { fg = \"fg-dim\" }\n\"ui.help\" = { fg = \"fg-main\", bg = \"bg-active\" }\n\"ui.gutter\" = { bg = \"bg-dim\" }\n\"ui.debug.breakpoint\" = { fg = \"red-intense\" }\n\"ui.debug.active\" = { fg = \"yellow-intense\" }\n\"ui.debug\" = { fg = \"yellow-intense\" }\n\"ui.gutter.selected\" = { bg = \"bg-active\" }\n\"ui.text\" = \"fg-main\"\n\"ui.text.directory\" = \"blue-cooler\"\n\"ui.text.focus\" = { fg = \"fg-main\", bg = \"bg-completion\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = { fg = \"fg-dim\" }\n\"ui.text.info\" = { fg = \"cyan\" }\n\"ui.virtual\" = \"bg-active\"\n\"ui.virtual.ruler\" = { bg = \"bg-dim\" }\n\"ui.virtual.inlay-hint\" = { fg = \"fg-dim\", modifiers = [\"italic\"] }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"fg-dim\", modifiers = [\"italic\"] }\n\"ui.virtual.inlay-hint.type\" = { fg = \"fg-dim\", modifiers = [\"italic\"] }\n\"ui.virtual.indent-guide\" = { fg = \"fg-dim\" }\n\"ui.virtual.whitespace\" = { fg = \"fg-dim\" }\n\"ui.virtual.wrap\" = { fg = \"fg-dim\" }\n\"ui.virtual.jump-label\" = { fg = \"yellow-cooler\", modifiers = [\"bold\"] }\n\n\"ui.selection\" = { bg = \"bg-inactive\" }\n\"ui.selection.primary\" = { bg = \"bg-active\" }\n\n\"ui.cursor\" = { fg = \"bg-main\", bg = \"fg-main\" }\n\"ui.cursor.normal\" = { fg = \"bg-main\", bg = \"fg-main\" }\n\"ui.cursor.insert\" = { fg = \"bg-main\", bg = \"fg-main\" }\n\"ui.cursor.select\" = { fg = \"bg-main\", bg = \"fg-main\" }\n\"ui.cursor.primary\" = { fg = \"bg-main\", bg = \"fg-dim\" }\n\"ui.cursor.primary.normal\" = { fg = \"bg-main\", bg = \"fg-dim\" }\n\"ui.cursor.primary.insert\" = { fg = \"bg-main\", bg = \"fg-dim\" }\n\"ui.cursor.primary.select\" = { fg = \"bg-main\", bg = \"fg-dim\" }\n\"ui.cursor.match\" = { bg = \"bg-paren-match\", fg = \"fg-main\" }\n\"ui.cursorline.primary\" = { bg = \"bg-hl-line\" }\n\n\"ui.highlight\" = { bg = \"bg-hl-line\" }\n\"ui.highlight.frameline\" = { bg = \"bg-paren-match\" }\n\n\"ui.menu\" = { fg = \"fg-main\", bg = \"bg-dim\" }\n\"ui.menu.selected\" = { fg = \"fg-main\", bg = \"bg-completion\", modifiers = [\"bold\"] }\n\"ui.menu.scroll\" = { fg = \"fg-dim\", bg = \"bg-cyan-intense\" }\n\n\"diagnostic.error\" = { underline = { color = \"red-intense\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow-intense\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"cyan-intense\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue-intense\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nerror = \"red\"\nwarning = \"yellow-warmer\"\ninfo = \"cyan-cooler\"\nhint = \"blue-cooler\"\n\nrainbow = [\"red\", \"yellow-warmer\", \"green-intense\", \"cyan\", \"blue\", \"magenta-intense\"]\n\n[palette]\n# Basic values\nbg-main = \"#000000\"\nbg-dim = \"#1e1e1e\"\nfg-main = \"#ffffff\"\nfg-dim = \"#989898\"\nfg-alt = \"#c6daff\"\nbg-active = \"#535353\"\nbg-inactive = \"#303030\"\n\n# Common accent foregrounds\nred = \"#ff5f59\"\nred-warmer = \"#ff6b55\"\nred-cooler = \"#ff7f86\"\nred-faint = \"#ff9580\"\nred-intense = \"#ff5f5f\"\ngreen = \"#44bc44\"\ngreen-warmer = \"#70b900\"\ngreen-cooler = \"#00c06f\"\ngreen-faint = \"#88ca9f\"\ngreen-intense = \"#44df44\"\nyellow = \"#d0bc00\"\nyellow-warmer = \"#fec43f\"\nyellow-cooler = \"#dfaf7a\"\nyellow-faint = \"#d2b580\"\nyellow-intense = \"#efef00\"\nblue = \"#2fafff\"\nblue-warmer = \"#79a8ff\"\nblue-cooler = \"#00bcff\"\nblue-faint = \"#82b0ec\"\nblue-intense = \"#338fff\"\nmagenta = \"#feacd0\"\nmagenta-warmer = \"#f78fe7\"\nmagenta-cooler = \"#b6a0ff\"\nmagenta-faint = \"#caa6df\"\nmagenta-intense = \"#ff66ff\"\ncyan = \"#00d3d0\"\ncyan-warmer = \"#4ae2f0\"\ncyan-cooler = \"#6ae4b9\"\ncyan-faint = \"#9ac8e0\"\ncyan-intense = \"#00eff0\"\n\n# Uncommon accent foregrounds\nrust = \"#db7b5f\"\ngold = \"#c0965b\"\nolive = \"#9cbd6f\"\nslate = \"#76afbf\"\nindigo = \"#9099d9\"\nmaroon = \"#cf7fa7\"\npink = \"#d09dc0\"\n\n# Common accent backgrounds\nbg-red-intense = \"#9d1f1f\"\nbg-green-intense = \"#2f822f\"\nbg-yellow-intense = \"#7a6100\"\nbg-blue-intense = \"#1640b0\"\nbg-magenta-intense = \"#7030af\"\nbg-cyan-intense = \"#2266ae\"\n\nbg-red-subtle = \"#620f2a\"\nbg-green-subtle = \"#00422a\"\nbg-yellow-subtle = \"#4a4000\"\nbg-blue-subtle = \"#242679\"\nbg-magenta-subtle = \"#552f5f\"\nbg-cyan-subtle = \"#004065\"\n\nbg-red-nuanced = \"#3a0c14\"\nbg-green-nuanced = \"#092f1f\"\nbg-yellow-nuanced = \"#381d0f\"\nbg-blue-nuanced = \"#12154a\"\nbg-magenta-nuanced = \"#2f0c3f\"\nbg-cyan-nuanced = \"#042837\"\n\n# Uncommon accent backgrounds\nbg-ochre = \"#462f20\"\nbg-lavender = \"#38325c\"\nbg-sage = \"#143e32\"\n\n# Special purpose\nbg-completion = \"#2f447f\"\nbg-hover = \"#45605e\"\nbg-hover-secondary = \"#654a39\"\nbg-hl-line = \"#2f3849\"\nbg-region = \"#5a5a5a\"\nfg-region = \"#ffffff\"\n\nbg-char-0 = \"#0050af\"\nbg-char-1 = \"#7f1f7f\"\nbg-char-2 = \"#625a00\"\n\nbg-mode-line-active = \"#505050\"\nfg-mode-line-active = \"#ffffff\"\nborder-mode-line-active = \"#959595\"\nbg-mode-line-inactive = \"#2d2d2d\"\nfg-mode-line-inactive = \"#969696\"\nborder-mode-line-inactive = \"#606060\"\n\nmodeline-err = \"#ffa9bf\"\nmodeline-warning = \"#dfcf43\"\nmodeline-info = \"#9fefff\"\n\nbg-tab-bar = \"#313131\"\nbg-tab-current = \"#000000\"\nbg-tab-other = \"#545454\"\n\n# Diffs\nbg-added = \"#00381f\"\nbg-added-faint = \"#002910\"\nbg-added-refine = \"#034f2f\"\nbg-added-fringe = \"#237f3f\"\nfg-added = \"#a0e0a0\"\nfg-added-intense = \"#80e080\"\n\nbg-changed = \"#363300\"\nbg-changed-faint = \"#2a1f00\"\nbg-changed-refine = \"#4a4a00\"\nbg-changed-fringe = \"#8a7a00\"\nfg-changed = \"#efef80\"\nfg-changed-intense = \"#c0b05f\"\n\nbg-removed = \"#4f1119\"\nbg-removed-faint = \"#380a0f\"\nbg-removed-refine = \"#781a1f\"\nbg-removed-fringe = \"#b81a1f\"\nfg-removed = \"#ffbfbf\"\nfg-removed-intense = \"#ff9095\"\n\nbg-diff-context = \"#1a1a1a\"\n\n# Paren match\nbg-paren-match = \"#2f7f9f\"\ntg-paren-expression = \"#453040\"\n"
  },
  {
    "path": "runtime/themes/modus_vivendi_deuteranopia.toml",
    "content": "# Author: Matous Dzivjak <matousdzivjak@gmail.com>\n# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou\n# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-deuteranopia-theme.el\n# Version 4.6.0\n\ninherits = \"modus_vivendi\"\n\n\"constant.character.escape\" = \"magenta\"\n\"comment\" = \"yellow-cooler\"\n\"function\" = \"yellow-warmer\"\n\"tag\" = \"blue-cooler\"\n\n\"ui.cursor\" = { fg = \"bg-main\", bg = \"blue-intense\" }\n\"ui.cursor.primary.normal\" = { fg = \"bg-main\", bg = \"blue-intense\" }\n\n\"diagnostic.error\" = { underline = { color = \"yellow-intense\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"magenta-faint\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"cyan\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue\", style = \"curl\" } }\n\nerror = \"yellow-intense\"\nwarning = \"magenta-faint\"\ninfo = \"cyan\"\nhint = \"blue\"\n\nrainbow = [\"red\", \"yellow-intense\", \"green-intense\", \"cyan\", \"blue\", \"magenta-intense\"]\n\n[palette]\n# Basic values\nbg-main = \"#000000\"\nbg-dim = \"#1e1e1e\"\nfg-main = \"#ffffff\"\nfg-dim = \"#989898\"\nfg-alt = \"#c6daff\"\nbg-active = \"#535353\"\nbg-inactive = \"#303030\"\nborder = \"#646464\"\n\n# Common accent foregrounds\nred = \"#ff5f59\"\nred-warmer = \"#ff6b55\"\nred-cooler = \"#ff7f86\"\nred-faint = \"#ff9580\"\nred-intense = \"#ff5f5f\"\ngreen = \"#44bc44\"\ngreen-warmer = \"#70b900\"\ngreen-cooler = \"#00c06f\"\ngreen-faint = \"#88ca9f\"\ngreen-intense = \"#44df44\"\nyellow = \"#cabf00\"\nyellow-warmer = \"#ffa00f\"\nyellow-cooler = \"#d8af7a\"\nyellow-faint = \"#d2b580\"\nyellow-intense = \"#efef00\"\nblue = \"#2fafff\"\nblue-warmer = \"#79a8ff\"\nblue-cooler = \"#00bcff\"\nblue-faint = \"#82b0ec\"\nblue-intense = \"#338fff\"\nmagenta = \"#feacd0\"\nmagenta-warmer = \"#f78fe7\"\nmagenta-cooler = \"#b6a0ff\"\nmagenta-faint = \"#caa6df\"\nmagenta-intense = \"#ff66ff\"\ncyan = \"#00d3d0\"\ncyan-warmer = \"#4ae2f0\"\ncyan-cooler = \"#6ae4b9\"\ncyan-faint = \"#9ac8e0\"\ncyan-intense = \"#00eff0\"\n\n# Uncommon accent foregrounds\nrust = \"#db7b5f\"\ngold = \"#c0965b\"\nolive = \"#9cbd6f\"\nslate = \"#76afbf\"\nindigo = \"#9099d9\"\nmaroon = \"#cf7fa7\"\npink = \"#d09dc0\"\n\n# Common accent backgrounds\nbg-red-intense = \"#9d1f1f\"\nbg-green-intense = \"#2f822f\"\nbg-yellow-intense = \"#7a6100\"\nbg-blue-intense = \"#1640b0\"\nbg-magenta-intense = \"#7030af\"\nbg-cyan-intense = \"#2266ae\"\n\nbg-red-subtle = \"#620f2a\"\nbg-green-subtle = \"#00422a\"\nbg-yellow-subtle = \"#4a4000\"\nbg-blue-subtle = \"#242679\"\nbg-magenta-subtle = \"#552f5f\"\nbg-cyan-subtle = \"#004065\"\n\nbg-red-nuanced = \"#3a0c14\"\nbg-green-nuanced = \"#092f1f\"\nbg-yellow-nuanced = \"#381d0f\"\nbg-blue-nuanced = \"#12154a\"\nbg-magenta-nuanced = \"#2f0c3f\"\nbg-cyan-nuanced = \"#042837\"\n\n# Uncommon accent backgrounds\nbg-ochre = \"#462f20\"\nbg-lavender = \"#38325c\"\nbg-sage = \"#143e32\"\n\n# Special purpose\nbg-completion = \"#2f447f\"\nbg-hover = \"#45605e\"\nbg-hover-secondary = \"#604c30\"\nbg-hl-line = \"#2f3849\"\nbg-region = \"#5a5a5a\"\nfg-region = \"#ffffff\"\n\nbg-char-0 = \"#0050af\"\nbg-char-1 = \"#7f1f7f\"\nbg-char-2 = \"#625a00\"\n\nbg-mode-line-active = \"#2a2a6a\"\nfg-mode-line-active = \"#f0f0f0\"\nborder-mode-line-active = \"#8080a7\"\nbg-mode-line-inactive = \"#2d2d2d\"\nfg-mode-line-inactive = \"#969696\"\nborder-mode-line-inactive = \"#606060\"\n\nmodeline-err = \"#e5bf00\"\nmodeline-warning = \"#c0cf35\"\nmodeline-info = \"#abeadf\"\n\nbg-tab-bar = \"#313131\"\nbg-tab-current = \"#000000\"\nbg-tab-other = \"#545454\"\n\n# Diffs\nbg-added = \"#003066\"\nbg-added-faint = \"#001a4f\"\nbg-added-refine = \"#0f4a77\"\nbg-added-fringe = \"#006fff\"\nfg-added = \"#c4d5ff\"\nfg-added-intense = \"#8080ff\"\n\nbg-changed = \"#2f123f\"\nbg-changed-faint = \"#1f022f\"\nbg-changed-refine = \"#3f325f\"\nbg-changed-fringe = \"#7f55a0\"\nfg-changed = \"#e3cfff\"\nfg-changed-intense = \"#cf9fe2\"\n\nbg-removed = \"#3d3d00\"\nbg-removed-faint = \"#281f00\"\nbg-removed-refine = \"#555500\"\nbg-removed-fringe = \"#d0c03f\"\nfg-removed = \"#d4d48f\"\nfg-removed-intense = \"#d0b05f\"\n\nbg-diff-context = \"#1a1a1a\"\n\n# Paren match\nbg-paren-match = \"#2f7f9f\"\nbg-paren-expression = \"#453040\"\n"
  },
  {
    "path": "runtime/themes/modus_vivendi_tinted.toml",
    "content": "# Author: Matous Dzivjak <matousdzivjak@gmail.com>\n# Adapted from: https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou\n# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-tinted-theme.el\n# Version 4.6.0\n\ninherits = \"modus_vivendi\"\n\n\"comment\" = \"red-faint\"\n\n\"ui.cursor.primary\" = { fg = \"bg-main\", bg = \"magenta-intense\" }\n\n[palette]\n# Basic values\nbg-main = \"#0d0e1c\"\nbg-dim = \"#1d2235\"\nfg-main = \"#ffffff\"\nfg-dim = \"#989898\"\nfg-alt = \"#c6daff\"\nbg-active = \"#4a4f69\"\nbg-inactive = \"#2b3045\"\nborder = \"#61647a\"\n\n# Common accent foregrounds\nred = \"#ff5f59\"\nred-warmer = \"#ff6b55\"\nred-cooler = \"#ff7f86\"\nred-faint = \"#ef8386\"\nred-intense = \"#ff5f5f\"\ngreen = \"#44bc44\"\ngreen-warmer = \"#75c13e\"\ngreen-cooler = \"#11c777\"\ngreen-faint = \"#88ca9f\"\ngreen-intense = \"#44df44\"\nyellow = \"#d0bc00\"\nyellow-warmer = \"#fec43f\"\nyellow-cooler = \"#dfaf7a\"\nyellow-faint = \"#d2b580\"\nyellow-intense = \"#efef00\"\nblue = \"#2fafff\"\nblue-warmer = \"#79a8ff\"\nblue-cooler = \"#00bcff\"\nblue-faint = \"#82b0ec\"\nblue-intense = \"#338fff\"\nmagenta = \"#feacd0\"\nmagenta-warmer = \"#f78fe7\"\nmagenta-cooler = \"#b6a0ff\"\nmagenta-faint = \"#caa6df\"\nmagenta-intense = \"#ff66ff\"\ncyan = \"#00d3d0\"\ncyan-warmer = \"#4ae2f0\"\ncyan-cooler = \"#6ae4b9\"\ncyan-faint = \"#9ac8e0\"\ncyan-intense = \"#00eff0\"\n\n# Uncommon accent foregrounds\nrust = \"#db8b3f\"\ngold = \"#c0965b\"\nolive = \"#9cbd6f\"\nslate = \"#76afbf\"\nindigo = \"#9099d9\"\nmaroon = \"#cf7fa7\"\npink = \"#d09dc0\"\n\n# Common accent backgrounds\nbg-red-intense = \"#9d1f1f\"\nbg-green-intense = \"#2f822f\"\nbg-yellow-intense = \"#7a6100\"\nbg-blue-intense = \"#1640b0\"\nbg-magenta-intense = \"#7030af\"\nbg-cyan-intense = \"#2266ae\"\n\nbg-red-subtle = \"#620f2a\"\nbg-green-subtle = \"#00422a\"\nbg-yellow-subtle = \"#4a4000\"\nbg-blue-subtle = \"#242679\"\nbg-magenta-subtle = \"#552f5f\"\nbg-cyan-subtle = \"#004065\"\n\nbg-red-nuanced = \"#3a0c14\"\nbg-green-nuanced = \"#092f1f\"\nbg-yellow-nuanced = \"#381d0f\"\nbg-blue-nuanced = \"#12154a\"\nbg-magenta-nuanced = \"#2f0c3f\"\nbg-cyan-nuanced = \"#042837\"\n\n# Special purpose\nbg-completion = \"#483d8a\"\nbg-hover = \"#45605e\"\nbg-hover-secondary = \"#64404f\"\nbg-hl-line = \"#303a6f\"\nbg-region = \"#555a66\"\nfg-region = \"#ffffff\"\n\nbg-char-0 = \"#0050af\"\nbg-char-1 = \"#7f1f7f\"\nbg-char-2 = \"#625a00\"\n\nbg-mode-line-active = \"#484d67\"\nfg-mode-line-active = \"#ffffff\"\nborder-mode-line-active = \"#979797\"\nbg-mode-line-inactive = \"#292d48\"\nfg-mode-line-inactive = \"#969696\"\nborder-mode-line-inactive = \"#606270\"\n\nmodeline-err = \"#ffa9bf\"\nmodeline-warning = \"#dfcf43\"\nmodeline-info = \"#9fefff\"\n\nbg-tab-bar = \"#2c3045\"\nbg-tab-current = \"#0d0e1c\"\nbg-tab-other = \"#4a4f6a\"\n\n# Diffs\nbg-added = \"#003a2f\"\nbg-added-faint = \"#002922\"\nbg-added-refine = \"#035542\"\nbg-added-fringe = \"#23884f\"\nfg-added = \"#a0e0a0\"\nfg-added-intense = \"#80e080\"\n\nbg-changed = \"#363300\"\nbg-changed-faint = \"#2a1f00\"\nbg-changed-refine = \"#4a4a00\"\nbg-changed-fringe = \"#8f7a30\"\nfg-changed = \"#efef80\"\nfg-changed-intense = \"#c0b05f\"\n\nbg-removed = \"#4f1127\"\nbg-removed-faint = \"#380a19\"\nbg-removed-refine = \"#781a3a\"\nbg-removed-fringe = \"#b81a26\"\nfg-removed = \"#ffbfbf\"\nfg-removed-intense = \"#ff9095\"\n\nbg-diff-context = \"#1a1f30\"\n\n# Uncommon accent backgrounds\nbg-ochre = \"#462f20\"\nbg-lavender = \"#38325c\"\nbg-sage = \"#143e32\"\n\n# Paren match\nbg-paren-match = \"#4f7f9f\"\nbg-paren-expression = \"#453040\"\n"
  },
  {
    "path": "runtime/themes/modus_vivendi_tritanopia.toml",
    "content": "# Author: Matous Dzivjak <matousdzivjak@gmail.com>\n# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou\n# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-tritanopia-theme.el\n# Version 4.6.0\n\ninherits = \"modus_vivendi\"\n\n\"type\" = \"blue-warmer\"\n\"constructor\" = \"blue-warmer\"\n\"constant\" = \"green-faint\"\n\"constant.character.escape\" = \"red-cooler\"\n\"string\" = \"cyan\"\n\"comment\" = \"red-faint\"\n\"variable.parameter\" = \"cyan-cooler\"\n\"keyword\" = \"red-cooler\"\n\"keyword.directive\" = \"red-warmer\"\n\"function\" = \"cyan-warmer\"\n\"function.macro\" = \"red-warmer\"\n\"tag\" = \"red-cooler\"\n\n\"markup.heading.2\" = { fg = \"red-faint\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"cyan-faint\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"magenta-faint\", modifiers = [\"bold\"] }\n\"markup.link.url\" = { fg = \"cyan-cooler\" }\n\"markup.link.text\" = { fg = \"cyan\", modifiers = [\"underlined\"] }\n\n\"ui.cursor\" = { fg = \"bg-main\", bg = \"red-intense\" }\n\"ui.cursor.primary.normal\" = { fg = \"bg-main\", bg = \"red-intense\" }\n\n\"diagnostic.error\" = { underline = { color = \"red-warmer\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"magenta\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"cyan\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"blue\", style = \"curl\" } }\n\nerror = \"red-warmer\"\nwarning = \"magenta\"\ninfo = \"cyan\"\nhint = \"blue\"\n\nrainbow = [\"red\", \"magenta\", \"green-intense\", \"cyan\", \"blue\", \"magenta-intense\"]\n\n[palette]\n# Basic values\nbg-main = \"#000000\"\nbg-dim = \"#1e1e1e\"\nfg-main = \"#ffffff\"\nfg-dim = \"#989898\"\nfg-alt = \"#a0d7f2\"\nbg-active = \"#535353\"\nbg-inactive = \"#303030\"\nborder = \"#646464\"\n\n# Common accent foregrounds\nred = \"#ff5f59\"\nred-warmer = \"#ff6740\"\nred-cooler = \"#ff7f86\"\nred-faint = \"#ff9070\"\nred-intense = \"#ff5f5f\"\ngreen = \"#44bc44\"\ngreen-warmer = \"#70b900\"\ngreen-cooler = \"#00c06f\"\ngreen-faint = \"#88ca9f\"\ngreen-intense = \"#44df44\"\nyellow = \"#cabf00\"\nyellow-warmer = \"#ffa00f\"\nyellow-cooler = \"#d8af7a\"\nyellow-faint = \"#d2b580\"\nyellow-intense = \"#efef00\"\nblue = \"#2fafff\"\nblue-warmer = \"#79a8ff\"\nblue-cooler = \"#00bcff\"\nblue-faint = \"#82b0ec\"\nblue-intense = \"#338fff\"\nmagenta = \"#feacd0\"\nmagenta-warmer = \"#f78fe7\"\nmagenta-cooler = \"#b6a0ff\"\nmagenta-faint = \"#caa6df\"\nmagenta-intense = \"#ef7fff\"\ncyan = \"#00d3d0\"\ncyan-warmer = \"#4ae2ff\"\ncyan-cooler = \"#6ae4b9\"\ncyan-faint = \"#7fdbdf\"\ncyan-intense = \"#00eff0\"\n\n# Uncommon accent foregrounds\nrust = \"#db7b5f\"\ngold = \"#c0965b\"\nolive = \"#9cbd6f\"\nslate = \"#76afbf\"\nindigo = \"#9099d9\"\nmaroon = \"#cf7fa7\"\npink = \"#d09dc0\"\n\n# Common accent backgrounds\nbg-red-intense = \"#9d1f1f\"\nbg-green-intense = \"#2f822f\"\nbg-yellow-intense = \"#7a6100\"\nbg-blue-intense = \"#1640b0\"\nbg-magenta-intense = \"#7030af\"\nbg-cyan-intense = \"#2266ae\"\n\nbg-red-subtle = \"#620f2a\"\nbg-green-subtle = \"#00422a\"\nbg-yellow-subtle = \"#4a4000\"\nbg-blue-subtle = \"#242679\"\nbg-magenta-subtle = \"#552f5f\"\nbg-cyan-subtle = \"#004065\"\n\nbg-red-nuanced = \"#3a0c14\"\nbg-green-nuanced = \"#092f1f\"\nbg-yellow-nuanced = \"#381d0f\"\nbg-blue-nuanced = \"#12154a\"\nbg-magenta-nuanced = \"#2f0c3f\"\nbg-cyan-nuanced = \"#042837\"\n\n# Uncommon accent backgrounds\nbg-ochre = \"#462f20\"\nbg-lavender = \"#38325c\"\nbg-sage = \"#143e32\"\n\n# Graphs\nbg-graph-red-0 = \"#b52c2c\"\nbg-graph-red-1 = \"#702020\"\nbg-graph-green-0 = \"#afd1c0\"\nbg-graph-green-1 = \"#607a8f\"\nbg-graph-yellow-0 = \"#facfd6\"\nbg-graph-yellow-1 = \"#b57b85\"\nbg-graph-blue-0 = \"#4f9fdf\"\nbg-graph-blue-1 = \"#004559\"\nbg-graph-magenta-0 = \"#b6427f\"\nbg-graph-magenta-1 = \"#7f506f\"\nbg-graph-cyan-0 = \"#57dfea\"\nbg-graph-cyan-1 = \"#00808f\"\n\n# Special purpose\nbg-completion = \"#004253\"\nbg-hover = \"#8e3e3b\"\nbg-hover-secondary = \"#204853\"\nbg-hl-line = \"#2f3849\"\nbg-region = \"#5a5a5a\"\nfg-region = \"#ffffff\"\n\nbg-char-0 = \"#922a00\"\nbg-char-1 = \"#00709f\"\nbg-char-2 = \"#5f3faf\"\n\nbg-mode-line-active = \"#003c52\"\nfg-mode-line-active = \"#f0f0f0\"\nborder-mode-line-active = \"#5f8fb4\"\nbg-mode-line-inactive = \"#2d2d2d\"\nfg-mode-line-inactive = \"#969696\"\nborder-mode-line-inactive = \"#606060\"\n\nmodeline-err = \"#ff7fbf\"\nmodeline-warning = \"#df9f93\"\nmodeline-info = \"#4fcfef\"\n\nbg-tab-bar = \"#313131\"\nbg-tab-current = \"#000000\"\nbg-tab-other = \"#545454\"\n\n# Diffs\nbg-added = \"#004254\"\nbg-added-faint = \"#003042\"\nbg-added-refine = \"#004f7f\"\nbg-added-fringe = \"#008fcf\"\nfg-added = \"#9fdfdf\"\nfg-added-intense = \"#50c0ef\"\n\nbg-changed = \"#2f123f\"\nbg-changed-faint = \"#1f022f\"\nbg-changed-refine = \"#3f325f\"\nbg-changed-fringe = \"#7f55a0\"\nfg-changed = \"#e3cfff\"\nfg-changed-intense = \"#cf9fe2\"\n\nbg-removed = \"#4f1119\"\nbg-removed-faint = \"#380a0f\"\nbg-removed-refine = \"#781a1f\"\nbg-removed-fringe = \"#b81a1f\"\nfg-removed = \"#ffbfbf\"\nfg-removed-intense = \"#ff9095\"\n\nbg-diff-context = \"#1a1a1a\"\n\n# Paren match\nbg-paren-match = \"#2f7f9f\"\nbg-paren-expression = \"#453040\"\n"
  },
  {
    "path": "runtime/themes/molokai.toml",
    "content": "# Author : Maxwell Anderson <zaechus@pm.me>\n\ninherits = \"monokai\"\n\n\"comment\" = \"comment\"\n\"comment.block.documentation\" = { fg = \"comment\", modifiers = [\"bold\"] }\n\"comment.line.documentation\" = { fg = \"comment\", modifiers = [\"bold\"] }\n\"constant.character.escape\" = { fg = \"light-blue\", modifiers = [\"italic\"] }\n\"function.macro\" = { fg = \"#c4be89\", modifiers = [\"italic\"] }\n\"keyword\" = { fg = \"keyword\", modifiers = [\"bold\"] }\n\"keyword.control\" = { fg = \"keyword\", modifiers = [\"bold\"] }\n\"keyword.control.exception\" = { fg = \"fn_declaration\", modifiers = [\"bold\"] }\n\"keyword.directive\" = { fg = \"fn_declaration\", modifiers = [\"bold\"] }\n\"keyword.storage.modifier\" = { fg = \"#fd971f\", modifiers = [\"italic\"] }\n\"label\" = \"#e6db74\"\n\"operator\" = \"keyword\"\n\"punctuation.delimiter\" = \"#8f8f8f\"\n\"type\" = \"light-blue\"\n\"variable.builtin\" = { fg = \"#ae81ff\", modifiers = [\"bold\"] }\n\"tag.builtin\" = { fg = \"#ae81ff\", modifiers = [\"bold\"] }\n\"variable.parameter\" = \"variable\"\n\n\"diff.plus\" = \"text\"\n\"diff.delta\" = \"#89807d\"\n\"diff.minus\" = \"#960050\"\n\n\"ui.cursor.primary\" = { fg = \"#000000\", bg = \"#f8f8f0\" }\n\"ui.cursor.match\" = { fg = \"#000000\", bg = \"#fd971f\", modifiers = [\"bold\"] }\n\"ui.selection\" = { bg = \"#403d3d\" }\n\"ui.linenr\" = \"#465457\"\n\"ui.linenr.selected\" = \"#fd971f\"\n\n\"ui.help\" = { fg = \"light-blue\", bg = \"#000000\" }\n\"ui.menu\" = { fg = \"light-blue\", bg = \"#000000\" }\n\"ui.popup\" = { fg = \"light-blue\", bg = \"#000000\" }\n\"ui.popup.info\" = { fg = \"light-blue\", bg = \"#000000\" }\n\"ui.text.info\" = { fg = \"light-blue\", bg = \"#000000\" }\n\n\"ui.statusline.normal\" = { fg = \"#080808\", bg = \"#e6db74\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"#282828\", bg = \"#8787af\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"#282828\", bg = \"#ffd700\", modifiers = [\"bold\"] }\n\n\"warning\" = { fg = \"#ffffff\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"#ffffff\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"#ffffff\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"#ffffff\", modifiers = [\"bold\"] }\n\n[palette]\nlight-blue = \"#66d9ef\"\n\nbackground = \"#1b1d1e\"\n\ncomment = \"#7e8e91\"\n"
  },
  {
    "path": "runtime/themes/monokai.toml",
    "content": "# Author: Shafkath Shuhan <shafkathshuhannyc@gmail.com>\n\n\"tag\" = { fg = \"tag\" }\n\n\"namespace\" = { fg = \"type\" }\n\"module\" = { fg = \"type\" }\n\n\"type\" = { fg = \"type\" }\n\"type.builtin\" = { fg = \"#66D9EF\" }\n\"type.enum.variant\" = { fg = \"text\" } \n\"constructor\" = { fg = \"fn_declaration\" }\n\"variable.other.member\" = { fg = \"variable\" }\n\n\"keyword\" = { fg = \"keyword\" }\n\"keyword.directive\" = { fg = \"keyword\" }\n\"keyword.control\" = { fg = \"keyword\" }\n\"label\" = { fg = \"keyword\" }\n\n\"special\" = { fg = \"keyword\" }\n\"operator\" = { fg = \"text\" }\n\n\"punctuation\" = { fg = \"text\" }\n\"punctuation.delimiter\" = { fg = \"text\" }\n\n\"variable\" = { fg = \"variable\" }\n\"variable.parameter\" = { fg = \"#fd971f\" }\n\"variable.builtin\" = { fg = \"keyword\" }\n\"constant\" = { fg = \"variable\" }\n\"constant.builtin\" = { fg = \"#ae81ff\" }\n\n\"function\" = { fg = \"fn_declaration\" }\n\"function.builtin\" = { fg = \"fn_declaration\" }\n\"function.macro\" = { fg = \"keyword\" }\n\"attribute\" = { fg = \"fn_declaration\" }\n\n\"comment\" = { fg = \"#88846F\" }\n\"ui.virtual.whitespace\" = \"#88846F\"\n\"ui.virtual.ruler\" = { bg = \"#24241e\" }\n\"ui.virtual.jump-label\" = { fg = \"special\", modifiers = [\"bold\"] }\n\n\"string\" = { fg = \"#e6db74\" }\n\"constant.character\" = { fg = \"#e6db74\" }\n\"string.regexp\" = { fg = \"regex\" }\n\"constant.numeric\" = { fg = \"#ae81ff\" }\n\"constant.character.escape\" = { fg = \"#ae81ff\" }\n\n# TODO\n\"markup.heading\" = \"blue\"\n\"markup.list\" = \"red\"\n\"markup.bold\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"red\"\n\"markup.quote\" = \"cyan\"\n\"markup.raw\" = \"green\"\n\n\"diff.plus\" = { fg = \"#a6e22e\" }\n\"diff.delta\" = { fg = \"#fd971f\" }\n\"diff.minus\" = { fg = \"#f92672\" }\n\n\"ui.background\" = { fg = \"text\", bg = \"background\" }\n\n\"ui.window\" = { bg = \"widget\" }\n\"ui.popup\" = { fg = \"text\", bg = \"widget\" }\n\"ui.help\" = { fg = \"text\", bg = \"widget\" }\n\"ui.menu\" = { fg = \"text\", bg = \"widget\" }\n\"ui.menu.selected\" = { bg = \"#414339\" }\n\n\"ui.cursor\" = { fg = \"cursor\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"cursor\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"#888888\", modifiers = [\"reversed\"] }\n\n\"ui.selection\" = { bg = \"#878b91\" }\n\"ui.selection.primary\" = { bg = \"#575b61\" }\n\n\"ui.linenr\" = { fg = \"#90908a\" }\n\"ui.linenr.selected\" = { fg = \"#c2c2bf\" }\n\n\"ui.cursorline\" = { bg = \"#24241e\" }\n\"ui.statusline\" = { fg = \"active_text\", bg = \"#414339\" }\n\"ui.statusline.inactive\" = { fg = \"active_text\", bg = \"#75715e\" }\n\n# Malformed ANSI: grey2, bg3. See 'https://github.com/helix-editor/helix/issues/5709'\n# \"ui.bufferline\" = { fg = \"grey2\", bg = \"bg3\" }\n\"ui.bufferline.active\" = { fg = \"active_text\", bg = \"selection\", modifiers = [\n  \"bold\",\n] }\n\"ui.virtual.inlay-hint\" = { fg = \"#88846F\" }\n\n\"ui.text\" = { fg = \"text\" }\n\"ui.text.focus\" = { fg = \"active_text\" }\n\n\"warning\" = { fg = \"#cca700\" }\n\"error\" = { fg = \"#f48771\" }\n\"info\" = { fg = \"#75beff\" }\n\"hint\" = { fg = \"#eeeeb3\" }\n\n\"diagnostic.warning\" = { underline = { color = \"#cca700\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"#f48771\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"#75beff\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"#eeeeb3\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\ntype = \"#A6E22E\"\nkeyword = \"#F92672\"\nregex = \"#CE9178\"\nspecial = \"#C586C0\"\nvariable = \"#F8F8F2\"\nfn_declaration = \"#A6E22E\"\n\nbackground = \"#272822\"\ntext = \"#f8f8f2\"\nactive_text = \"#ffffff\"\ncursor = \"#a6a6a6\"\ninactive_cursor = \"#878b91\"\nwidget = \"#1e1f1c\"\nselection = \"#414339\"\ntag = \"#F92672\"\n"
  },
  {
    "path": "runtime/themes/monokai_aqua.toml",
    "content": "inherits = \"monokai\"\n\n\"keyword.control.import\" = { fg = \"cyan\", modifiers = [\"italic\"] }\n\"keyword.function\" = { fg = \"cyan\", modifiers = [\"italic\"] }\n\"keyword.storage.type\" = { fg = \"cyan\", modifiers = [\"italic\"] }\n\n\"namespace\" = { fg = \"text\" }\n\n\"type\" = { fg = \"type\", modifiers = [\"bold\"] }\n\n# Malformed ANSI: light-black, purple. See 'https://github.com/helix-editor/helix/issues/5709'\n# \"ui.statusline.normal\" = { fg = \"light-black\", bg = \"cyan\" }\n\"ui.statusline.normal\" = { bg = \"cyan\" }\n# \"ui.statusline.insert\" = { fg = \"light-black\", bg = \"green\" }\n\"ui.statusline.insert\" = { bg = \"green\" }\n# \"ui.statusline.select\" = { fg = \"light-black\", bg = \"purple\" }\n\n\"ui.virtual.jump-label\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\n[palette]\ncyan = \"#66D9EF\"\ntype = \"#66D9EF\"\n"
  },
  {
    "path": "runtime/themes/monokai_pro.toml",
    "content": "# Author : WindSoilder<WindSoilder@outlook.com>\n# The unofficial Monokai Pro theme, simply migrate from jetbrains monokai pro theme: https://github.com/subtheme-dev/monokai-pro\n# Credit goes to the original creator: https://monokai.pro\n\n\"ui.linenr.selected\" = { bg = \"base3\" }\n\"ui.text.focus\" = { fg = \"yellow\", modifiers= [\"bold\"] }\n\"ui.menu\" = { fg = \"base8\", bg = \"base3\" }\n\"ui.menu.selected\" = { fg = \"base2\", bg = \"yellow\" }\n\"ui.virtual.whitespace\" = \"base5\"\n\"ui.virtual.ruler\" = { bg = \"base1\" }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"info\" = \"base8\"\n\"hint\" = \"base8\"\n\n# background color\n\"ui.background\" = { bg = \"base2\" }\n\n# status bars, panels, modals, autocompletion\n\"ui.statusline\" = { fg = \"base8\", bg = \"base4\" }\n\"ui.statusline.inactive\" = { fg = \"base8\", bg = \"base8x0c\" }\n\"ui.statusline.normal\" = { fg = \"base4\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"base4\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"base4\", bg = \"purple\" }\n\"ui.popup\" = { bg = \"base3\" }\n\"ui.window\" = { bg = \"base3\" }\n\"ui.help\" = { fg = \"base8\", bg = \"base3\" }\n\n# active line, highlighting\n\"ui.selection\" = { bg = \"base4\" }\n\"ui.cursor.match\" = { bg = \"base4\" }\n\"ui.cursorline\" = { bg = \"base1\" }\n\n# bufferline, inlay hints\n\"ui.bufferline\" = { fg = \"base6\", bg = \"base8x0c\" }\n\"ui.bufferline.active\" = { fg = \"base8\", bg = \"base4\" }\n\"ui.virtual.inlay-hint\" = { fg = \"base6\" }\n\n# comments, nord3 based lighter color\n\"comment\" = { fg = \"base5\", modifiers = [\"italic\"] }\n\"ui.linenr\" = { fg = \"base5\" }\n\n# cursor, variables, constants, attributes, fields\n\"ui.cursor.primary\" = { fg = \"base7\", modifiers = [\"reversed\"] }\n\"attribute\" = \"blue\"\n\"variable\"  = \"base8\"\n\"constant\"  = \"orange\"\n\"variable.builtin\" = \"red\"\n\"constant.builtin\" = \"red\"\n\"namespace\" = \"base8\"\n\n# base text, punctuation\n\"ui.text\" = { fg = \"base8\" }\n\"punctuation\" = \"base6\"\n\n# classes, types, primitives\n\"type\" = \"green\"\n\"type.builtin\" = { fg = \"red\"}\n\"label\" = \"base8\"\n\n# declaration, methods, routines\n\"constructor\" = \"blue\"\n\"function\" = \"green\"\n\"function.macro\" = { fg = \"blue\" }\n\"function.builtin\" = { fg = \"cyan\" }\n\n# operator, tags, units, punctuations\n\"operator\" = \"red\"\n\"variable.other.member\" = \"base8\"\n\n# keywords, special\n\"keyword\" = { fg = \"red\" }\n\"keyword.directive\" = \"blue\"\n\"variable.parameter\" = \"#f59762\"\n\n# error\n\"error\" = \"red\"\n\n# annotations, decorators\n\"special\" = \"#f59762\"\n\"module\" = \"#f59762\"\n\n# warnings, escape characters, regex\n\"warning\" = \"orange\"\n\"constant.character.escape\" = { fg = \"base8\" }\n\n# strings\n\"string\" = \"yellow\"\n\n# integer, floating point\n\"constant.numeric\" = \"purple\"\n\n# vcs\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"orange\"\n\"diff.minus\" = \"red\"\n\n# make diagnostic underlined, to distinguish with selection text.\n\"diagnostic.warning\" = { underline = { color = \"orange\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"base8\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"base8\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n# markup highlight, no need for `markup.raw` and `markup.list`, make them to be default\n\"markup.heading\" = \"green\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"orange\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"orange\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"yellow\"\n\"markup.quote\" = \"green\"\n\n[palette]\n# primary colors\n\"red\" = \"#ff6188\"\n\"orange\" = \"#fc9867\"\n\"yellow\" = \"#ffd866\"\n\"green\" = \"#a9dc76\"\n\"blue\" = \"#78dce8\"\n\"purple\" = \"#ab9df2\"\n# base colors, sorted from darkest to lightest\n\"base0\" = \"#19181a\"\n\"base1\" = \"#221f22\"\n\"base2\" = \"#2d2a2e\"\n\"base3\" = \"#403e41\"\n\"base4\" = \"#5b595c\"\n\"base5\" = \"#727072\"\n\"base6\" = \"#939293\"\n\"base7\" = \"#c1c0c0\"\n\"base8\" = \"#fcfcfa\"\n# variants (for when transparency isn't supported)\n\"base8x0c\" = \"#363337\" # using base2 as bg\n"
  },
  {
    "path": "runtime/themes/monokai_pro_machine.toml",
    "content": "# Author : WindSoilder<WindSoilder@outlook.com>\n# The unofficial Monokai Pro theme, simply migrate from jetbrains monokai pro theme: https://github.com/subtheme-dev/monokai-pro\n# Credit goes to the original creator: https://monokai.pro\n\n\"ui.linenr.selected\" = { bg = \"base3\" }\n\"ui.text.focus\" = { fg = \"yellow\", modifiers= [\"bold\"] }\n\"ui.menu\" = { fg = \"base8\", bg = \"base3\" }\n\"ui.menu.selected\" = { fg = \"base2\", bg = \"yellow\" }\n\"ui.virtual.whitespace\" = \"base5\"\n\"ui.virtual.ruler\" = { bg = \"base1\" }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"info\" = \"base8\"\n\"hint\" = \"base8\"\n\n# background color\n\"ui.background\" = { bg = \"base2\" }\n\"ui.statusline.inactive\" = { fg = \"base8\", bg = \"base8x0c\" }\n\n# status bars, panels, modals, autocompletion\n\"ui.statusline\" = { fg = \"base8\", bg = \"base4\" }\n\"ui.popup\" = { bg = \"base3\" }\n\"ui.window\" = { bg = \"base3\" }\n\"ui.help\" = { fg = \"base8\", bg = \"base3\" }\n\n# active line, highlighting\n\"ui.selection\" = { bg = \"base4\" }\n\"ui.cursor.match\" = { bg = \"base4\" }\n\"ui.cursorline\" = { bg = \"base1\" }\n\n# bufferline, inlay hints\n\"ui.bufferline\" = { fg = \"base6\", bg = \"base8x0c\" }\n\"ui.bufferline.active\" = { fg = \"base8\", bg = \"base4\" }\n\"ui.virtual.inlay-hint\" = { fg = \"base6\" }\n\n# comments, nord3 based lighter color\n\"comment\" = { fg = \"base5\", modifiers = [\"italic\"] }\n\"ui.linenr\" = { fg = \"base5\" }\n\n# cursor, variables, constants, attributes, fields\n\"ui.cursor.primary\" = { fg = \"base7\", modifiers = [\"reversed\"] }\n\"attribute\" = \"blue\"\n\"variable\"  = \"base8\"\n\"constant\"  = \"orange\"\n\"variable.builtin\" = \"red\"\n\"constant.builtin\" = \"red\"\n\"namespace\" = \"base8\"\n\n# base text, punctuation\n\"ui.text\" = { fg = \"base8\" }\n\"punctuation\" = \"base6\"\n\n# classes, types, primitives\n\"type\" = \"green\"\n\"type.builtin\" = { fg = \"red\"}\n\"label\" = \"base8\"\n\n# declaration, methods, routines\n\"constructor\" = \"blue\"\n\"function\" = \"green\"\n\"function.macro\" = { fg = \"blue\" }\n\"function.builtin\" = { fg = \"cyan\" }\n\n# operator, tags, units, punctuations\n\"operator\" = \"red\"\n\"variable.other.member\" = \"base8\"\n\n# keywords, special\n\"keyword\" = { fg = \"red\" }\n\"keyword.directive\" = \"blue\"\n\"variable.parameter\" = \"#f59762\"\n\n# error\n\"error\" = \"red\"\n\n# annotations, decorators\n\"special\" = \"#f59762\"\n\"module\" = \"#f59762\"\n\n# warnings, escape characters, regex\n\"warning\" = \"orange\"\n\"constant.character.escape\" = { fg = \"base8\" }\n\n# strings\n\"string\" = \"yellow\"\n\n# integer, floating point\n\"constant.numeric\" = \"purple\"\n\n# vcs\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"orange\"\n\"diff.minus\" = \"red\"\n\n# make diagnostic underlined, to distinguish with selection text.\n\"diagnostic.warning\" = { underline = { color = \"orange\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"base8\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"base8\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n# markup highlight, no need for `markup.raw` and `markup.list`, make them to be default\n\"markup.heading\" = \"green\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"orange\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"orange\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"yellow\"\n\"markup.quote\" = \"green\"\n\n[palette]\n# primary colors\n\"red\" = \"#ff6d7e\"\n\"orange\" = \"#ffb270\"\n\"yellow\" = \"#ffed72\"\n\"green\" = \"#a2e57b\"\n\"blue\" = \"#7cd5f1\"\n\"purple\" = \"#baa0f8\"\n# base colors\n\"base0\" = \"#161b1e\"\n\"base1\" = \"#1d2528\"\n\"base2\" = \"#273136\"\n\"base3\" = \"#3a4449\"\n\"base4\" = \"#545f62\"\n\"base5\" = \"#6b7678\"\n\"base6\" = \"#798384\"\n\"base7\" = \"#b8c4c3\"\n\"base8\" = \"#f2fffc\"\n# variants\n\"base8x0c\" = \"#303a3e\"\n"
  },
  {
    "path": "runtime/themes/monokai_pro_octagon.toml",
    "content": "# Author : WindSoilder<WindSoilder@outlook.com>\n# The unofficial Monokai Pro theme, simply migrate from jetbrains monokai pro theme: https://github.com/subtheme-dev/monokai-pro\n# Credit goes to the original creator: https://monokai.pro\n\n\"ui.linenr.selected\" = { bg = \"base3\" }\n\"ui.text.focus\" = { fg = \"yellow\", modifiers= [\"bold\"] }\n\"ui.menu\" = { fg = \"base8\", bg = \"base3\" }\n\"ui.menu.selected\" = { fg = \"base2\", bg = \"yellow\" }\n\"ui.virtual.whitespace\" = \"base5\"\n\"ui.virtual.ruler\" = { bg = \"base1\" }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"info\" = \"base8\"\n\"hint\" = \"base8\"\n\n# background color\n\"ui.background\" = { bg = \"base2\" }\n\"ui.statusline.inactive\" = { fg = \"base8\", bg = \"base8x0c\" }\n\n# status bars, panels, modals, autocompletion\n\"ui.statusline\" = { fg = \"base8\", bg = \"base4\" }\n\"ui.statusline.normal\" = { fg = \"base4\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"base4\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"base4\", bg = \"purple\" }\n\"ui.popup\" = { bg = \"base3\" }\n\"ui.window\" = { bg = \"base3\" }\n\"ui.help\" = { fg = \"base8\", bg = \"base3\" }\n\n# active line, highlighting\n\"ui.selection\" = { bg = \"base4\" }\n\"ui.cursor.match\" = { bg = \"base4\" }\n\"ui.cursorline\" = { bg = \"base1\" }\n\n# bufferline, inlay hints\n\"ui.bufferline\" = { fg = \"base6\", bg = \"base8x0c\" }\n\"ui.bufferline.active\" = { fg = \"base8\", bg = \"base4\" }\n\"ui.virtual.inlay-hint\" = { fg = \"base6\" }\n\n# comments, nord3 based lighter color\n\"comment\" = { fg = \"base5\", modifiers = [\"italic\"] }\n\"ui.linenr\" = { fg = \"base5\" }\n\n# cursor, variables, constants, attributes, fields\n\"ui.cursor.primary\" = { fg = \"base7\", modifiers = [\"reversed\"] }\n\"attribute\" = \"blue\"\n\"variable\"  = \"base8\"\n\"constant\"  = \"orange\"\n\"variable.builtin\" = \"red\"\n\"constant.builtin\" = \"red\"\n\"namespace\" = \"base8\"\n\n# base text, punctuation\n\"ui.text\" = { fg = \"base8\" }\n\"punctuation\" = \"base6\"\n\n# classes, types, primitives\n\"type\" = \"green\"\n\"type.builtin\" = { fg = \"red\"}\n\"label\" = \"base8\"\n\n# declaration, methods, routines\n\"constructor\" = \"blue\"\n\"function\" = \"green\"\n\"function.macro\" = { fg = \"blue\" }\n\"function.builtin\" = { fg = \"cyan\" }\n\n# operator, tags, units, punctuations\n\"operator\" = \"red\"\n\"variable.other.member\" = \"base8\"\n\n# keywords, special\n\"keyword\" = { fg = \"red\" }\n\"keyword.directive\" = \"blue\"\n\"variable.parameter\" = \"#f59762\"\n\n# error\n\"error\" = \"red\"\n\n# annotations, decorators\n\"special\" = \"#f59762\"\n\"module\" = \"#f59762\"\n\n# warnings, escape characters, regex\n\"warning\" = \"orange\"\n\"constant.character.escape\" = { fg = \"base8\" }\n\n# strings\n\"string\" = \"yellow\"\n\n# integer, floating point\n\"constant.numeric\" = \"purple\"\n\n# vcs\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"orange\"\n\"diff.minus\" = \"red\"\n\n# make diagnostic underlined, to distinguish with selection text.\n\"diagnostic.warning\" = { underline = { color = \"orange\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"base8\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"base8\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n# markup highlight, no need for `markup.raw` and `markup.list`, make them to be default\n\"markup.heading\" = \"green\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"orange\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"orange\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"yellow\"\n\"markup.quote\" = \"green\"\n\n[palette]\n# primary colors\n\"red\" = \"#ff657a\"\n\"orange\" = \"#ff9b5e\"\n\"yellow\" = \"#ffd76d\"\n\"green\" = \"#bad761\"\n\"blue\" = \"#9cd1bb\"\n\"purple\" = \"#c39ac9\"\n# base colors\n\"base0\" = \"#161821\"\n\"base1\" = \"#1e1f2b\"\n\"base2\" = \"#282a3a\"\n\"base3\" = \"#3a3d4b\"\n\"base4\" = \"#535763\"\n\"base5\" = \"#696d77\"\n\"base6\" = \"#767b81\"\n\"base7\" = \"#b2b9bd\"\n\"base8\" = \"#eaf2f1\"\n# variants\n\"base8x0c\" = \"#303342\"\n"
  },
  {
    "path": "runtime/themes/monokai_pro_ristretto.toml",
    "content": "# Author : WindSoilder<WindSoilder@outlook.com>\n# The unofficial Monokai Pro theme, simply migrate from jetbrains monokai pro theme: https://github.com/subtheme-dev/monokai-pro\n# Credit goes to the original creator: https://monokai.pro\n\n\"ui.linenr.selected\" = { bg = \"base3\" }\n\"ui.text.focus\" = { fg = \"yellow\", modifiers= [\"bold\"] }\n\"ui.menu\" = { fg = \"base8\", bg = \"base3\" }\n\"ui.menu.selected\" = { fg = \"base2\", bg = \"yellow\" }\n\"ui.virtual.whitespace\" = \"base5\"\n\"ui.virtual.ruler\" = { bg = \"base1\" }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"info\" = \"base8\"\n\"hint\" = \"base8\"\n\n# background color\n\"ui.background\" = { bg = \"base2\" }\n\"ui.statusline.inactive\" = { fg = \"base8\", bg = \"base8x0c\" }\n\n# status bars, panels, modals, autocompletion\n\"ui.statusline\" = { fg = \"base8\", bg = \"base4\" }\n\"ui.popup\" = { bg = \"base3\" }\n\"ui.window\" = { bg = \"base3\" }\n\"ui.help\" = { fg = \"base8\", bg = \"base3\" }\n\n# active line, highlighting\n\"ui.selection\" = { bg = \"base4\" }\n\"ui.cursor.match\" = { bg = \"base4\" }\n\"ui.cursorline\" = { bg = \"base1\" }\n\n# bufferline, inlay hints\n\"ui.bufferline\" = { fg = \"base6\", bg = \"base8x0c\" }\n\"ui.bufferline.active\" = { fg = \"base8\", bg = \"base4\" }\n\"ui.virtual.inlay-hint\" = { fg = \"base6\" }\n\n# comments, nord3 based lighter color\n\"comment\" = { fg = \"base5\", modifiers = [\"italic\"] }\n\"ui.linenr\" = { fg = \"base5\" }\n\n# cursor, variables, constants, attributes, fields\n\"ui.cursor.primary\" = { fg = \"base7\", modifiers = [\"reversed\"] }\n\"attribute\" = \"blue\"\n\"variable\"  = \"base8\"\n\"constant\"  = \"orange\"\n\"variable.builtin\" = \"red\"\n\"constant.builtin\" = \"red\"\n\"namespace\" = \"base8\"\n\n# base text, punctuation\n\"ui.text\" = { fg = \"base8\" }\n\"punctuation\" = \"base6\"\n\n# classes, types, primitives\n\"type\" = \"green\"\n\"type.builtin\" = { fg = \"red\"}\n\"label\" = \"base8\"\n\n# declaration, methods, routines\n\"constructor\" = \"blue\"\n\"function\" = \"green\"\n\"function.macro\" = { fg = \"blue\" }\n\"function.builtin\" = { fg = \"cyan\" }\n\n# operator, tags, units, punctuations\n\"operator\" = \"red\"\n\"variable.other.member\" = \"base8\"\n\n# keywords, special\n\"keyword\" = { fg = \"red\" }\n\"keyword.directive\" = \"blue\"\n\"variable.parameter\" = \"#f59762\"\n\n# error\n\"error\" = \"red\"\n\n# annotations, decorators\n\"special\" = \"#f59762\"\n\"module\" = \"#f59762\"\n\n# warnings, escape characters, regex\n\"warning\" = \"orange\"\n\"constant.character.escape\" = { fg = \"base8\" }\n\n# strings\n\"string\" = \"yellow\"\n\n# integer, floating point\n\"constant.numeric\" = \"purple\"\n\n# vcs\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"orange\"\n\"diff.minus\" = \"red\"\n\n# make diagnostic underlined, to distinguish with selection text.\n\"diagnostic.warning\" = { underline = { color = \"orange\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"base8\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"base8\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n# markup highlight, no need for `markup.raw` and `markup.list`, make them to be default\n\"markup.heading\" = \"green\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"orange\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"orange\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"yellow\"\n\"markup.quote\" = \"green\"\n\n[palette]\n# primary colors\n\"red\" = \"#fd6883\"\n\"orange\" = \"#f38d70\"\n\"yellow\" = \"#f9cc6c\"\n\"green\" = \"#adda78\"\n\"blue\" = \"#85dacc\"\n\"purple\" = \"#a8a9eb\"\n# base colors\n\"base0\" = \"#191515\"\n\"base1\" = \"#211c1c\"\n\"base2\" = \"#2c2525\"\n\"base3\" = \"#403838\"\n\"base4\" = \"#5b5353\"\n\"base5\" = \"#72696a\"\n\"base6\" = \"#8c8384\"\n\"base7\" = \"#c3b7b8\"\n\"base8\" = \"#fff1f3\"\n# variants\n\"base8x0c\" = \"#352e2e\"\n"
  },
  {
    "path": "runtime/themes/monokai_pro_spectrum.toml",
    "content": "# Author : WindSoilder<WindSoilder@outlook.com>\n# The unofficial Monokai Pro theme, simply migrate from jetbrains monokai pro theme: https://github.com/subtheme-dev/monokai-pro\n# Credit goes to the original creator: https://monokai.pro\n\n\"ui.linenr.selected\" = { bg = \"base3\" }\n\"ui.text.focus\" = { fg = \"yellow\", modifiers= [\"bold\"] }\n\"ui.menu\" = { fg = \"base8\", bg = \"base3\" }\n\"ui.menu.selected\" = { fg = \"base2\", bg = \"yellow\" }\n\"ui.virtual.whitespace\" = \"base4\"\n\"ui.virtual.ruler\" = { bg = \"base1\" }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"info\" = \"base8\"\n\"hint\" = \"base8\"\n\n# background color\n\"ui.background\" = { bg = \"base2\" }\n\n# status bars, panels, modals, autocompletion\n\"ui.statusline\" = { fg = \"base8\", bg = \"base4\" }\n\"ui.statusline.inactive\" = { fg = \"base8\", bg = \"base8x0c\" }\n\"ui.popup\" = { bg = \"base3\" }\n\"ui.window\" = { bg = \"base3\" }\n\"ui.help\" = { fg = \"base8\", bg = \"base3\" }\n\n# active line, highlighting\n\"ui.selection\" = { bg = \"base4\" }\n\"ui.cursor.match\" = { bg = \"base4\" }\n\"ui.cursorline\" = { bg = \"base1\" }\n\n# bufferline, inlay hints\n\"ui.bufferline\" = { fg = \"base6\", bg = \"base8x0c\" }\n\"ui.bufferline.active\" = { fg = \"base8\", bg = \"base4\" }\n\"ui.virtual.inlay-hint\" = { fg = \"base6\" }\n\n# comments, nord3 based lighter color\n\"comment\" = { fg = \"base5\", modifiers = [\"italic\"] }\n\"ui.linenr\" = { fg = \"base5\" }\n\n# cursor, variables, constants, attributes, fields\n\"ui.cursor.primary\" = { fg = \"base7\", modifiers = [\"reversed\"] }\n\"attribute\" = \"blue\"\n\"variable\"  = \"base8\"\n\"constant\"  = \"orange\"\n\"variable.builtin\" = \"red\"\n\"constant.builtin\" = \"red\"\n\"namespace\" = \"base8\"\n\n# base text, punctuation\n\"ui.text\" = { fg = \"base8\" }\n\"punctuation\" = \"base6\"\n\n# classes, types, primitives\n\"type\" = \"green\"\n\"type.builtin\" = { fg = \"red\"}\n\"label\" = \"base8\"\n\n# declaration, methods, routines\n\"constructor\" = \"blue\"\n\"function\" = \"green\"\n\"function.macro\" = { fg = \"blue\" }\n\"function.builtin\" = { fg = \"blue\" }\n\n# operator, tags, units, punctuations\n\"operator\" = \"red\"\n\"variable.other.member\" = \"base8\"\n\n# keywords, special\n\"keyword\" = { fg = \"red\" }\n\"keyword.directive\" = \"blue\"\n\"variable.parameter\" = \"#f59762\"\n\n# error\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n# annotations, decorators\n\"special\" = \"#f59762\"\n\"module\" = \"#f59762\"\n\n# warnings, escape characters, regex\n\"warning\" = \"orange\"\n\"constant.character.escape\" = { fg = \"base8\" }\n\n# strings\n\"string\" = \"yellow\"\n\n# integer, floating point\n\"constant.numeric\" = \"purple\"\n\n# vcs\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"orange\"\n\"diff.minus\" = \"red\"\n\n# make diagnostic underlined, to distinguish with selection text.\n\"diagnostic.warning\" = { underline = { color = \"orange\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"base8\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"base8\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n# markup highlight, no need for `markup.raw` and `markup.list`, make them to be default\n\"markup.heading\" = \"green\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"orange\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"orange\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"yellow\"\n\"markup.quote\" = \"green\"\n\n[palette]\n# primary colors\n\"red\" = \"#fc618d\"\n\"orange\" = \"#fd9353\"\n\"yellow\" = \"#fce566\"\n\"green\" = \"#7bd88f\"\n\"blue\" = \"#5ad4e6\"\n\"purple\" = \"#948ae3\"\n# base colors\n\"base0\" = \"#131313\"\n\"base1\" = \"#191919\"\n\"base2\" = \"#222222\"\n\"base3\" = \"#363537\"\n\"base4\" = \"#525053\"\n\"base5\" = \"#69676c\"\n\"base6\" = \"#8b888f\"\n\"base7\" = \"#bab6c0\"\n\"base8\" = \"#f7f1ff\"\n# variants\n\"base8x0c\" = \"#2b2b2b\"\n"
  },
  {
    "path": "runtime/themes/monokai_soda.toml",
    "content": "# Monokai Soda port for Helix (https://helix-editor.com)\n# Author : Jimmy Zelinskie <jimmy@zelinskie.com>\n\n# Syntax\n\n## Constants\n\"constant\" = \"white\"\n\"constant.builtin\" = \"pink\"\n\"constant.character.escape\" = \"blue\"\n\"constant.numeric\" = \"purple\"\n\n## Diagnostics\n\"diagnostic\" = { modifiers = [\"underlined\"] }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"pink\" } }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"orange\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"white\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n## Diffs\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"orange\"\n\"diff.minus\" = \"pink\"\n\"diff.delta.moved\" = \"orange\"\n\n## Functions\n\"function\" = \"green\"\n\"function.macro\" = \"blue\"\n\"function.builtin\" = \"pink\"\n\"constructor\" = \"blue\"\n\n## Keywords\n\"keyword\" = \"pink\"\n\"keyword.directive\" = \"blue\"\n\n## Punctuation\n\"punctuation\" = \"gray\"\n\n## Strings\n\"string\" = \"yellow\"\n\n## Types\n\"type\" = \"blue\"\n\"type.builtin\" = \"pink\"\n\n## Variables\n\"variable\"  = \"white\"\n\"variable.builtin\" = \"pink\"\n\"variable.other.member\" = \"white\"\n\"variable.parameter\" = \"softorange\"\n\n## Markup\n\"markup.heading\" = \"green\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"orange\", modifiers = [\"italic\"] }\n\"markup.link.url\" = { fg = \"orange\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"yellow\"\n\"markup.quote\" = \"green\"\n\n## Misc\n\"attribute\" = \"blue\"\n\"comment\" = { fg = \"gray\", modifiers = [\"italic\"] }\n\"error\" = \"pink\"\n\"hint\" = \"white\"\n\"info\" = \"white\"\n\"label\" = \"yellow\"\n\"module\" = \"softorange\"\n\"namespace\" = \"pink\"\n\"operator\" = \"pink\"\n\"special\" = \"softorange\"\n\"warning\" = \"orange\"\n\n# Editor UI\n\n## Main\n\"ui.background\" = { bg = \"background\" }\n\"ui.text\" = \"white\"\n\"ui.window\" = { bg = \"darkgray\" }\n\n## Debug (TODO)\n\n## Menus\n\"ui.menu\" = { fg = \"white\", bg = \"darkgray\" }\n\"ui.menu.selected\" = { modifiers = [\"reversed\"] }\n\"ui.popup\" = { bg = \"darkgray\" }\n\"ui.help\" = { fg = \"white\", bg = \"darkgray\" }\n\n## Gutter\n\"ui.linenr\" = \"darkgray\"\n\"ui.linenr.selected\" = \"orange\"\n\n## Cursor\n\"ui.cursor.primary\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.selection\" = { bg = \"darkgray\" }\n\n## Statusline\n\"ui.statusline\" = { bg = \"darkgray\" }\n\"ui.statusline.inactive\" = { fg = \"white\", bg = \"darkgray\" }\n\"ui.statusline.normal\" = { fg = \"white\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"white\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"white\", bg = \"purple\" }\n\n\"ui.text.focus\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"ui.virtual\" = \"darkgray\"\n\"ui.virtual.ruler\" = { bg = \"darkgray\" }\n\"ui.virtual.jump-label\" = { fg = \"softorange\", modifiers = [\"bold\"] }\n\n# Palette\n\n[palette]\n\"purple\" = \"#AE81FF\"\n\"yellow\" = \"#E6DB74\"\n\"pink\" = \"#f92a72\"\n\"white\" = \"#cfcfc2\"\n\"gray\" = \"#75715e\"\n\"darkgray\" = \"#444444\"\n\"black\" = \"#222222\"\n\"blue\" = \"#66d9ef\"\n\"green\" = \"#a6e22e\"\n\"softorange\" = \"#f59762\"\n\"orange\" = \"#fd971f\"\n\"background\" = \"#191919\"\n"
  },
  {
    "path": "runtime/themes/naysayer.toml",
    "content": "# Author: Nick Saika <n@nesv.ca>\n#\n# This theme is a port of naysayer-theme.el:\n#    https://github.com/nickav/naysayer-theme.el\n\n\"ui.background\" = { bg = \"bg\" }\n\"ui.text\" = \"text\"\n\"ui.linenr\" = { bg = \"bg\", fg = \"line-fg\" }\n\"ui.linenr.selected\" = { bg = \"highlight-line\", fg = \"line-fg\" }\n\"ui.selection\" = { bg = \"selection\" }\n\"ui.cursorline\" = { bg = \"highlight-line\" }\n\"ui.statusline\" = { fg = \"bg\", bg = \"text\" }\n\"ui.statusline.inactive\" = { fg = \"text\", bg = \"bg\" }\n\"ui.virtual\" = \"indent\"\n\"ui.virtual.ruler\" = { bg = \"line-fg\" }\n\"ui.cursor.match\" = { bg = \"cyan\" }\n\"ui.cursor\" = { bg = \"#777777\" }\n\"ui.cursor.primary\" = { bg = \"white\" }\n\"ui.debug\" = { fg = \"orange\" }\n\"ui.highlight.frameline\" = { bg = \"#da8581\" }\n\"ui.help\" = { fg = \"text\", bg = \"bg\" }\n\"ui.popup\" = { fg = \"text\", bg = \"bg\" }\n\"ui.menu\" = { fg = \"text\", bg = \"bg\" }\n\"ui.menu.selected\" = { fg = \"text\", bg = \"bg\", modifiers = ['underlined'] }\n\"ui.window\" = { bg = \"bg\" }\n\"diagnostic.error\" = { bg = \"error\", fg = \"text\", modifiers = [\"bold\"] }\n\"diagnostic.warning\" = { bg = \"warning\", fg = \"text\", modifiers = [\"bold\"] }\n\"diagnostic.hint\" = { bg = \"cyan\", modifiers = [\"bold\"] }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"ui.bufferline\" = { fg = \"text\", bg = \"bg\" }\n\"ui.bufferline.active\" = { fg = \"text\", bg = \"bg\", modifiers = ['underlined'] }\n\"ui.gutter.selected\" = { bg = \"highlight-line\", modifiers = [\"bold\"] }\n\"ui.highlight\" = { bg = \"highlight-line\" }\n\n# Scopes: Syntax Highlighting.\n\"attribute\" = \"text\"\n\"type\" = \"text\"\n\"type.builtin\" = \"builtin\"\n\"constructor\" = \"functions\"\n\"constant\" = \"constants\"\n\"constant.builtin\" = \"builtin\"\n\"constant.builtin.boolean\" = \"builtin\"\n\"constant.character\" = \"text\"\n\"constant.numeric\" = \"numbers\"\n\"string\" = \"strings\"\n\"comment\" = \"comments\"\n\"variable\" = \"variables\"\n\"variable.builtin\" = \"builtin\"\n\"punctuation\" = \"punctuation\"\n\"keyword\" = \"keywords\"\n\"function\" = \"functions\"\n\"function.method\" = \"methods\"\n\"function.builtin\" = \"builtin\"\n\"function.macro\" = \"macros\"\n\"function.special\" = \"macros\"\n\"tag.builtin\" = \"builtin\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"diff.plus\" = { fg = \"green\" }\n\"diff.minus\" = { fg = \"red\" }\n\"diff.delta\" = { fg = \"blue\" }\n\n[palette]\nbg = \"#062329\"\ntext = \"#d1b897\"\nbuiltin = \"#ffffff\"\nselection = \"#0000ff\"\ncomments = \"#44b340\"\npunctuation = \"#8cde94\"\nkeywords = \"#ffffff\"\nvariables = \"#c1d1e3\"\nfunctions = \"#ffffff\"\nmethods = \"#c1d1e3\"\nstrings = \"#2ec90c\"\nconstants = \"#7ad0c6\"\nmacros = \"#8cde94\"\nnumbers = \"#7ad0c6\"\nwhite = \"#ffffff\"\nerror = \"#ff0000\"\nwarning = \"#ffaa00\"\nhighlight-line = \"#0b3335\"\nline-fg = \"#126367\"\nindent = \"#aaaaaa\"\n\nyellow = \"#e6db74\"\norange = \"#fd971f\"\nred = \"#f92672\"\nmagenta = \"#fd5ff0\"\nblue = \"#66d9ef\"\ngreen = \"#a6e22e\"\ncyan = \"#a1efe4\"\nviolet = \"#a381ff\"\n"
  },
  {
    "path": "runtime/themes/neonotte.toml",
    "content": "# NeoNotte Theme\n#\n# Author: b52es (https://github.com/b52es)\n# Inspired by Catppuccin Mocha and Tokyo Night.\n\n# Syntax highlighting\n# -------------------\n\"attribute\" = \"blue\"\n\"comment\" = { fg = \"comment_dark\", modifiers = [\"italic\"] }\n\"constant\" = \"orange\"\n\"constant.builtin\" = \"orange\"\n\"constant.character\" = \"teal\"\n\"constant.character.escape\" = \"fuchsia\"\n\"constructor\" = \"cyan\"\n\"function\" = \"blue\"\n\"function.macro\" = \"magenta\"\n\"keyword\" = \"magenta\"\n\"keyword.storage.modifier.ref\" = \"teal\"\n\"keyword.control.conditional\" = { fg = \"magenta\" }\n\"label\" = \"cyan\"\n\"namespace\" = \"orange\"\n\"operator\" = \"red\"\n\"punctuation\" = \"comment\"\n\"punctuation.special\" = \"sky_blue\"\n\"punctuation.bracket\" = \"red\"\n\"punctuation.delimiter\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"special\" = \"blue\"\n\"string\" = \"green\"\n\"string.regexp\" = \"orange\"\n\"string.special\" = \"blue\"\n\"tag\" = \"magenta\"\n\"type\" = \"yellow\"\n\"variable\" = \"fg\"\n\"variable.builtin\" = \"red\"\n\"variable.parameter\" = { fg = \"red_muted\" }\n\"variable.other.member\" = \"teal\"\n\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.heading.marker\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.heading.1\" = \"indigo\"\n\"markup.heading.2\" = \"magenta\"\n\"markup.heading.3\" = \"green\"\n\"markup.heading.4\" = \"yellow\"\n\"markup.heading.5\" = \"fuchsia\"\n\"markup.heading.6\" = \"teal\"\n\"markup.italic\" = \"pink_light\"\n\"markup.link.url\" = { fg = \"pink_light\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"blue\"\n\"markup.list\" = \"magenta\"\n\"markup.raw\" = \"pink_hot\"\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"blue\"\n\n# User Interface\n# --------------\n\"ui.background\" = { fg = \"fg\", bg = \"bg\" }\n\n\"ui.linenr\" = { fg = \"bg_highlight\" }\n\"ui.linenr.selected\" = { fg = \"indigo\" }\n\n\"ui.statusline\" = { fg = \"fg_subtle\", bg = \"bg_dark\" }\n\"ui.statusline.inactive\" = { fg = \"bg_inactive\", bg = \"bg_dark\" }\n\"ui.statusline.normal\" = { fg = \"bg\", bg = \"indigo\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"bg\", bg = \"green\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"bg\", bg = \"pink_hot\", modifiers = [\"bold\"] }\n\n\"ui.popup\" = { fg = \"fg\", bg = \"bg_surface\" }\n\"ui.window\" = { fg = \"bg_darkest\" }\n\"ui.help\" = { fg = \"comment\", bg = \"bg_surface\" }\n\n\"ui.bufferline\" = { fg = \"fg_dark\", bg = \"bg_dark\" }\n\"ui.bufferline.active\" = { fg = \"sky_blue\", bg = \"cursorline\", modifiers = [\"bold\"] }\n\"ui.bufferline.background\" = \"bg\"\n\n\"ui.text\" = \"fg\"\n\"ui.text.focus\" = { fg = \"fg\", bg = \"bg_surface\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = { fg = \"comment_dark\" }\n\n\"ui.virtual\" = \"guide\"\n\"ui.virtual.ruler\" = { bg = \"bg_surface\" }\n\"ui.virtual.indent-guide\" = \"bg_surface\"\n\"ui.virtual.inlay-hint\" = { fg = \"guide\", bg = \"bg\" }\n\n\"ui.selection\" = { bg = \"bg_highlight\" }\n\n\"ui.cursor\" = { fg = \"bg\", bg = \"secondary_cursor\" }\n\"ui.cursor.primary\" = { fg = \"bg\", bg = \"pink_light\" }\n\"ui.cursor.match\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\n\"ui.cursor.primary.normal\" = { fg = \"bg\", bg = \"indigo\" }\n\"ui.cursor.primary.insert\" = { fg = \"bg\", bg = \"green\" }\n\"ui.cursor.primary.select\" = { fg = \"bg\", bg = \"pink_hot\" }\n\n\"ui.cursor.normal\" = { fg = \"bg\", bg = \"secondary_cursor_normal\" }\n\"ui.cursor.insert\" = { fg = \"bg\", bg = \"secondary_cursor_insert\" }\n\"ui.cursor.select\" = { fg = \"bg\", bg = \"secondary_cursor\" }\n\n\"ui.cursorline.primary\" = { bg = \"cursorline\" }\n\n\"ui.highlight\" = { bg = \"bg_highlight\", modifiers = [\"bold\"] }\n\n\"ui.menu\" = { fg = \"comment\", bg = \"bg_surface\" }\n\"ui.menu.selected\" = { fg = \"fg\", bg = \"bg_highlight\", modifiers = [\"bold\"] }\n\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"sky_blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"teal\", style = \"curl\" } }\n\n\"error\" = { fg = \"red\", modifiers = ['bold'] }\n\"warning\" = { fg = \"yellow\", modifiers = ['bold'] }\n\"info\" = \"sky_blue\"\n\"hint\" = \"teal\"\n\n[palette]\n# Accent Colors\npink_light = \"#f8ded9\"\npink_hot = \"#f7c8c8\"\nfuchsia = \"#ffc1fc\"\nmagenta = \"#ee82ee\"\nred = \"#ff7ea2\"\nred_muted = \"#f497a6\"\norange = \"#ea8743\"\nyellow = \"#ffea9b\"\ngreen = \"#9feb99\"\nteal = \"#59d2be\"\nsky_blue = \"#7de4f7\"\ncyan = \"#65cdfb\"\nblue = \"#7bb1ff\"\nindigo = \"#abb7ff\"\n\n# Foreground/Text\nfg = \"#cdd6f4\"\nfg_subtle = \"#b5bfe3\"\nfg_dark = \"#a2abcc\"\ncomment = \"#8f97b6\"\ncomment_dark = \"#7b82a0\"\nguide = \"#696e89\"\n\n# Background\nbg_darkest = \"#08080d\"\nbg_dark = \"#1f212d\"\nbg = \"#151520\"\nbg_surface = \"#272836\"\nbg_highlight = \"#42455d\"\nbg_inactive = \"#555973\"\n\n# Derived colors\ncursorline = \"#28293e\"\nsecondary_cursor = \"#b7a4a7\"\nsecondary_cursor_normal = \"#8089c7\"\nsecondary_cursor_insert = \"#78ad79\"\n"
  },
  {
    "path": "runtime/themes/neonotte84.toml",
    "content": "# NeoNotte84 Theme\n#\n# Author: b52es (https://github.com/b52es)\n# Inspired by Catppuccin Mocha and Tokyo Night.\n\n# Inherits from neonotte.toml and applies a few modifications.\ninherits = \"neonotte\"\n\n# Syntax highlighting overrides\n# ---------------------------\n\"comment\" = { fg = \"comment_alt\", modifiers = [\"italic\"] }\n\n# Palette overrides\n# -----------------\n[palette]\nmagenta = \"#f578de\"\nyellow = \"#ffd866\"\ncomment_alt = \"#647a8c\"\n"
  },
  {
    "path": "runtime/themes/new_moon.toml",
    "content": "\n\"namespace\" = { fg = \"blue\" }\n\"module\" = { fg = \"blue\" }\n\n\"type\" = { fg = \"blue\" }\n\"type.builtin\" = { fg = \"blue\" }\n\"type.enum.variant\" = { fg = \"blue\" } # or aqua\n\"constructor\" = { fg = \"blue\" }\n\"variable.other.member\" = { fg = \"red\" }\n\n\"keyword\" = { fg = \"light_yellow\" }\n\"keyword.directive\" = { fg = \"light_yellow\" }\n\"keyword.control\" = { fg = \"light_yellow\" }\n\"label\" = { fg = \"blue\" }\n\"tag\" = \"blue\"\n\n\"special\" = { fg = \"lightest\" } # or beige\n\"operator\" = { fg = \"beige\" }\n\n\"punctuation\" = { fg = \"text\" }\n\"punctuation.delimiter\" = { fg = \"text\" }\n\n\"variable\" = { fg = \"red\" }\n\"variable.parameter\" = { fg = \"red\" }\n\"variable.builtin\" = { fg = \"blue\" }\n\"constant\" = { fg = \"purple\" }\n\"constant.builtin\" = { fg = \"purple\" }\n\n\"function\" = { fg = \"lightest\" }\n\"function.builtin\" = { fg = \"lightest\" }\n\"function.macro\" = { fg = \"blue\" }\n\"attribute\" = { fg = \"yellow\" }\n\n\"comment\" = { fg = \"medium\" }\n\n\"string\" = { fg = \"green\" }\n\"constant.character\" = { fg = \"green\" }\n\"string.regexp\" = { fg = \"orange\" }\n\"constant.numeric\" = { fg = \"orange\" }\n\"constant.character.escape\" = { fg = \"aqua\" }\n\n\"markup.heading\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.list\" = \"aqua\"\n\"markup.bold\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"orange\"\n\"markup.quote\" = \"green\"\n\"markup.raw\" = \"orange\"\n\n\"diff.plus\" = { fg = \"green\" }\n\"diff.delta\" = { fg = \"blue\" }\n\"diff.minus\" = { fg = \"red\" }\n\n\"ui.background\" = { fg = \"light\", bg = \"darkest\" }\n\n\"ui.window\" = { bg = \"widget\" }\n\"ui.popup\" = { fg = \"beige\", bg = \"widget\" }\n\"ui.help\" = { fg = \"text\", bg = \"widget\" }\n\"ui.menu\" = { fg = \"text\", bg = \"widget\" }\n\"ui.menu.selected\" = { bg = \"darker_blue\" }\n\n\"ui.cursor\" = { fg = \"cursor\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"cursor\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { bg = \"#3a3d41\", modifiers = [\"underlined\"] }\n\n\"ui.selection\" = { bg = \"#3a3d41\" }\n\"ui.selection.primary\" = { bg = \"darkest_blue\" }\n\n\"ui.linenr\" = { fg = \"dark_gray_virtual\" }\n\"ui.linenr.selected\" = { fg = \"light_gray_virtual\" }\n\n\"ui.cursorline.primary\" = { bg = \"active_line\" }\n\"ui.statusline\" = { fg = \"white\", bg = \"darker_blue\" }\n# \"ui.statusline.inactive\" = { fg = \"white\", bg = \"blue\" }\n# \"ui.statusline.insert\" = { fg = \"white\", bg = \"yellow\" }\n# \"ui.statusline.select\" = { fg = \"white\", bg = \"magenta\" }\n\n\"ui.bufferline\" = { fg = \"text\", bg = \"widget\" }\n\"ui.bufferline.active\" = { fg = \"white\", bg = \"darker_blue\" }\n\"ui.bufferline.background\" = { bg = \"darkest\" }\n\n\"ui.text\" = { fg = \"text\" }\n\"ui.text.focus\" = { fg = \"lightest\" }\n\n\"ui.virtual.whitespace\" = { fg = \"dark_gray_virtual\" }\n\"ui.virtual.ruler\" = { bg = \"borders\" }\n\"ui.virtual.indent-guide\" = { fg = \"dark_gray_virtual\" }\n\"ui.virtual.inlay-hint\" = { fg = \"dark_gray_virtual\"}\n\n\"warning\" = { fg = \"yellow\" }\n\"error\" = { fg = \"red\" }\n\"info\" = { fg = \"blue\" }\n\"hint\" = { fg = \"light_gray\" }\n\n\"diagnostic.error\".underline = { color = \"red\", style = \"curl\" }\n\"diagnostic\".underline = { color = \"yellow\", style = \"curl\" }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\ndarkest = \"#2d2d2d\"\nmedium = \"#777c85\"\nlight = \"#b3b9c5\"\nlightest = \"#ffffff\"\nred = \"#f2777a\"\norange = \"#fca369\"\nyellow = \"#ffd479\"\nlight_yellow = \"#ffeea6\"\ngreen = \"#92d192\"\nblue = \"#6ab0f3\"\ndarker_blue = \"#007acc\"\ndarkest_blue= \"#264f78\"\naqua = \"#76d4d6\"\npurple = \"#e1a6f2\"\nbeige = \"#ac8d58\"\nlight_gray = \"#eeeeee\"\ndark_gray_virtual = \"#606060\"\nlight_gray_virtual = \"#909090\"\nactive_line = \"#252525\"\n\ntext = \"#d4d4d4\"\ncursor = \"#a6a6a6\"\nwidget = \"#252526\"\nborders = \"#323232\"\n"
  },
  {
    "path": "runtime/themes/night_owl.toml",
    "content": "# Author : Joe Mckay joemckay3006@gmail.com\n# Palette from https://github.com/haishanh/night-owl.vim\n\n'warning' = { fg = 'peach', modifiers = ['dim'] }\n'error' = { fg = 'red', modifiers = ['dim'] }\n'info' = { fg = 'blue', modifiers = ['dim'] }\n'hint' = { fg = 'paleblue', modifiers = ['dim'] }\n\n\"diagnostic.warning\" = { underline = { color = \"peach\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"paleblue\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n# UI\n'ui.background' = { fg = 'foreground', bg = 'background' }\n'ui.window' = { fg = 'grey7' }\n'ui.gutter' = { bg = 'grey2' }\n'ui.text' = { fg = 'foreground' }\n'ui.text.focus' = { fg = 'foreground' }\n'ui.text.info' = { fg = 'foreground'}\n'ui.cursor' = { fg = 'background', bg = 'blue' }\n'ui.cursor.primary' = { fg = 'background', bg = 'gold' }\n'ui.cursor.match' = { bg = 'selection', modifiers = ['underlined'] }\n'ui.selection' = { bg = 'selection', modifiers = ['dim'] }\n'ui.linenr' = { fg = 'grey4', bg = 'background2' }\n'ui.linenr.selected' = { fg = 'greyE', bg = 'background2'  }\n'ui.statusline' = { fg = 'greyE', bg = 'background2' }\n'ui.statusline.inactive' = { fg = 'grey7', bg = 'background2' }\n'ui.statusline.normal' = { bg = 'slate' }\n'ui.statusline.insert' = { bg = 'peach' }\n'ui.statusline.select' = { bg = 'green' }\n'ui.menu' = { fg = 'foreground', bg = 'selection' }\n'ui.menu.selected' = { fg = 'foreground', bg = 'pink' }\n'ui.popup' = { fg = 'foreground', bg = 'background2' }\n'ui.popup.info' = { fg = 'gold', bg = 'background2'}\n'ui.help' = { fg = 'gold', bg = 'background2'}\n'ui.virtual.ruler' = { bg = 'grey4' }\n'ui.virtual.whitespace' = { fg = 'grey4' }\n'ui.cursorline.primary' = { bg = 'background2' }\n\n# SYNTAX\n'type' = { fg = 'green' }\n'constructor' = { fg = 'blue' }\n'constant' = { fg = 'foreground' }\n'constant.builtin' = { fg = 'paleblue' }\n'constant.character.escape' = { fg = 'peach' }\n'string' = { fg = 'gold' }\n'string.regexp' = { fg = 'green' }\n'string.special.url' = { fg = 'gold', modifiers = ['underlined'] }\n'comment' = { fg = 'slate', modifiers = ['italic'] }\n'comment.block.documentation' = { fg = 'slate' }\n'comment.line.documentation' = { fg = 'slate' }\n'variable' = { fg = 'green' }\n'variable.builtin' = { fg = 'green', modifiers = ['italic'] }\n'label' = { fg = 'foreground' }\n'punctuation' = { fg = 'foreground' }\n'punctuation.special' = { fg = 'pink' }\n'keyword' = { fg = 'pink' }\n'keyword.control.import' = { fg = 'green', modifiers = ['italic'] }\n'keyword.control.return' = { fg = 'pink', modifiers = ['italic'] }\n'keyword.control.exception' = { fg = 'red' }\n'operator' = { fg = 'pink' }\n'function' = { fg = 'blue' }\n'function.macro' = { fg = 'peach' }\n'function.special' = { fg = 'pink' }\n'tag' = { fg = 'blue' }\n'namespace' = { fg = 'peach' }\n'special' = { fg = 'greyE' }\n'module' = { fg = 'greyE' }\n'attribute' = { fg = 'paleblue' }\n\n# MARKUP\n'markup.heading' = { fg = 'blue', modifiers = ['bold'] }\n'markup.heading.marker' = { fg = 'grey4', modifiers = ['dim'] }\n'markup.heading.1' = { fg = 'blue', modifiers = ['bold'] }\n'markup.heading.2' = { fg = 'paleblue', modifiers = ['bold']  }\n'markup.heading.3' = { fg = 'green', modifiers = ['bold'] }\n'markup.heading.4' = { fg = 'pink', modifiers = ['bold'] }\n'markup.heading.5' = { fg = 'peach', modifiers = ['bold'] }\n'markup.heading.6' = { fg = 'slate', modifiers = ['bold'] }\n'markup.list' = { fg = 'pink' }\n'markup.bold' = { fg = 'foreground', modifiers = ['bold'] }\n'markup.italic' = { fg = 'foreground', modifiers = ['italic'] }\n'markup.strikethrough' = { fg = 'foreground', modifiers = ['crossed_out'] }\n'markup.link' = { fg = 'pink', modifiers = ['underlined'] }\n'markup.link.url' = { fg = 'slate', modifiers = ['underlined'] }\n'markup.quote' = { fg = 'green', modifiers = ['italic'] }\n'markup.raw' = { fg = 'gold', bg = 'background2' }\n\n# DIFF\n'diff.plus' = { fg = 'green' }\n'diff.minus' = { fg = 'red' }\n'diff.delta' = { fg = 'blue' }\n'diff.delta.moved' = { fg = 'blue', modifiers = ['italic'] }\n\n[palette]\nbackground = '#011627'\nbackground2 = '#112630'\nforeground = '#d6deeb'\nselection = '#2d2c5d'\n\nslate = '#637777'\nred = '#ff5874'\npeach = '#f78c6c'\ngold = '#ecc48d'\npink = '#c792ea'\ngreen = '#addb67'\nblue = '#82aaff'\npaleblue = '#7fdbca'\n\n# Greys are named after their value.\ngrey2 = '#222222'\ngrey4 = '#444444'\ngrey7 = '#777777'\ngreyE = '#eeeeee'\n"
  },
  {
    "path": "runtime/themes/night_rider.toml",
    "content": "# Author: F.Nomeniavo Joe <24nomeniavo@gmail.com>\n# Ported Theme: Night Rider\n#\n# Original Author Credit:\n# This color scheme is based on the original VS Code theme by trustfall.\n# Repository: https://github.com/trustfall/vscode-night-rider# \n\n# SYNTAX\n\"attribute\" = \"#7b79b5\"\n\"comment\" = { fg = \"#5C588A\", modifiers = [\"italic\"] }\n\"constant\" = \"#e591ff\"\n\"constant.builtin\" = \"#AC70FC\"\n\"constant.character\" = \"#71E4FE\"\n\"contant.character.escape\" = \"#71E4FE\"\n\"constant.numeric\" = \"#DA65BA\"\n\"constructor\" = { fg = \"#e591ff\", modifiers = [\"italic\"] }\n\"diff.delta\" = \"#F1C56C\"\n\"diff.minus\" = \"#FF6E9C\"\n\"diff.plus\" = \"#45F5CF\"\n\"function\" = \"#D8608C\"\n\"function.builtin\" = { fg = \"#D8608C\", modifiers = [\"italic\"] }\n\"function.macro\" = \"#AC70FC\"\n\"keyword\" = \"#AC70FC\"\n\"keyword.control\" = \"#A68AE1\"\n\"keyword.directive\" = \"#A68AE1\"\n\"label\" = \"#7DA7FF\"\n\"module\" = \"#e591ff\"\n\"namespace\" = \"#e591ff\"\n\"operator\" = \"#9C57F0\"\n\"punctuation\" = \"#6FFEE0\"\n\"punctuation.delimiter\" = \"#C9CBDB\"\n\"string\" = \"#74FEE1\"\n\"string.regexp\" = \"#71E4FE\"\n\"tag\" = \"#7EA7F3\"\n\"special\" = \"#7EA7FF\"\n\"type\" = { fg = \"#e591ff\", modifiers = [\"italic\"] }\n\"type.builtin\" = { fg = \"#e591ff\", modifiers = [\"italic\"] }\n\"type.enum.variant\" = { fg = \"#e591ff\", modifiers = [\"italic\"] }\n\"variable\" = \"#C9CBDB\"\n\"variable.builtin\" = \"#e591ff\"\n\"variable.other.member\" = \"#C9CBDB\"\n\"variable.parameter\" = \"#C9CBDB\"\n\n# UI\n\"ui.background\" = { \"bg\" = \"background\" }\n\"ui.window\" = { \"bg\" = \"widget\" }\n\"ui.popup\" = { \"fg\" = \"text\", bg = \"widget\" }\n\"ui.help\" = { \"fg\" = \"text\", bg = \"widget\" }\n\"ui.menu\" = { \"fg\" = \"text\", bg = \"widget\" }\n\"ui.menu.selected\" = { fg = \"#789ef8\", modifiers = [\"reversed\"] }\n\n\"ui.cursor\" = { fg = \"cursor\", modifiers = [\"reversed\"] }\n\"ui.selection\" = { \"bg\" = \"selection\" }\n\"ui.selection.primary\" = { \"bg\" = \"#625D88\" }\n\"ui.linenr\" = { fg = \"#696292\" }\n\"ui.linenr.selected\" = { fg = \"#27264B\" }\n\"ui.cursorline.primary\" = { bg = \"#887ced\" }\n\"ui.statusline\" = { fg = \"status_fg\", bg = \"status_bg\" }\n\"ui.statusline.inactive\" = { fg = \"#5C588A\", bg = \"background\" }\n\"ui.statusline.normal\" = { fg = \"status_bg\", bg = \"status_fg\" }\n\"ui.statusline.insert\" = { fg = \"status_bg\", bg = \"#7EA7FB\" }\n\"ui.statusline.select\" = { fg = \"status_bg\", bg = \"#e591ff\" }\n\n\"ui.bufferline\" = { fg = \"text\", bg = \"widget\" }\n\"ui.bufferline.active\" = { fg = \"#789EF8\", bg = \"background\" }\n\"ui.bufferline.background\" = { bg = \"background\" }\n\"ui.text\" = { fg = \"text\" }\n\"ui.text.focus\" = { fg = \"#ffffff\" }\n\"ui.text.directory\" = { fg = \"#AC70FC\" }\n\"ui.text.inactive\" = { fg = \"#7EA7F3\" }\n\"ui.virtual.whitespace\" = { fg = \"#5C588A\" }\n\"ui.virtual.indent-guide\" = { bg = \"#24215E\" }\n\"ui.debug.active\" = { fg = \"#A68AE1\" }\n\"ui.debug.breakpoint\" = { fg = \"white\" }\n\"ui.picker.header.column\" = { underline.style = \"line\" }\n\"ui.picker.header.column.active\" = { fg = \"white\", underline.style = \"line\" }\n\n\"warning\" = { \"fg\" = \"#71E4FE\" }\n\"error\" = { \"fg\" = \"#FF709D\" }\n\"info\" = { \"fg\" = \"#7DA7FF\" }\n\"hint\" = { \"fg\" = \"#7DA7FF\" }\n\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { fg = \"white\", bg = \"#454568\" }\n\n\"diagnostic.error\" = { underline = { color = \"text\", style = \"curl\" } }\n\"diagnostic\".underline = { color = \"text\", style = \"curl\" }\n\n\n[palette]\nbackground = \"#1e1c3f\"\nwidget = \"#222246\"\nselection = \"#5D4089\"\ncursor = \"#7EA7FB\"\nstatus_bg = \"#171530\"\nstatus_fg = \"#5D5988\"\ntext = \"#C9CBDB\"\nred = \"#D8608C\"\nwhite = \"#FFFFFF\"\n"
  },
  {
    "path": "runtime/themes/nightfox.toml",
    "content": "# Author: github.com/jhscheer\n#\n# This theme is an adaptation of\n# github.com/EdenEast/nightfox.nvim\n\n\n# INTERFACE\n# These scopes are used for theming the editor interface.\n\n\"ui.background\" = { bg = \"bg1\" } # Default background color.\n\"ui.window\" = { fg = \"bg0\" } # Window border between splits.\n\"ui.gutter\" = { fg = \"fg3\" } # Left gutter for diagnostics and breakpoints.\n\n\"ui.text\" = { fg = \"fg1\" } # Default text color.\n\"ui.text.directory\" = { fg = \"blue-bright\" } # Directory names in prompt completion.\n\"ui.text.focus\" = { bg = \"sel1\", fg = \"fg1\" } # Selection highlight in buffer-picker or file-picker.\n\"ui.text.info\" = { fg = \"fg2\", bg = \"sel0\" } # Info popup contents (space mode menu).\n\n\"ui.cursor\" = { bg = \"fg3\", fg = \"bg1\" } # Fallback cursor colour, non-primary cursors when there are multiple (shift-c).\n\"ui.cursor.primary\" = { bg = \"fg1\", fg = \"bg1\" } # The primary cursor when there are multiple (shift-c).\n\"ui.cursor.match\" = { fg = \"yellow\", modifiers = [\"bold\"] } # The matching parentheses of that under the cursor.\n\n\"ui.selection\" = { bg = \"bg4\" } # All currently selected text.\n\"ui.selection.primary\" = { bg = \"sel1\" } # The primary selection when there are multiple.\n\"ui.cursorline.primary\" = { bg = \"bg3\" } # The line of the primary cursor (if cursorline is enabled)\n# \"ui.cursorline.secondary\" = { } #\tThe lines of any other cursors (if cursorline is enabled)\n# \"ui.cursorcolumn.primary\" = { } #\tThe column of the primary cursor (if cursorcolumn is enabled)\n# \"ui.cursorcolumn.secondary\" = { } #\tThe columns of any other cursors (if cursorcolumn is enabled)\n\n\"ui.linenr\" = { fg = \"fg3\" } # Line numbers.\n\"ui.linenr.selected\" = { fg = \"yellow\", modifiers = [\"bold\"] } # Current line number.\n\n# \"ui.virtual\" = { } # Namespace for additions to the editing area.\n\"ui.virtual.ruler\" = { bg = \"bg3\" } # Vertical rulers (colored columns in editing area).\n\"ui.virtual.whitespace\" = { fg = \"bg3\" } # Whitespace markers in editing area.\n\"ui.virtual.indent-guide\" = { fg = \"black\" } # Vertical indent width guides\n\"ui.virtual.inlay-hint\" = { fg = \"comment\", bg = \"bg2\" } # Default style for inlay hints of all kinds\n\"ui.virtual.jump-label\" = { fg = \"blue\", modifiers = [\"bold\"] } # Style for virtual jump labels\n\"ui.virtual.wrap\" = { fg = \"fg3\" } # Soft-wrap indicator.\n\n\"ui.statusline\" = { fg = \"fg2\", bg = \"bg0\" } # Status line.\n\"ui.statusline.inactive\" = { fg = \"fg3\", bg = \"bg0\" } # Status line in unfocused windows.\n\"ui.statusline.normal\" = { bg = \"blue\", fg = \"bg0\", modifiers = [\"bold\"] } # Statusline mode during normal mode (only if editor.color-modes is enabled)\n\"ui.statusline.insert\" = { bg = \"green\", fg = \"bg0\", modifiers = [\"bold\"] } # Statusline mode during insert mode (only if editor.color-modes is enabled)\n\"ui.statusline.select\" = { bg = \"magenta\", fg = \"bg0\", modifiers = [\"bold\"] } # Statusline mode during select mode (only if editor.color-modes is enabled)\n\n\"ui.bufferline\" = { fg = \"fg3\", bg = \"bg2\", underline = { style = \"line\" } }\n\"ui.bufferline.active\" = { fg = \"fg2\", bg = \"bg4\" }\n\"ui.bufferline.background\" = { bg = \"bg0\" }\n\n\"ui.help\" = { bg = \"sel0\", fg = \"fg1\" } # Description box for commands.\n\n\"ui.menu\" = { bg = \"sel0\", fg = \"fg1\" } # Code and command completion menus.\n\"ui.menu.selected\" = { bg = \"fg3\" } # Selected autocomplete item.\n\"ui.menu.scroll\"\t= { fg = \"fg3\" } # fg sets thumb color, bg sets track color of scrollbar.\n\n\"ui.popup\" = { bg = \"bg0\", fg = \"fg1\" } # Documentation popups (space-k).\n\"ui.popup.info\" = { bg = \"sel0\", fg = \"fg1\" } # Info popups box (space mode menu).\n\n\"markup.raw\" = { fg = \"magenta\" } # Code block in Markdown.\n\"markup.raw.inline\" = { fg = \"orange\" } # `Inline code block` in Markdown.\n\"markup.heading\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.list\" = { fg = \"magenta\", modifiers = [\"bold\"] }\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"pink\" }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link\" = { fg = \"yellow-bright\", modifiers = [\"bold\"] }\n\"markup.quote\" = { fg = \"blue\" }\n\n\n# DIAGNOSTICS\n\"warning\" = { fg = \"yellow\", bg = \"bg1\" } # Diagnostics warning (gutter)\n\"error\" = { fg = \"red\", bg = \"bg1\" } # Diagnostics error (gutter)\n\"info\" = { fg = \"blue\", bg = \"bg1\" } # Diagnostics info (gutter)\n\"hint\" = { fg = \"green\", bg = \"bg1\" } # Diagnostics hint (gutter)\n\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } } #\tDiagnostics warning (editing area)\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } } #\tDiagnostics error (editing area)\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } } #\tDiagnostics info (editing area)\n\"diagnostic.hint\" = { underline = { color = \"green\", style = \"curl\" } } #\tDiagnostics hint (editing area)\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\n# SYNTAX HIGHLIGHTING\n# These keys match tree-sitter scopes.\n\n\"special\" = { fg = \"fg2\" } # Special symbols e.g `?` in Rust, `...` in Hare.\n\"attribute\" = { fg = \"yellow\" } # Class attributes, html tag attributes.\n\n\"type\" = { fg = \"yellow\" } # Variable type, like integer or string, including program defined classes, structs etc..\n\"type.builtin\" = { fg = \"cyan-bright\" } # Primitive types of the language (string, int, float).\n\"type.enum.variant\" = { fg = \"orange-bright\" }\n\n\"constructor\" = { fg = \"magenta\" } # Constructor method for a class or struct.\n\n\"constant\" = { fg = \"orange-bright\" } # Constant value\n\"constant.builtin\" = { fg = \"orange-bright\" } # Special constants like `true`, `false`, `none`, etc.\n\"constant.builtin.boolean\" = { fg = \"orange\" } # True or False.\n\"constant.character\" = { fg = \"green\" } # Constant of character type.\n\"constant.character.escape\" = { fg = \"yellow-bright\", modifiers = [\"bold\"] } # escape codes like \\n.\n\"constant.numeric\"  = { fg = \"orange\" } # constant integer or float value.\n\n\"string\" = { fg = \"green\" } # String literal.\n\"string.regexp\" = { fg = \"yellow-bright\" } # Regular expression literal.\n\"string.special\" = { fg = \"yellow-bright\", modifiers = [\"bold\"] } # Strings containing a path, URL, etc.\n\"string.special.url\" = { fg = \"cyan\", modifiers = [\"bold\"] } # String containing a web URL.\n\n\"comment\" = { fg = \"comment\" } # This is a comment.\n\"comment.block.documentation\" = { fg = \"comment\", modifiers = [\"bold\"] } # Block doc comments, e.g '/** */' in rust.\n\"comment.line.documentation\" = { fg = \"comment\", modifiers = [\"bold\"] } # Line doc comments, e.g '///' in rust.\n\n\"variable\" = { fg = \"white\" }  # Variable names.\n\"variable.builtin\" = { fg = \"red\" } # Language reserved variables: `this`, `self`, `super`, etc.\n\"variable.parameter\" = { fg = \"cyan-bright\" } # Function parameters.\n\"variable.other.member\" = { fg = \"fg2\" } # Fields of composite data types (e.g. structs, unions).\n\n\"label\" = { fg = \"magenta-bright\" } # lifetimes - Loop labels, among other things.\n\n\"punctuation\" = { fg = \"fg2\" } # Any punctuation symbol.\n# \"punctuation.delimiter\" = { fg = \"fg2\" } # Commas, colons or other delimiter depending on the language.\n# \"punctuation.bracket\" = { fg = \"fg2\" } # Parentheses, angle brackets, etc.\n# \"punctuation.special\" = { fg = \"fg2\" } # String interpolation brackets\n\n\"keyword\" = { fg = \"magenta\" } # Language reserved keywords.\n\"keyword.control\" = { fg = \"pink\" } # Control keywords.\n\"keyword.control.conditional\" = { fg = \"magenta-bright\" } # `if`, `else`, `elif`.\n\"keyword.control.repeat\" = { fg = \"magenta-bright\" } # `for`, `while`, `loop`.\n\"keyword.control.import\" = { fg = \"pink-bright\" } # `import`, `export` `use`.\n\"keyword.control.return\" = { fg = \"magenta\" } # `return` in most languages.\n\"keyword.control.exception\" = { fg = \"magenta\" } # `try`, `catch`, `raise`/`throw` and related.\n\"keyword.operator\" = { fg = \"fg2\", modifiers = [\"bold\"] } # 'or', 'and', 'in'.\n\"keyword.directive\" = { fg = \"pink-bright\" } # Preprocessor directives (#if in C...).\n\"keyword.function\" = { fg = \"red\" } # The keyword to define a function: 'def', 'fun', 'fn'.\n\"keyword.storage\" = { fg = \"magenta\" } # Keywords describing how things are stored\n\"keyword.storage.type\" = { fg = \"magenta\" } #  The type of something, class, function, var, let, etc.\n\"keyword.storage.modifier\" = { fg = \"yellow\" } # Storage modifiers like static, mut, const, ref, etc.\n\n\"operator\" = {  fg = \"fg2\" } # Logical, mathematical, and other operators.\n\n\"function\" = { fg = \"blue-bright\" }\n\"function.builtin\" = { fg = \"red\" }\n\"function.macro\" = { fg = \"red\" }\n# \"function.special\" = { fg = \"blue-bright\" } # Preprocessor function in C.\n# \"function.method\" = { fg = \"blue-bright\" } # Class / Struct methods.\n\n\"tag\" = { fg = \"blue-bright\" } # As in <body> for html, css tags.\n\n\"namespace\" = { fg = \"cyan-bright\" } # Namespace or module identifier.\n\n\n# Diff ==============================\n# Version control changes.\n\n\"diff.plus\" = \"green\" # Additions.\n\"diff.minus\" = \"red\" # Deletions.\n\"diff.delta\" = \"blue\" # Modifications.\n\"diff.delta.moved\" = \"cyan\" # Renamed or moved files.\n\n# color palette\n[palette]\nblack          = \"#393b44\"\nred            = \"#c94f6d\"\nred-dim        = \"#2f2837\"\ngreen          = \"#81b29a\"\ngreen-dim      = \"#26343c\"\nyellow         = \"#dbc074\"\nyellow-bright  = \"#e0c989\"\nblue           = \"#719cd6\"\nblue-bright    = \"#86abdc\"\nblue-dim       = \"#2f2837\"\nmagenta        = \"#9d79d6\"\nmagenta-bright = \"#baa1e2\"\ncyan           = \"#63cdcf\"\ncyan-bright    = \"#7ad4d6\"\ncyan-dim       = \"#253f4a\"\nwhite          = \"#dfdfe0\"\norange         = \"#f4a261\"\norange-bright  = \"#f6b079\"\npink           = \"#d67ad2\"\npink-bright    = \"#dc8ed9\"\ncomment        = \"#738091\"\n# spec\nbg0            = \"#131a24\" # Dark bg (status line and float)\nbg1            = \"#192330\" # Default bg\nbg2            = \"#212e3f\" # Lighter bg (colorcolm folds)\nbg3            = \"#29394f\" # Lighter bg (cursor line)\nbg4            = \"#39506d\" # Conceal, border fg\nfg0            = \"#d6d6d7\" # Lighter fg\nfg1            = \"#cdcecf\" # Default fg\nfg2            = \"#aeafb0\" # Darker fg (status line)\nfg3            = \"#71839b\" # Darker fg (line numbers, fold columns)\nsel0           = \"#2b3b51\" # Popup bg, visual selection bg\nsel1           = \"#3c5372\" # Popup sel bg, search bg\n"
  },
  {
    "path": "runtime/themes/noctis.toml",
    "content": "# Author : 0rphee <0rph3e@proton.me>\n\n# Template written with the help of https://github.com/n0s4/helix-theme-template\n# Keep in mind that I made this to fit Haskell and Python syntax, it may not work so well with other languages.\n\n## GENERAL ==============================\n\n'property' = { fg = \"red\" } # Regex group names.\n\"warning\" = { fg =\"yellow\", modifiers = [\"bold\"] } # Editor warnings.\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] } # Editor errors, like mistyping a command.\n\"info\" = { fg = \"mid-blue\" } # Code diagnostic info in gutter (LSP).\n# ? Difference between info and hint ?\n\"hint\" = { fg = \"light-green\", modifiers = [\"bold\"] } # Code diagnostics hint in gutter (LSP).\n\n# Code diagnostics in editing area (LSP).\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"mid-blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"light-green\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n# UI ==============================\n# For styling helix itself.\n\n'ui.background' = { fg = \"autocomp-green\", bg = \"dark-green\" } # Default background color.\n'ui.window' = { fg = \"mid-green\" } # Window border between splits.\n\n'ui.gutter' = { } # Left gutter for diagnostics and breakpoints.\n\n'ui.text' = { fg = \"white\" } # Default text color.\n'ui.text.focus' = { fg = \"white\", bg = \"mid-green\", modifiers = [\"bold\"] } # Selection highlight in buffer-picker or file-picker.\n'ui.text.info' = { fg = \"white\" } # Info popup contents (space mode menu).\n\n'ui.cursor' = { fg = \"dark-green\", bg = \"white\" } # Fallback cursor colour, non-primary cursors when there are multiple (shift-c).\n'ui.cursor.primary' = { fg = \"dark-green\", bg = \"light-blue\" } # The primary cursor when there are multiple (shift-c).\n'ui.cursor.insert' = { fg = \"dark-green\", bg = \"light-blue\" } # The cursor in insert mode (i).\n'ui.cursor.select' = { fg = \"dark-green\", bg = \"light-blue\" } # The cursor in select mode (v).\n'ui.cursor.match' = { fg = \"dark-green\", bg = \"red\", modifiers = [\"bold\"] } # The matching parentheses of that under the cursor.\n\n'ui.selection' = { bg = \"autocomp-green\" } # All currently selected text.\n'ui.selection.primary' = { bg = \"autocomp-green\" } # The primary selection when there are multiple.\n'ui.cursorline.primary' = { bg = 'mid-green' }\n\n'ui.linenr' = {  fg = \"gray\"  } # Line numbers.\n'ui.linenr.selected' = { fg = \"light-green\", modifiers = [ \"bold\" ] } # Current line number.\n\n'ui.virtual' = { fg = \"autocomp-green\" } # Namespace for additions to the editing area.\n'ui.virtual.ruler' = { bg = \"mid-green\" } # Vertical rulers (colored columns in editing area).\n'ui.virtual.whitespace' = { fg = \"mid-green\"} # Whitespace markers in editing area.\n'ui.virtual.inlay-hint' = { fg = \"autocomp-green\" } # LSP inlay hints\n'ui.virtual.indent-guide' = { fg = \"mid-green\" } # Indentation guides.\n'ui.virtual.wrap' = { fg = \"mid-green\"} # Soft-wrap indicators\n'ui.virtual.jump-label' = { fg = \"autocomp-green\", modifiers = [ \"bold\" ] } # Word-jump labels\n\n'ui.statusline' = { fg = \"light-green\", bg = \"autocomp-green\"} # Status line.\n'ui.statusline.inactive' = { fg = \"white\", bg = \"mid-green\"} # Status line in unfocused windows.\n\n\"ui.statusline.normal\" = { fg = \"dark-green\", bg = \"mid-blue\", modifiers = [ \"bold\" ] }\n\"ui.statusline.insert\" = { fg = \"dark-green\", bg = \"pink\", modifiers = [ \"bold\" ] }\n\"ui.statusline.select\" = { fg = \"dark-green\", bg = \"yellow\", modifiers = [ \"bold\" ] }\n\n'ui.help' = { bg = \"mid-green\", fg = \"white\"} # `:command` descriptions above the command line.\n\n'ui.highlight' = { bg = \"mid-green\"} # selected contents of symbol pickers (spc-s, spc-S) and current line in buffer picker (spc-b).\n\n'ui.menu' = { fg = \"white\", bg = \"mid-green\" } # Autocomplete menu.\n'ui.menu.selected' = { fg = \"light-green\", bg = \"autocomp-green\" } # Selected autocomplete item.\n\n'ui.popup' = { bg = \"mid-green\" } # Documentation popups (space-k).\n# 'ui.ppopup.info' = { bg = \"midgreen\", fg = \"gray\", modifiers = [\"bold\"] } # Info popups box (space mode menu).\n\n# SYNTAX HIGHLIGHTING ==============================\n# All the keys here are Treesitter scopes.\n\n'special' = { fg = \"mid-blue\"} # Special symbols e.g `?` in Rust, `...` in Hare.\n'attribute' = { fg = \"yellow\" } # Class attributes, html tag attributes.\n\n'type' = { fg = \"orange\"} # Variable type, like integer or string, including program defined classes, structs etc..\n#'type.builtin' = { } # Primitive types of the language (string, int, float).\n#'type.enum.variant' = { } # A variant of an enum.\n\n'constructor' = { fg = \"light-blue\", modifiers = [\"bold\"]} # Constructor method for a class or struct. And in some cases applies to module names\n\n'constant' = { fg = \"light-blue\", modifiers = [\"bold\"] } # Constant value\n'constant.builtin' = { fg = \"mid-blue\", modifiers = [\"bold\"] } # Special constants like `true`, `false`, `none`, etc.\n'constant.builtin.boolean' = { } # True or False.\n'constant.character' = { fg = \"light-green\"} # Constant of character type.\n'constant.character.escape' = { fg = \"purple\", modifiers = [\"bold\"] } # escape codes like \\n.\n'constant.numeric'  = { fg = \"purple\"} # constant integer or float value.\n# 'constant.numeric.integer' = { } # constant integer value.\n# 'constant.numeric.float' = { } # constant float value.\n\n'string' = { fg = \"light-green\" } # String literal.\n'string.regexp' = { } # Regular expression literal.\n'string.special' = { fg = \"red\" } # Strings containing a path, URL, etc.\n# 'string.special.path' = { } # String containing a file path.\n# 'string.special.url' = { } # String containing a web URL.\n# 'string.special.symbol' = { } # Erlang/Elixir atoms, Ruby symbols, Clojure keywords.\n\n'comment' = { fg = \"gray\", modifiers = [\"italic\"] } # This is a comment.\n'comment.line' = { } # Line comments, like this.\n'comment.line.documentation' = { } # Doc comments, e.g '///' in rust.\n'comment.block' = { } # Block comments, like /* this */ in some languages.\n'comment.block.documentation' = { } # Doc comments, e.g '/** */' in rust.\n\n'variable' = { fg = \"light-orange\" }  # Variable names.\n# 'variable.builtin' = { } # Language reserved variables: `this`, `self`, `super`, etc.\n# 'variable.parameter' = { } # Function parameters.\n'variable.other.member' = { fg = \"orange\" } # Fields of composite data types (e.g. structs, unions).\n\n'label' = { fg = \"purple\" } # Loop labels in rust.\n\n'punctuation' =  { fg = \"yellow\", modifiers = [\"bold\"] } # (){}[]:;,.\n# 'punctuation.delimiter' = { fg = \"yellow\" } # Commas and colons.\n# 'punctuation.bracket' = { fg = \"yellow\" } # Parentheses, angle brackets, etc.\n\n'keyword' = { fg = \"pink\", modifiers = [\"bold\"] } # Language reserved keywords.\n'keyword.control' = { fg = \"pink\", modifiers = [\"bold\"] } # Control keywords.\n'keyword.control.conditional' = { fg = \"pink\", modifiers = [\"bold\"] } # 'if', 'else', 'elif'.\n# 'keyword.control.repeat' = { } # 'for', 'while', 'loop'.\n'keyword.control.import' = { fg = \"pink\", modifiers = [\"italic\"] } # 'import', 'export' ('use'?).\n# 'keyword.control.return' = { } # 'return' in most languages.\n'keyword.control.exception' = {fg = \"pink\", modifiers = [\"bold\"] } # 'raise' in python.\n'keyword.operator' = { fg = \"pink\" } # 'or', 'and', 'in'.\n'keyword.directive' = { fg = \"purple\" } # Preprocessor directives (#if in C).\n'keyword.function' = { fg= \"red\" } # The keyword to define a function: 'def', 'fun', 'fn'.\n\n'operator' = { fg = \"pink\", modifiers = [\"bold\"] } # Logical (&&, ||) and - I assume - Mathematical (+, %) operators\n\n'function' = { fg = \"mid-blue\"}\n'function.builtin' = { fg = \"dark-blue\" }\n'function.method' = { fg = \"dark-blue\" } # Class / Struct methods.\n'function.macro' = { fg = \"purple\" } # Like macros in rust.\n# 'function.special' = { fg = \"yellow\" } # Preprocessor in C.\n\n'tag' = { fg = \"yellow\"} # As in <body> for html.\n\n'namespace' = { fg = \"mid-blue\" } # * Namespace keyword in java, C#, etc.\n\n# Markup ==============================\n# Colors for markup languages, like Markdown or XML.\n\n'markup.heading' = { } # Markdown headings\n'markup.heading.1' = { } # Markdown heading 1 color.\n'markup.heading.2' = { } # Markdown heading 2 color.\n'markup.heading.3' = { } # Markdown heading 3 color.\n'markup.heading.4' = { } # Markdown heading 4 color.\n'markup.heading.5' = { } # Markdown heading 5 color.\n'markup.heading.6' = { } # Markdown heading 6 color.\n'markup.heading.marker' = { fg = \"red\" } # Hashtag color on Markdown headings.\n\n'markup.list' = { fg = \"red\" }\n'markup.list.numbered' = { } # Numbered list.\n'markup.list.unnumbered' = { } # Bullet point list.\n\n'markup.bold' = { modifiers = [\"bold\"] } # Bold text.\n'markup.italic' = { modifiers = [\"italic\"] } # Italicised text.\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] } # Crossed out text.\n\n'markup.link' = { fg = \"light-blue\", modifiers = [\"underlined\"] }\n'markup.link.url' = { } # Urls pointed to by links.\n'markup.link.label' = { } # Non-URL link references.\n'markup.link.text' = { fg = \"purple\"} # URL and image descriptions in links.\n\n'markup.quote' = { } # `> Quotes` in Markdown.\n\n\n# Markup - Interface ==============================\n# \"These scopes are used for theming the editor interface.\"\n\n'markup.normal' = { }\n'markup.normal.completion' = { } # For completion doc popup ui.\n'markup.normal.raw' = { } # For hover popup ui.\n\n'markup.heading.completion' = { } # Headings for completion doc popup ui.\n'markup.heading.raw' = { } # Headings for hover popup ui.\n\n'markup.raw' = { } # Code block in Markdown.\n'markup.raw.block' = { } # Multiline (```) codeblock in Markdown.\n'markup.raw.inline' = { } # `Inline code block` in Markdown.\n'markup.raw.inline.completion' = { } # ?\n'markup.raw.inline.hover' = { } # ?\n\n# Diff ==============================\n# Version control changes.\n\n'diff.plus' = \"light-green\" # { } # Additions.\n'diff.minus' = \"red\" # { } # Deletions.\n'diff.delta' = \"yellow\" # { } # Modifications.\n# 'diff.delta.moved' = { } # Renamed or moved files / changes.\n\n\n[palette] # Define your custom colors here.\ndark-green = \"#00262a\" # backgrounds\nmid-green = \"#073a40\" # highlights\nautocomp-green = \"#0d6772\" # lighter than mid-green\nlight-green = \"#48e9a7\" # strings\n\npink = \"#df769b\"\nyellow = \"#ffd800\"\npurple = \"#918cff\"\nwhite = \"#b1cace\"\norange = \"#ffa864\"\nlight-orange = \"#fff2c5\"\ngray = \"#5b858b\" # mainly for comments/background text\nlight-gray = \"#2a3c41\" # used when whitespace rendering is enabled and for indent-guides\nred = \"#e34e1b\"\n\ndark-blue = \"#19a2b7\"\nmid-blue = \"#47ace8\"\nlight-blue = \"#87efff\"\n\n"
  },
  {
    "path": "runtime/themes/noctis_bordo.toml",
    "content": "# Author: Joseph Harrison-Lim <josephharrisonlim@gmail.com>\n\n\"attribute\" = { fg = \"#7060eb\", modifiers = [\"bold\"] }\n\"comment\" = { fg = \"base03\", modifiers = [\"italic\"] }\n\"comment.line.documentation\" = { fg = \"base06\", modifiers = [\"italic\"] }\n\"comment.block.documentation\" = { fg = \"base06\", modifiers = [\"italic\"] }\n\"constant\" = \"base09\"\n\"constant.character.escape\" = \"base0C\"\n\"constant.numeric\" = \"#7060eb\"\n\"constructor\" = \"base0D\"\n\"function\" = \"base0D\"\n\"keyword\" = \"base0E\"\n\"keyword.control\" = { fg = \"base0E\", modifiers = [\"bold\"] }\n\"keyword.directive\" = \"white\"\n\"keyword.import\" = { fg = \"#df769b\" }\n\"keyword.operator\" = { fg = \"base0E\", modifiers = [\"italic\"] }\n\"label\" = \"base0E\"\n\"namespace\" = \"base0E\"\n\"operator\" = \"base05\"\n\"string\"  = \"base0B\"\n\"type\" = \"base10\"\n\"variable\" = \"base08\"\n\"variable.other.member\" = \"base08\"\n\"special\" = \"base0D\"\n\n\"ui.background\" = { bg = \"base00\" }\n\"ui.virtual\" = \"base03\"\n\"ui.virtual.ruler\" = { bg = \"base01\" }\n\"ui.menu\" = { fg = \"base05\", bg = \"base01\" }\n\"ui.menu.selected\" = { fg = \"base0B\", bg = \"base01\" }\n\"ui.popup\" = { bg = \"base01\" }\n\"ui.window\" = { bg = \"base01\" }\n\"ui.linenr\" = { fg = \"#715b63\", bg = \"base01\" }\n\"ui.linenr.selected\" = { fg = \"base02\", bg = \"base01\", modifiers = [\"bold\"] }\n\"ui.selection\" = { fg = \"base05\", bg = \"base02\" }\n\"ui.cursorline\" = { bg = \"base01\" }\n\"ui.statusline\" = { fg = \"base02\", bg = \"base01\" }\n\"ui.cursor\" = { fg = \"base04\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"base05\", modifiers = [\"reversed\"] }\n\"ui.text\" = \"base05\"\n\"ui.text.focus\" = \"base05\"\n\"ui.cursor.match\" = { fg = \"base0A\", modifiers = [\"underlined\"] }\n\"ui.help\" = { fg = \"base06\", bg = \"base01\" }\n\n\"markup.bold\" = { fg = \"base0A\", modifiers = [\"bold\"] }\n\"markup.heading\" = \"base0D\"\n\"markup.italic\" = { fg = \"base0E\", modifiers = [\"italic\"] }\n\"markup.link.text\" = \"base08\"\n\"markup.link.url\" = { fg = \"base09\", modifiers = [\"underlined\"] }\n\"markup.list\" = \"base08\"\n\"markup.quote\" = \"base0C\"\n\"markup.raw\" = \"base0B\"\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\n\"diff.delta\" = \"base09\"\n\"diff.plus\" = \"base0B\"\n\"diff.minus\" = \"base08\"\n\n\"diagnostic.info\" = { underline = { color = \"base0D\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"base03\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"base09\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"base08\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"ui.gutter\" = { bg = \"base01\" }\n\"info\" = \"base0D\"\n\"hint\" = \"base03\"\n\"debug\" = \"base03\"\n\"warning\" = \"base09\"\n\"error\" = \"base08\"\n\n[palette]\nbase00 = \"#322a2d\" # Default Background\nbase01 = \"#2c2528\" # Lighter Background (Used for status bars, line number and folding marks)\nbase02 = \"#997582\" # Selection Background\nbase03 = \"#585858\" # Comments, Invisibles, Line Highlighting\nbase04 = \"#322a2d\" # Dark Foreground (Used for status bars)\nbase05 = \"#cbbec2\" # Default Foreground, Caret, Delimiters, Operators\nbase06 = \"#e8e8e8\" # Light Foreground (Not often used)\nbase07 = \"#f8f8f8\" # Light Background (Not often used)\nbase08 = \"#e4b781\" # Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted\nbase09 = \"#d5971a\" # Integers, Boolean, Constants, XML Attributes, Markup Link Url\nbase0A = \"#df769b\" # Classes, Markup Bold, Search Text Background\nbase0B = \"#49e9a6\" # Strings, Inherited Class, Markup Code, Diff Inserted\nbase0C = \"#16b673\" # Support, Regular Expressions, Escape Characters, Markup Quotes\nbase0D = \"#16a3b6\" # Functions, Methods, Attribute IDs, Headings\nbase0E = \"#ba8baf\" # Keywords, Storage, Selector, Markup Italic, Diff Changed\nbase0F = \"#d67e5c\" # Deprecated, Opening/Closing Embedded Language Tags, e.g. <?php ?>\nbase10 = \"#b0b0ff\" # Types\n"
  },
  {
    "path": "runtime/themes/nord-night.toml",
    "content": "# Nord Night\n#\n# Based on the Nord theme, with minor modifications.\n# The Background and the Primary Text color have been slightly darkened.\n# The Aurora color palette has been used more generously.\n\ninherits = 'nord'\n\n'constant' = 'nord13'\n'constant.builtin.boolean' = 'nord13'\n'constant.numeric' = 'nord13'\n\n'keyword.control' = 'nord11'\n'keyword.control.conditional' = 'nord11'\n'keyword.control.exception' = 'nord11'\n'keyword.control.repeat' = 'nord11'\n'keyword.control.return' = 'nord11'\n\n'variable.parameter' = 'nord15'\n\n[palette]\nnord0 = '#252933'\nnord4 = '#C0C5CF'\n"
  },
  {
    "path": "runtime/themes/nord.toml",
    "content": "# Nord (Dark Ambiance) port for Helix (https://helix-editor.com/)\n# https://docs.helix-editor.com/themes.html\n# https://www.nordtheme.com/docs/colors-and-palettes\n\n## SYNTAX HIGHLIGHTING\n\n# Constants\n\"constant\" = \"nord4\"\n\"constant.builtin\" = \"nord9\"\n\"constant.builtin.boolean\" = \"nord9\"\n\"constant.builtin.character\" = \"nord15\"\n\"constant.character.escape\" = \"nord13\"\n\"constant.macro\" = \"nord9\"\n\"constant.numeric\" = \"nord15\"\n\"constructor\" = \"nord8\"\n\n# Diagnostics\n\"diagnostic\" = { underline = { color = \"nord13\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"nord11\", style = \"curl\" } }\n\"error\" = \"nord11\"\n\"diagnostic.hint\" = { underline = { color = \"nord10\", style = \"curl\" } }\n\"hint\" = \"nord10\"\n\"diagnostic.info\" = { underline = { color = \"nord8\", style = \"curl\" } }\n\"info\" = \"nord8\"\n\"diagnostic.warning\" = { underline = { color = \"nord13\", style = \"curl\" } }\n\"warning\" = \"nord13\"\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n# Diffs\n\"diff.delta\" = \"nord13\"\n\"diff.minus\" = \"nord11\"\n\"diff.plus\" = \"nord14\"\n\n# Functions\n\"function\" = \"nord8\"\n\"function.builtin\" = \"nord7\"\n\"function.method\" = \"nord8\"\n\"function.macro\" = \"nord9\"\n\"function.special\" = \"nord9\"\n\n# Git\n\"git.delta.moved\" = \"nord12\"\n\n# Keywords\n\"keyword\" = \"nord9\"\n\"keyword.control.conditional\" = \"nord9\"\n\"keyword.control.exception\" = \"nord9\"\n\"keyword.control.repeat\" = \"nord9\"\n\"keyword.directive\" = \"nord9\"\n\"keyword.function\" = \"nord9\"\n\"keyword.operator\" = \"nord9\"\n\"keyword.return\" = \"nord9\"\n\"keyword.storage.modifier\" = \"nord9\"\n\"keyword.storage.type\" = \"nord9\"\n\n# Punctuation\n\"punctuation\" = \"nord6\"\n\"punctuation.bracket\" = \"nord6\"\n\"punctuation.delimiter\" = \"nord6\"\n\"punctuation.special\" = \"nord9\"\n\n# Strings\n\"string\" = \"nord14\"\n\"string.escape\" = \"nord13\"\n\"string.regex\" = \"nord13\"\n\"string.special\" = \"nord13\"\n\n# Types\n\"type\" = \"nord7\"\n\"type.builtin\" = \"nord7\"\n\n# Variables\n\"variable\" = \"nord4\"\n\"variable.builtin\" = \"nord9\"\n\"variable.other.member\" = \"nord4\"\n\"variable.parameter\" = \"nord8\"\n\"attribute\" = \"nord9\"\n\n# Misc.\n\"label\" = \"nord7\"\n\"namespace\" = \"nord4\"\n\"operator\" = \"nord9\"\n\"special\" = \"nord9\"\n\"tag\" = \"nord7\"\n\"comment\" = { fg = \"nord3_bright\", modifiers = [\"italic\"] }\n\n## EDITOR UI COLORS\n\n\"ui.background\" = { bg = \"nord0\" }\n\"ui.text\" = \"nord4\"\n\"ui.window\" = \"nord1\"\n\n# Debug\n\"ui.debug.active\" = \"nord13\"\n\"ui.debug.breakpoint\" = \"nord11\"\n\n# Popus and menus\n\"ui.menu\" = { bg = \"nord1\" }\n\"ui.menu.scroll\" = { fg = \"nord4\", bg = \"nord3\" }\n\"ui.menu.selected\" = { fg = \"nord8\", bg = \"nord2\" }\n\"ui.popup\" = { bg = \"nord1\" }\n\"ui.popup.info\" = { bg = \"nord1\" }\n\"ui.help\" = { bg = \"nord1\" }\n\"ui.text.focus\" = { fg = \"nord8\", bg = \"nord2\" }\n\n# Gutter\n\"ui.gutter\" = \"nord5\"\n\"ui.linenr\" = \"nord3\"\n\"ui.linenr.selected\" = \"nord5\"\n\n# Cursor\n\"ui.cursor\" = { fg = \"nord4\", modifiers = [\"reversed\"] }\n\"ui.cursorcolumn.primary\" = { bg = \"nord1\" }\n\"ui.cursorline.primary\" = { bg = \"nord1\" }\n\"ui.cursor.match\" = { bg = \"nord3\" }\n\n\"ui.selection\" = { bg = \"nord3\" }\n\"ui.highlight\" = { fg = \"nord8\", bg = \"nord2\" }\n\n# Statusline\n\"ui.statusline\" = { bg = \"nord1\" }\n\"ui.statusline.inactive\" = { fg = \"nord8\", bg = \"nord1\" }\n\"ui.statusline.insert\" = { fg = \"nord1\", bg = \"nord6\" }\n\"ui.statusline.normal\" = { fg = \"nord1\", bg = \"nord8\" }\n\"ui.statusline.select\" = { fg = \"nord1\", bg = \"nord7\" }\n\"ui.statusline.separator\" = \"nord3\"\n\n# Virtual/invisible text\n\"ui.virtual.indent-guide\" = \"nord3\"\n\"ui.virtual.inlay-hint\" = { fg = \"nord3\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"nord11\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"nord1\" }\n\"ui.virtual.whitespace\" = \"nord3\"\n\"ui.virtual.wrap\" = \"nord3\"\n\n# Bufferline\n\"ui.bufferline\" = { fg = \"nord5\", bg = \"nord1\" }\n\"ui.bufferline.active\" = { fg = \"nord6\", bg = \"nord2\", underline = { color = \"nord8\", style = \"line\" }, modifiers = [\n  \"italic\",\n] }\n\n# Markup\n\"markup.heading\" = \"nord8\"\n\"markup.list\" = \"nord9\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.text\" = \"nord8\"\n\"markup.raw\" = \"nord7\"\n\n# Rainbow brackets\nrainbow = [\"nord13\", \"nord15\", \"nord14\", \"nord12\"]\n\n[palette]\n# Polar Night is made up of four darker colors that are commonly used for base elements like backgrounds or text color in bright ambiance designs.\n#\n# The origin color or the Polar Night palette\nnord0 = \"#2e3440\"\n# A brighter shade color based on nord0\nnord1 = \"#3B4252\"\n# An even more brighter shade color of nord0\nnord2 = \"#434C5E\"\n# The brightest shade color based on nord0\nnord3 = \"#4C566A\"\n# 10% brighter for comments, see https://github.com/nordtheme/nord/issues/94\nnord3_bright = \"#616e88\"\n\n# Snow Storm is made up of three bright colors that are commonly used for text colors or base UI elements in bright ambiance designs.\n# The origin color or the Snow Storm palette\nnord4 = \"#D8DEE9\"\n# A brighter shade color of nord4\nnord5 = \"#E5E9F0\"\n# The brightest shade color based on nord4\nnord6 = \"#ECEFF4\"\n\n# Frost can be described as the heart palette of Nord, a group of four bluish colors that are commonly used for primary UI component and text highlighting and essential code syntax elements.\n#\n# A calm and highly contrasted color reminiscent of frozen polar water\nnord7 = \"#8FBCBB\"\n# The bright and shiny primary accent color reminiscent of pure and clear ice\nnord8 = \"#88C0D0\"\n# A more darkened and less saturated color reminiscent of arctic waters\nnord9 = \"#81A1C1\"\n# A dark and intensive color reminiscent of the deep arctic ocean\nnord10 = \"#5E81AC\"\n\n# Aurora consists of five colorful components reminiscent of the \"Aurora borealis\", sometimes referred to as polar lights or northern lights.\n#\n# Red\nnord11 = \"#BF616A\"\n# Orange\nnord12 = \"#D08770\"\n# Yellow\nnord13 = \"#EBCB8B\"\n# Green\nnord14 = \"#A3BE8C\"\n# Purple\nnord15 = \"#B48EAD\"\n"
  },
  {
    "path": "runtime/themes/nord_light.toml",
    "content": "# Author: Two-Six<twopsix@duck.com>\n\n\"ui.background\" = {bg=\"nord6\"}\n\"ui.text\" = \"nord0\"\n\"ui.selection\" = {bg=\"nord7\", fg=\"nord6\"}\n\"ui.cursorline\" = {bg=\"nord4\"}\n\"ui.statusline\" = {bg=\"nord4\", fg=\"nord0\"}\n\"ui.statusline.inactive\" = {bg=\"nord5\", fg=\"nord0\"}\n\"ui.cursor.match\" = {bg=\"nord8\"}\n\"ui.cursor\" = {bg=\"nord10\", fg=\"nord6\"}\n\"ui.cursorline.primary\" = {bg=\"nord5\"}\n\"ui.linenr\" = {fg=\"nord7\"}\n\"ui.linenr.selected\" = {fg=\"nord0\", bg=\"nord5\"}\n\"ui.menu\" = {bg=\"nord4\",fg=\"nord0\"}\n\"ui.menu.selected\" = {bg=\"nord5\"}\n\"ui.popup\" = {bg=\"nord4\"}\n\"ui.popup.info\" = {bg=\"nord4\",fg=\"nord0\"}\n\"ui.help\" = {bg=\"nord4\",fg=\"nord0\"}\n\"ui.window\" = {bg=\"nord4\"}\n\n\n\"ui.statusline.normal\" = { fg = \"nord0\", bg = \"nord8\" }\n\"ui.statusline.insert\" = { fg = \"nord0\", bg = \"nord13\" }\n\"ui.statusline.select\" = { fg = \"nord0\", bg = \"nord15\" }\n\n# Virtual/invisible text\n\"ui.virtual\" = \"nord8\"\n\"ui.virtual.ruler\" = {bg=\"nord4\"}\n\"ui.virtual.inlay-hint\" = { fg = \"nord3\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"nord11\", modifiers = [\"bold\"] }\n\n\n\n\"diagnostic.error\" = { underline = { color = \"nord11\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"nord13\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"nord13\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"nord13\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"constant.numeric\" = {fg=\"nord15\"}\n\"constant.builtin\" = {fg=\"nord15\"}\n\n\"keyword\" = {fg=\"nord2\"}\n\"keyword.control\" = {fg=\"nord2\"}\n\"keyword.function\" = {fg=\"nord2\"}\n\n\"function\" = {fg=\"nord3\"}\n\"function.macro\" = {fg=\"nord10\", modifiers=[\"bold\"]}\n\"function.method\" = {fg=\"nord0\"}\n\"function.builtin\" = {fg=\"nord10\"}\n\n\"variable.builtin\" = {fg=\"nord3\"}\n\"variable.other\" = {fg=\"nord3\"}\n\"variable\" = {fg=\"nord0\"}\n\n\"string\" = \"nord14\"\n\"comment\" = \"nord7\"\n\"namespace\" = {fg=\"nord10\"}\n\"attribute\" = {fg=\"nord10\"}\n\"type\" = {fg=\"nord10\"}\n\n\"markup.heading\" = {fg=\"nord0\", modifiers=[\"bold\"]}\n\"markup.raw\" = {fg=\"nord10\"}\n\"markup.link.url\" = {fg=\"nord3\"}\n\"markup.link.text\" = {fg=\"nord12\"}\n\"markup.quote\" = {fg=\"nord3\", modifiers=[\"italic\"]}\n\n\"diff.plus\" = {fg = \"nord14\"}\n\"diff.delta\" = {fg = \"nord13\"}\n\"diff.minus\" = {fg = \"nord11\"}\n\n\n[palette]\nnord0 = \"#2E3440\"\nnord1 = \"#3B4252\"\nnord2 = \"#434C5E\"\nnord3 = \"#4C566A\"\nnord4 = \"#D8DEE9\"\nnord5 = \"#E5E9F0\"\nnord6 = \"#ECEFF4\"\nnord7 = \"#8FBCBB\"\nnord8 = \"#88C0D0\"\nnord9 = \"#81A1C1\"\nnord10 = \"#5E81AC\"\nnord11 = \"#BF616A\"\nnord12 = \"#D08770\"\nnord13 = \"#EBCB8B\"\nnord14 = \"#A3BE8C\"\nnord15 = \"#B48EAD\"\n"
  },
  {
    "path": "runtime/themes/nvchad_solarized_dark.toml",
    "content": "# Author : Uladzislau Hinko <uladzislau.hinko@gmail.com>\n\n\"attribute\" = { fg = \"yellow\" }\n\n\"keyword\" = { fg = \"blue\" }\n\"keyword.directive\" = { fg = \"blue\" }\n\"keyword.control.import\" = { fg = \"blue\" }\n\"keyword.control.conditional\" = { fg = \"blue\" }\n\"keyword.control.repeat\" = { fg = \"blue\" }\n\"keyword.function\" = { fg = \"violet\" }\n\"keyword.storage\" = { fg = \"violet\" }\n\"keyword.storage.type\" = { fg = \"violet\" }\n\"keyword.operator\" = { fg = \"green\" }\n\n\"namespace\" = { fg = \"red\" }\n\"module\" = { fg = \"red\" }\n\n\"type\" = { fg = \"yellow\" }\n\"type.enum.variant\" = { fg = \"yellow\" }\n\"type.builtin\" = { fg = \"yellow\" }\n\"type.parameter\" = { fg = \"yellow\" }\n\"type.qualifier\" = { fg = \"yellow\" }\n\"type.definition\" = { fg = \"yellow\" }\n\n\"variable\" = { fg = \"base1\" }\n\"variable.builtin\" = { fg = \"red\" }\n\"variable.parameter\" = { fg = \"base1\" }\n\"variable.other.member\" = { fg = \"red\" }\n\n\"constant\" = { fg = \"orange\" }\n\"constant.character\" = { fg = \"green\" }\n\"constant.character.escape\" = { fg = \"cyan\" }\n\"constant.macro\" = { fg = \"orange\" }\n\"constant.builtin\" = { fg = \"orange\" }\n\"constant.numeric\" = { fg = \"orange\" }\n\"constant.numeric.integer\" = { fg = \"orange\" }\n\"constant.numeric.float\" = { fg = \"orange\" }\n\"constant.boolean\" = { fg = \"orange\" }\n\"number\" = { fg = \"orange\" }\n\n\"constructor\" = { fg = \"blue\" }\n\"function\" = { fg = \"blue\" }\n\"function.macro\" = { fg = \"blue\" }\n\"function.builtin\" = { fg = \"blue\" }\n\"function.special\" = { fg = \"blue\" }\n\"function.method\" = { fg = \"blue\" }\n\"function.call\" = { fg = \"blue\" }\n\n\"comment\" = { fg = \"base01\" }\n\"comment.documentation\" = { fg = \"base01\" }\n\n\"string\" = { fg = \"green\" }\n\"string.regexp\" = { fg = \"cyan\" }\n\"string.special\" = { fg = \"cyan\" }\n\"string.symbol\" = { fg = \"green\" }\n\"string.escape\" = { fg = \"cyan\" }\n\"character\" = { fg = \"green\" }\n\"escape\" = { fg = \"cyan\" }\n\n\"label\" = { fg = \"yellow\" }\n\"annotation\" = { fg = \"yellow\" }\n\n\"tag\" = { fg = \"red\" }\n\"tag.attribute\" = { fg = \"orange\" }\n\"tag.delimiter\" = { fg = \"base1\" }\n\n\"operator\" = { fg = \"base1\" }\n\n\"punctuation.bracket\" = { fg = \"magenta\" }\n\"punctuation.delimiter\" = { fg = \"base1\" }\n\"punctuation.special\" = { fg = \"magenta\" }\n\n\"embedded\" = { fg = \"green\" }\n\n\"markup.heading\" = { fg = \"blue\" }\n\"markup.list\" = { fg = \"red\" }\n\"markup.bold\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"red\" }\n\"markup.quote\" = { fg = \"cyan\" }\n\"markup.raw\" = { fg = \"green\" }\n\n\"diff.plus\" = { fg = \"green\" }\n\"diff.delta\" = { fg = \"yellow\" }\n\"diff.minus\" = { fg = \"red\" }\n\n\"ui.background\" = { bg = \"base03\" }\n\n\"ui.virtual.whitespace\" = { fg = \"base01\" }\n\"ui.virtual.inlay-hint\" = { fg = \"#586e75\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"ui.virtual.indent-guide\" = { fg = \"base02\" }\n\"ui.virtual.ruler\" = { bg = \"base02\" }\n\n\"ui.linenr\" = { fg = \"base01\", bg = \"base03\" }\n\"ui.linenr.selected\" = { fg = \"base1\", bg = \"base03\" }\n\n\"ui.cursorline\" = { bg = \"base025\" }\n\"ui.cursorline.primary\" = { bg = \"base02\" }\n\"ui.cursorline.secondary\" = { bg = \"base025\" }\n\n\"ui.cursor.primary\" = { fg = \"base03\", bg = \"base1\" }\n\"ui.cursor.select\" = { fg = \"base02\", bg = \"cyan\" }\n\"ui.cursor\" = { fg = \"base02\", bg = \"cyan\" }\n\"ui.cursor.insert\" = { fg = \"base03\", bg = \"base3\" }\n\"ui.cursor.match\" = { fg = \"base03\", bg = \"base00\" }\n\n\"ui.selection\" = { bg = \"base0175\" }\n\"ui.selection.primary\" = { bg = \"base015\" }\n\n\"ui.statusline\" = { fg = \"base1\", bg = \"base02\" }\n\"ui.statusline.normal\" = { fg = \"base3\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"base3\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"base3\", bg = \"yellow\" }\n\"ui.statusline.inactive\" = { fg = \"base01\", bg = \"base02\" }\n\n\"ui.bufferline\" = { fg = \"base0\", bg = \"base02\" }\n\"ui.bufferline.active\" = { fg = \"base3\", bg = \"magenta\", modifiers = [\"bold\"] }\n\"ui.bufferline.background\" = { bg = \"base02\" }\n\n\"ui.popup\" = { fg = \"base1\", bg = \"base02\" }\n\"ui.menu\" = { fg = \"base1\", bg = \"base02\" }\n\"ui.menu.selected\" = { fg = \"base3\", bg = \"blue\" }\n\"ui.menu.scroll\" = { fg = \"base1\", bg = \"base01\" }\n\"ui.window\" = { fg = \"base1\", bg = \"base02\" }\n\"ui.help\" = { fg = \"base1\", bg = \"base02\" }\n\n\"ui.popup.info\" = { fg = \"base1\", bg = \"base02\" }\n\"ui.text.info\" = { fg = \"base1\", bg = \"base02\" }\n\n\"ui.text\" = { fg = \"base1\" }\n\"ui.text.focus\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\n\"warning\" = { fg = \"orange\", modifiers = [\"bold\", \"underlined\"] }\n\"error\" = { fg = \"red\", modifiers = [\"bold\", \"underlined\"] }\n\"info\" = { fg = \"blue\", modifiers = [\"bold\", \"underlined\"] }\n\"hint\" = { fg = \"base01\", modifiers = [\"bold\", \"underlined\"] }\n\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"orange\" } }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"red\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"blue\" } }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"base01\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nbase03   = \"#002b36\"\nbase025  = \"#06313c\"\nbase02   = \"#0a3540\"\nbase0175 = \"#133e49\"\nbase015  = \"#1b4651\"\nbase01   = \"#28535e\"\nbase00   = \"#325d68\"\nbase0    = \"#3c6772\"\nbase1    = \"#93a1a1\"\nbase2    = \"#eee8d5\"\nbase3    = \"#fdf6e3\"\nyellow  = \"#b58900\"\norange  = \"#cb4b16\"\nred     = \"#dc322f\"\nmagenta = \"#d33682\"\nviolet  = \"#6c71c4\"\nblue    = \"#268bd2\"\ncyan    = \"#2aa198\"\ngreen   = \"#859900\"\nwhite = \"#ffffff\"\n"
  },
  {
    "path": "runtime/themes/nvim-dark.toml",
    "content": "# A port of Neovim's default dark color scheme created by echasnovski: https://github.com/neovim/neovim/pull/26334\n# Based on Kim Nørgaard's Neovim dark (accented) theme for Zed: https://github.com/KimNorgaard/zed-neovim-default\n\nattribute = \"fog\"\nkeyword = { fg = \"fog\", modifiers = [\"bold\"] }\n\"keyword.directive\" = { fg = \"fog\", modifiers = [\"bold\"] }\nnamespace = \"fog\"\npunctuation = \"fog\"\n\"punctuation.delimiter\" = \"fog\"\noperator = \"fog\"\nspecial = \"aqua\"\n\"variable.other.member\" = \"sky\"\nvariable = \"fog\"\n\"variable.parameter\" = { fg = \"aqua\" }\n\"variable.builtin\" = \"aqua\"\ntype = \"fog\"\n\"type.builtin\" = \"aqua\"\nconstructor = \"aqua\"\nfunction = \"aqua\"\n\"function.macro\" = \"fog\"\n\"function.builtin\" = \"aqua\"\ntag = \"aqua\"\ncomment = \"stone\"\nconstant = \"fog\"\n\"constant.builtin\" = \"fog\"\nstring = \"leaf\"\n\"constant.numeric\" = \"fog\"\n\"constant.character.escape\" = \"aqua\"\nlabel = { fg = \"fog\", modifiers = [\"bold\"] }\ntabstop = { modifiers = [\"italic\"], bg = \"panel\"}\n\n\"markup.heading\" = \"fog\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"aqua\", modifiers = [\"italic\"] }\n\"markup.link.text\" = \"aqua\"\n\"markup.raw\" = \"aqua\"\n\n\"diff.plus\" = \"leaf\"\n\"diff.minus\" = \"rose\"\n\"diff.delta\" = \"sun\"\n\n\"ui.background\" = { bg = \"night\" }\n\"ui.background.separator\" = { fg = \"panel\" }\n\"ui.linenr\" = { fg = \"slate\" }\n\"ui.linenr.selected\" = { fg = \"fog\" }\n\n\"ui.statusline\" = { fg = \"fog\", bg = \"panel\" }\n\"ui.statusline.inactive\" = { fg = \"stone\", bg = \"panel\" }\n\"ui.statusline.normal\" = { bg = \"aqua\", fg = \"panel\" }\n\"ui.statusline.insert\" = { bg = \"leaf\", fg = \"panel\" }\n\"ui.statusline.select\" = { bg = \"sky\", fg = \"panel\" }\n\n\"ui.popup\" = { bg = \"panel\" }\n\"ui.window\" = { fg = \"panel\" }\n\"ui.help\" = { bg = \"panel\", fg = \"fog\" }\n\"ui.text\" = { fg = \"fog\" }\n\"ui.text.focus\" = { fg = \"fog\" }\n\"ui.text.inactive\" = \"stone\"\n\"ui.text.directory\" = { fg = \"sky\" }\n\"ui.virtual\" = { fg = \"slate\" }\n\"ui.virtual.ruler\" = { bg = \"panel\" }\n\"ui.virtual.jump-label\" = { fg = \"sun\", modifiers = [\"bold\"] }\n\n\"ui.virtual.indent-guide\" = { fg = \"slate\" }\n\n\"ui.selection\" = { bg = \"oxford\" }\n\"ui.selection.primary\" = { bg = \"oxford\" }\n\"ui.cursor.select\" = { bg = \"aqua\" }\n\"ui.cursor.insert\" = { bg = \"fog\" }\n\"ui.cursor.primary.select\" = { bg = \"aqua\" }\n\"ui.cursor.primary.insert\" = { bg = \"fog\" }\n\"ui.cursor.match\" = { fg = \"night\", bg = \"slate\" }\n\"ui.cursor\" = { modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { bg = \"panel\" }\n\"ui.highlight\" = { bg = \"panel\" }\n\"ui.highlight.frameline\" = { bg = \"slate\" }\n\"ui.debug\" = { fg = \"slate\" }\n\"ui.debug.breakpoint\" = { fg = \"sun\" }\n\"ui.menu\" = { fg = \"fog\", bg = \"panel\" }\n\"ui.menu.selected\" = { fg = \"night\", bg = \"fog\" }\n\"ui.menu.scroll\" = { fg = \"fog\", bg = \"panel\" }\n\n\"diagnostic.hint\" = { underline = { color = \"stone\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"aqua\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"sun\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"rose\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nwarning = \"sun\"\nerror = \"rose\"\ninfo = \"aqua\"\nhint = \"stone\"\n\n[palette]\nfog   = \"#e0e2ea\"\nstone = \"#9b9ea4\"  \nnight = \"#14161b\"  \npanel = \"#2c2e33\"\nslate = \"#4f5258\"  \n\naqua   = \"#8cf8f7\"\nleaf   = \"#b3f6c0\"  \nsun    = \"#fce094\"  \nrose   = \"#ffc0b9\"  \nsky    = \"#a6dbff\"\noxford = \"#0D2847\" \n"
  },
  {
    "path": "runtime/themes/nyxvamp-obsidian.toml",
    "content": "# nyxvamp - obsidian variant\n# author: zoedsoupe <zoey.spessanha@zeetech.io>\n\ninherits = \"nyxvamp-radiance\"\n\n# Rainbow parentheses colors\nrainbow = [\"keyword_fg\", \"function_fg\", \"string_fg\", \"type_fg\"]\n\n# Override specific styles for obsidian variant\n\"function\" = { fg = \"function_fg\", modifiers = [\"bold\"] }\n\"function.builtin\" = { fg = \"function_builtin_fg\", modifiers = [\"bold\"] }\n\"ui.match_paren\" = { fg = \"match_paren_fg\", bg = \"match_paren_bg\", modifiers = [\"bold\"] }\n\n# Palette overrides\n[palette]\n# Very dark theme colors\nbackground = \"#000A0F\"  # Very dark background\nforeground = \"#C0C0CE\"  # Slightly muted foreground\ncursor_fg = \"#0E0E10\"\ncursor_bg = \"#F28FAD\"  # Pink cursor\ncursorline = \"#1E1E20\"  # Slightly lighter background\nselection = \"#2E2E30\"  # Dark gray selection\nline_nr = \"#5E5A76\"  # Dark gray line numbers\nline_nr_selected = \"#C0C0CE\"  # Foreground color for selected line number\n\n# Status line colors\nstatus_fg = \"#C0C0CE\"\nstatus_bg = \"#1E1E20\"\nstatus_inactive_fg = \"#5E5A76\"\nstatus_inactive_bg = \"#0E0E10\"\n\n# Menu colors\nmenu_fg = \"#C0C0CE\"\nmenu_bg = \"#1E1E20\"\nmenu_sel_fg = \"#C0C0CE\"\nmenu_sel_bg = \"#2E2E30\"\nmenu_scroll_fg = \"#5E5A76\"\nmenu_scroll_bg = \"#1E1E20\"\npopup_fg = \"#C0C0CE\"\npopup_bg = \"#1E1E20\"\n\n# UI virtual\nvirtual_ruler_bg = \"#191921\"  # Slightly lighter than background, close to comment color\n\n# Syntax highlighting\nmatch_paren_fg = \"#F28FAD\"\nmatch_paren_bg = \"#0E0E10\"\ncomment_fg = \"#5E5A76\"  # Dark gray comments\nstring_fg = \"#8FBF8F\"  # Muted green strings\nstring_special_fg = \"#F28FAD\"  # Pink special strings\nconstant_fg = \"#F28FAD\"  # Pink constants\nconstant_builtin_fg = \"#F28FAD\"\nnumber_fg = \"#D8A080\"  # Muted peach numbers\nboolean_fg = \"#F28FAD\"\nfunction_fg = \"#7FAFD7\"  # Muted blue functions\nfunction_builtin_fg = \"#7FAFD7\"\nkeyword_fg = \"#F5C2E7\"  # Pink keywords\nkeyword_control_fg = \"#F5C2E7\"\noperator_fg = \"#C0C0CE\"  # Foreground color for operators\nvariable_fg = \"#C0C0CE\"\nvariable_builtin_fg = \"#F28FAD\"\ntype_fg = \"#A0A0D0\"  # Muted lavender types\ntype_builtin_fg = \"#A0A0D0\"\nattribute_fg = \"#F5C2E7\"\nnamespace_fg = \"#A0A0D0\"  # Muted lavender namespaces (Base16 base0E)\npunctuation_fg = \"#C0C0CE\"\nsymbol_fg = \"#F28FAD\"\n\n# Diagnostics\nerror_fg = \"#F28FAD\"  # Base16 base08 - red errors\nwarning_fg = \"#D8A080\"  # Base16 base09 - orange warnings\ninfo_fg = \"#7FAFD7\"  # Base16 base0B - blue info\nhint_fg = \"#7BB5A8\"  # Base16 base0C - cyan hints\n\n# Diff colors\ndiff_add_fg = \"#86BA75\"  # Muted green additions\ndiff_delete_fg = \"#D78284\"  # Muted red deletions\ndiff_change_fg = \"#D5B880\"  # Muted yellow changes\n\n# Markup colors\nmarkup_heading_fg = \"#F5C2E7\"\nmarkup_bold_fg = \"#F5C2E7\"\nmarkup_italic_fg = \"#F5C2E7\"\nmarkup_link_url_fg = \"#7FAFD7\"\nmarkup_link_text_fg = \"#F5C2E7\"\nmarkup_quote_fg = \"#5E5A76\"\n"
  },
  {
    "path": "runtime/themes/nyxvamp-radiance.toml",
    "content": "# nyxvamp - radiance variant\n# author: <zoey.spessanha@zeetech.io>\n\n# Rainbow parentheses colors\nrainbow = [\"keyword_fg\", \"function_fg\", \"constant_fg\", \"string_fg\"]\n\n# UI Elements\n\"ui.background\"               = { bg = \"background\", fg = \"foreground\" }\n\"ui.text\"                     = { fg = \"foreground\" }\n\"ui.text.focus\"               = { fg = \"menu_sel_fg\", bg = \"menu_sel_bg\" }\n\"ui.text.inactive\"            = { fg = \"comment_fg\" }\n\"ui.text.info\"                = { fg = \"menu_fg\", bg = \"menu_bg\" }\n\"ui.cursor\"                   = { fg = \"cursor_fg\", bg = \"cursor_bg\" }\n\"ui.cursorline.primary\"       = { bg = \"cursorline\" }\n\"ui.selection\"                = { bg = \"selection\" }\n\"ui.linenr\"                   = { fg = \"line_nr\" }\n\"ui.linenr.selected\"          = { fg = \"line_nr_selected\", modifiers = [\"bold\"] }\n\"ui.statusline\"               = { fg = \"status_fg\", bg = \"status_bg\" }\n\"ui.statusline.inactive\"      = { fg = \"status_inactive_fg\", bg = \"status_inactive_bg\" }\n\"ui.menu\"                     = { fg = \"menu_fg\", bg = \"menu_bg\" }\n\"ui.menu.selected\"            = { fg = \"menu_sel_fg\", bg = \"menu_sel_bg\" }\n\"ui.menu.scroll\"              = { fg = \"menu_scroll_fg\", bg = \"menu_scroll_bg\" }\n\"ui.popup\"                    = { fg = \"popup_fg\", bg = \"popup_bg\" }\n\"ui.popup.info\"               = { fg = \"menu_fg\", bg = \"menu_bg\" }\n\"ui.match_paren\"              = { fg = \"match_paren_fg\", bg = \"match_paren_bg\", modifiers = [\"bold\"] }\n\"ui.virtual\"                  = { fg = \"comment_fg\" }\n\"ui.virtual.ruler\"            = { bg = \"virtual_ruler_bg\" }\n\"ui.highlight\"                = { fg = \"menu_sel_fg\", bg = \"menu_sel_bg\" }\n\"ui.picker.header\"            = { fg = \"menu_fg\", bg = \"menu_bg\" }\n\"ui.picker.header.column\"     = { fg = \"menu_fg\", bg = \"menu_bg\" }\n\"ui.picker.header.column.active\" = { fg = \"menu_sel_fg\", bg = \"menu_sel_bg\" }\n\"ui.window\"                   = { fg = \"foreground\" }\n\"ui.help\"                     = { fg = \"menu_fg\", bg = \"menu_bg\" }\n\"ui.text.directory\"           = { fg = \"function_fg\", modifiers = [\"bold\"] }\n\"ui.selection.primary\"          = { bg = \"selection\" }\n\n# Syntax Highlighting\n\"comment\"                     = { fg = \"comment_fg\", modifiers = [\"italic\"] }\n\"string\"                      = { fg = \"string_fg\" }\n\"string.special\"              = { fg = \"string_special_fg\" }\n\"constant\"                    = { fg = \"constant_fg\" }\n\"constant.builtin\"            = { fg = \"constant_builtin_fg\", modifiers = [\"bold\"] }\n\"number\"                      = { fg = \"number_fg\" }\n\"boolean\"                     = { fg = \"boolean_fg\" }\n\"function\"                    = { fg = \"function_fg\", modifiers = [\"bold\"] }  # Added bold for better distinction\n\"function.builtin\"            = { fg = \"function_builtin_fg\", modifiers = [\"bold\"] }\n\"keyword\"                     = { fg = \"keyword_fg\", modifiers = [\"bold\"] }\n\"keyword.control\"             = { fg = \"keyword_control_fg\", modifiers = [\"bold\"] }\n\"operator\"                    = { fg = \"operator_fg\" }\n\"variable\"                    = { fg = \"variable_fg\" }\n\"variable.builtin\"            = { fg = \"variable_builtin_fg\", modifiers = [\"italic\"] }\n\"type\"                        = { fg = \"type_fg\", modifiers = [\"italic\"] }\n\"type.builtin\"                = { fg = \"type_builtin_fg\", modifiers = [\"italic\"] }\n\"attribute\"                   = { fg = \"attribute_fg\" }\n\"namespace\"                   = { fg = \"namespace_fg\" }\n\"punctuation\"                 = { fg = \"punctuation_fg\" }\n\"symbol\"                      = { fg = \"symbol_fg\", modifiers = [\"italic\"] }\n\n# Diagnostics\n\"warning\"                     = { fg = \"warning_fg\" }\n\"error\"                       = { fg = \"error_fg\" }\n\"info\"                        = { fg = \"info_fg\" }\n\"hint\"                        = { fg = \"hint_fg\" }\n\"diagnostic\"                  = { fg = \"error_fg\" }\n\"diagnostic.error\"            = { fg = \"error_fg\", modifiers = [\"bold\"] }\n\"diagnostic.warning\"          = { fg = \"warning_fg\", modifiers = [\"bold\"] }\n\"diagnostic.info\"             = { fg = \"info_fg\", modifiers = [\"bold\"] }\n\"diagnostic.hint\"             = { fg = \"hint_fg\", modifiers = [\"bold\"] }\n\n# Diff\n\"diff.plus\"                   = { fg = \"diff_add_fg\" }\n\"diff.minus\"                  = { fg = \"diff_delete_fg\" }\n\"diff.delta\"                  = { fg = \"diff_change_fg\" }\n\n# Markup\n\"markup.heading\"              = { fg = \"markup_heading_fg\", modifiers = [\"bold\"] }\n\"markup.bold\"                 = { fg = \"markup_bold_fg\", modifiers = [\"bold\"] }\n\"markup.italic\"               = { fg = \"markup_italic_fg\", modifiers = [\"italic\"] }\n\"markup.link.url\"             = { fg = \"markup_link_url_fg\", modifiers = [\"underlined\"] }\n\"markup.link.text\"            = { fg = \"markup_link_text_fg\" }\n\"markup.quote\"                = { fg = \"markup_quote_fg\", modifiers = [\"italic\"] }\n\n# Palette\n[palette]\nbackground                    = \"#F7F7FF\"  # Off-white background (from your visual identity)\nforeground                    = \"#1E1E2E\"  # Deep navy foreground (from your visual identity)\ncursor_fg                     = \"#F7F7FF\"  # Off-white cursor text\ncursor_bg                     = \"#9655FF\"  # Deep purple cursor (from your visual identity)\ncursorline                    = \"#E8E8F0\"  # Slightly darker than background\nselection                     = \"#E8D5FF\"  # Light purple selection that matches theme palette\nline_nr                       = \"#5A5570\"  # Darker gray for line numbers\nline_nr_selected              = \"#1E1E2E\"  # Deep navy for selected line number\nstatus_fg                     = \"#1E1E2E\"  # Deep navy\nstatus_bg                     = \"#E8E8F0\"  # Light gray\nstatus_inactive_fg            = \"#5A5570\"  # Darker gray\nstatus_inactive_bg            = \"#F7F7FF\"  # Off-white\nmenu_fg                       = \"#1E1E2E\"  # Deep navy\nmenu_bg                       = \"#E8E8F0\"  # Light gray\nmenu_sel_fg                   = \"#1E1E2E\"  # Dark navy text for better contrast\nmenu_sel_bg                   = \"#E8D5FF\"  # Light purple selection\nmenu_scroll_fg                = \"#5A5570\"  # Darker gray\nmenu_scroll_bg                = \"#E8E8F0\"  # Light gray\npopup_fg                      = \"#1E1E2E\"  # Deep navy\npopup_bg                      = \"#E8E8F0\"  # Light gray\nmatch_paren_fg                = \"#1E1E2E\"  # Deep navy\nmatch_paren_bg                = \"#E8D5FF\"  # Light purple matching selection\nvirtual_ruler_bg              = \"#EAEAF0\"  # Slightly lighter than comment color background\n\ncomment_fg                    = \"#5A5570\"  # Darker gray comments for better contrast\nstring_fg                     = \"#B8860B\"  # Dark golden rod - much better contrast on light background\nstring_special_fg             = \"#9F1239\"  # Even darker pink special strings\nconstant_fg                   = \"#9F1239\"  # Even darker pink constants for maximum contrast\nconstant_builtin_fg           = \"#9F1239\"  # Even darker pink built-in constants\nnumber_fg                     = \"#C2410C\"  # Darker orange numbers for better contrast\nboolean_fg                    = \"#9F1239\"  # Even darker pink booleans\nfunction_fg                   = \"#005F87\"  # Dark blue functions (more distinguishable)\nfunction_builtin_fg           = \"#005F87\"  # Dark blue built-in functions\nkeyword_fg                    = \"#9655FF\"  # Deep purple keywords\nkeyword_control_fg            = \"#9655FF\"  # Deep purple control keywords\noperator_fg                   = \"#4A4560\"  # Darker purple-gray operators for better contrast\nvariable_fg                   = \"#1E1E2E\"  # Deep navy variables\nvariable_builtin_fg           = \"#9F1239\"  # Even darker pink built-in variables\ntype_fg                       = \"#6B46C1\"  # Darker purple types for better contrast\ntype_builtin_fg               = \"#6B46C1\"  # Darker purple built-in types for better contrast\nattribute_fg                  = \"#9655FF\"  # Deep purple attributes\nnamespace_fg                  = \"#6B46C1\"  # Darker purple namespaces (Base16 base0E)\npunctuation_fg                = \"#1E1E2E\"  # Deep navy punctuation\nsymbol_fg                     = \"#9F1239\"  # Even darker pink symbols (atoms) for maximum contrast\n\nerror_fg                      = \"#9F1239\"  # Base16 base08 - red errors\nwarning_fg                    = \"#C2410C\"  # Base16 base09 - orange warnings\ninfo_fg                       = \"#005F87\"  # Base16 base0B - blue info\nhint_fg                       = \"#8BD5CA\"  # Base16 base0C - cyan hints\n\ndiff_add_fg                   = \"#A6DA95\"  # Soft green additions\ndiff_delete_fg                = \"#E78284\"  # Soft red deletions\ndiff_change_fg                = \"#E5C890\"  # Soft yellow changes\n\nmarkup_heading_fg             = \"#9655FF\"  # Deep purple headings\nmarkup_bold_fg                = \"#1E1E2E\"  # Deep navy bold text\nmarkup_italic_fg              = \"#1E1E2E\"  # Deep navy italic text\nmarkup_link_url_fg            = \"#005F87\"  # Dark blue links\nmarkup_link_text_fg           = \"#9655FF\"  # Deep purple link text\nmarkup_quote_fg               = \"#5A5570\"  # Darker gray quotes\n"
  },
  {
    "path": "runtime/themes/nyxvamp-transparent.toml",
    "content": "# nyxvamp: override variant (fully transparent)\n# author: zoedsoupe <zoey.spessanha@zeetech.io>\n\ninherits = \"nyxvamp-veil\"\n\n# Override UI elements for transparency while maintaining readability\n\"ui.background\" = {}\n\"ui.statusline\" = { fg = \"status_fg\" }\n\"ui.statusline.inactive\" = { fg = \"status_inactive_fg\" }\n\"ui.cursorline.primary\" = {}\n\"ui.virtual.ruler\" = {}\n\n# Keep menus fully transparent but improve text contrast\n\"ui.menu\" = { fg = \"bright_text\" }\n\"ui.menu.selected\" = { fg = \"selected_bright\", bg = \"selection_subtle\", modifiers = [\"bold\"] }\n\"ui.menu.scroll\" = { fg = \"menu_scroll_fg\" }\n\n# Popups remain transparent with better text\n\"ui.popup\" = { fg = \"bright_text\" }\n\"ui.popup.info\" = { fg = \"bright_text\" }\n\n# Improve picker visibility while keeping transparency\n\"ui.picker.header\" = { fg = \"header_bright\", modifiers = [\"bold\", \"underlined\"] }\n\"ui.picker.header.column\" = { fg = \"header_bright\" }\n\"ui.picker.header.column.active\" = { fg = \"active_column_fg\", bg = \"active_column_bg\", modifiers = [\"bold\", \"underlined\"] }\n\n# Focus and selection improvements\n\"ui.text.focus\" = { fg = \"selected_bright\", bg = \"selection_subtle\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = { fg = \"text_inactive_fg\" }\n\"ui.text.directory\" = { fg = \"directory_fg\", modifiers = [\"italic\"] }\n\n# Improve other UI elements\n\"ui.match_paren\" = { fg = \"match_paren_fg\", bg = \"match_paren_highlight_bg\", modifiers = [\"bold\"] }\n\"ui.selection\" = { bg = \"selection_transparent\" }\n\"ui.selection.primary\" = { bg = \"selection_primary_transparent\" }\n\n# Add palette for transparent-specific colors\n[palette]\n# Much brighter colors for transparent backgrounds - maximum readability\nbright_text = \"#FFFFFF\"  # Pure white for maximum contrast on any background\nselected_bright = \"#FF6B9D\"  # Bright pink that's still muted but very visible\nheader_bright = \"#5DADE2\"  # Bright blue but not harsh\ndirectory_fg = \"#E8D5FF\"  # Very bright lavender for directories\ntext_inactive_fg = \"#A0A0A0\"  # Bright gray for inactive text\n\n# Stronger selection backgrounds for transparent theme\nselection_subtle = \"#DDA0DD\"  # 31% muted plum selection\nmatch_paren_highlight_bg = \"#DDA0DD\"  # 25% muted plum highlight\nselection_transparent = \"#483D8B\"  # 25% dark slate blue selection\nselection_primary_transparent = \"#483D8B\"  # 31% dark slate blue primary\n\n# Active column highlighting for better visibility\nactive_column_fg = \"#1E1E2E\"  # Dark text for contrast\nactive_column_bg = \"#87CEEB\"  # 50% sky blue background - matches header color\n"
  },
  {
    "path": "runtime/themes/nyxvamp-veil.toml",
    "content": "# nyxvamp: veil variant\n# author: zoedsoupe <zoey.spessanha@zeetech.io>\n\ninherits = \"nyxvamp-radiance\"\n\n# Rainbow parentheses colors\nrainbow = [\"keyword_fg\", \"function_fg\", \"string_fg\", \"number_fg\"]\n\n# Override specific styles for veil variant\n\"function\" = { fg = \"function_fg\", modifiers = [\"bold\"] }\n\"function.builtin\" = { fg = \"function_builtin_fg\", modifiers = [\"bold\"] }\n\"ui.match_paren\" = { fg = \"match_paren_fg\", bg = \"match_paren_bg\", modifiers = [\"bold\"] }\n\n# Palette overrides\n[palette]\n# Dark theme colors - only override what's different from the base theme\nbackground = \"#1E1E2E\"  # Dark purple background\nforeground = \"#D9E0EE\"  # Light lavender foreground\ncursor_fg = \"#1E1E2E\"\ncursor_bg = \"#F5C2E7\"  # Soft pink cursor\ncursorline = \"#2E2E3E\"  # Slightly lighter background\nselection = \"#494D64\"  # Grayish selection\nline_nr = \"#6E6A86\"  # Medium gray for line numbers\nline_nr_selected = \"#D9E0EE\"  # Foreground color for selected line number\n\n# Status line colors\nstatus_fg = \"#D9E0EE\"\nstatus_bg = \"#2E2E3E\"\nstatus_inactive_fg = \"#6E6A86\"\nstatus_inactive_bg = \"#1E1E2E\"\n\n# Menu colors\nmenu_fg = \"#D9E0EE\"\nmenu_bg = \"#1E1E2E\"\nmenu_sel_fg = \"#D9E0EE\"\nmenu_sel_bg = \"#494D64\"\nmenu_scroll_fg = \"#6E6A86\"\nmenu_scroll_bg = \"#1E1E2E\"\npopup_fg = \"#D9E0EE\"\npopup_bg = \"#1E1E2E\"\n\n# UI virtual\nvirtual_ruler_bg = \"#2A2A3C\"  # Slightly lighter than background, close to comment color\n\n# Syntax highlighting\nmatch_paren_fg = \"#F28FAD\"\nmatch_paren_bg = \"#1E1E2E\"\ncomment_fg = \"#6E6A86\"  # Gray comments\nstring_fg = \"#ABE9B3\"  # Green strings\nstring_special_fg = \"#F28FAD\"  # Pink special strings\nconstant_fg = \"#F28FAD\"  # Pink constants\nconstant_builtin_fg = \"#F28FAD\"  # Pink built-in constants\nnumber_fg = \"#F8BD96\"  # Peach numbers\nboolean_fg = \"#F28FAD\"  # Pink booleans\nfunction_fg = \"#96CDFB\"  # Blue functions\nfunction_builtin_fg = \"#96CDFB\"  # Blue built-in functions\nkeyword_fg = \"#F5C2E7\"  # Pink keywords\nkeyword_control_fg = \"#F5C2E7\"  # Pink control keywords\noperator_fg = \"#D9E0EE\"  # Foreground color for operators\nvariable_fg = \"#D9E0EE\"  # Foreground color for variables\nvariable_builtin_fg = \"#F28FAD\"  # Pink built-in variables\ntype_fg = \"#C9CBFF\"  # Lavender types\ntype_builtin_fg = \"#C9CBFF\"  # Lavender built-in types\nattribute_fg = \"#F5C2E7\"  # Pink attributes\nnamespace_fg = \"#C9CBFF\"  # Lavender namespaces (Base16 base0E)\npunctuation_fg = \"#D9E0EE\"  # Foreground color for punctuation\nsymbol_fg = \"#F28FAD\"  # Pink symbols (e.g., Elixir atoms)\n\n# Diagnostics\nerror_fg = \"#F28FAD\"  # Base16 base08 - red errors\nwarning_fg = \"#F8BD96\"  # Base16 base09 - orange warnings\ninfo_fg = \"#96CDFB\"  # Base16 base0B - blue info\nhint_fg = \"#8BD5CA\"  # Base16 base0C - cyan hints\n\n# Diff colors\ndiff_add_fg = \"#A6DA95\"  # Green additions\ndiff_delete_fg = \"#E78284\"  # Red deletions\ndiff_change_fg = \"#E5C890\"  # Yellow changes\n\n# Markup colors\nmarkup_heading_fg = \"#F5C2E7\"  # Pink headings\nmarkup_bold_fg = \"#F5C2E7\"  # Pink bold text\nmarkup_italic_fg = \"#F5C2E7\"  # Pink italic text\nmarkup_link_url_fg = \"#96CDFB\"  # Blue links\nmarkup_link_text_fg = \"#F5C2E7\"  # Pink link text\nmarkup_quote_fg = \"#6E6A86\"  # Gray quotes\n"
  },
  {
    "path": "runtime/themes/ocean-space.toml",
    "content": "# Author: mikastiv\n\n\"attribute\" = \"red\"\n\"type\" = \"orange\"\n\"type.builtin\" = \"purple\"\n\"type.enum\" = \"purple\"\n\"constructor\" = \"yellow\"\n\"constant\" = \"red\"\n\"string\" = \"green\"\n\"constant.numeric\" = \"orange\"\n\"constant.builtin\" = \"purple\"\n\"constant.character.escape\" = \"red\"\n\"comment\" = \"light-gray\"\n\"variable\" = \"cyan\"\n\"variable.builtin\" = \"purple\"\n\"label\" = \"white\"\n\"punctuation\" = \"white\"\n\"keyword\" = \"purple\"\n\"operator\" = \"red\"\n\"function\" = \"yellow\"\n\"function.builtin\" = \"orange\"\n\"function.macro\" = \"orange\"\n\"tag\" = \"orange\"\n\"namespace\" = \"white\"\n\"special\" = \"orange\"\n\"markup.heading\" = \"hot-pink\"\n\"markup.list\" = \"yellow\"\n\"markup.link\" = \"purple\"\n\"markup.quote\" = \"green\"\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"orange\"\n\n\"ui.background\" = { bg = \"bg\" }\n\"ui.cursor\" = { bg = \"cursor-light\", fg = \"bg\" }\n\"ui.cursor.primary\" = { bg = \"cursor\", fg = \"bg\" }\n\"ui.cursor.match\" = { fg = \"hot-pink\", modifiers = [\"bold\"] }\n\"ui.debug.breakpoint\" = \"red\"\n\"ui.debug.active\" = \"red\"\n\"ui.linenr\" = \"light-gray\"\n\"ui.linenr.selected\" = \"white\"\n\"ui.statusline\" = { bg = \"bar\", fg = \"bg\" }\n\"ui.bufferline\" = { bg = \"bg-light\", fg = \"light-gray\" }\n\"ui.bufferline.active\" = { bg = \"bar\", fg = \"bg\" }\n\"ui.window\" = \"light-gray\"\n\"ui.help\" = { bg = \"bg\" }\n\"ui.popup\" = { bg = \"bg\" }\n\"ui.text\" = \"white\"\n\"ui.text.focus\" = { bg = \"selected\" }\n\"ui.text.inactive\" = \"light-gray\"\n\"ui.text.directory\" = \"cyan\"\n\"ui.virtual.ruler\" = { bg = \"bg-light\" }\n\"ui.virtual.indent-guide\" = \"light-gray\"\n\"ui.virtual.inlay-hint\" = { modifiers = [\"dim\"] }\n\"ui.virtual.jump-label\" = { fg = \"hot-pink\", modifiers = [\"bold\"] }\n\"ui.menu\" = { bg = \"bg\" }\n\"ui.menu.selected\" = { bg = \"selected\" }\n\"ui.menu.scroll\" = \"bar\"\n\"ui.selection\" = { bg = \"selected\" }\n\"ui.cursorline.primary\" = { bg = \"bg-light\" }\n\n\"warning\" = \"yellow\"\n\"error\" = \"red\"\n\"hint\" = \"blue\"\n\"info\" = \"blue\"\n\n\"diagnostic.hint\".underline = { color = \"blue\", style = \"curl\" }\n\"diagnostic.info\".underline = { color = \"blue\", style = \"curl\" }\n\"diagnostic.warning\".underline = { color = \"yellow\", style = \"curl\" }\n\"diagnostic.error\".underline = { color = \"red\", style = \"curl\" }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nwhite = \"#d5ced9\"\nlight-gray = \"#6e7178\"\ncyan = \"#87d3f8\"\nblue = \"#3a75c4\"\norange = \"#f39c12\"\nyellow = \"#f2f27a\"\npurple = \"#c74ded\"\nred = \"#e25822\"\npink = \"#ff00aa\"\nhot-pink = \"#f92672\"\ngreen = \"#14b37d\"\nbg = \"#0f111a\"\nbg-light = \"#25293a\"\nselected = \"#414a5b\"\ncursor = \"#d5d5d5\"\ncursor-light = \"#92969f\"\nbar = \"#00b491\"\n"
  },
  {
    "path": "runtime/themes/omicron_dark.toml",
    "content": "# Author: Ricardo Fernández Serrata <rudxain@gmail.com>\n\nerror = \"err\"\nwarning = \"warn\"\nhint = \"diag\"\ninfo = \"diag\"\ndiagnostic = { underline = { color = \"ghost\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"err\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"warn\", style = \"curl\" } }\n\"diagnostic.deprecated\" = { fg = \"code_unsafe\", modifiers = [\"crossed_out\"] }\n\n\"ui.background\" = { bg = \"bg\" }\n\"ui.window\" = { bg = \"bg_ui\" }\n\"ui.gutter\" = { bg = \"bg_ui\" }\n\"ui.linenr\" = \"default_weak\"\n\"ui.linenr.selected\" = \"default\"\n\"ui.text\" = \"default\"\n\"ui.text.focus\" = { bg = \"sel\" }\n# secondary\n\"ui.cursor\" = { fg = \"#111\", bg = \"#ccc\" }\n# it only uses 1 cell, and it must be skimmable,\n# so force max contrast\n\"ui.cursor.primary\" = { fg = \"#000\", bg = \"#fff\" }\n\"ui.cursor.match\" = { bg = \"#333\" }\n\"ui.debug\" = \"default\"\n# it feels questionable, but it's more consistent and clean than `reversed`;\n# some web-browsers do the same\n\"ui.selection\" = { fg = \"#222\", bg = \"#aaa\" }\n\"ui.cursorline\" = { bg = \"sel_weak\" }\n\"ui.cursorcolumn\" = { bg = \"sel_weak\" }\n\"ui.virtual\" = \"ghost\"\n\"ui.virtual.ruler\" = { bg = \"sel_weak\" }\n\"ui.virtual.inlay-hint\" = \"ghost\"\n# these are ephemeral and user-controllable,\n# are not part of the buffer,\n# should be skimmable,\n# so override FG & BG to guarantee contrast\n# while also signaling that they are special text\n\"ui.virtual.jump-label\" = { fg = \"#fff\", bg = \"sym\" }\n\"ui.statusline\" = { fg = \"default\", bg = \"bg_ui\" }\n\"ui.bufferline\" = { fg = \"default\", bg = \"bg_ui\" }\n\"ui.bufferline.active\" = { bg = \"sel\", modifiers = [\"bold\"] }\n\"ui.help\" = { fg = \"doc\", bg = \"bg_ui\" }\n\"ui.highlight\" = { bg = \"sel\" }\n\"ui.menu\" = { fg = \"code\", bg = \"bg_ui\" }\n\"ui.menu.selected\" = { bg = \"sel\" }\n\"ui.popup\" = { fg = \"#fff\", bg = \"#333\" }\n\"ui.picker.header\" = { modifiers = [\"bold\", \"underlined\"] }\n\n\n# Tree-Sitter scopes (syntax highlight)\n\n# NOTE: builtin HTML ones can be trivially auto-checked,\n# but custom ones (contain hyphens) need highlighting.\n#\"attribute\" = {}\n#\"tag\" = {}\n\"tag.error\" = { fg = \"err\", underline = { style = \"line\" } }\n\"constant\" = \"literal\"\n# TO-DO: escapes need highlight, but not unsafe\n\"constant.character.escape\" = \"literal_unsafe\"\n# floats are a plague!\n# https://github.com/you-dont-need/You-Dont-Need/issues/13\n\"constant.numeric.float\" = \"literal_unsafe\"\n\"string\" = \"literal\"\n\"string.regexp\" = \"literal_unsafe\"\n\"string.special\" = \"sym\"\n\"comment\" = \"doc\"\n# some are mutable and can be misused without triggering warns\n#\"variable.builtin\" = \"literal_unsafe\"\n\"punctuation\" = \"default_weak\"\n# beware of the Halting Problem!\n\"keyword.control.repeat\" = \"code_unsafe\"\n\"markup.heading\" = { modifiers = [\"bold\"] }\n\"markup.heading.marker\" = \"sym\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link\" = { fg = \"sym\", underline = { style = \"line\" } }\n\"markup.quote\" = \"doc\"\n\n\"markup.normal\" = \"default\"\n\"markup.normal.raw\" = \"code\"\n\"markup.heading.raw\" = \"code\"\n\"markup.raw\" = \"code\"\n\n\"diff.plus\" = \"green\" # + add\n\"diff.minus\" = \"red\" # - delete\n\"diff.delta\" = \"yellow\" # ± edit\n\"diff.delta.moved\" = \"sym\" # -> rename\n\"diff.delta.conflict\" = \"err\" # ❌\n\n[palette]\nbg = \"#000\"\nbg_ui = \"#111\"\ndefault = \"#ccc\"\ndefault_weak = \"#999\"\nghost = \"#666\"\ncode = \"#9c9\"\ncode_unsafe = \"#fc7\"\nred = \"#b33\"\ngreen = \"#3a3\"\nyellow = \"#aa3\"\nsel = \"#333\"\nsel_weak = \"#171717\"\n# I call this \"eye-piercing red\" because\n# it's designed to be jarring like a laser\nerr = \"#f20\"\nwarn = \"#ed3\"\ndiag = \"#07f\"\nliteral = \"#0d7\"\nliteral_unsafe = \"#f70\"\nsym = \"#1af\"\n# inspired by ⭐ Gleam's \"faf pink\"\ndoc = \"#c7c\"\n"
  },
  {
    "path": "runtime/themes/omicron_light.toml",
    "content": "# Author: Ricardo Fernández Serrata <rudxain@gmail.com>\n\nerror = \"err\"\nwarning = \"warn\"\nhint = \"diag\"\ninfo = \"diag\"\ndiagnostic = { underline = { color = \"ghost\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"err\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"warn\", style = \"curl\" } }\n\"diagnostic.deprecated\" = { fg = \"code_unsafe\", bg = \"code_bg_unsafe\", modifiers = [\n\t\"crossed_out\",\n] }\n\n\"ui.background\" = { bg = \"bg\" }\n\"ui.window\" = { bg = \"bg_ui\" }\n\"ui.gutter\" = { bg = \"bg_ui\" }\n\"ui.linenr\" = \"default_weak\"\n\"ui.linenr.selected\" = \"default\"\n\"ui.text\" = \"default\"\n\"ui.text.focus\" = { bg = \"sel\" }\n# secondary\n\"ui.cursor\" = { fg = \"#eee\", bg = \"#333\" }\n# it only uses 1 cell, and it must be skimmable,\n# so force max contrast\n\"ui.cursor.primary\" = { fg = \"#fff\", bg = \"#000\" }\n\"ui.cursor.match\" = { bg = \"#ccc\" }\n\"ui.debug\" = \"default\"\n# it feels questionable, but it's more consistent and clean than `reversed`;\n# some web-browsers do the same\n\"ui.selection\" = { fg = \"#ddd\", bg = \"#555\" }\n\"ui.cursorline\" = { bg = \"sel_weak\" }\n\"ui.cursorcolumn\" = { bg = \"sel_weak\" }\n\"ui.virtual\" = \"ghost\"\n\"ui.virtual.ruler\" = { bg = \"sel_weak\" }\n\"ui.virtual.inlay-hint\" = \"ghost\"\n# these are ephemeral and user-controllable,\n# are not part of the buffer,\n# should be skimmable,\n# so override FG & BG to guarantee contrast\n# while also signaling that they are special text\n\"ui.virtual.jump-label\" = { fg = \"#000\", bg = \"sym\" }\n\"ui.statusline\" = { fg = \"default\", bg = \"bg_ui\" }\n\"ui.bufferline\" = { fg = \"default\", bg = \"bg_ui\" }\n\"ui.bufferline.active\" = { bg = \"sel\", modifiers = [\"bold\"] }\n\"ui.help\" = { fg = \"doc\", bg = \"bg_ui\" }\n\"ui.highlight\" = { bg = \"sel\" }\n\"ui.menu\" = { fg = \"code\", bg = \"bg_ui\" }\n\"ui.menu.selected\" = { bg = \"sel\" }\n\"ui.popup\" = { fg = \"#000\", bg = \"#ccc\" }\n\"ui.picker.header\" = { modifiers = [\"bold\", \"underlined\"] }\n\n\n# Tree-Sitter scopes (syntax highlight)\n\n# NOTE: builtin HTML ones can be trivially auto-checked,\n# but custom ones (contain hyphens) need highlighting.\n#\"attribute\" = {}\n#\"tag\" = {}\n\"tag.error\" = { fg = \"err\", underline = { style = \"line\" } }\n\"constant\" = \"literal\"\n# TO-DO: escapes need highlight, but not unsafe\n\"constant.character.escape\" = \"literal_unsafe\"\n# floats are a plague!\n# https://github.com/you-dont-need/You-Dont-Need/issues/13\n\"constant.numeric.float\" = { fg = \"literal_unsafe\", bg = \"literal_bg_unsafe\" }\n\"string\" = \"literal\"\n\"string.regexp\" = { fg = \"literal_unsafe\", bg = \"literal_bg_unsafe\" }\n\"string.special\" = \"sym\"\n\"comment\" = \"doc\"\n# some are mutable and can be misused without triggering warns\n#\"variable.builtin\" = \"literal_unsafe\"\n\"punctuation\" = \"default_weak\"\n# beware of the Halting Problem!\n\"keyword.control.repeat\" = { fg = \"code_unsafe\", bg = \"code_bg_unsafe\" }\n\"markup.heading\" = { modifiers = [\"bold\"] }\n\"markup.heading.marker\" = \"sym\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link\" = { fg = \"sym\", underline = { style = \"line\" } }\n\"markup.quote\" = \"doc\"\n\n\"markup.normal\" = \"default\"\n\"markup.normal.raw\" = \"code\"\n\"markup.heading.raw\" = \"code\"\n\"markup.raw\" = \"code\"\n\n\"diff.plus\" = \"green\" # + add\n\"diff.minus\" = \"red\" # - delete\n\"diff.delta\" = \"yellow\" # ± edit\n\"diff.delta.moved\" = \"sym\" # -> rename\n\"diff.delta.conflict\" = \"err\" # ❌\n\n[palette]\nbg = \"#eee\"\nbg_ui = \"#ddd\"\ndefault = \"#333\"\ndefault_weak = \"#666\"\nghost = \"#999\"\ncode = \"#363\"\ncode_unsafe = \"#300\"\ncode_bg_unsafe = \"#edd\"\nred = \"#800\"\ngreen = \"#070\"\nyellow = \"#770\"\nsel = \"#ccc\"\nsel_weak = \"#e7e7e7\"\nerr = \"#f00\"\nwarn = \"#ba0\"\ndiag = \"#06a\"\nliteral = \"#093\"\nliteral_unsafe = \"#410\"\nliteral_bg_unsafe = \"#eca\"\nsym = \"#0af\"\ndoc = \"#707\"\n"
  },
  {
    "path": "runtime/themes/onedark.toml",
    "content": "# Author : Gokul Soumya <gokulps15@gmail.com>\n\n\"tag\" = { fg = \"red\" }\n\"attribute\" = { fg = \"yellow\" }\n\"comment\" = { fg = \"light-gray\", modifiers = [\"italic\"] }\n\"constant\" = { fg = \"cyan\" }\n\"constant.numeric\" = { fg = \"gold\" }\n\"constant.builtin\" = { fg = \"gold\" }\n\"constant.character.escape\" = { fg = \"gold\" }\n\"constructor\" = { fg = \"blue\" }\n\"function\" = { fg = \"blue\" }\n\"function.builtin\" = { fg = \"blue\" }\n\"function.macro\" = { fg = \"purple\" }\n\"keyword\" = { fg = \"red\" }\n\"keyword.control\" = { fg = \"purple\" }\n\"keyword.control.import\" = { fg = \"red\" }\n\"keyword.directive\" = { fg = \"purple\" }\n\"keyword.storage\" = { fg = \"purple\" }\n\"label\" = { fg = \"purple\" }\n\"namespace\" = { fg = \"blue\" }\n\"operator\" = { fg = \"purple\" }\n\"keyword.operator\" = { fg = \"purple\" }\n\"special\" = { fg = \"blue\" }\n\"string\" = { fg = \"green\" }\n\"type\" = { fg = \"yellow\" }\n# \"variable\" = { fg = \"blue\" }\n\"variable.builtin\" = { fg = \"blue\" }\n\"variable.parameter\" = { fg = \"red\" }\n\"variable.other.member\" = { fg = \"red\" }\n\n\"markup.heading\" = { fg = \"red\" }\n\"markup.raw.inline\" = { fg = \"green\" }\n\"markup.bold\" = { fg = \"gold\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.list\" = { fg = \"red\" }\n\"markup.quote\" = { fg = \"yellow\" }\n\"markup.link.url\" = { fg = \"cyan\", modifiers = [\"underlined\"]}\n\"markup.link.text\" = { fg = \"purple\" }\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"gold\"\n\"diff.minus\" = \"red\"\n\n\"diagnostic.info\".underline = { color = \"blue\", style = \"curl\" } \n\"diagnostic.hint\".underline = { color = \"green\", style = \"curl\" } \n\"diagnostic.warning\".underline = { color = \"yellow\", style = \"curl\" } \n\"diagnostic.error\".underline = { color = \"red\", style = \"curl\" } \n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"info\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"warning\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"ui.background\" = { bg = \"black\" }\n\"ui.virtual\" = { fg = \"faint-gray\" }\n\"ui.virtual.indent-guide\" = { fg = \"faint-gray\" }\n\"ui.virtual.whitespace\" = { fg = \"light-gray\" }\n\"ui.virtual.ruler\" = { bg = \"gray\" }\n\"ui.virtual.inlay-hint\" = { fg = \"light-gray\" }\n\"ui.virtual.jump-label\" = { fg = \"light-gray\", modifiers = [\"bold\"] }\n\n\"ui.cursor\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"blue\", modifiers = [\"underlined\"]}\n\n\"ui.selection\" = { bg = \"faint-gray\" }\n\"ui.selection.primary\" = { bg = \"light-gray\" }\n\"ui.cursorline.primary\" = { bg = \"light-black\" }\n\n\"ui.highlight\" = { bg = \"gray\" }\n\"ui.highlight.frameline\" = { bg = \"#97202a\" }\n\n\"ui.linenr\" = { fg = \"linenr\" }\n\"ui.linenr.selected\" = { fg = \"white\" }\n\n\"ui.statusline\" = { fg = \"white\", bg = \"light-black\" }\n\"ui.statusline.inactive\" = { fg = \"light-gray\", bg = \"light-black\" }\n\"ui.statusline.normal\" = { fg = \"light-black\", bg = \"blue\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"light-black\", bg = \"green\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"light-black\", bg = \"purple\", modifiers = [\"bold\"] }\n\n\"ui.bufferline\" = { fg = \"light-gray\", bg = \"light-black\" }\n\"ui.bufferline.active\" = { fg = \"light-black\", bg = \"blue\", underline = { color = \"light-black\", style = \"line\" } }\n\"ui.bufferline.background\" = { bg = \"light-black\" }\n\n\"ui.text\" = { fg = \"white\" }\n\"ui.text.directory\" = { fg = \"blue\" }\n\"ui.text.focus\" = { fg = \"white\", bg = \"light-black\", modifiers = [\"bold\"] }\n\n\"ui.help\" = { fg = \"white\", bg = \"gray\" }\n\"ui.popup\" = { bg = \"gray\" }\n\"ui.window\" = { fg = \"gray\" }\n\"ui.menu\" = { fg = \"white\", bg = \"gray\" }\n\"ui.menu.selected\" = { fg = \"black\", bg = \"blue\" }\n\"ui.menu.scroll\" = { fg = \"white\", bg = \"light-gray\" }\n\n\"ui.debug\" = { fg = \"red\" }\n\n[palette]\n\nyellow = \"#E5C07B\"\nblue = \"#61AFEF\"\nred = \"#E06C75\"\npurple = \"#C678DD\"\ngreen = \"#98C379\"\ngold = \"#D19A66\"\ncyan = \"#56B6C2\"\nwhite = \"#ABB2BF\"\nblack = \"#282C34\"\nlight-black = \"#2C323C\"\ngray = \"#3E4452\"\nfaint-gray = \"#3B4048\"\nlight-gray = \"#5C6370\"\nlinenr = \"#4B5263\"\n"
  },
  {
    "path": "runtime/themes/onedark_vibrant.toml",
    "content": "# Author: Based on M47E theme by Mhammed Talhaouy (MIT License)\n# Adapted for Helix editor - Vibrant OneDark variant with aggressive color saturation\n\n# SYNTAX HIGHLIGHTING\n\"attribute\" = \"electric_cyan\"\n\"comment\" = { fg = \"bright_gray\", modifiers = [\"italic\"] }\n\"constant\" = \"neon_orange\"\n\"constant.builtin\" = \"hot_magenta\"\n\"constant.character\" = \"lime_green\"\n\"constant.character.escape\" = \"electric_cyan\"\n\"constant.numeric\" = \"electric_yellow\"\n\"constructor\" = \"sky_blue\"\n\"diff.delta\" = \"sky_blue\"\n\"diff.minus\" = \"hot_pink\"\n\"diff.plus\" = \"lime_green\"\n\"function\" = \"sky_blue\"\n\"function.builtin\" = \"hot_magenta\"\n\"function.macro\" = \"electric_cyan\"\n\"keyword\" = \"hot_pink\"\n\"keyword.control\" = \"hot_magenta\"\n\"keyword.directive\" = \"hot_magenta\"\n\"label\" = \"sky_blue\"\n\"module\" = \"electric_yellow\"\n\"namespace\" = \"electric_yellow\"\n\"operator\" = \"hot_pink\"\n\"punctuation\" = \"bright_white\"\n\"punctuation.delimiter\" = \"bright_white\"\n\"special\" = \"electric_cyan\"\n\"string\" = \"lime_green\"\n\"string.regexp\" = \"electric_cyan\"\n\"tag\" = \"hot_pink\"\n\"type\" = \"electric_yellow\"\n\"type.builtin\" = \"hot_magenta\"\n\"type.enum.variant\" = \"electric_cyan\"\n\"variable\" = \"bright_white\"\n\"variable.builtin\" = \"hot_magenta\"\n\"variable.other.member\" = \"bright_white\"\n\"variable.parameter\" = \"neon_orange\"\n\n# MARKUP\n\"markup.heading\" = { fg = \"sky_blue\", modifiers = [\"bold\"] }\n\"markup.list\" = \"hot_pink\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"electric_cyan\", underline = { style = \"line\" } }\n\"markup.link.text\" = \"sky_blue\"\n\"markup.quote\" = \"electric_yellow\"\n\"markup.raw\" = \"neon_orange\"\n\n# UI INTERFACE\n\"ui.background\" = { bg = \"deep_black\" }\n\"ui.cursor\" = { bg = \"electric_yellow\", fg = \"deep_black\" }\n\"ui.cursor.primary\" = { bg = \"electric_yellow\", fg = \"deep_black\" }\n\"ui.cursor.match\" = { bg = \"hot_magenta\", fg = \"deep_black\" }\n\"ui.cursor.select\" = { bg = \"selection_purple\" }\n\"ui.cursorline.primary\" = { bg = \"dark_surface\" }\n\"ui.gutter\" = { bg = \"deep_black\" }\n\"ui.gutter.selected\" = { bg = \"dark_surface\" }\n\"ui.linenr\" = \"medium_gray\"\n\"ui.linenr.selected\" = { fg = \"electric_yellow\", modifiers = [\"bold\"] }\n\"ui.menu\" = { fg = \"bright_white\", bg = \"popup_black\" }\n\"ui.menu.selected\" = { fg = \"deep_black\", bg = \"sky_blue\" }\n\"ui.menu.scroll\" = { fg = \"bright_white\", bg = \"bright_gray\" }\n\"ui.popup\" = { fg = \"bright_white\", bg = \"popup_black\" }\n\"ui.popup.info\" = { fg = \"electric_cyan\", bg = \"popup_black\" }\n\"ui.selection\" = { bg = \"selection_purple\" }\n\"ui.selection.primary\" = { bg = \"selection_purple\" }\n\"ui.statusline\" = { fg = \"bright_white\", bg = \"status_dark\" }\n\"ui.statusline.inactive\" = { fg = \"bright_gray\", bg = \"status_dark\" }\n\"ui.statusline.normal\" = { fg = \"deep_black\", bg = \"sky_blue\" }\n\"ui.statusline.insert\" = { fg = \"deep_black\", bg = \"lime_green\" }\n\"ui.statusline.select\" = { fg = \"deep_black\", bg = \"hot_magenta\" }\n\"ui.text\" = \"bright_white\"\n\"ui.text.focus\" = { fg = \"electric_yellow\", bg = \"selection_bg\", modifiers = [\"bold\"] }\n\"ui.virtual.indent-guide\" = \"indent_dark\"\n\"ui.virtual.inlay-hint\" = { fg = \"bright_gray\", bg = \"hint_dark\" }\n\"ui.virtual.jump-label\" = { fg = \"deep_black\", bg = \"electric_yellow\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"ruler_dark\" }\n\"ui.virtual.whitespace\" = \"whitespace_gray\"\n\"ui.virtual.wrap\" = \"bright_gray\"\n\"ui.window\" = \"border_gray\"\n\"ui.help\" = { fg = \"bright_white\", bg = \"popup_black\" }\n\n# DIAGNOSTICS\n\"error\" = \"hot_pink\"\n\"warning\" = \"electric_yellow\"\n\"info\" = \"sky_blue\"\n\"hint\" = \"electric_cyan\"\n\"diagnostic.error\" = { underline = { color = \"hot_pink\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"electric_yellow\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"sky_blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"electric_cyan\", style = \"curl\" } }\n\n[palette]\n# Vibrant colors with ORIGINAL OneDark backgrounds\ndeep_black = \"#282C34\"        # SAME as original OneDark\nbright_white = \"#e6efff\"      # Slightly enhanced white\nbright_gray = \"#c5d1e4\"       # Enhanced gray\nmedium_gray = \"#8691a8\"       # Enhanced medium gray\n\n# MORE vibrant OneDark colors - increased saturation\nhot_pink = \"#ff6ba7\"          # More vibrant red/pink (was #E06C75)\nlime_green = \"#6ee76e\"        # More vibrant green (was #98C379)\nelectric_yellow = \"#ffd93d\"   # More vibrant yellow (was #E5C07B)\nsky_blue = \"#3fb8ff\"          # More vibrant blue (was #61AFEF)\nhot_magenta = \"#e455ff\"       # More vibrant purple (was #C678DD)\nelectric_cyan = \"#2dd4da\"     # More vibrant cyan (was #56B6C2)\nneon_orange = \"#ff9f40\"       # More vibrant gold (was #D19A66)\n\n# UI backgrounds - SAME as original OneDark\ndark_surface = \"#2C323C\"      # SAME as original light-black\npopup_black = \"#21252B\"       # Similar to original darker areas\nstatus_dark = \"#21252B\"       # Darker status bar\nselection_purple = \"#e455ff\"  # Semi-transparent enhanced purple\nselection_bg = \"#3E4452\"      # SAME as original gray\nborder_gray = \"#3E4452\"       # SAME as original gray\nindent_dark = \"#3B4048\"       # SAME as original faint-gray\nhint_dark = \"#2C323C\"         # SAME as original light-black\nruler_dark = \"#3E4452\"        # SAME as original gray\nwhitespace_gray = \"#3B4048\"   # SAME as original faint-gray\n"
  },
  {
    "path": "runtime/themes/onedarker.toml",
    "content": "# Author : nuid32 <lvkuzvesov@proton.me>\n\n\"attribute\" = { fg = \"yellow\" }\n\"comment\" = { fg = \"light-gray\", modifiers = [\"italic\"] }\n\"constant\" = { fg = \"gold\" }\n\"constant.numeric\" = { fg = \"gold\" }\n\"constant.builtin\" = { fg = \"gold\" }\n\"constant.character.escape\" = { fg = \"gold\" }\n\"constructor\" = { fg = \"blue\" }\n\"function\" = { fg = \"white\" }\n\"function.builtin\" = { fg = \"blue\" }\n\"function.macro\" = { fg = \"purple\" }\n\"keyword\" = { fg = \"purple\" }\n\"keyword.control\" = { fg = \"purple\" }\n\"keyword.control.import\" = { fg = \"purple\" }\n\"keyword.directive\" = { fg = \"purple\" }\n\"label\" = { fg = \"purple\" }\n\"namespace\" = { fg = \"purple\" }\n\"operator\" = { fg = \"white\" }\n\"keyword.operator\" = { fg = \"white\" }\n\"special\" = { fg = \"blue\" }\n\"string\" = { fg = \"green\" }\n\"tag\" = { fg = \"purple\" }\n\"type\" = { fg = \"yellow\" }\n\"variable\" = { fg = \"white\" }\n\"variable.builtin\" = { fg = \"red\" }\n\"variable.parameter\" = { fg = \"red\" }\n\"variable.other.member\" = { fg = \"blue\" }\n\n\"markup.heading\" = { fg = \"red\" }\n\"markup.raw.inline\" = { fg = \"green\" }\n\"markup.raw.block\" = { fg = \"white\" }\n\"markup.bold\" = { fg = \"gold\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.list\" = { fg = \"red\" }\n\"markup.quote\" = { fg = \"yellow\" }\n\"markup.link.url\" = { fg = \"blue\", modifiers = [\"underlined\"]}\n\"markup.link.text\" = { fg = \"white\" }\n\"markup.link.label\" = { fg = \"white\" }\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"gold\"\n\"diff.minus\" = \"red\"\n\n\"diagnostic.info\".underline = { color = \"blue\", style = \"curl\" } \n\"diagnostic.hint\".underline = { color = \"green\", style = \"curl\" } \n\"diagnostic.warning\".underline = { color = \"yellow\", style = \"curl\" } \n\"diagnostic.error\".underline = { color = \"red\", style = \"curl\" } \n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"info\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"warning\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"ui.background\" = { bg = \"black\" }\n\"ui.virtual\" = { fg = \"faint-gray\" }\n\"ui.virtual.indent-guide\" = { fg = \"faint-gray\" }\n\"ui.virtual.whitespace\" = { fg = \"light-gray\" }\n\"ui.virtual.ruler\" = { bg = \"gray\" }\n\"ui.virtual.inlay-hint\" = { fg = \"light-gray\" }\n\"ui.virtual.jump-label\" = { fg = \"gold\", modifiers = [\"bold\", \"underlined\"] }\n\n\"ui.cursor\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"blue\", modifiers = [\"underlined\"]}\n\n\"ui.selection\" = { bg = \"black\", modifiers = [\"reversed\"] }\n\"ui.selection.primary\" = { bg = \"gray\" }\n\"ui.cursorline.primary\" = { bg = \"dark-black\" }\n\n\"ui.linenr\" = { fg = \"linenr\" }\n\"ui.linenr.selected\" = { fg = \"white\" }\n\n\"ui.statusline\" = { fg = \"white\", bg = \"light-black\" }\n\"ui.statusline.inactive\" = { fg = \"light-gray\", bg = \"light-black\" }\n\"ui.statusline.normal\" = { fg = \"light-black\", bg = \"purple\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"light-black\", bg = \"green\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"light-black\", bg = \"cyan\", modifiers = [\"bold\"] }\n\n\"ui.bufferline\" = { fg = \"light-gray\", bg = \"light-black\" }\n\"ui.bufferline.active\" = { fg = \"light-black\", bg = \"blue\", underline = { color = \"light-black\", style = \"line\" } }\n\"ui.bufferline.background\" = { bg = \"light-black\" }\n\n\"ui.text\" = { fg = \"white\" }\n\"ui.text.directory\" = { fg = \"blue\" }\n\"ui.text.focus\" = { fg = \"white\", bg = \"light-black\", modifiers = [\"bold\"] }\n\n\"ui.help\" = { fg = \"white\", bg = \"gray\" }\n\"ui.debug\" = { fg = \"red\" }\n\"ui.highlight.frameline\" = { bg = \"#97202a\" }\n\"ui.popup\" = { bg = \"gray\" }\n\"ui.window\" = { fg = \"gray\" }\n\"ui.menu\" = { fg = \"white\", bg = \"gray\" }\n\"ui.menu.selected\" = { fg = \"black\", bg = \"blue\" }\n\"ui.menu.scroll\" = { fg = \"white\", bg = \"light-gray\" }\n\n[palette]\n\nyellow = \"#D5B06B\"\nblue = \"#519FDF\"\nred = \"#D05C65\"\npurple = \"#B668CD\"\ngreen = \"#7DA869\"\ngold = \"#D19A66\"\ncyan = \"#46A6B2\"\nwhite = \"#ABB2BF\"\nblack = \"#16181A\"\ndark-black = \"#12100E\"\nlight-black = \"#2C323C\"\ngray = \"#252D30\"\nfaint-gray = \"#ABB2BF\"\nlight-gray = \"#636C6E\"\nlinenr = \"#282C34\"\n"
  },
  {
    "path": "runtime/themes/onedarker_vibrant.toml",
    "content": "# Author: Based on M47E theme by Mhammed Talhaouy (MIT License)\n# Adapted for Helix editor - Vibrant OneDarker variant with aggressive color saturation\n\n# SYNTAX HIGHLIGHTING\n\"attribute\" = \"electric_cyan\"\n\"comment\" = { fg = \"bright_gray\", modifiers = [\"italic\"] }\n\"constant\" = \"neon_orange\"\n\"constant.builtin\" = \"hot_magenta\"\n\"constant.character\" = \"lime_green\"\n\"constant.character.escape\" = \"electric_cyan\"\n\"constant.numeric\" = \"electric_yellow\"\n\"constructor\" = \"sky_blue\"\n\"diff.delta\" = \"sky_blue\"\n\"diff.minus\" = \"hot_pink\"\n\"diff.plus\" = \"lime_green\"\n\"function\" = \"sky_blue\"\n\"function.builtin\" = \"hot_magenta\"\n\"function.macro\" = \"electric_cyan\"\n\"keyword\" = \"hot_pink\"\n\"keyword.control\" = \"hot_magenta\"\n\"keyword.directive\" = \"hot_magenta\"\n\"label\" = \"sky_blue\"\n\"module\" = \"electric_yellow\"\n\"namespace\" = \"electric_yellow\"\n\"operator\" = \"hot_pink\"\n\"punctuation\" = \"bright_white\"\n\"punctuation.delimiter\" = \"bright_white\"\n\"special\" = \"electric_cyan\"\n\"string\" = \"lime_green\"\n\"string.regexp\" = \"electric_cyan\"\n\"tag\" = \"hot_pink\"\n\"type\" = \"electric_yellow\"\n\"type.builtin\" = \"hot_magenta\"\n\"type.enum.variant\" = \"electric_cyan\"\n\"variable\" = \"bright_white\"\n\"variable.builtin\" = \"hot_magenta\"\n\"variable.other.member\" = \"bright_white\"\n\"variable.parameter\" = \"neon_orange\"\n\n# MARKUP\n\"markup.heading\" = { fg = \"sky_blue\", modifiers = [\"bold\"] }\n\"markup.list\" = \"hot_pink\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"electric_cyan\", underline = { style = \"line\" } }\n\"markup.link.text\" = \"sky_blue\"\n\"markup.quote\" = \"electric_yellow\"\n\"markup.raw\" = \"neon_orange\"\n\n# UI INTERFACE\n\"ui.background\" = { bg = \"ultra_black\" }\n\"ui.cursor\" = { bg = \"electric_yellow\", fg = \"ultra_black\" }\n\"ui.cursor.primary\" = { bg = \"electric_yellow\", fg = \"ultra_black\" }\n\"ui.cursor.match\" = { bg = \"hot_magenta\", fg = \"ultra_black\" }\n\"ui.cursor.select\" = { bg = \"selection_purple\" }\n\"ui.cursorline.primary\" = { bg = \"darker_surface\" }\n\"ui.gutter\" = { bg = \"ultra_black\" }\n\"ui.gutter.selected\" = { bg = \"darker_surface\" }\n\"ui.linenr\" = \"darker_gray\"\n\"ui.linenr.selected\" = { fg = \"electric_yellow\", modifiers = [\"bold\"] }\n\"ui.menu\" = { fg = \"bright_white\", bg = \"darker_popup\" }\n\"ui.menu.selected\" = { fg = \"ultra_black\", bg = \"electric_cyan\" }\n\"ui.menu.scroll\" = { fg = \"bright_white\", bg = \"bright_gray\" }\n\"ui.popup\" = { fg = \"bright_white\", bg = \"darker_popup\" }\n\"ui.popup.info\" = { fg = \"electric_cyan\", bg = \"darker_popup\" }\n\"ui.selection\" = { bg = \"selection_purple\" }\n\"ui.selection.primary\" = { bg = \"selection_purple\" }\n\"ui.statusline\" = { fg = \"bright_white\", bg = \"darker_status\" }\n\"ui.statusline.inactive\" = { fg = \"bright_gray\", bg = \"darker_status\" }\n\"ui.statusline.normal\" = { fg = \"ultra_black\", bg = \"sky_blue\" }\n\"ui.statusline.insert\" = { fg = \"ultra_black\", bg = \"lime_green\" }\n\"ui.statusline.select\" = { fg = \"ultra_black\", bg = \"hot_magenta\" }\n\"ui.text\" = \"bright_white\"\n\"ui.text.focus\" = { fg = \"electric_yellow\", bg = \"darker_selection\", modifiers = [\"bold\"] }\n\"ui.virtual.indent-guide\" = \"darker_indent\"\n\"ui.virtual.inlay-hint\" = { fg = \"bright_gray\", bg = \"darker_hint\" }\n\"ui.virtual.jump-label\" = { fg = \"ultra_black\", bg = \"electric_yellow\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"darker_ruler\" }\n\"ui.virtual.whitespace\" = \"darker_whitespace\"\n\"ui.virtual.wrap\" = \"bright_gray\"\n\"ui.window\" = \"darker_border\"\n\"ui.help\" = { fg = \"bright_white\", bg = \"darker_popup\" }\n\n# DIAGNOSTICS\n\"error\" = \"hot_pink\"\n\"warning\" = \"electric_yellow\"\n\"info\" = \"sky_blue\"\n\"hint\" = \"electric_cyan\"\n\"diagnostic.error\" = { underline = { color = \"hot_pink\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"electric_yellow\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"sky_blue\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"electric_cyan\", style = \"curl\" } }\n\n[palette]\n# Vibrant colors with ORIGINAL OneDarker backgrounds\nultra_black = \"#16181A\"       # SAME as original OneDarker black\nbright_white = \"#d5dae6\"      # Enhanced white\nbright_gray = \"#b4bcc8\"       # Enhanced gray\ndarker_gray = \"#7a8590\"       # Enhanced medium gray\n\n# MORE vibrant OneDarker colors - increased saturation\nhot_pink = \"#ff5d8f\"          # More vibrant red (was #D05C65)\nlime_green = \"#5dd75d\"        # More vibrant green (was #7DA869)\nelectric_yellow = \"#e8d154\"   # More vibrant yellow (was #D5B06B)\nsky_blue = \"#2fa5f0\"          # More vibrant blue (was #519FDF)\nhot_magenta = \"#d147ff\"       # More vibrant purple (was #B668CD)\nelectric_cyan = \"#1abde0\"     # More vibrant cyan (was #46A6B2)\nneon_orange = \"#ff8f35\"       # More vibrant gold (same as OneDark: #D19A66)\n\n# UI backgrounds - SAME as original OneDarker\ndarker_surface = \"#2C323C\"    # SAME as original light-black\ndarker_popup = \"#12100E\"      # SAME as original dark-black\ndarker_status = \"#252D30\"     # SAME as original gray\nselection_purple = \"#d147ff\"  # Semi-transparent enhanced purple\ndarker_selection = \"#2C323C\"  # SAME as original light-black\ndarker_border = \"#252D30\"     # SAME as original gray\ndarker_indent = \"#2C323C\"     # SAME as original light-black\ndarker_hint = \"#2C323C\"       # SAME as original light-black\ndarker_ruler = \"#252D30\"      # SAME as original gray\ndarker_whitespace = \"#252D30\" # SAME as original gray\n"
  },
  {
    "path": "runtime/themes/onelight.toml",
    "content": "# Author : erasin<erasinoo@gmail.com>\n\n\"attribute\" = { fg = \"yellow\" }\n\"label\" = { fg = \"cyan\" }\n\"operator\" = { fg = \"red\" }\n\"tag\" = { fg = \"cyan\" }\n\"special\" = { fg = \"deep-purple\" }\n\"property\" = { fg = \"purple\" }\n\"constructor\" = { fg = \"blue\" }\n\"namespace\" = { fg = \"blue\" }\n\"module\" = { fg = \"blue\" }\n\n\"type\" = { fg = \"gold\" }\n\"type.builtin\" = { fg = \"yellow\" }\n\"type.enum\" = { fg = \"cyan\" }\n\"type.enum.variant\" = { fg = \"cyan\" }\n\n\"constant\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\"constant.builtin\" = { fg = \"deep-purple\" }\n\"constant.builtin.boolean\" = { fg = \"purple\" , modifiers = [\"bold\"]}\n\"constant.character\" = { fg = \"green\" }\n\"constant.character.escape\" = { fg = \"brown\" , modifiers = [\"bold\"]}\n\"constant.numeric\" = { fg = \"brown\" , modifiers = [\"bold\"]}\n\"constant.numeric.integer\" = { fg = \"brown\" , modifiers = [\"bold\"]}\n\"constant.numeric.float\" = { fg = \"brown\" , modifiers = [\"bold\"]}\n\n\"string\" = { fg = \"green\" }\n\"string.regexp\" = { fg = \"purple\" }\n\"string.special\" = { fg = \"green\" }\n\"string.special.path\" = { fg = \"blue\" }\n\"string.special.url\" = { fg = \"light-blue\" }\n\"string.special.symbol\" = { fg = \"pink\" }\n\n\"comment\" = { fg = \"grey\", modifiers = [\"italic\"] }\n\"comment.line\" = { fg = \"grey\", modifiers = [\"italic\"] }\n\"comment.line.documentation\" = { fg = \"grey\", modifiers = [\"italic\"] }\n\"comment.block\" = { fg = \"grey\", modifiers = [\"italic\"] }\n\"comment.block.documentation\" = { fg = \"grey\", modifiers = [\"italic\"] }\n\n# \"variable\" = { fg = \"black\" }\n\"variable.builtin\" = { fg = \"light-blue\" }\n\"variable.parameter\" = { fg = \"red\" }\n\"variable.other\" = { fg = \"pink\" }\n\"variable.other.member\" = { fg = \"pink\" }\n\n\"punctuation\" = { fg = \"black\" }\n\"punctuation.delimiter\" = { fg = \"purple\" }\n\"punctuation.bracket\" = { fg = \"brown\" }\n\"punctuation.special\" = { fg = \"brown\" }\n\n\"keyword\" = { fg = \"purple\" }\n\"keyword.control\" = { fg = \"purple\" }\n\"keyword.control.conditional\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"keyword.control.repeat\" = { fg = \"pink\", modifiers = [\"bold\"] }\n\"keyword.control.import\" = { fg = \"red\" }\n\"keyword.control.return\" = { fg = \"deep-purple\", modifiers = [\"bold\"] }\n\"keyword.control.exception\" = { fg = \"purple\" }\n\"keyword.operator\" = { fg = \"red\" }\n\"keyword.directive\" = { fg = \"deep-purple\" }\n\"keyword.function\" = { fg = \"purple\" }\n\"keyword.storage\" = { fg = \"purple\" }\n\"keyword.storage.type\" = { fg = \"purple\" }\n\"keyword.storage.modifier\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\n\"function\" = { fg = \"blue\" }\n\"function.builtin\" = { fg = \"cyan\" }\n\"function.method\" = { fg = \"light-blue\" }\n\"function.macro\" = { fg = \"pink\", modifiers = [\"bold\"] }\n\"function.special\" = { fg = \"cyan\" }\n\n\"markup.heading\" = { fg = \"red\" }\n\"markup.heading.marker\" = { fg = \"red\" }\n\"markup.heading.1\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"gold\", modifiers = [\n  \"bold\",\n], underline = { style = \"line\" } }\n\"markup.heading.3\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\"markup.list\" = { fg = \"light-blue\" }\n\"markup.list.unnumbered\" = { fg = \"light-blue\" }\n\"markup.list.numbered\" = { fg = \"light-blue\" }\n\"markup.list.checked\" = { fg = \"green\" }\n\"markup.list.unchecked\" = { fg = \"blue\" }\n\"markup.bold\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { fg = \"red\", modifiers = [\"crossed_out\"] }\n\"markup.link\" = { fg = \"light-blue\" }\n\"markup.link.url\" = { fg = \"cyan\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"light-blue\" }\n\"markup.quote\" = { fg = \"grey\" }\n\"markup.raw\" = { fg = \"brown\" }\n\"markup.raw.inline\" = { fg = \"green\" }\n\"markup.raw.block\" = { fg = \"brown\" }\n\n\"diff\" = { fg = \"red\" }\n\"diff.plus\" = { fg = \"green\" }\n\"diff.minus\" = { fg = \"red\" }\n\"diff.delta\" = { fg = \"cyan\" }\n\"diff.delta.moved\" = { fg = \"cyan\" }\n\"diff.delta.conflict\" = {fg = \"blue\"}\n\n\"ui.background\" = { bg = \"white\" }\n\"ui.background.separator\" = { bg = \"white\" }\n\n\"ui.cursor\" = { fg = \"white\", bg = \"grey\" }\n\"ui.cursor.normal\" = { fg = \"white\", bg = \"grey\" }\n\"ui.cursor.insert\" = { fg = \"white\", bg = \"grey\" }\n\"ui.cursor.select\" = { fg = \"white\", bg = \"grey\" }\n\"ui.cursor.match\" = { bg = \"grey-300\", modifiers = [\"bold\"] }\n\"ui.cursor.primary\" = { fg = \"white\", bg = \"black\" }\n\"ui.cursor.primary.normal\" = { fg = \"white\", bg = \"black\" }\n\"ui.cursor.primary.insert\" = { fg = \"red\", bg = \"black\" }\n\"ui.cursor.primary.select\" = { fg = \"white\", bg = \"black\" }\n\n\"ui.gutter\" = { fg = \"grey-500\" }\n\"ui.gutter.selected\" = { fg = \"black\" }\n\n\"ui.linenr\" = { fg = \"grey-500\" }\n\"ui.linenr.selected\" = { fg = \"black\", modifiers = [\"bold\"] }\n\n\"ui.statusline\" = { fg = \"black\", bg = \"grey-300\" }\n\"ui.statusline.inactive\" = { fg = \"grey\", bg = \"grey-200\" }\n\"ui.statusline.normal\" = { fg = \"grey-300\", bg = \"light-blue\" }\n\"ui.statusline.insert\" = { fg = \"grey-300\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"grey-300\", bg = \"purple\" }\n\n\"ui.popup\" = { fg = \"black\", bg = \"grey-200\" }\n\"ui.popup.info\" = { fg = \"black\", bg = \"grey-200\" }\n\"ui.window\" = { fg = \"grey-500\", bg = \"grey-100\" }\n\"ui.help\" = { fg = \"black\", bg = \"grey-200\" }\n\n\"ui.text\" = { fg = \"black\" }\n\"ui.text.focus\" = { fg = \"red\", bg = \"grey-300\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = { fg = \"grey\" }\n\"ui.text.info\" = { fg = \"black\" }\n\"ui.text.directory\" = { fg = \"blue\", underline = { style = \"line\" } }\n\n\"ui.virtual\" = { fg = \"grey-500\" }\n\"ui.virtual.ruler\" = { bg = \"grey-200\" }\n\"ui.virtual.wrap\" = { fg = \"grey-500\" }\n\"ui.virtual.whitespace\" = { fg = \"grey-400\" }\n\"ui.virtual.indent-guide\" = { fg = \"grey-500\" }\n\"ui.virtual.inlay-hint\" = { fg = \"grey-500\" }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"grey-500\", modifiers = [\"italic\"] }\n\"ui.virtual.inlay-hint.type\" = { fg = \"grey-500\" }\n\"ui.virtual.jump-label\" = { fg = \"black\", bg = \"grey-200\", modifiers = [\"bold\" ] }\n\n\"ui.menu\" = { fg = \"black\", bg = \"grey-300\" }\n\"ui.menu.selected\" = { fg = \"white\", bg = \"light-blue\" }\n\"ui.menu.scroll\" = { fg = \"light-blue\", bg = \"white\" }\n\n\"ui.selection\" = { bg = \"grey-300\", modifiers = [\"dim\"] }\n\"ui.selection.primary\" = { bg = \"grey-300\" }\n\n\"ui.cursorline.primary\" = { fg = \"white\", bg = \"grey-100\" }\n\"ui.cursorline.secondary\" = { fg = \"white\", bg = \"grey-200\" }\n\n\"ui.cursorcolumn.primary\" = { fg = \"white\", bg = \"grey-100\" }\n\"ui.cursorcolumn.secondary\" = { fg = \"white\", bg = \"grey-200\" }\n\n\"ui.highlight\" = { bg = \"grey-300\" }\n\n\"ui.picker.header\" = { fg = \"purple\"}\n\"ui.picker.header.column.active\" = { fg = \"blue\"}\n\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"dotted\" } }\n\"diagnostic.hint\" = { underline = { color = \"green\", style = \"dashed\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"info\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"warning\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"tabstop\" = { modifiers = [\"italic\"], bg = \"grey-300\" }\n\n[palette]\nwhite = \"#FAFAFA\"\nyellow = \"#FF6F00\"\ngold = \"#D35400\"\nbrown = \"#795548\"\nblue = \"#0061FF\"\nlight-blue = \"#0091EA\"\nred = \"#D50000\"\npink = \"#C2185B\"\npurple = \"#B500A9\"\ndeep-purple = \"#651FFF\"\ngreen = \"#24A443\"\ncyan = \"#0086C1\"\nblack = \"#282C34\"\ngrey = \"#5C6370\"\ngrey-500 = \"#9E9E9E\"\ngrey-400 = \"#BDBDBD\"\ngrey-300 = \"#E0E0E0\"\ngrey-200 = \"#EEEEEE\"\ngrey-100 = \"#F2F2F2\"\n"
  },
  {
    "path": "runtime/themes/papercolor-dark.toml",
    "content": "# Palette based on https://github.com/NLKNguyen/papercolor-theme\n# Author: Soc Virnyl Estela <socvirnyl.estela@gmail.com>\n\ninherits = \"papercolor-light\"\n\n[palette]\nbackground = \"#1c1c1c\"\nforeground = \"#d0d0d0\"\n\nregular0 = \"#1c1c1c\" # color00 \"Background\"\nregular1 = \"#af005f\" # color01 \"Negative\"\nregular2 = \"#5faf00\" # color02 \"Positive\"\nregular3 = \"#d7af5f\" # color03 \"Olive\"\nregular4 = \"#5fafd7\" # color04 \"Neutral\" / Aqua\nregular5 = \"#808080\" # color05 \"Comment\"\nregular6 = \"#d7875f\" # color06 \"Navy\"\nregular7 = \"#d0d0d0\" # color07 \"Foreground\"\nbright0 = \"#585858\"  # color08 \"Nontext\"\nbright1 = \"#5faf5f\"  # color09 \"Red\"\nbright2 = \"#afd700\"  # color10 \"Pink\"\nbright3 = \"#af87d7\"  # color11 \"Purple\"\nbright4 = \"#ffaf00\"  # color12 \"Accent\"\nbright5 = \"#ff5faf\"  # color13 \"Orange\"\nbright6 = \"#00afaf\"  # color14 \"Blue\"\nbright7 = \"#5f8787\"  # color15 \"Highlight\"\n\nselection_fg = \"#000000\"\nselection_bg = \"#8787af\"\nselection_secondary_fg = \"#333333\"\nselection_secondary_bg = \"#707097\"\nspecial = \"#3e999f\"\n\ncursorline_bg = \"#303030\"\ncursorline_secondary_bg = \"#2a2a2a\"\ncursorcolumn_bg = \"#303030\"\ncursorcolumn_secondary_bg = \"#2a2a2a\"\ncursorlinenr_fg = \"#ffff00\"\npopupmenu_fg = \"#c6c6c6\"\npopupmenu_bg = \"#303030\"\nlinenumber_fg = \"#585858\"\nvertsplit_fg = \"#5f8787\"\nstatusline_active_fg = \"#1c1c1c\"\nstatusline_active_bg = \"#5f8787\"\nstatusline_inactive_fg = \"#bcbcbc\"\nstatusline_inactive_bg = \"#3a3a3a\"\ntodo_fg = \"#ff8700\"\nerror_fg = \"#af005f\"\nerror_bg = \"#5f0000\"\nmatchparen_bg = \"#4e4e4e\"\nmatchparen_fg = \"#c6c6c6\"\nwildmenu_fg = \"#1c1c1c\"\nwildmenu_bg = \"#afd700\"\ndiffadd_fg = \"#87d700\"\ndiffadd_bg = \"#005f00\"\ndiffdelete_fg = \"#af005f\"\ndiffdelete_bg = \"#5f0000\"\ndiffchange_bg = \"#005f5f\"\n\n# 16 bit ANSI color names\nblack = \"#1c1c1c\"\nred = \"#af005f\"\ngreen = \"#5faf00\"\nyellow = \"#d7af5f\"\nblue = \"#5fafd7\"\nmagenta = \"#808080\"\ncyan = \"#d7875f\"\nwhite = \"#d0d0d0\"\nlight-black = \"#585858\"\nlight-red = \"#5faf5f\"\nlight-green = \"#afd700\"\nlight-yellow = \"#af87d7\"\nlight-blue = \"#ffaf00\"\nlight-magenta = \"#ff5faf\"\nlight-cyan = \"#00afaf\"\nlight-white = \"#5f8787\"\n"
  },
  {
    "path": "runtime/themes/papercolor-light.toml",
    "content": "# Palette based on https://github.com/NLKNguyen/papercolor-theme\n# Author: Soc Virnyl Estela <socvirnyl.estela@gmail.com>\n\n\"ui.linenr.selected\" = { fg = \"cursorlinenr_fg\", modifiers = [\"bold\"] }\n\"ui.linenr\" = { fg = \"linenumber_fg\" }\n\"ui.background\" = { bg = \"background\" }\n\"ui.text\" = \"foreground\"\n\"ui.text.focus\" = { fg = \"selection_bg\", modifiers = [\"bold\"] }\n\"ui.selection\" = { bg = \"selection_secondary_bg\", fg = \"selection_secondary_fg\" }\n\"ui.selection.primary\" = { bg = \"selection_bg\", fg = \"selection_fg\" }\n\"ui.highlight\" = { bg = \"cursorline_bg\" }\n\n\"ui.cursorline\" = { bg = \"cursorline_bg\" }\n\"ui.cursorline.secondary\" = { bg = \"cursorline_secondary_bg\" }\n\"ui.cursorcolumn\" = { bg = \"cursorline_bg\" }\n\"ui.cursorcolumn.secondary\" = { bg = \"cursorcolumn_secondary_bg\" }\n\n\"ui.statusline\" = { bg = \"statusline_active_bg\", fg = \"statusline_active_fg\" }\n\"ui.statusline.inactive\" = { bg = \"statusline_inactive_bg\", fg = \"statusline_inactive_fg\" }\n\"ui.statusline.normal\" = { bg = \"statusline_inactive_bg\", fg = \"bright6\" }\n\"ui.statusline.insert\" = { bg = \"statusline_inactive_bg\", fg = \"bright4\" }\n\"ui.statusline.select\" = { bg = \"statusline_inactive_bg\", fg = \"regular3\" }\n\"ui.statusline.separator\" = { bg = \"statusline_active_bg\", fg = \"statusline_active_bg\" }\n\n\"ui.virtual\" = { fg = \"cursorlinenr_fg\" }\n\"ui.virtual.whitespace\" = { fg = \"regular5\" }\n\"ui.virtual.indent-guide\" = { fg = \"bright0\" }\n\"ui.virtual.ruler\" = { bg = \"cursorline_secondary_bg\", fg = \"regular4\" }\n\"ui.virtual.inlay-hint\" = { fg = \"regular5\", modifiers = [\"italic\"] }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"regular5\", modifiers = [\"italic\"] }\n\"ui.virtual.inlay-hint.type\" = { fg = \"regular5\", modifiers = [\"bold\", \"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"bright1\", modifiers = [\"bold\"] }  \n\"ui.cursor.match\" = { bg = \"matchparen_bg\", fg = \"matchparen_fg\" }\n\"ui.cursor\" = { bg = \"regular5\", fg = \"background\" }\n\"ui.cursor.primary\" = { bg = \"foreground\", fg = \"background\" }\n\"ui.window\" = { fg = \"vertsplit_fg\" }\n\"ui.help\" = { bg = \"wildmenu_bg\", fg = \"wildmenu_fg\" }\n\"ui.popup\" = { bg = \"popupmenu_bg\", fg = \"popupmenu_fg\" }\n\"ui.popup.info\" = { bg = \"popupmenu_bg\", fg = \"bright7\", modifiers = [\"bold\"] }\n\"ui.menu\" = { bg = \"popupmenu_bg\", fg = \"foreground\" }\n\"ui.menu.selected\" = { bg = \"selection_bg\", fg = \"selection_fg\" }\n\n\"warning\" = \"bright4\"\n\"hint\" = \"bright6\"\n\"error\" = { bg = \"error_bg\", fg = \"error_fg\" }\n\"info\" = \"todo_fg\"\n\n\"diagnostic.warning\" = { fg = \"bright0\", modifiers = [\n  \"dim\",\n], underline = { color = \"bright5\", style = \"curl\" } }\n\"diagnostic.error\".underline = { color = \"bright1\", style = \"curl\" }\n\"diagnostic.info\".underline = { color = \"bright4\", style = \"curl\" }\n\"diagnostic.hint\".underline = { color = \"bright6\", style = \"curl\" }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n# Tree-sitter scopes for syntax highlighting\n\"attribute\" = \"bright4\"\n\n\"type\" = { fg = \"bright2\", modifiers = [\"bold\"] }\n\"type.builtin\" = { fg = \"bright2\", modifiers = [\"bold\"] }\n\"type.parameter\" = { fg = \"foreground\" }\n\"type.enum\" = { fg = \"foreground\" }\n\"type.enum.variant\" = { fg = \"foreground\" }\n\n\"constructor\" = \"foreground\"\n\n\"constant\" = \"bright5\"\n\"constant.builtin\" = \"regular3\"\n\"constant.builtin.boolean\" = { fg = \"regular2\", modifiers = [\"bold\"] }\n\"constant.character.escape\" = { fg = \"bright3\", modifiers = [\"bold\"] }\n\"constant.character\" = { fg = \"regular3\" }\n\"constant.numeric\" = \"bright5\"\n\n\"string\" = \"regular3\"\n\"string.regexp\" = \"bright3\"\n\n\"comment\" = { fg = \"regular5\", modifiers = [\"italic\"] }\n\"comment.line\" = { fg = \"regular5\", modifiers = [\"italic\"] }\n\"comment.line.documentation\" = { fg = \"regular5\", modifiers = [\"bold\"] }\n\"comment.block\" = { fg = \"regular5\", modifiers = [\"italic\"] }\n\"comment.block.documentation\" = { fg = \"regular5\", modifiers = [\"bold\"] }\n\n\"variable\" = \"foreground\"\n\"variable.builtin\" = \"bright5\"\n\"variable.other.member\" = \"foreground\"\n\"variable.parameter\" = \"foreground\"\n\n\"label\" = { fg = \"selection_bg\", modifiers = [\"bold\", \"italic\"] }\n\n\"punctuation\" = { fg = \"foreground\" }\n\"punctuation.delimiter\" = { fg = \"regular4\", modifiers = [\"bold\"] }\n\"punctuation.bracket\" = { fg = \"foreground\" }\n\"punctuation.special\" = { fg = \"bright1\", modifiers = [\"bold\"] }\n\n\"keyword\" = { fg = \"bright2\" }\n\"keyword.control\" = \"bright1\"\n\"keyword.control.conditional\" = { fg = \"bright3\", modifiers = [\"bold\"] }\n\"keyword.control.repeat\" = { fg = \"bright3\", modifiers = [\"bold\"] }\n\"keyword.control.import\" = { fg = \"bright2\" }\n\"keyword.control.return\" = { fg = \"bright2\" }\n\"keyword.control.exception\" = { fg = \"bright1\" }\n\n\"keyword.operator\" = { fg = \"regular4\", modifiers = [\"bold\"] }\n\"keyword.directive\" = \"regular4\"\n\"keyword.function\" = \"bright2\"\n\"keyword.storage\" = \"bright2\"\n\"keyword.storage.type\" = { fg = \"regular4\", modifiers = [\"bold\"] }\n\"keyword.storage.modifier\" = { fg = \"regular6\", modifiers = [\"bold\"] }\n\"keyword.storage.modifier.ref\" = { fg = \"regular4\", modifiers = [\"bold\"] }\n\"keyword.special\" = \"bright1\"\n\n\"operator\" = { fg = \"regular4\", modifiers = [\"bold\"] }\n\n\"function\" = { fg = \"foreground\" }\n\"function.builtin\" = { fg = \"bright6\" }\n\"function.method\" = { fg = \"foreground\" }\n\"function.macro\" = { fg = \"regular3\", modifiers = [\"bold\"] }\n\"function.special\" = { fg = \"bright4\" }\n\n\"tag\" = { fg = \"regular4\" }\n\n\"namespace\" = \"bright6\"\n\n\"special\" = \"special\"\n\n\"markup.heading\" = { fg = \"bright4\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = { fg = \"bright2\", modifiers = [\"bold\"] }\n\"markup.heading.1\" = { fg = \"bright2\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"bright5\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"bright3\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"bright4\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"bright4\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"bright4\", modifiers = [\"bold\"] }\n\"markup.list\" = \"regular4\"\n\"markup.bold\" = { fg = \"foreground\", modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"bright6\", underline.style = \"line\" }\n\"markup.link.text\" = \"bright2\"\n\"markup.link.label\" = { fg = \"regular2\", modifiers = [\"bold\"] }\n\"markup.quote\" = \"regular4\"\n# Both inline and block code\n\"markup.raw\" = \"regular3\"\n\n\"diff.plus\" = { bg = \"diffadd_bg\", fg = \"diffadd_fg\" }\n\"diff.delta\" = { bg = \"diffchange_bg\" }\n\"diff.delta.moved\" = { modifiers = [\"italic\"] }\n\"diff.minus\" = { bg = \"diffdelete_bg\", fg = \"diffdelete_fg\" }\n\n[palette]\nbackground = \"#eeeeee\"\nforeground = \"#444444\"\nregular0 = \"#eeeeee\"   # color00 \"Background\"\nregular1 = \"#af0000\"   # color01 \"Negative\"\nregular2 = \"#008700\"   # color02 \"Positive\"\nregular3 = \"#5f8700\"   # color03 \"Olve\"\nregular4 = \"#0087af\"   # color04 \"Neutral\" / Aqua\nregular5 = \"#878787\"   # color05 \"Comment\"\nregular6 = \"#005f87\"   # color06 \"Navy\"\nregular7 = \"#444444\"   # color07 \"Foreground\"\nbright0 = \"#bcbcbc\"    # color08 \"Nontext\"\nbright1 = \"#d70000\"    # color09 \"Red\"\nbright2 = \"#d70087\"    # color10 \"Pink\"\nbright3 = \"#8700af\"    # color11 \"Purple\"\nbright4 = \"#d75f00\"    # color12 \"Accent\"\nbright5 = \"#d75f00\"    # color13 \"Orange\"\nbright6 = \"#005faf\"    # color14 \"Blue\"\nbright7 = \"#005f87\"    # color15 \"Highlight\"\n\nselection_fg = \"#eeeeee\"\nselection_bg = \"#0087af\"\nselection_secondary_fg = \"#d9d7d7\"\nselection_secondary_bg = \"#2c687a\"\nspecial = \"#3e999f\"\n\ncursorline_bg = \"#e4e4e4\"\ncursorline_secondary_bg = \"#eaeaea\"\ncursorcolumn_bg = \"#e4e4e4\"\ncursorcolumn_secondary_bg = \"#eaeaea\"\ncursorlinenr_fg = \"#af5f00\"\npopupmenu_fg = \"#444444\"\npopupmenu_bg = \"#d0d0d0\"\nlinenumber_fg = \"#b2b2b2\"\nvertsplit_fg = \"#005f87\"\nstatusline_active_fg = \"#e4e4e4\"\nstatusline_active_bg = \"#005f87\"\nstatusline_inactive_fg = \"#444444\"\nstatusline_inactive_bg = \"#d0d0d0\"\ntodo_fg = \"#00af5f\"\nerror_fg = \"#af0000\"\nerror_bg = \"#ffd7ff\"\nmatchparen_bg = \"#c6c6c6\"\nmatchparen_fg = \"#005f87\"\nwildmenu_fg = \"#444444\"\nwildmenu_bg = \"#ffff00\"\ndiffadd_fg = \"#008700\"\ndiffadd_bg = \"#afffaf\"\ndiffdelete_fg = \"#af0000\"\ndiffdelete_bg = \"#ffd7ff\"\ndiffchange_bg = \"#ffd787\"\n\n# 16 bit ANSI color names\nblack = \"#eeeeee\"\nred = \"#d70000\"\ngreen = \"#008700\"\nyellow = \"#5f8700\"\nblue = \"#0087af\"\nmagenta = \"#878787\"\ncyan = \"#005f87\"\nwhite = \"#444444\"\nlight-black = \"#bcbcbc\"\nlight-red = \"#d70000\"\nlight-green = \"#d70087\"\nlight-yellow = \"#8700af\"\nlight-blue = \"#d75f00\"\nlight-magenta = \"#d75f00\"\nlight-cyan = \"#4c7a4d\"\nlight-white = \"#005faf\"\n"
  },
  {
    "path": "runtime/themes/peachpuff.toml",
    "content": "# Author : geonove <andre.novellini@gmail.com>\n# License : Vim License\n\n\"ui.menu\" = { fg = \"light-gray\", bg = \"gray\" }\n\"ui.menu.selected\" = { modifiers = [\"reversed\"] }\n\"ui.linenr\" = \"yellow\"\n\"ui.popup\" = { bg = \"black\" }\n\"ui.window\" = { bg = \"black\" }\n\"ui.linenr.selected\" = \"light-yellow\"\n\"ui.selection\" = { fg = \"gray\", modifiers = [\"reversed\"] }\n\"ui.text.focus\" = { fg = \"black\", bg = \"white\" }\n\"comment\" = \"light-green\"\n\"comment.line\" = \"light-green\"\n\"comment.line.documentation\" = \"light-green\"\n\"comment.block\" = \"red\"\n\"comment.block.documentation\" = \"red\"\n\"ui.statusline\" = { fg = \"black\", bg = \"light-cyan\" }\n\"ui.statusline.inactive\" = { fg = \"gray\", bg = \"black\" }\n\"ui.help\" = { fg = \"white\", bg = \"black\" }\n\"ui.cursor\" = { fg = \"light-gray\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"light-gray\", modifiers = [\"reversed\"] }\n\"ui.virtual.whitespace\" = \"light-gray\"\n\"ui.virtual.jump-label\" = { fg = \"blue\", modifiers = [\"bold\", \"underlined\"] }\n\"ui.virtual.ruler\" = { bg = \"black\" }\n\"variable\" = \"white\"\n\"constant.numeric\" = \"red\"\n\"constant\" = \"white\"\n\"constant.builtin\" = \"red\"\n\"attribute\" = \"yellow\"\n\"type\" = \"green\"\n\"type.builtin\" = \"cyan\"\n\"ui.cursor.match\" = { fg = \"light-gray\", modifiers = [\"reversed\"] }\n\"string\"  = \"red\"\n\"variable.other.member\" = \"white\"\n\"constant.character.escape\" = \"light-cyan\"\n#\"function.builtin\" = \"cyan\"\n#\"function.method\" = \"cyan\"\n#\"function.method.private\" = \"cyan\"\n\"function\" = \"cyan\"\n\"constructor\" = \"cyan\"\n\"special\" = \"light-blue\"\n\"keyword\" = \"yellow\"\n\"keyword.control.import\" = \"magenta\"\n\"label\" = \"white\"\n\"namespace\" = \"white\"\n\n\"markup.heading\" = \"light-magenta\"\n\"markup.list\" = \"light-red\"\n\"markup.bold\" = { fg = \"light-yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"light-magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"light-red\"\n\"markup.quote\" = \"light-cyan\"\n\"markup.raw\" = \"light-green\"\n\n\"diff.plus\" = \"light-green\"\n\"diff.delta\" = \"yellow\"\n\"diff.minus\" = \"light-red\"\n\n\"diagnostic\" = { modifiers = [\"underlined\"] }\n\"info\" = \"light-blue\"\n\"hint\" = \"gray\"\n\"debug\" = \"gray\"\n\"warning\" = \"yellow\"\n\"error\" = \"light-red\"\n"
  },
  {
    "path": "runtime/themes/penumbra+.toml",
    "content": "##########\n# SYNTAX #\n##########\n\ncomment = \"sky-\"\n\ntype = \"green\"\n\"type.enum.variant\" = \"green\"\nlabel = \"blue\"\ntag = \"blue\"\n\nconstant = \"purple\"\n\"constant.numeric\" = \"cyan\"\n\"constant.character\" = \"purple\"\n\nstring = \"yellow\"\n\"string.special.symbol\" = \"cyan\"\n\"string.special.path\" = \"cyan\"\n\nvariable = \"sky\"\n\"variable.builtin\" = \"red\"\n\nkeyword = \"magenta\"\n\nfunction = \"blue\"\n\"function.macro\" = \"purple\"\n\npunctuation = \"sky\"\noperator = \"magenta\"\nnamespace = \"sky\"\n\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"cyan\"\n\n\n##########\n#   UI   #\n##########\n\nhint = \"sky-\"\ninfo = \"sky\"\nwarning = \"yellow\"\nerror = \"red\"\n\n\"diagnostic.hint\".underline = { color = \"sky-\", style = \"curl\" } \n\"diagnostic.info\".underline = { color = \"sky\", style = \"curl\" } \n\"diagnostic.warning\".underline = { color = \"yellow\", style = \"curl\" } \n\"diagnostic.error\".underline = { color = \"red\", style = \"curl\" } \n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"ui.background\" = { bg = \"shade\" }\n\"ui.background.separator\" = \"sky\"\n\n\"ui.cursor\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { bg = \"shade+\" }\n\n\"ui.cursorline.primary\" = { bg = \"shade-\" }\n# \"ui.cursorline.secondary\" = { bg = \"shade+\" }\n\n\"ui.linenr\" = \"sky-\"\n\"ui.linenr.selected\" = \"sky\"\n\n# Using themed status line:\n\"ui.statusline\" = { fg = \"shade\", bg = \"sky\" }\n\"ui.statusline.inactive\" = { fg = \"sky\", bg = \"shade+\" }\n\"ui.statusline.normal\" = { fg = \"shade\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"shade\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"shade\", bg = \"purple\" }\n\n# Without themed status line:\n# \"ui.statusline\" = { fg = \"shade-\", bg = \"blue\" }\n# \"ui.statusline.inactive\" = { fg = \"sky\", bg = \"shade+\" }\n\n\"ui.popup\" = { bg = \"shade-\" }\n\"ui.popup.info\" = { bg = \"shade\" }\n\n\"ui.window\" = \"sky\"\n\"ui.help\" = { fg = \"sky\", bg = \"shade-\" }\n\n\"ui.text\" = \"sky\"\n\"ui.text.focus\" = \"blue\"\n\"ui.text.info\" = \"sky\"\n\n\"ui.virtual.ruler\" = { bg = \"shade-\" }\n\"ui.virtual.whitespace\" = \"sky-\"\n\"ui.virtual.indent-guide\" = \"shade+\"\n\n\"ui.menu\" = { fg = \"sky\", bg = \"shade-\" }\n\"ui.menu.selected\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"ui.menu.scroll\" = { fg = \"sky\", bg = \"shade+\" }\n\n\"ui.selection\" = { bg = \"shade+\" }\n\n\"markup.heading\" = { fg = \"sky+\", modifiers = [\"bold\"] }\n\"markup.list\" = \"sky\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"magenta\"\n\"markup.quote\" = \"green\"\n\"markup.raw\" = \"orange\"\n\n\n[palette]\n\n# contrast+ accents\nred = \"#DF7F78\"\norange = \"#CE9042\"\nyellow = \"#9CA748\"\ngreen = \"#50B584\"\ncyan = \"#00B3C2\"\nblue = \"#61A3E6\"\npurple = \"#A48FE1\"\nmagenta = \"#D080B6\"\n\n# contrast+ base\n\"sun+\" = \"#FFFDFB\"\n\"sun\" = \"#FFF7ED\"\n\"sun-\" = \"#F2E6D4\"\n\"sky+\" = \"#CECECE\"\n\"sky\" = \"#9E9E9E\"\n\"sky-\" = \"#636363\"\n\"shade+\" = \"#3E4044\"\n\"shade\" = \"#24272B\"\n\"shade-\" = \"#181B1F\""
  },
  {
    "path": "runtime/themes/poimandres.toml",
    "content": "# Author: Ambuj Kumar <ambujs89@gmail.com>\n# Ported from: https://github.com/drcmda/poimandres-theme\n\nattribute = { fg = \"desaturatedBlue\", modifiers = [\"italic\"] }\nkeyword = \"brightMint\"\n\"keyword.directive\" = \"gray\"\n\"keyword.storage.type\" = \"desaturatedBlue\"\n\"keyword.storage.modifier\" = \"lowerMint\"\n\"keyword.other\" = \"brightMint\"\n\"keyword.operator\" = \"desaturatedBlue\"\nnamespace = \"lightBlue\"\npunctuation = \"gray\"\n\"punctuation.bracket\" = \"desaturatedBlue\"\noperator = \"desaturatedBlue\"\nspecial = \"desaturatedBlue\"\nvariable = \"offWhite\"\n\"variable.parameter\" = { fg = \"offWhite\" }\n\"variable.builtin\" = { fg = \"lightBlue\", modifiers = [\"italic\"] }\n\"variable.other\" = \"offWhite\"\ntype = { fg = \"gray.c0\" }\n\"type.builtin\" = { fg = \"desaturatedBlue\" }\nconstructor = \"lightBlue\"\nfunction = \"lightBlue\"\n\"function.method\" = { fg = \"lightBlue\" }\ntag = \"brightMint\"\ncomment = { fg = \"darkerGray.b0\", modifiers = [\"italic\"] }\nconstant = \"brightMint\"\n\"constant.character.escape\" = { fg = \"offWhite\" }\n\"constant.numeric\" = { fg = \"brightMint\" }\n\"constant.builtin\" = { fg = \"hotRed\" }\nlabel = { fg = \"gray.c0\" }\nstring = { fg = \"brightMint\" }\n\n# Markup\n\"markup.heading\" = { fg = \"brightMint\" }\n\"markup.bold\" = { fg = \"bluishGrayBrighter\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"bluishGrayBrighter\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"italic\", \"crossed_out\"] }\n\n# UI\n\"markup.link.url\" = { fg = \"lightBlue\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"lightBlue\", modifiers = [\"underlined\"] }\n\"markup.raw\" = { fg = \"lightBlue\" }\n\n\"ui.background\" = { bg = \"bg\" }\n\"ui.background.separator\" = { fg = \"darkerGray\" }\n\"ui.linenr\" = \"darkerGray.50\"\n\"ui.linenr.selected\" = \"offWhite\"\n\"ui.cursor\" = { bg = \"gray\", fg = \"bg\" }\n\"ui.cursor.match\" = { bg = \"focus\" }\n\"ui.cursorline\" = { bg = \"#242837\" }\n\n\"ui.help\" = { bg = \"#20232d\" }\n\"ui.popup\" = { bg = \"#20232d\" }\n\"ui.window\" = \"gray\"\n\n\"ui.text\" = \"gray\"\n\"ui.text.focus\" = { fg = \"offWhite\", bg = \"focus\", modifiers = [\"bold\"] }\n\"ui.text.inactive\" = \"darkerGray\"\n\"ui.virtual\" = { fg = \"darkerGray.b0\" }\n\"ui.virtual.indent-guide\" = \"#303442\"\n\"ui.virtual.ruler\" = { bg =\"selection\" }\n\n\"ui.selection\" = { bg = \"focus\" }\n\"ui.selection.primary\" = { bg = \"selection\" }\n\n\"ui.menu\" = { fg = \"offWhite\", bg = \"bg\" }\n\"ui.menu.selected\" = { fg = \"bg\", bg = \"gray\" }\n\"ui.menu.scroll\" = { fg = \"gray\", bg = \"bg\" }\n\n\"ui.statusline\" = { fg = \"offWhite\", bg = \"selection\" }\n\"ui.statusline.inactive\" = { fg = \"lightBlue\", bg = \"bg\" }\n\"ui.statusline.normal\" = { bg = \"lightBlue\", fg = \"bg\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { bg = \"brightMint\", fg = \"bg\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { bg = \"hotRed\", fg = \"bg\", modifiers = [\"bold\"] }\n\n\"diagnostic.hint\" = { underline = { color = \"lowerMint\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"lightBlue\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"brightYellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"hotRed\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nhint = \"lowerMint\"\ninfo = \"lightBlue\"\nwarning = \"brightYellow\"\nerror = \"hotRed\"\n\n# Version Control\n\"diff.plus\" = \"lowerMint\"\n\"diff.minus\" = \"hotRed\"\n\"diff.delta\" = \"lightBlue\"\n\n[palette]\nbrightYellow = \"#fffac2\"\nbrightMint = \"#5DE4c7\"\nlowerMint = \"#5fb3a1\"\nblueishGreen = \"#42675A\"\nlowerBlue = \"#89ddff\"\nlightBlue = \"#ADD7FF\"\ndesaturatedBlue = \"#91B4D5\"\nbluishGrayBrighter = \"#7390AA\"\nhotRed = \"#d0679d\"\npink = \"#f087bd\"\ngray = \"#a6accd\"\n\"gray.c0\" = \"#98a0c2\"\ndarkerGray = \"#767c9d\"\n\"darkerGray.50\" = \"#404559\"\n\"darkerGray.b0\" = \"#6c7494\"\nbluishGray = \"#506477\"\nfocus = \"#303340\"\nbg = \"#1b1e28\"\noffWhite = \"#e4f0fb\"\nselection = \"#30354a\"\nwhite = \"#ffffff\"\nblack = \"#000000\"\ntransparent = \"#000000\"\n"
  },
  {
    "path": "runtime/themes/poimandres_storm.toml",
    "content": "# Author: Ambuj Kumar <ambujs89@gmail.com>\n# Ported from: https://github.com/drcmda/poimandres-theme\n\ninherits = \"poimandres\"\n\n\"ui.cursorline\" = { bg = \"#303747\" }\n\"ui.help\" = { bg = \"#2a303c\" }\n\"ui.popup\" = { bg = \"#2a303c\" }\n\"ui.virtual.indent-guide\" = \"#3a4151\"\n\n[palette]\n\"gray.c0\" = \"#98a2c4\"\ndarkerGray = \"#868cad\"\n\"darkerGray.50\" = \"#4f576d\"\n\"darkerGray.b0\" = \"#818cae\"\nbluishGray = \"#607487\"\nfocus = \"#404350\"\nbg = \"#252b37\"\nselection = \"#3d455c\"\nblack = \"#101010\"\n"
  },
  {
    "path": "runtime/themes/pop-dark.toml",
    "content": "# Pop Dark theme for the Helix Editor\n# Author: workingj<workingj@pm.me>\n# Repo: https://github.com/workingJ/helix-pop-theme\n# Version: 1.0\n# This theme is based on Nathaniel Webb's VSCodePopTheme <https://github.com/ArtisanByteCrafter/VSCodePopTheme>\n\ninfo = { fg = 'brownD' }\nhint = { fg = 'yellowH', modifiers = ['bold'] }\nwarning = { fg = 'orangeW', modifiers = ['bold'] }\nerror = { fg = 'redE', modifiers = ['bold'] }\n'diagnostic.info'.underline = { color = 'yellowH', style = 'curl' } \n'diagnostic.hint'.underline = { color = 'yellowH', style = 'curl' } \n'diagnostic.warning'.underline = { color = 'orangeW', style = 'curl' } \n'diagnostic.error'.underline = { color = 'redE', style = 'curl' } \n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n'ui.background' = { bg = 'brownN' }\n'ui.window' = { bg = 'brownH', fg = 'brownD' } \n'ui.gutter' = { bg = 'brownU' }\n'ui.text' = { fg = 'greyT' }\n'ui.text.focus' = { fg = 'orangeN' }\n'ui.text.info' = { fg = 'orangeH', bg = 'brownH' }\n'ui.cursor' = { fg = 'greyD', bg = 'orangeY' }\n'ui.cursor.insert' = { fg = 'orangeN', bg = 'orangeN' }\n'ui.cursor.select' = { fg = 'black', bg = 'orangeN' }\n'ui.cursor.match' = { fg = 'black', bg = 'blueD' }\n'ui.cursor.primary' = { fg = 'black', bg = 'orangeN' }\n'ui.selection' = { bg = 'blueH', fg = 'white' }\n'ui.selection.primary' = { bg = 'blueD', fg = 'white' }\n'ui.linenr' = { bg = 'brownU', fg = 'greyL' }\n'ui.linenr.selected' = { fg = 'orangeH' }\n'ui.cursorline' = { bg = 'brownH' }\n'ui.statusline' = { fg = 'greyT', bg = 'brownU' }\n'ui.statusline.inactive' = { fg = 'greyT', bg = 'brownN' }\n'ui.statusline.normal' = { fg = 'greyT', bg = 'brownD', modifiers = ['bold'] }\n'ui.statusline.select' = { bg = 'blueL', fg = 'brownD', modifiers = ['bold'] }\n'ui.statusline.insert' = { bg = 'orangeL', fg = 'brownD', modifiers = ['bold'] }\n'ui.help' = { fg = 'greyT', bg = 'brownD' }\n'ui.highlight' = { bg = 'brownH' }\n'ui.virtual' = { fg = 'brownV' }\n'ui.virtual.ruler' = { bg = 'brownR' }\n'ui.virtual.whitespace' = { fg = 'brownV' }\n'ui.virtual.indent-guide' = { fg = 'brownR' }\n'ui.virtual.inlay-hint' = {fg = 'brownD', bg = 'brownU'}\n'ui.virtual.jump-label' = { bg = 'black', fg = 'white', modifiers = ['bold'] }\n'ui.menu' = { fg = 'greyT', bg = 'brownD' }\n'ui.menu.selected' = { fg = 'orangeH', bg = 'brownH' }\n'ui.popup' = { bg = 'brownD' }\n'ui.popup.info' = { bg = 'brownH', fg = 'greyT' }\ntag = { fg = 'blueH' }\nlabel = { fg = 'greenS' }\nmodule = { bg = 'orangeL' }\nspecial = { fg = 'orangeW' }\noperator = { fg = 'orangeY' }\nattribute = { fg = 'orangeL' }\nnamespace = { fg = 'orangeL' }\n'type' = { fg = 'redH' }\n'type.builtin' = { fg = 'orangeL' }\n'type.enum.variant' = { fg = 'orangeL' }\n'constructor' = { fg = 'blueD' }\n'constant' = { fg = 'greyG' }\n'constant.builtin' = { fg = 'redL' }\n'constant.builtin.boolean' = { fg = 'redL' }\n'constant.character' = { fg = 'greenS' }\n'constant.character.escape' = { fg = 'blueL' }\n'constant.numeric' = { fg = 'redH' }\n'string' = { fg = 'greenN' }\n'string.regexp' = { fg = 'blueL' }\n'string.special' = { fg = 'orangeW' }\n'string.special.path' = { fg = 'orangeW' }\n'string.special.url' = { fg = 'orangeW' }\n'string.special.symbol' = { fg = 'orangeW' }\n'comment' = { fg = 'greyC', modifiers = ['italic'] }\n'comment.line' = { fg = 'greyC', modifiers = ['italic'] }\n'comment.line.documentation' = { fg = 'greyC', modifiers = ['italic'] }\n'comment.block' = { fg = 'greyC', modifiers = ['italic'] }\n'comment.block.documentation' = { fg = 'greyC', modifiers = ['italic'] }\n'variable' = { fg = 'greyT' }\n'variable.builtin' = { fg = 'blueL' }\n'variable.parameter' = { fg = 'white' }\n'variable.other.member' = { fg = 'orangeH' }\n'variable.function' = { fg = 'blueL' }\n'punctuation' = { fg = 'blueL' }\n'punctuation.delimiter' = { fg = 'blueH' }\n'punctuation.bracket' = { fg = 'orangeN' }\n'keyword' = { fg = 'blueH' }\n'keyword.control' = { fg = 'blueL' }\n'keyword.control.conditional' = { fg = 'blueL' }\n'keyword.control.repeat' = { fg = 'blueL' }\n'keyword.control.import' = { fg = 'redH' }\n'keyword.control.return' = { fg = 'blueL' }\n'keyword.control.exception' = { fg = 'redH' }\n'keyword.operator' = { fg = 'blueL' }\n'keyword.directive' = { fg = 'blueL' }\n'keyword.function' = { fg = 'redH' }\n'function' = { fg = 'blueH' }\n'function.builtin' = { fg = 'blueH' }\n'function.method' = { fg = 'blueH' }\n'function.macro' = { fg = 'greyH' }\n'function.special' = { fg = 'blueD' }\n'markup.heading' = { fg = 'greenN' }\n'markup.heading.1' = { fg = '#FFC977' }\n'markup.heading.2' = { fg = '#FFC26C' }\n'markup.heading.3' = { fg = '#FFC166' }\n'markup.heading.4' = { fg = '#FFB950' }\n'markup.heading.5' = { fg = '#FFB340' }\n'markup.heading.6' = { fg = '#FFAD34' }\n'markup.heading.marker' = { fg = 'orangeN' }\n'markup.list' = { fg = 'greenN' }\n'markup.list.numbered' = { fg = 'greenN' }\n'markup.list.unnumbered' = { fg = 'greenN' }\n'markup.bold' = { modifiers = ['bold'] }\n'markup.italic' = { modifiers = ['italic'] }\n'markup.strikethrough' = { modifiers = ['crossed_out'] }\n'markup.link' = { fg = 'blueD' }\n'markup.link.url' = { fg = 'blueL' }\n'markup.link.label' = { fg = 'blueH' }\n'markup.link.text' = { fg = 'blueN' }\n'markup.quote' = { fg = 'blueL' }\n'markup.normal' = { fg = 'blueL' }\n'markup.normal.completion' = { bg = 'brownN' }\n'markup.normal.raw' = { bg = 'brownN' }\n'markup.heading.completion' = { fg = 'greenN' }\n'markup.heading.raw' = { bg = 'brownN' }\n'markup.raw' = { bg = 'brownN' }\n'markup.raw.block' = { bg = 'brownH', fg = 'orangeH' }\n'markup.raw.inline' = { fg = 'blueL' }\n'markup.raw.inline.completion' = { fg = 'greenN' }\n'markup.raw.inline.hover' = { fg = 'greenS' }\n'diff.plus' = { fg = '#4dd44d' }\n'diff.minus' = { fg = '#dd4d4d' }\n'diff.delta' = { fg = '#4d4ddd' }\n'diff.delta.moved' = { fg = '#dd4ddd' }\n\n[palette]\nwhite = '#FFFFFF'\ngreyH = '#CFCFCF'\ngreyT = '#DEDEDE'\ngreyG = '#DDFFDD'\ngreyC = '#A0B4A7'\ngreyL = '#9A9A9A'\ngreyD = '#444444'\nblack = '#000000'\nyellowH = '#FFCC00'\norangeH = '#FFD68A'\norangeL = '#FFCB6B'\norangeY = '#FDC33B'\norangeN = '#FDAF1F'\norangeW = '#FF9500'\norangeS = '#F79A6C'\nredH = '#F78C6C'\nredL = '#F96964'\nredE = '#FF2200'\nredD = '#CC3333'\ngreenN = '#73C48F'\ngreenS = '#6FC475'\nblueH = '#8DEEF9'\nblueL = '#6dd2fa'\nblueN = '#39B7C7'\nblueD = '#4AAAD6'\nbrownV = '#67634F'\nbrownH = '#4b4845'\nbrownN = '#3E3B39'\nbrownR = '#35312f'\nbrownD = '#2B2928'\nbrownU = '#4C4643'\n"
  },
  {
    "path": "runtime/themes/rasmus.toml",
    "content": "# Author : Rohit K Viswanath <kvrohit@gmail.com>\n# Ported from : [rsms/sublime-theme](https://github.com/rsms/sublime-theme)\n\n\"attribute\" = \"cyan\"\n\n\"keyword\" = \"blue\"\n\"keyword.control.conditional\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\"keyword.directive\" = \"magenta\" # -- preprocessor comments (#if in C)\n\n\"namespace\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\n\"punctuation\" = \"gray06\"\n\"punctuation.delimiter\" = \"gray06\"\n\n\"operator\" = \"yellow\"\n\"special\" = \"yellow\"\n\n\"variable\" = \"white\"\n\"variable.builtin\" = \"bright_blue\"\n\"variable.parameter\" = \"bright_white\"\n\"variable.other.member\" = \"white\"\n\n\"type\" = \"bright_white\"\n\"type.builtin\" = \"magenta\"\n\"type.enum.variant\" = \"magenta\"\n\n\"constructor\" = \"yellow\"\n\n\"function\" = \"white\"\n\"function.macro\" = \"blue\"\n\"function.builtin\" = \"blue\"\n\n\"tag\" = \"yellow\"\n\"comment\" = { fg = \"gray05\", modifiers = [\"italic\"] }\n\n\"string\" = \"cyan\"\n\"string.regexp\" = \"green\"\n\"string.special\" = \"blue\"\n\n\"constant\" = \"white\"\n\"constant.builtin\" = \"white\"\n\"constant.numeric\" = \"magenta\"\n\"constant.character.escape\" = \"magenta\"\n\n# used for lifetimes\n\"label\" = \"yellow\"\n\n\"markup.heading.marker\" = { fg = \"gray07\" }\n\"markup.heading.1\" = { fg = \"white\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"gray07\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"gray07\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"gray07\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"gray06\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"gray06\", modifiers = [\"bold\"] }\n\"markup.list\" = \"gray07\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"cyan\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"blue\"\n\"markup.raw\" = \"yellow\"\n\n\"diff.plus\" = \"bright_green\"\n\"diff.minus\" = \"bright_red\"\n\"diff.delta\" = \"bright_cyan\"\n\n\"ui.background\" = { bg = \"bg\" }\n\"ui.background.separator\" = { fg = \"fg\" }\n\n\"ui.linenr\" = { fg = \"gray04\" }\n\"ui.linenr.selected\" = { fg = \"gray07\" }\n\n\"ui.statusline\" = { fg = \"gray07\", bg = \"gray02\" }\n\"ui.statusline.inactive\" = { fg = \"gray05\", bg = \"gray01\" }\n\"ui.statusline.normal\" = { fg = \"black\", bg = \"cyan\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"blue\", modifiers = [\"bold\"]  }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"magenta\", modifiers = [\"bold\"]  }\n\n\"ui.popup\" = { bg = \"gray01\" }\n\"ui.window\" = { fg = \"gray02\" }\n\"ui.help\" = { bg = \"gray01\", fg = \"fg\" }\n\n\"ui.text\" = { fg = \"fg\" }\n\"ui.text.focus\" = { fg = \"white\" }\n\n\"ui.virtual\" = { fg = \"gray03\" }\n\"ui.virtual.ruler\" = { bg = \"gray03\" }\n\"ui.virtual.indent-guide\" = { fg = \"gray04\" }\n\"ui.virtual.inlay-hint\" = { fg = \"gray05\" }\n\n\"ui.selection\" = { bg = \"gray03\" }\n\"ui.selection.primary\" = { bg = \"gray03\" }\n\n\"ui.cursor\" = { bg = \"gray04\" }\n\"ui.cursor.insert\" = { bg = \"white\" }\n\"ui.cursor.match\" = { fg = \"bright_yellow\" }\n\"ui.cursor.select\" = { bg = \"gray03\" }\n\"ui.cursorline.primary\" = { bg = \"gray01\" }\n\n\"ui.highlight\" = { bg = \"gray03\" }\n\n\"ui.menu\" = { fg = \"white\", bg = \"gray01\" }\n\"ui.menu.selected\" = { fg = \"fg\", bg = \"gray03\" }\n\"ui.menu.scroll\" = { fg = \"white\", bg = \"gray01\" }\n\n\"diagnostic.warning\".underline = { color = \"bright_yellow\", style = \"curl\" } \n\"diagnostic.error\".underline = { color = \"bright_red\", style = \"curl\" } \n\"diagnostic.info\".underline = { color = \"bright_blue\", style = \"curl\" } \n\"diagnostic.hint\".underline = { color = \"bright_cyan\", style = \"curl\" } \n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nwarning = \"bright_yellow\"\nerror = \"bright_red\"\ninfo = \"bright_blue\"\nhint = \"bright_cyan\"\n\n[palette]\nbg = \"#1a1a19\"\nfg = \"#d1d1d1\"\nblack = \"#333332\"\nred = \"#ff968c\"\ngreen = \"#61957f\"\nyellow = \"#ffc591\"\nblue = \"#8db4d4\"\nmagenta = \"#de9bc8\"\ncyan = \"#7bb099\"\nwhite = \"#d1d1d1\"\nbright_black = \"#4c4c4b\"\nbright_red = \"#ffafa5\"\nbright_green = \"#7aae98\"\nbright_yellow = \"#ffdeaa\"\nbright_blue = \"#a6cded\"\nbright_magenta = \"#f7b4e1\"\nbright_cyan = \"#94c9b2\"\nbright_white = \"#eaeaea\"\ngray01 = \"#222221\"\ngray02 = \"#2a2a29\"\ngray03 = \"#323231\"\ngray04 = \"#3a3a39\"\ngray05 = \"#6a6a69\"\ngray06 = \"#767675\"\ngray07 = \"#b6b6b5\"\n"
  },
  {
    "path": "runtime/themes/rose_pine.toml",
    "content": "# Author: Rosé Pine <hi@rosepinetheme.com>\n# Upstream: https://github.com/rose-pine/helix\n# Contributing:\n#   Please submit changes to https://github.com/rose-pine/helix.\n#   The Rosé Pine team will update Helix, including you as a co-author.\n\n\"ui.background\" = { bg = \"base\" }\n\"ui.background.separator\" = { bg = \"base\" }\n\n\"ui.cursor\" = { fg = \"text\", bg = \"highlight_high\" }\n# \"ui.cursor.select\" = {}\n\"ui.cursor.match\" = { fg = \"text\", bg = \"highlight_med\" }\n\"ui.cursor.primary\" = { fg = \"text\", bg = \"muted\" }\n\n# \"ui.gutter\" = {}\n# \"ui.gutter.selected\" = {}\n\n\"ui.linenr\" = { fg = \"muted\" }\n\"ui.linenr.selected\" = { fg = \"text\" }\n\n\"ui.bufferline\" = { fg = \"muted\", bg = \"base\" }\n\"ui.bufferline.active\" = { fg = \"text\", bg = \"overlay\" }\n\"ui.statusline\" = { fg = \"subtle\", bg = \"surface\" }\n\"ui.statusline.inactive\" = { fg = \"muted\", bg = \"surface\" }\n\"ui.statusline.normal\" = { fg = \"rose\", bg = \"rose_10\" }\n\"ui.statusline.insert\" = { fg = \"foam\", bg = \"foam_10\" }\n\"ui.statusline.select\" = { fg = \"iris\", bg = \"iris_10\" }\n# \"ui.statusline.separator\" = {}\n\n\"ui.popup\" = { bg = \"surface\" }\n\"ui.popup.info\" = { bg = \"surface\" }\n\n\"ui.window\" = { fg = \"overlay\", bg = \"base\" }\n\"ui.help\" = { fg = \"subtle\", bg = \"overlay\" }\n\n\"ui.text\" = { fg = \"text\" }\n\"ui.text.focus\" = { bg = \"overlay\" }\n\"ui.text.info\" = { fg = \"subtle\" }\n\"ui.text.directory\" = { fg = \"iris\" }\n\n\"ui.virtual.jump-label\" = { fg = \"love\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"overlay\" }\n\"ui.virtual.whitespace\" = { fg = \"highlight_high\" }\n\"ui.virtual.indent-guide\" = { fg = \"muted\" }\n\"ui.virtual.inlay-hint\" = { fg = \"subtle\" }\n\n\"ui.menu\" = { fg = \"subtle\", bg = \"surface\" }\n\"ui.menu.selected\" = { fg = \"text\", bg = \"overlay\" }\n\"ui.menu.scroll\" = { fg = \"muted\", bg = \"highlight_med\" }\n\n\"ui.selection\" = { bg = \"overlay\" }\n\"ui.selection.primary\" = { bg = \"highlight_med\" }\n\n\"ui.cursorline.primary\" = { bg = \"highlight_low\" }\n\"ui.cursorline.secondary\" = { bg = \"surface\" }\n\n\"warning\" = \"gold\"\n\"error\" = \"love\"\n\"info\" = \"foam\"\n\"hint\" = \"iris\"\n\"debug\" = \"rose\"\n\n\"diagnostic\" = { underline = { color = \"subtle\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"iris\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"foam\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"gold\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"love\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"special\" = \"rose\"\n\n\"attribute\" = \"iris\"\n\n\"type\" = \"foam\"\n# \"type.builtin\" = \"\"\n\n\"constructor\" = \"foam\"\n\n\"constant\" = \"foam\"\n\"constant.builtin\" = \"love\"\n\"constant.builtin.boolean\" = \"rose\"\n\"constant.character\" = \"gold\"\n\"constant.character.escape\" = \"pine\"\n\"constant.numeric\" = \"gold\"\n# \"constant.numeric.integer\" = \"\"\n# \"constant.numeric.float\" = \"\"\n\n\"string\" = \"gold\"\n# \"string.regexp\" = \"\"\n# \"string.special\" = \"\"\n# \"string.special.path\" = \"\"\n# \"string.special.url\" = \"\"\n# \"string.special.symbol\" = \"\"\n\n\"comment\" = { fg = \"muted\", modifiers = [\"italic\"] }\n# \"comment.line\" = \"\"\n# \"comment.line.documentation\" = \"\"\n# \"comment.block\" = \"\"\n# \"comment.block.documentation\" = \"\"\n\n\"variable\" = \"text\"\n\"variable.builtin\" = \"love\"\n\"variable.parameter\" = \"iris\"\n# \"variable.other\" = \"\"\n\"variable.other.member\" = \"foam\"\n\n\"label\" = \"foam\"\n\n\"punctuation\" = \"subtle\"\n# \"punctuation.delimiter\" = \"\"\n# \"punctuation.bracket\" = \"\"\n# \"punctuation.special\" = \"\"\n\n\"keyword\" = \"pine\"\n# \"keyword.control\" = \"\"\n# \"keyword.control.conditional\" = \"\"\n# \"keyword.control.repeat\" = \"\"\n# \"keyword.control.import\" = \"\"\n# \"keyword.control.return\" = \"\"\n# \"keyword.control.exception\" = \"\"\n\"keyword.operator\" = \"subtle\"\n# \"keyword.directive\" = \"\"\n# \"keyword.function\" = \"\"\n# \"keyword.storage\" = \"\"\n# \"keyword.storage.type\" = \"\"\n# \"keyword.storage.modifier\" = \"\"\n\n\"operator\" = \"subtle\"\n\n\"function\" = \"rose\"         # maybe pine\n\"function.builtin\" = \"love\"\n# \"function.method\" = \"\"\n# \"function.macro\" = \"\"\n# \"function.special\" = \"\"\n\n\"tag\" = \"foam\"\n\n\"namespace\" = \"text\"\n\n\"markup.heading.marker\" = \"muted\"\n\"markup.heading\" = { fg = \"iris\", modifiers = [\"bold\"] }\n\"markup.heading.1\" = { fg = \"iris\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"foam\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"rose\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"gold\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"pine\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"foam\", modifiers = [\"bold\"] }\n# \"markup.heading.completion\" = \"\"\n# \"markup.heading.hover\" = \"\"\n\"markup.list\" = \"muted\"\n# \"markup.list.unnumbered\" = \"\"\n# \"markup.list.numbered\" = \"\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link\" = \"iris\"\n\"markup.link.url\" = { fg = \"iris\", underline = { color = \"iris\", style = \"line\" } }\n\"markup.link.label\" = \"subtle\"\n\"markup.link.text\" = \"text\"\n\"markup.quote\" = \"subtle\"\n\"markup.raw\" = \"subtle\"\n# \"markup.raw.inline\" = {}\n# \"markup.raw.inline.completion\" = {}\n# \"markup.raw.inline.hover\" = {}\n# \"markup.raw.block\" = {}\n# \"markup.normal\" = \"\"\n# \"markup.normal.completion\" = \"\"\n# \"markup.normal.hover\" = \"\"\n\n\"diff\" = \"overlay\"\n\"diff.plus\" = \"foam\"\n\"diff.minus\" = \"love\"\n\"diff.delta\" = \"highlight_high\"\n# \"diff.delta.moved\" = \"\"\n\n[palette]\nbase = \"#191724\"\nsurface = \"#1f1d2e\"\noverlay = \"#26233a\"\nmuted = \"#6e6a86\"\nsubtle = \"#908caa\"\ntext = \"#e0def4\"\nlove = \"#eb6f92\"\nlove_10 = \"#311f30\"\ngold = \"#f6c177\"\ngold_10 = \"#30282c\"\nrose = \"#ebbcba\"\nrose_10 = \"#2f2834\"\npine = \"#31748f\"\npine_10 = \"#1a2030\"\nfoam = \"#9ccfd8\"\nfoam_10 = \"#252937\"\niris = \"#c4a7e7\"\niris_10 = \"#2b2539\"\nhighlight_low = \"#21202e\"\nhighlight_med = \"#403d52\"\nhighlight_high = \"#524f67\"\n"
  },
  {
    "path": "runtime/themes/rose_pine_dawn.toml",
    "content": "# Author: Rosé Pine <hi@rosepinetheme.com>\n# Upstream: https://github.com/rose-pine/helix\n# Contributing:\n#   Please submit changes to https://github.com/rose-pine/helix.\n#   The Rosé Pine team will update Helix, including you as a co-author.\n\ninherits = \"rose_pine\"\n\n[palette]\nbase           = \"#faf4ed\" \nsurface        = \"#fffaf3\" \noverlay        = \"#f2e9e1\"\nmuted          = \"#9893a5\"\nsubtle         = \"#797593\"\ntext           = \"#575279\"\nlove           = \"#b4637a\"\nlove_10        = \"#f6e4e0\"\ngold           = \"#ea9d34\"\ngold_10        = \"#fbead8\"\nrose           = \"#d7827e\"\nrose_10        = \"#fae8e1\"\npine           = \"#286983\"\npine_10        = \"#e5e6e2\"\nfoam           = \"#56949f\"\nfoam_10        = \"#eaeae5\"\niris           = \"#907aa9\"\niris_10        = \"#f1e8e6\"\nhighlight_low  = \"#f4ede8\"\nhighlight_med  = \"#dfdad9\"\nhighlight_high = \"#cecacd\"\n"
  },
  {
    "path": "runtime/themes/rose_pine_moon.toml",
    "content": "# Author: Rosé Pine <hi@rosepinetheme.com>\n# Upstream: https://github.com/rose-pine/helix\n# Contributing:\n#   Please submit changes to https://github.com/rose-pine/helix.\n#   The Rosé Pine team will update Helix, including you as a co-author.\n\ninherits = \"rose_pine\"\n\n[palette]\nbase           = \"#232136\" \nsurface        = \"#2a273f\" \noverlay        = \"#393552\"\nmuted          = \"#6e6a86\"\nsubtle         = \"#908caa\"\ntext           = \"#e0def4\"\nlove           = \"#eb6f92\"\nlove_10        = \"#3a2841\"\ngold           = \"#f6c177\"\ngold_10        = \"#39313e\"\nrose           = \"#ea9a97\"\nrose_10        = \"#392d41\"\npine           = \"#3e8fb0\"\npine_10        = \"#252c44\"\nfoam           = \"#9ccfd8\"\nfoam_10        = \"#2e3248\"\niris           = \"#c4a7e7\"\niris_10        = \"#342e4a\"\nhighlight_low  = \"#2a283e\"\nhighlight_med  = \"#44415a\"\nhighlight_high = \"#56526e\"\n"
  },
  {
    "path": "runtime/themes/seoul256-dark-hard.toml",
    "content": "# Seoul256 Dark Hard\n# Author : EricHenry\n# Original Creator: https://github.com/junegunn/seoul256.vim\n\ninherits = \"seoul256-dark\"\n\n\"ui.background\" = { bg = \"gray1\" }\n\"ui.gutter\" = { bg = \"gray2\" }\n\"ui.cursorline.primary\" = { bg = \"gray\" }\n\"ui.gutter.selected\" = { bg = \"gray\" }\n\"ui.linenr.selected\" = { bg = \"gray\", fg = \"magenta\", modifiers = [\"bold\"] }\n\"ui.virtual.inlay-hint\" = { fg = \"gray4\", modifiers = [\"bold\"] }\n\n\"ui.help\" = { bg = \"gray\" }\n\"ui.popup\" = { bg = \"gray\" }\n\"ui.menu\" = { bg = \"gray\" }\n"
  },
  {
    "path": "runtime/themes/seoul256-dark-soft.toml",
    "content": "# Seoul256 Dark Soft\n# Author : EricHenry\n# Original Creator: https://github.com/junegunn/seoul256.vim\n\ninherits = \"seoul256-dark\"\n\n\"ui.background\" = { bg = \"gray8\" }\n\"ui.gutter\" = { bg = \"gray6\" }\n\"ui.cursorline.primary\" = { bg = \"gray5\" }\n\"ui.gutter.selected\" = { bg = \"gray5\" }\n\"ui.linenr.selected\" = { bg = \"gray5\", fg = \"magenta\", modifiers = [\"bold\"] }\n\n\"ui.help\" = { bg = \"gray5\" }\n\"ui.popup\" = { bg = \"gray5\" }\n\"ui.menu\" = { bg = \"gray5\" }\n"
  },
  {
    "path": "runtime/themes/seoul256-dark.toml",
    "content": "# Seoul256 Dark\n# Author : EricHenry\n# Original Creator: https://github.com/junegunn/seoul256.vim\n\n# Syntax highlighting configuration\n\"attribute\" = { fg = \"yellow\" }\n\"comment\" = { fg = \"green1\" }\n\"constant\" = { fg = \"blue5\" }\n\"constant.numeric\" = { fg = \"yellow1\" }\n\"constant.builtin.boolean\" = { fg = \"purple\" }\n\"constant.character.escape\" = { fg = \"salmon\" }\n\"constructor\" = { fg = \"yellow\" }\n\"function\" = { fg = \"yellow2\" }\n\"function.builtin\" = { fg = \"blue1\" }\n\"function.method\" = { fg = \"salmon\" }\n\"function.macro\" = { fg = \"yellow2\" }\n\"keyword\" = { fg = \"mauve\" }\n\"label\" = { fg = \"magenta\" }\n\"namespace\" = { fg = \"cyan\" }\n\"operator\" = { fg = \"yellow3\" }\n\"punctuation\" = { fg = \"brown\" }\n\"special\" = { fg = \"yellow2\" }\n\"string\" = { fg = \"blue\" }\n\"type\" = { fg = \"yellow\" }\n\"type.builtin\" = { fg = \"salmon\" }\n\"variable\" = { fg = \"white\" }\n\"variable.builtin\" = { fg = \"salmon\" }\n\"variable.parameter\" = { fg = \"white\" }\n\"variable.other.member\" = { fg = \"white\" }\n\n\"markup.heading\" = { fg = \"salmon2\", modifiers = [\"bold\"] }\n\"markup.raw.inline\" = { fg = \"green\" }\n\"markup.bold\" = { fg = \"yellow1\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"magenta1\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.list\" = { fg = \"salmon\" }\n\"markup.quote\" = { fg = \"yellow\" }\n\"markup.link.url\" = { fg = \"cyan\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"salmon2\" }\n\n\"diff.plus\" = { fg = \"green3\" }\n\"diff.delta\" = { fg = \"blue1\" }\n\"diff.minus\" = { fg = \"magenta3\" }\n\n\"diagnostic.info\".underline = { color = \"cyan\", style = \"curl\" }\n\"diagnostic.hint\".underline = { color = \"green1\", style = \"curl\" }\n\"diagnostic.warning\".underline = { color = \"yellow1\", style = \"curl\" }\n\"diagnostic.error\".underline = { color = \"red\", style = \"curl\" }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"info\" = { fg = \"blue2\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"blue3\", modifiers = [\"bold\"] }\n\"warning\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"ui.background\" = { bg = \"gray4\" }\n\"ui.gutter\" = { bg = \"gray5\" }\n\"ui.gutter.selected\" = { bg = \"gray3\" }\n\"ui.virtual\" = { fg = \"gray6\" }\n\"ui.virtual.indent-guide\" = { fg = \"gray6\" }\n\"ui.virtual.whitespace\" = { fg = \"gray6\" }\n\"ui.virtual.ruler\" = { bg = \"gray5\" }\n\"ui.virtual.inlay-hint\" = { fg = \"gray9\", modifiers = [\"bold\"] }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"ui.cursor\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { bg = \"gray4\", modifiers = [\"underlined\"] }\n\"ui.cursor.insert\" = { fg = \"blue1\" }\n\n\"ui.selection\" = { bg = \"magenta2\" }\n\"ui.selection.primary\" = { bg = \"blue4\" }\n\"ui.cursorline.primary\" = { bg = \"gray3\" }\n\n\"ui.highlight\" = { bg = \"gray5\" }\n\"ui.highlight.frameline\" = { bg = \"red\" }\n\n\"ui.linenr\" = { fg = \"yellow4\" }\n\"ui.linenr.selected\" = { bg = \"gray3\", fg = \"magenta\", modifiers = [\"bold\"] }\n\n\"ui.statusline\" = { fg = \"magenta2\", bg = \"yellow2\" }\n\"ui.statusline.inactive\" = { fg = \"gray6\", bg = \"black\" }\n\"ui.statusline.normal\" = { fg = \"black\", bg = \"blue2\" }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"green2\" }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"magenta\" }\n\n\"ui.text\" = { fg = \"white\" }\n\"ui.text.focus\" = { fg = \"white\", bg = \"magenta2\", modifiers = [\"bold\"] }\n\n\"ui.help\" = { fg = \"white\", bg = \"gray3\" }\n\"ui.popup\" = { fg = \"white\", bg = \"gray3\" }\n\"ui.window\" = { fg = \"white\" }\n\"ui.menu\" = { fg = \"white\", bg = \"gray3\" }\n\"ui.menu.selected\" = { fg = \"white\", bg = \"magenta2\" }\n\"ui.menu.scroll\" = { fg = \"gray7\", bg = \"gray6\" }\n\n\"ui.debug\" = { fg = \"red\" }\n\n# Colors (Seoul256)\n[palette]\nblack = '#000000'    # Black\nblack1 = '#14161B'\nred = '#d70000'      # Red\ngreen = '#afd75f'    # Greenish Yellow\ngreen1 = '#5f875f'   # Greenish Gray\ngreen2 = '#5f8700'   # Green\ngreen3 = '#87af87'\ngreen4 = '#5f5f00'\nyellow = '#d8af5f'   # Yellow\nyellow1 = '#ffd787'  # Bright Yellow\nyellow2 = '#d7d7af'  # Yellowish\nyellow3 = '#d7d787'  # Yellow Dim\nyellow4 = '#87875f'  # Olive\nyellow5 = '#6B5300'\nblue = '#87afaf'     # Light Blue\nblue1 = '#5f87d7'    # Bright Blue\nblue2 = '#5f5f87'    # Blue\nblue3 = '#a6dbff'    # Lightest Blue\nblue4 = '#005f5f'    # Blue Green\nblue5 = '#5fafaf'    # Dark Blue\nblue6 = '#008787'\nmagenta = '#af5f5f'  # Magenta\nmagenta1 = '#af5f87' # Soft Magenta\nmagenta2 = '#875f5f' # Dark Magenta\nmagenta3 = '#d7005f' # Darker Magenta\ncyan = '#87d7d7'     # Bright Cyan\ncyan1 = '#afd7d7'\nwhite = '#d0d0d0'    # White\nwhite1 = '#dadada'   # White\npurple = '#8787af'   # Purple\nbrown = '#af875f'    # Brownish\nbrown1 = '#875f00'   # Brownish\norange = '#ff5f00'   # Orange\nsalmon = '#ffaf87'   # Salmon\nsalmon1 = '#d78787'  # Salmon Bright\nsalmon2 = '#d7afaf'  # Salmon Light\nsalmon3 = '#d7875f'  # Yellowish\nmauve = '#d75f87'    # Mauve\n\ngray = '#121212'     # Very Dark Gray\ngray1 = '#1c1c1c'    # Darker Gray\ngray2 = '#262626'    # Dark Gray\ngray3 = '#303030'    # Dark Medium Gray\ngray4 = '#3a3a3a'    # Medium Gray\ngray5 = '#444444'    # Lighter Medium Gray\ngray6 = '#585858'    # Light Gray\ngray7 = '#626262'    # Lighter Gray\ngray8 = '#4e4e4e'    # Even Lighter Gray\ngray9 = '#5f5f5f'\ngray10 = '#c6c6c6'\ngray11 = '#eeeeee'\ngray12 = '#e4e4e4'\ngray13 = '#bcbcbc'\n\n# 233 = '#121212' \n# 234 = '#1c1c1c'\n# 235 = '#262626'\n# 236 = '#303030'\n# 237 = '#3a3a3a' # Default\n# 238 = '#444444'\n# 239 = '#4e4e4e'\n"
  },
  {
    "path": "runtime/themes/seoul256-light-hard.toml",
    "content": "# Seoul256 Light Hard\n# Author : EricHenry\n# Original Creator: https://github.com/junegunn/seoul256.vim\n\ninherits = \"seoul256-light\"\n\n\"ui.background\" = { bg = \"gray11\" }\n\"ui.cursor.match\" = { bg = \"gray10\", modifiers = [\"underlined\"] }\n\"ui.gutter\" = { bg = \"white1\" }\n\"ui.cursorline.primary\" = { bg = \"gray12\" }\n\"ui.gutter.selected\" = { bg = \"gray12\" }\n\"ui.linenr.selected\" = { bg = \"gray12\", fg = \"magenta\", modifiers = [\"bold\"] }\n\n\"ui.help\" = { fg = \"black1\", bg = \"gray12\" }\n\"ui.popup\" = { fg = \"black1\", bg = \"gray12\" }\n\"ui.menu\" = { fg = \"black1\", bg = \"gray12\" }\n"
  },
  {
    "path": "runtime/themes/seoul256-light-soft.toml",
    "content": "# Seoul256 Light Soft\n# Author : EricHenry\n# Original Creator: https://github.com/junegunn/seoul256.vim\n\ninherits = \"seoul256-light\"\n\n\"ui.background\" = { bg = \"white\" }\n\"ui.cursor.match\" = { bg = \"gray13\", modifiers = [\"underlined\"] }\n\"ui.gutter\" = { bg = \"gray13\" }\n\"ui.cursorline.primary\" = { bg = \"gray10\" }\n\"ui.gutter.selected\" = { bg = \"gray10\" }\n\"ui.linenr.selected\" = { bg = \"gray10\", fg = \"magenta\", modifiers = [\"bold\"] }\n\n\"ui.help\" = { fg = \"black1\", bg = \"gray10\" }\n\"ui.popup\" = { fg = \"black1\", bg = \"gray10\" }\n\"ui.menu\" = { fg = \"black1\", bg = \"gray10\" }\n"
  },
  {
    "path": "runtime/themes/seoul256-light.toml",
    "content": "# Seoul256 Light\n# Author : EricHenry\n# Original Creator: https://github.com/junegunn/seoul256.vim\n\ninherits = \"seoul256-dark\"\n\n\"constructor\" = { fg = \"brown1\" }\n\"constant.numeric\" = { fg = \"magenta2\" }\n\"constant.builtin.boolean\" = { fg = \"mauve\" }\n\"constant.character.escape\" = { fg = \"salmon3\" }\n\"function\" = { fg = \"green4\" }\n\"function.builtin\" = { fg = \"blue1\" }\n\"function.method\" = { fg = \"salmon\" }\n\"function.macro\" = { fg = \"green4\" }\n\"namespace\" = { fg = \"blue4\" }\n\"operator\" = { fg = \"brown1\" }\n\"punctuation\" = { fg = \"brown1\" }\n\"special\" = { fg = \"green4\" } \n\"string\" = { fg = \"blue6\" }\n\"type\" = { fg = \"brown1\" }\n\"type.builtin\" = { fg = \"salmon3\" }\n\"variable\" = { fg = \"black1\" }\n\"variable.builtin\" = { fg = \"salmon3\" }\n\"variable.parameter\" = { fg = \"black1\" }\n\"variable.other.member\" = { fg = \"black1\" }\n\n\"diagnostic.info\".underline = { color = \"green1\", style = \"curl\" }\n\"info\" = { fg = \"green1\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"warning\" = { fg = \"yellow5\", modifiers = [\"bold\"] }\n\n\"ui.background\" = { bg = \"white1\" }\n\"ui.cursor\" = { fg = \"gray4\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"gray4\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { bg = \"gray13\", modifiers = [\"underlined\"] }\n\"ui.cursor.insert\" = { fg = \"blue1\" }\n\"ui.cursorline.primary\" = { bg = \"white\" }\n\"ui.gutter\" = { bg = \"gray10\" }\n\"ui.gutter.selected\" = { bg = \"white\" }\n\"ui.linenr.selected\" = { bg = \"white\", fg = \"magenta\", modifiers = [\"bold\"] }\n\"ui.virtual.inlay-hint\" = { fg = \"gray6\", modifiers = [\"bold\"] }\n\n\"ui.selection\" = { bg = \"yellow2\" }\n\"ui.selection.primary\" = { bg = \"cyan1\" }\n\n\"ui.text\" = { fg = \"black1\" }\n\n\"ui.help\" = { fg = \"black1\", bg = \"white\" }\n\"ui.popup\" = { fg = \"black1\", bg = \"white\" }\n\"ui.menu\" = { fg = \"black1\", bg = \"white\" }\n\n"
  },
  {
    "path": "runtime/themes/serika-dark.toml",
    "content": "# Serika (Dark)\n# Author: VuiMuich\n\n# Original Author:\n# URL: https://github.com/arturoalviar/serika-syntax\n# Author: arturoalviar\n# License: MIT License\n\n\"escape\" = \"orange\"\n\"type\" = \"yellow\"\n\"constant\" = \"purple\"\n\"number\" = \"purple\"\n\"string\" = \"fg\"\n\"comment\" = { fg = \"grey2\", modifiers = [ \"italic\" ] }\n\"variable\" = \"yellow\"\n\"variable.builtin\" = \"blue\"\n\"variable.parameter\" = \"yellow\"\n\"variable.property\" = \"yellow\"\n\"label\" = \"aqua\"\n\"punctuation\" = \"grey0\"\n\"punctuation.delimiter\" = \"bg4\"\n\"punctuation.bracket\" = \"fg\"\n\"keyword\" = \"red\"\n\"operator\" = \"grey0\"\n\"function\" = \"green\"\n\"function.builtin\" = \"blue\"\n\"function.macro\" = \"aqua\"\n\"tag\" = \"yellow\"\n\"namespace\" = \"fg\"\n\"attribute\" = \"aqua\"\n\"constructor\" = \"yellow\"\n\"module\" = \"blue\"\n\"special\" = \"orange\"\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.background.separator\" = { fg = \"bg2\" }\n\"ui.bufferline\" = { fg = \"grey1\" }\n\"ui.bufferline.active\" = { fg = \"yellow\" }\n\"ui.bufferline.background\" = { bg = \"bg2\" }\n\"ui.cursor\" = { fg = \"fg\", bg = \"dark-red\" }\n\"ui.cursor.match\" = { fg = \"grey2\", bg = \"pale-yellow\" }\n\"ui.cursor.insert\" = { fg = \"bg0\", bg = \"pale-yellow\" }\n\"ui.cursor.select\" = { fg = \"bg0\", bg = \"bg-yellow\" }\n\"ui.cursor.primary\" = { fg = \"dark-red\", bg = \"fg\" }\n\"ui.cursor.primary.match\" = { fg = \"pale-yellow\", bg = \"grey2\" }\n\"ui.cursor.primary.insert\" = { fg = \"dark-red\", bg = \"bg-yellow\" }\n\"ui.cursor.primary.select\" = { fg = \"yellow\", bg = \"nasty-red\" }\n\"ui.linenr\" = { fg = \"yellow\", modifiers = [\"dim\"] }\n\"ui.linenr.selected\" = { fg = \"fg\", modifiers = [\"dim\"], underline.style = \"line\" }\n\"ui.cursorline\" = { fg = \"grey1\", bg = \"bg2\" }\n\"ui.statusline\" = { fg = \"grey1\", bg = \"bg2\" }\n\"ui.statusline.inactive\" = { fg = \"bg5\", bg = \"bg1\" }\n\"ui.statusline.insert\" = { fg = \"blue\" }\n\"ui.statusline.select\" = { fg = \"pale-yellow\" }\n\"ui.popup\" = { fg = \"grey2\", bg = \"bg1\" }\n\"ui.picker.header\" = { fg = \"bg2\", underline.style = \"dashed\" }\n\"ui.window\" = { fg = \"bg1\", bg = \"bg1\" }\n\"ui.help\" = { fg = \"fg\", bg = \"bg1\" }\n\"ui.text\" = \"fg\"\n\"ui.text.focus\" = \"yellow\"\n\"ui.text.inactive\" = { fg = \"fg\", modifiers = [ \"dim\" ] }\n\"ui.text.directory\" = \"grey0\"\n\"ui.menu\" = { fg = \"fg\", bg = \"bg2\" }\n\"ui.menu.selected\" = { fg = \"bg0\", bg = \"bg-yellow\" }\n\"ui.selection\" = { bg = \"yellow\", modifiers = [ \"dim\" ] }\n\"ui.selection.prime\" = { underline.style = \"line\" }\n\"ui.virtual.inlay-hint\" = { fg = \"grey2\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"nasty-red\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"bg1\" } \n\"ui.virtual.whitespace\" = { fg = \"grey2\", modifiers = [ \"italic\" ] }\n\"ui.virtual.wrap\" = { fg = \"grey2\", modifiers = [ \"italic\" ] }\n\n\"hint\" = \"blue\"\n\"info\" = \"aqua\"\n\"warning\" = \"yellow\"\n\"error\" = \"nasty-red\"\n\n\"diagnostic\" = { underline = { style = \"curl\", color = \"purple\" } }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"blue\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"aqua\" } }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"yellow\" } }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"nasty-red\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"diff.plus\" = { fg = \"green\" }\n\"diff.delta\" = { fg = \"orange\" }\n\"diff.minus\" = { fg = \"nasty-red\" }\n\n\"markup.heading\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\"markup.list\" = \"cyan\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = \"cyan\"\n\"markup.link.text\" = \"pink\"\n\"markup.quote\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.raw\" = { fg = \"fg\" }\n\n[palette]\n\nbg0 = \"#323437\"\nbg1 = \"#494c50\"\nbg2 = \"#55585e\"\nbg3 = \"#61656b\"\nbg4 = \"#6d7278\"\nbg5 = \"#797e86\"\nbg-visual = \"#646669\"\nbg-red = \"#7e2a33\"\nbg-green = \"#86b365\"\nbg-blue = \"#6a89af\"\nbg-yellow = \"#e2b714\"\n\nfg = \"#d1d0c5\"\nred = \"#e29da7\"\nnasty-red = \"#ca4754\"\ndark-red = \"#7e2a33\"\norange = \"#dd8a3c\"\nyellow = \"#e2b714\"\npale-yellow = \"#f3e0a1\"\ngreen = \"#bcd5a8\"\naqua = \"#b9c2c6\"\nblue = \"#adc9db\"\npurple = \"#be9ec9\"\ngrey0 = \"#aaaeb3\"\ngrey1 = \"#e1e1e3\"\ngrey2 = \"#646669\"\npink = \"#e06c75\"\n"
  },
  {
    "path": "runtime/themes/serika-light.toml",
    "content": "# Serika (Light)\n# Author: VuiMuich\n\n# Original Author:\n# URL: https://github.com/arturoalviar/serika-syntax\n# Author: arturoalviar\n# License: MIT License\n\n\"escape\" = \"orange\"\n\"type\" = \"yellow\"\n\"constant\" = \"purple\"\n\"number\" = \"purple\"\n\"string\" = \"fg\"\n\"comment\" = { fg = \"grey2\", modifiers = [ \"italic\" ] }\n\"variable\" = \"yellow\"\n\"variable.builtin\" = \"blue\"\n\"variable.parameter\" = \"yellow\"\n\"variable.property\" = \"yellow\"\n\"label\" = \"aqua\"\n\"punctuation\" = \"grey0\"\n\"punctuation.delimiter\" = \"grey2\"\n\"punctuation.bracket\" = \"fg\"\n\"keyword\" = \"red\"\n\"operator\" = \"grey2\"\n\"function\" = \"green\"\n\"function.builtin\" = \"blue\"\n\"function.macro\" = \"aqua\"\n\"tag\" = \"yellow\"\n\"namespace\" = \"fg\"\n\"attribute\" = \"aqua\"\n\"constructor\" = \"yellow\"\n\"module\" = \"blue\"\n\"special\" = \"orange\"\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.background.separator\" = { fg = \"bg5\" }\n\"ui.bufferline\" = { fg = \"grey1\" }\n\"ui.bufferline.active\" = { fg = \"pale-yellow\" }\n\"ui.bufferline.background\" = { bg = \"bg5\" }\n\"ui.cursor\" = { fg = \"bg0\", bg = \"dark-red\" }\n\"ui.cursor.match\" = { fg = \"pale-yellow\", bg = \"bg5\" }\n\"ui.cursor.insert\" = { fg = \"fg\", bg = \"pale-yellow\" }\n\"ui.cursor.select\" = { fg = \"fg\", bg = \"bg-yellow\" }\n\"ui.cursor.primary\" = { fg = \"nasty-red\", bg = \"grey0\" }\n\"ui.cursor.primary.match\" = { fg = \"grey2\", bg = \"pale-yellow\" }\n\"ui.cursor.primary.insert\" = { fg = \"dark-red\", bg = \"yellow\" }\n\"ui.cursor.primary.select\" = { fg = \"yellow\", bg = \"dark-red\" }\n\"ui.linenr\" = { fg = \"yellow\", modifiers = [\"dim\"] }\n\"ui.linenr.selected\" = { fg = \"fg\", modifiers = [\"dim\"], underline.style = \"line\" }\n\"ui.cursorline\" = { bg = \"bg0\", modifiers = [\"dim\"] }\n\"ui.statusline\" = { fg = \"grey1\", bg = \"bg5\" }\n\"ui.statusline.inactive\" = { fg = \"grey1\", bg = \"bg3\" }\n\"ui.statusline.insert\" = { fg = \"blue\" }\n\"ui.statusline.select\" = { fg = \"pale-yellow\" }\n\"ui.popup\" = { fg = \"bg0\", bg = \"bg5\" }\n\"ui.picker.header\" = { fg = \"bg2\", underline.style = \"dashed\" }\n\"ui.window\" = { fg = \"bg5\", bg = \"bg5\" }\n\"ui.help\" = { fg = \"bg0\", bg = \"bg5\" }\n\"ui.text\" = \"fg\"\n\"ui.text.focus\" = \"yellow\"\n\"ui.text.inactive\" = { fg = \"fg\", modifiers = [ \"dim\" ] }\n\"ui.text.directory\" = \"grey2\"\n\"ui.menu\" = { fg = \"bg0\", bg = \"bg3\" }\n\"ui.menu.selected\" = { fg = \"bg0\", bg = \"bg-yellow\" }\n\"ui.selection\" = { bg = \"grey0\", modifiers = [ \"dim\" ] }\n\"ui.selection.prime\" = { underline.style = \"line\" }\n\"ui.virtual.inlay-hint\" = { fg = \"grey2\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"nasty-red\", modifiers = [\"bold\"] }\n\"ui.virtual.ruler\" = { bg = \"bg0\", modifiers = [\"dim\"] }\n\"ui.virtual.whitespace\" = { fg = \"grey2\", modifiers = [ \"italic\" ] }\n\"ui.virtual.wrap\" = { fg = \"grey2\", modifiers = [ \"italic\" ] }\n\n\"hint\" = \"blue\"\n\"info\" = \"aqua\"\n\"warning\" = \"yellow\"\n\"error\" = \"nasty-red\"\n\n\"diagnostic\" = { underline = { style = \"curl\", color = \"purple\" } }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"blue\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"aqua\" } }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"yellow\" } }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"nasty-red\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"diff.plus\" = { fg = \"bg-green\" }\n\"diff.delta\" = { fg = \"bg-blue\" }\n\"diff.minus\" = { fg = \"nasty-red\" }\n\n\"markup.heading\" = { fg = \"purple\", modifiers = [\"bold\"] }\n\"markup.list\" = \"cyan\"\n\"markup.bold\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = \"cyan\"\n\"markup.link.text\" = \"pink\"\n\"markup.quote\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.raw\" = { fg = \"fg\" }\n\n[palette]\n\nbg0 = \"#d1d0c5\"\nbg1 = \"#494c50\"\nbg2 = \"#55585e\"\nbg3 = \"#61656b\"\nbg4 = \"#6d7278\"\nbg5 = \"#797e86\"\nbg-visual = \"#646669\"\nbg-red = \"#7e2a33\"\nbg-green = \"#86b365\"\nbg-blue = \"#6a89af\"\nbg-yellow = \"#e2b714\"\n\nfg = \"#323437\"\nred = \"#621d28\"\nnasty-red = \"#da3333\"\ndark-red = \"#791717\"\norange = \"#57320f\"\nyellow = \"#9a7d0e\"\npale-yellow = \"#e2b714\"\ngreen = \"#3d5128\"\naqua = \"#455054\"\nblue = \"#3f5673\"\npurple = \"#5a4066\"\ngrey0 = \"#aaaeb3\"\ngrey1 = \"#e1e1e3\"\ngrey2 = \"#646669\"\npink = \"#e06c75\"\n"
  },
  {
    "path": "runtime/themes/sidra.toml",
    "content": "# License: MIT License\n# Sidra Theme for the Helix Editor\n# Author: Md Atiquz Zaman <atiquzz42@gmail.com>\n# Repo: https://github.com/atiquz/sidra\n# Inspired by: One Monokai, Dracula, One Dark Pro\n# Description: A customizable, balanced dark theme built for readability and flexibility.\n\n\n# ===========================\n# UI Element Styling\n# ===========================\n\n\n# USER INTERFACE\n\"ui.background\"               = {  fg = \"foreground\",           bg = \"background\"                                            }\n\"ui.background.separator\"     = {  fg = \"white\"                                                                              }\n\n\"ui.linenr\"                   = {  fg = \"fg_linenr\"                                                                          }\n\"ui.linenr.selected\"          = {  fg = \"fg_linenr_sld\"                                                                      }\n\n\"ui.help\"                     = {  fg = \"fg_help\",              bg = \"bg_help\"                                               }\n\"ui.popup\"                    = {                               bg = \"bg_popup\"                                              }\n\"ui.window\"                   = {  fg = \"fg_window\"                                                                          }\n\n\"ui.text\"                     = {  fg = \"fg_text\"                                                                            }\n\"ui.text.focus\"               = {  fg = \"fg_text_focus\"                                                                      }\n\"ui.text.inactive\"            = {  fg = \"fg_text_inactive\"                                                                   }\n\n\"ui.virtual\"                  = {  fg = \"fg_virtual\"                                                                         }\n\"ui.virtual.ruler\"            = {                               bg = \"bg_virtual_ruler\"                                      }\n\"ui.virtual.indent-guide\"     = {  fg = \"fg_virtual_indent\"                                                                  }\n\n\"ui.debug\"                    = {  fg = \"fg_debug\",                                      modifiers = [\"bold\"]                }\n\"ui.debug.active\"             = {  fg = \"fg_debug_active\",                               modifiers = [\"bold\"]                }\n\"ui.debug.breakpoint\"         = {  fg = \"fg_debug_breakpoint\",                           modifiers = [\"bold\"]                }\n\n\"ui.menu\"                     = {  fg = \"gray\",                 bg = \"black\"                                                 }\n\"ui.menu.selected\"            = {  fg = \"black\",                bg = \"gray\"                                                  }\n\n# CURSOR\n\"ui.cursor\"                   = {  fg = \"foreground\",           bg = \"bg_normal\",        modifiers = [\"dim\"]                 }\n\"ui.cursor.match\"             = {  fg = \"foreground\",           bg = \"bg_match\",         modifiers = [\"dim\"]                 }\n\"ui.cursor.normal\"            = {  fg = \"background\",           bg = \"bg_normal\",        modifiers = [\"dim\"]                 }\n\"ui.cursor.insert\"            = {  fg = \"background\",           bg = \"bg_insert\",        modifiers = [\"dim\"]                 }\n\"ui.cursor.select\"            = {  fg = \"background\",           bg = \"bg_select\",        modifiers = [\"dim\"]                 }\n\"ui.cursor.primary.normal\"    = {  fg = \"background\",           bg = \"bg_normal\"                                             }\n\"ui.cursor.primary.insert\"    = {  fg = \"background\",           bg = \"bg_insert\"                                             }\n\"ui.cursor.primary.select\"    = {  fg = \"background\",           bg = \"bg_select\"                                             }\n\"ui.cursorline\"               = {                               bg = \"bg_cursorline\"                                         }\n\"ui.cursorline.primary\"       = {                               bg = \"bg_cursorline\"                                         }\n\n\n# SELECTION\n\"ui.selection\"                = {  fg = \"white\",                bg = \"bg_selection\"                                          }\n\"ui.selection.primary\"        = {  fg = \"white\",                bg = \"bg_selection\"                                          }\n\n\n# STATUS LINE\n\"ui.statusline\"               = {  fg = \"fg_statusline\",        bg = \"bg_statusline\"                                         }\n\"ui.statusline.inactive\"      = {  fg = \"fg_inactive\",          bg = \"bg_inactive\"                                           }\n\"ui.statusline.normal\"        = {  fg = \"black\",                bg = \"bg_normal\",        modifiers = [\"bold\"]                }\n\"ui.statusline.insert\"        = {  fg = \"black\",                bg = \"bg_insert\",        modifiers = [\"bold\"]                }\n\"ui.statusline.select\"        = {  fg = \"black\",                bg = \"bg_select\",        modifiers = [\"bold\"]                }\n\n# MARKUP\n\"markup.heading\"              = {  fg = \"markup_heading\"    }\n\"markup.bold\"                 = {  fg = \"markup_bold\",                                   modifiers = [\"bold\"]                }\n\"markup.italic\"               = {  fg = \"markup_italic\",                                 modifiers = [\"italic\"]              }\n\"markup.strikethrough\"        = {  fg = \"markup_strikethrough\",                          modifiers = [\"crossed_out\", \"bold\"] }\n\"markup.link.url\"             = {  fg = \"markup_link_url\",                               modifiers = [\"underlined\"]          }\n\"markup.link.text\"            = {  fg = \"markup_link_text\"                                                                   }\n\"markup.raw\"                  = {  fg = \"markup_raw\"                                                                         }\n\n\n# GIT\n\"diff.plus\"                   = {  fg = \"plus\",                                          modifiers = [\"bold\"] }\n\"diff.minus\"                  = {  fg = \"minus\",                                         modifiers = [\"bold\"] }\n\"diff.delta\"                  = {  fg = \"delta\",                                         modifiers = [\"bold\"] }\n\n\n# HINT INFO ERROR & WARNING\n\"diagnostic.hint\"             = {  underline   = {   color = \"cl_hint\",                  style = \"curl\" }       }\n\"diagnostic.info\"             = {  underline   = {   color = \"cl_info\",                  style = \"curl\" }       }\n\"diagnostic.error\"            = {  underline   = {   color = \"cl_error\",                 style = \"curl\" }       }\n\"diagnostic.warning\"          = {  underline   = {   color = \"cl_warning\",               style = \"curl\" }       }\n\nhint                          =    \"cl_hint\"\ninfo                          =    \"cl_info\"\nerror                         =    \"cl_error\"\nwarning                       =    \"cl_warning\"\n\n\n# ===========================\n# SYNTAX COLORS\n# ===========================\n\n\n# === ATTRIBUTES & KEYWORDS ===\nattribute                     = \"#a7bf67\"  # Olive green\nnamespace                     = \"#7095bf\"  # Steel blue\n\n\"keyword\"                     = { fg = \"#d37a78\",               modifiers = [\"bold\"]           }\n\"keyword.control\"             = { fg = \"#d37a78\",               modifiers = [\"bold\"]           }\n\"keyword.control.conditional\" = { fg = \"#82AAFF\",               modifiers = [\"bold\"]           }\n\"keyword.control.repeat\"      = { fg = \"#d37a78\",               modifiers = [\"bold\"]           }\n\"keyword.control.import\"      = { fg = \"#C678DD\",               modifiers = [\"bold\"]           }\n\"keyword.control.return\"      = { fg = \"#88aece\",               modifiers = [\"bold\"]           }\n\"keyword.control.exception\"   = { fg = \"#FF79C6\",               modifiers = [\"bold\"]           }\n\"keyword.operator\"            = { fg = \"#528BFF\"                                               }\n\"keyword.function\"            = { fg = \"#d37a78\",               modifiers = [\"bold\"]           }\n\"keyword.storage\"             = { fg = \"#C678DD\",               modifiers = [\"bold\"]           }\n\"keyword.storage.type\"        = { fg = \"#56B6C2\",               modifiers = [\"bold\"]           }\n\"keyword.storage.modifier\"    = { fg = \"#56B6C2\",               modifiers = [\"bold\"]           }\n\n\n# === SYMBOLS & OPERATORS ===\n\"punctuation\"                = \"#FFFFFF\"  # White\n\"punctuation.delimiter\"      = \"#F3F2CC\"  # White (delimiter punctuation)\n\"punctuation.bracket\"        = \"#FFFFFF\"  # Yellow\n\"punctuation.special\"        = \"#ffd700\"  # Yello\noperator                     = \"#F3F2CC\"  # Dusty brown (used to be \"muddy\")\nspecial                      = \"#c90076\"  # Pink Color\n\n# === VARIABLES ===\n\"variable\"                   = \"#F3F2CC\"  # Soft green\n\"variable.other\"             = \"#cfba8b\"  # Pale mint green (special language svars)\n\"variable.other.member\"      = \"#AB9DF2\"  # Pale mint green (special language svars)\n\"variable.builtin\"           = \"#FC9867\"  # Blue\n\"variable.parameter\"         = \"#F3F2CC\"  # Pale mint green\n\n# === TYPES ===\ntype                         = \"#efbe4c\"  # Golden yellow\n\"type.builtin\"               = \"#efbe4c\"  # Golden yellow (built-in types)\nconstructor                  = \"#c19ef7\"  # Light lilac\n\n# === FUNCTIONS ===\n\"function\"                   = \"#FAD566\"  # Green\n\"function.macro\"             = \"#FAD566\"  # Green\n\"function.method\"            = \"#FAD566\"  # Green\n\"function.builtin\"           = \"#db985e\"  # Orange tan\n\"function.special\"           = \"#db985e\"  # Orange tan\n\n# === TAGS ===\ntag                          = \"#d37a78\"  # Soft salmon pink\n\n# === COMMENTS ===\ncomment                      = \"#646f69\"  # Light gray\n\n# === CONSTANTS ===\nconstant                     = \"#A5C4D4\"  # Pale blue\n\"constant.builtin\"           = \"#76c490\"  # Bright yellow\n\"constant.numeric\"           = \"#86c1b9\"  # Muted violet\n\"constant.character.escape\"  = \"#c95c56\"  # Coral red (escape characters)\n\n# === STRINGS ===\nstring                       = \"#A9DC76\"  # Sandy yellow-orange\n\n# === LABELS ===\nlabel                        = \"#abcc8a\"  # Pale green\n\n# ===========================\n# Color Palette\n# ===========================\n\n[palette]\n\n# ===== MODES COLORS =====\n\nbg_normal               = \"#BD93F9\"        # Light purple\nbg_insert               = \"#50fa7b\"        # Neon green\nbg_select               = \"#8be9fd\"        # Cyan blue\nbg_match                = \"#D3D3D3\"        # Light gray\n\n# ===== GIT COLORS =====\n\nplus                    = \"#4F6F52\"        # Forest green\nminus                   = \"#B80000\"        # Vivid red\ndelta                   = \"#3876BF\"        # Steel blue\n\n# ===== MARKUP COLORS =====\n\nmarkup_heading          = \"#ff69b4\"        # Hot pink\nmarkup_bold             = \"#e7c547\"        # Bright yellow\nmarkup_italic           = \"#b294bb\"        # Lavender\nmarkup_strikethrough    = \"#d7005f\"        # Deep pink-red\nmarkup_link_url         = \"#3876BF\"        # Steel blue\nmarkup_link_text        = \"#FFA500\"        # Orange\nmarkup_raw              = \"#808080\"        # Medium gray\n\n# ===== PRIMARY UI COLORS =====\n\nforeground              = \"#D3D3D3\"        # Light gray (default text)\nbackground              = \"#232323\"        # Very dark gray (background)\n\n# ===== UI INTERFACE COLORS =====\n\nfg_linenr               = \"#747575\"        # Dull silver (line numbers)\nfg_linenr_sld           = \"#c7dddd\"        # Light cyan (selected line number)\nfg_help                 = \"#D3D3D3\"        # Light gray (help text)\nbg_help                 = \"#35353a\"        # Charcoal (help background)\nbg_popup                = \"#3b3b3d\"        # Dark gray (popup background)\nfg_window               = \"#F1DCA7\"        # Soft cream (window border/title)\n\nfg_text                 = \"#D3D3D3\"        # Light gray (main text)\nfg_text_focus           = \"#83c679\"        # Light green (focused text)\nfg_text_inactive        = \"#93a56f\"        # Olive green (inactive text)\n\n# ===== VIRTUAL COLORS =====\n\nfg_virtual              = \"#F1DCA7\"        # Cream (virtual text)\nbg_virtual_ruler        = \"#363638\"        # Deep gray (ruler background)\nfg_virtual_indent       = \"#5B5B5A\"        # Medium-dark gray (indent guides)\n\n# ===== DEBUGGING COLORS =====\n\nfg_debug                = \"#634450\"        # Plum (debug info)\nfg_debug_active         = \"#3876BF\"        # Blue (active debug line)\nfg_debug_breakpoint     = \"#B80000\"        # Red (breakpoint marker)\n\n# ===== CURSOR, SELECTION, STATUSLINE =====\n\nbg_cursorline           = \"#2d303e\"        # Slate blue-gray (cursor line)\nbg_selection            = \"#71797E\"        # Cool gray (selected text background)\nfg_statusline           = \"#D3D3D3\"        # Light gray (statusline text)\nbg_statusline           = \"#303030\"        # Dark gray (statusline background)\nfg_inactive             = \"#4b5059\"        # Dim gray (inactive statusline text)\nbg_inactive             = \"#303030\"        # Dark gray (inactive statusline bg)\n\n# ===== HINT INFO ERROR & WARNING COLORS =====\n\ncl_hint                 = \"#f1fa8c\"        # Bright yellow\ncl_info                 = \"#f1fa8c\"        # Same as hint\ncl_error                = \"#ff69b4\"        # Bright pink\ncl_warning              = \"#f1fa8c\"        # Same as hint\n"
  },
  {
    "path": "runtime/themes/snazzy.toml",
    "content": "# Author : Timothy DeHerrera <tim@nrdxp.dev>\n\"comment\".fg = \"comment\"\n\n\"constant.builtin\".fg          = \"olive\"\n\"constant.character.escape\".fg = \"magenta\"\n\"constant.character\".fg        = \"carnation\"\n\"constant\".fg                  = \"purple\"\n\"constant.numeric\".fg          = \"cyan\"\n\"constant.numeric.float\".fg    = \"red\"\n\n\"function.builtin\".fg = \"sand\"\n\"function\".fg         = \"green\"\n\"function.macro\".fg   = \"blue\"\n\"function.method\".fg  = \"opal\"\n\n\"keyword\"                   = { fg = \"magenta\", modifiers = [\"bold\"] }\n\"keyword.control\"           = { fg = \"carnation\", modifiers = [\"bold\"] }\n\"keyword.control.exception\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"keyword.function\"          = { fg = \"lilac\", modifiers = [\"bold\"] }\n\"keyword.operator\"          = { fg = \"coral\", modifiers = [\"bold\"] }\n\"keyword.storage\"           = { fg = \"coral\", modifiers = [\"bold\"] }\n\n\"operator\".fg = \"coral\"\n\n\"punctuation.bracket\".fg   = \"foreground\"\n\"punctuation.delimiter\".fg = \"coral\"\n\"punctuation\".fg           = \"magenta\"\n\n\"attribute\".fg      = \"opal\"\n\"string\".fg         = \"yellow\"\n\"string.regexp\".fg  = \"red\"\n\"string.special\".fg = \"blue\"\n\"tag\".fg            = \"carnation\"\n\n\"type.builtin\".fg      = \"yellow\"\n\"type.enum.variant\".fg = \"sand\"\n\"type\".fg              = \"opal\"\n\"type.variant\".fg      = \"sand\"\n\n\"variable.builtin\".fg      = \"olive\"\n\"variable\".fg              = \"cyan\"\n\"variable.other.member\".fg = \"lilac\"\n\"variable.parameter\"       = { fg = \"blue\", modifiers = [\"italic\"] }\n\n\"constructor\".fg = \"sand\"\n\"label\".fg       = \"magenta\"\n\"namespace\".fg   = \"olive\"\n\"special\".fg     = \"magenta\"\n\n\"diff.delta\".fg = \"blue\"\n\"diff.minus\".fg = \"red\"\n\"diff.plus\".fg  = \"green\"\n\n\"ui.background\"           = { fg = \"foreground\", bg = \"background\" }\n\"ui.cursor\"               = { fg = \"background\", bg = \"blue\", modifiers = [\"dim\"] }\n\"ui.cursor.match\"         = { fg = \"green\", modifiers = [\"underlined\"] }\n\"ui.cursor.primary\"       = { fg = \"background\", bg = \"cyan\", modifiers = [\"dim\"] }\n\"ui.cursorline\"           = { bg = \"background_dark\" }\n\"ui.help\"                 = { fg = \"foreground\", bg = \"background_dark\" }\n\"ui.linenr\"               = { fg = \"comment\" }\n\"ui.linenr.selected\"      = { fg = \"foreground\" }\n\"ui.menu\"                 = { fg = \"foreground\", bg = \"background_dark\" }\n\"ui.menu.selected\"        = { fg = \"cyan\", bg = \"background_dark\" }\n\"ui.popup\"                = { fg = \"foreground\", bg = \"background_dark\" }\n\"ui.selection\"            = { bg = \"secondary_highlight\" }\n\"ui.selection.primary\"    = { bg = \"primary_highlight\" }\n\"ui.statusline\"           = { fg = \"foreground\", bg = \"background_dark\" }\n\"ui.statusline.inactive\"  = { fg = \"comment\", bg = \"background_dark\" }\n\"ui.statusline.insert\"    = { fg = \"olive\", bg = \"background_dark\" }\n\"ui.statusline.normal\"    = { fg = \"opal\", bg = \"background_dark\" }\n\"ui.statusline.select\"    = { fg = \"carnation\", bg = \"background_dark\" }\n\"ui.text\"                 = { fg = \"foreground\" }\n\"ui.text.focus\"           = { fg = \"cyan\" }\n\"ui.virtual.indent-guide\" = { fg = \"opal\" }\n\"ui.virtual.ruler\"        = { bg = \"background_dark\" }\n\"ui.virtual.inlay-hint\" =   { bg = \"background_dark\", fg = \"comment\" }\n\"ui.virtual.whitespace\"   = { fg = \"comment\" }\n\"ui.window\"               = { fg = \"foreground\" }\n\n\"error\"   = { fg = \"red\" }\n\"warning\" = { fg = \"cyan\" }\n\n\"diagnostic\"             = { underline = { style = \"line\", color = \"coral\" }, bg = \"cyan\" }\n\"diagnostic.deprecated\"  = { modifiers = [\"crossed_out\"] }\n\"diagnostic.error\"       = { underline = { style = \"curl\", color = \"red\" } }\n\"diagnostic.hint\"        = { underline = { style = \"line\", color = \"cyan\" } }\n\"diagnostic.info\"        = { underline = { style = \"line\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.warning\"     = { underline = { style = \"curl\", color = \"yellow\" } }\n\n\"markup.bold\"          = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.heading\"       = { fg = \"purple\", modifiers = [\"bold\"] }\n\"markup.italic\"        = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.link.label\"    = { fg = \"blue\", modifiers = [\"italic\"] }\n\"markup.link.text\"     = \"magenta\"\n\"markup.link.url\"      = \"cyan\"\n\"markup.list\"          = \"cyan\"\n\"markup.quote\"         = { fg = \"yellow\", modifiers = [\"italic\"] }\n\"markup.raw\"           = { fg = \"foreground\" }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nbackground          = \"#282a36\"\nbackground_dark     = \"#21222c\"\ncomment             = \"#a39e9b\"\nforeground          = \"#eff0eb\"\nprimary_highlight   = \"#800049\"\nsecondary_highlight = \"#4d4f66\"\n\n# main colors\nblue    = \"#57c7ff\"\ncyan    = \"#9aedfe\"\ngreen   = \"#5af78e\"\nmagenta = \"#ff6ac1\"\npurple  = \"#bd93f9\"\nred     = \"#ff5c57\"\nyellow  = \"#f3f99d\"\n\n# aux colors\ncarnation = \"#f99fc6\"\ncoral     = \"#f97c7c\"\nlilac     = \"#c9c5fb\"\nolive     = \"#b6d37c\"\nopal      = \"#b1d7c7\"\nsand      = \"#ffab6f\"\n"
  },
  {
    "path": "runtime/themes/solarized_dark.toml",
    "content": "\"attribute\" = { fg = \"violet\" }\n\"keyword\" = { fg = \"green\" }\n\"keyword.directive\" = { fg = \"orange\" }\n\"namespace\" = { fg = \"violet\" }\n\"operator\" = { fg = \"green\" }\n\"special\" = { fg = \"orange\" }\n\"variable.builtin\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\"variable.function\" = { fg = \"blue\" }\n\"type\" = { fg = \"yellow\" }\n\"type.builtin\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"constructor\" = { fg = \"blue\" }\n\"function\" = { fg = \"blue\" }\n\"function.macro\" = { fg = \"magenta\" }\n\"function.builtin\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"function.special\" = { fg = \"magenta\" }\n\"comment\" = { fg = \"base01\" }\n\"string\" = { fg = \"cyan\" }\n\"constant\" = { fg = \"cyan\" }\n\"constant.builtin\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\"constant.character.escape\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"label\" = { fg = \"green\" }\n\"module\" = { fg = \"violet\" }\n\"tag\" = { fg = \"magenta\" }\n\n# TODO\n\"markup.heading\" = \"blue\"\n\"markup.list\" = \"red\"\n\"markup.bold\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"red\"\n\"markup.quote\" = \"cyan\"\n\"markup.raw\" = \"green\"\n\n\"diff.plus\" = { fg = \"green\" }\n\"diff.delta\" = { fg = \"yellow\" }\n\"diff.minus\" = { fg = \"red\" }\n\n# 背景\n\"ui.background\" = { bg = \"base03\" }\n\n\"ui.virtual.whitespace\" = { fg = \"base01\" }\n\"ui.virtual.inlay-hint\" = { fg = \"base01\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n# 行号栏\n\"ui.linenr\" = { fg = \"base0\", bg = \"base02\" }\n# 当前行号栏\n\"ui.linenr.selected\" = { fg = \"blue\", modifiers = [\"bold\"] }\n#cursorline\n\"ui.cursorline\" = { bg = \"base03\" }\n\n# 状态栏\n\"ui.statusline\" = { fg = \"base03\", bg = \"base0\" }\n\"ui.statusline.normal\" = { bg = \"blue\" }\n\"ui.statusline.insert\" = { bg = \"green\" }\n\"ui.statusline.select\" = { bg = \"yellow\" }\n\n# 非活动状态栏\n\"ui.statusline.inactive\" = { fg = \"base1\", bg = \"base01\" }\n\n# 补全窗口, preview窗口\n\"ui.popup\" = { bg = \"base02\" }\n# 影响 补全选中 cmd弹出信息选中\n\"ui.menu.selected\" = { fg = \"base02\", bg = \"base2\"}\n\"ui.menu\" = { fg = \"base0\", bg = \"base02\" }\n# ??\n\"ui.window\" = { fg = \"base3\" }\n# 命令行 补全的帮助信息\n\"ui.help\" = { modifiers = [\"reversed\"] }\n\n# 快捷键窗口 \n\"ui.popup.info\" = {fg = \"base02\", bg = \"base1\", modifiers = [\"bold\"]}\n# 快捷键字体\n\"ui.text.info\" = {fg = \"base02\", modifiers = [\"bold\"]}\n\n# 普通ui的字体样式\n\"ui.text\" = { fg = \"base1\" }\n# 影响 picker列表选中, 快捷键帮助窗口文本\n\"ui.text.focus\" = { fg = \"blue\", modifiers = [\"bold\"]}\n\n# 主光标/selectio\n\"ui.cursor.primary\" = { fg = \"base03\", bg = \"base1\" }\n\"ui.cursor.select\" = { fg = \"base02\", bg = \"cyan\" }\n\"ui.cursorline.primary\" = { bg = \"base02\" }\n\"ui.cursorline.secondary\" = { bg = \"base025\" }\n\n\"ui.selection\" = { bg = \"base0175\" }\n\"ui.selection.primary\" = { bg = \"base015\" }\n\n\"ui.virtual.indent-guide\" = { fg = \"base02\" }\n\"ui.virtual.ruler\" = { bg = \"base02\" }\n\n# normal模式的光标\n\"ui.cursor\" = {fg = \"base02\", bg = \"cyan\"}\n\"ui.cursor.insert\" = {fg = \"base03\", bg = \"base3\"}\n# 当前光标匹配的标点符号\n\"ui.cursor.match\" = { fg = \"base03\", bg = \"base00\" }\n\n\"warning\" =  { fg = \"orange\", modifiers= [\"bold\", \"underlined\"] }\n\"error\" = { fg = \"red\", modifiers= [\"bold\", \"underlined\"] }\n\"info\" = { fg = \"blue\", modifiers= [\"bold\", \"underlined\"] }\n\"hint\" = { fg = \"base01\", modifiers= [\"bold\", \"underlined\"] }\n\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"orange\" } }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"red\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"blue\" } }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"base01\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\n# 深色 越来越深\nbase03   = \"#002b36\"\nbase025  = \"#03303b\"\nbase02   = \"#073642\"\nbase0175 = \"#16404b\"\nbase015  = \"#2c4f59\"\nbase01   = \"#586e75\"\nbase00   = \"#657b83\"\nbase0    = \"#839496\"\nbase1    = \"#93a1a1\"\nbase2    = \"#eee8d5\"\nbase3    = \"#fdf6e3\"\n\n# 浅色 越來越浅\nyellow  = \"#b58900\"\norange  = \"#cb4b16\"\nred     = \"#dc322f\"\nmagenta = \"#d33682\"\nviolet  = \"#6c71c4\"\nblue    = \"#268bd2\"\ncyan    = \"#2aa198\"\ngreen   = \"#859900\"\n"
  },
  {
    "path": "runtime/themes/solarized_light.toml",
    "content": "\"attribute\" = { fg = \"violet\" }\n\"keyword\" = { fg = \"green\" }\n\"keyword.directive\" = { fg = \"orange\" }\n\"namespace\" = { fg = \"violet\" }\n\"operator\" = { fg = \"green\" }\n\"special\" = { fg = \"orange\" }\n\"variable.builtin\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\"variable.function\" = { fg = \"blue\" }\n\"type\" = { fg = \"yellow\" }\n\"type.builtin\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"constructor\" = { fg = \"blue\" }\n\"function\" = { fg = \"blue\" }\n\"function.macro\" = { fg = \"magenta\" }\n\"function.builtin\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"function.special\" = { fg = \"magenta\" }\n\"comment\" = { fg = \"base01\" }\n\"string\" = { fg = \"cyan\" }\n\"constant\" = { fg = \"cyan\" }\n\"constant.builtin\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\"constant.character.escape\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"label\" = { fg = \"green\" }\n\"module\" = { fg = \"violet\" }\n\"tag\" = { fg = \"magenta\" }\n\n# TODO\n\"markup.heading\" = \"blue\"\n\"markup.list\" = \"red\"\n\"markup.bold\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"red\"\n\"markup.quote\" = \"cyan\"\n\"markup.raw\" = \"green\"\n\n\"diff.plus\" = { fg = \"green\" }\n\"diff.delta\" = { fg = \"yellow\" }\n\"diff.minus\" = { fg = \"red\" }\n\n# 背景\n# background\n\"ui.background\" = { bg = \"base03\" }\n\n\"ui.virtual.whitespace\" = { fg = \"base01\" }\n\"ui.virtual.inlay-hint\" = { fg = \"base01\", modifiers = [\"italic\"] }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n# 行号栏\n# line number column\n\"ui.linenr\" = { fg = \"base0\", bg = \"base02\" }\n# 当前行号栏\n# current line number column\n\"ui.linenr.selected\" = { fg = \"blue\", modifiers = [\"bold\"] }\n# cursorline\n\"ui.cursorline\" = { bg = \"base0\" }\n\n# 状态栏\n# status bar\n\"ui.statusline\" = { fg = \"base03\", bg = \"base0\" }\n\"ui.statusline.normal\" = { bg = \"blue\" }\n\"ui.statusline.insert\" = { bg = \"green\" }\n\"ui.statusline.select\" = { bg = \"yellow\" }\n\n# 非活动状态栏\n# inactive status bar\n\"ui.statusline.inactive\" = { fg = \"base1\", bg = \"base01\" }\n\n# 补全窗口, preview窗口\n# Completion window, preview window\n\"ui.popup\" = { bg = \"base02\" }\n# 影响 补全选中 cmd弹出信息选中\n# Affect completion selection, cmd pop-up information selection\n\"ui.menu.selected\" = { fg = \"base02\", bg = \"base2\"}\n\"ui.menu\" = { fg = \"base0\", bg = \"base02\" }\n# ??\n\"ui.window\" = { fg = \"base3\" }\n# 命令行 补全的帮助信息\n# Command line completion help information\n\"ui.help\" = { modifiers = [\"reversed\"] }\n\n# 快捷键窗口 \n# Shortcut window\n\"ui.popup.info\" = { bg = \"base1\" }\n# 快捷键字体\n# Shortcut font\n\"ui.text.info\" = {fg = \"base02\", modifiers = [\"bold\"]}\n\n# 普通ui的字体样式\n# Normal ui font style\n\"ui.text\" = { fg = \"base1\" }\n# 影响 picker列表选中, 快捷键帮助窗口文本\n# Affects picker list selection, shortcut key help window text\n\"ui.text.focus\" = { fg = \"blue\", modifiers = [\"bold\"]}\n\n# 主光标/selection\n# main cursor/selection\n\"ui.cursor.primary\" = { fg = \"base03\", bg = \"base1\" }\n\"ui.cursor.select\" = { fg = \"base02\", bg = \"cyan\" }\n\n\"ui.cursorline.primary\" = { bg = \"base02\" }\n\"ui.cursorline.secondary\" = { bg = \"base025\" }\n\n\"ui.selection\" = { bg = \"base0175\" }\n\"ui.selection.primary\" = { bg = \"base015\" }\n\n\"ui.virtual.indent-guide\" = { fg = \"base02\" }\n\"ui.virtual.ruler\" = { bg = \"base02\" }\n\n# normal模式的光标\n# normal mode cursor\n\"ui.cursor\" = {fg = \"base02\", bg = \"cyan\"}\n\"ui.cursor.insert\" = {fg = \"base03\", bg = \"base3\"}\n# 当前光标匹配的标点符号\n# The punctuation character matched by the current cursor\n\"ui.cursor.match\" = { fg = \"base02\", bg = \"base015\" }\n\n\"warning\" =  { fg = \"orange\", modifiers= [\"bold\", \"underlined\"] }\n\"error\" = { fg = \"red\", modifiers= [\"bold\", \"underlined\"] }\n\"info\" = { fg = \"blue\", modifiers= [\"bold\", \"underlined\"] }\n\"hint\" = { fg = \"base01\", modifiers= [\"bold\", \"underlined\"] }\n\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"orange\" } }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"red\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"blue\" } }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"base01\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\n[palette]\nred      = '#dc322f'\ngreen    = '#859900'\nyellow   = '#b58900'\nblue     = '#268bd2'\nmagenta  = '#d33682'\ncyan     = '#2aa198'\norange   = '#cb4b16'\nviolet   = '#6c71c4'\n\n# 深色 越来越深\n# dark getting darker\nbase0    = '#657b83'\nbase1    = '#586e75'\nbase2    = '#073642'\nbase3    = '#002b36'\n\n# 浅色 越來越浅\n# Lighter and lighter\nbase00   = '#839496'\nbase01   = '#93a1a1'\nbase015  = '#c5c8bd'\nbase0175 = '#dddbcc'\nbase02   = '#eee8d5'\nbase025  = '#f5eedb'\nbase03   = '#fdf6e3'\n"
  },
  {
    "path": "runtime/themes/sonokai.toml",
    "content": "### Sublime Text Sonokai Theme\n## Original Author: sainnhe\n# URL: https://github.com/sainnhe/sonokai\n## Modified by p4ymak\n# URL: https://github.com/p4ymak\n# License: MIT License\n\n\"type\" = \"blue\"\n\"constant\" = \"fg\"\n\"constant.builtin\" = \"purple\"\n\"constant.numeric\" = \"purple\"\n\"constant.character.escape\" = \"orange\"\n\"string\" = \"yellow\"\n\"comment\" = \"grey\"\n\"variable\" = \"fg\"\n\"variable.builtin\" = \"purple\"\n\"variable.parameter\" = \"fg\"\n\"variable.other.member\" = \"orange\"\n\"label\" = \"red\"\n\"punctuation\" = \"grey\"\n\"punctuation.special\" = \"yellow\"\n\"keyword\" = \"red\"\n\"operator\" = \"red\"\n\"function\" = \"green\"\n\"function.builtin\" = \"green\"\n\"function.macro\" = \"green\"\n\"tag\" = \"yellow\"\n\"namespace\" = \"blue\"\n\"attribute\" = \"purple\"\n\"constructor\" = \"blue\"\n\"module\" = \"blue\"\n\"special\" = \"orange\"\n\n\"markup.heading.marker\" = \"grey\"\n\"markup.heading.1\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"fg\", modifiers = [\"bold\"] }\n\"markup.list\" = \"red\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"blue\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"purple\"\n\"markup.quote\" = \"grey\"\n\"markup.raw\" = \"green\"\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"blue\"\n\"diff.minus\" = \"red\"\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.cursor\" = { modifiers = ['reversed'] }\n\"ui.cursor.match\" = { bg = \"bg4\" }\n\"ui.cursor.insert\" = { fg = \"black\", bg = \"grey\" }\n\"ui.cursor.select\" = { fg = \"bg0\", bg = \"blue\" }\n\"ui.selection\" = { bg = \"bg5\" }\n\"ui.selection.primary\" = { bg = \"bg4\" }\n\"ui.linenr\" = \"grey\"\n\"ui.linenr.selected\" = \"fg\"\n\"ui.cursorline.primary\" = { bg = \"bg1\" }\n\"ui.statusline\" = { fg = \"fg\", bg = \"bg3\" }\n\"ui.statusline.inactive\" = { fg = \"grey\", bg = \"bg1\" }\n\"ui.statusline.normal\" = { fg = \"bg0\", bg = \"blue\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { fg = \"bg0\", bg = \"green\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { fg = \"bg0\", bg = \"purple\", modifiers = [\"bold\"] }\n\"ui.popup\" = { fg = \"grey\", bg = \"bg2\" }\n\"ui.window\" = { fg = \"grey\", bg = \"bg0\" }\n\"ui.help\" = { fg = \"fg\", bg = \"bg1\" }\n\"ui.text\" = \"fg\"\n\"ui.text.focus\" = \"green\"\n\"ui.menu\" = { fg = \"fg\", bg = \"bg2\" }\n\"ui.menu.selected\" = { fg = \"bg0\", bg = \"green\" }\n\"ui.virtual.whitespace\" = \"bg4\" \n\"ui.virtual.ruler\" = { bg = \"bg3\" }\n\"ui.virtual.inlay-hint\" = { fg = \"grey_dim\" }\n\ninfo = { fg = 'green', bg = 'bg2' }\nhint = { fg = 'blue', bg = 'bg2', modifiers = ['bold'] }\nwarning = { fg = 'yellow', bg = 'bg2', modifiers = ['bold'] }\nerror = { fg = 'red', bg = 'bg2', modifiers = ['bold'] }\n\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"green\" } }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"blue\" } }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"yellow\" } }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"red\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\n\n[palette]\n\nblack = \"#181819\"\nbg_dim = \"#222327\"\nbg0 = \"#2c2e34\"\nbg1 = \"#33353f\"\nbg2 = \"#363944\"\nbg3 = \"#3b3e48\"\nbg4 = \"#414550\"\nbg5 = \"#444852\"\nbg_red = \"#ff6077\"\ndiff_red = \"#55393d\"\nbg_green = \"#a7df78\"\ndiff_green = \"#394634\"\nbg_blue = \"#85d3f2\"\ndiff_blue = \"#354157\"\ndiff_yellow = \"#4e432f\"\nfg = \"#e2e2e3\"\nred = \"#fc5d7c\"\norange = \"#f39660\"\nyellow = \"#e7c664\"\ngreen = \"#9ed072\"\ncyan = \"#8dd0b6\" # added for compatibility with `edge` scheme\nblue = \"#76cce0\"\npurple = \"#b39df3\"\ngrey = \"#7f8490\"\ngrey_dim = \"#595f6f\"\n"
  },
  {
    "path": "runtime/themes/spacebones_light.toml",
    "content": "# Author : Koen Van der Auwera <atog@hey.com>\n# Based on SpaceBones Light https://github.com/chipotle/spacebones\n# https://github.com/chipotle/spacebones/blob/main/SpaceBones%20Light.bbColorScheme\n\n\"attribute\" = \"#b1951d\"\n\"keyword\" = { fg = \"#3a81c3\" }\n\"keyword.directive\" = \"#3a81c3\"\n\"namespace\" = \"#b1951d\"\n\"punctuation\" = \"#6c3163\"\n\"punctuation.delimiter\" = \"#6c3163\"\n\"operator\" = \"#ba2f59\"\n\"special\" = \"#ba2f59\"\n\"variable.property\" = \"#7590db\"\n\"variable\" = \"#715ab1\"\n\"variable.builtin\" = \"#715ab1\"\n\"variable.parameter\" = \"#7590db\"\n\"variable.other.member\" = \"#002db3\"\n\"type\" = \"#6c3163\"\n\"type.builtin\" = \"#6c3163\"\n\"constructor\" = { fg = \"#4e3163\", modifiers = [\"bold\"] }\n\"function\" = { fg = \"#715ab1\", modifiers = [\"bold\"] }\n\"function.macro\" = \"#b1951d\"\n\"function.builtin\" = \"#b1951d\"\n\"comment\" = { fg = \"#a49da5\", modifiers = [\"italic\"]  }\n\"constant\" = { fg = \"#6c3163\" }\n\"constant.builtin\" = { fg = \"#6c3163\", modifiers = [\"bold\"] }\n\"string\" = \"theme_aqua\"\n\"number\" = \"#6c3163\"\n\"escape\" = { fg = \"fg2\", modifiers = [\"bold\"] }\n\"label\" = \"#b1951d\"\n\"module\" = \"#b1951d\"\n\n# TODO\n\"markup.heading\" = \"theme_blue\"\n\"markup.list\" = \"theme_red\"\n\"markup.bold\" = { fg = \"theme_yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"theme_magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"theme_yellow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"theme_red\"\n\"markup.quote\" = \"theme_cyan\"\n\"markup.raw\" = \"theme_green\"\n\n\"diff.plus\" = \"theme_aqua\"\n\"diff.delta\" = \"#715ab1\"\n\"diff.minus\" = \"#ba2f59\"\n\n\"warning\" = { fg = \"meta\" }\n\"error\" = { fg = \"#e0211d\" }\n\"info\" = { fg = \"theme_blue\" }\n\"hint\" = { fg = \"bg2\" }\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.linenr\" = { fg = \"bg3\" }\n\"ui.linenr.selected\" = { fg = \"theme_yellow\" }\n\"ui.cursorline\" = { bg = \"bg2\" }\n\"ui.statusline\" = { fg = \"fg1\", bg = \"bg2\" }\n\"ui.statusline.inactive\" = { fg = \"fg4\", bg = \"bg1\" }\n\"ui.statusline.normal\" = { fg = \"bg1\", bg = \"theme_cyan\" }\n\"ui.statusline.insert\" = { fg = \"bg1\", bg = \"theme_green\" }\n\"ui.statusline.select\" = { fg = \"bg1\", bg = \"theme_magenta\" }\n\"ui.popup\" = { bg = \"bg1\" }\n\"ui.window\" = { bg = \"bg1\" }\n\"ui.help\" = { bg = \"bg1\", fg = \"fg1\" }\n\"ui.text\" = { fg = \"fg1\" }\n\"ui.text.focus\" = { fg = \"fg1\", modifiers = [\"bold\"] }\n\"ui.text.directory\" = { fg = \"theme_blue\" }\n\"ui.selection\" = { bg = \"hl2\" }\n\"ui.selection.primary\" = { bg = \"hl1\" }\n\"ui.cursor.primary\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { bg = \"bg3\" }\n\"ui.cursorline.primary\" = { bg = \"bg1\" }\n\"ui.menu\" = { fg = \"fg1\", bg = \"bg2\" }\n\"ui.menu.selected\" = { fg = \"base\", bg = \"bg2\", modifiers = [\"bold\"] }\n\"ui.virtual\" = \"base-dim\"\n\"ui.virtual.ruler\" = { bg = \"bg1\" }\n\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"meta\" } }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"#e0211d\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"theme_blue\" } }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"bg2\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n[palette]\nbase = \"#655370\"\nbase-dim = \"#a094a2\"\nmeta = \"#da8b55\"\n\nbg0 = \"#fbf8ef\"\nbg1 = \"#efeae9\"\nbg2 = \"#d1dcdf\"\nbg3 = \"#b4c6cb\"\n\nhl1 = \"#d3d3e7\"\nhl2 = \"#e7e7fc\"\n\nfg1 = \"#655370\"\nfg2 = \"#5f3bc4\"\nfg3 = \"#bdae93\"\nfg4 = \"#a89984\"\n\ntheme_magenta = \"#a31db1\"\ntheme_blue = \"#3a81c3\"\ntheme_yellow = \"#b1951d\"\ntheme_cyan = \"#21b8c7\"\ntheme_aqua = \"#2d9574\"\ntheme_green = \"#67b11d\"\ntheme_red = \"#c10e0b\"\n"
  },
  {
    "path": "runtime/themes/starlight.toml",
    "content": "# Author : eemilhaa <eemil.haapanen@gmail.com> \n# Palette from : https://github.com/CosmicToast/starlight\n\n# Syntax\n\"function\"               = \"green\"\n\"constructor\"            = \"green\"\n\n\"type\"                   = \"cyan\"\n\"string.special\"         = \"cyan\"\n\"string.regexp\"          = \"cyan\"\n\"constant\"               = \"cyan\"\n\"punctuation.special\"    = \"cyan\"\n\n\"namespace\"              = \"white\"\n\"module\"                 = \"white\"\n\"variable\"               = \"white\"\n\n\"attribute\"              = \"magenta\"\n\"variable.parameter\"     = \"magenta\"\n\"variable.other.member\"  = \"magenta\"\n\"type.parameter\"         = \"magenta\"\n\n\"keyword\"                = \"blue\"\n\"variable.builtin\"       = \"blue\"\n\"label\"                  = \"blue\"\n\"tag\"                    = \"blue\"\n\"operator\"               = \"blue\"\n\"special\"                = \"blue\"\n\n\"string\"                 = \"yellow\"\n\n\"punctuation\"            = \"punct\"\n\n\"comment\"                = \"dark-fg\"\n\n# Markup\n\"markup.heading.marker\"  = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.heading\"         = { fg = \"white\", modifiers = [\"bold\"] }\n\"markup.list\"            = \"blue\"\n\"markup.bold\"            = { fg = \"magenta\", modifiers = [\"bold\"] }\n\"markup.italic\"          = { fg = \"magenta\", modifiers = [\"italic\"] }\n\"markup.strikethrough\"   = \"red\"\n\"markup.link\"            = \"cyan\"\n\"markup.link.text\"       = \"yellow\"\n\"markup.quote\"           = \"magenta\"\n\"markup.raw\"             = \"green\"\n\n# UI\n\"diff.plus\"   = \"green\"\n\"diff.minus\"  = \"red\"\n\"diff.delta\"  = \"blue\"\n\n\"ui.background\"             = { fg = \"dark-fg\", bg = \"dark-bg\" }\n\"ui.cursor\"                 = { fg = \"black\", bg = \"light-fg\" }\n\"ui.cursor.primary\"         = { fg = \"black\", bg = \"yellow\" }\n\"ui.cursor.match\"           = { fg = \"black\", bg = \"dark-blue\", modifiers = [\"bold\"] }\n\"ui.linenr\"                 = \"dark-fg\"\n\"ui.linenr.selected\"        = \"yellow\"\n\"ui.statusline\"             = { fg = \"light-fg\", bg = \"light-bg\" }\n\"ui.statusline.inactive\"    = { fg = \"dark-fg\", bg = \"light-bg\" }\n\"ui.statusline.insert\"      = { fg = \"black\", bg = \"green\" }\n\"ui.statusline.select\"      = { fg = \"black\", bg = \"magenta\" }\n\"ui.statusline.normal\"      = { fg = \"black\", bg = \"blue\" }\n\"ui.popup\"                  = { fg = \"dark-fg\", bg = \"light-bg\" }\n\"ui.window\"                 = { fg = \"light-bg\", bg = \"dark-bg\" }\n\"ui.help\"                   = { fg = \"light-fg\", bg = \"light-bg\" }\n\"ui.text\"                   = \"light-fg\"\n\"ui.text.focus\"             = { fg = \"white\", bg = \"light-bg\", modifiers = [\"bold\"] }\n\"ui.virtual\"                = \"dark-fg\"\n\"ui.virtual.ruler\"          = { bg = \"medium-bg\" }\n\"ui.virtual.indent-guide\"   = \"indent\"\n\"ui.virtual.whitespace\"     = \"indent\"\n\"ui.menu\"                   = { fg = \"light-fg\", bg = \"light-bg\" }\n\"ui.menu.selected\"          = { fg = \"white\", bg = \"dark-fg\", modifiers = [\"bold\"] }\n\"ui.selection\"              = { fg = \"light-fg\", bg = \"dark-fg\" }\n\"ui.selection.primary\"      = { fg = \"white\", bg = \"dark-blue\" }\n\"ui.highlight\"              = { bg = \"light-bg\" }\n\"ui.cursorline.primary\"     = { bg = \"black\" }\n\"ui.cursorcolumn.primary\"   = { bg = \"black\" }\n\"ui.bufferline.background\"  = { bg = \"dark-bg\" }\n\"ui.bufferline\"             = { fg = \"light-fg\", bg = \"light-bg\" }\n\"ui.bufferline.active\"      = { fg = \"white\", bg = \"dark-fg\" }\n\n\"diagnostic.error\"    = { underline = { color = \"red\", style = \"curl\" } }\n\"diagnostic.warning\"  = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.info\"     = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.hint\"     = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"info\"     = \"blue\"\n\"hint\"     = \"blue\"\n\"warning\"  = \"yellow\"\n\"error\"    = \"red\"\n\n[palette]\n# Colors\nred        = \"#FF4D51\"\ngreen      = \"#35D450\"\nyellow     = \"#E9E836\"\nblue       = \"#5DC5F8\"\ndark-blue  = \"#24ACD4\"\nmagenta    = \"#FEABF2\"\ncyan       = \"#24DFC4\"\nwhite      = \"#ffffff\"\npunct      = \"#C9C9C9\"\n\n# Grays\nblack      = \"#1e1e1e\"\ndark-bg    = \"#242424\"\nmedium-bg  = \"#2D2D2D\"\nlight-bg   = \"#353535\"\nindent     = \"#616161\"\ndark-fg    = \"#929292\"\nlight-fg   = \"#E6E6E6\"\n"
  },
  {
    "path": "runtime/themes/sunset.toml",
    "content": "# Sunset\n# Author : Egor Afanasin <afanasin.egor@gmail.com>\n# Repo: https://github.com/pithecantrope/sunset\n\n# Syntax highlighting\n# ----------------------------------------------------------------\nattribute = \"mud\"\n\ntype = \"mud\"\n\"type.builtin\" = { fg = \"mud\", modifiers = [\"italic\"] }\n\nconstructor = \"wood\"\n\nconstant = \"fire\"\n\"constant.builtin\"   = { fg = \"fire\", modifiers = [\"italic\"] }\n\"constant.character\" = \"wood\"\n\"constant.numeric\"   = \"wood\"\n\nstring = \"grass\"\n\"string.regexp\"  = \"mud\"\n\"string.special\" = \"rose\"\n\"string.special.symbol\" = \"fire\"\n\ncomment = { fg = \"cmnt\", modifiers = [\"italic\"] }\n\"comment.block.documentation\" = \"grass\"\n\"comment.line.documentation\" = \"grass\"\n\nvariable = \"text\"\n\"variable.builtin\"   = { fg = \"sky\", modifiers = [\"italic\"] }\n\"variable.parameter\" = \"rose\"\n\"variable.other.member\" = \"pink\"\n\nlabel = \"sky\"\n\npunctuation = \"cmnt\"\n\"punctuation.special\" = \"wine\"\n\nkeyword = \"sun\"\n\"keyword.control.return\"    = { fg = \"sun\", modifiers = [\"italic\"] }\n\"keyword.control.exception\" = { fg = \"sun\", modifiers = [\"italic\"] }\n\"keyword.directive\" = \"sky\"\n\noperator = \"wine\"\n\nfunction = \"peach\"\n\"function.builtin\" = { fg = \"peach\", modifiers = [\"italic\"] }\n\"function.macro\"   = \"sky\"\n\ntag = \"peach\"\n\nnamespace = { fg = \"text\", modifiers = [\"italic\"] }\n\nspecial = \"wine\"\n\n# Editor interface\n# ----------------------------------------------------------------\n\"markup.heading.marker\" = \"sun\"\n\"markup.heading.1\" = \"fire\"\n\"markup.heading.2\" = \"wine\"\n\"markup.heading.3\" = \"rose\"\n\"markup.heading.4\" = \"peach\"\n\"markup.heading.5\" = \"grass\"\n\"markup.heading.6\" = \"wood\"\n\n\"markup.list\" = \"wood\"\n\n\"markup.bold\"          = { modifiers = [\"bold\"] }\n\"markup.italic\"        = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\n\"markup.link.url\"   = { fg = \"sky\", underline.style = \"line\" }\n\"markup.link.label\" = \"sky\"\n\"markup.link.text\"  = \"mud\"\n\n\"markup.quote\" = \"mud\"\n\n\"markup.raw\" = \"pink\"\n\n\"diff.plus\"  = \"grass\"\n\"diff.minus\" = \"attn\"\n\"diff.delta\" = \"sky\"\n\n# User interface\n# ----------------------------------------------------------------\n\"ui.background\" = { fg = \"text\", bg = \"base\" }\n\n\"ui.cursor\" = { fg = \"base\", bg = \"cmnt\" }\n\"ui.cursor.primary.normal\" = { fg = \"base\", bg = \"text\" }\n\"ui.cursor.primary.insert\" = { fg = \"base\", bg = \"grass\" }\n\"ui.cursor.primary.select\" = { fg = \"base\", bg = \"sky\" }\n\"ui.cursor.match\" = { fg = \"attn\", modifiers = [\"bold\"] }\n\n# TODO: ui.debug\n\n\"ui.linenr\" = \"block\"\n\"ui.linenr.selected\" = \"cmnt\"\n\n\"ui.statusline\" = { bg = \"block\" }\n\"ui.statusline.inactive\" = { fg = \"cmnt\" }\n\"ui.statusline.normal\"   = { fg = \"block\", bg = \"text\",  modifiers = [\"bold\"] }\n\"ui.statusline.insert\"   = { fg = \"block\", bg = \"grass\", modifiers = [\"bold\"] }\n\"ui.statusline.select\"   = { fg = \"block\", bg = \"sky\",   modifiers = [\"bold\"] }\n\n\"ui.bufferline\" = { fg = \"cmnt\", bg = \"block\" }\n\"ui.bufferline.active\" = \"fire\"\n\n\"ui.popup\" = { fg = \"text\", bg = \"base\" }\n\"ui.popup.info\" = { fg = \"text\", bg = \"block\" }\n\n\"ui.picker.header\" = { underline.style = \"line\" }\n\n\"ui.window\" = { fg = \"block\", modifiers = [\"bold\"] }\n\n\"ui.help\" = { fg = \"text\", bg = \"block\" }\n\n\"ui.text\" = \"text\"\n\"ui.text.focus\"     = \"sun\"\n\"ui.text.inactive\"  = { fg = \"cmnt\", modifiers = [\"italic\"] }\n\"ui.text.info\"      = { bg = \"block\" }\n\"ui.text.directory\" = \"sky\"\n\n\"ui.virtual\" = { fg = \"block\" }\n\"ui.virtual.ruler\"        = { bg = \"block\" }\n\"ui.virtual.jump-label\"   = { fg = \"attn\", modifiers = [\"bold\"] }\n\n\"ui.menu\" = { fg = \"text\", bg = \"base\" }\n\"ui.menu.selected\" = { bg = \"sel\" }\n\"ui.menu.scroll\"   = \"block\"\n\n\"ui.selection\" = { bg = \"sel\" }\n\n\"ui.highlight\" = { bg = \"sel\" }\n\nerror   = \"attn\"\nwarning = \"fire\"\ninfo    = \"sky\"\nhint    = \"mud\"\n\ndiagnostic = { underline.style = \"line\" }\n\n[palette]\n# Reddish\nfire  = \"#EE7711\"\nrose  = \"#EE7777\"\npeach = \"#EEBB77\"\npink  = \"#EEAAAA\"\nwood  = \"#997755\"\n\n# Greenish\ngrass = \"#66CC33\"\nmud   = \"#AACC77\"\nsun   = \"#EEEE11\"\n\n# Bluish\nsky   = \"#77AAAA\"\nwine  = \"#775599\"\n\n# Ui\nbase  = \"#111111\"\nblock = \"#222222\"\nsel   = \"#333333\"\ncmnt  = \"#777777\"\ntext  = \"#EEEEEE\"\nattn  = \"#EE1111\"\n"
  },
  {
    "path": "runtime/themes/term16_dark.toml",
    "content": "# Author: dgkf\n\n\"ui.background\" = { }\n\"ui.background.separator\" = { fg = \"red\" }\n\"ui.cursor\" = { fg = \"light-gray\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"light-yellow\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"light-gray\", modifiers = [\"reversed\"] }\n\"ui.cursor.secondary\" = { fg = \"gray\", modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { bg = \"black\" }\n\"ui.gutter\" = { }\n\"ui.gutter.selected\" = { bg = \"black\" }\n\"ui.help\" = { fg = \"white\", bg = \"black\" }\n\"ui.linenr\" = { fg = \"gray\", modifiers = [\"bold\"] }\n\"ui.linenr.selected\" = { fg = \"white\", modifiers = [\"bold\"] }\n\"ui.menu\" = { fg = \"light-gray\", bg = \"gray\" }\n\"ui.menu.selected\" = { modifiers = [\"reversed\"] }\n\"ui.menu.scroll\" = { fg = \"light-blue\" }\n\"ui.popup\" = { bg = \"black\" }\n\"ui.selection\" = { bg = \"gray\" }\n\"ui.statusline\" = { fg = \"light-gray\", bg = \"gray\" }\n\"ui.statusline.inactive\" = { bg = \"black\" }\n\"ui.virtual\" = { bg = \"black\" }\n\"ui.virtual.indent-guide\" = { fg = \"gray\" }\n\"ui.virtual.whitespace\" = {}\n\"ui.virtual.wrap\" = { fg = \"gray\" }\n\"ui.virtual.inlay-hint\" = { fg = \"light-gray\", modifiers = [\"dim\", \"italic\"] }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"yellow\", modifiers = [\"dim\", \"italic\"] }\n\"ui.virtual.inlay-hint.type\" = { fg = \"blue\", modifiers = [\"dim\", \"italic\"] }\n\"ui.window\" = { fg = \"gray\", modifiers = [\"dim\"] }\n\n\"comment\" = { fg = \"light-gray\", modifiers = [\"italic\", \"dim\"] }\n\n\"attribute\" = \"light-yellow\"\n\"constant\" = { fg = \"light-yellow\", modifiers = [\"bold\", \"dim\"] }\n\"constant.numeric\" = \"light-yellow\"\n\"constant.character.escape\" = \"light-cyan\"\n\"constructor\" = \"light-blue\"\n\"function\" = \"light-blue\"\n\"function.macro\" = \"light-red\"\n\"function.builtin\" = { fg = \"light-blue\", modifiers = [\"bold\"] }\n\"tag\" = { fg = \"light-magenta\", modifiers = [\"dim\"] }\n\"type\" = \"blue\"\n\"type.builtin\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"type.enum.variant\" = { fg = \"light-magenta\", modifiers = [\"dim\"] }\n\"string\"  = \"light-green\"\n\"special\" = \"light-red\"\n\"variable\" = \"white\"\n\"variable.parameter\" = { fg = \"light-yellow\", modifiers = [\"italic\"] }\n\"variable.other.member\" = \"light-green\"\n\"keyword\" = \"light-magenta\"\n\"keyword.control.exception\" = \"light-red\"\n\"keyword.directive\" = { fg = \"light-yellow\", modifiers = [\"bold\"] }\n\"keyword.operator\" = { fg = \"light-blue\", modifiers = [\"bold\"] }\n\"label\" = \"light-green\"\n\"namespace\" = { fg = \"blue\", modifiers = [\"dim\"] }\n\n\"markup.heading\" = \"light-blue\"\n\"markup.list\" = \"light-red\"\n\"markup.bold\" = { fg = \"light-cyan\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"light-blue\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"magenta\", modifiers = [\"dim\"] }\n\"markup.link.text\" = \"light-magenta\"\n\"markup.quote\" = \"light-cyan\"\n\"markup.raw\" = \"light-green\"\n\n\"diff.plus\" = \"light-green\"\n\"diff.delta\" = \"light-yellow\"\n\"diff.minus\" = \"light-red\"\n\n\"diagnostic.hint\" = { underline = { color = \"gray\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"light-cyan\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"light-yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"light-red\", style = \"curl\" } }\n\n\"info\" = \"light-cyan\"\n\"hint\" = { fg = \"light-gray\", modifiers = [\"dim\"] }\n\"debug\" = \"white\"\n\"warning\" = \"yellow\"\n\"error\" = \"light-red\"\n"
  },
  {
    "path": "runtime/themes/term16_light.toml",
    "content": "# Author: dgkf\n# Modified from base16_terminal, Author: NNB <nnbnh@protonmail.com>\n\ninherits = \"term16_dark\"\n\n\"ui.background.separator\" = \"light-gray\"\n\"ui.cursor\" = { fg = \"gray\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"yellow\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"black\", modifiers = [\"reversed\"] }\n\"ui.cursor.secondary\" = { fg = \"gray\", modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { bg = \"white\" }\n\"ui.cursorline.secondary\" = { bg = \"white\" }\n\"ui.cursorcolumn.primary\" = { bg = \"white\" }\n\"ui.cursorcolumn.secondary\" = { bg = \"white\" }\n\"ui.gutter\" = { }\n\"ui.gutter.selected\" = { bg = \"white\" }\n\"ui.linenr\" = { fg = \"gray\", modifiers = [\"dim\"] }\n\"ui.linenr.selected\" = { fg = \"black\",  modifiers = [\"bold\"] }\n\"ui.menu\" = { bg = \"light-gray\" }\n\"ui.menu.selected\" = { fg = \"white\", bg = \"gray\", modifiers = [\"bold\"] }\n\"ui.menu.scroll\" = { fg = \"light-blue\" }\n\"ui.help\" = { }\n\"ui.text\" = { }\n\"ui.text.focus\" = { }\n\"ui.popup\" = { bg = \"white\" }\n\"ui.selection\" = { bg = \"light-gray\" }\n\"ui.statusline\" = { bg = \"white\" }\n\"ui.statusline.inactive\" = { fg = \"gray\", modifiers = [\"underlined\"] }\n\"ui.statusline.insert\" = { fg = \"white\", bg = \"blue\" }\n\"ui.statusline.select\" = { fg = \"white\", bg = \"magenta\" }\n\"ui.virtual\" = { fg = \"light-gray\" }\n\"ui.virtual.indent-guide\" = { fg = \"light-gray\", modifiers = [\"dim\"] }\n\"ui.virtual.ruler\" = { bg = \"white\" }\n\"ui.virtual.wrap\" = { fg = \"light-gray\" }\n\"ui.window\" = { fg = \"gray\", modifiers = [\"dim\"] }\n\n\"comment\" = { fg = \"gray\", modifiers = [\"italic\", \"dim\"] }\n\n\"attribute\" = \"yellow\"\n\"constant\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"constant.numeric\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"constant.character.escape\" = \"blue\"\n\"constructor\" = \"blue\"\n\"function\" = \"blue\"\n\"function.builtin\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"tag\" = { fg = \"magenta\", modifiers = [\"dim\"] }\n\"type\" = \"blue\"\n\"type.builtin\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"type.enum.variant\" = { fg = \"magenta\", modifiers = [\"dim\"] }\n\"string\"  = \"green\"\n\"special\" = \"red\"\n\"variable\" = { fg = \"black\", modifiers = [\"dim\"] }\n\"variable.parameter\" = { fg = \"red\", modifiers = [\"italic\", \"dim\"] }\n\"variable.other.member\" = \"green\"\n\"keyword\" = \"magenta\"\n\"keyword.control.exception\" = \"red\"\n\"keyword.directive\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"keyword.operator\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"label\" = \"red\"\n\"namespace\" = { fg = \"blue\", modifiers = [\"dim\"] }\n\n\"markup.heading\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.list\" = \"red\"\n\"markup.bold\" = { fg = \"cyan\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"blue\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"magenta\", modifiers = [\"dim\"] }\n\"markup.link.text\" = { fg = \"magenta\", modifiers = [\"bold\"] }\n\"markup.quote\" = \"cyan\"\n\"markup.raw\" = \"blue\"\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"yellow\"\n\"diff.minus\" = \"red\"\n\n\"diagnostic.hint\" = { underline = { color = \"cyan\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"blue\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"yellow\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"red\", style = \"curl\" } }\n\n\"hint\" = \"cyan\"\n\"info\" = \"blue\"\n\"debug\" = \"light-yellow\"\n\"warning\" = \"yellow\"\n\"error\" = \"red\"\n"
  },
  {
    "path": "runtime/themes/tokyonight.toml",
    "content": "# Author: Paul Graydon <untimely.creation97@proton.me>\n\nattribute = { fg = \"cyan\" }\ncomment = { fg = \"comment\", modifiers = [\"italic\"] }\n\"comment.block.documentation\" = { fg = \"yellow\" }\n\"comment.line.documentation\" = { fg = \"yellow\" }\nconstant = { fg = \"orange\" }\n\"constant.builtin\" = { fg = \"aqua\" }\n\"constant.character\" = { fg = \"light-green\" }\n\"constant.character.escape\" = { fg = \"magenta\" }\nconstructor = { fg = \"aqua\" }\nfunction = { fg = \"blue\", modifiers = [\"italic\"] }\n\"function.builtin\" = { fg = \"aqua\" }\n\"function.macro\" = { fg = \"cyan\" }\n\"function.special\" = { fg = \"cyan\" }\nkeyword = { fg = \"purple\", modifiers = [\"italic\"] }\n\"keyword.control\" = { fg = \"magenta\" }\n\"keyword.control.import\" = { fg = \"cyan\" }\n\"keyword.control.return\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"keyword.directive\" = { fg = \"cyan\" }\n\"keyword.function\" = { fg = \"magenta\" }\n\"keyword.operator\" = { fg = \"magenta\" }\nlabel = { fg = \"blue\" }\nnamespace = { fg = \"cyan\" }\noperator = { fg = \"turquoise\" }\npunctuation = { fg = \"turquoise\" }\nspecial = { fg = \"aqua\" }\nstring = { fg = \"light-green\" }\n\"string.regexp\" = { fg = \"light-cyan\" }\n\"string.special\" = { fg = \"aqua\" }\ntag = { fg = \"magenta\" }\ntype = { fg = \"aqua\" }\n\"type.builtin\" = { fg = \"aqua\" }\n\"type.enum.variant\" = { fg = \"orange\" }\nvariable = { fg = \"fg\" }\n\"variable.builtin\" = { fg = \"red\" }\n\"variable.other.member\" = { fg = \"green\" }\n\"variable.parameter\" = { fg = \"yellow\", modifiers = [\"italic\"] }\n\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.heading\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.heading.completion\" = { bg = \"bg-menu\", fg = \"fg\" }\n\"markup.heading.hover\" = { bg = \"fg-selected\" }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link\" = { fg = \"blue\", underline = { style = \"line\" } }\n\"markup.link.label\" = { fg = \"teal\" }\n\"markup.link.text\" = { fg = \"teal\" }\n\"markup.link.url\" = { underline = { style = \"line\" } }\n\"markup.list\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.normal.completion\" = { fg = \"comment\" }\n\"markup.normal.hover\" = { fg = \"fg-dark\" }\n\"markup.raw\" = { fg = \"teal\" }\n\"markup.raw.inline\" = { bg = \"black\", fg = \"blue\" }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\n\"diff.delta\" = { fg = \"change\" }\n\"diff.delta.moved\" = { fg = \"blue\" }\n\"diff.minus\" = { fg = \"delete\" }\n\"diff.plus\" = { fg = \"add\" }\n\nerror = { fg = \"error\" }\nwarning = { fg = \"yellow\" }\ninfo = { fg = \"info\" }\nhint = { fg = \"hint\" }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"error\" } }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"yellow\"} }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"info\"} }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"hint\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\n\"ui.background\" = { bg = \"bg\", fg = \"fg\" }\n\"ui.cursor\" = { modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"ui.cursorline.primary\" = { bg = \"bg-menu\" }\n\"ui.help\" = { bg = \"bg-menu\", fg = \"fg\" }\n\"ui.linenr\" = { fg = \"fg-gutter\" }\n\"ui.linenr.selected\" = { fg = \"fg-linenr\" }\n\"ui.menu\" = { bg = \"bg-menu\", fg = \"fg\" }\n\"ui.menu.selected\" = { bg = \"fg-selected\" }\n\"ui.popup\" = { bg = \"bg-menu\", fg = \"border-highlight\" }\n\"ui.selection\" = { bg = \"bg-selection\" }\n\"ui.selection.primary\" = { bg = \"bg-selection\" }\n\"ui.statusline\" = { bg = \"bg-menu\", fg = \"fg-dark\" }\n\"ui.statusline.inactive\" = { bg = \"bg-menu\", fg = \"fg-gutter\" }\n\"ui.statusline.normal\" = { bg = \"blue\", fg = \"bg\", modifiers = [\"bold\"] }\n\"ui.statusline.insert\" = { bg = \"light-green\", fg = \"bg\", modifiers = [\"bold\"] }\n\"ui.statusline.select\" = { bg = \"magenta\", fg = \"bg\", modifiers = [\"bold\"] }\n\"ui.text\" = { fg = \"fg\" }\n\"ui.text.focus\" = { bg = \"bg-focus\" }\n\"ui.text.inactive\" = { fg = \"comment\", modifiers = [\"italic\"] }\n\"ui.text.info\" = { bg = \"bg-menu\", fg = \"fg\" }\n\"ui.text.directory\" = { fg = \"cyan\" }\n\"ui.virtual.ruler\" = { bg = \"fg-gutter\" }\n\"ui.virtual.whitespace\" = { fg = \"fg-gutter\" }\n\"ui.virtual.inlay-hint\" = {  bg = \"bg-inlay\", fg = \"teal\" }\n\"ui.virtual.jump-label\" = {  fg = \"orange\", modifiers = [\"bold\"] }\n\"ui.window\" = { fg = \"border\", modifiers = [\"bold\"] }\n\n[palette]\nred = \"#f7768e\"\norange = \"#ff9e64\"\nyellow = \"#e0af68\"\nlight-green = \"#9ece6a\"\ngreen = \"#73daca\"\naqua = \"#2ac3de\"\nteal = \"#1abc9c\"\nturquoise = \"#89ddff\"\nlight-cyan = \"#b4f9f8\"\ncyan = \"#7dcfff\"\nblue = \"#7aa2f7\"\npurple = \"#9d7cd8\"\nmagenta = \"#bb9af7\"\ncomment = \"#565f89\"\nblack = \"#414868\"\n\nadd = \"#449dab\"\nchange = \"#6183bb\"\ndelete = \"#914c54\"\n\nerror = \"#db4b4b\"\ninfo = \"#0db9d7\"\nhint = \"#1abc9c\"\n\nfg = \"#c0caf5\"\nfg-dark = \"#a9b1d6\"\nfg-gutter = \"#3b4261\"\nfg-linenr = \"#737aa2\"\nfg-selected = \"#343a55\"\nborder = \"#15161e\"\nborder-highlight = \"#27a1b9\"\nbg = \"#1a1b26\"\nbg-inlay = \"#1a2b32\"\nbg-selection = \"#283457\"\nbg-menu = \"#16161e\"\nbg-focus = \"#292e42\"\n"
  },
  {
    "path": "runtime/themes/tokyonight_day.toml",
    "content": "# Author: Paul Graydon <untimely.creation97@proton.me>\n\ninherits = \"tokyonight\"\n\n[palette]\nred = \"#f52a65\"\norange = \"#b15c00\"\nyellow = \"#8c6c3e\"\nlight-green = \"#587539\"\ngreen = \"#387068\"\naqua = \"#188092\"\nteal = \"#118c74\"\nturquoise = \"#006a83\"\nlight-cyan = \"#2e5857\"\ncyan = \"#007197\"\nblue = \"#2e7de9\"\npurple = \"#7847bd\"\nmagenta = \"#9854f1\"\ncomment = \"#848cb5\"\nblack = \"#a1a6c5\"\n\nadd = \"#aecde6\"\nchange = \"#d6d8e3\"\ndelete = \"#dfccd4\"\n\nerror = \"#c64343\"\nhint = \"#118c74\"\ninfo = \"#07879d\"\n\nfg = \"#3760bf\"\nfg-dark = \"#6172b0\"\nfg-gutter = \"#a8aecb\"\nfg-linenr = \"#68709a\"\nfg-selected = \"#b3b8d1\"\nborder = \"#e9e9ed\"\nborder-highlight = \"#2496ac\"\nbg = \"#e1e2e7\"\nbg-inlay = \"#acd7eb\"\nbg-selection = \"#c4c8da\"\nbg-menu = \"#e9e9ec\"\nbg-focus = \"#b6bfe2\"\n"
  },
  {
    "path": "runtime/themes/tokyonight_moon.toml",
    "content": "# Author: Paul Graydon <untimely.creation97@proton.me>\n\ninherits = \"tokyonight\"\n\n[palette]\nred = \"#ff757f\"\norange = \"#ff966c\"\nyellow = \"#ffc777\"\nlight-green = \"#c3e88d\"\ngreen = \"#4fd6be\"\naqua = \"#65bcff\"\nteal = \"#4fd6be\"\nturquoise = \"#89ddff\"\nlight-cyan = \"#b4f9f8\"\ncyan = \"#86e1fc\"\nblue = \"#82aaff\"\npurple = \"#fca7ea\"\nmagenta = \"#c099ff\"\ncomment = \"#636da6\"\nblack = \"#444a73\"\n\nadd = \"#b8db87\"\nchange = \"#7ca1f2\"\ndelete = \"#e26a75\"\n\nerror = \"#c53b53\"\nhint = \"#4fd6be\"\ninfo = \"#0db9d7\"\n\nfg = \"#c8d3f5\"\nfg-dark = \"#828bb8\"\nfg-gutter = \"#3b4261\"\nfg-linenr = \"#737aa2\"\nfg-selected = \"#363c58\"\nborder = \"#1b1d2b\"\nborder-highlight = \"#589ed7\"\nbg = \"#222436\"\nbg-inlay = \"#273644\"\nbg-selection = \"#2f334d\"\nbg-menu = \"#1e2030\"\nbg-focus = \"#2d3f76\"\n"
  },
  {
    "path": "runtime/themes/tokyonight_storm.toml",
    "content": "# Author: Paul Graydon <untimely.creation97@proton.me>\n\ninherits = \"tokyonight\"\n\n[palette]\nborder = \"#1d202f\"\nbg = \"#24283b\"\nbg-inlay = \"#233745\"\nbg-selection = \"#373d5a\"\nbg-menu = \"#1f2335\"\nbg-focus = \"#2e3c64\"\nborder-highlight = \"#29a4bd\"\n"
  },
  {
    "path": "runtime/themes/ttox.toml",
    "content": "# Author : Tomas Ruud <git@me.2ms.no>\n\n\"ui.selection\" = { fg = \"white\", bg = \"gray\" }\n\"ui.cursor\" = { fg = \"black\", bg = \"light-gray\" }\n\"ui.cursor.primary\" = { fg = \"black\", bg = \"light-gray\" }\n\"ui.cursor.match\" = { modifiers = [\"underlined\"] }\n\"ui.background.separator\" = \"gray\"\n\"ui.linenr\" = \"gray\"\n\"ui.linenr.selected\" = { fg = \"white\", bg = \"gray\" }\n\"ui.statusline\" = { bg = \"black\", fg = \"white\" }\n\"ui.menu\" = { fg = \"white\", bg = \"black\" }\n\"ui.menu.selected\" = { bg = \"light-gray\", fg = \"black\" }\n\"ui.popup\" = { fg = \"white\", bg = \"black\" }\n\"ui.help\" = { fg = \"white\", bg = \"black\" }\n\"ui.virtual.ruler\" = { underline = { style = \"line\"} }\n\n\"string\" = { bg = \"light-green\", fg = \"black\" }\n\"constant\" = { bg = \"light-cyan\", fg = \"black\" }\n\"comment\" = { bg = \"light-magenta\", fg = \"black\" }\n\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"gray\"\n\n\"warning\" = { fg = \"black\", bg = \"light-yellow\" }\n\"error\" = { fg = \"black\", bg = \"light-red\" }\n\"hint\" = { fg = \"black\", bg = \"light-blue\" }\n\n\"diagnostic.warning\" = { fg = \"black\", bg = \"light-yellow\" }\n\"diagnostic.error\" = { fg = \"black\", bg = \"light-red\" }\n\"diagnostic.hint\" = { fg = \"black\", bg = \"light-blue\" }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n"
  },
  {
    "path": "runtime/themes/ttox_soft.toml",
    "content": "# Author : Samuel Guyah <ssguyah@gmail.com>\n\n\"ui.selection\" = { fg = \"white\", bg = \"gray\" }\n\"ui.cursor\" = { fg = \"black\", bg = \"light-gray\" }\n\"ui.cursor.primary\" = { fg = \"black\", bg = \"light-gray\" }\n\"ui.cursor.match\" = { modifiers = [\"underlined\"] }\n\"ui.background.separator\" = \"gray\"\n\"ui.linenr\" = \"gray\"\n\"ui.linenr.selected\" = { fg = \"white\", bg = \"gray\" }\n\"ui.statusline\" = { bg = \"black\", fg = \"white\" }\n\"ui.menu\" = { fg = \"white\", bg = \"black\" }\n\"ui.menu.selected\" = { bg = \"light-gray\", fg = \"black\" }\n\"ui.popup\" = { fg = \"white\", bg = \"black\" }\n\"ui.help\" = { fg = \"white\", bg = \"black\" }\n\"ui.virtual.ruler\" = { underline = { style = \"line\" } }\n\"ui.bufferline\" = { fg = \"white\", bg = \"black\" }\n\"ui.bufferline.active\" = { fg = \"black\", bg = \"white\" }\n\"ui.bufferline.background\" = { bg = \"black\" }\n\n\n\"string\" = { fg = \"light-green\" }\n\"constant\" = { fg = \"light-cyan\" }\n\"comment\" = { fg = \"light-magenta\" }\n\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"gray\"\n\n\"warning\" = { fg = \"light-yellow\" }\n\"error\" = { fg = \"light-red\" }\n\"hint\" = { fg = \"light-blue\" }\n\n\"diagnostic.warning\" = { fg = \"light-yellow\" }\n\"diagnostic.error\" = { fg = \"light-red\" }\n\"diagnostic.hint\" = { fg = \"light-blue\" }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n"
  },
  {
    "path": "runtime/themes/varua.toml",
    "content": "# Varua: an easy on the eyes color palette based on Gruvbox Material and Everforest by sainnhe.\n# Author : Kamek <b.kamek@gmail.com>\n\n\"constant.character.escape\" = \"orange\"\n\"type\" = \"blue\"\n\"constant\" = \"purple\"\n\"constant.numeric\" = \"purple\"\n\"string\" = \"green\"\n\"comment\" = \"grey0\"\n\"variable\" = \"fg\"\n\"variable.builtin\" = \"blue\"\n\"variable.parameter\" = \"fg\"\n\"variable.other.member\" = \"fg\"\n\"label\" = \"aqua\"\n\"punctuation\" = \"grey2\"\n\"punctuation.delimiter\" = \"grey2\"\n\"punctuation.bracket\" = \"fg\"\n\"keyword\" = \"purple\"\n\"operator\" = \"orange\"\n\"function\" = \"green\"\n\"function.builtin\" = \"blue\"\n\"function.macro\" = \"aqua\"\n\"tag\" = \"yellow\"\n\"namespace\" = \"aqua\"\n\"attribute\" = \"aqua\"\n\"constructor\" = \"aqua\"\n\"module\" = \"blue\"\n\"special\" = \"orange\"\n\n\"markup.heading.marker\" = \"grey2\"\n\"markup.heading.1\" = { fg = \"red\", modifiers = [\"bold\"] }\n\"markup.heading.2\" = { fg = \"orange\", modifiers = [\"bold\"] }\n\"markup.heading.3\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.heading.4\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"markup.heading.5\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"markup.heading.6\" = { fg = \"fg\", modifiers = [\"bold\"] }\n\"markup.list\" = \"red\"\n\"markup.link.url\" = { fg = \"blue\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"purple\"\n\"markup.quote\" = \"grey2\"\n\"markup.raw\" = \"green\"\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"orange\"\n\"diff.minus\" = \"red\"\n\n\"ui.background\" = { bg = \"bg0\" }\n\"ui.cursorline.primary\" = { bg = \"bg6\" }\n\"ui.cursor\" = { fg = \"bg0\", bg = \"fg\" }\n\"ui.cursor.match\" = { fg = \"orange\", bg = \"bg_yellow\" }\n\"ui.cursor.insert\" = { fg = \"bg0\", bg = \"grey1\" }\n\"ui.cursor.select\" = { fg = \"bg0\", bg = \"blue\" }\n\"ui.linenr\" = \"grey0\"\n\"ui.linenr.selected\" = \"fg\"\n\"ui.statusline\" = { fg = \"fg\", bg = \"bg2\" }\n\"ui.statusline.inactive\" = { fg = \"grey0\", bg = \"bg1\" }\n\"ui.popup\" = { fg = \"grey0\", bg = \"bg2\" }\n\"ui.window\" = { fg = \"grey0\", bg = \"bg1\" }\n\"ui.help\" = { fg = \"fg\", bg = \"bg1\" }\n\"ui.text\" = \"fg\"\n\"ui.text.focus\" = \"fg\"\n\"ui.menu\" = { fg = \"fg\", bg = \"bg2\" }\n\"ui.menu.selected\" = { fg = \"fg\", bg = \"bg1\" }\n\"ui.selection\" = { bg = \"bg3\" }\n\"ui.virtual.whitespace\" = \"grey0\"\n\"ui.statusline.insert\" = { bg = \"green\", fg = \"bg2\" }\n\"ui.statusline.select\" = { bg = \"blue\", fg = \"bg2\" }\n\"ui.virtual.wrap\" = { fg = \"grey0\" }\n\"ui.virtual.inlay-hint\" = { fg = \"grey1\" }\n\"ui.virtual.ruler\" = { bg = \"bg2\"}\n\n\"hint\" = \"blue\"\n\"info\" = \"aqua\"\n\"warning\" = \"yellow\"\n\"error\" = \"red\"\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"blue\" } }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"aqua\" } }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"yellow\" } }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"red\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"ui.virtual.jump-label\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n[palette]\nbg0 = \"#282828\"\nbg1 = \"#45403d\"\nbg2 = \"#32302f\"\nbg3 = \"#3c3836\"\nbg4 = \"#4c555b\"\nbg5 = \"#53605c\"\nbg6 = \"#2c2c2c\"\nbg_visual = \"#503946\"\nbg_red = \"#4e3e43\"\nbg_green = \"#404d44\"\nbg_blue = \"#394f5a\"\nbg_yellow = \"#4a4940\"\n\nfg = \"#dfbf8e\"\nred = \"#e67e80\"\norange = \"#e69875\"\nyellow = \"#dbbc7f\"\ngreen = \"#a7c080\"\naqua = \"#83c092\"\nblue = \"#7fbbb3\"\npurple = \"#d699b6\"\ngrey0 = \"#928374\"\ngrey1 = \"#859289\"\ngrey2 = \"#9da9a0\"\n"
  },
  {
    "path": "runtime/themes/vesper-transparent.toml",
    "content": "# Author: IwantHappiness <IwantHappiness95@gmail.com>\n\ninherits = \"vesper\"\n\n\"markup.raw\" = { bg = \"white\" }\n\"markup.normal\" = { bg = \"white\" }\n\"markup.heading\" = { bg = \"white\" }\n\n# UI\n\"ui.window\" = { bg = \"white\" }\n\"ui.background\" = { fg = \"white\" }\n\n[palette]\nred = \"#ff8080\"\ngray = \"#A0A0A0\"\nwhite = \"#ffffff\"\nbeige = \"#ffc799\"\nblack = \"#101010\"\ndim-gray = \"#505050\"\ndark-gray = \"#1C1C1C\"\nbright-green = \"#99FFE4\"\n\ncursor = \"#aeafad\"\ncomment = \"#8b8b8b\"\nbg-selection = \"#666666\"\n"
  },
  {
    "path": "runtime/themes/vesper.toml",
    "content": "# Author: IwantHappiness <IwantHappiness95@gmail.com>\n\ntag = { fg = \"beige\" }\ntype = { fg = \"beige\" }\n\nlabel = { fg = \"beige\" }\n\noperator = { fg = \"gray\" }\n\nattribute = { fg = \"gray\" }\n\nfunction = { fg = \"beige\" }\n\nnamespace = { fg = \"beige\" }\n\ncomment = { fg = \"comment\" }\n\nconstructor = { fg = \"beige\" }\n\nconstant = { fg = \"beige\" }\n\"constant.character.escape\" = { fg = \"gray\" }\n\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.link\" = { fg = \"bright-green\", underline = { style = \"line\" } }\n\nvariable = { fg = \"white\" }\n\"variable.builtin\" = { fg = \"gray\" }\n\"variable.parameter\" = { modifiers = [\"italic\"] }\n\n\"murkup.raw\" = { bg = \"white\" }\n\"murkup.normal\" = { bg = \"white\" }\n\"murkup.heading\" = { bg = \"white\" }\n\n\"diff.delta\" = { fg = \"beige\" }\n\"diff.minus\" = { fg = \"#FF8080\" }\n\"diff.plus\" = { fg = \"bright-green\" }\n\nstring = { fg = \"bright-green\" }\n\"string.regexp\" = { fg = \"gray\" }\n\"string.special.path\" = { fg = \"gray\" }\n\"string.special.url\" = { fg = \"white\", underline = { style = \"line\" } }\n\npunctuation = { fg = \"gray\" }\n\"punctuation.bracket\" = { fg = \"gray\" }\n\"punctuation.delimiter\" = { fg = \"white\" }\n\"punctuation.special\" = { fg = \"bright-green\" }\n\nkeyword = { fg = \"gray\" }\n\"keyword.operator\" = { fg = \"beige\" }\n\"keyword.function\" = { fg = \"beige\" }\n\"keyword.directive\" = { fg = \"beige\" }\n\"keyword.storage.type\" = { fg = \"beige\" }\n\"keyword.control.repeat\" = { fg = \"gray\" }\n\"keyword.control.import\" = { fg = \"beige\" }\n\"keyword.control.conditional\" = { fg = \"gray\" }\n\nerror = { fg = \"red\" }\nhint = { fg = \"gray\" }\ninfo = { fg = \"white\" }\nwarning = { fg = \"beige\" }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"diagnostic.error\" = { underline = { style = \"curl\", color = \"red\" } }\n\"diagnostic.warning\" = { underline = { style = \"curl\", color = \"beige\"} }\n\"diagnostic.info\" = { underline = { style = \"curl\", color = \"white\"} }\n\"diagnostic.hint\" = { underline = { style = \"curl\", color = \"gray\" } }\n\n# tabstop = { bg = \"white\" }\n\n# UI\n# \"ui.window\" = { bg = \"white\" }\n\n\"ui.popup\" = { bg = \"dark-gray\" }\n \n\"ui.selection\" = { bg = \"bg-selection\" }\n\n\"ui.help\" = { bg = \"dark-gray\", fg = \"beige\" }\n\n\"ui.background\" = { bg = \"black\", fg = \"white\" }\n\n\"ui.picker.header.column.active\" = { bg = \"gray\" }\n\n\"ui.linenr\" = { fg = \"dim-gray\" }\n\"ui.linenr.selected\" = { fg = \"white\" }\n\n\"ui.virtual.whitespace\" = { fg = \"dim-gray\" }\n\"ui.virtual.inlay-hint\" = { bg = \"dark-gray\", fg = \"gray\" }\n\n\"ui.text\" = { fg = \"white\" }\n\"ui.text.inactive\" = { fg = \"comment\" }\n\"ui.text.focus\" = { bg = \"bright-green\", fg = \"black\" }\n\n\"ui.menu.scroll\" = { fg = \"white\" }\n\"ui.menu.selected\" = { bg = \"dim-gray\" }\n\"ui.menu\" = { fg = \"white\", bg = \"dark-gray\" }\n\n\"ui.statusline\" = { bg = \"dark-gray\" }\n\"ui.statusline.inactive\" = { bg = \"dark-gray\" }\n\"ui.statusline.select\" = { bg = \"red\", fg = \"black\" }\n\"ui.statusline.normal\" = { bg = \"beige\", fg = \"black\" }\n\"ui.statusline.insert\" = { bg = \"bright-green\", fg = \"black\" }\n\n\"ui.cursor.insert\" = { bg = \"bright-green\" }\n\"ui.cursorline.primary\" = { bg = \"dark-gray\" }\n\"ui.cursorline.secondary\" = { bg = \"dark-gray\" }\n\"ui.cursor.primary\" = { bg = \"cursor\", fg = \"black\" }\n\"ui.cursor\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\n[palette]\nred = \"#ff8080\"\ngray = \"#A0A0A0\"\nwhite = \"#ffffff\"\nbeige = \"#ffc799\"\nblack = \"#101010\"\ndim-gray = \"#505050\"\ndark-gray = \"#1C1C1C\"\nbright-green = \"#99FFE4\"\n\ncursor = \"#aeafad\"\ncomment = \"#8b8b8b\"\nbg-selection = \"#666666\"\n"
  },
  {
    "path": "runtime/themes/vim_dark_high_contrast.toml",
    "content": "\"ui.background\" = { bg = \"black\" }\n\"ui.bufferline\" = { bg = \"black\" }\n\"ui.bufferline.active\" = { fg = \"light-magenta\", bg = \"dark-magenta\" }\n\"ui.cursor\" = { fg = \"green\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"light-cyan\", bg = \"dark-cyan\" }\n\"ui.cursor.primary\" = { fg = \"light-green\", modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { bg = \"gray\" }\n\"ui.menu\" = { bg = \"dark-white\" }\n\"ui.menu.selected\" = { fg = \"yellow\" }\n\"ui.popup\" = { bg = \"dark-white\" }\n\"ui.selection\" = { bg = \"dark-white\" }\n\"ui.statusline\" = { fg = \"light-magenta\", bg = \"dark-magenta\" }\n\"ui.statusline.normal\" = { fg = \"black\", bg = \"light-yellow\" }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"light-cyan\" }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"yellow\" }\n\"ui.text\" = { fg = \"default\" }\n\"ui.text.info\" = { bg = \"dark-white\" }\n\"ui.text.focus\" = { fg = \"yellow\" }\n\"ui.virtual.wrap\" = { fg = \"dark-blue\" }\n\"ui.virtual.indent-guide\" = { fg = \"dark-blue\" }\n\"ui.virtual.ruler\" = { bg = \"dark-white\" }\n\"ui.virtual.jump-label\" = { fg = \"light-yellow\", modifiers = [\"bold\"] }\n\"ui.window\" = { bg = \"dark-white\" }\n\n\"diagnostic.error\" = { bg = \"dark-red\" }\n\"diagnostic.warning\" = { bg = \"dark-yellow\" }\n\"diagnostic.hint\" = { bg = \"dark-cyan\" }\n\"diagnostic.info\" = { bg = \"dark-white\" }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"warning\" = { fg = \"yellow\", bg = \"dark-yellow\" }\n\"error\" = { fg = \"red\", bg = \"dark-red\" }\n\"info\" = { fg = \"default\", bg = \"dark-white\" }\n\"hint\" = { fg = \"cyan\", bg = \"dark-cyan\" }\n\n\"type\" = \"green\"\n\"constructor\" = \"light-cyan\"\n\"constant\" = \"red\"\n\"constant.character.escape\" = \"magenta\"\n\"string\" = \"red\"\n\"comment\" = \"light-black\"\n\"comment.documentation\" = \"magenta\"\n\"label\" = \"green\"\n\"keyword\" = \"yellow\"\n\"keyword.directive\" = \"magenta\"\n\"function\" = \"light-cyan\"\n\"function.macro\" = \"magenta\"\n\"special\" = \"cyan\"\n\n\"diff.plus\" = \"green\"\n\"diff.minus\" = \"red\"\n\"diff.delta\" = \"yellow\"\n\n[palette]\nblack = \"#000000\"\nred = \"#ed5f74\"\ngreen = \"#1ea672\"\ngray = \"#111111\"\nyellow = \"#d97917\"\nblue = \"#688ef1\"\nmagenta = \"#c96ed0\"\ncyan = \"#3a97d4\"\nwhite = \"#e3e8ee\"\nlight-black = \"#697386\"\nlight-red = \"#fbb5b2\"\nlight-green = \"#85d996\"\nlight-yellow = \"#efc078\"\nlight-blue = \"#9fcdff\"\nlight-magenta = \"#f0b4e4\"\nlight-cyan = \"#7fd3ed\"\nlight-white = \"#ffffff\"\ndark-black = \"#000000\"\ndark-red = \"#742833\"\ndark-green = \"#00643c\"\ndark-yellow = \"#6e3500\"\ndark-blue = \"#2c4074\"\ndark-magenta = \"#602864\"\ndark-cyan = \"#144c71\"\ndark-white = \"#3e4043\"\ndefault = \"#c1c9d2\"\n"
  },
  {
    "path": "runtime/themes/vintage.toml",
    "content": "# Vintage Theme for the Helix Editor\n# Author: rojebd<roniellberrios@gmail.com>\n# Repo: https://github.com/rojebd/vintage\n# This theme is vintage inspired\n# Info: I made this theme one afternoon because my bus was late and I stayed home :)\n\nattribute = \"#a7bf67\" \nkeyword = \"#A4A2B4\"  \n\"keyword.directive\" = \"light-gray\" \nnamespace = \"#7095bf\" \npunctuation = \"white\" \n\"punctuation.delimiter\" = \"white\"\noperator = \"muddy\" \nspecial = \"pink\" \n\"variable.other.member\" = \"green\" \nvariable = \"green\" \n\"variable.parameter\" = \"light-green\" \n\"variable.builtin\" = \"light-green\" \ntype = \"#efbe4c\" \n\"type.builtin\" = \"#efbe4c\" \nconstructor = \"#c19ef7\" \nfunction = \"muddy\" \n\"function.macro\" = \"muddy\" \n\"function.builtin\" = \"#db985e\" \ntag = \"#d37a78\" \ncomment = \"light-gray\" \nconstant = \"#A5C4D4\" \n\"constant.builtin\" = \"bright-yellow\" \nstring = \"#d6a560\" \n\"constant.numeric\" = \"#b577b0\" \n\"constant.character.escape\" = \"#c95c56\" \nlabel = \"#abcc8a\" \n\n\"markup.heading\" = \"bright-pink\" \n\"markup.bold\" = { fg = \"markdown-bold\", modifiers = [\"bold\"] } \n\"markup.italic\" = { fg = \"markdown-italic\", modifiers = [\"italic\"] } \n\"markup.strikethrough\" = { fg = \"bright-pink\", modifiers = [\"crossed_out\", \"bold\"] } \n\"markup.link.url\" = { fg = \"blueish\", modifiers = [\"underlined\"] } \n\"markup.link.text\" = \"orange\" \n\"markup.raw\" = \"gray\" \n\n\"diff.plus\" =  { fg = \"bright-green\", modifiers = [\"bold\"] }\n\"diff.minus\" = { fg = \"redish\",       modifiers = [\"bold\"] }\n\"diff.delta\" = { fg = \"blueish\",      modifiers = [\"bold\"] }\n\n\"ui.background\" = { bg = \"background\" } \n\"ui.background.separator\" = { fg = \"white\" } \n\"ui.linenr\" = { fg = \"#747575\" } \n\"ui.linenr.selected\" = { fg = \"#c7dddd\" } \n\"ui.statusline\" = { fg = \"black\", bg = \"gray\" } \n\"ui.statusline.inactive\" = { fg = \"gray\", bg = \"#3c3836\" } \n\"ui.popup\" = { bg = \"#3b3b3d\" } \n\"ui.window\" = { fg = \"yellow\" } \n\"ui.help\" = { bg = \"#35353a\", fg = \"light-gray\" } \n\n\"ui.text\" = { fg = \"light-gray\" } \n\"ui.text.focus\" = { fg = \"#83c679\" } \n\"ui.text.inactive\" = \"#93a56f\" \n\"ui.virtual\" = { fg = \"yellow\" } \n\"ui.virtual.indent-guide\" = { fg = \"#5b5b5a\" } \n\"ui.virtual.ruler\" = { bg = \"#363638\" }\n\n\"ui.selection\" = { fg = \"white\", bg = \"gray\" } \n\"ui.selection.primary\" = { fg = \"white\", bg = \"gray\" } \n\"ui.cursor.match\" = { fg = \"white\", bg = \"gray\" } \n\"ui.cursor\" = { modifiers = [\"reversed\"] } \n\"ui.cursorline.primary\" = { bg = \"#3b3b3f\" } \n\n\"ui.debug\" = { fg = \"#634450\" } \n\"ui.debug.breakpoint\" = { fg = \"redish\" } \n\"ui.debug.active\" = { fg = \"blueish\" } \n\"ui.menu\" = { fg = \"gray\", bg = \"black\" } \n\"ui.menu.selected\" = { fg = \"black\", bg = \"gray\" } \n\n\"diagnostic.hint\" = { underline = { color = \"bright-yellow\", style = \"curl\" } } \n\"diagnostic.info\" = { underline = { color = \"bright-yellow\", style = \"curl\" } }  \n\"diagnostic.warning\" = { underline = { color = \"bright-yellow\", style = \"curl\" } } \n\"diagnostic.error\" = { underline = { color = \"bright-pink\", style = \"curl\" } } \n\nwarning = \"bright-yellow\" \nerror = \"bright-pink\" \ninfo = \"bright-yellow\" \nhint = \"bright-yellow\" \n\n[palette]\nbright-pink = \"#DE6468\"\nbackground = \"#1f1f21\"\ngreen = \"#778e61\"\nlight-green = \"#9B9B7A\"\nbrown = \"#BAA587\"\npink = \"#D9AE94\"\nyellow = \"#F1DCA7\"\nbright-yellow = \"#FFCB69\"\norange = \"#E8AC65\"\nmuddy = \"#D08C60\"\nmarkdown-italic = \"#80a552\"\nmarkdown-bold = \"#6faa75\"\ndark-brown = \"#B58463\"\npurple-ish = \"#997B66\"\nbright-green = \"#4F6F52\"\nblueish = \"#3876BF\"\nredish = \"#B80000\"\n"
  },
  {
    "path": "runtime/themes/voxed.toml",
    "content": "# Voxed theme for the Helix Editor\n# Author: rojebd<roniellberrios@gmail.com>\n# Repo: https://github.com/rojebd/voxed\n# Version: 1.0\n# Info: This is a theme I made one afternoon because I was bored\n\nattribute = \"buff\"\nkeyword = \"sglow\"\n\"keyword.directive\" = \"defineish\" \nnamespace = \"blue\"\npunctuation = \"white\"\n\"punctuation.delimiter\" = \"functionish\"\noperator = \"greenish\"\nspecial = \"maize\"\n\"variable.other.member\" = \"bsienna\"\nvariable = \"tan\"\n\"variable.parameter\" = { fg = \"parameters\" }\n\"variable.builtin\" = \"white\"\ntype = \"light-blue\"\n\"type.builtin\" = \"functionish\" \nconstructor = \"typeish\"\nfunction = \"functionish\"\n\"function.macro\" = \"blue\"\n\"function.builtin\" = \"typeish\" \ntag = \"functionish\"\ncomment = \"bgrey\"\nconstant = \"tan\"\n\"constant.builtin\" = \"#D38588\"\nstring = \"redish\"\n\"constant.numeric\" = \"functionish\"\n\"constant.character.escape\" = \"cyan\"\nlabel = \"yellow\"\n\n\"markup.heading\" = \"functionish\"\n\"markup.list\" = \"status-two\"\n\"markup.quote\" = \"tan\"\n\"markup.bold\" = { fg = \"sglow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"sglow\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"sglow\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"greenish\"\n\"markup.raw\" = \"light-grey\"\n\n\"diff.plus\" = \"#7DDF64\"\n\"diff.minus\" = \"#F22B29\"\n\"diff.delta\" = \"#6f44f0\"\n\n\"ui.background\" = { fg = \"#25262B\", bg=\"#1f1f21\" }\n\"ui.background.separator\" = { fg = \"sglow\" }\n\"ui.linenr\" = { fg = \"light-grey\", modifiers = [\"italic\"] }\n\"ui.linenr.selected\" = { fg = \"bpink\", modifiers = [\"bold\"] }\n\n\"ui.statusline\" = { fg = \"black\", bg = \"light-grey\", modifiers = [\"bold\"] }\n\"ui.statusline.inactive\" = { fg = \"black\", bg = \"bgrey-two\" }\n\"ui.popup\" = { fg = \"bgrey\", bg = \"#25262B\" }\n\"ui.window\" = { fg = \"white\" }\n\"ui.help\" = { bg = \"#3f4047\", fg = \"light-grey\" }\n\n\"ui.text\" = { fg = \"white\" }\n\"ui.text.focus\" = { fg = \"maize\", bg = \"bgrey\" }\n\"ui.text.inactive\" = \"bgrey\"\n\"ui.virtual\" = { fg = \"blue\" }\n\"ui.virtual.ruler\" = { bg = \"bgrey-two\" }\n\"ui.virtual.indent-guide\" = { fg = \"gray\" }\n\n\n\"ui.selection\" = { bg = \"maize\" }\n\"ui.selection.primary\" = { fg = \"white\", bg = \"bgrey\" }\n\"ui.cursor.select\" = { bg = \"white\" }\n\"ui.cursor.insert\" = { bg = \"white\" }\n\"ui.cursor.match\" = { fg = \"#212121\", bg = \"#6C6999\" }\n\"ui.cursor\" = { bg = \"bgrey-two\", modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { bg = \"#44414c\" }\n\n\"ui.highlight\" = { bg = \"white\" }\n\"ui.highlight.frameline\" = { bg = \"#634450\" }\n\"ui.debug\" = { fg = \"#634450\" }\n\"ui.debug.breakpoint\" = { fg = \"bpink\" }\n\"ui.menu\" = { fg = \"white\", bg = \"#23232d\" }\n\"ui.menu.selected\" = { fg = \"white\", bg = \"bgrey\" }\n\"ui.menu.scroll\" = { fg = \"white\", bg = \"white\" }\n\n\"diagnostic.hint\" = { underline = { color = \"maize\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"sglow\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"redish\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"bpink\", style = \"curl\" } }\n\nwarning = \"bpink\"\nerror = \"bsienna\"\ninfo = \"maize\"\nhint = \"tan\"\n\n[palette]\nparameters = \"#d89182\"\ndefineish = \"#71c45c\"\nbuff = \"#f0dc82\"\ntan = \"#DAB785\"\ntypeish = \"#AAAAA5\"\ngreenish = \"#458588\"\nfunctionish = \"#b784a3\"\nbsienna = \"#D5896F\"\nbpink = \"#FF5964\"\nmaize = \"#FFE74C\"\nbgrey = \"#8c8681\"\nsglow = \"#FFCF56\"\nstatus = \"#15616D\"\nstatus-two = \"#3879A1\"\nredish = \"#E76B74\"\nlight-grey = \"#b7afa8\"\nbgrey-two = \"#706b68\"\ngruvgreen = \"#B8BB26\"\n"
  },
  {
    "path": "runtime/themes/wolf-alabaster-dark-bg.toml",
    "content": "# wolf-alabaster-dark-bg.toml\n#\n# Author: Wolf <wolf@zv.cx>\n# Project: https://github.com/wolf/alabaster-for-helix\n#\n# This is the dark \"BG\" (background) variant of Alabaster for Helix.\n# Uses background colors for syntax highlighting while keeping text mostly light grey.\n#\n# Based on tonsky's \"Alabaster BG\" variant adapted for dark backgrounds.\n\ninherits = \"wolf-alabaster-dark\"\n\n# SYNTAX HIGHLIGHTING - DARK BG VARIANT\n# Override to use BACKGROUND colors instead of text colors\n# Text stays light grey, categories distinguished by background\n\n\"string\" = { fg = \"fg\", bg = \"string-bg\" }\n\"string.regexp\" = { fg = \"fg\", bg = \"string-bg\" }\n\"string.special\" = { fg = \"fg\", bg = \"string-bg-dark\" }\n\n# Constants keep foreground color (same as base)\n\"constant\" = { fg = \"constant\" }\n\"constant.numeric\" = { fg = \"constant\" }\n\"constant.character\" = { fg = \"constant\" }\n\"constant.builtin\" = { fg = \"constant\" }\n\n\"comment\" = { fg = \"fg\", bg = \"comment-bg\" }\n\"comment.line\" = { fg = \"fg\", bg = \"comment-bg\" }\n\"comment.block\" = { fg = \"fg\", bg = \"comment-bg\" }\n\n\"function\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"function.builtin\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"function.method\" = { fg = \"fg\", bg = \"definition-bg\" }\n\n\"constructor\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"type\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"type.builtin\" = { fg = \"fg\", bg = \"definition-bg\" }\n\n# Special cases\n\"tag\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"namespace\" = { fg = \"fg\", bg = \"definition-bg\" }\n\n# MARKUP overrides\n\"markup.heading\" = { fg = \"fg\", bg = \"definition-bg\", modifiers = [\"bold\"] }\n\"markup.link.url\" = { fg = \"fg\", bg = \"string-bg\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"markup.quote\" = { fg = \"fg\", bg = \"comment-bg\" }\n\"markup.raw\" = { fg = \"fg\", bg = \"string-bg\" }\n\n# DIFF overrides\n\"diff.plus\" = { fg = \"fg\", bg = \"string-bg\" }\n\"diff.minus\" = { fg = \"fg\", bg = \"error-bg\" }\n\n[palette]\n# Add background colors for dark BG variant\n# Darker, subdued backgrounds that work on dark background\nstring-bg = \"#1F3A1F\"        # Dark green - strings\nstring-bg-dark = \"#2A4A2A\"   # Slightly brighter dark green - escape sequences\ndefinition-bg = \"#1F2F3F\"    # Dark blue - definitions\ncomment-bg = \"#3F3F1F\"       # Dark yellow - comments\nerror-bg = \"#3F1F1F\"         # Dark red - errors\n\n# Selection colors need to be more visible against colored syntax backgrounds\nselection-primary = \"#5A8FC7\"  # Brighter blue - visible against all syntax backgrounds\nselection = \"#2A4A6F\"          # Medium dark blue - secondary selections\n"
  },
  {
    "path": "runtime/themes/wolf-alabaster-dark-mono.toml",
    "content": "# wolf-alabaster-dark-mono.toml\n#\n# Author: Wolf <wolf@zv.cx>\n# Project: https://github.com/wolf/alabaster-for-helix\n#\n# This is the dark \"Mono\" (monochromatic) variant of Alabaster for Helix.\n# Uses minimal color - mostly grayscale with subtle backgrounds for strings/constants.\n# Only errors and search results use color.\n#\n# Based on tonsky's \"Alabaster Dark Mono\" variant.\n\ninherits = \"wolf-alabaster-dark\"\n\n# SYNTAX HIGHLIGHTING - DARK MONO VARIANT\n# Almost entirely grayscale with subtle background highlighting\n\n\"string\" = { fg = \"fg\", bg = \"string-bg\" }\n\"string.regexp\" = { fg = \"fg\", bg = \"string-bg\" }\n\"string.special\" = { fg = \"fg\", bg = \"string-bg-dark\" }\n\n\"constant\" = { fg = \"fg\", bg = \"string-bg\" }\n\"constant.numeric\" = { fg = \"fg\", bg = \"string-bg\" }\n\"constant.character\" = { fg = \"fg\", bg = \"string-bg\" }\n\"constant.builtin\" = { fg = \"fg\", bg = \"string-bg\" }\n\n\"comment\" = { fg = \"comment-grey\" }\n\"comment.line\" = { fg = \"comment-grey\" }\n\"comment.block\" = { fg = \"comment-grey\" }\n\n# Definitions stay default (no highlighting in mono)\n\"function\" = { fg = \"fg\" }\n\"function.builtin\" = { fg = \"fg\" }\n\"function.method\" = { fg = \"fg\" }\n\n\"constructor\" = { fg = \"fg\" }\n\"type\" = { fg = \"fg\" }\n\"type.builtin\" = { fg = \"fg\" }\n\n# Punctuation dimmed\n\"punctuation\" = { fg = \"punctuation-dark\" }\n\"punctuation.bracket\" = { fg = \"punctuation-dark\" }\n\"punctuation.delimiter\" = { fg = \"punctuation-dark\" }\n\"operator\" = { fg = \"punctuation-dark\" }\n\n# Special cases\n\"tag\" = { fg = \"fg\" }\n\"namespace\" = { fg = \"fg\" }\n\n# MARKUP\n\"markup.heading\" = { fg = \"fg\", modifiers = [\"bold\"] }\n\"markup.link.url\" = { fg = \"fg\", bg = \"string-bg\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"fg\" }\n\"markup.quote\" = { fg = \"comment-grey\" }\n\"markup.raw\" = { fg = \"fg\", bg = \"string-bg\" }\n\n# DIFF - Keep some color for version control\n\"diff.plus\" = { fg = \"diff-green\" }\n\"diff.minus\" = { fg = \"diff-red\" }\n\"diff.delta\" = { fg = \"diff-orange\" }\n\n# Errors keep color (important!)\nerror = { fg = \"error-red\", modifiers = [\"bold\"] }\n\"diagnostic.error\" = { underline = { color = \"error-red\", style = \"curl\" } }\n\n# Virtual text - grey in mono (no colored definitions)\n\"ui.virtual\" = { fg = \"inlay-hint\" }\n\"ui.virtual.inlay-hint\" = { fg = \"inlay-hint\" }\n\n[palette]\n# Dark monochromatic palette\ncomment-grey = \"#777777\"          # Grey - comments\npunctuation-dark = \"#555555\"      # Dark grey - punctuation\nstring-bg = \"#2A2A2A\"             # Dark grey - strings/constants background\nstring-bg-dark = \"#333333\"        # Slightly lighter grey - escape sequences\ninlay-hint = \"#555555\"            # Dimmed grey - virtual text (type hints)\n# Note: error-red, diff-green, diff-red, diff-orange inherited from parent (identical values)\n"
  },
  {
    "path": "runtime/themes/wolf-alabaster-dark.toml",
    "content": "# wolf-alabaster-dark.toml\n#\n# Author: Wolf <wolf@zv.cx>\n# Project: https://github.com/wolf/alabaster-for-helix\n# Download: https://raw.githubusercontent.com/wolf/alabaster-for-helix/main/helix/dot-config/helix/themes/wolf-alabaster-dark.toml\n#\n# This is a dark-background theme especically for the Helix editor.\n#\n# The most important part here is the syntax stuff, but the theme includes UI stuff specifically for Helix, as well.\n#\n# What I care about is:\n#   * Readable syntax, no matter the language\n#   * The error messages provided by the LSP\n#   * Anything special needed to make the UI non-surprising\n#   * Building a minimal definition\n#\n# I started from a couple important sources:\n#   * The [priorities and ideas](https://tonsky.me/blog/syntax-highlighting/) behind the Alabaster Theme (which exists for many editors) by Nikita Prokopov\n#   * His [actual repo implementing the theme](https://github.com/tonsky/sublime-scheme-alabaster)\n#   * A [theme template](https://github.com/joegm/helix-theme-template) on GitHub provided by joegm\n\n# I don't consider this to be done! I absolutely want feedback. I absolutely will continue to tinker.\n\n# GENERAL - Diagnostics (LSP errors/warnings)\nwarning = { fg = \"highlight\" }\nerror = { fg = \"error-red\", modifiers = [\"bold\"] }\ninfo = { fg = \"definition\" }\nhint = { fg = \"punctuation\" }\ndiagnostic = { underline = { style = \"curl\" } }\n\n# UI - Interface elements\n\"ui.background\" = { bg = \"bg\" }\n\"ui.text\" = { fg = \"fg\" }\n\"ui.text.focus\" = { fg = \"active\", modifiers = [\"bold\"] }\n\n\"ui.cursor\" = { bg = \"active\", fg = \"bg\" }\n\"ui.cursor.primary\" = { bg = \"active\", fg = \"bg\" }\n\"ui.cursor.match\" = { bg = \"highlight\" }\n\"ui.cursorline\" = { bg = \"cursorline\" }\n\"ui.cursorcolumn\" = { bg = \"cursorline\" }\n\n\"ui.gutter\" = { bg = \"bg\" }\n\n\"ui.selection\" = { bg = \"selection\" }\n\"ui.selection.primary\" = { bg = \"selection-primary\" }\n\n\"ui.linenr\" = { fg = \"punctuation\" }\n\"ui.linenr.selected\" = { fg = \"active\", modifiers = [\"bold\"] }\n\n\"ui.statusline\" = { fg = \"fg\", bg = \"panel\" }\n\"ui.statusline.inactive\" = { fg = \"punctuation\", bg = \"panel\" }\n\n# Bufferline - make active buffer clearly visible (like onelight-fixed-bufferline)\n\"ui.bufferline.active\" = { fg = \"fg\", bg = \"bg\", modifiers = [\"bold\"] }\n\"ui.bufferline.background\" = { bg = \"bg\" }\n\"ui.bufferline\" = { fg = \"punctuation\", bg = \"panel\" }\n\n\"ui.menu\" = { fg = \"fg\", bg = \"panel\" }\n\"ui.menu.selected\" = { fg = \"bg\", bg = \"active\" }\n\n\"ui.popup\" = { fg = \"fg\", bg = \"panel\" }\n\"ui.popup.info\" = { fg = \"fg\", bg = \"panel\" }\n\"ui.window\" = { fg = \"punctuation\" }\n\"ui.help\" = { fg = \"fg\", bg = \"bg\" }\n\n# Jump labels - extremely visible\n\"ui.virtual.jump-label\" = { fg = \"jump-label\", modifiers = [\"bold\"] }\n\n# Virtual text (inlay hints, etc.) - dimmed type color\n\"ui.virtual\" = { fg = \"inlay-hint\" }\n\"ui.virtual.inlay-hint\" = { fg = \"inlay-hint\" }\n\"ui.virtual.ruler\" = { bg = \"cursorline\" }\n\n# LSP diagnostic inline/expanded text\n\"diagnostic.error\" = { underline = { color = \"error-red\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"highlight\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"definition\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"punctuation\", style = \"curl\" } }\n\"diagnostic.deprecated\" = { fg = \"punctuation\", modifiers = [\"crossed_out\"] }\n\n# SYNTAX HIGHLIGHTING - Following Alabaster's minimal approach\n# Only 4 categories get color: strings, constants, comments, definitions\n# Everything else (keywords, variables, calls) stays default fg\n\n\"string\" = { fg = \"string\" }\n\"string.regexp\" = { fg = \"string\" }\n\"string.special\" = { fg = \"string\" }\n\n\"constant\" = { fg = \"constant\" }\n\"constant.numeric\" = { fg = \"constant\" }\n\"constant.character\" = { fg = \"constant\" }\n\"constant.builtin\" = { fg = \"constant\" }\n\n\"comment\" = { fg = \"comment\" }\n\"comment.line\" = { fg = \"comment\" }\n\"comment.block\" = { fg = \"comment\" }\n\n\"function\" = { fg = \"definition\" }\n\"function.builtin\" = { fg = \"definition\" }\n\"function.method\" = { fg = \"definition\" }\n\n\"constructor\" = { fg = \"definition\" }\n\"type\" = { fg = \"definition\" }\n\"type.builtin\" = { fg = \"definition\" }\n\n# These are NOT highlighted (Alabaster philosophy: keywords are obvious)\n\"keyword\" = { fg = \"fg\" }\n\"keyword.control\" = { fg = \"fg\" }\n\"keyword.operator\" = { fg = \"fg\" }\n\"variable\" = { fg = \"fg\" }\n\"variable.parameter\" = { fg = \"fg\" }\n\"variable.builtin\" = { fg = \"fg\" }\n\n# Punctuation is dimmed\n\"punctuation\" = { fg = \"punctuation\" }\n\"punctuation.bracket\" = { fg = \"punctuation\" }\n\"punctuation.delimiter\" = { fg = \"punctuation\" }\n\n\"operator\" = { fg = \"punctuation\" }\n\n# Special cases\n\"tag\" = { fg = \"definition\" }\n\"tag.error\" = { fg = \"error-red\", underline = { style = \"line\" } }\n\"attribute\" = { fg = \"fg\" }\n\"namespace\" = { fg = \"definition\" }\n\"label\" = { fg = \"constant\" }\n\n# MARKUP - For markdown/documentation\n\"markup.heading\" = { fg = \"definition\", modifiers = [\"bold\"] }\n\"markup.list\" = { fg = \"fg\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link.url\" = { fg = \"string\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"definition\" }\n\"markup.quote\" = { fg = \"comment\" }\n\"markup.raw\" = { fg = \"string\" }\n\n# DIFF - Version control\n\"diff.plus\" = { fg = \"string\" }\n\"diff.minus\" = { fg = \"error-red\" }\n\"diff.delta\" = { fg = \"highlight\" }\n\n[palette]\n# Core colors (Original Alabaster Dark)\nfg = \"#CECECE\"           # Main text - light grey\nbg = \"#0E1415\"           # Background - very dark blue-black\n\n# The 4 semantic colors (Original Alabaster Dark)\nstring = \"#95CB82\"       # Green - strings & numbers\nconstant = \"#CC8BC9\"     # Magenta - constants, booleans\ncomment = \"#DFDF8E\"      # Yellow - comments (important!)\ndefinition = \"#71ADE7\"   # Blue - function/class definitions\n\n# Supporting colors\npunctuation = \"#8C8C8C\"  # Grey - dimmed operators/brackets\nselection = \"#1E3A5F\"    # Very dark blue - secondary selections (subtle)\nselection-primary = \"#4A7BA7\"  # Bright blue - primary selection (clearly distinct)\nactive = \"#CD974B\"       # Golden brown - cursor, active elements (original Alabaster Dark)\nhighlight = \"#FF9800\"    # Orange - search, warnings\nerror-red = \"#DFDF8E\"    # Yellow - errors (use comment color for visibility)\npanel = \"#252526\"        # Slightly lighter grey - UI panels, menus, popups\ncursorline = \"#1A2022\"   # Subtle highlight - cursorline, ruler\njump-label = \"#FF6B35\"   # Bright orange - jump destinations\ninlay-hint = \"#4A7090\"   # Dimmed blue - virtual text (type hints)\n\n# Diff colors\ndiff-green = \"#95CB82\"   # Green - additions (same as string)\ndiff-red = \"#DFDF8E\"     # Yellow - deletions (same as error-red)\ndiff-orange = \"#FF9800\"  # Orange - changes (same as highlight)\n"
  },
  {
    "path": "runtime/themes/wolf-alabaster-light-bg.toml",
    "content": "# wolf-alabaster-light-bg.toml\n#\n# Author: Wolf <wolf@zv.cx>\n# Project: https://github.com/wolf/alabaster-for-helix\n#\n# This is the \"BG\" (background) variant of Alabaster for Helix.\n# Unlike the standard version that uses text colors, this variant uses background colors\n# for syntax highlighting while keeping text mostly black.\n#\n# Based on tonsky's \"Alabaster BG\" variant from:\n# https://github.com/tonsky/sublime-scheme-alabaster\n\ninherits = \"wolf-alabaster-light\"\n\n# SYNTAX HIGHLIGHTING - BG VARIANT\n# Override to use BACKGROUND colors instead of text colors\n# Text stays black, categories distinguished by background\n\n\"string\" = { fg = \"fg\", bg = \"string-bg\" }\n\"string.regexp\" = { fg = \"fg\", bg = \"string-bg\" }\n\"string.special\" = { fg = \"fg\", bg = \"string-bg-dark\" }\n\n# Constants keep foreground color (same as base)\n\"constant\" = { fg = \"constant\" }\n\"constant.numeric\" = { fg = \"constant\" }\n\"constant.character\" = { fg = \"constant\" }\n\"constant.builtin\" = { fg = \"constant\" }\n\n\"comment\" = { fg = \"fg\", bg = \"comment-bg\" }\n\"comment.line\" = { fg = \"fg\", bg = \"comment-bg\" }\n\"comment.block\" = { fg = \"fg\", bg = \"comment-bg\" }\n\n\"function\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"function.builtin\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"function.method\" = { fg = \"fg\", bg = \"definition-bg\" }\n\n\"constructor\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"type\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"type.builtin\" = { fg = \"fg\", bg = \"definition-bg\" }\n\n# Special cases\n\"tag\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"namespace\" = { fg = \"fg\", bg = \"definition-bg\" }\n\n# MARKUP overrides\n\"markup.heading\" = { fg = \"fg\", bg = \"definition-bg\", modifiers = [\"bold\"] }\n\"markup.link.url\" = { fg = \"fg\", bg = \"string-bg\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"fg\", bg = \"definition-bg\" }\n\"markup.quote\" = { fg = \"fg\", bg = \"comment-bg\" }\n\"markup.raw\" = { fg = \"fg\", bg = \"string-bg\" }\n\n# DIFF overrides\n\"diff.plus\" = { fg = \"fg\", bg = \"string-bg\" }\n\"diff.minus\" = { fg = \"fg\", bg = \"error-bg\" }\n\n[palette]\n# Add background colors for BG variant (from Alabaster BG)\nstring-bg = \"#F1FADF\"        # Light green - strings\nstring-bg-dark = \"#DBECB6\"   # Darker green - escape sequences\ndefinition-bg = \"#DBF1FF\"    # Light blue - definitions\ncomment-bg = \"#FFFABC\"       # Light yellow - comments\nerror-bg = \"#FFE0E0\"         # Light pink - errors\n\n# Override selection colors (Alabaster BG uses slightly darker selection)\nselection-primary = \"#B4D8FD\"  # Original Alabaster BG selection\nselection = \"#D5E5F3\"          # Lighter for secondary selections\n"
  },
  {
    "path": "runtime/themes/wolf-alabaster-light-mono.toml",
    "content": "# wolf-alabaster-light-mono.toml\n#\n# Author: Wolf <wolf@zv.cx>\n# Project: https://github.com/wolf/alabaster-for-helix\n#\n# This is the \"Mono\" (monochromatic) variant of Alabaster for Helix.\n# Uses minimal color - mostly grayscale with light backgrounds for strings/constants.\n# Only errors and search results use color.\n#\n# Based on tonsky's \"Alabaster Mono\" variant from:\n# https://github.com/tonsky/sublime-scheme-alabaster\n\ninherits = \"wolf-alabaster-light\"\n\n# SYNTAX HIGHLIGHTING - MONO VARIANT\n# Almost entirely grayscale with subtle background highlighting\n\n\"string\" = { fg = \"fg\", bg = \"string-bg\" }\n\"string.regexp\" = { fg = \"fg\", bg = \"string-bg\" }\n\"string.special\" = { fg = \"fg\", bg = \"string-bg-dark\" }\n\n\"constant\" = { fg = \"fg\", bg = \"string-bg\" }\n\"constant.numeric\" = { fg = \"fg\", bg = \"string-bg\" }\n\"constant.character\" = { fg = \"fg\", bg = \"string-bg\" }\n\"constant.builtin\" = { fg = \"fg\", bg = \"string-bg\" }\n\n\"comment\" = { fg = \"comment-grey\" }\n\"comment.line\" = { fg = \"comment-grey\" }\n\"comment.block\" = { fg = \"comment-grey\" }\n\n# Definitions stay default (no highlighting in mono)\n\"function\" = { fg = \"fg\" }\n\"function.builtin\" = { fg = \"fg\" }\n\"function.method\" = { fg = \"fg\" }\n\n\"constructor\" = { fg = \"fg\" }\n\"type\" = { fg = \"fg\" }\n\"type.builtin\" = { fg = \"fg\" }\n\n# Punctuation even more dimmed\n\"punctuation\" = { fg = \"punctuation-light\" }\n\"punctuation.bracket\" = { fg = \"punctuation-light\" }\n\"punctuation.delimiter\" = { fg = \"punctuation-light\" }\n\"operator\" = { fg = \"punctuation-light\" }\n\n# Special cases\n\"tag\" = { fg = \"fg\" }\n\"namespace\" = { fg = \"fg\" }\n\n# MARKUP\n\"markup.heading\" = { fg = \"fg\", modifiers = [\"bold\"] }\n\"markup.link.url\" = { fg = \"fg\", bg = \"string-bg\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"fg\" }\n\"markup.quote\" = { fg = \"comment-grey\" }\n\"markup.raw\" = { fg = \"fg\", bg = \"string-bg\" }\n\n# DIFF - Keep some color for version control\n\"diff.plus\" = { fg = \"diff-green\" }\n\"diff.minus\" = { fg = \"diff-red\" }\n\"diff.delta\" = { fg = \"diff-orange\" }\n\n# Errors keep color (important!)\nerror = { fg = \"error-red\", modifiers = [\"bold\"] }\n\"diagnostic.error\" = { underline = { color = \"error-red\", style = \"curl\" } }\n\n# Virtual text - grey in mono (no colored definitions)\n\"ui.virtual\" = { fg = \"inlay-hint\" }\n\"ui.virtual.inlay-hint\" = { fg = \"inlay-hint\" }\n\n[palette]\n# Monochromatic palette\ncomment-grey = \"#999999\"          # Grey - comments\npunctuation-light = \"#BBBBBB\"     # Light grey - punctuation\nstring-bg = \"#EEEEEE\"             # Very light grey - strings/constants background\nstring-bg-dark = \"#D9D9D9\"        # Slightly darker grey - escape sequences\ninlay-hint = \"#AAAAAA\"            # Dimmed grey - virtual text (type hints)\n\n# Override parent colors with more muted tones for monochromatic aesthetic\nerror-red = \"#CC3333\"             # Red - errors (more muted than parent)\ndiff-green = \"#5F8700\"            # Green - additions (more muted than parent)\ndiff-red = \"#CC3333\"              # Red - deletions\ndiff-orange = \"#D78700\"           # Orange - changes (more muted than parent)\n"
  },
  {
    "path": "runtime/themes/wolf-alabaster-light.toml",
    "content": "# wolf-alabaster-light.toml\n#\n# Author: Wolf <wolf@zv.cx>\n# Project: https://github.com/wolf/alabaster-for-helix\n# Download: https://raw.githubusercontent.com/wolf/alabaster-for-helix/main/helix/dot-config/helix/themes/wolf-alabaster-light.toml\n#\n# This is a light-background theme especically for the Helix editor.\n#\n# The most important part here is the syntax stuff, but the theme includes UI stuff specifically for Helix, as well.\n#\n# What I care about is:\n#   * Readable syntax, no matter the language\n#   * The error messages provided by the LSP\n#   * Anything special needed to make the UI non-surprising\n#   * Building a minimal definition\n#\n# I started from a couple important sources:\n#   * The [priorities and ideas](https://tonsky.me/blog/syntax-highlighting/) behind the Alabaster Theme (which exists for many editors) by Nikita Prokopov\n#   * His [actual repo implementing the theme](https://github.com/tonsky/sublime-scheme-alabaster)\n#   * A [theme template](https://github.com/joegm/helix-theme-template) on GitHub provided by joegm\n\n# I don't consider this to be done! I absolutely want feedback. I absolutely will continue to tinker.\n\n# GENERAL - Diagnostics (LSP errors/warnings)\nwarning = { fg = \"highlight\" }\nerror = { fg = \"error-red\", modifiers = [\"bold\"] }\ninfo = { fg = \"definition\" }\nhint = { fg = \"punctuation\" }\ndiagnostic = { underline = { style = \"curl\" } }\n\n# UI - Interface elements\n\"ui.background\" = { bg = \"bg\" }\n\"ui.text\" = { fg = \"fg\" }\n\"ui.text.focus\" = { fg = \"active\", modifiers = [\"bold\"] }\n\n\"ui.cursor\" = { bg = \"active\", fg = \"bg\" }\n\"ui.cursor.primary\" = { bg = \"active\", fg = \"bg\" }\n\"ui.cursor.match\" = { bg = \"highlight\" }\n\"ui.cursorline\" = { bg = \"cursorline\" }\n\"ui.cursorcolumn\" = { bg = \"cursorline\" }\n\n\"ui.gutter\" = { bg = \"bg\" }\n\n\"ui.selection\" = { bg = \"selection\" }\n\"ui.selection.primary\" = { bg = \"selection-primary\" }\n\n\"ui.linenr\" = { fg = \"punctuation\" }\n\"ui.linenr.selected\" = { fg = \"active\", modifiers = [\"bold\"] }\n\n\"ui.statusline\" = { fg = \"fg\", bg = \"panel\" }\n\"ui.statusline.inactive\" = { fg = \"punctuation\", bg = \"panel\" }\n\n# Bufferline - make active buffer clearly visible (like onelight-fixed-bufferline)\n\"ui.bufferline.active\" = { fg = \"fg\", bg = \"bg\", modifiers = [\"bold\"] }\n\"ui.bufferline.background\" = { bg = \"bg\" }\n\"ui.bufferline\" = { fg = \"punctuation\", bg = \"panel\" }\n\n\"ui.menu\" = { fg = \"fg\", bg = \"panel\" }\n\"ui.menu.selected\" = { fg = \"bg\", bg = \"active\" }\n\n\"ui.popup\" = { fg = \"fg\", bg = \"panel\" }\n\"ui.popup.info\" = { fg = \"fg\", bg = \"panel\" }\n\"ui.window\" = { fg = \"punctuation\" }\n\"ui.help\" = { fg = \"fg\", bg = \"bg\" }\n\n# Jump labels - extremely visible\n\"ui.virtual.jump-label\" = { fg = \"jump-label\", modifiers = [\"bold\"] }\n\n# Virtual text (inlay hints, etc.) - dimmed type color\n\"ui.virtual\" = { fg = \"inlay-hint\" }\n\"ui.virtual.inlay-hint\" = { fg = \"inlay-hint\" }\n\"ui.virtual.ruler\" = { bg = \"cursorline\" }\n\n# LSP diagnostic inline/expanded text\n\"diagnostic.error\" = { underline = { color = \"error-red\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"highlight\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"definition\", style = \"curl\" } }\n\"diagnostic.hint\" = { underline = { color = \"punctuation\", style = \"curl\" } }\n\"diagnostic.deprecated\" = { fg = \"punctuation\", modifiers = [\"crossed_out\"] }\n\n# SYNTAX HIGHLIGHTING - Following Alabaster's minimal approach\n# Only 4 categories get color: strings, constants, comments, definitions\n# Everything else (keywords, variables, calls) stays default fg\n\n\"string\" = { fg = \"string\" }\n\"string.regexp\" = { fg = \"string\" }\n\"string.special\" = { fg = \"string\" }\n\n\"constant\" = { fg = \"constant\" }\n\"constant.numeric\" = { fg = \"constant\" }\n\"constant.character\" = { fg = \"constant\" }\n\"constant.builtin\" = { fg = \"constant\" }\n\n\"comment\" = { fg = \"comment\" }\n\"comment.line\" = { fg = \"comment\" }\n\"comment.block\" = { fg = \"comment\" }\n\n\"function\" = { fg = \"definition\" }\n\"function.builtin\" = { fg = \"definition\" }\n\"function.method\" = { fg = \"definition\" }\n\n\"constructor\" = { fg = \"definition\" }\n\"type\" = { fg = \"definition\" }\n\"type.builtin\" = { fg = \"definition\" }\n\n# These are NOT highlighted (Alabaster philosophy: keywords are obvious)\n\"keyword\" = { fg = \"fg\" }\n\"keyword.control\" = { fg = \"fg\" }\n\"keyword.operator\" = { fg = \"fg\" }\n\"variable\" = { fg = \"fg\" }\n\"variable.parameter\" = { fg = \"fg\" }\n\"variable.builtin\" = { fg = \"fg\" }\n\n# Punctuation is dimmed\n\"punctuation\" = { fg = \"punctuation\" }\n\"punctuation.bracket\" = { fg = \"punctuation\" }\n\"punctuation.delimiter\" = { fg = \"punctuation\" }\n\n\"operator\" = { fg = \"punctuation\" }\n\n# Special cases\n\"tag\" = { fg = \"definition\" }\n\"tag.error\" = { fg = \"error-red\", underline = { style = \"line\" } }\n\"attribute\" = { fg = \"fg\" }\n\"namespace\" = { fg = \"definition\" }\n\"label\" = { fg = \"constant\" }\n\n# MARKUP - For markdown/documentation\n\"markup.heading\" = { fg = \"definition\", modifiers = [\"bold\"] }\n\"markup.list\" = { fg = \"fg\" }\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.link.url\" = { fg = \"string\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"definition\" }\n\"markup.quote\" = { fg = \"comment\" }\n\"markup.raw\" = { fg = \"string\" }\n\n# DIFF - Version control\n\"diff.plus\" = { fg = \"string\" }\n\"diff.minus\" = { fg = \"error-red\" }\n\"diff.delta\" = { fg = \"highlight\" }\n\n[palette]\n# Core colors (Alabaster-inspired)\nfg = \"#000000\"           # Main text (Alabaster uses pure black)\nbg = \"#F7F7F7\"           # Background (Alabaster's light grey)\n\n# The 4 semantic colors\nstring = \"#448C27\"       # Green - strings & numbers\nconstant = \"#7A3E9D\"     # Magenta - constants, booleans\ncomment = \"#AA3731\"      # Red - comments (important!)\ndefinition = \"#325CC0\"   # Blue - function/class definitions\n\n# Supporting colors\npunctuation = \"#777777\"  # Grey - dimmed operators/brackets\nselection = \"#DDE7ED\"    # Light gray-blue - secondary selections (subtle but distinct)\nselection-primary = \"#BFDBFE\"  # Light blue - primary selection (original Alabaster)\nactive = \"#007ACC\"       # Bright blue - cursor, active elements\nhighlight = \"#FFBC5D\"    # Orange - search, warnings\nerror-red = \"#AA3731\"    # Red - errors\npanel = \"#EEEEEE\"        # Darker grey - UI panels, menus, popups\ncursorline = \"#EFEFEF\"   # Subtle highlight - cursorline, ruler\njump-label = \"#FF4500\"   # Bright orange-red - jump destinations\ninlay-hint = \"#8090B8\"   # Dimmed blue - virtual text (type hints)\n\n# Diff colors\ndiff-green = \"#448C27\"   # Green - additions (same as string)\ndiff-red = \"#AA3731\"     # Red - deletions (same as error-red)\ndiff-orange = \"#FFBC5D\"  # Orange - changes (same as highlight)\n"
  },
  {
    "path": "runtime/themes/yellowed.toml",
    "content": "# author: Gael Lopes Da Silva\n# project: Yellowed\n# github: https://github.com/Gael-Lopes-Da-Silva/YellowedHelix\n\n\"attribute\"                       = { fg = \"text\" }\n\"type\"                            = { fg = \"text\" }\n\"type.builtin\"                    = { fg = \"keywords\" }\n\"type.enum\"                       = { fg = \"keywords\" }\n\"constructor\"                     = { fg = \"text\", modifiers = [\"bold\"] }\n\"constant\"                        = { fg = \"text\", modifiers = [\"bold\"] }\n\"constant.builtin\"                = { fg = \"constants\", modifiers = [\"bold\"] }\n\"constant.character\"              = { fg = \"string\" }\n\"constant.character.escape\"       = { fg = \"constants\", modifiers = [\"bold\"] }\n\"constant.numeric\"                = { fg = \"keywords\" }\n\"string\"                          = { fg = \"string\" }\n\"string.regexp\"                   = { fg = \"constants\" }\n\"comment\"                         = { fg = \"comment\" }\n\"variable\"                        = { fg = \"text\" }\n\"variable.builtin\"                = { fg = \"keywords\" }\n\"variable.parameter\"              = { fg = \"text\", modifiers = [\"italic\"] }\n\"label\"                           = { fg = \"text\" }\n\"punctuation\"                     = { fg = \"text\" }\n\"punctuation.special\"             = { fg = \"constants\", modifiers = [\"bold\"] }\n\"keyword\"                         = { fg = \"keywords\", modifiers = [\"bold\"] }\n\"keyword.control\"                 = { fg = \"keywords\" }\n\"keyword.control.return\"          = { fg = \"keywords\", modifiers = [\"bold\"] }\n\"keyword.operator\"                = { fg = \"keywords\" }\n\"keyword.directive\"               = { fg = \"keywords\" }\n\"operator\"                        = { fg = \"keywords\" }\n\"function\"                        = { fg = \"text\", modifiers = [\"bold\"] }\n\"tag\"                             = { fg = \"keywords\", modifiers = [\"bold\"] }\n\"namespace\"                       = { fg = \"text\" }\n\"special\"                         = { fg = \"yellow\" }\n\n\"markup.heading.marker\"           = { fg = \"keywords\", modifiers = [\"bold\"] }\n\"markup.heading.1\"                = { fg = \"text\", modifiers = [\"bold\"] }\n\"markup.heading.2\"                = { fg = \"text\", modifiers = [\"bold\"] }\n\"markup.heading.3\"                = { fg = \"text\", modifiers = [\"bold\"] }\n\"markup.heading.4\"                = { fg = \"text\", modifiers = [\"bold\"] }\n\"markup.heading.5\"                = { fg = \"text\", modifiers = [\"bold\"] }\n\"markup.heading.6\"                = { fg = \"text\", modifiers = [\"bold\"] }\n\"markup.list\"                     = { fg = \"keywords\", modifiers = [\"bold\"] }\n\"markup.bold\"                     = { modifiers = [\"bold\"] }\n\"markup.italic\"                   = { modifiers = [\"italic\"] }\n\"markup.link.url\"                 = { fg = \"text\", modifiers = [\"underlined\"] }\n\"markup.link.text\"                = { fg = \"string\" }\n\"markup.quote\"                    = { fg = \"text\" }\n\"markup.raw\"                      = { fg = \"string\" }\n\n\"diff.plus\"                       = { fg = \"green\" }\n\"diff.minus\"                      = { fg = \"red\" }\n\"diff.delta\"                      = { fg = \"blue\" }\n\"diff.delta.moved\"                = { fg = \"gray\" }\n\n\"ui.background\"                   = { bg = \"dark_gray\", fg = \"text\" }\n\"ui.background.separator\"         = { fg = \"text\" }\n\"ui.cursor\"                       = { bg = \"yellow\", fg = \"black\" }\n\"ui.cursor.normal\"                = { bg = \"yellow\", fg = \"black\" }\n\"ui.cursor.insert\"                = { bg = \"yellow\", fg = \"black\" }\n\"ui.cursor.select\"                = { bg = \"yellow\", fg = \"black\" }\n\"ui.cursor.match\"                 = { bg = \"light_gray\" }\n\"ui.cursor.primary\"               = { bg = \"yellow\", fg = \"black\" }\n\"ui.cursor.primary.normal\"        = { bg = \"yellow\", fg = \"black\" }\n\"ui.cursor.primary.insert\"        = { bg = \"yellow\", fg = \"black\" }\n\"ui.cursor.primary.select\"        = { bg = \"yellow\", fg = \"black\" }\n\"ui.debug.breakpoint\"             = { fg = \"red\" }\n\"ui.debug.active\"                 = { fg = \"green\" }\n\"ui.gutter\"                       = { fg = \"light_gray\" }\n\"ui.gutter.selected\"              = { fg = \"light_gray\" }\n\"ui.highlight.frameline\"          = { fg = \"gray\" }\n\"ui.linenr\"                       = { fg = \"light_gray\" }\n\"ui.linenr.selected\"              = { fg = \"yellow\" }\n\"ui.statusline\"                   = { fg = \"text\", bg = \"gray\" }\n\"ui.statusline.inactive\"          = { fg = \"light_gray\", bg = \"gray\" }\n\"ui.statusline.normal\"            = { bg = \"light_gray\" }\n\"ui.statusline.insert\"            = { bg = \"green\" }\n\"ui.statusline.select\"            = { bg = \"purple\" }\n\"ui.statusline.separator\"         = { fg = \"dark_gray\" }\n\"ui.popup\"                        = { bg = \"menu\", fg = \"text\" }\n\"ui.popup.info\"                   = { bg = \"menu\", fg = \"text\" }\n\"ui.window\"                       = { fg = \"text\" }\n\"ui.help\"                         = { fg = \"text\", bg = \"menu\" }\n\"ui.text\"                         = { fg = \"text\" }\n\"ui.text.focus\"                   = { bg = \"gray\" }\n\"ui.text.inactive\"                = { fg = \"text\" }\n\"ui.text.info\"                    = { fg = \"text\" }\n\"ui.virtual.ruler\"                = { bg = \"light_gray\" }\n\"ui.virtual.whitespace\"           = { fg = \"light_gray\" }\n\"ui.virtual.indent-guide\"         = { fg = \"light_gray\" }\n\"ui.virtual.inlay-hint\"           = { fg = \"light_gray\" }\n\"ui.virtual.inlay-hint.parameter\" = { fg = \"light_gray\" }\n\"ui.virtual.inlay-hint.type\"      = { fg = \"light_gray\" }\n\"ui.virtual.wrap\"                 = { fg = \"light_gray\" }\n\"ui.menu\"                         = { fg = \"text\", bg = \"gray\" }\n\"ui.menu.selected\"                = { fg = \"text\", bg = \"light_gray\", modifiers = [\"bold\"] }\n\"ui.menu.scroll\"                  = { fg = \"light_gray\", bg = \"dark_gray\" }\n\"ui.selection\"                    = { bg = \"selection\" }\n\"ui.selection.primary\"            = { bg = \"selection\" }\n\"ui.highlight\"                    = { bg = \"light_gray\" }\n\"ui.cursorline.primary\"           = { bg = \"gray\" }\n\"ui.cursorline.secondary\"         = { bg = \"gray\" }\n\"ui.cursorcolumn.primary\"         = { bg = \"gray\" }\n\"ui.cursorcolumn.secondary\"       = { bg = \"gray\" }\n\n\"warning\"                         = { fg = \"warning\" }\n\"error\"                           = { fg = \"error\" }\n\"info\"                            = { fg = \"info\" }\n\"hint\"                            = { fg = \"hint\" }\n\n\"diagnostic.warning\"              = { underline = { color = \"warning\", style = \"curl\" } }\n\"diagnostic.error\"                = { underline = { color = \"error\", style = \"curl\" } }\n\"diagnostic.info\"                 = { underline = { color = \"info\", style = \"curl\" } }\n\"diagnostic.hint\"                 = { underline = { color = \"hint\", style = \"curl\" } }\n\"diagnostic.unnecessary\"          = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\"           = { modifiers = [\"crossed_out\"] }\n\n[palette]\n# interface\nyellow      = \"#ffd900\"\ngray        = \"#2a2a2a\"\ndark_gray   = \"#242424\"\nlight_gray  = \"#545454\"\npurple      = \"#994c92\"\nblue        = \"#008DFF\"\nmenu        = \"#202020\"\nselection   = \"#3f3f3f\"\n\n# syntax\ntext        = \"#FFFFFF\"\ncomment     = \"#6b6b6b\"\nstring      = \"#378b1d\"\nconstants   = \"#ff80f4\"\nkeywords    = \"#ffd900\"\nwarning     = \"#FF9C00\"\nerror       = \"#FF0000\"\ninfo        = \"#0092FF\"\nhint        = \"#4DFF00\"\n"
  },
  {
    "path": "runtime/themes/yo.toml",
    "content": "# Author: Michael McClintock <michael.mcclintock@hey.com>\n# License: MIT\n\n# Yo - Themes for Helix inspired by Zenbones & Alabaster with Radix Colors.\n# https://github.com/mrmcc3/yo-theme-helix\n\n# background/text\n\"ui.background\" = { fg = \"p11\", bg = \"p2\" }\n\"ui.background.separator\" = { fg = \"p7\" }\n\"ui.text\" = { fg = \"p11\" }\n\"ui.text.focus\" = { fg = \"p12\", modifiers = [\"bold\"] }\n\n# popups/menus\n\"ui.window\" = { fg = \"p7\" }\n\"ui.popup\" = { fg = \"p12\", bg = \"p4\" }\n\"ui.popup.info\" = { fg = \"p12\", bg = \"p2\" }\n\"ui.text.info\" = { fg = \"p12\", bg = \"p2\" }\n\"ui.help\" = { fg = \"p12\", bg = \"p2\" }\n\"ui.menu\" = { fg = \"p11\", bg = \"p4\" }\n\"ui.menu.selected\" = { fg = \"p12\", modifiers = [\"bold\"] }\n\"ui.menu.scroll\" = { fg = \"p8\", bg = \"p4\" }\n\"ui.picker.header.column\" = { underline.style = \"line\" }\n\n# cursor/selection\n\"ui.cursor\" = { fg = \"p2\", bg = \"p11\" }\n\"ui.cursor.insert\" = { fg = \"p2\", bg = \"keyword\" }\n\"ui.cursor.select\" = { fg = \"p2\", bg = \"p12\" }\n\"ui.cursor.match\" = { fg = \"p12\", modifiers = [\"bold\"] }\n\"ui.cursor.primary\" = { fg = \"p2\", bg = \"p11\", modifiers = [\"bold\"] }\n\"ui.cursor.primary.insert\" = { fg = \"p2\", bg = \"keyword\", modifiers = [\"bold\"] }\n\"ui.cursor.primary.select\" = { fg = \"p2\", bg = \"p12\", modifiers = [\"bold\"] }\n\"ui.selection\" = { bg = \"p4\" }\n\"ui.selection.primary\" = { bg = \"p5\" }\n\"ui.cursorline.primary\" = { bg = \"p3\" }\n\"ui.cursorcolumn.primary\" = { bg = \"p3\" }\n\n# line numbers / diff\n\"ui.linenr\" = { fg = \"p7\" }\n\"ui.linenr.selected\" = { fg = \"p11\" }\ndiff = { fg = \"p8\" }\n\n# bufferline/statusline\n\"ui.bufferline\" = { fg = \"p11\", bg = \"p4\" }\n\"ui.bufferline.active\" = { fg = \"p2\", bg = \"p11\" }\n\"ui.statusline\" = { fg = \"p11\", bg = \"p4\" }\n\"ui.statusline.inactive\" = { fg = \"p11\", bg = \"p2\" }\n\"ui.statusline.normal\" = { fg = \"p2\", bg = \"p11\" }\n\"ui.statusline.insert\" = { fg = \"p2\", bg = \"keyword\" }\n\"ui.statusline.select\" = { fg = \"p2\", bg = \"p12\" }\n\"ui.statusline.separator\" = { fg = \"p7\" }\n\n# virtual\n\"ui.virtual\" = { fg = \"p6\" }\n\"ui.virtual.ruler\" = { bg = \"p3\" }\n\"ui.virtual.inlay-hint\" = { fg = \"p7\", underline.style = \"dotted\" }\n\"ui.virtual.jump-label\" = { fg = \"p12\", modifiers = [\n  \"bold\",\n], underline = { style = \"curl\", color = \"info\" } }\n\n# diagnostics\nerror = { fg = \"error\", modifiers = [\"bold\"] }\nwarning = { fg = \"warning\", modifiers = [\"bold\"] }\ninfo = { fg = \"info\", modifiers = [\"bold\"] }\nhint = { fg = \"info\", modifiers = [\"bold\"] }\n\"diagnostic.error\" = { fg = \"error\", modifiers = [\"bold\"] }\n\"diagnostic.warning\" = { fg = \"warning\", modifiers = [\"bold\"] }\n\"diagnostic.info\" = { fg = \"info\", modifiers = [\"bold\"] }\n\"diagnostic.hint\" = { fg = \"info\", modifiers = [\"bold\"] }\n# \"diagnostic.unnecessary\" = {}\n# \"diagnostic.deprecated\" = {}\n\n# code\ncomment = { fg = \"info\" }\nkeyword = { fg = \"keyword\" }\noperator = { fg = \"keyword\" }\nstring = { fg = \"string\" }\nconstant = { fg = \"constant\" }\n\"string.special.symbol\" = { fg = \"constant\" }\nvariable = { fg = \"p10\" }\nnamespace = { fg = \"p10\" }\npunctuation = { fg = \"p9\" }\n\"punctuation.delimiter\" = { fg = \"p8\" }\nfunction = { fg = \"p11\" }\nattribute = { fg = \"p10\" }\ntag = { fg = \"keyword\" }\nlabel = { fg = \"p12\" }\nconstructor = { fg = \"p12\" }\ntype = { fg = \"p12\" }\n\n# markup\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.heading\" = { fg = \"p12\", modifiers = [\"bold\"] }\n\"markup.heading.marker\" = { fg = \"p8\" }\n\"markup.list\" = { fg = \"p8\" }\n\"markup.link.url\" = { underline.style = \"line\" }\n\"markup.link.label\" = { underline.style = \"dotted\" }\n# \"markup.link.text\" = {}\n\"markup.quote\" = { fg = \"p10\" }\n# \"markup.raw\" = {}\n\n[palette] # https://www.radix-ui.com/colors\n\n# grayDark\np1 = \"#111111\"\np2 = \"#191919\"\np3 = \"#222222\"\np4 = \"#2a2a2a\"\np5 = \"#313131\"\np6 = \"#3a3a3a\"\np7 = \"#484848\"\np8 = \"#606060\"\np9 = \"#6e6e6e\"\np10 = \"#7b7b7b\"\np11 = \"#b4b4b4\"\np12 = \"#eeeeee\"\n\nerror = \"#ec5d5e\"   # redDark-10\nwarning = \"#ff801f\" # orangeDark-10\ninfo = \"#3b9eff\"    # blueDark-10\n\nstring = \"#33b074\"   # greenDark-10\nconstant = \"#9a5cd0\" # purpleDark-10\nkeyword = \"#ae8c7e\"  # bronzeDark-10\n"
  },
  {
    "path": "runtime/themes/yo_berry.toml",
    "content": "# Author: Michael McClintock <michael.mcclintock@hey.com>\n# License: MIT\n\n# Yo - Themes for Helix inspired by Zenbones & Alabaster with Radix Colors.\n# https://github.com/mrmcc3/yo-theme-helix\n\ninherits = \"yo\"\n\n[palette]\n\n# mauveDark\np1 = \"#121113\"\np2 = \"#1a191b\"\np3 = \"#232225\"\np4 = \"#2b292d\"\np5 = \"#323035\"\np6 = \"#3c393f\"\np7 = \"#49474e\"\np8 = \"#625f69\"\np9 = \"#6f6d78\"\np10 = \"#7c7a85\"\np11 = \"#b5b2bc\"\np12 = \"#eeeef0\"\n\nerror = \"#ee518a\"   # crimsonDark-10\nwarning = \"#ffff57\" # yellowDark-10\ninfo = \"#3b9eff\"    # blueDark-10\n\nstring = \"#0eb39e\"   # teal-10\nconstant = \"#b658c4\" # plum-10\nkeyword = \"#9eb1ff\"  # indigo-11\n"
  },
  {
    "path": "runtime/themes/yo_light.toml",
    "content": "# Author: Michael McClintock <michael.mcclintock@hey.com>\n# License: MIT\n\n# Yo - Themes for Helix inspired by Zenbones & Alabaster with Radix Colors.\n# https://github.com/mrmcc3/yo-theme-helix\n\ninherits = \"yo\"\n\n\"ui.virtual.inlay-hint\" = { fg = \"p8\", underline.style = \"dotted\" }\n\"markup.quote\" = { fg = \"p9\" }\n\n[palette]\n\n# gray\np1 = \"#fcfcfc\"\np2 = \"#f9f9f9\"\np3 = \"#f0f0f0\"\np4 = \"#e8e8e8\"\np5 = \"#e0e0e0\"\np6 = \"#d9d9d9\"\np7 = \"#cecece\"\np8 = \"#bbbbbb\"\np9 = \"#8d8d8d\"\np10 = \"#838383\"\np11 = \"#646464\"\np12 = \"#202020\"\n\nerror = \"#dc3e42\"   # red-10\nwarning = \"#ef5f00\" # orange-10\ninfo = \"#0588f0\"    # blue-10\n\nstring = \"#2b9a66\"   # green-10\nconstant = \"#8347b9\" # purple-10\nkeyword = \"#957468\"  # bronze-10\n"
  },
  {
    "path": "runtime/themes/zed_onedark.toml",
    "content": "# Zed OneDark\n# Author : EricHenry\n\n\"attribute\" = { fg = \"yellow\" }\n\"comment\" = { fg = \"light-gray\", modifiers = [\"italic\"] }\n\"constant\" = { fg = \"yellow\" }\n\"constant.numeric\" = { fg = \"orange\" }\n\"constant.builtin\" = { fg = \"yellow\" }\n\"constant.builtin.boolean\" = { fg = \"yellow\" }\n\"constant.character.escape\" = { fg = \"yellow\" }\n\"constructor\" = { fg = \"blue\" }\n\"function\" = { fg = \"blue\" }\n\"function.builtin\" = { fg = \"blue\" }\n\"function.method\" = { fg = \"blue\" }\n\"function.macro\" = { fg = \"blue\" }\n\"keyword\" = { fg = \"purple\" }\n\"label\" = { fg = \"ui-text\" }\n\"namespace\" = { fg = \"ui-text\" }\n\"operator\" = { fg = \"ui-text\" }\n\"puncuation\" = { fg = \"ui-text\" }\n\"special\" = { fg = \"ui-text\" }\n\"string\" = { fg = \"green\" }\n\"type\" = { fg = \"cyan\" }\n\"variable.builtin\" = { fg = \"orange\" }\n\"variable.parameter\" = { fg = \"ui-text\" }\n\"variable.other.member\" = { fg = \"red\" }\n\n\"markup.heading\" = { fg = \"red\" }\n\"markup.raw.inline\" = { fg = \"green\" }\n\"markup.bold\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"markup.italic\" = { fg = \"purple\", modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.list\" = { fg = \"red\" }\n\"markup.quote\" = { fg = \"yellow\" }\n\"markup.link.url\" = { fg = \"cyan\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = { fg = \"purple\" }\n\n\"diff.plus\" = \"green\"\n\"diff.delta\" = \"yellow\"\n\"diff.minus\" = \"red\"\n\n\"diagnostic.info\".underline = { color = \"blue\", style = \"curl\" }\n\"diagnostic.hint\".underline = { color = \"green\", style = \"curl\" }\n\"diagnostic.warning\".underline = { color = \"yellow\", style = \"curl\" }\n\"diagnostic.error\".underline = { color = \"red\", style = \"curl\" }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\"info\" = { fg = \"blue\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"green\", modifiers = [\"bold\"] }\n\"warning\" = { fg = \"yellow\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"red\", modifiers = [\"bold\"] }\n\n\"ui.background\" = { bg = \"ui-text-reversed\" }\n\"ui.gutter\" = { bg = \"gray\" }\n\"ui.virtual\" = { fg = \"faint-gray\" }\n\"ui.virtual.indent-guide\" = { fg = \"faint-gray\" }\n\"ui.virtual.whitespace\" = { fg = \"light-gray\" }\n\"ui.virtual.ruler\" = { bg = \"gray\" }\n\"ui.virtual.inlay-hint\" = { fg = \"blue-gray\", modifiers = [\"bold\"] }\n\"ui.virtual.jump-label\" = { fg = \"purple\", modifiers = [\"bold\", \"italic\"] }\n\n\"ui.cursor\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"white\", modifiers = [\"reversed\"] }\n\"ui.cursor.match\" = { fg = \"blue\", modifiers = [\"underlined\"] }\n# Malformed ANSI: dark-blue. See 'https://github.com/helix-editor/helix/issues/5709'\n# \"ui.cursor.insert\" = { fg = \"dark-blue\" }\n\n\"ui.selection\" = { bg = \"faint-gray\" }\n\"ui.selection.primary\" = { bg = \"#293b5b\" }\n\"ui.cursorline.primary\" = { bg = \"gray\" }\n\n\"ui.highlight\" = { bg = \"gray\" }\n\"ui.highlight.frameline\" = { bg = \"#97202a\" }\n\n\"ui.linenr\" = { fg = \"linenr\" }\n\"ui.linenr.selected\" = { fg = \"ui-text\" }\n\n\"ui.statusline\" = { fg = \"white\", bg = \"gray\" }\n\"ui.statusline.inactive\" = { fg = \"light-gray\", bg = \"black\" }\n\"ui.statusline.normal\" = { fg = \"black\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"black\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"black\", bg = \"purple\" }\n\n\"ui.text\" = { fg = \"ui-text\" }\n\"ui.text.focus\" = { fg = \"white\", bg = \"gray\", modifiers = [\"bold\"] }\n\n\"ui.help\" = { fg = \"white\", bg = \"gray\" }\n\"ui.popup\" = { bg = \"gray\" }\n\"ui.window\" = { fg = \"gray\" }\n\"ui.menu\" = { fg = \"ui-text\", bg = \"gray\" }\n\"ui.menu.selected\" = { fg = \"ui-text-reversed\", bg = \"blue\" }\n\"ui.menu.scroll\" = { fg = \"ui-text\", bg = \"light-gray\" }\n\n\"ui.debug\" = { fg = \"red\" }\n\n[palette]\nyellow = \"#dfc184\"\norange = \"#bf956a\"\nblue = \"#73ade9\"\nblue-gray = \"#5a6f89\"\nred = \"#d07277\"\npurple = \"#b477cf\"\ngreen = \"#a1c181\"\ncyan = \"#6eb4bf\"\ngray = \"#2f343e\"\nlight-gray = \"#5d636f\"\nfaint-gray = \"#3B4048\"\nlinenr = \"#5d636f\"\n\nwhite = \"#c8ccd4\"\nblack = \"#282c33\"\n# black and white are used for a lot of the UI text\nui-text = \"#c8ccd4\"          #white\nui-text-reversed = \"#282c33\" #black\n"
  },
  {
    "path": "runtime/themes/zed_onelight.toml",
    "content": "# Zed OneLight\n# Author : EricHenry\n\ninherits = \"zed_onedark\"\n\n\"attribute\" = { fg = \"green\" }\n\"constant\" = { fg = \"green\" }\n\"constant.numeric\" = { fg = \"gold\" }\n\"constant.builtin\" = { fg = \"gold\" }\n\"constant.builtin.boolean\" = { fg = \"green\" }\n\"variable.builtin\" = { fg = \"gold\" }\n\"variable.other.member\" = { fg = \"orange\" }\n\n\"markup.heading\" = { fg = \"orange\" }\n\"markup.list\" = { fg = \"orange\" }\n\"markup.quote\" = { fg = \"green\" }\n\n\"ui.cursor\" = { fg = \"dark-blue\", modifiers = [\"reversed\"] }\n\"ui.cursor.primary\" = { fg = \"dark-blue\", modifiers = [\"reversed\"] }\n\"ui.cursor.insert\" = { fg = \"dark-blue\" }\n\n\"ui.selection.primary\" = { bg = \"blue-gray\" }\n\"ui.cursorline.primary\" = { bg = \"faint-gray\" }\n\n\"ui.virtual.inlay-hint\" = { fg = \"violet\", modifiers = [\"bold\"] }\n\n\"ui.statusline\" = { fg = \"black\", bg = \"gray\" }\n\"ui.statusline.inactive\" = { fg = \"white\", bg = \"light-black\" }\n\"ui.statusline.normal\" = { fg = \"white\", bg = \"blue\" }\n\"ui.statusline.insert\" = { fg = \"white\", bg = \"green\" }\n\"ui.statusline.select\" = { fg = \"white\", bg = \"purple\" }\n\n\"ui.text.focus\" = { fg = \"ui-text\", bg = \"gray\", modifiers = [\"bold\"] }\n\n\"ui.help\" = { fg = \"black\", bg = \"dark-gray\" }\n\"ui.popup\" = { bg = \"dark-gray\" }\n\"ui.window\" = { fg = \"dark-gray\" }\n\n[palette]\nyellow = \"#dabb7e\"\nred = \"#d36151\"\norange = \"#d3604f\"\nblue = \"#5b79e3\"\ndark-blue = \"#4a62db\"\npurple = \"#a449ab\"\nviolet = \"#9294be\"\ngreen = \"#649f57\"\ngold = \"#ad6e25\"\ncyan = \"#3882b7\"\nlight-black = \"#2e323a\"\n# gray = \"#dcdcdd\"\ngray = \"#eaeaed\"\ndark-gray = \"#ebebec\"\nlight-gray = \"#a2a3a7\"\nblue-gray = \"#d9dcea\"\nfaint-gray = \"#efefef\"\nlinenr = \"#b0b1b3\"\n\nblack = \"#383a41\"\nwhite = \"#fafafa\"\nui-text = \"#383a41\"\nui-text-reversed = \"#fafafa\"\n"
  },
  {
    "path": "runtime/themes/zenburn.toml",
    "content": "# Port of Vim's Zenburn theme (https://github.com/jnurmine/Zenburn/)\n# based on theli-ua's Helix port (https://github.com/theli-ua/helix/tree/zenburn)\n# Author: Jakob Jordan <jakobjordan(at)posteo.de>\n# License: GNU GPL <http://www.gnu.org/licenses/gpl.html> \n\n# \"attribute\"\n\"type\" = \"zb-type-fg\"\n\"type.builtin\" = { fg = \"zb-type-fg\", modifiers = [\"bold\"] }\n\"type.parameter\" = { fg = \"zb-typedef-fg\", modifiers = [\"bold\"] }\n\"type.enum\" = { fg = \"zb-structure-fg\", modifiers = [\"bold\"] }\n# \"type.enum.variant\"\n\"constructor\" = \"zb-type-fg\"\n\"constant\" = { fg = \"zb-constant-fg\", modifiers = [\"bold\"] }\n# \"constant.builtin\"\n\"constant.builtin.boolean\" = \"zb-boolean-fg\"\n\"constant.character\" = { fg = \"zb-character-fg\", modifiers = [\"bold\"] }\n# \"constant.character.escape\"\n\"constant.numeric.integer\" = { fg = \"zb-number-fg\" }\n\"constant.numeric.float\" = { fg = \"zb-float-fg\" }\n\"string\" = \"zb-string-fg\"\n# \"string.regexp\"\n# \"string.special\"\n# \"string.special.path\"\n# \"string.special.url\"\n# \"string.special.symbol\"\n\"comment\" = \"zb-comment-fg\"\n# \"comment.line\"\n\"comment.line.documentation\" = { fg = \"zb-specialcomment-fg\", modifiers = [\"bold\"] }\n# \"comment.block\"\n\"comment.block.documentation\" = { fg = \"zb-specialcomment-fg\", modifiers = [\"bold\"] }\n\"variable\" = \"zb-identifier-fg\"\n\"variable.builtin\" = { modifiers = [\"bold\"] }\n# \"variable.parameter\"\n# \"variable.other\"\n# \"variable.other.member\"\n# \"variable.other.member.private\"\n\"label\" = { fg = \"zb-label-fg\", underline = { style = 'line' } }\n# \"punctuation\"\n\"punctuation.delimiter\" = \"zb-delimiter-fg\"\n# \"punctuation.bracket\"\n\"punctuation.special\" = \"zb-special-fg\"\n\"keyword\" = { fg = \"zb-keyword-fg\", modifiers = [\"bold\"] }\n# \"keyword.control\"\n\"keyword.control.conditional\" = { fg = \"zb-conditional-fg\", modifiers = [\"bold\"] }\n\"keyword.control.repeat\" = { fg = \"zb-repeat-fg\", modifiers = [\"bold\"] }\n\"keyword.control.import\" = { fg = \"zb-preproc-fg\", modifiers = [\"bold\"] }\n# \"keyword.control.return\"\n\"keyword.control.exception\" = { fg = \"zb-exception-fg\", modifiers = [\"bold\"] }\n# \"keyword.operator\"\n# \"keyword.directive\"\n# \"keyword.function\"\n# \"keyword.storage\"\n\"keyword.storage.type\" = { fg = \"zb-storageclass-fg\", modifiers = [\"bold\"] }\n# \"keyword.storage.modifier\"\n\"operator\" = \"zb-operator-fg\"\n\"function\" = \"zb-function-fg\"\n\"function.builtin\" = { fg = \"zb-function-fg\", modifiers = [\"bold\"] }\n# \"function.method\"\n# \"function.method.private\"\n\"function.macro\" = { fg = \"zb-macro-fg\", modifiers = [\"bold\"] }\n# \"function.special\"\n\"tag\" = { fg = \"zb-tag-fg\", modifiers = [\"bold\"] }\n# \"tag.builtin\"\n\"namespace\" = { fg = \"zb-include-fg\", modifiers = [\"bold\"] }\n\"special\" = \"zb-special-fg\"\n# \"markup\"\n\"markup.heading\" = { fg = \"zb-constant-fg\", modifiers = [\"bold\"] }\n# \"markup.heading.marker\"\n# \"markup.heading.1\"\n# \"markup.heading.2\"\n# \"markup.heading.3\"\n# \"markup.heading.4\"\n# \"markup.heading.5\"\n# \"markup.heading.6\"\n\"markup.list\" = \"zb-number-fg\"\n# \"markup.list.unnumbered\"\n# \"markup.list.numbered\"\n# \"markup.list.checked\"\n# \"markup.list.unchecked\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link\" = { underline.style = \"line\" }\n# \"markup.link.url\"\n# \"markup.link.label\"\n# \"markup.link.text\" = \"zb-cyan\"\n\"markup.quote\" = \"zb-comment-fg\"\n\"markup.raw\" = \"zb-delimiter-fg\"\n# \"markup.raw.inline\"\n# \"markup.raw.block\"\n# \"diff\"\n\"diff.plus\" = { fg = \"zb-diffadd-fg\", bg = \"zb-diffadd-bg\", modifiers = [\"bold\"] }\n\"diff.plus.gutter\" = \"zb-diffadd-fg\"\n\"diff.minus\" = { fg = \"zb-diffdelete-fg\", bg = \"zb-diffdelete-bg\" }\n\"diff.minus.gutter\" = \"zb-string-fg\"\n\"diff.delta\" = { bg = \"zb-diffchange-bg\" }\n# \"diff.delta.moved\"\n# \"diff.delta.conflict\"\n\"diff.delta.gutter\" = \"zb-normal-fg\"\n\n\"ui.background\" = { bg = \"zb-normal-bg\" }\n# \"ui.background.separator\"\n\"ui.cursor\" = { fg = \"zb-cursor-fg\", bg = \"zb-cursor-bg\", modifiers = [\"bold\"] }\n# \"ui.cursor.normal\"\n# \"ui.cursor.insert\"\n# \"ui.cursor.select\"\n\"ui.cursor.match\" = { fg = \"zb-matchparen-fg\", bg = \"zb-matchparen-bg\", modifiers = [\"bold\"] }\n# \"ui.cursor.primary\"\n# \"ui.cursor.primary.normal\"\n# \"ui.cursor.primary.insert\"\n# \"ui.cursor.primary.select\"\n# \"ui.debug.breakpoint\"\n# \"ui.debug.active\"\n\"ui.gutter\" = { bg = \"zb-linenr-bg\" }\n# ui.gutter.selected\tGutter for the line the cursor is on\n\"ui.linenr\" = { fg = \"zb-linenr-fg\", bg = \"zb-linenr-bg\" }\n\"ui.linenr.selected\" = { fg = \"zb-cursorlinenr-fg\", bg = \"zb-cursorlinenr-bg\", modifiers = [\"bold\"] }\n\"ui.statusline\" = { bg = \"zb-statusline-fg\", fg = \"zb-statusline-bg\", modifiers = [\"bold\"] }\n\"ui.statusline.inactive\" = { bg = \"zb-statuslinenc-fg\", fg = \"zb-statuslinenc-bg\", modifiers = [] }\n# \"ui.statusline.normal\"\n# \"ui.statusline.insert\"\n# \"ui.statusline.select\"\n# \"ui.statusline.separator\"\n# \"ui.bufferline\"\n# \"ui.bufferline.active\"\n# \"ui.bufferline.background\"\n\"ui.popup\" = { fg = \"zb-pmenu-fg\", bg = \"zb-pmenu-bg\" }\n# \"ui.popup.info\"\n# \"ui.picker.header\"\n# \"ui.picker.header.column\"\n# \"ui.picker.header.column.active\"\n# \"ui.window\" = \"zb-lineno\"\n\"ui.help\" = { fg = \"zb-pmenu-fg\", bg = \"zb-pmenu-bg\" }\n\"ui.text\" = \"zb-normal-fg\"\n\"ui.text.focus\" = { modifiers = [\"bold\"] }\n# \"ui.text.inactive\"\n\"ui.text.info\" = { fg = \"zb-pmenu-fg\", bg = \"zb-pmenu-bg\" }\n\"ui.virtual.ruler\" = { bg = \"zb-colorcolumn-bg\" }\n\"ui.virtual.whitespace\" = { fg = \"zb-nontext-fg\", modifiers = [\"bold\"] }\n\"ui.virtual.indent-guide\" = { fg = \"zb-colorcolumn-bg\" }\n# \"ui.virtual.inlay-hint\"\n# \"ui.virtual.inlay-hint.parameter\"\n# \"ui.virtual.inlay-hint.type\"\n# \"ui.virtual.wrap\"\n\"ui.virtual.jump-label\" = { modifiers = [\"bold\"] }\n\"ui.menu\" = { fg = \"zb-pmenu-fg\", bg = \"zb-pmenu-bg\" }\n\"ui.menu.selected\" = { fg = \"zb-pmenusel-fg\", bg = \"zb-pmenusel-bg\", modifiers = [\"bold\"] }\n# \"ui.menu.scroll\"\n\"ui.selection\" = { bg = \"#373737\" }\n\"ui.selection.primary\" = { bg = \"zb-visual-bg\" }\n# \"ui.highlight\"\n# \"ui.highlight.frameline\"\n\"ui.cursorline.primary\" = { bg = \"zb-cursorline-bg\" }\n# \"ui.cursorline.secondary\"\n\"ui.cursorcolumn.primary\" = { bg = \"zb-cursorcolumn-bg\" }\n# \"ui.cursorcolumn.secondary\"\n\"warning\" = { fg = \"zb-error-fg\", modifiers = [\"bold\"] }\n\"error\" = { fg = \"zb-error-fg\", modifiers = [\"bold\"] }\n\"info\" = { fg = \"zb-todo-fg\", modifiers = [\"bold\"] }\n\"hint\" = { fg = \"zb-todo-fg\", modifiers = [\"bold\"] }\n# \"diagnostic\"\n\"diagnostic.hint\" = { fg = \"zb-todo-fg\", bg = \"zb-todo-bg\", modifiers = [\"bold\"] }\n\"diagnostic.info\" = { fg = \"zb-todo-fg\", bg = \"zb-todo-bg\", modifiers = [\"bold\"] }\n\"diagnostic.warning\" = { fg = \"zb-error-fg\", bg = \"zb-error-bg\", modifiers = [\"bold\"] }\n\"diagnostic.error\" = { fg = \"zb-error-fg\", bg = \"zb-error-bg\", modifiers = [\"bold\"] }\n\"diagnostic.unnecessary\" = { fg = \"zb-todo-fg\", bg = \"zb-todo-bg\", modifiers = [\"bold\"] }\n\"diagnostic.deprecated\"= { fg = \"zb-todo-fg\", bg = \"zb-todo-bg\", modifiers = [\"bold\"] }\n\n[palette]\n\"zb-boolean-fg\" = \"#dca3a3\"\n\"zb-character-fg\" = \"#dca3a3\" # gui=bold\n\"zb-comment-fg\" = \"#7f9f7f\"\n\"zb-conditional-fg\" = \"#f0dfaf\" # gui=bold\n\"zb-constant-fg\" = \"#dca3a3\" # gui=bold\n\"zb-cursor-fg\" = \"#000d18\"\n\"zb-cursor-bg\" = \"#8faf9f\" # gui=bold\n\"zb-debug-fg\" = \"#bca3a3\" # gui=bold\n\"zb-define-fg\" = \"#ffcfaf\" # gui=bold\n\"zb-delimiter-fg\" = \"#8f8f8f\"\n\"zb-diffadd-fg\" = \"#709080\"\n\"zb-diffadd-bg\" = \"#313c36\" # gui=bold\n\"zb-diffchange-bg\" = \"#333333\"\n\"zb-diffdelete-fg\" = \"#333333\"\n\"zb-diffdelete-bg\" = \"#464646\"\n\"zb-difftext-fg\" = \"#ecbcbc\"\n\"zb-difftext-bg\" = \"#41363c\" # gui=bold\n\"zb-directory-fg\" = \"#9fafaf\" # gui=bold\n\"zb-errormsg-fg\" = \"#80d4aa\"\n\"zb-errormsg-bg\" = \"#2f2f2f\" # gui=bold\n\"zb-exception-fg\" = \"#c3bf9f\" # gui=bold\n\"zb-float-fg\" = \"#c0bed1\"\n# \"zb-foldcolumn-fg\" = \"#93b3a3\"\n# \"zb-foldcolumn-bg\" = \"#3f4040\"\n# \"zb-folded-fg\" = \"#93b3a3\"\n# \"zb-folded-bg\" = \"#3f4040\"\n\"zb-function-fg\" = \"#efef8f\"\n\"zb-identifier-fg\" = \"#efdcbc\"\n\"zb-incsearch-fg\" = \"#f8f893\"\n\"zb-incsearch-bg\" = \"#385f38\"\n\"zb-keyword-fg\" = \"#f0dfaf\" # gui=bold\n\"zb-macro-fg\" = \"#ffcfaf\" # gui=bold\n\"zb-modemsg-fg\" = \"#ffcfaf\" # gui=none\n\"zb-moremsg-fg\" = \"#ffffff\" # gui=bold\n\"zb-number-fg\" = \"#8cd0d3\"\n\"zb-operator-fg\" = \"#f0efd0\"\n\"zb-pmenusbar-fg\" = \"#000000\"\n\"zb-pmenusbar-bg\" = \"#2e3330\"\n\"zb-pmenuthumb-fg\" = \"#040404\"\n\"zb-pmenuthumb-bg\" = \"#a0afa0\"\n\"zb-precondit-fg\" = \"#dfaf8f\" # gui=bold\n\"zb-preproc-fg\" = \"#ffcfaf\" # gui=bold\n\"zb-question-fg\" = \"#ffffff\" # gui=bold\n\"zb-repeat-fg\" = \"#ffd7a7\" # gui=bold\n\"zb-search-fg\" = \"#ffffe0\"\n\"zb-search-bg\" = \"#284f28\"\n\"zb-signcolumn-fg\" = \"#9fafaf\" # gui=bold\n\"zb-specialchar-fg\" = \"#dca3a3\" # gui=bold\n\"zb-specialcomment-fg\" = \"#82a282\" # gui=bold\n\"zb-special-fg\" = \"#cfbfaf\"\n\"zb-specialkey-fg\" = \"#9ece9e\"\n\"zb-statement-fg\" = \"#e3ceab\" # gui=none\n\"zb-statusline-fg\" = \"#313633\"\n\"zb-statusline-bg\" = \"#ccdc90\"\n\"zb-statuslinenc-fg\" = \"#2e3330\"\n\"zb-statuslinenc-bg\" = \"#88b090\"\n\"zb-storageclass-fg\" = \"#c3bf9f\" # gui=bold\n\"zb-string-fg\" = \"#cc9393\"\n\"zb-structure-fg\" = \"#efefaf\" # gui=bold\n\"zb-tag-fg\" = \"#e89393\" # gui=bold\n\"zb-title-fg\" = \"#efefef\" # gui=bold\n\"zb-todo-fg\" = \"#dfdfdf\" # gui=bold\n\"zb-todo-bg\" = \"#575757\"\n\"zb-typedef-fg\" = \"#dfe4cf\" # gui=bold\n\"zb-type-fg\" = \"#dfdfbf\" # gui=bold\n\"zb-underlined-fg\" = \"#dcdccc\" # gui=underline\n\"zb-vertsplit-fg\" = \"#2e3330\"\n\"zb-vertsplit-bg\" = \"#688060\"\n# \"zb-visualnos-fg\" = \"#333333\"\n# \"zb-visualnos-bg\" = \"#f18c96\" # gui=bold,underline\n\"zb-warningmsg-fg\" = \"#ffffff\"\n\"zb-warningmsg-bg\" = \"#333333\" # gui=bold\n\"zb-wildmenu-fg\" = \"#cbecd0\"\n\"zb-wildmenu-bg\" = \"#2c302d\" # gui=underline\n\n\"zb-normal-fg\" = \"#dcdccc\"\n\"zb-normal-bg\" = \"#3f3f3f\"\n\"zb-conceal-fg\" = \"#8f8f8f\"\n\"zb-conceal-bg\" = \"#484848\"\n\"zb-colorcolumn-bg\" = \"#484848\"\n\"zb-cursorline-bg\" = \"#434443\"\n\"zb-cursorlinenr-fg\" = \"#d2d39b\"\n\"zb-cursorlinenr-bg\" = \"#262626\"\n\"zb-cursorcolumn-bg\" = \"#4f4f4f\"\n\"zb-foldcolumn-bg\" = \"#333333\"\n\"zb-folded-bg\" = \"#333333\"\n\"zb-linenr-fg\" = \"#9fafaf\"\n\"zb-linenr-bg\" = \"#262626\"\n\"zb-nontext-fg\" = \"#5b605e\" # gui=bold\n\"zb-pmenu-fg\" = \"#9f9f9f\"\n\"zb-pmenu-bg\" = \"#2c2e2e\"\n\"zb-pmenusel-fg\" = \"#d0d0a0\"\n\"zb-pmenusel-bg\" = \"#242424\" # gui=bold\n\"zb-matchparen-fg\" = \"#ffffe0\"\n\"zb-matchparen-bg\" = \"#284f28\" # gui=bold\n\"zb-signcolumn-bg\" = \"#343434\"\n\"zb-specialkey-bg\" = \"#444444\"\n\"zb-tabline-fg\" = \"#d0d0b8\"\n\"zb-tabline-bg\" = \"#222222\" # gui=none\n\"zb-tablinesel-fg\" = \"#f0f0b0\"\n\"zb-tablinesel-bg\" = \"#333333\" # gui=bold\n\"zb-tablinefill-fg\" = \"#dccdcc\"\n\"zb-tablinefill-bg\" = \"#101010\" # gui=none\n\"zb-visual-bg\" = \"#2f2f2f\"\n\"zb-visualnos-bg\" = \"#2f2f2f\"\n\"zb-error-fg\" = \"#e37170\"\n\"zb-error-bg\" = \"#3d3535\" # gui=bold\n\"zb-include-fg\" = \"#dfaf8f\" # gui=bold\n\"zb-label-fg\" = \"#dfcfaf\" # gui=underline\n"
  },
  {
    "path": "runtime/tutor",
    "content": "\n\n       .\n       ###x.        .|\n       d#####x,   ,v||\n        '+#####v||||||\n           ,v|||||+'.      _     _           _\n        ,v|||||^'>####    | |   | |   ___   | | (_) __  __\n       |||||^'  .v####    | |___| |  /   \\  | |  _  \\ \\/ /\n       ||||=..v#####P'    |  ___  | /  ^  | | | | |  \\  /\n       ''v'>#####P'       | |   | | |  ---  | | | |  /  \\\n       ,######/P||x.      |_|   |_|  \\___/  |_| |_| /_/\\_\\\n       ####P' \"x|||||,\n       |/'       'x|||    A post-modern modal text editor.\n        '           '|\n\n\n                 Welcome to the Helix tutorial!\n        Press the j key until you reach the introduction.\n\n\n\n=================================================================\n=                        INTRODUCTION                           =\n=================================================================\n\n Welcome to the Helix editor! Helix is different from editors\n you might be used to in that it is modal, meaning that it has\n different modes for editing text. The primary modes you will\n use are Normal mode and Insert mode. While in Normal mode, the\n keys you type won't actually type text. Instead, they will\n perform various actions with the text. This allows for more\n efficient editing. This tutor will teach you how you can make\n use of Helix's modal editing features. To begin, ensure your\n CapsLock key is not pressed and hold the j key until you reach\n the first lesson.\n\n\n\n\n\n\n\n\n=================================================================\n=                  1.1 BASIC CURSOR MOVEMENT                    =\n=================================================================\n\n          ↑\n          k       * h is on the left\n      ← h   l →   * l is on the right\n          j       * j looks like a down arrow\n          ↓\n\n The cursor can be moved using the h, j, k, l keys, as shown\n above. The cursor / arrow keys will also work, but it is faster\n to use the hjkl keys as they are closer to the other keys you\n will be using. Try moving around to get a feel for hjkl.\n Once you're ready, hold j to continue to the next lesson.\n\n\n\n\n\n\n\n=================================================================\n=                      1.2 EXITING HELIX                        =\n=================================================================\n\n 1. Type : to enter Command mode. Your cursor will\n    move to the bottom of the screen.\n 2. Type q or quit and press Enter to exit Helix.\n\n Note: The quit command will fail if there are unsaved changes.\n       To force quit and DISCARD these changes, type q! or quit!.\n       You will learn how to save files later.\n\n To exit Command mode without entering a command, press Escape.\n\n Now, move on to the next lesson.\n\n\n\n\n\n\n\n=================================================================\n=                         1.3 DELETION                          =\n=================================================================\n\n Type the d key to delete the character under the cursor.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Move the cursor to each extra character, and type d to\n    delete it.\n\n --> Thhiss senttencee haass exxtra charracterss.\n     This sentence has extra characters.\n\n Once the sentence is correct, move on to the next lesson.\n\n\n\n\n\n\n\n\n=================================================================\n=                       1.4 INSERT MODE                         =\n=================================================================\n\n Type the i key to enter Insert mode.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Move to a place in the line which is missing text and type\n    i to enter Insert mode. Keys you type will now type text.\n 3. Enter the missing text.\n 4. Press Escape to exit Insert mode and return to Normal mode.\n 5. Repeat until the line matches the line below it.\n\n --> Th stce misg so.\n     This sentence is missing some text.\n\n Note: The status bar will display your current mode.\n       Notice that when you type i, 'NOR' changes to 'INS'.\n\n\n\n\n=================================================================\n=                      1.5 SAVING A FILE                        =\n=================================================================\n\n Type :w / :write to save a file.\n\n 1. Exit Helix using :q! as explained before, or open a new\n    terminal.\n 2. Open a file in Helix by running: hx FILENAME\n 3. Make some edits to the file.\n 4. Type : to enter Command mode.\n 5. Type w or write, and press Enter to save the file.\n\n You can also type wq or write-quit to save and exit.\n\n Note: You can optionally enter a file path after the w / write\n       command in order to save to that path.\n Note: If there are any unsaved changes to a file, a plus [+]\n       will appear next to the file name in the status bar.\n\n\n\n=================================================================\n=                        CHAPTER 1 RECAP                        =\n=================================================================\n\n * Use the h,j,k,l keys to move the cursor.\n\n * Type : to enter Command mode.\n   * The q / quit and q! / quit! commands will exit Helix. The\n     former fails when there are unsaved changes. The latter\n     discards them.\n   * The w / write command will save the file.\n   * The wq / write-quit command will do both.\n\n * Type d to delete the character at the cursor.\n\n * Type i to enter Insert mode and type text. Press Escape to\n   return to Normal mode.\n\n\n\n\n\n=================================================================\n=                   2.1 MORE INSERT COMMANDS                    =\n=================================================================\n\n As you saw, you can type i to enter Insert mode at the current\n position of the cursor. There are a few other ways you can\n enter Insert mode at different locations.\n\n Common examples of insertion commands include:\n   i - Insert before the selection.\n   a - Insert after the selection. (a means 'append')\n   I - Insert at the start of the line.\n   A - Insert at the end of the line.\n\n 1. Move to anywhere in the line marked '-->' below.\n 2. Type A (Shift-a), your cursor will move to the end of\n    the line and you will be able to type.\n 3. Type the text necessary to match the line below.\n\n --> This sentence is miss\n     This sentence is missing some text.\n\n=================================================================\n=                      2.2 OPENING LINES                        =\n=================================================================\n\n Type o to add a newline and insert below the cursor.\n Type O to add a newline and insert above the cursor.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Type o to open a line below and type your answer.\n\n --> What is the best editor?\n\n\n\n\n\n\n\n\n\n\n\n=================================================================\n=                        CHAPTER 2 RECAP                        =\n=================================================================\n\n * Type a to append to the selection.\n\n * Type I to enter Insert mode at the first non-whitespace\n   character at the start of a line.\n\n * Type A to enter Insert mode at the end of a line.\n\n * Use o and O to open lines below and above the cursor respectively.\n\n\n\n\n\n\n\n\n\n\n=================================================================\n=                  3.1 MOTIONS AND SELECTIONS                   =\n=================================================================\n\n Type w to select forward until the next word.\n\n The d key doesn't actually delete the character at the cursor,\n it deletes all selected text. Your cursor is like a\n single-character selection.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Move to the beginning of a word that needs to be deleted.\n 3. Type w to select until the beginning of the next word.\n 4. Type d to delete the selection.\n 5. Repeat for all extra words in the line.\n\n --> This sentence pencil has vacuum extra words in the it.\n     This sentence has extra words in it.\n\n\n\n\n=================================================================\n=                     3.2 MORE MOTIONS                          =\n=================================================================\n\n As you saw, typing w moves the cursor forward until the start\n of the next word, selecting the text traversed. This is useful\n for moving around text and for selecting text to operate on.\n\n Some common motions include:\n   w - Move forward to before the beginning of the next word.\n   e - Move forward to the end of the current word.\n   b - Move backward to the beginning of the current word.\n\n To select the word under cursor, combine e and b.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Move to a 'd' letter.\n 3. Type e to select a half of the word.\n 4. Type b to select the rest.\n\n--> The Middle Kingdom.\n\n=================================================================\n=                     3.3 WORDS AND words                       =\n=================================================================\n\n The w,e,b motions also have counterparts - W,E,B - which\n traverse WORDS instead of words. WORDS are only separated by\n whitespace, whereas words can be separated by other characters\n in addition to whitespace.\n\n 1. Move the cursor to the beginning of the line marked with '-->'.\n 2. Type w repeatedly to select individual words until you\n    reach the end of the line.\n 3. Note that 'one-of-a-kind' required 7 keystrokes to be\n    traversed. '\"modal\"' required 3 keystrokes.\n 4. Move the cursor back to beginning of the line marked '-->'.\n 5. Type W repeatedly to select individual WORDS.\n 6. Note that 'one-of-a-kind' and '\"modal\"' have been selected\n    both with one keystroke each.\n\n--> Helix is a one-of-a-kind \"modal\" text editor\n\n\n=================================================================\n=                    3.4 THE CHANGE COMMAND                     =\n=================================================================\n\n Type c to change the current selection.\n\n The change command deletes the current selection and enters\n Insert mode, so it is a very common shorthand for di.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Move to the start of an incorrect word and type e to\n    select it.\n 3. Type c to delete the word and enter Insert mode.\n 4. Type the correct word.\n 5. Repeat until the line matches the line below it.\n\n --> This paper has heavy words behind it.\n     This sentence has incorrect words in it.\n\n\n\n\n=================================================================\n=                   3.5 COUNTS WITH MOTIONS                     =\n=================================================================\n\n Type a number before a motion to repeat it that many times.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Type 2w to move 2 words forward.\n 3. Type 3e to move to the end of the third word forward.\n 4. Type 2b to move 2 words backwards.\n 5. Try the above with different numbers.\n\n --> This is just a line with words you can move around in.\n\n\n\n\n\n\n\n\n\n=================================================================\n=                    3.6 SELECT / EXTEND MODE                   =\n=================================================================\n\n Type v to enter Select mode.\n Type v again or Escape to return to Normal mode\n In Select mode every movement will extend the selection, as\n opposed to replacing it.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Move to the F of FOO and type v2w to select the two words.\n 3. Type d to remove the two words. Notice d returns you to\n    Normal mode.\n 4. Move to the B of BAZ and repeat the sequence to delete them.\n\n --> Remove the FOO BAR distracting words BAZ BIZ from this line.\n\n\n\n\n\n\n=================================================================\n=                     3.7 SELECTING LINES                       =\n=================================================================\n\n Type x to select a whole line. Type x again to select the next.\n\n 1. Move the cursor to the second line marked '-->' below.\n 2. Type x to select the line, and d to delete it.\n 3. Move to the fourth line.\n 4. Type x twice or type 2x to select 2 lines, and d to delete.\n\n --> 1) Roses are red,\n --> 2) Mud is fun,\n --> 3) Violets are blue,\n --> 4) I have a car,\n --> 5) Clocks tell time,\n --> 6) Sugar is sweet,\n --> 7) And so are you.\n\n Note: X works similarly to x although it doesn't extend to\n       subsequent lines. X on an empty line does nothing.\n\n=================================================================\n=                   3.8 COLLAPSING SELECTIONS                   =\n=================================================================\n\n Type ; to collapse selections to single cursors.\n\n Sometimes, you want to deselect without having to move the\n cursor(s). This can be done using the ; key.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Use the motions you have learned to move around the line,\n    and try using ; to deselect the text after it is selected\n    by the motions.\n\n --> This is an error-free line with words to move around in.\n\n Note: This works the same in Select mode.\n Note: Another related command is Alt-; which flips the direction\n       of the selection (flips the selection's cursor and anchor).\n\n\n\n=================================================================\n=                        CHAPTER 3 RECAP                        =\n=================================================================\n\n * Type w to select forward until the next word.\n   * Type e to select to the end of the current word.\n   * Type b to select backward to the start of the current word.\n   * Use uppercase counterparts, W,E,B, to traverse WORDS.\n\n * Type d to delete the entire selection.\n   * Type c to delete the selection and enter Insert mode.\n\n * Type a number before a motion to repeat it that many times.\n\n * Type v to enter Select mode, where all motions extend the\n   selection.\n\n * Type x to select the entire current line. Type x again to\n   select the next line.\n\n * Type semicolon ( ; ) to collapse selection.\n\n=================================================================\n=                         4.1 UNDOING                           =\n=================================================================\n\n Type u to undo. Type U to redo.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Move to the first error, and type d to delete it.\n 3. Type u to undo your deletion.\n 4. Fix all the errors on the line.\n 5. Type u several times to undo your fixes.\n 6. Type U (Shift-u) several times to redo your fixes.\n\n --> Fiix the errors on thhis line and reeplace them witth undo.\n\n\n\n\n\n\n\n\n=================================================================\n=                 4.2 COPYING AND PASTING TEXT                  =\n=================================================================\n\n Type y to yank (copy) the selection.\n Type p to paste the yanked selection after the cursor.\n Type P to paste the yanked text before the cursor.\n\n 1. Move the cursor to the line marked '-->' below.\n    Make sure your cursor is on the \"b\" of banana.\n 2. Type w to select \"banana\" and y to yank it.\n 3. Move to the space between \"2\" and \"3\" and type p to paste.\n 4. Repeat between \"3\" and \"4\".\n\n --> 1 banana 2 3 4\n     1 banana 2 banana 3 banana 4\n\n Note: Whenever you delete or change text, Helix will copy the\n       altered text. Use Alt-d / Alt-c instead to avoid this.\n Note: Helix doesn't share the system clipboard by default. Type\n       Space + y / p to yank / paste on the system's clipboard.\n\n=================================================================\n=                     4.3 SEARCHING IN FILE                     =\n=================================================================\n\n Type / to search forward in file, Enter to confirm search.\n Type n to go to the next search match.\n Type N to go to the previous search match.\n\n 1. Type / and type in a common word, like 'banana'.\n 2. Press Enter to confirm the search.\n 3. Use n and N to cycle through the matches.\n\n Searching uses regular expressions, allowing you to target more\n complex expressions, which you'll learn about in the lesson on\n the select command.\n\n Note: To search backwards, type ? (Shift-/).\n Note: Unlike Vim, ? doesn't change the search direction.\n       N always goes backwards and n always goes forwards.\n\n\n\n=================================================================\n=                        CHAPTER 4 RECAP                        =\n=================================================================\n\n * Type u to undo. Type U to redo.\n\n * Type y to yank (copy) text and p to paste.\n   * Use Space + y and Space + p to yank / paste on the system\n     clipboard.\n\n * Type / to search forward in file, and ? to search backwards.\n   * Use n and N to cycle through search matches.\n\n\n\n\n\n\n\n\n\n\n=================================================================\n=                     5.1 MULTIPLE CURSORS                      =\n=================================================================\n\n Type C to duplicate the cursor to the next suitable line.\n\n 1. Move the cursor to the first line marked '-->' below. Place\n    the cursor somewhere past the '-->'.\n 2. Type C to duplicate the cursor to the next suitable line.\n    Notice how it skips the line in the middle. Keys you type\n    will now affect both cursors.\n 3. Use Insert mode to correct the lines. The two cursors will\n    fix both lines simultaneously.\n 4. Type , to remove the first cursor.\n\n --> Fix th two nes at same ime.\n -->\n --> Fix th two nes at same ime.\n     Fix these two lines at the same time.\n\n Note: Press Alt-C to do the same above the cursor.\n\n=================================================================\n=                    5.2 THE SELECT COMMAND                     =\n=================================================================\n\n Type s to select matches in the selection.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Type x to select the line.\n 3. Type s. A prompt will appear.\n 4. Type 'apples' and press Enter. Both occurrences of\n    'apples' in the line will be selected.\n 5. You can now type c and change 'apples' to something else,\n    like 'oranges'.\n 6. Press Escape to exit Insert mode.\n 7. Type , to remove the second cursor.\n\n --> I like to eat apples since my favorite fruit is apples.\n     I like to eat oranges since my favorite fruit is oranges.\n\n\n\n\n=================================================================\n=                    5.3 SELECTING VIA REGEX                    =\n=================================================================\n\n Like searching, the select command selects regular expressions,\n not just exact matches.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Select the line with x and then type s.\n 3. Type '  +' to select any amount of consecutive spaces >1,\n    then press Enter.\n 4. Type c and change the matches to single spaces.\n\n --> This  sentence has   some      extra spaces.\n     This sentence has some extra spaces.\n\n Note: If you want to perform find-and-replace, the select\n       command is the way to do it. Select the text you want\n       to replace in — type % to select the whole file — and\n       then perform the steps explained above.\n\n\n=================================================================\n=                      5.4 ALIGN SELECTIONS                     =\n=================================================================\n\n Type & to align the contents of the selections.\n\n 1. Move the cursor to the first line marked '-->' below. Place\n    the cursor on the whitespace just after the arrow.\n 2. Type C four times or 4C.\n 3. Type W to select the numbers and brackets.\n 4. Type & to align the words.\n\n --> 97) lorem\n --> 98) ipsum\n --> 99) dolor\n --> 100) sit\n --> 101) amet\n\n Note: & only cares about the alignment of the \"head\" of the\n       selections - the end that moves. The other end is called\n       the \"anchor\".\n\n=================================================================\n=                 5.5 SPLIT SELECTION INTO LINES                =\n=================================================================\n\n Press Alt-s to split the selection(s) on newlines.\n\n 1. Move the cursor to the first row of the table below.\n 2. Select the entire table with 6x.\n 3. Press Alt-s to split into selections at each line.\n 4. Align the table with &.\n\n    | FRUIT   | AMOUNT |\n    |---------|--------|\n | Apples  | 8      |\n    | Bananas | 6      |\n  | Oranges | 3      |\n     | Donuts  | 4      |\n\n Note: On macOS, you may need to configure your terminal to use\n       Option as Alt (e.g. macos-option-as-alt = left).\n       This is also true for future Alt- commands.\n\n=================================================================\n=                        CHAPTER 5 RECAP                        =\n=================================================================\n\n * Type C to duplicate the cursor to the next suitable line\n   and Alt-C for previous suitable line.\n\n * Type s to select all instances of a regex pattern inside\n   the current selection.\n\n * Type & to align selections.\n\n * Press Alt-s to split the selection into lines.\n\n\n\n\n\n\n\n\n\n=================================================================\n=                 6.1 SELECTING TO A CHARACTER                  =\n=================================================================\n\n Type f<ch> to select up to and including (find) a character.\n Type t<ch> to do the same, but not including (till) a character.\n Type uppercase F / T to do the same backwards.\n\n 1. Move the cursor to the line marked '-->' below. Place the\n    cursor on the first dash.\n 2. Type f[ to select to the square bracket.\n 3. Type d to delete your selection.\n 4. Go to the end of the line and repeat with F].\n 5. Move to the second line marked '-->', just after the arrow.\n 6. Use t and T to delete the dashes around the sentence.\n\n --> -----[Free this sentence of its brackets!]-----\n --> ------Free this sentence of its dashes!------\n\n Note: Unlike Vim, Helix doesn't limit these commands to the\n       current line. It searches for the character in the file.\n\n=================================================================\n=                    6.2 THE REPLACE COMMAND                    =\n=================================================================\n\n Type r<ch> to replace all selected characters with <ch>.\n\n 1. Move to the second line of the table, place the cursor on the\n    first =.\n 2. Type t| (Shift-\\) to select the = separator.\n 3. Type r- to replace the separator with dashes.\n\n\n | Month | Days |\n |=======|------|\n | Jan   | 31   |\n | Feb   | 28   |\n | Mar   | 31   |\n | ...   | ...  |\n\n\n\n\n=================================================================\n=                         6.3 REPETITION                        =\n=================================================================\n\n Type . to repeat the last insert command.\n Press Alt-. to repeat the last f / t selection.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Make a change, insertion or appendage and repeat it with . .\n 3. Try using Alt-. with f and t, to select multiple sentences\n    for instance.\n\n --> This is some text for you to repeat things. You can repeat\n     insertions like changing words, or repeat selections like\n     f / t.\n\n\n\n\n\n\n\n=================================================================\n=                        CHAPTER 6 RECAP                        =\n=================================================================\n\n * Type f / F to extend selection up to & including a character.\n   * Type t / T to extend selection until a character.\n\n * Type r to replace selected characters.\n\n * Type . to repeat the last insertion.\n   * Press Alt-. to repeat the last f / t selection.\n\n\n\n\n\n\n\n\n\n\n\n=================================================================\n=                  7.1 REPLACE WITH YANKED TEXT                 =\n=================================================================\n\n Type R to replace the selection with previously yanked text.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Type w to select \"watermelons\" and then y to yank it.\n 3. Select \"oranges\" with w.\n 4. Type R to replace \"oranges\" with \"watermelons\".\n\n\n --> I like watermelons because oranges are refreshing.\n     I like watermelons because watermelons are refreshing.\n\n\n\n\n\n\n\n\n=================================================================\n=                       7.2 JOINING LINES                       =\n=================================================================\n\n Type J to join together lines in selection.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Type x four times or 4x to select all four lines.\n 3. Type J to join the lines together.\n\n --> This sentence\nis spilling over\nonto other\nlines.\n\n     This sentence is spilling over onto other lines.\n\n\n\n\n\n\n=================================================================\n=                      7.3 INDENTING LINES                      =\n=================================================================\n\n Type > to indent a line and < to unindent it.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Move down to the second line and type > to indent it.\n 3. Move to the third line and type < to unindent it.\n\n --> These lines\n    are indented\n         very poorly.\n\n     These lines\n     are indented\n     much better.\n\n\n\n\n\n=================================================================\n=               7.4 INCREMENTING AND DECREMENTING               =\n=================================================================\n\n Press Ctrl-a to increment the number under selection.\n Press Ctrl-x to decrement the number under selection.\n\n 1. Move the cursor to the third line marked '-->' below.\n 2. Move the cursor onto the number 2, then press Ctrl-a.\n 3. Move onto the number 3 on the next line and press Ctrl-a.\n 4. Move onto the number 6 on the last line and press Ctrl-x.\n\n --> 1) First point.\n --> 2) Added point.\n --> 2) Next point.\n --> 3) Another point.\n --> 6) Last point.\n\n\n\n\n\n=================================================================\n=                        CHAPTER 7 RECAP                        =\n=================================================================\n\n * Type R to replace the selection with yanked text.\n\n * Type J to join lines in selection.\n\n * Type > and < to indent / unindent lines.\n\n * Press Ctrl-a to increment the selected number.\n   * Press Ctrl-x to decrement the selected number.\n\n\n\n\n\n\n\n\n\n\n=================================================================\n=                         8.1 REGISTERS                         =\n=================================================================\n\n Registers are containers identified by a character for storing\n things like yanked text. Registers are also used to store the\n most recent search term as well as macros, which you'll learn\n about in the next section.\n\n Type \"<ch> to select register <ch>.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Type w to select \"watermelons\" and yank with y.\n 3. Type w to select \"bananas\".\n 4. Change to register b with \"b and yank with y.\n 5. Select \"mangoes\" and type R to replace it with \"watermelons\".\n 6. Select \"pineapples\" then type \"b R to replace with \"bananas\".\n\n --> I like watermelons and bananas because my favorite fruits\n     are mangoes and pineapples.\n\n\n=================================================================\n=                          8.2 MACROS                           =\n=================================================================\n\n Macros are a way to record a set of actions you want to repeat.\n You can also record macros to a specific register (default @).\n Type Q to start recording a macro - you should see a popup at\n the bottom of your screen. Type Q again to stop recording.\n Type q to repeat the macro from register @ (the default).\n\n 1. Move the cursor to the first line marked '-->' below.\n    Ensure your cursor is on the '>' of the arrow.\n 2. Type Q to start recording.\n 3. Edit the line to look like the bottom one.\n 4. Exit insert and type Q again to stop recording.\n 5. Move to the line below and put your cursor on '>' again.\n 6. Type q to repeat the macro.\n\n --> ... sentence doesn't have its first and last ... .\n --> ... sentence doesn't have its first and last ... .\n     This sentence doesn't have its first and last word.\n\n=================================================================\n=                        CHAPTER 8 RECAP                        =\n=================================================================\n\n * Type \" to select a different register.\n\n * Type Q to start and stop recording a macro to a register,\n   the default being @.\n\n * Type q to replay a macro from @ or the selected register.\n\n\n\n\n\n\n\n\n\n\n\n\n=================================================================\n=                  9.1 SEARCHING FOR SELECTIONS                 =\n=================================================================\n\n The most recent search with / is stored in register /.\n n and N both refer to register /, this means we can set that\n register without having to type in a search.\n\n Type * to copy the selection into register /, setting the search\n term to the selection. This copies the primary selection, which\n you will learn about in the section on cycling selections.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Select \"horse\" with e and type *.\n 3. Use n and N to jump between the instances of \"horse\".\n\n --> A horse is a horse, of course, of course,\n --> And no one can talk to a horse of course.\n\n Note: * is like a shorthand for \"/y as all it really does is\n       copy the selection into the / register.\n\n=================================================================\n=           9.2 ADDING SELECTION ON NEXT SEARCH MATCH           =\n=================================================================\n\n A property of Select mode (v) when using n and N is that instead\n of moving the selection to the next match, it adds a new\n selection on each match.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Select the first \"bat\" and type * to set it to search.\n 3. Type v to enter Select mode.\n 4. Type n to select the other \"bat\".\n 5. Use c (or r after selecting the \"b\"s) to change the \"bat\"s to\n    \"cat\".\n\n --> Everybody wants to be a bat,\n --> because a cat's the only bat\n --> who knows where it's at.\n\n\n\n\n=================================================================\n=                     9.3 USING THE JUMPLIST                    =\n=================================================================\n\n Helix can keep track of \"jumps\" which are big movements, like\n searching or jumping to the definition of a function in code. It\n stores these in what's called the jumplist.\n\n Press Ctrl-s to manually save your current position to\n the jumplist.\n\n Press Ctrl-i (\"in\") and Ctrl-o (\"out\") to move forward and\n backwards in the jumplist respectively.\n\n 1. Press Ctrl-s somewhere.\n 2. Move far away in the file.\n 3. Press Ctrl-o (just once!) to come back to where you saved.\n\n\n\n\n\n=================================================================\n=             9.4 JUMP WITH TWO-CHARACTER LABELS                =\n=================================================================\n\n Type gw to enable the 2-character labels. The start of each word\n will be replaced by 2 highlighted characters. Type any sequence\n of 2 highlighted characters to jump to the corresponding label,\n or use ESC to drop the labels.\n\n The 2-character labels allow you to quickly jump to any location\n in the viewable selection.\n\n 1. Move the cursor to the start of the line marked '-->' below.\n 2. Press gw to enable the 2-character labels, and then the two\n    characters that replace the two letters 'he' at the start of\n    'here' to jump to the corresponding word.\n\n --> This is just a simple line of text.\n     There may be many such lines\n     But you really want to jump here!\n     This is fast with the 2-character labels.\n\n=================================================================\n=                        CHAPTER 9 RECAP                        =\n=================================================================\n\n * Type * to set the search register to the primary selection.\n\n * Type n / N in Select mode to add selections on each search\n   match.\n\n * Press Ctrl-s to save position to the jumplist.\n   * Press Ctrl-i and Ctrl-o to go forward and backward in the\n     jumplist.\n\n * Type gw to enable 2-character labels, and any 2 characters to\n   jump to the corresponding label, or ESC to drop the labels.\n\n\n\n\n\n\n\n=================================================================\n=             10.1 CYCLING AND REMOVING SELECTIONS              =\n=================================================================\n\n Type ) and ( to cycle the primary selection forward and backward\n through selections respectively.\n\n Press Alt-, to remove the primary selection.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Select both lines with xx or 2x.\n 3. Type s to select, type \"would\" and enter.\n 4. Use ( and ) to cycle the primary selection and deselect\n    the second \"would\" with Alt-, .\n 5. Type c \"wood\" to change the remaining \"would\"s to \"wood\".\n\n --> How much would would a wouldchuck chuck\n --> if a wouldchuck could chuck would?\n\n Note: The primary selection can be hard to see in some themes.\n       Check the status bar (bottom right) for the active index.\n\n=================================================================\n=             10.2 CYCLING THE CONTENT OF SELECTIONS            =\n=================================================================\n\n Press Alt-) and Alt-( to cycle the content of the selections\n forward and backward respectively.\n\n 1. Move the cursor to the line marked '-->' below.\n 2. Select both lines with xx or 2x.\n 3. Type s to select, type \"through|water|know\" and enter.\n 4. Use Alt-( and Alt-) to cycle the content of the selections.\n\n --> Jumping through the water,\n --> daring to know.\n\n\n\n\n\n\n\n\n=================================================================\n=                     10.3 CHANGING CASE                        =\n=================================================================\n\n Type ~ to switch the case of all selected letters.\n Type ` to set all selected letters to lowercase.\n Press Alt-` to set all selected letters to uppercase.\n\n 1. Move the cursor to the first line marked '-->' below.\n 2. Select each wrongly capitalised or lowercase letter\n    and type ~ over them.\n 3. Move to the second line marked '-->'.\n 4. Type x to select the line.\n 5. Type ` to change the line to lowercase.\n 6. Move to the third line marked '-->'.\n 7. Type x to select the line.\n 8. Press Alt-` to change the line to uppercase.\n\n --> thIs sENtencE hAs MIS-cApitalIsed leTTerS.\n --> this SENTENCE SHOULD all be in LOWERCASE.\n --> THIS sentence should ALL BE IN uppercase!\n\n=================================================================\n=                   10.4 SPLITTING SELECTIONS                   =\n=================================================================\n\n Type S to split each selection on a regex pattern.\n\n 1. Move the cursor to the line under ---.\n 2. Type xx / 2x to select the lines.\n 3. Type S then \\. |! Enter (note the spaces after . and !).\n    This effectively splits the selection into sentences at each\n    dot or exclamation mark.\n 4. Press Alt-; to reverse the selections.\n 5. Type ; to reduce selections to a single character - the first\n    letter of each sentence.\n 6. Press Alt-` to convert all selected letters to uppercase.\n\n---\nthese are sentences. some sentences don't start with uppercase\nletters! that is not good grammar. you can fix this.\n\n\n\n=================================================================\n=                        CHAPTER 10 RECAP                       =\n=================================================================\n\n * Use ) and ( to cycle the primary selection back and forward\n   through selections respectively.\n   * Press Alt-, to remove the primary selection.\n   * Press Alt-) and Alt-( to cycle the content of the selections.\n\n * Type ~ to alternate case of selected letters.\n   * Use ` and Alt-` to set the case of selected letters to\n     lower and upper respectively.\n\n * Type S to split selections on regex.\n\n\n\n\n\n\n\n\n=================================================================\n=                     11.1 COMMENTING A LINE                    =\n=================================================================\n\n Press Ctrl-c to comment the line under your cursor.\n To uncomment the line, press Ctrl-c again.\n\n 1. Move your cursor to the line marked '-->' below.\n 2. Now comment the line marked with '-->'.\n 3. Now try uncommenting the line.\n\n --> Comment me please\n\n\n\n\n\n\n\n\n\n\n=================================================================\n=                 11.2 COMMENTING MULTIPLE LINES                =\n=================================================================\n\n Using the selections and multi-cursor functionality, you can\n comment multiple lines as long as they are under the selection or\n cursors. To uncomment the lines, press Ctrl-c again.\n\n 1. Move your cursor to the line marked with '-->' below.\n 2. Now try to select or add more cursors to the other lines marked\n    with '-->'.\n 3. Comment those lines.\n 4. Uncomment those lines.\n\n --> What are you doing?!\n --> Stop commenting me!\n --> AAAAaargh!!!\n --> Enough! Uncomment me now!\n\n Note: If there are only some commented lines under selections or\n multiple cursors, they won't be uncommented but commented again.\n\n=================================================================\n=                       CHAPTER 11 RECAP                        =\n=================================================================\n\n * Use Ctrl-c to comment a line under your cursor. Press Ctrl-c\n   again to uncomment.\n * To comment multiple lines, use the selections or multi-cursors\n   before typing Ctrl-c. Press Ctrl-c again to uncomment.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n=================================================================\n=                   12.1 USING MATCH MODE JUMP                  =\n=================================================================\n\n To switch to match mode from normal mode, type m. This feature\n is particularly useful for handling bracket pairs and their\n contents.\n\n There are several actions that can be performed in match mode,\n as indicated by the help pop-up. To jump to a matching bracket pair,\n simply press mm. For example on the lines below (starting with\n -->), move the cursor in normal mode to (, and then press mm to jump\n to the matching ). You can do the same on the line below: for example\n move to ], and press mm to jump to [ .\n\n --> you can (jump between matching parentheses)\n --> or between matching [ square brackets ]\n --> now { you know the drill: this works with brackets too }\n\n\n\n\n=================================================================\n=              12.2 USING MATCH MODE SELECT INSIDE              =\n=================================================================\n\n Match mode also lets you select the \"inside\" content between a\n pair of brackets or other delimiters. In the lines below:\n\n - move to the --> line, put your cursor in normal mode at any\n location between the parentheses, for example at 'x', and press\n mi( or mi) to select the whole content inside the parentheses\n (parentheses excluded). As usual, you can then do anything you want\n with the selection (for example, press c to change it)\n\n --> outside and (inside x parentheses) - and outside again\n\n Test below that you can do the same with [], or {}, or with\n nested combinations of these (this will act on the immediately\n surrounding matching pair). This also works with \"\" and similar\n\n --> test [ with square brackets ] !\n --> try ( with nested [ pairs of ( parentheses) and \"brackets\" ])\n\n=================================================================\n=               12.3 USING MATCH MODE SELECT AROUND             =\n=================================================================\n\n You can also select the \"around\" content, i.e. both the inside\n content and the delimiters themselves, by using the ma select.\n For example, move to the line under, move your cursor in normal\n mode to any position between the (), and select the content of\n the (), including the surrounding (), by typing ma( or ma). As\n usual, you can do anything you want with the selection, for\n example delete it all with ma(d .\n\n --> you ( select x around ) to include delimiters in the select\n\n This naturally works with other delimiters too:\n\n --> try [ with 'square' brackets ] too!\n\n\n\n\n\n=================================================================\n=                12.4 USING MATCH MODE SURROUND                 =\n=================================================================\n\n The match mode can also be used to add surrounding around the\n current selection. For example, move to the line below, then:\n  * i) select the \"select all of this\" line segment (for example,\n move in normal mode the cursor to the start of select, then enter\n selection mode with v , then select the 4 next words with 4e ),\n  * ii) press ms( or ms) to surround the selection with a pair of\n parentheses.\n\n --> so, select all of this, and surround it with ()\n\n You can do the same with other delimiters: for example, ms' on\n WORD below to surround it with a pair of ''. You can try also\n with adding a surrounding pair of \"\", or {}, or [].\n\n --> surround this WORD !\n\n\n\n=================================================================\n=              12.5 USING MATCH MODE DELETE SURROUND            =\n=================================================================\n\n You can delete surrounding pair of delimiters with the md\n command. On the line below, move the cursor anywhere\n within the pair of (), for example to the 'x', then from there,\n in normal mode, press md( or md) to delete the surrounding\n pair of parentheses.\n\n --> delete (the x pair of parentheses) from within!\n\n You can naturally delete other kinds of surroundings:\n\n --> delete (nested [delimiters]): \"this\" will delete the nearest\n matching surrounding pair.\n --> delete \"layers \"of\" quote marks\" too: this will delete the\n nearest previous and following quote marks\n\n Trying to delete nonexistent surrounding delimiters prints an error\n at the bottom bar and does nothing.\n\n=================================================================\n=             12.6 USING MATCH MODE REPLACE SURROUND            =\n=================================================================\n\n You can replace surrounding pairs of delimiters with the mr\n command. On the line below, move the cursor to\n anywhere within the pair of (), for example on the 'x', then in\n normal mode, press mr([ to replace the pair of () with a pair\n of [].\n\n --> replace the (pair from x within), with something else\n\n This command will act on the closest enclosing pair, so you\n can try replacing different surrounding in the following:\n\n --> some (nested surroundings [can be replaced])\n --> this \"works with 'other surroundings' too\"\n\n You can try to replace a nonexistent pair: this will show\n an error warning at the bottom bar and do nothing.\n\n\n=================================================================\n=                       CHAPTER 12 RECAP                        =\n=================================================================\n\n You can enter the match mode with the m key; this will show the\n actions available in a popup. This will allow you to:\n  * jump to matching pair of delimiters with mm (you must have a\n  delimiter belonging to a pair under your cursor)\n  * select inside a pair of delimiters surrounding your cursor\n  (i.e. select the content but not the delimiters) with mi(\n  and similar\n  * select around a pair of delimiters surrounding your cursor\n  (i.e. select the content and the delimiters) with ma( and\n  similar\n  * delete surrounding delimiters with md( and similar\n  * add surrounding delimiters around the selection with ms(\n  * replace a pair of delimiters surrounding your selection with\n  mr([ to replace for example surrounding () with []\n\n\n\n\n=================================================================\n=                CHAPTER 13.1 CREATE NEW SPLIT                  =\n=================================================================\n\n In Normal mode, press Ctrl-w to open the Window menu, which displays\n a list of available commands.\n\n To open a new empty buffer in a vertical split on the right half\n of your current window, use Ctrl-w nv (i.e., press Ctrl\n and w simultaneously, then press n, followed by v). Your current\n window will now split in 2 vertically. A new empty buffer split\n will appear on the right half and your cursor will jump to the\n new vertical split.\n\n To create a new empty buffer in a horizontal split, press\n Ctrl-w ns. This action divides your current window into two\n horizontally, creates a new buffer, and moves your cursor to the\n new horizontal split.\n\n\n\n\n=================================================================\n=                CHAPTER 13.2 MOVE BETWEEN SPLITS               =\n=================================================================\n\n Use Ctrl-w k to move to the split above your current split. Use\n Ctrl-w j to move to the split below. Use Ctrl-w h to move to\n the split on the left and Ctrl-w l to move to the split on the\n right. To navigate to the next split (in the order they were\n opened), press Ctrl-w w.\n\n You can now do whatever you want in your new buffers and splits.\n Once you are done with using your new buffer split,\n you can close it with Ctrl-w q . Move to the bottom right split\n with Ctrl-w l then Ctrl-w j, then press Ctrl-w q to close this\n specific split.\n\n You can also close all splits except the current one with Ctrl-w o .\n Open a third vertical split with Ctrl-w nv , then move to the\n leftmost split with Ctrl-w h twice, then from inside the split on\n the left press Ctrl-w o to close all except this split.\n\n\n=================================================================\n=               CHAPTER 13.3 SPLIT CURRENT BUFFER               =\n=================================================================\n\n Use Ctrl-w s to split the view of the current buffer horizontally\n and Ctrl-w v to split it vertically with the buffer opened in both\n splits.\n\n Close extra splits with Ctrl-w o to return to a single window view.\n\n\n\n\n\n\n\n\n\n\n\n\n\n=================================================================\n=               CHAPTER 13.4 USE COMMANDS TO SPLIT              =\n=================================================================\n\n The :vsplit (or :vs for short) and :hsplit (or :hs) commands can\n also be used to split a specific buffer vertically or horizontally.\n For example, enter the command:\n\n :vs something\n\n to open a new vertical split named \"something\" to the right. Here,\n \"something\" is not an existing file, so a new buffer with this name\n will open; however, you can replace \"something\" with any file name\n to open it in a new buffer. Similarly, you can enter the command:\n\n :hs some_more\n\n to open a new buffer named \"some_more\" in the lower half.\n \"some_more\" could be any file or path to open this specific file\n or path instead of a new empty buffer.\n\n\n=================================================================\n=                  CHAPTER 13.5 SWAPPING SPLITS                 =\n=================================================================\n\n Open a split on the right with :vs hello1 and then a split below\n with :hs hello2.\n\n From hello2, press Ctrl-w K to swap it with the split above. Now\n hello2 is at the top while hello1 is at the bottom.\n\n Still from hello2, press Ctrl-w H to swap with the split on the\n left: now hello2 is on the left and the tutor is on the top\n right. After Ctrl-w you can use HJKL to swap with the buffer\n on the left / below / above / on the right.\n\n Move back to the tutor split, and press Ctrl-w o to only keep\n this split.\n\n\n\n\n\n=================================================================\n=                CHAPTER 13.6 TRANSPOSE SPLITS                  =\n=================================================================\n\n Open a split on the right with :vs hello1 and then a split below\n with :hs hello2.\n\n Move to the tutor split, then press Ctrl-w t to transpose the\n vertical split opened from this window: now, hello1 and\n hello2 are below, rather than to the right of, the tutor. Press\n Ctrl-w t again to transpose back.\n\n Move to the hello1 split, then press Ctrl-w t to transpose the\n horizontal split that was opened from this window: now hello2\n is on the right, rather than below, hello1. Press Ctrl-w t to\n transpose back.\n\n Move back to the tutor split and press Ctrl-w o to close all but\n the tutor window.\n\n\n\n=================================================================\n=             CHAPTER 13.7 OPEN SPLIT FROM FILEPICKER           =\n=================================================================\n\n Splits can also be opened directly from the file picker. Press\n space f to open the file picker. From there, you can type in text\n to perform file lookup with fuzzy matching, and use the arrows\n up and down to move the selected file (indicated by the > symbol).\n If you want to exit the file picker, press Escape.\n\n Select any file you like in the file picker. You could open it in\n the current view by pressing enter (do not do this at present).\n But you can also open it in a new split. Press Ctrl-v to open\n the selected file in a new vertical split. Press space f again,\n select any file you want, and press Ctrl-s to open it in a\n horizontal split.\n\n Move back to the tutor split, and press Ctrl-w o to close all\n splits except this one.\n\n\n\n=================================================================\n=                        CHAPTER 13 RECAP                       =\n=================================================================\n\n Splits can be used to display either the same buffer several times\n or several buffers. To access the main windows and splits commands,\n press Ctrl-w . You can move between splits with Ctrl-w hjkl ,\n you can close a split with Ctrl-w q , and you can close all but\n the present split with Ctrl-w o .\n\n Splits can also be opened by using the :vs FILENAME and\n :hs FILENAME commands.\n\n Splits can also be used directly from the file pickers, by using\n Ctrl-v to open the file selected in a new vertical split, and\n Ctrl-s in a horizontal split.\n\n\n\n\n\n\n=================================================================\n This tutorial is still a work-in-progress.\n More sections are planned.\n"
  },
  {
    "path": "rust-toolchain.toml",
    "content": "[toolchain]\nchannel = \"1.87.0\"\ncomponents = [\"rustfmt\", \"rust-src\", \"clippy\"]\n"
  },
  {
    "path": "rustfmt.toml",
    "content": ""
  },
  {
    "path": "shell.nix",
    "content": "# Flake's devShell for non-flake-enabled nix instances\nlet\n  compat = builtins.fetchTarball {\n    url = \"https://github.com/edolstra/flake-compat/archive/b4a34015c698c7793d592d66adbab377907a2be8.tar.gz\";\n    sha256 = \"sha256:1qc703yg0babixi6wshn5wm2kgl5y1drcswgszh4xxzbrwkk9sv7\";\n  };\nin\n  (import compat {src = ./.;}).shellNix.default\n"
  },
  {
    "path": "theme.toml",
    "content": "attribute = \"lilac\"\nkeyword = \"almond\"\n\"keyword.directive\" = \"lilac\" # -- preprocessor comments (#if in C)\nnamespace = \"lilac\"\npunctuation = \"lavender\"\n\"punctuation.delimiter\" = \"lavender\"\noperator = \"lilac\"\nspecial = \"honey\"\n\"variable.other.member\" = \"white\"\nvariable = \"lavender\"\n# variable = \"almond\" # TODO: metavariables only\n# \"variable.parameter\" = { fg = \"lavender\", modifiers = [\"underlined\"] }\n\"variable.parameter\" = { fg = \"lavender\" }\n\"variable.builtin\" = \"mint\"\ntype = \"white\"\n\"type.builtin\" = \"white\" # TODO: distinguish?\nconstructor = \"lilac\"\nfunction = \"white\"\n\"function.macro\" = \"lilac\"\n\"function.builtin\" = \"white\"\ntag = \"almond\"\ncomment = \"sirocco\"\nconstant = \"white\"\n\"constant.builtin\" = \"white\"\nstring = \"silver\"\n\"constant.numeric\" = \"chamois\"\n\"constant.character.escape\" = \"honey\"\n# used for lifetimes\nlabel = \"honey\"\ntabstop = { modifiers = [\"italic\"], bg = \"bossanova\" }\n\n\"markup.heading\" = \"lilac\"\n\"markup.bold\" = { modifiers = [\"bold\"] }\n\"markup.italic\" = { modifiers = [\"italic\"] }\n\"markup.strikethrough\" = { modifiers = [\"crossed_out\"] }\n\"markup.link.url\" = { fg = \"silver\", modifiers = [\"underlined\"] }\n\"markup.link.text\" = \"almond\"\n\"markup.raw\" = \"almond\"\n\n\"diff.plus\" = \"#35bf86\"\n\"diff.minus\" = \"#f22c86\"\n\"diff.delta\" = \"#6f44f0\"\n\n# TODO: differentiate doc comment\n# concat (ERROR) @error.syntax and \"MISSING ;\" selectors for errors\n\n\"ui.background\" = { bg = \"midnight\" }\n\"ui.background.separator\" = { fg = \"comet\" }\n\"ui.linenr\" = { fg = \"comet\" }\n\"ui.linenr.selected\" = { fg = \"lilac\" }\n\"ui.statusline\" = { fg = \"lilac\", bg = \"revolver\" }\n\"ui.statusline.inactive\" = { fg = \"lavender\", bg = \"revolver\" }\n\"ui.popup\" = { bg = \"revolver\" }\n\"ui.window\" = { fg = \"bossanova\" }\n\"ui.help\" = { bg = \"#7958DC\", fg = \"#171452\" }\n\"ui.text\" = { fg = \"lavender\" }\n\"ui.text.focus\" = { fg = \"white\" }\n\"ui.text.inactive\" = \"sirocco\"\n\"ui.text.directory\" = { fg = \"lilac\" }\n\"ui.virtual\" = { fg = \"comet\" }\n\"ui.virtual.ruler\" = { bg = \"bossanova\" }\n\"ui.virtual.jump-label\" = { fg = \"apricot\", modifiers = [\"bold\"] }\n\n\"ui.virtual.indent-guide\" = { fg = \"comet\" }\n\n\"ui.selection\" = { bg = \"#540099\" }\n\"ui.selection.primary\" = { bg = \"#540099\" }\n# TODO: namespace ui.cursor as ui.selection.cursor?\n\"ui.cursor.select\" = { bg = \"delta\" }\n\"ui.cursor.insert\" = { bg = \"white\" }\n\"ui.cursor.primary.select\" = { bg = \"delta\" }\n\"ui.cursor.primary.insert\" = { bg = \"white\" }\n\"ui.cursor.match\" = { fg = \"#212121\", bg = \"#6C6999\" }\n\"ui.cursor\" = { modifiers = [\"reversed\"] }\n\"ui.cursorline.primary\" = { bg = \"bossanova\" }\n\"ui.highlight\" = { bg = \"bossanova\" }\n\"ui.highlight.frameline\" = { bg = \"#634450\" }\n\"ui.debug\" = { fg = \"#634450\" }\n\"ui.debug.breakpoint\" = { fg = \"apricot\" }\n\"ui.menu\" = { fg = \"lavender\", bg = \"revolver\" }\n\"ui.menu.selected\" = { fg = \"revolver\", bg = \"white\" }\n\"ui.menu.scroll\" = { fg = \"lavender\", bg = \"comet\" }\n\n\"diagnostic.hint\" = { underline = { color = \"silver\", style = \"curl\" } }\n\"diagnostic.info\" = { underline = { color = \"delta\", style = \"curl\" } }\n\"diagnostic.warning\" = { underline = { color = \"lightning\", style = \"curl\" } }\n\"diagnostic.error\" = { underline = { color = \"apricot\", style = \"curl\" } }\n\"diagnostic.unnecessary\" = { modifiers = [\"dim\"] }\n\"diagnostic.deprecated\" = { modifiers = [\"crossed_out\"] }\n\nwarning = \"lightning\"\nerror = \"apricot\"\ninfo = \"delta\"\nhint = \"silver\"\n\n[palette]\nwhite = \"#ffffff\"\nlilac = \"#dbbfef\"\nlavender = \"#a4a0e8\"\ncomet = \"#5a5977\"\nbossanova = \"#452859\"\nmidnight = \"#3b224c\"\nrevolver = \"#281733\"\n\nsilver = \"#cccccc\"\nsirocco = \"#697C81\"\nmint = \"#9ff28f\"\nalmond = \"#eccdba\"\nchamois = \"#E8DCA0\"\nhoney = \"#efba5d\"\n\napricot = \"#f47868\"\nlightning = \"#ffcd1c\"\ndelta = \"#6F44F0\"\n"
  },
  {
    "path": "xtask/Cargo.toml",
    "content": "[package]\nname = \"xtask\"\nversion.workspace = true\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\nrust-version.workspace = true\ncategories.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\nhelix-term = { path = \"../helix-term\" }\nhelix-core = { path = \"../helix-core\" }\nhelix-view = { path = \"../helix-view\" }\nhelix-loader = { path = \"../helix-loader\" }\ntoml.workspace = true\n"
  },
  {
    "path": "xtask/src/docgen.rs",
    "content": "use crate::helpers;\nuse crate::path;\nuse crate::DynError;\n\nuse helix_term::commands::MappableCommand;\nuse helix_term::commands::TYPABLE_COMMAND_LIST;\nuse helix_term::health::TsFeature;\nuse helix_view::document::Mode;\n\nuse std::collections::HashSet;\nuse std::fs;\n\npub const TYPABLE_COMMANDS_MD_OUTPUT: &str = \"typable-cmd.md\";\npub const STATIC_COMMANDS_MD_OUTPUT: &str = \"static-cmd.md\";\npub const LANG_SUPPORT_MD_OUTPUT: &str = \"lang-support.md\";\n\nfn md_table_heading(cols: &[String]) -> String {\n    let mut header = String::new();\n    header += &md_table_row(cols);\n    header += &md_table_row(&vec![\"---\".to_string(); cols.len()]);\n    header\n}\n\nfn md_table_row(cols: &[String]) -> String {\n    format!(\"| {} |\\n\", cols.join(\" | \"))\n}\n\nfn md_mono(s: &str) -> String {\n    format!(\"`{}`\", s)\n}\n\npub fn typable_commands() -> Result<String, DynError> {\n    let mut md = String::new();\n    md.push_str(&md_table_heading(&[\n        \"Name\".to_owned(),\n        \"Description\".to_owned(),\n    ]));\n\n    // escape | so it doesn't get rendered as a column separator\n    let cmdify = |s: &str| format!(\"`:{}`\", s.replace('|', \"\\\\|\"));\n\n    for cmd in TYPABLE_COMMAND_LIST {\n        let names = std::iter::once(&cmd.name)\n            .chain(cmd.aliases.iter())\n            .map(|a| cmdify(a))\n            .collect::<Vec<_>>()\n            .join(\", \");\n\n        let doc = cmd.doc.replace('\\n', \"<br>\");\n\n        md.push_str(&md_table_row(&[names.to_owned(), doc.to_owned()]));\n    }\n\n    Ok(md)\n}\n\npub fn static_commands() -> Result<String, DynError> {\n    let mut md = String::new();\n    let keymap = helix_term::keymap::default();\n    let keymaps = [\n        (\"normal\", keymap[&Mode::Normal].reverse_map()),\n        (\"select\", keymap[&Mode::Select].reverse_map()),\n        (\"insert\", keymap[&Mode::Insert].reverse_map()),\n    ];\n\n    md.push_str(&md_table_heading(&[\n        \"Name\".to_owned(),\n        \"Description\".to_owned(),\n        \"Default keybinds\".to_owned(),\n    ]));\n\n    for cmd in MappableCommand::STATIC_COMMAND_LIST {\n        let keymap_strings: Vec<_> = keymaps\n            .iter()\n            .map(|(mode, keymap)| {\n                let bindings = keymap\n                    .get(cmd.name())\n                    .map(|bindings| {\n                        let mut bind_strings: Vec<_> = bindings\n                            .iter()\n                            .map(|bind| {\n                                let keys = &bind\n                                    .iter()\n                                    .map(|key| key.key_sequence_format())\n                                    .collect::<String>()\n                                    // escape | so it doesn't get rendered as a column separator\n                                    .replace('|', \"\\\\|\");\n                                format!(\"`` {} ``\", keys)\n                            })\n                            .collect();\n                        // sort for stable output. sorting by length puts simple\n                        // keybindings first and groups similar keys together\n                        bind_strings.sort_by_key(|s| (s.len(), s.to_owned()));\n                        bind_strings.join(\", \")\n                    })\n                    .unwrap_or_default();\n\n                (mode, bindings)\n            })\n            .collect();\n\n        let keymap_string = keymap_strings\n            .iter()\n            .filter(|(_, bindings)| !bindings.is_empty())\n            .map(|(mode, bindings)| format!(\"{}: {}\", mode, bindings))\n            .collect::<Vec<_>>()\n            .join(\", \");\n\n        md.push_str(&md_table_row(&[\n            md_mono(cmd.name()),\n            cmd.doc().to_owned(),\n            keymap_string,\n        ]));\n    }\n\n    Ok(md)\n}\n\npub fn lang_features() -> Result<String, DynError> {\n    let mut md = String::new();\n    let ts_features = TsFeature::all();\n\n    let mut cols = vec![\"Language\".to_owned()];\n    cols.append(\n        &mut ts_features\n            .iter()\n            .map(|t| t.long_title().to_string())\n            .collect::<Vec<_>>(),\n    );\n    cols.push(\"Default language servers\".to_owned());\n\n    md.push_str(&md_table_heading(&cols));\n    let config = helix_core::config::default_lang_config();\n\n    let mut langs = config\n        .language\n        .iter()\n        .map(|l| l.language_id.clone())\n        .collect::<Vec<_>>();\n    langs.sort_unstable();\n\n    let mut ts_features_to_langs = Vec::new();\n    for &feat in ts_features {\n        ts_features_to_langs.push((feat, helpers::ts_lang_support(feat)));\n    }\n\n    let mut row = Vec::new();\n    for lang in langs {\n        let lc = config\n            .language\n            .iter()\n            .find(|l| l.language_id == lang)\n            .unwrap(); // lang comes from config\n        row.push(lc.language_id.clone());\n\n        for (_feat, support_list) in &ts_features_to_langs {\n            row.push(\n                if support_list.contains(&lang) {\n                    \"✓\"\n                } else {\n                    \"\"\n                }\n                .to_owned(),\n            );\n        }\n        let mut seen_commands = HashSet::new();\n        let mut commands = String::new();\n        for ls_config in lc\n            .language_servers\n            .iter()\n            .filter_map(|ls| config.language_server.get(&ls.name))\n        {\n            let command = &ls_config.command;\n            if !seen_commands.insert(command) {\n                continue;\n            }\n\n            if !commands.is_empty() {\n                commands.push_str(\", \");\n            }\n\n            commands.push_str(&md_mono(command));\n        }\n        row.push(commands);\n\n        md.push_str(&md_table_row(&row));\n        row.clear();\n    }\n\n    Ok(md)\n}\n\npub fn write(filename: &str, data: &str) {\n    let error = format!(\"Could not write to {}\", filename);\n    let path = path::book_gen().join(filename);\n    fs::write(path, data).expect(&error);\n}\n"
  },
  {
    "path": "xtask/src/helpers.rs",
    "content": "use std::path::{Path, PathBuf};\n\nuse crate::path;\nuse helix_term::health::TsFeature;\n\n/// Get the list of languages that support a particular tree-sitter\n/// based feature.\npub fn ts_lang_support(feat: TsFeature) -> Vec<String> {\n    let queries_dir = path::ts_queries();\n\n    find_files(&queries_dir, feat.runtime_filename())\n        .iter()\n        .map(|f| {\n            // .../helix/runtime/queries/python/highlights.scm\n            let tail = f.strip_prefix(&queries_dir).unwrap(); // python/highlights.scm\n            let lang = tail.components().next().unwrap(); // python\n            lang.as_os_str().to_string_lossy().to_string()\n        })\n        .collect()\n}\n\n// naive implementation, but suffices for our needs\npub fn find_files(dir: &Path, filename: &str) -> Vec<PathBuf> {\n    std::fs::read_dir(dir)\n        .unwrap()\n        .filter_map(|entry| {\n            let path = entry.ok()?.path();\n            if path.is_dir() {\n                Some(find_files(&path, filename))\n            } else if path.file_name()?.to_string_lossy() == filename {\n                Some(vec![path])\n            } else {\n                None\n            }\n        })\n        .flatten()\n        .collect()\n}\n"
  },
  {
    "path": "xtask/src/main.rs",
    "content": "mod docgen;\nmod helpers;\nmod path;\n\nuse std::{env, error::Error};\n\ntype DynError = Box<dyn Error>;\n\npub mod tasks {\n    use crate::DynError;\n    use std::collections::HashSet;\n\n    pub fn docgen() -> Result<(), DynError> {\n        use crate::docgen::*;\n        write(TYPABLE_COMMANDS_MD_OUTPUT, &typable_commands()?);\n        write(STATIC_COMMANDS_MD_OUTPUT, &static_commands()?);\n        write(LANG_SUPPORT_MD_OUTPUT, &lang_features()?);\n        Ok(())\n    }\n\n    pub fn querycheck(languages: impl Iterator<Item = String>) -> Result<(), DynError> {\n        use helix_core::syntax::LanguageData;\n\n        let languages_to_check: HashSet<_> = languages.collect();\n        let loader = helix_core::config::default_lang_loader();\n        for (_language, lang_data) in loader.languages() {\n            if !languages_to_check.is_empty()\n                && !languages_to_check.contains(&lang_data.config().language_id)\n            {\n                continue;\n            }\n            let config = lang_data.config();\n            let Some(syntax_config) = LanguageData::compile_syntax_config(config, &loader)? else {\n                continue;\n            };\n            let grammar = syntax_config.grammar;\n            LanguageData::compile_indent_query(grammar, config)?;\n            LanguageData::compile_textobject_query(grammar, config)?;\n            LanguageData::compile_tag_query(grammar, config)?;\n            LanguageData::compile_rainbow_query(grammar, config)?;\n        }\n\n        println!(\"Query check succeeded\");\n\n        Ok(())\n    }\n\n    pub fn themecheck(themes: impl Iterator<Item = String>) -> Result<(), DynError> {\n        use helix_view::theme::Loader;\n\n        let themes_to_check: HashSet<_> = themes.collect();\n\n        let theme_names = [\n            vec![\"default\".to_string(), \"base16_default\".to_string()],\n            Loader::read_names(&crate::path::themes()),\n        ]\n        .concat();\n        let loader = Loader::new(&[crate::path::runtime()]);\n        let mut errors_present = false;\n\n        for name in theme_names {\n            if !themes_to_check.is_empty() && !themes_to_check.contains(&name) {\n                continue;\n            }\n\n            let (_, warnings) = loader.load_with_warnings(&name).unwrap();\n\n            if !warnings.is_empty() {\n                errors_present = true;\n                println!(\"Theme '{name}' loaded with errors:\");\n                for warning in warnings {\n                    println!(\"\\t* {}\", warning);\n                }\n            }\n        }\n\n        match errors_present {\n            true => Err(\"Errors found when loading bundled themes\".into()),\n            false => {\n                println!(\"Theme check successful!\");\n                Ok(())\n            }\n        }\n    }\n\n    pub fn print_help() {\n        println!(\n            \"\nUsage: Run with `cargo xtask <task>`, eg. `cargo xtask docgen`.\n\n    Tasks:\n        docgen                     Generate files to be included in the mdbook output.\n        query-check [languages]    Check that tree-sitter queries are valid for the given\n                                   languages, or all languages if none are specified.\n        theme-check [themes]       Check that the theme files in runtime/themes/ are valid for the\n                                   given themes, or all themes if none are specified.\n\"\n        );\n    }\n}\n\nfn main() -> Result<(), DynError> {\n    let mut args = env::args().skip(1);\n    let task = args.next();\n    match task {\n        None => tasks::print_help(),\n        Some(t) => match t.as_str() {\n            \"docgen\" => tasks::docgen()?,\n            \"query-check\" => tasks::querycheck(args)?,\n            \"theme-check\" => tasks::themecheck(args)?,\n            invalid => return Err(format!(\"Invalid task name: {}\", invalid).into()),\n        },\n    };\n    Ok(())\n}\n"
  },
  {
    "path": "xtask/src/path.rs",
    "content": "use std::path::{Path, PathBuf};\n\npub fn project_root() -> PathBuf {\n    Path::new(env!(\"CARGO_MANIFEST_DIR\"))\n        .parent()\n        .unwrap()\n        .to_path_buf()\n}\n\npub fn book_gen() -> PathBuf {\n    project_root().join(\"book/src/generated/\")\n}\n\npub fn runtime() -> PathBuf {\n    project_root().join(\"runtime\")\n}\n\npub fn ts_queries() -> PathBuf {\n    runtime().join(\"queries\")\n}\n\npub fn themes() -> PathBuf {\n    runtime().join(\"themes\")\n}\n"
  }
]